1
Most of this is the Neon decodetree patches, followed by Edgar's versal cleanups.
1
Nothing earth-shaking in here, just a lot of refactoring and cleanup
2
and a few bugfixes. I suspect I'll have another pullreq to come in
3
the early part of next week...
2
4
3
thanks
5
The following changes since commit 19591e9e0938ea5066984553c256a043bd5d822f:
4
-- PMM
5
6
6
7
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging (2020-08-27 16:59:02 +0100)
7
The following changes since commit 2ef486e76d64436be90f7359a3071fb2a56ce835:
8
9
Merge remote-tracking branch 'remotes/marcel/tags/rdma-pull-request' into staging (2020-05-03 14:12:56 +0100)
10
8
11
are available in the Git repository at:
9
are available in the Git repository at:
12
10
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200504
11
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200828
14
12
15
for you to fetch changes up to 9aefc6cf9b73f66062d2f914a0136756e7a28211:
13
for you to fetch changes up to ed78849d9711805bda37ee026018d6ee7a606d0e:
16
14
17
target/arm: Move gen_ function typedefs to translate.h (2020-05-04 12:59:26 +0100)
15
target/arm: Convert sq{, r}dmulh to gvec for aa64 advsimd (2020-08-28 10:02:50 +0100)
18
16
19
----------------------------------------------------------------
17
----------------------------------------------------------------
20
target-arm queue:
18
target-arm queue:
21
* Start of conversion of Neon insns to decodetree
19
* target/arm: Cleanup and refactoring preparatory to SVE2
22
* versal board: support SD and RTC
20
* armsse: Define ARMSSEClass correctly
23
* Implement ARMv8.2-TTS2UXN
21
* hw/misc/unimp: Improve information provided in log messages
24
* Make VQDMULL undefined when U=1
22
* hw/qdev-clock: Avoid calling qdev_connect_clock_in after DeviceRealize
25
* Some minor code cleanups
23
* hw/arm/xilinx_zynq: Call qdev_connect_clock_in() before DeviceRealize
24
* hw/net/allwinner-sun8i-emac: Use AddressSpace for DMA transfers
25
* hw/sd/allwinner-sdhost: Use AddressSpace for DMA transfers
26
* target/arm: Fill in the WnR syndrome bit in mte_check_fail
27
* target/arm: Clarify HCR_EL2 ARMCPRegInfo type
28
* hw/arm/musicpal: Use AddressSpace for DMA transfers
29
* hw/clock: Minor cleanups
30
* hw/arm/sbsa-ref: fix typo breaking PCIe IRQs
26
31
27
----------------------------------------------------------------
32
----------------------------------------------------------------
28
Edgar E. Iglesias (11):
33
Eduardo Habkost (1):
29
hw/arm: versal: Remove inclusion of arm_gicv3_common.h
34
armsse: Define ARMSSEClass correctly
30
hw/arm: versal: Move misplaced comment
31
hw/arm: versal-virt: Fix typo xlnx-ve -> xlnx-versal
32
hw/arm: versal: Embed the UARTs into the SoC type
33
hw/arm: versal: Embed the GEMs into the SoC type
34
hw/arm: versal: Embed the ADMAs into the SoC type
35
hw/arm: versal: Embed the APUs into the SoC type
36
hw/arm: versal: Add support for SD
37
hw/arm: versal: Add support for the RTC
38
hw/arm: versal-virt: Add support for SD
39
hw/arm: versal-virt: Add support for the RTC
40
35
41
Fredrik Strupe (1):
36
Graeme Gregory (1):
42
target/arm: Make VQDMULL undefined when U=1
37
hw/arm/sbsa-ref: fix typo breaking PCIe IRQs
43
38
44
Peter Maydell (25):
39
Philippe Mathieu-Daudé (14):
45
target/arm: Don't use a TLB for ARMMMUIdx_Stage2
40
hw/clock: Remove unused clock_init*() functions
46
target/arm: Use enum constant in get_phys_addr_lpae() call
41
hw/clock: Let clock_set() return boolean value
47
target/arm: Add new 's1_is_el0' argument to get_phys_addr_lpae()
42
hw/clock: Only propagate clock changes if the clock is changed
48
target/arm: Implement ARMv8.2-TTS2UXN
43
hw/arm/musicpal: Use AddressSpace for DMA transfers
49
target/arm: Use correct variable for setting 'max' cpu's ID_AA64DFR0
44
target/arm: Clarify HCR_EL2 ARMCPRegInfo type
50
target/arm/translate-vfp.inc.c: Remove duplicate simd_r32 check
45
hw/sd/allwinner-sdhost: Use AddressSpace for DMA transfers
51
target/arm: Don't allow Thumb Neon insns without FEATURE_NEON
46
hw/net/allwinner-sun8i-emac: Use AddressSpace for DMA transfers
52
target/arm: Add stubs for AArch32 Neon decodetree
47
hw/arm/xilinx_zynq: Uninline cadence_uart_create()
53
target/arm: Convert VCMLA (vector) to decodetree
48
hw/arm/xilinx_zynq: Call qdev_connect_clock_in() before DeviceRealize
54
target/arm: Convert VCADD (vector) to decodetree
49
hw/qdev-clock: Uninline qdev_connect_clock_in()
55
target/arm: Convert V[US]DOT (vector) to decodetree
50
hw/qdev-clock: Avoid calling qdev_connect_clock_in after DeviceRealize
56
target/arm: Convert VFM[AS]L (vector) to decodetree
51
hw/misc/unimp: Display value after offset
57
target/arm: Convert VCMLA (scalar) to decodetree
52
hw/misc/unimp: Display the value with width of the access size
58
target/arm: Convert V[US]DOT (scalar) to decodetree
53
hw/misc/unimp: Display the offset with width of the region size
59
target/arm: Convert VFM[AS]L (scalar) to decodetree
60
target/arm: Convert Neon load/store multiple structures to decodetree
61
target/arm: Convert Neon 'load single structure to all lanes' to decodetree
62
target/arm: Convert Neon 'load/store single structure' to decodetree
63
target/arm: Convert Neon 3-reg-same VADD/VSUB to decodetree
64
target/arm: Convert Neon 3-reg-same logic ops to decodetree
65
target/arm: Convert Neon 3-reg-same VMAX/VMIN to decodetree
66
target/arm: Convert Neon 3-reg-same comparisons to decodetree
67
target/arm: Convert Neon 3-reg-same VQADD/VQSUB to decodetree
68
target/arm: Convert Neon 3-reg-same VMUL, VMLA, VMLS, VSHL to decodetree
69
target/arm: Move gen_ function typedefs to translate.h
70
54
71
Philippe Mathieu-Daudé (2):
55
Richard Henderson (19):
72
hw/arm/mps2-tz: Use TYPE_IOTKIT instead of hardcoded string
56
target/arm: Pass the entire mte descriptor to mte_check_fail
73
target/arm: Use uint64_t for midr field in CPU state struct
57
target/arm: Fill in the WnR syndrome bit in mte_check_fail
58
qemu/int128: Add int128_lshift
59
target/arm: Split out gen_gvec_fn_zz
60
target/arm: Split out gen_gvec_fn_zzz, do_zzz_fn
61
target/arm: Rearrange {sve,fp}_check_access assert
62
target/arm: Merge do_vector2_p into do_mov_p
63
target/arm: Clean up 4-operand predicate expansion
64
target/arm: Use tcg_gen_gvec_bitsel for trans_SEL_pppp
65
target/arm: Split out gen_gvec_ool_zzzp
66
target/arm: Merge helper_sve_clr_* and helper_sve_movz_*
67
target/arm: Split out gen_gvec_ool_zzp
68
target/arm: Split out gen_gvec_ool_zzz
69
target/arm: Split out gen_gvec_ool_zz
70
target/arm: Tidy SVE tszimm shift formats
71
target/arm: Generalize inl_qrdmlah_* helper functions
72
target/arm: Convert integer multiply (indexed) to gvec for aa64 advsimd
73
target/arm: Convert integer multiply-add (indexed) to gvec for aa64 advsimd
74
target/arm: Convert sq{, r}dmulh to gvec for aa64 advsimd
74
75
75
include/hw/arm/xlnx-versal.h | 31 +-
76
include/hw/arm/armsse.h | 2 +-
76
target/arm/cpu-param.h | 2 +-
77
include/hw/char/cadence_uart.h | 17 --
77
target/arm/cpu.h | 38 ++-
78
include/hw/clock.h | 30 +--
78
target/arm/translate-a64.h | 9 -
79
include/hw/misc/unimp.h | 1 +
79
target/arm/translate.h | 26 ++
80
include/hw/net/allwinner-sun8i-emac.h | 6 +
80
target/arm/neon-dp.decode | 86 +++++
81
include/hw/qdev-clock.h | 8 +-
81
target/arm/neon-ls.decode | 52 +++
82
include/hw/sd/allwinner-sdhost.h | 6 +
82
target/arm/neon-shared.decode | 66 ++++
83
include/qemu/int128.h | 16 ++
83
hw/arm/mps2-tz.c | 2 +-
84
target/arm/helper-sve.h | 5 -
84
hw/arm/xlnx-versal-virt.c | 74 ++++-
85
target/arm/helper.h | 28 +++
85
hw/arm/xlnx-versal.c | 115 +++++--
86
target/arm/translate.h | 1 +
86
target/arm/cpu.c | 3 +-
87
target/arm/sve.decode | 35 ++-
87
target/arm/cpu64.c | 8 +-
88
hw/arm/allwinner-a10.c | 2 +
88
target/arm/helper.c | 183 ++++------
89
hw/arm/allwinner-h3.c | 4 +
89
target/arm/translate-a64.c | 17 -
90
hw/arm/armsse.c | 1 +
90
target/arm/translate-neon.inc.c | 714 +++++++++++++++++++++++++++++++++++++++
91
hw/arm/musicpal.c | 45 ++--
91
target/arm/translate-vfp.inc.c | 6 -
92
hw/arm/sbsa-ref.c | 2 +-
92
target/arm/translate.c | 716 +++-------------------------------------
93
hw/arm/xilinx_zynq.c | 24 +-
93
target/arm/Makefile.objs | 18 +
94
hw/core/clock.c | 7 +-
94
19 files changed, 1302 insertions(+), 864 deletions(-)
95
hw/core/qdev-clock.c | 6 +
95
create mode 100644 target/arm/neon-dp.decode
96
hw/misc/unimp.c | 14 +-
96
create mode 100644 target/arm/neon-ls.decode
97
hw/net/allwinner-sun8i-emac.c | 46 ++--
97
create mode 100644 target/arm/neon-shared.decode
98
hw/sd/allwinner-sdhost.c | 37 +++-
98
create mode 100644 target/arm/translate-neon.inc.c
99
target/arm/helper.c | 1 -
100
target/arm/mte_helper.c | 19 +-
101
target/arm/sve_helper.c | 70 ++----
102
target/arm/translate-a64.c | 110 ++++++++--
103
target/arm/translate-sve.c | 399 ++++++++++++++--------------------
104
target/arm/vec_helper.c | 182 +++++++++++-----
105
29 files changed, 629 insertions(+), 495 deletions(-)
99
106
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Graeme Gregory <graeme@nuviainc.com>
2
2
3
Fix typo xlnx-ve -> xlnx-versal.
3
Fixing a typo in a previous patch that translated an "i" to a 1
4
and therefore breaking the allocation of PCIe interrupts. This was
5
discovered when virtio-net-pci devices ceased to function correctly.
4
6
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Fixes: 48ba18e6d3f3 ("hw/arm/sbsa-ref: Simplify by moving the gic in the machine state")
9
Signed-off-by: Graeme Gregory <graeme@nuviainc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
11
Message-id: 20200821083853.356490-1-graeme@nuviainc.com
9
Message-id: 20200427181649.26851-4-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
hw/arm/xlnx-versal-virt.c | 2 +-
14
hw/arm/sbsa-ref.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 1 insertion(+), 1 deletion(-)
14
16
15
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
17
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal-virt.c
19
--- a/hw/arm/sbsa-ref.c
18
+++ b/hw/arm/xlnx-versal-virt.c
20
+++ b/hw/arm/sbsa-ref.c
19
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
21
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms)
20
psci_conduit = QEMU_PSCI_CONDUIT_SMC;
22
23
for (i = 0; i < GPEX_NUM_IRQS; i++) {
24
sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
25
- qdev_get_gpio_in(sms->gic, irq + 1));
26
+ qdev_get_gpio_in(sms->gic, irq + i));
27
gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
21
}
28
}
22
29
23
- sysbus_init_child_obj(OBJECT(machine), "xlnx-ve", &s->soc,
24
+ sysbus_init_child_obj(OBJECT(machine), "xlnx-versal", &s->soc,
25
sizeof(s->soc), TYPE_XLNX_VERSAL);
26
object_property_set_link(OBJECT(&s->soc), OBJECT(machine->ram),
27
"ddr", &error_abort);
28
--
30
--
29
2.20.1
31
2.20.1
30
32
31
33
diff view generated by jsdifflib
1
Convert the Neon VMUL, VMLA, VMLS and VSHL insns in the
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
3-reg-same grouping to decodetree.
3
2
3
clock_init*() inlined funtions are simple wrappers around
4
clock_set*() and are not used. Remove them in favor of clock_set*().
5
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200806123858.30058-2-f4bug@amsat.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-20-peter.maydell@linaro.org
7
---
10
---
8
target/arm/neon-dp.decode | 9 +++++++
11
include/hw/clock.h | 13 -------------
9
target/arm/translate-neon.inc.c | 44 +++++++++++++++++++++++++++++++++
12
1 file changed, 13 deletions(-)
10
target/arm/translate.c | 28 +++------------------
11
3 files changed, 56 insertions(+), 25 deletions(-)
12
13
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
diff --git a/include/hw/clock.h b/include/hw/clock.h
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
--- a/include/hw/clock.h
16
+++ b/target/arm/neon-dp.decode
17
+++ b/include/hw/clock.h
17
@@ -XXX,XX +XXX,XX @@ VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
18
@@ -XXX,XX +XXX,XX @@ static inline bool clock_is_enabled(const Clock *clk)
18
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
19
return clock_get(clk) != 0;
19
VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
20
}
20
21
21
+VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same
22
-static inline void clock_init(Clock *clk, uint64_t value)
22
+VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same
23
-{
23
+
24
- clock_set(clk, value);
24
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
25
-}
25
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
26
-static inline void clock_init_hz(Clock *clk, uint64_t value)
26
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
27
-{
27
@@ -XXX,XX +XXX,XX @@ VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
28
- clock_set_hz(clk, value);
28
29
-}
29
VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
30
-static inline void clock_init_ns(Clock *clk, uint64_t value)
30
VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
31
-{
31
+
32
- clock_set_ns(clk, value);
32
+VMLA_3s 1111 001 0 0 . .. .... .... 1001 . . . 0 .... @3same
33
-}
33
+VMLS_3s 1111 001 1 0 . .. .... .... 1001 . . . 0 .... @3same
34
+
35
+VMUL_3s 1111 001 0 0 . .. .... .... 1001 . . . 1 .... @3same
36
+VMUL_p_3s 1111 001 1 0 . .. .... .... 1001 . . . 1 .... @3same
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-neon.inc.c
40
+++ b/target/arm/translate-neon.inc.c
41
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
42
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
43
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
44
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
45
+DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
46
47
#define DO_3SAME_CMP(INSN, COND) \
48
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
49
@@ -XXX,XX +XXX,XX @@ DO_3SAME_GVEC4(VQADD_S, sqadd_op)
50
DO_3SAME_GVEC4(VQADD_U, uqadd_op)
51
DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
52
DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
53
+
54
+static void gen_VMUL_p_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
55
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
56
+{
57
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz,
58
+ 0, gen_helper_gvec_pmul_b);
59
+}
60
+
61
+static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
62
+{
63
+ if (a->size != 0) {
64
+ return false;
65
+ }
66
+ return do_3same(s, a, gen_VMUL_p_3s);
67
+}
68
+
69
+#define DO_3SAME_GVEC3_NO_SZ_3(INSN, OPARRAY) \
70
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
71
+ uint32_t rn_ofs, uint32_t rm_ofs, \
72
+ uint32_t oprsz, uint32_t maxsz) \
73
+ { \
74
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
75
+ oprsz, maxsz, &OPARRAY[vece]); \
76
+ } \
77
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
78
+
79
+
80
+DO_3SAME_GVEC3_NO_SZ_3(VMLA, mla_op)
81
+DO_3SAME_GVEC3_NO_SZ_3(VMLS, mls_op)
82
+
83
+#define DO_3SAME_GVEC3_SHIFT(INSN, OPARRAY) \
84
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
85
+ uint32_t rn_ofs, uint32_t rm_ofs, \
86
+ uint32_t oprsz, uint32_t maxsz) \
87
+ { \
88
+ /* Note the operation is vshl vd,vm,vn */ \
89
+ tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, \
90
+ oprsz, maxsz, &OPARRAY[vece]); \
91
+ } \
92
+ DO_3SAME(INSN, gen_##INSN##_3s)
93
+
94
+DO_3SAME_GVEC3_SHIFT(VSHL_S, sshl_op)
95
+DO_3SAME_GVEC3_SHIFT(VSHL_U, ushl_op)
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 int disas_neon_data_insn(DisasContext *s, uint32_t insn)
101
}
102
return 1;
103
104
- case NEON_3R_VMUL: /* VMUL */
105
- if (u) {
106
- /* Polynomial case allows only P8. */
107
- if (size != 0) {
108
- return 1;
109
- }
110
- tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
111
- 0, gen_helper_gvec_pmul_b);
112
- } else {
113
- tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
114
- vec_size, vec_size);
115
- }
116
- return 0;
117
-
34
-
118
- case NEON_3R_VML: /* VMLA, VMLS */
35
#endif /* QEMU_HW_CLOCK_H */
119
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
120
- u ? &mls_op[size] : &mla_op[size]);
121
- return 0;
122
-
123
- case NEON_3R_VSHL:
124
- /* Note the operation is vshl vd,vm,vn */
125
- tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
126
- u ? &ushl_op[size] : &sshl_op[size]);
127
- return 0;
128
-
129
case NEON_3R_VADD_VSUB:
130
case NEON_3R_LOGIC:
131
case NEON_3R_VMAX:
132
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
133
case NEON_3R_VCGE:
134
case NEON_3R_VQADD:
135
case NEON_3R_VQSUB:
136
+ case NEON_3R_VMUL:
137
+ case NEON_3R_VML:
138
+ case NEON_3R_VSHL:
139
/* Already handled by decodetree */
140
return 1;
141
}
142
--
36
--
143
2.20.1
37
2.20.1
144
38
145
39
diff view generated by jsdifflib
1
Convert the Neon "load single structure to all lanes" insns to
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
decodetree.
3
2
3
Let clock_set() return a boolean value whether the clock
4
has been updated or not.
5
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200806123858.30058-3-f4bug@amsat.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-13-peter.maydell@linaro.org
7
---
10
---
8
target/arm/neon-ls.decode | 5 +++
11
include/hw/clock.h | 12 +++++++-----
9
target/arm/translate-neon.inc.c | 73 +++++++++++++++++++++++++++++++++
12
hw/core/clock.c | 7 ++++++-
10
target/arm/translate.c | 55 +------------------------
13
2 files changed, 13 insertions(+), 6 deletions(-)
11
3 files changed, 80 insertions(+), 53 deletions(-)
12
14
13
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
15
diff --git a/include/hw/clock.h b/include/hw/clock.h
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-ls.decode
17
--- a/include/hw/clock.h
16
+++ b/target/arm/neon-ls.decode
18
+++ b/include/hw/clock.h
17
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ void clock_set_source(Clock *clk, Clock *src);
18
20
* @value: the clock's value, 0 means unclocked
19
VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
21
*
20
vd=%vd_dp
22
* Set the local cached period value of @clk to @value.
21
+
23
+ *
22
+# Neon load single element to all lanes
24
+ * @return: true if the clock is changed.
23
+
25
*/
24
+VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
26
-void clock_set(Clock *clk, uint64_t value);
25
+ vd=%vd_dp
27
+bool clock_set(Clock *clk, uint64_t value);
26
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
29
-static inline void clock_set_hz(Clock *clk, unsigned hz)
30
+static inline bool clock_set_hz(Clock *clk, unsigned hz)
31
{
32
- clock_set(clk, CLOCK_PERIOD_FROM_HZ(hz));
33
+ return clock_set(clk, CLOCK_PERIOD_FROM_HZ(hz));
34
}
35
36
-static inline void clock_set_ns(Clock *clk, unsigned ns)
37
+static inline bool clock_set_ns(Clock *clk, unsigned ns)
38
{
39
- clock_set(clk, CLOCK_PERIOD_FROM_NS(ns));
40
+ return clock_set(clk, CLOCK_PERIOD_FROM_NS(ns));
41
}
42
43
/**
44
diff --git a/hw/core/clock.c b/hw/core/clock.c
27
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/translate-neon.inc.c
46
--- a/hw/core/clock.c
29
+++ b/target/arm/translate-neon.inc.c
47
+++ b/hw/core/clock.c
30
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
48
@@ -XXX,XX +XXX,XX @@ void clock_clear_callback(Clock *clk)
31
gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
49
clock_set_callback(clk, NULL, NULL);
32
return true;
33
}
50
}
34
+
51
35
+static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
52
-void clock_set(Clock *clk, uint64_t period)
36
+{
53
+bool clock_set(Clock *clk, uint64_t period)
37
+ /* Neon load single structure to all lanes */
54
{
38
+ int reg, stride, vec_size;
55
+ if (clk->period == period) {
39
+ int vd = a->vd;
40
+ int size = a->size;
41
+ int nregs = a->n + 1;
42
+ TCGv_i32 addr, tmp;
43
+
44
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
45
+ return false;
56
+ return false;
46
+ }
57
+ }
47
+
58
trace_clock_set(CLOCK_PATH(clk), CLOCK_PERIOD_TO_NS(clk->period),
48
+ /* UNDEF accesses to D16-D31 if they don't exist */
59
CLOCK_PERIOD_TO_NS(period));
49
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
60
clk->period = period;
50
+ return false;
51
+ }
52
+
53
+ if (size == 3) {
54
+ if (nregs != 4 || a->a == 0) {
55
+ return false;
56
+ }
57
+ /* For VLD4 size == 3 a == 1 means 32 bits at 16 byte alignment */
58
+ size = 2;
59
+ }
60
+ if (nregs == 1 && a->a == 1 && size == 0) {
61
+ return false;
62
+ }
63
+ if (nregs == 3 && a->a == 1) {
64
+ return false;
65
+ }
66
+
67
+ if (!vfp_access_check(s)) {
68
+ return true;
69
+ }
70
+
71
+ /*
72
+ * VLD1 to all lanes: T bit indicates how many Dregs to write.
73
+ * VLD2/3/4 to all lanes: T bit indicates register stride.
74
+ */
75
+ stride = a->t ? 2 : 1;
76
+ vec_size = nregs == 1 ? stride * 8 : 8;
77
+
78
+ tmp = tcg_temp_new_i32();
79
+ addr = tcg_temp_new_i32();
80
+ load_reg_var(s, addr, a->rn);
81
+ for (reg = 0; reg < nregs; reg++) {
82
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
83
+ s->be_data | size);
84
+ if ((vd & 1) && vec_size == 16) {
85
+ /*
86
+ * We cannot write 16 bytes at once because the
87
+ * destination is unaligned.
88
+ */
89
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
90
+ 8, 8, tmp);
91
+ tcg_gen_gvec_mov(0, neon_reg_offset(vd + 1, 0),
92
+ neon_reg_offset(vd, 0), 8, 8);
93
+ } else {
94
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
95
+ vec_size, vec_size, tmp);
96
+ }
97
+ tcg_gen_addi_i32(addr, addr, 1 << size);
98
+ vd += stride;
99
+ }
100
+ tcg_temp_free_i32(tmp);
101
+ tcg_temp_free_i32(addr);
102
+
103
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << size) * nregs);
104
+
61
+
105
+ return true;
62
+ return true;
106
+}
63
}
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
64
108
index XXXXXXX..XXXXXXX 100644
65
static void clock_propagate_period(Clock *clk, bool call_callbacks)
109
--- a/target/arm/translate.c
110
+++ b/target/arm/translate.c
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
112
int size;
113
int reg;
114
int load;
115
- int vec_size;
116
TCGv_i32 addr;
117
TCGv_i32 tmp;
118
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
120
} else {
121
size = (insn >> 10) & 3;
122
if (size == 3) {
123
- /* Load single element to all lanes. */
124
- int a = (insn >> 4) & 1;
125
- if (!load) {
126
- return 1;
127
- }
128
- size = (insn >> 6) & 3;
129
- nregs = ((insn >> 8) & 3) + 1;
130
-
131
- if (size == 3) {
132
- if (nregs != 4 || a == 0) {
133
- return 1;
134
- }
135
- /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
136
- size = 2;
137
- }
138
- if (nregs == 1 && a == 1 && size == 0) {
139
- return 1;
140
- }
141
- if (nregs == 3 && a == 1) {
142
- return 1;
143
- }
144
- addr = tcg_temp_new_i32();
145
- load_reg_var(s, addr, rn);
146
-
147
- /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
148
- * VLD2/3/4 to all lanes: bit 5 indicates register stride.
149
- */
150
- stride = (insn & (1 << 5)) ? 2 : 1;
151
- vec_size = nregs == 1 ? stride * 8 : 8;
152
-
153
- tmp = tcg_temp_new_i32();
154
- for (reg = 0; reg < nregs; reg++) {
155
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
156
- s->be_data | size);
157
- if ((rd & 1) && vec_size == 16) {
158
- /* We cannot write 16 bytes at once because the
159
- * destination is unaligned.
160
- */
161
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
162
- 8, 8, tmp);
163
- tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
164
- neon_reg_offset(rd, 0), 8, 8);
165
- } else {
166
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
167
- vec_size, vec_size, tmp);
168
- }
169
- tcg_gen_addi_i32(addr, addr, 1 << size);
170
- rd += stride;
171
- }
172
- tcg_temp_free_i32(tmp);
173
- tcg_temp_free_i32(addr);
174
- stride = (1 << size) * nregs;
175
+ /* Load single element to all lanes -- handled by decodetree */
176
+ return 1;
177
} else {
178
/* Single element. */
179
int idx = (insn >> 4) & 0xf;
180
--
66
--
181
2.20.1
67
2.20.1
182
68
183
69
diff view generated by jsdifflib
1
Convert the Neon VQADD/VQSUB insns in the 3-reg-same grouping
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
to decodetree.
3
2
3
Avoid propagating the clock change when the clock does not change.
4
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200806123858.30058-4-f4bug@amsat.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-19-peter.maydell@linaro.org
7
---
9
---
8
target/arm/neon-dp.decode | 6 ++++++
10
include/hw/clock.h | 5 +++--
9
target/arm/translate-neon.inc.c | 15 +++++++++++++++
11
1 file changed, 3 insertions(+), 2 deletions(-)
10
target/arm/translate.c | 14 ++------------
11
3 files changed, 23 insertions(+), 12 deletions(-)
12
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
diff --git a/include/hw/clock.h b/include/hw/clock.h
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
15
--- a/include/hw/clock.h
16
+++ b/target/arm/neon-dp.decode
16
+++ b/include/hw/clock.h
17
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ void clock_propagate(Clock *clk);
18
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
18
*/
19
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
19
static inline void clock_update(Clock *clk, uint64_t value)
20
20
{
21
+VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
21
- clock_set(clk, value);
22
+VQADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 1 .... @3same
22
- clock_propagate(clk);
23
+
23
+ if (clock_set(clk, value)) {
24
@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
24
+ clock_propagate(clk);
25
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
25
+ }
26
27
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
28
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
29
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
30
31
+VQSUB_S_3s 1111 001 0 0 . .. .... .... 0010 . . . 1 .... @3same
32
+VQSUB_U_3s 1111 001 1 0 . .. .... .... 0010 . . . 1 .... @3same
33
+
34
VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
35
VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
36
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-neon.inc.c
40
+++ b/target/arm/translate-neon.inc.c
41
@@ -XXX,XX +XXX,XX @@ static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
42
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
43
}
26
}
44
DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
27
45
+
28
static inline void clock_update_hz(Clock *clk, unsigned hz)
46
+#define DO_3SAME_GVEC4(INSN, OPARRAY) \
47
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
48
+ uint32_t rn_ofs, uint32_t rm_ofs, \
49
+ uint32_t oprsz, uint32_t maxsz) \
50
+ { \
51
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc), \
52
+ rn_ofs, rm_ofs, oprsz, maxsz, &OPARRAY[vece]); \
53
+ } \
54
+ DO_3SAME(INSN, gen_##INSN##_3s)
55
+
56
+DO_3SAME_GVEC4(VQADD_S, sqadd_op)
57
+DO_3SAME_GVEC4(VQADD_U, uqadd_op)
58
+DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
59
+DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
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
}
66
return 1;
67
68
- case NEON_3R_VQADD:
69
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
70
- rn_ofs, rm_ofs, vec_size, vec_size,
71
- (u ? uqadd_op : sqadd_op) + size);
72
- return 0;
73
-
74
- case NEON_3R_VQSUB:
75
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
76
- rn_ofs, rm_ofs, vec_size, vec_size,
77
- (u ? uqsub_op : sqsub_op) + size);
78
- return 0;
79
-
80
case NEON_3R_VMUL: /* VMUL */
81
if (u) {
82
/* Polynomial case allows only P8. */
83
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
84
case NEON_3R_VTST_VCEQ:
85
case NEON_3R_VCGT:
86
case NEON_3R_VCGE:
87
+ case NEON_3R_VQADD:
88
+ case NEON_3R_VQSUB:
89
/* Already handled by decodetree */
90
return 1;
91
}
92
--
29
--
93
2.20.1
30
2.20.1
94
31
95
32
diff view generated by jsdifflib
1
Convert the Neon 3-reg-same VMAX and VMIN insns to decodetree.
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Allow the device to execute the DMA transfers in a different
4
AddressSpace.
5
6
We keep using the system_memory address space, but via the
7
proper dma_memory_access() API.
8
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20200814125533.4047-1-f4bug@amsat.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-17-peter.maydell@linaro.org
6
---
13
---
7
target/arm/neon-dp.decode | 5 +++++
14
hw/arm/musicpal.c | 45 +++++++++++++++++++++++++++++++--------------
8
target/arm/translate-neon.inc.c | 14 ++++++++++++++
15
1 file changed, 31 insertions(+), 14 deletions(-)
9
target/arm/translate.c | 21 ++-------------------
10
3 files changed, 21 insertions(+), 19 deletions(-)
11
16
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
17
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-dp.decode
19
--- a/hw/arm/musicpal.c
15
+++ b/target/arm/neon-dp.decode
20
+++ b/hw/arm/musicpal.c
16
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
21
@@ -XXX,XX +XXX,XX @@
17
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
22
#include "hw/audio/wm8750.h"
18
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
23
#include "sysemu/block-backend.h"
19
24
#include "sysemu/runstate.h"
20
+VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
25
+#include "sysemu/dma.h"
21
+VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
26
#include "exec/address-spaces.h"
22
+VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
27
#include "ui/pixel_ops.h"
23
+VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
28
#include "qemu/cutils.h"
24
+
29
@@ -XXX,XX +XXX,XX @@ typedef struct mv88w8618_eth_state {
25
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
30
26
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
31
MemoryRegion iomem;
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
32
qemu_irq irq;
28
index XXXXXXX..XXXXXXX 100644
33
+ MemoryRegion *dma_mr;
29
--- a/target/arm/translate-neon.inc.c
34
+ AddressSpace dma_as;
30
+++ b/target/arm/translate-neon.inc.c
35
uint32_t smir;
31
@@ -XXX,XX +XXX,XX @@ DO_3SAME(VEOR, tcg_gen_gvec_xor)
36
uint32_t icr;
32
DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
37
uint32_t imr;
33
DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
38
@@ -XXX,XX +XXX,XX @@ typedef struct mv88w8618_eth_state {
34
DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
39
NICConf conf;
35
+
40
} mv88w8618_eth_state;
36
+#define DO_3SAME_NO_SZ_3(INSN, FUNC) \
41
37
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
42
-static void eth_rx_desc_put(uint32_t addr, mv88w8618_rx_desc *desc)
38
+ { \
43
+static void eth_rx_desc_put(AddressSpace *dma_as, uint32_t addr,
39
+ if (a->size == 3) { \
44
+ mv88w8618_rx_desc *desc)
40
+ return false; \
45
{
41
+ } \
46
cpu_to_le32s(&desc->cmdstat);
42
+ return do_3same(s, a, FUNC); \
47
cpu_to_le16s(&desc->bytes);
48
cpu_to_le16s(&desc->buffer_size);
49
cpu_to_le32s(&desc->buffer);
50
cpu_to_le32s(&desc->next);
51
- cpu_physical_memory_write(addr, desc, sizeof(*desc));
52
+ dma_memory_write(dma_as, addr, desc, sizeof(*desc));
53
}
54
55
-static void eth_rx_desc_get(uint32_t addr, mv88w8618_rx_desc *desc)
56
+static void eth_rx_desc_get(AddressSpace *dma_as, uint32_t addr,
57
+ mv88w8618_rx_desc *desc)
58
{
59
- cpu_physical_memory_read(addr, desc, sizeof(*desc));
60
+ dma_memory_read(dma_as, addr, desc, sizeof(*desc));
61
le32_to_cpus(&desc->cmdstat);
62
le16_to_cpus(&desc->bytes);
63
le16_to_cpus(&desc->buffer_size);
64
@@ -XXX,XX +XXX,XX @@ static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size)
65
continue;
66
}
67
do {
68
- eth_rx_desc_get(desc_addr, &desc);
69
+ eth_rx_desc_get(&s->dma_as, desc_addr, &desc);
70
if ((desc.cmdstat & MP_ETH_RX_OWN) && desc.buffer_size >= size) {
71
- cpu_physical_memory_write(desc.buffer + s->vlan_header,
72
+ dma_memory_write(&s->dma_as, desc.buffer + s->vlan_header,
73
buf, size);
74
desc.bytes = size + s->vlan_header;
75
desc.cmdstat &= ~MP_ETH_RX_OWN;
76
@@ -XXX,XX +XXX,XX @@ static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size)
77
if (s->icr & s->imr) {
78
qemu_irq_raise(s->irq);
79
}
80
- eth_rx_desc_put(desc_addr, &desc);
81
+ eth_rx_desc_put(&s->dma_as, desc_addr, &desc);
82
return size;
83
}
84
desc_addr = desc.next;
85
@@ -XXX,XX +XXX,XX @@ static ssize_t eth_receive(NetClientState *nc, const uint8_t *buf, size_t size)
86
return size;
87
}
88
89
-static void eth_tx_desc_put(uint32_t addr, mv88w8618_tx_desc *desc)
90
+static void eth_tx_desc_put(AddressSpace *dma_as, uint32_t addr,
91
+ mv88w8618_tx_desc *desc)
92
{
93
cpu_to_le32s(&desc->cmdstat);
94
cpu_to_le16s(&desc->res);
95
cpu_to_le16s(&desc->bytes);
96
cpu_to_le32s(&desc->buffer);
97
cpu_to_le32s(&desc->next);
98
- cpu_physical_memory_write(addr, desc, sizeof(*desc));
99
+ dma_memory_write(dma_as, addr, desc, sizeof(*desc));
100
}
101
102
-static void eth_tx_desc_get(uint32_t addr, mv88w8618_tx_desc *desc)
103
+static void eth_tx_desc_get(AddressSpace *dma_as, uint32_t addr,
104
+ mv88w8618_tx_desc *desc)
105
{
106
- cpu_physical_memory_read(addr, desc, sizeof(*desc));
107
+ dma_memory_read(dma_as, addr, desc, sizeof(*desc));
108
le32_to_cpus(&desc->cmdstat);
109
le16_to_cpus(&desc->res);
110
le16_to_cpus(&desc->bytes);
111
@@ -XXX,XX +XXX,XX @@ static void eth_send(mv88w8618_eth_state *s, int queue_index)
112
int len;
113
114
do {
115
- eth_tx_desc_get(desc_addr, &desc);
116
+ eth_tx_desc_get(&s->dma_as, desc_addr, &desc);
117
next_desc = desc.next;
118
if (desc.cmdstat & MP_ETH_TX_OWN) {
119
len = desc.bytes;
120
if (len < 2048) {
121
- cpu_physical_memory_read(desc.buffer, buf, len);
122
+ dma_memory_read(&s->dma_as, desc.buffer, buf, len);
123
qemu_send_packet(qemu_get_queue(s->nic), buf, len);
124
}
125
desc.cmdstat &= ~MP_ETH_TX_OWN;
126
s->icr |= 1 << (MP_ETH_IRQ_TXLO_BIT - queue_index);
127
- eth_tx_desc_put(desc_addr, &desc);
128
+ eth_tx_desc_put(&s->dma_as, desc_addr, &desc);
129
}
130
desc_addr = next_desc;
131
} while (desc_addr != s->tx_queue[queue_index]);
132
@@ -XXX,XX +XXX,XX @@ static void mv88w8618_eth_realize(DeviceState *dev, Error **errp)
133
{
134
mv88w8618_eth_state *s = MV88W8618_ETH(dev);
135
136
+ if (!s->dma_mr) {
137
+ error_setg(errp, TYPE_MV88W8618_ETH " 'dma-memory' link not set");
138
+ return;
43
+ }
139
+ }
44
+
140
+
45
+DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
141
+ address_space_init(&s->dma_as, s->dma_mr, "emac-dma");
46
+DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
142
s->nic = qemu_new_nic(&net_mv88w8618_info, &s->conf,
47
+DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
143
object_get_typename(OBJECT(dev)), dev->id, s);
48
+DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
144
}
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
145
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mv88w8618_eth_vmsd = {
50
index XXXXXXX..XXXXXXX 100644
146
51
--- a/target/arm/translate.c
147
static Property mv88w8618_eth_properties[] = {
52
+++ b/target/arm/translate.c
148
DEFINE_NIC_PROPERTIES(mv88w8618_eth_state, conf),
53
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
149
+ DEFINE_PROP_LINK("dma-memory", mv88w8618_eth_state, dma_mr,
54
rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
150
+ TYPE_MEMORY_REGION, MemoryRegion *),
55
return 0;
151
DEFINE_PROP_END_OF_LIST(),
56
152
};
57
- case NEON_3R_VMAX:
153
58
- if (u) {
154
@@ -XXX,XX +XXX,XX @@ static void musicpal_init(MachineState *machine)
59
- tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
155
qemu_check_nic_model(&nd_table[0], "mv88w8618");
60
- vec_size, vec_size);
156
dev = qdev_new(TYPE_MV88W8618_ETH);
61
- } else {
157
qdev_set_nic_properties(dev, &nd_table[0]);
62
- tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
158
+ object_property_set_link(OBJECT(dev), "dma-memory",
63
- vec_size, vec_size);
159
+ OBJECT(get_system_memory()), &error_fatal);
64
- }
160
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
65
- return 0;
161
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, MP_ETH_BASE);
66
- case NEON_3R_VMIN:
162
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[MP_ETH_IRQ]);
67
- if (u) {
68
- tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
69
- vec_size, vec_size);
70
- } else {
71
- tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
72
- vec_size, vec_size);
73
- }
74
- return 0;
75
-
76
case NEON_3R_VSHL:
77
/* Note the operation is vshl vd,vm,vn */
78
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
79
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
80
81
case NEON_3R_VADD_VSUB:
82
case NEON_3R_LOGIC:
83
+ case NEON_3R_VMAX:
84
+ case NEON_3R_VMIN:
85
/* Already handled by decodetree */
86
return 1;
87
}
88
--
163
--
89
2.20.1
164
2.20.1
90
165
91
166
diff view generated by jsdifflib
1
The access_type argument to get_phys_addr_lpae() is an MMUAccessType;
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
use the enum constant MMU_DATA_LOAD rather than a literal 0 when we
3
call it in S1_ptw_translate().
4
2
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
In commit ce4afed839 ("target/arm: Implement AArch32 HCR and HCR2")
4
the HCR_EL2 register has been changed from type NO_RAW (no underlying
5
state and does not support raw access for state saving/loading) to
6
type CONST (TCG can assume the value to be constant), removing the
7
read/write accessors.
8
We forgot to remove the previous type ARM_CP_NO_RAW. This is not
9
really a problem since the field is overwritten. However it makes
10
code review confuse, so remove it.
11
12
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200330210400.11724-3-peter.maydell@linaro.org
15
Message-id: 20200812111223.7787-1-f4bug@amsat.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
17
---
10
target/arm/helper.c | 5 +++--
18
target/arm/helper.c | 1 -
11
1 file changed, 3 insertions(+), 2 deletions(-)
19
1 file changed, 1 deletion(-)
12
20
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
23
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
24
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
25
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
18
pcacheattrs = &cacheattrs;
26
.access = PL2_RW,
19
}
27
.readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore },
20
28
{ .name = "HCR_EL2", .state = ARM_CP_STATE_BOTH,
21
- ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_Stage2, &s2pa,
29
- .type = ARM_CP_NO_RAW,
22
- &txattrs, &s2prot, &s2size, fi, pcacheattrs);
30
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
23
+ ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
31
.access = PL2_RW,
24
+ &s2pa, &txattrs, &s2prot, &s2size, fi,
32
.type = ARM_CP_CONST, .resetvalue = 0 },
25
+ pcacheattrs);
26
if (ret) {
27
assert(fi->type != ARMFault_None);
28
fi->s2addr = addr;
29
--
33
--
30
2.20.1
34
2.20.1
31
35
32
36
diff view generated by jsdifflib
1
For ARMv8.2-TTS2UXN, the stage 2 page table walk wants to know
1
From: Richard Henderson <richard.henderson@linaro.org>
2
whether the stage 1 access is for EL0 or not, because whether
3
exec permission is given can depend on whether this is an EL0
4
or EL1 access. Add a new argument to get_phys_addr_lpae() so
5
the call sites can pass this information in.
6
2
7
Since get_phys_addr_lpae() doesn't already have a doc comment,
3
We need more information than just the mmu_idx in order
8
add one so we have a place to put the documentation of the
4
to create the proper exception syndrome. Only change the
9
semantics of the new s1_is_el0 argument.
5
function signature so far.
10
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200813200816.3037186-2-richard.henderson@linaro.org
9
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
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20200330210400.11724-4-peter.maydell@linaro.org
15
---
11
---
16
target/arm/helper.c | 29 ++++++++++++++++++++++++++++-
12
target/arm/mte_helper.c | 10 +++++-----
17
1 file changed, 28 insertions(+), 1 deletion(-)
13
1 file changed, 5 insertions(+), 5 deletions(-)
18
14
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
17
--- a/target/arm/mte_helper.c
22
+++ b/target/arm/helper.c
18
+++ b/target/arm/mte_helper.c
23
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ void HELPER(stzgm_tags)(CPUARMState *env, uint64_t ptr, uint64_t val)
24
25
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
26
MMUAccessType access_type, ARMMMUIdx mmu_idx,
27
+ bool s1_is_el0,
28
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
29
target_ulong *page_size_ptr,
30
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
31
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
32
}
33
34
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
35
+ false,
36
&s2pa, &txattrs, &s2prot, &s2size, fi,
37
pcacheattrs);
38
if (ret) {
39
@@ -XXX,XX +XXX,XX @@ static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
40
};
41
}
20
}
42
21
43
+/**
22
/* Record a tag check failure. */
44
+ * get_phys_addr_lpae: perform one stage of page table walk, LPAE format
23
-static void mte_check_fail(CPUARMState *env, int mmu_idx,
45
+ *
24
+static void mte_check_fail(CPUARMState *env, uint32_t desc,
46
+ * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
25
uint64_t dirty_ptr, uintptr_t ra)
47
+ * prot and page_size may not be filled in, and the populated fsr value provides
26
{
48
+ * information on why the translation aborted, in the format of a long-format
27
+ int mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX);
49
+ * DFSR/IFSR fault register, with the following caveats:
28
ARMMMUIdx arm_mmu_idx = core_to_aa64_mmu_idx(mmu_idx);
50
+ * * the WnR bit is never set (the caller must do this).
29
int el, reg_el, tcf, select;
51
+ *
30
uint64_t sctlr;
52
+ * @env: CPUARMState
31
@@ -XXX,XX +XXX,XX @@ uint64_t mte_check1(CPUARMState *env, uint32_t desc,
53
+ * @address: virtual address to get physical address for
54
+ * @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH
55
+ * @mmu_idx: MMU index indicating required translation regime
56
+ * @s1_is_el0: if @mmu_idx is ARMMMUIdx_Stage2 (so this is a stage 2 page table
57
+ * walk), must be true if this is stage 2 of a stage 1+2 walk for an
58
+ * EL0 access). If @mmu_idx is anything else, @s1_is_el0 is ignored.
59
+ * @phys_ptr: set to the physical address corresponding to the virtual address
60
+ * @attrs: set to the memory transaction attributes to use
61
+ * @prot: set to the permissions for the page containing phys_ptr
62
+ * @page_size_ptr: set to the size of the page containing phys_ptr
63
+ * @fi: set to fault info if the translation fails
64
+ * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
65
+ */
66
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
67
MMUAccessType access_type, ARMMMUIdx mmu_idx,
68
+ bool s1_is_el0,
69
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
70
target_ulong *page_size_ptr,
71
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
72
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
73
74
/* S1 is done. Now do S2 translation. */
75
ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_Stage2,
76
+ mmu_idx == ARMMMUIdx_E10_0,
77
phys_ptr, attrs, &s2_prot,
78
page_size, fi,
79
cacheattrs != NULL ? &cacheattrs2 : NULL);
80
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
81
}
32
}
82
33
83
if (regime_using_lpae_format(env, mmu_idx)) {
34
if (unlikely(!mte_probe1_int(env, desc, ptr, ra, bit55))) {
84
- return get_phys_addr_lpae(env, address, access_type, mmu_idx,
35
- int mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX);
85
+ return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
36
- mte_check_fail(env, mmu_idx, ptr, ra);
86
phys_ptr, attrs, prot, page_size,
37
+ mte_check_fail(env, desc, ptr, ra);
87
fi, cacheattrs);
38
}
88
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
39
40
return useronly_clean_ptr(ptr);
41
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
42
43
fail_ofs = tag_first + n * TAG_GRANULE - ptr;
44
fail_ofs = ROUND_UP(fail_ofs, esize);
45
- mte_check_fail(env, mmu_idx, ptr + fail_ofs, ra);
46
+ mte_check_fail(env, desc, ptr + fail_ofs, ra);
47
}
48
49
done:
50
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mte_check_zva)(CPUARMState *env, uint32_t desc, uint64_t ptr)
51
fail:
52
/* Locate the first nibble that differs. */
53
i = ctz64(mem_tag ^ ptr_tag) >> 4;
54
- mte_check_fail(env, mmu_idx, align_ptr + i * TAG_GRANULE, ra);
55
+ mte_check_fail(env, desc, align_ptr + i * TAG_GRANULE, ra);
56
57
done:
58
return useronly_clean_ptr(ptr);
89
--
59
--
90
2.20.1
60
2.20.1
91
61
92
62
diff view generated by jsdifflib
1
Convert the Neon comparison ops in the 3-reg-same grouping
1
From: Richard Henderson <richard.henderson@linaro.org>
2
to decodetree.
3
2
3
According to AArch64.TagCheckFault, none of the other ISS values are
4
provided, so we do not need to go so far as merge_syn_data_abort.
5
But we were missing the WnR bit.
6
7
Tested-by: Andrey Konovalov <andreyknvl@google.com>
8
Reported-by: Andrey Konovalov <andreyknvl@google.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200813200816.3037186-3-richard.henderson@linaro.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-18-peter.maydell@linaro.org
7
---
13
---
8
target/arm/neon-dp.decode | 8 ++++++++
14
target/arm/mte_helper.c | 9 +++++----
9
target/arm/translate-neon.inc.c | 22 ++++++++++++++++++++++
15
1 file changed, 5 insertions(+), 4 deletions(-)
10
target/arm/translate.c | 23 +++--------------------
11
3 files changed, 33 insertions(+), 20 deletions(-)
12
16
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
17
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
19
--- a/target/arm/mte_helper.c
16
+++ b/target/arm/neon-dp.decode
20
+++ b/target/arm/mte_helper.c
17
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
21
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
18
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
22
{
19
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
23
int mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX);
20
24
ARMMMUIdx arm_mmu_idx = core_to_aa64_mmu_idx(mmu_idx);
21
+VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
25
- int el, reg_el, tcf, select;
22
+VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
26
+ int el, reg_el, tcf, select, is_write, syn;
23
+VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
27
uint64_t sctlr;
24
+VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
28
29
reg_el = regime_el(env, arm_mmu_idx);
30
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
31
*/
32
cpu_restore_state(env_cpu(env), ra, true);
33
env->exception.vaddress = dirty_ptr;
34
- raise_exception(env, EXCP_DATA_ABORT,
35
- syn_data_abort_no_iss(el != 0, 0, 0, 0, 0, 0, 0x11),
36
- exception_target_el(env));
25
+
37
+
26
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
38
+ is_write = FIELD_EX32(desc, MTEDESC, WRITE);
27
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
39
+ syn = syn_data_abort_no_iss(el != 0, 0, 0, 0, 0, is_write, 0x11);
28
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
40
+ raise_exception(env, EXCP_DATA_ABORT, syn, exception_target_el(env));
29
@@ -XXX,XX +XXX,XX @@ VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
41
/* noreturn, but fall through to the assert anyway */
30
42
31
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
43
case 0:
32
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
33
+
34
+VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
35
+VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
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_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
41
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
42
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
43
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
44
+
45
+#define DO_3SAME_CMP(INSN, COND) \
46
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
47
+ uint32_t rn_ofs, uint32_t rm_ofs, \
48
+ uint32_t oprsz, uint32_t maxsz) \
49
+ { \
50
+ tcg_gen_gvec_cmp(COND, vece, rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz); \
51
+ } \
52
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
53
+
54
+DO_3SAME_CMP(VCGT_S, TCG_COND_GT)
55
+DO_3SAME_CMP(VCGT_U, TCG_COND_GTU)
56
+DO_3SAME_CMP(VCGE_S, TCG_COND_GE)
57
+DO_3SAME_CMP(VCGE_U, TCG_COND_GEU)
58
+DO_3SAME_CMP(VCEQ, TCG_COND_EQ)
59
+
60
+static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
61
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
62
+{
63
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
64
+}
65
+DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
71
u ? &mls_op[size] : &mla_op[size]);
72
return 0;
73
74
- case NEON_3R_VTST_VCEQ:
75
- if (u) { /* VCEQ */
76
- tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
77
- vec_size, vec_size);
78
- } else { /* VTST */
79
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
80
- vec_size, vec_size, &cmtst_op[size]);
81
- }
82
- return 0;
83
-
84
- case NEON_3R_VCGT:
85
- tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
86
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
87
- return 0;
88
-
89
- case NEON_3R_VCGE:
90
- tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
91
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
92
- return 0;
93
-
94
case NEON_3R_VSHL:
95
/* Note the operation is vshl vd,vm,vn */
96
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
97
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
98
case NEON_3R_LOGIC:
99
case NEON_3R_VMAX:
100
case NEON_3R_VMIN:
101
+ case NEON_3R_VTST_VCEQ:
102
+ case NEON_3R_VCGT:
103
+ case NEON_3R_VCGE:
104
/* Already handled by decodetree */
105
return 1;
106
}
107
--
44
--
108
2.20.1
45
2.20.1
109
46
110
47
diff view generated by jsdifflib
1
Convert the Neon 3-reg-same VADD and VSUB insns to decodetree.
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Note that we don't need the neon_3r_sizes[op] check here because all
3
Allow the device to execute the DMA transfers in a different
4
size values are OK for VADD and VSUB; we'll add this when we convert
4
AddressSpace.
5
the first insn that has size restrictions.
6
5
7
For this we need one of the GVecGen*Fn typedefs currently in
6
The A10 and H3 SoC keep using the system_memory address space,
8
translate-a64.h; move them all to translate.h as a block so they
7
but via the proper dma_memory_access() API.
9
are visible to the 32-bit decoder.
10
8
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
11
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
12
Message-id: 20200814110057.307-1-f4bug@amsat.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20200430181003.21682-15-peter.maydell@linaro.org
14
---
14
---
15
target/arm/translate-a64.h | 9 --------
15
include/hw/sd/allwinner-sdhost.h | 6 ++++++
16
target/arm/translate.h | 9 ++++++++
16
hw/arm/allwinner-a10.c | 2 ++
17
target/arm/neon-dp.decode | 17 +++++++++++++++
17
hw/arm/allwinner-h3.c | 2 ++
18
target/arm/translate-neon.inc.c | 38 +++++++++++++++++++++++++++++++++
18
hw/sd/allwinner-sdhost.c | 37 ++++++++++++++++++++++++++------
19
target/arm/translate.c | 14 ++++--------
19
4 files changed, 41 insertions(+), 6 deletions(-)
20
5 files changed, 68 insertions(+), 19 deletions(-)
21
20
22
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
21
diff --git a/include/hw/sd/allwinner-sdhost.h b/include/hw/sd/allwinner-sdhost.h
23
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/translate-a64.h
23
--- a/include/hw/sd/allwinner-sdhost.h
25
+++ b/target/arm/translate-a64.h
24
+++ b/include/hw/sd/allwinner-sdhost.h
26
@@ -XXX,XX +XXX,XX @@ static inline int vec_full_reg_size(DisasContext *s)
25
@@ -XXX,XX +XXX,XX @@ typedef struct AwSdHostState {
27
26
/** Interrupt output signal to notify CPU */
28
bool disas_sve(DisasContext *, uint32_t);
27
qemu_irq irq;
29
28
30
-/* Note that the gvec expanders operate on offsets + sizes. */
29
+ /** Memory region where DMA transfers are done */
31
-typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
30
+ MemoryRegion *dma_mr;
32
-typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
31
+
33
- uint32_t, uint32_t);
32
+ /** Address space used internally for DMA transfers */
34
-typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
33
+ AddressSpace dma_as;
35
- uint32_t, uint32_t, uint32_t);
34
+
36
-typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
35
/** Number of bytes left in current DMA transfer */
37
- uint32_t, uint32_t, uint32_t);
36
uint32_t transfer_cnt;
38
-
37
39
#endif /* TARGET_ARM_TRANSLATE_A64_H */
38
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
40
diff --git a/target/arm/translate.h b/target/arm/translate.h
41
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate.h
40
--- a/hw/arm/allwinner-a10.c
43
+++ b/target/arm/translate.h
41
+++ b/hw/arm/allwinner-a10.c
44
@@ -XXX,XX +XXX,XX @@ void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
42
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
45
#define dc_isar_feature(name, ctx) \
43
}
46
({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
44
47
45
/* SD/MMC */
48
+/* Note that the gvec expanders operate on offsets + sizes. */
46
+ object_property_set_link(OBJECT(&s->mmc0), "dma-memory",
49
+typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
47
+ OBJECT(get_system_memory()), &error_fatal);
50
+typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
48
sysbus_realize(SYS_BUS_DEVICE(&s->mmc0), &error_fatal);
51
+ uint32_t, uint32_t);
49
sysbus_mmio_map(SYS_BUS_DEVICE(&s->mmc0), 0, AW_A10_MMC0_BASE);
52
+typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
50
sysbus_connect_irq(SYS_BUS_DEVICE(&s->mmc0), 0, qdev_get_gpio_in(dev, 32));
53
+ uint32_t, uint32_t, uint32_t);
51
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
54
+typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
52
index XXXXXXX..XXXXXXX 100644
55
+ uint32_t, uint32_t, uint32_t);
53
--- a/hw/arm/allwinner-h3.c
54
+++ b/hw/arm/allwinner-h3.c
55
@@ -XXX,XX +XXX,XX @@ static void allwinner_h3_realize(DeviceState *dev, Error **errp)
56
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sid), 0, s->memmap[AW_H3_SID]);
57
58
/* SD/MMC */
59
+ object_property_set_link(OBJECT(&s->mmc0), "dma-memory",
60
+ OBJECT(get_system_memory()), &error_fatal);
61
sysbus_realize(SYS_BUS_DEVICE(&s->mmc0), &error_fatal);
62
sysbus_mmio_map(SYS_BUS_DEVICE(&s->mmc0), 0, s->memmap[AW_H3_MMC0]);
63
sysbus_connect_irq(SYS_BUS_DEVICE(&s->mmc0), 0,
64
diff --git a/hw/sd/allwinner-sdhost.c b/hw/sd/allwinner-sdhost.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/hw/sd/allwinner-sdhost.c
67
+++ b/hw/sd/allwinner-sdhost.c
68
@@ -XXX,XX +XXX,XX @@
69
#include "qemu/log.h"
70
#include "qemu/module.h"
71
#include "qemu/units.h"
72
+#include "qapi/error.h"
73
#include "sysemu/blockdev.h"
74
+#include "sysemu/dma.h"
75
+#include "hw/qdev-properties.h"
76
#include "hw/irq.h"
77
#include "hw/sd/allwinner-sdhost.h"
78
#include "migration/vmstate.h"
79
@@ -XXX,XX +XXX,XX @@ static uint32_t allwinner_sdhost_process_desc(AwSdHostState *s,
80
uint8_t buf[1024];
81
82
/* Read descriptor */
83
- cpu_physical_memory_read(desc_addr, desc, sizeof(*desc));
84
+ dma_memory_read(&s->dma_as, desc_addr, desc, sizeof(*desc));
85
if (desc->size == 0) {
86
desc->size = klass->max_desc_size;
87
} else if (desc->size > klass->max_desc_size) {
88
@@ -XXX,XX +XXX,XX @@ static uint32_t allwinner_sdhost_process_desc(AwSdHostState *s,
89
90
/* Write to SD bus */
91
if (is_write) {
92
- cpu_physical_memory_read((desc->addr & DESC_SIZE_MASK) + num_done,
93
- buf, buf_bytes);
94
+ dma_memory_read(&s->dma_as,
95
+ (desc->addr & DESC_SIZE_MASK) + num_done,
96
+ buf, buf_bytes);
97
sdbus_write_data(&s->sdbus, buf, buf_bytes);
98
99
/* Read from SD bus */
100
} else {
101
sdbus_read_data(&s->sdbus, buf, buf_bytes);
102
- cpu_physical_memory_write((desc->addr & DESC_SIZE_MASK) + num_done,
103
- buf, buf_bytes);
104
+ dma_memory_write(&s->dma_as,
105
+ (desc->addr & DESC_SIZE_MASK) + num_done,
106
+ buf, buf_bytes);
107
}
108
num_done += buf_bytes;
109
}
110
111
/* Clear hold flag and flush descriptor */
112
desc->status &= ~DESC_STATUS_HOLD;
113
- cpu_physical_memory_write(desc_addr, desc, sizeof(*desc));
114
+ dma_memory_write(&s->dma_as, desc_addr, desc, sizeof(*desc));
115
116
return num_done;
117
}
118
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_allwinner_sdhost = {
119
}
120
};
121
122
+static Property allwinner_sdhost_properties[] = {
123
+ DEFINE_PROP_LINK("dma-memory", AwSdHostState, dma_mr,
124
+ TYPE_MEMORY_REGION, MemoryRegion *),
125
+ DEFINE_PROP_END_OF_LIST(),
126
+};
56
+
127
+
57
#endif /* TARGET_ARM_TRANSLATE_H */
128
static void allwinner_sdhost_init(Object *obj)
58
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
129
{
59
index XXXXXXX..XXXXXXX 100644
130
AwSdHostState *s = AW_SDHOST(obj);
60
--- a/target/arm/neon-dp.decode
131
@@ -XXX,XX +XXX,XX @@ static void allwinner_sdhost_init(Object *obj)
61
+++ b/target/arm/neon-dp.decode
132
sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq);
62
@@ -XXX,XX +XXX,XX @@
133
}
63
#
134
64
# This file is processed by scripts/decodetree.py
135
+static void allwinner_sdhost_realize(DeviceState *dev, Error **errp)
65
#
136
+{
66
+# VFP/Neon register fields; same as vfp.decode
137
+ AwSdHostState *s = AW_SDHOST(dev);
67
+%vm_dp 5:1 0:4
68
+%vn_dp 7:1 16:4
69
+%vd_dp 22:1 12:4
70
71
# Encodings for Neon data processing instructions where the T32 encoding
72
# is a simple transformation of the A32 encoding.
73
@@ -XXX,XX +XXX,XX @@
74
# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
75
# This file works on the A32 encoding only; calling code for T32 has to
76
# transform the insn into the A32 version first.
77
+
138
+
78
+######################################################################
139
+ if (!s->dma_mr) {
79
+# 3-reg-same grouping:
140
+ error_setg(errp, TYPE_AW_SDHOST " 'dma-memory' link not set");
80
+# 1111 001 U 0 D sz:2 Vn:4 Vd:4 opc:4 N Q M op Vm:4
141
+ return;
81
+######################################################################
82
+
83
+&3same vm vn vd q size
84
+
85
+@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
86
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
87
+
88
+VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
89
+VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
90
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/translate-neon.inc.c
93
+++ b/target/arm/translate-neon.inc.c
94
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
95
96
return true;
97
}
98
+
99
+static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
100
+{
101
+ int vec_size = a->q ? 16 : 8;
102
+ int rd_ofs = neon_reg_offset(a->vd, 0);
103
+ int rn_ofs = neon_reg_offset(a->vn, 0);
104
+ int rm_ofs = neon_reg_offset(a->vm, 0);
105
+
106
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
107
+ return false;
108
+ }
142
+ }
109
+
143
+
110
+ /* UNDEF accesses to D16-D31 if they don't exist. */
144
+ address_space_init(&s->dma_as, s->dma_mr, "sdhost-dma");
111
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
112
+ ((a->vd | a->vn | a->vm) & 0x10)) {
113
+ return false;
114
+ }
115
+
116
+ if ((a->vn | a->vm | a->vd) & a->q) {
117
+ return false;
118
+ }
119
+
120
+ if (!vfp_access_check(s)) {
121
+ return true;
122
+ }
123
+
124
+ fn(a->size, rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
125
+ return true;
126
+}
145
+}
127
+
146
+
128
+#define DO_3SAME(INSN, FUNC) \
147
static void allwinner_sdhost_reset(DeviceState *dev)
129
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
148
{
130
+ { \
149
AwSdHostState *s = AW_SDHOST(dev);
131
+ return do_3same(s, a, FUNC); \
150
@@ -XXX,XX +XXX,XX @@ static void allwinner_sdhost_class_init(ObjectClass *klass, void *data)
132
+ }
151
133
+
152
dc->reset = allwinner_sdhost_reset;
134
+DO_3SAME(VADD, tcg_gen_gvec_add)
153
dc->vmsd = &vmstate_allwinner_sdhost;
135
+DO_3SAME(VSUB, tcg_gen_gvec_sub)
154
+ dc->realize = allwinner_sdhost_realize;
136
diff --git a/target/arm/translate.c b/target/arm/translate.c
155
+ device_class_set_props(dc, allwinner_sdhost_properties);
137
index XXXXXXX..XXXXXXX 100644
156
}
138
--- a/target/arm/translate.c
157
139
+++ b/target/arm/translate.c
158
static void allwinner_sdhost_sun4i_class_init(ObjectClass *klass, void *data)
140
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
141
}
142
return 0;
143
144
- case NEON_3R_VADD_VSUB:
145
- if (u) {
146
- tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
147
- vec_size, vec_size);
148
- } else {
149
- tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
150
- vec_size, vec_size);
151
- }
152
- return 0;
153
-
154
case NEON_3R_VQADD:
155
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
156
rn_ofs, rm_ofs, vec_size, vec_size,
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
158
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
159
u ? &ushl_op[size] : &sshl_op[size]);
160
return 0;
161
+
162
+ case NEON_3R_VADD_VSUB:
163
+ /* Already handled by decodetree */
164
+ return 1;
165
}
166
167
if (size == 3) {
168
--
159
--
169
2.20.1
160
2.20.1
170
161
171
162
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Add support for SD.
3
Allow the device to execute the DMA transfers in a different
4
4
AddressSpace.
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
The H3 SoC keeps using the system_memory address space,
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
but via the proper dma_memory_access() API.
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
9
Message-id: 20200427181649.26851-9-edgar.iglesias@gmail.com
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
12
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
13
Message-id: 20200814122907.27732-1-f4bug@amsat.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
include/hw/arm/xlnx-versal.h | 12 ++++++++++++
16
include/hw/net/allwinner-sun8i-emac.h | 6 ++++
13
hw/arm/xlnx-versal.c | 31 +++++++++++++++++++++++++++++++
17
hw/arm/allwinner-h3.c | 2 ++
14
2 files changed, 43 insertions(+)
18
hw/net/allwinner-sun8i-emac.c | 46 +++++++++++++++++----------
15
19
3 files changed, 38 insertions(+), 16 deletions(-)
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
20
21
diff --git a/include/hw/net/allwinner-sun8i-emac.h b/include/hw/net/allwinner-sun8i-emac.h
17
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
23
--- a/include/hw/net/allwinner-sun8i-emac.h
19
+++ b/include/hw/arm/xlnx-versal.h
24
+++ b/include/hw/net/allwinner-sun8i-emac.h
25
@@ -XXX,XX +XXX,XX @@ typedef struct AwSun8iEmacState {
26
/** Interrupt output signal to notify CPU */
27
qemu_irq irq;
28
29
+ /** Memory region where DMA transfers are done */
30
+ MemoryRegion *dma_mr;
31
+
32
+ /** Address space used internally for DMA transfers */
33
+ AddressSpace dma_as;
34
+
35
/** Generic Network Interface Controller (NIC) for networking API */
36
NICState *nic;
37
38
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/allwinner-h3.c
41
+++ b/hw/arm/allwinner-h3.c
42
@@ -XXX,XX +XXX,XX @@ static void allwinner_h3_realize(DeviceState *dev, Error **errp)
43
qemu_check_nic_model(&nd_table[0], TYPE_AW_SUN8I_EMAC);
44
qdev_set_nic_properties(DEVICE(&s->emac), &nd_table[0]);
45
}
46
+ object_property_set_link(OBJECT(&s->emac), "dma-memory",
47
+ OBJECT(get_system_memory()), &error_fatal);
48
sysbus_realize(SYS_BUS_DEVICE(&s->emac), &error_fatal);
49
sysbus_mmio_map(SYS_BUS_DEVICE(&s->emac), 0, s->memmap[AW_H3_EMAC]);
50
sysbus_connect_irq(SYS_BUS_DEVICE(&s->emac), 0,
51
diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/net/allwinner-sun8i-emac.c
54
+++ b/hw/net/allwinner-sun8i-emac.c
20
@@ -XXX,XX +XXX,XX @@
55
@@ -XXX,XX +XXX,XX @@
21
56
57
#include "qemu/osdep.h"
58
#include "qemu/units.h"
59
+#include "qapi/error.h"
22
#include "hw/sysbus.h"
60
#include "hw/sysbus.h"
23
#include "hw/arm/boot.h"
61
#include "migration/vmstate.h"
24
+#include "hw/sd/sdhci.h"
62
#include "net/net.h"
25
#include "hw/intc/arm_gicv3.h"
26
#include "hw/char/pl011.h"
27
#include "hw/dma/xlnx-zdma.h"
28
@@ -XXX,XX +XXX,XX @@
63
@@ -XXX,XX +XXX,XX @@
29
#define XLNX_VERSAL_NR_UARTS 2
64
#include "net/checksum.h"
30
#define XLNX_VERSAL_NR_GEMS 2
65
#include "qemu/module.h"
31
#define XLNX_VERSAL_NR_ADMAS 8
66
#include "exec/cpu-common.h"
32
+#define XLNX_VERSAL_NR_SDS 2
67
+#include "sysemu/dma.h"
33
#define XLNX_VERSAL_NR_IRQS 192
68
#include "hw/net/allwinner-sun8i-emac.h"
34
69
35
typedef struct Versal {
70
/* EMAC register offsets */
36
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
71
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_update_irq(AwSun8iEmacState *s)
37
} iou;
72
qemu_set_irq(s->irq, (s->int_sta & s->int_en) != 0);
38
} lpd;
73
}
39
74
40
+ /* The Platform Management Controller subsystem. */
75
-static uint32_t allwinner_sun8i_emac_next_desc(FrameDescriptor *desc,
41
+ struct {
76
+static uint32_t allwinner_sun8i_emac_next_desc(AwSun8iEmacState *s,
42
+ struct {
77
+ FrameDescriptor *desc,
43
+ SDHCIState sd[XLNX_VERSAL_NR_SDS];
78
size_t min_size)
44
+ } iou;
79
{
45
+ } pmc;
80
uint32_t paddr = desc->next;
46
+
81
47
struct {
82
- cpu_physical_memory_read(paddr, desc, sizeof(*desc));
48
MemoryRegion *mr_ddr;
83
+ dma_memory_read(&s->dma_as, paddr, desc, sizeof(*desc));
49
uint32_t psci_conduit;
84
50
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
85
if ((desc->status & DESC_STATUS_CTL) &&
51
#define VERSAL_GEM1_IRQ_0 58
86
(desc->status2 & DESC_STATUS2_BUF_SIZE_MASK) >= min_size) {
52
#define VERSAL_GEM1_WAKE_IRQ_0 59
87
@@ -XXX,XX +XXX,XX @@ static uint32_t allwinner_sun8i_emac_next_desc(FrameDescriptor *desc,
53
#define VERSAL_ADMA_IRQ_0 60
54
+#define VERSAL_SD0_IRQ_0 126
55
56
/* Architecturally reserved IRQs suitable for virtualization. */
57
#define VERSAL_RSVD_IRQ_FIRST 111
58
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
59
#define MM_FPD_CRF 0xfd1a0000U
60
#define MM_FPD_CRF_SIZE 0x140000
61
62
+#define MM_PMC_SD0 0xf1040000U
63
+#define MM_PMC_SD0_SIZE 0x10000
64
#define MM_PMC_CRP 0xf1260000U
65
#define MM_PMC_CRP_SIZE 0x10000
66
#endif
67
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/arm/xlnx-versal.c
70
+++ b/hw/arm/xlnx-versal.c
71
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
72
}
88
}
73
}
89
}
74
90
75
+#define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */
91
-static uint32_t allwinner_sun8i_emac_get_desc(FrameDescriptor *desc,
76
+static void versal_create_sds(Versal *s, qemu_irq *pic)
92
+static uint32_t allwinner_sun8i_emac_get_desc(AwSun8iEmacState *s,
77
+{
93
+ FrameDescriptor *desc,
78
+ int i;
94
uint32_t start_addr,
79
+
95
size_t min_size)
80
+ for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) {
96
{
81
+ DeviceState *dev;
97
@@ -XXX,XX +XXX,XX @@ static uint32_t allwinner_sun8i_emac_get_desc(FrameDescriptor *desc,
82
+ MemoryRegion *mr;
98
83
+
99
/* Note that the list is a cycle. Last entry points back to the head. */
84
+ sysbus_init_child_obj(OBJECT(s), "sd[*]",
100
while (desc_addr != 0) {
85
+ &s->pmc.iou.sd[i], sizeof(s->pmc.iou.sd[i]),
101
- cpu_physical_memory_read(desc_addr, desc, sizeof(*desc));
86
+ TYPE_SYSBUS_SDHCI);
102
+ dma_memory_read(&s->dma_as, desc_addr, desc, sizeof(*desc));
87
+ dev = DEVICE(&s->pmc.iou.sd[i]);
103
88
+
104
if ((desc->status & DESC_STATUS_CTL) &&
89
+ object_property_set_uint(OBJECT(dev),
105
(desc->status2 & DESC_STATUS2_BUF_SIZE_MASK) >= min_size) {
90
+ 3, "sd-spec-version", &error_fatal);
106
@@ -XXX,XX +XXX,XX @@ static uint32_t allwinner_sun8i_emac_rx_desc(AwSun8iEmacState *s,
91
+ object_property_set_uint(OBJECT(dev), SDHCI_CAPABILITIES, "capareg",
107
FrameDescriptor *desc,
92
+ &error_fatal);
108
size_t min_size)
93
+ object_property_set_uint(OBJECT(dev), UHS_I, "uhs", &error_fatal);
109
{
94
+ qdev_init_nofail(dev);
110
- return allwinner_sun8i_emac_get_desc(desc, s->rx_desc_curr, min_size);
95
+
111
+ return allwinner_sun8i_emac_get_desc(s, desc, s->rx_desc_curr, min_size);
96
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
112
}
97
+ memory_region_add_subregion(&s->mr_ps,
113
98
+ MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr);
114
static uint32_t allwinner_sun8i_emac_tx_desc(AwSun8iEmacState *s,
99
+
115
FrameDescriptor *desc,
100
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
116
size_t min_size)
101
+ pic[VERSAL_SD0_IRQ_0 + i * 2]);
117
{
118
- return allwinner_sun8i_emac_get_desc(desc, s->tx_desc_head, min_size);
119
+ return allwinner_sun8i_emac_get_desc(s, desc, s->tx_desc_head, min_size);
120
}
121
122
-static void allwinner_sun8i_emac_flush_desc(FrameDescriptor *desc,
123
+static void allwinner_sun8i_emac_flush_desc(AwSun8iEmacState *s,
124
+ FrameDescriptor *desc,
125
uint32_t phys_addr)
126
{
127
- cpu_physical_memory_write(phys_addr, desc, sizeof(*desc));
128
+ dma_memory_write(&s->dma_as, phys_addr, desc, sizeof(*desc));
129
}
130
131
static bool allwinner_sun8i_emac_can_receive(NetClientState *nc)
132
@@ -XXX,XX +XXX,XX @@ static ssize_t allwinner_sun8i_emac_receive(NetClientState *nc,
133
<< RX_DESC_STATUS_FRM_LEN_SHIFT;
134
}
135
136
- cpu_physical_memory_write(desc.addr, buf, desc_bytes);
137
- allwinner_sun8i_emac_flush_desc(&desc, s->rx_desc_curr);
138
+ dma_memory_write(&s->dma_as, desc.addr, buf, desc_bytes);
139
+ allwinner_sun8i_emac_flush_desc(s, &desc, s->rx_desc_curr);
140
trace_allwinner_sun8i_emac_receive(s->rx_desc_curr, desc.addr,
141
desc_bytes);
142
143
@@ -XXX,XX +XXX,XX @@ static ssize_t allwinner_sun8i_emac_receive(NetClientState *nc,
144
bytes_left -= desc_bytes;
145
146
/* Move to the next descriptor */
147
- s->rx_desc_curr = allwinner_sun8i_emac_next_desc(&desc, 64);
148
+ s->rx_desc_curr = allwinner_sun8i_emac_next_desc(s, &desc, 64);
149
if (!s->rx_desc_curr) {
150
/* Not enough buffer space available */
151
s->int_sta |= INT_STA_RX_BUF_UA;
152
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_transmit(AwSun8iEmacState *s)
153
desc.status |= TX_DESC_STATUS_LENGTH_ERR;
154
break;
155
}
156
- cpu_physical_memory_read(desc.addr, packet_buf + packet_bytes, bytes);
157
+ dma_memory_read(&s->dma_as, desc.addr, packet_buf + packet_bytes, bytes);
158
packet_bytes += bytes;
159
desc.status &= ~DESC_STATUS_CTL;
160
- allwinner_sun8i_emac_flush_desc(&desc, s->tx_desc_curr);
161
+ allwinner_sun8i_emac_flush_desc(s, &desc, s->tx_desc_curr);
162
163
/* After the last descriptor, send the packet */
164
if (desc.status2 & TX_DESC_STATUS2_LAST_DESC) {
165
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_transmit(AwSun8iEmacState *s)
166
packet_bytes = 0;
167
transmitted++;
168
}
169
- s->tx_desc_curr = allwinner_sun8i_emac_next_desc(&desc, 0);
170
+ s->tx_desc_curr = allwinner_sun8i_emac_next_desc(s, &desc, 0);
171
}
172
173
/* Raise transmit completed interrupt */
174
@@ -XXX,XX +XXX,XX @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, hwaddr offset,
175
break;
176
case REG_TX_CUR_BUF: /* Transmit Current Buffer */
177
if (s->tx_desc_curr != 0) {
178
- cpu_physical_memory_read(s->tx_desc_curr, &desc, sizeof(desc));
179
+ dma_memory_read(&s->dma_as, s->tx_desc_curr, &desc, sizeof(desc));
180
value = desc.addr;
181
} else {
182
value = 0;
183
@@ -XXX,XX +XXX,XX @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, hwaddr offset,
184
break;
185
case REG_RX_CUR_BUF: /* Receive Current Buffer */
186
if (s->rx_desc_curr != 0) {
187
- cpu_physical_memory_read(s->rx_desc_curr, &desc, sizeof(desc));
188
+ dma_memory_read(&s->dma_as, s->rx_desc_curr, &desc, sizeof(desc));
189
value = desc.addr;
190
} else {
191
value = 0;
192
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_realize(DeviceState *dev, Error **errp)
193
{
194
AwSun8iEmacState *s = AW_SUN8I_EMAC(dev);
195
196
+ if (!s->dma_mr) {
197
+ error_setg(errp, TYPE_AW_SUN8I_EMAC " 'dma-memory' link not set");
198
+ return;
102
+ }
199
+ }
103
+}
200
+
104
+
201
+ address_space_init(&s->dma_as, s->dma_mr, "emac-dma");
105
/* This takes the board allocated linear DDR memory and creates aliases
202
+
106
* for each split DDR range/aperture on the Versal address map.
203
qemu_macaddr_default_if_unset(&s->conf.macaddr);
107
*/
204
s->nic = qemu_new_nic(&net_allwinner_sun8i_emac_info, &s->conf,
108
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
205
object_get_typename(OBJECT(dev)), dev->id, s);
109
versal_create_uarts(s, pic);
206
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_realize(DeviceState *dev, Error **errp)
110
versal_create_gems(s, pic);
207
static Property allwinner_sun8i_emac_properties[] = {
111
versal_create_admas(s, pic);
208
DEFINE_NIC_PROPERTIES(AwSun8iEmacState, conf),
112
+ versal_create_sds(s, pic);
209
DEFINE_PROP_UINT8("phy-addr", AwSun8iEmacState, mii_phy_addr, 0),
113
versal_map_ddr(s);
210
+ DEFINE_PROP_LINK("dma-memory", AwSun8iEmacState, dma_mr,
114
versal_unimp(s);
211
+ TYPE_MEMORY_REGION, MemoryRegion *),
212
DEFINE_PROP_END_OF_LIST(),
213
};
115
214
116
--
215
--
117
2.20.1
216
2.20.1
118
217
119
218
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Remove inclusion of arm_gicv3_common.h, this already gets
3
As we want to call qdev_connect_clock_in() before the device
4
included via xlnx-versal.h.
4
is realized, we need to uninline cadence_uart_create() first.
5
5
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20200803105647.22223-2-f4bug@amsat.org
9
Message-id: 20200427181649.26851-2-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
hw/arm/xlnx-versal.c | 1 -
11
include/hw/char/cadence_uart.h | 17 -----------------
13
1 file changed, 1 deletion(-)
12
hw/arm/xilinx_zynq.c | 14 ++++++++++++--
13
2 files changed, 12 insertions(+), 19 deletions(-)
14
14
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
15
diff --git a/include/hw/char/cadence_uart.h b/include/hw/char/cadence_uart.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
17
--- a/include/hw/char/cadence_uart.h
18
+++ b/hw/arm/xlnx-versal.c
18
+++ b/include/hw/char/cadence_uart.h
19
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ typedef struct {
20
#include "hw/arm/boot.h"
20
Clock *refclk;
21
#include "kvm_arm.h"
21
} CadenceUARTState;
22
#include "hw/misc/unimp.h"
22
23
-#include "hw/intc/arm_gicv3_common.h"
23
-static inline DeviceState *cadence_uart_create(hwaddr addr,
24
#include "hw/arm/xlnx-versal.h"
24
- qemu_irq irq,
25
#include "hw/char/pl011.h"
25
- Chardev *chr)
26
-{
27
- DeviceState *dev;
28
- SysBusDevice *s;
29
-
30
- dev = qdev_new(TYPE_CADENCE_UART);
31
- s = SYS_BUS_DEVICE(dev);
32
- qdev_prop_set_chr(dev, "chardev", chr);
33
- sysbus_realize_and_unref(s, &error_fatal);
34
- sysbus_mmio_map(s, 0, addr);
35
- sysbus_connect_irq(s, 0, irq);
36
-
37
- return dev;
38
-}
39
-
40
#endif
41
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/xilinx_zynq.c
44
+++ b/hw/arm/xilinx_zynq.c
45
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
46
sysbus_create_simple(TYPE_CHIPIDEA, 0xE0002000, pic[53 - IRQ_OFFSET]);
47
sysbus_create_simple(TYPE_CHIPIDEA, 0xE0003000, pic[76 - IRQ_OFFSET]);
48
49
- dev = cadence_uart_create(0xE0000000, pic[59 - IRQ_OFFSET], serial_hd(0));
50
+ dev = qdev_new(TYPE_CADENCE_UART);
51
+ busdev = SYS_BUS_DEVICE(dev);
52
+ qdev_prop_set_chr(dev, "chardev", serial_hd(0));
53
+ sysbus_realize_and_unref(busdev, &error_fatal);
54
+ sysbus_mmio_map(busdev, 0, 0xE0000000);
55
+ sysbus_connect_irq(busdev, 0, pic[59 - IRQ_OFFSET]);
56
qdev_connect_clock_in(dev, "refclk",
57
qdev_get_clock_out(slcr, "uart0_ref_clk"));
58
- dev = cadence_uart_create(0xE0001000, pic[82 - IRQ_OFFSET], serial_hd(1));
59
+ dev = qdev_new(TYPE_CADENCE_UART);
60
+ busdev = SYS_BUS_DEVICE(dev);
61
+ qdev_prop_set_chr(dev, "chardev", serial_hd(1));
62
+ sysbus_realize_and_unref(busdev, &error_fatal);
63
+ sysbus_mmio_map(busdev, 0, 0xE0001000);
64
+ sysbus_connect_irq(busdev, 0, pic[82 - IRQ_OFFSET]);
65
qdev_connect_clock_in(dev, "refclk",
66
qdev_get_clock_out(slcr, "uart1_ref_clk"));
26
67
27
--
68
--
28
2.20.1
69
2.20.1
29
70
30
71
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
By using the TYPE_* definitions for devices, we can:
3
Clock canonical name is set in device_set_realized (see the block
4
- quickly find where devices are used with 'git-grep'
4
added to hw/core/qdev.c in commit 0e6934f264).
5
- easily rename a device (one-line change).
5
If we connect a clock after the device is realized, this code is
6
not executed. This is currently not a problem as this name is only
7
used for trace events, however this disrupt tracing.
8
9
Fix by calling qdev_connect_clock_in() before realizing.
6
10
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200428154650.21991-1-f4bug@amsat.org
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20200803105647.22223-3-f4bug@amsat.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
hw/arm/mps2-tz.c | 2 +-
16
hw/arm/xilinx_zynq.c | 18 +++++++++---------
13
1 file changed, 1 insertion(+), 1 deletion(-)
17
1 file changed, 9 insertions(+), 9 deletions(-)
14
18
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
19
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2-tz.c
21
--- a/hw/arm/xilinx_zynq.c
18
+++ b/hw/arm/mps2-tz.c
22
+++ b/hw/arm/xilinx_zynq.c
19
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
23
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
20
exit(EXIT_FAILURE);
24
1, 0x0066, 0x0022, 0x0000, 0x0000, 0x0555, 0x2aa,
21
}
25
0);
22
26
23
- sysbus_init_child_obj(OBJECT(machine), "iotkit", &mms->iotkit,
27
- /* Create slcr, keep a pointer to connect clocks */
24
+ sysbus_init_child_obj(OBJECT(machine), TYPE_IOTKIT, &mms->iotkit,
28
- slcr = qdev_new("xilinx,zynq_slcr");
25
sizeof(mms->iotkit), mmc->armsse_type);
29
- sysbus_realize_and_unref(SYS_BUS_DEVICE(slcr), &error_fatal);
26
iotkitdev = DEVICE(&mms->iotkit);
30
- sysbus_mmio_map(SYS_BUS_DEVICE(slcr), 0, 0xF8000000);
27
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
31
-
32
/* Create the main clock source, and feed slcr with it */
33
zynq_machine->ps_clk = CLOCK(object_new(TYPE_CLOCK));
34
object_property_add_child(OBJECT(zynq_machine), "ps_clk",
35
OBJECT(zynq_machine->ps_clk));
36
object_unref(OBJECT(zynq_machine->ps_clk));
37
clock_set_hz(zynq_machine->ps_clk, PS_CLK_FREQUENCY);
38
+
39
+ /* Create slcr, keep a pointer to connect clocks */
40
+ slcr = qdev_new("xilinx,zynq_slcr");
41
qdev_connect_clock_in(slcr, "ps_clk", zynq_machine->ps_clk);
42
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(slcr), &error_fatal);
43
+ sysbus_mmio_map(SYS_BUS_DEVICE(slcr), 0, 0xF8000000);
44
45
dev = qdev_new(TYPE_A9MPCORE_PRIV);
46
qdev_prop_set_uint32(dev, "num-cpu", 1);
47
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
48
dev = qdev_new(TYPE_CADENCE_UART);
49
busdev = SYS_BUS_DEVICE(dev);
50
qdev_prop_set_chr(dev, "chardev", serial_hd(0));
51
+ qdev_connect_clock_in(dev, "refclk",
52
+ qdev_get_clock_out(slcr, "uart0_ref_clk"));
53
sysbus_realize_and_unref(busdev, &error_fatal);
54
sysbus_mmio_map(busdev, 0, 0xE0000000);
55
sysbus_connect_irq(busdev, 0, pic[59 - IRQ_OFFSET]);
56
- qdev_connect_clock_in(dev, "refclk",
57
- qdev_get_clock_out(slcr, "uart0_ref_clk"));
58
dev = qdev_new(TYPE_CADENCE_UART);
59
busdev = SYS_BUS_DEVICE(dev);
60
qdev_prop_set_chr(dev, "chardev", serial_hd(1));
61
+ qdev_connect_clock_in(dev, "refclk",
62
+ qdev_get_clock_out(slcr, "uart1_ref_clk"));
63
sysbus_realize_and_unref(busdev, &error_fatal);
64
sysbus_mmio_map(busdev, 0, 0xE0001000);
65
sysbus_connect_irq(busdev, 0, pic[82 - IRQ_OFFSET]);
66
- qdev_connect_clock_in(dev, "refclk",
67
- qdev_get_clock_out(slcr, "uart1_ref_clk"));
68
69
sysbus_create_varargs("cadence_ttc", 0xF8001000,
70
pic[42-IRQ_OFFSET], pic[43-IRQ_OFFSET], pic[44-IRQ_OFFSET], NULL);
28
--
71
--
29
2.20.1
72
2.20.1
30
73
31
74
diff view generated by jsdifflib
1
Convert the V[US]DOT (scalar) insns in the 2reg-scalar-ext group
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
to decodetree.
3
2
3
We want to assert the device is not realized. To avoid overloading
4
this header including "hw/qdev-core.h", uninline the function first.
5
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20200803105647.22223-4-f4bug@amsat.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-10-peter.maydell@linaro.org
7
---
10
---
8
target/arm/neon-shared.decode | 3 +++
11
include/hw/qdev-clock.h | 6 +-----
9
target/arm/translate-neon.inc.c | 35 +++++++++++++++++++++++++++++++++
12
hw/core/qdev-clock.c | 5 +++++
10
target/arm/translate.c | 13 +-----------
13
2 files changed, 6 insertions(+), 5 deletions(-)
11
3 files changed, 39 insertions(+), 12 deletions(-)
12
14
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
15
diff --git a/include/hw/qdev-clock.h b/include/hw/qdev-clock.h
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
17
--- a/include/hw/qdev-clock.h
16
+++ b/target/arm/neon-shared.decode
18
+++ b/include/hw/qdev-clock.h
17
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
19
@@ -XXX,XX +XXX,XX @@ Clock *qdev_get_clock_out(DeviceState *dev, const char *name);
18
vn=%vn_dp vd=%vd_dp size=0
20
* Set the source clock of input clock @name of device @dev to @source.
19
VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
21
* @source period update will be propagated to @name clock.
20
vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
22
*/
21
+
23
-static inline void qdev_connect_clock_in(DeviceState *dev, const char *name,
22
+VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
24
- Clock *source)
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
25
-{
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
26
- clock_set_source(qdev_get_clock_in(dev, name), source);
27
-}
28
+void qdev_connect_clock_in(DeviceState *dev, const char *name, Clock *source);
29
30
/**
31
* qdev_alias_clock:
32
diff --git a/hw/core/qdev-clock.c b/hw/core/qdev-clock.c
25
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-neon.inc.c
34
--- a/hw/core/qdev-clock.c
27
+++ b/target/arm/translate-neon.inc.c
35
+++ b/hw/core/qdev-clock.c
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
36
@@ -XXX,XX +XXX,XX @@ Clock *qdev_alias_clock(DeviceState *dev, const char *name,
29
tcg_temp_free_ptr(fpst);
37
30
return true;
38
return ncl->clock;
31
}
39
}
32
+
40
+
33
+static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
41
+void qdev_connect_clock_in(DeviceState *dev, const char *name, Clock *source)
34
+{
42
+{
35
+ gen_helper_gvec_3 *fn_gvec;
43
+ clock_set_source(qdev_get_clock_in(dev, name), source);
36
+ int opr_sz;
37
+ TCGv_ptr fpst;
38
+
39
+ if (!dc_isar_feature(aa32_dp, s)) {
40
+ return false;
41
+ }
42
+
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
45
+ ((a->vd | a->vn) & 0x10)) {
46
+ return false;
47
+ }
48
+
49
+ if ((a->vd | a->vn) & a->q) {
50
+ return false;
51
+ }
52
+
53
+ if (!vfp_access_check(s)) {
54
+ return true;
55
+ }
56
+
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
58
+ opr_sz = (1 + a->q) * 8;
59
+ fpst = get_fpstatus_ptr(1);
60
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->rm),
63
+ opr_sz, opr_sz, a->index, fn_gvec);
64
+ tcg_temp_free_ptr(fpst);
65
+ return true;
66
+}
44
+}
67
diff --git a/target/arm/translate.c b/target/arm/translate.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/translate.c
70
+++ b/target/arm/translate.c
71
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
72
bool is_long = false, q = extract32(insn, 6, 1);
73
bool ptr_is_env = false;
74
75
- if ((insn & 0xffb00f00) == 0xfe200d00) {
76
- /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
77
- int u = extract32(insn, 4, 1);
78
-
79
- if (!dc_isar_feature(aa32_dp, s)) {
80
- return 1;
81
- }
82
- fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
83
- /* rm is just Vm, and index is M. */
84
- data = extract32(insn, 5, 1); /* index */
85
- rm = extract32(insn, 0, 4);
86
- } else if ((insn & 0xffa00f10) == 0xfe000810) {
87
+ if ((insn & 0xffa00f10) == 0xfe000810) {
88
/* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
89
int is_s = extract32(insn, 20, 1);
90
int vm20 = extract32(insn, 0, 3);
91
--
45
--
92
2.20.1
46
2.20.1
93
47
94
48
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Embed the ADMAs into the SoC type.
3
Clock canonical name is set in device_set_realized (see the block
4
added to hw/core/qdev.c in commit 0e6934f264).
5
If we connect a clock after the device is realized, this code is
6
not executed. This is currently not a problem as this name is only
7
used for trace events, however this disrupt tracing.
4
8
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
9
Add a comment to document qdev_connect_clock_in() must be called
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
before the device is realized, and assert this condition.
11
12
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20200803105647.22223-5-f4bug@amsat.org
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-7-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
16
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
17
include/hw/qdev-clock.h | 2 ++
14
hw/arm/xlnx-versal.c | 14 +++++++-------
18
hw/core/qdev-clock.c | 1 +
15
2 files changed, 9 insertions(+), 8 deletions(-)
19
2 files changed, 3 insertions(+)
16
20
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
21
diff --git a/include/hw/qdev-clock.h b/include/hw/qdev-clock.h
18
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
23
--- a/include/hw/qdev-clock.h
20
+++ b/include/hw/arm/xlnx-versal.h
24
+++ b/include/hw/qdev-clock.h
21
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ Clock *qdev_get_clock_out(DeviceState *dev, const char *name);
22
#include "hw/arm/boot.h"
26
*
23
#include "hw/intc/arm_gicv3.h"
27
* Set the source clock of input clock @name of device @dev to @source.
24
#include "hw/char/pl011.h"
28
* @source period update will be propagated to @name clock.
25
+#include "hw/dma/xlnx-zdma.h"
29
+ *
26
#include "hw/net/cadence_gem.h"
30
+ * Must be called before @dev is realized.
27
31
*/
28
#define TYPE_XLNX_VERSAL "xlnx-versal"
32
void qdev_connect_clock_in(DeviceState *dev, const char *name, Clock *source);
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
33
30
struct {
34
diff --git a/hw/core/qdev-clock.c b/hw/core/qdev-clock.c
31
PL011State uart[XLNX_VERSAL_NR_UARTS];
32
CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
33
- SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
34
+ XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
35
} iou;
36
} lpd;
37
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
36
--- a/hw/core/qdev-clock.c
41
+++ b/hw/arm/xlnx-versal.c
37
+++ b/hw/core/qdev-clock.c
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
38
@@ -XXX,XX +XXX,XX @@ Clock *qdev_alias_clock(DeviceState *dev, const char *name,
43
DeviceState *dev;
39
44
MemoryRegion *mr;
40
void qdev_connect_clock_in(DeviceState *dev, const char *name, Clock *source)
45
41
{
46
- dev = qdev_create(NULL, "xlnx.zdma");
42
+ assert(!dev->realized);
47
- s->lpd.iou.adma[i] = SYS_BUS_DEVICE(dev);
43
clock_set_source(qdev_get_clock_in(dev, name), source);
48
- object_property_set_int(OBJECT(s->lpd.iou.adma[i]), 128, "bus-width",
49
- &error_abort);
50
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
51
+ sysbus_init_child_obj(OBJECT(s), name,
52
+ &s->lpd.iou.adma[i], sizeof(s->lpd.iou.adma[i]),
53
+ TYPE_XLNX_ZDMA);
54
+ dev = DEVICE(&s->lpd.iou.adma[i]);
55
+ object_property_set_int(OBJECT(dev), 128, "bus-width", &error_abort);
56
qdev_init_nofail(dev);
57
58
- mr = sysbus_mmio_get_region(s->lpd.iou.adma[i], 0);
59
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
60
memory_region_add_subregion(&s->mr_ps,
61
MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr);
62
63
- sysbus_connect_irq(s->lpd.iou.adma[i], 0, pic[VERSAL_ADMA_IRQ_0 + i]);
64
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]);
65
g_free(name);
66
}
67
}
44
}
68
--
45
--
69
2.20.1
46
2.20.1
70
47
71
48
diff view generated by jsdifflib
1
Convert the Neon logic ops in the 3-reg-same grouping to decodetree.
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
Note that for the logic ops the 'size' field forms part of their
3
decode and the actual operations are always bitwise.
4
2
3
To better align the read/write accesses, display the value after
4
the offset (read accesses only display the offset).
5
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200812190206.31595-2-f4bug@amsat.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200430181003.21682-16-peter.maydell@linaro.org
8
---
10
---
9
target/arm/neon-dp.decode | 12 +++++++++++
11
hw/misc/unimp.c | 8 ++++----
10
target/arm/translate-neon.inc.c | 19 +++++++++++++++++
12
1 file changed, 4 insertions(+), 4 deletions(-)
11
target/arm/translate.c | 38 +--------------------------------
12
3 files changed, 32 insertions(+), 37 deletions(-)
13
13
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
diff --git a/hw/misc/unimp.c b/hw/misc/unimp.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/neon-dp.decode
16
--- a/hw/misc/unimp.c
17
+++ b/target/arm/neon-dp.decode
17
+++ b/hw/misc/unimp.c
18
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static uint64_t unimp_read(void *opaque, hwaddr offset, unsigned size)
19
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
19
{
20
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(opaque);
21
21
22
+@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
22
- qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
23
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
23
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
24
+
24
"(size %d, offset 0x%" HWADDR_PRIx ")\n",
25
+VAND_3s 1111 001 0 0 . 00 .... .... 0001 ... 1 .... @3same_logic
25
s->name, size, offset);
26
+VBIC_3s 1111 001 0 0 . 01 .... .... 0001 ... 1 .... @3same_logic
26
return 0;
27
+VORR_3s 1111 001 0 0 . 10 .... .... 0001 ... 1 .... @3same_logic
27
@@ -XXX,XX +XXX,XX @@ static void unimp_write(void *opaque, hwaddr offset,
28
+VORN_3s 1111 001 0 0 . 11 .... .... 0001 ... 1 .... @3same_logic
28
UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(opaque);
29
+VEOR_3s 1111 001 1 0 . 00 .... .... 0001 ... 1 .... @3same_logic
29
30
+VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
30
qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
31
+VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
31
- "(size %d, value 0x%" PRIx64
32
+VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
32
- ", offset 0x%" HWADDR_PRIx ")\n",
33
+
33
- s->name, size, value, offset);
34
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
34
+ "(size %d, offset 0x%" HWADDR_PRIx
35
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
35
+ ", value 0x%" PRIx64 ")\n",
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
36
+ s->name, size, offset, value);
37
index XXXXXXX..XXXXXXX 100644
37
}
38
--- a/target/arm/translate-neon.inc.c
38
39
+++ b/target/arm/translate-neon.inc.c
39
static const MemoryRegionOps unimp_ops = {
40
@@ -XXX,XX +XXX,XX @@ static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
41
42
DO_3SAME(VADD, tcg_gen_gvec_add)
43
DO_3SAME(VSUB, tcg_gen_gvec_sub)
44
+DO_3SAME(VAND, tcg_gen_gvec_and)
45
+DO_3SAME(VBIC, tcg_gen_gvec_andc)
46
+DO_3SAME(VORR, tcg_gen_gvec_or)
47
+DO_3SAME(VORN, tcg_gen_gvec_orc)
48
+DO_3SAME(VEOR, tcg_gen_gvec_xor)
49
+
50
+/* These insns are all gvec_bitsel but with the inputs in various orders. */
51
+#define DO_3SAME_BITSEL(INSN, O1, O2, O3) \
52
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
53
+ uint32_t rn_ofs, uint32_t rm_ofs, \
54
+ uint32_t oprsz, uint32_t maxsz) \
55
+ { \
56
+ tcg_gen_gvec_bitsel(vece, rd_ofs, O1, O2, O3, oprsz, maxsz); \
57
+ } \
58
+ DO_3SAME(INSN, gen_##INSN##_3s)
59
+
60
+DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
61
+DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
62
+DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
63
diff --git a/target/arm/translate.c b/target/arm/translate.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate.c
66
+++ b/target/arm/translate.c
67
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
68
}
69
return 1;
70
71
- case NEON_3R_LOGIC: /* Logic ops. */
72
- switch ((u << 2) | size) {
73
- case 0: /* VAND */
74
- tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
75
- vec_size, vec_size);
76
- break;
77
- case 1: /* VBIC */
78
- tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
79
- vec_size, vec_size);
80
- break;
81
- case 2: /* VORR */
82
- tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
83
- vec_size, vec_size);
84
- break;
85
- case 3: /* VORN */
86
- tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
87
- vec_size, vec_size);
88
- break;
89
- case 4: /* VEOR */
90
- tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
91
- vec_size, vec_size);
92
- break;
93
- case 5: /* VBSL */
94
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
95
- vec_size, vec_size);
96
- break;
97
- case 6: /* VBIT */
98
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
99
- vec_size, vec_size);
100
- break;
101
- case 7: /* VBIF */
102
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
103
- vec_size, vec_size);
104
- break;
105
- }
106
- return 0;
107
-
108
case NEON_3R_VQADD:
109
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
110
rn_ofs, rm_ofs, vec_size, vec_size,
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
112
return 0;
113
114
case NEON_3R_VADD_VSUB:
115
+ case NEON_3R_LOGIC:
116
/* Already handled by decodetree */
117
return 1;
118
}
119
--
40
--
120
2.20.1
41
2.20.1
121
42
122
43
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
MIDR_EL1 is a 64-bit system register with the top 32-bit being RES0.
3
To quickly notice the access size, display the value with the
4
Represent it in QEMU's ARMCPU struct with a uint64_t, not a
4
width of the access (i.e. 16-bit access is displayed 0x0000,
5
uint32_t.
5
while 8-bit access 0x00).
6
6
7
This fixes an error when compiling with -Werror=conversion
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
because we were manipulating the register value using a
9
local uint64_t variable:
10
11
target/arm/cpu64.c: In function ‘aarch64_max_initfn’:
12
target/arm/cpu64.c:628:21: error: conversion from ‘uint64_t’ {aka ‘long unsigned int’} to ‘uint32_t’ {aka ‘unsigned int’} may change value [-Werror=conversion]
13
628 | cpu->midr = t;
14
| ^
15
16
and future-proofs us against a possible future architecture
17
change using some of the top 32 bits.
18
19
Suggested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
20
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
9
Message-id: 20200812190206.31595-3-f4bug@amsat.org
23
Message-id: 20200428172634.29707-1-f4bug@amsat.org
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
11
---
27
target/arm/cpu.h | 2 +-
12
hw/misc/unimp.c | 4 ++--
28
target/arm/cpu.c | 2 +-
13
1 file changed, 2 insertions(+), 2 deletions(-)
29
2 files changed, 2 insertions(+), 2 deletions(-)
30
14
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/hw/misc/unimp.c b/hw/misc/unimp.c
32
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.h
17
--- a/hw/misc/unimp.c
34
+++ b/target/arm/cpu.h
18
+++ b/hw/misc/unimp.c
35
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
19
@@ -XXX,XX +XXX,XX @@ static void unimp_write(void *opaque, hwaddr offset,
36
uint64_t id_aa64dfr0;
20
37
uint64_t id_aa64dfr1;
21
qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
38
} isar;
22
"(size %d, offset 0x%" HWADDR_PRIx
39
- uint32_t midr;
23
- ", value 0x%" PRIx64 ")\n",
40
+ uint64_t midr;
24
- s->name, size, offset, value);
41
uint32_t revidr;
25
+ ", value 0x%0*" PRIx64 ")\n",
42
uint32_t reset_fpsid;
26
+ s->name, size, offset, size << 1, value);
43
uint32_t ctr;
27
}
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
28
45
index XXXXXXX..XXXXXXX 100644
29
static const MemoryRegionOps unimp_ops = {
46
--- a/target/arm/cpu.c
47
+++ b/target/arm/cpu.c
48
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
49
static Property arm_cpu_properties[] = {
50
DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
51
DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0),
52
- DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0),
53
+ DEFINE_PROP_UINT64("midr", ARMCPU, midr, 0),
54
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
55
mp_affinity, ARM64_AFFINITY_INVALID),
56
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
57
--
30
--
58
2.20.1
31
2.20.1
59
32
60
33
diff view generated by jsdifflib
1
Convert the VFM[AS]L (vector) insns to decodetree. This is the last
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
insn in the legacy decoder for the 3same_ext group, so we can
3
delete the legacy decoder function for the group entirely.
4
2
5
Note that in disas_thumb2_insn() the parts of this encoding space
3
To have a better idea of how big is the region where the offset
6
where the decodetree decoder returns false will correctly be directed
4
belongs, display the value with the width of the region size
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
5
(i.e. a region of 0x1000 bytes uses 0x000 format).
8
into disas_coproc_insn() by mistake.
9
6
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20200812190206.31595-4-f4bug@amsat.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-8-peter.maydell@linaro.org
13
---
11
---
14
target/arm/neon-shared.decode | 6 +++
12
include/hw/misc/unimp.h | 1 +
15
target/arm/translate-neon.inc.c | 31 +++++++++++
13
hw/misc/unimp.c | 10 ++++++----
16
target/arm/translate.c | 92 +--------------------------------
14
2 files changed, 7 insertions(+), 4 deletions(-)
17
3 files changed, 38 insertions(+), 91 deletions(-)
18
15
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
16
diff --git a/include/hw/misc/unimp.h b/include/hw/misc/unimp.h
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
18
--- a/include/hw/misc/unimp.h
22
+++ b/target/arm/neon-shared.decode
19
+++ b/include/hw/misc/unimp.h
23
@@ -XXX,XX +XXX,XX @@ VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
20
@@ -XXX,XX +XXX,XX @@
24
# VUDOT and VSDOT
21
typedef struct {
25
VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
22
SysBusDevice parent_obj;
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
23
MemoryRegion iomem;
27
+
24
+ unsigned offset_fmt_width;
28
+# VFM[AS]L
25
char *name;
29
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
26
uint64_t size;
30
+ vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
27
} UnimplementedDeviceState;
31
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
28
diff --git a/hw/misc/unimp.c b/hw/misc/unimp.c
32
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
33
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
34
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-neon.inc.c
30
--- a/hw/misc/unimp.c
36
+++ b/target/arm/translate-neon.inc.c
31
+++ b/hw/misc/unimp.c
37
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
32
@@ -XXX,XX +XXX,XX @@ static uint64_t unimp_read(void *opaque, hwaddr offset, unsigned size)
38
opr_sz, opr_sz, 0, fn_gvec);
33
UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(opaque);
39
return true;
34
40
}
35
qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
41
+
36
- "(size %d, offset 0x%" HWADDR_PRIx ")\n",
42
+static bool trans_VFML(DisasContext *s, arg_VFML *a)
37
- s->name, size, offset);
43
+{
38
+ "(size %d, offset 0x%0*" HWADDR_PRIx ")\n",
44
+ int opr_sz;
39
+ s->name, size, s->offset_fmt_width, offset);
45
+
46
+ if (!dc_isar_feature(aa32_fhm, s)) {
47
+ return false;
48
+ }
49
+
50
+ /* UNDEF accesses to D16-D31 if they don't exist. */
51
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
52
+ (a->vd & 0x10)) {
53
+ return false;
54
+ }
55
+
56
+ if (a->vd & a->q) {
57
+ return false;
58
+ }
59
+
60
+ if (!vfp_access_check(s)) {
61
+ return true;
62
+ }
63
+
64
+ opr_sz = (1 + a->q) * 8;
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(a->q, a->vn),
67
+ vfp_reg_offset(a->q, a->vm),
68
+ cpu_env, opr_sz, opr_sz, a->s, /* is_2 == 0 */
69
+ gen_helper_gvec_fmlal_a32);
70
+ return true;
71
+}
72
diff --git a/target/arm/translate.c b/target/arm/translate.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/translate.c
75
+++ b/target/arm/translate.c
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
77
return 0;
40
return 0;
78
}
41
}
79
42
80
-/* Advanced SIMD three registers of the same length extension.
43
@@ -XXX,XX +XXX,XX @@ static void unimp_write(void *opaque, hwaddr offset,
81
- * 31 25 23 22 20 16 12 11 10 9 8 3 0
44
UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(opaque);
82
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
45
83
- * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
46
qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
84
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
47
- "(size %d, offset 0x%" HWADDR_PRIx
85
- */
48
+ "(size %d, offset 0x%0*" HWADDR_PRIx
86
-static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
49
", value 0x%0*" PRIx64 ")\n",
87
-{
50
- s->name, size, offset, size << 1, value);
88
- gen_helper_gvec_3 *fn_gvec = NULL;
51
+ s->name, size, s->offset_fmt_width, offset, size << 1, value);
89
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
52
}
90
- int rd, rn, rm, opr_sz;
53
91
- int data = 0;
54
static const MemoryRegionOps unimp_ops = {
92
- int off_rn, off_rm;
55
@@ -XXX,XX +XXX,XX @@ static void unimp_realize(DeviceState *dev, Error **errp)
93
- bool is_long = false, q = extract32(insn, 6, 1);
56
return;
94
- bool ptr_is_env = false;
57
}
95
-
58
96
- if ((insn & 0xff300f10) == 0xfc200810) {
59
+ s->offset_fmt_width = DIV_ROUND_UP(64 - clz64(s->size - 1), 4);
97
- /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
60
+
98
- int is_s = extract32(insn, 23, 1);
61
memory_region_init_io(&s->iomem, OBJECT(s), &unimp_ops, s,
99
- if (!dc_isar_feature(aa32_fhm, s)) {
62
s->name, s->size);
100
- return 1;
63
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
101
- }
102
- is_long = true;
103
- data = is_s; /* is_2 == 0 */
104
- fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
105
- ptr_is_env = true;
106
- } else {
107
- return 1;
108
- }
109
-
110
- VFP_DREG_D(rd, insn);
111
- if (rd & q) {
112
- return 1;
113
- }
114
- if (q || !is_long) {
115
- VFP_DREG_N(rn, insn);
116
- VFP_DREG_M(rm, insn);
117
- if ((rn | rm) & q & !is_long) {
118
- return 1;
119
- }
120
- off_rn = vfp_reg_offset(1, rn);
121
- off_rm = vfp_reg_offset(1, rm);
122
- } else {
123
- rn = VFP_SREG_N(insn);
124
- rm = VFP_SREG_M(insn);
125
- off_rn = vfp_reg_offset(0, rn);
126
- off_rm = vfp_reg_offset(0, rm);
127
- }
128
-
129
- if (s->fp_excp_el) {
130
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
131
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
132
- return 0;
133
- }
134
- if (!s->vfp_enabled) {
135
- return 1;
136
- }
137
-
138
- opr_sz = (1 + q) * 8;
139
- if (fn_gvec_ptr) {
140
- TCGv_ptr ptr;
141
- if (ptr_is_env) {
142
- ptr = cpu_env;
143
- } else {
144
- ptr = get_fpstatus_ptr(1);
145
- }
146
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
147
- opr_sz, opr_sz, data, fn_gvec_ptr);
148
- if (!ptr_is_env) {
149
- tcg_temp_free_ptr(ptr);
150
- }
151
- } else {
152
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
153
- opr_sz, opr_sz, data, fn_gvec);
154
- }
155
- return 0;
156
-}
157
-
158
/* Advanced SIMD two registers and a scalar extension.
159
* 31 24 23 22 20 16 12 11 10 9 8 3 0
160
* +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
161
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
162
}
163
}
164
}
165
- } else if ((insn & 0x0e000a00) == 0x0c000800
166
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
167
- if (disas_neon_insn_3same_ext(s, insn)) {
168
- goto illegal_op;
169
- }
170
- return;
171
} else if ((insn & 0x0f000a00) == 0x0e000800
172
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
173
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
174
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
175
}
176
break;
177
}
178
- if ((insn & 0xfe000a00) == 0xfc000800
179
+ if ((insn & 0xff000a00) == 0xfe000800
180
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
181
/* The Thumb2 and ARM encodings are identical. */
182
- if (disas_neon_insn_3same_ext(s, insn)) {
183
- goto illegal_op;
184
- }
185
- } else if ((insn & 0xff000a00) == 0xfe000800
186
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
187
- /* The Thumb2 and ARM encodings are identical. */
188
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
189
goto illegal_op;
190
}
191
--
64
--
192
2.20.1
65
2.20.1
193
66
194
67
diff view generated by jsdifflib
1
From: Fredrik Strupe <fredrik@strupe.net>
1
From: Eduardo Habkost <ehabkost@redhat.com>
2
2
3
According to Arm ARM, VQDMULL is only valid when U=0, while having
3
TYPE_ARM_SSE is a TYPE_SYS_BUS_DEVICE subclass, but
4
U=1 is unallocated.
4
ARMSSEClass::parent_class is declared as DeviceClass.
5
5
6
Signed-off-by: Fredrik Strupe <fredrik@strupe.net>
6
It never caused any problems by pure luck:
7
Fixes: 695272dcb976 ("target-arm: Handle UNDEF cases for Neon 3-regs-different-widths")
7
8
We were not setting class_size for TYPE_ARM_SSE, so class_size of
9
TYPE_SYS_BUS_DEVICE was being used (sizeof(SysBusDeviceClass)).
10
This made the system allocate enough memory for TYPE_ARM_SSE
11
devices even though ARMSSEClass was too small for a sysbus
12
device.
13
14
Additionally, the ARMSSEClass::info field ended up at the same
15
offset as SysBusDeviceClass::explicit_ofw_unit_address. This
16
would make sysbus_get_fw_dev_path() crash for the device.
17
Luckily, sysbus_get_fw_dev_path() never gets called for
18
TYPE_ARM_SSE devices, because qdev_get_fw_dev_path() is only used
19
by the boot device code, and TYPE_ARM_SSE devices don't appear at
20
the fw_boot_order list.
21
22
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
23
Message-id: 20200826181006.4097163-1-ehabkost@redhat.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
26
---
11
target/arm/translate.c | 2 +-
27
include/hw/arm/armsse.h | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
28
hw/arm/armsse.c | 1 +
29
2 files changed, 2 insertions(+), 1 deletion(-)
13
30
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
31
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
15
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
33
--- a/include/hw/arm/armsse.h
17
+++ b/target/arm/translate.c
34
+++ b/include/hw/arm/armsse.h
18
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
35
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
19
{0, 0, 0, 0}, /* VMLSL */
36
typedef struct ARMSSEInfo ARMSSEInfo;
20
{0, 0, 0, 9}, /* VQDMLSL */
37
21
{0, 0, 0, 0}, /* Integer VMULL */
38
typedef struct ARMSSEClass {
22
- {0, 0, 0, 1}, /* VQDMULL */
39
- DeviceClass parent_class;
23
+ {0, 0, 0, 9}, /* VQDMULL */
40
+ SysBusDeviceClass parent_class;
24
{0, 0, 0, 0xa}, /* Polynomial VMULL */
41
const ARMSSEInfo *info;
25
{0, 0, 0, 7}, /* Reserved: always UNDEF */
42
} ARMSSEClass;
26
};
43
44
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/armsse.c
47
+++ b/hw/arm/armsse.c
48
@@ -XXX,XX +XXX,XX @@ static const TypeInfo armsse_info = {
49
.name = TYPE_ARMSSE,
50
.parent = TYPE_SYS_BUS_DEVICE,
51
.instance_size = sizeof(ARMSSE),
52
+ .class_size = sizeof(ARMSSEClass),
53
.instance_init = armsse_init,
54
.abstract = true,
55
.interfaces = (InterfaceInfo[]) {
27
--
56
--
28
2.20.1
57
2.20.1
29
58
30
59
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add support for the RTC.
3
Add left-shift to match the existing right-shift.
4
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
7
Message-id: 20200815013145.539409-2-richard.henderson@linaro.org
8
Message-id: 20200427181649.26851-12-edgar.iglesias@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
hw/arm/xlnx-versal-virt.c | 22 ++++++++++++++++++++++
10
include/qemu/int128.h | 16 ++++++++++++++++
12
1 file changed, 22 insertions(+)
11
1 file changed, 16 insertions(+)
13
12
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
13
diff --git a/include/qemu/int128.h b/include/qemu/int128.h
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
15
--- a/include/qemu/int128.h
17
+++ b/hw/arm/xlnx-versal-virt.c
16
+++ b/include/qemu/int128.h
18
@@ -XXX,XX +XXX,XX @@ static void fdt_add_sd_nodes(VersalVirt *s)
17
@@ -XXX,XX +XXX,XX @@ static inline Int128 int128_rshift(Int128 a, int n)
18
return a >> n;
19
}
20
21
+static inline Int128 int128_lshift(Int128 a, int n)
22
+{
23
+ return a << n;
24
+}
25
+
26
static inline Int128 int128_add(Int128 a, Int128 b)
27
{
28
return a + b;
29
@@ -XXX,XX +XXX,XX @@ static inline Int128 int128_rshift(Int128 a, int n)
19
}
30
}
20
}
31
}
21
32
22
+static void fdt_add_rtc_node(VersalVirt *s)
33
+static inline Int128 int128_lshift(Int128 a, int n)
23
+{
34
+{
24
+ const char compat[] = "xlnx,zynqmp-rtc";
35
+ uint64_t l = a.lo << (n & 63);
25
+ const char interrupt_names[] = "alarm\0sec";
36
+ if (n >= 64) {
26
+ char *name = g_strdup_printf("/rtc@%x", MM_PMC_RTC);
37
+ return int128_make128(0, l);
27
+
38
+ } else if (n > 0) {
28
+ qemu_fdt_add_subnode(s->fdt, name);
39
+ return int128_make128(l, (a.hi << n) | (a.lo >> (64 - n)));
29
+
40
+ }
30
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
41
+ return a;
31
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_ALARM_IRQ,
32
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI,
33
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_SECONDS_IRQ,
34
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
35
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
36
+ interrupt_names, sizeof(interrupt_names));
37
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
38
+ 2, MM_PMC_RTC, 2, MM_PMC_RTC_SIZE);
39
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
40
+ g_free(name);
41
+}
42
+}
42
+
43
+
43
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
44
static inline Int128 int128_add(Int128 a, Int128 b)
44
{
45
{
45
Error *err = NULL;
46
uint64_t lo = a.lo + b.lo;
46
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
47
fdt_add_timer_nodes(s);
48
fdt_add_zdma_nodes(s);
49
fdt_add_sd_nodes(s);
50
+ fdt_add_rtc_node(s);
51
fdt_add_cpu_nodes(s, psci_conduit);
52
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
53
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
54
--
47
--
55
2.20.1
48
2.20.1
56
49
57
50
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Embed the APUs into the SoC type.
3
Model the new function on gen_gvec_fn2 in translate-a64.c, but
4
indicating which kind of register and in which order. Since there
5
is only one user of do_vector2_z, fold it into do_mov_z.
4
6
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20200815013145.539409-3-richard.henderson@linaro.org
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-8-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
include/hw/arm/xlnx-versal.h | 2 +-
12
target/arm/translate-sve.c | 19 ++++++++++---------
14
hw/arm/xlnx-versal-virt.c | 4 ++--
13
1 file changed, 10 insertions(+), 9 deletions(-)
15
hw/arm/xlnx-versal.c | 19 +++++--------------
16
3 files changed, 8 insertions(+), 17 deletions(-)
17
14
18
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
15
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/xlnx-versal.h
17
--- a/target/arm/translate-sve.c
21
+++ b/include/hw/arm/xlnx-versal.h
18
+++ b/target/arm/translate-sve.c
22
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
19
@@ -XXX,XX +XXX,XX @@ static int pred_gvec_reg_size(DisasContext *s)
23
struct {
24
struct {
25
MemoryRegion mr;
26
- ARMCPU *cpu[XLNX_VERSAL_NR_ACPUS];
27
+ ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
28
GICv3State gic;
29
} apu;
30
} fpd;
31
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/xlnx-versal-virt.c
34
+++ b/hw/arm/xlnx-versal-virt.c
35
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
36
s->binfo.get_dtb = versal_virt_get_dtb;
37
s->binfo.modify_dtb = versal_virt_modify_dtb;
38
if (machine->kernel_filename) {
39
- arm_load_kernel(s->soc.fpd.apu.cpu[0], machine, &s->binfo);
40
+ arm_load_kernel(&s->soc.fpd.apu.cpu[0], machine, &s->binfo);
41
} else {
42
- AddressSpace *as = arm_boot_address_space(s->soc.fpd.apu.cpu[0],
43
+ AddressSpace *as = arm_boot_address_space(&s->soc.fpd.apu.cpu[0],
44
&s->binfo);
45
/* Some boot-loaders (e.g u-boot) don't like blobs at address 0 (NULL).
46
* Offset things by 4K. */
47
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/xlnx-versal.c
50
+++ b/hw/arm/xlnx-versal.c
51
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
52
53
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
54
Object *obj;
55
- char *name;
56
-
57
- obj = object_new(XLNX_VERSAL_ACPU_TYPE);
58
- if (!obj) {
59
- error_report("Unable to create apu.cpu[%d] of type %s",
60
- i, XLNX_VERSAL_ACPU_TYPE);
61
- exit(EXIT_FAILURE);
62
- }
63
-
64
- name = g_strdup_printf("apu-cpu[%d]", i);
65
- object_property_add_child(OBJECT(s), name, obj, &error_fatal);
66
- g_free(name);
67
68
+ object_initialize_child(OBJECT(s), "apu-cpu[*]",
69
+ &s->fpd.apu.cpu[i], sizeof(s->fpd.apu.cpu[i]),
70
+ XLNX_VERSAL_ACPU_TYPE, &error_abort, NULL);
71
+ obj = OBJECT(&s->fpd.apu.cpu[i]);
72
object_property_set_int(obj, s->cfg.psci_conduit,
73
"psci-conduit", &error_abort);
74
if (i) {
75
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
76
object_property_set_link(obj, OBJECT(&s->fpd.apu.mr), "memory",
77
&error_abort);
78
object_property_set_bool(obj, true, "realized", &error_fatal);
79
- s->fpd.apu.cpu[i] = ARM_CPU(obj);
80
}
81
}
20
}
82
21
83
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
22
/* Invoke a vector expander on two Zregs. */
84
}
23
-static bool do_vector2_z(DisasContext *s, GVecGen2Fn *gvec_fn,
85
24
- int esz, int rd, int rn)
86
for (i = 0; i < nr_apu_cpus; i++) {
25
+
87
- DeviceState *cpudev = DEVICE(s->fpd.apu.cpu[i]);
26
+static void gen_gvec_fn_zz(DisasContext *s, GVecGen2Fn *gvec_fn,
88
+ DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]);
27
+ int esz, int rd, int rn)
89
int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
28
{
90
qemu_irq maint_irq;
29
- if (sve_access_check(s)) {
91
int ti;
30
- unsigned vsz = vec_full_reg_size(s);
31
- gvec_fn(esz, vec_full_reg_offset(s, rd),
32
- vec_full_reg_offset(s, rn), vsz, vsz);
33
- }
34
- return true;
35
+ unsigned vsz = vec_full_reg_size(s);
36
+ gvec_fn(esz, vec_full_reg_offset(s, rd),
37
+ vec_full_reg_offset(s, rn), vsz, vsz);
38
}
39
40
/* Invoke a vector expander on three Zregs. */
41
@@ -XXX,XX +XXX,XX @@ static bool do_vector3_z(DisasContext *s, GVecGen3Fn *gvec_fn,
42
/* Invoke a vector move on two Zregs. */
43
static bool do_mov_z(DisasContext *s, int rd, int rn)
44
{
45
- return do_vector2_z(s, tcg_gen_gvec_mov, 0, rd, rn);
46
+ if (sve_access_check(s)) {
47
+ gen_gvec_fn_zz(s, tcg_gen_gvec_mov, MO_8, rd, rn);
48
+ }
49
+ return true;
50
}
51
52
/* Initialize a Zreg with replications of a 64-bit immediate. */
92
--
53
--
93
2.20.1
54
2.20.1
94
55
95
56
diff view generated by jsdifflib
1
Convert the Neon "load/store single structure to one lane" insns to
1
From: Richard Henderson <richard.henderson@linaro.org>
2
decodetree.
3
2
4
As this is the last set of insns in the neon load/store group,
3
Model gen_gvec_fn_zzz on gen_gvec_fn3 in translate-a64.c, but
5
we can remove the whole disas_neon_ls_insn() function.
4
indicating which kind of register and in which order.
6
5
6
Model do_zzz_fn on the other do_foo functions that take an
7
argument set and verify sve enabled.
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20200815013145.539409-4-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200430181003.21682-14-peter.maydell@linaro.org
10
---
13
---
11
target/arm/neon-ls.decode | 11 +++
14
target/arm/translate-sve.c | 43 +++++++++++++++++++++-----------------
12
target/arm/translate-neon.inc.c | 89 +++++++++++++++++++
15
1 file changed, 24 insertions(+), 19 deletions(-)
13
target/arm/translate.c | 147 --------------------------------
14
3 files changed, 100 insertions(+), 147 deletions(-)
15
16
16
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
17
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/neon-ls.decode
19
--- a/target/arm/translate-sve.c
19
+++ b/target/arm/neon-ls.decode
20
+++ b/target/arm/translate-sve.c
20
@@ -XXX,XX +XXX,XX @@ VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
21
@@ -XXX,XX +XXX,XX @@ static void gen_gvec_fn_zz(DisasContext *s, GVecGen2Fn *gvec_fn,
21
22
}
22
VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
23
23
vd=%vd_dp
24
/* Invoke a vector expander on three Zregs. */
24
+
25
-static bool do_vector3_z(DisasContext *s, GVecGen3Fn *gvec_fn,
25
+# Neon load/store single structure to one lane
26
- int esz, int rd, int rn, int rm)
26
+%imm1_5_p1 5:1 !function=plus1
27
+static void gen_gvec_fn_zzz(DisasContext *s, GVecGen3Fn *gvec_fn,
27
+%imm1_6_p1 6:1 !function=plus1
28
+ int esz, int rd, int rn, int rm)
28
+
29
{
29
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 00 n:2 reg_idx:3 align:1 rm:4 \
30
- if (sve_access_check(s)) {
30
+ vd=%vd_dp size=0 stride=1
31
- unsigned vsz = vec_full_reg_size(s);
31
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 01 n:2 reg_idx:2 align:2 rm:4 \
32
- gvec_fn(esz, vec_full_reg_offset(s, rd),
32
+ vd=%vd_dp size=1 stride=%imm1_5_p1
33
- vec_full_reg_offset(s, rn),
33
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 10 n:2 reg_idx:1 align:3 rm:4 \
34
- vec_full_reg_offset(s, rm), vsz, vsz);
34
+ vd=%vd_dp size=2 stride=%imm1_6_p1
35
- }
35
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
36
- return true;
36
index XXXXXXX..XXXXXXX 100644
37
+ unsigned vsz = vec_full_reg_size(s);
37
--- a/target/arm/translate-neon.inc.c
38
+ gvec_fn(esz, vec_full_reg_offset(s, rd),
38
+++ b/target/arm/translate-neon.inc.c
39
+ vec_full_reg_offset(s, rn),
39
@@ -XXX,XX +XXX,XX @@
40
+ vec_full_reg_offset(s, rm), vsz, vsz);
40
* It might be possible to convert it to a standalone .c file eventually.
41
}
42
43
/* Invoke a vector move on two Zregs. */
44
@@ -XXX,XX +XXX,XX @@ const uint64_t pred_esz_masks[4] = {
45
*** SVE Logical - Unpredicated Group
41
*/
46
*/
42
47
43
+static inline int plus1(DisasContext *s, int x)
48
+static bool do_zzz_fn(DisasContext *s, arg_rrr_esz *a, GVecGen3Fn *gvec_fn)
44
+{
49
+{
45
+ return x + 1;
50
+ if (sve_access_check(s)) {
51
+ gen_gvec_fn_zzz(s, gvec_fn, a->esz, a->rd, a->rn, a->rm);
52
+ }
53
+ return true;
46
+}
54
+}
47
+
55
+
48
/* Include the generated Neon decoder */
56
static bool trans_AND_zzz(DisasContext *s, arg_rrr_esz *a)
49
#include "decode-neon-dp.inc.c"
57
{
50
#include "decode-neon-ls.inc.c"
58
- return do_vector3_z(s, tcg_gen_gvec_and, 0, a->rd, a->rn, a->rm);
51
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
59
+ return do_zzz_fn(s, a, tcg_gen_gvec_and);
52
53
return true;
54
}
60
}
55
+
61
56
+static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
62
static bool trans_ORR_zzz(DisasContext *s, arg_rrr_esz *a)
57
+{
63
{
58
+ /* Neon load/store single structure to one lane */
64
- return do_vector3_z(s, tcg_gen_gvec_or, 0, a->rd, a->rn, a->rm);
59
+ int reg;
65
+ return do_zzz_fn(s, a, tcg_gen_gvec_or);
60
+ int nregs = a->n + 1;
61
+ int vd = a->vd;
62
+ TCGv_i32 addr, tmp;
63
+
64
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
65
+ return false;
66
+ }
67
+
68
+ /* UNDEF accesses to D16-D31 if they don't exist */
69
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
70
+ return false;
71
+ }
72
+
73
+ /* Catch the UNDEF cases. This is unavoidably a bit messy. */
74
+ switch (nregs) {
75
+ case 1:
76
+ if (((a->align & (1 << a->size)) != 0) ||
77
+ (a->size == 2 && ((a->align & 3) == 1 || (a->align & 3) == 2))) {
78
+ return false;
79
+ }
80
+ break;
81
+ case 3:
82
+ if ((a->align & 1) != 0) {
83
+ return false;
84
+ }
85
+ /* fall through */
86
+ case 2:
87
+ if (a->size == 2 && (a->align & 2) != 0) {
88
+ return false;
89
+ }
90
+ break;
91
+ case 4:
92
+ if ((a->size == 2) && ((a->align & 3) == 3)) {
93
+ return false;
94
+ }
95
+ break;
96
+ default:
97
+ abort();
98
+ }
99
+ if ((vd + a->stride * (nregs - 1)) > 31) {
100
+ /*
101
+ * Attempts to write off the end of the register file are
102
+ * UNPREDICTABLE; we choose to UNDEF because otherwise we would
103
+ * access off the end of the array that holds the register data.
104
+ */
105
+ return false;
106
+ }
107
+
108
+ if (!vfp_access_check(s)) {
109
+ return true;
110
+ }
111
+
112
+ tmp = tcg_temp_new_i32();
113
+ addr = tcg_temp_new_i32();
114
+ load_reg_var(s, addr, a->rn);
115
+ /*
116
+ * TODO: if we implemented alignment exceptions, we should check
117
+ * addr against the alignment encoded in a->align here.
118
+ */
119
+ for (reg = 0; reg < nregs; reg++) {
120
+ if (a->l) {
121
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
122
+ s->be_data | a->size);
123
+ neon_store_element(vd, a->reg_idx, a->size, tmp);
124
+ } else { /* Store */
125
+ neon_load_element(tmp, vd, a->reg_idx, a->size);
126
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
127
+ s->be_data | a->size);
128
+ }
129
+ vd += a->stride;
130
+ tcg_gen_addi_i32(addr, addr, 1 << a->size);
131
+ }
132
+ tcg_temp_free_i32(addr);
133
+ tcg_temp_free_i32(tmp);
134
+
135
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << a->size) * nregs);
136
+
137
+ return true;
138
+}
139
diff --git a/target/arm/translate.c b/target/arm/translate.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/target/arm/translate.c
142
+++ b/target/arm/translate.c
143
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
144
tcg_temp_free_i32(rd);
145
}
66
}
146
67
147
-
68
static bool trans_EOR_zzz(DisasContext *s, arg_rrr_esz *a)
148
-/* Translate a NEON load/store element instruction. Return nonzero if the
149
- instruction is invalid. */
150
-static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
151
-{
152
- int rd, rn, rm;
153
- int nregs;
154
- int stride;
155
- int size;
156
- int reg;
157
- int load;
158
- TCGv_i32 addr;
159
- TCGv_i32 tmp;
160
-
161
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
162
- return 1;
163
- }
164
-
165
- /* FIXME: this access check should not take precedence over UNDEF
166
- * for invalid encodings; we will generate incorrect syndrome information
167
- * for attempts to execute invalid vfp/neon encodings with FP disabled.
168
- */
169
- if (s->fp_excp_el) {
170
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
171
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
172
- return 0;
173
- }
174
-
175
- if (!s->vfp_enabled)
176
- return 1;
177
- VFP_DREG_D(rd, insn);
178
- rn = (insn >> 16) & 0xf;
179
- rm = insn & 0xf;
180
- load = (insn & (1 << 21)) != 0;
181
- if ((insn & (1 << 23)) == 0) {
182
- /* Load store all elements -- handled already by decodetree */
183
- return 1;
184
- } else {
185
- size = (insn >> 10) & 3;
186
- if (size == 3) {
187
- /* Load single element to all lanes -- handled by decodetree */
188
- return 1;
189
- } else {
190
- /* Single element. */
191
- int idx = (insn >> 4) & 0xf;
192
- int reg_idx;
193
- switch (size) {
194
- case 0:
195
- reg_idx = (insn >> 5) & 7;
196
- stride = 1;
197
- break;
198
- case 1:
199
- reg_idx = (insn >> 6) & 3;
200
- stride = (insn & (1 << 5)) ? 2 : 1;
201
- break;
202
- case 2:
203
- reg_idx = (insn >> 7) & 1;
204
- stride = (insn & (1 << 6)) ? 2 : 1;
205
- break;
206
- default:
207
- abort();
208
- }
209
- nregs = ((insn >> 8) & 3) + 1;
210
- /* Catch the UNDEF cases. This is unavoidably a bit messy. */
211
- switch (nregs) {
212
- case 1:
213
- if (((idx & (1 << size)) != 0) ||
214
- (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
215
- return 1;
216
- }
217
- break;
218
- case 3:
219
- if ((idx & 1) != 0) {
220
- return 1;
221
- }
222
- /* fall through */
223
- case 2:
224
- if (size == 2 && (idx & 2) != 0) {
225
- return 1;
226
- }
227
- break;
228
- case 4:
229
- if ((size == 2) && ((idx & 3) == 3)) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- abort();
235
- }
236
- if ((rd + stride * (nregs - 1)) > 31) {
237
- /* Attempts to write off the end of the register file
238
- * are UNPREDICTABLE; we choose to UNDEF because otherwise
239
- * the neon_load_reg() would write off the end of the array.
240
- */
241
- return 1;
242
- }
243
- tmp = tcg_temp_new_i32();
244
- addr = tcg_temp_new_i32();
245
- load_reg_var(s, addr, rn);
246
- for (reg = 0; reg < nregs; reg++) {
247
- if (load) {
248
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
249
- s->be_data | size);
250
- neon_store_element(rd, reg_idx, size, tmp);
251
- } else { /* Store */
252
- neon_load_element(tmp, rd, reg_idx, size);
253
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
254
- s->be_data | size);
255
- }
256
- rd += stride;
257
- tcg_gen_addi_i32(addr, addr, 1 << size);
258
- }
259
- tcg_temp_free_i32(addr);
260
- tcg_temp_free_i32(tmp);
261
- stride = nregs * (1 << size);
262
- }
263
- }
264
- if (rm != 15) {
265
- TCGv_i32 base;
266
-
267
- base = load_reg(s, rn);
268
- if (rm == 13) {
269
- tcg_gen_addi_i32(base, base, stride);
270
- } else {
271
- TCGv_i32 index;
272
- index = load_reg(s, rm);
273
- tcg_gen_add_i32(base, base, index);
274
- tcg_temp_free_i32(index);
275
- }
276
- store_reg(s, rn, base);
277
- }
278
- return 0;
279
-}
280
-
281
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
282
{
69
{
283
switch (size) {
70
- return do_vector3_z(s, tcg_gen_gvec_xor, 0, a->rd, a->rn, a->rm);
284
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
71
+ return do_zzz_fn(s, a, tcg_gen_gvec_xor);
285
}
72
}
286
return;
73
287
}
74
static bool trans_BIC_zzz(DisasContext *s, arg_rrr_esz *a)
288
- if ((insn & 0x0f100000) == 0x04000000) {
75
{
289
- /* NEON load/store. */
76
- return do_vector3_z(s, tcg_gen_gvec_andc, 0, a->rd, a->rn, a->rm);
290
- if (disas_neon_ls_insn(s, insn)) {
77
+ return do_zzz_fn(s, a, tcg_gen_gvec_andc);
291
- goto illegal_op;
78
}
292
- }
79
293
- return;
80
/*
294
- }
81
@@ -XXX,XX +XXX,XX @@ static bool trans_BIC_zzz(DisasContext *s, arg_rrr_esz *a)
295
if ((insn & 0x0e000f00) == 0x0c000100) {
82
296
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
83
static bool trans_ADD_zzz(DisasContext *s, arg_rrr_esz *a)
297
/* iWMMXt register transfer. */
84
{
298
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
85
- return do_vector3_z(s, tcg_gen_gvec_add, a->esz, a->rd, a->rn, a->rm);
299
}
86
+ return do_zzz_fn(s, a, tcg_gen_gvec_add);
300
break;
87
}
301
case 12:
88
302
- if ((insn & 0x01100000) == 0x01000000) {
89
static bool trans_SUB_zzz(DisasContext *s, arg_rrr_esz *a)
303
- if (disas_neon_ls_insn(s, insn)) {
90
{
304
- goto illegal_op;
91
- return do_vector3_z(s, tcg_gen_gvec_sub, a->esz, a->rd, a->rn, a->rm);
305
- }
92
+ return do_zzz_fn(s, a, tcg_gen_gvec_sub);
306
- break;
93
}
307
- }
94
308
goto illegal_op;
95
static bool trans_SQADD_zzz(DisasContext *s, arg_rrr_esz *a)
309
default:
96
{
310
illegal_op:
97
- return do_vector3_z(s, tcg_gen_gvec_ssadd, a->esz, a->rd, a->rn, a->rm);
98
+ return do_zzz_fn(s, a, tcg_gen_gvec_ssadd);
99
}
100
101
static bool trans_SQSUB_zzz(DisasContext *s, arg_rrr_esz *a)
102
{
103
- return do_vector3_z(s, tcg_gen_gvec_sssub, a->esz, a->rd, a->rn, a->rm);
104
+ return do_zzz_fn(s, a, tcg_gen_gvec_sssub);
105
}
106
107
static bool trans_UQADD_zzz(DisasContext *s, arg_rrr_esz *a)
108
{
109
- return do_vector3_z(s, tcg_gen_gvec_usadd, a->esz, a->rd, a->rn, a->rm);
110
+ return do_zzz_fn(s, a, tcg_gen_gvec_usadd);
111
}
112
113
static bool trans_UQSUB_zzz(DisasContext *s, arg_rrr_esz *a)
114
{
115
- return do_vector3_z(s, tcg_gen_gvec_ussub, a->esz, a->rd, a->rn, a->rm);
116
+ return do_zzz_fn(s, a, tcg_gen_gvec_ussub);
117
}
118
119
/*
311
--
120
--
312
2.20.1
121
2.20.1
313
122
314
123
diff view generated by jsdifflib
1
We're going to want at least some of the NeonGen* typedefs
1
From: Richard Henderson <richard.henderson@linaro.org>
2
for the refactored 32-bit Neon decoder, so move them all
3
to translate.h since it makes more sense to keep them in
4
one group.
5
2
3
We want to ensure that access is checked by the time we ask
4
for a specific fp/vector register. We want to ensure that
5
we do not emit two lots of code to raise an exception.
6
7
But sometimes it's difficult to cleanly organize the code
8
such that we never pass through sve_check_access exactly once.
9
Allow multiple calls so long as the result is true, that is,
10
no exception to be raised.
11
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20200815013145.539409-5-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200430181003.21682-23-peter.maydell@linaro.org
9
---
16
---
10
target/arm/translate.h | 17 +++++++++++++++++
17
target/arm/translate.h | 1 +
11
target/arm/translate-a64.c | 17 -----------------
18
target/arm/translate-a64.c | 27 ++++++++++++++++-----------
12
2 files changed, 17 insertions(+), 17 deletions(-)
19
2 files changed, 17 insertions(+), 11 deletions(-)
13
20
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
21
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
23
--- a/target/arm/translate.h
17
+++ b/target/arm/translate.h
24
+++ b/target/arm/translate.h
18
@@ -XXX,XX +XXX,XX @@ typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
25
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
19
typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
26
* that it is set at the point where we actually touch the FP regs.
20
uint32_t, uint32_t, uint32_t);
27
*/
21
28
bool fp_access_checked;
22
+/* Function prototype for gen_ functions for calling Neon helpers */
29
+ bool sve_access_checked;
23
+typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
30
/* ARMv8 single-step state (this is distinct from the QEMU gdbstub
24
+typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
31
* single-step support).
25
+typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
32
*/
26
+typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
27
+typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
28
+typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
29
+typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
30
+typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
31
+typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
32
+typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
33
+typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
34
+typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
35
+typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
36
+typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
37
+typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
38
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
40
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
33
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
41
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-a64.c
35
--- a/target/arm/translate-a64.c
43
+++ b/target/arm/translate-a64.c
36
+++ b/target/arm/translate-a64.c
44
@@ -XXX,XX +XXX,XX @@ typedef struct AArch64DecodeTable {
37
@@ -XXX,XX +XXX,XX @@ static void do_vec_ld(DisasContext *s, int destidx, int element,
45
AArch64DecodeFn *disas_fn;
38
* unallocated-encoding checks (otherwise the syndrome information
46
} AArch64DecodeTable;
39
* for the resulting exception will be incorrect).
47
40
*/
48
-/* Function prototype for gen_ functions for calling Neon helpers */
41
-static inline bool fp_access_check(DisasContext *s)
49
-typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
42
+static bool fp_access_check(DisasContext *s)
50
-typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
43
{
51
-typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
44
- assert(!s->fp_access_checked);
52
-typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
45
- s->fp_access_checked = true;
53
-typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
46
+ if (s->fp_excp_el) {
54
-typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
47
+ assert(!s->fp_access_checked);
55
-typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
48
+ s->fp_access_checked = true;
56
-typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
49
57
-typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
50
- if (!s->fp_excp_el) {
58
-typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
51
- return true;
59
-typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
52
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
60
-typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
53
+ syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
61
-typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
54
+ return false;
62
-typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
55
}
63
-typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
64
-
56
-
65
/* initialize TCG globals. */
57
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
66
void a64_translate_init(void)
58
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
59
- return false;
60
+ s->fp_access_checked = true;
61
+ return true;
62
}
63
64
/* Check that SVE access is enabled. If it is, return true.
65
@@ -XXX,XX +XXX,XX @@ static inline bool fp_access_check(DisasContext *s)
66
bool sve_access_check(DisasContext *s)
67
{
67
{
68
if (s->sve_excp_el) {
69
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_sve_access_trap(),
70
- s->sve_excp_el);
71
+ assert(!s->sve_access_checked);
72
+ s->sve_access_checked = true;
73
+
74
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
75
+ syn_sve_access_trap(), s->sve_excp_el);
76
return false;
77
}
78
+ s->sve_access_checked = true;
79
return fp_access_check(s);
80
}
81
82
@@ -XXX,XX +XXX,XX @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
83
s->base.pc_next += 4;
84
85
s->fp_access_checked = false;
86
+ s->sve_access_checked = false;
87
88
if (dc_isar_feature(aa64_bti, s)) {
89
if (s->base.num_insns == 1) {
68
--
90
--
69
2.20.1
91
2.20.1
70
92
71
93
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add support for SD.
3
This is the only user of the function.
4
4
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
7
Message-id: 20200815013145.539409-6-richard.henderson@linaro.org
8
Message-id: 20200427181649.26851-11-edgar.iglesias@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
hw/arm/xlnx-versal-virt.c | 46 +++++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 19 ++++++-------------
12
1 file changed, 46 insertions(+)
11
1 file changed, 6 insertions(+), 13 deletions(-)
13
12
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
13
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/xlnx-versal-virt.c
15
--- a/target/arm/translate-sve.c
17
+++ b/hw/arm/xlnx-versal-virt.c
16
+++ b/target/arm/translate-sve.c
18
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static void do_dupi_z(DisasContext *s, int rd, uint64_t word)
19
#include "hw/arm/sysbus-fdt.h"
18
tcg_gen_gvec_dup_imm(MO_64, vec_full_reg_offset(s, rd), vsz, vsz, word);
20
#include "hw/arm/fdt.h"
21
#include "cpu.h"
22
+#include "hw/qdev-properties.h"
23
#include "hw/arm/xlnx-versal.h"
24
25
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
26
@@ -XXX,XX +XXX,XX @@ static void fdt_add_zdma_nodes(VersalVirt *s)
27
}
28
}
19
}
29
20
30
+static void fdt_add_sd_nodes(VersalVirt *s)
21
-/* Invoke a vector expander on two Pregs. */
31
+{
22
-static bool do_vector2_p(DisasContext *s, GVecGen2Fn *gvec_fn,
32
+ const char clocknames[] = "clk_xin\0clk_ahb";
23
- int esz, int rd, int rn)
33
+ const char compat[] = "arasan,sdhci-8.9a";
24
-{
34
+ int i;
25
- if (sve_access_check(s)) {
35
+
26
- unsigned psz = pred_gvec_reg_size(s);
36
+ for (i = ARRAY_SIZE(s->soc.pmc.iou.sd) - 1; i >= 0; i--) {
27
- gvec_fn(esz, pred_full_reg_offset(s, rd),
37
+ uint64_t addr = MM_PMC_SD0 + MM_PMC_SD0_SIZE * i;
28
- pred_full_reg_offset(s, rn), psz, psz);
38
+ char *name = g_strdup_printf("/sdhci@%" PRIx64, addr);
29
- }
39
+
30
- return true;
40
+ qemu_fdt_add_subnode(s->fdt, name);
31
-}
41
+
32
-
42
+ qemu_fdt_setprop_cells(s->fdt, name, "clocks",
33
/* Invoke a vector expander on three Pregs. */
43
+ s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
34
static bool do_vector3_p(DisasContext *s, GVecGen3Fn *gvec_fn,
44
+ qemu_fdt_setprop(s->fdt, name, "clock-names",
35
int esz, int rd, int rn, int rm)
45
+ clocknames, sizeof(clocknames));
36
@@ -XXX,XX +XXX,XX @@ static bool do_vecop4_p(DisasContext *s, const GVecGen4 *gvec_op,
46
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
37
/* Invoke a vector move on two Pregs. */
47
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_SD0_IRQ_0 + i * 2,
38
static bool do_mov_p(DisasContext *s, int rd, int rn)
48
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
39
{
49
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
40
- return do_vector2_p(s, tcg_gen_gvec_mov, 0, rd, rn);
50
+ 2, addr, 2, MM_PMC_SD0_SIZE);
41
+ if (sve_access_check(s)) {
51
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
42
+ unsigned psz = pred_gvec_reg_size(s);
52
+ g_free(name);
43
+ tcg_gen_gvec_mov(MO_8, pred_full_reg_offset(s, rd),
44
+ pred_full_reg_offset(s, rn), psz, psz);
53
+ }
45
+ }
54
+}
46
+ return true;
55
+
56
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
57
{
58
Error *err = NULL;
59
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
60
}
61
}
47
}
62
48
63
+static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
49
/* Set the cpu flags as per a return from an SVE helper. */
64
+{
65
+ BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
66
+ DeviceState *card;
67
+
68
+ card = qdev_create(qdev_get_child_bus(DEVICE(sd), "sd-bus"), TYPE_SD_CARD);
69
+ object_property_add_child(OBJECT(sd), "card[*]", OBJECT(card),
70
+ &error_fatal);
71
+ qdev_prop_set_drive(card, "drive", blk, &error_fatal);
72
+ object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
73
+}
74
+
75
static void versal_virt_init(MachineState *machine)
76
{
77
VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
78
int psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
79
+ int i;
80
81
/*
82
* If the user provides an Operating System to be loaded, we expect them
83
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
84
fdt_add_gic_nodes(s);
85
fdt_add_timer_nodes(s);
86
fdt_add_zdma_nodes(s);
87
+ fdt_add_sd_nodes(s);
88
fdt_add_cpu_nodes(s, psci_conduit);
89
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
90
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
91
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
92
memory_region_add_subregion_overlap(get_system_memory(),
93
0, &s->soc.fpd.apu.mr, 0);
94
95
+ /* Plugin SD cards. */
96
+ for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
97
+ sd_plugin_card(&s->soc.pmc.iou.sd[i], drive_get_next(IF_SD));
98
+ }
99
+
100
s->binfo.ram_size = machine->ram_size;
101
s->binfo.loader_start = 0x0;
102
s->binfo.get_dtb = versal_virt_get_dtb;
103
--
50
--
104
2.20.1
51
2.20.1
105
52
106
53
diff view generated by jsdifflib
1
Convert VCMLA (scalar) in the 2reg-scalar-ext group to decodetree.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Move the check for !S into do_pppp_flags, which allows to merge in
4
do_vecop4_p. Split out gen_gvec_fn_ppp without sve_access_check,
5
to mirror gen_gvec_fn_zzz.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20200815013145.539409-7-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-9-peter.maydell@linaro.org
6
---
11
---
7
target/arm/neon-shared.decode | 5 +++++
12
target/arm/translate-sve.c | 111 ++++++++++++++-----------------------
8
target/arm/translate-neon.inc.c | 40 +++++++++++++++++++++++++++++++++
13
1 file changed, 43 insertions(+), 68 deletions(-)
9
target/arm/translate.c | 26 +--------------------
14
10
3 files changed, 46 insertions(+), 25 deletions(-)
15
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
11
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
17
--- a/target/arm/translate-sve.c
15
+++ b/target/arm/neon-shared.decode
18
+++ b/target/arm/translate-sve.c
16
@@ -XXX,XX +XXX,XX @@ VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
19
@@ -XXX,XX +XXX,XX @@ static void do_dupi_z(DisasContext *s, int rd, uint64_t word)
17
vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
20
}
18
VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
21
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
22
/* Invoke a vector expander on three Pregs. */
20
+
23
-static bool do_vector3_p(DisasContext *s, GVecGen3Fn *gvec_fn,
21
+VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
24
- int esz, int rd, int rn, int rm)
22
+ vn=%vn_dp vd=%vd_dp size=0
25
+static void gen_gvec_fn_ppp(DisasContext *s, GVecGen3Fn *gvec_fn,
23
+VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
26
+ int rd, int rn, int rm)
24
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
27
{
25
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
- if (sve_access_check(s)) {
26
index XXXXXXX..XXXXXXX 100644
29
- unsigned psz = pred_gvec_reg_size(s);
27
--- a/target/arm/translate-neon.inc.c
30
- gvec_fn(esz, pred_full_reg_offset(s, rd),
28
+++ b/target/arm/translate-neon.inc.c
31
- pred_full_reg_offset(s, rn),
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML(DisasContext *s, arg_VFML *a)
32
- pred_full_reg_offset(s, rm), psz, psz);
30
gen_helper_gvec_fmlal_a32);
33
- }
31
return true;
34
- return true;
32
}
35
-}
33
+
36
-
34
+static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
37
-/* Invoke a vector operation on four Pregs. */
35
+{
38
-static bool do_vecop4_p(DisasContext *s, const GVecGen4 *gvec_op,
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
39
- int rd, int rn, int rm, int rg)
37
+ int opr_sz;
40
-{
38
+ TCGv_ptr fpst;
41
- if (sve_access_check(s)) {
39
+
42
- unsigned psz = pred_gvec_reg_size(s);
40
+ if (!dc_isar_feature(aa32_vcma, s)) {
43
- tcg_gen_gvec_4(pred_full_reg_offset(s, rd),
41
+ return false;
44
- pred_full_reg_offset(s, rn),
42
+ }
45
- pred_full_reg_offset(s, rm),
43
+ if (a->size == 0 && !dc_isar_feature(aa32_fp16_arith, s)) {
46
- pred_full_reg_offset(s, rg),
44
+ return false;
47
- psz, psz, gvec_op);
45
+ }
48
- }
46
+
49
- return true;
47
+ /* UNDEF accesses to D16-D31 if they don't exist. */
50
+ unsigned psz = pred_gvec_reg_size(s);
48
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
51
+ gvec_fn(MO_64, pred_full_reg_offset(s, rd),
49
+ ((a->vd | a->vn | a->vm) & 0x10)) {
52
+ pred_full_reg_offset(s, rn),
50
+ return false;
53
+ pred_full_reg_offset(s, rm), psz, psz);
51
+ }
54
}
52
+
55
53
+ if ((a->vd | a->vn) & a->q) {
56
/* Invoke a vector move on two Pregs. */
54
+ return false;
57
@@ -XXX,XX +XXX,XX @@ static bool do_pppp_flags(DisasContext *s, arg_rprr_s *a,
55
+ }
58
int mofs = pred_full_reg_offset(s, a->rm);
56
+
59
int gofs = pred_full_reg_offset(s, a->pg);
57
+ if (!vfp_access_check(s)) {
60
61
+ if (!a->s) {
62
+ tcg_gen_gvec_4(dofs, nofs, mofs, gofs, psz, psz, gvec_op);
58
+ return true;
63
+ return true;
59
+ }
64
+ }
60
+
65
+
61
+ fn_gvec_ptr = (a->size ? gen_helper_gvec_fcmlas_idx
66
if (psz == 8) {
62
+ : gen_helper_gvec_fcmlah_idx);
67
/* Do the operation and the flags generation in temps. */
63
+ opr_sz = (1 + a->q) * 8;
68
TCGv_i64 pd = tcg_temp_new_i64();
64
+ fpst = get_fpstatus_ptr(1);
69
@@ -XXX,XX +XXX,XX @@ static bool trans_AND_pppp(DisasContext *s, arg_rprr_s *a)
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
70
.fno = gen_helper_sve_and_pppp,
66
+ vfp_reg_offset(1, a->vn),
71
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
67
+ vfp_reg_offset(1, a->vm),
72
};
68
+ fpst, opr_sz, opr_sz,
73
- if (a->s) {
69
+ (a->index << 2) | a->rot, fn_gvec_ptr);
74
- return do_pppp_flags(s, a, &op);
70
+ tcg_temp_free_ptr(fpst);
75
- } else if (a->rn == a->rm) {
71
+ return true;
76
- if (a->pg == a->rn) {
72
+}
77
- return do_mov_p(s, a->rd, a->rn);
73
diff --git a/target/arm/translate.c b/target/arm/translate.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/target/arm/translate.c
76
+++ b/target/arm/translate.c
77
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
78
bool is_long = false, q = extract32(insn, 6, 1);
79
bool ptr_is_env = false;
80
81
- if ((insn & 0xff000f10) == 0xfe000800) {
82
- /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
83
- int rot = extract32(insn, 20, 2);
84
- int size = extract32(insn, 23, 1);
85
- int index;
86
-
87
- if (!dc_isar_feature(aa32_vcma, s)) {
88
- return 1;
89
- }
90
- if (size == 0) {
91
- if (!dc_isar_feature(aa32_fp16_arith, s)) {
92
- return 1;
93
- }
94
- /* For fp16, rm is just Vm, and index is M. */
95
- rm = extract32(insn, 0, 4);
96
- index = extract32(insn, 5, 1);
97
- } else {
78
- } else {
98
- /* For fp32, rm is the usual M:Vm, and index is 0. */
79
- return do_vector3_p(s, tcg_gen_gvec_and, 0, a->rd, a->rn, a->pg);
99
- VFP_DREG_M(rm, insn);
80
+
100
- index = 0;
81
+ if (!a->s) {
101
- }
82
+ if (!sve_access_check(s)) {
102
- data = (index << 2) | rot;
83
+ return true;
103
- fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
84
+ }
104
- : gen_helper_gvec_fcmlah_idx);
85
+ if (a->rn == a->rm) {
105
- } else if ((insn & 0xffb00f00) == 0xfe200d00) {
86
+ if (a->pg == a->rn) {
106
+ if ((insn & 0xffb00f00) == 0xfe200d00) {
87
+ do_mov_p(s, a->rd, a->rn);
107
/* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
88
+ } else {
108
int u = extract32(insn, 4, 1);
89
+ gen_gvec_fn_ppp(s, tcg_gen_gvec_and, a->rd, a->rn, a->pg);
109
90
+ }
91
+ return true;
92
+ } else if (a->pg == a->rn || a->pg == a->rm) {
93
+ gen_gvec_fn_ppp(s, tcg_gen_gvec_and, a->rd, a->rn, a->rm);
94
+ return true;
95
}
96
- } else if (a->pg == a->rn || a->pg == a->rm) {
97
- return do_vector3_p(s, tcg_gen_gvec_and, 0, a->rd, a->rn, a->rm);
98
- } else {
99
- return do_vecop4_p(s, &op, a->rd, a->rn, a->rm, a->pg);
100
}
101
+ return do_pppp_flags(s, a, &op);
102
}
103
104
static void gen_bic_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg)
105
@@ -XXX,XX +XXX,XX @@ static bool trans_BIC_pppp(DisasContext *s, arg_rprr_s *a)
106
.fno = gen_helper_sve_bic_pppp,
107
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
108
};
109
- if (a->s) {
110
- return do_pppp_flags(s, a, &op);
111
- } else if (a->pg == a->rn) {
112
- return do_vector3_p(s, tcg_gen_gvec_andc, 0, a->rd, a->rn, a->rm);
113
- } else {
114
- return do_vecop4_p(s, &op, a->rd, a->rn, a->rm, a->pg);
115
+
116
+ if (!a->s && a->pg == a->rn) {
117
+ if (sve_access_check(s)) {
118
+ gen_gvec_fn_ppp(s, tcg_gen_gvec_andc, a->rd, a->rn, a->rm);
119
+ }
120
+ return true;
121
}
122
+ return do_pppp_flags(s, a, &op);
123
}
124
125
static void gen_eor_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg)
126
@@ -XXX,XX +XXX,XX @@ static bool trans_EOR_pppp(DisasContext *s, arg_rprr_s *a)
127
.fno = gen_helper_sve_eor_pppp,
128
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
129
};
130
- if (a->s) {
131
- return do_pppp_flags(s, a, &op);
132
- } else {
133
- return do_vecop4_p(s, &op, a->rd, a->rn, a->rm, a->pg);
134
- }
135
+ return do_pppp_flags(s, a, &op);
136
}
137
138
static void gen_sel_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg)
139
@@ -XXX,XX +XXX,XX @@ static bool trans_SEL_pppp(DisasContext *s, arg_rprr_s *a)
140
.fno = gen_helper_sve_sel_pppp,
141
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
142
};
143
+
144
if (a->s) {
145
return false;
146
- } else {
147
- return do_vecop4_p(s, &op, a->rd, a->rn, a->rm, a->pg);
148
}
149
+ return do_pppp_flags(s, a, &op);
150
}
151
152
static void gen_orr_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg)
153
@@ -XXX,XX +XXX,XX @@ static bool trans_ORR_pppp(DisasContext *s, arg_rprr_s *a)
154
.fno = gen_helper_sve_orr_pppp,
155
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
156
};
157
- if (a->s) {
158
- return do_pppp_flags(s, a, &op);
159
- } else if (a->pg == a->rn && a->rn == a->rm) {
160
+
161
+ if (!a->s && a->pg == a->rn && a->rn == a->rm) {
162
return do_mov_p(s, a->rd, a->rn);
163
- } else {
164
- return do_vecop4_p(s, &op, a->rd, a->rn, a->rm, a->pg);
165
}
166
+ return do_pppp_flags(s, a, &op);
167
}
168
169
static void gen_orn_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg)
170
@@ -XXX,XX +XXX,XX @@ static bool trans_ORN_pppp(DisasContext *s, arg_rprr_s *a)
171
.fno = gen_helper_sve_orn_pppp,
172
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
173
};
174
- if (a->s) {
175
- return do_pppp_flags(s, a, &op);
176
- } else {
177
- return do_vecop4_p(s, &op, a->rd, a->rn, a->rm, a->pg);
178
- }
179
+ return do_pppp_flags(s, a, &op);
180
}
181
182
static void gen_nor_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg)
183
@@ -XXX,XX +XXX,XX @@ static bool trans_NOR_pppp(DisasContext *s, arg_rprr_s *a)
184
.fno = gen_helper_sve_nor_pppp,
185
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
186
};
187
- if (a->s) {
188
- return do_pppp_flags(s, a, &op);
189
- } else {
190
- return do_vecop4_p(s, &op, a->rd, a->rn, a->rm, a->pg);
191
- }
192
+ return do_pppp_flags(s, a, &op);
193
}
194
195
static void gen_nand_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg)
196
@@ -XXX,XX +XXX,XX @@ static bool trans_NAND_pppp(DisasContext *s, arg_rprr_s *a)
197
.fno = gen_helper_sve_nand_pppp,
198
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
199
};
200
- if (a->s) {
201
- return do_pppp_flags(s, a, &op);
202
- } else {
203
- return do_vecop4_p(s, &op, a->rd, a->rn, a->rm, a->pg);
204
- }
205
+ return do_pppp_flags(s, a, &op);
206
}
207
208
/*
110
--
209
--
111
2.20.1
210
2.20.1
112
211
113
212
diff view generated by jsdifflib
1
We define ARMMMUIdx_Stage2 as being an MMU index which uses a QEMU
1
From: Richard Henderson <richard.henderson@linaro.org>
2
TLB. However we never actually use the TLB -- all stage 2 lookups
3
are done by direct calls to get_phys_addr_lpae() followed by a
4
physical address load via address_space_ld*().
5
2
6
Remove Stage2 from the list of ARM MMU indexes which correspond to
3
The gvec operation was added after the initial implementation
7
real core MMU indexes, and instead put it in the set of "NOTLB" ARM
4
of the SEL instruction and was missed in the conversion.
8
MMU indexes.
9
5
10
This allows us to drop NB_MMU_MODES to 11. It also means we can
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
safely add support for the ARMv8.3-TTS2UXN extension, which adds
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
permission bits to the stage 2 descriptors which define execute
8
Message-id: 20200815013145.539409-8-richard.henderson@linaro.org
13
permission separatel for EL0 and EL1; supporting that while keeping
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Stage2 in a QEMU TLB would require us to use separate TLBs for
10
---
15
"Stage2 for an EL0 access" and "Stage2 for an EL1 access", which is a
11
target/arm/translate-sve.c | 31 ++++++++-----------------------
16
lot of extra complication given we aren't even using the QEMU TLB.
12
1 file changed, 8 insertions(+), 23 deletions(-)
17
13
18
In the process of updating the comment on our MMU index use,
14
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
19
fix a couple of other minor errors:
20
* NS EL2 EL2&0 was missing from the list in the comment
21
* some text hadn't been updated from when we bumped NB_MMU_MODES
22
above 8
23
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20200330210400.11724-2-peter.maydell@linaro.org
28
---
29
target/arm/cpu-param.h | 2 +-
30
target/arm/cpu.h | 21 +++++---
31
target/arm/helper.c | 112 ++++-------------------------------------
32
3 files changed, 27 insertions(+), 108 deletions(-)
33
34
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
35
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/cpu-param.h
16
--- a/target/arm/translate-sve.c
37
+++ b/target/arm/cpu-param.h
17
+++ b/target/arm/translate-sve.c
38
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static bool trans_EOR_pppp(DisasContext *s, arg_rprr_s *a)
39
# define TARGET_PAGE_BITS_MIN 10
19
return do_pppp_flags(s, a, &op);
40
#endif
41
42
-#define NB_MMU_MODES 12
43
+#define NB_MMU_MODES 11
44
45
#endif
46
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/cpu.h
49
+++ b/target/arm/cpu.h
50
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
51
* handling via the TLB. The only way to do a stage 1 translation without
52
* the immediate stage 2 translation is via the ATS or AT system insns,
53
* which can be slow-pathed and always do a page table walk.
54
+ * The only use of stage 2 translations is either as part of an s1+2
55
+ * lookup or when loading the descriptors during a stage 1 page table walk,
56
+ * and in both those cases we don't use the TLB.
57
* 4. we can also safely fold together the "32 bit EL3" and "64 bit EL3"
58
* translation regimes, because they map reasonably well to each other
59
* and they can't both be active at the same time.
60
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
61
* NS EL1 EL1&0 stage 1+2 (aka NS PL1)
62
* NS EL1 EL1&0 stage 1+2 +PAN
63
* NS EL0 EL2&0
64
+ * NS EL2 EL2&0
65
* NS EL2 EL2&0 +PAN
66
* NS EL2 (aka NS PL2)
67
* S EL0 EL1&0 (aka S PL0)
68
* S EL1 EL1&0 (not used if EL3 is 32 bit)
69
* S EL1 EL1&0 +PAN
70
* S EL3 (aka S PL1)
71
- * NS EL1&0 stage 2
72
*
73
- * for a total of 12 different mmu_idx.
74
+ * for a total of 11 different mmu_idx.
75
*
76
* R profile CPUs have an MPU, but can use the same set of MMU indexes
77
* as A profile. They only need to distinguish NS EL0 and NS EL1 (and
78
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
79
* are not quite the same -- different CPU types (most notably M profile
80
* vs A/R profile) would like to use MMU indexes with different semantics,
81
* but since we don't ever need to use all of those in a single CPU we
82
- * can avoid setting NB_MMU_MODES to more than 8. The lower bits of
83
+ * can avoid having to set NB_MMU_MODES to "total number of A profile MMU
84
+ * modes + total number of M profile MMU modes". The lower bits of
85
* ARMMMUIdx are the core TLB mmu index, and the higher bits are always
86
* the same for any particular CPU.
87
* Variables of type ARMMUIdx are always full values, and the core
88
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
89
ARMMMUIdx_SE10_1_PAN = 9 | ARM_MMU_IDX_A,
90
ARMMMUIdx_SE3 = 10 | ARM_MMU_IDX_A,
91
92
- ARMMMUIdx_Stage2 = 11 | ARM_MMU_IDX_A,
93
-
94
/*
95
* These are not allocated TLBs and are used only for AT system
96
* instructions or for the first stage of an S12 page table walk.
97
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
98
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
99
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
100
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
101
+ /*
102
+ * Not allocated a TLB: used only for second stage of an S12 page
103
+ * table walk, or for descriptor loads during first stage of an S1
104
+ * page table walk. Note that if we ever want to have a TLB for this
105
+ * then various TLB flush insns which currently are no-ops or flush
106
+ * only stage 1 MMU indexes will need to change to flush stage 2.
107
+ */
108
+ ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
109
110
/*
111
* M-profile.
112
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
113
TO_CORE_BIT(SE10_1),
114
TO_CORE_BIT(SE10_1_PAN),
115
TO_CORE_BIT(SE3),
116
- TO_CORE_BIT(Stage2),
117
118
TO_CORE_BIT(MUser),
119
TO_CORE_BIT(MPriv),
120
diff --git a/target/arm/helper.c b/target/arm/helper.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/target/arm/helper.c
123
+++ b/target/arm/helper.c
124
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
125
tlb_flush_by_mmuidx(cs,
126
ARMMMUIdxBit_E10_1 |
127
ARMMMUIdxBit_E10_1_PAN |
128
- ARMMMUIdxBit_E10_0 |
129
- ARMMMUIdxBit_Stage2);
130
+ ARMMMUIdxBit_E10_0);
131
}
20
}
132
21
133
static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
22
-static void gen_sel_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg)
134
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
135
tlb_flush_by_mmuidx_all_cpus_synced(cs,
136
ARMMMUIdxBit_E10_1 |
137
ARMMMUIdxBit_E10_1_PAN |
138
- ARMMMUIdxBit_E10_0 |
139
- ARMMMUIdxBit_Stage2);
140
+ ARMMMUIdxBit_E10_0);
141
}
142
143
-static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
144
- uint64_t value)
145
-{
23
-{
146
- /* Invalidate by IPA. This has to invalidate any structures that
24
- tcg_gen_and_i64(pn, pn, pg);
147
- * contain only stage 2 translation information, but does not need
25
- tcg_gen_andc_i64(pm, pm, pg);
148
- * to apply to structures that contain combined stage 1 and stage 2
26
- tcg_gen_or_i64(pd, pn, pm);
149
- * translation information.
150
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
151
- */
152
- CPUState *cs = env_cpu(env);
153
- uint64_t pageaddr;
154
-
155
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
156
- return;
157
- }
158
-
159
- pageaddr = sextract64(value << 12, 0, 40);
160
-
161
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
162
-}
27
-}
163
-
28
-
164
-static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
29
-static void gen_sel_pg_vec(unsigned vece, TCGv_vec pd, TCGv_vec pn,
165
- uint64_t value)
30
- TCGv_vec pm, TCGv_vec pg)
166
-{
31
-{
167
- CPUState *cs = env_cpu(env);
32
- tcg_gen_and_vec(vece, pn, pn, pg);
168
- uint64_t pageaddr;
33
- tcg_gen_andc_vec(vece, pm, pm, pg);
169
-
34
- tcg_gen_or_vec(vece, pd, pn, pm);
170
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
171
- return;
172
- }
173
-
174
- pageaddr = sextract64(value << 12, 0, 40);
175
-
176
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
177
- ARMMMUIdxBit_Stage2);
178
-}
179
180
static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
181
uint64_t value)
182
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
183
tlb_flush_by_mmuidx(cs,
184
ARMMMUIdxBit_E10_1 |
185
ARMMMUIdxBit_E10_1_PAN |
186
- ARMMMUIdxBit_E10_0 |
187
- ARMMMUIdxBit_Stage2);
188
+ ARMMMUIdxBit_E10_0);
189
raw_write(env, ri, value);
190
}
191
}
192
@@ -XXX,XX +XXX,XX @@ static int alle1_tlbmask(CPUARMState *env)
193
return ARMMMUIdxBit_SE10_1 |
194
ARMMMUIdxBit_SE10_1_PAN |
195
ARMMMUIdxBit_SE10_0;
196
- } else if (arm_feature(env, ARM_FEATURE_EL2)) {
197
- return ARMMMUIdxBit_E10_1 |
198
- ARMMMUIdxBit_E10_1_PAN |
199
- ARMMMUIdxBit_E10_0 |
200
- ARMMMUIdxBit_Stage2;
201
} else {
202
return ARMMMUIdxBit_E10_1 |
203
ARMMMUIdxBit_E10_1_PAN |
204
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
205
ARMMMUIdxBit_SE3);
206
}
207
208
-static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
209
- uint64_t value)
210
-{
211
- /* Invalidate by IPA. This has to invalidate any structures that
212
- * contain only stage 2 translation information, but does not need
213
- * to apply to structures that contain combined stage 1 and stage 2
214
- * translation information.
215
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
216
- */
217
- ARMCPU *cpu = env_archcpu(env);
218
- CPUState *cs = CPU(cpu);
219
- uint64_t pageaddr;
220
-
221
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
222
- return;
223
- }
224
-
225
- pageaddr = sextract64(value << 12, 0, 48);
226
-
227
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
228
-}
35
-}
229
-
36
-
230
-static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
37
static bool trans_SEL_pppp(DisasContext *s, arg_rprr_s *a)
231
- uint64_t value)
38
{
232
-{
39
- static const GVecGen4 op = {
233
- CPUState *cs = env_cpu(env);
40
- .fni8 = gen_sel_pg_i64,
234
- uint64_t pageaddr;
41
- .fniv = gen_sel_pg_vec,
42
- .fno = gen_helper_sve_sel_pppp,
43
- .prefer_i64 = TCG_TARGET_REG_BITS == 64,
44
- };
235
-
45
-
236
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
46
if (a->s) {
237
- return;
47
return false;
238
- }
48
}
239
-
49
- return do_pppp_flags(s, a, &op);
240
- pageaddr = sextract64(value << 12, 0, 48);
50
+ if (sve_access_check(s)) {
241
-
51
+ unsigned psz = pred_gvec_reg_size(s);
242
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
52
+ tcg_gen_gvec_bitsel(MO_8, pred_full_reg_offset(s, a->rd),
243
- ARMMMUIdxBit_Stage2);
53
+ pred_full_reg_offset(s, a->pg),
244
-}
54
+ pred_full_reg_offset(s, a->rn),
245
-
55
+ pred_full_reg_offset(s, a->rm), psz, psz);
246
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
56
+ }
247
bool isread)
57
+ return true;
248
{
58
}
249
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
59
250
.writefn = tlbi_aa64_vae1_write },
60
static void gen_orr_pg_i64(TCGv_i64 pd, TCGv_i64 pn, TCGv_i64 pm, TCGv_i64 pg)
251
{ .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
252
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
253
- .access = PL2_W, .type = ARM_CP_NO_RAW,
254
- .writefn = tlbi_aa64_ipas2e1is_write },
255
+ .access = PL2_W, .type = ARM_CP_NOP },
256
{ .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64,
257
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
258
- .access = PL2_W, .type = ARM_CP_NO_RAW,
259
- .writefn = tlbi_aa64_ipas2e1is_write },
260
+ .access = PL2_W, .type = ARM_CP_NOP },
261
{ .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
262
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
263
.access = PL2_W, .type = ARM_CP_NO_RAW,
264
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
265
.writefn = tlbi_aa64_alle1is_write },
266
{ .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64,
267
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
268
- .access = PL2_W, .type = ARM_CP_NO_RAW,
269
- .writefn = tlbi_aa64_ipas2e1_write },
270
+ .access = PL2_W, .type = ARM_CP_NOP },
271
{ .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64,
272
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
273
- .access = PL2_W, .type = ARM_CP_NO_RAW,
274
- .writefn = tlbi_aa64_ipas2e1_write },
275
+ .access = PL2_W, .type = ARM_CP_NOP },
276
{ .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64,
277
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
278
.access = PL2_W, .type = ARM_CP_NO_RAW,
279
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
280
.writefn = tlbimva_hyp_is_write },
281
{ .name = "TLBIIPAS2",
282
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
283
- .type = ARM_CP_NO_RAW, .access = PL2_W,
284
- .writefn = tlbiipas2_write },
285
+ .type = ARM_CP_NOP, .access = PL2_W },
286
{ .name = "TLBIIPAS2IS",
287
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
288
- .type = ARM_CP_NO_RAW, .access = PL2_W,
289
- .writefn = tlbiipas2_is_write },
290
+ .type = ARM_CP_NOP, .access = PL2_W },
291
{ .name = "TLBIIPAS2L",
292
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
293
- .type = ARM_CP_NO_RAW, .access = PL2_W,
294
- .writefn = tlbiipas2_write },
295
+ .type = ARM_CP_NOP, .access = PL2_W },
296
{ .name = "TLBIIPAS2LIS",
297
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
298
- .type = ARM_CP_NO_RAW, .access = PL2_W,
299
- .writefn = tlbiipas2_is_write },
300
+ .type = ARM_CP_NOP, .access = PL2_W },
301
/* 32 bit cache operations */
302
{ .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
303
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
304
--
61
--
305
2.20.1
62
2.20.1
306
63
307
64
diff view generated by jsdifflib
1
Convert the Neon "load/store multiple structures" insns to decodetree.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Model after gen_gvec_fn_zzz et al.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20200815013145.539409-9-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-12-peter.maydell@linaro.org
6
---
9
---
7
target/arm/neon-ls.decode | 7 ++
10
target/arm/translate-sve.c | 35 ++++++++++++++++-------------------
8
target/arm/translate-neon.inc.c | 124 ++++++++++++++++++++++++++++++++
11
1 file changed, 16 insertions(+), 19 deletions(-)
9
target/arm/translate.c | 91 +----------------------
10
3 files changed, 133 insertions(+), 89 deletions(-)
11
12
12
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
13
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-ls.decode
15
--- a/target/arm/translate-sve.c
15
+++ b/target/arm/neon-ls.decode
16
+++ b/target/arm/translate-sve.c
16
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static int pred_gvec_reg_size(DisasContext *s)
17
# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
18
return size_for_gvec(pred_full_reg_size(s));
18
# This file works on the A32 encoding only; calling code for T32 has to
19
}
19
# transform the insn into the A32 version first.
20
20
+
21
-/* Invoke a vector expander on two Zregs. */
21
+%vd_dp 22:1 12:4
22
+/* Invoke an out-of-line helper on 3 Zregs and a predicate. */
22
+
23
+static void gen_gvec_ool_zzzp(DisasContext *s, gen_helper_gvec_4 *fn,
23
+# Neon load/store multiple structures
24
+ int rd, int rn, int rm, int pg, int data)
24
+
25
+{
25
+VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
26
+ unsigned vsz = vec_full_reg_size(s);
26
+ vd=%vd_dp
27
+ tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
+ vec_full_reg_offset(s, rn),
28
index XXXXXXX..XXXXXXX 100644
29
+ vec_full_reg_offset(s, rm),
29
--- a/target/arm/translate-neon.inc.c
30
+ pred_full_reg_offset(s, pg),
30
+++ b/target/arm/translate-neon.inc.c
31
+ vsz, vsz, data, fn);
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
32
+}
32
gen_helper_gvec_fmlal_idx_a32);
33
34
+/* Invoke a vector expander on two Zregs. */
35
static void gen_gvec_fn_zz(DisasContext *s, GVecGen2Fn *gvec_fn,
36
int esz, int rd, int rn)
37
{
38
@@ -XXX,XX +XXX,XX @@ static bool trans_UQSUB_zzz(DisasContext *s, arg_rrr_esz *a)
39
40
static bool do_zpzz_ool(DisasContext *s, arg_rprr_esz *a, gen_helper_gvec_4 *fn)
41
{
42
- unsigned vsz = vec_full_reg_size(s);
43
if (fn == NULL) {
44
return false;
45
}
46
if (sve_access_check(s)) {
47
- tcg_gen_gvec_4_ool(vec_full_reg_offset(s, a->rd),
48
- vec_full_reg_offset(s, a->rn),
49
- vec_full_reg_offset(s, a->rm),
50
- pred_full_reg_offset(s, a->pg),
51
- vsz, vsz, 0, fn);
52
+ gen_gvec_ool_zzzp(s, fn, a->rd, a->rn, a->rm, a->pg, 0);
53
}
33
return true;
54
return true;
34
}
55
}
35
+
56
@@ -XXX,XX +XXX,XX @@ static void do_sel_z(DisasContext *s, int rd, int rn, int rm, int pg, int esz)
36
+static struct {
57
gen_helper_sve_sel_zpzz_b, gen_helper_sve_sel_zpzz_h,
37
+ int nregs;
58
gen_helper_sve_sel_zpzz_s, gen_helper_sve_sel_zpzz_d
38
+ int interleave;
59
};
39
+ int spacing;
60
- unsigned vsz = vec_full_reg_size(s);
40
+} const neon_ls_element_type[11] = {
61
- tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
41
+ {1, 4, 1},
62
- vec_full_reg_offset(s, rn),
42
+ {1, 4, 2},
63
- vec_full_reg_offset(s, rm),
43
+ {4, 1, 1},
64
- pred_full_reg_offset(s, pg),
44
+ {2, 2, 2},
65
- vsz, vsz, 0, fns[esz]);
45
+ {1, 3, 1},
66
+ gen_gvec_ool_zzzp(s, fns[esz], rd, rn, rm, pg, 0);
46
+ {1, 3, 2},
47
+ {3, 1, 1},
48
+ {1, 1, 1},
49
+ {1, 2, 1},
50
+ {1, 2, 2},
51
+ {2, 1, 1}
52
+};
53
+
54
+static void gen_neon_ldst_base_update(DisasContext *s, int rm, int rn,
55
+ int stride)
56
+{
57
+ if (rm != 15) {
58
+ TCGv_i32 base;
59
+
60
+ base = load_reg(s, rn);
61
+ if (rm == 13) {
62
+ tcg_gen_addi_i32(base, base, stride);
63
+ } else {
64
+ TCGv_i32 index;
65
+ index = load_reg(s, rm);
66
+ tcg_gen_add_i32(base, base, index);
67
+ tcg_temp_free_i32(index);
68
+ }
69
+ store_reg(s, rn, base);
70
+ }
71
+}
72
+
73
+static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
74
+{
75
+ /* Neon load/store multiple structures */
76
+ int nregs, interleave, spacing, reg, n;
77
+ MemOp endian = s->be_data;
78
+ int mmu_idx = get_mem_index(s);
79
+ int size = a->size;
80
+ TCGv_i64 tmp64;
81
+ TCGv_i32 addr, tmp;
82
+
83
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
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) && (a->vd & 0x10)) {
89
+ return false;
90
+ }
91
+ if (a->itype > 10) {
92
+ return false;
93
+ }
94
+ /* Catch UNDEF cases for bad values of align field */
95
+ switch (a->itype & 0xc) {
96
+ case 4:
97
+ if (a->align >= 2) {
98
+ return false;
99
+ }
100
+ break;
101
+ case 8:
102
+ if (a->align == 3) {
103
+ return false;
104
+ }
105
+ break;
106
+ default:
107
+ break;
108
+ }
109
+ nregs = neon_ls_element_type[a->itype].nregs;
110
+ interleave = neon_ls_element_type[a->itype].interleave;
111
+ spacing = neon_ls_element_type[a->itype].spacing;
112
+ if (size == 3 && (interleave | spacing) != 1) {
113
+ return false;
114
+ }
115
+
116
+ if (!vfp_access_check(s)) {
117
+ return true;
118
+ }
119
+
120
+ /* For our purposes, bytes are always little-endian. */
121
+ if (size == 0) {
122
+ endian = MO_LE;
123
+ }
124
+ /*
125
+ * Consecutive little-endian elements from a single register
126
+ * can be promoted to a larger little-endian operation.
127
+ */
128
+ if (interleave == 1 && endian == MO_LE) {
129
+ size = 3;
130
+ }
131
+ tmp64 = tcg_temp_new_i64();
132
+ addr = tcg_temp_new_i32();
133
+ tmp = tcg_const_i32(1 << size);
134
+ load_reg_var(s, addr, a->rn);
135
+ for (reg = 0; reg < nregs; reg++) {
136
+ for (n = 0; n < 8 >> size; n++) {
137
+ int xs;
138
+ for (xs = 0; xs < interleave; xs++) {
139
+ int tt = a->vd + reg + spacing * xs;
140
+
141
+ if (a->l) {
142
+ gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
143
+ neon_store_element64(tt, n, size, tmp64);
144
+ } else {
145
+ neon_load_element64(tmp64, tt, n, size);
146
+ gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
147
+ }
148
+ tcg_gen_add_i32(addr, addr, tmp);
149
+ }
150
+ }
151
+ }
152
+ tcg_temp_free_i32(addr);
153
+ tcg_temp_free_i32(tmp);
154
+ tcg_temp_free_i64(tmp64);
155
+
156
+ gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
157
+ return true;
158
+}
159
diff --git a/target/arm/translate.c b/target/arm/translate.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/target/arm/translate.c
162
+++ b/target/arm/translate.c
163
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
164
}
67
}
165
68
166
69
#define DO_ZPZZ(NAME, name) \
167
-static struct {
70
@@ -XXX,XX +XXX,XX @@ static bool trans_RBIT(DisasContext *s, arg_rpr_esz *a)
168
- int nregs;
71
static bool trans_SPLICE(DisasContext *s, arg_rprr_esz *a)
169
- int interleave;
170
- int spacing;
171
-} const neon_ls_element_type[11] = {
172
- {1, 4, 1},
173
- {1, 4, 2},
174
- {4, 1, 1},
175
- {2, 2, 2},
176
- {1, 3, 1},
177
- {1, 3, 2},
178
- {3, 1, 1},
179
- {1, 1, 1},
180
- {1, 2, 1},
181
- {1, 2, 2},
182
- {2, 1, 1}
183
-};
184
-
185
/* Translate a NEON load/store element instruction. Return nonzero if the
186
instruction is invalid. */
187
static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
188
{
72
{
189
int rd, rn, rm;
73
if (sve_access_check(s)) {
190
- int op;
74
- unsigned vsz = vec_full_reg_size(s);
191
int nregs;
75
- tcg_gen_gvec_4_ool(vec_full_reg_offset(s, a->rd),
192
- int interleave;
76
- vec_full_reg_offset(s, a->rn),
193
- int spacing;
77
- vec_full_reg_offset(s, a->rm),
194
int stride;
78
- pred_full_reg_offset(s, a->pg),
195
int size;
79
- vsz, vsz, a->esz, gen_helper_sve_splice);
196
int reg;
80
+ gen_gvec_ool_zzzp(s, gen_helper_sve_splice,
197
int load;
81
+ a->rd, a->rn, a->rm, a->pg, 0);
198
- int n;
82
}
199
int vec_size;
83
return true;
200
- int mmu_idx;
84
}
201
- MemOp endian;
202
TCGv_i32 addr;
203
TCGv_i32 tmp;
204
- TCGv_i32 tmp2;
205
- TCGv_i64 tmp64;
206
207
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
208
return 1;
209
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
210
rn = (insn >> 16) & 0xf;
211
rm = insn & 0xf;
212
load = (insn & (1 << 21)) != 0;
213
- endian = s->be_data;
214
- mmu_idx = get_mem_index(s);
215
if ((insn & (1 << 23)) == 0) {
216
- /* Load store all elements. */
217
- op = (insn >> 8) & 0xf;
218
- size = (insn >> 6) & 3;
219
- if (op > 10)
220
- return 1;
221
- /* Catch UNDEF cases for bad values of align field */
222
- switch (op & 0xc) {
223
- case 4:
224
- if (((insn >> 5) & 1) == 1) {
225
- return 1;
226
- }
227
- break;
228
- case 8:
229
- if (((insn >> 4) & 3) == 3) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- break;
235
- }
236
- nregs = neon_ls_element_type[op].nregs;
237
- interleave = neon_ls_element_type[op].interleave;
238
- spacing = neon_ls_element_type[op].spacing;
239
- if (size == 3 && (interleave | spacing) != 1) {
240
- return 1;
241
- }
242
- /* For our purposes, bytes are always little-endian. */
243
- if (size == 0) {
244
- endian = MO_LE;
245
- }
246
- /* Consecutive little-endian elements from a single register
247
- * can be promoted to a larger little-endian operation.
248
- */
249
- if (interleave == 1 && endian == MO_LE) {
250
- size = 3;
251
- }
252
- tmp64 = tcg_temp_new_i64();
253
- addr = tcg_temp_new_i32();
254
- tmp2 = tcg_const_i32(1 << size);
255
- load_reg_var(s, addr, rn);
256
- for (reg = 0; reg < nregs; reg++) {
257
- for (n = 0; n < 8 >> size; n++) {
258
- int xs;
259
- for (xs = 0; xs < interleave; xs++) {
260
- int tt = rd + reg + spacing * xs;
261
-
262
- if (load) {
263
- gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
264
- neon_store_element64(tt, n, size, tmp64);
265
- } else {
266
- neon_load_element64(tmp64, tt, n, size);
267
- gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
268
- }
269
- tcg_gen_add_i32(addr, addr, tmp2);
270
- }
271
- }
272
- }
273
- tcg_temp_free_i32(addr);
274
- tcg_temp_free_i32(tmp2);
275
- tcg_temp_free_i64(tmp64);
276
- stride = nregs * interleave * 8;
277
+ /* Load store all elements -- handled already by decodetree */
278
+ return 1;
279
} else {
280
size = (insn >> 10) & 3;
281
if (size == 3) {
282
--
85
--
283
2.20.1
86
2.20.1
284
87
285
88
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Embed the GEMs into the SoC type.
3
The existing clr functions have only one vector argument, and so
4
4
can only clear in place. The existing movz functions have two
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
5
vector arguments, and so can clear while moving. Merge them, with
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
a flag that controls the sense of active vs inactive elements
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
being cleared.
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200427181649.26851-6-edgar.iglesias@gmail.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20200815013145.539409-10-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
14
target/arm/helper-sve.h | 5 ---
14
hw/arm/xlnx-versal.c | 15 ++++++++-------
15
target/arm/sve_helper.c | 70 ++++++++------------------------------
15
2 files changed, 10 insertions(+), 8 deletions(-)
16
target/arm/translate-sve.c | 53 +++++++++++------------------
16
17
3 files changed, 34 insertions(+), 94 deletions(-)
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
19
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
21
--- a/target/arm/helper-sve.h
20
+++ b/include/hw/arm/xlnx-versal.h
22
+++ b/target/arm/helper-sve.h
21
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve_uminv_h, TCG_CALL_NO_RWG, i64, ptr, ptr, i32)
22
#include "hw/arm/boot.h"
24
DEF_HELPER_FLAGS_3(sve_uminv_s, TCG_CALL_NO_RWG, i64, ptr, ptr, i32)
23
#include "hw/intc/arm_gicv3.h"
25
DEF_HELPER_FLAGS_3(sve_uminv_d, TCG_CALL_NO_RWG, i64, ptr, ptr, i32)
24
#include "hw/char/pl011.h"
26
25
+#include "hw/net/cadence_gem.h"
27
-DEF_HELPER_FLAGS_3(sve_clr_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
26
28
-DEF_HELPER_FLAGS_3(sve_clr_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
29
-DEF_HELPER_FLAGS_3(sve_clr_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
30
-DEF_HELPER_FLAGS_3(sve_clr_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
31
-
30
32
DEF_HELPER_FLAGS_4(sve_movz_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
struct {
33
DEF_HELPER_FLAGS_4(sve_movz_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
PL011State uart[XLNX_VERSAL_NR_UARTS];
34
DEF_HELPER_FLAGS_4(sve_movz_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
- SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
35
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
34
+ CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
35
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
36
} iou;
37
} lpd;
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
37
--- a/target/arm/sve_helper.c
41
+++ b/hw/arm/xlnx-versal.c
38
+++ b/target/arm/sve_helper.c
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
39
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_pnext)(void *vd, void *vg, uint32_t pred_desc)
43
DeviceState *dev;
40
return flags;
44
MemoryRegion *mr;
41
}
45
42
46
- dev = qdev_create(NULL, "cadence_gem");
43
-/* Store zero into every active element of Zd. We will use this for two
47
- s->lpd.iou.gem[i] = SYS_BUS_DEVICE(dev);
44
- * and three-operand predicated instructions for which logic dictates a
48
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
45
- * zero result. In particular, logical shift by element size, which is
49
+ sysbus_init_child_obj(OBJECT(s), name,
46
- * otherwise undefined on the host.
50
+ &s->lpd.iou.gem[i], sizeof(s->lpd.iou.gem[i]),
47
- *
51
+ TYPE_CADENCE_GEM);
48
- * For element sizes smaller than uint64_t, we use tables to expand
52
+ dev = DEVICE(&s->lpd.iou.gem[i]);
49
- * the N bits of the controlling predicate to a byte mask, and clear
53
if (nd->used) {
50
- * those bytes.
54
qemu_check_nic_model(nd, "cadence_gem");
51
+/*
55
qdev_set_nic_properties(dev, nd);
52
+ * Copy Zn into Zd, and store zero into inactive elements.
56
}
53
+ * If inv, store zeros into the active elements.
57
- object_property_set_int(OBJECT(s->lpd.iou.gem[i]),
54
*/
58
+ object_property_set_int(OBJECT(dev),
55
-void HELPER(sve_clr_b)(void *vd, void *vg, uint32_t desc)
59
2, "num-priority-queues",
56
-{
60
&error_abort);
57
- intptr_t i, opr_sz = simd_oprsz(desc) / 8;
61
- object_property_set_link(OBJECT(s->lpd.iou.gem[i]),
58
- uint64_t *d = vd;
62
+ object_property_set_link(OBJECT(dev),
59
- uint8_t *pg = vg;
63
OBJECT(&s->mr_ps), "dma",
60
- for (i = 0; i < opr_sz; i += 1) {
64
&error_abort);
61
- d[i] &= ~expand_pred_b(pg[H1(i)]);
65
qdev_init_nofail(dev);
62
- }
66
63
-}
67
- mr = sysbus_mmio_get_region(s->lpd.iou.gem[i], 0);
64
-
68
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
65
-void HELPER(sve_clr_h)(void *vd, void *vg, uint32_t desc)
69
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
66
-{
70
67
- intptr_t i, opr_sz = simd_oprsz(desc) / 8;
71
- sysbus_connect_irq(s->lpd.iou.gem[i], 0, pic[irqs[i]]);
68
- uint64_t *d = vd;
72
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
69
- uint8_t *pg = vg;
73
g_free(name);
70
- for (i = 0; i < opr_sz; i += 1) {
74
}
71
- d[i] &= ~expand_pred_h(pg[H1(i)]);
72
- }
73
-}
74
-
75
-void HELPER(sve_clr_s)(void *vd, void *vg, uint32_t desc)
76
-{
77
- intptr_t i, opr_sz = simd_oprsz(desc) / 8;
78
- uint64_t *d = vd;
79
- uint8_t *pg = vg;
80
- for (i = 0; i < opr_sz; i += 1) {
81
- d[i] &= ~expand_pred_s(pg[H1(i)]);
82
- }
83
-}
84
-
85
-void HELPER(sve_clr_d)(void *vd, void *vg, uint32_t desc)
86
-{
87
- intptr_t i, opr_sz = simd_oprsz(desc) / 8;
88
- uint64_t *d = vd;
89
- uint8_t *pg = vg;
90
- for (i = 0; i < opr_sz; i += 1) {
91
- if (pg[H1(i)] & 1) {
92
- d[i] = 0;
93
- }
94
- }
95
-}
96
-
97
-/* Copy Zn into Zd, and store zero into inactive elements. */
98
void HELPER(sve_movz_b)(void *vd, void *vn, void *vg, uint32_t desc)
99
{
100
intptr_t i, opr_sz = simd_oprsz(desc) / 8;
101
+ uint64_t inv = -(uint64_t)(simd_data(desc) & 1);
102
uint64_t *d = vd, *n = vn;
103
uint8_t *pg = vg;
104
+
105
for (i = 0; i < opr_sz; i += 1) {
106
- d[i] = n[i] & expand_pred_b(pg[H1(i)]);
107
+ d[i] = n[i] & (expand_pred_b(pg[H1(i)]) ^ inv);
108
}
109
}
110
111
void HELPER(sve_movz_h)(void *vd, void *vn, void *vg, uint32_t desc)
112
{
113
intptr_t i, opr_sz = simd_oprsz(desc) / 8;
114
+ uint64_t inv = -(uint64_t)(simd_data(desc) & 1);
115
uint64_t *d = vd, *n = vn;
116
uint8_t *pg = vg;
117
+
118
for (i = 0; i < opr_sz; i += 1) {
119
- d[i] = n[i] & expand_pred_h(pg[H1(i)]);
120
+ d[i] = n[i] & (expand_pred_h(pg[H1(i)]) ^ inv);
121
}
122
}
123
124
void HELPER(sve_movz_s)(void *vd, void *vn, void *vg, uint32_t desc)
125
{
126
intptr_t i, opr_sz = simd_oprsz(desc) / 8;
127
+ uint64_t inv = -(uint64_t)(simd_data(desc) & 1);
128
uint64_t *d = vd, *n = vn;
129
uint8_t *pg = vg;
130
+
131
for (i = 0; i < opr_sz; i += 1) {
132
- d[i] = n[i] & expand_pred_s(pg[H1(i)]);
133
+ d[i] = n[i] & (expand_pred_s(pg[H1(i)]) ^ inv);
134
}
135
}
136
137
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_movz_d)(void *vd, void *vn, void *vg, uint32_t desc)
138
intptr_t i, opr_sz = simd_oprsz(desc) / 8;
139
uint64_t *d = vd, *n = vn;
140
uint8_t *pg = vg;
141
+ uint8_t inv = simd_data(desc);
142
+
143
for (i = 0; i < opr_sz; i += 1) {
144
- d[i] = n[i] & -(uint64_t)(pg[H1(i)] & 1);
145
+ d[i] = n[i] & -(uint64_t)((pg[H1(i)] ^ inv) & 1);
146
}
147
}
148
149
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
150
index XXXXXXX..XXXXXXX 100644
151
--- a/target/arm/translate-sve.c
152
+++ b/target/arm/translate-sve.c
153
@@ -XXX,XX +XXX,XX @@ static bool trans_SADDV(DisasContext *s, arg_rpr_esz *a)
154
*** SVE Shift by Immediate - Predicated Group
155
*/
156
157
-/* Store zero into every active element of Zd. We will use this for two
158
- * and three-operand predicated instructions for which logic dictates a
159
- * zero result.
160
+/*
161
+ * Copy Zn into Zd, storing zeros into inactive elements.
162
+ * If invert, store zeros into the active elements.
163
*/
164
-static bool do_clr_zp(DisasContext *s, int rd, int pg, int esz)
165
-{
166
- static gen_helper_gvec_2 * const fns[4] = {
167
- gen_helper_sve_clr_b, gen_helper_sve_clr_h,
168
- gen_helper_sve_clr_s, gen_helper_sve_clr_d,
169
- };
170
- if (sve_access_check(s)) {
171
- unsigned vsz = vec_full_reg_size(s);
172
- tcg_gen_gvec_2_ool(vec_full_reg_offset(s, rd),
173
- pred_full_reg_offset(s, pg),
174
- vsz, vsz, 0, fns[esz]);
175
- }
176
- return true;
177
-}
178
-
179
-/* Copy Zn into Zd, storing zeros into inactive elements. */
180
-static void do_movz_zpz(DisasContext *s, int rd, int rn, int pg, int esz)
181
+static bool do_movz_zpz(DisasContext *s, int rd, int rn, int pg,
182
+ int esz, bool invert)
183
{
184
static gen_helper_gvec_3 * const fns[4] = {
185
gen_helper_sve_movz_b, gen_helper_sve_movz_h,
186
gen_helper_sve_movz_s, gen_helper_sve_movz_d,
187
};
188
- unsigned vsz = vec_full_reg_size(s);
189
- tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
190
- vec_full_reg_offset(s, rn),
191
- pred_full_reg_offset(s, pg),
192
- vsz, vsz, 0, fns[esz]);
193
+
194
+ if (sve_access_check(s)) {
195
+ unsigned vsz = vec_full_reg_size(s);
196
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
197
+ vec_full_reg_offset(s, rn),
198
+ pred_full_reg_offset(s, pg),
199
+ vsz, vsz, invert, fns[esz]);
200
+ }
201
+ return true;
202
}
203
204
static bool do_zpzi_ool(DisasContext *s, arg_rpri_esz *a,
205
@@ -XXX,XX +XXX,XX @@ static bool trans_LSR_zpzi(DisasContext *s, arg_rpri_esz *a)
206
/* Shift by element size is architecturally valid.
207
For logical shifts, it is a zeroing operation. */
208
if (a->imm >= (8 << a->esz)) {
209
- return do_clr_zp(s, a->rd, a->pg, a->esz);
210
+ return do_movz_zpz(s, a->rd, a->rd, a->pg, a->esz, true);
211
} else {
212
return do_zpzi_ool(s, a, fns[a->esz]);
213
}
214
@@ -XXX,XX +XXX,XX @@ static bool trans_LSL_zpzi(DisasContext *s, arg_rpri_esz *a)
215
/* Shift by element size is architecturally valid.
216
For logical shifts, it is a zeroing operation. */
217
if (a->imm >= (8 << a->esz)) {
218
- return do_clr_zp(s, a->rd, a->pg, a->esz);
219
+ return do_movz_zpz(s, a->rd, a->rd, a->pg, a->esz, true);
220
} else {
221
return do_zpzi_ool(s, a, fns[a->esz]);
222
}
223
@@ -XXX,XX +XXX,XX @@ static bool trans_ASRD(DisasContext *s, arg_rpri_esz *a)
224
/* Shift by element size is architecturally valid. For arithmetic
225
right shift for division, it is a zeroing operation. */
226
if (a->imm >= (8 << a->esz)) {
227
- return do_clr_zp(s, a->rd, a->pg, a->esz);
228
+ return do_movz_zpz(s, a->rd, a->rd, a->pg, a->esz, true);
229
} else {
230
return do_zpzi_ool(s, a, fns[a->esz]);
231
}
232
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1R_zpri(DisasContext *s, arg_rpri_load *a)
233
234
/* Zero the inactive elements. */
235
gen_set_label(over);
236
- do_movz_zpz(s, a->rd, a->rd, a->pg, esz);
237
- return true;
238
+ return do_movz_zpz(s, a->rd, a->rd, a->pg, esz, false);
239
}
240
241
static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
242
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVPRFX_m(DisasContext *s, arg_rpr_esz *a)
243
244
static bool trans_MOVPRFX_z(DisasContext *s, arg_rpr_esz *a)
245
{
246
- if (sve_access_check(s)) {
247
- do_movz_zpz(s, a->rd, a->rn, a->pg, a->esz);
248
- }
249
- return true;
250
+ return do_movz_zpz(s, a->rd, a->rn, a->pg, a->esz, false);
75
}
251
}
76
--
252
--
77
2.20.1
253
2.20.1
78
254
79
255
diff view generated by jsdifflib
1
Convert the V[US]DOT (vector) insns to decodetree.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Model after gen_gvec_fn_zzz et al.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20200815013145.539409-11-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-7-peter.maydell@linaro.org
6
---
9
---
7
target/arm/neon-shared.decode | 4 ++++
10
target/arm/translate-sve.c | 29 ++++++++++++++---------------
8
target/arm/translate-neon.inc.c | 32 ++++++++++++++++++++++++++++++++
11
1 file changed, 14 insertions(+), 15 deletions(-)
9
target/arm/translate.c | 9 +--------
10
3 files changed, 37 insertions(+), 8 deletions(-)
11
12
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
15
--- a/target/arm/translate-sve.c
15
+++ b/target/arm/neon-shared.decode
16
+++ b/target/arm/translate-sve.c
16
@@ -XXX,XX +XXX,XX @@ VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
17
@@ -XXX,XX +XXX,XX @@ static int pred_gvec_reg_size(DisasContext *s)
17
18
return size_for_gvec(pred_full_reg_size(s));
18
VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
19
}
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
21
+/* Invoke an out-of-line helper on 2 Zregs and a predicate. */
22
+static void gen_gvec_ool_zzp(DisasContext *s, gen_helper_gvec_3 *fn,
23
+ int rd, int rn, int pg, int data)
24
+{
25
+ unsigned vsz = vec_full_reg_size(s);
26
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
27
+ vec_full_reg_offset(s, rn),
28
+ pred_full_reg_offset(s, pg),
29
+ vsz, vsz, data, fn);
30
+}
20
+
31
+
21
+# VUDOT and VSDOT
32
/* Invoke an out-of-line helper on 3 Zregs and a predicate. */
22
+VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
33
static void gen_gvec_ool_zzzp(DisasContext *s, gen_helper_gvec_4 *fn,
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
34
int rd, int rn, int rm, int pg, int data)
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
35
@@ -XXX,XX +XXX,XX @@ static bool do_zpz_ool(DisasContext *s, arg_rpr_esz *a, gen_helper_gvec_3 *fn)
25
index XXXXXXX..XXXXXXX 100644
36
return false;
26
--- a/target/arm/translate-neon.inc.c
37
}
27
+++ b/target/arm/translate-neon.inc.c
38
if (sve_access_check(s)) {
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
39
- unsigned vsz = vec_full_reg_size(s);
29
tcg_temp_free_ptr(fpst);
40
- tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
41
- vec_full_reg_offset(s, a->rn),
42
- pred_full_reg_offset(s, a->pg),
43
- vsz, vsz, 0, fn);
44
+ gen_gvec_ool_zzp(s, fn, a->rd, a->rn, a->pg, 0);
45
}
30
return true;
46
return true;
31
}
47
}
32
+
48
@@ -XXX,XX +XXX,XX @@ static bool do_movz_zpz(DisasContext *s, int rd, int rn, int pg,
33
+static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
49
};
34
+{
50
35
+ int opr_sz;
51
if (sve_access_check(s)) {
36
+ gen_helper_gvec_3 *fn_gvec;
52
- unsigned vsz = vec_full_reg_size(s);
37
+
53
- tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
38
+ if (!dc_isar_feature(aa32_dp, s)) {
54
- vec_full_reg_offset(s, rn),
39
+ return false;
55
- pred_full_reg_offset(s, pg),
40
+ }
56
- vsz, vsz, invert, fns[esz]);
41
+
57
+ gen_gvec_ool_zzp(s, fns[esz], rd, rn, pg, invert);
42
+ /* UNDEF accesses to D16-D31 if they don't exist. */
58
}
43
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
59
return true;
44
+ ((a->vd | a->vn | a->vm) & 0x10)) {
60
}
45
+ return false;
61
@@ -XXX,XX +XXX,XX @@ static bool do_zpzi_ool(DisasContext *s, arg_rpri_esz *a,
46
+ }
62
gen_helper_gvec_3 *fn)
47
+
63
{
48
+ if ((a->vn | a->vm | a->vd) & a->q) {
64
if (sve_access_check(s)) {
49
+ return false;
65
- unsigned vsz = vec_full_reg_size(s);
50
+ }
66
- tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
51
+
67
- vec_full_reg_offset(s, a->rn),
52
+ if (!vfp_access_check(s)) {
68
- pred_full_reg_offset(s, a->pg),
53
+ return true;
69
- vsz, vsz, a->imm, fn);
54
+ }
70
+ gen_gvec_ool_zzp(s, fn, a->rd, a->rn, a->pg, a->imm);
55
+
71
}
56
+ opr_sz = (1 + a->q) * 8;
72
return true;
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
73
}
58
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
59
+ vfp_reg_offset(1, a->vn),
60
+ vfp_reg_offset(1, a->vm),
61
+ opr_sz, opr_sz, 0, fn_gvec);
62
+ return true;
63
+}
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate.c
67
+++ b/target/arm/translate.c
68
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
69
bool is_long = false, q = extract32(insn, 6, 1);
70
bool ptr_is_env = false;
71
72
- if ((insn & 0xfeb00f00) == 0xfc200d00) {
73
- /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
74
- bool u = extract32(insn, 4, 1);
75
- if (!dc_isar_feature(aa32_dp, s)) {
76
- return 1;
77
- }
78
- fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
79
- } else if ((insn & 0xff300f10) == 0xfc200810) {
80
+ if ((insn & 0xff300f10) == 0xfc200810) {
81
/* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
82
int is_s = extract32(insn, 23, 1);
83
if (!dc_isar_feature(aa32_fhm, s)) {
84
--
74
--
85
2.20.1
75
2.20.1
86
76
87
77
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
hw/arm: versal: Add support for the RTC.
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Message-id: 20200815013145.539409-12-richard.henderson@linaro.org
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-10-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
7
---
12
include/hw/arm/xlnx-versal.h | 8 ++++++++
8
target/arm/translate-sve.c | 53 +++++++++++++-------------------------
13
hw/arm/xlnx-versal.c | 21 +++++++++++++++++++++
9
1 file changed, 18 insertions(+), 35 deletions(-)
14
2 files changed, 29 insertions(+)
15
10
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
11
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-versal.h
13
--- a/target/arm/translate-sve.c
19
+++ b/include/hw/arm/xlnx-versal.h
14
+++ b/target/arm/translate-sve.c
20
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static int pred_gvec_reg_size(DisasContext *s)
21
#include "hw/char/pl011.h"
16
return size_for_gvec(pred_full_reg_size(s));
22
#include "hw/dma/xlnx-zdma.h"
23
#include "hw/net/cadence_gem.h"
24
+#include "hw/rtc/xlnx-zynqmp-rtc.h"
25
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
27
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
28
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
29
struct {
30
SDHCIState sd[XLNX_VERSAL_NR_SDS];
31
} iou;
32
+
33
+ XlnxZynqMPRTC rtc;
34
} pmc;
35
36
struct {
37
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
38
#define VERSAL_GEM1_IRQ_0 58
39
#define VERSAL_GEM1_WAKE_IRQ_0 59
40
#define VERSAL_ADMA_IRQ_0 60
41
+#define VERSAL_RTC_APB_ERR_IRQ 121
42
#define VERSAL_SD0_IRQ_0 126
43
+#define VERSAL_RTC_ALARM_IRQ 142
44
+#define VERSAL_RTC_SECONDS_IRQ 143
45
46
/* Architecturally reserved IRQs suitable for virtualization. */
47
#define VERSAL_RSVD_IRQ_FIRST 111
48
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
49
#define MM_PMC_SD0_SIZE 0x10000
50
#define MM_PMC_CRP 0xf1260000U
51
#define MM_PMC_CRP_SIZE 0x10000
52
+#define MM_PMC_RTC 0xf12a0000
53
+#define MM_PMC_RTC_SIZE 0x10000
54
#endif
55
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/xlnx-versal.c
58
+++ b/hw/arm/xlnx-versal.c
59
@@ -XXX,XX +XXX,XX @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
60
}
61
}
17
}
62
18
63
+static void versal_create_rtc(Versal *s, qemu_irq *pic)
19
+/* Invoke an out-of-line helper on 3 Zregs. */
20
+static void gen_gvec_ool_zzz(DisasContext *s, gen_helper_gvec_3 *fn,
21
+ int rd, int rn, int rm, int data)
64
+{
22
+{
65
+ SysBusDevice *sbd;
23
+ unsigned vsz = vec_full_reg_size(s);
66
+ MemoryRegion *mr;
24
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
67
+
25
+ vec_full_reg_offset(s, rn),
68
+ sysbus_init_child_obj(OBJECT(s), "rtc", &s->pmc.rtc, sizeof(s->pmc.rtc),
26
+ vec_full_reg_offset(s, rm),
69
+ TYPE_XLNX_ZYNQMP_RTC);
27
+ vsz, vsz, data, fn);
70
+ sbd = SYS_BUS_DEVICE(&s->pmc.rtc);
71
+ qdev_init_nofail(DEVICE(sbd));
72
+
73
+ mr = sysbus_mmio_get_region(sbd, 0);
74
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr);
75
+
76
+ /*
77
+ * TODO: Connect the ALARM and SECONDS interrupts once our RTC model
78
+ * supports them.
79
+ */
80
+ sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
81
+}
28
+}
82
+
29
+
83
/* This takes the board allocated linear DDR memory and creates aliases
30
/* Invoke an out-of-line helper on 2 Zregs and a predicate. */
84
* for each split DDR range/aperture on the Versal address map.
31
static void gen_gvec_ool_zzp(DisasContext *s, gen_helper_gvec_3 *fn,
85
*/
32
int rd, int rn, int pg, int data)
86
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
33
@@ -XXX,XX +XXX,XX @@ static bool do_zzw_ool(DisasContext *s, arg_rrr_esz *a, gen_helper_gvec_3 *fn)
87
versal_create_gems(s, pic);
34
return false;
88
versal_create_admas(s, pic);
35
}
89
versal_create_sds(s, pic);
36
if (sve_access_check(s)) {
90
+ versal_create_rtc(s, pic);
37
- unsigned vsz = vec_full_reg_size(s);
91
versal_map_ddr(s);
38
- tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
92
versal_unimp(s);
39
- vec_full_reg_offset(s, a->rn),
93
40
- vec_full_reg_offset(s, a->rm),
41
- vsz, vsz, 0, fn);
42
+ gen_gvec_ool_zzz(s, fn, a->rd, a->rn, a->rm, 0);
43
}
44
return true;
45
}
46
@@ -XXX,XX +XXX,XX @@ static bool trans_RDVL(DisasContext *s, arg_RDVL *a)
47
static bool do_adr(DisasContext *s, arg_rrri *a, gen_helper_gvec_3 *fn)
48
{
49
if (sve_access_check(s)) {
50
- unsigned vsz = vec_full_reg_size(s);
51
- tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
52
- vec_full_reg_offset(s, a->rn),
53
- vec_full_reg_offset(s, a->rm),
54
- vsz, vsz, a->imm, fn);
55
+ gen_gvec_ool_zzz(s, fn, a->rd, a->rn, a->rm, a->imm);
56
}
57
return true;
58
}
59
@@ -XXX,XX +XXX,XX @@ static bool trans_FTSSEL(DisasContext *s, arg_rrr_esz *a)
60
return false;
61
}
62
if (sve_access_check(s)) {
63
- unsigned vsz = vec_full_reg_size(s);
64
- tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
65
- vec_full_reg_offset(s, a->rn),
66
- vec_full_reg_offset(s, a->rm),
67
- vsz, vsz, 0, fns[a->esz]);
68
+ gen_gvec_ool_zzz(s, fns[a->esz], a->rd, a->rn, a->rm, 0);
69
}
70
return true;
71
}
72
@@ -XXX,XX +XXX,XX @@ static bool trans_TBL(DisasContext *s, arg_rrr_esz *a)
73
};
74
75
if (sve_access_check(s)) {
76
- unsigned vsz = vec_full_reg_size(s);
77
- tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
78
- vec_full_reg_offset(s, a->rn),
79
- vec_full_reg_offset(s, a->rm),
80
- vsz, vsz, 0, fns[a->esz]);
81
+ gen_gvec_ool_zzz(s, fns[a->esz], a->rd, a->rn, a->rm, 0);
82
}
83
return true;
84
}
85
@@ -XXX,XX +XXX,XX @@ static bool do_zzz_data_ool(DisasContext *s, arg_rrr_esz *a, int data,
86
gen_helper_gvec_3 *fn)
87
{
88
if (sve_access_check(s)) {
89
- unsigned vsz = vec_full_reg_size(s);
90
- tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
91
- vec_full_reg_offset(s, a->rn),
92
- vec_full_reg_offset(s, a->rm),
93
- vsz, vsz, data, fn);
94
+ gen_gvec_ool_zzz(s, fn, a->rd, a->rn, a->rm, data);
95
}
96
return true;
97
}
98
@@ -XXX,XX +XXX,XX @@ static bool trans_DOT_zzz(DisasContext *s, arg_DOT_zzz *a)
99
};
100
101
if (sve_access_check(s)) {
102
- unsigned vsz = vec_full_reg_size(s);
103
- tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
104
- vec_full_reg_offset(s, a->rn),
105
- vec_full_reg_offset(s, a->rm),
106
- vsz, vsz, 0, fns[a->u][a->sz]);
107
+ gen_gvec_ool_zzz(s, fns[a->u][a->sz], a->rd, a->rn, a->rm, 0);
108
}
109
return true;
110
}
111
@@ -XXX,XX +XXX,XX @@ static bool trans_DOT_zzx(DisasContext *s, arg_DOT_zzx *a)
112
};
113
114
if (sve_access_check(s)) {
115
- unsigned vsz = vec_full_reg_size(s);
116
- tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
117
- vec_full_reg_offset(s, a->rn),
118
- vec_full_reg_offset(s, a->rm),
119
- vsz, vsz, a->index, fns[a->u][a->sz]);
120
+ gen_gvec_ool_zzz(s, fns[a->u][a->sz], a->rd, a->rn, a->rm, a->index);
121
}
122
return true;
123
}
94
--
124
--
95
2.20.1
125
2.20.1
96
126
97
127
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Embed the UARTs into the SoC type.
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20200815013145.539409-13-richard.henderson@linaro.org
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-5-edgar.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
7
---
13
include/hw/arm/xlnx-versal.h | 3 ++-
8
target/arm/translate-sve.c | 20 ++++++++++++--------
14
hw/arm/xlnx-versal.c | 12 ++++++------
9
1 file changed, 12 insertions(+), 8 deletions(-)
15
2 files changed, 8 insertions(+), 7 deletions(-)
16
10
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
11
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/xlnx-versal.h
13
--- a/target/arm/translate-sve.c
20
+++ b/include/hw/arm/xlnx-versal.h
14
+++ b/target/arm/translate-sve.c
21
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static int pred_gvec_reg_size(DisasContext *s)
22
#include "hw/sysbus.h"
16
return size_for_gvec(pred_full_reg_size(s));
23
#include "hw/arm/boot.h"
17
}
24
#include "hw/intc/arm_gicv3.h"
18
25
+#include "hw/char/pl011.h"
19
+/* Invoke an out-of-line helper on 2 Zregs. */
26
20
+static void gen_gvec_ool_zz(DisasContext *s, gen_helper_gvec_2 *fn,
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
21
+ int rd, int rn, int data)
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
22
+{
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
23
+ unsigned vsz = vec_full_reg_size(s);
30
MemoryRegion mr_ocm;
24
+ tcg_gen_gvec_2_ool(vec_full_reg_offset(s, rd),
31
25
+ vec_full_reg_offset(s, rn),
32
struct {
26
+ vsz, vsz, data, fn);
33
- SysBusDevice *uart[XLNX_VERSAL_NR_UARTS];
27
+}
34
+ PL011State uart[XLNX_VERSAL_NR_UARTS];
28
+
35
SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
29
/* Invoke an out-of-line helper on 3 Zregs. */
36
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
30
static void gen_gvec_ool_zzz(DisasContext *s, gen_helper_gvec_3 *fn,
37
} iou;
31
int rd, int rn, int rm, int data)
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
32
@@ -XXX,XX +XXX,XX @@ static bool trans_FEXPA(DisasContext *s, arg_rr_esz *a)
39
index XXXXXXX..XXXXXXX 100644
33
return false;
40
--- a/hw/arm/xlnx-versal.c
41
+++ b/hw/arm/xlnx-versal.c
42
@@ -XXX,XX +XXX,XX @@
43
#include "kvm_arm.h"
44
#include "hw/misc/unimp.h"
45
#include "hw/arm/xlnx-versal.h"
46
-#include "hw/char/pl011.h"
47
48
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
49
#define GEM_REVISION 0x40070106
50
@@ -XXX,XX +XXX,XX @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
51
DeviceState *dev;
52
MemoryRegion *mr;
53
54
- dev = qdev_create(NULL, TYPE_PL011);
55
- s->lpd.iou.uart[i] = SYS_BUS_DEVICE(dev);
56
+ sysbus_init_child_obj(OBJECT(s), name,
57
+ &s->lpd.iou.uart[i], sizeof(s->lpd.iou.uart[i]),
58
+ TYPE_PL011);
59
+ dev = DEVICE(&s->lpd.iou.uart[i]);
60
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
61
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
62
qdev_init_nofail(dev);
63
64
- mr = sysbus_mmio_get_region(s->lpd.iou.uart[i], 0);
65
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
66
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
67
68
- sysbus_connect_irq(s->lpd.iou.uart[i], 0, pic[irqs[i]]);
69
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
70
g_free(name);
71
}
34
}
35
if (sve_access_check(s)) {
36
- unsigned vsz = vec_full_reg_size(s);
37
- tcg_gen_gvec_2_ool(vec_full_reg_offset(s, a->rd),
38
- vec_full_reg_offset(s, a->rn),
39
- vsz, vsz, 0, fns[a->esz]);
40
+ gen_gvec_ool_zz(s, fns[a->esz], a->rd, a->rn, 0);
41
}
42
return true;
43
}
44
@@ -XXX,XX +XXX,XX @@ static bool trans_REV_v(DisasContext *s, arg_rr_esz *a)
45
};
46
47
if (sve_access_check(s)) {
48
- unsigned vsz = vec_full_reg_size(s);
49
- tcg_gen_gvec_2_ool(vec_full_reg_offset(s, a->rd),
50
- vec_full_reg_offset(s, a->rn),
51
- vsz, vsz, 0, fns[a->esz]);
52
+ gen_gvec_ool_zz(s, fns[a->esz], a->rd, a->rn, 0);
53
}
54
return true;
72
}
55
}
73
--
56
--
74
2.20.1
57
2.20.1
75
58
76
59
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Move misplaced comment.
3
Rather than require the user to fill in the immediate (shl or shr),
4
create full formats that include the immediate.
4
5
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200815013145.539409-14-richard.henderson@linaro.org
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-3-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
hw/arm/xlnx-versal.c | 2 +-
11
target/arm/sve.decode | 35 ++++++++++++++++-------------------
13
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 16 insertions(+), 19 deletions(-)
14
13
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
14
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xlnx-versal.c
16
--- a/target/arm/sve.decode
18
+++ b/hw/arm/xlnx-versal.c
17
+++ b/target/arm/sve.decode
19
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
18
@@ -XXX,XX +XXX,XX @@
20
19
@rd_rn_i6 ........ ... rn:5 ..... imm:s6 rd:5 &rri
21
obj = object_new(XLNX_VERSAL_ACPU_TYPE);
20
22
if (!obj) {
21
# Two register operand, one immediate operand, with predicate,
23
- /* Secondary CPUs start in PSCI powered-down state */
22
-# element size encoded as TSZHL. User must fill in imm.
24
error_report("Unable to create apu.cpu[%d] of type %s",
23
-@rdn_pg_tszimm ........ .. ... ... ... pg:3 ..... rd:5 \
25
i, XLNX_VERSAL_ACPU_TYPE);
24
- &rpri_esz rn=%reg_movprfx esz=%tszimm_esz
26
exit(EXIT_FAILURE);
25
+# element size encoded as TSZHL.
27
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
26
+@rdn_pg_tszimm_shl ........ .. ... ... ... pg:3 ..... rd:5 \
28
object_property_set_int(obj, s->cfg.psci_conduit,
27
+ &rpri_esz rn=%reg_movprfx esz=%tszimm_esz imm=%tszimm_shl
29
"psci-conduit", &error_abort);
28
+@rdn_pg_tszimm_shr ........ .. ... ... ... pg:3 ..... rd:5 \
30
if (i) {
29
+ &rpri_esz rn=%reg_movprfx esz=%tszimm_esz imm=%tszimm_shr
31
+ /* Secondary CPUs start in PSCI powered-down state */
30
32
object_property_set_bool(obj, true,
31
# Similarly without predicate.
33
"start-powered-off", &error_abort);
32
-@rd_rn_tszimm ........ .. ... ... ...... rn:5 rd:5 \
34
}
33
- &rri_esz esz=%tszimm16_esz
34
+@rd_rn_tszimm_shl ........ .. ... ... ...... rn:5 rd:5 \
35
+ &rri_esz esz=%tszimm16_esz imm=%tszimm16_shl
36
+@rd_rn_tszimm_shr ........ .. ... ... ...... rn:5 rd:5 \
37
+ &rri_esz esz=%tszimm16_esz imm=%tszimm16_shr
38
39
# Two register operand, one immediate operand, with 4-bit predicate.
40
# User must fill in imm.
41
@@ -XXX,XX +XXX,XX @@ UMINV 00000100 .. 001 011 001 ... ..... ..... @rd_pg_rn
42
### SVE Shift by Immediate - Predicated Group
43
44
# SVE bitwise shift by immediate (predicated)
45
-ASR_zpzi 00000100 .. 000 000 100 ... .. ... ..... \
46
- @rdn_pg_tszimm imm=%tszimm_shr
47
-LSR_zpzi 00000100 .. 000 001 100 ... .. ... ..... \
48
- @rdn_pg_tszimm imm=%tszimm_shr
49
-LSL_zpzi 00000100 .. 000 011 100 ... .. ... ..... \
50
- @rdn_pg_tszimm imm=%tszimm_shl
51
-ASRD 00000100 .. 000 100 100 ... .. ... ..... \
52
- @rdn_pg_tszimm imm=%tszimm_shr
53
+ASR_zpzi 00000100 .. 000 000 100 ... .. ... ..... @rdn_pg_tszimm_shr
54
+LSR_zpzi 00000100 .. 000 001 100 ... .. ... ..... @rdn_pg_tszimm_shr
55
+LSL_zpzi 00000100 .. 000 011 100 ... .. ... ..... @rdn_pg_tszimm_shl
56
+ASRD 00000100 .. 000 100 100 ... .. ... ..... @rdn_pg_tszimm_shr
57
58
# SVE bitwise shift by vector (predicated)
59
ASR_zpzz 00000100 .. 010 000 100 ... ..... ..... @rdn_pg_rm
60
@@ -XXX,XX +XXX,XX @@ RDVL 00000100 101 11111 01010 imm:s6 rd:5
61
### SVE Bitwise Shift - Unpredicated Group
62
63
# SVE bitwise shift by immediate (unpredicated)
64
-ASR_zzi 00000100 .. 1 ..... 1001 00 ..... ..... \
65
- @rd_rn_tszimm imm=%tszimm16_shr
66
-LSR_zzi 00000100 .. 1 ..... 1001 01 ..... ..... \
67
- @rd_rn_tszimm imm=%tszimm16_shr
68
-LSL_zzi 00000100 .. 1 ..... 1001 11 ..... ..... \
69
- @rd_rn_tszimm imm=%tszimm16_shl
70
+ASR_zzi 00000100 .. 1 ..... 1001 00 ..... ..... @rd_rn_tszimm_shr
71
+LSR_zzi 00000100 .. 1 ..... 1001 01 ..... ..... @rd_rn_tszimm_shr
72
+LSL_zzi 00000100 .. 1 ..... 1001 11 ..... ..... @rd_rn_tszimm_shl
73
74
# SVE bitwise shift by wide elements (unpredicated)
75
# Note esz != 3
35
--
76
--
36
2.20.1
77
2.20.1
37
78
38
79
diff view generated by jsdifflib
1
Convert the VFM[AS]L (scalar) insns in the 2reg-scalar-ext group
1
From: Richard Henderson <richard.henderson@linaro.org>
2
to decodetree. These are the last ones in the group so we can remove
3
all the legacy decode for the group.
4
2
5
Note that in disas_thumb2_insn() the parts of this encoding space
3
Unify add/sub helpers and add a parameter for rounding.
6
where the decodetree decoder returns false will correctly be directed
4
This will allow saturating non-rounding to reuse this code.
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
8
into disas_coproc_insn() by mistake.
9
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
[PMM: fixed accidental use of '=' rather than '+=' in do_sqrdmlah_s]
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20200815013145.539409-15-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
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-11-peter.maydell@linaro.org
13
---
11
---
14
target/arm/neon-shared.decode | 7 +++
12
target/arm/vec_helper.c | 80 +++++++++++++++--------------------------
15
target/arm/translate-neon.inc.c | 32 ++++++++++
13
1 file changed, 29 insertions(+), 51 deletions(-)
16
target/arm/translate.c | 107 +-------------------------------
17
3 files changed, 40 insertions(+), 106 deletions(-)
18
14
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
15
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/neon-shared.decode
17
--- a/target/arm/vec_helper.c
22
+++ b/target/arm/neon-shared.decode
18
+++ b/target/arm/vec_helper.c
23
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
19
@@ -XXX,XX +XXX,XX @@
24
20
#endif
25
VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
21
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
22
/* Signed saturating rounding doubling multiply-accumulate high half, 16-bit */
23
-static int16_t inl_qrdmlah_s16(int16_t src1, int16_t src2,
24
- int16_t src3, uint32_t *sat)
25
+static int16_t do_sqrdmlah_h(int16_t src1, int16_t src2, int16_t src3,
26
+ bool neg, bool round, uint32_t *sat)
27
{
28
- /* Simplify:
29
+ /*
30
+ * Simplify:
31
* = ((a3 << 16) + ((e1 * e2) << 1) + (1 << 15)) >> 16
32
* = ((a3 << 15) + (e1 * e2) + (1 << 14)) >> 15
33
*/
34
int32_t ret = (int32_t)src1 * src2;
35
- ret = ((int32_t)src3 << 15) + ret + (1 << 14);
36
+ if (neg) {
37
+ ret = -ret;
38
+ }
39
+ ret += ((int32_t)src3 << 15) + (round << 14);
40
ret >>= 15;
27
+
41
+
28
+%vfml_scalar_q0_rm 0:3 5:1
42
if (ret != (int16_t)ret) {
29
+%vfml_scalar_q1_index 5:1 3:1
43
*sat = 1;
30
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 0 . 1 index:1 ... \
44
- ret = (ret < 0 ? -0x8000 : 0x7fff);
31
+ rm=%vfml_scalar_q0_rm vn=%vn_sp vd=%vd_dp q=0
45
+ ret = (ret < 0 ? INT16_MIN : INT16_MAX);
32
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 1 . 1 . rm:3 \
46
}
33
+ index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp q=1
47
return ret;
34
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-neon.inc.c
37
+++ b/target/arm/translate-neon.inc.c
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
39
tcg_temp_free_ptr(fpst);
40
return true;
41
}
48
}
42
+
49
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(neon_qrdmlah_s16)(CPUARMState *env, uint32_t src1,
43
+static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
50
uint32_t src2, uint32_t src3)
44
+{
51
{
45
+ int opr_sz;
52
uint32_t *sat = &env->vfp.qc[0];
46
+
53
- uint16_t e1 = inl_qrdmlah_s16(src1, src2, src3, sat);
47
+ if (!dc_isar_feature(aa32_fhm, s)) {
54
- uint16_t e2 = inl_qrdmlah_s16(src1 >> 16, src2 >> 16, src3 >> 16, sat);
48
+ return false;
55
+ uint16_t e1 = do_sqrdmlah_h(src1, src2, src3, false, true, sat);
49
+ }
56
+ uint16_t e2 = do_sqrdmlah_h(src1 >> 16, src2 >> 16, src3 >> 16,
50
+
57
+ false, true, sat);
51
+ /* UNDEF accesses to D16-D31 if they don't exist. */
58
return deposit32(e1, 16, 16, e2);
52
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
53
+ ((a->vd & 0x10) || (a->q && (a->vn & 0x10)))) {
54
+ return false;
55
+ }
56
+
57
+ if (a->vd & a->q) {
58
+ return false;
59
+ }
60
+
61
+ if (!vfp_access_check(s)) {
62
+ return true;
63
+ }
64
+
65
+ opr_sz = (1 + a->q) * 8;
66
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
67
+ vfp_reg_offset(a->q, a->vn),
68
+ vfp_reg_offset(a->q, a->rm),
69
+ cpu_env, opr_sz, opr_sz,
70
+ (a->index << 2) | a->s, /* is_2 == 0 */
71
+ gen_helper_gvec_fmlal_idx_a32);
72
+ return true;
73
+}
74
diff --git a/target/arm/translate.c b/target/arm/translate.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/translate.c
77
+++ b/target/arm/translate.c
78
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
79
}
59
}
80
60
81
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
61
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_qrdmlah_s16)(void *vd, void *vn, void *vm,
82
-#define VFP_SREG(insn, bigbit, smallbit) \
62
uintptr_t i;
83
- ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
63
84
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
64
for (i = 0; i < opr_sz / 2; ++i) {
85
if (dc_isar_feature(aa32_simd_r32, s)) { \
65
- d[i] = inl_qrdmlah_s16(n[i], m[i], d[i], vq);
86
reg = (((insn) >> (bigbit)) & 0x0f) \
66
+ d[i] = do_sqrdmlah_h(n[i], m[i], d[i], false, true, vq);
87
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
67
}
88
reg = ((insn) >> (bigbit)) & 0x0f; \
68
clear_tail(d, opr_sz, simd_maxsz(desc));
89
}} while (0)
90
91
-#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
92
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
93
-#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
94
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
95
-#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
96
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
97
98
static void gen_neon_dup_low16(TCGv_i32 var)
99
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
100
return 0;
101
}
69
}
102
70
103
-/* Advanced SIMD two registers and a scalar extension.
71
-/* Signed saturating rounding doubling multiply-subtract high half, 16-bit */
104
- * 31 24 23 22 20 16 12 11 10 9 8 3 0
72
-static int16_t inl_qrdmlsh_s16(int16_t src1, int16_t src2,
105
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
73
- int16_t src3, uint32_t *sat)
106
- * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
107
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
108
- *
109
- */
110
-
111
-static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
112
-{
74
-{
113
- gen_helper_gvec_3 *fn_gvec = NULL;
75
- /* Similarly, using subtraction:
114
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
76
- * = ((a3 << 16) - ((e1 * e2) << 1) + (1 << 15)) >> 16
115
- int rd, rn, rm, opr_sz, data;
77
- * = ((a3 << 15) - (e1 * e2) + (1 << 14)) >> 15
116
- int off_rn, off_rm;
78
- */
117
- bool is_long = false, q = extract32(insn, 6, 1);
79
- int32_t ret = (int32_t)src1 * src2;
118
- bool ptr_is_env = false;
80
- ret = ((int32_t)src3 << 15) - ret + (1 << 14);
119
-
81
- ret >>= 15;
120
- if ((insn & 0xffa00f10) == 0xfe000810) {
82
- if (ret != (int16_t)ret) {
121
- /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
83
- *sat = 1;
122
- int is_s = extract32(insn, 20, 1);
84
- ret = (ret < 0 ? -0x8000 : 0x7fff);
123
- int vm20 = extract32(insn, 0, 3);
124
- int vm3 = extract32(insn, 3, 1);
125
- int m = extract32(insn, 5, 1);
126
- int index;
127
-
128
- if (!dc_isar_feature(aa32_fhm, s)) {
129
- return 1;
130
- }
131
- if (q) {
132
- rm = vm20;
133
- index = m * 2 + vm3;
134
- } else {
135
- rm = vm20 * 2 + m;
136
- index = vm3;
137
- }
138
- is_long = true;
139
- data = (index << 2) | is_s; /* is_2 == 0 */
140
- fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
141
- ptr_is_env = true;
142
- } else {
143
- return 1;
144
- }
85
- }
145
-
86
- return ret;
146
- VFP_DREG_D(rd, insn);
147
- if (rd & q) {
148
- return 1;
149
- }
150
- if (q || !is_long) {
151
- VFP_DREG_N(rn, insn);
152
- if (rn & q & !is_long) {
153
- return 1;
154
- }
155
- off_rn = vfp_reg_offset(1, rn);
156
- off_rm = vfp_reg_offset(1, rm);
157
- } else {
158
- rn = VFP_SREG_N(insn);
159
- off_rn = vfp_reg_offset(0, rn);
160
- off_rm = vfp_reg_offset(0, rm);
161
- }
162
- if (s->fp_excp_el) {
163
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
164
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
165
- return 0;
166
- }
167
- if (!s->vfp_enabled) {
168
- return 1;
169
- }
170
-
171
- opr_sz = (1 + q) * 8;
172
- if (fn_gvec_ptr) {
173
- TCGv_ptr ptr;
174
- if (ptr_is_env) {
175
- ptr = cpu_env;
176
- } else {
177
- ptr = get_fpstatus_ptr(1);
178
- }
179
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
180
- opr_sz, opr_sz, data, fn_gvec_ptr);
181
- if (!ptr_is_env) {
182
- tcg_temp_free_ptr(ptr);
183
- }
184
- } else {
185
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
186
- opr_sz, opr_sz, data, fn_gvec);
187
- }
188
- return 0;
189
-}
87
-}
190
-
88
-
191
static int disas_coproc_insn(DisasContext *s, uint32_t insn)
89
uint32_t HELPER(neon_qrdmlsh_s16)(CPUARMState *env, uint32_t src1,
90
uint32_t src2, uint32_t src3)
192
{
91
{
193
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
92
uint32_t *sat = &env->vfp.qc[0];
194
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
93
- uint16_t e1 = inl_qrdmlsh_s16(src1, src2, src3, sat);
195
}
94
- uint16_t e2 = inl_qrdmlsh_s16(src1 >> 16, src2 >> 16, src3 >> 16, sat);
196
}
95
+ uint16_t e1 = do_sqrdmlah_h(src1, src2, src3, true, true, sat);
197
}
96
+ uint16_t e2 = do_sqrdmlah_h(src1 >> 16, src2 >> 16, src3 >> 16,
198
- } else if ((insn & 0x0f000a00) == 0x0e000800
97
+ true, true, sat);
199
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
98
return deposit32(e1, 16, 16, e2);
200
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
99
}
201
- goto illegal_op;
100
202
- }
101
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_qrdmlsh_s16)(void *vd, void *vn, void *vm,
203
- return;
102
uintptr_t i;
204
}
103
205
goto illegal_op;
104
for (i = 0; i < opr_sz / 2; ++i) {
105
- d[i] = inl_qrdmlsh_s16(n[i], m[i], d[i], vq);
106
+ d[i] = do_sqrdmlah_h(n[i], m[i], d[i], true, true, vq);
206
}
107
}
207
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
108
clear_tail(d, opr_sz, simd_maxsz(desc));
208
}
109
}
209
break;
110
210
}
111
/* Signed saturating rounding doubling multiply-accumulate high half, 32-bit */
211
- if ((insn & 0xff000a00) == 0xfe000800
112
-static int32_t inl_qrdmlah_s32(int32_t src1, int32_t src2,
212
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
113
- int32_t src3, uint32_t *sat)
213
- /* The Thumb2 and ARM encodings are identical. */
114
+static int32_t do_sqrdmlah_s(int32_t src1, int32_t src2, int32_t src3,
214
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
115
+ bool neg, bool round, uint32_t *sat)
215
- goto illegal_op;
116
{
216
- }
117
/* Simplify similarly to int_qrdmlah_s16 above. */
217
- } else if (((insn >> 24) & 3) == 3) {
118
int64_t ret = (int64_t)src1 * src2;
218
+ if (((insn >> 24) & 3) == 3) {
119
- ret = ((int64_t)src3 << 31) + ret + (1 << 30);
219
/* Translate into the equivalent ARM encoding. */
120
+ if (neg) {
220
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
121
+ ret = -ret;
221
if (disas_neon_data_insn(s, insn)) {
122
+ }
123
+ ret += ((int64_t)src3 << 31) + (round << 30);
124
ret >>= 31;
125
+
126
if (ret != (int32_t)ret) {
127
*sat = 1;
128
ret = (ret < 0 ? INT32_MIN : INT32_MAX);
129
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(neon_qrdmlah_s32)(CPUARMState *env, int32_t src1,
130
int32_t src2, int32_t src3)
131
{
132
uint32_t *sat = &env->vfp.qc[0];
133
- return inl_qrdmlah_s32(src1, src2, src3, sat);
134
+ return do_sqrdmlah_s(src1, src2, src3, false, true, sat);
135
}
136
137
void HELPER(gvec_qrdmlah_s32)(void *vd, void *vn, void *vm,
138
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_qrdmlah_s32)(void *vd, void *vn, void *vm,
139
uintptr_t i;
140
141
for (i = 0; i < opr_sz / 4; ++i) {
142
- d[i] = inl_qrdmlah_s32(n[i], m[i], d[i], vq);
143
+ d[i] = do_sqrdmlah_s(n[i], m[i], d[i], false, true, vq);
144
}
145
clear_tail(d, opr_sz, simd_maxsz(desc));
146
}
147
148
-/* Signed saturating rounding doubling multiply-subtract high half, 32-bit */
149
-static int32_t inl_qrdmlsh_s32(int32_t src1, int32_t src2,
150
- int32_t src3, uint32_t *sat)
151
-{
152
- /* Simplify similarly to int_qrdmlsh_s16 above. */
153
- int64_t ret = (int64_t)src1 * src2;
154
- ret = ((int64_t)src3 << 31) - ret + (1 << 30);
155
- ret >>= 31;
156
- if (ret != (int32_t)ret) {
157
- *sat = 1;
158
- ret = (ret < 0 ? INT32_MIN : INT32_MAX);
159
- }
160
- return ret;
161
-}
162
-
163
uint32_t HELPER(neon_qrdmlsh_s32)(CPUARMState *env, int32_t src1,
164
int32_t src2, int32_t src3)
165
{
166
uint32_t *sat = &env->vfp.qc[0];
167
- return inl_qrdmlsh_s32(src1, src2, src3, sat);
168
+ return do_sqrdmlah_s(src1, src2, src3, true, true, sat);
169
}
170
171
void HELPER(gvec_qrdmlsh_s32)(void *vd, void *vn, void *vm,
172
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_qrdmlsh_s32)(void *vd, void *vn, void *vm,
173
uintptr_t i;
174
175
for (i = 0; i < opr_sz / 4; ++i) {
176
- d[i] = inl_qrdmlsh_s32(n[i], m[i], d[i], vq);
177
+ d[i] = do_sqrdmlah_s(n[i], m[i], d[i], true, true, vq);
178
}
179
clear_tail(d, opr_sz, simd_maxsz(desc));
180
}
222
--
181
--
223
2.20.1
182
2.20.1
224
183
225
184
diff view generated by jsdifflib
1
Somewhere along theline we accidentally added a duplicate
1
From: Richard Henderson <richard.henderson@linaro.org>
2
"using D16-D31 when they don't exist" check to do_vfm_dp()
3
(probably an artifact of a patchseries rebase). Remove it.
4
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20200815013145.539409-19-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200430181003.21682-2-peter.maydell@linaro.org
9
---
7
---
10
target/arm/translate-vfp.inc.c | 6 ------
8
target/arm/helper.h | 4 ++++
11
1 file changed, 6 deletions(-)
9
target/arm/translate-a64.c | 16 ++++++++++++++++
10
target/arm/vec_helper.c | 29 +++++++++++++++++++++++++----
11
3 files changed, 45 insertions(+), 4 deletions(-)
12
12
13
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
13
diff --git a/target/arm/helper.h b/target/arm/helper.h
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-vfp.inc.c
15
--- a/target/arm/helper.h
16
+++ b/target/arm/translate-vfp.inc.c
16
+++ b/target/arm/helper.h
17
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_uaba_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
18
return false;
18
DEF_HELPER_FLAGS_4(gvec_uaba_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
19
DEF_HELPER_FLAGS_4(gvec_uaba_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
20
21
+DEF_HELPER_FLAGS_4(gvec_mul_idx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
22
+DEF_HELPER_FLAGS_4(gvec_mul_idx_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
+DEF_HELPER_FLAGS_4(gvec_mul_idx_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
+
25
#ifdef TARGET_AARCH64
26
#include "helper-a64.h"
27
#include "helper-sve.h"
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-a64.c
31
+++ b/target/arm/translate-a64.c
32
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
33
data, gen_helper_gvec_fmlal_idx_a64);
34
}
35
return;
36
+
37
+ case 0x08: /* MUL */
38
+ if (!is_long && !is_scalar) {
39
+ static gen_helper_gvec_3 * const fns[3] = {
40
+ gen_helper_gvec_mul_idx_h,
41
+ gen_helper_gvec_mul_idx_s,
42
+ gen_helper_gvec_mul_idx_d,
43
+ };
44
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
45
+ vec_full_reg_offset(s, rn),
46
+ vec_full_reg_offset(s, rm),
47
+ is_q ? 16 : 8, vec_full_reg_size(s),
48
+ index, fns[size - 1]);
49
+ return;
50
+ }
51
+ break;
19
}
52
}
20
53
21
- /* UNDEF accesses to D16-D31 if they don't exist. */
54
if (size == 3) {
22
- if (!dc_isar_feature(aa32_simd_r32, s) &&
55
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
23
- ((a->vd | a->vn | a->vm) & 0x10)) {
56
index XXXXXXX..XXXXXXX 100644
24
- return false;
57
--- a/target/arm/vec_helper.c
25
- }
58
+++ b/target/arm/vec_helper.c
26
-
59
@@ -XXX,XX +XXX,XX @@ DO_3OP(gvec_rsqrts_d, helper_rsqrtsf_f64, float64)
27
if (!vfp_access_check(s)) {
60
*/
28
return true;
61
29
}
62
#define DO_MUL_IDX(NAME, TYPE, H) \
63
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
64
+{ \
65
+ intptr_t i, j, oprsz = simd_oprsz(desc), segment = 16 / sizeof(TYPE); \
66
+ intptr_t idx = simd_data(desc); \
67
+ TYPE *d = vd, *n = vn, *m = vm; \
68
+ for (i = 0; i < oprsz / sizeof(TYPE); i += segment) { \
69
+ TYPE mm = m[H(i + idx)]; \
70
+ for (j = 0; j < segment; j++) { \
71
+ d[i + j] = n[i + j] * mm; \
72
+ } \
73
+ } \
74
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
75
+}
76
+
77
+DO_MUL_IDX(gvec_mul_idx_h, uint16_t, H2)
78
+DO_MUL_IDX(gvec_mul_idx_s, uint32_t, H4)
79
+DO_MUL_IDX(gvec_mul_idx_d, uint64_t, )
80
+
81
+#undef DO_MUL_IDX
82
+
83
+#define DO_FMUL_IDX(NAME, TYPE, H) \
84
void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
85
{ \
86
intptr_t i, j, oprsz = simd_oprsz(desc), segment = 16 / sizeof(TYPE); \
87
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
88
clear_tail(d, oprsz, simd_maxsz(desc)); \
89
}
90
91
-DO_MUL_IDX(gvec_fmul_idx_h, float16, H2)
92
-DO_MUL_IDX(gvec_fmul_idx_s, float32, H4)
93
-DO_MUL_IDX(gvec_fmul_idx_d, float64, )
94
+DO_FMUL_IDX(gvec_fmul_idx_h, float16, H2)
95
+DO_FMUL_IDX(gvec_fmul_idx_s, float32, H4)
96
+DO_FMUL_IDX(gvec_fmul_idx_d, float64, )
97
98
-#undef DO_MUL_IDX
99
+#undef DO_FMUL_IDX
100
101
#define DO_FMLA_IDX(NAME, TYPE, H) \
102
void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, \
30
--
103
--
31
2.20.1
104
2.20.1
32
105
33
106
diff view generated by jsdifflib
1
Add the infrastructure for building and invoking a decodetree decoder
1
From: Richard Henderson <richard.henderson@linaro.org>
2
for the AArch32 Neon encodings. At the moment the new decoder covers
3
nothing, so we always fall back to the existing hand-written decode.
4
2
5
We follow the same pattern we did for the VFP decodetree conversion
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
(commit 78e138bc1f672c145ef6ace74617d and following): code that deals
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
with Neon will be moving gradually out to translate-neon.vfp.inc,
5
Message-id: 20200815013145.539409-20-richard.henderson@linaro.org
8
which we #include into translate.c.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper.h | 14 ++++++++++++++
9
target/arm/translate-a64.c | 34 ++++++++++++++++++++++++++++++++++
10
target/arm/vec_helper.c | 25 +++++++++++++++++++++++++
11
3 files changed, 73 insertions(+)
9
12
10
In order to share the decode files between A32 and T32, we
13
diff --git a/target/arm/helper.h b/target/arm/helper.h
11
split Neon into 3 parts:
14
index XXXXXXX..XXXXXXX 100644
12
* data-processing
15
--- a/target/arm/helper.h
13
* load-store
16
+++ b/target/arm/helper.h
14
* 'shared' encodings
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_mul_idx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
15
18
DEF_HELPER_FLAGS_4(gvec_mul_idx_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
16
The first two groups of instructions have similar but not identical
19
DEF_HELPER_FLAGS_4(gvec_mul_idx_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
17
A32 and T32 encodings, so we need to manually transform the T32
20
18
encoding into the A32 one before calling the decoder; the third group
21
+DEF_HELPER_FLAGS_5(gvec_mla_idx_h, TCG_CALL_NO_RWG,
19
covers the Neon instructions which are identical in A32 and T32.
22
+ void, ptr, ptr, ptr, ptr, i32)
20
23
+DEF_HELPER_FLAGS_5(gvec_mla_idx_s, TCG_CALL_NO_RWG,
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
+ void, ptr, ptr, ptr, ptr, i32)
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
+DEF_HELPER_FLAGS_5(gvec_mla_idx_d, TCG_CALL_NO_RWG,
23
Message-id: 20200430181003.21682-4-peter.maydell@linaro.org
26
+ void, ptr, ptr, ptr, ptr, i32)
24
---
25
target/arm/neon-dp.decode | 29 ++++++++++++++++++++++++++
26
target/arm/neon-ls.decode | 29 ++++++++++++++++++++++++++
27
target/arm/neon-shared.decode | 27 +++++++++++++++++++++++++
28
target/arm/translate-neon.inc.c | 32 +++++++++++++++++++++++++++++
29
target/arm/translate.c | 36 +++++++++++++++++++++++++++++++--
30
target/arm/Makefile.objs | 18 +++++++++++++++++
31
6 files changed, 169 insertions(+), 2 deletions(-)
32
create mode 100644 target/arm/neon-dp.decode
33
create mode 100644 target/arm/neon-ls.decode
34
create mode 100644 target/arm/neon-shared.decode
35
create mode 100644 target/arm/translate-neon.inc.c
36
37
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/target/arm/neon-dp.decode
42
@@ -XXX,XX +XXX,XX @@
43
+# AArch32 Neon data-processing instruction descriptions
44
+#
45
+# Copyright (c) 2020 Linaro, Ltd
46
+#
47
+# This library is free software; you can redistribute it and/or
48
+# modify it under the terms of the GNU Lesser General Public
49
+# License as published by the Free Software Foundation; either
50
+# version 2 of the License, or (at your option) any later version.
51
+#
52
+# This library is distributed in the hope that it will be useful,
53
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
54
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
55
+# Lesser General Public License for more details.
56
+#
57
+# You should have received a copy of the GNU Lesser General Public
58
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
59
+
27
+
60
+#
28
+DEF_HELPER_FLAGS_5(gvec_mls_idx_h, TCG_CALL_NO_RWG,
61
+# This file is processed by scripts/decodetree.py
29
+ void, ptr, ptr, ptr, ptr, i32)
62
+#
30
+DEF_HELPER_FLAGS_5(gvec_mls_idx_s, TCG_CALL_NO_RWG,
31
+ void, ptr, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_5(gvec_mls_idx_d, TCG_CALL_NO_RWG,
33
+ void, ptr, ptr, ptr, ptr, i32)
63
+
34
+
64
+# Encodings for Neon data processing instructions where the T32 encoding
35
#ifdef TARGET_AARCH64
65
+# is a simple transformation of the A32 encoding.
36
#include "helper-a64.h"
66
+# More specifically, this file covers instructions where the A32 encoding is
37
#include "helper-sve.h"
67
+# 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
38
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
68
+# and the T32 encoding is
69
+# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
70
+# This file works on the A32 encoding only; calling code for T32 has to
71
+# transform the insn into the A32 version first.
72
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
73
new file mode 100644
74
index XXXXXXX..XXXXXXX
75
--- /dev/null
76
+++ b/target/arm/neon-ls.decode
77
@@ -XXX,XX +XXX,XX @@
78
+# AArch32 Neon load/store instruction descriptions
79
+#
80
+# Copyright (c) 2020 Linaro, Ltd
81
+#
82
+# This library is free software; you can redistribute it and/or
83
+# modify it under the terms of the GNU Lesser General Public
84
+# License as published by the Free Software Foundation; either
85
+# version 2 of the License, or (at your option) any later version.
86
+#
87
+# This library is distributed in the hope that it will be useful,
88
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
89
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
90
+# Lesser General Public License for more details.
91
+#
92
+# You should have received a copy of the GNU Lesser General Public
93
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
94
+
95
+#
96
+# This file is processed by scripts/decodetree.py
97
+#
98
+
99
+# Encodings for Neon load/store instructions where the T32 encoding
100
+# is a simple transformation of the A32 encoding.
101
+# More specifically, this file covers instructions where the A32 encoding is
102
+# 0b1111_0100_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
103
+# and the T32 encoding is
104
+# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
105
+# This file works on the A32 encoding only; calling code for T32 has to
106
+# transform the insn into the A32 version first.
107
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
108
new file mode 100644
109
index XXXXXXX..XXXXXXX
110
--- /dev/null
111
+++ b/target/arm/neon-shared.decode
112
@@ -XXX,XX +XXX,XX @@
113
+# AArch32 Neon instruction descriptions
114
+#
115
+# Copyright (c) 2020 Linaro, Ltd
116
+#
117
+# This library is free software; you can redistribute it and/or
118
+# modify it under the terms of the GNU Lesser General Public
119
+# License as published by the Free Software Foundation; either
120
+# version 2 of the License, or (at your option) any later version.
121
+#
122
+# This library is distributed in the hope that it will be useful,
123
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
124
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
125
+# Lesser General Public License for more details.
126
+#
127
+# You should have received a copy of the GNU Lesser General Public
128
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
129
+
130
+#
131
+# This file is processed by scripts/decodetree.py
132
+#
133
+
134
+# Encodings for Neon instructions whose encoding is the same for
135
+# both A32 and T32.
136
+
137
+# More specifically, this covers:
138
+# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
139
+# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
140
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
141
new file mode 100644
142
index XXXXXXX..XXXXXXX
143
--- /dev/null
144
+++ b/target/arm/translate-neon.inc.c
145
@@ -XXX,XX +XXX,XX @@
146
+/*
147
+ * ARM translation: AArch32 Neon instructions
148
+ *
149
+ * Copyright (c) 2003 Fabrice Bellard
150
+ * Copyright (c) 2005-2007 CodeSourcery
151
+ * Copyright (c) 2007 OpenedHand, Ltd.
152
+ * Copyright (c) 2020 Linaro, Ltd.
153
+ *
154
+ * This library is free software; you can redistribute it and/or
155
+ * modify it under the terms of the GNU Lesser General Public
156
+ * License as published by the Free Software Foundation; either
157
+ * version 2 of the License, or (at your option) any later version.
158
+ *
159
+ * This library is distributed in the hope that it will be useful,
160
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
161
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
162
+ * Lesser General Public License for more details.
163
+ *
164
+ * You should have received a copy of the GNU Lesser General Public
165
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
166
+ */
167
+
168
+/*
169
+ * This file is intended to be included from translate.c; it uses
170
+ * some macros and definitions provided by that file.
171
+ * It might be possible to convert it to a standalone .c file eventually.
172
+ */
173
+
174
+/* Include the generated Neon decoder */
175
+#include "decode-neon-dp.inc.c"
176
+#include "decode-neon-ls.inc.c"
177
+#include "decode-neon-shared.inc.c"
178
diff --git a/target/arm/translate.c b/target/arm/translate.c
179
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
180
--- a/target/arm/translate.c
40
--- a/target/arm/translate-a64.c
181
+++ b/target/arm/translate.c
41
+++ b/target/arm/translate-a64.c
182
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
42
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
183
184
#define ARM_CP_RW_BIT (1 << 20)
185
186
-/* Include the VFP decoder */
187
+/* Include the VFP and Neon decoders */
188
#include "translate-vfp.inc.c"
189
+#include "translate-neon.inc.c"
190
191
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
192
{
193
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
194
/* Unconditional instructions. */
195
/* TODO: Perhaps merge these into one decodetree output file. */
196
if (disas_a32_uncond(s, insn) ||
197
- disas_vfp_uncond(s, insn)) {
198
+ disas_vfp_uncond(s, insn) ||
199
+ disas_neon_dp(s, insn) ||
200
+ disas_neon_ls(s, insn) ||
201
+ disas_neon_shared(s, insn)) {
202
return;
43
return;
203
}
44
}
204
/* fall back to legacy decoder */
45
break;
205
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
206
ARCH(6T2);
207
}
208
209
+ if ((insn & 0xef000000) == 0xef000000) {
210
+ /*
211
+ * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
212
+ * transform into
213
+ * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
214
+ */
215
+ uint32_t a32_insn = (insn & 0xe2ffffff) |
216
+ ((insn & (1 << 28)) >> 4) | (1 << 28);
217
+
46
+
218
+ if (disas_neon_dp(s, a32_insn)) {
47
+ case 0x10: /* MLA */
48
+ if (!is_long && !is_scalar) {
49
+ static gen_helper_gvec_4 * const fns[3] = {
50
+ gen_helper_gvec_mla_idx_h,
51
+ gen_helper_gvec_mla_idx_s,
52
+ gen_helper_gvec_mla_idx_d,
53
+ };
54
+ tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
55
+ vec_full_reg_offset(s, rn),
56
+ vec_full_reg_offset(s, rm),
57
+ vec_full_reg_offset(s, rd),
58
+ is_q ? 16 : 8, vec_full_reg_size(s),
59
+ index, fns[size - 1]);
219
+ return;
60
+ return;
220
+ }
61
+ }
221
+ }
62
+ break;
222
+
63
+
223
+ if ((insn & 0xff100000) == 0xf9000000) {
64
+ case 0x14: /* MLS */
224
+ /*
65
+ if (!is_long && !is_scalar) {
225
+ * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
66
+ static gen_helper_gvec_4 * const fns[3] = {
226
+ * transform into
67
+ gen_helper_gvec_mls_idx_h,
227
+ * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
68
+ gen_helper_gvec_mls_idx_s,
228
+ */
69
+ gen_helper_gvec_mls_idx_d,
229
+ uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
70
+ };
230
+
71
+ tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
231
+ if (disas_neon_ls(s, a32_insn)) {
72
+ vec_full_reg_offset(s, rn),
73
+ vec_full_reg_offset(s, rm),
74
+ vec_full_reg_offset(s, rd),
75
+ is_q ? 16 : 8, vec_full_reg_size(s),
76
+ index, fns[size - 1]);
232
+ return;
77
+ return;
233
+ }
78
+ }
234
+ }
79
+ break;
80
}
81
82
if (size == 3) {
83
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/target/arm/vec_helper.c
86
+++ b/target/arm/vec_helper.c
87
@@ -XXX,XX +XXX,XX @@ DO_MUL_IDX(gvec_mul_idx_d, uint64_t, )
88
89
#undef DO_MUL_IDX
90
91
+#define DO_MLA_IDX(NAME, TYPE, OP, H) \
92
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, uint32_t desc) \
93
+{ \
94
+ intptr_t i, j, oprsz = simd_oprsz(desc), segment = 16 / sizeof(TYPE); \
95
+ intptr_t idx = simd_data(desc); \
96
+ TYPE *d = vd, *n = vn, *m = vm, *a = va; \
97
+ for (i = 0; i < oprsz / sizeof(TYPE); i += segment) { \
98
+ TYPE mm = m[H(i + idx)]; \
99
+ for (j = 0; j < segment; j++) { \
100
+ d[i + j] = a[i + j] OP n[i + j] * mm; \
101
+ } \
102
+ } \
103
+ clear_tail(d, oprsz, simd_maxsz(desc)); \
104
+}
235
+
105
+
236
/*
106
+DO_MLA_IDX(gvec_mla_idx_h, uint16_t, +, H2)
237
* TODO: Perhaps merge these into one decodetree output file.
107
+DO_MLA_IDX(gvec_mla_idx_s, uint32_t, +, H4)
238
* Note disas_vfp is written for a32 with cond field in the
108
+DO_MLA_IDX(gvec_mla_idx_d, uint64_t, +, )
239
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
240
*/
241
if (disas_t32(s, insn) ||
242
disas_vfp_uncond(s, insn) ||
243
+ disas_neon_shared(s, insn) ||
244
((insn >> 28) == 0xe && disas_vfp(s, insn))) {
245
return;
246
}
247
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
248
index XXXXXXX..XXXXXXX 100644
249
--- a/target/arm/Makefile.objs
250
+++ b/target/arm/Makefile.objs
251
@@ -XXX,XX +XXX,XX @@ target/arm/decode-sve.inc.c: $(SRC_PATH)/target/arm/sve.decode $(DECODETREE)
252
     $(PYTHON) $(DECODETREE) --decode disas_sve -o $@ $<,\
253
     "GEN", $(TARGET_DIR)$@)
254
255
+target/arm/decode-neon-shared.inc.c: $(SRC_PATH)/target/arm/neon-shared.decode $(DECODETREE)
256
+    $(call quiet-command,\
257
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_shared -o $@ $<,\
258
+     "GEN", $(TARGET_DIR)$@)
259
+
109
+
260
+target/arm/decode-neon-dp.inc.c: $(SRC_PATH)/target/arm/neon-dp.decode $(DECODETREE)
110
+DO_MLA_IDX(gvec_mls_idx_h, uint16_t, -, H2)
261
+    $(call quiet-command,\
111
+DO_MLA_IDX(gvec_mls_idx_s, uint32_t, -, H4)
262
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_dp -o $@ $<,\
112
+DO_MLA_IDX(gvec_mls_idx_d, uint64_t, -, )
263
+     "GEN", $(TARGET_DIR)$@)
264
+
113
+
265
+target/arm/decode-neon-ls.inc.c: $(SRC_PATH)/target/arm/neon-ls.decode $(DECODETREE)
114
+#undef DO_MLA_IDX
266
+    $(call quiet-command,\
267
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_ls -o $@ $<,\
268
+     "GEN", $(TARGET_DIR)$@)
269
+
115
+
270
target/arm/decode-vfp.inc.c: $(SRC_PATH)/target/arm/vfp.decode $(DECODETREE)
116
#define DO_FMUL_IDX(NAME, TYPE, H) \
271
    $(call quiet-command,\
117
void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
272
     $(PYTHON) $(DECODETREE) --static-decode disas_vfp -o $@ $<,\
118
{ \
273
@@ -XXX,XX +XXX,XX @@ target/arm/decode-t16.inc.c: $(SRC_PATH)/target/arm/t16.decode $(DECODETREE)
274
     "GEN", $(TARGET_DIR)$@)
275
276
target/arm/translate-sve.o: target/arm/decode-sve.inc.c
277
+target/arm/translate.o: target/arm/decode-neon-shared.inc.c
278
+target/arm/translate.o: target/arm/decode-neon-dp.inc.c
279
+target/arm/translate.o: target/arm/decode-neon-ls.inc.c
280
target/arm/translate.o: target/arm/decode-vfp.inc.c
281
target/arm/translate.o: target/arm/decode-vfp-uncond.inc.c
282
target/arm/translate.o: target/arm/decode-a32.inc.c
283
--
119
--
284
2.20.1
120
2.20.1
285
121
286
122
diff view generated by jsdifflib
1
The ARMv8.2-TTS2UXN feature extends the XN field in stage 2
1
From: Richard Henderson <richard.henderson@linaro.org>
2
translation table descriptors from just bit [54] to bits [54:53],
3
allowing stage 2 to control execution permissions separately for EL0
4
and EL1. Implement the new semantics of the XN field and enable
5
the feature for our 'max' CPU.
6
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20200815013145.539409-21-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200330210400.11724-5-peter.maydell@linaro.org
11
---
7
---
12
target/arm/cpu.h | 15 +++++++++++++++
8
target/arm/helper.h | 10 ++++++++
13
target/arm/cpu.c | 1 +
9
target/arm/translate-a64.c | 33 ++++++++++++++++++--------
14
target/arm/cpu64.c | 2 ++
10
target/arm/vec_helper.c | 48 ++++++++++++++++++++++++++++++++++++++
15
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++------
11
3 files changed, 81 insertions(+), 10 deletions(-)
16
4 files changed, 49 insertions(+), 6 deletions(-)
17
12
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/helper.h b/target/arm/helper.h
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
15
--- a/target/arm/helper.h
21
+++ b/target/arm/cpu.h
16
+++ b/target/arm/helper.h
22
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_mls_idx_s, TCG_CALL_NO_RWG,
23
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
18
DEF_HELPER_FLAGS_5(gvec_mls_idx_d, TCG_CALL_NO_RWG,
19
void, ptr, ptr, ptr, ptr, i32)
20
21
+DEF_HELPER_FLAGS_5(neon_sqdmulh_h, TCG_CALL_NO_RWG,
22
+ void, ptr, ptr, ptr, ptr, i32)
23
+DEF_HELPER_FLAGS_5(neon_sqdmulh_s, TCG_CALL_NO_RWG,
24
+ void, ptr, ptr, ptr, ptr, i32)
25
+
26
+DEF_HELPER_FLAGS_5(neon_sqrdmulh_h, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_5(neon_sqrdmulh_s, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
+
31
#ifdef TARGET_AARCH64
32
#include "helper-a64.h"
33
#include "helper-sve.h"
34
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-a64.c
37
+++ b/target/arm/translate-a64.c
38
@@ -XXX,XX +XXX,XX @@ static void gen_gvec_op3_fpst(DisasContext *s, bool is_q, int rd, int rn,
39
tcg_temp_free_ptr(fpst);
24
}
40
}
25
41
26
+static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
42
+/* Expand a 3-operand + qc + operation using an out-of-line helper. */
43
+static void gen_gvec_op3_qc(DisasContext *s, bool is_q, int rd, int rn,
44
+ int rm, gen_helper_gvec_3_ptr *fn)
27
+{
45
+{
28
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0;
46
+ TCGv_ptr qc_ptr = tcg_temp_new_ptr();
47
+
48
+ tcg_gen_addi_ptr(qc_ptr, cpu_env, offsetof(CPUARMState, vfp.qc));
49
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
50
+ vec_full_reg_offset(s, rn),
51
+ vec_full_reg_offset(s, rm), qc_ptr,
52
+ is_q ? 16 : 8, vec_full_reg_size(s), 0, fn);
53
+ tcg_temp_free_ptr(qc_ptr);
29
+}
54
+}
30
+
55
+
31
/*
56
/* Set ZF and NF based on a 64 bit result. This is alas fiddlier
32
* 64-bit feature tests via id registers.
57
* than the 32 bit equivalent.
33
*/
58
*/
34
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
59
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
35
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
60
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_mla, size);
61
}
62
return;
63
+ case 0x16: /* SQDMULH, SQRDMULH */
64
+ {
65
+ static gen_helper_gvec_3_ptr * const fns[2][2] = {
66
+ { gen_helper_neon_sqdmulh_h, gen_helper_neon_sqrdmulh_h },
67
+ { gen_helper_neon_sqdmulh_s, gen_helper_neon_sqrdmulh_s },
68
+ };
69
+ gen_gvec_op3_qc(s, is_q, rd, rn, rm, fns[size - 1][u]);
70
+ }
71
+ return;
72
case 0x11:
73
if (!u) { /* CMTST */
74
gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_cmtst, size);
75
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
76
genenvfn = fns[size][u];
77
break;
78
}
79
- case 0x16: /* SQDMULH, SQRDMULH */
80
- {
81
- static NeonGenTwoOpEnvFn * const fns[2][2] = {
82
- { gen_helper_neon_qdmulh_s16, gen_helper_neon_qrdmulh_s16 },
83
- { gen_helper_neon_qdmulh_s32, gen_helper_neon_qrdmulh_s32 },
84
- };
85
- assert(size == 1 || size == 2);
86
- genenvfn = fns[size - 1][u];
87
- break;
88
- }
89
default:
90
g_assert_not_reached();
91
}
92
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/target/arm/vec_helper.c
95
+++ b/target/arm/vec_helper.c
96
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_qrdmlsh_s16)(void *vd, void *vn, void *vm,
97
clear_tail(d, opr_sz, simd_maxsz(desc));
36
}
98
}
37
99
38
+static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
100
+void HELPER(neon_sqdmulh_h)(void *vd, void *vn, void *vm,
101
+ void *vq, uint32_t desc)
39
+{
102
+{
40
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
103
+ intptr_t i, opr_sz = simd_oprsz(desc);
104
+ int16_t *d = vd, *n = vn, *m = vm;
105
+
106
+ for (i = 0; i < opr_sz / 2; ++i) {
107
+ d[i] = do_sqrdmlah_h(n[i], m[i], 0, false, false, vq);
108
+ }
109
+ clear_tail(d, opr_sz, simd_maxsz(desc));
41
+}
110
+}
42
+
111
+
43
/*
112
+void HELPER(neon_sqrdmulh_h)(void *vd, void *vn, void *vm,
44
* Feature tests for "does this exist in either 32-bit or 64-bit?"
113
+ void *vq, uint32_t desc)
45
*/
46
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
47
return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
48
}
49
50
+static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
51
+{
114
+{
52
+ return isar_feature_aa64_tts2uxn(id) || isar_feature_aa32_tts2uxn(id);
115
+ intptr_t i, opr_sz = simd_oprsz(desc);
116
+ int16_t *d = vd, *n = vn, *m = vm;
117
+
118
+ for (i = 0; i < opr_sz / 2; ++i) {
119
+ d[i] = do_sqrdmlah_h(n[i], m[i], 0, false, true, vq);
120
+ }
121
+ clear_tail(d, opr_sz, simd_maxsz(desc));
53
+}
122
+}
54
+
123
+
55
/*
124
/* Signed saturating rounding doubling multiply-accumulate high half, 32-bit */
56
* Forward to the above feature tests given an ARMCPU pointer.
125
static int32_t do_sqrdmlah_s(int32_t src1, int32_t src2, int32_t src3,
57
*/
126
bool neg, bool round, uint32_t *sat)
58
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
127
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_qrdmlsh_s32)(void *vd, void *vn, void *vm,
59
index XXXXXXX..XXXXXXX 100644
128
clear_tail(d, opr_sz, simd_maxsz(desc));
60
--- a/target/arm/cpu.c
129
}
61
+++ b/target/arm/cpu.c
130
62
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
131
+void HELPER(neon_sqdmulh_s)(void *vd, void *vn, void *vm,
63
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
132
+ void *vq, uint32_t desc)
64
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
133
+{
65
t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
134
+ intptr_t i, opr_sz = simd_oprsz(desc);
66
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
135
+ int32_t *d = vd, *n = vn, *m = vm;
67
cpu->isar.id_mmfr4 = t;
136
+
68
}
137
+ for (i = 0; i < opr_sz / 4; ++i) {
69
#endif
138
+ d[i] = do_sqrdmlah_s(n[i], m[i], 0, false, false, vq);
70
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
139
+ }
71
index XXXXXXX..XXXXXXX 100644
140
+ clear_tail(d, opr_sz, simd_maxsz(desc));
72
--- a/target/arm/cpu64.c
141
+}
73
+++ b/target/arm/cpu64.c
142
+
74
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
143
+void HELPER(neon_sqrdmulh_s)(void *vd, void *vn, void *vm,
75
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
144
+ void *vq, uint32_t desc)
76
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
145
+{
77
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */
146
+ intptr_t i, opr_sz = simd_oprsz(desc);
78
+ t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */
147
+ int32_t *d = vd, *n = vn, *m = vm;
79
cpu->isar.id_aa64mmfr1 = t;
148
+
80
149
+ for (i = 0; i < opr_sz / 4; ++i) {
81
t = cpu->isar.id_aa64mmfr2;
150
+ d[i] = do_sqrdmlah_s(n[i], m[i], 0, false, true, vq);
82
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
151
+ }
83
u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
152
+ clear_tail(d, opr_sz, simd_maxsz(desc));
84
u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
153
+}
85
u = FIELD_DP32(u, ID_MMFR4, CNP, 1); /* TTCNP */
154
+
86
+ u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
155
/* Integer 8 and 16-bit dot-product.
87
cpu->isar.id_mmfr4 = u;
88
89
u = cpu->isar.id_aa64dfr0;
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/helper.c
93
+++ b/target/arm/helper.c
94
@@ -XXX,XX +XXX,XX @@ simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
95
*
156
*
96
* @env: CPUARMState
157
* Note that for the loops herein, host endianness does not matter
97
* @s2ap: The 2-bit stage2 access permissions (S2AP)
98
- * @xn: XN (execute-never) bit
99
+ * @xn: XN (execute-never) bits
100
+ * @s1_is_el0: true if this is S2 of an S1+2 walk for EL0
101
*/
102
-static int get_S2prot(CPUARMState *env, int s2ap, int xn)
103
+static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
104
{
105
int prot = 0;
106
107
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn)
108
if (s2ap & 2) {
109
prot |= PAGE_WRITE;
110
}
111
- if (!xn) {
112
- if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
113
+
114
+ if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
115
+ switch (xn) {
116
+ case 0:
117
prot |= PAGE_EXEC;
118
+ break;
119
+ case 1:
120
+ if (s1_is_el0) {
121
+ prot |= PAGE_EXEC;
122
+ }
123
+ break;
124
+ case 2:
125
+ break;
126
+ case 3:
127
+ if (!s1_is_el0) {
128
+ prot |= PAGE_EXEC;
129
+ }
130
+ break;
131
+ default:
132
+ g_assert_not_reached();
133
+ }
134
+ } else {
135
+ if (!extract32(xn, 1, 1)) {
136
+ if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
137
+ prot |= PAGE_EXEC;
138
+ }
139
}
140
}
141
return prot;
142
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
143
}
144
145
ap = extract32(attrs, 4, 2);
146
- xn = extract32(attrs, 12, 1);
147
148
if (mmu_idx == ARMMMUIdx_Stage2) {
149
ns = true;
150
- *prot = get_S2prot(env, ap, xn);
151
+ xn = extract32(attrs, 11, 2);
152
+ *prot = get_S2prot(env, ap, xn, s1_is_el0);
153
} else {
154
ns = extract32(attrs, 3, 1);
155
+ xn = extract32(attrs, 12, 1);
156
pxn = extract32(attrs, 11, 1);
157
*prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
158
}
159
--
158
--
160
2.20.1
159
2.20.1
161
160
162
161
diff view generated by jsdifflib
Deleted patch
1
In aarch64_max_initfn() we update both 32-bit and 64-bit ID
2
registers. The intended pattern is that for 64-bit ID registers we
3
use FIELD_DP64 and the uint64_t 't' register, while 32-bit ID
4
registers use FIELD_DP32 and the uint32_t 'u' register. For
5
ID_AA64DFR0 we accidentally used 'u', meaning that the top 32 bits of
6
this 64-bit ID register would end up always zero. Luckily at the
7
moment that's what they should be anyway, so this bug has no visible
8
effects.
9
1
10
Use the right-sized variable.
11
12
Fixes: 3bec78447a958d481991
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20200423110915.10527-1-peter.maydell@linaro.org
17
---
18
target/arm/cpu64.c | 6 +++---
19
1 file changed, 3 insertions(+), 3 deletions(-)
20
21
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu64.c
24
+++ b/target/arm/cpu64.c
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
26
u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
27
cpu->isar.id_mmfr4 = u;
28
29
- u = cpu->isar.id_aa64dfr0;
30
- u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
31
- cpu->isar.id_aa64dfr0 = u;
32
+ t = cpu->isar.id_aa64dfr0;
33
+ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
34
+ cpu->isar.id_aa64dfr0 = t;
35
36
u = cpu->isar.id_dfr0;
37
u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
38
--
39
2.20.1
40
41
diff view generated by jsdifflib
Deleted patch
1
We were accidentally permitting decode of Thumb Neon insns even if
2
the CPU didn't have the FEATURE_NEON bit set, because the feature
3
check was being done before the call to disas_neon_data_insn() and
4
disas_neon_ls_insn() in the Arm decoder but was omitted from the
5
Thumb decoder. Push the feature bit check down into the called
6
functions so it is done for both Arm and Thumb encodings.
7
1
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20200430181003.21682-3-peter.maydell@linaro.org
12
---
13
target/arm/translate.c | 16 ++++++++--------
14
1 file changed, 8 insertions(+), 8 deletions(-)
15
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
19
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
21
TCGv_i32 tmp2;
22
TCGv_i64 tmp64;
23
24
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
25
+ return 1;
26
+ }
27
+
28
/* FIXME: this access check should not take precedence over UNDEF
29
* for invalid encodings; we will generate incorrect syndrome information
30
* for attempts to execute invalid vfp/neon encodings with FP disabled.
31
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
32
TCGv_ptr ptr1, ptr2, ptr3;
33
TCGv_i64 tmp64;
34
35
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
36
+ return 1;
37
+ }
38
+
39
/* FIXME: this access check should not take precedence over UNDEF
40
* for invalid encodings; we will generate incorrect syndrome information
41
* for attempts to execute invalid vfp/neon encodings with FP disabled.
42
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
43
44
if (((insn >> 25) & 7) == 1) {
45
/* NEON Data processing. */
46
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
47
- goto illegal_op;
48
- }
49
-
50
if (disas_neon_data_insn(s, insn)) {
51
goto illegal_op;
52
}
53
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
54
}
55
if ((insn & 0x0f100000) == 0x04000000) {
56
/* NEON load/store. */
57
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
58
- goto illegal_op;
59
- }
60
-
61
if (disas_neon_ls_insn(s, insn)) {
62
goto illegal_op;
63
}
64
--
65
2.20.1
66
67
diff view generated by jsdifflib
Deleted patch
1
Convert the VCMLA (vector) insns in the 3same extension group to
2
decodetree.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-5-peter.maydell@linaro.org
7
---
8
target/arm/neon-shared.decode | 11 ++++++++++
9
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 11 +---------
11
3 files changed, 49 insertions(+), 10 deletions(-)
12
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
16
+++ b/target/arm/neon-shared.decode
17
@@ -XXX,XX +XXX,XX @@
18
# More specifically, this covers:
19
# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
20
# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
21
+
22
+# VFP/Neon register fields; same as vfp.decode
23
+%vm_dp 5:1 0:4
24
+%vm_sp 0:4 5:1
25
+%vn_dp 7:1 16:4
26
+%vn_sp 16:4 7:1
27
+%vd_dp 22:1 12:4
28
+%vd_sp 12:4 22:1
29
+
30
+VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
31
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
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 @@
37
#include "decode-neon-dp.inc.c"
38
#include "decode-neon-ls.inc.c"
39
#include "decode-neon-shared.inc.c"
40
+
41
+static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
42
+{
43
+ int opr_sz;
44
+ TCGv_ptr fpst;
45
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
46
+
47
+ if (!dc_isar_feature(aa32_vcma, s)
48
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
49
+ return false;
50
+ }
51
+
52
+ /* UNDEF accesses to D16-D31 if they don't exist. */
53
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
54
+ ((a->vd | a->vn | a->vm) & 0x10)) {
55
+ return false;
56
+ }
57
+
58
+ if ((a->vn | a->vm | a->vd) & a->q) {
59
+ return false;
60
+ }
61
+
62
+ if (!vfp_access_check(s)) {
63
+ return true;
64
+ }
65
+
66
+ opr_sz = (1 + a->q) * 8;
67
+ fpst = get_fpstatus_ptr(1);
68
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
69
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
70
+ vfp_reg_offset(1, a->vn),
71
+ vfp_reg_offset(1, a->vm),
72
+ fpst, opr_sz, opr_sz, a->rot,
73
+ fn_gvec_ptr);
74
+ tcg_temp_free_ptr(fpst);
75
+ return true;
76
+}
77
diff --git a/target/arm/translate.c b/target/arm/translate.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/translate.c
80
+++ b/target/arm/translate.c
81
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
82
bool is_long = false, q = extract32(insn, 6, 1);
83
bool ptr_is_env = false;
84
85
- if ((insn & 0xfe200f10) == 0xfc200800) {
86
- /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
87
- int size = extract32(insn, 20, 1);
88
- data = extract32(insn, 23, 2); /* rot */
89
- if (!dc_isar_feature(aa32_vcma, s)
90
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
91
- return 1;
92
- }
93
- fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
94
- } else if ((insn & 0xfea00f10) == 0xfc800800) {
95
+ if ((insn & 0xfea00f10) == 0xfc800800) {
96
/* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
97
int size = extract32(insn, 20, 1);
98
data = extract32(insn, 24, 1); /* rot */
99
--
100
2.20.1
101
102
diff view generated by jsdifflib
Deleted patch
1
Convert the VCADD (vector) insns to decodetree.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-6-peter.maydell@linaro.org
6
---
7
target/arm/neon-shared.decode | 3 +++
8
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 11 +---------
10
3 files changed, 41 insertions(+), 10 deletions(-)
11
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
15
+++ b/target/arm/neon-shared.decode
16
@@ -XXX,XX +XXX,XX @@
17
18
VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
+
21
+VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
22
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
23
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/translate-neon.inc.c
26
+++ b/target/arm/translate-neon.inc.c
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
28
tcg_temp_free_ptr(fpst);
29
return true;
30
}
31
+
32
+static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
33
+{
34
+ int opr_sz;
35
+ TCGv_ptr fpst;
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
37
+
38
+ if (!dc_isar_feature(aa32_vcma, s)
39
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
40
+ return false;
41
+ }
42
+
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
45
+ ((a->vd | a->vn | a->vm) & 0x10)) {
46
+ return false;
47
+ }
48
+
49
+ if ((a->vn | a->vm | a->vd) & a->q) {
50
+ return false;
51
+ }
52
+
53
+ if (!vfp_access_check(s)) {
54
+ return true;
55
+ }
56
+
57
+ opr_sz = (1 + a->q) * 8;
58
+ fpst = get_fpstatus_ptr(1);
59
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
60
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->vm),
63
+ fpst, opr_sz, opr_sz, a->rot,
64
+ fn_gvec_ptr);
65
+ tcg_temp_free_ptr(fpst);
66
+ return true;
67
+}
68
diff --git a/target/arm/translate.c b/target/arm/translate.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/translate.c
71
+++ b/target/arm/translate.c
72
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
73
bool is_long = false, q = extract32(insn, 6, 1);
74
bool ptr_is_env = false;
75
76
- if ((insn & 0xfea00f10) == 0xfc800800) {
77
- /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
78
- int size = extract32(insn, 20, 1);
79
- data = extract32(insn, 24, 1); /* rot */
80
- if (!dc_isar_feature(aa32_vcma, s)
81
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
82
- return 1;
83
- }
84
- fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
85
- } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
86
+ if ((insn & 0xfeb00f00) == 0xfc200d00) {
87
/* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
88
bool u = extract32(insn, 4, 1);
89
if (!dc_isar_feature(aa32_dp, s)) {
90
--
91
2.20.1
92
93
diff view generated by jsdifflib