1
Mostly this is patches from me and RTH cleaning up and doing
1
Hi; here's the first target-arm pullreq for the 7.0 cycle.
2
more decodetree conversion for AArch32 Neon. The major new feature
3
is Dongjiu Geng's patchset to report host memory errors to KVM guests;
4
also a new aspeed board from Patrick Williams.
5
2
6
thanks
3
thanks
7
-- PMM
4
-- PMM
8
5
9
The following changes since commit 035b448b84f3557206abc44d786c5d3db2638f7d:
6
The following changes since commit 76b56fdfc9fa43ec6e5986aee33f108c6c6a511e:
10
7
11
Merge remote-tracking branch 'remotes/gkurz/tags/9p-next-2020-05-14' into staging (2020-05-14 10:58:30 +0100)
8
Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2021-12-14 12:46:18 -0800)
12
9
13
are available in the Git repository at:
10
are available in the Git repository at:
14
11
15
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200514
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20211215
16
13
17
for you to fetch changes up to e95485f85657be21135c17a9226e297c21e73360:
14
for you to fetch changes up to aed176558806674d030a8305d989d4e6a5073359:
18
15
19
target/arm: Convert NEON VFMA, VFMS 3-reg-same insns to decodetree (2020-05-14 15:03:09 +0100)
16
tests/acpi: add expected blob for VIOT test on virt machine (2021-12-15 10:35:26 +0000)
20
17
21
----------------------------------------------------------------
18
----------------------------------------------------------------
22
target-arm queue:
19
target-arm queue:
23
* target/arm: Use correct GDB XML for M-profile cores
20
* ITS: error reporting cleanup
24
* target/arm: Code cleanup to use gvec APIs better
21
* aspeed: improve documentation
25
* aspeed: Add support for the sonorapass-bmc board
22
* Fix STM32F2XX USART data register readout
26
* target/arm: Support reporting KVM host memory errors
23
* allow emulated GICv3 to be disabled in non-TCG builds
27
to the guest via ACPI notifications
24
* fix exception priority for singlestep, misaligned PC, bp, etc
28
* target/arm: Finish conversion of Neon 3-reg-same insns to decodetree
25
* Correct calculation of tlb range invalidate length
26
* npcm7xx_emc: fix missing queue_flush
27
* virt: Add VIOT ACPI table for virtio-iommu
28
* target/i386: Use assert() to sanity-check b1 in SSE decode
29
* Don't include qemu-common unnecessarily
29
30
30
----------------------------------------------------------------
31
----------------------------------------------------------------
31
Dongjiu Geng (10):
32
Alex Bennée (1):
32
acpi: nvdimm: change NVDIMM_UUID_LE to a common macro
33
hw/intc: clean-up error reporting for failed ITS cmd
33
hw/arm/virt: Introduce a RAS machine option
34
docs: APEI GHES generation and CPER record description
35
ACPI: Build related register address fields via hardware error fw_cfg blob
36
ACPI: Build Hardware Error Source Table
37
ACPI: Record the Generic Error Status Block address
38
KVM: Move hwpoison page related functions into kvm-all.c
39
ACPI: Record Generic Error Status Block(GESB) table
40
target-arm: kvm64: handle SIGBUS signal from kernel or KVM
41
MAINTAINERS: Add ACPI/HEST/GHES entries
42
34
43
Patrick Williams (1):
35
Jean-Philippe Brucker (8):
44
aspeed: Add support for the sonorapass-bmc board
36
hw/arm/virt-acpi-build: Add VIOT table for virtio-iommu
37
hw/arm/virt: Remove device tree restriction for virtio-iommu
38
hw/arm/virt: Reject instantiation of multiple IOMMUs
39
hw/arm/virt: Use object_property_set instead of qdev_prop_set
40
tests/acpi: allow updates of VIOT expected data files
41
tests/acpi: add test case for VIOT
42
tests/acpi: add expected blobs for VIOT test on q35 machine
43
tests/acpi: add expected blob for VIOT test on virt machine
45
44
46
Peter Maydell (18):
45
Joel Stanley (4):
47
target/arm: Use correct GDB XML for M-profile cores
46
docs: aspeed: Add new boards
48
target/arm: Convert Neon 3-reg-same VQRDMLAH/VQRDMLSH to decodetree
47
docs: aspeed: Update OpenBMC image URL
49
target/arm: Convert Neon 3-reg-same SHA to decodetree
48
docs: aspeed: Give an example of booting a kernel
50
target/arm: Convert Neon 64-bit element 3-reg-same insns
49
docs: aspeed: ADC is now modelled
51
target/arm: Convert Neon VHADD 3-reg-same insns
52
target/arm: Convert Neon VABA/VABD 3-reg-same to decodetree
53
target/arm: Convert Neon VRHADD, VHSUB 3-reg-same insns to decodetree
54
target/arm: Convert Neon VQSHL, VRSHL, VQRSHL 3-reg-same insns to decodetree
55
target/arm: Convert Neon VPMAX/VPMIN 3-reg-same insns to decodetree
56
target/arm: Convert Neon VPADD 3-reg-same insns to decodetree
57
target/arm: Convert Neon VQDMULH/VQRDMULH 3-reg-same to decodetree
58
target/arm: Convert Neon VADD, VSUB, VABD 3-reg-same insns to decodetree
59
target/arm: Convert Neon VPMIN/VPMAX/VPADD float 3-reg-same insns to decodetree
60
target/arm: Convert Neon fp VMUL, VMLA, VMLS 3-reg-same insns to decodetree
61
target/arm: Convert Neon 3-reg-same compare insns to decodetree
62
target/arm: Move 'env' argument of recps_f32 and rsqrts_f32 helpers to usual place
63
target/arm: Convert Neon fp VMAX/VMIN/VMAXNM/VMINNM/VRECPS/VRSQRTS to decodetree
64
target/arm: Convert NEON VFMA, VFMS 3-reg-same insns to decodetree
65
50
66
Richard Henderson (16):
51
Olivier Hériveaux (1):
67
target/arm: Create gen_gvec_[us]sra
52
Fix STM32F2XX USART data register readout
68
target/arm: Create gen_gvec_{u,s}{rshr,rsra}
69
target/arm: Create gen_gvec_{sri,sli}
70
target/arm: Remove unnecessary range check for VSHL
71
target/arm: Tidy handle_vec_simd_shri
72
target/arm: Create gen_gvec_{ceq,clt,cle,cgt,cge}0
73
target/arm: Create gen_gvec_{mla,mls}
74
target/arm: Swap argument order for VSHL during decode
75
target/arm: Create gen_gvec_{cmtst,ushl,sshl}
76
target/arm: Create gen_gvec_{uqadd, sqadd, uqsub, sqsub}
77
target/arm: Remove fp_status from helper_{recpe, rsqrte}_u32
78
target/arm: Create gen_gvec_{qrdmla,qrdmls}
79
target/arm: Pass pointer to qc to qrdmla/qrdmls
80
target/arm: Clear tail in gvec_fmul_idx_*, gvec_fmla_idx_*
81
target/arm: Vectorize SABD/UABD
82
target/arm: Vectorize SABA/UABA
83
53
84
docs/specs/acpi_hest_ghes.rst | 110 ++
54
Patrick Venture (1):
85
docs/specs/index.rst | 1 +
55
hw/net: npcm7xx_emc fix missing queue_flush
86
configure | 4 +-
87
default-configs/arm-softmmu.mak | 1 +
88
include/hw/acpi/aml-build.h | 1 +
89
include/hw/acpi/generic_event_device.h | 2 +
90
include/hw/acpi/ghes.h | 74 +
91
include/hw/arm/virt.h | 1 +
92
include/qemu/uuid.h | 27 +
93
include/sysemu/kvm.h | 3 +-
94
include/sysemu/kvm_int.h | 12 +
95
target/arm/cpu.h | 4 +
96
target/arm/helper.h | 78 +-
97
target/arm/internals.h | 5 +-
98
target/arm/translate.h | 84 +-
99
target/i386/cpu.h | 2 +
100
target/arm/neon-dp.decode | 119 +-
101
accel/kvm/kvm-all.c | 36 +
102
hw/acpi/aml-build.c | 2 +
103
hw/acpi/generic_event_device.c | 19 +
104
hw/acpi/ghes.c | 448 ++++++
105
hw/acpi/nvdimm.c | 10 +-
106
hw/arm/aspeed.c | 78 ++
107
hw/arm/virt-acpi-build.c | 15 +
108
hw/arm/virt.c | 23 +
109
target/arm/cpu_tcg.c | 1 +
110
target/arm/gdbstub.c | 22 +-
111
target/arm/helper.c | 2 +-
112
target/arm/kvm64.c | 77 ++
113
target/arm/neon_helper.c | 17 -
114
target/arm/tlb_helper.c | 2 +-
115
target/arm/translate-a64.c | 210 +--
116
target/arm/translate-neon.inc.c | 682 +++++++++-
117
target/arm/translate.c | 2349 +++++++++++++++++---------------
118
target/arm/vec_helper.c | 240 +++-
119
target/arm/vfp_helper.c | 9 +-
120
target/i386/kvm.c | 36 -
121
MAINTAINERS | 9 +
122
gdb-xml/arm-m-profile.xml | 27 +
123
hw/acpi/Kconfig | 4 +
124
hw/acpi/Makefile.objs | 1 +
125
41 files changed, 3402 insertions(+), 1445 deletions(-)
126
create mode 100644 docs/specs/acpi_hest_ghes.rst
127
create mode 100644 include/hw/acpi/ghes.h
128
create mode 100644 hw/acpi/ghes.c
129
create mode 100644 gdb-xml/arm-m-profile.xml
130
56
57
Peter Maydell (6):
58
target/i386: Use assert() to sanity-check b1 in SSE decode
59
include/hw/i386: Don't include qemu-common.h in .h files
60
target/hexagon/cpu.h: don't include qemu-common.h
61
target/rx/cpu.h: Don't include qemu-common.h
62
hw/arm: Don't include qemu-common.h unnecessarily
63
target/arm: Correct calculation of tlb range invalidate length
64
65
Philippe Mathieu-Daudé (2):
66
hw/intc/arm_gicv3: Extract gicv3_set_gicv3state from arm_gicv3_cpuif.c
67
hw/intc/arm_gicv3: Introduce CONFIG_ARM_GIC_TCG Kconfig selector
68
69
Richard Henderson (10):
70
target/arm: Hoist pc_next to a local variable in aarch64_tr_translate_insn
71
target/arm: Hoist pc_next to a local variable in arm_tr_translate_insn
72
target/arm: Hoist pc_next to a local variable in thumb_tr_translate_insn
73
target/arm: Split arm_pre_translate_insn
74
target/arm: Advance pc for arch single-step exception
75
target/arm: Split compute_fsr_fsc out of arm_deliver_fault
76
target/arm: Take an exception if PC is misaligned
77
target/arm: Assert thumb pc is aligned
78
target/arm: Suppress bp for exceptions with more priority
79
tests/tcg: Add arm and aarch64 pc alignment tests
80
81
docs/system/arm/aspeed.rst | 26 ++++++++++++----
82
include/hw/i386/microvm.h | 1 -
83
include/hw/i386/x86.h | 1 -
84
target/arm/helper.h | 1 +
85
target/arm/syndrome.h | 5 +++
86
target/hexagon/cpu.h | 1 -
87
target/rx/cpu.h | 1 -
88
hw/arm/boot.c | 1 -
89
hw/arm/digic_boards.c | 1 -
90
hw/arm/highbank.c | 1 -
91
hw/arm/npcm7xx_boards.c | 1 -
92
hw/arm/sbsa-ref.c | 1 -
93
hw/arm/stm32f405_soc.c | 1 -
94
hw/arm/vexpress.c | 1 -
95
hw/arm/virt-acpi-build.c | 7 +++++
96
hw/arm/virt.c | 21 ++++++-------
97
hw/char/stm32f2xx_usart.c | 3 +-
98
hw/intc/arm_gicv3.c | 2 +-
99
hw/intc/arm_gicv3_cpuif.c | 10 +-----
100
hw/intc/arm_gicv3_cpuif_common.c | 22 +++++++++++++
101
hw/intc/arm_gicv3_its.c | 39 +++++++++++++++--------
102
hw/net/npcm7xx_emc.c | 18 +++++------
103
hw/virtio/virtio-iommu-pci.c | 12 ++------
104
linux-user/aarch64/cpu_loop.c | 46 ++++++++++++++++------------
105
linux-user/hexagon/cpu_loop.c | 1 +
106
target/arm/debug_helper.c | 23 ++++++++++++++
107
target/arm/gdbstub.c | 9 ++++--
108
target/arm/helper.c | 6 ++--
109
target/arm/machine.c | 10 ++++++
110
target/arm/tlb_helper.c | 63 ++++++++++++++++++++++++++++----------
111
target/arm/translate-a64.c | 23 ++++++++++++--
112
target/arm/translate.c | 58 ++++++++++++++++++++++++++---------
113
target/i386/tcg/translate.c | 12 ++------
114
tests/qtest/bios-tables-test.c | 38 +++++++++++++++++++++++
115
tests/tcg/aarch64/pcalign-a64.c | 37 ++++++++++++++++++++++
116
tests/tcg/arm/pcalign-a32.c | 46 ++++++++++++++++++++++++++++
117
hw/arm/Kconfig | 1 +
118
hw/intc/Kconfig | 5 +++
119
hw/intc/meson.build | 11 ++++---
120
tests/data/acpi/q35/DSDT.viot | Bin 0 -> 9398 bytes
121
tests/data/acpi/q35/VIOT.viot | Bin 0 -> 112 bytes
122
tests/data/acpi/virt/VIOT | Bin 0 -> 88 bytes
123
tests/tcg/aarch64/Makefile.target | 4 +--
124
tests/tcg/arm/Makefile.target | 4 +++
125
44 files changed, 429 insertions(+), 145 deletions(-)
126
create mode 100644 hw/intc/arm_gicv3_cpuif_common.c
127
create mode 100644 tests/tcg/aarch64/pcalign-a64.c
128
create mode 100644 tests/tcg/arm/pcalign-a32.c
129
create mode 100644 tests/data/acpi/q35/DSDT.viot
130
create mode 100644 tests/data/acpi/q35/VIOT.viot
131
create mode 100644 tests/data/acpi/virt/VIOT
132
diff view generated by jsdifflib
Deleted patch
1
GDB's remote protocol requires M-profile cores to use the feature
2
name 'org.gnu.gdb.arm.m-profile' instead of the 'org.gnu.gdb.arm.core'
3
feature used for A- and R-profile cores. We weren't doing this, which
4
meant GDB treated our M-profile cores like A-profile ones. This mostly
5
doesn't matter, but for instance means that it doesn't correctly
6
handle backtraces where an M-profile exception frame is involved.
7
1
8
Ship a copy of GDB's arm-m-profile.xml and use it on the M-profile
9
cores. The integer registers have the same offsets as the
10
arm-core.xml, but register 25 is the M-profile XPSR rather than the
11
A-profile CPSR, so we need to update arm_cpu_gdb_read_register() and
12
arm_cpu_gdb_write_register() to handle XSPR reads and writes.
13
14
Fixes: https://bugs.launchpad.net/qemu/+bug/1877136
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Message-id: 20200507134755.13997-1-peter.maydell@linaro.org
18
---
19
configure | 4 ++--
20
target/arm/cpu_tcg.c | 1 +
21
target/arm/gdbstub.c | 22 ++++++++++++++++++----
22
gdb-xml/arm-m-profile.xml | 27 +++++++++++++++++++++++++++
23
4 files changed, 48 insertions(+), 6 deletions(-)
24
create mode 100644 gdb-xml/arm-m-profile.xml
25
26
diff --git a/configure b/configure
27
index XXXXXXX..XXXXXXX 100755
28
--- a/configure
29
+++ b/configure
30
@@ -XXX,XX +XXX,XX @@ case "$target_name" in
31
TARGET_SYSTBL_ABI=common,oabi
32
bflt="yes"
33
mttcg="yes"
34
- gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
35
+ gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml arm-m-profile.xml"
36
;;
37
aarch64|aarch64_be)
38
TARGET_ARCH=aarch64
39
TARGET_BASE_ARCH=arm
40
bflt="yes"
41
mttcg="yes"
42
- gdb_xml_files="aarch64-core.xml aarch64-fpu.xml arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
43
+ gdb_xml_files="aarch64-core.xml aarch64-fpu.xml arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml arm-m-profile.xml"
44
;;
45
cris)
46
;;
47
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/cpu_tcg.c
50
+++ b/target/arm/cpu_tcg.c
51
@@ -XXX,XX +XXX,XX @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
52
#endif
53
54
cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
55
+ cc->gdb_core_xml_file = "arm-m-profile.xml";
56
}
57
58
static const ARMCPUInfo arm_tcg_cpus[] = {
59
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/arm/gdbstub.c
62
+++ b/target/arm/gdbstub.c
63
@@ -XXX,XX +XXX,XX @@ int arm_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
64
}
65
return gdb_get_reg32(mem_buf, 0);
66
case 25:
67
- /* CPSR */
68
- return gdb_get_reg32(mem_buf, cpsr_read(env));
69
+ /* CPSR, or XPSR for M-profile */
70
+ if (arm_feature(env, ARM_FEATURE_M)) {
71
+ return gdb_get_reg32(mem_buf, xpsr_read(env));
72
+ } else {
73
+ return gdb_get_reg32(mem_buf, cpsr_read(env));
74
+ }
75
}
76
/* Unknown register. */
77
return 0;
78
@@ -XXX,XX +XXX,XX @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
79
}
80
return 4;
81
case 25:
82
- /* CPSR */
83
- cpsr_write(env, tmp, 0xffffffff, CPSRWriteByGDBStub);
84
+ /* CPSR, or XPSR for M-profile */
85
+ if (arm_feature(env, ARM_FEATURE_M)) {
86
+ /*
87
+ * Don't allow writing to XPSR.Exception as it can cause
88
+ * a transition into or out of handler mode (it's not
89
+ * writeable via the MSR insn so this is a reasonable
90
+ * restriction). Other fields are safe to update.
91
+ */
92
+ xpsr_write(env, tmp, ~XPSR_EXCP);
93
+ } else {
94
+ cpsr_write(env, tmp, 0xffffffff, CPSRWriteByGDBStub);
95
+ }
96
return 4;
97
}
98
/* Unknown register. */
99
diff --git a/gdb-xml/arm-m-profile.xml b/gdb-xml/arm-m-profile.xml
100
new file mode 100644
101
index XXXXXXX..XXXXXXX
102
--- /dev/null
103
+++ b/gdb-xml/arm-m-profile.xml
104
@@ -XXX,XX +XXX,XX @@
105
+<?xml version="1.0"?>
106
+<!-- Copyright (C) 2010-2020 Free Software Foundation, Inc.
107
+
108
+ Copying and distribution of this file, with or without modification,
109
+ are permitted in any medium without royalty provided the copyright
110
+ notice and this notice are preserved. -->
111
+
112
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
113
+<feature name="org.gnu.gdb.arm.m-profile">
114
+ <reg name="r0" bitsize="32"/>
115
+ <reg name="r1" bitsize="32"/>
116
+ <reg name="r2" bitsize="32"/>
117
+ <reg name="r3" bitsize="32"/>
118
+ <reg name="r4" bitsize="32"/>
119
+ <reg name="r5" bitsize="32"/>
120
+ <reg name="r6" bitsize="32"/>
121
+ <reg name="r7" bitsize="32"/>
122
+ <reg name="r8" bitsize="32"/>
123
+ <reg name="r9" bitsize="32"/>
124
+ <reg name="r10" bitsize="32"/>
125
+ <reg name="r11" bitsize="32"/>
126
+ <reg name="r12" bitsize="32"/>
127
+ <reg name="sp" bitsize="32" type="data_ptr"/>
128
+ <reg name="lr" bitsize="32"/>
129
+ <reg name="pc" bitsize="32" type="code_ptr"/>
130
+ <reg name="xpsr" bitsize="32" regnum="25"/>
131
+</feature>
132
--
133
2.20.1
134
135
diff view generated by jsdifflib
1
From: Patrick Williams <patrick@stwcx.xyz>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
Sonora Pass is a 2 socket x86 motherboard designed by Facebook
3
While trying to debug a GIC ITS failure I saw some guest errors that
4
and supported by OpenBMC. Strapping configuration was obtained
4
had poor formatting as well as leaving me confused as to what failed.
5
from hardware and i2c configuration is based on dts found at:
5
As most of the checks aren't possible without a valid dte split that
6
check apart and then check the other conditions in steps. This avoids
7
us relying on undefined data.
6
8
7
https://github.com/facebook/openbmc-linux/blob/1633c87b8ba7c162095787c988979b748ba65dc8/arch/arm/boot/dts/aspeed-bmc-facebook-sonorapass.dts
9
I still get a failure with the current kvm-unit-tests but at least I
10
know (partially) why now:
8
11
9
Booted a test image of http://github.com/facebook/openbmc to login
12
Exception return from AArch64 EL1 to AArch64 EL1 PC 0x40080588
10
prompt.
13
PASS: gicv3: its-trigger: inv/invall: dev2/eventid=20 now triggers an LPI
14
ITS: MAPD devid=2 size = 0x8 itt=0x40430000 valid=0
15
INT dev_id=2 event_id=20
16
process_its_cmd: invalid command attributes: invalid dte: 0 for 2 (MEM_TX: 0)
17
PASS: gicv3: its-trigger: mapd valid=false: no LPI after device unmap
18
SUMMARY: 6 tests, 1 unexpected failures
11
19
12
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
20
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
13
Reviewed-by: Amithash Prasad <amithash@fb.com>
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Cédric Le Goater <clg@kaod.org>
22
Message-id: 20211112170454.3158925-1-alex.bennee@linaro.org
15
[PMM: fixed block comment style nit]
23
Cc: Shashi Mallela <shashi.mallela@linaro.org>
24
Cc: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
26
---
18
hw/arm/aspeed.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++
27
hw/intc/arm_gicv3_its.c | 39 +++++++++++++++++++++++++++------------
19
1 file changed, 78 insertions(+)
28
1 file changed, 27 insertions(+), 12 deletions(-)
20
29
21
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
30
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
22
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/aspeed.c
32
--- a/hw/intc/arm_gicv3_its.c
24
+++ b/hw/arm/aspeed.c
33
+++ b/hw/intc/arm_gicv3_its.c
25
@@ -XXX,XX +XXX,XX @@ struct AspeedBoardState {
34
@@ -XXX,XX +XXX,XX @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
26
SCU_AST2500_HW_STRAP_ACPI_ENABLE | \
35
if (res != MEMTX_OK) {
27
SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER))
36
return result;
28
37
}
29
+/* Sonorapass hardware value: 0xF100D216 */
38
+ } else {
30
+#define SONORAPASS_BMC_HW_STRAP1 ( \
39
+ qemu_log_mask(LOG_GUEST_ERROR,
31
+ SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \
40
+ "%s: invalid command attributes: "
32
+ SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE | \
41
+ "invalid dte: %"PRIx64" for %d (MEM_TX: %d)\n",
33
+ SCU_AST2500_HW_STRAP_UART_DEBUG | \
42
+ __func__, dte, devid, res);
34
+ SCU_AST2500_HW_STRAP_RESERVED28 | \
43
+ return result;
35
+ SCU_AST2500_HW_STRAP_DDR4_ENABLE | \
44
}
36
+ SCU_HW_STRAP_VGA_CLASS_CODE | \
45
37
+ SCU_HW_STRAP_LPC_RESET_PIN | \
46
- if ((devid > s->dt.maxids.max_devids) || !dte_valid || !ite_valid ||
38
+ SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER) | \
47
- !cte_valid || (eventid > max_eventid)) {
39
+ SCU_AST2500_HW_STRAP_SET_AXI_AHB_RATIO(AXI_AHB_RATIO_2_1) | \
40
+ SCU_HW_STRAP_VGA_BIOS_ROM | \
41
+ SCU_HW_STRAP_VGA_SIZE_SET(VGA_16M_DRAM) | \
42
+ SCU_AST2500_HW_STRAP_RESERVED1)
43
+
44
/* Swift hardware value: 0xF11AD206 */
45
#define SWIFT_BMC_HW_STRAP1 ( \
46
AST2500_HW_STRAP1_DEFAULTS | \
47
@@ -XXX,XX +XXX,XX @@ static void swift_bmc_i2c_init(AspeedBoardState *bmc)
48
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 12), "tmp105", 0x4a);
49
}
50
51
+static void sonorapass_bmc_i2c_init(AspeedBoardState *bmc)
52
+{
53
+ AspeedSoCState *soc = &bmc->soc;
54
+
55
+ /* bus 2 : */
56
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 2), "tmp105", 0x48);
57
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 2), "tmp105", 0x49);
58
+ /* bus 2 : pca9546 @ 0x73 */
59
+
60
+ /* bus 3 : pca9548 @ 0x70 */
61
+
62
+ /* bus 4 : */
63
+ uint8_t *eeprom4_54 = g_malloc0(8 * 1024);
64
+ smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), 0x54,
65
+ eeprom4_54);
66
+ /* PCA9539 @ 0x76, but PCA9552 is compatible */
67
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "pca9552", 0x76);
68
+ /* PCA9539 @ 0x77, but PCA9552 is compatible */
69
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "pca9552", 0x77);
70
+
71
+ /* bus 6 : */
72
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 6), "tmp105", 0x48);
73
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 6), "tmp105", 0x49);
74
+ /* bus 6 : pca9546 @ 0x73 */
75
+
76
+ /* bus 8 : */
77
+ uint8_t *eeprom8_56 = g_malloc0(8 * 1024);
78
+ smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 8), 0x56,
79
+ eeprom8_56);
80
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 8), "pca9552", 0x60);
81
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 8), "pca9552", 0x61);
82
+ /* bus 8 : adc128d818 @ 0x1d */
83
+ /* bus 8 : adc128d818 @ 0x1f */
84
+
48
+
85
+ /*
49
+ /*
86
+ * bus 13 : pca9548 @ 0x71
50
+ * In this implementation, in case of guest errors we ignore the
87
+ * - channel 3:
51
+ * command and move onto the next command in the queue.
88
+ * - tmm421 @ 0x4c
89
+ * - tmp421 @ 0x4e
90
+ * - tmp421 @ 0x4f
91
+ */
52
+ */
53
+ if (devid > s->dt.maxids.max_devids) {
54
qemu_log_mask(LOG_GUEST_ERROR,
55
- "%s: invalid command attributes "
56
- "devid %d or eventid %d or invalid dte %d or"
57
- "invalid cte %d or invalid ite %d\n",
58
- __func__, devid, eventid, dte_valid, cte_valid,
59
- ite_valid);
60
- /*
61
- * in this implementation, in case of error
62
- * we ignore this command and move onto the next
63
- * command in the queue
64
- */
65
+ "%s: invalid command attributes: devid %d>%d",
66
+ __func__, devid, s->dt.maxids.max_devids);
92
+
67
+
93
+}
68
+ } else if (!dte_valid || !ite_valid || !cte_valid) {
94
+
69
+ qemu_log_mask(LOG_GUEST_ERROR,
95
static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
70
+ "%s: invalid command attributes: "
96
{
71
+ "dte: %s, ite: %s, cte: %s\n",
97
AspeedSoCState *soc = &bmc->soc;
72
+ __func__,
98
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_romulus_class_init(ObjectClass *oc, void *data)
73
+ dte_valid ? "valid" : "invalid",
99
mc->default_ram_size = 512 * MiB;
74
+ ite_valid ? "valid" : "invalid",
100
};
75
+ cte_valid ? "valid" : "invalid");
101
76
+ } else if (eventid > max_eventid) {
102
+static void aspeed_machine_sonorapass_class_init(ObjectClass *oc, void *data)
77
+ qemu_log_mask(LOG_GUEST_ERROR,
103
+{
78
+ "%s: invalid command attributes: eventid %d > %d\n",
104
+ MachineClass *mc = MACHINE_CLASS(oc);
79
+ __func__, eventid, max_eventid);
105
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
80
} else {
106
+
81
/*
107
+ mc->desc = "OCP SonoraPass BMC (ARM1176)";
82
* Current implementation only supports rdbase == procnum
108
+ amc->soc_name = "ast2500-a1";
109
+ amc->hw_strap1 = SONORAPASS_BMC_HW_STRAP1;
110
+ amc->fmc_model = "mx66l1g45g";
111
+ amc->spi_model = "mx66l1g45g";
112
+ amc->num_cs = 2;
113
+ amc->i2c_init = sonorapass_bmc_i2c_init;
114
+ mc->default_ram_size = 512 * MiB;
115
+};
116
+
117
static void aspeed_machine_swift_class_init(ObjectClass *oc, void *data)
118
{
119
MachineClass *mc = MACHINE_CLASS(oc);
120
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_machine_types[] = {
121
.name = MACHINE_TYPE_NAME("swift-bmc"),
122
.parent = TYPE_ASPEED_MACHINE,
123
.class_init = aspeed_machine_swift_class_init,
124
+ }, {
125
+ .name = MACHINE_TYPE_NAME("sonorapass-bmc"),
126
+ .parent = TYPE_ASPEED_MACHINE,
127
+ .class_init = aspeed_machine_sonorapass_class_init,
128
}, {
129
.name = MACHINE_TYPE_NAME("witherspoon-bmc"),
130
.parent = TYPE_ASPEED_MACHINE,
131
--
83
--
132
2.20.1
84
2.25.1
133
85
134
86
diff view generated by jsdifflib
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
I and Xiang are willing to review the APEI-related patches and
3
Add X11, FP5280G2, G220A, Rainier and Fuji. Mention that Swift will be
4
volunteer as the reviewers for the HEST/GHES part.
4
removed in v7.0.
5
5
6
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
6
Signed-off-by: Joel Stanley <joel@jms.id.au>
7
Signed-off-by: Xiang Zheng <zhengxiang9@huawei.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20211117065752.330632-2-joel@jms.id.au
9
Acked-by: Michael S. Tsirkin <mst@redhat.com>
10
Message-id: 20200512030609.19593-11-gengdongjiu@huawei.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
MAINTAINERS | 9 +++++++++
11
docs/system/arm/aspeed.rst | 7 ++++++-
14
1 file changed, 9 insertions(+)
12
1 file changed, 6 insertions(+), 1 deletion(-)
15
13
16
diff --git a/MAINTAINERS b/MAINTAINERS
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/MAINTAINERS
16
--- a/docs/system/arm/aspeed.rst
19
+++ b/MAINTAINERS
17
+++ b/docs/system/arm/aspeed.rst
20
@@ -XXX,XX +XXX,XX @@ F: tests/qtest/bios-tables-test.c
18
@@ -XXX,XX +XXX,XX @@ AST2400 SoC based machines :
21
F: tests/qtest/acpi-utils.[hc]
19
22
F: tests/data/acpi/
20
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
23
21
- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
24
+ACPI/HEST/GHES
22
+- ``supermicrox11-bmc`` Supermicro X11 BMC
25
+R: Dongjiu Geng <gengdongjiu@huawei.com>
23
26
+R: Xiang Zheng <zhengxiang9@huawei.com>
24
AST2500 SoC based machines :
27
+L: qemu-arm@nongnu.org
25
28
+S: Maintained
26
@@ -XXX,XX +XXX,XX @@ AST2500 SoC based machines :
29
+F: hw/acpi/ghes.c
27
- ``romulus-bmc`` OpenPOWER Romulus POWER9 BMC
30
+F: include/hw/acpi/ghes.h
28
- ``witherspoon-bmc`` OpenPOWER Witherspoon POWER9 BMC
31
+F: docs/specs/acpi_hest_ghes.rst
29
- ``sonorapass-bmc`` OCP SonoraPass BMC
32
+
30
-- ``swift-bmc`` OpenPOWER Swift BMC POWER9
33
ppc4xx
31
+- ``swift-bmc`` OpenPOWER Swift BMC POWER9 (to be removed in v7.0)
34
M: David Gibson <david@gibson.dropbear.id.au>
32
+- ``fp5280g2-bmc`` Inspur FP5280G2 BMC
35
L: qemu-ppc@nongnu.org
33
+- ``g220a-bmc`` Bytedance G220A BMC
34
35
AST2600 SoC based machines :
36
37
- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex-A7)
38
- ``tacoma-bmc`` OpenPOWER Witherspoon POWER9 AST2600 BMC
39
+- ``rainier-bmc`` IBM Rainier POWER10 BMC
40
+- ``fuji-bmc`` Facebook Fuji BMC
41
42
Supported devices
43
-----------------
36
--
44
--
37
2.20.1
45
2.25.1
38
46
39
47
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
These operations do not touch fp_status.
3
This is the latest URL for the OpenBMC CI. The old URL still works, but
4
redirects.
4
5
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
7
Message-id: 20200513163245.17915-12-richard.henderson@linaro.org
8
Message-id: 20211117065752.330632-3-joel@jms.id.au
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/helper.h | 4 ++--
11
docs/system/arm/aspeed.rst | 2 +-
11
target/arm/translate-a64.c | 5 ++---
12
1 file changed, 1 insertion(+), 1 deletion(-)
12
target/arm/translate.c | 12 ++----------
13
target/arm/vfp_helper.c | 5 ++---
14
4 files changed, 8 insertions(+), 18 deletions(-)
15
13
16
diff --git a/target/arm/helper.h b/target/arm/helper.h
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.h
16
--- a/docs/system/arm/aspeed.rst
19
+++ b/target/arm/helper.h
17
+++ b/docs/system/arm/aspeed.rst
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(recpe_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
18
@@ -XXX,XX +XXX,XX @@ The Aspeed machines can be started using the ``-kernel`` option to
21
DEF_HELPER_FLAGS_2(rsqrte_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
19
load a Linux kernel or from a firmware. Images can be downloaded from
22
DEF_HELPER_FLAGS_2(rsqrte_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
20
the OpenBMC jenkins :
23
DEF_HELPER_FLAGS_2(rsqrte_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
21
24
-DEF_HELPER_2(recpe_u32, i32, i32, ptr)
22
- https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/distro=ubuntu,label=docker-builder
25
-DEF_HELPER_FLAGS_2(rsqrte_u32, TCG_CALL_NO_RWG, i32, i32, ptr)
23
+ https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/
26
+DEF_HELPER_FLAGS_1(recpe_u32, TCG_CALL_NO_RWG, i32, i32)
24
27
+DEF_HELPER_FLAGS_1(rsqrte_u32, TCG_CALL_NO_RWG, i32, i32)
25
or directly from the OpenBMC GitHub release repository :
28
DEF_HELPER_FLAGS_4(neon_tbl, TCG_CALL_NO_RWG, i32, i32, i32, ptr, i32)
29
30
DEF_HELPER_3(shl_cc, i32, env, i32, i32)
31
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate-a64.c
34
+++ b/target/arm/translate-a64.c
35
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_reciprocal(DisasContext *s, int opcode,
36
37
switch (opcode) {
38
case 0x3c: /* URECPE */
39
- gen_helper_recpe_u32(tcg_res, tcg_op, fpst);
40
+ gen_helper_recpe_u32(tcg_res, tcg_op);
41
break;
42
case 0x3d: /* FRECPE */
43
gen_helper_recpe_f32(tcg_res, tcg_op, fpst);
44
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
45
unallocated_encoding(s);
46
return;
47
}
48
- need_fpstatus = true;
49
break;
50
case 0x1e: /* FRINT32Z */
51
case 0x1f: /* FRINT64Z */
52
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
53
gen_helper_rints_exact(tcg_res, tcg_op, tcg_fpstatus);
54
break;
55
case 0x7c: /* URSQRTE */
56
- gen_helper_rsqrte_u32(tcg_res, tcg_op, tcg_fpstatus);
57
+ gen_helper_rsqrte_u32(tcg_res, tcg_op);
58
break;
59
case 0x1e: /* FRINT32Z */
60
case 0x5e: /* FRINT32X */
61
diff --git a/target/arm/translate.c b/target/arm/translate.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/translate.c
64
+++ b/target/arm/translate.c
65
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
66
break;
67
}
68
case NEON_2RM_VRECPE:
69
- {
70
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
71
- gen_helper_recpe_u32(tmp, tmp, fpstatus);
72
- tcg_temp_free_ptr(fpstatus);
73
+ gen_helper_recpe_u32(tmp, tmp);
74
break;
75
- }
76
case NEON_2RM_VRSQRTE:
77
- {
78
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
79
- gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
80
- tcg_temp_free_ptr(fpstatus);
81
+ gen_helper_rsqrte_u32(tmp, tmp);
82
break;
83
- }
84
case NEON_2RM_VRECPE_F:
85
{
86
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
87
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/target/arm/vfp_helper.c
90
+++ b/target/arm/vfp_helper.c
91
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
92
return make_float64(val);
93
}
94
95
-uint32_t HELPER(recpe_u32)(uint32_t a, void *fpstp)
96
+uint32_t HELPER(recpe_u32)(uint32_t a)
97
{
98
- /* float_status *s = fpstp; */
99
int input, estimate;
100
101
if ((a & 0x80000000) == 0) {
102
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(recpe_u32)(uint32_t a, void *fpstp)
103
return deposit32(0, (32 - 9), 9, estimate);
104
}
105
106
-uint32_t HELPER(rsqrte_u32)(uint32_t a, void *fpstp)
107
+uint32_t HELPER(rsqrte_u32)(uint32_t a)
108
{
109
int estimate;
110
26
111
--
27
--
112
2.20.1
28
2.25.1
113
29
114
30
diff view generated by jsdifflib
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
Record the GHEB address via fw_cfg file, when recording
3
A common use case for the ASPEED machine is to boot a Linux kernel.
4
a error to CPER, it will use this address to find out
4
Provide a full example command line.
5
Generic Error Data Entries and write the error.
6
5
7
In order to avoid migration failure, make hardware
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
error table address to a part of GED device instead
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
9
of global variable, then this address will be migrated
8
Message-id: 20211117065752.330632-4-joel@jms.id.au
10
to target QEMU.
11
12
Acked-by: Xiang Zheng <zhengxiang9@huawei.com>
13
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
14
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
15
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
16
Message-id: 20200512030609.19593-7-gengdongjiu@huawei.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
10
---
19
include/hw/acpi/generic_event_device.h | 2 ++
11
docs/system/arm/aspeed.rst | 15 ++++++++++++---
20
include/hw/acpi/ghes.h | 6 ++++++
12
1 file changed, 12 insertions(+), 3 deletions(-)
21
hw/acpi/generic_event_device.c | 19 +++++++++++++++++++
22
hw/acpi/ghes.c | 14 ++++++++++++++
23
hw/arm/virt-acpi-build.c | 8 ++++++++
24
5 files changed, 49 insertions(+)
25
13
26
diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
27
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/acpi/generic_event_device.h
16
--- a/docs/system/arm/aspeed.rst
29
+++ b/include/hw/acpi/generic_event_device.h
17
+++ b/docs/system/arm/aspeed.rst
30
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ Missing devices
31
19
Boot options
32
#include "hw/sysbus.h"
20
------------
33
#include "hw/acpi/memory_hotplug.h"
21
34
+#include "hw/acpi/ghes.h"
22
-The Aspeed machines can be started using the ``-kernel`` option to
35
23
-load a Linux kernel or from a firmware. Images can be downloaded from
36
#define ACPI_POWER_BUTTON_DEVICE "PWRB"
24
-the OpenBMC jenkins :
37
25
+The Aspeed machines can be started using the ``-kernel`` and ``-dtb`` options
38
@@ -XXX,XX +XXX,XX @@ typedef struct AcpiGedState {
26
+to load a Linux kernel or from a firmware. Images can be downloaded from the
39
GEDState ged_state;
27
+OpenBMC jenkins :
40
uint32_t ged_event_bitmap;
28
41
qemu_irq irq;
29
https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/
42
+ AcpiGhesState ghes_state;
30
43
} AcpiGedState;
31
@@ -XXX,XX +XXX,XX @@ or directly from the OpenBMC GitHub release repository :
44
32
45
void build_ged_aml(Aml *table, const char* name, HotplugHandler *hotplug_dev,
33
https://github.com/openbmc/openbmc/releases
46
diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h
34
47
index XXXXXXX..XXXXXXX 100644
35
+To boot a kernel directly from a Linux build tree:
48
--- a/include/hw/acpi/ghes.h
49
+++ b/include/hw/acpi/ghes.h
50
@@ -XXX,XX +XXX,XX @@ enum {
51
ACPI_HEST_SRC_ID_RESERVED,
52
};
53
54
+typedef struct AcpiGhesState {
55
+ uint64_t ghes_addr_le;
56
+} AcpiGhesState;
57
+
36
+
58
void build_ghes_error_table(GArray *hardware_errors, BIOSLinker *linker);
37
+.. code-block:: bash
59
void acpi_build_hest(GArray *table_data, BIOSLinker *linker);
60
+void acpi_ghes_add_fw_cfg(AcpiGhesState *vms, FWCfgState *s,
61
+ GArray *hardware_errors);
62
#endif
63
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/acpi/generic_event_device.c
66
+++ b/hw/acpi/generic_event_device.c
67
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_ged_state = {
68
}
69
};
70
71
+static bool ghes_needed(void *opaque)
72
+{
73
+ AcpiGedState *s = opaque;
74
+ return s->ghes_state.ghes_addr_le;
75
+}
76
+
38
+
77
+static const VMStateDescription vmstate_ghes_state = {
39
+ $ qemu-system-arm -M ast2600-evb -nographic \
78
+ .name = "acpi-ged/ghes",
40
+ -kernel arch/arm/boot/zImage \
79
+ .version_id = 1,
41
+ -dtb arch/arm/boot/dts/aspeed-ast2600-evb.dtb \
80
+ .minimum_version_id = 1,
42
+ -initrd rootfs.cpio
81
+ .needed = ghes_needed,
82
+ .fields = (VMStateField[]) {
83
+ VMSTATE_STRUCT(ghes_state, AcpiGedState, 1,
84
+ vmstate_ghes_state, AcpiGhesState),
85
+ VMSTATE_END_OF_LIST()
86
+ }
87
+};
88
+
43
+
89
static const VMStateDescription vmstate_acpi_ged = {
44
The image should be attached as an MTD drive. Run :
90
.name = "acpi-ged",
45
91
.version_id = 1,
46
.. code-block:: bash
92
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_acpi_ged = {
93
},
94
.subsections = (const VMStateDescription * []) {
95
&vmstate_memhp_state,
96
+ &vmstate_ghes_state,
97
NULL
98
}
99
};
100
diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/hw/acpi/ghes.c
103
+++ b/hw/acpi/ghes.c
104
@@ -XXX,XX +XXX,XX @@
105
#include "hw/acpi/ghes.h"
106
#include "hw/acpi/aml-build.h"
107
#include "qemu/error-report.h"
108
+#include "hw/acpi/generic_event_device.h"
109
+#include "hw/nvram/fw_cfg.h"
110
111
#define ACPI_GHES_ERRORS_FW_CFG_FILE "etc/hardware_errors"
112
#define ACPI_GHES_DATA_ADDR_FW_CFG_FILE "etc/hardware_errors_addr"
113
@@ -XXX,XX +XXX,XX @@ void acpi_build_hest(GArray *table_data, BIOSLinker *linker)
114
build_header(linker, table_data, (void *)(table_data->data + hest_start),
115
"HEST", table_data->len - hest_start, 1, NULL, NULL);
116
}
117
+
118
+void acpi_ghes_add_fw_cfg(AcpiGhesState *ags, FWCfgState *s,
119
+ GArray *hardware_error)
120
+{
121
+ /* Create a read-only fw_cfg file for GHES */
122
+ fw_cfg_add_file(s, ACPI_GHES_ERRORS_FW_CFG_FILE, hardware_error->data,
123
+ hardware_error->len);
124
+
125
+ /* Create a read-write fw_cfg file for Address */
126
+ fw_cfg_add_file_callback(s, ACPI_GHES_DATA_ADDR_FW_CFG_FILE, NULL, NULL,
127
+ NULL, &(ags->ghes_addr_le), sizeof(ags->ghes_addr_le), false);
128
+}
129
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/hw/arm/virt-acpi-build.c
132
+++ b/hw/arm/virt-acpi-build.c
133
@@ -XXX,XX +XXX,XX @@ void virt_acpi_setup(VirtMachineState *vms)
134
{
135
AcpiBuildTables tables;
136
AcpiBuildState *build_state;
137
+ AcpiGedState *acpi_ged_state;
138
139
if (!vms->fw_cfg) {
140
trace_virt_acpi_setup();
141
@@ -XXX,XX +XXX,XX @@ void virt_acpi_setup(VirtMachineState *vms)
142
fw_cfg_add_file(vms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data,
143
acpi_data_len(tables.tcpalog));
144
145
+ if (vms->ras) {
146
+ assert(vms->acpi_dev);
147
+ acpi_ged_state = ACPI_GED(vms->acpi_dev);
148
+ acpi_ghes_add_fw_cfg(&acpi_ged_state->ghes_state,
149
+ vms->fw_cfg, tables.hardware_errors);
150
+ }
151
+
152
build_state->rsdp_mr = acpi_add_rom_blob(virt_acpi_build_update,
153
build_state, tables.rsdp,
154
ACPI_BUILD_RSDP_FILE, 0);
155
--
47
--
156
2.20.1
48
2.25.1
157
49
158
50
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
Provide a functional interface for the vector expansion.
3
Move it to the supported list.
4
This fits better with the existing set of helpers that
5
we provide for other operations.
6
4
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20211117065752.330632-5-joel@jms.id.au
9
Message-id: 20200513163245.17915-10-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
target/arm/translate.h | 10 ++-
9
docs/system/arm/aspeed.rst | 2 +-
13
target/arm/translate-a64.c | 18 ++--
10
1 file changed, 1 insertion(+), 1 deletion(-)
14
target/arm/translate-neon.inc.c | 23 +----
15
target/arm/translate.c | 146 +++++++++++++++++---------------
16
4 files changed, 95 insertions(+), 102 deletions(-)
17
11
18
diff --git a/target/arm/translate.h b/target/arm/translate.h
12
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.h
14
--- a/docs/system/arm/aspeed.rst
21
+++ b/target/arm/translate.h
15
+++ b/docs/system/arm/aspeed.rst
22
@@ -XXX,XX +XXX,XX @@ void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
16
@@ -XXX,XX +XXX,XX @@ Supported devices
23
void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
17
* Front LEDs (PCA9552 on I2C bus)
24
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
18
* LPC Peripheral Controller (a subset of subdevices are supported)
25
19
* Hash/Crypto Engine (HACE) - Hash support only. TODO: HMAC and RSA
26
-extern const GVecGen3 cmtst_op[4];
20
+ * ADC
27
-extern const GVecGen3 sshl_op[4];
21
28
-extern const GVecGen3 ushl_op[4];
22
29
+void gen_gvec_cmtst(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
23
Missing devices
30
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
24
---------------
31
+void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
25
32
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
26
* Coprocessor support
33
+void gen_gvec_ushl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
27
- * ADC (out of tree implementation)
34
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
28
* PWM and Fan Controller
35
+
29
* Slave GPIO Controller
36
extern const GVecGen4 uqadd_op[4];
30
* Super I/O Controller
37
extern const GVecGen4 sqadd_op[4];
38
extern const GVecGen4 uqsub_op[4];
39
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate-a64.c
42
+++ b/target/arm/translate-a64.c
43
@@ -XXX,XX +XXX,XX @@ static void gen_gvec_fn4(DisasContext *s, bool is_q, int rd, int rn, int rm,
44
is_q ? 16 : 8, vec_full_reg_size(s));
45
}
46
47
-/* Expand a 3-operand AdvSIMD vector operation using an op descriptor. */
48
-static void gen_gvec_op3(DisasContext *s, bool is_q, int rd,
49
- int rn, int rm, const GVecGen3 *gvec_op)
50
-{
51
- tcg_gen_gvec_3(vec_full_reg_offset(s, rd), vec_full_reg_offset(s, rn),
52
- vec_full_reg_offset(s, rm), is_q ? 16 : 8,
53
- vec_full_reg_size(s), gvec_op);
54
-}
55
-
56
/* Expand a 3-operand operation using an out-of-line helper. */
57
static void gen_gvec_op3_ool(DisasContext *s, bool is_q, int rd,
58
int rn, int rm, int data, gen_helper_gvec_3 *fn)
59
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
60
(u ? uqsub_op : sqsub_op) + size);
61
return;
62
case 0x08: /* SSHL, USHL */
63
- gen_gvec_op3(s, is_q, rd, rn, rm,
64
- u ? &ushl_op[size] : &sshl_op[size]);
65
+ if (u) {
66
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_ushl, size);
67
+ } else {
68
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sshl, size);
69
+ }
70
return;
71
case 0x0c: /* SMAX, UMAX */
72
if (u) {
73
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
74
return;
75
case 0x11:
76
if (!u) { /* CMTST */
77
- gen_gvec_op3(s, is_q, rd, rn, rm, &cmtst_op[size]);
78
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_cmtst, size);
79
return;
80
}
81
/* else CMEQ */
82
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/target/arm/translate-neon.inc.c
85
+++ b/target/arm/translate-neon.inc.c
86
@@ -XXX,XX +XXX,XX @@ DO_3SAME(VBIC, tcg_gen_gvec_andc)
87
DO_3SAME(VORR, tcg_gen_gvec_or)
88
DO_3SAME(VORN, tcg_gen_gvec_orc)
89
DO_3SAME(VEOR, tcg_gen_gvec_xor)
90
+DO_3SAME(VSHL_S, gen_gvec_sshl)
91
+DO_3SAME(VSHL_U, gen_gvec_ushl)
92
93
/* These insns are all gvec_bitsel but with the inputs in various orders. */
94
#define DO_3SAME_BITSEL(INSN, O1, O2, O3) \
95
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
96
DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
97
DO_3SAME_NO_SZ_3(VMLA, gen_gvec_mla)
98
DO_3SAME_NO_SZ_3(VMLS, gen_gvec_mls)
99
+DO_3SAME_NO_SZ_3(VTST, gen_gvec_cmtst)
100
101
#define DO_3SAME_CMP(INSN, COND) \
102
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
103
@@ -XXX,XX +XXX,XX @@ DO_3SAME_CMP(VCGE_S, TCG_COND_GE)
104
DO_3SAME_CMP(VCGE_U, TCG_COND_GEU)
105
DO_3SAME_CMP(VCEQ, TCG_COND_EQ)
106
107
-static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
108
- uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
109
-{
110
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
111
-}
112
-DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
113
-
114
#define DO_3SAME_GVEC4(INSN, OPARRAY) \
115
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
116
uint32_t rn_ofs, uint32_t rm_ofs, \
117
@@ -XXX,XX +XXX,XX @@ static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
118
}
119
return do_3same(s, a, gen_VMUL_p_3s);
120
}
121
-
122
-#define DO_3SAME_GVEC3_SHIFT(INSN, OPARRAY) \
123
- static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
124
- uint32_t rn_ofs, uint32_t rm_ofs, \
125
- uint32_t oprsz, uint32_t maxsz) \
126
- { \
127
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
128
- oprsz, maxsz, &OPARRAY[vece]); \
129
- } \
130
- DO_3SAME(INSN, gen_##INSN##_3s)
131
-
132
-DO_3SAME_GVEC3_SHIFT(VSHL_S, sshl_op)
133
-DO_3SAME_GVEC3_SHIFT(VSHL_U, ushl_op)
134
diff --git a/target/arm/translate.c b/target/arm/translate.c
135
index XXXXXXX..XXXXXXX 100644
136
--- a/target/arm/translate.c
137
+++ b/target/arm/translate.c
138
@@ -XXX,XX +XXX,XX @@ static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
139
tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
140
}
141
142
-static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
143
-
144
-const GVecGen3 cmtst_op[4] = {
145
- { .fni4 = gen_helper_neon_tst_u8,
146
- .fniv = gen_cmtst_vec,
147
- .opt_opc = vecop_list_cmtst,
148
- .vece = MO_8 },
149
- { .fni4 = gen_helper_neon_tst_u16,
150
- .fniv = gen_cmtst_vec,
151
- .opt_opc = vecop_list_cmtst,
152
- .vece = MO_16 },
153
- { .fni4 = gen_cmtst_i32,
154
- .fniv = gen_cmtst_vec,
155
- .opt_opc = vecop_list_cmtst,
156
- .vece = MO_32 },
157
- { .fni8 = gen_cmtst_i64,
158
- .fniv = gen_cmtst_vec,
159
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
160
- .opt_opc = vecop_list_cmtst,
161
- .vece = MO_64 },
162
-};
163
+void gen_gvec_cmtst(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
164
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
165
+{
166
+ static const TCGOpcode vecop_list[] = { INDEX_op_cmp_vec, 0 };
167
+ static const GVecGen3 ops[4] = {
168
+ { .fni4 = gen_helper_neon_tst_u8,
169
+ .fniv = gen_cmtst_vec,
170
+ .opt_opc = vecop_list,
171
+ .vece = MO_8 },
172
+ { .fni4 = gen_helper_neon_tst_u16,
173
+ .fniv = gen_cmtst_vec,
174
+ .opt_opc = vecop_list,
175
+ .vece = MO_16 },
176
+ { .fni4 = gen_cmtst_i32,
177
+ .fniv = gen_cmtst_vec,
178
+ .opt_opc = vecop_list,
179
+ .vece = MO_32 },
180
+ { .fni8 = gen_cmtst_i64,
181
+ .fniv = gen_cmtst_vec,
182
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
183
+ .opt_opc = vecop_list,
184
+ .vece = MO_64 },
185
+ };
186
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
187
+}
188
189
void gen_ushl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
190
{
191
@@ -XXX,XX +XXX,XX @@ static void gen_ushl_vec(unsigned vece, TCGv_vec dst,
192
tcg_temp_free_vec(rsh);
193
}
194
195
-static const TCGOpcode ushl_list[] = {
196
- INDEX_op_neg_vec, INDEX_op_shlv_vec,
197
- INDEX_op_shrv_vec, INDEX_op_cmp_vec, 0
198
-};
199
-
200
-const GVecGen3 ushl_op[4] = {
201
- { .fniv = gen_ushl_vec,
202
- .fno = gen_helper_gvec_ushl_b,
203
- .opt_opc = ushl_list,
204
- .vece = MO_8 },
205
- { .fniv = gen_ushl_vec,
206
- .fno = gen_helper_gvec_ushl_h,
207
- .opt_opc = ushl_list,
208
- .vece = MO_16 },
209
- { .fni4 = gen_ushl_i32,
210
- .fniv = gen_ushl_vec,
211
- .opt_opc = ushl_list,
212
- .vece = MO_32 },
213
- { .fni8 = gen_ushl_i64,
214
- .fniv = gen_ushl_vec,
215
- .opt_opc = ushl_list,
216
- .vece = MO_64 },
217
-};
218
+void gen_gvec_ushl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
219
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
220
+{
221
+ static const TCGOpcode vecop_list[] = {
222
+ INDEX_op_neg_vec, INDEX_op_shlv_vec,
223
+ INDEX_op_shrv_vec, INDEX_op_cmp_vec, 0
224
+ };
225
+ static const GVecGen3 ops[4] = {
226
+ { .fniv = gen_ushl_vec,
227
+ .fno = gen_helper_gvec_ushl_b,
228
+ .opt_opc = vecop_list,
229
+ .vece = MO_8 },
230
+ { .fniv = gen_ushl_vec,
231
+ .fno = gen_helper_gvec_ushl_h,
232
+ .opt_opc = vecop_list,
233
+ .vece = MO_16 },
234
+ { .fni4 = gen_ushl_i32,
235
+ .fniv = gen_ushl_vec,
236
+ .opt_opc = vecop_list,
237
+ .vece = MO_32 },
238
+ { .fni8 = gen_ushl_i64,
239
+ .fniv = gen_ushl_vec,
240
+ .opt_opc = vecop_list,
241
+ .vece = MO_64 },
242
+ };
243
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
244
+}
245
246
void gen_sshl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
247
{
248
@@ -XXX,XX +XXX,XX @@ static void gen_sshl_vec(unsigned vece, TCGv_vec dst,
249
tcg_temp_free_vec(tmp);
250
}
251
252
-static const TCGOpcode sshl_list[] = {
253
- INDEX_op_neg_vec, INDEX_op_umin_vec, INDEX_op_shlv_vec,
254
- INDEX_op_sarv_vec, INDEX_op_cmp_vec, INDEX_op_cmpsel_vec, 0
255
-};
256
-
257
-const GVecGen3 sshl_op[4] = {
258
- { .fniv = gen_sshl_vec,
259
- .fno = gen_helper_gvec_sshl_b,
260
- .opt_opc = sshl_list,
261
- .vece = MO_8 },
262
- { .fniv = gen_sshl_vec,
263
- .fno = gen_helper_gvec_sshl_h,
264
- .opt_opc = sshl_list,
265
- .vece = MO_16 },
266
- { .fni4 = gen_sshl_i32,
267
- .fniv = gen_sshl_vec,
268
- .opt_opc = sshl_list,
269
- .vece = MO_32 },
270
- { .fni8 = gen_sshl_i64,
271
- .fniv = gen_sshl_vec,
272
- .opt_opc = sshl_list,
273
- .vece = MO_64 },
274
-};
275
+void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
276
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
277
+{
278
+ static const TCGOpcode vecop_list[] = {
279
+ INDEX_op_neg_vec, INDEX_op_umin_vec, INDEX_op_shlv_vec,
280
+ INDEX_op_sarv_vec, INDEX_op_cmp_vec, INDEX_op_cmpsel_vec, 0
281
+ };
282
+ static const GVecGen3 ops[4] = {
283
+ { .fniv = gen_sshl_vec,
284
+ .fno = gen_helper_gvec_sshl_b,
285
+ .opt_opc = vecop_list,
286
+ .vece = MO_8 },
287
+ { .fniv = gen_sshl_vec,
288
+ .fno = gen_helper_gvec_sshl_h,
289
+ .opt_opc = vecop_list,
290
+ .vece = MO_16 },
291
+ { .fni4 = gen_sshl_i32,
292
+ .fniv = gen_sshl_vec,
293
+ .opt_opc = vecop_list,
294
+ .vece = MO_32 },
295
+ { .fni8 = gen_sshl_i64,
296
+ .fniv = gen_sshl_vec,
297
+ .opt_opc = vecop_list,
298
+ .vece = MO_64 },
299
+ };
300
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
301
+}
302
303
static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
304
TCGv_vec a, TCGv_vec b)
305
--
31
--
306
2.20.1
32
2.25.1
307
33
308
34
diff view generated by jsdifflib
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
1
From: Olivier Hériveaux <olivier.heriveaux@ledger.fr>
2
2
3
This patch builds Hardware Error Source Table(HEST) via fw_cfg blobs.
3
Fix issue where the data register may be overwritten by next character
4
Now it only supports ARMv8 SEA, a type of Generic Hardware Error
4
reception before being read and returned.
5
Source version 2(GHESv2) error source. Afterwards, we can extend
6
the supported types if needed. For the CPER section, currently it
7
is memory section because kernel mainly wants userspace to handle
8
the memory errors.
9
5
10
This patch follows the spec ACPI 6.2 to build the Hardware Error
6
Signed-off-by: Olivier Hériveaux <olivier.heriveaux@ledger.fr>
11
Source table. For more detailed information, please refer to
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
document: docs/specs/acpi_hest_ghes.rst
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
9
Message-id: 20211128120723.4053-1-olivier.heriveaux@ledger.fr
14
build_ghes_hw_error_notification() helper will help to add Hardware
15
Error Notification to ACPI tables without using packed C structures
16
and avoid endianness issues as API doesn't need explicit conversion.
17
18
Signed-off-by: Xiang Zheng <zhengxiang9@huawei.com>
19
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
20
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
21
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
22
Message-id: 20200512030609.19593-6-gengdongjiu@huawei.com
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
11
---
25
include/hw/acpi/ghes.h | 39 ++++++++++++
12
hw/char/stm32f2xx_usart.c | 3 ++-
26
hw/acpi/ghes.c | 126 +++++++++++++++++++++++++++++++++++++++
13
1 file changed, 2 insertions(+), 1 deletion(-)
27
hw/arm/virt-acpi-build.c | 2 +
28
3 files changed, 167 insertions(+)
29
14
30
diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h
15
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
31
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
32
--- a/include/hw/acpi/ghes.h
17
--- a/hw/char/stm32f2xx_usart.c
33
+++ b/include/hw/acpi/ghes.h
18
+++ b/hw/char/stm32f2xx_usart.c
34
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr,
35
20
return retvalue;
36
#include "hw/acpi/bios-linker-loader.h"
21
case USART_DR:
37
22
DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) s->usart_dr);
38
+/*
23
+ retvalue = s->usart_dr & 0x3FF;
39
+ * Values for Hardware Error Notification Type field
24
s->usart_sr &= ~USART_SR_RXNE;
40
+ */
25
qemu_chr_fe_accept_input(&s->chr);
41
+enum AcpiGhesNotifyType {
26
qemu_set_irq(s->irq, 0);
42
+ /* Polled */
27
- return s->usart_dr & 0x3FF;
43
+ ACPI_GHES_NOTIFY_POLLED = 0,
28
+ return retvalue;
44
+ /* External Interrupt */
29
case USART_BRR:
45
+ ACPI_GHES_NOTIFY_EXTERNAL = 1,
30
return s->usart_brr;
46
+ /* Local Interrupt */
31
case USART_CR1:
47
+ ACPI_GHES_NOTIFY_LOCAL = 2,
48
+ /* SCI */
49
+ ACPI_GHES_NOTIFY_SCI = 3,
50
+ /* NMI */
51
+ ACPI_GHES_NOTIFY_NMI = 4,
52
+ /* CMCI, ACPI 5.0: 18.3.2.7, Table 18-290 */
53
+ ACPI_GHES_NOTIFY_CMCI = 5,
54
+ /* MCE, ACPI 5.0: 18.3.2.7, Table 18-290 */
55
+ ACPI_GHES_NOTIFY_MCE = 6,
56
+ /* GPIO-Signal, ACPI 6.0: 18.3.2.7, Table 18-332 */
57
+ ACPI_GHES_NOTIFY_GPIO = 7,
58
+ /* ARMv8 SEA, ACPI 6.1: 18.3.2.9, Table 18-345 */
59
+ ACPI_GHES_NOTIFY_SEA = 8,
60
+ /* ARMv8 SEI, ACPI 6.1: 18.3.2.9, Table 18-345 */
61
+ ACPI_GHES_NOTIFY_SEI = 9,
62
+ /* External Interrupt - GSIV, ACPI 6.1: 18.3.2.9, Table 18-345 */
63
+ ACPI_GHES_NOTIFY_GSIV = 10,
64
+ /* Software Delegated Exception, ACPI 6.2: 18.3.2.9, Table 18-383 */
65
+ ACPI_GHES_NOTIFY_SDEI = 11,
66
+ /* 12 and greater are reserved */
67
+ ACPI_GHES_NOTIFY_RESERVED = 12
68
+};
69
+
70
+enum {
71
+ ACPI_HEST_SRC_ID_SEA = 0,
72
+ /* future ids go here */
73
+ ACPI_HEST_SRC_ID_RESERVED,
74
+};
75
+
76
void build_ghes_error_table(GArray *hardware_errors, BIOSLinker *linker);
77
+void acpi_build_hest(GArray *table_data, BIOSLinker *linker);
78
#endif
79
diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/acpi/ghes.c
82
+++ b/hw/acpi/ghes.c
83
@@ -XXX,XX +XXX,XX @@
84
#include "qemu/units.h"
85
#include "hw/acpi/ghes.h"
86
#include "hw/acpi/aml-build.h"
87
+#include "qemu/error-report.h"
88
89
#define ACPI_GHES_ERRORS_FW_CFG_FILE "etc/hardware_errors"
90
#define ACPI_GHES_DATA_ADDR_FW_CFG_FILE "etc/hardware_errors_addr"
91
@@ -XXX,XX +XXX,XX @@
92
/* Now only support ARMv8 SEA notification type error source */
93
#define ACPI_GHES_ERROR_SOURCE_COUNT 1
94
95
+/* Generic Hardware Error Source version 2 */
96
+#define ACPI_GHES_SOURCE_GENERIC_ERROR_V2 10
97
+
98
+/* Address offset in Generic Address Structure(GAS) */
99
+#define GAS_ADDR_OFFSET 4
100
+
101
+/*
102
+ * Hardware Error Notification
103
+ * ACPI 4.0: 17.3.2.7 Hardware Error Notification
104
+ * Composes dummy Hardware Error Notification descriptor of specified type
105
+ */
106
+static void build_ghes_hw_error_notification(GArray *table, const uint8_t type)
107
+{
108
+ /* Type */
109
+ build_append_int_noprefix(table, type, 1);
110
+ /*
111
+ * Length:
112
+ * Total length of the structure in bytes
113
+ */
114
+ build_append_int_noprefix(table, 28, 1);
115
+ /* Configuration Write Enable */
116
+ build_append_int_noprefix(table, 0, 2);
117
+ /* Poll Interval */
118
+ build_append_int_noprefix(table, 0, 4);
119
+ /* Vector */
120
+ build_append_int_noprefix(table, 0, 4);
121
+ /* Switch To Polling Threshold Value */
122
+ build_append_int_noprefix(table, 0, 4);
123
+ /* Switch To Polling Threshold Window */
124
+ build_append_int_noprefix(table, 0, 4);
125
+ /* Error Threshold Value */
126
+ build_append_int_noprefix(table, 0, 4);
127
+ /* Error Threshold Window */
128
+ build_append_int_noprefix(table, 0, 4);
129
+}
130
+
131
/*
132
* Build table for the hardware error fw_cfg blob.
133
* Initialize "etc/hardware_errors" and "etc/hardware_errors_addr" fw_cfg blobs.
134
@@ -XXX,XX +XXX,XX @@ void build_ghes_error_table(GArray *hardware_errors, BIOSLinker *linker)
135
bios_linker_loader_write_pointer(linker, ACPI_GHES_DATA_ADDR_FW_CFG_FILE,
136
0, sizeof(uint64_t), ACPI_GHES_ERRORS_FW_CFG_FILE, 0);
137
}
138
+
139
+/* Build Generic Hardware Error Source version 2 (GHESv2) */
140
+static void build_ghes_v2(GArray *table_data, int source_id, BIOSLinker *linker)
141
+{
142
+ uint64_t address_offset;
143
+ /*
144
+ * Type:
145
+ * Generic Hardware Error Source version 2(GHESv2 - Type 10)
146
+ */
147
+ build_append_int_noprefix(table_data, ACPI_GHES_SOURCE_GENERIC_ERROR_V2, 2);
148
+ /* Source Id */
149
+ build_append_int_noprefix(table_data, source_id, 2);
150
+ /* Related Source Id */
151
+ build_append_int_noprefix(table_data, 0xffff, 2);
152
+ /* Flags */
153
+ build_append_int_noprefix(table_data, 0, 1);
154
+ /* Enabled */
155
+ build_append_int_noprefix(table_data, 1, 1);
156
+
157
+ /* Number of Records To Pre-allocate */
158
+ build_append_int_noprefix(table_data, 1, 4);
159
+ /* Max Sections Per Record */
160
+ build_append_int_noprefix(table_data, 1, 4);
161
+ /* Max Raw Data Length */
162
+ build_append_int_noprefix(table_data, ACPI_GHES_MAX_RAW_DATA_LENGTH, 4);
163
+
164
+ address_offset = table_data->len;
165
+ /* Error Status Address */
166
+ build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 0x40, 0,
167
+ 4 /* QWord access */, 0);
168
+ bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
169
+ address_offset + GAS_ADDR_OFFSET, sizeof(uint64_t),
170
+ ACPI_GHES_ERRORS_FW_CFG_FILE, source_id * sizeof(uint64_t));
171
+
172
+ switch (source_id) {
173
+ case ACPI_HEST_SRC_ID_SEA:
174
+ /*
175
+ * Notification Structure
176
+ * Now only enable ARMv8 SEA notification type
177
+ */
178
+ build_ghes_hw_error_notification(table_data, ACPI_GHES_NOTIFY_SEA);
179
+ break;
180
+ default:
181
+ error_report("Not support this error source");
182
+ abort();
183
+ }
184
+
185
+ /* Error Status Block Length */
186
+ build_append_int_noprefix(table_data, ACPI_GHES_MAX_RAW_DATA_LENGTH, 4);
187
+
188
+ /*
189
+ * Read Ack Register
190
+ * ACPI 6.1: 18.3.2.8 Generic Hardware Error Source
191
+ * version 2 (GHESv2 - Type 10)
192
+ */
193
+ address_offset = table_data->len;
194
+ build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 0x40, 0,
195
+ 4 /* QWord access */, 0);
196
+ bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
197
+ address_offset + GAS_ADDR_OFFSET,
198
+ sizeof(uint64_t), ACPI_GHES_ERRORS_FW_CFG_FILE,
199
+ (ACPI_GHES_ERROR_SOURCE_COUNT + source_id) * sizeof(uint64_t));
200
+
201
+ /*
202
+ * Read Ack Preserve field
203
+ * We only provide the first bit in Read Ack Register to OSPM to write
204
+ * while the other bits are preserved.
205
+ */
206
+ build_append_int_noprefix(table_data, ~0x1ULL, 8);
207
+ /* Read Ack Write */
208
+ build_append_int_noprefix(table_data, 0x1, 8);
209
+}
210
+
211
+/* Build Hardware Error Source Table */
212
+void acpi_build_hest(GArray *table_data, BIOSLinker *linker)
213
+{
214
+ uint64_t hest_start = table_data->len;
215
+
216
+ /* Hardware Error Source Table header*/
217
+ acpi_data_push(table_data, sizeof(AcpiTableHeader));
218
+
219
+ /* Error Source Count */
220
+ build_append_int_noprefix(table_data, ACPI_GHES_ERROR_SOURCE_COUNT, 4);
221
+
222
+ build_ghes_v2(table_data, ACPI_HEST_SRC_ID_SEA, linker);
223
+
224
+ build_header(linker, table_data, (void *)(table_data->data + hest_start),
225
+ "HEST", table_data->len - hest_start, 1, NULL, NULL);
226
+}
227
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
228
index XXXXXXX..XXXXXXX 100644
229
--- a/hw/arm/virt-acpi-build.c
230
+++ b/hw/arm/virt-acpi-build.c
231
@@ -XXX,XX +XXX,XX @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
232
233
if (vms->ras) {
234
build_ghes_error_table(tables->hardware_errors, tables->linker);
235
+ acpi_add_table(table_offsets, tables_blob);
236
+ acpi_build_hest(tables_blob, tables->linker);
237
}
238
239
if (ms->numa_state->num_nodes > 0) {
240
--
32
--
241
2.20.1
33
2.25.1
242
34
243
35
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Provide a functional interface for the vector expansion.
3
gicv3_set_gicv3state() is used by arm_gicv3_common.c in
4
This fits better with the existing set of helpers that
4
arm_gicv3_common_realize(). Since we want to restrict
5
we provide for other operations.
5
arm_gicv3_cpuif.c to TCG, extract gicv3_set_gicv3state()
6
to a new file. Add this file to the meson 'specific'
7
source set, since it needs access to "cpu.h".
6
8
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20211115223619.2599282-2-philmd@redhat.com
9
Message-id: 20200513163245.17915-8-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
target/arm/translate.h | 7 +-
14
hw/intc/arm_gicv3_cpuif.c | 10 +---------
13
target/arm/translate-a64.c | 4 +-
15
hw/intc/arm_gicv3_cpuif_common.c | 22 ++++++++++++++++++++++
14
target/arm/translate-neon.inc.c | 16 +----
16
hw/intc/meson.build | 1 +
15
target/arm/translate.c | 117 +++++++++++++++++---------------
17
3 files changed, 24 insertions(+), 9 deletions(-)
16
4 files changed, 71 insertions(+), 73 deletions(-)
18
create mode 100644 hw/intc/arm_gicv3_cpuif_common.c
17
19
18
diff --git a/target/arm/translate.h b/target/arm/translate.h
20
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
19
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.h
22
--- a/hw/intc/arm_gicv3_cpuif.c
21
+++ b/target/arm/translate.h
23
+++ b/hw/intc/arm_gicv3_cpuif.c
22
@@ -XXX,XX +XXX,XX @@ void gen_gvec_cle0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
24
@@ -XXX,XX +XXX,XX @@
23
void gen_gvec_cge0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
25
/*
24
uint32_t opr_sz, uint32_t max_sz);
26
- * ARM Generic Interrupt Controller v3
25
27
+ * ARM Generic Interrupt Controller v3 (emulation)
26
-extern const GVecGen3 mla_op[4];
28
*
27
-extern const GVecGen3 mls_op[4];
29
* Copyright (c) 2016 Linaro Limited
28
+void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
30
* Written by Peter Maydell
29
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
31
@@ -XXX,XX +XXX,XX @@
30
+void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
32
#include "hw/irq.h"
31
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
33
#include "cpu.h"
32
+
34
33
extern const GVecGen3 cmtst_op[4];
35
-void gicv3_set_gicv3state(CPUState *cpu, GICv3CPUState *s)
34
extern const GVecGen3 sshl_op[4];
36
-{
35
extern const GVecGen3 ushl_op[4];
37
- ARMCPU *arm_cpu = ARM_CPU(cpu);
36
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
38
- CPUARMState *env = &arm_cpu->env;
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-a64.c
39
+++ b/target/arm/translate-a64.c
40
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
41
return;
42
case 0x12: /* MLA, MLS */
43
if (u) {
44
- gen_gvec_op3(s, is_q, rd, rn, rm, &mls_op[size]);
45
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_mls, size);
46
} else {
47
- gen_gvec_op3(s, is_q, rd, rn, rm, &mla_op[size]);
48
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_mla, size);
49
}
50
return;
51
case 0x11:
52
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/translate-neon.inc.c
55
+++ b/target/arm/translate-neon.inc.c
56
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
57
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
58
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
59
DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
60
+DO_3SAME_NO_SZ_3(VMLA, gen_gvec_mla)
61
+DO_3SAME_NO_SZ_3(VMLS, gen_gvec_mls)
62
63
#define DO_3SAME_CMP(INSN, COND) \
64
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
65
@@ -XXX,XX +XXX,XX @@ static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
66
return do_3same(s, a, gen_VMUL_p_3s);
67
}
68
69
-#define DO_3SAME_GVEC3_NO_SZ_3(INSN, OPARRAY) \
70
- static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
71
- uint32_t rn_ofs, uint32_t rm_ofs, \
72
- uint32_t oprsz, uint32_t maxsz) \
73
- { \
74
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
75
- oprsz, maxsz, &OPARRAY[vece]); \
76
- } \
77
- DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
78
-
39
-
79
-
40
- env->gicv3state = (void *)s;
80
-DO_3SAME_GVEC3_NO_SZ_3(VMLA, mla_op)
81
-DO_3SAME_GVEC3_NO_SZ_3(VMLS, mls_op)
82
-
83
#define DO_3SAME_GVEC3_SHIFT(INSN, OPARRAY) \
84
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
85
uint32_t rn_ofs, uint32_t rm_ofs, \
86
diff --git a/target/arm/translate.c b/target/arm/translate.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/arm/translate.c
89
+++ b/target/arm/translate.c
90
@@ -XXX,XX +XXX,XX @@ static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
91
/* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
92
* these tables are shared with AArch64 which does support them.
93
*/
94
+void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
95
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
96
+{
97
+ static const TCGOpcode vecop_list[] = {
98
+ INDEX_op_mul_vec, INDEX_op_add_vec, 0
99
+ };
100
+ static const GVecGen3 ops[4] = {
101
+ { .fni4 = gen_mla8_i32,
102
+ .fniv = gen_mla_vec,
103
+ .load_dest = true,
104
+ .opt_opc = vecop_list,
105
+ .vece = MO_8 },
106
+ { .fni4 = gen_mla16_i32,
107
+ .fniv = gen_mla_vec,
108
+ .load_dest = true,
109
+ .opt_opc = vecop_list,
110
+ .vece = MO_16 },
111
+ { .fni4 = gen_mla32_i32,
112
+ .fniv = gen_mla_vec,
113
+ .load_dest = true,
114
+ .opt_opc = vecop_list,
115
+ .vece = MO_32 },
116
+ { .fni8 = gen_mla64_i64,
117
+ .fniv = gen_mla_vec,
118
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
119
+ .load_dest = true,
120
+ .opt_opc = vecop_list,
121
+ .vece = MO_64 },
122
+ };
123
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
124
+}
125
126
-static const TCGOpcode vecop_list_mla[] = {
127
- INDEX_op_mul_vec, INDEX_op_add_vec, 0
128
-};
41
-};
129
-
42
-
130
-static const TCGOpcode vecop_list_mls[] = {
43
static GICv3CPUState *icc_cs_from_env(CPUARMState *env)
131
- INDEX_op_mul_vec, INDEX_op_sub_vec, 0
44
{
132
-};
45
return env->gicv3state;
133
-
46
diff --git a/hw/intc/arm_gicv3_cpuif_common.c b/hw/intc/arm_gicv3_cpuif_common.c
134
-const GVecGen3 mla_op[4] = {
47
new file mode 100644
135
- { .fni4 = gen_mla8_i32,
48
index XXXXXXX..XXXXXXX
136
- .fniv = gen_mla_vec,
49
--- /dev/null
137
- .load_dest = true,
50
+++ b/hw/intc/arm_gicv3_cpuif_common.c
138
- .opt_opc = vecop_list_mla,
51
@@ -XXX,XX +XXX,XX @@
139
- .vece = MO_8 },
52
+/* SPDX-License-Identifier: GPL-2.0-or-later */
140
- { .fni4 = gen_mla16_i32,
53
+/*
141
- .fniv = gen_mla_vec,
54
+ * ARM Generic Interrupt Controller v3
142
- .load_dest = true,
55
+ *
143
- .opt_opc = vecop_list_mla,
56
+ * Copyright (c) 2016 Linaro Limited
144
- .vece = MO_16 },
57
+ * Written by Peter Maydell
145
- { .fni4 = gen_mla32_i32,
58
+ *
146
- .fniv = gen_mla_vec,
59
+ * This code is licensed under the GPL, version 2 or (at your option)
147
- .load_dest = true,
60
+ * any later version.
148
- .opt_opc = vecop_list_mla,
61
+ */
149
- .vece = MO_32 },
62
+
150
- { .fni8 = gen_mla64_i64,
63
+#include "qemu/osdep.h"
151
- .fniv = gen_mla_vec,
64
+#include "gicv3_internal.h"
152
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
65
+#include "cpu.h"
153
- .load_dest = true,
66
+
154
- .opt_opc = vecop_list_mla,
67
+void gicv3_set_gicv3state(CPUState *cpu, GICv3CPUState *s)
155
- .vece = MO_64 },
156
-};
157
-
158
-const GVecGen3 mls_op[4] = {
159
- { .fni4 = gen_mls8_i32,
160
- .fniv = gen_mls_vec,
161
- .load_dest = true,
162
- .opt_opc = vecop_list_mls,
163
- .vece = MO_8 },
164
- { .fni4 = gen_mls16_i32,
165
- .fniv = gen_mls_vec,
166
- .load_dest = true,
167
- .opt_opc = vecop_list_mls,
168
- .vece = MO_16 },
169
- { .fni4 = gen_mls32_i32,
170
- .fniv = gen_mls_vec,
171
- .load_dest = true,
172
- .opt_opc = vecop_list_mls,
173
- .vece = MO_32 },
174
- { .fni8 = gen_mls64_i64,
175
- .fniv = gen_mls_vec,
176
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
177
- .load_dest = true,
178
- .opt_opc = vecop_list_mls,
179
- .vece = MO_64 },
180
-};
181
+void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
182
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
183
+{
68
+{
184
+ static const TCGOpcode vecop_list[] = {
69
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
185
+ INDEX_op_mul_vec, INDEX_op_sub_vec, 0
70
+ CPUARMState *env = &arm_cpu->env;
186
+ };
71
+
187
+ static const GVecGen3 ops[4] = {
72
+ env->gicv3state = (void *)s;
188
+ { .fni4 = gen_mls8_i32,
73
+};
189
+ .fniv = gen_mls_vec,
74
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
190
+ .load_dest = true,
75
index XXXXXXX..XXXXXXX 100644
191
+ .opt_opc = vecop_list,
76
--- a/hw/intc/meson.build
192
+ .vece = MO_8 },
77
+++ b/hw/intc/meson.build
193
+ { .fni4 = gen_mls16_i32,
78
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_PMU', if_true: files('xlnx-pmu-iomod-in
194
+ .fniv = gen_mls_vec,
79
195
+ .load_dest = true,
80
specific_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: files('allwinner-a10-pic.c'))
196
+ .opt_opc = vecop_list,
81
specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c', 'apic_common.c'))
197
+ .vece = MO_16 },
82
+specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_common.c'))
198
+ { .fni4 = gen_mls32_i32,
83
specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif.c'))
199
+ .fniv = gen_mls_vec,
84
specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'))
200
+ .load_dest = true,
85
specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
201
+ .opt_opc = vecop_list,
202
+ .vece = MO_32 },
203
+ { .fni8 = gen_mls64_i64,
204
+ .fniv = gen_mls_vec,
205
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
206
+ .load_dest = true,
207
+ .opt_opc = vecop_list,
208
+ .vece = MO_64 },
209
+ };
210
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
211
+}
212
213
/* CMTST : test is "if (X & Y != 0)". */
214
static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
215
--
86
--
216
2.20.1
87
2.25.1
217
88
218
89
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Rather than perform the argument swap during code generation,
3
The TYPE_ARM_GICV3 device is an emulated one. When using
4
perform it during decode. This means it doesn't have to be
4
KVM, it is recommended to use the TYPE_KVM_ARM_GICV3 device
5
special cased later, and we can share code with aarch64 code
5
(which uses in-kernel support).
6
generation. Hopefully the decode comment addresses any confusion
7
that might arise in between.
8
6
7
When using --with-devices-FOO, it is possible to build a
8
binary with a specific set of devices. When this binary is
9
restricted to KVM accelerator, the TYPE_ARM_GICV3 device is
10
irrelevant, and it is desirable to remove it from the binary.
11
12
Therefore introduce the CONFIG_ARM_GIC_TCG Kconfig selector
13
which select the files required to have the TYPE_ARM_GICV3
14
device, but also allowing to de-select this device.
15
16
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20211115223619.2599282-3-philmd@redhat.com
11
Message-id: 20200513163245.17915-9-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
20
---
14
target/arm/neon-dp.decode | 17 +++++++++++++++--
21
hw/intc/arm_gicv3.c | 2 +-
15
target/arm/translate-neon.inc.c | 3 +--
22
hw/intc/Kconfig | 5 +++++
16
2 files changed, 16 insertions(+), 4 deletions(-)
23
hw/intc/meson.build | 10 ++++++----
24
3 files changed, 12 insertions(+), 5 deletions(-)
17
25
18
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
26
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
19
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/neon-dp.decode
28
--- a/hw/intc/arm_gicv3.c
21
+++ b/target/arm/neon-dp.decode
29
+++ b/hw/intc/arm_gicv3.c
22
@@ -XXX,XX +XXX,XX @@ VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
30
@@ -XXX,XX +XXX,XX @@
23
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
31
/*
24
VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
32
- * ARM Generic Interrupt Controller v3
25
33
+ * ARM Generic Interrupt Controller v3 (emulation)
26
-VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same
34
*
27
-VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same
35
* Copyright (c) 2015 Huawei.
28
+# The _rev suffix indicates that Vn and Vm are reversed. This is
36
* Copyright (c) 2016 Linaro Limited
29
+# the case for shifts. In the Arm ARM these insns are documented
37
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
30
+# with the Vm and Vn fields in their usual places, but in the
38
index XXXXXXX..XXXXXXX 100644
31
+# assembly the operands are listed "backwards", ie in the order
39
--- a/hw/intc/Kconfig
32
+# Dd, Dm, Dn where other insns use Dd, Dn, Dm. For QEMU we choose
40
+++ b/hw/intc/Kconfig
33
+# to consider Vm and Vn as being in different fields in the insn,
41
@@ -XXX,XX +XXX,XX @@ config APIC
34
+# which allows us to avoid special-casing shifts in the trans_
42
select MSI_NONBROKEN
35
+# function code. We would otherwise need to manually swap the operands
43
select I8259
36
+# over to call Neon helper functions that are shared with AArch64,
44
37
+# which does not have this odd reversed-operand situation.
45
+config ARM_GIC_TCG
38
+@3same_rev .... ... . . . size:2 .... .... .... . q:1 . . .... \
46
+ bool
39
+ &3same vn=%vm_dp vm=%vn_dp vd=%vd_dp
47
+ default y
48
+ depends on ARM_GIC && TCG
40
+
49
+
41
+VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same_rev
50
config ARM_GIC_KVM
42
+VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same_rev
51
bool
43
52
default y
44
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
53
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
45
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
46
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
47
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate-neon.inc.c
55
--- a/hw/intc/meson.build
49
+++ b/target/arm/translate-neon.inc.c
56
+++ b/hw/intc/meson.build
50
@@ -XXX,XX +XXX,XX @@ static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
57
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ARM_GIC', if_true: files(
51
uint32_t rn_ofs, uint32_t rm_ofs, \
58
'arm_gic.c',
52
uint32_t oprsz, uint32_t maxsz) \
59
'arm_gic_common.c',
53
{ \
60
'arm_gicv2m.c',
54
- /* Note the operation is vshl vd,vm,vn */ \
61
- 'arm_gicv3.c',
55
- tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, \
62
'arm_gicv3_common.c',
56
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
63
- 'arm_gicv3_dist.c',
57
oprsz, maxsz, &OPARRAY[vece]); \
64
'arm_gicv3_its_common.c',
58
} \
65
- 'arm_gicv3_redist.c',
59
DO_3SAME(INSN, gen_##INSN##_3s)
66
+))
67
+softmmu_ss.add(when: 'CONFIG_ARM_GIC_TCG', if_true: files(
68
+ 'arm_gicv3.c',
69
+ 'arm_gicv3_dist.c',
70
'arm_gicv3_its.c',
71
+ 'arm_gicv3_redist.c',
72
))
73
softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_pic.c'))
74
softmmu_ss.add(when: 'CONFIG_HEATHROW_PIC', if_true: files('heathrow_pic.c'))
75
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_PMU', if_true: files('xlnx-pmu-iomod-in
76
specific_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: files('allwinner-a10-pic.c'))
77
specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c', 'apic_common.c'))
78
specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_common.c'))
79
-specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif.c'))
80
+specific_ss.add(when: 'CONFIG_ARM_GIC_TCG', if_true: files('arm_gicv3_cpuif.c'))
81
specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'))
82
specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
83
specific_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_nvic.c'))
60
--
84
--
61
2.20.1
85
2.25.1
62
86
63
87
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Now that we've converted all cases to gvec, there is quite a bit
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
of dead code at the end of the function. Remove it.
5
6
Sink the call to gen_gvec_fn2i to the end, loading a function
7
pointer within the switch statement.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20200513163245.17915-6-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
6
---
14
target/arm/translate-a64.c | 56 ++++++++++----------------------------
7
target/arm/translate-a64.c | 7 ++++---
15
1 file changed, 14 insertions(+), 42 deletions(-)
8
1 file changed, 4 insertions(+), 3 deletions(-)
16
9
17
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
10
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
18
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate-a64.c
12
--- a/target/arm/translate-a64.c
20
+++ b/target/arm/translate-a64.c
13
+++ b/target/arm/translate-a64.c
21
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
14
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
22
int size = 32 - clz32(immh) - 1;
15
{
23
int immhb = immh << 3 | immb;
16
DisasContext *s = container_of(dcbase, DisasContext, base);
24
int shift = 2 * (8 << size) - immhb;
17
CPUARMState *env = cpu->env_ptr;
25
- bool accumulate = false;
18
+ uint64_t pc = s->base.pc_next;
26
- int dsize = is_q ? 128 : 64;
19
uint32_t insn;
27
- int esize = 8 << size;
20
28
- int elements = dsize/esize;
21
if (s->ss_active && !s->pstate_ss) {
29
- MemOp memop = size | (is_u ? 0 : MO_SIGN);
22
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
30
- TCGv_i64 tcg_rn = new_tmp_a64(s);
23
return;
31
- TCGv_i64 tcg_rd = new_tmp_a64(s);
32
- TCGv_i64 tcg_round;
33
- uint64_t round_const;
34
- int i;
35
+ GVecGen2iFn *gvec_fn;
36
37
if (extract32(immh, 3, 1) && !is_q) {
38
unallocated_encoding(s);
39
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
40
41
switch (opcode) {
42
case 0x02: /* SSRA / USRA (accumulate) */
43
- gen_gvec_fn2i(s, is_q, rd, rn, shift,
44
- is_u ? gen_gvec_usra : gen_gvec_ssra, size);
45
- return;
46
+ gvec_fn = is_u ? gen_gvec_usra : gen_gvec_ssra;
47
+ break;
48
49
case 0x08: /* SRI */
50
- gen_gvec_fn2i(s, is_q, rd, rn, shift, gen_gvec_sri, size);
51
- return;
52
+ gvec_fn = gen_gvec_sri;
53
+ break;
54
55
case 0x00: /* SSHR / USHR */
56
if (is_u) {
57
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
58
/* Shift count the same size as element size produces zero. */
59
tcg_gen_gvec_dup_imm(size, vec_full_reg_offset(s, rd),
60
is_q ? 16 : 8, vec_full_reg_size(s), 0);
61
- } else {
62
- gen_gvec_fn2i(s, is_q, rd, rn, shift, tcg_gen_gvec_shri, size);
63
+ return;
64
}
65
+ gvec_fn = tcg_gen_gvec_shri;
66
} else {
67
/* Shift count the same size as element size produces all sign. */
68
if (shift == 8 << size) {
69
shift -= 1;
70
}
71
- gen_gvec_fn2i(s, is_q, rd, rn, shift, tcg_gen_gvec_sari, size);
72
+ gvec_fn = tcg_gen_gvec_sari;
73
}
74
- return;
75
+ break;
76
77
case 0x04: /* SRSHR / URSHR (rounding) */
78
- gen_gvec_fn2i(s, is_q, rd, rn, shift,
79
- is_u ? gen_gvec_urshr : gen_gvec_srshr, size);
80
- return;
81
+ gvec_fn = is_u ? gen_gvec_urshr : gen_gvec_srshr;
82
+ break;
83
84
case 0x06: /* SRSRA / URSRA (accum + rounding) */
85
- gen_gvec_fn2i(s, is_q, rd, rn, shift,
86
- is_u ? gen_gvec_ursra : gen_gvec_srsra, size);
87
- return;
88
+ gvec_fn = is_u ? gen_gvec_ursra : gen_gvec_srsra;
89
+ break;
90
91
default:
92
g_assert_not_reached();
93
}
24
}
94
25
95
- round_const = 1ULL << (shift - 1);
26
- s->pc_curr = s->base.pc_next;
96
- tcg_round = tcg_const_i64(round_const);
27
- insn = arm_ldl_code(env, &s->base, s->base.pc_next, s->sctlr_b);
97
-
28
+ s->pc_curr = pc;
98
- for (i = 0; i < elements; i++) {
29
+ insn = arm_ldl_code(env, &s->base, pc, s->sctlr_b);
99
- read_vec_element(s, tcg_rn, rn, i, memop);
30
s->insn = insn;
100
- if (accumulate) {
31
- s->base.pc_next += 4;
101
- read_vec_element(s, tcg_rd, rd, i, memop);
32
+ s->base.pc_next = pc + 4;
102
- }
33
103
-
34
s->fp_access_checked = false;
104
- handle_shri_with_rndacc(tcg_rd, tcg_rn, tcg_round,
35
s->sve_access_checked = false;
105
- accumulate, is_u, size, shift);
106
-
107
- write_vec_element(s, tcg_rd, rd, i, size);
108
- }
109
- tcg_temp_free_i64(tcg_round);
110
-
111
- clear_vec_high(s, is_q, rd);
112
+ gen_gvec_fn2i(s, is_q, rd, rn, shift, gvec_fn, size);
113
}
114
115
/* SHL/SLI - Vector shift left */
116
--
36
--
117
2.20.1
37
2.25.1
118
38
119
39
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Pass a pointer directly to env->vfp.qc[0], rather than env.
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
This will allow SVE2, which does not modify QC, to pass a
5
pointer to dummy storage.
6
7
Change the return type of inl_qrdml.h_s16 to match the
8
sense of the operation: signed.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200513163245.17915-14-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
6
---
15
target/arm/translate.c | 18 ++++++++---
7
target/arm/translate.c | 9 +++++----
16
target/arm/vec_helper.c | 70 +++++++++++++++++++++++------------------
8
1 file changed, 5 insertions(+), 4 deletions(-)
17
2 files changed, 54 insertions(+), 34 deletions(-)
18
9
19
diff --git a/target/arm/translate.c b/target/arm/translate.c
10
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate.c
12
--- a/target/arm/translate.c
22
+++ b/target/arm/translate.c
13
+++ b/target/arm/translate.c
23
@@ -XXX,XX +XXX,XX @@ static const uint8_t neon_2rm_sizes[] = {
14
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
24
[NEON_2RM_VCVT_UF] = 0x4,
25
};
26
27
+static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs,
28
+ uint32_t opr_sz, uint32_t max_sz,
29
+ gen_helper_gvec_3_ptr *fn)
30
+{
31
+ TCGv_ptr qc_ptr = tcg_temp_new_ptr();
32
+
33
+ tcg_gen_addi_ptr(qc_ptr, cpu_env, offsetof(CPUARMState, vfp.qc));
34
+ tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, qc_ptr,
35
+ opr_sz, max_sz, 0, fn);
36
+ tcg_temp_free_ptr(qc_ptr);
37
+}
38
+
39
void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
40
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
41
{
15
{
42
@@ -XXX,XX +XXX,XX @@ void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
16
DisasContext *dc = container_of(dcbase, DisasContext, base);
43
gen_helper_gvec_qrdmlah_s16, gen_helper_gvec_qrdmlah_s32
17
CPUARMState *env = cpu->env_ptr;
44
};
18
+ uint32_t pc = dc->base.pc_next;
45
tcg_debug_assert(vece >= 1 && vece <= 2);
19
unsigned int insn;
46
- tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, cpu_env,
20
47
- opr_sz, max_sz, 0, fns[vece - 1]);
21
if (arm_pre_translate_insn(dc)) {
48
+ gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
22
- dc->base.pc_next += 4;
49
}
23
+ dc->base.pc_next = pc + 4;
50
24
return;
51
void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
52
@@ -XXX,XX +XXX,XX @@ void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
53
gen_helper_gvec_qrdmlsh_s16, gen_helper_gvec_qrdmlsh_s32
54
};
55
tcg_debug_assert(vece >= 1 && vece <= 2);
56
- tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, cpu_env,
57
- opr_sz, max_sz, 0, fns[vece - 1]);
58
+ gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
59
}
60
61
#define GEN_CMP0(NAME, COND) \
62
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/target/arm/vec_helper.c
65
+++ b/target/arm/vec_helper.c
66
@@ -XXX,XX +XXX,XX @@
67
#define H4(x) (x)
68
#endif
69
70
-#define SET_QC() env->vfp.qc[0] = 1
71
-
72
static void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz)
73
{
74
uint64_t *d = vd + opr_sz;
75
@@ -XXX,XX +XXX,XX @@ static void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz)
76
}
77
78
/* Signed saturating rounding doubling multiply-accumulate high half, 16-bit */
79
-static uint16_t inl_qrdmlah_s16(CPUARMState *env, int16_t src1,
80
- int16_t src2, int16_t src3)
81
+static int16_t inl_qrdmlah_s16(int16_t src1, int16_t src2,
82
+ int16_t src3, uint32_t *sat)
83
{
84
/* Simplify:
85
* = ((a3 << 16) + ((e1 * e2) << 1) + (1 << 15)) >> 16
86
@@ -XXX,XX +XXX,XX @@ static uint16_t inl_qrdmlah_s16(CPUARMState *env, int16_t src1,
87
ret = ((int32_t)src3 << 15) + ret + (1 << 14);
88
ret >>= 15;
89
if (ret != (int16_t)ret) {
90
- SET_QC();
91
+ *sat = 1;
92
ret = (ret < 0 ? -0x8000 : 0x7fff);
93
}
25
}
94
return ret;
26
95
@@ -XXX,XX +XXX,XX @@ static uint16_t inl_qrdmlah_s16(CPUARMState *env, int16_t src1,
27
- dc->pc_curr = dc->base.pc_next;
96
uint32_t HELPER(neon_qrdmlah_s16)(CPUARMState *env, uint32_t src1,
28
- insn = arm_ldl_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
97
uint32_t src2, uint32_t src3)
29
+ dc->pc_curr = pc;
98
{
30
+ insn = arm_ldl_code(env, &dc->base, pc, dc->sctlr_b);
99
- uint16_t e1 = inl_qrdmlah_s16(env, src1, src2, src3);
31
dc->insn = insn;
100
- uint16_t e2 = inl_qrdmlah_s16(env, src1 >> 16, src2 >> 16, src3 >> 16);
32
- dc->base.pc_next += 4;
101
+ uint32_t *sat = &env->vfp.qc[0];
33
+ dc->base.pc_next = pc + 4;
102
+ uint16_t e1 = inl_qrdmlah_s16(src1, src2, src3, sat);
34
disas_arm_insn(dc, insn);
103
+ uint16_t e2 = inl_qrdmlah_s16(src1 >> 16, src2 >> 16, src3 >> 16, sat);
35
104
return deposit32(e1, 16, 16, e2);
36
arm_post_translate_insn(dc);
105
}
106
107
void HELPER(gvec_qrdmlah_s16)(void *vd, void *vn, void *vm,
108
- void *ve, uint32_t desc)
109
+ void *vq, uint32_t desc)
110
{
111
uintptr_t opr_sz = simd_oprsz(desc);
112
int16_t *d = vd;
113
int16_t *n = vn;
114
int16_t *m = vm;
115
- CPUARMState *env = ve;
116
uintptr_t i;
117
118
for (i = 0; i < opr_sz / 2; ++i) {
119
- d[i] = inl_qrdmlah_s16(env, n[i], m[i], d[i]);
120
+ d[i] = inl_qrdmlah_s16(n[i], m[i], d[i], vq);
121
}
122
clear_tail(d, opr_sz, simd_maxsz(desc));
123
}
124
125
/* Signed saturating rounding doubling multiply-subtract high half, 16-bit */
126
-static uint16_t inl_qrdmlsh_s16(CPUARMState *env, int16_t src1,
127
- int16_t src2, int16_t src3)
128
+static int16_t inl_qrdmlsh_s16(int16_t src1, int16_t src2,
129
+ int16_t src3, uint32_t *sat)
130
{
131
/* Similarly, using subtraction:
132
* = ((a3 << 16) - ((e1 * e2) << 1) + (1 << 15)) >> 16
133
@@ -XXX,XX +XXX,XX @@ static uint16_t inl_qrdmlsh_s16(CPUARMState *env, int16_t src1,
134
ret = ((int32_t)src3 << 15) - ret + (1 << 14);
135
ret >>= 15;
136
if (ret != (int16_t)ret) {
137
- SET_QC();
138
+ *sat = 1;
139
ret = (ret < 0 ? -0x8000 : 0x7fff);
140
}
141
return ret;
142
@@ -XXX,XX +XXX,XX @@ static uint16_t inl_qrdmlsh_s16(CPUARMState *env, int16_t src1,
143
uint32_t HELPER(neon_qrdmlsh_s16)(CPUARMState *env, uint32_t src1,
144
uint32_t src2, uint32_t src3)
145
{
146
- uint16_t e1 = inl_qrdmlsh_s16(env, src1, src2, src3);
147
- uint16_t e2 = inl_qrdmlsh_s16(env, src1 >> 16, src2 >> 16, src3 >> 16);
148
+ uint32_t *sat = &env->vfp.qc[0];
149
+ uint16_t e1 = inl_qrdmlsh_s16(src1, src2, src3, sat);
150
+ uint16_t e2 = inl_qrdmlsh_s16(src1 >> 16, src2 >> 16, src3 >> 16, sat);
151
return deposit32(e1, 16, 16, e2);
152
}
153
154
void HELPER(gvec_qrdmlsh_s16)(void *vd, void *vn, void *vm,
155
- void *ve, uint32_t desc)
156
+ void *vq, uint32_t desc)
157
{
158
uintptr_t opr_sz = simd_oprsz(desc);
159
int16_t *d = vd;
160
int16_t *n = vn;
161
int16_t *m = vm;
162
- CPUARMState *env = ve;
163
uintptr_t i;
164
165
for (i = 0; i < opr_sz / 2; ++i) {
166
- d[i] = inl_qrdmlsh_s16(env, n[i], m[i], d[i]);
167
+ d[i] = inl_qrdmlsh_s16(n[i], m[i], d[i], vq);
168
}
169
clear_tail(d, opr_sz, simd_maxsz(desc));
170
}
171
172
/* Signed saturating rounding doubling multiply-accumulate high half, 32-bit */
173
-uint32_t HELPER(neon_qrdmlah_s32)(CPUARMState *env, int32_t src1,
174
- int32_t src2, int32_t src3)
175
+static int32_t inl_qrdmlah_s32(int32_t src1, int32_t src2,
176
+ int32_t src3, uint32_t *sat)
177
{
178
/* Simplify similarly to int_qrdmlah_s16 above. */
179
int64_t ret = (int64_t)src1 * src2;
180
ret = ((int64_t)src3 << 31) + ret + (1 << 30);
181
ret >>= 31;
182
if (ret != (int32_t)ret) {
183
- SET_QC();
184
+ *sat = 1;
185
ret = (ret < 0 ? INT32_MIN : INT32_MAX);
186
}
187
return ret;
188
}
189
190
+uint32_t HELPER(neon_qrdmlah_s32)(CPUARMState *env, int32_t src1,
191
+ int32_t src2, int32_t src3)
192
+{
193
+ uint32_t *sat = &env->vfp.qc[0];
194
+ return inl_qrdmlah_s32(src1, src2, src3, sat);
195
+}
196
+
197
void HELPER(gvec_qrdmlah_s32)(void *vd, void *vn, void *vm,
198
- void *ve, uint32_t desc)
199
+ void *vq, uint32_t desc)
200
{
201
uintptr_t opr_sz = simd_oprsz(desc);
202
int32_t *d = vd;
203
int32_t *n = vn;
204
int32_t *m = vm;
205
- CPUARMState *env = ve;
206
uintptr_t i;
207
208
for (i = 0; i < opr_sz / 4; ++i) {
209
- d[i] = helper_neon_qrdmlah_s32(env, n[i], m[i], d[i]);
210
+ d[i] = inl_qrdmlah_s32(n[i], m[i], d[i], vq);
211
}
212
clear_tail(d, opr_sz, simd_maxsz(desc));
213
}
214
215
/* Signed saturating rounding doubling multiply-subtract high half, 32-bit */
216
-uint32_t HELPER(neon_qrdmlsh_s32)(CPUARMState *env, int32_t src1,
217
- int32_t src2, int32_t src3)
218
+static int32_t inl_qrdmlsh_s32(int32_t src1, int32_t src2,
219
+ int32_t src3, uint32_t *sat)
220
{
221
/* Simplify similarly to int_qrdmlsh_s16 above. */
222
int64_t ret = (int64_t)src1 * src2;
223
ret = ((int64_t)src3 << 31) - ret + (1 << 30);
224
ret >>= 31;
225
if (ret != (int32_t)ret) {
226
- SET_QC();
227
+ *sat = 1;
228
ret = (ret < 0 ? INT32_MIN : INT32_MAX);
229
}
230
return ret;
231
}
232
233
+uint32_t HELPER(neon_qrdmlsh_s32)(CPUARMState *env, int32_t src1,
234
+ int32_t src2, int32_t src3)
235
+{
236
+ uint32_t *sat = &env->vfp.qc[0];
237
+ return inl_qrdmlsh_s32(src1, src2, src3, sat);
238
+}
239
+
240
void HELPER(gvec_qrdmlsh_s32)(void *vd, void *vn, void *vm,
241
- void *ve, uint32_t desc)
242
+ void *vq, uint32_t desc)
243
{
244
uintptr_t opr_sz = simd_oprsz(desc);
245
int32_t *d = vd;
246
int32_t *n = vn;
247
int32_t *m = vm;
248
- CPUARMState *env = ve;
249
uintptr_t i;
250
251
for (i = 0; i < opr_sz / 4; ++i) {
252
- d[i] = helper_neon_qrdmlsh_s32(env, n[i], m[i], d[i]);
253
+ d[i] = inl_qrdmlsh_s32(n[i], m[i], d[i], vq);
254
}
255
clear_tail(d, opr_sz, simd_maxsz(desc));
256
}
257
--
37
--
258
2.20.1
38
2.25.1
259
39
260
40
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
In 1dc8425e551, while converting to gvec, I added an extra range check
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
against the shift count. This was unnecessary because the encoding of
5
the shift count produces 0 to the element size - 1.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200513163245.17915-5-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
6
---
12
target/arm/translate.c | 12 ++----------
7
target/arm/translate.c | 16 ++++++++--------
13
1 file changed, 2 insertions(+), 10 deletions(-)
8
1 file changed, 8 insertions(+), 8 deletions(-)
14
9
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
10
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
12
--- a/target/arm/translate.c
18
+++ b/target/arm/translate.c
13
+++ b/target/arm/translate.c
19
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
14
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
20
gen_gvec_sli(size, rd_ofs, rm_ofs, shift,
15
{
21
vec_size, vec_size);
16
DisasContext *dc = container_of(dcbase, DisasContext, base);
22
} else { /* VSHL */
17
CPUARMState *env = cpu->env_ptr;
23
- /* Shifts larger than the element size are
18
+ uint32_t pc = dc->base.pc_next;
24
- * architecturally valid and results in zero.
19
uint32_t insn;
25
- */
20
bool is_16bit;
26
- if (shift >= 8 << size) {
21
27
- tcg_gen_gvec_dup_imm(size, rd_ofs,
22
if (arm_pre_translate_insn(dc)) {
28
- vec_size, vec_size, 0);
23
- dc->base.pc_next += 2;
29
- } else {
24
+ dc->base.pc_next = pc + 2;
30
- tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
25
return;
31
- vec_size, vec_size);
26
}
32
- }
27
33
+ tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
28
- dc->pc_curr = dc->base.pc_next;
34
+ vec_size, vec_size);
29
- insn = arm_lduw_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
35
}
30
+ dc->pc_curr = pc;
36
return 0;
31
+ insn = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
37
}
32
is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
33
- dc->base.pc_next += 2;
34
+ pc += 2;
35
if (!is_16bit) {
36
- uint32_t insn2 = arm_lduw_code(env, &dc->base, dc->base.pc_next,
37
- dc->sctlr_b);
38
-
39
+ uint32_t insn2 = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
40
insn = insn << 16 | insn2;
41
- dc->base.pc_next += 2;
42
+ pc += 2;
43
}
44
+ dc->base.pc_next = pc;
45
dc->insn = insn;
46
47
if (dc->pstate_il) {
38
--
48
--
39
2.20.1
49
2.25.1
40
50
41
51
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Provide a functional interface for the vector expansion.
3
Create arm_check_ss_active and arm_check_kernelpage.
4
This fits better with the existing set of helpers that
5
we provide for other operations.
6
4
7
Macro-ize the 5 nearly identical comparisons.
5
Reverse the order of the tests. While it doesn't matter in practice,
6
because only user-only has a kernel page and user-only never sets
7
ss_active, ss_active has priority over execution exceptions and it
8
is best to keep them in the proper order.
8
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20200513163245.17915-7-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
target/arm/translate.h | 16 ++-
14
target/arm/translate.c | 10 +++++++---
15
target/arm/translate-a64.c | 22 ++--
15
1 file changed, 7 insertions(+), 3 deletions(-)
16
target/arm/translate.c | 254 ++++++++-----------------------------
17
3 files changed, 74 insertions(+), 218 deletions(-)
18
16
19
diff --git a/target/arm/translate.h b/target/arm/translate.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate.h
22
+++ b/target/arm/translate.h
23
@@ -XXX,XX +XXX,XX @@ static inline void gen_swstep_exception(DisasContext *s, int isv, int ex)
24
uint64_t vfp_expand_imm(int size, uint8_t imm8);
25
26
/* Vector operations shared between ARM and AArch64. */
27
-extern const GVecGen2 ceq0_op[4];
28
-extern const GVecGen2 clt0_op[4];
29
-extern const GVecGen2 cgt0_op[4];
30
-extern const GVecGen2 cle0_op[4];
31
-extern const GVecGen2 cge0_op[4];
32
+void gen_gvec_ceq0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
33
+ uint32_t opr_sz, uint32_t max_sz);
34
+void gen_gvec_clt0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
35
+ uint32_t opr_sz, uint32_t max_sz);
36
+void gen_gvec_cgt0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
37
+ uint32_t opr_sz, uint32_t max_sz);
38
+void gen_gvec_cle0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
39
+ uint32_t opr_sz, uint32_t max_sz);
40
+void gen_gvec_cge0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
41
+ uint32_t opr_sz, uint32_t max_sz);
42
+
43
extern const GVecGen3 mla_op[4];
44
extern const GVecGen3 mls_op[4];
45
extern const GVecGen3 cmtst_op[4];
46
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate-a64.c
49
+++ b/target/arm/translate-a64.c
50
@@ -XXX,XX +XXX,XX @@ static void gen_gvec_fn4(DisasContext *s, bool is_q, int rd, int rn, int rm,
51
is_q ? 16 : 8, vec_full_reg_size(s));
52
}
53
54
-/* Expand a 2-operand AdvSIMD vector operation using an op descriptor. */
55
-static void gen_gvec_op2(DisasContext *s, bool is_q, int rd,
56
- int rn, const GVecGen2 *gvec_op)
57
-{
58
- tcg_gen_gvec_2(vec_full_reg_offset(s, rd), vec_full_reg_offset(s, rn),
59
- is_q ? 16 : 8, vec_full_reg_size(s), gvec_op);
60
-}
61
-
62
/* Expand a 3-operand AdvSIMD vector operation using an op descriptor. */
63
static void gen_gvec_op3(DisasContext *s, bool is_q, int rd,
64
int rn, int rm, const GVecGen3 *gvec_op)
65
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
66
}
67
break;
68
case 0x8: /* CMGT, CMGE */
69
- gen_gvec_op2(s, is_q, rd, rn, u ? &cge0_op[size] : &cgt0_op[size]);
70
+ if (u) {
71
+ gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cge0, size);
72
+ } else {
73
+ gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cgt0, size);
74
+ }
75
return;
76
case 0x9: /* CMEQ, CMLE */
77
- gen_gvec_op2(s, is_q, rd, rn, u ? &cle0_op[size] : &ceq0_op[size]);
78
+ if (u) {
79
+ gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_cle0, size);
80
+ } else {
81
+ gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_ceq0, size);
82
+ }
83
return;
84
case 0xa: /* CMLT */
85
- gen_gvec_op2(s, is_q, rd, rn, &clt0_op[size]);
86
+ gen_gvec_fn2(s, is_q, rd, rn, gen_gvec_clt0, size);
87
return;
88
case 0xb:
89
if (u) { /* ABS, NEG */
90
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
91
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/translate.c
19
--- a/target/arm/translate.c
93
+++ b/target/arm/translate.c
20
+++ b/target/arm/translate.c
94
@@ -XXX,XX +XXX,XX @@ static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
21
@@ -XXX,XX +XXX,XX @@ static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
95
return 1;
22
dc->insn_start = tcg_last_op();
96
}
23
}
97
24
98
-static void gen_ceq0_i32(TCGv_i32 d, TCGv_i32 a)
25
-static bool arm_pre_translate_insn(DisasContext *dc)
99
-{
26
+static bool arm_check_kernelpage(DisasContext *dc)
100
- tcg_gen_setcondi_i32(TCG_COND_EQ, d, a, 0);
101
- tcg_gen_neg_i32(d, d);
102
-}
103
-
104
-static void gen_ceq0_i64(TCGv_i64 d, TCGv_i64 a)
105
-{
106
- tcg_gen_setcondi_i64(TCG_COND_EQ, d, a, 0);
107
- tcg_gen_neg_i64(d, d);
108
-}
109
-
110
-static void gen_ceq0_vec(unsigned vece, TCGv_vec d, TCGv_vec a)
111
-{
112
- TCGv_vec zero = tcg_const_zeros_vec_matching(d);
113
- tcg_gen_cmp_vec(TCG_COND_EQ, vece, d, a, zero);
114
- tcg_temp_free_vec(zero);
115
-}
116
+#define GEN_CMP0(NAME, COND) \
117
+ static void gen_##NAME##0_i32(TCGv_i32 d, TCGv_i32 a) \
118
+ { \
119
+ tcg_gen_setcondi_i32(COND, d, a, 0); \
120
+ tcg_gen_neg_i32(d, d); \
121
+ } \
122
+ static void gen_##NAME##0_i64(TCGv_i64 d, TCGv_i64 a) \
123
+ { \
124
+ tcg_gen_setcondi_i64(COND, d, a, 0); \
125
+ tcg_gen_neg_i64(d, d); \
126
+ } \
127
+ static void gen_##NAME##0_vec(unsigned vece, TCGv_vec d, TCGv_vec a) \
128
+ { \
129
+ TCGv_vec zero = tcg_const_zeros_vec_matching(d); \
130
+ tcg_gen_cmp_vec(COND, vece, d, a, zero); \
131
+ tcg_temp_free_vec(zero); \
132
+ } \
133
+ void gen_gvec_##NAME##0(unsigned vece, uint32_t d, uint32_t m, \
134
+ uint32_t opr_sz, uint32_t max_sz) \
135
+ { \
136
+ const GVecGen2 op[4] = { \
137
+ { .fno = gen_helper_gvec_##NAME##0_b, \
138
+ .fniv = gen_##NAME##0_vec, \
139
+ .opt_opc = vecop_list_cmp, \
140
+ .vece = MO_8 }, \
141
+ { .fno = gen_helper_gvec_##NAME##0_h, \
142
+ .fniv = gen_##NAME##0_vec, \
143
+ .opt_opc = vecop_list_cmp, \
144
+ .vece = MO_16 }, \
145
+ { .fni4 = gen_##NAME##0_i32, \
146
+ .fniv = gen_##NAME##0_vec, \
147
+ .opt_opc = vecop_list_cmp, \
148
+ .vece = MO_32 }, \
149
+ { .fni8 = gen_##NAME##0_i64, \
150
+ .fniv = gen_##NAME##0_vec, \
151
+ .opt_opc = vecop_list_cmp, \
152
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64, \
153
+ .vece = MO_64 }, \
154
+ }; \
155
+ tcg_gen_gvec_2(d, m, opr_sz, max_sz, &op[vece]); \
156
+ }
157
158
static const TCGOpcode vecop_list_cmp[] = {
159
INDEX_op_cmp_vec, 0
160
};
161
162
-const GVecGen2 ceq0_op[4] = {
163
- { .fno = gen_helper_gvec_ceq0_b,
164
- .fniv = gen_ceq0_vec,
165
- .opt_opc = vecop_list_cmp,
166
- .vece = MO_8 },
167
- { .fno = gen_helper_gvec_ceq0_h,
168
- .fniv = gen_ceq0_vec,
169
- .opt_opc = vecop_list_cmp,
170
- .vece = MO_16 },
171
- { .fni4 = gen_ceq0_i32,
172
- .fniv = gen_ceq0_vec,
173
- .opt_opc = vecop_list_cmp,
174
- .vece = MO_32 },
175
- { .fni8 = gen_ceq0_i64,
176
- .fniv = gen_ceq0_vec,
177
- .opt_opc = vecop_list_cmp,
178
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
179
- .vece = MO_64 },
180
-};
181
+GEN_CMP0(ceq, TCG_COND_EQ)
182
+GEN_CMP0(cle, TCG_COND_LE)
183
+GEN_CMP0(cge, TCG_COND_GE)
184
+GEN_CMP0(clt, TCG_COND_LT)
185
+GEN_CMP0(cgt, TCG_COND_GT)
186
187
-static void gen_cle0_i32(TCGv_i32 d, TCGv_i32 a)
188
-{
189
- tcg_gen_setcondi_i32(TCG_COND_LE, d, a, 0);
190
- tcg_gen_neg_i32(d, d);
191
-}
192
-
193
-static void gen_cle0_i64(TCGv_i64 d, TCGv_i64 a)
194
-{
195
- tcg_gen_setcondi_i64(TCG_COND_LE, d, a, 0);
196
- tcg_gen_neg_i64(d, d);
197
-}
198
-
199
-static void gen_cle0_vec(unsigned vece, TCGv_vec d, TCGv_vec a)
200
-{
201
- TCGv_vec zero = tcg_const_zeros_vec_matching(d);
202
- tcg_gen_cmp_vec(TCG_COND_LE, vece, d, a, zero);
203
- tcg_temp_free_vec(zero);
204
-}
205
-
206
-const GVecGen2 cle0_op[4] = {
207
- { .fno = gen_helper_gvec_cle0_b,
208
- .fniv = gen_cle0_vec,
209
- .opt_opc = vecop_list_cmp,
210
- .vece = MO_8 },
211
- { .fno = gen_helper_gvec_cle0_h,
212
- .fniv = gen_cle0_vec,
213
- .opt_opc = vecop_list_cmp,
214
- .vece = MO_16 },
215
- { .fni4 = gen_cle0_i32,
216
- .fniv = gen_cle0_vec,
217
- .opt_opc = vecop_list_cmp,
218
- .vece = MO_32 },
219
- { .fni8 = gen_cle0_i64,
220
- .fniv = gen_cle0_vec,
221
- .opt_opc = vecop_list_cmp,
222
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
223
- .vece = MO_64 },
224
-};
225
-
226
-static void gen_cge0_i32(TCGv_i32 d, TCGv_i32 a)
227
-{
228
- tcg_gen_setcondi_i32(TCG_COND_GE, d, a, 0);
229
- tcg_gen_neg_i32(d, d);
230
-}
231
-
232
-static void gen_cge0_i64(TCGv_i64 d, TCGv_i64 a)
233
-{
234
- tcg_gen_setcondi_i64(TCG_COND_GE, d, a, 0);
235
- tcg_gen_neg_i64(d, d);
236
-}
237
-
238
-static void gen_cge0_vec(unsigned vece, TCGv_vec d, TCGv_vec a)
239
-{
240
- TCGv_vec zero = tcg_const_zeros_vec_matching(d);
241
- tcg_gen_cmp_vec(TCG_COND_GE, vece, d, a, zero);
242
- tcg_temp_free_vec(zero);
243
-}
244
-
245
-const GVecGen2 cge0_op[4] = {
246
- { .fno = gen_helper_gvec_cge0_b,
247
- .fniv = gen_cge0_vec,
248
- .opt_opc = vecop_list_cmp,
249
- .vece = MO_8 },
250
- { .fno = gen_helper_gvec_cge0_h,
251
- .fniv = gen_cge0_vec,
252
- .opt_opc = vecop_list_cmp,
253
- .vece = MO_16 },
254
- { .fni4 = gen_cge0_i32,
255
- .fniv = gen_cge0_vec,
256
- .opt_opc = vecop_list_cmp,
257
- .vece = MO_32 },
258
- { .fni8 = gen_cge0_i64,
259
- .fniv = gen_cge0_vec,
260
- .opt_opc = vecop_list_cmp,
261
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
262
- .vece = MO_64 },
263
-};
264
-
265
-static void gen_clt0_i32(TCGv_i32 d, TCGv_i32 a)
266
-{
267
- tcg_gen_setcondi_i32(TCG_COND_LT, d, a, 0);
268
- tcg_gen_neg_i32(d, d);
269
-}
270
-
271
-static void gen_clt0_i64(TCGv_i64 d, TCGv_i64 a)
272
-{
273
- tcg_gen_setcondi_i64(TCG_COND_LT, d, a, 0);
274
- tcg_gen_neg_i64(d, d);
275
-}
276
-
277
-static void gen_clt0_vec(unsigned vece, TCGv_vec d, TCGv_vec a)
278
-{
279
- TCGv_vec zero = tcg_const_zeros_vec_matching(d);
280
- tcg_gen_cmp_vec(TCG_COND_LT, vece, d, a, zero);
281
- tcg_temp_free_vec(zero);
282
-}
283
-
284
-const GVecGen2 clt0_op[4] = {
285
- { .fno = gen_helper_gvec_clt0_b,
286
- .fniv = gen_clt0_vec,
287
- .opt_opc = vecop_list_cmp,
288
- .vece = MO_8 },
289
- { .fno = gen_helper_gvec_clt0_h,
290
- .fniv = gen_clt0_vec,
291
- .opt_opc = vecop_list_cmp,
292
- .vece = MO_16 },
293
- { .fni4 = gen_clt0_i32,
294
- .fniv = gen_clt0_vec,
295
- .opt_opc = vecop_list_cmp,
296
- .vece = MO_32 },
297
- { .fni8 = gen_clt0_i64,
298
- .fniv = gen_clt0_vec,
299
- .opt_opc = vecop_list_cmp,
300
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
301
- .vece = MO_64 },
302
-};
303
-
304
-static void gen_cgt0_i32(TCGv_i32 d, TCGv_i32 a)
305
-{
306
- tcg_gen_setcondi_i32(TCG_COND_GT, d, a, 0);
307
- tcg_gen_neg_i32(d, d);
308
-}
309
-
310
-static void gen_cgt0_i64(TCGv_i64 d, TCGv_i64 a)
311
-{
312
- tcg_gen_setcondi_i64(TCG_COND_GT, d, a, 0);
313
- tcg_gen_neg_i64(d, d);
314
-}
315
-
316
-static void gen_cgt0_vec(unsigned vece, TCGv_vec d, TCGv_vec a)
317
-{
318
- TCGv_vec zero = tcg_const_zeros_vec_matching(d);
319
- tcg_gen_cmp_vec(TCG_COND_GT, vece, d, a, zero);
320
- tcg_temp_free_vec(zero);
321
-}
322
-
323
-const GVecGen2 cgt0_op[4] = {
324
- { .fno = gen_helper_gvec_cgt0_b,
325
- .fniv = gen_cgt0_vec,
326
- .opt_opc = vecop_list_cmp,
327
- .vece = MO_8 },
328
- { .fno = gen_helper_gvec_cgt0_h,
329
- .fniv = gen_cgt0_vec,
330
- .opt_opc = vecop_list_cmp,
331
- .vece = MO_16 },
332
- { .fni4 = gen_cgt0_i32,
333
- .fniv = gen_cgt0_vec,
334
- .opt_opc = vecop_list_cmp,
335
- .vece = MO_32 },
336
- { .fni8 = gen_cgt0_i64,
337
- .fniv = gen_cgt0_vec,
338
- .opt_opc = vecop_list_cmp,
339
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
340
- .vece = MO_64 },
341
-};
342
+#undef GEN_CMP0
343
344
static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
345
{
27
{
346
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
28
#ifdef CONFIG_USER_ONLY
347
break;
29
/* Intercept jump to the magic kernel page. */
348
30
@@ -XXX,XX +XXX,XX @@ static bool arm_pre_translate_insn(DisasContext *dc)
349
case NEON_2RM_VCEQ0:
31
return true;
350
- tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
32
}
351
- vec_size, &ceq0_op[size]);
33
#endif
352
+ gen_gvec_ceq0(size, rd_ofs, rm_ofs, vec_size, vec_size);
34
+ return false;
353
break;
35
+}
354
case NEON_2RM_VCGT0:
36
355
- tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
37
+static bool arm_check_ss_active(DisasContext *dc)
356
- vec_size, &cgt0_op[size]);
38
+{
357
+ gen_gvec_cgt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
39
if (dc->ss_active && !dc->pstate_ss) {
358
break;
40
/* Singlestep state is Active-pending.
359
case NEON_2RM_VCLE0:
41
* If we're in this state at the start of a TB then either
360
- tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
42
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
361
- vec_size, &cle0_op[size]);
43
uint32_t pc = dc->base.pc_next;
362
+ gen_gvec_cle0(size, rd_ofs, rm_ofs, vec_size, vec_size);
44
unsigned int insn;
363
break;
45
364
case NEON_2RM_VCGE0:
46
- if (arm_pre_translate_insn(dc)) {
365
- tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
47
+ if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
366
- vec_size, &cge0_op[size]);
48
dc->base.pc_next = pc + 4;
367
+ gen_gvec_cge0(size, rd_ofs, rm_ofs, vec_size, vec_size);
49
return;
368
break;
50
}
369
case NEON_2RM_VCLT0:
51
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
370
- tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
52
uint32_t insn;
371
- vec_size, &clt0_op[size]);
53
bool is_16bit;
372
+ gen_gvec_clt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
54
373
break;
55
- if (arm_pre_translate_insn(dc)) {
374
56
+ if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
375
default:
57
dc->base.pc_next = pc + 2;
58
return;
59
}
376
--
60
--
377
2.20.1
61
2.25.1
378
62
379
63
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Provide a functional interface for the vector expansion.
3
The size of the code covered by a TranslationBlock cannot be 0;
4
This fits better with the existing set of helpers that
4
this is checked via assert in tb_gen_code.
5
we provide for other operations.
6
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200513163245.17915-13-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
target/arm/translate.h | 5 ++++
10
target/arm/translate-a64.c | 1 +
13
target/arm/translate-a64.c | 34 ++----------------------
11
1 file changed, 1 insertion(+)
14
target/arm/translate.c | 54 +++++++++++++++++++-------------------
15
3 files changed, 34 insertions(+), 59 deletions(-)
16
12
17
diff --git a/target/arm/translate.h b/target/arm/translate.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate.h
20
+++ b/target/arm/translate.h
21
@@ -XXX,XX +XXX,XX @@ void gen_gvec_sri(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
22
void gen_gvec_sli(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
23
int64_t shift, uint32_t opr_sz, uint32_t max_sz);
24
25
+void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
26
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
27
+void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
28
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
29
+
30
/*
31
* Forward to the isar_feature_* tests given a DisasContext pointer.
32
*/
33
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
34
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-a64.c
15
--- a/target/arm/translate-a64.c
36
+++ b/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
37
@@ -XXX,XX +XXX,XX @@ static void gen_gvec_op3_ool(DisasContext *s, bool is_q, int rd,
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
38
is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
18
assert(s->base.num_insns == 1);
39
}
19
gen_swstep_exception(s, 0, 0);
40
20
s->base.is_jmp = DISAS_NORETURN;
41
-/* Expand a 3-operand + env pointer operation using
21
+ s->base.pc_next = pc + 4;
42
- * an out-of-line helper.
43
- */
44
-static void gen_gvec_op3_env(DisasContext *s, bool is_q, int rd,
45
- int rn, int rm, gen_helper_gvec_3_ptr *fn)
46
-{
47
- tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
48
- vec_full_reg_offset(s, rn),
49
- vec_full_reg_offset(s, rm), cpu_env,
50
- is_q ? 16 : 8, vec_full_reg_size(s), 0, fn);
51
-}
52
-
53
/* Expand a 3-operand + fpstatus pointer + simd data value operation using
54
* an out-of-line helper.
55
*/
56
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
57
58
switch (opcode) {
59
case 0x0: /* SQRDMLAH (vector) */
60
- switch (size) {
61
- case 1:
62
- gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlah_s16);
63
- break;
64
- case 2:
65
- gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlah_s32);
66
- break;
67
- default:
68
- g_assert_not_reached();
69
- }
70
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqrdmlah_qc, size);
71
return;
22
return;
72
23
}
73
case 0x1: /* SQRDMLSH (vector) */
74
- switch (size) {
75
- case 1:
76
- gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlsh_s16);
77
- break;
78
- case 2:
79
- gen_gvec_op3_env(s, is_q, rd, rn, rm, gen_helper_gvec_qrdmlsh_s32);
80
- break;
81
- default:
82
- g_assert_not_reached();
83
- }
84
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqrdmlsh_qc, size);
85
return;
86
87
case 0x2: /* SDOT / UDOT */
88
diff --git a/target/arm/translate.c b/target/arm/translate.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/translate.c
91
+++ b/target/arm/translate.c
92
@@ -XXX,XX +XXX,XX @@ static const uint8_t neon_2rm_sizes[] = {
93
[NEON_2RM_VCVT_UF] = 0x4,
94
};
95
96
-
97
-/* Expand v8.1 simd helper. */
98
-static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
99
- int q, int rd, int rn, int rm)
100
+void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
101
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
102
{
103
- if (dc_isar_feature(aa32_rdm, s)) {
104
- int opr_sz = (1 + q) * 8;
105
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
106
- vfp_reg_offset(1, rn),
107
- vfp_reg_offset(1, rm), cpu_env,
108
- opr_sz, opr_sz, 0, fn);
109
- return 0;
110
- }
111
- return 1;
112
+ static gen_helper_gvec_3_ptr * const fns[2] = {
113
+ gen_helper_gvec_qrdmlah_s16, gen_helper_gvec_qrdmlah_s32
114
+ };
115
+ tcg_debug_assert(vece >= 1 && vece <= 2);
116
+ tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, cpu_env,
117
+ opr_sz, max_sz, 0, fns[vece - 1]);
118
+}
119
+
120
+void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
121
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
122
+{
123
+ static gen_helper_gvec_3_ptr * const fns[2] = {
124
+ gen_helper_gvec_qrdmlsh_s16, gen_helper_gvec_qrdmlsh_s32
125
+ };
126
+ tcg_debug_assert(vece >= 1 && vece <= 2);
127
+ tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, cpu_env,
128
+ opr_sz, max_sz, 0, fns[vece - 1]);
129
}
130
131
#define GEN_CMP0(NAME, COND) \
132
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
133
break; /* VPADD */
134
}
135
/* VQRDMLAH */
136
- switch (size) {
137
- case 1:
138
- return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
139
- q, rd, rn, rm);
140
- case 2:
141
- return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
142
- q, rd, rn, rm);
143
+ if (dc_isar_feature(aa32_rdm, s) && (size == 1 || size == 2)) {
144
+ gen_gvec_sqrdmlah_qc(size, rd_ofs, rn_ofs, rm_ofs,
145
+ vec_size, vec_size);
146
+ return 0;
147
}
148
return 1;
149
150
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
151
break;
152
}
153
/* VQRDMLSH */
154
- switch (size) {
155
- case 1:
156
- return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
157
- q, rd, rn, rm);
158
- case 2:
159
- return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
160
- q, rd, rn, rm);
161
+ if (dc_isar_feature(aa32_rdm, s) && (size == 1 || size == 2)) {
162
+ gen_gvec_sqrdmlsh_qc(size, rd_ofs, rn_ofs, rm_ofs,
163
+ vec_size, vec_size);
164
+ return 0;
165
}
166
return 1;
167
24
168
--
25
--
169
2.20.1
26
2.25.1
170
27
171
28
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Include 64-bit element size in preparation for SVE2.
3
We will reuse this section of arm_deliver_fault for
4
raising pc alignment faults.
4
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200513163245.17915-16-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
9
---
10
target/arm/helper.h | 10 +++
10
target/arm/tlb_helper.c | 45 +++++++++++++++++++++++++----------------
11
target/arm/translate.h | 5 ++
11
1 file changed, 28 insertions(+), 17 deletions(-)
12
target/arm/translate-a64.c | 8 ++-
13
target/arm/translate.c | 133 ++++++++++++++++++++++++++++++++++++-
14
target/arm/vec_helper.c | 24 +++++++
15
5 files changed, 176 insertions(+), 4 deletions(-)
16
12
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
13
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.h
15
--- a/target/arm/tlb_helper.c
20
+++ b/target/arm/helper.h
16
+++ b/target/arm/tlb_helper.c
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(gvec_sli_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
17
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
22
DEF_HELPER_FLAGS_3(gvec_sli_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
18
return syn;
23
DEF_HELPER_FLAGS_3(gvec_sli_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
24
25
+DEF_HELPER_FLAGS_4(gvec_sabd_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(gvec_sabd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(gvec_sabd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(gvec_sabd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
+
30
+DEF_HELPER_FLAGS_4(gvec_uabd_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(gvec_uabd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(gvec_uabd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_4(gvec_uabd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
+
35
#ifdef TARGET_AARCH64
36
#include "helper-a64.h"
37
#include "helper-sve.h"
38
diff --git a/target/arm/translate.h b/target/arm/translate.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/translate.h
41
+++ b/target/arm/translate.h
42
@@ -XXX,XX +XXX,XX @@ void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
43
void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
44
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
45
46
+void gen_gvec_sabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
47
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
48
+void gen_gvec_uabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
49
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
50
+
51
/*
52
* Forward to the isar_feature_* tests given a DisasContext pointer.
53
*/
54
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/translate-a64.c
57
+++ b/target/arm/translate-a64.c
58
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
59
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_smin, size);
60
}
61
return;
62
+ case 0xe: /* SABD, UABD */
63
+ if (u) {
64
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uabd, size);
65
+ } else {
66
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sabd, size);
67
+ }
68
+ return;
69
case 0x10: /* ADD, SUB */
70
if (u) {
71
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_sub, size);
72
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
73
genenvfn = fns[size][u];
74
break;
75
}
76
- case 0xe: /* SABD, UABD */
77
case 0xf: /* SABA, UABA */
78
{
79
static NeonGenTwoOpFn * const fns[3][2] = {
80
diff --git a/target/arm/translate.c b/target/arm/translate.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/translate.c
83
+++ b/target/arm/translate.c
84
@@ -XXX,XX +XXX,XX @@ void gen_gvec_sqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
85
rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
86
}
19
}
87
20
88
+static void gen_sabd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
21
-static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
89
+{
22
- MMUAccessType access_type,
90
+ TCGv_i32 t = tcg_temp_new_i32();
23
- int mmu_idx, ARMMMUFaultInfo *fi)
91
+
24
+static uint32_t compute_fsr_fsc(CPUARMState *env, ARMMMUFaultInfo *fi,
92
+ tcg_gen_sub_i32(t, a, b);
25
+ int target_el, int mmu_idx, uint32_t *ret_fsc)
93
+ tcg_gen_sub_i32(d, b, a);
26
{
94
+ tcg_gen_movcond_i32(TCG_COND_LT, d, a, b, d, t);
27
- CPUARMState *env = &cpu->env;
95
+ tcg_temp_free_i32(t);
28
- int target_el;
29
- bool same_el;
30
- uint32_t syn, exc, fsr, fsc;
31
ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
32
-
33
- target_el = exception_target_el(env);
34
- if (fi->stage2) {
35
- target_el = 2;
36
- env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
37
- if (arm_is_secure_below_el3(env) && fi->s1ns) {
38
- env->cp15.hpfar_el2 |= HPFAR_NS;
39
- }
40
- }
41
- same_el = (arm_current_el(env) == target_el);
42
+ uint32_t fsr, fsc;
43
44
if (target_el == 2 || arm_el_is_aa64(env, target_el) ||
45
arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
46
@@ -XXX,XX +XXX,XX @@ static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
47
fsc = 0x3f;
48
}
49
50
+ *ret_fsc = fsc;
51
+ return fsr;
96
+}
52
+}
97
+
53
+
98
+static void gen_sabd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
54
+static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
55
+ MMUAccessType access_type,
56
+ int mmu_idx, ARMMMUFaultInfo *fi)
99
+{
57
+{
100
+ TCGv_i64 t = tcg_temp_new_i64();
58
+ CPUARMState *env = &cpu->env;
59
+ int target_el;
60
+ bool same_el;
61
+ uint32_t syn, exc, fsr, fsc;
101
+
62
+
102
+ tcg_gen_sub_i64(t, a, b);
63
+ target_el = exception_target_el(env);
103
+ tcg_gen_sub_i64(d, b, a);
64
+ if (fi->stage2) {
104
+ tcg_gen_movcond_i64(TCG_COND_LT, d, a, b, d, t);
65
+ target_el = 2;
105
+ tcg_temp_free_i64(t);
66
+ env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
106
+}
67
+ if (arm_is_secure_below_el3(env) && fi->s1ns) {
68
+ env->cp15.hpfar_el2 |= HPFAR_NS;
69
+ }
70
+ }
71
+ same_el = (arm_current_el(env) == target_el);
107
+
72
+
108
+static void gen_sabd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
73
+ fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc);
109
+{
110
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
111
+
74
+
112
+ tcg_gen_smin_vec(vece, t, a, b);
75
if (access_type == MMU_INST_FETCH) {
113
+ tcg_gen_smax_vec(vece, d, a, b);
76
syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc);
114
+ tcg_gen_sub_vec(vece, d, d, t);
77
exc = EXCP_PREFETCH_ABORT;
115
+ tcg_temp_free_vec(t);
116
+}
117
+
118
+void gen_gvec_sabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
119
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
120
+{
121
+ static const TCGOpcode vecop_list[] = {
122
+ INDEX_op_sub_vec, INDEX_op_smin_vec, INDEX_op_smax_vec, 0
123
+ };
124
+ static const GVecGen3 ops[4] = {
125
+ { .fniv = gen_sabd_vec,
126
+ .fno = gen_helper_gvec_sabd_b,
127
+ .opt_opc = vecop_list,
128
+ .vece = MO_8 },
129
+ { .fniv = gen_sabd_vec,
130
+ .fno = gen_helper_gvec_sabd_h,
131
+ .opt_opc = vecop_list,
132
+ .vece = MO_16 },
133
+ { .fni4 = gen_sabd_i32,
134
+ .fniv = gen_sabd_vec,
135
+ .fno = gen_helper_gvec_sabd_s,
136
+ .opt_opc = vecop_list,
137
+ .vece = MO_32 },
138
+ { .fni8 = gen_sabd_i64,
139
+ .fniv = gen_sabd_vec,
140
+ .fno = gen_helper_gvec_sabd_d,
141
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
142
+ .opt_opc = vecop_list,
143
+ .vece = MO_64 },
144
+ };
145
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
146
+}
147
+
148
+static void gen_uabd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
149
+{
150
+ TCGv_i32 t = tcg_temp_new_i32();
151
+
152
+ tcg_gen_sub_i32(t, a, b);
153
+ tcg_gen_sub_i32(d, b, a);
154
+ tcg_gen_movcond_i32(TCG_COND_LTU, d, a, b, d, t);
155
+ tcg_temp_free_i32(t);
156
+}
157
+
158
+static void gen_uabd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
159
+{
160
+ TCGv_i64 t = tcg_temp_new_i64();
161
+
162
+ tcg_gen_sub_i64(t, a, b);
163
+ tcg_gen_sub_i64(d, b, a);
164
+ tcg_gen_movcond_i64(TCG_COND_LTU, d, a, b, d, t);
165
+ tcg_temp_free_i64(t);
166
+}
167
+
168
+static void gen_uabd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
169
+{
170
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
171
+
172
+ tcg_gen_umin_vec(vece, t, a, b);
173
+ tcg_gen_umax_vec(vece, d, a, b);
174
+ tcg_gen_sub_vec(vece, d, d, t);
175
+ tcg_temp_free_vec(t);
176
+}
177
+
178
+void gen_gvec_uabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
179
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
180
+{
181
+ static const TCGOpcode vecop_list[] = {
182
+ INDEX_op_sub_vec, INDEX_op_umin_vec, INDEX_op_umax_vec, 0
183
+ };
184
+ static const GVecGen3 ops[4] = {
185
+ { .fniv = gen_uabd_vec,
186
+ .fno = gen_helper_gvec_uabd_b,
187
+ .opt_opc = vecop_list,
188
+ .vece = MO_8 },
189
+ { .fniv = gen_uabd_vec,
190
+ .fno = gen_helper_gvec_uabd_h,
191
+ .opt_opc = vecop_list,
192
+ .vece = MO_16 },
193
+ { .fni4 = gen_uabd_i32,
194
+ .fniv = gen_uabd_vec,
195
+ .fno = gen_helper_gvec_uabd_s,
196
+ .opt_opc = vecop_list,
197
+ .vece = MO_32 },
198
+ { .fni8 = gen_uabd_i64,
199
+ .fniv = gen_uabd_vec,
200
+ .fno = gen_helper_gvec_uabd_d,
201
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
202
+ .opt_opc = vecop_list,
203
+ .vece = MO_64 },
204
+ };
205
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
206
+}
207
+
208
/* Translate a NEON data processing instruction. Return nonzero if the
209
instruction is invalid.
210
We process data in a mixture of 32-bit and 64-bit chunks.
211
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
212
}
213
return 1;
214
215
+ case NEON_3R_VABD:
216
+ if (u) {
217
+ gen_gvec_uabd(size, rd_ofs, rn_ofs, rm_ofs,
218
+ vec_size, vec_size);
219
+ } else {
220
+ gen_gvec_sabd(size, rd_ofs, rn_ofs, rm_ofs,
221
+ vec_size, vec_size);
222
+ }
223
+ return 0;
224
+
225
case NEON_3R_VADD_VSUB:
226
case NEON_3R_LOGIC:
227
case NEON_3R_VMAX:
228
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
229
case NEON_3R_VQRSHL:
230
GEN_NEON_INTEGER_OP_ENV(qrshl);
231
break;
232
- case NEON_3R_VABD:
233
- GEN_NEON_INTEGER_OP(abd);
234
- break;
235
case NEON_3R_VABA:
236
GEN_NEON_INTEGER_OP(abd);
237
tcg_temp_free_i32(tmp2);
238
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
239
index XXXXXXX..XXXXXXX 100644
240
--- a/target/arm/vec_helper.c
241
+++ b/target/arm/vec_helper.c
242
@@ -XXX,XX +XXX,XX @@ DO_CMP0(gvec_cgt0_h, int16_t, >)
243
DO_CMP0(gvec_cge0_h, int16_t, >=)
244
245
#undef DO_CMP0
246
+
247
+#define DO_ABD(NAME, TYPE) \
248
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
249
+{ \
250
+ intptr_t i, opr_sz = simd_oprsz(desc); \
251
+ TYPE *d = vd, *n = vn, *m = vm; \
252
+ \
253
+ for (i = 0; i < opr_sz / sizeof(TYPE); ++i) { \
254
+ d[i] = n[i] < m[i] ? m[i] - n[i] : n[i] - m[i]; \
255
+ } \
256
+ clear_tail(d, opr_sz, simd_maxsz(desc)); \
257
+}
258
+
259
+DO_ABD(gvec_sabd_b, int8_t)
260
+DO_ABD(gvec_sabd_h, int16_t)
261
+DO_ABD(gvec_sabd_s, int32_t)
262
+DO_ABD(gvec_sabd_d, int64_t)
263
+
264
+DO_ABD(gvec_uabd_b, uint8_t)
265
+DO_ABD(gvec_uabd_h, uint16_t)
266
+DO_ABD(gvec_uabd_s, uint32_t)
267
+DO_ABD(gvec_uabd_d, uint64_t)
268
+
269
+#undef DO_ABD
270
--
78
--
271
2.20.1
79
2.25.1
272
80
273
81
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Include 64-bit element size in preparation for SVE2.
3
For A64, any input to an indirect branch can cause this.
4
4
5
For A32, many indirect branch paths force the branch to be aligned,
6
but BXWritePC does not. This includes the BX instruction but also
7
other interworking changes to PC. Prior to v8, this case is UNDEFINED.
8
With v8, this is CONSTRAINED UNPREDICTABLE and may either raise an
9
exception or force align the PC.
10
11
We choose to raise an exception because we have the infrastructure,
12
it makes the generated code for gen_bx simpler, and it has the
13
possibility of catching more guest bugs.
14
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200513163245.17915-17-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
18
---
10
target/arm/helper.h | 17 +++--
19
target/arm/helper.h | 1 +
11
target/arm/translate.h | 5 ++
20
target/arm/syndrome.h | 5 ++++
12
target/arm/neon_helper.c | 10 ---
21
linux-user/aarch64/cpu_loop.c | 46 ++++++++++++++++++++---------------
13
target/arm/translate-a64.c | 17 ++---
22
target/arm/tlb_helper.c | 18 ++++++++++++++
14
target/arm/translate.c | 134 +++++++++++++++++++++++++++++++++++--
23
target/arm/translate-a64.c | 15 ++++++++++++
15
target/arm/vec_helper.c | 24 +++++++
24
target/arm/translate.c | 22 ++++++++++++++++-
16
6 files changed, 174 insertions(+), 33 deletions(-)
25
6 files changed, 87 insertions(+), 20 deletions(-)
17
26
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
27
diff --git a/target/arm/helper.h b/target/arm/helper.h
19
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.h
29
--- a/target/arm/helper.h
21
+++ b/target/arm/helper.h
30
+++ b/target/arm/helper.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_pmax_s8, i32, i32, i32)
31
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_NO_RWG_SE,
23
DEF_HELPER_2(neon_pmax_u16, i32, i32, i32)
32
DEF_HELPER_2(exception_internal, void, env, i32)
24
DEF_HELPER_2(neon_pmax_s16, i32, i32, i32)
33
DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32)
25
34
DEF_HELPER_2(exception_bkpt_insn, void, env, i32)
26
-DEF_HELPER_2(neon_abd_u8, i32, i32, i32)
35
+DEF_HELPER_2(exception_pc_alignment, noreturn, env, tl)
27
-DEF_HELPER_2(neon_abd_s8, i32, i32, i32)
36
DEF_HELPER_1(setend, void, env)
28
-DEF_HELPER_2(neon_abd_u16, i32, i32, i32)
37
DEF_HELPER_2(wfi, void, env, i32)
29
-DEF_HELPER_2(neon_abd_s16, i32, i32, i32)
38
DEF_HELPER_1(wfe, void, env)
30
-DEF_HELPER_2(neon_abd_u32, i32, i32, i32)
39
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
31
-DEF_HELPER_2(neon_abd_s32, i32, i32, i32)
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/syndrome.h
42
+++ b/target/arm/syndrome.h
43
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_illegalstate(void)
44
return (EC_ILLEGALSTATE << ARM_EL_EC_SHIFT) | ARM_EL_IL;
45
}
46
47
+static inline uint32_t syn_pcalignment(void)
48
+{
49
+ return (EC_PCALIGNMENT << ARM_EL_EC_SHIFT) | ARM_EL_IL;
50
+}
51
+
52
#endif /* TARGET_ARM_SYNDROME_H */
53
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/linux-user/aarch64/cpu_loop.c
56
+++ b/linux-user/aarch64/cpu_loop.c
57
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
58
break;
59
case EXCP_PREFETCH_ABORT:
60
case EXCP_DATA_ABORT:
61
- /* We should only arrive here with EC in {DATAABORT, INSNABORT}. */
62
ec = syn_get_ec(env->exception.syndrome);
63
- assert(ec == EC_DATAABORT || ec == EC_INSNABORT);
32
-
64
-
33
DEF_HELPER_2(neon_shl_u16, i32, i32, i32)
65
- /* Both EC have the same format for FSC, or close enough. */
34
DEF_HELPER_2(neon_shl_s16, i32, i32, i32)
66
- fsc = extract32(env->exception.syndrome, 0, 6);
35
DEF_HELPER_2(neon_rshl_u8, i32, i32, i32)
67
- switch (fsc) {
36
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_uabd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
68
- case 0x04 ... 0x07: /* Translation fault, level {0-3} */
37
DEF_HELPER_FLAGS_4(gvec_uabd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
69
- si_signo = TARGET_SIGSEGV;
38
DEF_HELPER_FLAGS_4(gvec_uabd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
70
- si_code = TARGET_SEGV_MAPERR;
39
71
+ switch (ec) {
40
+DEF_HELPER_FLAGS_4(gvec_saba_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
72
+ case EC_DATAABORT:
41
+DEF_HELPER_FLAGS_4(gvec_saba_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
73
+ case EC_INSNABORT:
42
+DEF_HELPER_FLAGS_4(gvec_saba_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
74
+ /* Both EC have the same format for FSC, or close enough. */
43
+DEF_HELPER_FLAGS_4(gvec_saba_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
75
+ fsc = extract32(env->exception.syndrome, 0, 6);
44
+
76
+ switch (fsc) {
45
+DEF_HELPER_FLAGS_4(gvec_uaba_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
77
+ case 0x04 ... 0x07: /* Translation fault, level {0-3} */
46
+DEF_HELPER_FLAGS_4(gvec_uaba_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
78
+ si_signo = TARGET_SIGSEGV;
47
+DEF_HELPER_FLAGS_4(gvec_uaba_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
79
+ si_code = TARGET_SEGV_MAPERR;
48
+DEF_HELPER_FLAGS_4(gvec_uaba_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
80
+ break;
49
+
81
+ case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
50
#ifdef TARGET_AARCH64
82
+ case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
51
#include "helper-a64.h"
83
+ si_signo = TARGET_SIGSEGV;
52
#include "helper-sve.h"
84
+ si_code = TARGET_SEGV_ACCERR;
53
diff --git a/target/arm/translate.h b/target/arm/translate.h
85
+ break;
54
index XXXXXXX..XXXXXXX 100644
86
+ case 0x11: /* Synchronous Tag Check Fault */
55
--- a/target/arm/translate.h
87
+ si_signo = TARGET_SIGSEGV;
56
+++ b/target/arm/translate.h
88
+ si_code = TARGET_SEGV_MTESERR;
57
@@ -XXX,XX +XXX,XX @@ void gen_gvec_sabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
89
+ break;
58
void gen_gvec_uabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
90
+ case 0x21: /* Alignment fault */
59
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
91
+ si_signo = TARGET_SIGBUS;
60
92
+ si_code = TARGET_BUS_ADRALN;
61
+void gen_gvec_saba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
93
+ break;
62
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
94
+ default:
63
+void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
95
+ g_assert_not_reached();
64
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
96
+ }
65
+
97
break;
98
- case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
99
- case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
100
- si_signo = TARGET_SIGSEGV;
101
- si_code = TARGET_SEGV_ACCERR;
102
- break;
103
- case 0x11: /* Synchronous Tag Check Fault */
104
- si_signo = TARGET_SIGSEGV;
105
- si_code = TARGET_SEGV_MTESERR;
106
- break;
107
- case 0x21: /* Alignment fault */
108
+ case EC_PCALIGNMENT:
109
si_signo = TARGET_SIGBUS;
110
si_code = TARGET_BUS_ADRALN;
111
break;
112
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/tlb_helper.c
115
+++ b/target/arm/tlb_helper.c
116
@@ -XXX,XX +XXX,XX @@
117
#include "cpu.h"
118
#include "internals.h"
119
#include "exec/exec-all.h"
120
+#include "exec/helper-proto.h"
121
122
static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
123
unsigned int target_el,
124
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
125
arm_deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi);
126
}
127
128
+void helper_exception_pc_alignment(CPUARMState *env, target_ulong pc)
129
+{
130
+ ARMMMUFaultInfo fi = { .type = ARMFault_Alignment };
131
+ int target_el = exception_target_el(env);
132
+ int mmu_idx = cpu_mmu_index(env, true);
133
+ uint32_t fsc;
134
+
135
+ env->exception.vaddress = pc;
136
+
137
+ /*
138
+ * Note that the fsc is not applicable to this exception,
139
+ * since any syndrome is pcalignment not insn_abort.
140
+ */
141
+ env->exception.fsr = compute_fsr_fsc(env, &fi, target_el, mmu_idx, &fsc);
142
+ raise_exception(env, EXCP_PREFETCH_ABORT, syn_pcalignment(), target_el);
143
+}
144
+
145
#if !defined(CONFIG_USER_ONLY)
146
66
/*
147
/*
67
* Forward to the isar_feature_* tests given a DisasContext pointer.
68
*/
69
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/neon_helper.c
72
+++ b/target/arm/neon_helper.c
73
@@ -XXX,XX +XXX,XX @@ NEON_POP(pmax_s16, neon_s16, 2)
74
NEON_POP(pmax_u16, neon_u16, 2)
75
#undef NEON_FN
76
77
-#define NEON_FN(dest, src1, src2) \
78
- dest = (src1 > src2) ? (src1 - src2) : (src2 - src1)
79
-NEON_VOP(abd_s8, neon_s8, 4)
80
-NEON_VOP(abd_u8, neon_u8, 4)
81
-NEON_VOP(abd_s16, neon_s16, 2)
82
-NEON_VOP(abd_u16, neon_u16, 2)
83
-NEON_VOP(abd_s32, neon_s32, 1)
84
-NEON_VOP(abd_u32, neon_u32, 1)
85
-#undef NEON_FN
86
-
87
#define NEON_FN(dest, src1, src2) do { \
88
int8_t tmp; \
89
tmp = (int8_t)src2; \
90
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
148
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
91
index XXXXXXX..XXXXXXX 100644
149
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/translate-a64.c
150
--- a/target/arm/translate-a64.c
93
+++ b/target/arm/translate-a64.c
151
+++ b/target/arm/translate-a64.c
94
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
152
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
95
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sabd, size);
153
uint64_t pc = s->base.pc_next;
96
}
154
uint32_t insn;
155
156
+ /* Singlestep exceptions have the highest priority. */
157
if (s->ss_active && !s->pstate_ss) {
158
/* Singlestep state is Active-pending.
159
* If we're in this state at the start of a TB then either
160
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
97
return;
161
return;
98
+ case 0xf: /* SABA, UABA */
162
}
99
+ if (u) {
163
100
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uaba, size);
164
+ if (pc & 3) {
101
+ } else {
165
+ /*
102
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_saba, size);
166
+ * PC alignment fault. This has priority over the instruction abort
103
+ }
167
+ * that we would receive from a translation fault via arm_ldl_code.
168
+ * This should only be possible after an indirect branch, at the
169
+ * start of the TB.
170
+ */
171
+ assert(s->base.num_insns == 1);
172
+ gen_helper_exception_pc_alignment(cpu_env, tcg_constant_tl(pc));
173
+ s->base.is_jmp = DISAS_NORETURN;
174
+ s->base.pc_next = QEMU_ALIGN_UP(pc, 4);
104
+ return;
175
+ return;
105
case 0x10: /* ADD, SUB */
176
+ }
106
if (u) {
177
+
107
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_sub, size);
178
s->pc_curr = pc;
108
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
179
insn = arm_ldl_code(env, &s->base, pc, s->sctlr_b);
109
genenvfn = fns[size][u];
180
s->insn = insn;
110
break;
111
}
112
- case 0xf: /* SABA, UABA */
113
- {
114
- static NeonGenTwoOpFn * const fns[3][2] = {
115
- { gen_helper_neon_abd_s8, gen_helper_neon_abd_u8 },
116
- { gen_helper_neon_abd_s16, gen_helper_neon_abd_u16 },
117
- { gen_helper_neon_abd_s32, gen_helper_neon_abd_u32 },
118
- };
119
- genfn = fns[size][u];
120
- break;
121
- }
122
case 0x16: /* SQDMULH, SQRDMULH */
123
{
124
static NeonGenTwoOpEnvFn * const fns[2][2] = {
125
diff --git a/target/arm/translate.c b/target/arm/translate.c
181
diff --git a/target/arm/translate.c b/target/arm/translate.c
126
index XXXXXXX..XXXXXXX 100644
182
index XXXXXXX..XXXXXXX 100644
127
--- a/target/arm/translate.c
183
--- a/target/arm/translate.c
128
+++ b/target/arm/translate.c
184
+++ b/target/arm/translate.c
129
@@ -XXX,XX +XXX,XX @@ void gen_gvec_uabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
185
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
130
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
186
uint32_t pc = dc->base.pc_next;
131
}
187
unsigned int insn;
132
188
133
+static void gen_saba_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
189
- if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
134
+{
190
+ /* Singlestep exceptions have the highest priority. */
135
+ TCGv_i32 t = tcg_temp_new_i32();
191
+ if (arm_check_ss_active(dc)) {
136
+ gen_sabd_i32(t, a, b);
192
+ dc->base.pc_next = pc + 4;
137
+ tcg_gen_add_i32(d, d, t);
193
+ return;
138
+ tcg_temp_free_i32(t);
194
+ }
139
+}
195
+
140
+
196
+ if (pc & 3) {
141
+static void gen_saba_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
197
+ /*
142
+{
198
+ * PC alignment fault. This has priority over the instruction abort
143
+ TCGv_i64 t = tcg_temp_new_i64();
199
+ * that we would receive from a translation fault via arm_ldl_code
144
+ gen_sabd_i64(t, a, b);
200
+ * (or the execution of the kernelpage entrypoint). This should only
145
+ tcg_gen_add_i64(d, d, t);
201
+ * be possible after an indirect branch, at the start of the TB.
146
+ tcg_temp_free_i64(t);
202
+ */
147
+}
203
+ assert(dc->base.num_insns == 1);
148
+
204
+ gen_helper_exception_pc_alignment(cpu_env, tcg_constant_tl(pc));
149
+static void gen_saba_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
205
+ dc->base.is_jmp = DISAS_NORETURN;
150
+{
206
+ dc->base.pc_next = QEMU_ALIGN_UP(pc, 4);
151
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
207
+ return;
152
+ gen_sabd_vec(vece, t, a, b);
208
+ }
153
+ tcg_gen_add_vec(vece, d, d, t);
209
+
154
+ tcg_temp_free_vec(t);
210
+ if (arm_check_kernelpage(dc)) {
155
+}
211
dc->base.pc_next = pc + 4;
156
+
212
return;
157
+void gen_gvec_saba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
213
}
158
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
159
+{
160
+ static const TCGOpcode vecop_list[] = {
161
+ INDEX_op_sub_vec, INDEX_op_add_vec,
162
+ INDEX_op_smin_vec, INDEX_op_smax_vec, 0
163
+ };
164
+ static const GVecGen3 ops[4] = {
165
+ { .fniv = gen_saba_vec,
166
+ .fno = gen_helper_gvec_saba_b,
167
+ .opt_opc = vecop_list,
168
+ .load_dest = true,
169
+ .vece = MO_8 },
170
+ { .fniv = gen_saba_vec,
171
+ .fno = gen_helper_gvec_saba_h,
172
+ .opt_opc = vecop_list,
173
+ .load_dest = true,
174
+ .vece = MO_16 },
175
+ { .fni4 = gen_saba_i32,
176
+ .fniv = gen_saba_vec,
177
+ .fno = gen_helper_gvec_saba_s,
178
+ .opt_opc = vecop_list,
179
+ .load_dest = true,
180
+ .vece = MO_32 },
181
+ { .fni8 = gen_saba_i64,
182
+ .fniv = gen_saba_vec,
183
+ .fno = gen_helper_gvec_saba_d,
184
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
185
+ .opt_opc = vecop_list,
186
+ .load_dest = true,
187
+ .vece = MO_64 },
188
+ };
189
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
190
+}
191
+
192
+static void gen_uaba_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
193
+{
194
+ TCGv_i32 t = tcg_temp_new_i32();
195
+ gen_uabd_i32(t, a, b);
196
+ tcg_gen_add_i32(d, d, t);
197
+ tcg_temp_free_i32(t);
198
+}
199
+
200
+static void gen_uaba_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
201
+{
202
+ TCGv_i64 t = tcg_temp_new_i64();
203
+ gen_uabd_i64(t, a, b);
204
+ tcg_gen_add_i64(d, d, t);
205
+ tcg_temp_free_i64(t);
206
+}
207
+
208
+static void gen_uaba_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
209
+{
210
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
211
+ gen_uabd_vec(vece, t, a, b);
212
+ tcg_gen_add_vec(vece, d, d, t);
213
+ tcg_temp_free_vec(t);
214
+}
215
+
216
+void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
217
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
218
+{
219
+ static const TCGOpcode vecop_list[] = {
220
+ INDEX_op_sub_vec, INDEX_op_add_vec,
221
+ INDEX_op_umin_vec, INDEX_op_umax_vec, 0
222
+ };
223
+ static const GVecGen3 ops[4] = {
224
+ { .fniv = gen_uaba_vec,
225
+ .fno = gen_helper_gvec_uaba_b,
226
+ .opt_opc = vecop_list,
227
+ .load_dest = true,
228
+ .vece = MO_8 },
229
+ { .fniv = gen_uaba_vec,
230
+ .fno = gen_helper_gvec_uaba_h,
231
+ .opt_opc = vecop_list,
232
+ .load_dest = true,
233
+ .vece = MO_16 },
234
+ { .fni4 = gen_uaba_i32,
235
+ .fniv = gen_uaba_vec,
236
+ .fno = gen_helper_gvec_uaba_s,
237
+ .opt_opc = vecop_list,
238
+ .load_dest = true,
239
+ .vece = MO_32 },
240
+ { .fni8 = gen_uaba_i64,
241
+ .fniv = gen_uaba_vec,
242
+ .fno = gen_helper_gvec_uaba_d,
243
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
244
+ .opt_opc = vecop_list,
245
+ .load_dest = true,
246
+ .vece = MO_64 },
247
+ };
248
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
249
+}
250
+
251
/* Translate a NEON data processing instruction. Return nonzero if the
252
instruction is invalid.
253
We process data in a mixture of 32-bit and 64-bit chunks.
254
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
255
}
256
return 0;
257
258
+ case NEON_3R_VABA:
259
+ if (u) {
260
+ gen_gvec_uaba(size, rd_ofs, rn_ofs, rm_ofs,
261
+ vec_size, vec_size);
262
+ } else {
263
+ gen_gvec_saba(size, rd_ofs, rn_ofs, rm_ofs,
264
+ vec_size, vec_size);
265
+ }
266
+ return 0;
267
+
268
case NEON_3R_VADD_VSUB:
269
case NEON_3R_LOGIC:
270
case NEON_3R_VMAX:
271
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
272
case NEON_3R_VQRSHL:
273
GEN_NEON_INTEGER_OP_ENV(qrshl);
274
break;
275
- case NEON_3R_VABA:
276
- GEN_NEON_INTEGER_OP(abd);
277
- tcg_temp_free_i32(tmp2);
278
- tmp2 = neon_load_reg(rd, pass);
279
- gen_neon_add(size, tmp, tmp2);
280
- break;
281
case NEON_3R_VPMAX:
282
GEN_NEON_INTEGER_OP(pmax);
283
break;
284
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
285
index XXXXXXX..XXXXXXX 100644
286
--- a/target/arm/vec_helper.c
287
+++ b/target/arm/vec_helper.c
288
@@ -XXX,XX +XXX,XX @@ DO_ABD(gvec_uabd_s, uint32_t)
289
DO_ABD(gvec_uabd_d, uint64_t)
290
291
#undef DO_ABD
292
+
293
+#define DO_ABA(NAME, TYPE) \
294
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
295
+{ \
296
+ intptr_t i, opr_sz = simd_oprsz(desc); \
297
+ TYPE *d = vd, *n = vn, *m = vm; \
298
+ \
299
+ for (i = 0; i < opr_sz / sizeof(TYPE); ++i) { \
300
+ d[i] += n[i] < m[i] ? m[i] - n[i] : n[i] - m[i]; \
301
+ } \
302
+ clear_tail(d, opr_sz, simd_maxsz(desc)); \
303
+}
304
+
305
+DO_ABA(gvec_saba_b, int8_t)
306
+DO_ABA(gvec_saba_h, int16_t)
307
+DO_ABA(gvec_saba_s, int32_t)
308
+DO_ABA(gvec_saba_d, int64_t)
309
+
310
+DO_ABA(gvec_uaba_b, uint8_t)
311
+DO_ABA(gvec_uaba_h, uint16_t)
312
+DO_ABA(gvec_uaba_s, uint32_t)
313
+DO_ABA(gvec_uaba_d, uint64_t)
314
+
315
+#undef DO_ABA
316
--
214
--
317
2.20.1
215
2.25.1
318
216
319
217
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The functions eliminate duplication of the special cases for
3
Misaligned thumb PC is architecturally impossible.
4
this operation. They match up with the GVecGen2iFn typedef.
4
Assert is better than proceeding, in case we've missed
5
something somewhere.
5
6
6
Add out-of-line helpers. We got away with only having inline
7
Expand a comment about aligning the pc in gdbstub.
7
expanders because the neon vector size is only 16 bytes, and
8
Fail an incoming migrate if a thumb pc is misaligned.
8
we know that the inline expansion will always succeed.
9
When we reuse this for SVE, tcg-gvec-op may decide to use an
10
out-of-line helper due to longer vector lengths.
11
9
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200513163245.17915-4-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
13
---
17
target/arm/helper.h | 10 ++
14
target/arm/gdbstub.c | 9 +++++++--
18
target/arm/translate.h | 7 +-
15
target/arm/machine.c | 10 ++++++++++
19
target/arm/translate-a64.c | 20 +---
16
target/arm/translate.c | 3 +++
20
target/arm/translate.c | 186 +++++++++++++++++++++----------------
17
3 files changed, 20 insertions(+), 2 deletions(-)
21
target/arm/vec_helper.c | 38 ++++++++
22
5 files changed, 160 insertions(+), 101 deletions(-)
23
18
24
diff --git a/target/arm/helper.h b/target/arm/helper.h
19
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
25
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.h
21
--- a/target/arm/gdbstub.c
27
+++ b/target/arm/helper.h
22
+++ b/target/arm/gdbstub.c
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(gvec_ursra_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
23
@@ -XXX,XX +XXX,XX @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
29
DEF_HELPER_FLAGS_3(gvec_ursra_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
24
30
DEF_HELPER_FLAGS_3(gvec_ursra_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
25
tmp = ldl_p(mem_buf);
31
26
32
+DEF_HELPER_FLAGS_3(gvec_sri_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
27
- /* Mask out low bit of PC to workaround gdb bugs. This will probably
33
+DEF_HELPER_FLAGS_3(gvec_sri_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
28
- cause problems if we ever implement the Jazelle DBX extensions. */
34
+DEF_HELPER_FLAGS_3(gvec_sri_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
29
+ /*
35
+DEF_HELPER_FLAGS_3(gvec_sri_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
30
+ * Mask out low bits of PC to workaround gdb bugs.
31
+ * This avoids an assert in thumb_tr_translate_insn, because it is
32
+ * architecturally impossible to misalign the pc.
33
+ * This will probably cause problems if we ever implement the
34
+ * Jazelle DBX extensions.
35
+ */
36
if (n == 15) {
37
tmp &= ~1;
38
}
39
diff --git a/target/arm/machine.c b/target/arm/machine.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/machine.c
42
+++ b/target/arm/machine.c
43
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
44
return -1;
45
}
46
}
36
+
47
+
37
+DEF_HELPER_FLAGS_3(gvec_sli_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
48
+ /*
38
+DEF_HELPER_FLAGS_3(gvec_sli_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
49
+ * Misaligned thumb pc is architecturally impossible.
39
+DEF_HELPER_FLAGS_3(gvec_sli_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
50
+ * We have an assert in thumb_tr_translate_insn to verify this.
40
+DEF_HELPER_FLAGS_3(gvec_sli_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
51
+ * Fail an incoming migrate to avoid this assert.
52
+ */
53
+ if (!is_a64(env) && env->thumb && (env->regs[15] & 1)) {
54
+ return -1;
55
+ }
41
+
56
+
42
#ifdef TARGET_AARCH64
57
if (!kvm_enabled()) {
43
#include "helper-a64.h"
58
pmu_op_finish(&cpu->env);
44
#include "helper-sve.h"
45
diff --git a/target/arm/translate.h b/target/arm/translate.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/translate.h
48
+++ b/target/arm/translate.h
49
@@ -XXX,XX +XXX,XX @@ extern const GVecGen3 mls_op[4];
50
extern const GVecGen3 cmtst_op[4];
51
extern const GVecGen3 sshl_op[4];
52
extern const GVecGen3 ushl_op[4];
53
-extern const GVecGen2i sri_op[4];
54
-extern const GVecGen2i sli_op[4];
55
extern const GVecGen4 uqadd_op[4];
56
extern const GVecGen4 sqadd_op[4];
57
extern const GVecGen4 uqsub_op[4];
58
@@ -XXX,XX +XXX,XX @@ void gen_gvec_srsra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
59
void gen_gvec_ursra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
60
int64_t shift, uint32_t opr_sz, uint32_t max_sz);
61
62
+void gen_gvec_sri(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
63
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz);
64
+void gen_gvec_sli(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
65
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz);
66
+
67
/*
68
* Forward to the isar_feature_* tests given a DisasContext pointer.
69
*/
70
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/translate-a64.c
73
+++ b/target/arm/translate-a64.c
74
@@ -XXX,XX +XXX,XX @@ static void gen_gvec_op2(DisasContext *s, bool is_q, int rd,
75
is_q ? 16 : 8, vec_full_reg_size(s), gvec_op);
76
}
77
78
-/* Expand a 2-operand + immediate AdvSIMD vector operation using
79
- * an op descriptor.
80
- */
81
-static void gen_gvec_op2i(DisasContext *s, bool is_q, int rd,
82
- int rn, int64_t imm, const GVecGen2i *gvec_op)
83
-{
84
- tcg_gen_gvec_2i(vec_full_reg_offset(s, rd), vec_full_reg_offset(s, rn),
85
- is_q ? 16 : 8, vec_full_reg_size(s), imm, gvec_op);
86
-}
87
-
88
/* Expand a 3-operand AdvSIMD vector operation using an op descriptor. */
89
static void gen_gvec_op3(DisasContext *s, bool is_q, int rd,
90
int rn, int rm, const GVecGen3 *gvec_op)
91
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
92
gen_gvec_fn2i(s, is_q, rd, rn, shift,
93
is_u ? gen_gvec_usra : gen_gvec_ssra, size);
94
return;
95
+
96
case 0x08: /* SRI */
97
- /* Shift count same as element size is valid but does nothing. */
98
- if (shift == 8 << size) {
99
- goto done;
100
- }
101
- gen_gvec_op2i(s, is_q, rd, rn, shift, &sri_op[size]);
102
+ gen_gvec_fn2i(s, is_q, rd, rn, shift, gen_gvec_sri, size);
103
return;
104
105
case 0x00: /* SSHR / USHR */
106
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
107
}
108
tcg_temp_free_i64(tcg_round);
109
110
- done:
111
clear_vec_high(s, is_q, rd);
112
}
113
114
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shli(DisasContext *s, bool is_q, bool insert,
115
}
116
117
if (insert) {
118
- gen_gvec_op2i(s, is_q, rd, rn, shift, &sli_op[size]);
119
+ gen_gvec_fn2i(s, is_q, rd, rn, shift, gen_gvec_sli, size);
120
} else {
121
gen_gvec_fn2i(s, is_q, rd, rn, shift, tcg_gen_gvec_shli, size);
122
}
59
}
123
diff --git a/target/arm/translate.c b/target/arm/translate.c
60
diff --git a/target/arm/translate.c b/target/arm/translate.c
124
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
125
--- a/target/arm/translate.c
62
--- a/target/arm/translate.c
126
+++ b/target/arm/translate.c
63
+++ b/target/arm/translate.c
127
@@ -XXX,XX +XXX,XX @@ static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
64
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
128
65
uint32_t insn;
129
static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
66
bool is_16bit;
130
{
67
131
- if (sh == 0) {
68
+ /* Misaligned thumb PC is architecturally impossible. */
132
- tcg_gen_mov_vec(d, a);
69
+ assert((dc->base.pc_next & 1) == 0);
133
- } else {
134
- TCGv_vec t = tcg_temp_new_vec_matching(d);
135
- TCGv_vec m = tcg_temp_new_vec_matching(d);
136
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
137
+ TCGv_vec m = tcg_temp_new_vec_matching(d);
138
139
- tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
140
- tcg_gen_shri_vec(vece, t, a, sh);
141
- tcg_gen_and_vec(vece, d, d, m);
142
- tcg_gen_or_vec(vece, d, d, t);
143
+ tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
144
+ tcg_gen_shri_vec(vece, t, a, sh);
145
+ tcg_gen_and_vec(vece, d, d, m);
146
+ tcg_gen_or_vec(vece, d, d, t);
147
148
- tcg_temp_free_vec(t);
149
- tcg_temp_free_vec(m);
150
- }
151
+ tcg_temp_free_vec(t);
152
+ tcg_temp_free_vec(m);
153
}
154
155
-static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
156
+void gen_gvec_sri(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
157
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz)
158
+{
159
+ static const TCGOpcode vecop_list[] = { INDEX_op_shri_vec, 0 };
160
+ const GVecGen2i ops[4] = {
161
+ { .fni8 = gen_shr8_ins_i64,
162
+ .fniv = gen_shr_ins_vec,
163
+ .fno = gen_helper_gvec_sri_b,
164
+ .load_dest = true,
165
+ .opt_opc = vecop_list,
166
+ .vece = MO_8 },
167
+ { .fni8 = gen_shr16_ins_i64,
168
+ .fniv = gen_shr_ins_vec,
169
+ .fno = gen_helper_gvec_sri_h,
170
+ .load_dest = true,
171
+ .opt_opc = vecop_list,
172
+ .vece = MO_16 },
173
+ { .fni4 = gen_shr32_ins_i32,
174
+ .fniv = gen_shr_ins_vec,
175
+ .fno = gen_helper_gvec_sri_s,
176
+ .load_dest = true,
177
+ .opt_opc = vecop_list,
178
+ .vece = MO_32 },
179
+ { .fni8 = gen_shr64_ins_i64,
180
+ .fniv = gen_shr_ins_vec,
181
+ .fno = gen_helper_gvec_sri_d,
182
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
183
+ .load_dest = true,
184
+ .opt_opc = vecop_list,
185
+ .vece = MO_64 },
186
+ };
187
188
-const GVecGen2i sri_op[4] = {
189
- { .fni8 = gen_shr8_ins_i64,
190
- .fniv = gen_shr_ins_vec,
191
- .load_dest = true,
192
- .opt_opc = vecop_list_sri,
193
- .vece = MO_8 },
194
- { .fni8 = gen_shr16_ins_i64,
195
- .fniv = gen_shr_ins_vec,
196
- .load_dest = true,
197
- .opt_opc = vecop_list_sri,
198
- .vece = MO_16 },
199
- { .fni4 = gen_shr32_ins_i32,
200
- .fniv = gen_shr_ins_vec,
201
- .load_dest = true,
202
- .opt_opc = vecop_list_sri,
203
- .vece = MO_32 },
204
- { .fni8 = gen_shr64_ins_i64,
205
- .fniv = gen_shr_ins_vec,
206
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
207
- .load_dest = true,
208
- .opt_opc = vecop_list_sri,
209
- .vece = MO_64 },
210
-};
211
+ /* tszimm encoding produces immediates in the range [1..esize]. */
212
+ tcg_debug_assert(shift > 0);
213
+ tcg_debug_assert(shift <= (8 << vece));
214
+
70
+
215
+ /* Shift of esize leaves destination unchanged. */
71
if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
216
+ if (shift < (8 << vece)) {
72
dc->base.pc_next = pc + 2;
217
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
73
return;
218
+ } else {
219
+ /* Nop, but we do need to clear the tail. */
220
+ tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
221
+ }
222
+}
223
224
static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
225
{
226
@@ -XXX,XX +XXX,XX @@ static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
227
228
static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
229
{
230
- if (sh == 0) {
231
- tcg_gen_mov_vec(d, a);
232
- } else {
233
- TCGv_vec t = tcg_temp_new_vec_matching(d);
234
- TCGv_vec m = tcg_temp_new_vec_matching(d);
235
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
236
+ TCGv_vec m = tcg_temp_new_vec_matching(d);
237
238
- tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
239
- tcg_gen_shli_vec(vece, t, a, sh);
240
- tcg_gen_and_vec(vece, d, d, m);
241
- tcg_gen_or_vec(vece, d, d, t);
242
+ tcg_gen_shli_vec(vece, t, a, sh);
243
+ tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
244
+ tcg_gen_and_vec(vece, d, d, m);
245
+ tcg_gen_or_vec(vece, d, d, t);
246
247
- tcg_temp_free_vec(t);
248
- tcg_temp_free_vec(m);
249
- }
250
+ tcg_temp_free_vec(t);
251
+ tcg_temp_free_vec(m);
252
}
253
254
-static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
255
+void gen_gvec_sli(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
256
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz)
257
+{
258
+ static const TCGOpcode vecop_list[] = { INDEX_op_shli_vec, 0 };
259
+ const GVecGen2i ops[4] = {
260
+ { .fni8 = gen_shl8_ins_i64,
261
+ .fniv = gen_shl_ins_vec,
262
+ .fno = gen_helper_gvec_sli_b,
263
+ .load_dest = true,
264
+ .opt_opc = vecop_list,
265
+ .vece = MO_8 },
266
+ { .fni8 = gen_shl16_ins_i64,
267
+ .fniv = gen_shl_ins_vec,
268
+ .fno = gen_helper_gvec_sli_h,
269
+ .load_dest = true,
270
+ .opt_opc = vecop_list,
271
+ .vece = MO_16 },
272
+ { .fni4 = gen_shl32_ins_i32,
273
+ .fniv = gen_shl_ins_vec,
274
+ .fno = gen_helper_gvec_sli_s,
275
+ .load_dest = true,
276
+ .opt_opc = vecop_list,
277
+ .vece = MO_32 },
278
+ { .fni8 = gen_shl64_ins_i64,
279
+ .fniv = gen_shl_ins_vec,
280
+ .fno = gen_helper_gvec_sli_d,
281
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
282
+ .load_dest = true,
283
+ .opt_opc = vecop_list,
284
+ .vece = MO_64 },
285
+ };
286
287
-const GVecGen2i sli_op[4] = {
288
- { .fni8 = gen_shl8_ins_i64,
289
- .fniv = gen_shl_ins_vec,
290
- .load_dest = true,
291
- .opt_opc = vecop_list_sli,
292
- .vece = MO_8 },
293
- { .fni8 = gen_shl16_ins_i64,
294
- .fniv = gen_shl_ins_vec,
295
- .load_dest = true,
296
- .opt_opc = vecop_list_sli,
297
- .vece = MO_16 },
298
- { .fni4 = gen_shl32_ins_i32,
299
- .fniv = gen_shl_ins_vec,
300
- .load_dest = true,
301
- .opt_opc = vecop_list_sli,
302
- .vece = MO_32 },
303
- { .fni8 = gen_shl64_ins_i64,
304
- .fniv = gen_shl_ins_vec,
305
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
306
- .load_dest = true,
307
- .opt_opc = vecop_list_sli,
308
- .vece = MO_64 },
309
-};
310
+ /* tszimm encoding produces immediates in the range [0..esize-1]. */
311
+ tcg_debug_assert(shift >= 0);
312
+ tcg_debug_assert(shift < (8 << vece));
313
+
314
+ if (shift == 0) {
315
+ tcg_gen_gvec_mov(vece, rd_ofs, rm_ofs, opr_sz, max_sz);
316
+ } else {
317
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
318
+ }
319
+}
320
321
static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
322
{
323
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
324
}
325
/* Right shift comes here negative. */
326
shift = -shift;
327
- /* Shift out of range leaves destination unchanged. */
328
- if (shift < 8 << size) {
329
- tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
330
- shift, &sri_op[size]);
331
- }
332
+ gen_gvec_sri(size, rd_ofs, rm_ofs, shift,
333
+ vec_size, vec_size);
334
return 0;
335
336
case 5: /* VSHL, VSLI */
337
if (u) { /* VSLI */
338
- /* Shift out of range leaves destination unchanged. */
339
- if (shift < 8 << size) {
340
- tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
341
- vec_size, shift, &sli_op[size]);
342
- }
343
+ gen_gvec_sli(size, rd_ofs, rm_ofs, shift,
344
+ vec_size, vec_size);
345
} else { /* VSHL */
346
/* Shifts larger than the element size are
347
* architecturally valid and results in zero.
348
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
349
index XXXXXXX..XXXXXXX 100644
350
--- a/target/arm/vec_helper.c
351
+++ b/target/arm/vec_helper.c
352
@@ -XXX,XX +XXX,XX @@ DO_RSRA(gvec_ursra_d, uint64_t)
353
354
#undef DO_RSRA
355
356
+#define DO_SRI(NAME, TYPE) \
357
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
358
+{ \
359
+ intptr_t i, oprsz = simd_oprsz(desc); \
360
+ int shift = simd_data(desc); \
361
+ TYPE *d = vd, *n = vn; \
362
+ for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
363
+ d[i] = deposit64(d[i], 0, sizeof(TYPE) * 8 - shift, n[i] >> shift); \
364
+ } \
365
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
366
+}
367
+
368
+DO_SRI(gvec_sri_b, uint8_t)
369
+DO_SRI(gvec_sri_h, uint16_t)
370
+DO_SRI(gvec_sri_s, uint32_t)
371
+DO_SRI(gvec_sri_d, uint64_t)
372
+
373
+#undef DO_SRI
374
+
375
+#define DO_SLI(NAME, TYPE) \
376
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
377
+{ \
378
+ intptr_t i, oprsz = simd_oprsz(desc); \
379
+ int shift = simd_data(desc); \
380
+ TYPE *d = vd, *n = vn; \
381
+ for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
382
+ d[i] = deposit64(d[i], shift, sizeof(TYPE) * 8 - shift, n[i]); \
383
+ } \
384
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
385
+}
386
+
387
+DO_SLI(gvec_sli_b, uint8_t)
388
+DO_SLI(gvec_sli_h, uint16_t)
389
+DO_SLI(gvec_sli_s, uint32_t)
390
+DO_SLI(gvec_sli_d, uint64_t)
391
+
392
+#undef DO_SLI
393
+
394
/*
395
* Convert float16 to float32, raising no exceptions and
396
* preserving exceptional values, including SNaN.
397
--
74
--
398
2.20.1
75
2.25.1
399
76
400
77
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The functions eliminate duplication of the special cases for
3
Both single-step and pc alignment faults have priority over
4
this operation. They match up with the GVecGen2iFn typedef.
4
breakpoint exceptions.
5
6
Add out-of-line helpers. We got away with only having inline
7
expanders because the neon vector size is only 16 bytes, and
8
we know that the inline expansion will always succeed.
9
When we reuse this for SVE, tcg-gvec-op may decide to use an
10
out-of-line helper due to longer vector lengths.
11
5
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200513163245.17915-2-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
9
---
17
target/arm/helper.h | 10 +++
10
target/arm/debug_helper.c | 23 +++++++++++++++++++++++
18
target/arm/translate.h | 7 +-
11
1 file changed, 23 insertions(+)
19
target/arm/translate-a64.c | 15 +---
20
target/arm/translate.c | 161 ++++++++++++++++++++++---------------
21
target/arm/vec_helper.c | 25 ++++++
22
5 files changed, 139 insertions(+), 79 deletions(-)
23
12
24
diff --git a/target/arm/helper.h b/target/arm/helper.h
13
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
25
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.h
15
--- a/target/arm/debug_helper.c
27
+++ b/target/arm/helper.h
16
+++ b/target/arm/debug_helper.c
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_pmull_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
17
@@ -XXX,XX +XXX,XX @@ bool arm_debug_check_breakpoint(CPUState *cs)
29
18
{
30
DEF_HELPER_FLAGS_4(neon_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
19
ARMCPU *cpu = ARM_CPU(cs);
31
20
CPUARMState *env = &cpu->env;
32
+DEF_HELPER_FLAGS_3(gvec_ssra_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
21
+ target_ulong pc;
33
+DEF_HELPER_FLAGS_3(gvec_ssra_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
22
int n;
34
+DEF_HELPER_FLAGS_3(gvec_ssra_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
23
35
+DEF_HELPER_FLAGS_3(gvec_ssra_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
24
/*
36
+
25
@@ -XXX,XX +XXX,XX @@ bool arm_debug_check_breakpoint(CPUState *cs)
37
+DEF_HELPER_FLAGS_3(gvec_usra_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
26
return false;
38
+DEF_HELPER_FLAGS_3(gvec_usra_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
27
}
39
+DEF_HELPER_FLAGS_3(gvec_usra_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
28
40
+DEF_HELPER_FLAGS_3(gvec_usra_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
29
+ /*
41
+
30
+ * Single-step exceptions have priority over breakpoint exceptions.
42
#ifdef TARGET_AARCH64
31
+ * If single-step state is active-pending, suppress the bp.
43
#include "helper-a64.h"
32
+ */
44
#include "helper-sve.h"
33
+ if (arm_singlestep_active(env) && !(env->pstate & PSTATE_SS)) {
45
diff --git a/target/arm/translate.h b/target/arm/translate.h
34
+ return false;
46
index XXXXXXX..XXXXXXX 100644
35
+ }
47
--- a/target/arm/translate.h
48
+++ b/target/arm/translate.h
49
@@ -XXX,XX +XXX,XX @@ extern const GVecGen3 mls_op[4];
50
extern const GVecGen3 cmtst_op[4];
51
extern const GVecGen3 sshl_op[4];
52
extern const GVecGen3 ushl_op[4];
53
-extern const GVecGen2i ssra_op[4];
54
-extern const GVecGen2i usra_op[4];
55
extern const GVecGen2i sri_op[4];
56
extern const GVecGen2i sli_op[4];
57
extern const GVecGen4 uqadd_op[4];
58
@@ -XXX,XX +XXX,XX @@ void gen_sshl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
59
void gen_ushl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
60
void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
61
62
+void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
63
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz);
64
+void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
65
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz);
66
+
67
/*
68
* Forward to the isar_feature_* tests given a DisasContext pointer.
69
*/
70
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/translate-a64.c
73
+++ b/target/arm/translate-a64.c
74
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
75
76
switch (opcode) {
77
case 0x02: /* SSRA / USRA (accumulate) */
78
- if (is_u) {
79
- /* Shift count same as element size produces zero to add. */
80
- if (shift == 8 << size) {
81
- goto done;
82
- }
83
- gen_gvec_op2i(s, is_q, rd, rn, shift, &usra_op[size]);
84
- } else {
85
- /* Shift count same as element size produces all sign to add. */
86
- if (shift == 8 << size) {
87
- shift -= 1;
88
- }
89
- gen_gvec_op2i(s, is_q, rd, rn, shift, &ssra_op[size]);
90
- }
91
+ gen_gvec_fn2i(s, is_q, rd, rn, shift,
92
+ is_u ? gen_gvec_usra : gen_gvec_ssra, size);
93
return;
94
case 0x08: /* SRI */
95
/* Shift count same as element size is valid but does nothing. */
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
101
tcg_gen_add_vec(vece, d, d, a);
102
}
103
104
-static const TCGOpcode vecop_list_ssra[] = {
105
- INDEX_op_sari_vec, INDEX_op_add_vec, 0
106
-};
107
+void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
108
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz)
109
+{
110
+ static const TCGOpcode vecop_list[] = {
111
+ INDEX_op_sari_vec, INDEX_op_add_vec, 0
112
+ };
113
+ static const GVecGen2i ops[4] = {
114
+ { .fni8 = gen_ssra8_i64,
115
+ .fniv = gen_ssra_vec,
116
+ .fno = gen_helper_gvec_ssra_b,
117
+ .load_dest = true,
118
+ .opt_opc = vecop_list,
119
+ .vece = MO_8 },
120
+ { .fni8 = gen_ssra16_i64,
121
+ .fniv = gen_ssra_vec,
122
+ .fno = gen_helper_gvec_ssra_h,
123
+ .load_dest = true,
124
+ .opt_opc = vecop_list,
125
+ .vece = MO_16 },
126
+ { .fni4 = gen_ssra32_i32,
127
+ .fniv = gen_ssra_vec,
128
+ .fno = gen_helper_gvec_ssra_s,
129
+ .load_dest = true,
130
+ .opt_opc = vecop_list,
131
+ .vece = MO_32 },
132
+ { .fni8 = gen_ssra64_i64,
133
+ .fniv = gen_ssra_vec,
134
+ .fno = gen_helper_gvec_ssra_b,
135
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
136
+ .opt_opc = vecop_list,
137
+ .load_dest = true,
138
+ .vece = MO_64 },
139
+ };
140
141
-const GVecGen2i ssra_op[4] = {
142
- { .fni8 = gen_ssra8_i64,
143
- .fniv = gen_ssra_vec,
144
- .load_dest = true,
145
- .opt_opc = vecop_list_ssra,
146
- .vece = MO_8 },
147
- { .fni8 = gen_ssra16_i64,
148
- .fniv = gen_ssra_vec,
149
- .load_dest = true,
150
- .opt_opc = vecop_list_ssra,
151
- .vece = MO_16 },
152
- { .fni4 = gen_ssra32_i32,
153
- .fniv = gen_ssra_vec,
154
- .load_dest = true,
155
- .opt_opc = vecop_list_ssra,
156
- .vece = MO_32 },
157
- { .fni8 = gen_ssra64_i64,
158
- .fniv = gen_ssra_vec,
159
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
160
- .opt_opc = vecop_list_ssra,
161
- .load_dest = true,
162
- .vece = MO_64 },
163
-};
164
+ /* tszimm encoding produces immediates in the range [1..esize]. */
165
+ tcg_debug_assert(shift > 0);
166
+ tcg_debug_assert(shift <= (8 << vece));
167
+
36
+
168
+ /*
37
+ /*
169
+ * Shifts larger than the element size are architecturally valid.
38
+ * PC alignment faults have priority over breakpoint exceptions.
170
+ * Signed results in all sign bits.
171
+ */
39
+ */
172
+ shift = MIN(shift, (8 << vece) - 1);
40
+ pc = is_a64(env) ? env->pc : env->regs[15];
173
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
41
+ if ((is_a64(env) || !env->thumb) && (pc & 3) != 0) {
174
+}
42
+ return false;
175
43
+ }
176
static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
177
{
178
@@ -XXX,XX +XXX,XX @@ static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
179
tcg_gen_add_vec(vece, d, d, a);
180
}
181
182
-static const TCGOpcode vecop_list_usra[] = {
183
- INDEX_op_shri_vec, INDEX_op_add_vec, 0
184
-};
185
+void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
186
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz)
187
+{
188
+ static const TCGOpcode vecop_list[] = {
189
+ INDEX_op_shri_vec, INDEX_op_add_vec, 0
190
+ };
191
+ static const GVecGen2i ops[4] = {
192
+ { .fni8 = gen_usra8_i64,
193
+ .fniv = gen_usra_vec,
194
+ .fno = gen_helper_gvec_usra_b,
195
+ .load_dest = true,
196
+ .opt_opc = vecop_list,
197
+ .vece = MO_8, },
198
+ { .fni8 = gen_usra16_i64,
199
+ .fniv = gen_usra_vec,
200
+ .fno = gen_helper_gvec_usra_h,
201
+ .load_dest = true,
202
+ .opt_opc = vecop_list,
203
+ .vece = MO_16, },
204
+ { .fni4 = gen_usra32_i32,
205
+ .fniv = gen_usra_vec,
206
+ .fno = gen_helper_gvec_usra_s,
207
+ .load_dest = true,
208
+ .opt_opc = vecop_list,
209
+ .vece = MO_32, },
210
+ { .fni8 = gen_usra64_i64,
211
+ .fniv = gen_usra_vec,
212
+ .fno = gen_helper_gvec_usra_d,
213
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
214
+ .load_dest = true,
215
+ .opt_opc = vecop_list,
216
+ .vece = MO_64, },
217
+ };
218
219
-const GVecGen2i usra_op[4] = {
220
- { .fni8 = gen_usra8_i64,
221
- .fniv = gen_usra_vec,
222
- .load_dest = true,
223
- .opt_opc = vecop_list_usra,
224
- .vece = MO_8, },
225
- { .fni8 = gen_usra16_i64,
226
- .fniv = gen_usra_vec,
227
- .load_dest = true,
228
- .opt_opc = vecop_list_usra,
229
- .vece = MO_16, },
230
- { .fni4 = gen_usra32_i32,
231
- .fniv = gen_usra_vec,
232
- .load_dest = true,
233
- .opt_opc = vecop_list_usra,
234
- .vece = MO_32, },
235
- { .fni8 = gen_usra64_i64,
236
- .fniv = gen_usra_vec,
237
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
238
- .load_dest = true,
239
- .opt_opc = vecop_list_usra,
240
- .vece = MO_64, },
241
-};
242
+ /* tszimm encoding produces immediates in the range [1..esize]. */
243
+ tcg_debug_assert(shift > 0);
244
+ tcg_debug_assert(shift <= (8 << vece));
245
+
44
+
246
+ /*
45
+ /*
247
+ * Shifts larger than the element size are architecturally valid.
46
+ * Instruction aborts have priority over breakpoint exceptions.
248
+ * Unsigned results in all zeros as input to accumulate: nop.
47
+ * TODO: We would need to look up the page for PC and verify that
48
+ * it is present and executable.
249
+ */
49
+ */
250
+ if (shift < (8 << vece)) {
251
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
252
+ } else {
253
+ /* Nop, but we do need to clear the tail. */
254
+ tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
255
+ }
256
+}
257
258
static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
259
{
260
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
261
case 1: /* VSRA */
262
/* Right shift comes here negative. */
263
shift = -shift;
264
- /* Shifts larger than the element size are architecturally
265
- * valid. Unsigned results in all zeros; signed results
266
- * in all sign bits.
267
- */
268
- if (!u) {
269
- tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
270
- MIN(shift, (8 << size) - 1),
271
- &ssra_op[size]);
272
- } else if (shift >= 8 << size) {
273
- /* rd += 0 */
274
+ if (u) {
275
+ gen_gvec_usra(size, rd_ofs, rm_ofs, shift,
276
+ vec_size, vec_size);
277
} else {
278
- tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
279
- shift, &usra_op[size]);
280
+ gen_gvec_ssra(size, rd_ofs, rm_ofs, shift,
281
+ vec_size, vec_size);
282
}
283
return 0;
284
285
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
286
index XXXXXXX..XXXXXXX 100644
287
--- a/target/arm/vec_helper.c
288
+++ b/target/arm/vec_helper.c
289
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_sqsub_d)(void *vd, void *vq, void *vn,
290
clear_tail(d, oprsz, simd_maxsz(desc));
291
}
292
293
+
50
+
294
+#define DO_SRA(NAME, TYPE) \
51
for (n = 0; n < ARRAY_SIZE(env->cpu_breakpoint); n++) {
295
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
52
if (bp_wp_matches(cpu, n, false)) {
296
+{ \
53
return true;
297
+ intptr_t i, oprsz = simd_oprsz(desc); \
298
+ int shift = simd_data(desc); \
299
+ TYPE *d = vd, *n = vn; \
300
+ for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
301
+ d[i] += n[i] >> shift; \
302
+ } \
303
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
304
+}
305
+
306
+DO_SRA(gvec_ssra_b, int8_t)
307
+DO_SRA(gvec_ssra_h, int16_t)
308
+DO_SRA(gvec_ssra_s, int32_t)
309
+DO_SRA(gvec_ssra_d, int64_t)
310
+
311
+DO_SRA(gvec_usra_b, uint8_t)
312
+DO_SRA(gvec_usra_h, uint16_t)
313
+DO_SRA(gvec_usra_s, uint32_t)
314
+DO_SRA(gvec_usra_d, uint64_t)
315
+
316
+#undef DO_SRA
317
+
318
/*
319
* Convert float16 to float32, raising no exceptions and
320
* preserving exceptional values, including SNaN.
321
--
54
--
322
2.20.1
55
2.25.1
323
56
324
57
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
Create vectorized versions of handle_shri_with_rndacc
4
for shift+round and shift+round+accumulate. Add out-of-line
5
helpers in preparation for longer vector lengths from SVE.
6
2
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200513163245.17915-3-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
6
---
12
target/arm/helper.h | 20 ++
7
tests/tcg/aarch64/pcalign-a64.c | 37 +++++++++++++++++++++++++
13
target/arm/translate.h | 9 +
8
tests/tcg/arm/pcalign-a32.c | 46 +++++++++++++++++++++++++++++++
14
target/arm/translate-a64.c | 11 +-
9
tests/tcg/aarch64/Makefile.target | 4 +--
15
target/arm/translate.c | 463 +++++++++++++++++++++++++++++++++++--
10
tests/tcg/arm/Makefile.target | 4 +++
16
target/arm/vec_helper.c | 50 ++++
11
4 files changed, 89 insertions(+), 2 deletions(-)
17
5 files changed, 527 insertions(+), 26 deletions(-)
12
create mode 100644 tests/tcg/aarch64/pcalign-a64.c
13
create mode 100644 tests/tcg/arm/pcalign-a32.c
18
14
19
diff --git a/target/arm/helper.h b/target/arm/helper.h
15
diff --git a/tests/tcg/aarch64/pcalign-a64.c b/tests/tcg/aarch64/pcalign-a64.c
20
index XXXXXXX..XXXXXXX 100644
16
new file mode 100644
21
--- a/target/arm/helper.h
17
index XXXXXXX..XXXXXXX
22
+++ b/target/arm/helper.h
18
--- /dev/null
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(gvec_usra_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
19
+++ b/tests/tcg/aarch64/pcalign-a64.c
24
DEF_HELPER_FLAGS_3(gvec_usra_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
20
@@ -XXX,XX +XXX,XX @@
25
DEF_HELPER_FLAGS_3(gvec_usra_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
21
+/* Test PC misalignment exception */
26
27
+DEF_HELPER_FLAGS_3(gvec_srshr_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_3(gvec_srshr_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_3(gvec_srshr_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_3(gvec_srshr_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
31
+
22
+
32
+DEF_HELPER_FLAGS_3(gvec_urshr_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
23
+#include <assert.h>
33
+DEF_HELPER_FLAGS_3(gvec_urshr_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
24
+#include <signal.h>
34
+DEF_HELPER_FLAGS_3(gvec_urshr_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
25
+#include <stdlib.h>
35
+DEF_HELPER_FLAGS_3(gvec_urshr_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
26
+#include <stdio.h>
36
+
27
+
37
+DEF_HELPER_FLAGS_3(gvec_srsra_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
28
+static void *expected;
38
+DEF_HELPER_FLAGS_3(gvec_srsra_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_3(gvec_srsra_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_3(gvec_srsra_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
41
+
29
+
42
+DEF_HELPER_FLAGS_3(gvec_ursra_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
30
+static void sigbus(int sig, siginfo_t *info, void *vuc)
43
+DEF_HELPER_FLAGS_3(gvec_ursra_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_3(gvec_ursra_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_3(gvec_ursra_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
46
+
47
#ifdef TARGET_AARCH64
48
#include "helper-a64.h"
49
#include "helper-sve.h"
50
diff --git a/target/arm/translate.h b/target/arm/translate.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/translate.h
53
+++ b/target/arm/translate.h
54
@@ -XXX,XX +XXX,XX @@ void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
55
void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
56
int64_t shift, uint32_t opr_sz, uint32_t max_sz);
57
58
+void gen_gvec_srshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
59
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz);
60
+void gen_gvec_urshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
61
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz);
62
+void gen_gvec_srsra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
63
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz);
64
+void gen_gvec_ursra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
65
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz);
66
+
67
/*
68
* Forward to the isar_feature_* tests given a DisasContext pointer.
69
*/
70
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/translate-a64.c
73
+++ b/target/arm/translate-a64.c
74
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
75
return;
76
77
case 0x04: /* SRSHR / URSHR (rounding) */
78
- break;
79
+ gen_gvec_fn2i(s, is_q, rd, rn, shift,
80
+ is_u ? gen_gvec_urshr : gen_gvec_srshr, size);
81
+ return;
82
+
83
case 0x06: /* SRSRA / URSRA (accum + rounding) */
84
- accumulate = true;
85
- break;
86
+ gen_gvec_fn2i(s, is_q, rd, rn, shift,
87
+ is_u ? gen_gvec_ursra : gen_gvec_srsra, size);
88
+ return;
89
+
90
default:
91
g_assert_not_reached();
92
}
93
diff --git a/target/arm/translate.c b/target/arm/translate.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/target/arm/translate.c
96
+++ b/target/arm/translate.c
97
@@ -XXX,XX +XXX,XX @@ void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
98
}
99
}
100
101
+/*
102
+ * Shift one less than the requested amount, and the low bit is
103
+ * the rounding bit. For the 8 and 16-bit operations, because we
104
+ * mask the low bit, we can perform a normal integer shift instead
105
+ * of a vector shift.
106
+ */
107
+static void gen_srshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
108
+{
31
+{
109
+ TCGv_i64 t = tcg_temp_new_i64();
32
+ assert(info->si_code == BUS_ADRALN);
110
+
33
+ assert(info->si_addr == expected);
111
+ tcg_gen_shri_i64(t, a, sh - 1);
34
+ exit(EXIT_SUCCESS);
112
+ tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
113
+ tcg_gen_vec_sar8i_i64(d, a, sh);
114
+ tcg_gen_vec_add8_i64(d, d, t);
115
+ tcg_temp_free_i64(t);
116
+}
35
+}
117
+
36
+
118
+static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
37
+int main()
119
+{
38
+{
120
+ TCGv_i64 t = tcg_temp_new_i64();
39
+ void *tmp;
121
+
40
+
122
+ tcg_gen_shri_i64(t, a, sh - 1);
41
+ struct sigaction sa = {
123
+ tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
42
+ .sa_sigaction = sigbus,
124
+ tcg_gen_vec_sar16i_i64(d, a, sh);
43
+ .sa_flags = SA_SIGINFO
125
+ tcg_gen_vec_add16_i64(d, d, t);
44
+ };
126
+ tcg_temp_free_i64(t);
45
+
46
+ if (sigaction(SIGBUS, &sa, NULL) < 0) {
47
+ perror("sigaction");
48
+ return EXIT_FAILURE;
49
+ }
50
+
51
+ asm volatile("adr %0, 1f + 1\n\t"
52
+ "str %0, %1\n\t"
53
+ "br %0\n"
54
+ "1:"
55
+ : "=&r"(tmp), "=m"(expected));
56
+ abort();
57
+}
58
diff --git a/tests/tcg/arm/pcalign-a32.c b/tests/tcg/arm/pcalign-a32.c
59
new file mode 100644
60
index XXXXXXX..XXXXXXX
61
--- /dev/null
62
+++ b/tests/tcg/arm/pcalign-a32.c
63
@@ -XXX,XX +XXX,XX @@
64
+/* Test PC misalignment exception */
65
+
66
+#ifdef __thumb__
67
+#error "This test must be compiled for ARM"
68
+#endif
69
+
70
+#include <assert.h>
71
+#include <signal.h>
72
+#include <stdlib.h>
73
+#include <stdio.h>
74
+
75
+static void *expected;
76
+
77
+static void sigbus(int sig, siginfo_t *info, void *vuc)
78
+{
79
+ assert(info->si_code == BUS_ADRALN);
80
+ assert(info->si_addr == expected);
81
+ exit(EXIT_SUCCESS);
127
+}
82
+}
128
+
83
+
129
+static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
84
+int main()
130
+{
85
+{
131
+ TCGv_i32 t = tcg_temp_new_i32();
86
+ void *tmp;
132
+
87
+
133
+ tcg_gen_extract_i32(t, a, sh - 1, 1);
88
+ struct sigaction sa = {
134
+ tcg_gen_sari_i32(d, a, sh);
89
+ .sa_sigaction = sigbus,
135
+ tcg_gen_add_i32(d, d, t);
90
+ .sa_flags = SA_SIGINFO
136
+ tcg_temp_free_i32(t);
137
+}
138
+
139
+static void gen_srshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
140
+{
141
+ TCGv_i64 t = tcg_temp_new_i64();
142
+
143
+ tcg_gen_extract_i64(t, a, sh - 1, 1);
144
+ tcg_gen_sari_i64(d, a, sh);
145
+ tcg_gen_add_i64(d, d, t);
146
+ tcg_temp_free_i64(t);
147
+}
148
+
149
+static void gen_srshr_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
150
+{
151
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
152
+ TCGv_vec ones = tcg_temp_new_vec_matching(d);
153
+
154
+ tcg_gen_shri_vec(vece, t, a, sh - 1);
155
+ tcg_gen_dupi_vec(vece, ones, 1);
156
+ tcg_gen_and_vec(vece, t, t, ones);
157
+ tcg_gen_sari_vec(vece, d, a, sh);
158
+ tcg_gen_add_vec(vece, d, d, t);
159
+
160
+ tcg_temp_free_vec(t);
161
+ tcg_temp_free_vec(ones);
162
+}
163
+
164
+void gen_gvec_srshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
165
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz)
166
+{
167
+ static const TCGOpcode vecop_list[] = {
168
+ INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
169
+ };
170
+ static const GVecGen2i ops[4] = {
171
+ { .fni8 = gen_srshr8_i64,
172
+ .fniv = gen_srshr_vec,
173
+ .fno = gen_helper_gvec_srshr_b,
174
+ .opt_opc = vecop_list,
175
+ .vece = MO_8 },
176
+ { .fni8 = gen_srshr16_i64,
177
+ .fniv = gen_srshr_vec,
178
+ .fno = gen_helper_gvec_srshr_h,
179
+ .opt_opc = vecop_list,
180
+ .vece = MO_16 },
181
+ { .fni4 = gen_srshr32_i32,
182
+ .fniv = gen_srshr_vec,
183
+ .fno = gen_helper_gvec_srshr_s,
184
+ .opt_opc = vecop_list,
185
+ .vece = MO_32 },
186
+ { .fni8 = gen_srshr64_i64,
187
+ .fniv = gen_srshr_vec,
188
+ .fno = gen_helper_gvec_srshr_d,
189
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
190
+ .opt_opc = vecop_list,
191
+ .vece = MO_64 },
192
+ };
91
+ };
193
+
92
+
194
+ /* tszimm encoding produces immediates in the range [1..esize] */
93
+ if (sigaction(SIGBUS, &sa, NULL) < 0) {
195
+ tcg_debug_assert(shift > 0);
94
+ perror("sigaction");
196
+ tcg_debug_assert(shift <= (8 << vece));
95
+ return EXIT_FAILURE;
96
+ }
197
+
97
+
198
+ if (shift == (8 << vece)) {
98
+ asm volatile("adr %0, 1f + 2\n\t"
199
+ /*
99
+ "str %0, %1\n\t"
200
+ * Shifts larger than the element size are architecturally valid.
100
+ "bx %0\n"
201
+ * Signed results in all sign bits. With rounding, this produces
101
+ "1:"
202
+ * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
102
+ : "=&r"(tmp), "=m"(expected));
203
+ * I.e. always zero.
204
+ */
205
+ tcg_gen_gvec_dup_imm(vece, rd_ofs, opr_sz, max_sz, 0);
206
+ } else {
207
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
208
+ }
209
+}
210
+
211
+static void gen_srsra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
212
+{
213
+ TCGv_i64 t = tcg_temp_new_i64();
214
+
215
+ gen_srshr8_i64(t, a, sh);
216
+ tcg_gen_vec_add8_i64(d, d, t);
217
+ tcg_temp_free_i64(t);
218
+}
219
+
220
+static void gen_srsra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
221
+{
222
+ TCGv_i64 t = tcg_temp_new_i64();
223
+
224
+ gen_srshr16_i64(t, a, sh);
225
+ tcg_gen_vec_add16_i64(d, d, t);
226
+ tcg_temp_free_i64(t);
227
+}
228
+
229
+static void gen_srsra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
230
+{
231
+ TCGv_i32 t = tcg_temp_new_i32();
232
+
233
+ gen_srshr32_i32(t, a, sh);
234
+ tcg_gen_add_i32(d, d, t);
235
+ tcg_temp_free_i32(t);
236
+}
237
+
238
+static void gen_srsra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
239
+{
240
+ TCGv_i64 t = tcg_temp_new_i64();
241
+
242
+ gen_srshr64_i64(t, a, sh);
243
+ tcg_gen_add_i64(d, d, t);
244
+ tcg_temp_free_i64(t);
245
+}
246
+
247
+static void gen_srsra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
248
+{
249
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
250
+
251
+ gen_srshr_vec(vece, t, a, sh);
252
+ tcg_gen_add_vec(vece, d, d, t);
253
+ tcg_temp_free_vec(t);
254
+}
255
+
256
+void gen_gvec_srsra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
257
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz)
258
+{
259
+ static const TCGOpcode vecop_list[] = {
260
+ INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
261
+ };
262
+ static const GVecGen2i ops[4] = {
263
+ { .fni8 = gen_srsra8_i64,
264
+ .fniv = gen_srsra_vec,
265
+ .fno = gen_helper_gvec_srsra_b,
266
+ .opt_opc = vecop_list,
267
+ .load_dest = true,
268
+ .vece = MO_8 },
269
+ { .fni8 = gen_srsra16_i64,
270
+ .fniv = gen_srsra_vec,
271
+ .fno = gen_helper_gvec_srsra_h,
272
+ .opt_opc = vecop_list,
273
+ .load_dest = true,
274
+ .vece = MO_16 },
275
+ { .fni4 = gen_srsra32_i32,
276
+ .fniv = gen_srsra_vec,
277
+ .fno = gen_helper_gvec_srsra_s,
278
+ .opt_opc = vecop_list,
279
+ .load_dest = true,
280
+ .vece = MO_32 },
281
+ { .fni8 = gen_srsra64_i64,
282
+ .fniv = gen_srsra_vec,
283
+ .fno = gen_helper_gvec_srsra_d,
284
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
285
+ .opt_opc = vecop_list,
286
+ .load_dest = true,
287
+ .vece = MO_64 },
288
+ };
289
+
290
+ /* tszimm encoding produces immediates in the range [1..esize] */
291
+ tcg_debug_assert(shift > 0);
292
+ tcg_debug_assert(shift <= (8 << vece));
293
+
103
+
294
+ /*
104
+ /*
295
+ * Shifts larger than the element size are architecturally valid.
105
+ * From v8, it is CONSTRAINED UNPREDICTABLE whether BXWritePC aligns
296
+ * Signed results in all sign bits. With rounding, this produces
106
+ * the address or not. If so, we can legitimately fall through.
297
+ * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
298
+ * I.e. always zero. With accumulation, this leaves D unchanged.
299
+ */
107
+ */
300
+ if (shift == (8 << vece)) {
108
+ return EXIT_SUCCESS;
301
+ /* Nop, but we do need to clear the tail. */
302
+ tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
303
+ } else {
304
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
305
+ }
306
+}
109
+}
110
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
111
index XXXXXXX..XXXXXXX 100644
112
--- a/tests/tcg/aarch64/Makefile.target
113
+++ b/tests/tcg/aarch64/Makefile.target
114
@@ -XXX,XX +XXX,XX @@ VPATH         += $(ARM_SRC)
115
AARCH64_SRC=$(SRC_PATH)/tests/tcg/aarch64
116
VPATH         += $(AARCH64_SRC)
117
118
-# Float-convert Tests
119
-AARCH64_TESTS=fcvt
120
+# Base architecture tests
121
+AARCH64_TESTS=fcvt pcalign-a64
122
123
fcvt: LDFLAGS+=-lm
124
125
diff --git a/tests/tcg/arm/Makefile.target b/tests/tcg/arm/Makefile.target
126
index XXXXXXX..XXXXXXX 100644
127
--- a/tests/tcg/arm/Makefile.target
128
+++ b/tests/tcg/arm/Makefile.target
129
@@ -XXX,XX +XXX,XX @@ run-fcvt: fcvt
130
    $(call run-test,fcvt,$(QEMU) $<,"$< on $(TARGET_NAME)")
131
    $(call diff-out,fcvt,$(ARM_SRC)/fcvt.ref)
132
133
+# PC alignment test
134
+ARM_TESTS += pcalign-a32
135
+pcalign-a32: CFLAGS+=-marm
307
+
136
+
308
+static void gen_urshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
137
ifeq ($(CONFIG_ARM_COMPATIBLE_SEMIHOSTING),y)
309
+{
138
310
+ TCGv_i64 t = tcg_temp_new_i64();
139
# Semihosting smoke test for linux-user
311
+
312
+ tcg_gen_shri_i64(t, a, sh - 1);
313
+ tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
314
+ tcg_gen_vec_shr8i_i64(d, a, sh);
315
+ tcg_gen_vec_add8_i64(d, d, t);
316
+ tcg_temp_free_i64(t);
317
+}
318
+
319
+static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
320
+{
321
+ TCGv_i64 t = tcg_temp_new_i64();
322
+
323
+ tcg_gen_shri_i64(t, a, sh - 1);
324
+ tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
325
+ tcg_gen_vec_shr16i_i64(d, a, sh);
326
+ tcg_gen_vec_add16_i64(d, d, t);
327
+ tcg_temp_free_i64(t);
328
+}
329
+
330
+static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
331
+{
332
+ TCGv_i32 t = tcg_temp_new_i32();
333
+
334
+ tcg_gen_extract_i32(t, a, sh - 1, 1);
335
+ tcg_gen_shri_i32(d, a, sh);
336
+ tcg_gen_add_i32(d, d, t);
337
+ tcg_temp_free_i32(t);
338
+}
339
+
340
+static void gen_urshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
341
+{
342
+ TCGv_i64 t = tcg_temp_new_i64();
343
+
344
+ tcg_gen_extract_i64(t, a, sh - 1, 1);
345
+ tcg_gen_shri_i64(d, a, sh);
346
+ tcg_gen_add_i64(d, d, t);
347
+ tcg_temp_free_i64(t);
348
+}
349
+
350
+static void gen_urshr_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t shift)
351
+{
352
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
353
+ TCGv_vec ones = tcg_temp_new_vec_matching(d);
354
+
355
+ tcg_gen_shri_vec(vece, t, a, shift - 1);
356
+ tcg_gen_dupi_vec(vece, ones, 1);
357
+ tcg_gen_and_vec(vece, t, t, ones);
358
+ tcg_gen_shri_vec(vece, d, a, shift);
359
+ tcg_gen_add_vec(vece, d, d, t);
360
+
361
+ tcg_temp_free_vec(t);
362
+ tcg_temp_free_vec(ones);
363
+}
364
+
365
+void gen_gvec_urshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
366
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz)
367
+{
368
+ static const TCGOpcode vecop_list[] = {
369
+ INDEX_op_shri_vec, INDEX_op_add_vec, 0
370
+ };
371
+ static const GVecGen2i ops[4] = {
372
+ { .fni8 = gen_urshr8_i64,
373
+ .fniv = gen_urshr_vec,
374
+ .fno = gen_helper_gvec_urshr_b,
375
+ .opt_opc = vecop_list,
376
+ .vece = MO_8 },
377
+ { .fni8 = gen_urshr16_i64,
378
+ .fniv = gen_urshr_vec,
379
+ .fno = gen_helper_gvec_urshr_h,
380
+ .opt_opc = vecop_list,
381
+ .vece = MO_16 },
382
+ { .fni4 = gen_urshr32_i32,
383
+ .fniv = gen_urshr_vec,
384
+ .fno = gen_helper_gvec_urshr_s,
385
+ .opt_opc = vecop_list,
386
+ .vece = MO_32 },
387
+ { .fni8 = gen_urshr64_i64,
388
+ .fniv = gen_urshr_vec,
389
+ .fno = gen_helper_gvec_urshr_d,
390
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
391
+ .opt_opc = vecop_list,
392
+ .vece = MO_64 },
393
+ };
394
+
395
+ /* tszimm encoding produces immediates in the range [1..esize] */
396
+ tcg_debug_assert(shift > 0);
397
+ tcg_debug_assert(shift <= (8 << vece));
398
+
399
+ if (shift == (8 << vece)) {
400
+ /*
401
+ * Shifts larger than the element size are architecturally valid.
402
+ * Unsigned results in zero. With rounding, this produces a
403
+ * copy of the most significant bit.
404
+ */
405
+ tcg_gen_gvec_shri(vece, rd_ofs, rm_ofs, shift - 1, opr_sz, max_sz);
406
+ } else {
407
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
408
+ }
409
+}
410
+
411
+static void gen_ursra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
412
+{
413
+ TCGv_i64 t = tcg_temp_new_i64();
414
+
415
+ if (sh == 8) {
416
+ tcg_gen_vec_shr8i_i64(t, a, 7);
417
+ } else {
418
+ gen_urshr8_i64(t, a, sh);
419
+ }
420
+ tcg_gen_vec_add8_i64(d, d, t);
421
+ tcg_temp_free_i64(t);
422
+}
423
+
424
+static void gen_ursra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
425
+{
426
+ TCGv_i64 t = tcg_temp_new_i64();
427
+
428
+ if (sh == 16) {
429
+ tcg_gen_vec_shr16i_i64(t, a, 15);
430
+ } else {
431
+ gen_urshr16_i64(t, a, sh);
432
+ }
433
+ tcg_gen_vec_add16_i64(d, d, t);
434
+ tcg_temp_free_i64(t);
435
+}
436
+
437
+static void gen_ursra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
438
+{
439
+ TCGv_i32 t = tcg_temp_new_i32();
440
+
441
+ if (sh == 32) {
442
+ tcg_gen_shri_i32(t, a, 31);
443
+ } else {
444
+ gen_urshr32_i32(t, a, sh);
445
+ }
446
+ tcg_gen_add_i32(d, d, t);
447
+ tcg_temp_free_i32(t);
448
+}
449
+
450
+static void gen_ursra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
451
+{
452
+ TCGv_i64 t = tcg_temp_new_i64();
453
+
454
+ if (sh == 64) {
455
+ tcg_gen_shri_i64(t, a, 63);
456
+ } else {
457
+ gen_urshr64_i64(t, a, sh);
458
+ }
459
+ tcg_gen_add_i64(d, d, t);
460
+ tcg_temp_free_i64(t);
461
+}
462
+
463
+static void gen_ursra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
464
+{
465
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
466
+
467
+ if (sh == (8 << vece)) {
468
+ tcg_gen_shri_vec(vece, t, a, sh - 1);
469
+ } else {
470
+ gen_urshr_vec(vece, t, a, sh);
471
+ }
472
+ tcg_gen_add_vec(vece, d, d, t);
473
+ tcg_temp_free_vec(t);
474
+}
475
+
476
+void gen_gvec_ursra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
477
+ int64_t shift, uint32_t opr_sz, uint32_t max_sz)
478
+{
479
+ static const TCGOpcode vecop_list[] = {
480
+ INDEX_op_shri_vec, INDEX_op_add_vec, 0
481
+ };
482
+ static const GVecGen2i ops[4] = {
483
+ { .fni8 = gen_ursra8_i64,
484
+ .fniv = gen_ursra_vec,
485
+ .fno = gen_helper_gvec_ursra_b,
486
+ .opt_opc = vecop_list,
487
+ .load_dest = true,
488
+ .vece = MO_8 },
489
+ { .fni8 = gen_ursra16_i64,
490
+ .fniv = gen_ursra_vec,
491
+ .fno = gen_helper_gvec_ursra_h,
492
+ .opt_opc = vecop_list,
493
+ .load_dest = true,
494
+ .vece = MO_16 },
495
+ { .fni4 = gen_ursra32_i32,
496
+ .fniv = gen_ursra_vec,
497
+ .fno = gen_helper_gvec_ursra_s,
498
+ .opt_opc = vecop_list,
499
+ .load_dest = true,
500
+ .vece = MO_32 },
501
+ { .fni8 = gen_ursra64_i64,
502
+ .fniv = gen_ursra_vec,
503
+ .fno = gen_helper_gvec_ursra_d,
504
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
505
+ .opt_opc = vecop_list,
506
+ .load_dest = true,
507
+ .vece = MO_64 },
508
+ };
509
+
510
+ /* tszimm encoding produces immediates in the range [1..esize] */
511
+ tcg_debug_assert(shift > 0);
512
+ tcg_debug_assert(shift <= (8 << vece));
513
+
514
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
515
+}
516
+
517
static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
518
{
519
uint64_t mask = dup_const(MO_8, 0xff >> shift);
520
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
521
}
522
return 0;
523
524
+ case 2: /* VRSHR */
525
+ /* Right shift comes here negative. */
526
+ shift = -shift;
527
+ if (u) {
528
+ gen_gvec_urshr(size, rd_ofs, rm_ofs, shift,
529
+ vec_size, vec_size);
530
+ } else {
531
+ gen_gvec_srshr(size, rd_ofs, rm_ofs, shift,
532
+ vec_size, vec_size);
533
+ }
534
+ return 0;
535
+
536
+ case 3: /* VRSRA */
537
+ /* Right shift comes here negative. */
538
+ shift = -shift;
539
+ if (u) {
540
+ gen_gvec_ursra(size, rd_ofs, rm_ofs, shift,
541
+ vec_size, vec_size);
542
+ } else {
543
+ gen_gvec_srsra(size, rd_ofs, rm_ofs, shift,
544
+ vec_size, vec_size);
545
+ }
546
+ return 0;
547
+
548
case 4: /* VSRI */
549
if (!u) {
550
return 1;
551
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
552
neon_load_reg64(cpu_V0, rm + pass);
553
tcg_gen_movi_i64(cpu_V1, imm);
554
switch (op) {
555
- case 2: /* VRSHR */
556
- case 3: /* VRSRA */
557
- if (u)
558
- gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
559
- else
560
- gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
561
- break;
562
case 6: /* VQSHLU */
563
gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
564
cpu_V0, cpu_V1);
565
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
566
default:
567
g_assert_not_reached();
568
}
569
- if (op == 3) {
570
- /* Accumulate. */
571
- neon_load_reg64(cpu_V1, rd + pass);
572
- tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
573
- }
574
neon_store_reg64(cpu_V0, rd + pass);
575
} else { /* size < 3 */
576
/* Operands in T0 and T1. */
577
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
578
tmp2 = tcg_temp_new_i32();
579
tcg_gen_movi_i32(tmp2, imm);
580
switch (op) {
581
- case 2: /* VRSHR */
582
- case 3: /* VRSRA */
583
- GEN_NEON_INTEGER_OP(rshl);
584
- break;
585
case 6: /* VQSHLU */
586
switch (size) {
587
case 0:
588
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
589
g_assert_not_reached();
590
}
591
tcg_temp_free_i32(tmp2);
592
-
593
- if (op == 3) {
594
- /* Accumulate. */
595
- tmp2 = neon_load_reg(rd, pass);
596
- gen_neon_add(size, tmp, tmp2);
597
- tcg_temp_free_i32(tmp2);
598
- }
599
neon_store_reg(rd, pass, tmp);
600
}
601
} /* for pass */
602
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
603
index XXXXXXX..XXXXXXX 100644
604
--- a/target/arm/vec_helper.c
605
+++ b/target/arm/vec_helper.c
606
@@ -XXX,XX +XXX,XX @@ DO_SRA(gvec_usra_d, uint64_t)
607
608
#undef DO_SRA
609
610
+#define DO_RSHR(NAME, TYPE) \
611
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
612
+{ \
613
+ intptr_t i, oprsz = simd_oprsz(desc); \
614
+ int shift = simd_data(desc); \
615
+ TYPE *d = vd, *n = vn; \
616
+ for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
617
+ TYPE tmp = n[i] >> (shift - 1); \
618
+ d[i] = (tmp >> 1) + (tmp & 1); \
619
+ } \
620
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
621
+}
622
+
623
+DO_RSHR(gvec_srshr_b, int8_t)
624
+DO_RSHR(gvec_srshr_h, int16_t)
625
+DO_RSHR(gvec_srshr_s, int32_t)
626
+DO_RSHR(gvec_srshr_d, int64_t)
627
+
628
+DO_RSHR(gvec_urshr_b, uint8_t)
629
+DO_RSHR(gvec_urshr_h, uint16_t)
630
+DO_RSHR(gvec_urshr_s, uint32_t)
631
+DO_RSHR(gvec_urshr_d, uint64_t)
632
+
633
+#undef DO_RSHR
634
+
635
+#define DO_RSRA(NAME, TYPE) \
636
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
637
+{ \
638
+ intptr_t i, oprsz = simd_oprsz(desc); \
639
+ int shift = simd_data(desc); \
640
+ TYPE *d = vd, *n = vn; \
641
+ for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
642
+ TYPE tmp = n[i] >> (shift - 1); \
643
+ d[i] += (tmp >> 1) + (tmp & 1); \
644
+ } \
645
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
646
+}
647
+
648
+DO_RSRA(gvec_srsra_b, int8_t)
649
+DO_RSRA(gvec_srsra_h, int16_t)
650
+DO_RSRA(gvec_srsra_s, int32_t)
651
+DO_RSRA(gvec_srsra_d, int64_t)
652
+
653
+DO_RSRA(gvec_ursra_b, uint8_t)
654
+DO_RSRA(gvec_ursra_h, uint16_t)
655
+DO_RSRA(gvec_ursra_s, uint32_t)
656
+DO_RSRA(gvec_ursra_d, uint64_t)
657
+
658
+#undef DO_RSRA
659
+
660
/*
661
* Convert float16 to float32, raising no exceptions and
662
* preserving exceptional values, including SNaN.
663
--
140
--
664
2.20.1
141
2.25.1
665
142
666
143
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Provide a functional interface for the vector expansion.
4
This fits better with the existing set of helpers that
5
we provide for other operations.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200513163245.17915-11-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate.h | 13 +-
13
target/arm/translate-a64.c | 22 ++-
14
target/arm/translate-neon.inc.c | 19 +--
15
target/arm/translate.c | 228 +++++++++++++++++---------------
16
4 files changed, 147 insertions(+), 135 deletions(-)
17
18
diff --git a/target/arm/translate.h b/target/arm/translate.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.h
21
+++ b/target/arm/translate.h
22
@@ -XXX,XX +XXX,XX @@ void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
23
void gen_gvec_ushl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
24
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
25
26
-extern const GVecGen4 uqadd_op[4];
27
-extern const GVecGen4 sqadd_op[4];
28
-extern const GVecGen4 uqsub_op[4];
29
-extern const GVecGen4 sqsub_op[4];
30
void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
31
void gen_ushl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
32
void gen_sshl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
33
void gen_ushl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
34
void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
35
36
+void gen_gvec_uqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
37
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
38
+void gen_gvec_sqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
39
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
40
+void gen_gvec_uqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
41
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
42
+void gen_gvec_sqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
43
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
44
+
45
void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
46
int64_t shift, uint32_t opr_sz, uint32_t max_sz);
47
void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
48
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/translate-a64.c
51
+++ b/target/arm/translate-a64.c
52
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
53
54
switch (opcode) {
55
case 0x01: /* SQADD, UQADD */
56
- tcg_gen_gvec_4(vec_full_reg_offset(s, rd),
57
- offsetof(CPUARMState, vfp.qc),
58
- vec_full_reg_offset(s, rn),
59
- vec_full_reg_offset(s, rm),
60
- is_q ? 16 : 8, vec_full_reg_size(s),
61
- (u ? uqadd_op : sqadd_op) + size);
62
+ if (u) {
63
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uqadd_qc, size);
64
+ } else {
65
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqadd_qc, size);
66
+ }
67
return;
68
case 0x05: /* SQSUB, UQSUB */
69
- tcg_gen_gvec_4(vec_full_reg_offset(s, rd),
70
- offsetof(CPUARMState, vfp.qc),
71
- vec_full_reg_offset(s, rn),
72
- vec_full_reg_offset(s, rm),
73
- is_q ? 16 : 8, vec_full_reg_size(s),
74
- (u ? uqsub_op : sqsub_op) + size);
75
+ if (u) {
76
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uqsub_qc, size);
77
+ } else {
78
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqsub_qc, size);
79
+ }
80
return;
81
case 0x08: /* SSHL, USHL */
82
if (u) {
83
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/target/arm/translate-neon.inc.c
86
+++ b/target/arm/translate-neon.inc.c
87
@@ -XXX,XX +XXX,XX @@ DO_3SAME(VORN, tcg_gen_gvec_orc)
88
DO_3SAME(VEOR, tcg_gen_gvec_xor)
89
DO_3SAME(VSHL_S, gen_gvec_sshl)
90
DO_3SAME(VSHL_U, gen_gvec_ushl)
91
+DO_3SAME(VQADD_S, gen_gvec_sqadd_qc)
92
+DO_3SAME(VQADD_U, gen_gvec_uqadd_qc)
93
+DO_3SAME(VQSUB_S, gen_gvec_sqsub_qc)
94
+DO_3SAME(VQSUB_U, gen_gvec_uqsub_qc)
95
96
/* These insns are all gvec_bitsel but with the inputs in various orders. */
97
#define DO_3SAME_BITSEL(INSN, O1, O2, O3) \
98
@@ -XXX,XX +XXX,XX @@ DO_3SAME_CMP(VCGE_S, TCG_COND_GE)
99
DO_3SAME_CMP(VCGE_U, TCG_COND_GEU)
100
DO_3SAME_CMP(VCEQ, TCG_COND_EQ)
101
102
-#define DO_3SAME_GVEC4(INSN, OPARRAY) \
103
- static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
104
- uint32_t rn_ofs, uint32_t rm_ofs, \
105
- uint32_t oprsz, uint32_t maxsz) \
106
- { \
107
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc), \
108
- rn_ofs, rm_ofs, oprsz, maxsz, &OPARRAY[vece]); \
109
- } \
110
- DO_3SAME(INSN, gen_##INSN##_3s)
111
-
112
-DO_3SAME_GVEC4(VQADD_S, sqadd_op)
113
-DO_3SAME_GVEC4(VQADD_U, uqadd_op)
114
-DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
115
-DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
116
-
117
static void gen_VMUL_p_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
118
uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
119
{
120
diff --git a/target/arm/translate.c b/target/arm/translate.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/target/arm/translate.c
123
+++ b/target/arm/translate.c
124
@@ -XXX,XX +XXX,XX @@ static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
125
tcg_temp_free_vec(x);
126
}
127
128
-static const TCGOpcode vecop_list_uqadd[] = {
129
- INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
130
-};
131
-
132
-const GVecGen4 uqadd_op[4] = {
133
- { .fniv = gen_uqadd_vec,
134
- .fno = gen_helper_gvec_uqadd_b,
135
- .write_aofs = true,
136
- .opt_opc = vecop_list_uqadd,
137
- .vece = MO_8 },
138
- { .fniv = gen_uqadd_vec,
139
- .fno = gen_helper_gvec_uqadd_h,
140
- .write_aofs = true,
141
- .opt_opc = vecop_list_uqadd,
142
- .vece = MO_16 },
143
- { .fniv = gen_uqadd_vec,
144
- .fno = gen_helper_gvec_uqadd_s,
145
- .write_aofs = true,
146
- .opt_opc = vecop_list_uqadd,
147
- .vece = MO_32 },
148
- { .fniv = gen_uqadd_vec,
149
- .fno = gen_helper_gvec_uqadd_d,
150
- .write_aofs = true,
151
- .opt_opc = vecop_list_uqadd,
152
- .vece = MO_64 },
153
-};
154
+void gen_gvec_uqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
155
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
156
+{
157
+ static const TCGOpcode vecop_list[] = {
158
+ INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
159
+ };
160
+ static const GVecGen4 ops[4] = {
161
+ { .fniv = gen_uqadd_vec,
162
+ .fno = gen_helper_gvec_uqadd_b,
163
+ .write_aofs = true,
164
+ .opt_opc = vecop_list,
165
+ .vece = MO_8 },
166
+ { .fniv = gen_uqadd_vec,
167
+ .fno = gen_helper_gvec_uqadd_h,
168
+ .write_aofs = true,
169
+ .opt_opc = vecop_list,
170
+ .vece = MO_16 },
171
+ { .fniv = gen_uqadd_vec,
172
+ .fno = gen_helper_gvec_uqadd_s,
173
+ .write_aofs = true,
174
+ .opt_opc = vecop_list,
175
+ .vece = MO_32 },
176
+ { .fniv = gen_uqadd_vec,
177
+ .fno = gen_helper_gvec_uqadd_d,
178
+ .write_aofs = true,
179
+ .opt_opc = vecop_list,
180
+ .vece = MO_64 },
181
+ };
182
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
183
+ rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
184
+}
185
186
static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
187
TCGv_vec a, TCGv_vec b)
188
@@ -XXX,XX +XXX,XX @@ static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
189
tcg_temp_free_vec(x);
190
}
191
192
-static const TCGOpcode vecop_list_sqadd[] = {
193
- INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
194
-};
195
-
196
-const GVecGen4 sqadd_op[4] = {
197
- { .fniv = gen_sqadd_vec,
198
- .fno = gen_helper_gvec_sqadd_b,
199
- .opt_opc = vecop_list_sqadd,
200
- .write_aofs = true,
201
- .vece = MO_8 },
202
- { .fniv = gen_sqadd_vec,
203
- .fno = gen_helper_gvec_sqadd_h,
204
- .opt_opc = vecop_list_sqadd,
205
- .write_aofs = true,
206
- .vece = MO_16 },
207
- { .fniv = gen_sqadd_vec,
208
- .fno = gen_helper_gvec_sqadd_s,
209
- .opt_opc = vecop_list_sqadd,
210
- .write_aofs = true,
211
- .vece = MO_32 },
212
- { .fniv = gen_sqadd_vec,
213
- .fno = gen_helper_gvec_sqadd_d,
214
- .opt_opc = vecop_list_sqadd,
215
- .write_aofs = true,
216
- .vece = MO_64 },
217
-};
218
+void gen_gvec_sqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
219
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
220
+{
221
+ static const TCGOpcode vecop_list[] = {
222
+ INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
223
+ };
224
+ static const GVecGen4 ops[4] = {
225
+ { .fniv = gen_sqadd_vec,
226
+ .fno = gen_helper_gvec_sqadd_b,
227
+ .opt_opc = vecop_list,
228
+ .write_aofs = true,
229
+ .vece = MO_8 },
230
+ { .fniv = gen_sqadd_vec,
231
+ .fno = gen_helper_gvec_sqadd_h,
232
+ .opt_opc = vecop_list,
233
+ .write_aofs = true,
234
+ .vece = MO_16 },
235
+ { .fniv = gen_sqadd_vec,
236
+ .fno = gen_helper_gvec_sqadd_s,
237
+ .opt_opc = vecop_list,
238
+ .write_aofs = true,
239
+ .vece = MO_32 },
240
+ { .fniv = gen_sqadd_vec,
241
+ .fno = gen_helper_gvec_sqadd_d,
242
+ .opt_opc = vecop_list,
243
+ .write_aofs = true,
244
+ .vece = MO_64 },
245
+ };
246
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
247
+ rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
248
+}
249
250
static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
251
TCGv_vec a, TCGv_vec b)
252
@@ -XXX,XX +XXX,XX @@ static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
253
tcg_temp_free_vec(x);
254
}
255
256
-static const TCGOpcode vecop_list_uqsub[] = {
257
- INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
258
-};
259
-
260
-const GVecGen4 uqsub_op[4] = {
261
- { .fniv = gen_uqsub_vec,
262
- .fno = gen_helper_gvec_uqsub_b,
263
- .opt_opc = vecop_list_uqsub,
264
- .write_aofs = true,
265
- .vece = MO_8 },
266
- { .fniv = gen_uqsub_vec,
267
- .fno = gen_helper_gvec_uqsub_h,
268
- .opt_opc = vecop_list_uqsub,
269
- .write_aofs = true,
270
- .vece = MO_16 },
271
- { .fniv = gen_uqsub_vec,
272
- .fno = gen_helper_gvec_uqsub_s,
273
- .opt_opc = vecop_list_uqsub,
274
- .write_aofs = true,
275
- .vece = MO_32 },
276
- { .fniv = gen_uqsub_vec,
277
- .fno = gen_helper_gvec_uqsub_d,
278
- .opt_opc = vecop_list_uqsub,
279
- .write_aofs = true,
280
- .vece = MO_64 },
281
-};
282
+void gen_gvec_uqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
283
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
284
+{
285
+ static const TCGOpcode vecop_list[] = {
286
+ INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
287
+ };
288
+ static const GVecGen4 ops[4] = {
289
+ { .fniv = gen_uqsub_vec,
290
+ .fno = gen_helper_gvec_uqsub_b,
291
+ .opt_opc = vecop_list,
292
+ .write_aofs = true,
293
+ .vece = MO_8 },
294
+ { .fniv = gen_uqsub_vec,
295
+ .fno = gen_helper_gvec_uqsub_h,
296
+ .opt_opc = vecop_list,
297
+ .write_aofs = true,
298
+ .vece = MO_16 },
299
+ { .fniv = gen_uqsub_vec,
300
+ .fno = gen_helper_gvec_uqsub_s,
301
+ .opt_opc = vecop_list,
302
+ .write_aofs = true,
303
+ .vece = MO_32 },
304
+ { .fniv = gen_uqsub_vec,
305
+ .fno = gen_helper_gvec_uqsub_d,
306
+ .opt_opc = vecop_list,
307
+ .write_aofs = true,
308
+ .vece = MO_64 },
309
+ };
310
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
311
+ rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
312
+}
313
314
static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
315
TCGv_vec a, TCGv_vec b)
316
@@ -XXX,XX +XXX,XX @@ static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
317
tcg_temp_free_vec(x);
318
}
319
320
-static const TCGOpcode vecop_list_sqsub[] = {
321
- INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
322
-};
323
-
324
-const GVecGen4 sqsub_op[4] = {
325
- { .fniv = gen_sqsub_vec,
326
- .fno = gen_helper_gvec_sqsub_b,
327
- .opt_opc = vecop_list_sqsub,
328
- .write_aofs = true,
329
- .vece = MO_8 },
330
- { .fniv = gen_sqsub_vec,
331
- .fno = gen_helper_gvec_sqsub_h,
332
- .opt_opc = vecop_list_sqsub,
333
- .write_aofs = true,
334
- .vece = MO_16 },
335
- { .fniv = gen_sqsub_vec,
336
- .fno = gen_helper_gvec_sqsub_s,
337
- .opt_opc = vecop_list_sqsub,
338
- .write_aofs = true,
339
- .vece = MO_32 },
340
- { .fniv = gen_sqsub_vec,
341
- .fno = gen_helper_gvec_sqsub_d,
342
- .opt_opc = vecop_list_sqsub,
343
- .write_aofs = true,
344
- .vece = MO_64 },
345
-};
346
+void gen_gvec_sqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
347
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
348
+{
349
+ static const TCGOpcode vecop_list[] = {
350
+ INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
351
+ };
352
+ static const GVecGen4 ops[4] = {
353
+ { .fniv = gen_sqsub_vec,
354
+ .fno = gen_helper_gvec_sqsub_b,
355
+ .opt_opc = vecop_list,
356
+ .write_aofs = true,
357
+ .vece = MO_8 },
358
+ { .fniv = gen_sqsub_vec,
359
+ .fno = gen_helper_gvec_sqsub_h,
360
+ .opt_opc = vecop_list,
361
+ .write_aofs = true,
362
+ .vece = MO_16 },
363
+ { .fniv = gen_sqsub_vec,
364
+ .fno = gen_helper_gvec_sqsub_s,
365
+ .opt_opc = vecop_list,
366
+ .write_aofs = true,
367
+ .vece = MO_32 },
368
+ { .fniv = gen_sqsub_vec,
369
+ .fno = gen_helper_gvec_sqsub_d,
370
+ .opt_opc = vecop_list,
371
+ .write_aofs = true,
372
+ .vece = MO_64 },
373
+ };
374
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
375
+ rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
376
+}
377
378
/* Translate a NEON data processing instruction. Return nonzero if the
379
instruction is invalid.
380
--
381
2.20.1
382
383
diff view generated by jsdifflib
1
Convert the Neon floating point VFMA and VFMS insn to decodetree.
1
In the SSE decode function gen_sse(), we combine a byte
2
These are the last insns in the 3-reg-same group so we can
2
'b' and a value 'b1' which can be [0..3], and switch on them:
3
remove all the support/loop code from the old decoder.
3
b |= (b1 << 8);
4
switch (b) {
5
...
6
default:
7
unknown_op:
8
gen_unknown_opcode(env, s);
9
return;
10
}
4
11
12
In three cases inside this switch, we were then also checking for
13
"if (b1 >= 2) { goto unknown_op; }".
14
However, this can never happen, because the 'case' values in each place
15
are 0x0nn or 0x1nn and the switch will have directed the b1 == (2, 3)
16
cases to the default already.
17
18
This check was added in commit c045af25a52e9 in 2010; the added code
19
was unnecessary then as well, and was apparently intended only to
20
ensure that we never accidentally ended up indexing off the end
21
of an sse_op_table with only 2 entries as a result of future bugs
22
in the decode logic.
23
24
Change the checks to assert() instead, and make sure they're always
25
immediately before the array access they are protecting.
26
27
Fixes: Coverity CID 1460207
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200512163904.10918-18-peter.maydell@linaro.org
8
---
30
---
9
target/arm/neon-dp.decode | 3 +
31
target/i386/tcg/translate.c | 12 +++---------
10
target/arm/translate-neon.inc.c | 41 ++++++++
32
1 file changed, 3 insertions(+), 9 deletions(-)
11
target/arm/translate.c | 176 +-------------------------------
12
3 files changed, 46 insertions(+), 174 deletions(-)
13
33
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
34
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
15
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/neon-dp.decode
36
--- a/target/i386/tcg/translate.c
17
+++ b/target/arm/neon-dp.decode
37
+++ b/target/i386/tcg/translate.c
18
@@ -XXX,XX +XXX,XX @@ SHA256H2_3s 1111 001 1 0 . 01 .... .... 1100 . 1 . 0 .... \
38
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
19
SHA256SU1_3s 1111 001 1 0 . 10 .... .... 1100 . 1 . 0 .... \
39
case 0x171: /* shift xmm, im */
20
vm=%vm_dp vn=%vn_dp vd=%vd_dp
40
case 0x172:
21
41
case 0x173:
22
+VFMA_fp_3s 1111 001 0 0 . 0 . .... .... 1100 ... 1 .... @3same_fp
42
- if (b1 >= 2) {
23
+VFMS_fp_3s 1111 001 0 0 . 1 . .... .... 1100 ... 1 .... @3same_fp
43
- goto unknown_op;
24
+
25
VQRDMLSH_3s 1111 001 1 0 . .. .... .... 1100 ... 1 .... @3same
26
27
VADD_fp_3s 1111 001 0 0 . 0 . .... .... 1101 ... 0 .... @3same_fp
28
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-neon.inc.c
31
+++ b/target/arm/translate-neon.inc.c
32
@@ -XXX,XX +XXX,XX @@ static bool trans_VRSQRTS_fp_3s(DisasContext *s, arg_3same *a)
33
return do_3same(s, a, gen_VRSQRTS_fp_3s);
34
}
35
36
+static void gen_VFMA_fp_3s(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm,
37
+ TCGv_ptr fpstatus)
38
+{
39
+ gen_helper_vfp_muladds(vd, vn, vm, vd, fpstatus);
40
+}
41
+
42
+static bool trans_VFMA_fp_3s(DisasContext *s, arg_3same *a)
43
+{
44
+ if (!dc_isar_feature(aa32_simdfmac, s)) {
45
+ return false;
46
+ }
47
+
48
+ if (a->size != 0) {
49
+ /* TODO fp16 support */
50
+ return false;
51
+ }
52
+
53
+ return do_3same_fp(s, a, gen_VFMA_fp_3s, true);
54
+}
55
+
56
+static void gen_VFMS_fp_3s(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm,
57
+ TCGv_ptr fpstatus)
58
+{
59
+ gen_helper_vfp_negs(vn, vn);
60
+ gen_helper_vfp_muladds(vd, vn, vm, vd, fpstatus);
61
+}
62
+
63
+static bool trans_VFMS_fp_3s(DisasContext *s, arg_3same *a)
64
+{
65
+ if (!dc_isar_feature(aa32_simdfmac, s)) {
66
+ return false;
67
+ }
68
+
69
+ if (a->size != 0) {
70
+ /* TODO fp16 support */
71
+ return false;
72
+ }
73
+
74
+ return do_3same_fp(s, a, gen_VFMS_fp_3s, true);
75
+}
76
+
77
static bool do_3same_fp_pair(DisasContext *s, arg_3same *a, VFPGen3OpSPFn *fn)
78
{
79
/* FP operations handled pairwise 32 bits at a time */
80
diff --git a/target/arm/translate.c b/target/arm/translate.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/translate.c
83
+++ b/target/arm/translate.c
84
@@ -XXX,XX +XXX,XX @@ static void gen_neon_narrow_op(int op, int u, int size,
85
}
86
}
87
88
-/* Symbolic constants for op fields for Neon 3-register same-length.
89
- * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
90
- * table A7-9.
91
- */
92
-#define NEON_3R_VHADD 0
93
-#define NEON_3R_VQADD 1
94
-#define NEON_3R_VRHADD 2
95
-#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
96
-#define NEON_3R_VHSUB 4
97
-#define NEON_3R_VQSUB 5
98
-#define NEON_3R_VCGT 6
99
-#define NEON_3R_VCGE 7
100
-#define NEON_3R_VSHL 8
101
-#define NEON_3R_VQSHL 9
102
-#define NEON_3R_VRSHL 10
103
-#define NEON_3R_VQRSHL 11
104
-#define NEON_3R_VMAX 12
105
-#define NEON_3R_VMIN 13
106
-#define NEON_3R_VABD 14
107
-#define NEON_3R_VABA 15
108
-#define NEON_3R_VADD_VSUB 16
109
-#define NEON_3R_VTST_VCEQ 17
110
-#define NEON_3R_VML 18 /* VMLA, VMLS */
111
-#define NEON_3R_VMUL 19
112
-#define NEON_3R_VPMAX 20
113
-#define NEON_3R_VPMIN 21
114
-#define NEON_3R_VQDMULH_VQRDMULH 22
115
-#define NEON_3R_VPADD_VQRDMLAH 23
116
-#define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
117
-#define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
118
-#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
119
-#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
120
-#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
121
-#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
122
-#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
123
-#define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
124
-
125
-static const uint8_t neon_3r_sizes[] = {
126
- [NEON_3R_VHADD] = 0x7,
127
- [NEON_3R_VQADD] = 0xf,
128
- [NEON_3R_VRHADD] = 0x7,
129
- [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
130
- [NEON_3R_VHSUB] = 0x7,
131
- [NEON_3R_VQSUB] = 0xf,
132
- [NEON_3R_VCGT] = 0x7,
133
- [NEON_3R_VCGE] = 0x7,
134
- [NEON_3R_VSHL] = 0xf,
135
- [NEON_3R_VQSHL] = 0xf,
136
- [NEON_3R_VRSHL] = 0xf,
137
- [NEON_3R_VQRSHL] = 0xf,
138
- [NEON_3R_VMAX] = 0x7,
139
- [NEON_3R_VMIN] = 0x7,
140
- [NEON_3R_VABD] = 0x7,
141
- [NEON_3R_VABA] = 0x7,
142
- [NEON_3R_VADD_VSUB] = 0xf,
143
- [NEON_3R_VTST_VCEQ] = 0x7,
144
- [NEON_3R_VML] = 0x7,
145
- [NEON_3R_VMUL] = 0x7,
146
- [NEON_3R_VPMAX] = 0x7,
147
- [NEON_3R_VPMIN] = 0x7,
148
- [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
149
- [NEON_3R_VPADD_VQRDMLAH] = 0x7,
150
- [NEON_3R_SHA] = 0xf, /* size field encodes op type */
151
- [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
152
- [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
153
- [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
154
- [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
155
- [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
156
- [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
157
- [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
158
-};
159
-
160
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
161
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
162
* table A7-13.
163
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
164
rm_ofs = neon_reg_offset(rm, 0);
165
166
if ((insn & (1 << 23)) == 0) {
167
- /* Three register same length. */
168
- op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
169
- /* Catch invalid op and bad size combinations: UNDEF */
170
- if ((neon_3r_sizes[op] & (1 << size)) == 0) {
171
- return 1;
172
- }
173
- /* All insns of this form UNDEF for either this condition or the
174
- * superset of cases "Q==1"; we catch the latter later.
175
- */
176
- if (q && ((rd | rn | rm) & 1)) {
177
- return 1;
178
- }
179
- switch (op) {
180
- case NEON_3R_VFM_VQRDMLSH:
181
- if (!u) {
182
- /* VFM, VFMS */
183
- if (size == 1) {
184
- return 1;
185
- }
186
- break;
187
- }
44
- }
188
- /* VQRDMLSH : handled by decodetree */
45
val = x86_ldub_code(env, s);
189
- return 1;
46
if (is_xmm) {
190
-
47
tcg_gen_movi_tl(s->T0, val);
191
- case NEON_3R_VADD_VSUB:
48
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
192
- case NEON_3R_LOGIC:
49
offsetof(CPUX86State, mmx_t0.MMX_L(1)));
193
- case NEON_3R_VMAX:
50
op1_offset = offsetof(CPUX86State,mmx_t0);
194
- case NEON_3R_VMIN:
51
}
195
- case NEON_3R_VTST_VCEQ:
52
+ assert(b1 < 2);
196
- case NEON_3R_VCGT:
53
sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
197
- case NEON_3R_VCGE:
54
(((modrm >> 3)) & 7)][b1];
198
- case NEON_3R_VQADD:
55
if (!sse_fn_epp) {
199
- case NEON_3R_VQSUB:
56
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
200
- case NEON_3R_VMUL:
57
rm = modrm & 7;
201
- case NEON_3R_VML:
58
reg = ((modrm >> 3) & 7) | REX_R(s);
202
- case NEON_3R_VSHL:
59
mod = (modrm >> 6) & 3;
203
- case NEON_3R_SHA:
60
- if (b1 >= 2) {
204
- case NEON_3R_VHADD:
61
- goto unknown_op;
205
- case NEON_3R_VRHADD:
206
- case NEON_3R_VHSUB:
207
- case NEON_3R_VABD:
208
- case NEON_3R_VABA:
209
- case NEON_3R_VQSHL:
210
- case NEON_3R_VRSHL:
211
- case NEON_3R_VQRSHL:
212
- case NEON_3R_VPMAX:
213
- case NEON_3R_VPMIN:
214
- case NEON_3R_VPADD_VQRDMLAH:
215
- case NEON_3R_VQDMULH_VQRDMULH:
216
- case NEON_3R_FLOAT_ARITH:
217
- case NEON_3R_FLOAT_MULTIPLY:
218
- case NEON_3R_FLOAT_CMP:
219
- case NEON_3R_FLOAT_ACMP:
220
- case NEON_3R_FLOAT_MINMAX:
221
- case NEON_3R_FLOAT_MISC:
222
- /* Already handled by decodetree */
223
- return 1;
224
- }
225
-
226
- if (size == 3) {
227
- /* 64-bit element instructions: handled by decodetree */
228
- return 1;
229
- }
230
- switch (op) {
231
- case NEON_3R_VFM_VQRDMLSH:
232
- if (!dc_isar_feature(aa32_simdfmac, s)) {
233
- return 1;
234
- }
62
- }
235
- break;
63
236
- default:
64
+ assert(b1 < 2);
237
- break;
65
sse_fn_epp = sse_op_table6[b].op[b1];
238
- }
66
if (!sse_fn_epp) {
239
-
67
goto unknown_op;
240
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
68
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
241
-
69
rm = modrm & 7;
242
- /* Elementwise. */
70
reg = ((modrm >> 3) & 7) | REX_R(s);
243
- tmp = neon_load_reg(rn, pass);
71
mod = (modrm >> 6) & 3;
244
- tmp2 = neon_load_reg(rm, pass);
72
- if (b1 >= 2) {
245
- switch (op) {
73
- goto unknown_op;
246
- case NEON_3R_VFM_VQRDMLSH:
247
- {
248
- /* VFMA, VFMS: fused multiply-add */
249
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
250
- TCGv_i32 tmp3 = neon_load_reg(rd, pass);
251
- if (size) {
252
- /* VFMS */
253
- gen_helper_vfp_negs(tmp, tmp);
254
- }
74
- }
255
- gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
75
256
- tcg_temp_free_i32(tmp3);
76
+ assert(b1 < 2);
257
- tcg_temp_free_ptr(fpstatus);
77
sse_fn_eppi = sse_op_table7[b].op[b1];
258
- break;
78
if (!sse_fn_eppi) {
259
- }
79
goto unknown_op;
260
- default:
261
- abort();
262
- }
263
- tcg_temp_free_i32(tmp2);
264
-
265
- neon_store_reg(rd, pass, tmp);
266
-
267
- } /* for pass */
268
- /* End of 3 register same size operations. */
269
+ /* Three register same length: handled by decodetree */
270
+ return 1;
271
} else if (insn & (1 << 4)) {
272
if ((insn & 0x00380080) != 0) {
273
/* Two registers and shift. */
274
--
80
--
275
2.20.1
81
2.25.1
276
82
277
83
diff view generated by jsdifflib
1
Convert the Neon fp VMAX/VMIN/VMAXNM/VMINNM/VRECPS/VRSQRTS 3-reg-same
1
The qemu-common.h header is not supposed to be included from any
2
insns to decodetree. (These are all the remaining non-accumulation
2
other header files, only from .c files (as documented in a comment at
3
instructions in this group.)
3
the start of it).
4
5
include/hw/i386/x86.h and include/hw/i386/microvm.h break this rule.
6
In fact, the include is not required at all, so we can just drop it
7
from both files.
4
8
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200512163904.10918-17-peter.maydell@linaro.org
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20211129200510.1233037-2-peter.maydell@linaro.org
8
---
13
---
9
target/arm/neon-dp.decode | 6 +++
14
include/hw/i386/microvm.h | 1 -
10
target/arm/translate-neon.inc.c | 70 +++++++++++++++++++++++++++++++++
15
include/hw/i386/x86.h | 1 -
11
target/arm/translate.c | 42 +-------------------
16
2 files changed, 2 deletions(-)
12
3 files changed, 78 insertions(+), 40 deletions(-)
13
17
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
18
diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/neon-dp.decode
20
--- a/include/hw/i386/microvm.h
17
+++ b/target/arm/neon-dp.decode
21
+++ b/include/hw/i386/microvm.h
18
@@ -XXX,XX +XXX,XX @@ VCGE_fp_3s 1111 001 1 0 . 0 . .... .... 1110 ... 0 .... @3same_fp
22
@@ -XXX,XX +XXX,XX @@
19
VACGE_fp_3s 1111 001 1 0 . 0 . .... .... 1110 ... 1 .... @3same_fp
23
#ifndef HW_I386_MICROVM_H
20
VCGT_fp_3s 1111 001 1 0 . 1 . .... .... 1110 ... 0 .... @3same_fp
24
#define HW_I386_MICROVM_H
21
VACGT_fp_3s 1111 001 1 0 . 1 . .... .... 1110 ... 1 .... @3same_fp
25
22
+VMAX_fp_3s 1111 001 0 0 . 0 . .... .... 1111 ... 0 .... @3same_fp
26
-#include "qemu-common.h"
23
+VMIN_fp_3s 1111 001 0 0 . 1 . .... .... 1111 ... 0 .... @3same_fp
27
#include "exec/hwaddr.h"
24
VPMAX_fp_3s 1111 001 1 0 . 0 . .... .... 1111 ... 0 .... @3same_fp_q0
28
#include "qemu/notify.h"
25
VPMIN_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 0 .... @3same_fp_q0
29
26
+VRECPS_fp_3s 1111 001 0 0 . 0 . .... .... 1111 ... 1 .... @3same_fp
30
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
27
+VRSQRTS_fp_3s 1111 001 0 0 . 1 . .... .... 1111 ... 1 .... @3same_fp
28
+VMAXNM_fp_3s 1111 001 1 0 . 0 . .... .... 1111 ... 1 .... @3same_fp
29
+VMINNM_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 1 .... @3same_fp
30
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
31
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate-neon.inc.c
32
--- a/include/hw/i386/x86.h
33
+++ b/target/arm/translate-neon.inc.c
33
+++ b/include/hw/i386/x86.h
34
@@ -XXX,XX +XXX,XX @@ DO_3S_FP(VCGE, gen_helper_neon_cge_f32, false)
34
@@ -XXX,XX +XXX,XX @@
35
DO_3S_FP(VCGT, gen_helper_neon_cgt_f32, false)
35
#ifndef HW_I386_X86_H
36
DO_3S_FP(VACGE, gen_helper_neon_acge_f32, false)
36
#define HW_I386_X86_H
37
DO_3S_FP(VACGT, gen_helper_neon_acgt_f32, false)
37
38
+DO_3S_FP(VMAX, gen_helper_vfp_maxs, false)
38
-#include "qemu-common.h"
39
+DO_3S_FP(VMIN, gen_helper_vfp_mins, false)
39
#include "exec/hwaddr.h"
40
40
#include "qemu/notify.h"
41
static void gen_VMLA_fp_3s(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm,
41
42
TCGv_ptr fpstatus)
43
@@ -XXX,XX +XXX,XX @@ static void gen_VMLS_fp_3s(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm,
44
DO_3S_FP(VMLA, gen_VMLA_fp_3s, true)
45
DO_3S_FP(VMLS, gen_VMLS_fp_3s, true)
46
47
+static bool trans_VMAXNM_fp_3s(DisasContext *s, arg_3same *a)
48
+{
49
+ if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
50
+ return false;
51
+ }
52
+
53
+ if (a->size != 0) {
54
+ /* TODO fp16 support */
55
+ return false;
56
+ }
57
+
58
+ return do_3same_fp(s, a, gen_helper_vfp_maxnums, false);
59
+}
60
+
61
+static bool trans_VMINNM_fp_3s(DisasContext *s, arg_3same *a)
62
+{
63
+ if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
64
+ return false;
65
+ }
66
+
67
+ if (a->size != 0) {
68
+ /* TODO fp16 support */
69
+ return false;
70
+ }
71
+
72
+ return do_3same_fp(s, a, gen_helper_vfp_minnums, false);
73
+}
74
+
75
+WRAP_ENV_FN(gen_VRECPS_tramp, gen_helper_recps_f32)
76
+
77
+static void gen_VRECPS_fp_3s(unsigned vece, uint32_t rd_ofs,
78
+ uint32_t rn_ofs, uint32_t rm_ofs,
79
+ uint32_t oprsz, uint32_t maxsz)
80
+{
81
+ static const GVecGen3 ops = { .fni4 = gen_VRECPS_tramp };
82
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &ops);
83
+}
84
+
85
+static bool trans_VRECPS_fp_3s(DisasContext *s, arg_3same *a)
86
+{
87
+ if (a->size != 0) {
88
+ /* TODO fp16 support */
89
+ return false;
90
+ }
91
+
92
+ return do_3same(s, a, gen_VRECPS_fp_3s);
93
+}
94
+
95
+WRAP_ENV_FN(gen_VRSQRTS_tramp, gen_helper_rsqrts_f32)
96
+
97
+static void gen_VRSQRTS_fp_3s(unsigned vece, uint32_t rd_ofs,
98
+ uint32_t rn_ofs, uint32_t rm_ofs,
99
+ uint32_t oprsz, uint32_t maxsz)
100
+{
101
+ static const GVecGen3 ops = { .fni4 = gen_VRSQRTS_tramp };
102
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &ops);
103
+}
104
+
105
+static bool trans_VRSQRTS_fp_3s(DisasContext *s, arg_3same *a)
106
+{
107
+ if (a->size != 0) {
108
+ /* TODO fp16 support */
109
+ return false;
110
+ }
111
+
112
+ return do_3same(s, a, gen_VRSQRTS_fp_3s);
113
+}
114
+
115
static bool do_3same_fp_pair(DisasContext *s, arg_3same *a, VFPGen3OpSPFn *fn)
116
{
117
/* FP operations handled pairwise 32 bits at a time */
118
diff --git a/target/arm/translate.c b/target/arm/translate.c
119
index XXXXXXX..XXXXXXX 100644
120
--- a/target/arm/translate.c
121
+++ b/target/arm/translate.c
122
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
123
case NEON_3R_FLOAT_MULTIPLY:
124
case NEON_3R_FLOAT_CMP:
125
case NEON_3R_FLOAT_ACMP:
126
+ case NEON_3R_FLOAT_MINMAX:
127
+ case NEON_3R_FLOAT_MISC:
128
/* Already handled by decodetree */
129
return 1;
130
}
131
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
132
return 1;
133
}
134
switch (op) {
135
- case NEON_3R_FLOAT_MINMAX:
136
- if (u) {
137
- return 1; /* VPMIN/VPMAX handled by decodetree */
138
- }
139
- break;
140
- case NEON_3R_FLOAT_MISC:
141
- /* VMAXNM/VMINNM in ARMv8 */
142
- if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
143
- return 1;
144
- }
145
- break;
146
case NEON_3R_VFM_VQRDMLSH:
147
if (!dc_isar_feature(aa32_simdfmac, s)) {
148
return 1;
149
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
150
tmp = neon_load_reg(rn, pass);
151
tmp2 = neon_load_reg(rm, pass);
152
switch (op) {
153
- case NEON_3R_FLOAT_MINMAX:
154
- {
155
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
156
- if (size == 0) {
157
- gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
158
- } else {
159
- gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
160
- }
161
- tcg_temp_free_ptr(fpstatus);
162
- break;
163
- }
164
- case NEON_3R_FLOAT_MISC:
165
- if (u) {
166
- /* VMAXNM/VMINNM */
167
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
168
- if (size == 0) {
169
- gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
170
- } else {
171
- gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
172
- }
173
- tcg_temp_free_ptr(fpstatus);
174
- } else {
175
- if (size == 0) {
176
- gen_helper_recps_f32(tmp, cpu_env, tmp, tmp2);
177
- } else {
178
- gen_helper_rsqrts_f32(tmp, cpu_env, tmp, tmp2);
179
- }
180
- }
181
- break;
182
case NEON_3R_VFM_VQRDMLSH:
183
{
184
/* VFMA, VFMS: fused multiply-add */
185
--
42
--
186
2.20.1
43
2.25.1
187
44
188
45
diff view generated by jsdifflib
1
The usual location for the env argument in the argument list of a TCG helper
1
The qemu-common.h header is not supposed to be included from any
2
is immediately after the return-value argument. recps_f32 and rsqrts_f32
2
other header files, only from .c files (as documented in a comment at
3
differ in that they put it at the end.
3
the start of it).
4
4
5
Move the env argument to its usual place; this will allow us to
5
Move the include to linux-user/hexagon/cpu_loop.c, which needs it for
6
more easily use these helper functions with the gvec APIs.
6
the declaration of cpu_exec_step_atomic().
7
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200512163904.10918-16-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
12
Message-id: 20211129200510.1233037-3-peter.maydell@linaro.org
11
---
13
---
12
target/arm/helper.h | 4 ++--
14
target/hexagon/cpu.h | 1 -
13
target/arm/translate.c | 4 ++--
15
linux-user/hexagon/cpu_loop.c | 1 +
14
target/arm/vfp_helper.c | 4 ++--
16
2 files changed, 1 insertion(+), 1 deletion(-)
15
3 files changed, 6 insertions(+), 6 deletions(-)
16
17
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
18
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.h
20
--- a/target/hexagon/cpu.h
20
+++ b/target/arm/helper.h
21
+++ b/target/hexagon/cpu.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(vfp_fcvt_f64_to_f16, TCG_CALL_NO_RWG, f16, f64, ptr, i32)
22
@@ -XXX,XX +XXX,XX @@ typedef struct CPUHexagonState CPUHexagonState;
22
DEF_HELPER_4(vfp_muladdd, f64, f64, f64, f64, ptr)
23
23
DEF_HELPER_4(vfp_muladds, f32, f32, f32, f32, ptr)
24
#include "fpu/softfloat-types.h"
24
25
25
-DEF_HELPER_3(recps_f32, f32, f32, f32, env)
26
-#include "qemu-common.h"
26
-DEF_HELPER_3(rsqrts_f32, f32, f32, f32, env)
27
#include "exec/cpu-defs.h"
27
+DEF_HELPER_3(recps_f32, f32, env, f32, f32)
28
#include "hex_regs.h"
28
+DEF_HELPER_3(rsqrts_f32, f32, env, f32, f32)
29
#include "mmvec/mmvec.h"
29
DEF_HELPER_FLAGS_2(recpe_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
30
diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
30
DEF_HELPER_FLAGS_2(recpe_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
31
DEF_HELPER_FLAGS_2(recpe_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
32
diff --git a/target/arm/translate.c b/target/arm/translate.c
33
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate.c
32
--- a/linux-user/hexagon/cpu_loop.c
35
+++ b/target/arm/translate.c
33
+++ b/linux-user/hexagon/cpu_loop.c
36
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
34
@@ -XXX,XX +XXX,XX @@
37
tcg_temp_free_ptr(fpstatus);
35
*/
38
} else {
36
39
if (size == 0) {
37
#include "qemu/osdep.h"
40
- gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
38
+#include "qemu-common.h"
41
+ gen_helper_recps_f32(tmp, cpu_env, tmp, tmp2);
39
#include "qemu.h"
42
} else {
40
#include "user-internals.h"
43
- gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
41
#include "cpu_loop-common.h"
44
+ gen_helper_rsqrts_f32(tmp, cpu_env, tmp, tmp2);
45
}
46
}
47
break;
48
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/vfp_helper.c
51
+++ b/target/arm/vfp_helper.c
52
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_fcvt_f64_to_f16)(float64 a, void *fpstp, uint32_t ahp_mode)
53
#define float32_three make_float32(0x40400000)
54
#define float32_one_point_five make_float32(0x3fc00000)
55
56
-float32 HELPER(recps_f32)(float32 a, float32 b, CPUARMState *env)
57
+float32 HELPER(recps_f32)(CPUARMState *env, float32 a, float32 b)
58
{
59
float_status *s = &env->vfp.standard_fp_status;
60
if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) ||
61
@@ -XXX,XX +XXX,XX @@ float32 HELPER(recps_f32)(float32 a, float32 b, CPUARMState *env)
62
return float32_sub(float32_two, float32_mul(a, b, s), s);
63
}
64
65
-float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUARMState *env)
66
+float32 HELPER(rsqrts_f32)(CPUARMState *env, float32 a, float32 b)
67
{
68
float_status *s = &env->vfp.standard_fp_status;
69
float32 product;
70
--
42
--
71
2.20.1
43
2.25.1
72
44
73
45
diff view generated by jsdifflib
1
Convert the Neon integer 3-reg-same compare insns VCGE, VCGT,
1
The qemu-common.h header is not supposed to be included from any
2
VCEQ, VACGE and VACGT to decodetree.
2
other header files, only from .c files (as documented in a comment at
3
the start of it).
4
5
Nothing actually relies on target/rx/cpu.h including it, so we can
6
just drop the include.
3
7
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200512163904.10918-15-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
12
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
13
Message-id: 20211129200510.1233037-4-peter.maydell@linaro.org
7
---
14
---
8
target/arm/neon-dp.decode | 5 +++++
15
target/rx/cpu.h | 1 -
9
target/arm/translate-neon.inc.c | 6 +++++
16
1 file changed, 1 deletion(-)
10
target/arm/translate.c | 39 ++-------------------------------
11
3 files changed, 13 insertions(+), 37 deletions(-)
12
17
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
18
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
14
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
20
--- a/target/rx/cpu.h
16
+++ b/target/arm/neon-dp.decode
21
+++ b/target/rx/cpu.h
17
@@ -XXX,XX +XXX,XX @@ VABD_fp_3s 1111 001 1 0 . 1 . .... .... 1101 ... 0 .... @3same_fp
22
@@ -XXX,XX +XXX,XX @@
18
VMLA_fp_3s 1111 001 0 0 . 0 . .... .... 1101 ... 1 .... @3same_fp
23
#define RX_CPU_H
19
VMLS_fp_3s 1111 001 0 0 . 1 . .... .... 1101 ... 1 .... @3same_fp
24
20
VMUL_fp_3s 1111 001 1 0 . 0 . .... .... 1101 ... 1 .... @3same_fp
25
#include "qemu/bitops.h"
21
+VCEQ_fp_3s 1111 001 0 0 . 0 . .... .... 1110 ... 0 .... @3same_fp
26
-#include "qemu-common.h"
22
+VCGE_fp_3s 1111 001 1 0 . 0 . .... .... 1110 ... 0 .... @3same_fp
27
#include "hw/registerfields.h"
23
+VACGE_fp_3s 1111 001 1 0 . 0 . .... .... 1110 ... 1 .... @3same_fp
28
#include "cpu-qom.h"
24
+VCGT_fp_3s 1111 001 1 0 . 1 . .... .... 1110 ... 0 .... @3same_fp
29
25
+VACGT_fp_3s 1111 001 1 0 . 1 . .... .... 1110 ... 1 .... @3same_fp
26
VPMAX_fp_3s 1111 001 1 0 . 0 . .... .... 1111 ... 0 .... @3same_fp_q0
27
VPMIN_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 0 .... @3same_fp_q0
28
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-neon.inc.c
31
+++ b/target/arm/translate-neon.inc.c
32
@@ -XXX,XX +XXX,XX @@ DO_3S_FP_GVEC(VMUL, gen_helper_gvec_fmul_s)
33
return do_3same_fp(s, a, FUNC, READS_VD); \
34
}
35
36
+DO_3S_FP(VCEQ, gen_helper_neon_ceq_f32, false)
37
+DO_3S_FP(VCGE, gen_helper_neon_cge_f32, false)
38
+DO_3S_FP(VCGT, gen_helper_neon_cgt_f32, false)
39
+DO_3S_FP(VACGE, gen_helper_neon_acge_f32, false)
40
+DO_3S_FP(VACGT, gen_helper_neon_acgt_f32, false)
41
+
42
static void gen_VMLA_fp_3s(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm,
43
TCGv_ptr fpstatus)
44
{
45
diff --git a/target/arm/translate.c b/target/arm/translate.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/translate.c
48
+++ b/target/arm/translate.c
49
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
50
case NEON_3R_VQDMULH_VQRDMULH:
51
case NEON_3R_FLOAT_ARITH:
52
case NEON_3R_FLOAT_MULTIPLY:
53
+ case NEON_3R_FLOAT_CMP:
54
+ case NEON_3R_FLOAT_ACMP:
55
/* Already handled by decodetree */
56
return 1;
57
}
58
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
59
return 1; /* VPMIN/VPMAX handled by decodetree */
60
}
61
break;
62
- case NEON_3R_FLOAT_CMP:
63
- if (!u && size) {
64
- /* no encoding for U=0 C=1x */
65
- return 1;
66
- }
67
- break;
68
- case NEON_3R_FLOAT_ACMP:
69
- if (!u) {
70
- return 1;
71
- }
72
- break;
73
case NEON_3R_FLOAT_MISC:
74
/* VMAXNM/VMINNM in ARMv8 */
75
if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
77
tmp = neon_load_reg(rn, pass);
78
tmp2 = neon_load_reg(rm, pass);
79
switch (op) {
80
- case NEON_3R_FLOAT_CMP:
81
- {
82
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
83
- if (!u) {
84
- gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
85
- } else {
86
- if (size == 0) {
87
- gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
88
- } else {
89
- gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
90
- }
91
- }
92
- tcg_temp_free_ptr(fpstatus);
93
- break;
94
- }
95
- case NEON_3R_FLOAT_ACMP:
96
- {
97
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
98
- if (size == 0) {
99
- gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
100
- } else {
101
- gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
102
- }
103
- tcg_temp_free_ptr(fpstatus);
104
- break;
105
- }
106
case NEON_3R_FLOAT_MINMAX:
107
{
108
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
109
--
30
--
110
2.20.1
31
2.25.1
111
32
112
33
diff view generated by jsdifflib
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
1
A lot of C files in hw/arm include qemu-common.h when they don't
2
need anything from it. Drop the include lines.
2
3
3
The little end UUID is used in many places, so make
4
omap1.c, pxa2xx.c and strongarm.c retain the include because they
4
NVDIMM_UUID_LE to a common macro to convert the UUID
5
use it for the prototype of qemu_get_timedate().
5
to a little end array.
6
6
7
Reviewed-by: Xiang Zheng <zhengxiang9@huawei.com>
8
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
9
Message-id: 20200512030609.19593-2-gengdongjiu@huawei.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
11
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
12
Message-id: 20211129200510.1233037-5-peter.maydell@linaro.org
12
---
13
---
13
include/qemu/uuid.h | 27 +++++++++++++++++++++++++++
14
hw/arm/boot.c | 1 -
14
hw/acpi/nvdimm.c | 10 +++-------
15
hw/arm/digic_boards.c | 1 -
15
2 files changed, 30 insertions(+), 7 deletions(-)
16
hw/arm/highbank.c | 1 -
17
hw/arm/npcm7xx_boards.c | 1 -
18
hw/arm/sbsa-ref.c | 1 -
19
hw/arm/stm32f405_soc.c | 1 -
20
hw/arm/vexpress.c | 1 -
21
hw/arm/virt.c | 1 -
22
8 files changed, 8 deletions(-)
16
23
17
diff --git a/include/qemu/uuid.h b/include/qemu/uuid.h
24
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
18
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
19
--- a/include/qemu/uuid.h
26
--- a/hw/arm/boot.c
20
+++ b/include/qemu/uuid.h
27
+++ b/hw/arm/boot.c
21
@@ -XXX,XX +XXX,XX @@ typedef struct {
22
};
23
} QemuUUID;
24
25
+/**
26
+ * UUID_LE - converts the fields of UUID to little-endian array,
27
+ * each of parameters is the filed of UUID.
28
+ *
29
+ * @time_low: The low field of the timestamp
30
+ * @time_mid: The middle field of the timestamp
31
+ * @time_hi_and_version: The high field of the timestamp
32
+ * multiplexed with the version number
33
+ * @clock_seq_hi_and_reserved: The high field of the clock
34
+ * sequence multiplexed with the variant
35
+ * @clock_seq_low: The low field of the clock sequence
36
+ * @node0: The spatially unique node0 identifier
37
+ * @node1: The spatially unique node1 identifier
38
+ * @node2: The spatially unique node2 identifier
39
+ * @node3: The spatially unique node3 identifier
40
+ * @node4: The spatially unique node4 identifier
41
+ * @node5: The spatially unique node5 identifier
42
+ */
43
+#define UUID_LE(time_low, time_mid, time_hi_and_version, \
44
+ clock_seq_hi_and_reserved, clock_seq_low, node0, node1, node2, \
45
+ node3, node4, node5) \
46
+ { (time_low) & 0xff, ((time_low) >> 8) & 0xff, ((time_low) >> 16) & 0xff, \
47
+ ((time_low) >> 24) & 0xff, (time_mid) & 0xff, ((time_mid) >> 8) & 0xff, \
48
+ (time_hi_and_version) & 0xff, ((time_hi_and_version) >> 8) & 0xff, \
49
+ (clock_seq_hi_and_reserved), (clock_seq_low), (node0), (node1), (node2),\
50
+ (node3), (node4), (node5) }
51
+
52
#define UUID_FMT "%02hhx%02hhx%02hhx%02hhx-" \
53
"%02hhx%02hhx-%02hhx%02hhx-" \
54
"%02hhx%02hhx-" \
55
diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/acpi/nvdimm.c
58
+++ b/hw/acpi/nvdimm.c
59
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
60
*/
29
*/
61
30
62
#include "qemu/osdep.h"
31
#include "qemu/osdep.h"
63
+#include "qemu/uuid.h"
32
-#include "qemu-common.h"
64
#include "hw/acpi/acpi.h"
33
#include "qemu/datadir.h"
65
#include "hw/acpi/aml-build.h"
34
#include "qemu/error-report.h"
66
#include "hw/acpi/bios-linker-loader.h"
35
#include "qapi/error.h"
36
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/digic_boards.c
39
+++ b/hw/arm/digic_boards.c
67
@@ -XXX,XX +XXX,XX @@
40
@@ -XXX,XX +XXX,XX @@
68
#include "hw/mem/nvdimm.h"
41
69
#include "qemu/nvdimm-utils.h"
42
#include "qemu/osdep.h"
70
43
#include "qapi/error.h"
71
-#define NVDIMM_UUID_LE(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
44
-#include "qemu-common.h"
72
- { (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
45
#include "qemu/datadir.h"
73
- (b) & 0xff, ((b) >> 8) & 0xff, (c) & 0xff, ((c) >> 8) & 0xff, \
46
#include "hw/boards.h"
74
- (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }
47
#include "qemu/error-report.h"
75
-
48
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
76
/*
49
index XXXXXXX..XXXXXXX 100644
77
* define Byte Addressable Persistent Memory (PM) Region according to
50
--- a/hw/arm/highbank.c
78
* ACPI 6.0: 5.2.25.1 System Physical Address Range Structure.
51
+++ b/hw/arm/highbank.c
52
@@ -XXX,XX +XXX,XX @@
79
*/
53
*/
80
static const uint8_t nvdimm_nfit_spa_uuid[] =
54
81
- NVDIMM_UUID_LE(0x66f0d379, 0xb4f3, 0x4074, 0xac, 0x43, 0x0d, 0x33,
55
#include "qemu/osdep.h"
82
- 0x18, 0xb7, 0x8c, 0xdb);
56
-#include "qemu-common.h"
83
+ UUID_LE(0x66f0d379, 0xb4f3, 0x4074, 0xac, 0x43, 0x0d, 0x33,
57
#include "qemu/datadir.h"
84
+ 0x18, 0xb7, 0x8c, 0xdb);
58
#include "qapi/error.h"
85
59
#include "hw/sysbus.h"
86
/*
60
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
87
* NVDIMM Firmware Interface Table
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/arm/npcm7xx_boards.c
63
+++ b/hw/arm/npcm7xx_boards.c
64
@@ -XXX,XX +XXX,XX @@
65
#include "hw/qdev-core.h"
66
#include "hw/qdev-properties.h"
67
#include "qapi/error.h"
68
-#include "qemu-common.h"
69
#include "qemu/datadir.h"
70
#include "qemu/units.h"
71
#include "sysemu/blockdev.h"
72
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/arm/sbsa-ref.c
75
+++ b/hw/arm/sbsa-ref.c
76
@@ -XXX,XX +XXX,XX @@
77
*/
78
79
#include "qemu/osdep.h"
80
-#include "qemu-common.h"
81
#include "qemu/datadir.h"
82
#include "qapi/error.h"
83
#include "qemu/error-report.h"
84
diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/arm/stm32f405_soc.c
87
+++ b/hw/arm/stm32f405_soc.c
88
@@ -XXX,XX +XXX,XX @@
89
90
#include "qemu/osdep.h"
91
#include "qapi/error.h"
92
-#include "qemu-common.h"
93
#include "exec/address-spaces.h"
94
#include "sysemu/sysemu.h"
95
#include "hw/arm/stm32f405_soc.h"
96
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/hw/arm/vexpress.c
99
+++ b/hw/arm/vexpress.c
100
@@ -XXX,XX +XXX,XX @@
101
102
#include "qemu/osdep.h"
103
#include "qapi/error.h"
104
-#include "qemu-common.h"
105
#include "qemu/datadir.h"
106
#include "cpu.h"
107
#include "hw/sysbus.h"
108
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/arm/virt.c
111
+++ b/hw/arm/virt.c
112
@@ -XXX,XX +XXX,XX @@
113
*/
114
115
#include "qemu/osdep.h"
116
-#include "qemu-common.h"
117
#include "qemu/datadir.h"
118
#include "qemu/units.h"
119
#include "qemu/option.h"
88
--
120
--
89
2.20.1
121
2.25.1
90
122
91
123
diff view generated by jsdifflib
1
Convert the VQSHL, VRSHL and VQRSHL insns in the 3-reg-same
1
The calculation of the length of TLB range invalidate operations
2
group to decodetree. We have already implemented the size==0b11
2
in tlbi_aa64_range_get_length() is incorrect in two ways:
3
case of these insns; this commit handles the remaining sizes.
3
* the NUM field is 5 bits, but we read only 4 bits
4
* we miscalculate the page_shift value, because of an
5
off-by-one error:
6
TG 0b00 is invalid
7
TG 0b01 is 4K granule size == 4096 == 2^12
8
TG 0b10 is 16K granule size == 16384 == 2^14
9
TG 0b11 is 64K granule size == 65536 == 2^16
10
so page_shift should be (TG - 1) * 2 + 12
4
11
12
Thanks to the bug report submitter Cha HyunSoo for identifying
13
both these errors.
14
15
Fixes: 84940ed82552d3c ("target/arm: Add support for FEAT_TLBIRANGE")
16
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/734
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200512163904.10918-8-peter.maydell@linaro.org
19
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20211130173257.1274194-1-peter.maydell@linaro.org
8
---
22
---
9
target/arm/neon-dp.decode | 30 ++++++++++++++++++-----
23
target/arm/helper.c | 6 +++---
10
target/arm/translate-neon.inc.c | 43 +++++++++++++++++++++++++++++++++
24
1 file changed, 3 insertions(+), 3 deletions(-)
11
target/arm/translate.c | 22 +++--------------
12
3 files changed, 70 insertions(+), 25 deletions(-)
13
25
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
26
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/neon-dp.decode
28
--- a/target/arm/helper.c
17
+++ b/target/arm/neon-dp.decode
29
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same_rev
30
@@ -XXX,XX +XXX,XX @@ static uint64_t tlbi_aa64_range_get_length(CPUARMState *env,
19
@3same_64_rev .... ... . . . 11 .... .... .... . q:1 . . .... \
31
uint64_t exponent;
20
&3same vm=%vn_dp vn=%vm_dp vd=%vd_dp size=3
32
uint64_t length;
21
33
22
-VQSHL_S64_3s 1111 001 0 0 . .. .... .... 0100 . . . 1 .... @3same_64_rev
34
- num = extract64(value, 39, 4);
23
-VQSHL_U64_3s 1111 001 1 0 . .. .... .... 0100 . . . 1 .... @3same_64_rev
35
+ num = extract64(value, 39, 5);
24
-VRSHL_S64_3s 1111 001 0 0 . .. .... .... 0101 . . . 0 .... @3same_64_rev
36
scale = extract64(value, 44, 2);
25
-VRSHL_U64_3s 1111 001 1 0 . .. .... .... 0101 . . . 0 .... @3same_64_rev
37
page_size_granule = extract64(value, 46, 2);
26
-VQRSHL_S64_3s 1111 001 0 0 . .. .... .... 0101 . . . 1 .... @3same_64_rev
38
27
-VQRSHL_U64_3s 1111 001 1 0 . .. .... .... 0101 . . . 1 .... @3same_64_rev
39
- page_shift = page_size_granule * 2 + 12;
28
+{
40
-
29
+ VQSHL_S64_3s 1111 001 0 0 . .. .... .... 0100 . . . 1 .... @3same_64_rev
41
if (page_size_granule == 0) {
30
+ VQSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 1 .... @3same_rev
42
qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
31
+}
43
page_size_granule);
32
+{
44
return 0;
33
+ VQSHL_U64_3s 1111 001 1 0 . .. .... .... 0100 . . . 1 .... @3same_64_rev
34
+ VQSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 1 .... @3same_rev
35
+}
36
+{
37
+ VRSHL_S64_3s 1111 001 0 0 . .. .... .... 0101 . . . 0 .... @3same_64_rev
38
+ VRSHL_S_3s 1111 001 0 0 . .. .... .... 0101 . . . 0 .... @3same_rev
39
+}
40
+{
41
+ VRSHL_U64_3s 1111 001 1 0 . .. .... .... 0101 . . . 0 .... @3same_64_rev
42
+ VRSHL_U_3s 1111 001 1 0 . .. .... .... 0101 . . . 0 .... @3same_rev
43
+}
44
+{
45
+ VQRSHL_S64_3s 1111 001 0 0 . .. .... .... 0101 . . . 1 .... @3same_64_rev
46
+ VQRSHL_S_3s 1111 001 0 0 . .. .... .... 0101 . . . 1 .... @3same_rev
47
+}
48
+{
49
+ VQRSHL_U64_3s 1111 001 1 0 . .. .... .... 0101 . . . 1 .... @3same_64_rev
50
+ VQRSHL_U_3s 1111 001 1 0 . .. .... .... 0101 . . . 1 .... @3same_rev
51
+}
52
53
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
54
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
55
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/translate-neon.inc.c
58
+++ b/target/arm/translate-neon.inc.c
59
@@ -XXX,XX +XXX,XX @@ DO_3SAME_64_ENV(VQRSHL_U64, gen_helper_neon_qrshl_u64)
60
return do_3same(s, a, gen_##INSN##_3s); \
61
}
45
}
62
46
63
+/*
47
+ page_shift = (page_size_granule - 1) * 2 + 12;
64
+ * Some helper functions need to be passed the cpu_env. In order
65
+ * to use those with the gvec APIs like tcg_gen_gvec_3() we need
66
+ * to create wrapper functions whose prototype is a NeonGenTwoOpFn()
67
+ * and which call a NeonGenTwoOpEnvFn().
68
+ */
69
+#define WRAP_ENV_FN(WRAPNAME, FUNC) \
70
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m) \
71
+ { \
72
+ FUNC(d, cpu_env, n, m); \
73
+ }
74
+
48
+
75
+#define DO_3SAME_32_ENV(INSN, FUNC) \
49
exponent = (5 * scale) + 1;
76
+ WRAP_ENV_FN(gen_##INSN##_tramp8, gen_helper_neon_##FUNC##8); \
50
length = (num + 1) << (exponent + page_shift);
77
+ WRAP_ENV_FN(gen_##INSN##_tramp16, gen_helper_neon_##FUNC##16); \
51
78
+ WRAP_ENV_FN(gen_##INSN##_tramp32, gen_helper_neon_##FUNC##32); \
79
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
80
+ uint32_t rn_ofs, uint32_t rm_ofs, \
81
+ uint32_t oprsz, uint32_t maxsz) \
82
+ { \
83
+ static const GVecGen3 ops[4] = { \
84
+ { .fni4 = gen_##INSN##_tramp8 }, \
85
+ { .fni4 = gen_##INSN##_tramp16 }, \
86
+ { .fni4 = gen_##INSN##_tramp32 }, \
87
+ { 0 }, \
88
+ }; \
89
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &ops[vece]); \
90
+ } \
91
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
92
+ { \
93
+ if (a->size > 2) { \
94
+ return false; \
95
+ } \
96
+ return do_3same(s, a, gen_##INSN##_3s); \
97
+ }
98
+
99
DO_3SAME_32(VHADD_S, hadd_s)
100
DO_3SAME_32(VHADD_U, hadd_u)
101
DO_3SAME_32(VHSUB_S, hsub_s)
102
DO_3SAME_32(VHSUB_U, hsub_u)
103
DO_3SAME_32(VRHADD_S, rhadd_s)
104
DO_3SAME_32(VRHADD_U, rhadd_u)
105
+DO_3SAME_32(VRSHL_S, rshl_s)
106
+DO_3SAME_32(VRSHL_U, rshl_u)
107
+
108
+DO_3SAME_32_ENV(VQSHL_S, qshl_s)
109
+DO_3SAME_32_ENV(VQSHL_U, qshl_u)
110
+DO_3SAME_32_ENV(VQRSHL_S, qrshl_s)
111
+DO_3SAME_32_ENV(VQRSHL_U, qrshl_u)
112
diff --git a/target/arm/translate.c b/target/arm/translate.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/translate.c
115
+++ b/target/arm/translate.c
116
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
117
case NEON_3R_VHSUB:
118
case NEON_3R_VABD:
119
case NEON_3R_VABA:
120
+ case NEON_3R_VQSHL:
121
+ case NEON_3R_VRSHL:
122
+ case NEON_3R_VQRSHL:
123
/* Already handled by decodetree */
124
return 1;
125
}
126
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
127
}
128
pairwise = 0;
129
switch (op) {
130
- case NEON_3R_VQSHL:
131
- case NEON_3R_VRSHL:
132
- case NEON_3R_VQRSHL:
133
- {
134
- int rtmp;
135
- /* Shift instruction operands are reversed. */
136
- rtmp = rn;
137
- rn = rm;
138
- rm = rtmp;
139
- }
140
- break;
141
case NEON_3R_VPADD_VQRDMLAH:
142
case NEON_3R_VPMAX:
143
case NEON_3R_VPMIN:
144
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
145
tmp2 = neon_load_reg(rm, pass);
146
}
147
switch (op) {
148
- case NEON_3R_VQSHL:
149
- GEN_NEON_INTEGER_OP_ENV(qshl);
150
- break;
151
- case NEON_3R_VRSHL:
152
- GEN_NEON_INTEGER_OP(rshl);
153
- break;
154
- case NEON_3R_VQRSHL:
155
- GEN_NEON_INTEGER_OP_ENV(qrshl);
156
break;
157
case NEON_3R_VPMAX:
158
GEN_NEON_INTEGER_OP(pmax);
159
--
52
--
160
2.20.1
53
2.25.1
161
54
162
55
diff view generated by jsdifflib
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
1
From: Patrick Venture <venture@google.com>
2
2
3
kvm_hwpoison_page_add() and kvm_unpoison_all() will both
3
The rx_active boolean change to true should always trigger a try_read
4
be used by X86 and ARM platforms, so moving them into
4
call that flushes the queue.
5
"accel/kvm/kvm-all.c" to avoid duplicate code.
6
5
7
For architectures that don't use the poison-list functionality
6
Signed-off-by: Patrick Venture <venture@google.com>
8
the reset handler will harmlessly do nothing, so let's register
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
the kvm_unpoison_all() function in the generic kvm_init() function.
8
Message-id: 20211203221002.1719306-1-venture@google.com
10
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
13
Signed-off-by: Xiang Zheng <zhengxiang9@huawei.com>
14
Acked-by: Xiang Zheng <zhengxiang9@huawei.com>
15
Message-id: 20200512030609.19593-8-gengdongjiu@huawei.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
10
---
18
include/sysemu/kvm_int.h | 12 ++++++++++++
11
hw/net/npcm7xx_emc.c | 18 ++++++++----------
19
accel/kvm/kvm-all.c | 36 ++++++++++++++++++++++++++++++++++++
12
1 file changed, 8 insertions(+), 10 deletions(-)
20
target/i386/kvm.c | 36 ------------------------------------
21
3 files changed, 48 insertions(+), 36 deletions(-)
22
13
23
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
14
diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c
24
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
25
--- a/include/sysemu/kvm_int.h
16
--- a/hw/net/npcm7xx_emc.c
26
+++ b/include/sysemu/kvm_int.h
17
+++ b/hw/net/npcm7xx_emc.c
27
@@ -XXX,XX +XXX,XX @@ void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml,
18
@@ -XXX,XX +XXX,XX @@ static void emc_halt_rx(NPCM7xxEMCState *emc, uint32_t mista_flag)
28
AddressSpace *as, int as_id);
19
emc_set_mista(emc, mista_flag);
29
30
void kvm_set_max_memslot_size(hwaddr max_slot_size);
31
+
32
+/**
33
+ * kvm_hwpoison_page_add:
34
+ *
35
+ * Parameters:
36
+ * @ram_addr: the address in the RAM for the poisoned page
37
+ *
38
+ * Add a poisoned page to the list
39
+ *
40
+ * Return: None.
41
+ */
42
+void kvm_hwpoison_page_add(ram_addr_t ram_addr);
43
#endif
44
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/accel/kvm/kvm-all.c
47
+++ b/accel/kvm/kvm-all.c
48
@@ -XXX,XX +XXX,XX @@
49
#include "qapi/visitor.h"
50
#include "qapi/qapi-types-common.h"
51
#include "qapi/qapi-visit-common.h"
52
+#include "sysemu/reset.h"
53
54
#include "hw/boards.h"
55
56
@@ -XXX,XX +XXX,XX @@ int kvm_vm_check_extension(KVMState *s, unsigned int extension)
57
return ret;
58
}
20
}
59
21
60
+typedef struct HWPoisonPage {
22
+static void emc_enable_rx_and_flush(NPCM7xxEMCState *emc)
61
+ ram_addr_t ram_addr;
62
+ QLIST_ENTRY(HWPoisonPage) list;
63
+} HWPoisonPage;
64
+
65
+static QLIST_HEAD(, HWPoisonPage) hwpoison_page_list =
66
+ QLIST_HEAD_INITIALIZER(hwpoison_page_list);
67
+
68
+static void kvm_unpoison_all(void *param)
69
+{
23
+{
70
+ HWPoisonPage *page, *next_page;
24
+ emc->rx_active = true;
71
+
25
+ qemu_flush_queued_packets(qemu_get_queue(emc->nic));
72
+ QLIST_FOREACH_SAFE(page, &hwpoison_page_list, list, next_page) {
73
+ QLIST_REMOVE(page, list);
74
+ qemu_ram_remap(page->ram_addr, TARGET_PAGE_SIZE);
75
+ g_free(page);
76
+ }
77
+}
26
+}
78
+
27
+
79
+void kvm_hwpoison_page_add(ram_addr_t ram_addr)
28
static void emc_set_next_tx_descriptor(NPCM7xxEMCState *emc,
80
+{
29
const NPCM7xxEMCTxDesc *tx_desc,
81
+ HWPoisonPage *page;
30
uint32_t desc_addr)
82
+
31
@@ -XXX,XX +XXX,XX @@ static ssize_t emc_receive(NetClientState *nc, const uint8_t *buf, size_t len1)
83
+ QLIST_FOREACH(page, &hwpoison_page_list, list) {
32
return len;
84
+ if (page->ram_addr == ram_addr) {
85
+ return;
86
+ }
87
+ }
88
+ page = g_new(HWPoisonPage, 1);
89
+ page->ram_addr = ram_addr;
90
+ QLIST_INSERT_HEAD(&hwpoison_page_list, page, list);
91
+}
92
+
93
static uint32_t adjust_ioeventfd_endianness(uint32_t val, uint32_t size)
94
{
95
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
96
@@ -XXX,XX +XXX,XX @@ static int kvm_init(MachineState *ms)
97
s->kernel_irqchip_split = mc->default_kernel_irqchip_split ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
98
}
99
100
+ qemu_register_reset(kvm_unpoison_all, NULL);
101
+
102
if (s->kernel_irqchip_allowed) {
103
kvm_irqchip_create(s);
104
}
105
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/i386/kvm.c
108
+++ b/target/i386/kvm.c
109
@@ -XXX,XX +XXX,XX @@
110
#include "sysemu/sysemu.h"
111
#include "sysemu/hw_accel.h"
112
#include "sysemu/kvm_int.h"
113
-#include "sysemu/reset.h"
114
#include "sysemu/runstate.h"
115
#include "kvm_i386.h"
116
#include "hyperv.h"
117
@@ -XXX,XX +XXX,XX @@ uint64_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
118
}
119
}
33
}
120
34
121
-
35
-static void emc_try_receive_next_packet(NPCM7xxEMCState *emc)
122
-typedef struct HWPoisonPage {
123
- ram_addr_t ram_addr;
124
- QLIST_ENTRY(HWPoisonPage) list;
125
-} HWPoisonPage;
126
-
127
-static QLIST_HEAD(, HWPoisonPage) hwpoison_page_list =
128
- QLIST_HEAD_INITIALIZER(hwpoison_page_list);
129
-
130
-static void kvm_unpoison_all(void *param)
131
-{
36
-{
132
- HWPoisonPage *page, *next_page;
37
- if (emc_can_receive(qemu_get_queue(emc->nic))) {
133
-
38
- qemu_flush_queued_packets(qemu_get_queue(emc->nic));
134
- QLIST_FOREACH_SAFE(page, &hwpoison_page_list, list, next_page) {
135
- QLIST_REMOVE(page, list);
136
- qemu_ram_remap(page->ram_addr, TARGET_PAGE_SIZE);
137
- g_free(page);
138
- }
39
- }
139
-}
40
-}
140
-
41
-
141
-static void kvm_hwpoison_page_add(ram_addr_t ram_addr)
42
static uint64_t npcm7xx_emc_read(void *opaque, hwaddr offset, unsigned size)
142
-{
143
- HWPoisonPage *page;
144
-
145
- QLIST_FOREACH(page, &hwpoison_page_list, list) {
146
- if (page->ram_addr == ram_addr) {
147
- return;
148
- }
149
- }
150
- page = g_new(HWPoisonPage, 1);
151
- page->ram_addr = ram_addr;
152
- QLIST_INSERT_HEAD(&hwpoison_page_list, page, list);
153
-}
154
-
155
static int kvm_get_mce_cap_supported(KVMState *s, uint64_t *mce_cap,
156
int *max_banks)
157
{
43
{
158
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
44
NPCM7xxEMCState *emc = opaque;
159
fprintf(stderr, "e820_add_entry() table is full\n");
45
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset,
160
return ret;
46
emc->regs[REG_MGSTA] |= REG_MGSTA_RXHA;
161
}
47
}
162
- qemu_register_reset(kvm_unpoison_all, NULL);
48
if (value & REG_MCMDR_RXON) {
163
49
- emc->rx_active = true;
164
shadow_mem = object_property_get_int(OBJECT(s), "kvm-shadow-mem", &error_abort);
50
+ emc_enable_rx_and_flush(emc);
165
if (shadow_mem != -1) {
51
} else {
52
emc_halt_rx(emc, 0);
53
}
54
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset,
55
break;
56
case REG_RSDR:
57
if (emc->regs[REG_MCMDR] & REG_MCMDR_RXON) {
58
- emc->rx_active = true;
59
- emc_try_receive_next_packet(emc);
60
+ emc_enable_rx_and_flush(emc);
61
}
62
break;
63
case REG_MIIDA:
166
--
64
--
167
2.20.1
65
2.25.1
168
66
169
67
diff view generated by jsdifflib
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
This patch builds error_block_address and read_ack_register fields
3
When a virtio-iommu is instantiated, describe it using the ACPI VIOT
4
in hardware errors table , the error_block_address points to Generic
4
table.
5
Error Status Block(GESB) via bios_linker. The max size for one GESB
6
is 1kb, For more detailed information, please refer to
7
document: docs/specs/acpi_hest_ghes.rst
8
5
9
Now we only support one Error source, if necessary, we can extend to
6
Acked-by: Igor Mammedov <imammedo@redhat.com>
10
support more.
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
8
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
12
Suggested-by: Laszlo Ersek <lersek@redhat.com>
9
Message-id: 20211210170415.583179-2-jean-philippe@linaro.org
13
Signed-off-by: Xiang Zheng <zhengxiang9@huawei.com>
14
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
15
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
16
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
17
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
18
Message-id: 20200512030609.19593-5-gengdongjiu@huawei.com
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
11
---
21
default-configs/arm-softmmu.mak | 1 +
12
hw/arm/virt-acpi-build.c | 7 +++++++
22
include/hw/acpi/aml-build.h | 1 +
13
hw/arm/Kconfig | 1 +
23
include/hw/acpi/ghes.h | 28 +++++++++++
14
2 files changed, 8 insertions(+)
24
hw/acpi/aml-build.c | 2 +
25
hw/acpi/ghes.c | 89 +++++++++++++++++++++++++++++++++
26
hw/arm/virt-acpi-build.c | 5 ++
27
hw/acpi/Kconfig | 4 ++
28
hw/acpi/Makefile.objs | 1 +
29
8 files changed, 131 insertions(+)
30
create mode 100644 include/hw/acpi/ghes.h
31
create mode 100644 hw/acpi/ghes.c
32
15
33
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
34
index XXXXXXX..XXXXXXX 100644
35
--- a/default-configs/arm-softmmu.mak
36
+++ b/default-configs/arm-softmmu.mak
37
@@ -XXX,XX +XXX,XX @@ CONFIG_FSL_IMX7=y
38
CONFIG_FSL_IMX6UL=y
39
CONFIG_SEMIHOSTING=y
40
CONFIG_ALLWINNER_H3=y
41
+CONFIG_ACPI_APEI=y
42
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/include/hw/acpi/aml-build.h
45
+++ b/include/hw/acpi/aml-build.h
46
@@ -XXX,XX +XXX,XX @@ struct AcpiBuildTables {
47
GArray *rsdp;
48
GArray *tcpalog;
49
GArray *vmgenid;
50
+ GArray *hardware_errors;
51
BIOSLinker *linker;
52
} AcpiBuildTables;
53
54
diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h
55
new file mode 100644
56
index XXXXXXX..XXXXXXX
57
--- /dev/null
58
+++ b/include/hw/acpi/ghes.h
59
@@ -XXX,XX +XXX,XX @@
60
+/*
61
+ * Support for generating APEI tables and recording CPER for Guests
62
+ *
63
+ * Copyright (c) 2020 HUAWEI TECHNOLOGIES CO., LTD.
64
+ *
65
+ * Author: Dongjiu Geng <gengdongjiu@huawei.com>
66
+ *
67
+ * This program is free software; you can redistribute it and/or modify
68
+ * it under the terms of the GNU General Public License as published by
69
+ * the Free Software Foundation; either version 2 of the License, or
70
+ * (at your option) any later version.
71
+
72
+ * This program is distributed in the hope that it will be useful,
73
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
74
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
75
+ * GNU General Public License for more details.
76
+
77
+ * You should have received a copy of the GNU General Public License along
78
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
79
+ */
80
+
81
+#ifndef ACPI_GHES_H
82
+#define ACPI_GHES_H
83
+
84
+#include "hw/acpi/bios-linker-loader.h"
85
+
86
+void build_ghes_error_table(GArray *hardware_errors, BIOSLinker *linker);
87
+#endif
88
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/hw/acpi/aml-build.c
91
+++ b/hw/acpi/aml-build.c
92
@@ -XXX,XX +XXX,XX @@ void acpi_build_tables_init(AcpiBuildTables *tables)
93
tables->table_data = g_array_new(false, true /* clear */, 1);
94
tables->tcpalog = g_array_new(false, true /* clear */, 1);
95
tables->vmgenid = g_array_new(false, true /* clear */, 1);
96
+ tables->hardware_errors = g_array_new(false, true /* clear */, 1);
97
tables->linker = bios_linker_loader_init();
98
}
99
100
@@ -XXX,XX +XXX,XX @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
101
g_array_free(tables->table_data, true);
102
g_array_free(tables->tcpalog, mfre);
103
g_array_free(tables->vmgenid, mfre);
104
+ g_array_free(tables->hardware_errors, mfre);
105
}
106
107
/*
108
diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
109
new file mode 100644
110
index XXXXXXX..XXXXXXX
111
--- /dev/null
112
+++ b/hw/acpi/ghes.c
113
@@ -XXX,XX +XXX,XX @@
114
+/*
115
+ * Support for generating APEI tables and recording CPER for Guests
116
+ *
117
+ * Copyright (c) 2020 HUAWEI TECHNOLOGIES CO., LTD.
118
+ *
119
+ * Author: Dongjiu Geng <gengdongjiu@huawei.com>
120
+ *
121
+ * This program is free software; you can redistribute it and/or modify
122
+ * it under the terms of the GNU General Public License as published by
123
+ * the Free Software Foundation; either version 2 of the License, or
124
+ * (at your option) any later version.
125
+
126
+ * This program is distributed in the hope that it will be useful,
127
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
128
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
129
+ * GNU General Public License for more details.
130
+
131
+ * You should have received a copy of the GNU General Public License along
132
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
133
+ */
134
+
135
+#include "qemu/osdep.h"
136
+#include "qemu/units.h"
137
+#include "hw/acpi/ghes.h"
138
+#include "hw/acpi/aml-build.h"
139
+
140
+#define ACPI_GHES_ERRORS_FW_CFG_FILE "etc/hardware_errors"
141
+#define ACPI_GHES_DATA_ADDR_FW_CFG_FILE "etc/hardware_errors_addr"
142
+
143
+/* The max size in bytes for one error block */
144
+#define ACPI_GHES_MAX_RAW_DATA_LENGTH (1 * KiB)
145
+
146
+/* Now only support ARMv8 SEA notification type error source */
147
+#define ACPI_GHES_ERROR_SOURCE_COUNT 1
148
+
149
+/*
150
+ * Build table for the hardware error fw_cfg blob.
151
+ * Initialize "etc/hardware_errors" and "etc/hardware_errors_addr" fw_cfg blobs.
152
+ * See docs/specs/acpi_hest_ghes.rst for blobs format.
153
+ */
154
+void build_ghes_error_table(GArray *hardware_errors, BIOSLinker *linker)
155
+{
156
+ int i, error_status_block_offset;
157
+
158
+ /* Build error_block_address */
159
+ for (i = 0; i < ACPI_GHES_ERROR_SOURCE_COUNT; i++) {
160
+ build_append_int_noprefix(hardware_errors, 0, sizeof(uint64_t));
161
+ }
162
+
163
+ /* Build read_ack_register */
164
+ for (i = 0; i < ACPI_GHES_ERROR_SOURCE_COUNT; i++) {
165
+ /*
166
+ * Initialize the value of read_ack_register to 1, so GHES can be
167
+ * writeable after (re)boot.
168
+ * ACPI 6.2: 18.3.2.8 Generic Hardware Error Source version 2
169
+ * (GHESv2 - Type 10)
170
+ */
171
+ build_append_int_noprefix(hardware_errors, 1, sizeof(uint64_t));
172
+ }
173
+
174
+ /* Generic Error Status Block offset in the hardware error fw_cfg blob */
175
+ error_status_block_offset = hardware_errors->len;
176
+
177
+ /* Reserve space for Error Status Data Block */
178
+ acpi_data_push(hardware_errors,
179
+ ACPI_GHES_MAX_RAW_DATA_LENGTH * ACPI_GHES_ERROR_SOURCE_COUNT);
180
+
181
+ /* Tell guest firmware to place hardware_errors blob into RAM */
182
+ bios_linker_loader_alloc(linker, ACPI_GHES_ERRORS_FW_CFG_FILE,
183
+ hardware_errors, sizeof(uint64_t), false);
184
+
185
+ for (i = 0; i < ACPI_GHES_ERROR_SOURCE_COUNT; i++) {
186
+ /*
187
+ * Tell firmware to patch error_block_address entries to point to
188
+ * corresponding "Generic Error Status Block"
189
+ */
190
+ bios_linker_loader_add_pointer(linker,
191
+ ACPI_GHES_ERRORS_FW_CFG_FILE, sizeof(uint64_t) * i,
192
+ sizeof(uint64_t), ACPI_GHES_ERRORS_FW_CFG_FILE,
193
+ error_status_block_offset + i * ACPI_GHES_MAX_RAW_DATA_LENGTH);
194
+ }
195
+
196
+ /*
197
+ * tell firmware to write hardware_errors GPA into
198
+ * hardware_errors_addr fw_cfg, once the former has been initialized.
199
+ */
200
+ bios_linker_loader_write_pointer(linker, ACPI_GHES_DATA_ADDR_FW_CFG_FILE,
201
+ 0, sizeof(uint64_t), ACPI_GHES_ERRORS_FW_CFG_FILE, 0);
202
+}
203
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
16
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
204
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
205
--- a/hw/arm/virt-acpi-build.c
18
--- a/hw/arm/virt-acpi-build.c
206
+++ b/hw/arm/virt-acpi-build.c
19
+++ b/hw/arm/virt-acpi-build.c
207
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
208
#include "sysemu/reset.h"
209
#include "kvm_arm.h"
21
#include "kvm_arm.h"
210
#include "migration/vmstate.h"
22
#include "migration/vmstate.h"
211
+#include "hw/acpi/ghes.h"
23
#include "hw/acpi/ghes.h"
24
+#include "hw/acpi/viot.h"
212
25
213
#define ARM_SPI_BASE 32
26
#define ARM_SPI_BASE 32
214
27
215
@@ -XXX,XX +XXX,XX @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
28
@@ -XXX,XX +XXX,XX @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
216
acpi_add_table(table_offsets, tables_blob);
29
}
217
build_spcr(tables_blob, tables->linker, vms);
30
#endif
218
31
219
+ if (vms->ras) {
32
+ if (vms->iommu == VIRT_IOMMU_VIRTIO) {
220
+ build_ghes_error_table(tables->hardware_errors, tables->linker);
33
+ acpi_add_table(table_offsets, tables_blob);
34
+ build_viot(ms, tables_blob, tables->linker, vms->virtio_iommu_bdf,
35
+ vms->oem_id, vms->oem_table_id);
221
+ }
36
+ }
222
+
37
+
223
if (ms->numa_state->num_nodes > 0) {
38
/* XSDT is pointed to by RSDP */
224
acpi_add_table(table_offsets, tables_blob);
39
xsdt = tables_blob->len;
225
build_srat(tables_blob, tables->linker, vms);
40
build_xsdt(tables_blob, tables->linker, table_offsets, vms->oem_id,
226
diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
41
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
227
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
228
--- a/hw/acpi/Kconfig
43
--- a/hw/arm/Kconfig
229
+++ b/hw/acpi/Kconfig
44
+++ b/hw/arm/Kconfig
230
@@ -XXX,XX +XXX,XX @@ config ACPI_HMAT
45
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
46
select DIMM
47
select ACPI_HW_REDUCED
48
select ACPI_APEI
49
+ select ACPI_VIOT
50
51
config CHEETAH
231
bool
52
bool
232
depends on ACPI
233
234
+config ACPI_APEI
235
+ bool
236
+ depends on ACPI
237
+
238
config ACPI_PCI
239
bool
240
depends on ACPI && PCI
241
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
242
index XXXXXXX..XXXXXXX 100644
243
--- a/hw/acpi/Makefile.objs
244
+++ b/hw/acpi/Makefile.objs
245
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
246
common-obj-$(CONFIG_ACPI_VMGENID) += vmgenid.o
247
common-obj-$(CONFIG_ACPI_HW_REDUCED) += generic_event_device.o
248
common-obj-$(CONFIG_ACPI_HMAT) += hmat.o
249
+common-obj-$(CONFIG_ACPI_APEI) += ghes.o
250
common-obj-$(call lnot,$(CONFIG_ACPI_X86)) += acpi-stub.o
251
common-obj-$(call lnot,$(CONFIG_PC)) += acpi-x86-stub.o
252
253
--
53
--
254
2.20.1
54
2.25.1
255
55
256
56
diff view generated by jsdifflib
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
RAS Virtualization feature is not supported now, so
3
virtio-iommu is now supported with ACPI VIOT as well as device tree.
4
add a RAS machine option and disable it by default.
4
Remove the restriction that prevents from instantiating a virtio-iommu
5
device under ACPI.
5
6
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Acked-by: Igor Mammedov <imammedo@redhat.com>
7
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Signed-off-by: Xiang Zheng <zhengxiang9@huawei.com>
9
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
9
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
10
Message-id: 20211210170415.583179-3-jean-philippe@linaro.org
10
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
11
Message-id: 20200512030609.19593-3-gengdongjiu@huawei.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
12
---
14
include/hw/arm/virt.h | 1 +
13
hw/arm/virt.c | 10 ++--------
15
hw/arm/virt.c | 23 +++++++++++++++++++++++
14
hw/virtio/virtio-iommu-pci.c | 12 ++----------
16
2 files changed, 24 insertions(+)
15
2 files changed, 4 insertions(+), 18 deletions(-)
17
16
18
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/virt.h
21
+++ b/include/hw/arm/virt.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct {
23
bool highmem_ecam;
24
bool its;
25
bool virt;
26
+ bool ras;
27
OnOffAuto acpi;
28
VirtGICType gic_version;
29
VirtIOMMUType iommu;
30
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
31
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/arm/virt.c
19
--- a/hw/arm/virt.c
33
+++ b/hw/arm/virt.c
20
+++ b/hw/arm/virt.c
34
@@ -XXX,XX +XXX,XX @@ static void virt_set_acpi(Object *obj, Visitor *v, const char *name,
21
@@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
35
visit_type_OnOffAuto(v, name, &vms->acpi, errp);
22
MachineClass *mc = MACHINE_GET_CLASS(machine);
23
24
if (device_is_dynamic_sysbus(mc, dev) ||
25
- (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM))) {
26
+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
27
+ object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
28
return HOTPLUG_HANDLER(machine);
29
}
30
- if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
31
- VirtMachineState *vms = VIRT_MACHINE(machine);
32
-
33
- if (!vms->bootinfo.firmware_loaded || !virt_is_acpi_enabled(vms)) {
34
- return HOTPLUG_HANDLER(machine);
35
- }
36
- }
37
return NULL;
36
}
38
}
37
39
38
+static bool virt_get_ras(Object *obj, Error **errp)
40
diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c
39
+{
41
index XXXXXXX..XXXXXXX 100644
40
+ VirtMachineState *vms = VIRT_MACHINE(obj);
42
--- a/hw/virtio/virtio-iommu-pci.c
41
+
43
+++ b/hw/virtio/virtio-iommu-pci.c
42
+ return vms->ras;
44
@@ -XXX,XX +XXX,XX @@ static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
43
+}
45
VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
44
+
46
45
+static void virt_set_ras(Object *obj, bool value, Error **errp)
47
if (!qdev_get_machine_hotplug_handler(DEVICE(vpci_dev))) {
46
+{
48
- MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
47
+ VirtMachineState *vms = VIRT_MACHINE(obj);
49
-
48
+
50
- error_setg(errp,
49
+ vms->ras = value;
51
- "%s machine fails to create iommu-map device tree bindings",
50
+}
52
- mc->name);
51
+
53
- error_append_hint(errp,
52
static char *virt_get_gic_version(Object *obj, Error **errp)
54
- "Check your machine implements a hotplug handler "
53
{
55
- "for the virtio-iommu-pci device\n");
54
VirtMachineState *vms = VIRT_MACHINE(obj);
56
- error_append_hint(errp, "Check the guest is booted without FW or with "
55
@@ -XXX,XX +XXX,XX @@ static void virt_instance_init(Object *obj)
57
- "-no-acpi\n");
56
"Valid values are none and smmuv3",
58
+ error_setg(errp, "Check your machine implements a hotplug handler "
57
NULL);
59
+ "for the virtio-iommu-pci device");
58
60
return;
59
+ /* Default disallows RAS instantiation */
61
}
60
+ vms->ras = false;
62
for (int i = 0; i < s->nb_reserved_regions; i++) {
61
+ object_property_add_bool(obj, "ras", virt_get_ras,
62
+ virt_set_ras, NULL);
63
+ object_property_set_description(obj, "ras",
64
+ "Set on/off to enable/disable reporting host memory errors "
65
+ "to a KVM guest using ACPI and guest external abort exceptions",
66
+ NULL);
67
+
68
vms->irqmap = a15irqmap;
69
70
virt_flash_create(vms);
71
--
63
--
72
2.20.1
64
2.25.1
73
65
74
66
diff view generated by jsdifflib
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
kvm_arch_on_sigbus_vcpu() error injection uses source_id as
3
We do not support instantiating multiple IOMMUs. Before adding a
4
index in etc/hardware_errors to find out Error Status Data
4
virtio-iommu, check that no other IOMMU is present. This will detect
5
Block entry corresponding to error source. So supported source_id
5
both "iommu=smmuv3" machine parameter and another virtio-iommu instance.
6
values should be assigned here and not be changed afterwards to
7
make sure that guest will write error into expected Error Status
8
Data Block.
9
6
10
Before QEMU writes a new error to ACPI table, it will check whether
7
Fixes: 70e89132c9 ("hw/arm/virt: Add the virtio-iommu device tree mappings")
11
previous error has been acknowledged. If not acknowledged, the new
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
12
errors will be ignored and not be recorded. For the errors section
13
type, QEMU simulate it to memory section error.
14
15
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
16
Signed-off-by: Xiang Zheng <zhengxiang9@huawei.com>
17
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
18
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
19
Message-id: 20200512030609.19593-9-gengdongjiu@huawei.com
11
Message-id: 20211210170415.583179-4-jean-philippe@linaro.org
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
13
---
22
include/hw/acpi/ghes.h | 1 +
14
hw/arm/virt.c | 5 +++++
23
hw/acpi/ghes.c | 219 +++++++++++++++++++++++++++++++++++++++++
15
1 file changed, 5 insertions(+)
24
2 files changed, 220 insertions(+)
25
16
26
diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
27
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/acpi/ghes.h
19
--- a/hw/arm/virt.c
29
+++ b/include/hw/acpi/ghes.h
20
+++ b/hw/arm/virt.c
30
@@ -XXX,XX +XXX,XX @@ void build_ghes_error_table(GArray *hardware_errors, BIOSLinker *linker);
21
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
31
void acpi_build_hest(GArray *table_data, BIOSLinker *linker);
22
hwaddr db_start = 0, db_end = 0;
32
void acpi_ghes_add_fw_cfg(AcpiGhesState *vms, FWCfgState *s,
23
char *resv_prop_str;
33
GArray *hardware_errors);
24
34
+int acpi_ghes_record_errors(uint8_t notify, uint64_t error_physical_addr);
25
+ if (vms->iommu != VIRT_IOMMU_NONE) {
35
#endif
26
+ error_setg(errp, "virt machine does not support multiple IOMMUs");
36
diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
27
+ return;
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/acpi/ghes.c
39
+++ b/hw/acpi/ghes.c
40
@@ -XXX,XX +XXX,XX @@
41
#include "qemu/error-report.h"
42
#include "hw/acpi/generic_event_device.h"
43
#include "hw/nvram/fw_cfg.h"
44
+#include "qemu/uuid.h"
45
46
#define ACPI_GHES_ERRORS_FW_CFG_FILE "etc/hardware_errors"
47
#define ACPI_GHES_DATA_ADDR_FW_CFG_FILE "etc/hardware_errors_addr"
48
@@ -XXX,XX +XXX,XX @@
49
/* Address offset in Generic Address Structure(GAS) */
50
#define GAS_ADDR_OFFSET 4
51
52
+/*
53
+ * The total size of Generic Error Data Entry
54
+ * ACPI 6.1/6.2: 18.3.2.7.1 Generic Error Data,
55
+ * Table 18-343 Generic Error Data Entry
56
+ */
57
+#define ACPI_GHES_DATA_LENGTH 72
58
+
59
+/* The memory section CPER size, UEFI 2.6: N.2.5 Memory Error Section */
60
+#define ACPI_GHES_MEM_CPER_LENGTH 80
61
+
62
+/* Masks for block_status flags */
63
+#define ACPI_GEBS_UNCORRECTABLE 1
64
+
65
+/*
66
+ * Total size for Generic Error Status Block except Generic Error Data Entries
67
+ * ACPI 6.2: 18.3.2.7.1 Generic Error Data,
68
+ * Table 18-380 Generic Error Status Block
69
+ */
70
+#define ACPI_GHES_GESB_SIZE 20
71
+
72
+/*
73
+ * Values for error_severity field
74
+ */
75
+enum AcpiGenericErrorSeverity {
76
+ ACPI_CPER_SEV_RECOVERABLE = 0,
77
+ ACPI_CPER_SEV_FATAL = 1,
78
+ ACPI_CPER_SEV_CORRECTED = 2,
79
+ ACPI_CPER_SEV_NONE = 3,
80
+};
81
+
82
/*
83
* Hardware Error Notification
84
* ACPI 4.0: 17.3.2.7 Hardware Error Notification
85
@@ -XXX,XX +XXX,XX @@ static void build_ghes_hw_error_notification(GArray *table, const uint8_t type)
86
build_append_int_noprefix(table, 0, 4);
87
}
88
89
+/*
90
+ * Generic Error Data Entry
91
+ * ACPI 6.1: 18.3.2.7.1 Generic Error Data
92
+ */
93
+static void acpi_ghes_generic_error_data(GArray *table,
94
+ const uint8_t *section_type, uint32_t error_severity,
95
+ uint8_t validation_bits, uint8_t flags,
96
+ uint32_t error_data_length, QemuUUID fru_id,
97
+ uint64_t time_stamp)
98
+{
99
+ const uint8_t fru_text[20] = {0};
100
+
101
+ /* Section Type */
102
+ g_array_append_vals(table, section_type, 16);
103
+
104
+ /* Error Severity */
105
+ build_append_int_noprefix(table, error_severity, 4);
106
+ /* Revision */
107
+ build_append_int_noprefix(table, 0x300, 2);
108
+ /* Validation Bits */
109
+ build_append_int_noprefix(table, validation_bits, 1);
110
+ /* Flags */
111
+ build_append_int_noprefix(table, flags, 1);
112
+ /* Error Data Length */
113
+ build_append_int_noprefix(table, error_data_length, 4);
114
+
115
+ /* FRU Id */
116
+ g_array_append_vals(table, fru_id.data, ARRAY_SIZE(fru_id.data));
117
+
118
+ /* FRU Text */
119
+ g_array_append_vals(table, fru_text, sizeof(fru_text));
120
+
121
+ /* Timestamp */
122
+ build_append_int_noprefix(table, time_stamp, 8);
123
+}
124
+
125
+/*
126
+ * Generic Error Status Block
127
+ * ACPI 6.1: 18.3.2.7.1 Generic Error Data
128
+ */
129
+static void acpi_ghes_generic_error_status(GArray *table, uint32_t block_status,
130
+ uint32_t raw_data_offset, uint32_t raw_data_length,
131
+ uint32_t data_length, uint32_t error_severity)
132
+{
133
+ /* Block Status */
134
+ build_append_int_noprefix(table, block_status, 4);
135
+ /* Raw Data Offset */
136
+ build_append_int_noprefix(table, raw_data_offset, 4);
137
+ /* Raw Data Length */
138
+ build_append_int_noprefix(table, raw_data_length, 4);
139
+ /* Data Length */
140
+ build_append_int_noprefix(table, data_length, 4);
141
+ /* Error Severity */
142
+ build_append_int_noprefix(table, error_severity, 4);
143
+}
144
+
145
+/* UEFI 2.6: N.2.5 Memory Error Section */
146
+static void acpi_ghes_build_append_mem_cper(GArray *table,
147
+ uint64_t error_physical_addr)
148
+{
149
+ /*
150
+ * Memory Error Record
151
+ */
152
+
153
+ /* Validation Bits */
154
+ build_append_int_noprefix(table,
155
+ (1ULL << 14) | /* Type Valid */
156
+ (1ULL << 1) /* Physical Address Valid */,
157
+ 8);
158
+ /* Error Status */
159
+ build_append_int_noprefix(table, 0, 8);
160
+ /* Physical Address */
161
+ build_append_int_noprefix(table, error_physical_addr, 8);
162
+ /* Skip all the detailed information normally found in such a record */
163
+ build_append_int_noprefix(table, 0, 48);
164
+ /* Memory Error Type */
165
+ build_append_int_noprefix(table, 0 /* Unknown error */, 1);
166
+ /* Skip all the detailed information normally found in such a record */
167
+ build_append_int_noprefix(table, 0, 7);
168
+}
169
+
170
+static int acpi_ghes_record_mem_error(uint64_t error_block_address,
171
+ uint64_t error_physical_addr)
172
+{
173
+ GArray *block;
174
+
175
+ /* Memory Error Section Type */
176
+ const uint8_t uefi_cper_mem_sec[] =
177
+ UUID_LE(0xA5BC1114, 0x6F64, 0x4EDE, 0xB8, 0x63, 0x3E, 0x83, \
178
+ 0xED, 0x7C, 0x83, 0xB1);
179
+
180
+ /* invalid fru id: ACPI 4.0: 17.3.2.6.1 Generic Error Data,
181
+ * Table 17-13 Generic Error Data Entry
182
+ */
183
+ QemuUUID fru_id = {};
184
+ uint32_t data_length;
185
+
186
+ block = g_array_new(false, true /* clear */, 1);
187
+
188
+ /* This is the length if adding a new generic error data entry*/
189
+ data_length = ACPI_GHES_DATA_LENGTH + ACPI_GHES_MEM_CPER_LENGTH;
190
+
191
+ /*
192
+ * Check whether it will run out of the preallocated memory if adding a new
193
+ * generic error data entry
194
+ */
195
+ if ((data_length + ACPI_GHES_GESB_SIZE) > ACPI_GHES_MAX_RAW_DATA_LENGTH) {
196
+ error_report("Not enough memory to record new CPER!!!");
197
+ g_array_free(block, true);
198
+ return -1;
199
+ }
200
+
201
+ /* Build the new generic error status block header */
202
+ acpi_ghes_generic_error_status(block, ACPI_GEBS_UNCORRECTABLE,
203
+ 0, 0, data_length, ACPI_CPER_SEV_RECOVERABLE);
204
+
205
+ /* Build this new generic error data entry header */
206
+ acpi_ghes_generic_error_data(block, uefi_cper_mem_sec,
207
+ ACPI_CPER_SEV_RECOVERABLE, 0, 0,
208
+ ACPI_GHES_MEM_CPER_LENGTH, fru_id, 0);
209
+
210
+ /* Build the memory section CPER for above new generic error data entry */
211
+ acpi_ghes_build_append_mem_cper(block, error_physical_addr);
212
+
213
+ /* Write the generic error data entry into guest memory */
214
+ cpu_physical_memory_write(error_block_address, block->data, block->len);
215
+
216
+ g_array_free(block, true);
217
+
218
+ return 0;
219
+}
220
+
221
/*
222
* Build table for the hardware error fw_cfg blob.
223
* Initialize "etc/hardware_errors" and "etc/hardware_errors_addr" fw_cfg blobs.
224
@@ -XXX,XX +XXX,XX @@ void acpi_ghes_add_fw_cfg(AcpiGhesState *ags, FWCfgState *s,
225
fw_cfg_add_file_callback(s, ACPI_GHES_DATA_ADDR_FW_CFG_FILE, NULL, NULL,
226
NULL, &(ags->ghes_addr_le), sizeof(ags->ghes_addr_le), false);
227
}
228
+
229
+int acpi_ghes_record_errors(uint8_t source_id, uint64_t physical_address)
230
+{
231
+ uint64_t error_block_addr, read_ack_register_addr, read_ack_register = 0;
232
+ uint64_t start_addr;
233
+ bool ret = -1;
234
+ AcpiGedState *acpi_ged_state;
235
+ AcpiGhesState *ags;
236
+
237
+ assert(source_id < ACPI_HEST_SRC_ID_RESERVED);
238
+
239
+ acpi_ged_state = ACPI_GED(object_resolve_path_type("", TYPE_ACPI_GED,
240
+ NULL));
241
+ g_assert(acpi_ged_state);
242
+ ags = &acpi_ged_state->ghes_state;
243
+
244
+ start_addr = le64_to_cpu(ags->ghes_addr_le);
245
+
246
+ if (physical_address) {
247
+
248
+ if (source_id < ACPI_HEST_SRC_ID_RESERVED) {
249
+ start_addr += source_id * sizeof(uint64_t);
250
+ }
28
+ }
251
+
29
+
252
+ cpu_physical_memory_read(start_addr, &error_block_addr,
30
switch (vms->msi_controller) {
253
+ sizeof(error_block_addr));
31
case VIRT_MSI_CTRL_NONE:
254
+
32
return;
255
+ error_block_addr = le64_to_cpu(error_block_addr);
256
+
257
+ read_ack_register_addr = start_addr +
258
+ ACPI_GHES_ERROR_SOURCE_COUNT * sizeof(uint64_t);
259
+
260
+ cpu_physical_memory_read(read_ack_register_addr,
261
+ &read_ack_register, sizeof(read_ack_register));
262
+
263
+ /* zero means OSPM does not acknowledge the error */
264
+ if (!read_ack_register) {
265
+ error_report("OSPM does not acknowledge previous error,"
266
+ " so can not record CPER for current error anymore");
267
+ } else if (error_block_addr) {
268
+ read_ack_register = cpu_to_le64(0);
269
+ /*
270
+ * Clear the Read Ack Register, OSPM will write it to 1 when
271
+ * it acknowledges this error.
272
+ */
273
+ cpu_physical_memory_write(read_ack_register_addr,
274
+ &read_ack_register, sizeof(uint64_t));
275
+
276
+ ret = acpi_ghes_record_mem_error(error_block_addr,
277
+ physical_address);
278
+ } else
279
+ error_report("can not find Generic Error Status Block");
280
+ }
281
+
282
+ return ret;
283
+}
284
--
33
--
285
2.20.1
34
2.25.1
286
35
287
36
diff view generated by jsdifflib
1
Convert the Neon integer VPMAX and VPMIN 3-reg-same insns to
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
decodetree. These are 'pairwise' operations.
3
2
3
To propagate errors to the caller of the pre_plug callback, use the
4
object_poperty_set*() functions directly instead of the qdev_prop_set*()
5
helpers.
6
7
Suggested-by: Igor Mammedov <imammedo@redhat.com>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
11
Message-id: 20211210170415.583179-5-jean-philippe@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200512163904.10918-9-peter.maydell@linaro.org
7
---
13
---
8
target/arm/neon-dp.decode | 9 +++++
14
hw/arm/virt.c | 5 +++--
9
target/arm/translate-neon.inc.c | 71 +++++++++++++++++++++++++++++++++
15
1 file changed, 3 insertions(+), 2 deletions(-)
10
target/arm/translate.c | 17 +-------
11
3 files changed, 82 insertions(+), 15 deletions(-)
12
16
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
19
--- a/hw/arm/virt.c
16
+++ b/target/arm/neon-dp.decode
20
+++ b/hw/arm/virt.c
17
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
18
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
22
db_start, db_end,
19
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
23
VIRTIO_IOMMU_RESV_MEM_T_MSI);
20
24
21
+@3same_q0 .... ... . . . size:2 .... .... .... . 0 . . .... \
25
- qdev_prop_set_uint32(dev, "len-reserved-regions", 1);
22
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp q=0
26
- qdev_prop_set_string(dev, "reserved-regions[0]", resv_prop_str);
23
+
27
+ object_property_set_uint(OBJECT(dev), "len-reserved-regions", 1, errp);
24
VHADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 0 .... @3same
28
+ object_property_set_str(OBJECT(dev), "reserved-regions[0]",
25
VHADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 0 .... @3same
29
+ resv_prop_str, errp);
26
VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
30
g_free(resv_prop_str);
27
@@ -XXX,XX +XXX,XX @@ VMLS_3s 1111 001 1 0 . .. .... .... 1001 . . . 0 .... @3same
28
VMUL_3s 1111 001 0 0 . .. .... .... 1001 . . . 1 .... @3same
29
VMUL_p_3s 1111 001 1 0 . .. .... .... 1001 . . . 1 .... @3same
30
31
+VPMAX_S_3s 1111 001 0 0 . .. .... .... 1010 . . . 0 .... @3same_q0
32
+VPMAX_U_3s 1111 001 1 0 . .. .... .... 1010 . . . 0 .... @3same_q0
33
+
34
+VPMIN_S_3s 1111 001 0 0 . .. .... .... 1010 . . . 1 .... @3same_q0
35
+VPMIN_U_3s 1111 001 1 0 . .. .... .... 1010 . . . 1 .... @3same_q0
36
+
37
VQRDMLAH_3s 1111 001 1 0 . .. .... .... 1011 ... 1 .... @3same
38
39
SHA1_3s 1111 001 0 0 . optype:2 .... .... 1100 . 1 . 0 .... \
40
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-neon.inc.c
43
+++ b/target/arm/translate-neon.inc.c
44
@@ -XXX,XX +XXX,XX @@ DO_3SAME_32_ENV(VQSHL_S, qshl_s)
45
DO_3SAME_32_ENV(VQSHL_U, qshl_u)
46
DO_3SAME_32_ENV(VQRSHL_S, qrshl_s)
47
DO_3SAME_32_ENV(VQRSHL_U, qrshl_u)
48
+
49
+static bool do_3same_pair(DisasContext *s, arg_3same *a, NeonGenTwoOpFn *fn)
50
+{
51
+ /* Operations handled pairwise 32 bits at a time */
52
+ TCGv_i32 tmp, tmp2, tmp3;
53
+
54
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
55
+ return false;
56
+ }
57
+
58
+ /* UNDEF accesses to D16-D31 if they don't exist. */
59
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
60
+ ((a->vd | a->vn | a->vm) & 0x10)) {
61
+ return false;
62
+ }
63
+
64
+ if (a->size == 3) {
65
+ return false;
66
+ }
67
+
68
+ if (!vfp_access_check(s)) {
69
+ return true;
70
+ }
71
+
72
+ assert(a->q == 0); /* enforced by decode patterns */
73
+
74
+ /*
75
+ * Note that we have to be careful not to clobber the source operands
76
+ * in the "vm == vd" case by storing the result of the first pass too
77
+ * early. Since Q is 0 there are always just two passes, so instead
78
+ * of a complicated loop over each pass we just unroll.
79
+ */
80
+ tmp = neon_load_reg(a->vn, 0);
81
+ tmp2 = neon_load_reg(a->vn, 1);
82
+ fn(tmp, tmp, tmp2);
83
+ tcg_temp_free_i32(tmp2);
84
+
85
+ tmp3 = neon_load_reg(a->vm, 0);
86
+ tmp2 = neon_load_reg(a->vm, 1);
87
+ fn(tmp3, tmp3, tmp2);
88
+ tcg_temp_free_i32(tmp2);
89
+
90
+ neon_store_reg(a->vd, 0, tmp);
91
+ neon_store_reg(a->vd, 1, tmp3);
92
+ return true;
93
+}
94
+
95
+#define DO_3SAME_PAIR(INSN, func) \
96
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
97
+ { \
98
+ static NeonGenTwoOpFn * const fns[] = { \
99
+ gen_helper_neon_##func##8, \
100
+ gen_helper_neon_##func##16, \
101
+ gen_helper_neon_##func##32, \
102
+ }; \
103
+ if (a->size > 2) { \
104
+ return false; \
105
+ } \
106
+ return do_3same_pair(s, a, fns[a->size]); \
107
+ }
108
+
109
+/* 32-bit pairwise ops end up the same as the elementwise versions. */
110
+#define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
111
+#define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
112
+#define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
113
+#define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
114
+
115
+DO_3SAME_PAIR(VPMAX_S, pmax_s)
116
+DO_3SAME_PAIR(VPMIN_S, pmin_s)
117
+DO_3SAME_PAIR(VPMAX_U, pmax_u)
118
+DO_3SAME_PAIR(VPMIN_U, pmin_u)
119
diff --git a/target/arm/translate.c b/target/arm/translate.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/translate.c
122
+++ b/target/arm/translate.c
123
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
124
}
31
}
125
}
32
}
126
127
-/* 32-bit pairwise ops end up the same as the elementwise versions. */
128
-#define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
129
-#define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
130
-#define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
131
-#define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
132
-
133
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
134
switch ((size << 1) | u) { \
135
case 0: \
136
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
137
case NEON_3R_VQSHL:
138
case NEON_3R_VRSHL:
139
case NEON_3R_VQRSHL:
140
+ case NEON_3R_VPMAX:
141
+ case NEON_3R_VPMIN:
142
/* Already handled by decodetree */
143
return 1;
144
}
145
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
146
pairwise = 0;
147
switch (op) {
148
case NEON_3R_VPADD_VQRDMLAH:
149
- case NEON_3R_VPMAX:
150
- case NEON_3R_VPMIN:
151
pairwise = 1;
152
break;
153
case NEON_3R_FLOAT_ARITH:
154
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
155
tmp2 = neon_load_reg(rm, pass);
156
}
157
switch (op) {
158
- break;
159
- case NEON_3R_VPMAX:
160
- GEN_NEON_INTEGER_OP(pmax);
161
- break;
162
- case NEON_3R_VPMIN:
163
- GEN_NEON_INTEGER_OP(pmin);
164
- break;
165
case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
166
if (!u) { /* VQDMULH */
167
switch (size) {
168
--
33
--
169
2.20.1
34
2.25.1
170
35
171
36
diff view generated by jsdifflib
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
Add APEI/GHES detailed design document
3
Create empty data files and allow updates for the upcoming VIOT tests.
4
4
5
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
5
Acked-by: Igor Mammedov <imammedo@redhat.com>
6
Signed-off-by: Xiang Zheng <zhengxiang9@huawei.com>
6
Reviewed-by: Eric Auger <eric.auger@redhat.com>
7
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
7
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
8
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
8
Message-id: 20211210170415.583179-6-jean-philippe@linaro.org
9
Message-id: 20200512030609.19593-4-gengdongjiu@huawei.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
docs/specs/acpi_hest_ghes.rst | 110 ++++++++++++++++++++++++++++++++++
11
tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
13
docs/specs/index.rst | 1 +
12
tests/data/acpi/q35/DSDT.viot | 0
14
2 files changed, 111 insertions(+)
13
tests/data/acpi/q35/VIOT.viot | 0
15
create mode 100644 docs/specs/acpi_hest_ghes.rst
14
tests/data/acpi/virt/VIOT | 0
15
4 files changed, 3 insertions(+)
16
create mode 100644 tests/data/acpi/q35/DSDT.viot
17
create mode 100644 tests/data/acpi/q35/VIOT.viot
18
create mode 100644 tests/data/acpi/virt/VIOT
16
19
17
diff --git a/docs/specs/acpi_hest_ghes.rst b/docs/specs/acpi_hest_ghes.rst
20
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/tests/qtest/bios-tables-test-allowed-diff.h
23
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
24
@@ -1 +1,4 @@
25
/* List of comma-separated changed AML files to ignore */
26
+"tests/data/acpi/virt/VIOT",
27
+"tests/data/acpi/q35/DSDT.viot",
28
+"tests/data/acpi/q35/VIOT.viot",
29
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
18
new file mode 100644
30
new file mode 100644
19
index XXXXXXX..XXXXXXX
31
index XXXXXXX..XXXXXXX
20
--- /dev/null
32
diff --git a/tests/data/acpi/q35/VIOT.viot b/tests/data/acpi/q35/VIOT.viot
21
+++ b/docs/specs/acpi_hest_ghes.rst
33
new file mode 100644
22
@@ -XXX,XX +XXX,XX @@
34
index XXXXXXX..XXXXXXX
23
+APEI tables generating and CPER record
35
diff --git a/tests/data/acpi/virt/VIOT b/tests/data/acpi/virt/VIOT
24
+======================================
36
new file mode 100644
25
+
37
index XXXXXXX..XXXXXXX
26
+..
27
+ Copyright (c) 2020 HUAWEI TECHNOLOGIES CO., LTD.
28
+
29
+ This work is licensed under the terms of the GNU GPL, version 2 or later.
30
+ See the COPYING file in the top-level directory.
31
+
32
+Design Details
33
+--------------
34
+
35
+::
36
+
37
+ etc/acpi/tables etc/hardware_errors
38
+ ==================== ===============================
39
+ + +--------------------------+ +----------------------------+
40
+ | | HEST | +--------->| error_block_address1 |------+
41
+ | +--------------------------+ | +----------------------------+ |
42
+ | | GHES1 | | +------->| error_block_address2 |------+-+
43
+ | +--------------------------+ | | +----------------------------+ | |
44
+ | | ................. | | | | .............. | | |
45
+ | | error_status_address-----+-+ | -----------------------------+ | |
46
+ | | ................. | | +--->| error_block_addressN |------+-+---+
47
+ | | read_ack_register--------+-+ | | +----------------------------+ | | |
48
+ | | read_ack_preserve | +-+---+--->| read_ack_register1 | | | |
49
+ | | read_ack_write | | | +----------------------------+ | | |
50
+ + +--------------------------+ | +-+--->| read_ack_register2 | | | |
51
+ | | GHES2 | | | | +----------------------------+ | | |
52
+ + +--------------------------+ | | | | ............. | | | |
53
+ | | ................. | | | | +----------------------------+ | | |
54
+ | | error_status_address-----+---+ | | +->| read_ack_registerN | | | |
55
+ | | ................. | | | | +----------------------------+ | | |
56
+ | | read_ack_register--------+-----+ | | |Generic Error Status Block 1|<-----+ | |
57
+ | | read_ack_preserve | | | |-+------------------------+-+ | |
58
+ | | read_ack_write | | | | | CPER | | | |
59
+ + +--------------------------| | | | | CPER | | | |
60
+ | | ............... | | | | | .... | | | |
61
+ + +--------------------------+ | | | | CPER | | | |
62
+ | | GHESN | | | |-+------------------------+-| | |
63
+ + +--------------------------+ | | |Generic Error Status Block 2|<-------+ |
64
+ | | ................. | | | |-+------------------------+-+ |
65
+ | | error_status_address-----+-------+ | | | CPER | | |
66
+ | | ................. | | | | CPER | | |
67
+ | | read_ack_register--------+---------+ | | .... | | |
68
+ | | read_ack_preserve | | | CPER | | |
69
+ | | read_ack_write | +-+------------------------+-+ |
70
+ + +--------------------------+ | .......... | |
71
+ |----------------------------+ |
72
+ |Generic Error Status Block N |<----------+
73
+ |-+-------------------------+-+
74
+ | | CPER | |
75
+ | | CPER | |
76
+ | | .... | |
77
+ | | CPER | |
78
+ +-+-------------------------+-+
79
+
80
+
81
+(1) QEMU generates the ACPI HEST table. This table goes in the current
82
+ "etc/acpi/tables" fw_cfg blob. Each error source has different
83
+ notification types.
84
+
85
+(2) A new fw_cfg blob called "etc/hardware_errors" is introduced. QEMU
86
+ also needs to populate this blob. The "etc/hardware_errors" fw_cfg blob
87
+ contains an address registers table and an Error Status Data Block table.
88
+
89
+(3) The address registers table contains N Error Block Address entries
90
+ and N Read Ack Register entries. The size for each entry is 8-byte.
91
+ The Error Status Data Block table contains N Error Status Data Block
92
+ entries. The size for each entry is 4096(0x1000) bytes. The total size
93
+ for the "etc/hardware_errors" fw_cfg blob is (N * 8 * 2 + N * 4096) bytes.
94
+ N is the number of the kinds of hardware error sources.
95
+
96
+(4) QEMU generates the ACPI linker/loader script for the firmware. The
97
+ firmware pre-allocates memory for "etc/acpi/tables", "etc/hardware_errors"
98
+ and copies blob contents there.
99
+
100
+(5) QEMU generates N ADD_POINTER commands, which patch addresses in the
101
+ "error_status_address" fields of the HEST table with a pointer to the
102
+ corresponding "address registers" in the "etc/hardware_errors" blob.
103
+
104
+(6) QEMU generates N ADD_POINTER commands, which patch addresses in the
105
+ "read_ack_register" fields of the HEST table with a pointer to the
106
+ corresponding "read_ack_register" within the "etc/hardware_errors" blob.
107
+
108
+(7) QEMU generates N ADD_POINTER commands for the firmware, which patch
109
+ addresses in the "error_block_address" fields with a pointer to the
110
+ respective "Error Status Data Block" in the "etc/hardware_errors" blob.
111
+
112
+(8) QEMU defines a third and write-only fw_cfg blob which is called
113
+ "etc/hardware_errors_addr". Through that blob, the firmware can send back
114
+ the guest-side allocation addresses to QEMU. The "etc/hardware_errors_addr"
115
+ blob contains a 8-byte entry. QEMU generates a single WRITE_POINTER command
116
+ for the firmware. The firmware will write back the start address of
117
+ "etc/hardware_errors" blob to the fw_cfg file "etc/hardware_errors_addr".
118
+
119
+(9) When QEMU gets a SIGBUS from the kernel, QEMU writes CPER into corresponding
120
+ "Error Status Data Block", guest memory, and then injects platform specific
121
+ interrupt (in case of arm/virt machine it's Synchronous External Abort) as a
122
+ notification which is necessary for notifying the guest.
123
+
124
+(10) This notification (in virtual hardware) will be handled by the guest
125
+ kernel, on receiving notification, guest APEI driver could read the CPER error
126
+ and take appropriate action.
127
+
128
+(11) kvm_arch_on_sigbus_vcpu() uses source_id as index in "etc/hardware_errors" to
129
+ find out "Error Status Data Block" entry corresponding to error source. So supported
130
+ source_id values should be assigned here and not be changed afterwards to make sure
131
+ that guest will write error into expected "Error Status Data Block" even if guest was
132
+ migrated to a newer QEMU.
133
diff --git a/docs/specs/index.rst b/docs/specs/index.rst
134
index XXXXXXX..XXXXXXX 100644
135
--- a/docs/specs/index.rst
136
+++ b/docs/specs/index.rst
137
@@ -XXX,XX +XXX,XX @@ Contents:
138
ppc-spapr-xive
139
acpi_hw_reduced_hotplug
140
tpm
141
+ acpi_hest_ghes
142
--
38
--
143
2.20.1
39
2.25.1
144
40
145
41
diff view generated by jsdifflib
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
Add a SIGBUS signal handler. In this handler, it checks the SIGBUS type,
3
Add two test cases for VIOT, one on the q35 machine and the other on
4
translates the host VA delivered by host to guest PA, then fills this PA
4
virt. To test complex topologies the q35 test has two PCIe buses that
5
to guest APEI GHES memory, then notifies guest according to the SIGBUS
5
bypass the IOMMU (and are therefore not described by VIOT), and two
6
type.
6
buses that are translated by virtio-iommu.
7
7
8
When guest accesses the poisoned memory, it will generate a Synchronous
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
External Abort(SEA). Then host kernel gets an APEI notification and calls
10
memory_failure() to unmapped the affected page in stage 2, finally
11
returns to guest.
12
13
Guest continues to access the PG_hwpoison page, it will trap to KVM as
14
stage2 fault, then a SIGBUS_MCEERR_AR synchronous signal is delivered to
15
Qemu, Qemu records this error address into guest APEI GHES memory and
16
notifes guest using Synchronous-External-Abort(SEA).
17
18
In order to inject a vSEA, we introduce the kvm_inject_arm_sea() function
19
in which we can setup the type of exception and the syndrome information.
20
When switching to guest, the target vcpu will jump to the synchronous
21
external abort vector table entry.
22
23
The ESR_ELx.DFSC is set to synchronous external abort(0x10), and the
24
ESR_ELx.FnV is set to not valid(0x1), which will tell guest that FAR is
25
not valid and hold an UNKNOWN value. These values will be set to KVM
26
register structures through KVM_SET_ONE_REG IOCTL.
27
28
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
29
Signed-off-by: Xiang Zheng <zhengxiang9@huawei.com>
30
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
31
Acked-by: Xiang Zheng <zhengxiang9@huawei.com>
32
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
34
Message-id: 20200512030609.19593-10-gengdongjiu@huawei.com
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
11
Message-id: 20211210170415.583179-7-jean-philippe@linaro.org
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
36
---
13
---
37
include/sysemu/kvm.h | 3 +-
14
tests/qtest/bios-tables-test.c | 38 ++++++++++++++++++++++++++++++++++
38
target/arm/cpu.h | 4 +++
15
1 file changed, 38 insertions(+)
39
target/arm/internals.h | 5 +--
40
target/i386/cpu.h | 2 ++
41
target/arm/helper.c | 2 +-
42
target/arm/kvm64.c | 77 +++++++++++++++++++++++++++++++++++++++++
43
target/arm/tlb_helper.c | 2 +-
44
7 files changed, 89 insertions(+), 6 deletions(-)
45
16
46
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
17
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
47
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
48
--- a/include/sysemu/kvm.h
19
--- a/tests/qtest/bios-tables-test.c
49
+++ b/include/sysemu/kvm.h
20
+++ b/tests/qtest/bios-tables-test.c
50
@@ -XXX,XX +XXX,XX @@ bool kvm_vcpu_id_is_valid(int vcpu_id);
21
@@ -XXX,XX +XXX,XX @@ static void test_acpi_virt_tcg(void)
51
/* Returns VCPU ID to be used on KVM_CREATE_VCPU ioctl() */
22
free_test_data(&data);
52
unsigned long kvm_arch_vcpu_id(CPUState *cpu);
53
54
-#ifdef TARGET_I386
55
-#define KVM_HAVE_MCE_INJECTION 1
56
+#ifdef KVM_HAVE_MCE_INJECTION
57
void kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr);
58
#endif
59
60
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/cpu.h
63
+++ b/target/arm/cpu.h
64
@@ -XXX,XX +XXX,XX @@
65
/* ARM processors have a weak memory model */
66
#define TCG_GUEST_DEFAULT_MO (0)
67
68
+#ifdef TARGET_AARCH64
69
+#define KVM_HAVE_MCE_INJECTION 1
70
+#endif
71
+
72
#define EXCP_UDEF 1 /* undefined instruction */
73
#define EXCP_SWI 2 /* software interrupt */
74
#define EXCP_PREFETCH_ABORT 3
75
diff --git a/target/arm/internals.h b/target/arm/internals.h
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/internals.h
78
+++ b/target/arm/internals.h
79
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
80
| ARM_EL_IL | (ea << 9) | (s1ptw << 7) | fsc;
81
}
23
}
82
24
83
-static inline uint32_t syn_data_abort_no_iss(int same_el,
25
+static void test_acpi_q35_viot(void)
84
+static inline uint32_t syn_data_abort_no_iss(int same_el, int fnv,
85
int ea, int cm, int s1ptw,
86
int wnr, int fsc)
87
{
88
return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
89
| ARM_EL_IL
90
- | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
91
+ | (fnv << 10) | (ea << 9) | (cm << 8) | (s1ptw << 7)
92
+ | (wnr << 6) | fsc;
93
}
94
95
static inline uint32_t syn_data_abort_with_iss(int same_el,
96
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/i386/cpu.h
99
+++ b/target/i386/cpu.h
100
@@ -XXX,XX +XXX,XX @@
101
/* The x86 has a strong memory model with some store-after-load re-ordering */
102
#define TCG_GUEST_DEFAULT_MO (TCG_MO_ALL & ~TCG_MO_ST_LD)
103
104
+#define KVM_HAVE_MCE_INJECTION 1
105
+
106
/* Maximum instruction code size */
107
#define TARGET_MAX_INSN_SIZE 16
108
109
diff --git a/target/arm/helper.c b/target/arm/helper.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/helper.c
112
+++ b/target/arm/helper.c
113
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
114
* Report exception with ESR indicating a fault due to a
115
* translation table walk for a cache maintenance instruction.
116
*/
117
- syn = syn_data_abort_no_iss(current_el == target_el,
118
+ syn = syn_data_abort_no_iss(current_el == target_el, 0,
119
fi.ea, 1, fi.s1ptw, 1, fsc);
120
env->exception.vaddress = value;
121
env->exception.fsr = fsr;
122
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/target/arm/kvm64.c
125
+++ b/target/arm/kvm64.c
126
@@ -XXX,XX +XXX,XX @@
127
#include "sysemu/kvm_int.h"
128
#include "kvm_arm.h"
129
#include "internals.h"
130
+#include "hw/acpi/acpi.h"
131
+#include "hw/acpi/ghes.h"
132
+#include "hw/arm/virt.h"
133
134
static bool have_guest_debug;
135
136
@@ -XXX,XX +XXX,XX @@ int kvm_arm_cpreg_level(uint64_t regidx)
137
return KVM_PUT_RUNTIME_STATE;
138
}
139
140
+/* Callers must hold the iothread mutex lock */
141
+static void kvm_inject_arm_sea(CPUState *c)
142
+{
26
+{
143
+ ARMCPU *cpu = ARM_CPU(c);
27
+ test_data data = {
144
+ CPUARMState *env = &cpu->env;
28
+ .machine = MACHINE_Q35,
145
+ CPUClass *cc = CPU_GET_CLASS(c);
29
+ .variant = ".viot",
146
+ uint32_t esr;
30
+ };
147
+ bool same_el;
148
+
149
+ c->exception_index = EXCP_DATA_ABORT;
150
+ env->exception.target_el = 1;
151
+
31
+
152
+ /*
32
+ /*
153
+ * Set the DFSC to synchronous external abort and set FnV to not valid,
33
+ * To keep things interesting, two buses bypass the IOMMU.
154
+ * this will tell guest the FAR_ELx is UNKNOWN for this abort.
34
+ * VIOT should only describes the other two buses.
155
+ */
35
+ */
156
+ same_el = arm_current_el(env) == env->exception.target_el;
36
+ test_acpi_one("-machine default_bus_bypass_iommu=on "
157
+ esr = syn_data_abort_no_iss(same_el, 1, 0, 0, 0, 0, 0x10);
37
+ "-device virtio-iommu-pci "
158
+
38
+ "-device pxb-pcie,bus_nr=0x10,id=pcie.100,bus=pcie.0 "
159
+ env->exception.syndrome = esr;
39
+ "-device pxb-pcie,bus_nr=0x20,id=pcie.200,bus=pcie.0,bypass_iommu=on "
160
+
40
+ "-device pxb-pcie,bus_nr=0x30,id=pcie.300,bus=pcie.0",
161
+ cc->do_interrupt(c);
41
+ &data);
42
+ free_test_data(&data);
162
+}
43
+}
163
+
44
+
164
#define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
45
+static void test_acpi_virt_viot(void)
165
KVM_REG_ARM_CORE | KVM_REG_ARM_CORE_REG(x))
166
167
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
168
return ret;
169
}
170
171
+void kvm_arch_on_sigbus_vcpu(CPUState *c, int code, void *addr)
172
+{
46
+{
173
+ ram_addr_t ram_addr;
47
+ test_data data = {
174
+ hwaddr paddr;
48
+ .machine = "virt",
175
+ Object *obj = qdev_get_machine();
49
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
176
+ VirtMachineState *vms = VIRT_MACHINE(obj);
50
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
177
+ bool acpi_enabled = virt_is_acpi_enabled(vms);
51
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
52
+ .ram_start = 0x40000000ULL,
53
+ .scan_len = 128ULL * 1024 * 1024,
54
+ };
178
+
55
+
179
+ assert(code == BUS_MCEERR_AR || code == BUS_MCEERR_AO);
56
+ test_acpi_one("-cpu cortex-a57 "
180
+
57
+ "-device virtio-iommu-pci", &data);
181
+ if (acpi_enabled && addr &&
58
+ free_test_data(&data);
182
+ object_property_get_bool(obj, "ras", NULL)) {
183
+ ram_addr = qemu_ram_addr_from_host(addr);
184
+ if (ram_addr != RAM_ADDR_INVALID &&
185
+ kvm_physical_memory_addr_from_host(c->kvm_state, addr, &paddr)) {
186
+ kvm_hwpoison_page_add(ram_addr);
187
+ /*
188
+ * If this is a BUS_MCEERR_AR, we know we have been called
189
+ * synchronously from the vCPU thread, so we can easily
190
+ * synchronize the state and inject an error.
191
+ *
192
+ * TODO: we currently don't tell the guest at all about
193
+ * BUS_MCEERR_AO. In that case we might either be being
194
+ * called synchronously from the vCPU thread, or a bit
195
+ * later from the main thread, so doing the injection of
196
+ * the error would be more complicated.
197
+ */
198
+ if (code == BUS_MCEERR_AR) {
199
+ kvm_cpu_synchronize_state(c);
200
+ if (!acpi_ghes_record_errors(ACPI_HEST_SRC_ID_SEA, paddr)) {
201
+ kvm_inject_arm_sea(c);
202
+ } else {
203
+ error_report("failed to record the error");
204
+ abort();
205
+ }
206
+ }
207
+ return;
208
+ }
209
+ if (code == BUS_MCEERR_AO) {
210
+ error_report("Hardware memory error at addr %p for memory used by "
211
+ "QEMU itself instead of guest system!", addr);
212
+ }
213
+ }
214
+
215
+ if (code == BUS_MCEERR_AR) {
216
+ error_report("Hardware memory error!");
217
+ exit(1);
218
+ }
219
+}
59
+}
220
+
60
+
221
/* C6.6.29 BRK instruction */
61
static void test_oem_fields(test_data *data)
222
static const uint32_t brk_insn = 0xd4200000;
62
{
223
63
int i;
224
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
64
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
225
index XXXXXXX..XXXXXXX 100644
65
qtest_add_func("acpi/q35/kvm/xapic", test_acpi_q35_kvm_xapic);
226
--- a/target/arm/tlb_helper.c
66
qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar);
227
+++ b/target/arm/tlb_helper.c
67
}
228
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
68
+ qtest_add_func("acpi/q35/viot", test_acpi_q35_viot);
229
* ISV field.
69
} else if (strcmp(arch, "aarch64") == 0) {
230
*/
70
if (has_tcg) {
231
if (!(template_syn & ARM_EL_ISV) || target_el != 2 || s1ptw) {
71
qtest_add_func("acpi/virt", test_acpi_virt_tcg);
232
- syn = syn_data_abort_no_iss(same_el,
72
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
233
+ syn = syn_data_abort_no_iss(same_el, 0,
73
qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp);
234
ea, 0, s1ptw, is_write, fsc);
74
qtest_add_func("acpi/virt/pxb", test_acpi_virt_tcg_pxb);
235
} else {
75
qtest_add_func("acpi/virt/oem-fields", test_acpi_oem_fields_virt);
236
/*
76
+ qtest_add_func("acpi/virt/viot", test_acpi_virt_viot);
77
}
78
}
79
ret = g_test_run();
237
--
80
--
238
2.20.1
81
2.25.1
239
82
240
83
diff view generated by jsdifflib
1
Convert the Neon integer VPADD 3-reg-same insns to decodetree. These
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
are 'pairwise' operations. (Note that VQRDMLAH, which shares the
2
3
same primary opcode but has U=1, has already been converted.)
3
Add expected blobs of the VIOT and DSDT table for the VIOT test on the
4
4
q35 machine.
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Since the test instantiates a virtio device and two PCIe expander
7
Message-id: 20200512163904.10918-10-peter.maydell@linaro.org
7
bridges, DSDT.viot has more blocks than the base DSDT.
8
---
8
9
target/arm/neon-dp.decode | 2 ++
9
The VIOT table generated for the q35 test is:
10
target/arm/translate-neon.inc.c | 2 ++
10
11
target/arm/translate.c | 19 +------------------
11
[000h 0000 4] Signature : "VIOT" [Virtual I/O Translation Table]
12
3 files changed, 5 insertions(+), 18 deletions(-)
12
[004h 0004 4] Table Length : 00000070
13
13
[008h 0008 1] Revision : 00
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
[009h 0009 1] Checksum : 3D
15
index XXXXXXX..XXXXXXX 100644
15
[00Ah 0010 6] Oem ID : "BOCHS "
16
--- a/target/arm/neon-dp.decode
16
[010h 0016 8] Oem Table ID : "BXPC "
17
+++ b/target/arm/neon-dp.decode
17
[018h 0024 4] Oem Revision : 00000001
18
@@ -XXX,XX +XXX,XX @@ VPMAX_U_3s 1111 001 1 0 . .. .... .... 1010 . . . 0 .... @3same_q0
18
[01Ch 0028 4] Asl Compiler ID : "BXPC"
19
VPMIN_S_3s 1111 001 0 0 . .. .... .... 1010 . . . 1 .... @3same_q0
19
[020h 0032 4] Asl Compiler Revision : 00000001
20
VPMIN_U_3s 1111 001 1 0 . .. .... .... 1010 . . . 1 .... @3same_q0
20
21
21
[024h 0036 2] Node count : 0003
22
+VPADD_3s 1111 001 0 0 . .. .... .... 1011 . . . 1 .... @3same_q0
22
[026h 0038 2] Node offset : 0030
23
+
23
[028h 0040 8] Reserved : 0000000000000000
24
VQRDMLAH_3s 1111 001 1 0 . .. .... .... 1011 ... 1 .... @3same
24
25
25
[030h 0048 1] Type : 03 [VirtIO-PCI IOMMU]
26
SHA1_3s 1111 001 0 0 . optype:2 .... .... 1100 . 1 . 0 .... \
26
[031h 0049 1] Reserved : 00
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
27
[032h 0050 2] Length : 0010
28
index XXXXXXX..XXXXXXX 100644
28
29
--- a/target/arm/translate-neon.inc.c
29
[034h 0052 2] PCI Segment : 0000
30
+++ b/target/arm/translate-neon.inc.c
30
[036h 0054 2] PCI BDF number : 0010
31
@@ -XXX,XX +XXX,XX @@ static bool do_3same_pair(DisasContext *s, arg_3same *a, NeonGenTwoOpFn *fn)
31
[038h 0056 8] Reserved : 0000000000000000
32
#define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
32
33
#define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
33
[040h 0064 1] Type : 01 [PCI Range]
34
#define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
34
[041h 0065 1] Reserved : 00
35
+#define gen_helper_neon_padd_u32 tcg_gen_add_i32
35
[042h 0066 2] Length : 0018
36
36
37
DO_3SAME_PAIR(VPMAX_S, pmax_s)
37
[044h 0068 4] Endpoint start : 00003000
38
DO_3SAME_PAIR(VPMIN_S, pmin_s)
38
[048h 0072 2] PCI Segment start : 0000
39
DO_3SAME_PAIR(VPMAX_U, pmax_u)
39
[04Ah 0074 2] PCI Segment end : 0000
40
DO_3SAME_PAIR(VPMIN_U, pmin_u)
40
[04Ch 0076 2] PCI BDF start : 3000
41
+DO_3SAME_PAIR(VPADD, padd_u)
41
[04Eh 0078 2] PCI BDF end : 30FF
42
diff --git a/target/arm/translate.c b/target/arm/translate.c
42
[050h 0080 2] Output node : 0030
43
index XXXXXXX..XXXXXXX 100644
43
[052h 0082 6] Reserved : 000000000000
44
--- a/target/arm/translate.c
44
45
+++ b/target/arm/translate.c
45
[058h 0088 1] Type : 01 [PCI Range]
46
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
46
[059h 0089 1] Reserved : 00
47
return 1;
47
[05Ah 0090 2] Length : 0018
48
49
[05Ch 0092 4] Endpoint start : 00001000
50
[060h 0096 2] PCI Segment start : 0000
51
[062h 0098 2] PCI Segment end : 0000
52
[064h 0100 2] PCI BDF start : 1000
53
[066h 0102 2] PCI BDF end : 10FF
54
[068h 0104 2] Output node : 0030
55
[06Ah 0106 6] Reserved : 000000000000
56
57
And the DSDT diff is:
58
59
@@ -XXX,XX +XXX,XX @@
60
*
61
* Disassembling to symbolic ASL+ operators
62
*
63
- * Disassembly of tests/data/acpi/q35/DSDT, Fri Dec 10 15:03:08 2021
64
+ * Disassembly of /tmp/aml-H9Y5D1, Fri Dec 10 15:02:27 2021
65
*
66
* Original Table Header:
67
* Signature "DSDT"
68
- * Length 0x00002061 (8289)
69
+ * Length 0x000024B6 (9398)
70
* Revision 0x01 **** 32-bit table (V1), no 64-bit math support
71
- * Checksum 0xFA
72
+ * Checksum 0xA7
73
* OEM ID "BOCHS "
74
* OEM Table ID "BXPC "
75
* OEM Revision 0x00000001 (1)
76
@@ -XXX,XX +XXX,XX @@
48
}
77
}
49
switch (op) {
78
}
50
- case NEON_3R_VPADD_VQRDMLAH:
79
51
- if (!u) {
80
+ Scope (\_SB)
52
- break; /* VPADD */
81
+ {
53
- }
82
+ Device (PC30)
54
- /* VQRDMLAH : handled by decodetree */
83
+ {
55
- return 1;
84
+ Name (_UID, 0x30) // _UID: Unique ID
56
-
85
+ Name (_BBN, 0x30) // _BBN: BIOS Bus Number
57
case NEON_3R_VFM_VQRDMLSH:
86
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
58
if (!u) {
87
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
59
/* VFM, VFMS */
88
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
60
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
89
+ {
61
case NEON_3R_VQRSHL:
90
+ CreateDWordField (Arg3, Zero, CDW1)
62
case NEON_3R_VPMAX:
91
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
63
case NEON_3R_VPMIN:
92
+ {
64
+ case NEON_3R_VPADD_VQRDMLAH:
93
+ CreateDWordField (Arg3, 0x04, CDW2)
65
/* Already handled by decodetree */
94
+ CreateDWordField (Arg3, 0x08, CDW3)
66
return 1;
95
+ Local0 = CDW3 /* \_SB_.PC30._OSC.CDW3 */
67
}
96
+ Local0 &= 0x1F
68
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
97
+ If ((Arg1 != One))
69
}
98
+ {
70
pairwise = 0;
99
+ CDW1 |= 0x08
71
switch (op) {
100
+ }
72
- case NEON_3R_VPADD_VQRDMLAH:
101
+
73
- pairwise = 1;
102
+ If ((CDW3 != Local0))
74
- break;
103
+ {
75
case NEON_3R_FLOAT_ARITH:
104
+ CDW1 |= 0x10
76
pairwise = (u && size < 2); /* if VPADD (float) */
105
+ }
77
break;
106
+
78
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
107
+ CDW3 = Local0
108
+ }
109
+ Else
110
+ {
111
+ CDW1 |= 0x04
112
+ }
113
+
114
+ Return (Arg3)
115
+ }
116
+
117
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
118
+ {
119
+ Local0 = Package (0x80){}
120
+ Local1 = Zero
121
+ While ((Local1 < 0x80))
122
+ {
123
+ Local2 = (Local1 >> 0x02)
124
+ Local3 = ((Local1 + Local2) & 0x03)
125
+ If ((Local3 == Zero))
126
+ {
127
+ Local4 = Package (0x04)
128
+ {
129
+ Zero,
130
+ Zero,
131
+ LNKD,
132
+ Zero
133
+ }
134
+ }
135
+
136
+ If ((Local3 == One))
137
+ {
138
+ Local4 = Package (0x04)
139
+ {
140
+ Zero,
141
+ Zero,
142
+ LNKA,
143
+ Zero
144
+ }
145
+ }
146
+
147
+ If ((Local3 == 0x02))
148
+ {
149
+ Local4 = Package (0x04)
150
+ {
151
+ Zero,
152
+ Zero,
153
+ LNKB,
154
+ Zero
155
+ }
156
+ }
157
+
158
+ If ((Local3 == 0x03))
159
+ {
160
+ Local4 = Package (0x04)
161
+ {
162
+ Zero,
163
+ Zero,
164
+ LNKC,
165
+ Zero
166
+ }
167
+ }
168
+
169
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
170
+ Local4 [One] = (Local1 & 0x03)
171
+ Local0 [Local1] = Local4
172
+ Local1++
173
+ }
174
+
175
+ Return (Local0)
176
+ }
177
+
178
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
179
+ {
180
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
181
+ 0x0000, // Granularity
182
+ 0x0030, // Range Minimum
183
+ 0x0030, // Range Maximum
184
+ 0x0000, // Translation Offset
185
+ 0x0001, // Length
186
+ ,, )
187
+ })
188
+ }
189
+ }
190
+
191
+ Scope (\_SB)
192
+ {
193
+ Device (PC20)
194
+ {
195
+ Name (_UID, 0x20) // _UID: Unique ID
196
+ Name (_BBN, 0x20) // _BBN: BIOS Bus Number
197
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
198
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
199
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
200
+ {
201
+ CreateDWordField (Arg3, Zero, CDW1)
202
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
203
+ {
204
+ CreateDWordField (Arg3, 0x04, CDW2)
205
+ CreateDWordField (Arg3, 0x08, CDW3)
206
+ Local0 = CDW3 /* \_SB_.PC20._OSC.CDW3 */
207
+ Local0 &= 0x1F
208
+ If ((Arg1 != One))
209
+ {
210
+ CDW1 |= 0x08
211
+ }
212
+
213
+ If ((CDW3 != Local0))
214
+ {
215
+ CDW1 |= 0x10
216
+ }
217
+
218
+ CDW3 = Local0
219
+ }
220
+ Else
221
+ {
222
+ CDW1 |= 0x04
223
+ }
224
+
225
+ Return (Arg3)
226
+ }
227
+
228
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
229
+ {
230
+ Local0 = Package (0x80){}
231
+ Local1 = Zero
232
+ While ((Local1 < 0x80))
233
+ {
234
+ Local2 = (Local1 >> 0x02)
235
+ Local3 = ((Local1 + Local2) & 0x03)
236
+ If ((Local3 == Zero))
237
+ {
238
+ Local4 = Package (0x04)
239
+ {
240
+ Zero,
241
+ Zero,
242
+ LNKD,
243
+ Zero
244
+ }
245
+ }
246
+
247
+ If ((Local3 == One))
248
+ {
249
+ Local4 = Package (0x04)
250
+ {
251
+ Zero,
252
+ Zero,
253
+ LNKA,
254
+ Zero
255
+ }
256
+ }
257
+
258
+ If ((Local3 == 0x02))
259
+ {
260
+ Local4 = Package (0x04)
261
+ {
262
+ Zero,
263
+ Zero,
264
+ LNKB,
265
+ Zero
266
+ }
267
+ }
268
+
269
+ If ((Local3 == 0x03))
270
+ {
271
+ Local4 = Package (0x04)
272
+ {
273
+ Zero,
274
+ Zero,
275
+ LNKC,
276
+ Zero
277
+ }
278
+ }
279
+
280
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
281
+ Local4 [One] = (Local1 & 0x03)
282
+ Local0 [Local1] = Local4
283
+ Local1++
284
+ }
285
+
286
+ Return (Local0)
287
+ }
288
+
289
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
290
+ {
291
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
292
+ 0x0000, // Granularity
293
+ 0x0020, // Range Minimum
294
+ 0x0020, // Range Maximum
295
+ 0x0000, // Translation Offset
296
+ 0x0001, // Length
297
+ ,, )
298
+ })
299
+ }
300
+ }
301
+
302
+ Scope (\_SB)
303
+ {
304
+ Device (PC10)
305
+ {
306
+ Name (_UID, 0x10) // _UID: Unique ID
307
+ Name (_BBN, 0x10) // _BBN: BIOS Bus Number
308
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
309
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
310
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
311
+ {
312
+ CreateDWordField (Arg3, Zero, CDW1)
313
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
314
+ {
315
+ CreateDWordField (Arg3, 0x04, CDW2)
316
+ CreateDWordField (Arg3, 0x08, CDW3)
317
+ Local0 = CDW3 /* \_SB_.PC10._OSC.CDW3 */
318
+ Local0 &= 0x1F
319
+ If ((Arg1 != One))
320
+ {
321
+ CDW1 |= 0x08
322
+ }
323
+
324
+ If ((CDW3 != Local0))
325
+ {
326
+ CDW1 |= 0x10
327
+ }
328
+
329
+ CDW3 = Local0
330
+ }
331
+ Else
332
+ {
333
+ CDW1 |= 0x04
334
+ }
335
+
336
+ Return (Arg3)
337
+ }
338
+
339
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
340
+ {
341
+ Local0 = Package (0x80){}
342
+ Local1 = Zero
343
+ While ((Local1 < 0x80))
344
+ {
345
+ Local2 = (Local1 >> 0x02)
346
+ Local3 = ((Local1 + Local2) & 0x03)
347
+ If ((Local3 == Zero))
348
+ {
349
+ Local4 = Package (0x04)
350
+ {
351
+ Zero,
352
+ Zero,
353
+ LNKD,
354
+ Zero
355
+ }
356
+ }
357
+
358
+ If ((Local3 == One))
359
+ {
360
+ Local4 = Package (0x04)
361
+ {
362
+ Zero,
363
+ Zero,
364
+ LNKA,
365
+ Zero
366
+ }
367
+ }
368
+
369
+ If ((Local3 == 0x02))
370
+ {
371
+ Local4 = Package (0x04)
372
+ {
373
+ Zero,
374
+ Zero,
375
+ LNKB,
376
+ Zero
377
+ }
378
+ }
379
+
380
+ If ((Local3 == 0x03))
381
+ {
382
+ Local4 = Package (0x04)
383
+ {
384
+ Zero,
385
+ Zero,
386
+ LNKC,
387
+ Zero
388
+ }
389
+ }
390
+
391
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
392
+ Local4 [One] = (Local1 & 0x03)
393
+ Local0 [Local1] = Local4
394
+ Local1++
395
+ }
396
+
397
+ Return (Local0)
398
+ }
399
+
400
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
401
+ {
402
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
403
+ 0x0000, // Granularity
404
+ 0x0010, // Range Minimum
405
+ 0x0010, // Range Maximum
406
+ 0x0000, // Translation Offset
407
+ 0x0001, // Length
408
+ ,, )
409
+ })
410
+ }
411
+ }
412
+
413
Scope (\_SB.PCI0)
414
{
415
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
416
@@ -XXX,XX +XXX,XX @@
417
WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
418
0x0000, // Granularity
419
0x0000, // Range Minimum
420
- 0x00FF, // Range Maximum
421
+ 0x000F, // Range Maximum
422
0x0000, // Translation Offset
423
- 0x0100, // Length
424
+ 0x0010, // Length
425
,, )
426
IO (Decode16,
427
0x0CF8, // Range Minimum
428
@@ -XXX,XX +XXX,XX @@
79
}
429
}
80
}
430
}
81
break;
431
82
- case NEON_3R_VPADD_VQRDMLAH:
432
+ Device (S10)
83
- switch (size) {
433
+ {
84
- case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
434
+ Name (_ADR, 0x00020000) // _ADR: Address
85
- case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
435
+ }
86
- case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
436
+
87
- default: abort();
437
+ Device (S18)
88
- }
438
+ {
89
- break;
439
+ Name (_ADR, 0x00030000) // _ADR: Address
90
case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
440
+ }
91
{
441
+
92
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
442
+ Device (S20)
443
+ {
444
+ Name (_ADR, 0x00040000) // _ADR: Address
445
+ }
446
+
447
+ Device (S28)
448
+ {
449
+ Name (_ADR, 0x00050000) // _ADR: Address
450
+ }
451
+
452
Method (PCNT, 0, NotSerialized)
453
{
454
}
455
456
Reviewed-by: Eric Auger <eric.auger@redhat.com>
457
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
458
Message-id: 20211210170415.583179-8-jean-philippe@linaro.org
459
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
460
---
461
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
462
tests/data/acpi/q35/DSDT.viot | Bin 0 -> 9398 bytes
463
tests/data/acpi/q35/VIOT.viot | Bin 0 -> 112 bytes
464
3 files changed, 2 deletions(-)
465
466
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
467
index XXXXXXX..XXXXXXX 100644
468
--- a/tests/qtest/bios-tables-test-allowed-diff.h
469
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
470
@@ -XXX,XX +XXX,XX @@
471
/* List of comma-separated changed AML files to ignore */
472
"tests/data/acpi/virt/VIOT",
473
-"tests/data/acpi/q35/DSDT.viot",
474
-"tests/data/acpi/q35/VIOT.viot",
475
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
476
index XXXXXXX..XXXXXXX 100644
477
GIT binary patch
478
literal 9398
479
zcmeHNO>7&-8J*>iv|O&FB}G~Oi$yp||57BBoWHhc5OS9yDTx$CQgH$r;8Idr*-4Q_
480
z5(9Az1F`}niVsB-)<KW7p`g9Br(A2Gm-gmc1N78GFS!;)e2V(MnH_0{q<{#yMgn&C
481
zn|*J-d9yqFhO_H6z19~`FlPL*u<DkZ*}|)JH;X@mF-FI<cPg<fti9tEN*yB^i5czN
482
zNq&q?!OZ;BE3B7{KWzJ-`Tn~f`9?Qj8~2^N8{Oc8J%57{==w%rS#;nOCp*nTr@iZ1
483
zb+?i;JLQUJ=O0?8*>S~D)a>NF1~WVB6^~_B#yhJ`H+JU@=6aXs`?Yv)J2h=N?drcS
484
zeLZ*n<<Bm^n}6`jfBx#u8&(W}1?)}iF9o#mZ~E2+zwdn7yK3AbIzKnxpZ>JRPm3~#
485
z&ICS{+_OayRW-l=Mtk=~uaS3o8z<_udd|(wqg`&JnVPfCe>BUOO`Su3e>pff_^UW%
486
z&JE^NO`)=Amg~iqRB1pPscP?(>#ZuY8GHCmlEvD$9g3%4Db~Dfz2SATnddvrR-Oe^
487
z;s;dJec!hnzi)ri^I6YN9vtkm{^TdUF8h7gX8-<Qe4p)GQ=)AtYx2VcwdLVAEXEjG
488
z^Mj|UHPqkj-LsWuzQem1>F3atdZn=zv3$#RmZzSHN+6-yyU#8cJb=YDilX&sl}vNm
489
znkgAR^O<3kj4if>{ly5fwRfMWuC5=lrlvKPX~i#654Cp}R_d*JS$9laZ$ra6)<ns8
490
zFZy28G%xP(nit&F>LDi%G<tIc=TY=gl$jSD&Uv!Yat~XR46h%rI$!}a%!|xG7u8Zn
491
zeY8_|n=K>xz_v_W8VX$W-Fg-qFWcT}7MCyz{%%{ia7hZ>Law-k6NOr}VI&_48U=2l
492
zwqDKFE8eTwwozDdms#e?x?5a|v>&JF;2_v0L~z5n%BYU^52<*cWuD4|GYUm@1+?))
493
zte^45>Rz)t*<T5V#={r>@t@{%?^i#W{i=HAZ*Dc9y59Va-+#P!jrGs;u38a{fLr`N
494
zvT@rUu>DljxJ?^&Z?-?vyJn3C>3D=qux{Y*bs5|5n)Qmi$TD^Zdn4GU$ocJS2Hh-<
495
z`xPI^^+v0nUVdjMos8k`WGl7hA`{03ju%<lrgAHSpd^DRf-*}_#Ly0mB!LSfVgWcQ
496
z&T$@~G9)JI=hz5m0vkrel+Xy{Oh7pkAu-V!j*W7rY(bO}Q$nMH2`FbGB&N)QaV4<4
497
zo)~9JXiP9=;}NPl<C@MmXG&;XFlFNrsyfFsonxFSp<}vEgsRSQP3O3#b6nSnP}ON_
498
zI!#Tdsp~|j>ckUB>FI=~GokB5sOq#dotCE4(sd$KbtW~PNlj-`*NIToiD#j5J#9^=
499
zt?NXn>YUJYPG~wObe#xQos*i*NloXZt`niEb4t@WrRki~bs|)CI+{*L)9L6s5vn><
500
zn$DD_Go|Z9sOn5>I@6lYw5}7Os&iV?Ij!lO)^#FOb!If38BJ$K*NIToIiu;E(R9w}
501
zIuWWmPiZ<&X*y5oIuWWmF_XaEC!a&Jn$B5WCqh-{X-(&8P3LJ{Cqh-{8P3dyPr@^t
502
zSqL9?X9Uwd3W@23*s~h*tj0X6GZCuHa~kuU#yqDp5vt7d8uPryJg+kms?5hU=3^T3
503
zF`bD}WnSP+=`t5MQ$FJ_2&Q~+BP6E0f^%BVIW6a$o)e+SX~IDBih-7z6{O~7YTy`&
504
zLjy&Cv?7QikV#>n0>>@MV8oK`Gmun34-FKdlm-J8SZSaNlnhir4-FI{S|bfqV8e)V
505
zss<{chX#reE#g=hsKAC%sF6d-Km}BWs!kZFsFpKfpbC@>6rprQGEjt4Ck#|zITHq|
506
zK*>M_l;<P^MJRQ`Kn0dFVW0|>3{*fllMEE0)CmI>Sk8ojDo`>|0p(0GP=xY&!axO<
507
zGhv_#lnhirIg<<&q0|Wj6<E%MfhtfkPyyvkGEjt4Ck#|zITHq|K*>M_lrzad5lWpf
508
zP=V!47^ngz0~JutBm+e#b;3XemNQ|X3X}{~Ksl2P6rt1!0~J`#gn=qhGEf2KOfpb}
509
zQYQ>lU^x>8szAv=1(Y+%KoLrvFi?TzOc<yFB?A>u&LjgxD0RX>1(q{mpbC@>R6seC
510
z3>2Z%2?G^a&V+#~P%=;f<xDbAgi<FARA4z12C6{GKn0XD$v_cGoiI>=<xCi;0wn_#
511
zP|hR+MJRQ`Kn0dFVW0|>3{*fllMEE0)CmI>Sk8ojDo`>|0p(0GP=rz^3{+q_69%e4
512
z$v_2^Gs!>^N}VuJf#pmXr~)Me6;RG314Srx!axxz28u{EP=u<1B2)}iVZuNaCK;&0
513
zBm-5LFi?dF167!0pbC==RAItE6($T+VUmF=Ofpb~2?JG_Fi?d_2C6X0Kouqo6p_5T
514
zFi=FeV!SiSKoR0H$dH(_Z(*Q_WZ%L-5y`$K14StNmJAdjmWs}HV4<vU_xO+1efmLq
515
zZ;W>N_U)fP6Qy6Nw5mbt9Y(#emWSi66=>tq#xoh#Ue=0qyhxi8ZOUe5y0V7VfPUhp
516
zwX=;ymc+i5%sg9Ja~lZ&8oAV@mHc>&CHP9v4R(jhtT?un;O4e9#pno)Xkh7OWgK&a
517
zyj=3Iv0OuoK_;5rOr5f(Kb~ZXDBO+V`OWYo#_C08imwChQxnjdd?wZLDou8aj;$SD
518
zGDYiA3<$Tu<JnHL(KPOChi#zrR32t83}naR$+ym4P_h?z_5#|cW-nw$XD_sOtE62l
519
zrD3@*)NVyiklt0&yF9%+klsBey&I<Y2E<!f(E8TuJte)z(|ZHyy<^gQVfx}=`q&B5
520
z7nSryp1wGczIaUfVwiq$Fn#<4=@*ssi#+|}K>EdF(l3VTOM~ghPLRH&q%ZOGrGfON
521
zW73zx^yR_y<0nX8R??Sw`tm^f@-gYlNFSp|*<gA{q?Zp5Oe-+l#rmyYmKozi9y=P>
522
zVReJU*h=ZuVXiS$ohTbw-O#v9>(yZbGE|)?8(H1ZIKvV!jWa0>vy!3eMA^vdhQ>`s
523
zuMSg{q3T50$m)j1!HixV<}X9liL#N^4c*tL^y)CF8LCc{jjV3yKAqL8!%SzWI#H%q
524
z=bSrQ&)%JCRttF5g4Zf`6l?y@>PzD7MA^D>wBlcH6r1ucwJ<p0O%rZ?JzIY3-QdmZ
525
zzs|n>`a5r3e|z)wcUaqS>nqFQ-8x}eCF4u`OWUxqst-@1rSmUs%WmKP5e0dcb?e2N
526
z;Z|x*!);VwF|Yuhqs^khqOM!@u*jY!WYldISF(V6`BoNd&6Qfk3>X#SuD^7J>p_D=
527
zBPa51y^_n#=cpOt#Zf$ya$Ae9Mfz56n|<i!a=ELS@)%a{^NIH3SDuN<R~sah1km#P
528
zU@?*f%<rG=4W1wgfi;C?_n|W@%lm$&8YfvNOJodIg&IcIpIJQRHr<+ej11GQ6)&eF
529
z2Lam*jIH}#y0>KnY%4JQfOYS$*uU%f#@$U6`N8I3N-lV?5ErFCdv~xDmu2(wexld4
530
z4v^;aVAT2k6GJ^m*FD(Wqc(Qg^)6a<?}h$zLoj}4;PP!+(O{@!a1y-hoAhF_7!z+6
531
zslpAmNtYbjHrw-~#SPVk_FUf>-Obg6yV`8o$8_`PyJe_;bY5_EMBfBfWU!Q=*9HsG
532
z%_Cda{@_Krr!oHVhv9+y+T5qR8zZ2aZ>5r!$*|f$^U%yBUYfR&B!+EYy_PwL!BeUi
533
zJH^}r3r9Q+B)X@Z)fk=P13w&7x#wBtXTZ)g>WITPg5r&pQc!nmyrmk#S(>>b9xnNr
534
zx_b#v9Xv-Y><Wb%?S^0Xe&<)bbKl_=Z|3C$tf|F<bYzE*mfHB;uC)`q-?buaBe?l?
535
zcLTpK*k<49Z32`K?|nSBMFqxTK^_IE-li2fEGdK~(ZdoKBl6ab4a;Hler#`xvEXJG
536
zb?<E%EZExfX>jcOVhS*0rS~RS1dA#xhkv@Nct@#q?LyeKS<$uFec!bw>{@uu$gZ6a
537
zyVen1i{1BKd%~`D7|m$;U0a<I*3I7%^N%N%lGYdU_GS!gaR8T$NA@GzFi~z`l7hdl
538
zarZy6590|88pi(1zq;V(>38zM0sT&<zX;R5$1w3;`_JMG`;&I&0Y23DMx1%@(w(R9
539
z4M$j;D5J+Gy%fijRQsctzFKf&cv|BAz#YLq3CZJWDdtL4u1u1|mkdcUp7|sxJC+?Y
540
z_@@s`v3j}Q7*z>6X~cwUxUL8G1KT)_XTp!KAbs;vCp{K3&~_X@+ew=-D}v`2MbFV0
541
zQsVsL=rXi-pI*G|iiz;VTCutgUs)hDzV1+4?8KcoP3xROf<M%qC6lgVdpFt4<-|uM
542
z=#rl_b1#YjSIl6Toj2z_hOZcKupkdE(LozC(fN=FY(x|sk)ym|;Rq2E1xJWD%Z!ol
543
Gu>S+TT-130
544
545
literal 0
546
HcmV?d00001
547
548
diff --git a/tests/data/acpi/q35/VIOT.viot b/tests/data/acpi/q35/VIOT.viot
549
index XXXXXXX..XXXXXXX 100644
550
GIT binary patch
551
literal 112
552
zcmWIZ^baXu00LVle`k+i1*eDrX9XZ&1PX!JAex!M0Hgv8m>C3sGzdcgBZCA3T-xBj
553
Q0Zb)W9Hva*zW_`e0M!8s0RR91
554
555
literal 0
556
HcmV?d00001
557
93
--
558
--
94
2.20.1
559
2.25.1
95
560
96
561
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
Must clear the tail for AdvSIMD when SVE is enabled.
3
The VIOT blob contains the following:
4
4
5
Fixes: ca40a6e6e39
5
[000h 0000 4] Signature : "VIOT" [Virtual I/O Translation Table]
6
Cc: qemu-stable@nongnu.org
6
[004h 0004 4] Table Length : 00000058
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
[008h 0008 1] Revision : 00
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
[009h 0009 1] Checksum : 66
9
Message-id: 20200513163245.17915-15-richard.henderson@linaro.org
9
[00Ah 0010 6] Oem ID : "BOCHS "
10
[010h 0016 8] Oem Table ID : "BXPC "
11
[018h 0024 4] Oem Revision : 00000001
12
[01Ch 0028 4] Asl Compiler ID : "BXPC"
13
[020h 0032 4] Asl Compiler Revision : 00000001
14
15
[024h 0036 2] Node count : 0002
16
[026h 0038 2] Node offset : 0030
17
[028h 0040 8] Reserved : 0000000000000000
18
19
[030h 0048 1] Type : 03 [VirtIO-PCI IOMMU]
20
[031h 0049 1] Reserved : 00
21
[032h 0050 2] Length : 0010
22
23
[034h 0052 2] PCI Segment : 0000
24
[036h 0054 2] PCI BDF number : 0008
25
[038h 0056 8] Reserved : 0000000000000000
26
27
[040h 0064 1] Type : 01 [PCI Range]
28
[041h 0065 1] Reserved : 00
29
[042h 0066 2] Length : 0018
30
31
[044h 0068 4] Endpoint start : 00000000
32
[048h 0072 2] PCI Segment start : 0000
33
[04Ah 0074 2] PCI Segment end : 0000
34
[04Ch 0076 2] PCI BDF start : 0000
35
[04Eh 0078 2] PCI BDF end : 00FF
36
[050h 0080 2] Output node : 0030
37
[052h 0082 6] Reserved : 000000000000
38
39
Acked-by: Ani Sinha <ani@anisinha.ca>
40
Reviewed-by: Eric Auger <eric.auger@redhat.com>
41
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
42
Message-id: 20211210170415.583179-9-jean-philippe@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
44
---
12
target/arm/vec_helper.c | 2 ++
45
tests/qtest/bios-tables-test-allowed-diff.h | 1 -
13
1 file changed, 2 insertions(+)
46
tests/data/acpi/virt/VIOT | Bin 0 -> 88 bytes
47
2 files changed, 1 deletion(-)
14
48
15
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
49
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
16
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/vec_helper.c
51
--- a/tests/qtest/bios-tables-test-allowed-diff.h
18
+++ b/target/arm/vec_helper.c
52
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
19
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
53
@@ -1,2 +1 @@
20
d[i + j] = TYPE##_mul(n[i + j], mm, stat); \
54
/* List of comma-separated changed AML files to ignore */
21
} \
55
-"tests/data/acpi/virt/VIOT",
22
} \
56
diff --git a/tests/data/acpi/virt/VIOT b/tests/data/acpi/virt/VIOT
23
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
57
index XXXXXXX..XXXXXXX 100644
24
}
58
GIT binary patch
25
59
literal 88
26
DO_MUL_IDX(gvec_fmul_idx_h, float16, H2)
60
zcmWIZ^bd((0D?3pe`k+i1*eDrX9XZ&1PX!JAexE60Hgv8m>C3sGzXN&z`)2L0cSHX
27
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, \
61
I{D-Rq0Q5fy0RR91
28
mm, a[i + j], 0, stat); \
62
29
} \
63
literal 0
30
} \
64
HcmV?d00001
31
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
65
32
}
33
34
DO_FMLA_IDX(gvec_fmla_idx_h, float16, H2)
35
--
66
--
36
2.20.1
67
2.25.1
37
68
38
69
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon VQRDMLAH and VQRDMLSH insns in the 3-reg-same group
2
to decodetree. These don't use do_3same() because they want to
3
operate on VFP double registers, whose offsets are different from the
4
neon_reg_offset() calculations do_3same does.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200512163904.10918-2-peter.maydell@linaro.org
9
---
10
target/arm/neon-dp.decode | 3 +++
11
target/arm/translate-neon.inc.c | 15 +++++++++++++++
12
target/arm/translate.c | 14 ++------------
13
3 files changed, 20 insertions(+), 12 deletions(-)
14
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/neon-dp.decode
18
+++ b/target/arm/neon-dp.decode
19
@@ -XXX,XX +XXX,XX @@ VMLS_3s 1111 001 1 0 . .. .... .... 1001 . . . 0 .... @3same
20
21
VMUL_3s 1111 001 0 0 . .. .... .... 1001 . . . 1 .... @3same
22
VMUL_p_3s 1111 001 1 0 . .. .... .... 1001 . . . 1 .... @3same
23
+
24
+VQRDMLAH_3s 1111 001 1 0 . .. .... .... 1011 ... 1 .... @3same
25
+VQRDMLSH_3s 1111 001 1 0 . .. .... .... 1100 ... 1 .... @3same
26
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/translate-neon.inc.c
29
+++ b/target/arm/translate-neon.inc.c
30
@@ -XXX,XX +XXX,XX @@ static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
31
}
32
return do_3same(s, a, gen_VMUL_p_3s);
33
}
34
+
35
+#define DO_VQRDMLAH(INSN, FUNC) \
36
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
37
+ { \
38
+ if (!dc_isar_feature(aa32_rdm, s)) { \
39
+ return false; \
40
+ } \
41
+ if (a->size != 1 && a->size != 2) { \
42
+ return false; \
43
+ } \
44
+ return do_3same(s, a, FUNC); \
45
+ }
46
+
47
+DO_VQRDMLAH(VQRDMLAH, gen_gvec_sqrdmlah_qc)
48
+DO_VQRDMLAH(VQRDMLSH, gen_gvec_sqrdmlsh_qc)
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/translate.c
52
+++ b/target/arm/translate.c
53
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
54
if (!u) {
55
break; /* VPADD */
56
}
57
- /* VQRDMLAH */
58
- if (dc_isar_feature(aa32_rdm, s) && (size == 1 || size == 2)) {
59
- gen_gvec_sqrdmlah_qc(size, rd_ofs, rn_ofs, rm_ofs,
60
- vec_size, vec_size);
61
- return 0;
62
- }
63
+ /* VQRDMLAH : handled by decodetree */
64
return 1;
65
66
case NEON_3R_VFM_VQRDMLSH:
67
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
68
}
69
break;
70
}
71
- /* VQRDMLSH */
72
- if (dc_isar_feature(aa32_rdm, s) && (size == 1 || size == 2)) {
73
- gen_gvec_sqrdmlsh_qc(size, rd_ofs, rn_ofs, rm_ofs,
74
- vec_size, vec_size);
75
- return 0;
76
- }
77
+ /* VQRDMLSH : handled by decodetree */
78
return 1;
79
80
case NEON_3R_VABD:
81
--
82
2.20.1
83
84
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon SHA instructions in the 3-reg-same group
2
to decodetree.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200512163904.10918-3-peter.maydell@linaro.org
7
---
8
target/arm/neon-dp.decode | 10 +++
9
target/arm/translate-neon.inc.c | 139 ++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 46 +----------
11
3 files changed, 151 insertions(+), 44 deletions(-)
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ VMUL_3s 1111 001 0 0 . .. .... .... 1001 . . . 1 .... @3same
18
VMUL_p_3s 1111 001 1 0 . .. .... .... 1001 . . . 1 .... @3same
19
20
VQRDMLAH_3s 1111 001 1 0 . .. .... .... 1011 ... 1 .... @3same
21
+
22
+SHA1_3s 1111 001 0 0 . optype:2 .... .... 1100 . 1 . 0 .... \
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
24
+SHA256H_3s 1111 001 1 0 . 00 .... .... 1100 . 1 . 0 .... \
25
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
26
+SHA256H2_3s 1111 001 1 0 . 01 .... .... 1100 . 1 . 0 .... \
27
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
28
+SHA256SU1_3s 1111 001 1 0 . 10 .... .... 1100 . 1 . 0 .... \
29
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
30
+
31
VQRDMLSH_3s 1111 001 1 0 . .. .... .... 1100 ... 1 .... @3same
32
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-neon.inc.c
35
+++ b/target/arm/translate-neon.inc.c
36
@@ -XXX,XX +XXX,XX @@ static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
37
38
DO_VQRDMLAH(VQRDMLAH, gen_gvec_sqrdmlah_qc)
39
DO_VQRDMLAH(VQRDMLSH, gen_gvec_sqrdmlsh_qc)
40
+
41
+static bool trans_SHA1_3s(DisasContext *s, arg_SHA1_3s *a)
42
+{
43
+ TCGv_ptr ptr1, ptr2, ptr3;
44
+ TCGv_i32 tmp;
45
+
46
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
47
+ !dc_isar_feature(aa32_sha1, s)) {
48
+ return false;
49
+ }
50
+
51
+ /* UNDEF accesses to D16-D31 if they don't exist. */
52
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
53
+ ((a->vd | a->vn | a->vm) & 0x10)) {
54
+ return false;
55
+ }
56
+
57
+ if ((a->vn | a->vm | a->vd) & 1) {
58
+ return false;
59
+ }
60
+
61
+ if (!vfp_access_check(s)) {
62
+ return true;
63
+ }
64
+
65
+ ptr1 = vfp_reg_ptr(true, a->vd);
66
+ ptr2 = vfp_reg_ptr(true, a->vn);
67
+ ptr3 = vfp_reg_ptr(true, a->vm);
68
+ tmp = tcg_const_i32(a->optype);
69
+ gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp);
70
+ tcg_temp_free_i32(tmp);
71
+ tcg_temp_free_ptr(ptr1);
72
+ tcg_temp_free_ptr(ptr2);
73
+ tcg_temp_free_ptr(ptr3);
74
+
75
+ return true;
76
+}
77
+
78
+static bool trans_SHA256H_3s(DisasContext *s, arg_SHA256H_3s *a)
79
+{
80
+ TCGv_ptr ptr1, ptr2, ptr3;
81
+
82
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
83
+ !dc_isar_feature(aa32_sha2, s)) {
84
+ return false;
85
+ }
86
+
87
+ /* UNDEF accesses to D16-D31 if they don't exist. */
88
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
89
+ ((a->vd | a->vn | a->vm) & 0x10)) {
90
+ return false;
91
+ }
92
+
93
+ if ((a->vn | a->vm | a->vd) & 1) {
94
+ return false;
95
+ }
96
+
97
+ if (!vfp_access_check(s)) {
98
+ return true;
99
+ }
100
+
101
+ ptr1 = vfp_reg_ptr(true, a->vd);
102
+ ptr2 = vfp_reg_ptr(true, a->vn);
103
+ ptr3 = vfp_reg_ptr(true, a->vm);
104
+ gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
105
+ tcg_temp_free_ptr(ptr1);
106
+ tcg_temp_free_ptr(ptr2);
107
+ tcg_temp_free_ptr(ptr3);
108
+
109
+ return true;
110
+}
111
+
112
+static bool trans_SHA256H2_3s(DisasContext *s, arg_SHA256H2_3s *a)
113
+{
114
+ TCGv_ptr ptr1, ptr2, ptr3;
115
+
116
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
117
+ !dc_isar_feature(aa32_sha2, s)) {
118
+ return false;
119
+ }
120
+
121
+ /* UNDEF accesses to D16-D31 if they don't exist. */
122
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
123
+ ((a->vd | a->vn | a->vm) & 0x10)) {
124
+ return false;
125
+ }
126
+
127
+ if ((a->vn | a->vm | a->vd) & 1) {
128
+ return false;
129
+ }
130
+
131
+ if (!vfp_access_check(s)) {
132
+ return true;
133
+ }
134
+
135
+ ptr1 = vfp_reg_ptr(true, a->vd);
136
+ ptr2 = vfp_reg_ptr(true, a->vn);
137
+ ptr3 = vfp_reg_ptr(true, a->vm);
138
+ gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
139
+ tcg_temp_free_ptr(ptr1);
140
+ tcg_temp_free_ptr(ptr2);
141
+ tcg_temp_free_ptr(ptr3);
142
+
143
+ return true;
144
+}
145
+
146
+static bool trans_SHA256SU1_3s(DisasContext *s, arg_SHA256SU1_3s *a)
147
+{
148
+ TCGv_ptr ptr1, ptr2, ptr3;
149
+
150
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
151
+ !dc_isar_feature(aa32_sha2, s)) {
152
+ return false;
153
+ }
154
+
155
+ /* UNDEF accesses to D16-D31 if they don't exist. */
156
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
157
+ ((a->vd | a->vn | a->vm) & 0x10)) {
158
+ return false;
159
+ }
160
+
161
+ if ((a->vn | a->vm | a->vd) & 1) {
162
+ return false;
163
+ }
164
+
165
+ if (!vfp_access_check(s)) {
166
+ return true;
167
+ }
168
+
169
+ ptr1 = vfp_reg_ptr(true, a->vd);
170
+ ptr2 = vfp_reg_ptr(true, a->vn);
171
+ ptr3 = vfp_reg_ptr(true, a->vm);
172
+ gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
173
+ tcg_temp_free_ptr(ptr1);
174
+ tcg_temp_free_ptr(ptr2);
175
+ tcg_temp_free_ptr(ptr3);
176
+
177
+ return true;
178
+}
179
diff --git a/target/arm/translate.c b/target/arm/translate.c
180
index XXXXXXX..XXXXXXX 100644
181
--- a/target/arm/translate.c
182
+++ b/target/arm/translate.c
183
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
184
int vec_size;
185
uint32_t imm;
186
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
187
- TCGv_ptr ptr1, ptr2, ptr3;
188
+ TCGv_ptr ptr1, ptr2;
189
TCGv_i64 tmp64;
190
191
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
192
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
193
return 1;
194
}
195
switch (op) {
196
- case NEON_3R_SHA:
197
- /* The SHA-1/SHA-256 3-register instructions require special
198
- * treatment here, as their size field is overloaded as an
199
- * op type selector, and they all consume their input in a
200
- * single pass.
201
- */
202
- if (!q) {
203
- return 1;
204
- }
205
- if (!u) { /* SHA-1 */
206
- if (!dc_isar_feature(aa32_sha1, s)) {
207
- return 1;
208
- }
209
- ptr1 = vfp_reg_ptr(true, rd);
210
- ptr2 = vfp_reg_ptr(true, rn);
211
- ptr3 = vfp_reg_ptr(true, rm);
212
- tmp4 = tcg_const_i32(size);
213
- gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
214
- tcg_temp_free_i32(tmp4);
215
- } else { /* SHA-256 */
216
- if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
217
- return 1;
218
- }
219
- ptr1 = vfp_reg_ptr(true, rd);
220
- ptr2 = vfp_reg_ptr(true, rn);
221
- ptr3 = vfp_reg_ptr(true, rm);
222
- switch (size) {
223
- case 0:
224
- gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
225
- break;
226
- case 1:
227
- gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
228
- break;
229
- case 2:
230
- gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
231
- break;
232
- }
233
- }
234
- tcg_temp_free_ptr(ptr1);
235
- tcg_temp_free_ptr(ptr2);
236
- tcg_temp_free_ptr(ptr3);
237
- return 0;
238
-
239
case NEON_3R_VPADD_VQRDMLAH:
240
if (!u) {
241
break; /* VPADD */
242
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
243
case NEON_3R_VMUL:
244
case NEON_3R_VML:
245
case NEON_3R_VSHL:
246
+ case NEON_3R_SHA:
247
/* Already handled by decodetree */
248
return 1;
249
}
250
--
251
2.20.1
252
253
diff view generated by jsdifflib
Deleted patch
1
Convert the 64-bit element insns in the 3-reg-same group
2
to decodetree. This covers VQSHL, VRSHL and VQRSHL where
3
size==0b11.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200512163904.10918-4-peter.maydell@linaro.org
8
---
9
target/arm/neon-dp.decode | 13 +++++++++++
10
target/arm/translate-neon.inc.c | 24 +++++++++++++++++++++
11
target/arm/translate.c | 38 ++-------------------------------
12
3 files changed, 39 insertions(+), 36 deletions(-)
13
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/neon-dp.decode
17
+++ b/target/arm/neon-dp.decode
18
@@ -XXX,XX +XXX,XX @@ VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
19
VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same_rev
20
VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same_rev
21
22
+# Insns operating on 64-bit elements (size!=0b11 handled elsewhere)
23
+# The _rev suffix indicates that Vn and Vm are reversed (as explained
24
+# by the comment for the @3same_rev format).
25
+@3same_64_rev .... ... . . . 11 .... .... .... . q:1 . . .... \
26
+ &3same vm=%vn_dp vn=%vm_dp vd=%vd_dp size=3
27
+
28
+VQSHL_S64_3s 1111 001 0 0 . .. .... .... 0100 . . . 1 .... @3same_64_rev
29
+VQSHL_U64_3s 1111 001 1 0 . .. .... .... 0100 . . . 1 .... @3same_64_rev
30
+VRSHL_S64_3s 1111 001 0 0 . .. .... .... 0101 . . . 0 .... @3same_64_rev
31
+VRSHL_U64_3s 1111 001 1 0 . .. .... .... 0101 . . . 0 .... @3same_64_rev
32
+VQRSHL_S64_3s 1111 001 0 0 . .. .... .... 0101 . . . 1 .... @3same_64_rev
33
+VQRSHL_U64_3s 1111 001 1 0 . .. .... .... 0101 . . . 1 .... @3same_64_rev
34
+
35
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
36
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
37
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
38
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/translate-neon.inc.c
41
+++ b/target/arm/translate-neon.inc.c
42
@@ -XXX,XX +XXX,XX @@ static bool trans_SHA256SU1_3s(DisasContext *s, arg_SHA256SU1_3s *a)
43
44
return true;
45
}
46
+
47
+#define DO_3SAME_64(INSN, FUNC) \
48
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
49
+ uint32_t rn_ofs, uint32_t rm_ofs, \
50
+ uint32_t oprsz, uint32_t maxsz) \
51
+ { \
52
+ static const GVecGen3 op = { .fni8 = FUNC }; \
53
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &op); \
54
+ } \
55
+ DO_3SAME(INSN, gen_##INSN##_3s)
56
+
57
+#define DO_3SAME_64_ENV(INSN, FUNC) \
58
+ static void gen_##INSN##_elt(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m) \
59
+ { \
60
+ FUNC(d, cpu_env, n, m); \
61
+ } \
62
+ DO_3SAME_64(INSN, gen_##INSN##_elt)
63
+
64
+DO_3SAME_64(VRSHL_S64, gen_helper_neon_rshl_s64)
65
+DO_3SAME_64(VRSHL_U64, gen_helper_neon_rshl_u64)
66
+DO_3SAME_64_ENV(VQSHL_S64, gen_helper_neon_qshl_s64)
67
+DO_3SAME_64_ENV(VQSHL_U64, gen_helper_neon_qshl_u64)
68
+DO_3SAME_64_ENV(VQRSHL_S64, gen_helper_neon_qrshl_s64)
69
+DO_3SAME_64_ENV(VQRSHL_U64, gen_helper_neon_qrshl_u64)
70
diff --git a/target/arm/translate.c b/target/arm/translate.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/translate.c
73
+++ b/target/arm/translate.c
74
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
75
}
76
77
if (size == 3) {
78
- /* 64-bit element instructions. */
79
- for (pass = 0; pass < (q ? 2 : 1); pass++) {
80
- neon_load_reg64(cpu_V0, rn + pass);
81
- neon_load_reg64(cpu_V1, rm + pass);
82
- switch (op) {
83
- case NEON_3R_VQSHL:
84
- if (u) {
85
- gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
86
- cpu_V1, cpu_V0);
87
- } else {
88
- gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
89
- cpu_V1, cpu_V0);
90
- }
91
- break;
92
- case NEON_3R_VRSHL:
93
- if (u) {
94
- gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
95
- } else {
96
- gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
97
- }
98
- break;
99
- case NEON_3R_VQRSHL:
100
- if (u) {
101
- gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
102
- cpu_V1, cpu_V0);
103
- } else {
104
- gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
105
- cpu_V1, cpu_V0);
106
- }
107
- break;
108
- default:
109
- abort();
110
- }
111
- neon_store_reg64(cpu_V0, rd + pass);
112
- }
113
- return 0;
114
+ /* 64-bit element instructions: handled by decodetree */
115
+ return 1;
116
}
117
pairwise = 0;
118
switch (op) {
119
--
120
2.20.1
121
122
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon VHADD insns in the 3-reg-same group to decodetree.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200512163904.10918-5-peter.maydell@linaro.org
6
---
7
target/arm/neon-dp.decode | 2 ++
8
target/arm/translate-neon.inc.c | 24 ++++++++++++++++++++++++
9
target/arm/translate.c | 4 +---
10
3 files changed, 27 insertions(+), 3 deletions(-)
11
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-dp.decode
15
+++ b/target/arm/neon-dp.decode
16
@@ -XXX,XX +XXX,XX @@
17
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
18
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
19
20
+VHADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 0 .... @3same
21
+VHADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 0 .... @3same
22
VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
23
VQADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 1 .... @3same
24
25
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/translate-neon.inc.c
28
+++ b/target/arm/translate-neon.inc.c
29
@@ -XXX,XX +XXX,XX @@ DO_3SAME_64_ENV(VQSHL_S64, gen_helper_neon_qshl_s64)
30
DO_3SAME_64_ENV(VQSHL_U64, gen_helper_neon_qshl_u64)
31
DO_3SAME_64_ENV(VQRSHL_S64, gen_helper_neon_qrshl_s64)
32
DO_3SAME_64_ENV(VQRSHL_U64, gen_helper_neon_qrshl_u64)
33
+
34
+#define DO_3SAME_32(INSN, FUNC) \
35
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
36
+ uint32_t rn_ofs, uint32_t rm_ofs, \
37
+ uint32_t oprsz, uint32_t maxsz) \
38
+ { \
39
+ static const GVecGen3 ops[4] = { \
40
+ { .fni4 = gen_helper_neon_##FUNC##8 }, \
41
+ { .fni4 = gen_helper_neon_##FUNC##16 }, \
42
+ { .fni4 = gen_helper_neon_##FUNC##32 }, \
43
+ { 0 }, \
44
+ }; \
45
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &ops[vece]); \
46
+ } \
47
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
48
+ { \
49
+ if (a->size > 2) { \
50
+ return false; \
51
+ } \
52
+ return do_3same(s, a, gen_##INSN##_3s); \
53
+ }
54
+
55
+DO_3SAME_32(VHADD_S, hadd_s)
56
+DO_3SAME_32(VHADD_U, hadd_u)
57
diff --git a/target/arm/translate.c b/target/arm/translate.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/translate.c
60
+++ b/target/arm/translate.c
61
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
62
case NEON_3R_VML:
63
case NEON_3R_VSHL:
64
case NEON_3R_SHA:
65
+ case NEON_3R_VHADD:
66
/* Already handled by decodetree */
67
return 1;
68
}
69
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
70
tmp2 = neon_load_reg(rm, pass);
71
}
72
switch (op) {
73
- case NEON_3R_VHADD:
74
- GEN_NEON_INTEGER_OP(hadd);
75
- break;
76
case NEON_3R_VRHADD:
77
GEN_NEON_INTEGER_OP(rhadd);
78
break;
79
--
80
2.20.1
81
82
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon VABA and VABD insns in the 3-reg-same group to
2
decodetree.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200512163904.10918-6-peter.maydell@linaro.org
7
---
8
target/arm/neon-dp.decode | 6 ++++++
9
target/arm/translate-neon.inc.c | 4 ++++
10
target/arm/translate.c | 22 ++--------------------
11
3 files changed, 12 insertions(+), 20 deletions(-)
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
18
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
19
VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
20
21
+VABD_S_3s 1111 001 0 0 . .. .... .... 0111 . . . 0 .... @3same
22
+VABD_U_3s 1111 001 1 0 . .. .... .... 0111 . . . 0 .... @3same
23
+
24
+VABA_S_3s 1111 001 0 0 . .. .... .... 0111 . . . 1 .... @3same
25
+VABA_U_3s 1111 001 1 0 . .. .... .... 0111 . . . 1 .... @3same
26
+
27
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
28
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
29
30
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate-neon.inc.c
33
+++ b/target/arm/translate-neon.inc.c
34
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
35
DO_3SAME_NO_SZ_3(VMLA, gen_gvec_mla)
36
DO_3SAME_NO_SZ_3(VMLS, gen_gvec_mls)
37
DO_3SAME_NO_SZ_3(VTST, gen_gvec_cmtst)
38
+DO_3SAME_NO_SZ_3(VABD_S, gen_gvec_sabd)
39
+DO_3SAME_NO_SZ_3(VABA_S, gen_gvec_saba)
40
+DO_3SAME_NO_SZ_3(VABD_U, gen_gvec_uabd)
41
+DO_3SAME_NO_SZ_3(VABA_U, gen_gvec_uaba)
42
43
#define DO_3SAME_CMP(INSN, COND) \
44
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
45
diff --git a/target/arm/translate.c b/target/arm/translate.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/translate.c
48
+++ b/target/arm/translate.c
49
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
50
/* VQRDMLSH : handled by decodetree */
51
return 1;
52
53
- case NEON_3R_VABD:
54
- if (u) {
55
- gen_gvec_uabd(size, rd_ofs, rn_ofs, rm_ofs,
56
- vec_size, vec_size);
57
- } else {
58
- gen_gvec_sabd(size, rd_ofs, rn_ofs, rm_ofs,
59
- vec_size, vec_size);
60
- }
61
- return 0;
62
-
63
- case NEON_3R_VABA:
64
- if (u) {
65
- gen_gvec_uaba(size, rd_ofs, rn_ofs, rm_ofs,
66
- vec_size, vec_size);
67
- } else {
68
- gen_gvec_saba(size, rd_ofs, rn_ofs, rm_ofs,
69
- vec_size, vec_size);
70
- }
71
- return 0;
72
-
73
case NEON_3R_VADD_VSUB:
74
case NEON_3R_LOGIC:
75
case NEON_3R_VMAX:
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
77
case NEON_3R_VSHL:
78
case NEON_3R_SHA:
79
case NEON_3R_VHADD:
80
+ case NEON_3R_VABD:
81
+ case NEON_3R_VABA:
82
/* Already handled by decodetree */
83
return 1;
84
}
85
--
86
2.20.1
87
88
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon VRHADD and VHSUB 3-reg-same insns to decodetree.
2
(These are all the other insns in 3-reg-same which were using
3
GEN_NEON_INTEGER_OP() and which are not pairwise or
4
reversed-operands.)
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200512163904.10918-7-peter.maydell@linaro.org
9
---
10
target/arm/neon-dp.decode | 6 ++++++
11
target/arm/translate-neon.inc.c | 4 ++++
12
target/arm/translate.c | 8 ++------
13
3 files changed, 12 insertions(+), 6 deletions(-)
14
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/neon-dp.decode
18
+++ b/target/arm/neon-dp.decode
19
@@ -XXX,XX +XXX,XX @@ VHADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 0 .... @3same
20
VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
21
VQADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 1 .... @3same
22
23
+VRHADD_S_3s 1111 001 0 0 . .. .... .... 0001 . . . 0 .... @3same
24
+VRHADD_U_3s 1111 001 1 0 . .. .... .... 0001 . . . 0 .... @3same
25
+
26
@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
27
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
28
29
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
30
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
31
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
32
33
+VHSUB_S_3s 1111 001 0 0 . .. .... .... 0010 . . . 0 .... @3same
34
+VHSUB_U_3s 1111 001 1 0 . .. .... .... 0010 . . . 0 .... @3same
35
+
36
VQSUB_S_3s 1111 001 0 0 . .. .... .... 0010 . . . 1 .... @3same
37
VQSUB_U_3s 1111 001 1 0 . .. .... .... 0010 . . . 1 .... @3same
38
39
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate-neon.inc.c
42
+++ b/target/arm/translate-neon.inc.c
43
@@ -XXX,XX +XXX,XX @@ DO_3SAME_64_ENV(VQRSHL_U64, gen_helper_neon_qrshl_u64)
44
45
DO_3SAME_32(VHADD_S, hadd_s)
46
DO_3SAME_32(VHADD_U, hadd_u)
47
+DO_3SAME_32(VHSUB_S, hsub_s)
48
+DO_3SAME_32(VHSUB_U, hsub_u)
49
+DO_3SAME_32(VRHADD_S, rhadd_s)
50
+DO_3SAME_32(VRHADD_U, rhadd_u)
51
diff --git a/target/arm/translate.c b/target/arm/translate.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/translate.c
54
+++ b/target/arm/translate.c
55
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
56
case NEON_3R_VSHL:
57
case NEON_3R_SHA:
58
case NEON_3R_VHADD:
59
+ case NEON_3R_VRHADD:
60
+ case NEON_3R_VHSUB:
61
case NEON_3R_VABD:
62
case NEON_3R_VABA:
63
/* Already handled by decodetree */
64
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
65
tmp2 = neon_load_reg(rm, pass);
66
}
67
switch (op) {
68
- case NEON_3R_VRHADD:
69
- GEN_NEON_INTEGER_OP(rhadd);
70
- break;
71
- case NEON_3R_VHSUB:
72
- GEN_NEON_INTEGER_OP(hsub);
73
- break;
74
case NEON_3R_VQSHL:
75
GEN_NEON_INTEGER_OP_ENV(qshl);
76
break;
77
--
78
2.20.1
79
80
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon VQDMULH and VQRDMULH 3-reg-same insns to
2
decodetree. These are the last integer operations in the
3
3-reg-same group.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200512163904.10918-11-peter.maydell@linaro.org
8
---
9
target/arm/neon-dp.decode | 3 +++
10
target/arm/translate-neon.inc.c | 24 ++++++++++++++++++++++++
11
target/arm/translate.c | 24 +-----------------------
12
3 files changed, 28 insertions(+), 23 deletions(-)
13
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/neon-dp.decode
17
+++ b/target/arm/neon-dp.decode
18
@@ -XXX,XX +XXX,XX @@ VPMAX_U_3s 1111 001 1 0 . .. .... .... 1010 . . . 0 .... @3same_q0
19
VPMIN_S_3s 1111 001 0 0 . .. .... .... 1010 . . . 1 .... @3same_q0
20
VPMIN_U_3s 1111 001 1 0 . .. .... .... 1010 . . . 1 .... @3same_q0
21
22
+VQDMULH_3s 1111 001 0 0 . .. .... .... 1011 . . . 0 .... @3same
23
+VQRDMULH_3s 1111 001 1 0 . .. .... .... 1011 . . . 0 .... @3same
24
+
25
VPADD_3s 1111 001 0 0 . .. .... .... 1011 . . . 1 .... @3same_q0
26
27
VQRDMLAH_3s 1111 001 1 0 . .. .... .... 1011 ... 1 .... @3same
28
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-neon.inc.c
31
+++ b/target/arm/translate-neon.inc.c
32
@@ -XXX,XX +XXX,XX @@ DO_3SAME_PAIR(VPMIN_S, pmin_s)
33
DO_3SAME_PAIR(VPMAX_U, pmax_u)
34
DO_3SAME_PAIR(VPMIN_U, pmin_u)
35
DO_3SAME_PAIR(VPADD, padd_u)
36
+
37
+#define DO_3SAME_VQDMULH(INSN, FUNC) \
38
+ WRAP_ENV_FN(gen_##INSN##_tramp16, gen_helper_neon_##FUNC##_s16); \
39
+ WRAP_ENV_FN(gen_##INSN##_tramp32, gen_helper_neon_##FUNC##_s32); \
40
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
41
+ uint32_t rn_ofs, uint32_t rm_ofs, \
42
+ uint32_t oprsz, uint32_t maxsz) \
43
+ { \
44
+ static const GVecGen3 ops[2] = { \
45
+ { .fni4 = gen_##INSN##_tramp16 }, \
46
+ { .fni4 = gen_##INSN##_tramp32 }, \
47
+ }; \
48
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &ops[vece - 1]); \
49
+ } \
50
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
51
+ { \
52
+ if (a->size != 1 && a->size != 2) { \
53
+ return false; \
54
+ } \
55
+ return do_3same(s, a, gen_##INSN##_3s); \
56
+ }
57
+
58
+DO_3SAME_VQDMULH(VQDMULH, qdmulh)
59
+DO_3SAME_VQDMULH(VQRDMULH, qrdmulh)
60
diff --git a/target/arm/translate.c b/target/arm/translate.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/translate.c
63
+++ b/target/arm/translate.c
64
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
65
case NEON_3R_VPMAX:
66
case NEON_3R_VPMIN:
67
case NEON_3R_VPADD_VQRDMLAH:
68
+ case NEON_3R_VQDMULH_VQRDMULH:
69
/* Already handled by decodetree */
70
return 1;
71
}
72
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
73
tmp2 = neon_load_reg(rm, pass);
74
}
75
switch (op) {
76
- case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
77
- if (!u) { /* VQDMULH */
78
- switch (size) {
79
- case 1:
80
- gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
81
- break;
82
- case 2:
83
- gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
84
- break;
85
- default: abort();
86
- }
87
- } else { /* VQRDMULH */
88
- switch (size) {
89
- case 1:
90
- gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
91
- break;
92
- case 2:
93
- gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
94
- break;
95
- default: abort();
96
- }
97
- }
98
- break;
99
case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
100
{
101
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
102
--
103
2.20.1
104
105
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon VADD, VSUB, VABD 3-reg-same insns to decodetree.
2
We already have gvec helpers for addition and subtraction, but must
3
add one for fabd.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200512163904.10918-12-peter.maydell@linaro.org
8
---
9
target/arm/helper.h | 3 ++-
10
target/arm/neon-dp.decode | 8 ++++++++
11
target/arm/neon_helper.c | 7 -------
12
target/arm/translate-neon.inc.c | 28 ++++++++++++++++++++++++++++
13
target/arm/translate.c | 10 +++-------
14
target/arm/vec_helper.c | 7 +++++++
15
6 files changed, 48 insertions(+), 15 deletions(-)
16
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.h
20
+++ b/target/arm/helper.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(neon_qneg_s16, TCG_CALL_NO_RWG, i32, env, i32)
22
DEF_HELPER_FLAGS_2(neon_qneg_s32, TCG_CALL_NO_RWG, i32, env, i32)
23
DEF_HELPER_FLAGS_2(neon_qneg_s64, TCG_CALL_NO_RWG, i64, env, i64)
24
25
-DEF_HELPER_3(neon_abd_f32, i32, i32, i32, ptr)
26
DEF_HELPER_3(neon_ceq_f32, i32, i32, i32, ptr)
27
DEF_HELPER_3(neon_cge_f32, i32, i32, i32, ptr)
28
DEF_HELPER_3(neon_cgt_f32, i32, i32, i32, ptr)
29
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_fmul_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
30
DEF_HELPER_FLAGS_5(gvec_fmul_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
31
DEF_HELPER_FLAGS_5(gvec_fmul_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
32
33
+DEF_HELPER_FLAGS_5(gvec_fabd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
34
+
35
DEF_HELPER_FLAGS_5(gvec_ftsmul_h, TCG_CALL_NO_RWG,
36
void, ptr, ptr, ptr, ptr, i32)
37
DEF_HELPER_FLAGS_5(gvec_ftsmul_s, TCG_CALL_NO_RWG,
38
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/neon-dp.decode
41
+++ b/target/arm/neon-dp.decode
42
@@ -XXX,XX +XXX,XX @@
43
@3same_q0 .... ... . . . size:2 .... .... .... . 0 . . .... \
44
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp q=0
45
46
+# For FP insns the high bit of 'size' is used as part of opcode decode
47
+@3same_fp .... ... . . . . size:1 .... .... .... . q:1 . . .... \
48
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
49
+
50
VHADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 0 .... @3same
51
VHADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 0 .... @3same
52
VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
53
@@ -XXX,XX +XXX,XX @@ SHA256SU1_3s 1111 001 1 0 . 10 .... .... 1100 . 1 . 0 .... \
54
vm=%vm_dp vn=%vn_dp vd=%vd_dp
55
56
VQRDMLSH_3s 1111 001 1 0 . .. .... .... 1100 ... 1 .... @3same
57
+
58
+VADD_fp_3s 1111 001 0 0 . 0 . .... .... 1101 ... 0 .... @3same_fp
59
+VSUB_fp_3s 1111 001 0 0 . 1 . .... .... 1101 ... 0 .... @3same_fp
60
+VABD_fp_3s 1111 001 1 0 . 1 . .... .... 1101 ... 0 .... @3same_fp
61
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/neon_helper.c
64
+++ b/target/arm/neon_helper.c
65
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_qneg_s64)(CPUARMState *env, uint64_t x)
66
}
67
68
/* NEON Float helpers. */
69
-uint32_t HELPER(neon_abd_f32)(uint32_t a, uint32_t b, void *fpstp)
70
-{
71
- float_status *fpst = fpstp;
72
- float32 f0 = make_float32(a);
73
- float32 f1 = make_float32(b);
74
- return float32_val(float32_abs(float32_sub(f0, f1, fpst)));
75
-}
76
77
/* Floating point comparisons produce an integer result.
78
* Note that EQ doesn't signal InvalidOp for QNaNs but GE and GT do.
79
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/arm/translate-neon.inc.c
82
+++ b/target/arm/translate-neon.inc.c
83
@@ -XXX,XX +XXX,XX @@ DO_3SAME_PAIR(VPADD, padd_u)
84
85
DO_3SAME_VQDMULH(VQDMULH, qdmulh)
86
DO_3SAME_VQDMULH(VQRDMULH, qrdmulh)
87
+
88
+/*
89
+ * For all the functions using this macro, size == 1 means fp16,
90
+ * which is an architecture extension we don't implement yet.
91
+ */
92
+#define DO_3S_FP_GVEC(INSN,FUNC) \
93
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
94
+ uint32_t rn_ofs, uint32_t rm_ofs, \
95
+ uint32_t oprsz, uint32_t maxsz) \
96
+ { \
97
+ TCGv_ptr fpst = get_fpstatus_ptr(1); \
98
+ tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, fpst, \
99
+ oprsz, maxsz, 0, FUNC); \
100
+ tcg_temp_free_ptr(fpst); \
101
+ } \
102
+ static bool trans_##INSN##_fp_3s(DisasContext *s, arg_3same *a) \
103
+ { \
104
+ if (a->size != 0) { \
105
+ /* TODO fp16 support */ \
106
+ return false; \
107
+ } \
108
+ return do_3same(s, a, gen_##INSN##_3s); \
109
+ }
110
+
111
+
112
+DO_3S_FP_GVEC(VADD, gen_helper_gvec_fadd_s)
113
+DO_3S_FP_GVEC(VSUB, gen_helper_gvec_fsub_s)
114
+DO_3S_FP_GVEC(VABD, gen_helper_gvec_fabd_s)
115
diff --git a/target/arm/translate.c b/target/arm/translate.c
116
index XXXXXXX..XXXXXXX 100644
117
--- a/target/arm/translate.c
118
+++ b/target/arm/translate.c
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
120
switch (op) {
121
case NEON_3R_FLOAT_ARITH:
122
pairwise = (u && size < 2); /* if VPADD (float) */
123
+ if (!pairwise) {
124
+ return 1; /* handled by decodetree */
125
+ }
126
break;
127
case NEON_3R_FLOAT_MINMAX:
128
pairwise = u; /* if VPMIN/VPMAX (float) */
129
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
130
{
131
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
132
switch ((u << 2) | size) {
133
- case 0: /* VADD */
134
case 4: /* VPADD */
135
gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
136
break;
137
- case 2: /* VSUB */
138
- gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
139
- break;
140
- case 6: /* VABD */
141
- gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
142
- break;
143
default:
144
abort();
145
}
146
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/target/arm/vec_helper.c
149
+++ b/target/arm/vec_helper.c
150
@@ -XXX,XX +XXX,XX @@ static float64 float64_ftsmul(float64 op1, uint64_t op2, float_status *stat)
151
return result;
152
}
153
154
+static float32 float32_abd(float32 op1, float32 op2, float_status *stat)
155
+{
156
+ return float32_abs(float32_sub(op1, op2, stat));
157
+}
158
+
159
#define DO_3OP(NAME, FUNC, TYPE) \
160
void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
161
{ \
162
@@ -XXX,XX +XXX,XX @@ DO_3OP(gvec_ftsmul_h, float16_ftsmul, float16)
163
DO_3OP(gvec_ftsmul_s, float32_ftsmul, float32)
164
DO_3OP(gvec_ftsmul_d, float64_ftsmul, float64)
165
166
+DO_3OP(gvec_fabd_s, float32_abd, float32)
167
+
168
#ifdef TARGET_AARCH64
169
170
DO_3OP(gvec_recps_h, helper_recpsf_f16, float16)
171
--
172
2.20.1
173
174
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon float VPMIN, VPMAX and VPADD 3-reg-same insns to
2
decodetree. These are the only remaining 'pairwise' operations,
3
so we can delete the pairwise-specific bits of the old decoder's
4
for-each-element loop now.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200512163904.10918-13-peter.maydell@linaro.org
9
---
10
target/arm/neon-dp.decode | 5 +++
11
target/arm/translate-neon.inc.c | 63 +++++++++++++++++++++++++++++++++
12
target/arm/translate.c | 63 +++++----------------------------
13
3 files changed, 76 insertions(+), 55 deletions(-)
14
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/neon-dp.decode
18
+++ b/target/arm/neon-dp.decode
19
@@ -XXX,XX +XXX,XX @@
20
# For FP insns the high bit of 'size' is used as part of opcode decode
21
@3same_fp .... ... . . . . size:1 .... .... .... . q:1 . . .... \
22
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
23
+@3same_fp_q0 .... ... . . . . size:1 .... .... .... . 0 . . .... \
24
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp q=0
25
26
VHADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 0 .... @3same
27
VHADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 0 .... @3same
28
@@ -XXX,XX +XXX,XX @@ VQRDMLSH_3s 1111 001 1 0 . .. .... .... 1100 ... 1 .... @3same
29
30
VADD_fp_3s 1111 001 0 0 . 0 . .... .... 1101 ... 0 .... @3same_fp
31
VSUB_fp_3s 1111 001 0 0 . 1 . .... .... 1101 ... 0 .... @3same_fp
32
+VPADD_fp_3s 1111 001 1 0 . 0 . .... .... 1101 ... 0 .... @3same_fp_q0
33
VABD_fp_3s 1111 001 1 0 . 1 . .... .... 1101 ... 0 .... @3same_fp
34
+VPMAX_fp_3s 1111 001 1 0 . 0 . .... .... 1111 ... 0 .... @3same_fp_q0
35
+VPMIN_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 0 .... @3same_fp_q0
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-neon.inc.c
39
+++ b/target/arm/translate-neon.inc.c
40
@@ -XXX,XX +XXX,XX @@ DO_3SAME_VQDMULH(VQRDMULH, qrdmulh)
41
DO_3S_FP_GVEC(VADD, gen_helper_gvec_fadd_s)
42
DO_3S_FP_GVEC(VSUB, gen_helper_gvec_fsub_s)
43
DO_3S_FP_GVEC(VABD, gen_helper_gvec_fabd_s)
44
+
45
+static bool do_3same_fp_pair(DisasContext *s, arg_3same *a, VFPGen3OpSPFn *fn)
46
+{
47
+ /* FP operations handled pairwise 32 bits at a time */
48
+ TCGv_i32 tmp, tmp2, tmp3;
49
+ TCGv_ptr fpstatus;
50
+
51
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
52
+ return false;
53
+ }
54
+
55
+ /* UNDEF accesses to D16-D31 if they don't exist. */
56
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
57
+ ((a->vd | a->vn | a->vm) & 0x10)) {
58
+ return false;
59
+ }
60
+
61
+ if (!vfp_access_check(s)) {
62
+ return true;
63
+ }
64
+
65
+ assert(a->q == 0); /* enforced by decode patterns */
66
+
67
+ /*
68
+ * Note that we have to be careful not to clobber the source operands
69
+ * in the "vm == vd" case by storing the result of the first pass too
70
+ * early. Since Q is 0 there are always just two passes, so instead
71
+ * of a complicated loop over each pass we just unroll.
72
+ */
73
+ fpstatus = get_fpstatus_ptr(1);
74
+ tmp = neon_load_reg(a->vn, 0);
75
+ tmp2 = neon_load_reg(a->vn, 1);
76
+ fn(tmp, tmp, tmp2, fpstatus);
77
+ tcg_temp_free_i32(tmp2);
78
+
79
+ tmp3 = neon_load_reg(a->vm, 0);
80
+ tmp2 = neon_load_reg(a->vm, 1);
81
+ fn(tmp3, tmp3, tmp2, fpstatus);
82
+ tcg_temp_free_i32(tmp2);
83
+ tcg_temp_free_ptr(fpstatus);
84
+
85
+ neon_store_reg(a->vd, 0, tmp);
86
+ neon_store_reg(a->vd, 1, tmp3);
87
+ return true;
88
+}
89
+
90
+/*
91
+ * For all the functions using this macro, size == 1 means fp16,
92
+ * which is an architecture extension we don't implement yet.
93
+ */
94
+#define DO_3S_FP_PAIR(INSN,FUNC) \
95
+ static bool trans_##INSN##_fp_3s(DisasContext *s, arg_3same *a) \
96
+ { \
97
+ if (a->size != 0) { \
98
+ /* TODO fp16 support */ \
99
+ return false; \
100
+ } \
101
+ return do_3same_fp_pair(s, a, FUNC); \
102
+ }
103
+
104
+DO_3S_FP_PAIR(VPADD, gen_helper_vfp_adds)
105
+DO_3S_FP_PAIR(VPMAX, gen_helper_vfp_maxs)
106
+DO_3S_FP_PAIR(VPMIN, gen_helper_vfp_mins)
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/target/arm/translate.c
110
+++ b/target/arm/translate.c
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
112
int shift;
113
int pass;
114
int count;
115
- int pairwise;
116
int u;
117
int vec_size;
118
uint32_t imm;
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
120
case NEON_3R_VPMIN:
121
case NEON_3R_VPADD_VQRDMLAH:
122
case NEON_3R_VQDMULH_VQRDMULH:
123
+ case NEON_3R_FLOAT_ARITH:
124
/* Already handled by decodetree */
125
return 1;
126
}
127
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
128
/* 64-bit element instructions: handled by decodetree */
129
return 1;
130
}
131
- pairwise = 0;
132
switch (op) {
133
- case NEON_3R_FLOAT_ARITH:
134
- pairwise = (u && size < 2); /* if VPADD (float) */
135
- if (!pairwise) {
136
- return 1; /* handled by decodetree */
137
- }
138
- break;
139
case NEON_3R_FLOAT_MINMAX:
140
- pairwise = u; /* if VPMIN/VPMAX (float) */
141
+ if (u) {
142
+ return 1; /* VPMIN/VPMAX handled by decodetree */
143
+ }
144
break;
145
case NEON_3R_FLOAT_CMP:
146
if (!u && size) {
147
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
148
break;
149
}
150
151
- if (pairwise && q) {
152
- /* All the pairwise insns UNDEF if Q is set */
153
- return 1;
154
- }
155
-
156
for (pass = 0; pass < (q ? 4 : 2); pass++) {
157
158
- if (pairwise) {
159
- /* Pairwise. */
160
- if (pass < 1) {
161
- tmp = neon_load_reg(rn, 0);
162
- tmp2 = neon_load_reg(rn, 1);
163
- } else {
164
- tmp = neon_load_reg(rm, 0);
165
- tmp2 = neon_load_reg(rm, 1);
166
- }
167
- } else {
168
- /* Elementwise. */
169
- tmp = neon_load_reg(rn, pass);
170
- tmp2 = neon_load_reg(rm, pass);
171
- }
172
+ /* Elementwise. */
173
+ tmp = neon_load_reg(rn, pass);
174
+ tmp2 = neon_load_reg(rm, pass);
175
switch (op) {
176
- case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
177
- {
178
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
179
- switch ((u << 2) | size) {
180
- case 4: /* VPADD */
181
- gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
182
- break;
183
- default:
184
- abort();
185
- }
186
- tcg_temp_free_ptr(fpstatus);
187
- break;
188
- }
189
case NEON_3R_FLOAT_MULTIPLY:
190
{
191
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
192
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
193
}
194
tcg_temp_free_i32(tmp2);
195
196
- /* Save the result. For elementwise operations we can put it
197
- straight into the destination register. For pairwise operations
198
- we have to be careful to avoid clobbering the source operands. */
199
- if (pairwise && rd == rm) {
200
- neon_store_scratch(pass, tmp);
201
- } else {
202
- neon_store_reg(rd, pass, tmp);
203
- }
204
+ neon_store_reg(rd, pass, tmp);
205
206
} /* for pass */
207
- if (pairwise && rd == rm) {
208
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
209
- tmp = neon_load_scratch(pass);
210
- neon_store_reg(rd, pass, tmp);
211
- }
212
- }
213
/* End of 3 register same size operations. */
214
} else if (insn & (1 << 4)) {
215
if ((insn & 0x00380080) != 0) {
216
--
217
2.20.1
218
219
diff view generated by jsdifflib
Deleted patch
1
Convert the Neon integer VMUL, VMLA, and VMLS 3-reg-same inssn to
2
decodetree.
3
1
4
We don't have a gvec helper for multiply-accumulate, so VMLA and VMLS
5
need a loop function do_3same_fp(). This takes a reads_vd parameter
6
to do_3same_fp() which tells it to load the old value into vd before
7
calling the callback function, in the same way that the do_vfp_3op_sp()
8
and do_vfp_3op_dp() functions in translate-vfp.inc.c work. (The
9
only uses in this patch pass reads_vd == true, but later commits
10
will use reads_vd == false.)
11
12
This conversion fixes in passing an underdecoding for VMUL
13
(originally reported by Fredrik Strupe <fredrik@strupe.net>): bit 1
14
of the 'size' field must be 0. The old decoder didn't enforce this,
15
but the decodetree pattern does.
16
17
The gen_VMLA_fp_reg() function performs the addition operation
18
with the operands in the opposite order to the old decoder:
19
since Neon sets 'default NaN mode' float32_add operations are
20
commutative so there is no behaviour difference, but putting
21
them this way around matches the Arm ARM pseudocode and the
22
required operation order for the subtraction in gen_VMLS_fp_reg().
23
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20200512163904.10918-14-peter.maydell@linaro.org
27
---
28
target/arm/neon-dp.decode | 3 ++
29
target/arm/translate-neon.inc.c | 81 +++++++++++++++++++++++++++++++++
30
target/arm/translate.c | 17 +------
31
3 files changed, 85 insertions(+), 16 deletions(-)
32
33
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/neon-dp.decode
36
+++ b/target/arm/neon-dp.decode
37
@@ -XXX,XX +XXX,XX @@ VADD_fp_3s 1111 001 0 0 . 0 . .... .... 1101 ... 0 .... @3same_fp
38
VSUB_fp_3s 1111 001 0 0 . 1 . .... .... 1101 ... 0 .... @3same_fp
39
VPADD_fp_3s 1111 001 1 0 . 0 . .... .... 1101 ... 0 .... @3same_fp_q0
40
VABD_fp_3s 1111 001 1 0 . 1 . .... .... 1101 ... 0 .... @3same_fp
41
+VMLA_fp_3s 1111 001 0 0 . 0 . .... .... 1101 ... 1 .... @3same_fp
42
+VMLS_fp_3s 1111 001 0 0 . 1 . .... .... 1101 ... 1 .... @3same_fp
43
+VMUL_fp_3s 1111 001 1 0 . 0 . .... .... 1101 ... 1 .... @3same_fp
44
VPMAX_fp_3s 1111 001 1 0 . 0 . .... .... 1111 ... 0 .... @3same_fp_q0
45
VPMIN_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 0 .... @3same_fp_q0
46
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/translate-neon.inc.c
49
+++ b/target/arm/translate-neon.inc.c
50
@@ -XXX,XX +XXX,XX @@ DO_3SAME_PAIR(VPADD, padd_u)
51
DO_3SAME_VQDMULH(VQDMULH, qdmulh)
52
DO_3SAME_VQDMULH(VQRDMULH, qrdmulh)
53
54
+static bool do_3same_fp(DisasContext *s, arg_3same *a, VFPGen3OpSPFn *fn,
55
+ bool reads_vd)
56
+{
57
+ /*
58
+ * FP operations handled elementwise 32 bits at a time.
59
+ * If reads_vd is true then the old value of Vd will be
60
+ * loaded before calling the callback function. This is
61
+ * used for multiply-accumulate type operations.
62
+ */
63
+ TCGv_i32 tmp, tmp2;
64
+ int pass;
65
+
66
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
67
+ return false;
68
+ }
69
+
70
+ /* UNDEF accesses to D16-D31 if they don't exist. */
71
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
72
+ ((a->vd | a->vn | a->vm) & 0x10)) {
73
+ return false;
74
+ }
75
+
76
+ if ((a->vn | a->vm | a->vd) & a->q) {
77
+ return false;
78
+ }
79
+
80
+ if (!vfp_access_check(s)) {
81
+ return true;
82
+ }
83
+
84
+ TCGv_ptr fpstatus = get_fpstatus_ptr(1);
85
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
86
+ tmp = neon_load_reg(a->vn, pass);
87
+ tmp2 = neon_load_reg(a->vm, pass);
88
+ if (reads_vd) {
89
+ TCGv_i32 tmp_rd = neon_load_reg(a->vd, pass);
90
+ fn(tmp_rd, tmp, tmp2, fpstatus);
91
+ neon_store_reg(a->vd, pass, tmp_rd);
92
+ tcg_temp_free_i32(tmp);
93
+ } else {
94
+ fn(tmp, tmp, tmp2, fpstatus);
95
+ neon_store_reg(a->vd, pass, tmp);
96
+ }
97
+ tcg_temp_free_i32(tmp2);
98
+ }
99
+ tcg_temp_free_ptr(fpstatus);
100
+ return true;
101
+}
102
+
103
/*
104
* For all the functions using this macro, size == 1 means fp16,
105
* which is an architecture extension we don't implement yet.
106
@@ -XXX,XX +XXX,XX @@ DO_3SAME_VQDMULH(VQRDMULH, qrdmulh)
107
DO_3S_FP_GVEC(VADD, gen_helper_gvec_fadd_s)
108
DO_3S_FP_GVEC(VSUB, gen_helper_gvec_fsub_s)
109
DO_3S_FP_GVEC(VABD, gen_helper_gvec_fabd_s)
110
+DO_3S_FP_GVEC(VMUL, gen_helper_gvec_fmul_s)
111
+
112
+/*
113
+ * For all the functions using this macro, size == 1 means fp16,
114
+ * which is an architecture extension we don't implement yet.
115
+ */
116
+#define DO_3S_FP(INSN,FUNC,READS_VD) \
117
+ static bool trans_##INSN##_fp_3s(DisasContext *s, arg_3same *a) \
118
+ { \
119
+ if (a->size != 0) { \
120
+ /* TODO fp16 support */ \
121
+ return false; \
122
+ } \
123
+ return do_3same_fp(s, a, FUNC, READS_VD); \
124
+ }
125
+
126
+static void gen_VMLA_fp_3s(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm,
127
+ TCGv_ptr fpstatus)
128
+{
129
+ gen_helper_vfp_muls(vn, vn, vm, fpstatus);
130
+ gen_helper_vfp_adds(vd, vd, vn, fpstatus);
131
+}
132
+
133
+static void gen_VMLS_fp_3s(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm,
134
+ TCGv_ptr fpstatus)
135
+{
136
+ gen_helper_vfp_muls(vn, vn, vm, fpstatus);
137
+ gen_helper_vfp_subs(vd, vd, vn, fpstatus);
138
+}
139
+
140
+DO_3S_FP(VMLA, gen_VMLA_fp_3s, true)
141
+DO_3S_FP(VMLS, gen_VMLS_fp_3s, true)
142
143
static bool do_3same_fp_pair(DisasContext *s, arg_3same *a, VFPGen3OpSPFn *fn)
144
{
145
diff --git a/target/arm/translate.c b/target/arm/translate.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/target/arm/translate.c
148
+++ b/target/arm/translate.c
149
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
150
case NEON_3R_VPADD_VQRDMLAH:
151
case NEON_3R_VQDMULH_VQRDMULH:
152
case NEON_3R_FLOAT_ARITH:
153
+ case NEON_3R_FLOAT_MULTIPLY:
154
/* Already handled by decodetree */
155
return 1;
156
}
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
158
tmp = neon_load_reg(rn, pass);
159
tmp2 = neon_load_reg(rm, pass);
160
switch (op) {
161
- case NEON_3R_FLOAT_MULTIPLY:
162
- {
163
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
164
- gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
165
- if (!u) {
166
- tcg_temp_free_i32(tmp2);
167
- tmp2 = neon_load_reg(rd, pass);
168
- if (size == 0) {
169
- gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
170
- } else {
171
- gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
172
- }
173
- }
174
- tcg_temp_free_ptr(fpstatus);
175
- break;
176
- }
177
case NEON_3R_FLOAT_CMP:
178
{
179
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
180
--
181
2.20.1
182
183
diff view generated by jsdifflib