1
First target-arm pullreq of the 4.0 series; most of this
1
Mostly this is patches from me and RTH cleaning up and doing
2
is Mao's cleanups that finally let us drop sysbus::init;
2
more decodetree conversion for AArch32 Neon. The major new feature
3
the most interesting user-visible feature is RTH's patches
3
is Dongjiu Geng's patchset to report host memory errors to KVM guests;
4
adding some v8.1 and v8.2 architecture features.
4
also a new aspeed board from Patrick Williams.
5
5
6
thanks
6
thanks
7
-- PMM
7
-- PMM
8
8
9
The following changes since commit 6145a6d84b3bf0f25935b88543febe076c61b0f4:
9
The following changes since commit 035b448b84f3557206abc44d786c5d3db2638f7d:
10
10
11
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20181212' into staging (2018-12-13 13:06:09 +0000)
11
Merge remote-tracking branch 'remotes/gkurz/tags/9p-next-2020-05-14' into staging (2020-05-14 10:58:30 +0100)
12
12
13
are available in the Git repository at:
13
are available in the Git repository at:
14
14
15
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20181213
15
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200514
16
16
17
for you to fetch changes up to 2d7137c10fafefe40a0a049ff8a7bd78b66e661f:
17
for you to fetch changes up to e95485f85657be21135c17a9226e297c21e73360:
18
18
19
target/arm: Implement the ARMv8.1-LOR extension (2018-12-13 14:41:24 +0000)
19
target/arm: Convert NEON VFMA, VFMS 3-reg-same insns to decodetree (2020-05-14 15:03:09 +0100)
20
20
21
----------------------------------------------------------------
21
----------------------------------------------------------------
22
target-arm queue:
22
target-arm queue:
23
* Convert various devices from sysbus init to instance_init
23
* target/arm: Use correct GDB XML for M-profile cores
24
* Remove the now unused sysbus init support entirely
24
* target/arm: Code cleanup to use gvec APIs better
25
* Allow AArch64 processors to boot from a kernel placed over 4GB
25
* aspeed: Add support for the sonorapass-bmc board
26
* hw: arm: musicpal: drop TYPE_WM8750 in object_property_set_link()
26
* target/arm: Support reporting KVM host memory errors
27
* versal: minor fixes to virtio-mmio instantation
27
to the guest via ACPI notifications
28
* arm: Implement the ARMv8.1-HPD extension
28
* target/arm: Finish conversion of Neon 3-reg-same insns to decodetree
29
* arm: Implement the ARMv8.2-AA32HPD extension
30
* arm: Implement the ARMv8.1-LOR extension (as the trivial
31
"no limited ordering regions provided" minimum)
32
29
33
----------------------------------------------------------------
30
----------------------------------------------------------------
34
Edgar E. Iglesias (4):
31
Dongjiu Geng (10):
35
hw/arm: versal: Remove bogus virtio-mmio creation
32
acpi: nvdimm: change NVDIMM_UUID_LE to a common macro
36
hw/arm: versal: Reduce number of virtio-mmio instances
33
hw/arm/virt: Introduce a RAS machine option
37
hw/arm: versal: Use IRQs 111 - 118 for virtio-mmio
34
docs: APEI GHES generation and CPER record description
38
hw/arm: versal: Correct the nr of IRQs to 192
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
39
42
40
Li Qiang (1):
43
Patrick Williams (1):
41
hw: arm: musicpal: drop TYPE_WM8750 in object_property_set_link()
44
aspeed: Add support for the sonorapass-bmc board
42
45
43
Mao Zhongyi (21):
46
Peter Maydell (18):
44
musicpal: Convert sysbus init function to realize function
47
target/arm: Use correct GDB XML for M-profile cores
45
block/noenand: Convert sysbus init function to realize function
48
target/arm: Convert Neon 3-reg-same VQRDMLAH/VQRDMLSH to decodetree
46
char/grlib_apbuart: Convert sysbus init function to realize function
49
target/arm: Convert Neon 3-reg-same SHA to decodetree
47
core/empty_slot: Convert sysbus init function to realize function
50
target/arm: Convert Neon 64-bit element 3-reg-same insns
48
display/g364fb: Convert sysbus init function to realize function
51
target/arm: Convert Neon VHADD 3-reg-same insns
49
dma/puv3_dma: Convert sysbus init function to realize function
52
target/arm: Convert Neon VABA/VABD 3-reg-same to decodetree
50
gpio/puv3_gpio: Convert sysbus init function to realize function
53
target/arm: Convert Neon VRHADD, VHSUB 3-reg-same insns to decodetree
51
milkymist-softusb: Convert sysbus init function to realize function
54
target/arm: Convert Neon VQSHL, VRSHL, VQRSHL 3-reg-same insns to decodetree
52
input/pl050: Convert sysbus init function to realize function
55
target/arm: Convert Neon VPMAX/VPMIN 3-reg-same insns to decodetree
53
intc/puv3_intc: Convert sysbus init function to realize function
56
target/arm: Convert Neon VPADD 3-reg-same insns to decodetree
54
milkymist-hpdmc: Convert sysbus init function to realize function
57
target/arm: Convert Neon VQDMULH/VQRDMULH 3-reg-same to decodetree
55
milkymist-pfpu: Convert sysbus init function to realize function
58
target/arm: Convert Neon VADD, VSUB, VABD 3-reg-same insns to decodetree
56
puv3_pm.c: Convert sysbus init function to realize function
59
target/arm: Convert Neon VPMIN/VPMAX/VPADD float 3-reg-same insns to decodetree
57
nvram/ds1225y: Convert sysbus init function to realize function
60
target/arm: Convert Neon fp VMUL, VMLA, VMLS 3-reg-same insns to decodetree
58
pci-bridge/dec: Convert sysbus init function to realize function
61
target/arm: Convert Neon 3-reg-same compare insns to decodetree
59
timer/etraxfs_timer: Convert sysbus init function to realize function
62
target/arm: Move 'env' argument of recps_f32 and rsqrts_f32 helpers to usual place
60
timer/grlib_gptimer: Convert sysbus init function to realize function
63
target/arm: Convert Neon fp VMAX/VMIN/VMAXNM/VMINNM/VRECPS/VRSQRTS to decodetree
61
timer/puv3_ost: Convert sysbus init function to realize function
64
target/arm: Convert NEON VFMA, VFMS 3-reg-same insns to decodetree
62
usb/tusb6010: Convert sysbus init function to realize function
63
xen_backend: remove xen_sysdev_init() function
64
core/sysbus: remove the SysBusDeviceClass::init path
65
65
66
Peter Maydell (1):
66
Richard Henderson (16):
67
target/arm: Move id_aa64mmfr* to ARMISARegisters
67
target/arm: Create gen_gvec_[us]sra
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
68
83
69
Ricardo Perez Blanco (1):
84
docs/specs/acpi_hest_ghes.rst | 110 ++
70
Allow AArch64 processors to boot from a kernel placed over 4GB
85
docs/specs/index.rst | 1 +
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
71
130
72
Richard Henderson (9):
73
target/arm: Add HCR_EL2 bits up to ARMv8.5
74
target/arm: Add SCR_EL3 bits up to ARMv8.5
75
target/arm: Fix HCR_EL2.TGE check in arm_phys_excp_target_el
76
target/arm: Tidy scr_write
77
target/arm: Implement the ARMv8.1-HPD extension
78
target/arm: Implement the ARMv8.2-AA32HPD extension
79
target/arm: Introduce arm_hcr_el2_eff
80
target/arm: Use arm_hcr_el2_eff more places
81
target/arm: Implement the ARMv8.1-LOR extension
82
83
include/hw/arm/xlnx-versal.h | 8 +-
84
include/hw/sysbus.h | 3 -
85
target/arm/cpu.h | 141 ++++++++++++++++-----------
86
target/arm/internals.h | 3 +-
87
hw/arm/boot.c | 35 ++++---
88
hw/arm/musicpal.c | 11 +--
89
hw/arm/xlnx-versal-virt.c | 7 +-
90
hw/block/onenand.c | 16 ++--
91
hw/char/grlib_apbuart.c | 12 +--
92
hw/core/empty_slot.c | 9 +-
93
hw/core/sysbus.c | 15 +--
94
hw/display/g364fb.c | 9 +-
95
hw/dma/puv3_dma.c | 10 +-
96
hw/gpio/puv3_gpio.c | 29 +++---
97
hw/input/milkymist-softusb.c | 16 ++--
98
hw/input/pl050.c | 11 +--
99
hw/intc/arm_gicv3_cpuif.c | 21 ++--
100
hw/intc/puv3_intc.c | 11 +--
101
hw/misc/milkymist-hpdmc.c | 9 +-
102
hw/misc/milkymist-pfpu.c | 12 +--
103
hw/misc/puv3_pm.c | 10 +-
104
hw/nvram/ds1225y.c | 12 +--
105
hw/pci-bridge/dec.c | 12 +--
106
hw/timer/etraxfs_timer.c | 14 +--
107
hw/timer/grlib_gptimer.c | 11 +--
108
hw/timer/puv3_ost.c | 13 ++-
109
hw/usb/tusb6010.c | 8 +-
110
hw/xen/xen_backend.c | 7 --
111
target/arm/cpu.c | 4 +
112
target/arm/cpu64.c | 11 ++-
113
target/arm/helper.c | 222 ++++++++++++++++++++++++++++++++++++-------
114
target/arm/kvm64.c | 4 +
115
target/arm/op_helper.c | 14 ++-
116
target/arm/translate-a64.c | 12 +++
117
34 files changed, 456 insertions(+), 286 deletions(-)
118
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
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.
2
7
3
Use DeviceClass rather than SysBusDeviceClass in
8
Ship a copy of GDB's arm-m-profile.xml and use it on the M-profile
4
puv3_pm_class_init().
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.
5
13
6
Cc: gxt@mprc.pku.edu.cn
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
7
25
8
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
26
diff --git a/configure b/configure
9
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
27
index XXXXXXX..XXXXXXX 100755
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
28
--- a/configure
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
29
+++ b/configure
12
Message-id: 20181130093852.20739-14-maozhongyi@cmss.chinamobile.com
30
@@ -XXX,XX +XXX,XX @@ case "$target_name" in
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
TARGET_SYSTBL_ABI=common,oabi
14
---
32
bflt="yes"
15
hw/misc/puv3_pm.c | 10 ++++------
33
mttcg="yes"
16
1 file changed, 4 insertions(+), 6 deletions(-)
34
- gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
17
35
+ gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml arm-m-profile.xml"
18
diff --git a/hw/misc/puv3_pm.c b/hw/misc/puv3_pm.c
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
19
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/misc/puv3_pm.c
49
--- a/target/arm/cpu_tcg.c
21
+++ b/hw/misc/puv3_pm.c
50
+++ b/target/arm/cpu_tcg.c
22
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps puv3_pm_ops = {
51
@@ -XXX,XX +XXX,XX @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
23
.endianness = DEVICE_NATIVE_ENDIAN,
52
#endif
24
};
53
25
54
cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
26
-static int puv3_pm_init(SysBusDevice *dev)
55
+ cc->gdb_core_xml_file = "arm-m-profile.xml";
27
+static void puv3_pm_realize(DeviceState *dev, Error **errp)
28
{
29
PUV3PMState *s = PUV3_PM(dev);
30
31
@@ -XXX,XX +XXX,XX @@ static int puv3_pm_init(SysBusDevice *dev)
32
33
memory_region_init_io(&s->iomem, OBJECT(s), &puv3_pm_ops, s, "puv3_pm",
34
PUV3_REGS_OFFSET);
35
- sysbus_init_mmio(dev, &s->iomem);
36
-
37
- return 0;
38
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
39
}
56
}
40
57
41
static void puv3_pm_class_init(ObjectClass *klass, void *data)
58
static const ARMCPUInfo arm_tcg_cpus[] = {
42
{
59
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
43
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
60
index XXXXXXX..XXXXXXX 100644
44
+ DeviceClass *dc = DEVICE_CLASS(klass);
61
--- a/target/arm/gdbstub.c
45
62
+++ b/target/arm/gdbstub.c
46
- sdc->init = puv3_pm_init;
63
@@ -XXX,XX +XXX,XX @@ int arm_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
47
+ dc->realize = puv3_pm_realize;
64
}
48
}
65
return gdb_get_reg32(mem_buf, 0);
49
66
case 25:
50
static const TypeInfo puv3_pm_info = {
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>
51
--
132
--
52
2.19.2
133
2.20.1
53
134
54
135
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use DeviceClass rather than SysBusDeviceClass in
3
The functions eliminate duplication of the special cases for
4
puv3_ost_class_init().
4
this operation. They match up with the GVecGen2iFn typedef.
5
5
6
Cc: gxt@mprc.pku.edu.cn
6
Add out-of-line helpers. We got away with only having inline
7
7
expanders because the neon vector size is only 16 bytes, and
8
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
8
we know that the inline expansion will always succeed.
9
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
9
When we reuse this for SVE, tcg-gvec-op may decide to use an
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
out-of-line helper due to longer vector lengths.
11
Message-id: 20181130093852.20739-19-maozhongyi@cmss.chinamobile.com
11
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200513163245.17915-2-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
16
---
14
hw/timer/puv3_ost.c | 13 ++++++-------
17
target/arm/helper.h | 10 +++
15
1 file changed, 6 insertions(+), 7 deletions(-)
18
target/arm/translate.h | 7 +-
16
19
target/arm/translate-a64.c | 15 +---
17
diff --git a/hw/timer/puv3_ost.c b/hw/timer/puv3_ost.c
20
target/arm/translate.c | 161 ++++++++++++++++++++++---------------
18
index XXXXXXX..XXXXXXX 100644
21
target/arm/vec_helper.c | 25 ++++++
19
--- a/hw/timer/puv3_ost.c
22
5 files changed, 139 insertions(+), 79 deletions(-)
20
+++ b/hw/timer/puv3_ost.c
23
21
@@ -XXX,XX +XXX,XX @@ static void puv3_ost_tick(void *opaque)
24
diff --git a/target/arm/helper.h b/target/arm/helper.h
22
}
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.h
27
+++ b/target/arm/helper.h
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_pmull_q, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
30
DEF_HELPER_FLAGS_4(neon_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
32
+DEF_HELPER_FLAGS_3(gvec_ssra_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_3(gvec_ssra_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_3(gvec_ssra_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_3(gvec_ssra_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
36
+
37
+DEF_HELPER_FLAGS_3(gvec_usra_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_3(gvec_usra_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_3(gvec_usra_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_3(gvec_usra_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
41
+
42
#ifdef TARGET_AARCH64
43
#include "helper-a64.h"
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 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);
23
}
102
}
24
103
25
-static int puv3_ost_init(SysBusDevice *dev)
104
-static const TCGOpcode vecop_list_ssra[] = {
26
+static void puv3_ost_realize(DeviceState *dev, Error **errp)
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
+
168
+ /*
169
+ * Shifts larger than the element size are architecturally valid.
170
+ * Signed results in all sign bits.
171
+ */
172
+ shift = MIN(shift, (8 << vece) - 1);
173
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
174
+}
175
176
static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
27
{
177
{
28
PUV3OSTState *s = PUV3_OST(dev);
178
@@ -XXX,XX +XXX,XX @@ static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
29
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
179
tcg_gen_add_vec(vece, d, d, a);
30
31
s->reg_OIER = 0;
32
s->reg_OSSR = 0;
33
s->reg_OSMR0 = 0;
34
s->reg_OSCR = 0;
35
36
- sysbus_init_irq(dev, &s->irq);
37
+ sysbus_init_irq(sbd, &s->irq);
38
39
s->bh = qemu_bh_new(puv3_ost_tick, s);
40
s->ptimer = ptimer_init(s->bh, PTIMER_POLICY_DEFAULT);
41
@@ -XXX,XX +XXX,XX @@ static int puv3_ost_init(SysBusDevice *dev)
42
43
memory_region_init_io(&s->iomem, OBJECT(s), &puv3_ost_ops, s, "puv3_ost",
44
PUV3_REGS_OFFSET);
45
- sysbus_init_mmio(dev, &s->iomem);
46
-
47
- return 0;
48
+ sysbus_init_mmio(sbd, &s->iomem);
49
}
180
}
50
181
51
static void puv3_ost_class_init(ObjectClass *klass, void *data)
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
+
246
+ /*
247
+ * Shifts larger than the element size are architecturally valid.
248
+ * Unsigned results in all zeros as input to accumulate: nop.
249
+ */
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)
52
{
259
{
53
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
260
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
54
+ DeviceClass *dc = DEVICE_CLASS(klass);
261
case 1: /* VSRA */
55
262
/* Right shift comes here negative. */
56
- sdc->init = puv3_ost_init;
263
shift = -shift;
57
+ dc->realize = puv3_ost_realize;
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));
58
}
291
}
59
292
60
static const TypeInfo puv3_ost_info = {
293
+
294
+#define DO_SRA(NAME, TYPE) \
295
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
296
+{ \
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.
61
--
321
--
62
2.19.2
322
2.20.1
63
323
64
324
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Currently, all sysbus devices have been converted to realize(),
3
Create vectorized versions of handle_shri_with_rndacc
4
so remove this path.
4
for shift+round and shift+round+accumulate. Add out-of-line
5
helpers in preparation for longer vector lengths from SVE.
5
6
6
Cc: ehabkost@redhat.com
7
Cc: thuth@redhat.com
8
Cc: pbonzini@redhat.com
9
Cc: armbru@redhat.com
10
Cc: peter.maydell@linaro.org
11
Cc: richard.henderson@linaro.org
12
Cc: alistair.francis@wdc.com
13
14
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
15
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
16
Message-id: 20181130093852.20739-22-maozhongyi@cmss.chinamobile.com
17
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-3-richard.henderson@linaro.org
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
11
---
20
include/hw/sysbus.h | 3 ---
12
target/arm/helper.h | 20 ++
21
hw/core/sysbus.c | 15 +++++----------
13
target/arm/translate.h | 9 +
22
2 files changed, 5 insertions(+), 13 deletions(-)
14
target/arm/translate-a64.c | 11 +-
15
target/arm/translate.c | 463 +++++++++++++++++++++++++++++++++++--
16
target/arm/vec_helper.c | 50 ++++
17
5 files changed, 527 insertions(+), 26 deletions(-)
23
18
24
diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h
19
diff --git a/target/arm/helper.h b/target/arm/helper.h
25
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/sysbus.h
21
--- a/target/arm/helper.h
27
+++ b/include/hw/sysbus.h
22
+++ b/target/arm/helper.h
28
@@ -XXX,XX +XXX,XX @@ typedef struct SysBusDevice SysBusDevice;
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(gvec_usra_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
29
typedef struct SysBusDeviceClass {
24
DEF_HELPER_FLAGS_3(gvec_usra_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
30
/*< private >*/
25
DEF_HELPER_FLAGS_3(gvec_usra_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
31
DeviceClass parent_class;
26
32
- /*< public >*/
27
+DEF_HELPER_FLAGS_3(gvec_srshr_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
33
-
28
+DEF_HELPER_FLAGS_3(gvec_srshr_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
34
- int (*init)(SysBusDevice *dev);
29
+DEF_HELPER_FLAGS_3(gvec_srshr_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
35
30
+DEF_HELPER_FLAGS_3(gvec_srshr_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
36
/*
31
+
37
* Let the sysbus device format its own non-PIO, non-MMIO unit address.
32
+DEF_HELPER_FLAGS_3(gvec_urshr_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
38
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
33
+DEF_HELPER_FLAGS_3(gvec_urshr_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_3(gvec_urshr_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_3(gvec_urshr_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
36
+
37
+DEF_HELPER_FLAGS_3(gvec_srsra_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
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
+
42
+DEF_HELPER_FLAGS_3(gvec_ursra_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
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
39
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/core/sysbus.c
52
--- a/target/arm/translate.h
41
+++ b/hw/core/sysbus.c
53
+++ b/target/arm/translate.h
42
@@ -XXX,XX +XXX,XX @@ void sysbus_init_ioports(SysBusDevice *dev, uint32_t ioport, uint32_t size)
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,
43
}
98
}
44
}
99
}
45
100
46
-/* TODO remove once all sysbus devices have been converted to realize */
101
+/*
47
+/* The purpose of preserving this empty realize function
102
+ * Shift one less than the requested amount, and the low bit is
48
+ * is to prevent the parent_realize field of some subclasses
103
+ * the rounding bit. For the 8 and 16-bit operations, because we
49
+ * from being set to NULL to break the normal init/realize
104
+ * mask the low bit, we can perform a normal integer shift instead
50
+ * of some devices.
105
+ * of a vector shift.
51
+ */
106
+ */
52
static void sysbus_realize(DeviceState *dev, Error **errp)
107
+static void gen_srshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
108
+{
109
+ TCGv_i64 t = tcg_temp_new_i64();
110
+
111
+ tcg_gen_shri_i64(t, a, sh - 1);
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
+}
117
+
118
+static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
119
+{
120
+ TCGv_i64 t = tcg_temp_new_i64();
121
+
122
+ tcg_gen_shri_i64(t, a, sh - 1);
123
+ tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
124
+ tcg_gen_vec_sar16i_i64(d, a, sh);
125
+ tcg_gen_vec_add16_i64(d, d, t);
126
+ tcg_temp_free_i64(t);
127
+}
128
+
129
+static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
130
+{
131
+ TCGv_i32 t = tcg_temp_new_i32();
132
+
133
+ tcg_gen_extract_i32(t, a, sh - 1, 1);
134
+ tcg_gen_sari_i32(d, a, sh);
135
+ tcg_gen_add_i32(d, d, t);
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
+ };
193
+
194
+ /* tszimm encoding produces immediates in the range [1..esize] */
195
+ tcg_debug_assert(shift > 0);
196
+ tcg_debug_assert(shift <= (8 << vece));
197
+
198
+ if (shift == (8 << vece)) {
199
+ /*
200
+ * Shifts larger than the element size are architecturally valid.
201
+ * Signed results in all sign bits. With rounding, this produces
202
+ * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
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
+
294
+ /*
295
+ * Shifts larger than the element size are architecturally valid.
296
+ * Signed results in all sign bits. With rounding, this produces
297
+ * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
298
+ * I.e. always zero. With accumulation, this leaves D unchanged.
299
+ */
300
+ if (shift == (8 << vece)) {
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
+}
307
+
308
+static void gen_urshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
309
+{
310
+ TCGv_i64 t = tcg_temp_new_i64();
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)
53
{
518
{
54
- SysBusDevice *sd = SYS_BUS_DEVICE(dev);
519
uint64_t mask = dup_const(MO_8, 0xff >> shift);
55
- SysBusDeviceClass *sbc = SYS_BUS_DEVICE_GET_CLASS(sd);
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);
56
-
592
-
57
- if (!sbc->init) {
593
- if (op == 3) {
58
- return;
594
- /* Accumulate. */
59
- }
595
- tmp2 = neon_load_reg(rd, pass);
60
- if (sbc->init(sd) < 0) {
596
- gen_neon_add(size, tmp, tmp2);
61
- error_setg(errp, "Device initialization failed");
597
- tcg_temp_free_i32(tmp2);
62
- }
598
- }
63
}
599
neon_store_reg(rd, pass, tmp);
64
600
}
65
DeviceState *sysbus_create_varargs(const char *name,
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.
66
--
663
--
67
2.19.2
664
2.20.1
68
665
69
666
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use DeviceClass rather than SysBusDeviceClass in
3
The functions eliminate duplication of the special cases for
4
etraxfs_timer_class_init().
4
this operation. They match up with the GVecGen2iFn typedef.
5
5
6
Cc: edgar.iglesias@gmail.com
6
Add out-of-line helpers. We got away with only having inline
7
7
expanders because the neon vector size is only 16 bytes, and
8
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
8
we know that the inline expansion will always succeed.
9
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
9
When we reuse this for SVE, tcg-gvec-op may decide to use an
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
out-of-line helper due to longer vector lengths.
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
12
Message-id: 20181130093852.20739-17-maozhongyi@cmss.chinamobile.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200513163245.17915-4-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
16
---
15
hw/timer/etraxfs_timer.c | 14 +++++++-------
17
target/arm/helper.h | 10 ++
16
1 file changed, 7 insertions(+), 7 deletions(-)
18
target/arm/translate.h | 7 +-
17
19
target/arm/translate-a64.c | 20 +---
18
diff --git a/hw/timer/etraxfs_timer.c b/hw/timer/etraxfs_timer.c
20
target/arm/translate.c | 186 +++++++++++++++++++++----------------
21
target/arm/vec_helper.c | 38 ++++++++
22
5 files changed, 160 insertions(+), 101 deletions(-)
23
24
diff --git a/target/arm/helper.h b/target/arm/helper.h
19
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/timer/etraxfs_timer.c
26
--- a/target/arm/helper.h
21
+++ b/hw/timer/etraxfs_timer.c
27
+++ b/target/arm/helper.h
22
@@ -XXX,XX +XXX,XX @@ static void etraxfs_timer_reset(void *opaque)
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(gvec_ursra_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
23
qemu_irq_lower(t->irq);
29
DEF_HELPER_FLAGS_3(gvec_ursra_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
30
DEF_HELPER_FLAGS_3(gvec_ursra_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
31
32
+DEF_HELPER_FLAGS_3(gvec_sri_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_3(gvec_sri_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_3(gvec_sri_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_3(gvec_sri_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
36
+
37
+DEF_HELPER_FLAGS_3(gvec_sli_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_3(gvec_sli_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_3(gvec_sli_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_3(gvec_sli_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
41
+
42
#ifdef TARGET_AARCH64
43
#include "helper-a64.h"
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);
24
}
76
}
25
77
26
-static int etraxfs_timer_init(SysBusDevice *dev)
78
-/* Expand a 2-operand + immediate AdvSIMD vector operation using
27
+static void etraxfs_timer_realize(DeviceState *dev, Error **errp)
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
}
123
diff --git a/target/arm/translate.c b/target/arm/translate.c
124
index XXXXXXX..XXXXXXX 100644
125
--- a/target/arm/translate.c
126
+++ 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)
128
129
static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
28
{
130
{
29
ETRAXTimerState *t = ETRAX_TIMER(dev);
131
- if (sh == 0) {
30
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
132
- tcg_gen_mov_vec(d, a);
31
133
- } else {
32
t->bh_t0 = qemu_bh_new(timer0_hit, t);
134
- TCGv_vec t = tcg_temp_new_vec_matching(d);
33
t->bh_t1 = qemu_bh_new(timer1_hit, t);
135
- TCGv_vec m = tcg_temp_new_vec_matching(d);
34
@@ -XXX,XX +XXX,XX @@ static int etraxfs_timer_init(SysBusDevice *dev)
136
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
35
t->ptimer_t1 = ptimer_init(t->bh_t1, PTIMER_POLICY_DEFAULT);
137
+ TCGv_vec m = tcg_temp_new_vec_matching(d);
36
t->ptimer_wd = ptimer_init(t->bh_wd, PTIMER_POLICY_DEFAULT);
138
37
139
- tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
38
- sysbus_init_irq(dev, &t->irq);
140
- tcg_gen_shri_vec(vece, t, a, sh);
39
- sysbus_init_irq(dev, &t->nmi);
141
- tcg_gen_and_vec(vece, d, d, m);
40
+ sysbus_init_irq(sbd, &t->irq);
142
- tcg_gen_or_vec(vece, d, d, t);
41
+ sysbus_init_irq(sbd, &t->nmi);
143
+ tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
42
144
+ tcg_gen_shri_vec(vece, t, a, sh);
43
memory_region_init_io(&t->mmio, OBJECT(t), &timer_ops, t,
145
+ tcg_gen_and_vec(vece, d, d, m);
44
"etraxfs-timer", 0x5c);
146
+ tcg_gen_or_vec(vece, d, d, t);
45
- sysbus_init_mmio(dev, &t->mmio);
147
46
+ sysbus_init_mmio(sbd, &t->mmio);
148
- tcg_temp_free_vec(t);
47
qemu_register_reset(etraxfs_timer_reset, t);
149
- tcg_temp_free_vec(m);
48
- return 0;
150
- }
151
+ tcg_temp_free_vec(t);
152
+ tcg_temp_free_vec(m);
49
}
153
}
50
154
51
static void etraxfs_timer_class_init(ObjectClass *klass, void *data)
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
+
215
+ /* Shift of esize leaves destination unchanged. */
216
+ if (shift < (8 << vece)) {
217
+ tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
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)
52
{
225
{
53
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
226
@@ -XXX,XX +XXX,XX @@ static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
54
+ DeviceClass *dc = DEVICE_CLASS(klass);
227
55
228
static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
56
- sdc->init = etraxfs_timer_init;
229
{
57
+ dc->realize = etraxfs_timer_realize;
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);
58
}
252
}
59
253
60
static const TypeInfo etraxfs_timer_info = {
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.
61
--
397
--
62
2.19.2
398
2.20.1
63
399
64
400
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Because EL3 has a fixed execution mode, we can properly decide
3
In 1dc8425e551, while converting to gvec, I added an extra range check
4
which of the bits are RES{0,1}.
4
against the shift count. This was unnecessary because the encoding of
5
the shift count produces 0 to the element size - 1.
5
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20181203203839.757-8-richard.henderson@linaro.org
9
Message-id: 20200513163245.17915-5-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/cpu.h | 2 --
12
target/arm/translate.c | 12 ++----------
12
target/arm/helper.c | 14 +++++++++-----
13
1 file changed, 2 insertions(+), 10 deletions(-)
13
2 files changed, 9 insertions(+), 7 deletions(-)
14
14
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
17
--- a/target/arm/translate.c
18
+++ b/target/arm/cpu.h
18
+++ b/target/arm/translate.c
19
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
19
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
20
#define SCR_FIEN (1U << 21)
20
gen_gvec_sli(size, rd_ofs, rm_ofs, shift,
21
#define SCR_ENSCXT (1U << 25)
21
vec_size, vec_size);
22
#define SCR_ATA (1U << 26)
22
} else { /* VSHL */
23
-#define SCR_AARCH32_MASK (0x3fff & ~(SCR_RW | SCR_ST))
23
- /* Shifts larger than the element size are
24
-#define SCR_AARCH64_MASK (0x3fff & ~SCR_NET)
24
- * architecturally valid and results in zero.
25
25
- */
26
/* Return the current FPSCR value. */
26
- if (shift >= 8 << size) {
27
uint32_t vfp_get_fpscr(CPUARMState *env);
27
- tcg_gen_gvec_dup_imm(size, rd_ofs,
28
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
- vec_size, vec_size, 0);
29
index XXXXXXX..XXXXXXX 100644
29
- } else {
30
--- a/target/arm/helper.c
30
- tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
31
+++ b/target/arm/helper.c
31
- vec_size, vec_size);
32
@@ -XXX,XX +XXX,XX @@ static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
32
- }
33
33
+ tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
34
static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
34
+ vec_size, vec_size);
35
{
35
}
36
- /* We only mask off bits that are RES0 both for AArch64 and AArch32.
36
return 0;
37
- * For bits that vary between AArch32/64, code needs to check the
37
}
38
- * current execution mode before directly using the feature bit.
39
- */
40
- uint32_t valid_mask = SCR_AARCH64_MASK | SCR_AARCH32_MASK;
41
+ /* Begin with base v8.0 state. */
42
+ uint32_t valid_mask = 0x3fff;
43
+
44
+ if (arm_el_is_aa64(env, 3)) {
45
+ value |= SCR_FW | SCR_AW; /* these two bits are RES1. */
46
+ valid_mask &= ~SCR_NET;
47
+ } else {
48
+ valid_mask &= ~(SCR_RW | SCR_ST);
49
+ }
50
51
if (!arm_feature(env, ARM_FEATURE_EL2)) {
52
valid_mask &= ~SCR_HCE;
53
--
38
--
54
2.19.2
39
2.20.1
55
40
56
41
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Since the TCR_*.HPD bits were RES0 in ARMv8.0, we can simply
3
Now that we've converted all cases to gvec, there is quite a bit
4
interpret the bits as if ARMv8.1-HPD is present without checking.
4
of dead code at the end of the function. Remove it.
5
We will need a slightly different check for hpd for aarch32.
5
6
Sink the call to gen_gvec_fn2i to the end, loading a function
7
pointer within the switch statement.
6
8
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20181203203839.757-10-richard.henderson@linaro.org
11
Message-id: 20200513163245.17915-6-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/cpu64.c | 4 ++++
14
target/arm/translate-a64.c | 56 ++++++++++----------------------------
13
target/arm/helper.c | 27 ++++++++++++++++++++-------
15
1 file changed, 14 insertions(+), 42 deletions(-)
14
2 files changed, 24 insertions(+), 7 deletions(-)
15
16
16
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
17
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu64.c
19
--- a/target/arm/translate-a64.c
19
+++ b/target/arm/cpu64.c
20
+++ b/target/arm/translate-a64.c
20
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
21
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
21
t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
22
int size = 32 - clz32(immh) - 1;
22
cpu->isar.id_aa64pfr0 = t;
23
int immhb = immh << 3 | immb;
23
24
int shift = 2 * (8 << size) - immhb;
24
+ t = cpu->isar.id_aa64mmfr1;
25
- bool accumulate = false;
25
+ t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */
26
- int dsize = is_q ? 128 : 64;
26
+ cpu->isar.id_aa64mmfr1 = t;
27
- int esize = 8 << size;
27
+
28
- int elements = dsize/esize;
28
/* Replicate the same data to the 32-bit id registers. */
29
- MemOp memop = size | (is_u ? 0 : MO_SIGN);
29
u = cpu->isar.id_isar5;
30
- TCGv_i64 tcg_rn = new_tmp_a64(s);
30
u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */
31
- TCGv_i64 tcg_rd = new_tmp_a64(s);
31
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
- TCGv_i64 tcg_round;
32
index XXXXXXX..XXXXXXX 100644
33
- uint64_t round_const;
33
--- a/target/arm/helper.c
34
- int i;
34
+++ b/target/arm/helper.c
35
+ GVecGen2iFn *gvec_fn;
35
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
36
36
bool ttbr1_valid = true;
37
if (extract32(immh, 3, 1) && !is_q) {
37
uint64_t descaddrmask;
38
unallocated_encoding(s);
38
bool aarch64 = arm_el_is_aa64(env, el);
39
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
39
+ bool hpd = false;
40
40
41
switch (opcode) {
41
/* TODO:
42
case 0x02: /* SSRA / USRA (accumulate) */
42
* This code does not handle the different format TCR for VTCR_EL2.
43
- gen_gvec_fn2i(s, is_q, rd, rn, shift,
43
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
44
- is_u ? gen_gvec_usra : gen_gvec_ssra, size);
44
if (tg == 2) { /* 16KB pages */
45
- return;
45
stride = 11;
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;
46
}
73
}
47
+ if (aarch64) {
74
- return;
48
+ if (el > 1) {
75
+ break;
49
+ hpd = extract64(tcr->raw_tcr, 24, 1);
76
50
+ } else {
77
case 0x04: /* SRSHR / URSHR (rounding) */
51
+ hpd = extract64(tcr->raw_tcr, 41, 1);
78
- gen_gvec_fn2i(s, is_q, rd, rn, shift,
52
+ }
79
- is_u ? gen_gvec_urshr : gen_gvec_srshr, size);
53
+ }
80
- return;
54
} else {
81
+ gvec_fn = is_u ? gen_gvec_urshr : gen_gvec_srshr;
55
/* We should only be here if TTBR1 is valid */
82
+ break;
56
assert(ttbr1_valid);
83
57
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
84
case 0x06: /* SRSRA / URSRA (accum + rounding) */
58
if (tg == 1) { /* 16KB pages */
85
- gen_gvec_fn2i(s, is_q, rd, rn, shift,
59
stride = 11;
86
- is_u ? gen_gvec_ursra : gen_gvec_srsra, size);
60
}
87
- return;
61
+ if (aarch64) {
88
+ gvec_fn = is_u ? gen_gvec_ursra : gen_gvec_srsra;
62
+ hpd = extract64(tcr->raw_tcr, 42, 1);
89
+ break;
63
+ }
90
91
default:
92
g_assert_not_reached();
64
}
93
}
65
94
66
/* Here we should have set up all the parameters for the translation:
95
- round_const = 1ULL << (shift - 1);
67
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
96
- tcg_round = tcg_const_i64(round_const);
68
descaddr = descriptor & descaddrmask;
97
-
69
98
- for (i = 0; i < elements; i++) {
70
if ((descriptor & 2) && (level < 3)) {
99
- read_vec_element(s, tcg_rn, rn, i, memop);
71
- /* Table entry. The top five bits are attributes which may
100
- if (accumulate) {
72
+ /* Table entry. The top five bits are attributes which may
101
- read_vec_element(s, tcg_rd, rd, i, memop);
73
* propagate down through lower levels of the table (and
74
* which are all arranged so that 0 means "no effect", so
75
* we can gather them up by ORing in the bits at each level).
76
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
77
break;
78
}
79
/* Merge in attributes from table descriptors */
80
- attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */
81
- attrs |= extract32(tableattrs, 3, 1) << 5; /* APTable[1] => AP[2] */
82
+ attrs |= nstable << 3; /* NS */
83
+ if (hpd) {
84
+ /* HPD disables all the table attributes except NSTable. */
85
+ break;
86
+ }
87
+ attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */
88
/* The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1
89
* means "force PL1 access only", which means forcing AP[1] to 0.
90
*/
91
- if (extract32(tableattrs, 2, 1)) {
92
- attrs &= ~(1 << 4);
93
- }
102
- }
94
- attrs |= nstable << 3; /* NS */
103
-
95
+ attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */
104
- handle_shri_with_rndacc(tcg_rd, tcg_rn, tcg_round,
96
+ attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */
105
- accumulate, is_u, size, shift);
97
break;
106
-
98
}
107
- write_vec_element(s, tcg_rd, rd, i, size);
99
/* Here descaddr is the final physical address, and attributes
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 */
100
--
116
--
101
2.19.2
117
2.20.1
102
118
103
119
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use DeviceClass rather than SysBusDeviceClass in
3
Provide a functional interface for the vector expansion.
4
grlib_gptimer_class_init().
4
This fits better with the existing set of helpers that
5
5
we provide for other operations.
6
Cc: chouteau@adacore.com
6
7
7
Macro-ize the 5 nearly identical comparisons.
8
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
8
9
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20181130093852.20739-18-maozhongyi@cmss.chinamobile.com
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
hw/timer/grlib_gptimer.c | 11 +++++------
14
target/arm/translate.h | 16 ++-
15
1 file changed, 5 insertions(+), 6 deletions(-)
15
target/arm/translate-a64.c | 22 ++--
16
16
target/arm/translate.c | 254 ++++++++-----------------------------
17
diff --git a/hw/timer/grlib_gptimer.c b/hw/timer/grlib_gptimer.c
17
3 files changed, 74 insertions(+), 218 deletions(-)
18
19
diff --git a/target/arm/translate.h b/target/arm/translate.h
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/timer/grlib_gptimer.c
21
--- a/target/arm/translate.h
20
+++ b/hw/timer/grlib_gptimer.c
22
+++ b/target/arm/translate.h
21
@@ -XXX,XX +XXX,XX @@ static void grlib_gptimer_reset(DeviceState *d)
23
@@ -XXX,XX +XXX,XX @@ static inline void gen_swstep_exception(DisasContext *s, int isv, int ex)
22
}
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));
23
}
52
}
24
53
25
-static int grlib_gptimer_init(SysBusDevice *dev)
54
-/* Expand a 2-operand AdvSIMD vector operation using an op descriptor. */
26
+static void grlib_gptimer_realize(DeviceState *dev, Error **errp)
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
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/translate.c
93
+++ b/target/arm/translate.c
94
@@ -XXX,XX +XXX,XX @@ static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
95
return 1;
96
}
97
98
-static void gen_ceq0_i32(TCGv_i32 d, TCGv_i32 a)
99
-{
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)
27
{
345
{
28
GPTimerUnit *unit = GRLIB_GPTIMER(dev);
346
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
29
unsigned int i;
347
break;
30
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
348
31
349
case NEON_2RM_VCEQ0:
32
assert(unit->nr_timers > 0);
350
- tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
33
assert(unit->nr_timers <= GPTIMER_MAX_TIMERS);
351
- vec_size, &ceq0_op[size]);
34
@@ -XXX,XX +XXX,XX @@ static int grlib_gptimer_init(SysBusDevice *dev)
352
+ gen_gvec_ceq0(size, rd_ofs, rm_ofs, vec_size, vec_size);
35
timer->id = i;
353
break;
36
354
case NEON_2RM_VCGT0:
37
/* One IRQ line for each timer */
355
- tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
38
- sysbus_init_irq(dev, &timer->irq);
356
- vec_size, &cgt0_op[size]);
39
+ sysbus_init_irq(sbd, &timer->irq);
357
+ gen_gvec_cgt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
40
358
break;
41
ptimer_set_freq(timer->ptimer, unit->freq_hz);
359
case NEON_2RM_VCLE0:
42
}
360
- tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
43
@@ -XXX,XX +XXX,XX @@ static int grlib_gptimer_init(SysBusDevice *dev)
361
- vec_size, &cle0_op[size]);
44
unit, "gptimer",
362
+ gen_gvec_cle0(size, rd_ofs, rm_ofs, vec_size, vec_size);
45
UNIT_REG_SIZE + GPTIMER_REG_SIZE * unit->nr_timers);
363
break;
46
364
case NEON_2RM_VCGE0:
47
- sysbus_init_mmio(dev, &unit->iomem);
365
- tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
48
- return 0;
366
- vec_size, &cge0_op[size]);
49
+ sysbus_init_mmio(sbd, &unit->iomem);
367
+ gen_gvec_cge0(size, rd_ofs, rm_ofs, vec_size, vec_size);
50
}
368
break;
51
369
case NEON_2RM_VCLT0:
52
static Property grlib_gptimer_properties[] = {
370
- tcg_gen_gvec_2(rd_ofs, rm_ofs, vec_size,
53
@@ -XXX,XX +XXX,XX @@ static Property grlib_gptimer_properties[] = {
371
- vec_size, &clt0_op[size]);
54
static void grlib_gptimer_class_init(ObjectClass *klass, void *data)
372
+ gen_gvec_clt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
55
{
373
break;
56
DeviceClass *dc = DEVICE_CLASS(klass);
374
57
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
375
default:
58
59
- k->init = grlib_gptimer_init;
60
+ dc->realize = grlib_gptimer_realize;
61
dc->reset = grlib_gptimer_reset;
62
dc->props = grlib_gptimer_properties;
63
}
64
--
376
--
65
2.19.2
377
2.20.1
66
378
67
379
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 bulk of the work here, beyond base HPD, is defining the
3
Provide a functional interface for the vector expansion.
4
TTBCR2 register. In addition we must check TTBCR.T2E, which
4
This fits better with the existing set of helpers that
5
is not present (RES0) for AArch64.
5
we provide for other operations.
6
6
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>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20181203203839.757-11-richard.henderson@linaro.org
9
Message-id: 20200513163245.17915-8-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
target/arm/cpu.h | 9 +++++++++
12
target/arm/translate.h | 7 +-
13
target/arm/cpu.c | 4 ++++
13
target/arm/translate-a64.c | 4 +-
14
target/arm/helper.c | 37 +++++++++++++++++++++++++++++--------
14
target/arm/translate-neon.inc.c | 16 +----
15
3 files changed, 42 insertions(+), 8 deletions(-)
15
target/arm/translate.c | 117 +++++++++++++++++---------------
16
16
4 files changed, 71 insertions(+), 73 deletions(-)
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
18
index XXXXXXX..XXXXXXX 100644
18
diff --git a/target/arm/translate.h b/target/arm/translate.h
19
--- a/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
+++ b/target/arm/cpu.h
20
--- a/target/arm/translate.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(ID_ISAR6, FHM, 8, 4)
21
+++ b/target/arm/translate.h
22
FIELD(ID_ISAR6, SB, 12, 4)
22
@@ -XXX,XX +XXX,XX @@ void gen_gvec_cle0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
23
FIELD(ID_ISAR6, SPECRES, 16, 4)
23
void gen_gvec_cge0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
24
24
uint32_t opr_sz, uint32_t max_sz);
25
+FIELD(ID_MMFR4, SPECSEI, 0, 4)
25
26
+FIELD(ID_MMFR4, AC2, 4, 4)
26
-extern const GVecGen3 mla_op[4];
27
+FIELD(ID_MMFR4, XNX, 8, 4)
27
-extern const GVecGen3 mls_op[4];
28
+FIELD(ID_MMFR4, CNP, 12, 4)
28
+void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
29
+FIELD(ID_MMFR4, HPDS, 16, 4)
29
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
30
+FIELD(ID_MMFR4, LSM, 20, 4)
30
+void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
31
+FIELD(ID_MMFR4, CCIDX, 24, 4)
31
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
32
+FIELD(ID_MMFR4, EVT, 28, 4)
33
+
32
+
34
FIELD(ID_AA64ISAR0, AES, 4, 4)
33
extern const GVecGen3 cmtst_op[4];
35
FIELD(ID_AA64ISAR0, SHA1, 8, 4)
34
extern const GVecGen3 sshl_op[4];
36
FIELD(ID_AA64ISAR0, SHA2, 12, 4)
35
extern const GVecGen3 ushl_op[4];
37
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
36
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
38
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/cpu.c
38
--- a/target/arm/translate-a64.c
40
+++ b/target/arm/cpu.c
39
+++ b/target/arm/translate-a64.c
41
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
40
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
42
t = cpu->isar.id_isar6;
41
return;
43
t = FIELD_DP32(t, ID_ISAR6, DP, 1);
42
case 0x12: /* MLA, MLS */
44
cpu->isar.id_isar6 = t;
43
if (u) {
45
+
44
- gen_gvec_op3(s, is_q, rd, rn, rm, &mls_op[size]);
46
+ t = cpu->id_mmfr4;
45
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_mls, size);
47
+ t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
46
} else {
48
+ cpu->id_mmfr4 = t;
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
}
49
}
50
#endif
50
return;
51
}
51
case 0x11:
52
diff --git a/target/arm/helper.c b/target/arm/helper.c
52
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
53
index XXXXXXX..XXXXXXX 100644
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/helper.c
54
--- a/target/arm/translate-neon.inc.c
55
+++ b/target/arm/helper.c
55
+++ b/target/arm/translate-neon.inc.c
56
@@ -XXX,XX +XXX,XX @@ static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
56
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
57
uint64_t value)
57
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
58
{
58
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
59
ARMCPU *cpu = arm_env_get_cpu(env);
59
DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
60
+ TCR *tcr = raw_ptr(env, ri);
60
+DO_3SAME_NO_SZ_3(VMLA, gen_gvec_mla)
61
61
+DO_3SAME_NO_SZ_3(VMLS, gen_gvec_mls)
62
if (arm_feature(env, ARM_FEATURE_LPAE)) {
62
63
/* With LPAE the TTBCR could result in a change of ASID
63
#define DO_3SAME_CMP(INSN, COND) \
64
@@ -XXX,XX +XXX,XX @@ static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
64
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
65
*/
65
@@ -XXX,XX +XXX,XX @@ static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
66
tlb_flush(CPU(cpu));
66
return do_3same(s, a, gen_VMUL_p_3s);
67
}
68
+ /* Preserve the high half of TCR_EL1, set via TTBCR2. */
69
+ value = deposit64(tcr->raw_tcr, 0, 32, value);
70
vmsa_ttbcr_raw_write(env, ri, value);
71
}
67
}
72
68
73
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
69
-#define DO_3SAME_GVEC3_NO_SZ_3(INSN, OPARRAY) \
74
REGINFO_SENTINEL
70
- static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
75
};
71
- uint32_t rn_ofs, uint32_t rm_ofs, \
76
72
- uint32_t oprsz, uint32_t maxsz) \
77
+/* Note that unlike TTBCR, writing to TTBCR2 does not require flushing
73
- { \
78
+ * qemu tlbs nor adjusting cached masks.
74
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
79
+ */
75
- oprsz, maxsz, &OPARRAY[vece]); \
80
+static const ARMCPRegInfo ttbcr2_reginfo = {
76
- } \
81
+ .name = "TTBCR2", .cp = 15, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 3,
77
- DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
82
+ .access = PL1_RW, .type = ARM_CP_ALIAS,
78
-
83
+ .bank_fieldoffsets = { offsetofhigh32(CPUARMState, cp15.tcr_el[3]),
79
-
84
+ offsetofhigh32(CPUARMState, cp15.tcr_el[1]) },
80
-DO_3SAME_GVEC3_NO_SZ_3(VMLA, mla_op)
85
+};
81
-DO_3SAME_GVEC3_NO_SZ_3(VMLS, mls_op)
86
+
82
-
87
static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri,
83
#define DO_3SAME_GVEC3_SHIFT(INSN, OPARRAY) \
88
uint64_t value)
84
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
89
{
85
uint32_t rn_ofs, uint32_t rm_ofs, \
90
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
86
diff --git a/target/arm/translate.c b/target/arm/translate.c
91
} else {
87
index XXXXXXX..XXXXXXX 100644
92
define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo);
88
--- a/target/arm/translate.c
93
define_arm_cp_regs(cpu, vmsa_cp_reginfo);
89
+++ b/target/arm/translate.c
94
+ /* TTCBR2 is introduced with ARMv8.2-A32HPD. */
90
@@ -XXX,XX +XXX,XX @@ static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
95
+ if (FIELD_EX32(cpu->id_mmfr4, ID_MMFR4, HPDS) != 0) {
91
/* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
96
+ define_one_arm_cp_reg(cpu, &ttbcr2_reginfo);
92
* these tables are shared with AArch64 which does support them.
97
+ }
93
*/
98
}
94
+void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
99
if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
95
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
100
define_arm_cp_regs(cpu, t2ee_cp_reginfo);
96
+{
101
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
97
+ static const TCGOpcode vecop_list[] = {
102
if (tg == 2) { /* 16KB pages */
98
+ INDEX_op_mul_vec, INDEX_op_add_vec, 0
103
stride = 11;
99
+ };
104
}
100
+ static const GVecGen3 ops[4] = {
105
- if (aarch64) {
101
+ { .fni4 = gen_mla8_i32,
106
- if (el > 1) {
102
+ .fniv = gen_mla_vec,
107
- hpd = extract64(tcr->raw_tcr, 24, 1);
103
+ .load_dest = true,
108
- } else {
104
+ .opt_opc = vecop_list,
109
- hpd = extract64(tcr->raw_tcr, 41, 1);
105
+ .vece = MO_8 },
110
- }
106
+ { .fni4 = gen_mla16_i32,
111
+ if (aarch64 && el > 1) {
107
+ .fniv = gen_mla_vec,
112
+ hpd = extract64(tcr->raw_tcr, 24, 1);
108
+ .load_dest = true,
113
+ } else {
109
+ .opt_opc = vecop_list,
114
+ hpd = extract64(tcr->raw_tcr, 41, 1);
110
+ .vece = MO_16 },
115
+ }
111
+ { .fni4 = gen_mla32_i32,
116
+ if (!aarch64) {
112
+ .fniv = gen_mla_vec,
117
+ /* For aarch32, hpd0 is not enabled without t2e as well. */
113
+ .load_dest = true,
118
+ hpd &= extract64(tcr->raw_tcr, 6, 1);
114
+ .opt_opc = vecop_list,
119
}
115
+ .vece = MO_32 },
120
} else {
116
+ { .fni8 = gen_mla64_i64,
121
/* We should only be here if TTBR1 is valid */
117
+ .fniv = gen_mla_vec,
122
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
118
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
123
if (tg == 1) { /* 16KB pages */
119
+ .load_dest = true,
124
stride = 11;
120
+ .opt_opc = vecop_list,
125
}
121
+ .vece = MO_64 },
126
- if (aarch64) {
122
+ };
127
- hpd = extract64(tcr->raw_tcr, 42, 1);
123
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
128
+ hpd = extract64(tcr->raw_tcr, 42, 1);
124
+}
129
+ if (!aarch64) {
125
130
+ /* For aarch32, hpd1 is not enabled without t2e as well. */
126
-static const TCGOpcode vecop_list_mla[] = {
131
+ hpd &= extract64(tcr->raw_tcr, 6, 1);
127
- INDEX_op_mul_vec, INDEX_op_add_vec, 0
132
}
128
-};
133
}
129
-
134
130
-static const TCGOpcode vecop_list_mls[] = {
131
- INDEX_op_mul_vec, INDEX_op_sub_vec, 0
132
-};
133
-
134
-const GVecGen3 mla_op[4] = {
135
- { .fni4 = gen_mla8_i32,
136
- .fniv = gen_mla_vec,
137
- .load_dest = true,
138
- .opt_opc = vecop_list_mla,
139
- .vece = MO_8 },
140
- { .fni4 = gen_mla16_i32,
141
- .fniv = gen_mla_vec,
142
- .load_dest = true,
143
- .opt_opc = vecop_list_mla,
144
- .vece = MO_16 },
145
- { .fni4 = gen_mla32_i32,
146
- .fniv = gen_mla_vec,
147
- .load_dest = true,
148
- .opt_opc = vecop_list_mla,
149
- .vece = MO_32 },
150
- { .fni8 = gen_mla64_i64,
151
- .fniv = gen_mla_vec,
152
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
153
- .load_dest = true,
154
- .opt_opc = vecop_list_mla,
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
+{
184
+ static const TCGOpcode vecop_list[] = {
185
+ INDEX_op_mul_vec, INDEX_op_sub_vec, 0
186
+ };
187
+ static const GVecGen3 ops[4] = {
188
+ { .fni4 = gen_mls8_i32,
189
+ .fniv = gen_mls_vec,
190
+ .load_dest = true,
191
+ .opt_opc = vecop_list,
192
+ .vece = MO_8 },
193
+ { .fni4 = gen_mls16_i32,
194
+ .fniv = gen_mls_vec,
195
+ .load_dest = true,
196
+ .opt_opc = vecop_list,
197
+ .vece = MO_16 },
198
+ { .fni4 = gen_mls32_i32,
199
+ .fniv = gen_mls_vec,
200
+ .load_dest = true,
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)
135
--
215
--
136
2.19.2
216
2.20.1
137
217
138
218
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Since arm_hcr_el2_eff includes a check against
3
Rather than perform the argument swap during code generation,
4
arm_is_secure_below_el3, we can often remove a
4
perform it during decode. This means it doesn't have to be
5
nearby check against secure state.
5
special cased later, and we can share code with aarch64 code
6
6
generation. Hopefully the decode comment addresses any confusion
7
In some cases, sort the call to arm_hcr_el2_eff
7
that might arise in between.
8
to the end of a short-circuit logical sequence.
9
8
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20181210150501.7990-3-richard.henderson@linaro.org
11
Message-id: 20200513163245.17915-9-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
13
---
15
target/arm/helper.c | 12 +++++-------
14
target/arm/neon-dp.decode | 17 +++++++++++++++--
16
target/arm/op_helper.c | 14 ++++++--------
15
target/arm/translate-neon.inc.c | 3 +--
17
2 files changed, 11 insertions(+), 15 deletions(-)
16
2 files changed, 16 insertions(+), 4 deletions(-)
18
17
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
20
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
20
--- a/target/arm/neon-dp.decode
22
+++ b/target/arm/helper.c
21
+++ b/target/arm/neon-dp.decode
23
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri,
22
@@ -XXX,XX +XXX,XX @@ VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
24
int el = arm_current_el(env);
23
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
25
bool mdcr_el2_tdosa = (env->cp15.mdcr_el2 & MDCR_TDOSA) ||
24
VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
26
(env->cp15.mdcr_el2 & MDCR_TDE) ||
25
27
- (env->cp15.hcr_el2 & HCR_TGE);
26
-VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same
28
+ (arm_hcr_el2_eff(env) & HCR_TGE);
27
-VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same
29
28
+# The _rev suffix indicates that Vn and Vm are reversed. This is
30
if (el < 2 && mdcr_el2_tdosa && !arm_is_secure_below_el3(env)) {
29
+# the case for shifts. In the Arm ARM these insns are documented
31
return CP_ACCESS_TRAP_EL2;
30
+# with the Vm and Vn fields in their usual places, but in the
32
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri,
31
+# assembly the operands are listed "backwards", ie in the order
33
int el = arm_current_el(env);
32
+# Dd, Dm, Dn where other insns use Dd, Dn, Dm. For QEMU we choose
34
bool mdcr_el2_tdra = (env->cp15.mdcr_el2 & MDCR_TDRA) ||
33
+# to consider Vm and Vn as being in different fields in the insn,
35
(env->cp15.mdcr_el2 & MDCR_TDE) ||
34
+# which allows us to avoid special-casing shifts in the trans_
36
- (env->cp15.hcr_el2 & HCR_TGE);
35
+# function code. We would otherwise need to manually swap the operands
37
+ (arm_hcr_el2_eff(env) & HCR_TGE);
36
+# over to call Neon helper functions that are shared with AArch64,
38
37
+# which does not have this odd reversed-operand situation.
39
if (el < 2 && mdcr_el2_tdra && !arm_is_secure_below_el3(env)) {
38
+@3same_rev .... ... . . . size:2 .... .... .... . q:1 . . .... \
40
return CP_ACCESS_TRAP_EL2;
39
+ &3same vn=%vm_dp vm=%vn_dp vd=%vd_dp
41
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri,
40
+
42
int el = arm_current_el(env);
41
+VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same_rev
43
bool mdcr_el2_tda = (env->cp15.mdcr_el2 & MDCR_TDA) ||
42
+VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same_rev
44
(env->cp15.mdcr_el2 & MDCR_TDE) ||
43
45
- (env->cp15.hcr_el2 & HCR_TGE);
44
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
46
+ (arm_hcr_el2_eff(env) & HCR_TGE);
45
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
47
46
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
48
if (el < 2 && mdcr_el2_tda && !arm_is_secure_below_el3(env)) {
49
return CP_ACCESS_TRAP_EL2;
50
@@ -XXX,XX +XXX,XX @@ int sve_exception_el(CPUARMState *env, int el)
51
if (disabled) {
52
/* route_to_el2 */
53
return (arm_feature(env, ARM_FEATURE_EL2)
54
- && !arm_is_secure(env)
55
- && (env->cp15.hcr_el2 & HCR_TGE) ? 2 : 1);
56
+ && (arm_hcr_el2_eff(env) & HCR_TGE) ? 2 : 1);
57
}
58
59
/* Check CPACR.FPEN. */
60
@@ -XXX,XX +XXX,XX @@ static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type)
61
* and CPS are treated as illegal mode changes.
62
*/
63
if (write_type == CPSRWriteByInstr &&
64
- (env->cp15.hcr_el2 & HCR_TGE) &&
65
(env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON &&
66
- !arm_is_secure_below_el3(env)) {
67
+ (arm_hcr_el2_eff(env) & HCR_TGE)) {
68
return 1;
69
}
70
return 0;
71
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
72
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/op_helper.c
48
--- a/target/arm/translate-neon.inc.c
74
+++ b/target/arm/op_helper.c
49
+++ b/target/arm/translate-neon.inc.c
75
@@ -XXX,XX +XXX,XX @@ void raise_exception(CPUARMState *env, uint32_t excp,
50
@@ -XXX,XX +XXX,XX @@ static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
76
{
51
uint32_t rn_ofs, uint32_t rm_ofs, \
77
CPUState *cs = CPU(arm_env_get_cpu(env));
52
uint32_t oprsz, uint32_t maxsz) \
78
53
{ \
79
- if ((env->cp15.hcr_el2 & HCR_TGE) &&
54
- /* Note the operation is vshl vd,vm,vn */ \
80
- target_el == 1 && !arm_is_secure(env)) {
55
- tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, \
81
+ if (target_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
56
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
82
/*
57
oprsz, maxsz, &OPARRAY[vece]); \
83
* Redirect NS EL1 exceptions to NS EL2. These are reported with
58
} \
84
* their original syndrome register value, with the exception of
59
DO_3SAME(INSN, gen_##INSN##_3s)
85
@@ -XXX,XX +XXX,XX @@ static inline int check_wfx_trap(CPUARMState *env, bool is_wfe)
86
* No need for ARM_FEATURE check as if HCR_EL2 doesn't exist the
87
* bits will be zero indicating no trap.
88
*/
89
- if (cur_el < 2 && !arm_is_secure(env)) {
90
- mask = (is_wfe) ? HCR_TWE : HCR_TWI;
91
- if (env->cp15.hcr_el2 & mask) {
92
+ if (cur_el < 2) {
93
+ mask = is_wfe ? HCR_TWE : HCR_TWI;
94
+ if (arm_hcr_el2_eff(env) & mask) {
95
return 2;
96
}
97
}
98
@@ -XXX,XX +XXX,XX @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
99
exception_target_el(env));
100
}
101
102
- if (!secure && cur_el == 1 && (env->cp15.hcr_el2 & HCR_TSC)) {
103
+ if (cur_el == 1 && (arm_hcr_el2_eff(env) & HCR_TSC)) {
104
/* In NS EL1, HCR controlled routing to EL2 has priority over SMD.
105
* We also want an EL2 guest to be able to forbid its EL1 from
106
* making PSCI calls into QEMU's "firmware" via HCR.TSC.
107
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env)
108
goto illegal_return;
109
}
110
111
- if (new_el == 1 && (env->cp15.hcr_el2 & HCR_TGE)
112
- && !arm_is_secure_below_el3(env)) {
113
+ if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
114
goto illegal_return;
115
}
116
117
--
60
--
118
2.19.2
61
2.20.1
119
62
120
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
The enable for TGE has already occurred within arm_hcr_el2_amo
3
Provide a functional interface for the vector expansion.
4
and friends. Moreover, when E2H is also set, the sense is
4
This fits better with the existing set of helpers that
5
supposed to be reversed, which has also already occurred within
5
we provide for other operations.
6
the helpers.
6
7
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20181203203839.757-5-richard.henderson@linaro.org
9
Message-id: 20200513163245.17915-10-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
target/arm/helper.c | 3 ---
12
target/arm/translate.h | 10 ++-
14
1 file changed, 3 deletions(-)
13
target/arm/translate-a64.c | 18 ++--
15
14
target/arm/translate-neon.inc.c | 23 +----
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
target/arm/translate.c | 146 +++++++++++++++++---------------
16
4 files changed, 95 insertions(+), 102 deletions(-)
17
18
diff --git a/target/arm/translate.h b/target/arm/translate.h
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
20
--- a/target/arm/translate.h
19
+++ b/target/arm/helper.c
21
+++ b/target/arm/translate.h
20
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
22
@@ -XXX,XX +XXX,XX @@ void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
21
break;
23
void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
22
};
24
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
23
25
24
- /* If HCR.TGE is set then HCR is treated as being 1 */
26
-extern const GVecGen3 cmtst_op[4];
25
- hcr |= ((env->cp15.hcr_el2 & HCR_TGE) == HCR_TGE);
27
-extern const GVecGen3 sshl_op[4];
26
-
28
-extern const GVecGen3 ushl_op[4];
27
/* Perform a table-lookup for the target EL given the current state */
29
+void gen_gvec_cmtst(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
28
target_el = target_el_table[is64][scr][rw][hcr][secure][cur_el];
30
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
29
31
+void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
32
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
33
+void gen_gvec_ushl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
34
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
35
+
36
extern const GVecGen4 uqadd_op[4];
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)
30
--
305
--
31
2.19.2
306
2.20.1
32
307
33
308
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use DeviceClass rather than SysBusDeviceClass in
3
Provide a functional interface for the vector expansion.
4
pci_dec_21154_device_class_init().
4
This fits better with the existing set of helpers that
5
5
we provide for other operations.
6
Cc: david@gibson.dropbear.id.au
6
7
Cc: mst@redhat.com
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Cc: marcel.apfelbaum@gmail.com
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Cc: qemu-ppc@nongnu.org
9
Message-id: 20200513163245.17915-11-richard.henderson@linaro.org
10
11
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
12
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
13
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
14
Acked-by: David Gibson <david@gibson.dropbear.id.au>
15
Message-id: 20181130093852.20739-16-maozhongyi@cmss.chinamobile.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
11
---
18
hw/pci-bridge/dec.c | 12 ++++++------
12
target/arm/translate.h | 13 +-
19
1 file changed, 6 insertions(+), 6 deletions(-)
13
target/arm/translate-a64.c | 22 ++-
20
14
target/arm/translate-neon.inc.c | 19 +--
21
diff --git a/hw/pci-bridge/dec.c b/hw/pci-bridge/dec.c
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
22
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/pci-bridge/dec.c
20
--- a/target/arm/translate.h
24
+++ b/hw/pci-bridge/dec.c
21
+++ b/target/arm/translate.h
25
@@ -XXX,XX +XXX,XX @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
22
@@ -XXX,XX +XXX,XX @@ void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
26
return pci_bridge_get_sec_bus(br);
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);
27
}
126
}
28
127
29
-static int pci_dec_21154_device_init(SysBusDevice *dev)
128
-static const TCGOpcode vecop_list_uqadd[] = {
30
+static void pci_dec_21154_device_realize(DeviceState *dev, Error **errp)
129
- INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
31
{
130
-};
32
PCIHostState *phb;
131
-
33
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
132
-const GVecGen4 uqadd_op[4] = {
34
133
- { .fniv = gen_uqadd_vec,
35
phb = PCI_HOST_BRIDGE(dev);
134
- .fno = gen_helper_gvec_uqadd_b,
36
135
- .write_aofs = true,
37
@@ -XXX,XX +XXX,XX @@ static int pci_dec_21154_device_init(SysBusDevice *dev)
136
- .opt_opc = vecop_list_uqadd,
38
dev, "pci-conf-idx", 0x1000);
137
- .vece = MO_8 },
39
memory_region_init_io(&phb->data_mem, OBJECT(dev), &pci_host_data_le_ops,
138
- { .fniv = gen_uqadd_vec,
40
dev, "pci-data-idx", 0x1000);
139
- .fno = gen_helper_gvec_uqadd_h,
41
- sysbus_init_mmio(dev, &phb->conf_mem);
140
- .write_aofs = true,
42
- sysbus_init_mmio(dev, &phb->data_mem);
141
- .opt_opc = vecop_list_uqadd,
43
- return 0;
142
- .vece = MO_16 },
44
+ sysbus_init_mmio(sbd, &phb->conf_mem);
143
- { .fniv = gen_uqadd_vec,
45
+ sysbus_init_mmio(sbd, &phb->data_mem);
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);
46
}
190
}
47
191
48
static void dec_21154_pci_host_realize(PCIDevice *d, Error **errp)
192
-static const TCGOpcode vecop_list_sqadd[] = {
49
@@ -XXX,XX +XXX,XX @@ static const TypeInfo dec_21154_pci_host_info = {
193
- INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
50
194
-};
51
static void pci_dec_21154_device_class_init(ObjectClass *klass, void *data)
195
-
52
{
196
-const GVecGen4 sqadd_op[4] = {
53
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
197
- { .fniv = gen_sqadd_vec,
54
+ DeviceClass *dc = DEVICE_CLASS(klass);
198
- .fno = gen_helper_gvec_sqadd_b,
55
199
- .opt_opc = vecop_list_sqadd,
56
- sdc->init = pci_dec_21154_device_init;
200
- .write_aofs = true,
57
+ dc->realize = pci_dec_21154_device_realize;
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);
58
}
254
}
59
255
60
static const TypeInfo pci_dec_21154_device_info = {
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.
61
--
380
--
62
2.19.2
381
2.20.1
63
382
64
383
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Post v8.4 bits taken from SysReg_v85_xml-00bet8.
3
These operations do not touch fp_status.
4
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20181203203839.757-4-richard.henderson@linaro.org
7
Message-id: 20200513163245.17915-12-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@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/cpu.h | 10 ++++++++++
10
target/arm/helper.h | 4 ++--
11
1 file changed, 10 insertions(+)
11
target/arm/translate-a64.c | 5 ++---
12
target/arm/translate.c | 12 ++----------
13
target/arm/vfp_helper.c | 5 ++---
14
4 files changed, 8 insertions(+), 18 deletions(-)
12
15
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/target/arm/helper.h b/target/arm/helper.h
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
18
--- a/target/arm/helper.h
16
+++ b/target/arm/cpu.h
19
+++ b/target/arm/helper.h
17
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(recpe_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
18
#define SCR_ST (1U << 11)
21
DEF_HELPER_FLAGS_2(rsqrte_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
19
#define SCR_TWI (1U << 12)
22
DEF_HELPER_FLAGS_2(rsqrte_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
20
#define SCR_TWE (1U << 13)
23
DEF_HELPER_FLAGS_2(rsqrte_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
21
+#define SCR_TLOR (1U << 14)
24
-DEF_HELPER_2(recpe_u32, i32, i32, ptr)
22
+#define SCR_TERR (1U << 15)
25
-DEF_HELPER_FLAGS_2(rsqrte_u32, TCG_CALL_NO_RWG, i32, i32, ptr)
23
+#define SCR_APK (1U << 16)
26
+DEF_HELPER_FLAGS_1(recpe_u32, TCG_CALL_NO_RWG, i32, i32)
24
+#define SCR_API (1U << 17)
27
+DEF_HELPER_FLAGS_1(rsqrte_u32, TCG_CALL_NO_RWG, i32, i32)
25
+#define SCR_EEL2 (1U << 18)
28
DEF_HELPER_FLAGS_4(neon_tbl, TCG_CALL_NO_RWG, i32, i32, i32, ptr, i32)
26
+#define SCR_EASE (1U << 19)
29
27
+#define SCR_NMEA (1U << 20)
30
DEF_HELPER_3(shl_cc, i32, env, i32, i32)
28
+#define SCR_FIEN (1U << 21)
31
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
+#define SCR_ENSCXT (1U << 25)
32
index XXXXXXX..XXXXXXX 100644
30
+#define SCR_ATA (1U << 26)
33
--- a/target/arm/translate-a64.c
31
#define SCR_AARCH32_MASK (0x3fff & ~(SCR_RW | SCR_ST))
34
+++ b/target/arm/translate-a64.c
32
#define SCR_AARCH64_MASK (0x3fff & ~SCR_NET)
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;
33
110
34
--
111
--
35
2.19.2
112
2.20.1
36
113
37
114
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use DeviceClass rather than SysBusDeviceClass in
3
Provide a functional interface for the vector expansion.
4
pl050_class_init().
4
This fits better with the existing set of helpers that
5
we provide for other operations.
5
6
6
Cc: peter.maydell@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Cc: qemu-arm@nongnu.org
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
9
Message-id: 20200513163245.17915-13-richard.henderson@linaro.org
9
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
10
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Message-id: 20181130093852.20739-10-maozhongyi@cmss.chinamobile.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
11
---
15
hw/input/pl050.c | 11 +++++------
12
target/arm/translate.h | 5 ++++
16
1 file changed, 5 insertions(+), 6 deletions(-)
13
target/arm/translate-a64.c | 34 ++----------------------
14
target/arm/translate.c | 54 +++++++++++++++++++-------------------
15
3 files changed, 34 insertions(+), 59 deletions(-)
17
16
18
diff --git a/hw/input/pl050.c b/hw/input/pl050.c
17
diff --git a/target/arm/translate.h b/target/arm/translate.h
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/input/pl050.c
19
--- a/target/arm/translate.h
21
+++ b/hw/input/pl050.c
20
+++ b/target/arm/translate.h
22
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps pl050_ops = {
21
@@ -XXX,XX +XXX,XX @@ void gen_gvec_sri(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
23
.endianness = DEVICE_NATIVE_ENDIAN,
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
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-a64.c
36
+++ b/target/arm/translate-a64.c
37
@@ -XXX,XX +XXX,XX @@ static void gen_gvec_op3_ool(DisasContext *s, bool is_q, int rd,
38
is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
39
}
40
41
-/* Expand a 3-operand + env pointer operation using
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;
72
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,
24
};
94
};
25
95
26
-static int pl050_initfn(SysBusDevice *dev)
96
-
27
+static void pl050_realize(DeviceState *dev, Error **errp)
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)
28
{
102
{
29
PL050State *s = PL050(dev);
103
- if (dc_isar_feature(aa32_rdm, s)) {
30
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
104
- int opr_sz = (1 + q) * 8;
31
105
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
32
memory_region_init_io(&s->iomem, OBJECT(s), &pl050_ops, s, "pl050", 0x1000);
106
- vfp_reg_offset(1, rn),
33
- sysbus_init_mmio(dev, &s->iomem);
107
- vfp_reg_offset(1, rm), cpu_env,
34
- sysbus_init_irq(dev, &s->irq);
108
- opr_sz, opr_sz, 0, fn);
35
+ sysbus_init_mmio(sbd, &s->iomem);
109
- return 0;
36
+ sysbus_init_irq(sbd, &s->irq);
110
- }
37
if (s->is_mouse) {
111
- return 1;
38
s->dev = ps2_mouse_init(pl050_update, s);
112
+ static gen_helper_gvec_3_ptr * const fns[2] = {
39
} else {
113
+ gen_helper_gvec_qrdmlah_s16, gen_helper_gvec_qrdmlah_s32
40
s->dev = ps2_kbd_init(pl050_update, s);
114
+ };
41
}
115
+ tcg_debug_assert(vece >= 1 && vece <= 2);
42
- return 0;
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]);
43
}
129
}
44
130
45
static void pl050_keyboard_init(Object *obj)
131
#define GEN_CMP0(NAME, COND) \
46
@@ -XXX,XX +XXX,XX @@ static const TypeInfo pl050_mouse_info = {
132
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
47
static void pl050_class_init(ObjectClass *oc, void *data)
133
break; /* VPADD */
48
{
134
}
49
DeviceClass *dc = DEVICE_CLASS(oc);
135
/* VQRDMLAH */
50
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(oc);
136
- switch (size) {
51
137
- case 1:
52
- sdc->init = pl050_initfn;
138
- return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
53
+ dc->realize = pl050_realize;
139
- q, rd, rn, rm);
54
dc->vmsd = &vmstate_pl050;
140
- case 2:
55
}
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;
56
167
57
--
168
--
58
2.19.2
169
2.20.1
59
170
60
171
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use DeviceClass rather than SysBusDeviceClass in
3
Pass a pointer directly to env->vfp.qc[0], rather than env.
4
grlib_apbuart_class_init().
4
This will allow SVE2, which does not modify QC, to pass a
5
5
pointer to dummy storage.
6
Cc: chouteau@adacore.com
6
7
Cc: marcandre.lureau@redhat.com
7
Change the return type of inl_qrdml.h_s16 to match the
8
Cc: pbonzini@redhat.com
8
sense of the operation: signed.
9
9
10
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Message-id: 20200513163245.17915-14-richard.henderson@linaro.org
13
Message-id: 20181130093852.20739-4-maozhongyi@cmss.chinamobile.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
14
---
16
hw/char/grlib_apbuart.c | 12 +++++-------
15
target/arm/translate.c | 18 ++++++++---
17
1 file changed, 5 insertions(+), 7 deletions(-)
16
target/arm/vec_helper.c | 70 +++++++++++++++++++++++------------------
18
17
2 files changed, 54 insertions(+), 34 deletions(-)
19
diff --git a/hw/char/grlib_apbuart.c b/hw/char/grlib_apbuart.c
18
19
diff --git a/target/arm/translate.c b/target/arm/translate.c
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/char/grlib_apbuart.c
21
--- a/target/arm/translate.c
22
+++ b/hw/char/grlib_apbuart.c
22
+++ b/target/arm/translate.c
23
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps grlib_apbuart_ops = {
23
@@ -XXX,XX +XXX,XX @@ static const uint8_t neon_2rm_sizes[] = {
24
.endianness = DEVICE_NATIVE_ENDIAN,
24
[NEON_2RM_VCVT_UF] = 0x4,
25
};
25
};
26
26
27
-static int grlib_apbuart_init(SysBusDevice *dev)
27
+static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs,
28
+static void grlib_apbuart_realize(DeviceState *dev, Error **errp)
28
+ uint32_t opr_sz, uint32_t max_sz,
29
{
29
+ gen_helper_gvec_3_ptr *fn)
30
UART *uart = GRLIB_APB_UART(dev);
30
+{
31
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
31
+ TCGv_ptr qc_ptr = tcg_temp_new_ptr();
32
32
+
33
qemu_chr_fe_set_handlers(&uart->chr,
33
+ tcg_gen_addi_ptr(qc_ptr, cpu_env, offsetof(CPUARMState, vfp.qc));
34
grlib_apbuart_can_receive,
34
+ tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, qc_ptr,
35
@@ -XXX,XX +XXX,XX @@ static int grlib_apbuart_init(SysBusDevice *dev)
35
+ opr_sz, max_sz, 0, fn);
36
grlib_apbuart_event,
36
+ tcg_temp_free_ptr(qc_ptr);
37
NULL, uart, NULL, true);
37
+}
38
38
+
39
- sysbus_init_irq(dev, &uart->irq);
39
void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
40
+ sysbus_init_irq(sbd, &uart->irq);
40
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
41
41
{
42
memory_region_init_io(&uart->iomem, OBJECT(uart), &grlib_apbuart_ops, uart,
42
@@ -XXX,XX +XXX,XX @@ void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
43
"uart", UART_REG_SIZE);
43
gen_helper_gvec_qrdmlah_s16, gen_helper_gvec_qrdmlah_s32
44
44
};
45
- sysbus_init_mmio(dev, &uart->iomem);
45
tcg_debug_assert(vece >= 1 && vece <= 2);
46
- tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, cpu_env,
47
- opr_sz, max_sz, 0, fns[vece - 1]);
48
+ gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
49
}
50
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
46
-
71
-
47
- return 0;
72
static void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz)
48
+ sysbus_init_mmio(sbd, &uart->iomem);
73
{
49
}
74
uint64_t *d = vd + opr_sz;
50
75
@@ -XXX,XX +XXX,XX @@ static void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz)
51
static void grlib_apbuart_reset(DeviceState *d)
76
}
52
@@ -XXX,XX +XXX,XX @@ static Property grlib_apbuart_properties[] = {
77
53
static void grlib_apbuart_class_init(ObjectClass *klass, void *data)
78
/* Signed saturating rounding doubling multiply-accumulate high half, 16-bit */
54
{
79
-static uint16_t inl_qrdmlah_s16(CPUARMState *env, int16_t src1,
55
DeviceClass *dc = DEVICE_CLASS(klass);
80
- int16_t src2, int16_t src3)
56
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
81
+static int16_t inl_qrdmlah_s16(int16_t src1, int16_t src2,
57
82
+ int16_t src3, uint32_t *sat)
58
- k->init = grlib_apbuart_init;
83
{
59
+ dc->realize = grlib_apbuart_realize;
84
/* Simplify:
60
dc->reset = grlib_apbuart_reset;
85
* = ((a3 << 16) + ((e1 * e2) << 1) + (1 << 15)) >> 16
61
dc->props = grlib_apbuart_properties;
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
}
94
return ret;
95
@@ -XXX,XX +XXX,XX @@ static uint16_t inl_qrdmlah_s16(CPUARMState *env, int16_t src1,
96
uint32_t HELPER(neon_qrdmlah_s16)(CPUARMState *env, uint32_t src1,
97
uint32_t src2, uint32_t src3)
98
{
99
- uint16_t e1 = inl_qrdmlah_s16(env, src1, src2, src3);
100
- uint16_t e2 = inl_qrdmlah_s16(env, src1 >> 16, src2 >> 16, src3 >> 16);
101
+ uint32_t *sat = &env->vfp.qc[0];
102
+ uint16_t e1 = inl_qrdmlah_s16(src1, src2, src3, sat);
103
+ uint16_t e2 = inl_qrdmlah_s16(src1 >> 16, src2 >> 16, src3 >> 16, sat);
104
return deposit32(e1, 16, 16, e2);
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));
62
}
256
}
63
--
257
--
64
2.19.2
258
2.20.1
65
259
66
260
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use DeviceClass rather than SysBusDeviceClass in
3
Must clear the tail for AdvSIMD when SVE is enabled.
4
milkymist_hpdmc_class_init().
5
4
6
Cc: gxt@mprc.pku.edu.cn
5
Fixes: ca40a6e6e39
7
Cc: michael@walle.cc
6
Cc: qemu-stable@nongnu.org
8
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
9
Message-id: 20200513163245.17915-15-richard.henderson@linaro.org
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Message-id: 20181130093852.20739-12-maozhongyi@cmss.chinamobile.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
11
---
15
hw/misc/milkymist-hpdmc.c | 9 +++------
12
target/arm/vec_helper.c | 2 ++
16
1 file changed, 3 insertions(+), 6 deletions(-)
13
1 file changed, 2 insertions(+)
17
14
18
diff --git a/hw/misc/milkymist-hpdmc.c b/hw/misc/milkymist-hpdmc.c
15
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/misc/milkymist-hpdmc.c
17
--- a/target/arm/vec_helper.c
21
+++ b/hw/misc/milkymist-hpdmc.c
18
+++ b/target/arm/vec_helper.c
22
@@ -XXX,XX +XXX,XX @@ static void milkymist_hpdmc_reset(DeviceState *d)
19
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
23
| IODELAY_PLL2_LOCKED;
20
d[i + j] = TYPE##_mul(n[i + j], mm, stat); \
21
} \
22
} \
23
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
24
}
24
}
25
25
26
-static int milkymist_hpdmc_init(SysBusDevice *dev)
26
DO_MUL_IDX(gvec_fmul_idx_h, float16, H2)
27
+static void milkymist_hpdmc_realize(DeviceState *dev, Error **errp)
27
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, \
28
{
28
mm, a[i + j], 0, stat); \
29
MilkymistHpdmcState *s = MILKYMIST_HPDMC(dev);
29
} \
30
30
} \
31
memory_region_init_io(&s->regs_region, OBJECT(dev), &hpdmc_mmio_ops, s,
31
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
32
"milkymist-hpdmc", R_MAX * 4);
33
- sysbus_init_mmio(dev, &s->regs_region);
34
-
35
- return 0;
36
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->regs_region);
37
}
32
}
38
33
39
static const VMStateDescription vmstate_milkymist_hpdmc = {
34
DO_FMLA_IDX(gvec_fmla_idx_h, float16, H2)
40
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_milkymist_hpdmc = {
41
static void milkymist_hpdmc_class_init(ObjectClass *klass, void *data)
42
{
43
DeviceClass *dc = DEVICE_CLASS(klass);
44
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
45
46
- k->init = milkymist_hpdmc_init;
47
+ dc->realize = milkymist_hpdmc_realize;
48
dc->reset = milkymist_hpdmc_reset;
49
dc->vmsd = &vmstate_milkymist_hpdmc;
50
}
51
--
35
--
52
2.19.2
36
2.20.1
53
37
54
38
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 trivial implementation with zero limited ordering regions,
3
Include 64-bit element size in preparation for SVE2.
4
which causes the LDLAR and STLLR instructions to devolve into the
5
LDAR and STLR instructions from the base ARMv8.0 instruction set.
6
4
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20181210150501.7990-4-richard.henderson@linaro.org
7
Message-id: 20200513163245.17915-16-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/cpu.h | 5 +++
10
target/arm/helper.h | 10 +++
13
target/arm/cpu64.c | 1 +
11
target/arm/translate.h | 5 ++
14
target/arm/helper.c | 75 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate-a64.c | 8 ++-
15
target/arm/translate-a64.c | 12 ++++++
13
target/arm/translate.c | 133 ++++++++++++++++++++++++++++++++++++-
16
4 files changed, 93 insertions(+)
14
target/arm/vec_helper.c | 24 +++++++
17
15
5 files changed, 176 insertions(+), 4 deletions(-)
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
19
index XXXXXXX..XXXXXXX 100644
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
20
--- a/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
21
+++ b/target/arm/cpu.h
19
--- a/target/arm/helper.h
22
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
20
+++ b/target/arm/helper.h
23
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(gvec_sli_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
24
}
22
DEF_HELPER_FLAGS_3(gvec_sli_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
25
23
DEF_HELPER_FLAGS_3(gvec_sli_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
26
+static inline bool isar_feature_aa64_lor(const ARMISARegisters *id)
24
27
+{
25
+DEF_HELPER_FLAGS_4(gvec_sabd_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0;
26
+DEF_HELPER_FLAGS_4(gvec_sabd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
+}
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);
30
+
50
+
31
/*
51
/*
32
* Forward to the above feature tests given an ARMCPU pointer.
52
* Forward to the isar_feature_* tests given a DisasContext pointer.
33
*/
53
*/
34
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/cpu64.c
37
+++ b/target/arm/cpu64.c
38
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
39
40
t = cpu->isar.id_aa64mmfr1;
41
t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */
42
+ t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);
43
cpu->isar.id_aa64mmfr1 = t;
44
45
/* Replicate the same data to the 32-bit id registers. */
46
diff --git a/target/arm/helper.c b/target/arm/helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/helper.c
49
+++ b/target/arm/helper.c
50
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
51
{
52
/* Begin with base v8.0 state. */
53
uint32_t valid_mask = 0x3fff;
54
+ ARMCPU *cpu = arm_env_get_cpu(env);
55
56
if (arm_el_is_aa64(env, 3)) {
57
value |= SCR_FW | SCR_AW; /* these two bits are RES1. */
58
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
59
valid_mask &= ~SCR_SMD;
60
}
61
}
62
+ if (cpu_isar_feature(aa64_lor, cpu)) {
63
+ valid_mask |= SCR_TLOR;
64
+ }
65
66
/* Clear all-context RES0 bits. */
67
value &= valid_mask;
68
@@ -XXX,XX +XXX,XX @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
69
*/
70
valid_mask &= ~HCR_TSC;
71
}
72
+ if (cpu_isar_feature(aa64_lor, cpu)) {
73
+ valid_mask |= HCR_TLOR;
74
+ }
75
76
/* Clear RES0 bits. */
77
value &= valid_mask;
78
@@ -XXX,XX +XXX,XX @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
79
return pfr0;
80
}
81
82
+/* Shared logic between LORID and the rest of the LOR* registers.
83
+ * Secure state has already been delt with.
84
+ */
85
+static CPAccessResult access_lor_ns(CPUARMState *env)
86
+{
87
+ int el = arm_current_el(env);
88
+
89
+ if (el < 2 && (arm_hcr_el2_eff(env) & HCR_TLOR)) {
90
+ return CP_ACCESS_TRAP_EL2;
91
+ }
92
+ if (el < 3 && (env->cp15.scr_el3 & SCR_TLOR)) {
93
+ return CP_ACCESS_TRAP_EL3;
94
+ }
95
+ return CP_ACCESS_OK;
96
+}
97
+
98
+static CPAccessResult access_lorid(CPUARMState *env, const ARMCPRegInfo *ri,
99
+ bool isread)
100
+{
101
+ if (arm_is_secure_below_el3(env)) {
102
+ /* Access ok in secure mode. */
103
+ return CP_ACCESS_OK;
104
+ }
105
+ return access_lor_ns(env);
106
+}
107
+
108
+static CPAccessResult access_lor_other(CPUARMState *env,
109
+ const ARMCPRegInfo *ri, bool isread)
110
+{
111
+ if (arm_is_secure_below_el3(env)) {
112
+ /* Access denied in secure mode. */
113
+ return CP_ACCESS_TRAP;
114
+ }
115
+ return access_lor_ns(env);
116
+}
117
+
118
void register_cp_regs_for_features(ARMCPU *cpu)
119
{
120
/* Register all the coprocessor registers based on feature bits */
121
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
122
define_one_arm_cp_reg(cpu, &sctlr);
123
}
124
125
+ if (cpu_isar_feature(aa64_lor, cpu)) {
126
+ /*
127
+ * A trivial implementation of ARMv8.1-LOR leaves all of these
128
+ * registers fixed at 0, which indicates that there are zero
129
+ * supported Limited Ordering regions.
130
+ */
131
+ static const ARMCPRegInfo lor_reginfo[] = {
132
+ { .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64,
133
+ .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0,
134
+ .access = PL1_RW, .accessfn = access_lor_other,
135
+ .type = ARM_CP_CONST, .resetvalue = 0 },
136
+ { .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64,
137
+ .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1,
138
+ .access = PL1_RW, .accessfn = access_lor_other,
139
+ .type = ARM_CP_CONST, .resetvalue = 0 },
140
+ { .name = "LORN_EL1", .state = ARM_CP_STATE_AA64,
141
+ .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2,
142
+ .access = PL1_RW, .accessfn = access_lor_other,
143
+ .type = ARM_CP_CONST, .resetvalue = 0 },
144
+ { .name = "LORC_EL1", .state = ARM_CP_STATE_AA64,
145
+ .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3,
146
+ .access = PL1_RW, .accessfn = access_lor_other,
147
+ .type = ARM_CP_CONST, .resetvalue = 0 },
148
+ { .name = "LORID_EL1", .state = ARM_CP_STATE_AA64,
149
+ .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7,
150
+ .access = PL1_R, .accessfn = access_lorid,
151
+ .type = ARM_CP_CONST, .resetvalue = 0 },
152
+ REGINFO_SENTINEL
153
+ };
154
+ define_arm_cp_regs(cpu, lor_reginfo);
155
+ }
156
+
157
if (cpu_isar_feature(aa64_sve, cpu)) {
158
define_one_arm_cp_reg(cpu, &zcr_el1_reginfo);
159
if (arm_feature(env, ARM_FEATURE_EL2)) {
160
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
54
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
161
index XXXXXXX..XXXXXXX 100644
55
index XXXXXXX..XXXXXXX 100644
162
--- a/target/arm/translate-a64.c
56
--- a/target/arm/translate-a64.c
163
+++ b/target/arm/translate-a64.c
57
+++ b/target/arm/translate-a64.c
164
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
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);
165
}
60
}
166
return;
61
return;
167
62
+ case 0xe: /* SABD, UABD */
168
+ case 0x8: /* STLLR */
63
+ if (u) {
169
+ if (!dc_isar_feature(aa64_lor, s)) {
64
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uabd, size);
170
+ break;
65
+ } else {
66
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sabd, size);
171
+ }
67
+ }
172
+ /* StoreLORelease is the same as Store-Release for QEMU. */
68
+ return;
173
+ /* fall through */
69
case 0x10: /* ADD, SUB */
174
case 0x9: /* STLR */
70
if (u) {
175
/* Generate ISS for non-exclusive accesses including LASR. */
71
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_sub, size);
176
if (rn == 31) {
72
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
177
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
73
genenvfn = fns[size][u];
178
disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
74
break;
179
return;
75
}
180
76
- case 0xe: /* SABD, UABD */
181
+ case 0xc: /* LDLAR */
77
case 0xf: /* SABA, UABA */
182
+ if (!dc_isar_feature(aa64_lor, s)) {
78
{
183
+ break;
79
static NeonGenTwoOpFn * const fns[3][2] = {
184
+ }
80
diff --git a/target/arm/translate.c b/target/arm/translate.c
185
+ /* LoadLOAcquire is the same as Load-Acquire for QEMU. */
81
index XXXXXXX..XXXXXXX 100644
186
+ /* fall through */
82
--- a/target/arm/translate.c
187
case 0xd: /* LDAR */
83
+++ b/target/arm/translate.c
188
/* Generate ISS for non-exclusive accesses including LASR. */
84
@@ -XXX,XX +XXX,XX @@ void gen_gvec_sqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
189
if (rn == 31) {
85
rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
86
}
87
88
+static void gen_sabd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
89
+{
90
+ TCGv_i32 t = tcg_temp_new_i32();
91
+
92
+ tcg_gen_sub_i32(t, a, b);
93
+ tcg_gen_sub_i32(d, b, a);
94
+ tcg_gen_movcond_i32(TCG_COND_LT, d, a, b, d, t);
95
+ tcg_temp_free_i32(t);
96
+}
97
+
98
+static void gen_sabd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
99
+{
100
+ TCGv_i64 t = tcg_temp_new_i64();
101
+
102
+ tcg_gen_sub_i64(t, a, b);
103
+ tcg_gen_sub_i64(d, b, a);
104
+ tcg_gen_movcond_i64(TCG_COND_LT, d, a, b, d, t);
105
+ tcg_temp_free_i64(t);
106
+}
107
+
108
+static void gen_sabd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
109
+{
110
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
111
+
112
+ tcg_gen_smin_vec(vece, t, a, b);
113
+ tcg_gen_smax_vec(vece, d, a, b);
114
+ tcg_gen_sub_vec(vece, d, d, t);
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
190
--
270
--
191
2.19.2
271
2.20.1
192
272
193
273
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Post v8.3 bits taken from SysReg_v85_xml-00bet8.
3
Include 64-bit element size in preparation for SVE2.
4
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20181203203839.757-3-richard.henderson@linaro.org
7
Message-id: 20200513163245.17915-17-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@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/cpu.h | 22 +++++++++++++++++++++-
10
target/arm/helper.h | 17 +++--
11
1 file changed, 21 insertions(+), 1 deletion(-)
11
target/arm/translate.h | 5 ++
12
12
target/arm/neon_helper.c | 10 ---
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
target/arm/translate-a64.c | 17 ++---
14
index XXXXXXX..XXXXXXX 100644
14
target/arm/translate.c | 134 +++++++++++++++++++++++++++++++++++--
15
--- a/target/arm/cpu.h
15
target/arm/vec_helper.c | 24 +++++++
16
+++ b/target/arm/cpu.h
16
6 files changed, 174 insertions(+), 33 deletions(-)
17
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
17
18
#define HCR_TIDCP (1ULL << 20)
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
19
#define HCR_TACR (1ULL << 21)
19
index XXXXXXX..XXXXXXX 100644
20
#define HCR_TSW (1ULL << 22)
20
--- a/target/arm/helper.h
21
-#define HCR_TPC (1ULL << 23)
21
+++ b/target/arm/helper.h
22
+#define HCR_TPCP (1ULL << 23)
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(neon_pmax_s8, i32, i32, i32)
23
#define HCR_TPU (1ULL << 24)
23
DEF_HELPER_2(neon_pmax_u16, i32, i32, i32)
24
#define HCR_TTLB (1ULL << 25)
24
DEF_HELPER_2(neon_pmax_s16, i32, i32, i32)
25
#define HCR_TVM (1ULL << 26)
25
26
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
26
-DEF_HELPER_2(neon_abd_u8, i32, i32, i32)
27
#define HCR_CD (1ULL << 32)
27
-DEF_HELPER_2(neon_abd_s8, i32, i32, i32)
28
#define HCR_ID (1ULL << 33)
28
-DEF_HELPER_2(neon_abd_u16, i32, i32, i32)
29
#define HCR_E2H (1ULL << 34)
29
-DEF_HELPER_2(neon_abd_s16, i32, i32, i32)
30
+#define HCR_TLOR (1ULL << 35)
30
-DEF_HELPER_2(neon_abd_u32, i32, i32, i32)
31
+#define HCR_TERR (1ULL << 36)
31
-DEF_HELPER_2(neon_abd_s32, i32, i32, i32)
32
+#define HCR_TEA (1ULL << 37)
32
-
33
+#define HCR_MIOCNCE (1ULL << 38)
33
DEF_HELPER_2(neon_shl_u16, i32, i32, i32)
34
+#define HCR_APK (1ULL << 40)
34
DEF_HELPER_2(neon_shl_s16, i32, i32, i32)
35
+#define HCR_API (1ULL << 41)
35
DEF_HELPER_2(neon_rshl_u8, i32, i32, i32)
36
+#define HCR_NV (1ULL << 42)
36
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_uabd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
37
+#define HCR_NV1 (1ULL << 43)
37
DEF_HELPER_FLAGS_4(gvec_uabd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
38
+#define HCR_AT (1ULL << 44)
38
DEF_HELPER_FLAGS_4(gvec_uabd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
39
+#define HCR_NV2 (1ULL << 45)
39
40
+#define HCR_FWB (1ULL << 46)
40
+DEF_HELPER_FLAGS_4(gvec_saba_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
41
+#define HCR_FIEN (1ULL << 47)
41
+DEF_HELPER_FLAGS_4(gvec_saba_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
42
+#define HCR_TID4 (1ULL << 49)
42
+DEF_HELPER_FLAGS_4(gvec_saba_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
43
+#define HCR_TICAB (1ULL << 50)
43
+DEF_HELPER_FLAGS_4(gvec_saba_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
44
+#define HCR_TOCU (1ULL << 52)
44
+
45
+#define HCR_TTLBIS (1ULL << 54)
45
+DEF_HELPER_FLAGS_4(gvec_uaba_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
46
+#define HCR_TTLBOS (1ULL << 55)
46
+DEF_HELPER_FLAGS_4(gvec_uaba_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
47
+#define HCR_ATA (1ULL << 56)
47
+DEF_HELPER_FLAGS_4(gvec_uaba_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
48
+#define HCR_DCT (1ULL << 57)
48
+DEF_HELPER_FLAGS_4(gvec_uaba_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
49
+
50
#ifdef TARGET_AARCH64
51
#include "helper-a64.h"
52
#include "helper-sve.h"
53
diff --git a/target/arm/translate.h b/target/arm/translate.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/translate.h
56
+++ b/target/arm/translate.h
57
@@ -XXX,XX +XXX,XX @@ void gen_gvec_sabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
58
void gen_gvec_uabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
59
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
60
61
+void gen_gvec_saba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
62
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
63
+void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
64
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
49
+
65
+
50
/*
66
/*
51
* When we actually implement ARMv8.1-VHE we should add HCR_E2H to
67
* Forward to the isar_feature_* tests given a DisasContext pointer.
52
* HCR_MASK and then clear it again if the feature bit is not set in
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
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/translate-a64.c
93
+++ b/target/arm/translate-a64.c
94
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
95
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sabd, size);
96
}
97
return;
98
+ case 0xf: /* SABA, UABA */
99
+ if (u) {
100
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uaba, size);
101
+ } else {
102
+ gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_saba, size);
103
+ }
104
+ return;
105
case 0x10: /* ADD, SUB */
106
if (u) {
107
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_sub, size);
108
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
109
genenvfn = fns[size][u];
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
126
index XXXXXXX..XXXXXXX 100644
127
--- a/target/arm/translate.c
128
+++ b/target/arm/translate.c
129
@@ -XXX,XX +XXX,XX @@ void gen_gvec_uabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
130
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
131
}
132
133
+static void gen_saba_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
134
+{
135
+ TCGv_i32 t = tcg_temp_new_i32();
136
+ gen_sabd_i32(t, a, b);
137
+ tcg_gen_add_i32(d, d, t);
138
+ tcg_temp_free_i32(t);
139
+}
140
+
141
+static void gen_saba_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
142
+{
143
+ TCGv_i64 t = tcg_temp_new_i64();
144
+ gen_sabd_i64(t, a, b);
145
+ tcg_gen_add_i64(d, d, t);
146
+ tcg_temp_free_i64(t);
147
+}
148
+
149
+static void gen_saba_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
150
+{
151
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
152
+ gen_sabd_vec(vece, t, a, b);
153
+ tcg_gen_add_vec(vece, d, d, t);
154
+ tcg_temp_free_vec(t);
155
+}
156
+
157
+void gen_gvec_saba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
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
53
--
316
--
54
2.19.2
317
2.20.1
55
318
56
319
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
From: Patrick Williams <patrick@stwcx.xyz>
2
2
3
The init function doesn't do anything at all, so we
3
Sonora Pass is a 2 socket x86 motherboard designed by Facebook
4
just omit it.
4
and supported by OpenBMC. Strapping configuration was obtained
5
from hardware and i2c configuration is based on dts found at:
5
6
6
Cc: sstabellini@kernel.org
7
https://github.com/facebook/openbmc-linux/blob/1633c87b8ba7c162095787c988979b748ba65dc8/arch/arm/boot/dts/aspeed-bmc-facebook-sonorapass.dts
7
Cc: anthony.perard@citrix.com
8
Cc: xen-devel@lists.xenproject.org
9
Cc: peter.maydell@linaro.org
10
8
11
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
9
Booted a test image of http://github.com/facebook/openbmc to login
12
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
10
prompt.
13
Acked-by: Anthony PERARD <anthony.perard@citrix.com>
11
14
Message-id: 20181130093852.20739-21-maozhongyi@cmss.chinamobile.com
12
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
13
Reviewed-by: Amithash Prasad <amithash@fb.com>
14
Reviewed-by: Cédric Le Goater <clg@kaod.org>
15
[PMM: fixed block comment style nit]
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
---
17
hw/xen/xen_backend.c | 7 -------
18
hw/arm/aspeed.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++
18
1 file changed, 7 deletions(-)
19
1 file changed, 78 insertions(+)
19
20
20
diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c
21
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
21
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/xen/xen_backend.c
23
--- a/hw/arm/aspeed.c
23
+++ b/hw/xen/xen_backend.c
24
+++ b/hw/arm/aspeed.c
24
@@ -XXX,XX +XXX,XX @@ static const TypeInfo xensysbus_info = {
25
@@ -XXX,XX +XXX,XX @@ struct AspeedBoardState {
25
}
26
SCU_AST2500_HW_STRAP_ACPI_ENABLE | \
27
SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER))
28
29
+/* Sonorapass hardware value: 0xF100D216 */
30
+#define SONORAPASS_BMC_HW_STRAP1 ( \
31
+ SCU_AST2500_HW_STRAP_SPI_AUTOFETCH_ENABLE | \
32
+ SCU_AST2500_HW_STRAP_GPIO_STRAP_ENABLE | \
33
+ SCU_AST2500_HW_STRAP_UART_DEBUG | \
34
+ SCU_AST2500_HW_STRAP_RESERVED28 | \
35
+ SCU_AST2500_HW_STRAP_DDR4_ENABLE | \
36
+ SCU_HW_STRAP_VGA_CLASS_CODE | \
37
+ SCU_HW_STRAP_LPC_RESET_PIN | \
38
+ SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER) | \
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
+
85
+ /*
86
+ * bus 13 : pca9548 @ 0x71
87
+ * - channel 3:
88
+ * - tmm421 @ 0x4c
89
+ * - tmp421 @ 0x4e
90
+ * - tmp421 @ 0x4f
91
+ */
92
+
93
+}
94
+
95
static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
96
{
97
AspeedSoCState *soc = &bmc->soc;
98
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_romulus_class_init(ObjectClass *oc, void *data)
99
mc->default_ram_size = 512 * MiB;
26
};
100
};
27
101
28
-static int xen_sysdev_init(SysBusDevice *dev)
102
+static void aspeed_machine_sonorapass_class_init(ObjectClass *oc, void *data)
29
-{
103
+{
30
- return 0;
104
+ MachineClass *mc = MACHINE_CLASS(oc);
31
-}
105
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
32
-
106
+
33
static Property xen_sysdev_properties[] = {
107
+ mc->desc = "OCP SonoraPass BMC (ARM1176)";
34
{/* end of property list */},
108
+ amc->soc_name = "ast2500-a1";
35
};
109
+ amc->hw_strap1 = SONORAPASS_BMC_HW_STRAP1;
36
@@ -XXX,XX +XXX,XX @@ static Property xen_sysdev_properties[] = {
110
+ amc->fmc_model = "mx66l1g45g";
37
static void xen_sysdev_class_init(ObjectClass *klass, void *data)
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)
38
{
118
{
39
DeviceClass *dc = DEVICE_CLASS(klass);
119
MachineClass *mc = MACHINE_CLASS(oc);
40
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
120
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_machine_types[] = {
41
121
.name = MACHINE_TYPE_NAME("swift-bmc"),
42
- k->init = xen_sysdev_init;
122
.parent = TYPE_ASPEED_MACHINE,
43
dc->props = xen_sysdev_properties;
123
.class_init = aspeed_machine_swift_class_init,
44
dc->bus_type = TYPE_XENSYSBUS;
124
+ }, {
45
}
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,
46
--
131
--
47
2.19.2
132
2.20.1
48
133
49
134
diff view generated by jsdifflib
1
From: Li Qiang <liq3ea@gmail.com>
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
2
2
3
The third argument of object_property_set_link() is the name of
3
The little end UUID is used in many places, so make
4
property, not related with the QOM type name, using the constant
4
NVDIMM_UUID_LE to a common macro to convert the UUID
5
string instead.
5
to a little end array.
6
6
7
Signed-off-by: Li Qiang <liq3ea@gmail.com>
7
Reviewed-by: Xiang Zheng <zhengxiang9@huawei.com>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
9
Message-id: 1542880825-2604-1-git-send-email-liq3ea@gmail.com
9
Message-id: 20200512030609.19593-2-gengdongjiu@huawei.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
hw/arm/musicpal.c | 2 +-
13
include/qemu/uuid.h | 27 +++++++++++++++++++++++++++
14
1 file changed, 1 insertion(+), 1 deletion(-)
14
hw/acpi/nvdimm.c | 10 +++-------
15
2 files changed, 30 insertions(+), 7 deletions(-)
15
16
16
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
17
diff --git a/include/qemu/uuid.h b/include/qemu/uuid.h
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/musicpal.c
19
--- a/include/qemu/uuid.h
19
+++ b/hw/arm/musicpal.c
20
+++ b/include/qemu/uuid.h
20
@@ -XXX,XX +XXX,XX @@ static void musicpal_init(MachineState *machine)
21
@@ -XXX,XX +XXX,XX @@ typedef struct {
21
dev = qdev_create(NULL, TYPE_MV88W8618_AUDIO);
22
};
22
s = SYS_BUS_DEVICE(dev);
23
} QemuUUID;
23
object_property_set_link(OBJECT(dev), OBJECT(wm8750_dev),
24
24
- TYPE_WM8750, NULL);
25
+/**
25
+ "wm8750", NULL);
26
+ * UUID_LE - converts the fields of UUID to little-endian array,
26
qdev_init_nofail(dev);
27
+ * each of parameters is the filed of UUID.
27
sysbus_mmio_map(s, 0, MP_AUDIO_BASE);
28
+ *
28
sysbus_connect_irq(s, 0, pic[MP_AUDIO_IRQ]);
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 @@
60
*/
61
62
#include "qemu/osdep.h"
63
+#include "qemu/uuid.h"
64
#include "hw/acpi/acpi.h"
65
#include "hw/acpi/aml-build.h"
66
#include "hw/acpi/bios-linker-loader.h"
67
@@ -XXX,XX +XXX,XX @@
68
#include "hw/mem/nvdimm.h"
69
#include "qemu/nvdimm-utils.h"
70
71
-#define NVDIMM_UUID_LE(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
72
- { (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
73
- (b) & 0xff, ((b) >> 8) & 0xff, (c) & 0xff, ((c) >> 8) & 0xff, \
74
- (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }
75
-
76
/*
77
* define Byte Addressable Persistent Memory (PM) Region according to
78
* ACPI 6.0: 5.2.25.1 System Physical Address Range Structure.
79
*/
80
static const uint8_t nvdimm_nfit_spa_uuid[] =
81
- NVDIMM_UUID_LE(0x66f0d379, 0xb4f3, 0x4074, 0xac, 0x43, 0x0d, 0x33,
82
- 0x18, 0xb7, 0x8c, 0xdb);
83
+ UUID_LE(0x66f0d379, 0xb4f3, 0x4074, 0xac, 0x43, 0x0d, 0x33,
84
+ 0x18, 0xb7, 0x8c, 0xdb);
85
86
/*
87
* NVDIMM Firmware Interface Table
29
--
88
--
30
2.19.2
89
2.20.1
31
90
32
91
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
2
2
3
Reduce number of virtio-mmio instances. This is in preparation
3
RAS Virtualization feature is not supported now, so
4
for correcting the interrupt setup for Versal.
4
add a RAS machine option and disable it by default.
5
5
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
8
Message-id: 20181129163655.20370-3-edgar.iglesias@gmail.com
8
Signed-off-by: Xiang Zheng <zhengxiang9@huawei.com>
9
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
10
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
11
Message-id: 20200512030609.19593-3-gengdongjiu@huawei.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
hw/arm/xlnx-versal-virt.c | 2 +-
14
include/hw/arm/virt.h | 1 +
12
1 file changed, 1 insertion(+), 1 deletion(-)
15
hw/arm/virt.c | 23 +++++++++++++++++++++++
16
2 files changed, 24 insertions(+)
13
17
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
18
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
20
--- a/include/hw/arm/virt.h
17
+++ b/hw/arm/xlnx-versal-virt.c
21
+++ b/include/hw/arm/virt.h
18
@@ -XXX,XX +XXX,XX @@ static void *versal_virt_get_dtb(const struct arm_boot_info *binfo,
22
@@ -XXX,XX +XXX,XX @@ typedef struct {
19
return board->fdt;
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
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/arm/virt.c
33
+++ b/hw/arm/virt.c
34
@@ -XXX,XX +XXX,XX @@ static void virt_set_acpi(Object *obj, Visitor *v, const char *name,
35
visit_type_OnOffAuto(v, name, &vms->acpi, errp);
20
}
36
}
21
37
22
-#define NUM_VIRTIO_TRANSPORT 32
38
+static bool virt_get_ras(Object *obj, Error **errp)
23
+#define NUM_VIRTIO_TRANSPORT 8
39
+{
24
static void create_virtio_regions(VersalVirt *s)
40
+ VirtMachineState *vms = VIRT_MACHINE(obj);
41
+
42
+ return vms->ras;
43
+}
44
+
45
+static void virt_set_ras(Object *obj, bool value, Error **errp)
46
+{
47
+ VirtMachineState *vms = VIRT_MACHINE(obj);
48
+
49
+ vms->ras = value;
50
+}
51
+
52
static char *virt_get_gic_version(Object *obj, Error **errp)
25
{
53
{
26
int virtio_mmio_size = 0x200;
54
VirtMachineState *vms = VIRT_MACHINE(obj);
55
@@ -XXX,XX +XXX,XX @@ static void virt_instance_init(Object *obj)
56
"Valid values are none and smmuv3",
57
NULL);
58
59
+ /* Default disallows RAS instantiation */
60
+ vms->ras = false;
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);
27
--
71
--
28
2.19.2
72
2.20.1
29
73
30
74
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
2
2
3
Correct the nr of IRQs to 192.
3
Add APEI/GHES detailed design document
4
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Signed-off-by: Xiang Zheng <zhengxiang9@huawei.com>
7
Message-id: 20181129163655.20370-5-edgar.iglesias@gmail.com
7
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
8
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
9
Message-id: 20200512030609.19593-4-gengdongjiu@huawei.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
include/hw/arm/xlnx-versal.h | 2 +-
12
docs/specs/acpi_hest_ghes.rst | 110 ++++++++++++++++++++++++++++++++++
11
1 file changed, 1 insertion(+), 1 deletion(-)
13
docs/specs/index.rst | 1 +
14
2 files changed, 111 insertions(+)
15
create mode 100644 docs/specs/acpi_hest_ghes.rst
12
16
13
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
17
diff --git a/docs/specs/acpi_hest_ghes.rst b/docs/specs/acpi_hest_ghes.rst
18
new file mode 100644
19
index XXXXXXX..XXXXXXX
20
--- /dev/null
21
+++ b/docs/specs/acpi_hest_ghes.rst
22
@@ -XXX,XX +XXX,XX @@
23
+APEI tables generating and CPER record
24
+======================================
25
+
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
14
index XXXXXXX..XXXXXXX 100644
134
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/xlnx-versal.h
135
--- a/docs/specs/index.rst
16
+++ b/include/hw/arm/xlnx-versal.h
136
+++ b/docs/specs/index.rst
17
@@ -XXX,XX +XXX,XX @@
137
@@ -XXX,XX +XXX,XX @@ Contents:
18
#define XLNX_VERSAL_NR_ACPUS 2
138
ppc-spapr-xive
19
#define XLNX_VERSAL_NR_UARTS 2
139
acpi_hw_reduced_hotplug
20
#define XLNX_VERSAL_NR_GEMS 2
140
tpm
21
-#define XLNX_VERSAL_NR_IRQS 256
141
+ acpi_hest_ghes
22
+#define XLNX_VERSAL_NR_IRQS 192
23
24
typedef struct Versal {
25
/*< private >*/
26
--
142
--
27
2.19.2
143
2.20.1
28
144
29
145
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
2
2
3
Use DeviceClass rather than SysBusDeviceClass in
3
This patch builds error_block_address and read_ack_register fields
4
tusb6010_class_init().
4
in hardware errors table , the error_block_address points to Generic
5
5
Error Status Block(GESB) via bios_linker. The max size for one GESB
6
Cc: kraxel@redhat.com
6
is 1kb, For more detailed information, please refer to
7
7
document: docs/specs/acpi_hest_ghes.rst
8
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
8
9
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
9
Now we only support one Error source, if necessary, we can extend to
10
Message-id: 20181130093852.20739-20-maozhongyi@cmss.chinamobile.com
10
support more.
11
12
Suggested-by: Laszlo Ersek <lersek@redhat.com>
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
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
20
---
13
hw/usb/tusb6010.c | 8 +++-----
21
default-configs/arm-softmmu.mak | 1 +
14
1 file changed, 3 insertions(+), 5 deletions(-)
22
include/hw/acpi/aml-build.h | 1 +
15
23
include/hw/acpi/ghes.h | 28 +++++++++++
16
diff --git a/hw/usb/tusb6010.c b/hw/usb/tusb6010.c
24
hw/acpi/aml-build.c | 2 +
17
index XXXXXXX..XXXXXXX 100644
25
hw/acpi/ghes.c | 89 +++++++++++++++++++++++++++++++++
18
--- a/hw/usb/tusb6010.c
26
hw/arm/virt-acpi-build.c | 5 ++
19
+++ b/hw/usb/tusb6010.c
27
hw/acpi/Kconfig | 4 ++
20
@@ -XXX,XX +XXX,XX @@ static void tusb6010_reset(DeviceState *dev)
28
hw/acpi/Makefile.objs | 1 +
21
musb_reset(s->musb);
29
8 files changed, 131 insertions(+)
30
create mode 100644 include/hw/acpi/ghes.h
31
create mode 100644 hw/acpi/ghes.c
32
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();
22
}
98
}
23
99
24
-static int tusb6010_init(SysBusDevice *sbd)
100
@@ -XXX,XX +XXX,XX @@ void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
25
+static void tusb6010_realize(DeviceState *dev, Error **errp)
101
g_array_free(tables->table_data, true);
26
{
102
g_array_free(tables->tcpalog, mfre);
27
- DeviceState *dev = DEVICE(sbd);
103
g_array_free(tables->vmgenid, mfre);
28
TUSBState *s = TUSB(dev);
104
+ g_array_free(tables->hardware_errors, mfre);
29
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
30
31
s->otg_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tusb_otg_tick, s);
32
s->pwr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tusb_power_tick, s);
33
@@ -XXX,XX +XXX,XX @@ static int tusb6010_init(SysBusDevice *sbd)
34
sysbus_init_irq(sbd, &s->irq);
35
qdev_init_gpio_in(dev, tusb6010_irq, musb_irq_max + 1);
36
s->musb = musb_init(dev, 1);
37
- return 0;
38
}
105
}
39
106
40
static void tusb6010_class_init(ObjectClass *klass, void *data)
107
/*
41
{
108
diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
42
DeviceClass *dc = DEVICE_CLASS(klass);
109
new file mode 100644
43
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
110
index XXXXXXX..XXXXXXX
44
111
--- /dev/null
45
- k->init = tusb6010_init;
112
+++ b/hw/acpi/ghes.c
46
+ dc->realize = tusb6010_realize;
113
@@ -XXX,XX +XXX,XX @@
47
dc->reset = tusb6010_reset;
114
+/*
48
}
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
204
index XXXXXXX..XXXXXXX 100644
205
--- a/hw/arm/virt-acpi-build.c
206
+++ b/hw/arm/virt-acpi-build.c
207
@@ -XXX,XX +XXX,XX @@
208
#include "sysemu/reset.h"
209
#include "kvm_arm.h"
210
#include "migration/vmstate.h"
211
+#include "hw/acpi/ghes.h"
212
213
#define ARM_SPI_BASE 32
214
215
@@ -XXX,XX +XXX,XX @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
216
acpi_add_table(table_offsets, tables_blob);
217
build_spcr(tables_blob, tables->linker, vms);
218
219
+ if (vms->ras) {
220
+ build_ghes_error_table(tables->hardware_errors, tables->linker);
221
+ }
222
+
223
if (ms->numa_state->num_nodes > 0) {
224
acpi_add_table(table_offsets, tables_blob);
225
build_srat(tables_blob, tables->linker, vms);
226
diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig
227
index XXXXXXX..XXXXXXX 100644
228
--- a/hw/acpi/Kconfig
229
+++ b/hw/acpi/Kconfig
230
@@ -XXX,XX +XXX,XX @@ config ACPI_HMAT
231
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
49
252
50
--
253
--
51
2.19.2
254
2.20.1
52
255
53
256
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
2
2
3
Use DeviceClass rather than SysBusDeviceClass in
3
This patch builds Hardware Error Source Table(HEST) via fw_cfg blobs.
4
nvram_sysbus_class_init().
4
Now it only supports ARMv8 SEA, a type of Generic Hardware Error
5
5
Source version 2(GHESv2) error source. Afterwards, we can extend
6
Cc: pbonzini@redhat.com
6
the supported types if needed. For the CPER section, currently it
7
Cc: marcandre.lureau@redhat.com
7
is memory section because kernel mainly wants userspace to handle
8
8
the memory errors.
9
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
9
10
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
10
This patch follows the spec ACPI 6.2 to build the Hardware Error
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Source table. For more detailed information, please refer to
12
Message-id: 20181130093852.20739-15-maozhongyi@cmss.chinamobile.com
12
document: docs/specs/acpi_hest_ghes.rst
13
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
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
24
---
15
hw/nvram/ds1225y.c | 12 +++++-------
25
include/hw/acpi/ghes.h | 39 ++++++++++++
16
1 file changed, 5 insertions(+), 7 deletions(-)
26
hw/acpi/ghes.c | 126 +++++++++++++++++++++++++++++++++++++++
17
27
hw/arm/virt-acpi-build.c | 2 +
18
diff --git a/hw/nvram/ds1225y.c b/hw/nvram/ds1225y.c
28
3 files changed, 167 insertions(+)
29
30
diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h
19
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/nvram/ds1225y.c
32
--- a/include/hw/acpi/ghes.h
21
+++ b/hw/nvram/ds1225y.c
33
+++ b/include/hw/acpi/ghes.h
22
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@
23
#include "qemu/osdep.h"
35
24
#include "hw/sysbus.h"
36
#include "hw/acpi/bios-linker-loader.h"
25
#include "trace.h"
37
38
+/*
39
+ * Values for Hardware Error Notification Type field
40
+ */
41
+enum AcpiGhesNotifyType {
42
+ /* Polled */
43
+ ACPI_GHES_NOTIFY_POLLED = 0,
44
+ /* External Interrupt */
45
+ ACPI_GHES_NOTIFY_EXTERNAL = 1,
46
+ /* Local Interrupt */
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"
26
+#include "qemu/error-report.h"
87
+#include "qemu/error-report.h"
27
88
28
typedef struct {
89
#define ACPI_GHES_ERRORS_FW_CFG_FILE "etc/hardware_errors"
29
MemoryRegion iomem;
90
#define ACPI_GHES_DATA_ADDR_FW_CFG_FILE "etc/hardware_errors_addr"
30
@@ -XXX,XX +XXX,XX @@ typedef struct {
91
@@ -XXX,XX +XXX,XX @@
31
NvRamState nvram;
92
/* Now only support ARMv8 SEA notification type error source */
32
} SysBusNvRamState;
93
#define ACPI_GHES_ERROR_SOURCE_COUNT 1
33
94
34
-static int nvram_sysbus_initfn(SysBusDevice *dev)
95
+/* Generic Hardware Error Source version 2 */
35
+static void nvram_sysbus_realize(DeviceState *dev, Error **errp)
96
+#define ACPI_GHES_SOURCE_GENERIC_ERROR_V2 10
36
{
97
+
37
SysBusNvRamState *sys = DS1225Y(dev);
98
+/* Address offset in Generic Address Structure(GAS) */
38
NvRamState *s = &sys->nvram;
99
+#define GAS_ADDR_OFFSET 4
39
@@ -XXX,XX +XXX,XX @@ static int nvram_sysbus_initfn(SysBusDevice *dev)
100
+
40
101
+/*
41
memory_region_init_io(&s->iomem, OBJECT(s), &nvram_ops, s,
102
+ * Hardware Error Notification
42
"nvram", s->chip_size);
103
+ * ACPI 4.0: 17.3.2.7 Hardware Error Notification
43
- sysbus_init_mmio(dev, &s->iomem);
104
+ * Composes dummy Hardware Error Notification descriptor of specified type
44
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
105
+ */
45
106
+static void build_ghes_hw_error_notification(GArray *table, const uint8_t type)
46
/* Read current file */
107
+{
47
file = s->filename ? fopen(s->filename, "rb") : NULL;
108
+ /* Type */
48
if (file) {
109
+ build_append_int_noprefix(table, type, 1);
49
/* Read nvram contents */
110
+ /*
50
if (fread(s->contents, s->chip_size, 1, file) != 1) {
111
+ * Length:
51
- printf("nvram_sysbus_initfn: short read\n");
112
+ * Total length of the structure in bytes
52
+ error_report("nvram_sysbus_realize: short read");
113
+ */
53
}
114
+ build_append_int_noprefix(table, 28, 1);
54
fclose(file);
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);
55
}
237
}
56
nvram_post_load(s, 0);
238
57
-
239
if (ms->numa_state->num_nodes > 0) {
58
- return 0;
59
}
60
61
static Property nvram_sysbus_properties[] = {
62
@@ -XXX,XX +XXX,XX @@ static Property nvram_sysbus_properties[] = {
63
static void nvram_sysbus_class_init(ObjectClass *klass, void *data)
64
{
65
DeviceClass *dc = DEVICE_CLASS(klass);
66
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
67
68
- k->init = nvram_sysbus_initfn;
69
+ dc->realize = nvram_sysbus_realize;
70
dc->vmsd = &vmstate_nvram;
71
dc->props = nvram_sysbus_properties;
72
}
73
--
240
--
74
2.19.2
241
2.20.1
75
242
76
243
diff view generated by jsdifflib
1
From: Ricardo Perez Blanco <ricardo.perez_blanco@nokia.com>
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
2
2
3
Architecturally, it's possible for an AArch64 machine to have
3
Record the GHEB address via fw_cfg file, when recording
4
all of its RAM over the 4GB mark, but our kernel/initrd loading
4
a error to CPER, it will use this address to find out
5
code in boot.c assumes that the upper half of the addresses
5
Generic Error Data Entries and write the error.
6
to load these images to is always zero. Write the whole 64 bit
7
address into the bootloader code fragment, not just the low half.
8
6
9
Note that, currently, none of the existing QEMU machines have
7
In order to avoid migration failure, make hardware
10
their main memory over 4GBs, so this was not a user-visible bug.
8
error table address to a part of GED device instead
9
of global variable, then this address will be migrated
10
to target QEMU.
11
11
12
Signed-off-by: Ricardo Perez Blanco <ricardo.perez_blanco@nokia.com>
12
Acked-by: Xiang Zheng <zhengxiang9@huawei.com>
13
[PMM: revised commit message and tweaked some long lines]
13
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
18
---
17
hw/arm/boot.c | 35 ++++++++++++++++++++++-------------
19
include/hw/acpi/generic_event_device.h | 2 ++
18
1 file changed, 22 insertions(+), 13 deletions(-)
20
include/hw/acpi/ghes.h | 6 ++++++
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(+)
19
25
20
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
26
diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h
21
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/boot.c
28
--- a/include/hw/acpi/generic_event_device.h
23
+++ b/hw/arm/boot.c
29
+++ b/include/hw/acpi/generic_event_device.h
24
@@ -XXX,XX +XXX,XX @@ typedef enum {
30
@@ -XXX,XX +XXX,XX @@
25
FIXUP_TERMINATOR, /* end of insns */
31
26
FIXUP_BOARDID, /* overwrite with board ID number */
32
#include "hw/sysbus.h"
27
FIXUP_BOARD_SETUP, /* overwrite with board specific setup code address */
33
#include "hw/acpi/memory_hotplug.h"
28
- FIXUP_ARGPTR, /* overwrite with pointer to kernel args */
34
+#include "hw/acpi/ghes.h"
29
- FIXUP_ENTRYPOINT, /* overwrite with kernel entry point */
35
30
+ FIXUP_ARGPTR_LO, /* overwrite with pointer to kernel args */
36
#define ACPI_POWER_BUTTON_DEVICE "PWRB"
31
+ FIXUP_ARGPTR_HI, /* overwrite with pointer to kernel args (high half) */
37
32
+ FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */
38
@@ -XXX,XX +XXX,XX @@ typedef struct AcpiGedState {
33
+ FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */
39
GEDState ged_state;
34
FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */
40
uint32_t ged_event_bitmap;
35
FIXUP_BOOTREG, /* overwrite with boot register address */
41
qemu_irq irq;
36
FIXUP_DSB, /* overwrite with correct DSB insn for cpu */
42
+ AcpiGhesState ghes_state;
37
@@ -XXX,XX +XXX,XX @@ static const ARMInsnFixup bootloader_aarch64[] = {
43
} AcpiGedState;
38
{ 0xaa1f03e3 }, /* mov x3, xzr */
44
39
{ 0x58000084 }, /* ldr x4, entry ; Load the lower 32-bits of kernel entry */
45
void build_ged_aml(Aml *table, const char* name, HotplugHandler *hotplug_dev,
40
{ 0xd61f0080 }, /* br x4 ; Jump to the kernel entry point */
46
diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h
41
- { 0, FIXUP_ARGPTR }, /* arg: .word @DTB Lower 32-bits */
47
index XXXXXXX..XXXXXXX 100644
42
- { 0 }, /* .word @DTB Higher 32-bits */
48
--- a/include/hw/acpi/ghes.h
43
- { 0, FIXUP_ENTRYPOINT }, /* entry: .word @Kernel Entry Lower 32-bits */
49
+++ b/include/hw/acpi/ghes.h
44
- { 0 }, /* .word @Kernel Entry Higher 32-bits */
50
@@ -XXX,XX +XXX,XX @@ enum {
45
+ { 0, FIXUP_ARGPTR_LO }, /* arg: .word @DTB Lower 32-bits */
51
ACPI_HEST_SRC_ID_RESERVED,
46
+ { 0, FIXUP_ARGPTR_HI}, /* .word @DTB Higher 32-bits */
47
+ { 0, FIXUP_ENTRYPOINT_LO }, /* entry: .word @Kernel Entry Lower 32-bits */
48
+ { 0, FIXUP_ENTRYPOINT_HI }, /* .word @Kernel Entry Higher 32-bits */
49
{ 0, FIXUP_TERMINATOR }
50
};
52
};
51
53
52
@@ -XXX,XX +XXX,XX @@ static const ARMInsnFixup bootloader[] = {
54
+typedef struct AcpiGhesState {
53
{ 0xe59f2004 }, /* ldr r2, [pc, #4] */
55
+ uint64_t ghes_addr_le;
54
{ 0xe59ff004 }, /* ldr pc, [pc, #4] */
56
+} AcpiGhesState;
55
{ 0, FIXUP_BOARDID },
57
+
56
- { 0, FIXUP_ARGPTR },
58
void build_ghes_error_table(GArray *hardware_errors, BIOSLinker *linker);
57
- { 0, FIXUP_ENTRYPOINT },
59
void acpi_build_hest(GArray *table_data, BIOSLinker *linker);
58
+ { 0, FIXUP_ARGPTR_LO },
60
+void acpi_ghes_add_fw_cfg(AcpiGhesState *vms, FWCfgState *s,
59
+ { 0, FIXUP_ENTRYPOINT_LO },
61
+ GArray *hardware_errors);
60
{ 0, FIXUP_TERMINATOR }
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
}
61
};
69
};
62
70
63
@@ -XXX,XX +XXX,XX @@ static void write_bootloader(const char *name, hwaddr addr,
71
+static bool ghes_needed(void *opaque)
64
break;
72
+{
65
case FIXUP_BOARDID:
73
+ AcpiGedState *s = opaque;
66
case FIXUP_BOARD_SETUP:
74
+ return s->ghes_state.ghes_addr_le;
67
- case FIXUP_ARGPTR:
75
+}
68
- case FIXUP_ENTRYPOINT:
76
+
69
+ case FIXUP_ARGPTR_LO:
77
+static const VMStateDescription vmstate_ghes_state = {
70
+ case FIXUP_ARGPTR_HI:
78
+ .name = "acpi-ged/ghes",
71
+ case FIXUP_ENTRYPOINT_LO:
79
+ .version_id = 1,
72
+ case FIXUP_ENTRYPOINT_HI:
80
+ .minimum_version_id = 1,
73
case FIXUP_GIC_CPU_IF:
81
+ .needed = ghes_needed,
74
case FIXUP_BOOTREG:
82
+ .fields = (VMStateField[]) {
75
case FIXUP_DSB:
83
+ VMSTATE_STRUCT(ghes_state, AcpiGedState, 1,
76
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
84
+ vmstate_ghes_state, AcpiGhesState),
77
/* Place the DTB after the initrd in memory with alignment. */
85
+ VMSTATE_END_OF_LIST()
78
info->dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size,
86
+ }
79
align);
87
+};
80
- fixupcontext[FIXUP_ARGPTR] = info->dtb_start;
88
+
81
+ fixupcontext[FIXUP_ARGPTR_LO] = info->dtb_start;
89
static const VMStateDescription vmstate_acpi_ged = {
82
+ fixupcontext[FIXUP_ARGPTR_HI] = info->dtb_start >> 32;
90
.name = "acpi-ged",
83
} else {
91
.version_id = 1,
84
- fixupcontext[FIXUP_ARGPTR] = info->loader_start + KERNEL_ARGS_ADDR;
92
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_acpi_ged = {
85
+ fixupcontext[FIXUP_ARGPTR_LO] =
93
},
86
+ info->loader_start + KERNEL_ARGS_ADDR;
94
.subsections = (const VMStateDescription * []) {
87
+ fixupcontext[FIXUP_ARGPTR_HI] =
95
&vmstate_memhp_state,
88
+ (info->loader_start + KERNEL_ARGS_ADDR) >> 32;
96
+ &vmstate_ghes_state,
89
if (info->ram_size >= (1ULL << 32)) {
97
NULL
90
error_report("RAM size must be less than 4GB to boot"
98
}
91
" Linux kernel using ATAGS (try passing a device tree"
99
};
92
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
100
diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
93
exit(1);
101
index XXXXXXX..XXXXXXX 100644
94
}
102
--- a/hw/acpi/ghes.c
95
}
103
+++ b/hw/acpi/ghes.c
96
- fixupcontext[FIXUP_ENTRYPOINT] = entry;
104
@@ -XXX,XX +XXX,XX @@
97
+ fixupcontext[FIXUP_ENTRYPOINT_LO] = entry;
105
#include "hw/acpi/ghes.h"
98
+ fixupcontext[FIXUP_ENTRYPOINT_HI] = entry >> 32;
106
#include "hw/acpi/aml-build.h"
99
107
#include "qemu/error-report.h"
100
write_bootloader("bootloader", info->loader_start,
108
+#include "hw/acpi/generic_event_device.h"
101
primary_loader, fixupcontext, as);
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);
102
--
155
--
103
2.19.2
156
2.20.1
104
157
105
158
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
2
2
3
Use DeviceClass rather than SysBusDeviceClass in
3
kvm_hwpoison_page_add() and kvm_unpoison_all() will both
4
milkymist_pfpu_class_init().
4
be used by X86 and ARM platforms, so moving them into
5
"accel/kvm/kvm-all.c" to avoid duplicate code.
5
6
6
Cc: michael@walle.cc
7
For architectures that don't use the poison-list functionality
8
the reset handler will harmlessly do nothing, so let's register
9
the kvm_unpoison_all() function in the generic kvm_init() function.
7
10
8
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
12
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Signed-off-by: Xiang Zheng <zhengxiang9@huawei.com>
11
Message-id: 20181130093852.20739-13-maozhongyi@cmss.chinamobile.com
14
Acked-by: Xiang Zheng <zhengxiang9@huawei.com>
15
Message-id: 20200512030609.19593-8-gengdongjiu@huawei.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
17
---
14
hw/misc/milkymist-pfpu.c | 12 +++++-------
18
include/sysemu/kvm_int.h | 12 ++++++++++++
15
1 file changed, 5 insertions(+), 7 deletions(-)
19
accel/kvm/kvm-all.c | 36 ++++++++++++++++++++++++++++++++++++
20
target/i386/kvm.c | 36 ------------------------------------
21
3 files changed, 48 insertions(+), 36 deletions(-)
16
22
17
diff --git a/hw/misc/milkymist-pfpu.c b/hw/misc/milkymist-pfpu.c
23
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
18
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/misc/milkymist-pfpu.c
25
--- a/include/sysemu/kvm_int.h
20
+++ b/hw/misc/milkymist-pfpu.c
26
+++ b/include/sysemu/kvm_int.h
21
@@ -XXX,XX +XXX,XX @@ static void milkymist_pfpu_reset(DeviceState *d)
27
@@ -XXX,XX +XXX,XX @@ void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml,
28
AddressSpace *as, int as_id);
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
}
59
60
+typedef struct HWPoisonPage {
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
+{
70
+ HWPoisonPage *page, *next_page;
71
+
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
+}
78
+
79
+void kvm_hwpoison_page_add(ram_addr_t ram_addr)
80
+{
81
+ HWPoisonPage *page;
82
+
83
+ QLIST_FOREACH(page, &hwpoison_page_list, list) {
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)
22
}
118
}
23
}
119
}
24
120
25
-static int milkymist_pfpu_init(SysBusDevice *dev)
121
-
26
+static void milkymist_pfpu_realize(DeviceState *dev, Error **errp)
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
-{
132
- HWPoisonPage *page, *next_page;
133
-
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
- }
139
-}
140
-
141
-static void kvm_hwpoison_page_add(ram_addr_t ram_addr)
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)
27
{
157
{
28
MilkymistPFPUState *s = MILKYMIST_PFPU(dev);
158
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
29
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
159
fprintf(stderr, "e820_add_entry() table is full\n");
30
160
return ret;
31
- sysbus_init_irq(dev, &s->irq);
161
}
32
+ sysbus_init_irq(sbd, &s->irq);
162
- qemu_register_reset(kvm_unpoison_all, NULL);
33
163
34
memory_region_init_io(&s->regs_region, OBJECT(dev), &pfpu_mmio_ops, s,
164
shadow_mem = object_property_get_int(OBJECT(s), "kvm-shadow-mem", &error_abort);
35
"milkymist-pfpu", MICROCODE_END * 4);
165
if (shadow_mem != -1) {
36
- sysbus_init_mmio(dev, &s->regs_region);
37
-
38
- return 0;
39
+ sysbus_init_mmio(sbd, &s->regs_region);
40
}
41
42
static const VMStateDescription vmstate_milkymist_pfpu = {
43
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_milkymist_pfpu = {
44
static void milkymist_pfpu_class_init(ObjectClass *klass, void *data)
45
{
46
DeviceClass *dc = DEVICE_CLASS(klass);
47
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
48
49
- k->init = milkymist_pfpu_init;
50
+ dc->realize = milkymist_pfpu_realize;
51
dc->reset = milkymist_pfpu_reset;
52
dc->vmsd = &vmstate_milkymist_pfpu;
53
}
54
--
166
--
55
2.19.2
167
2.20.1
56
168
57
169
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
2
2
3
Use DeviceClass rather than SysBusDeviceClass in
3
kvm_arch_on_sigbus_vcpu() error injection uses source_id as
4
puv3_intc_class_init().
4
index in etc/hardware_errors to find out Error Status Data
5
5
Block entry corresponding to error source. So supported source_id
6
Cc: gxt@mprc.pku.edu.cn
6
values should be assigned here and not be changed afterwards to
7
7
make sure that guest will write error into expected Error Status
8
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
8
Data Block.
9
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
9
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Before QEMU writes a new error to ACPI table, it will check whether
11
Message-id: 20181130093852.20739-11-maozhongyi@cmss.chinamobile.com
11
previous error has been acknowledged. If not acknowledged, the new
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>
18
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
19
Message-id: 20200512030609.19593-9-gengdongjiu@huawei.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
21
---
14
hw/intc/puv3_intc.c | 11 ++++-------
22
include/hw/acpi/ghes.h | 1 +
15
1 file changed, 4 insertions(+), 7 deletions(-)
23
hw/acpi/ghes.c | 219 +++++++++++++++++++++++++++++++++++++++++
16
24
2 files changed, 220 insertions(+)
17
diff --git a/hw/intc/puv3_intc.c b/hw/intc/puv3_intc.c
25
26
diff --git a/include/hw/acpi/ghes.h b/include/hw/acpi/ghes.h
18
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/puv3_intc.c
28
--- a/include/hw/acpi/ghes.h
20
+++ b/hw/intc/puv3_intc.c
29
+++ b/include/hw/acpi/ghes.h
21
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps puv3_intc_ops = {
30
@@ -XXX,XX +XXX,XX @@ void build_ghes_error_table(GArray *hardware_errors, BIOSLinker *linker);
22
.endianness = DEVICE_NATIVE_ENDIAN,
31
void acpi_build_hest(GArray *table_data, BIOSLinker *linker);
23
};
32
void acpi_ghes_add_fw_cfg(AcpiGhesState *vms, FWCfgState *s,
24
33
GArray *hardware_errors);
25
-static int puv3_intc_init(SysBusDevice *sbd)
34
+int acpi_ghes_record_errors(uint8_t notify, uint64_t error_physical_addr);
26
+static void puv3_intc_realize(DeviceState *dev, Error **errp)
35
#endif
27
{
36
diff --git a/hw/acpi/ghes.c b/hw/acpi/ghes.c
28
- DeviceState *dev = DEVICE(sbd);
37
index XXXXXXX..XXXXXXX 100644
29
PUV3INTCState *s = PUV3_INTC(dev);
38
--- a/hw/acpi/ghes.c
30
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
39
+++ b/hw/acpi/ghes.c
31
40
@@ -XXX,XX +XXX,XX @@
32
qdev_init_gpio_in(dev, puv3_intc_handler, PUV3_IRQS_NR);
41
#include "qemu/error-report.h"
33
sysbus_init_irq(sbd, &s->parent_irq);
42
#include "hw/acpi/generic_event_device.h"
34
@@ -XXX,XX +XXX,XX @@ static int puv3_intc_init(SysBusDevice *sbd)
43
#include "hw/nvram/fw_cfg.h"
35
memory_region_init_io(&s->iomem, OBJECT(s), &puv3_intc_ops, s, "puv3_intc",
44
+#include "qemu/uuid.h"
36
PUV3_REGS_OFFSET);
45
37
sysbus_init_mmio(sbd, &s->iomem);
46
#define ACPI_GHES_ERRORS_FW_CFG_FILE "etc/hardware_errors"
38
-
47
#define ACPI_GHES_DATA_ADDR_FW_CFG_FILE "etc/hardware_errors_addr"
39
- return 0;
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);
40
}
87
}
41
88
42
static void puv3_intc_class_init(ObjectClass *klass, void *data)
89
+/*
43
{
90
+ * Generic Error Data Entry
44
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
91
+ * ACPI 6.1: 18.3.2.7.1 Generic Error Data
45
-
92
+ */
46
- sdc->init = puv3_intc_init;
93
+static void acpi_ghes_generic_error_data(GArray *table,
47
+ DeviceClass *dc = DEVICE_CLASS(klass);
94
+ const uint8_t *section_type, uint32_t error_severity,
48
+ dc->realize = puv3_intc_realize;
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);
49
}
227
}
50
228
+
51
static const TypeInfo puv3_intc_info = {
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
+ }
251
+
252
+ cpu_physical_memory_read(start_addr, &error_block_addr,
253
+ sizeof(error_block_addr));
254
+
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
+}
52
--
284
--
53
2.19.2
285
2.20.1
54
286
55
287
diff view generated by jsdifflib
1
At the same time, define the fields for these registers,
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
2
and use those defines in arm_pamax().
2
3
3
Add a SIGBUS signal handler. In this handler, it checks the SIGBUS type,
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
translates the host VA delivered by host to guest PA, then fills this PA
5
Message-id: 20181203203839.757-2-richard.henderson@linaro.org
5
to guest APEI GHES memory, then notifies guest according to the SIGBUS
6
type.
7
8
When guest accesses the poisoned memory, it will generate a Synchronous
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>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
32
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
[PMM: fixed up typo (s/achf/ahcf/) belatedly spotted by RTH]
33
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
34
Message-id: 20200512030609.19593-10-gengdongjiu@huawei.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
36
---
10
target/arm/cpu.h | 26 ++++++++++++++++++++++++--
37
include/sysemu/kvm.h | 3 +-
11
target/arm/internals.h | 3 ++-
38
target/arm/cpu.h | 4 +++
12
target/arm/cpu64.c | 6 +++---
39
target/arm/internals.h | 5 +--
13
target/arm/helper.c | 4 ++--
40
target/i386/cpu.h | 2 ++
14
target/arm/kvm64.c | 4 ++++
41
target/arm/helper.c | 2 +-
15
5 files changed, 35 insertions(+), 8 deletions(-)
42
target/arm/kvm64.c | 77 +++++++++++++++++++++++++++++++++++++++++
16
43
target/arm/tlb_helper.c | 2 +-
44
7 files changed, 89 insertions(+), 6 deletions(-)
45
46
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/include/sysemu/kvm.h
49
+++ b/include/sysemu/kvm.h
50
@@ -XXX,XX +XXX,XX @@ bool kvm_vcpu_id_is_valid(int vcpu_id);
51
/* Returns VCPU ID to be used on KVM_CREATE_VCPU ioctl() */
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
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
60
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
61
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
62
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
63
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
64
@@ -XXX,XX +XXX,XX @@
22
uint64_t id_aa64isar1;
65
/* ARM processors have a weak memory model */
23
uint64_t id_aa64pfr0;
66
#define TCG_GUEST_DEFAULT_MO (0)
24
uint64_t id_aa64pfr1;
67
25
+ uint64_t id_aa64mmfr0;
68
+#ifdef TARGET_AARCH64
26
+ uint64_t id_aa64mmfr1;
69
+#define KVM_HAVE_MCE_INJECTION 1
27
} isar;
70
+#endif
28
uint32_t midr;
71
+
29
uint32_t revidr;
72
#define EXCP_UDEF 1 /* undefined instruction */
30
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
73
#define EXCP_SWI 2 /* software interrupt */
31
uint64_t id_aa64dfr1;
74
#define EXCP_PREFETCH_ABORT 3
32
uint64_t id_aa64afr0;
33
uint64_t id_aa64afr1;
34
- uint64_t id_aa64mmfr0;
35
- uint64_t id_aa64mmfr1;
36
uint32_t dbgdidr;
37
uint32_t clidr;
38
uint64_t mp_affinity; /* MP ID without feature bits */
39
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64PFR0, GIC, 24, 4)
40
FIELD(ID_AA64PFR0, RAS, 28, 4)
41
FIELD(ID_AA64PFR0, SVE, 32, 4)
42
43
+FIELD(ID_AA64MMFR0, PARANGE, 0, 4)
44
+FIELD(ID_AA64MMFR0, ASIDBITS, 4, 4)
45
+FIELD(ID_AA64MMFR0, BIGEND, 8, 4)
46
+FIELD(ID_AA64MMFR0, SNSMEM, 12, 4)
47
+FIELD(ID_AA64MMFR0, BIGENDEL0, 16, 4)
48
+FIELD(ID_AA64MMFR0, TGRAN16, 20, 4)
49
+FIELD(ID_AA64MMFR0, TGRAN64, 24, 4)
50
+FIELD(ID_AA64MMFR0, TGRAN4, 28, 4)
51
+FIELD(ID_AA64MMFR0, TGRAN16_2, 32, 4)
52
+FIELD(ID_AA64MMFR0, TGRAN64_2, 36, 4)
53
+FIELD(ID_AA64MMFR0, TGRAN4_2, 40, 4)
54
+FIELD(ID_AA64MMFR0, EXS, 44, 4)
55
+
56
+FIELD(ID_AA64MMFR1, HAFDBS, 0, 4)
57
+FIELD(ID_AA64MMFR1, VMIDBITS, 4, 4)
58
+FIELD(ID_AA64MMFR1, VH, 8, 4)
59
+FIELD(ID_AA64MMFR1, HPDS, 12, 4)
60
+FIELD(ID_AA64MMFR1, LO, 16, 4)
61
+FIELD(ID_AA64MMFR1, PAN, 20, 4)
62
+FIELD(ID_AA64MMFR1, SPECSEI, 24, 4)
63
+FIELD(ID_AA64MMFR1, XNX, 28, 4)
64
+
65
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
66
67
/* If adding a feature bit which corresponds to a Linux ELF
68
diff --git a/target/arm/internals.h b/target/arm/internals.h
75
diff --git a/target/arm/internals.h b/target/arm/internals.h
69
index XXXXXXX..XXXXXXX 100644
76
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/internals.h
77
--- a/target/arm/internals.h
71
+++ b/target/arm/internals.h
78
+++ b/target/arm/internals.h
72
@@ -XXX,XX +XXX,XX @@ static inline unsigned int arm_pamax(ARMCPU *cpu)
79
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
73
[4] = 44,
80
| ARM_EL_IL | (ea << 9) | (s1ptw << 7) | fsc;
74
[5] = 48,
81
}
75
};
82
76
- unsigned int parange = extract32(cpu->id_aa64mmfr0, 0, 4);
83
-static inline uint32_t syn_data_abort_no_iss(int same_el,
77
+ unsigned int parange =
84
+static inline uint32_t syn_data_abort_no_iss(int same_el, int fnv,
78
+ FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE);
85
int ea, int cm, int s1ptw,
79
86
int wnr, int fsc)
80
/* id_aa64mmfr0 is a read-only register so values outside of the
87
{
81
* supported mappings can be considered an implementation error. */
88
return (EC_DATAABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
82
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
89
| ARM_EL_IL
83
index XXXXXXX..XXXXXXX 100644
90
- | (ea << 9) | (cm << 8) | (s1ptw << 7) | (wnr << 6) | fsc;
84
--- a/target/arm/cpu64.c
91
+ | (fnv << 10) | (ea << 9) | (cm << 8) | (s1ptw << 7)
85
+++ b/target/arm/cpu64.c
92
+ | (wnr << 6) | fsc;
86
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
93
}
87
cpu->pmceid0 = 0x00000000;
94
88
cpu->pmceid1 = 0x00000000;
95
static inline uint32_t syn_data_abort_with_iss(int same_el,
89
cpu->isar.id_aa64isar0 = 0x00011120;
96
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
90
- cpu->id_aa64mmfr0 = 0x00001124;
97
index XXXXXXX..XXXXXXX 100644
91
+ cpu->isar.id_aa64mmfr0 = 0x00001124;
98
--- a/target/i386/cpu.h
92
cpu->dbgdidr = 0x3516d000;
99
+++ b/target/i386/cpu.h
93
cpu->clidr = 0x0a200023;
100
@@ -XXX,XX +XXX,XX @@
94
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
101
/* The x86 has a strong memory model with some store-after-load re-ordering */
95
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
102
#define TCG_GUEST_DEFAULT_MO (TCG_MO_ALL & ~TCG_MO_ST_LD)
96
cpu->isar.id_aa64pfr0 = 0x00002222;
103
97
cpu->id_aa64dfr0 = 0x10305106;
104
+#define KVM_HAVE_MCE_INJECTION 1
98
cpu->isar.id_aa64isar0 = 0x00011120;
105
+
99
- cpu->id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
106
/* Maximum instruction code size */
100
+ cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */
107
#define TARGET_MAX_INSN_SIZE 16
101
cpu->dbgdidr = 0x3516d000;
108
102
cpu->clidr = 0x0a200023;
103
cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
104
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
105
cpu->pmceid0 = 0x00000000;
106
cpu->pmceid1 = 0x00000000;
107
cpu->isar.id_aa64isar0 = 0x00011120;
108
- cpu->id_aa64mmfr0 = 0x00001124;
109
+ cpu->isar.id_aa64mmfr0 = 0x00001124;
110
cpu->dbgdidr = 0x3516d000;
111
cpu->clidr = 0x0a200023;
112
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
113
diff --git a/target/arm/helper.c b/target/arm/helper.c
109
diff --git a/target/arm/helper.c b/target/arm/helper.c
114
index XXXXXXX..XXXXXXX 100644
110
index XXXXXXX..XXXXXXX 100644
115
--- a/target/arm/helper.c
111
--- a/target/arm/helper.c
116
+++ b/target/arm/helper.c
112
+++ b/target/arm/helper.c
117
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
113
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
118
{ .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64,
114
* Report exception with ESR indicating a fault due to a
119
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0,
115
* translation table walk for a cache maintenance instruction.
120
.access = PL1_R, .type = ARM_CP_CONST,
116
*/
121
- .resetvalue = cpu->id_aa64mmfr0 },
117
- syn = syn_data_abort_no_iss(current_el == target_el,
122
+ .resetvalue = cpu->isar.id_aa64mmfr0 },
118
+ syn = syn_data_abort_no_iss(current_el == target_el, 0,
123
{ .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64,
119
fi.ea, 1, fi.s1ptw, 1, fsc);
124
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1,
120
env->exception.vaddress = value;
125
.access = PL1_R, .type = ARM_CP_CONST,
121
env->exception.fsr = fsr;
126
- .resetvalue = cpu->id_aa64mmfr1 },
127
+ .resetvalue = cpu->isar.id_aa64mmfr1 },
128
{ .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
129
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2,
130
.access = PL1_R, .type = ARM_CP_CONST,
131
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
122
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
132
index XXXXXXX..XXXXXXX 100644
123
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/kvm64.c
124
--- a/target/arm/kvm64.c
134
+++ b/target/arm/kvm64.c
125
+++ b/target/arm/kvm64.c
135
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
126
@@ -XXX,XX +XXX,XX @@
136
ARM64_SYS_REG(3, 0, 0, 6, 0));
127
#include "sysemu/kvm_int.h"
137
err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1,
128
#include "kvm_arm.h"
138
ARM64_SYS_REG(3, 0, 0, 6, 1));
129
#include "internals.h"
139
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr0,
130
+#include "hw/acpi/acpi.h"
140
+ ARM64_SYS_REG(3, 0, 0, 7, 0));
131
+#include "hw/acpi/ghes.h"
141
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1,
132
+#include "hw/arm/virt.h"
142
+ ARM64_SYS_REG(3, 0, 0, 7, 1));
133
143
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
+{
143
+ ARMCPU *cpu = ARM_CPU(c);
144
+ CPUARMState *env = &cpu->env;
145
+ CPUClass *cc = CPU_GET_CLASS(c);
146
+ uint32_t esr;
147
+ bool same_el;
148
+
149
+ c->exception_index = EXCP_DATA_ABORT;
150
+ env->exception.target_el = 1;
151
+
152
+ /*
153
+ * Set the DFSC to synchronous external abort and set FnV to not valid,
154
+ * this will tell guest the FAR_ELx is UNKNOWN for this abort.
155
+ */
156
+ same_el = arm_current_el(env) == env->exception.target_el;
157
+ esr = syn_data_abort_no_iss(same_el, 1, 0, 0, 0, 0, 0x10);
158
+
159
+ env->exception.syndrome = esr;
160
+
161
+ cc->do_interrupt(c);
162
+}
163
+
164
#define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
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
+{
173
+ ram_addr_t ram_addr;
174
+ hwaddr paddr;
175
+ Object *obj = qdev_get_machine();
176
+ VirtMachineState *vms = VIRT_MACHINE(obj);
177
+ bool acpi_enabled = virt_is_acpi_enabled(vms);
178
+
179
+ assert(code == BUS_MCEERR_AR || code == BUS_MCEERR_AO);
180
+
181
+ if (acpi_enabled && addr &&
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
+}
220
+
221
/* C6.6.29 BRK instruction */
222
static const uint32_t brk_insn = 0xd4200000;
223
224
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
225
index XXXXXXX..XXXXXXX 100644
226
--- a/target/arm/tlb_helper.c
227
+++ b/target/arm/tlb_helper.c
228
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
229
* ISV field.
230
*/
231
if (!(template_syn & ARM_EL_ISV) || target_el != 2 || s1ptw) {
232
- syn = syn_data_abort_no_iss(same_el,
233
+ syn = syn_data_abort_no_iss(same_el, 0,
234
ea, 0, s1ptw, is_write, fsc);
235
} else {
144
/*
236
/*
145
* Note that if AArch32 support is not present in the host,
146
--
237
--
147
2.19.2
238
2.20.1
148
239
149
240
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Dongjiu Geng <gengdongjiu@huawei.com>
2
2
3
Use IRQs 111 - 118 for virtio-mmio. The interrupts we're currently
3
I and Xiang are willing to review the APEI-related patches and
4
using 160+ are not available in the Versal GIC.
4
volunteer as the reviewers for the HEST/GHES part.
5
5
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Signed-off-by: Dongjiu Geng <gengdongjiu@huawei.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Xiang Zheng <zhengxiang9@huawei.com>
8
Message-id: 20181129163655.20370-4-edgar.iglesias@gmail.com
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Acked-by: Michael S. Tsirkin <mst@redhat.com>
10
Message-id: 20200512030609.19593-11-gengdongjiu@huawei.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
include/hw/arm/xlnx-versal.h | 6 +++---
13
MAINTAINERS | 9 +++++++++
12
hw/arm/xlnx-versal-virt.c | 4 ++--
14
1 file changed, 9 insertions(+)
13
2 files changed, 5 insertions(+), 5 deletions(-)
14
15
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
diff --git a/MAINTAINERS b/MAINTAINERS
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/xlnx-versal.h
18
--- a/MAINTAINERS
18
+++ b/include/hw/arm/xlnx-versal.h
19
+++ b/MAINTAINERS
19
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
20
@@ -XXX,XX +XXX,XX @@ F: tests/qtest/bios-tables-test.c
20
#define VERSAL_GEM1_IRQ_0 58
21
F: tests/qtest/acpi-utils.[hc]
21
#define VERSAL_GEM1_WAKE_IRQ_0 59
22
F: tests/data/acpi/
22
23
23
-/* Architecturally eserved IRQs suitable for virtualization. */
24
+ACPI/HEST/GHES
24
-#define VERSAL_RSVD_HIGH_IRQ_FIRST 160
25
+R: Dongjiu Geng <gengdongjiu@huawei.com>
25
-#define VERSAL_RSVD_HIGH_IRQ_LAST 255
26
+R: Xiang Zheng <zhengxiang9@huawei.com>
26
+/* Architecturally reserved IRQs suitable for virtualization. */
27
+L: qemu-arm@nongnu.org
27
+#define VERSAL_RSVD_IRQ_FIRST 111
28
+S: Maintained
28
+#define VERSAL_RSVD_IRQ_LAST 118
29
+F: hw/acpi/ghes.c
29
30
+F: include/hw/acpi/ghes.h
30
#define MM_TOP_RSVD 0xa0000000U
31
+F: docs/specs/acpi_hest_ghes.rst
31
#define MM_TOP_RSVD_SIZE 0x4000000
32
+
32
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
33
ppc4xx
33
index XXXXXXX..XXXXXXX 100644
34
M: David Gibson <david@gibson.dropbear.id.au>
34
--- a/hw/arm/xlnx-versal-virt.c
35
L: qemu-ppc@nongnu.org
35
+++ b/hw/arm/xlnx-versal-virt.c
36
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
37
for (i = 0; i < NUM_VIRTIO_TRANSPORT; i++) {
38
char *name = g_strdup_printf("virtio%d", i);;
39
hwaddr base = MM_TOP_RSVD + i * virtio_mmio_size;
40
- int irq = VERSAL_RSVD_HIGH_IRQ_FIRST + i;
41
+ int irq = VERSAL_RSVD_IRQ_FIRST + i;
42
MemoryRegion *mr;
43
DeviceState *dev;
44
qemu_irq pic_irq;
45
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
46
47
for (i = 0; i < NUM_VIRTIO_TRANSPORT; i++) {
48
hwaddr base = MM_TOP_RSVD + i * virtio_mmio_size;
49
- int irq = VERSAL_RSVD_HIGH_IRQ_FIRST + i;
50
+ int irq = VERSAL_RSVD_IRQ_FIRST + i;
51
char *name = g_strdup_printf("/virtio_mmio@%" PRIx64, base);
52
53
qemu_fdt_add_subnode(s->fdt, name);
54
--
36
--
55
2.19.2
37
2.20.1
56
38
57
39
diff view generated by jsdifflib
New 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.
1
5
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
New patch
1
1
Convert the Neon SHA instructions in the 3-reg-same group
2
to decodetree.
3
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
New 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.
1
4
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
New patch
1
Convert the Neon VHADD insns in the 3-reg-same group to decodetree.
1
2
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
New patch
1
Convert the Neon VABA and VABD insns in the 3-reg-same group to
2
decodetree.
1
3
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
New 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.)
1
5
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
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
Convert the VQSHL, VRSHL and VQRSHL insns in the 3-reg-same
2
group to decodetree. We have already implemented the size==0b11
3
case of these insns; this commit handles the remaining sizes.
2
4
3
Use DeviceClass rather than SysBusDeviceClass in
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
puv3_gpio_class_init().
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200512163904.10918-8-peter.maydell@linaro.org
8
---
9
target/arm/neon-dp.decode | 30 ++++++++++++++++++-----
10
target/arm/translate-neon.inc.c | 43 +++++++++++++++++++++++++++++++++
11
target/arm/translate.c | 22 +++--------------
12
3 files changed, 70 insertions(+), 25 deletions(-)
5
13
6
Cc: gxt@mprc.pku.edu.cn
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
7
Cc: peter.maydell@linaro.org
8
9
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
10
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Message-id: 20181130093852.20739-8-maozhongyi@cmss.chinamobile.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/gpio/puv3_gpio.c | 29 ++++++++++++++---------------
16
1 file changed, 14 insertions(+), 15 deletions(-)
17
18
diff --git a/hw/gpio/puv3_gpio.c b/hw/gpio/puv3_gpio.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/gpio/puv3_gpio.c
16
--- a/target/arm/neon-dp.decode
21
+++ b/hw/gpio/puv3_gpio.c
17
+++ b/target/arm/neon-dp.decode
22
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps puv3_gpio_ops = {
18
@@ -XXX,XX +XXX,XX @@ VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same_rev
23
.endianness = DEVICE_NATIVE_ENDIAN,
19
@3same_64_rev .... ... . . . 11 .... .... .... . q:1 . . .... \
24
};
20
&3same vm=%vn_dp vn=%vm_dp vd=%vd_dp size=3
25
21
26
-static int puv3_gpio_init(SysBusDevice *dev)
22
-VQSHL_S64_3s 1111 001 0 0 . .. .... .... 0100 . . . 1 .... @3same_64_rev
27
+static void puv3_gpio_realize(DeviceState *dev, Error **errp)
23
-VQSHL_U64_3s 1111 001 1 0 . .. .... .... 0100 . . . 1 .... @3same_64_rev
28
{
24
-VRSHL_S64_3s 1111 001 0 0 . .. .... .... 0101 . . . 0 .... @3same_64_rev
29
PUV3GPIOState *s = PUV3_GPIO(dev);
25
-VRSHL_U64_3s 1111 001 1 0 . .. .... .... 0101 . . . 0 .... @3same_64_rev
30
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
26
-VQRSHL_S64_3s 1111 001 0 0 . .. .... .... 0101 . . . 1 .... @3same_64_rev
31
27
-VQRSHL_U64_3s 1111 001 1 0 . .. .... .... 0101 . . . 1 .... @3same_64_rev
32
s->reg_GPLR = 0;
28
+{
33
s->reg_GPDR = 0;
29
+ VQSHL_S64_3s 1111 001 0 0 . .. .... .... 0100 . . . 1 .... @3same_64_rev
34
30
+ VQSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 1 .... @3same_rev
35
/* FIXME: these irqs not handled yet */
31
+}
36
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW0]);
32
+{
37
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW1]);
33
+ VQSHL_U64_3s 1111 001 1 0 . .. .... .... 0100 . . . 1 .... @3same_64_rev
38
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW2]);
34
+ VQSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 1 .... @3same_rev
39
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW3]);
35
+}
40
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW4]);
36
+{
41
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW5]);
37
+ VRSHL_S64_3s 1111 001 0 0 . .. .... .... 0101 . . . 0 .... @3same_64_rev
42
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW6]);
38
+ VRSHL_S_3s 1111 001 0 0 . .. .... .... 0101 . . . 0 .... @3same_rev
43
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW7]);
39
+}
44
- sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOHIGH]);
40
+{
45
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW0]);
41
+ VRSHL_U64_3s 1111 001 1 0 . .. .... .... 0101 . . . 0 .... @3same_64_rev
46
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW1]);
42
+ VRSHL_U_3s 1111 001 1 0 . .. .... .... 0101 . . . 0 .... @3same_rev
47
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW2]);
43
+}
48
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW3]);
44
+{
49
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW4]);
45
+ VQRSHL_S64_3s 1111 001 0 0 . .. .... .... 0101 . . . 1 .... @3same_64_rev
50
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW5]);
46
+ VQRSHL_S_3s 1111 001 0 0 . .. .... .... 0101 . . . 1 .... @3same_rev
51
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW6]);
47
+}
52
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW7]);
48
+{
53
+ sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOHIGH]);
49
+ VQRSHL_U64_3s 1111 001 1 0 . .. .... .... 0101 . . . 1 .... @3same_64_rev
54
50
+ VQRSHL_U_3s 1111 001 1 0 . .. .... .... 0101 . . . 1 .... @3same_rev
55
memory_region_init_io(&s->iomem, OBJECT(s), &puv3_gpio_ops, s, "puv3_gpio",
51
+}
56
PUV3_REGS_OFFSET);
52
57
- sysbus_init_mmio(dev, &s->iomem);
53
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
58
-
54
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
59
- return 0;
55
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
60
+ sysbus_init_mmio(sbd, &s->iomem);
56
index XXXXXXX..XXXXXXX 100644
61
}
57
--- a/target/arm/translate-neon.inc.c
62
58
+++ b/target/arm/translate-neon.inc.c
63
static void puv3_gpio_class_init(ObjectClass *klass, void *data)
59
@@ -XXX,XX +XXX,XX @@ DO_3SAME_64_ENV(VQRSHL_U64, gen_helper_neon_qrshl_u64)
64
{
60
return do_3same(s, a, gen_##INSN##_3s); \
65
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
61
}
66
+ DeviceClass *dc = DEVICE_CLASS(klass);
62
67
63
+/*
68
- sdc->init = puv3_gpio_init;
64
+ * Some helper functions need to be passed the cpu_env. In order
69
+ dc->realize = puv3_gpio_realize;
65
+ * to use those with the gvec APIs like tcg_gen_gvec_3() we need
70
}
66
+ * to create wrapper functions whose prototype is a NeonGenTwoOpFn()
71
67
+ * and which call a NeonGenTwoOpEnvFn().
72
static const TypeInfo puv3_gpio_info = {
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
+
75
+#define DO_3SAME_32_ENV(INSN, FUNC) \
76
+ WRAP_ENV_FN(gen_##INSN##_tramp8, gen_helper_neon_##FUNC##8); \
77
+ WRAP_ENV_FN(gen_##INSN##_tramp16, gen_helper_neon_##FUNC##16); \
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);
73
--
159
--
74
2.19.2
160
2.20.1
75
161
76
162
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
Convert the Neon integer VPMAX and VPMIN 3-reg-same insns to
2
decodetree. These are 'pairwise' operations.
2
3
3
Use DeviceClass rather than SysBusDeviceClass in
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
empty_slot_class_init().
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200512163904.10918-9-peter.maydell@linaro.org
7
---
8
target/arm/neon-dp.decode | 9 +++++
9
target/arm/translate-neon.inc.c | 71 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 17 +-------
11
3 files changed, 82 insertions(+), 15 deletions(-)
5
12
6
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
7
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20181130093852.20739-5-maozhongyi@cmss.chinamobile.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/core/empty_slot.c | 9 ++++-----
14
1 file changed, 4 insertions(+), 5 deletions(-)
15
16
diff --git a/hw/core/empty_slot.c b/hw/core/empty_slot.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/core/empty_slot.c
15
--- a/target/arm/neon-dp.decode
19
+++ b/hw/core/empty_slot.c
16
+++ b/target/arm/neon-dp.decode
20
@@ -XXX,XX +XXX,XX @@ void empty_slot_init(hwaddr addr, uint64_t slot_size)
17
@@ -XXX,XX +XXX,XX @@
18
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
19
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
21
+@3same_q0 .... ... . . . size:2 .... .... .... . 0 . . .... \
22
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp q=0
23
+
24
VHADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 0 .... @3same
25
VHADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 0 .... @3same
26
VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
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)
21
}
124
}
22
}
125
}
23
126
24
-static int empty_slot_init1(SysBusDevice *dev)
127
-/* 32-bit pairwise ops end up the same as the elementwise versions. */
25
+static void empty_slot_realize(DeviceState *dev, Error **errp)
128
-#define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
26
{
129
-#define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
27
EmptySlot *s = EMPTY_SLOT(dev);
130
-#define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
28
131
-#define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
29
memory_region_init_io(&s->iomem, OBJECT(s), &empty_slot_ops, s,
132
-
30
"empty-slot", s->size);
133
#define GEN_NEON_INTEGER_OP_ENV(name) do { \
31
- sysbus_init_mmio(dev, &s->iomem);
134
switch ((size << 1) | u) { \
32
- return 0;
135
case 0: \
33
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
136
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
34
}
137
case NEON_3R_VQSHL:
35
138
case NEON_3R_VRSHL:
36
static void empty_slot_class_init(ObjectClass *klass, void *data)
139
case NEON_3R_VQRSHL:
37
{
140
+ case NEON_3R_VPMAX:
38
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
141
+ case NEON_3R_VPMIN:
39
+ DeviceClass *dc = DEVICE_CLASS(klass);
142
/* Already handled by decodetree */
40
143
return 1;
41
- k->init = empty_slot_init1;
144
}
42
+ dc->realize = empty_slot_realize;
145
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
43
}
146
pairwise = 0;
44
147
switch (op) {
45
static const TypeInfo empty_slot_info = {
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) {
46
--
168
--
47
2.19.2
169
2.20.1
48
170
49
171
diff view generated by jsdifflib
New patch
1
Convert the Neon integer VPADD 3-reg-same insns to decodetree. These
2
are 'pairwise' operations. (Note that VQRDMLAH, which shares the
3
same primary opcode but has U=1, has already been converted.)
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200512163904.10918-10-peter.maydell@linaro.org
8
---
9
target/arm/neon-dp.decode | 2 ++
10
target/arm/translate-neon.inc.c | 2 ++
11
target/arm/translate.c | 19 +------------------
12
3 files changed, 5 insertions(+), 18 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
+VPADD_3s 1111 001 0 0 . .. .... .... 1011 . . . 1 .... @3same_q0
23
+
24
VQRDMLAH_3s 1111 001 1 0 . .. .... .... 1011 ... 1 .... @3same
25
26
SHA1_3s 1111 001 0 0 . optype:2 .... .... 1100 . 1 . 0 .... \
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/translate-neon.inc.c
30
+++ b/target/arm/translate-neon.inc.c
31
@@ -XXX,XX +XXX,XX @@ static bool do_3same_pair(DisasContext *s, arg_3same *a, NeonGenTwoOpFn *fn)
32
#define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
33
#define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
34
#define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
35
+#define gen_helper_neon_padd_u32 tcg_gen_add_i32
36
37
DO_3SAME_PAIR(VPMAX_S, pmax_s)
38
DO_3SAME_PAIR(VPMIN_S, pmin_s)
39
DO_3SAME_PAIR(VPMAX_U, pmax_u)
40
DO_3SAME_PAIR(VPMIN_U, pmin_u)
41
+DO_3SAME_PAIR(VPADD, padd_u)
42
diff --git a/target/arm/translate.c b/target/arm/translate.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/translate.c
45
+++ b/target/arm/translate.c
46
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
47
return 1;
48
}
49
switch (op) {
50
- case NEON_3R_VPADD_VQRDMLAH:
51
- if (!u) {
52
- break; /* VPADD */
53
- }
54
- /* VQRDMLAH : handled by decodetree */
55
- return 1;
56
-
57
case NEON_3R_VFM_VQRDMLSH:
58
if (!u) {
59
/* VFM, VFMS */
60
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
61
case NEON_3R_VQRSHL:
62
case NEON_3R_VPMAX:
63
case NEON_3R_VPMIN:
64
+ case NEON_3R_VPADD_VQRDMLAH:
65
/* Already handled by decodetree */
66
return 1;
67
}
68
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
69
}
70
pairwise = 0;
71
switch (op) {
72
- case NEON_3R_VPADD_VQRDMLAH:
73
- pairwise = 1;
74
- break;
75
case NEON_3R_FLOAT_ARITH:
76
pairwise = (u && size < 2); /* if VPADD (float) */
77
break;
78
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
79
}
80
}
81
break;
82
- case NEON_3R_VPADD_VQRDMLAH:
83
- switch (size) {
84
- case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
85
- case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
86
- case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
87
- default: abort();
88
- }
89
- break;
90
case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
91
{
92
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
93
--
94
2.20.1
95
96
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
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.
2
4
3
Use DeviceClass rather than SysBusDeviceClass in
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
puv3_dma_class_init().
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(-)
5
13
6
Cc: gxt@mprc.pku.edu.cn
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
7
8
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
9
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Message-id: 20181130093852.20739-7-maozhongyi@cmss.chinamobile.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/dma/puv3_dma.c | 10 ++++------
16
1 file changed, 4 insertions(+), 6 deletions(-)
17
18
diff --git a/hw/dma/puv3_dma.c b/hw/dma/puv3_dma.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/dma/puv3_dma.c
16
--- a/target/arm/neon-dp.decode
21
+++ b/hw/dma/puv3_dma.c
17
+++ b/target/arm/neon-dp.decode
22
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps puv3_dma_ops = {
18
@@ -XXX,XX +XXX,XX @@ VPMAX_U_3s 1111 001 1 0 . .. .... .... 1010 . . . 0 .... @3same_q0
23
.endianness = DEVICE_NATIVE_ENDIAN,
19
VPMIN_S_3s 1111 001 0 0 . .. .... .... 1010 . . . 1 .... @3same_q0
24
};
20
VPMIN_U_3s 1111 001 1 0 . .. .... .... 1010 . . . 1 .... @3same_q0
25
21
26
-static int puv3_dma_init(SysBusDevice *dev)
22
+VQDMULH_3s 1111 001 0 0 . .. .... .... 1011 . . . 0 .... @3same
27
+static void puv3_dma_realize(DeviceState *dev, Error **errp)
23
+VQRDMULH_3s 1111 001 1 0 . .. .... .... 1011 . . . 0 .... @3same
28
{
24
+
29
PUV3DMAState *s = PUV3_DMA(dev);
25
VPADD_3s 1111 001 0 0 . .. .... .... 1011 . . . 1 .... @3same_q0
30
int i;
26
31
@@ -XXX,XX +XXX,XX @@ static int puv3_dma_init(SysBusDevice *dev)
27
VQRDMLAH_3s 1111 001 1 0 . .. .... .... 1011 ... 1 .... @3same
32
28
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
33
memory_region_init_io(&s->iomem, OBJECT(s), &puv3_dma_ops, s, "puv3_dma",
29
index XXXXXXX..XXXXXXX 100644
34
PUV3_REGS_OFFSET);
30
--- a/target/arm/translate-neon.inc.c
35
- sysbus_init_mmio(dev, &s->iomem);
31
+++ b/target/arm/translate-neon.inc.c
36
-
32
@@ -XXX,XX +XXX,XX @@ DO_3SAME_PAIR(VPMIN_S, pmin_s)
37
- return 0;
33
DO_3SAME_PAIR(VPMAX_U, pmax_u)
38
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
34
DO_3SAME_PAIR(VPMIN_U, pmin_u)
39
}
35
DO_3SAME_PAIR(VPADD, padd_u)
40
36
+
41
static void puv3_dma_class_init(ObjectClass *klass, void *data)
37
+#define DO_3SAME_VQDMULH(INSN, FUNC) \
42
{
38
+ WRAP_ENV_FN(gen_##INSN##_tramp16, gen_helper_neon_##FUNC##_s16); \
43
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
39
+ WRAP_ENV_FN(gen_##INSN##_tramp32, gen_helper_neon_##FUNC##_s32); \
44
+ DeviceClass *dc = DEVICE_CLASS(klass);
40
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
45
41
+ uint32_t rn_ofs, uint32_t rm_ofs, \
46
- sdc->init = puv3_dma_init;
42
+ uint32_t oprsz, uint32_t maxsz) \
47
+ dc->realize = puv3_dma_realize;
43
+ { \
48
}
44
+ static const GVecGen3 ops[2] = { \
49
45
+ { .fni4 = gen_##INSN##_tramp16 }, \
50
static const TypeInfo puv3_dma_info = {
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);
51
--
102
--
52
2.19.2
103
2.20.1
53
104
54
105
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
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.
2
4
3
Use DeviceClass rather than SysBusDeviceClass in
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
mv88w8618_wlan_class_init().
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(-)
5
16
6
Cc: jan.kiszka@web.de
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
7
Cc: peter.maydell@linaro.org
8
Cc: qemu-arm@nongnu.org
9
10
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
11
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Message-id: 20181130093852.20739-2-maozhongyi@cmss.chinamobile.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
hw/arm/musicpal.c | 9 ++++-----
17
1 file changed, 4 insertions(+), 5 deletions(-)
18
19
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/musicpal.c
19
--- a/target/arm/helper.h
22
+++ b/hw/arm/musicpal.c
20
+++ b/target/arm/helper.h
23
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps mv88w8618_wlan_ops = {
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(neon_qneg_s16, TCG_CALL_NO_RWG, i32, env, i32)
24
.endianness = DEVICE_NATIVE_ENDIAN,
22
DEF_HELPER_FLAGS_2(neon_qneg_s32, TCG_CALL_NO_RWG, i32, env, i32)
25
};
23
DEF_HELPER_FLAGS_2(neon_qneg_s64, TCG_CALL_NO_RWG, i64, env, i64)
26
24
27
-static int mv88w8618_wlan_init(SysBusDevice *dev)
25
-DEF_HELPER_3(neon_abd_f32, i32, i32, i32, ptr)
28
+static void mv88w8618_wlan_realize(DeviceState *dev, Error **errp)
26
DEF_HELPER_3(neon_ceq_f32, i32, i32, i32, ptr)
29
{
27
DEF_HELPER_3(neon_cge_f32, i32, i32, i32, ptr)
30
MemoryRegion *iomem = g_new(MemoryRegion, 1);
28
DEF_HELPER_3(neon_cgt_f32, i32, i32, i32, ptr)
31
29
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_fmul_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
32
memory_region_init_io(iomem, OBJECT(dev), &mv88w8618_wlan_ops, NULL,
30
DEF_HELPER_FLAGS_5(gvec_fmul_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
33
"musicpal-wlan", MP_WLAN_SIZE);
31
DEF_HELPER_FLAGS_5(gvec_fmul_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
34
- sysbus_init_mmio(dev, iomem);
32
35
- return 0;
33
+DEF_HELPER_FLAGS_5(gvec_fabd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
36
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), iomem);
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)
37
}
66
}
38
67
39
/* GPIO register offsets */
68
/* NEON Float helpers. */
40
@@ -XXX,XX +XXX,XX @@ DEFINE_MACHINE("musicpal", musicpal_machine_init)
69
-uint32_t HELPER(neon_abd_f32)(uint32_t a, uint32_t b, void *fpstp)
41
70
-{
42
static void mv88w8618_wlan_class_init(ObjectClass *klass, void *data)
71
- float_status *fpst = fpstp;
43
{
72
- float32 f0 = make_float32(a);
44
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
73
- float32 f1 = make_float32(b);
45
+ DeviceClass *dc = DEVICE_CLASS(klass);
74
- return float32_val(float32_abs(float32_sub(f0, f1, fpst)));
46
75
-}
47
- sdc->init = mv88w8618_wlan_init;
76
48
+ dc->realize = mv88w8618_wlan_realize;
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;
49
}
152
}
50
153
51
static const TypeInfo mv88w8618_wlan_info = {
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)
52
--
171
--
53
2.19.2
172
2.20.1
54
173
55
174
diff view generated by jsdifflib
New patch
1
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
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
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
Convert the Neon integer VMUL, VMLA, and VMLS 3-reg-same inssn to
2
decodetree.
2
3
3
Use DeviceClass rather than SysBusDeviceClass in
4
We don't have a gvec helper for multiply-accumulate, so VMLA and VMLS
4
g364fb_sysbus_class_init().
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.)
5
11
6
Cc: pbonzini@redhat.com
12
This conversion fixes in passing an underdecoding for VMUL
7
Cc: kraxel@redhat.com
13
(originally reported by Fredrik Strupe <fredrik@strupe.net>): bit 1
8
Cc: f4bug@amsat.org
14
of the 'size' field must be 0. The old decoder didn't enforce this,
9
Cc: alistair.francis@wdc.com
15
but the decodetree pattern does.
10
16
11
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
17
The gen_VMLA_fp_reg() function performs the addition operation
12
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
18
with the operands in the opposite order to the old decoder:
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
19
since Neon sets 'default NaN mode' float32_add operations are
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
20
commutative so there is no behaviour difference, but putting
15
Message-id: 20181130093852.20739-6-maozhongyi@cmss.chinamobile.com
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
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
17
---
27
---
18
hw/display/g364fb.c | 9 +++------
28
target/arm/neon-dp.decode | 3 ++
19
1 file changed, 3 insertions(+), 6 deletions(-)
29
target/arm/translate-neon.inc.c | 81 +++++++++++++++++++++++++++++++++
30
target/arm/translate.c | 17 +------
31
3 files changed, 85 insertions(+), 16 deletions(-)
20
32
21
diff --git a/hw/display/g364fb.c b/hw/display/g364fb.c
33
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
22
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/display/g364fb.c
35
--- a/target/arm/neon-dp.decode
24
+++ b/hw/display/g364fb.c
36
+++ b/target/arm/neon-dp.decode
25
@@ -XXX,XX +XXX,XX @@ typedef struct {
37
@@ -XXX,XX +XXX,XX @@ VADD_fp_3s 1111 001 0 0 . 0 . .... .... 1101 ... 0 .... @3same_fp
26
G364State g364;
38
VSUB_fp_3s 1111 001 0 0 . 1 . .... .... 1101 ... 0 .... @3same_fp
27
} G364SysBusState;
39
VPADD_fp_3s 1111 001 1 0 . 0 . .... .... 1101 ... 0 .... @3same_fp_q0
28
40
VABD_fp_3s 1111 001 1 0 . 1 . .... .... 1101 ... 0 .... @3same_fp
29
-static int g364fb_sysbus_init(SysBusDevice *sbd)
41
+VMLA_fp_3s 1111 001 0 0 . 0 . .... .... 1101 ... 1 .... @3same_fp
30
+static void g364fb_sysbus_realize(DeviceState *dev, Error **errp)
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)
31
{
144
{
32
- DeviceState *dev = DEVICE(sbd);
145
diff --git a/target/arm/translate.c b/target/arm/translate.c
33
G364SysBusState *sbs = G364(dev);
146
index XXXXXXX..XXXXXXX 100644
34
G364State *s = &sbs->g364;
147
--- a/target/arm/translate.c
35
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
148
+++ b/target/arm/translate.c
36
149
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
37
g364fb_init(dev, s);
150
case NEON_3R_VPADD_VQRDMLAH:
38
sysbus_init_irq(sbd, &s->irq);
151
case NEON_3R_VQDMULH_VQRDMULH:
39
sysbus_init_mmio(sbd, &s->mem_ctrl);
152
case NEON_3R_FLOAT_ARITH:
40
sysbus_init_mmio(sbd, &s->mem_vram);
153
+ case NEON_3R_FLOAT_MULTIPLY:
41
-
154
/* Already handled by decodetree */
42
- return 0;
155
return 1;
43
}
156
}
44
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
45
static void g364fb_sysbus_reset(DeviceState *d)
158
tmp = neon_load_reg(rn, pass);
46
@@ -XXX,XX +XXX,XX @@ static Property g364fb_sysbus_properties[] = {
159
tmp2 = neon_load_reg(rm, pass);
47
static void g364fb_sysbus_class_init(ObjectClass *klass, void *data)
160
switch (op) {
48
{
161
- case NEON_3R_FLOAT_MULTIPLY:
49
DeviceClass *dc = DEVICE_CLASS(klass);
162
- {
50
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
163
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
51
164
- gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
52
- k->init = g364fb_sysbus_init;
165
- if (!u) {
53
+ dc->realize = g364fb_sysbus_realize;
166
- tcg_temp_free_i32(tmp2);
54
set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
167
- tmp2 = neon_load_reg(rd, pass);
55
dc->desc = "G364 framebuffer";
168
- if (size == 0) {
56
dc->reset = g364fb_sysbus_reset;
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);
57
--
180
--
58
2.19.2
181
2.20.1
59
182
60
183
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
Convert the Neon integer 3-reg-same compare insns VCGE, VCGT,
2
VCEQ, VACGE and VACGT to decodetree.
2
3
3
Remove bogus virtio-mmio creation. This was an accidental
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
left-over an experiment.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200512163904.10918-15-peter.maydell@linaro.org
7
---
8
target/arm/neon-dp.decode | 5 +++++
9
target/arm/translate-neon.inc.c | 6 +++++
10
target/arm/translate.c | 39 ++-------------------------------
11
3 files changed, 13 insertions(+), 37 deletions(-)
5
12
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20181129163655.20370-2-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/xlnx-versal-virt.c | 1 -
13
1 file changed, 1 deletion(-)
14
15
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal-virt.c
15
--- a/target/arm/neon-dp.decode
18
+++ b/hw/arm/xlnx-versal-virt.c
16
+++ b/target/arm/neon-dp.decode
19
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
17
@@ -XXX,XX +XXX,XX @@ VABD_fp_3s 1111 001 1 0 . 1 . .... .... 1101 ... 0 .... @3same_fp
20
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic_irq);
18
VMLA_fp_3s 1111 001 0 0 . 0 . .... .... 1101 ... 1 .... @3same_fp
21
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
19
VMLS_fp_3s 1111 001 0 0 . 1 . .... .... 1101 ... 1 .... @3same_fp
22
memory_region_add_subregion(&s->soc.mr_ps, base, mr);
20
VMUL_fp_3s 1111 001 1 0 . 0 . .... .... 1101 ... 1 .... @3same_fp
23
- sysbus_create_simple("virtio-mmio", base, pic_irq);
21
+VCEQ_fp_3s 1111 001 0 0 . 0 . .... .... 1110 ... 0 .... @3same_fp
22
+VCGE_fp_3s 1111 001 1 0 . 0 . .... .... 1110 ... 0 .... @3same_fp
23
+VACGE_fp_3s 1111 001 1 0 . 0 . .... .... 1110 ... 1 .... @3same_fp
24
+VCGT_fp_3s 1111 001 1 0 . 1 . .... .... 1110 ... 0 .... @3same_fp
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); \
24
}
34
}
25
35
26
for (i = 0; i < NUM_VIRTIO_TRANSPORT; i++) {
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);
27
--
109
--
28
2.19.2
110
2.20.1
29
111
30
112
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
The usual location for the env argument in the argument list of a TCG helper
2
is immediately after the return-value argument. recps_f32 and rsqrts_f32
3
differ in that they put it at the end.
2
4
3
Use DeviceClass rather than SysBusDeviceClass in
5
Move the env argument to its usual place; this will allow us to
4
onenand_class_init().
6
more easily use these helper functions with the gvec APIs.
5
7
6
Cc: kwolf@redhat.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Cc: mreitz@redhat.com
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Cc: qemu-block@nongnu.org
10
Message-id: 20200512163904.10918-16-peter.maydell@linaro.org
11
---
12
target/arm/helper.h | 4 ++--
13
target/arm/translate.c | 4 ++--
14
target/arm/vfp_helper.c | 4 ++--
15
3 files changed, 6 insertions(+), 6 deletions(-)
9
16
10
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
11
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Message-id: 20181130093852.20739-3-maozhongyi@cmss.chinamobile.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
hw/block/onenand.c | 16 +++++++---------
17
1 file changed, 7 insertions(+), 9 deletions(-)
18
19
diff --git a/hw/block/onenand.c b/hw/block/onenand.c
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/block/onenand.c
19
--- a/target/arm/helper.h
22
+++ b/hw/block/onenand.c
20
+++ b/target/arm/helper.h
23
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps onenand_ops = {
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(vfp_fcvt_f64_to_f16, TCG_CALL_NO_RWG, f16, f64, ptr, i32)
24
.endianness = DEVICE_NATIVE_ENDIAN,
22
DEF_HELPER_4(vfp_muladdd, f64, f64, f64, f64, ptr)
25
};
23
DEF_HELPER_4(vfp_muladds, f32, f32, f32, f32, ptr)
26
24
27
-static int onenand_initfn(SysBusDevice *sbd)
25
-DEF_HELPER_3(recps_f32, f32, f32, f32, env)
28
+static void onenand_realize(DeviceState *dev, Error **errp)
26
-DEF_HELPER_3(rsqrts_f32, f32, f32, f32, env)
27
+DEF_HELPER_3(recps_f32, f32, env, f32, f32)
28
+DEF_HELPER_3(rsqrts_f32, f32, env, f32, f32)
29
DEF_HELPER_FLAGS_2(recpe_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
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
34
--- a/target/arm/translate.c
35
+++ b/target/arm/translate.c
36
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
37
tcg_temp_free_ptr(fpstatus);
38
} else {
39
if (size == 0) {
40
- gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
41
+ gen_helper_recps_f32(tmp, cpu_env, tmp, tmp2);
42
} else {
43
- gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
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)
29
{
58
{
30
- DeviceState *dev = DEVICE(sbd);
59
float_status *s = &env->vfp.standard_fp_status;
31
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
60
if ((float32_is_infinity(a) && float32_is_zero_or_denormal(b)) ||
32
OneNANDState *s = ONE_NAND(dev);
61
@@ -XXX,XX +XXX,XX @@ float32 HELPER(recps_f32)(float32 a, float32 b, CPUARMState *env)
33
uint32_t size = 1 << (24 + ((s->id.dev >> 4) & 7));
62
return float32_sub(float32_two, float32_mul(a, b, s), s);
34
void *ram;
35
@@ -XXX,XX +XXX,XX @@ static int onenand_initfn(SysBusDevice *sbd)
36
0xff, size + (size >> 5));
37
} else {
38
if (blk_is_read_only(s->blk)) {
39
- error_report("Can't use a read-only drive");
40
- return -1;
41
+ error_setg(errp, "Can't use a read-only drive");
42
+ return;
43
}
44
blk_set_perm(s->blk, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE,
45
BLK_PERM_ALL, &local_err);
46
if (local_err) {
47
- error_report_err(local_err);
48
- return -1;
49
+ error_propagate(errp, local_err);
50
+ return;
51
}
52
s->blk_cur = s->blk;
53
}
54
@@ -XXX,XX +XXX,XX @@ static int onenand_initfn(SysBusDevice *sbd)
55
| ((s->id.dev & 0xff) << 8)
56
| (s->id.ver & 0xff),
57
&vmstate_onenand, s);
58
- return 0;
59
}
63
}
60
64
61
static Property onenand_properties[] = {
65
-float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUARMState *env)
62
@@ -XXX,XX +XXX,XX @@ static Property onenand_properties[] = {
66
+float32 HELPER(rsqrts_f32)(CPUARMState *env, float32 a, float32 b)
63
static void onenand_class_init(ObjectClass *klass, void *data)
64
{
67
{
65
DeviceClass *dc = DEVICE_CLASS(klass);
68
float_status *s = &env->vfp.standard_fp_status;
66
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
69
float32 product;
67
68
- k->init = onenand_initfn;
69
+ dc->realize = onenand_realize;
70
dc->reset = onenand_system_reset;
71
dc->props = onenand_properties;
72
}
73
--
70
--
74
2.19.2
71
2.20.1
75
72
76
73
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Convert the Neon fp VMAX/VMIN/VMAXNM/VMINNM/VRECPS/VRSQRTS 3-reg-same
2
insns to decodetree. (These are all the remaining non-accumulation
3
instructions in this group.)
2
4
3
Replace arm_hcr_el2_{fmo,imo,amo} with a more general routine
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
that also takes SCR_EL3.NS (aka arm_is_secure_below_el3) into
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
account, as documented for the plethora of bits in HCR_EL2.
7
Message-id: 20200512163904.10918-17-peter.maydell@linaro.org
8
---
9
target/arm/neon-dp.decode | 6 +++
10
target/arm/translate-neon.inc.c | 70 +++++++++++++++++++++++++++++++++
11
target/arm/translate.c | 42 +-------------------
12
3 files changed, 78 insertions(+), 40 deletions(-)
6
13
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
8
Message-id: 20181210150501.7990-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 67 +++++++++------------------------------
13
hw/intc/arm_gicv3_cpuif.c | 21 ++++++------
14
target/arm/helper.c | 66 ++++++++++++++++++++++++++++++++------
15
3 files changed, 83 insertions(+), 71 deletions(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
16
--- a/target/arm/neon-dp.decode
20
+++ b/target/arm/cpu.h
17
+++ b/target/arm/neon-dp.decode
21
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_secure(CPUARMState *env)
18
@@ -XXX,XX +XXX,XX @@ VCGE_fp_3s 1111 001 1 0 . 0 . .... .... 1110 ... 0 .... @3same_fp
22
}
19
VACGE_fp_3s 1111 001 1 0 . 0 . .... .... 1110 ... 1 .... @3same_fp
23
#endif
20
VCGT_fp_3s 1111 001 1 0 . 1 . .... .... 1110 ... 0 .... @3same_fp
24
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
+ * arm_hcr_el2_eff(): Return the effective value of HCR_EL2.
23
+VMIN_fp_3s 1111 001 0 0 . 1 . .... .... 1111 ... 0 .... @3same_fp
27
+ * E.g. when in secure state, fields in HCR_EL2 are suppressed,
24
VPMAX_fp_3s 1111 001 1 0 . 0 . .... .... 1111 ... 0 .... @3same_fp_q0
28
+ * "for all purposes other than a direct read or write access of HCR_EL2."
25
VPMIN_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 0 .... @3same_fp_q0
29
+ * Not included here is HCR_RW.
26
+VRECPS_fp_3s 1111 001 0 0 . 0 . .... .... 1111 ... 1 .... @3same_fp
30
+ */
27
+VRSQRTS_fp_3s 1111 001 0 0 . 1 . .... .... 1111 ... 1 .... @3same_fp
31
+uint64_t arm_hcr_el2_eff(CPUARMState *env);
28
+VMAXNM_fp_3s 1111 001 1 0 . 0 . .... .... 1111 ... 1 .... @3same_fp
32
+
29
+VMINNM_fp_3s 1111 001 1 0 . 1 . .... .... 1111 ... 1 .... @3same_fp
33
/* Return true if the specified exception level is running in AArch64 state. */
30
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
34
static inline bool arm_el_is_aa64(CPUARMState *env, int el)
35
{
36
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu);
37
# define TARGET_VIRT_ADDR_SPACE_BITS 32
38
#endif
39
40
-/**
41
- * arm_hcr_el2_imo(): Return the effective value of HCR_EL2.IMO.
42
- * Depending on the values of HCR_EL2.E2H and TGE, this may be
43
- * "behaves as 1 for all purposes other than direct read/write" or
44
- * "behaves as 0 for all purposes other than direct read/write"
45
- */
46
-static inline bool arm_hcr_el2_imo(CPUARMState *env)
47
-{
48
- switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) {
49
- case HCR_TGE:
50
- return true;
51
- case HCR_TGE | HCR_E2H:
52
- return false;
53
- default:
54
- return env->cp15.hcr_el2 & HCR_IMO;
55
- }
56
-}
57
-
58
-/**
59
- * arm_hcr_el2_fmo(): Return the effective value of HCR_EL2.FMO.
60
- */
61
-static inline bool arm_hcr_el2_fmo(CPUARMState *env)
62
-{
63
- switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) {
64
- case HCR_TGE:
65
- return true;
66
- case HCR_TGE | HCR_E2H:
67
- return false;
68
- default:
69
- return env->cp15.hcr_el2 & HCR_FMO;
70
- }
71
-}
72
-
73
-/**
74
- * arm_hcr_el2_amo(): Return the effective value of HCR_EL2.AMO.
75
- */
76
-static inline bool arm_hcr_el2_amo(CPUARMState *env)
77
-{
78
- switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) {
79
- case HCR_TGE:
80
- return true;
81
- case HCR_TGE | HCR_E2H:
82
- return false;
83
- default:
84
- return env->cp15.hcr_el2 & HCR_AMO;
85
- }
86
-}
87
-
88
static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
89
unsigned int target_el)
90
{
91
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
92
bool secure = arm_is_secure(env);
93
bool pstate_unmasked;
94
int8_t unmasked = 0;
95
+ uint64_t hcr_el2;
96
97
/* Don't take exceptions if they target a lower EL.
98
* This check should catch any exceptions that would not be taken but left
99
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
100
return false;
101
}
102
103
+ hcr_el2 = arm_hcr_el2_eff(env);
104
+
105
switch (excp_idx) {
106
case EXCP_FIQ:
107
pstate_unmasked = !(env->daif & PSTATE_F);
108
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
109
break;
110
111
case EXCP_VFIQ:
112
- if (secure || !arm_hcr_el2_fmo(env) || (env->cp15.hcr_el2 & HCR_TGE)) {
113
+ if (secure || !(hcr_el2 & HCR_FMO) || (hcr_el2 & HCR_TGE)) {
114
/* VFIQs are only taken when hypervized and non-secure. */
115
return false;
116
}
117
return !(env->daif & PSTATE_F);
118
case EXCP_VIRQ:
119
- if (secure || !arm_hcr_el2_imo(env) || (env->cp15.hcr_el2 & HCR_TGE)) {
120
+ if (secure || !(hcr_el2 & HCR_IMO) || (hcr_el2 & HCR_TGE)) {
121
/* VIRQs are only taken when hypervized and non-secure. */
122
return false;
123
}
124
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
125
* to the CPSR.F setting otherwise we further assess the state
126
* below.
127
*/
128
- hcr = arm_hcr_el2_fmo(env);
129
+ hcr = hcr_el2 & HCR_FMO;
130
scr = (env->cp15.scr_el3 & SCR_FIQ);
131
132
/* When EL3 is 32-bit, the SCR.FW bit controls whether the
133
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
134
* when setting the target EL, so it does not have a further
135
* affect here.
136
*/
137
- hcr = arm_hcr_el2_imo(env);
138
+ hcr = hcr_el2 & HCR_IMO;
139
scr = false;
140
break;
141
default:
142
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
143
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
144
--- a/hw/intc/arm_gicv3_cpuif.c
32
--- a/target/arm/translate-neon.inc.c
145
+++ b/hw/intc/arm_gicv3_cpuif.c
33
+++ b/target/arm/translate-neon.inc.c
146
@@ -XXX,XX +XXX,XX @@ static bool icv_access(CPUARMState *env, int hcr_flags)
34
@@ -XXX,XX +XXX,XX @@ DO_3S_FP(VCGE, gen_helper_neon_cge_f32, false)
147
* * access if NS EL1 and either IMO or FMO == 1:
35
DO_3S_FP(VCGT, gen_helper_neon_cgt_f32, false)
148
* CTLR, DIR, PMR, RPR
36
DO_3S_FP(VACGE, gen_helper_neon_acge_f32, false)
149
*/
37
DO_3S_FP(VACGT, gen_helper_neon_acgt_f32, false)
150
- bool flagmatch = ((hcr_flags & HCR_IMO) && arm_hcr_el2_imo(env)) ||
38
+DO_3S_FP(VMAX, gen_helper_vfp_maxs, false)
151
- ((hcr_flags & HCR_FMO) && arm_hcr_el2_fmo(env));
39
+DO_3S_FP(VMIN, gen_helper_vfp_mins, false)
152
+ uint64_t hcr_el2 = arm_hcr_el2_eff(env);
40
153
+ bool flagmatch = hcr_el2 & hcr_flags & (HCR_IMO | HCR_FMO);
41
static void gen_VMLA_fp_3s(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm,
154
42
TCGv_ptr fpstatus)
155
return flagmatch && arm_current_el(env) == 1
43
@@ -XXX,XX +XXX,XX @@ static void gen_VMLS_fp_3s(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm,
156
&& !arm_is_secure_below_el3(env);
44
DO_3S_FP(VMLA, gen_VMLA_fp_3s, true)
157
@@ -XXX,XX +XXX,XX @@ static void icc_dir_write(CPUARMState *env, const ARMCPRegInfo *ri,
45
DO_3S_FP(VMLS, gen_VMLS_fp_3s, true)
158
/* No need to include !IsSecure in route_*_to_el2 as it's only
46
159
* tested in cases where we know !IsSecure is true.
47
+static bool trans_VMAXNM_fp_3s(DisasContext *s, arg_3same *a)
160
*/
161
- route_fiq_to_el2 = arm_hcr_el2_fmo(env);
162
- route_irq_to_el2 = arm_hcr_el2_imo(env);
163
+ uint64_t hcr_el2 = arm_hcr_el2_eff(env);
164
+ route_fiq_to_el2 = hcr_el2 & HCR_FMO;
165
+ route_irq_to_el2 = hcr_el2 & HCR_IMO;
166
167
switch (arm_current_el(env)) {
168
case 3:
169
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gicv3_irqfiq_access(CPUARMState *env,
170
if ((env->cp15.scr_el3 & (SCR_FIQ | SCR_IRQ)) == (SCR_FIQ | SCR_IRQ)) {
171
switch (el) {
172
case 1:
173
- if (arm_is_secure_below_el3(env) ||
174
- (arm_hcr_el2_imo(env) == 0 && arm_hcr_el2_fmo(env) == 0)) {
175
+ /* Note that arm_hcr_el2_eff takes secure state into account. */
176
+ if ((arm_hcr_el2_eff(env) & (HCR_IMO | HCR_FMO)) == 0) {
177
r = CP_ACCESS_TRAP_EL3;
178
}
179
break;
180
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gicv3_dir_access(CPUARMState *env,
181
static CPAccessResult gicv3_sgi_access(CPUARMState *env,
182
const ARMCPRegInfo *ri, bool isread)
183
{
184
- if ((arm_hcr_el2_imo(env) || arm_hcr_el2_fmo(env)) &&
185
- arm_current_el(env) == 1 && !arm_is_secure_below_el3(env)) {
186
+ if (arm_current_el(env) == 1 &&
187
+ (arm_hcr_el2_eff(env) & (HCR_IMO | HCR_FMO)) != 0) {
188
/* Takes priority over a possible EL3 trap */
189
return CP_ACCESS_TRAP_EL2;
190
}
191
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gicv3_fiq_access(CPUARMState *env,
192
if (env->cp15.scr_el3 & SCR_FIQ) {
193
switch (el) {
194
case 1:
195
- if (arm_is_secure_below_el3(env) || !arm_hcr_el2_fmo(env)) {
196
+ if ((arm_hcr_el2_eff(env) & HCR_FMO) == 0) {
197
r = CP_ACCESS_TRAP_EL3;
198
}
199
break;
200
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gicv3_irq_access(CPUARMState *env,
201
if (env->cp15.scr_el3 & SCR_IRQ) {
202
switch (el) {
203
case 1:
204
- if (arm_is_secure_below_el3(env) || !arm_hcr_el2_imo(env)) {
205
+ if ((arm_hcr_el2_eff(env) & HCR_IMO) == 0) {
206
r = CP_ACCESS_TRAP_EL3;
207
}
208
break;
209
diff --git a/target/arm/helper.c b/target/arm/helper.c
210
index XXXXXXX..XXXXXXX 100644
211
--- a/target/arm/helper.c
212
+++ b/target/arm/helper.c
213
@@ -XXX,XX +XXX,XX @@ static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
214
static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
215
{
216
CPUState *cs = ENV_GET_CPU(env);
217
+ uint64_t hcr_el2 = arm_hcr_el2_eff(env);
218
uint64_t ret = 0;
219
220
- if (arm_hcr_el2_imo(env)) {
221
+ if (hcr_el2 & HCR_IMO) {
222
if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) {
223
ret |= CPSR_I;
224
}
225
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
226
}
227
}
228
229
- if (arm_hcr_el2_fmo(env)) {
230
+ if (hcr_el2 & HCR_FMO) {
231
if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) {
232
ret |= CPSR_F;
233
}
234
@@ -XXX,XX +XXX,XX @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
235
hcr_write(env, NULL, value);
236
}
237
238
+/*
239
+ * Return the effective value of HCR_EL2.
240
+ * Bits that are not included here:
241
+ * RW (read from SCR_EL3.RW as needed)
242
+ */
243
+uint64_t arm_hcr_el2_eff(CPUARMState *env)
244
+{
48
+{
245
+ uint64_t ret = env->cp15.hcr_el2;
49
+ if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
246
+
50
+ return false;
247
+ if (arm_is_secure_below_el3(env)) {
248
+ /*
249
+ * "This register has no effect if EL2 is not enabled in the
250
+ * current Security state". This is ARMv8.4-SecEL2 speak for
251
+ * !(SCR_EL3.NS==1 || SCR_EL3.EEL2==1).
252
+ *
253
+ * Prior to that, the language was "In an implementation that
254
+ * includes EL3, when the value of SCR_EL3.NS is 0 the PE behaves
255
+ * as if this field is 0 for all purposes other than a direct
256
+ * read or write access of HCR_EL2". With lots of enumeration
257
+ * on a per-field basis. In current QEMU, this is condition
258
+ * is arm_is_secure_below_el3.
259
+ *
260
+ * Since the v8.4 language applies to the entire register, and
261
+ * appears to be backward compatible, use that.
262
+ */
263
+ ret = 0;
264
+ } else if (ret & HCR_TGE) {
265
+ /* These bits are up-to-date as of ARMv8.4. */
266
+ if (ret & HCR_E2H) {
267
+ ret &= ~(HCR_VM | HCR_FMO | HCR_IMO | HCR_AMO |
268
+ HCR_BSU_MASK | HCR_DC | HCR_TWI | HCR_TWE |
269
+ HCR_TID0 | HCR_TID2 | HCR_TPCP | HCR_TPU |
270
+ HCR_TDZ | HCR_CD | HCR_ID | HCR_MIOCNCE);
271
+ } else {
272
+ ret |= HCR_FMO | HCR_IMO | HCR_AMO;
273
+ }
274
+ ret &= ~(HCR_SWIO | HCR_PTW | HCR_VF | HCR_VI | HCR_VSE |
275
+ HCR_FB | HCR_TID1 | HCR_TID3 | HCR_TSC | HCR_TACR |
276
+ HCR_TSW | HCR_TTLB | HCR_TVM | HCR_HCD | HCR_TRVM |
277
+ HCR_TLOR);
278
+ }
51
+ }
279
+
52
+
280
+ return ret;
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);
281
+}
59
+}
282
+
60
+
283
static const ARMCPRegInfo el2_cp_reginfo[] = {
61
+static bool trans_VMINNM_fp_3s(DisasContext *s, arg_3same *a)
284
{ .name = "HCR_EL2", .state = ARM_CP_STATE_AA64,
62
+{
285
.type = ARM_CP_IO,
63
+ if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
286
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
64
+ return false;
287
uint32_t cur_el, bool secure)
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)
288
{
116
{
289
CPUARMState *env = cs->env_ptr;
117
/* FP operations handled pairwise 32 bits at a time */
290
- int rw;
118
diff --git a/target/arm/translate.c b/target/arm/translate.c
291
- int scr;
119
index XXXXXXX..XXXXXXX 100644
292
- int hcr;
120
--- a/target/arm/translate.c
293
+ bool rw;
121
+++ b/target/arm/translate.c
294
+ bool scr;
122
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
295
+ bool hcr;
123
case NEON_3R_FLOAT_MULTIPLY:
296
int target_el;
124
case NEON_3R_FLOAT_CMP:
297
/* Is the highest EL AArch64? */
125
case NEON_3R_FLOAT_ACMP:
298
- int is64 = arm_feature(env, ARM_FEATURE_AARCH64);
126
+ case NEON_3R_FLOAT_MINMAX:
299
+ bool is64 = arm_feature(env, ARM_FEATURE_AARCH64);
127
+ case NEON_3R_FLOAT_MISC:
300
+ uint64_t hcr_el2;
128
/* Already handled by decodetree */
301
129
return 1;
302
if (arm_feature(env, ARM_FEATURE_EL3)) {
130
}
303
rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
131
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
304
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
132
return 1;
305
rw = is64;
133
}
306
}
134
switch (op) {
307
135
- case NEON_3R_FLOAT_MINMAX:
308
+ hcr_el2 = arm_hcr_el2_eff(env);
136
- if (u) {
309
switch (excp_idx) {
137
- return 1; /* VPMIN/VPMAX handled by decodetree */
310
case EXCP_IRQ:
138
- }
311
scr = ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ);
139
- break;
312
- hcr = arm_hcr_el2_imo(env);
140
- case NEON_3R_FLOAT_MISC:
313
+ hcr = hcr_el2 & HCR_IMO;
141
- /* VMAXNM/VMINNM in ARMv8 */
314
break;
142
- if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
315
case EXCP_FIQ:
143
- return 1;
316
scr = ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ);
144
- }
317
- hcr = arm_hcr_el2_fmo(env);
145
- break;
318
+ hcr = hcr_el2 & HCR_FMO;
146
case NEON_3R_VFM_VQRDMLSH:
319
break;
147
if (!dc_isar_feature(aa32_simdfmac, s)) {
320
default:
148
return 1;
321
scr = ((env->cp15.scr_el3 & SCR_EA) == SCR_EA);
149
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
322
- hcr = arm_hcr_el2_amo(env);
150
tmp = neon_load_reg(rn, pass);
323
+ hcr = hcr_el2 & HCR_AMO;
151
tmp2 = neon_load_reg(rm, pass);
324
break;
152
switch (op) {
325
};
153
- case NEON_3R_FLOAT_MINMAX:
326
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 */
327
--
185
--
328
2.19.2
186
2.20.1
329
187
330
188
diff view generated by jsdifflib
1
From: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
1
Convert the Neon floating point VFMA and VFMS insn to decodetree.
2
2
These are the last insns in the 3-reg-same group so we can
3
Use DeviceClass rather than SysBusDeviceClass in
3
remove all the support/loop code from the old decoder.
4
milkymist_softusb_class_init().
4
5
6
Cc: michael@walle.cc
7
8
Signed-off-by: Mao Zhongyi <maozhongyi@cmss.chinamobile.com>
9
Signed-off-by: Zhang Shengju <zhangshengju@cmss.chinamobile.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20181130093852.20739-9-maozhongyi@cmss.chinamobile.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200512163904.10918-18-peter.maydell@linaro.org
13
---
8
---
14
hw/input/milkymist-softusb.c | 16 +++++++---------
9
target/arm/neon-dp.decode | 3 +
15
1 file changed, 7 insertions(+), 9 deletions(-)
10
target/arm/translate-neon.inc.c | 41 ++++++++
16
11
target/arm/translate.c | 176 +-------------------------------
17
diff --git a/hw/input/milkymist-softusb.c b/hw/input/milkymist-softusb.c
12
3 files changed, 46 insertions(+), 174 deletions(-)
13
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/input/milkymist-softusb.c
16
--- a/target/arm/neon-dp.decode
20
+++ b/hw/input/milkymist-softusb.c
17
+++ b/target/arm/neon-dp.decode
21
@@ -XXX,XX +XXX,XX @@ static void milkymist_softusb_reset(DeviceState *d)
18
@@ -XXX,XX +XXX,XX @@ SHA256H2_3s 1111 001 1 0 . 01 .... .... 1100 . 1 . 0 .... \
22
s->regs[R_CTRL] = CTRL_RESET;
19
SHA256SU1_3s 1111 001 1 0 . 10 .... .... 1100 . 1 . 0 .... \
20
vm=%vm_dp vn=%vn_dp vd=%vd_dp
21
22
+VFMA_fp_3s 1111 001 0 0 . 0 . .... .... 1100 ... 1 .... @3same_fp
23
+VFMS_fp_3s 1111 001 0 0 . 1 . .... .... 1100 ... 1 .... @3same_fp
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);
23
}
34
}
24
35
25
-static int milkymist_softusb_init(SysBusDevice *dev)
36
+static void gen_VFMA_fp_3s(TCGv_i32 vd, TCGv_i32 vn, TCGv_i32 vm,
26
+static void milkymist_softusb_realize(DeviceState *dev, Error **errp)
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)
27
{
78
{
28
MilkymistSoftUsbState *s = MILKYMIST_SOFTUSB(dev);
79
/* FP operations handled pairwise 32 bits at a time */
29
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
80
diff --git a/target/arm/translate.c b/target/arm/translate.c
30
81
index XXXXXXX..XXXXXXX 100644
31
- sysbus_init_irq(dev, &s->irq);
82
--- a/target/arm/translate.c
32
+ sysbus_init_irq(sbd, &s->irq);
83
+++ b/target/arm/translate.c
33
84
@@ -XXX,XX +XXX,XX @@ static void gen_neon_narrow_op(int op, int u, int size,
34
memory_region_init_io(&s->regs_region, OBJECT(s), &softusb_mmio_ops, s,
85
}
35
"milkymist-softusb", R_MAX * 4);
36
- sysbus_init_mmio(dev, &s->regs_region);
37
+ sysbus_init_mmio(sbd, &s->regs_region);
38
39
/* register pmem and dmem */
40
memory_region_init_ram_nomigrate(&s->pmem, OBJECT(s), "milkymist-softusb.pmem",
41
s->pmem_size, &error_fatal);
42
vmstate_register_ram_global(&s->pmem);
43
s->pmem_ptr = memory_region_get_ram_ptr(&s->pmem);
44
- sysbus_init_mmio(dev, &s->pmem);
45
+ sysbus_init_mmio(sbd, &s->pmem);
46
memory_region_init_ram_nomigrate(&s->dmem, OBJECT(s), "milkymist-softusb.dmem",
47
s->dmem_size, &error_fatal);
48
vmstate_register_ram_global(&s->dmem);
49
s->dmem_ptr = memory_region_get_ram_ptr(&s->dmem);
50
- sysbus_init_mmio(dev, &s->dmem);
51
+ sysbus_init_mmio(sbd, &s->dmem);
52
53
hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain);
54
hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain);
55
-
56
- return 0;
57
}
86
}
58
87
59
static const VMStateDescription vmstate_milkymist_softusb = {
88
-/* Symbolic constants for op fields for Neon 3-register same-length.
60
@@ -XXX,XX +XXX,XX @@ static Property milkymist_softusb_properties[] = {
89
- * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
61
static void milkymist_softusb_class_init(ObjectClass *klass, void *data)
90
- * table A7-9.
62
{
91
- */
63
DeviceClass *dc = DEVICE_CLASS(klass);
92
-#define NEON_3R_VHADD 0
64
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
93
-#define NEON_3R_VQADD 1
65
94
-#define NEON_3R_VRHADD 2
66
- k->init = milkymist_softusb_init;
95
-#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
67
+ dc->realize = milkymist_softusb_realize;
96
-#define NEON_3R_VHSUB 4
68
dc->reset = milkymist_softusb_reset;
97
-#define NEON_3R_VQSUB 5
69
dc->vmsd = &vmstate_milkymist_softusb;
98
-#define NEON_3R_VCGT 6
70
dc->props = milkymist_softusb_properties;
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
- }
188
- /* VQRDMLSH : handled by decodetree */
189
- return 1;
190
-
191
- case NEON_3R_VADD_VSUB:
192
- case NEON_3R_LOGIC:
193
- case NEON_3R_VMAX:
194
- case NEON_3R_VMIN:
195
- case NEON_3R_VTST_VCEQ:
196
- case NEON_3R_VCGT:
197
- case NEON_3R_VCGE:
198
- case NEON_3R_VQADD:
199
- case NEON_3R_VQSUB:
200
- case NEON_3R_VMUL:
201
- case NEON_3R_VML:
202
- case NEON_3R_VSHL:
203
- case NEON_3R_SHA:
204
- case NEON_3R_VHADD:
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
- }
235
- break;
236
- default:
237
- break;
238
- }
239
-
240
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
241
-
242
- /* Elementwise. */
243
- tmp = neon_load_reg(rn, pass);
244
- tmp2 = neon_load_reg(rm, pass);
245
- switch (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
- }
255
- gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
256
- tcg_temp_free_i32(tmp3);
257
- tcg_temp_free_ptr(fpstatus);
258
- break;
259
- }
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. */
71
--
274
--
72
2.19.2
275
2.20.1
73
276
74
277
diff view generated by jsdifflib