1
Big fat pullreq this time around, because it has all of RTH's
1
The following changes since commit 3db29dcac23da85486704ef9e7a8e7217f7829cd:
2
SVE2 emulation patchset in it.
3
2
4
-- PMM
3
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging (2023-01-12 13:51:36 +0000)
5
6
The following changes since commit 0dab1d36f55c3ed649bb8e4c74b9269ef3a63049:
7
8
Merge remote-tracking branch 'remotes/stefanha-gitlab/tags/block-pull-request' into staging (2021-05-24 15:48:08 +0100)
9
4
10
are available in the Git repository at:
5
are available in the Git repository at:
11
6
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210525
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230113
13
8
14
for you to fetch changes up to f8680aaa6e5bfc6022b75157c23db7d2ea98ab11:
9
for you to fetch changes up to 08899b5c68a55a3780d707e2464073c8f2670d31:
15
10
16
target/arm: Enable SVE2 and related extensions (2021-05-25 16:01:44 +0100)
11
target/arm: allow writes to SCR_EL3.HXEn bit when FEAT_HCX is enabled (2023-01-13 13:19:36 +0000)
17
12
18
----------------------------------------------------------------
13
----------------------------------------------------------------
19
target-arm queue:
14
target-arm queue:
20
* Implement SVE2 emulation
15
hw/arm/stm32f405: correctly describe the memory layout
21
* Implement integer matrix multiply accumulate
16
hw/arm: Add Olimex H405 board
22
* Implement FEAT_TLBIOS
17
cubieboard: Support booting from an SD card image with u-boot on it
23
* Implement FEAT_TLBRANGE
18
target/arm: Fix sve_probe_page
24
* disas/libvixl: Protect C system header for C++ compiler
19
target/arm: allow writes to SCR_EL3.HXEn bit when FEAT_HCX is enabled
25
* Use correct SP in M-profile exception return
20
various code cleanups
26
* AN524, AN547: Correct modelling of internal SRAMs
27
* hw/intc/arm_gicv3_cpuif: Fix EOIR write access check logic
28
* hw/arm/smmuv3: Another range invalidation fix
29
21
30
----------------------------------------------------------------
22
----------------------------------------------------------------
31
Eric Auger (1):
23
Evgeny Iakovlev (1):
32
hw/arm/smmuv3: Another range invalidation fix
24
target/arm: allow writes to SCR_EL3.HXEn bit when FEAT_HCX is enabled
33
25
34
Peter Maydell (8):
26
Felipe Balbi (2):
35
hw/intc/arm_gicv3_cpuif: Fix EOIR write access check logic
27
hw/arm/stm32f405: correctly describe the memory layout
36
hw/arm/mps2-tz: Don't duplicate modelling of SRAM in AN524
28
hw/arm: Add Olimex H405
37
hw/arm/mps2-tz: Make SRAM_ADDR_WIDTH board-specific
38
hw/arm/armsse.c: Correct modelling of SSE-300 internal SRAMs
39
hw/arm/armsse: Convert armsse_realize() to use ERRP_GUARD
40
hw/arm/mps2-tz: Allow board to specify a boot RAM size
41
hw/arm: Model TCMs in the SSE-300, not the AN547
42
target/arm: Use correct SP in M-profile exception return
43
29
44
Philippe Mathieu-Daudé (1):
30
Philippe Mathieu-Daudé (27):
45
disas/libvixl: Protect C system header for C++ compiler
31
hw/arm/pxa2xx: Simplify pxa255_init()
32
hw/arm/pxa2xx: Simplify pxa270_init()
33
hw/arm/collie: Use the IEC binary prefix definitions
34
hw/arm/collie: Simplify flash creation using for() loop
35
hw/arm/gumstix: Improve documentation
36
hw/arm/gumstix: Use the IEC binary prefix definitions
37
hw/arm/mainstone: Use the IEC binary prefix definitions
38
hw/arm/musicpal: Use the IEC binary prefix definitions
39
hw/arm/omap_sx1: Remove unused 'total_ram' definitions
40
hw/arm/omap_sx1: Use the IEC binary prefix definitions
41
hw/arm/z2: Use the IEC binary prefix definitions
42
hw/arm/vexpress: Remove dead code in vexpress_common_init()
43
hw/arm: Remove unreachable code calling pflash_cfi01_register()
44
hw/arm/pxa: Avoid forward-declaring PXA2xxI2CState
45
hw/gpio/omap_gpio: Add local variable to avoid embedded cast
46
hw/arm/omap: Drop useless casts from void * to pointer
47
hw/gpio/omap_gpio: Use CamelCase for TYPE_OMAP1_GPIO type name
48
hw/gpio/omap_gpio: Use CamelCase for TYPE_OMAP2_GPIO type name
49
hw/intc/omap_intc: Use CamelCase for TYPE_OMAP_INTC type name
50
hw/arm/stellaris: Drop useless casts from void * to pointer
51
hw/arm/stellaris: Use CamelCase for STELLARIS_ADC type name
52
hw/arm/bcm2836: Remove definitions generated by OBJECT_DECLARE_TYPE()
53
hw/arm/npcm7xx: Declare QOM macros using OBJECT_DECLARE_SIMPLE_TYPE()
54
hw/misc/sbsa_ec: Rename TYPE_SBSA_EC -> TYPE_SBSA_SECURE_EC
55
hw/misc/sbsa_ec: Declare QOM macros using OBJECT_DECLARE_SIMPLE_TYPE()
56
hw/intc/xilinx_intc: Use 'XpsIntc' typedef instead of 'struct xlx_pic'
57
hw/timer/xilinx_timer: Use XpsTimerState instead of 'struct timerblock'
46
58
47
Rebecca Cran (3):
59
Richard Henderson (1):
48
target/arm: Add support for FEAT_TLBIRANGE
60
target/arm: Fix sve_probe_page
49
target/arm: Add support for FEAT_TLBIOS
50
target/arm: set ID_AA64ISAR0.TLB to 2 for max AARCH64 CPU type
51
61
52
Richard Henderson (84):
62
Strahinja Jankovic (7):
53
accel/tcg: Replace g_new() + memcpy() by g_memdup()
63
hw/misc: Allwinner-A10 Clock Controller Module Emulation
54
accel/tcg: Pass length argument to tlb_flush_range_locked()
64
hw/misc: Allwinner A10 DRAM Controller Emulation
55
accel/tlb: Rename TLBFlushPageBitsByMMUIdxData -> TLBFlushRangeData
65
{hw/i2c,docs/system/arm}: Allwinner TWI/I2C Emulation
56
accel/tcg: Remove {encode,decode}_pbm_to_runon
66
hw/misc: AXP209 PMU Emulation
57
accel/tcg: Add tlb_flush_range_by_mmuidx()
67
hw/arm: Add AXP209 to Cubieboard
58
accel/tcg: Add tlb_flush_range_by_mmuidx_all_cpus()
68
hw/arm: Allwinner A10 enable SPL load from MMC
59
accel/tlb: Add tlb_flush_range_by_mmuidx_all_cpus_synced()
69
tests/avocado: Add SD boot test to Cubieboard
60
accel/tcg: Rename tlb_flush_page_bits -> range]_by_mmuidx_async_0
61
accel/tlb: Rename tlb_flush_[page_bits > range]_by_mmuidx_async_[2 > 1]
62
target/arm: Add ID_AA64ZFR0 fields and isar_feature_aa64_sve2
63
target/arm: Implement SVE2 Integer Multiply - Unpredicated
64
target/arm: Implement SVE2 integer pairwise add and accumulate long
65
target/arm: Implement SVE2 integer unary operations (predicated)
66
target/arm: Split out saturating/rounding shifts from neon
67
target/arm: Implement SVE2 saturating/rounding bitwise shift left (predicated)
68
target/arm: Implement SVE2 integer halving add/subtract (predicated)
69
target/arm: Implement SVE2 integer pairwise arithmetic
70
target/arm: Implement SVE2 saturating add/subtract (predicated)
71
target/arm: Implement SVE2 integer add/subtract long
72
target/arm: Implement SVE2 integer add/subtract interleaved long
73
target/arm: Implement SVE2 integer add/subtract wide
74
target/arm: Implement SVE2 integer multiply long
75
target/arm: Implement SVE2 PMULLB, PMULLT
76
target/arm: Implement SVE2 bitwise shift left long
77
target/arm: Implement SVE2 bitwise exclusive-or interleaved
78
target/arm: Implement SVE2 bitwise permute
79
target/arm: Implement SVE2 complex integer add
80
target/arm: Implement SVE2 integer absolute difference and accumulate long
81
target/arm: Implement SVE2 integer add/subtract long with carry
82
target/arm: Implement SVE2 bitwise shift right and accumulate
83
target/arm: Implement SVE2 bitwise shift and insert
84
target/arm: Implement SVE2 integer absolute difference and accumulate
85
target/arm: Implement SVE2 saturating extract narrow
86
target/arm: Implement SVE2 SHRN, RSHRN
87
target/arm: Implement SVE2 SQSHRUN, SQRSHRUN
88
target/arm: Implement SVE2 UQSHRN, UQRSHRN
89
target/arm: Implement SVE2 SQSHRN, SQRSHRN
90
target/arm: Implement SVE2 WHILEGT, WHILEGE, WHILEHI, WHILEHS
91
target/arm: Implement SVE2 WHILERW, WHILEWR
92
target/arm: Implement SVE2 bitwise ternary operations
93
target/arm: Implement SVE2 saturating multiply-add long
94
target/arm: Implement SVE2 saturating multiply-add high
95
target/arm: Implement SVE2 integer multiply-add long
96
target/arm: Implement SVE2 complex integer multiply-add
97
target/arm: Implement SVE2 XAR
98
target/arm: Use correct output type for gvec_sdot_*_b
99
target/arm: Pass separate addend to {U, S}DOT helpers
100
target/arm: Pass separate addend to FCMLA helpers
101
target/arm: Split out formats for 2 vectors + 1 index
102
target/arm: Split out formats for 3 vectors + 1 index
103
target/arm: Implement SVE2 integer multiply (indexed)
104
target/arm: Implement SVE2 integer multiply-add (indexed)
105
target/arm: Implement SVE2 saturating multiply-add high (indexed)
106
target/arm: Implement SVE2 saturating multiply-add (indexed)
107
target/arm: Implement SVE2 saturating multiply (indexed)
108
target/arm: Implement SVE2 signed saturating doubling multiply high
109
target/arm: Implement SVE2 saturating multiply high (indexed)
110
target/arm: Implement SVE2 multiply-add long (indexed)
111
target/arm: Implement SVE2 integer multiply long (indexed)
112
target/arm: Implement SVE2 complex integer multiply-add (indexed)
113
target/arm: Implement SVE2 complex integer dot product
114
target/arm: Macroize helper_gvec_{s,u}dot_{b,h}
115
target/arm: Macroize helper_gvec_{s,u}dot_idx_{b,h}
116
target/arm: Implement SVE mixed sign dot product (indexed)
117
target/arm: Implement SVE mixed sign dot product
118
target/arm: Implement SVE2 crypto unary operations
119
target/arm: Implement SVE2 crypto destructive binary operations
120
target/arm: Implement SVE2 crypto constructive binary operations
121
target/arm: Implement SVE2 FCVTNT
122
target/arm: Share table of sve load functions
123
target/arm: Tidy do_ldrq
124
target/arm: Implement SVE2 LD1RO
125
target/arm: Implement 128-bit ZIP, UZP, TRN
126
target/arm: Move endian adjustment macros to vec_internal.h
127
target/arm: Implement aarch64 SUDOT, USDOT
128
target/arm: Split out do_neon_ddda_fpst
129
target/arm: Remove unused fpst from VDOT_scalar
130
target/arm: Fix decode for VDOT (indexed)
131
target/arm: Split out do_neon_ddda
132
target/arm: Split decode of VSDOT and VUDOT
133
target/arm: Implement aarch32 VSUDOT, VUSDOT
134
target/arm: Implement integer matrix multiply accumulate
135
linux-user/aarch64: Enable hwcap bits for sve2 and related extensions
136
target/arm: Enable SVE2 and related extensions
137
70
138
Stephen Long (17):
71
docs/system/arm/cubieboard.rst | 1 +
139
target/arm: Implement SVE2 floating-point pairwise
72
docs/system/arm/orangepi.rst | 1 +
140
target/arm: Implement SVE2 MATCH, NMATCH
73
docs/system/arm/stm32.rst | 1 +
141
target/arm: Implement SVE2 ADDHNB, ADDHNT
74
configs/devices/arm-softmmu/default.mak | 1 +
142
target/arm: Implement SVE2 RADDHNB, RADDHNT
75
include/hw/adc/npcm7xx_adc.h | 7 +-
143
target/arm: Implement SVE2 SUBHNB, SUBHNT
76
include/hw/arm/allwinner-a10.h | 27 ++
144
target/arm: Implement SVE2 RSUBHNB, RSUBHNT
77
include/hw/arm/allwinner-h3.h | 3 +
145
target/arm: Implement SVE2 HISTCNT, HISTSEG
78
include/hw/arm/npcm7xx.h | 18 +-
146
target/arm: Implement SVE2 scatter store insns
79
include/hw/arm/omap.h | 24 +-
147
target/arm: Implement SVE2 gather load insns
80
include/hw/arm/pxa.h | 11 +-
148
target/arm: Implement SVE2 FMMLA
81
include/hw/arm/stm32f405_soc.h | 5 +-
149
target/arm: Implement SVE2 SPLICE, EXT
82
include/hw/i2c/allwinner-i2c.h | 55 ++++
150
target/arm: Implement SVE2 TBL, TBX
83
include/hw/i2c/npcm7xx_smbus.h | 7 +-
151
target/arm: Implement SVE2 FCVTLT
84
include/hw/misc/allwinner-a10-ccm.h | 67 +++++
152
target/arm: Implement SVE2 FCVTXNT, FCVTX
85
include/hw/misc/allwinner-a10-dramc.h | 68 +++++
153
target/arm: Implement SVE2 FLOGB
86
include/hw/misc/npcm7xx_clk.h | 2 +-
154
target/arm: Implement SVE2 bitwise shift immediate
87
include/hw/misc/npcm7xx_gcr.h | 6 +-
155
target/arm: Implement SVE2 fp multiply-add long
88
include/hw/misc/npcm7xx_mft.h | 7 +-
89
include/hw/misc/npcm7xx_pwm.h | 3 +-
90
include/hw/misc/npcm7xx_rng.h | 6 +-
91
include/hw/net/npcm7xx_emc.h | 5 +-
92
include/hw/sd/npcm7xx_sdhci.h | 4 +-
93
hw/arm/allwinner-a10.c | 40 +++
94
hw/arm/allwinner-h3.c | 11 +-
95
hw/arm/bcm2836.c | 9 +-
96
hw/arm/collie.c | 25 +-
97
hw/arm/cubieboard.c | 11 +
98
hw/arm/gumstix.c | 45 ++--
99
hw/arm/mainstone.c | 37 ++-
100
hw/arm/musicpal.c | 9 +-
101
hw/arm/olimex-stm32-h405.c | 69 +++++
102
hw/arm/omap1.c | 115 ++++----
103
hw/arm/omap2.c | 40 ++-
104
hw/arm/omap_sx1.c | 53 ++--
105
hw/arm/palm.c | 2 +-
106
hw/arm/pxa2xx.c | 8 +-
107
hw/arm/spitz.c | 6 +-
108
hw/arm/stellaris.c | 73 +++--
109
hw/arm/stm32f405_soc.c | 8 +
110
hw/arm/tosa.c | 2 +-
111
hw/arm/versatilepb.c | 6 +-
112
hw/arm/vexpress.c | 10 +-
113
hw/arm/z2.c | 16 +-
114
hw/char/omap_uart.c | 7 +-
115
hw/display/omap_dss.c | 15 +-
116
hw/display/omap_lcdc.c | 9 +-
117
hw/dma/omap_dma.c | 15 +-
118
hw/gpio/omap_gpio.c | 48 ++--
119
hw/i2c/allwinner-i2c.c | 459 ++++++++++++++++++++++++++++++++
120
hw/intc/omap_intc.c | 38 +--
121
hw/intc/xilinx_intc.c | 28 +-
122
hw/misc/allwinner-a10-ccm.c | 224 ++++++++++++++++
123
hw/misc/allwinner-a10-dramc.c | 179 +++++++++++++
124
hw/misc/axp209.c | 238 +++++++++++++++++
125
hw/misc/omap_gpmc.c | 12 +-
126
hw/misc/omap_l4.c | 7 +-
127
hw/misc/omap_sdrc.c | 7 +-
128
hw/misc/omap_tap.c | 5 +-
129
hw/misc/sbsa_ec.c | 12 +-
130
hw/sd/omap_mmc.c | 9 +-
131
hw/ssi/omap_spi.c | 7 +-
132
hw/timer/omap_gptimer.c | 22 +-
133
hw/timer/omap_synctimer.c | 4 +-
134
hw/timer/xilinx_timer.c | 27 +-
135
target/arm/helper.c | 3 +
136
target/arm/sve_helper.c | 14 +-
137
MAINTAINERS | 8 +
138
hw/arm/Kconfig | 9 +
139
hw/arm/meson.build | 1 +
140
hw/i2c/Kconfig | 4 +
141
hw/i2c/meson.build | 1 +
142
hw/i2c/trace-events | 5 +
143
hw/misc/Kconfig | 10 +
144
hw/misc/meson.build | 3 +
145
hw/misc/trace-events | 5 +
146
tests/avocado/boot_linux_console.py | 47 ++++
147
76 files changed, 1951 insertions(+), 455 deletions(-)
148
create mode 100644 include/hw/i2c/allwinner-i2c.h
149
create mode 100644 include/hw/misc/allwinner-a10-ccm.h
150
create mode 100644 include/hw/misc/allwinner-a10-dramc.h
151
create mode 100644 hw/arm/olimex-stm32-h405.c
152
create mode 100644 hw/i2c/allwinner-i2c.c
153
create mode 100644 hw/misc/allwinner-a10-ccm.c
154
create mode 100644 hw/misc/allwinner-a10-dramc.c
155
create mode 100644 hw/misc/axp209.c
156
156
157
disas/libvixl/vixl/code-buffer.h | 2 +-
158
disas/libvixl/vixl/globals.h | 16 +-
159
disas/libvixl/vixl/invalset.h | 2 +-
160
disas/libvixl/vixl/platform.h | 2 +
161
disas/libvixl/vixl/utils.h | 2 +-
162
include/exec/exec-all.h | 44 +
163
include/hw/arm/armsse.h | 2 +
164
target/arm/cpu.h | 76 +
165
target/arm/helper-sve.h | 722 ++++++++-
166
target/arm/helper.h | 110 +-
167
target/arm/translate-a64.h | 3 +
168
target/arm/vec_internal.h | 167 ++
169
target/arm/neon-shared.decode | 24 +-
170
target/arm/sve.decode | 574 ++++++-
171
accel/tcg/cputlb.c | 231 ++-
172
hw/arm/armsse.c | 35 +-
173
hw/arm/mps2-tz.c | 39 +-
174
hw/arm/smmuv3.c | 50 +-
175
hw/intc/arm_gicv3_cpuif.c | 48 +-
176
linux-user/elfload.c | 10 +
177
target/arm/cpu.c | 2 +
178
target/arm/cpu64.c | 14 +
179
target/arm/cpu_tcg.c | 1 +
180
target/arm/helper.c | 327 +++-
181
target/arm/kvm64.c | 21 +-
182
target/arm/m_helper.c | 3 +-
183
target/arm/neon_helper.c | 507 +-----
184
target/arm/sve_helper.c | 2110 +++++++++++++++++++++++--
185
target/arm/translate-a64.c | 111 +-
186
target/arm/translate-neon.c | 231 +--
187
target/arm/translate-sve.c | 3200 +++++++++++++++++++++++++++++++++++---
188
target/arm/vec_helper.c | 887 ++++++++---
189
disas/libvixl/vixl/utils.cc | 2 +-
190
33 files changed, 8275 insertions(+), 1300 deletions(-)
191
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Felipe Balbi <balbi@kernel.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
STM32F405 has 128K of SRAM and another 64K of CCM (Core-coupled
4
Signed-off-by: Stephen Long <steplong@quicinc.com>
4
Memory) at a different base address. Correctly describe the memory
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
layout to give existing FW images a chance to run unmodified.
6
Message-id: 20210525010358.152808-73-richard.henderson@linaro.org
6
7
Message-Id: <20200428174332.17162-2-steplong@quicinc.com>
7
Reviewed-by: Alistair Francis <alistair@alistair23.me>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Signed-off-by: Felipe Balbi <balbi@kernel.org>
10
Message-id: 20221230145733.200496-2-balbi@kernel.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/helper-sve.h | 5 +++++
13
include/hw/arm/stm32f405_soc.h | 5 ++++-
12
target/arm/sve.decode | 4 ++++
14
hw/arm/stm32f405_soc.c | 8 ++++++++
13
target/arm/sve_helper.c | 20 ++++++++++++++++++++
15
2 files changed, 12 insertions(+), 1 deletion(-)
14
target/arm/translate-sve.c | 16 ++++++++++++++++
15
4 files changed, 45 insertions(+)
16
16
17
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
17
diff --git a/include/hw/arm/stm32f405_soc.h b/include/hw/arm/stm32f405_soc.h
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper-sve.h
19
--- a/include/hw/arm/stm32f405_soc.h
20
+++ b/target/arm/helper-sve.h
20
+++ b/include/hw/arm/stm32f405_soc.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_cdot_idx_s, TCG_CALL_NO_RWG,
21
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(STM32F405State, STM32F405_SOC)
22
void, ptr, ptr, ptr, ptr, i32)
22
#define FLASH_BASE_ADDRESS 0x08000000
23
DEF_HELPER_FLAGS_5(sve2_cdot_idx_d, TCG_CALL_NO_RWG,
23
#define FLASH_SIZE (1024 * 1024)
24
void, ptr, ptr, ptr, ptr, i32)
24
#define SRAM_BASE_ADDRESS 0x20000000
25
-#define SRAM_SIZE (192 * 1024)
26
+#define SRAM_SIZE (128 * 1024)
27
+#define CCM_BASE_ADDRESS 0x10000000
28
+#define CCM_SIZE (64 * 1024)
29
30
struct STM32F405State {
31
/*< private >*/
32
@@ -XXX,XX +XXX,XX @@ struct STM32F405State {
33
STM32F2XXADCState adc[STM_NUM_ADCS];
34
STM32F2XXSPIState spi[STM_NUM_SPIS];
35
36
+ MemoryRegion ccm;
37
MemoryRegion sram;
38
MemoryRegion flash;
39
MemoryRegion flash_alias;
40
diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/arm/stm32f405_soc.c
43
+++ b/hw/arm/stm32f405_soc.c
44
@@ -XXX,XX +XXX,XX @@ static void stm32f405_soc_realize(DeviceState *dev_soc, Error **errp)
45
}
46
memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, &s->sram);
47
48
+ memory_region_init_ram(&s->ccm, NULL, "STM32F405.ccm", CCM_SIZE,
49
+ &err);
50
+ if (err != NULL) {
51
+ error_propagate(errp, err);
52
+ return;
53
+ }
54
+ memory_region_add_subregion(system_memory, CCM_BASE_ADDRESS, &s->ccm);
25
+
55
+
26
+DEF_HELPER_FLAGS_5(sve2_fcvtnt_sh, TCG_CALL_NO_RWG,
56
armv7m = DEVICE(&s->armv7m);
27
+ void, ptr, ptr, ptr, ptr, i32)
57
qdev_prop_set_uint32(armv7m, "num-irq", 96);
28
+DEF_HELPER_FLAGS_5(sve2_fcvtnt_ds, TCG_CALL_NO_RWG,
58
qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
29
+ void, ptr, ptr, ptr, ptr, i32)
30
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/sve.decode
33
+++ b/target/arm/sve.decode
34
@@ -XXX,XX +XXX,XX @@ SM4E 01000101 00 10001 1 11100 0 ..... ..... @rdn_rm_e0
35
# SVE2 crypto constructive binary operations
36
SM4EKEY 01000101 00 1 ..... 11110 0 ..... ..... @rd_rn_rm_e0
37
RAX1 01000101 00 1 ..... 11110 1 ..... ..... @rd_rn_rm_e0
38
+
39
+### SVE2 floating-point convert precision odd elements
40
+FCVTNT_sh 01100100 10 0010 00 101 ... ..... ..... @rd_pg_rn_e0
41
+FCVTNT_ds 01100100 11 0010 10 101 ... ..... ..... @rd_pg_rn_e0
42
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/sve_helper.c
45
+++ b/target/arm/sve_helper.c
46
@@ -XXX,XX +XXX,XX @@ void HELPER(fmmla_d)(void *vd, void *vn, void *vm, void *va,
47
d[3] = float64_add(a[3], float64_add(p0, p1, status), status);
48
}
49
}
50
+
51
+#define DO_FCVTNT(NAME, TYPEW, TYPEN, HW, HN, OP) \
52
+void HELPER(NAME)(void *vd, void *vn, void *vg, void *status, uint32_t desc) \
53
+{ \
54
+ intptr_t i = simd_oprsz(desc); \
55
+ uint64_t *g = vg; \
56
+ do { \
57
+ uint64_t pg = g[(i - 1) >> 6]; \
58
+ do { \
59
+ i -= sizeof(TYPEW); \
60
+ if (likely((pg >> (i & 63)) & 1)) { \
61
+ TYPEW nn = *(TYPEW *)(vn + HW(i)); \
62
+ *(TYPEN *)(vd + HN(i + sizeof(TYPEN))) = OP(nn, status); \
63
+ } \
64
+ } while (i & 63); \
65
+ } while (i != 0); \
66
+}
67
+
68
+DO_FCVTNT(sve2_fcvtnt_sh, uint32_t, uint16_t, H1_4, H1_2, sve_f32_to_f16)
69
+DO_FCVTNT(sve2_fcvtnt_ds, uint64_t, uint32_t, , H1_4, float64_to_float32)
70
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/translate-sve.c
73
+++ b/target/arm/translate-sve.c
74
@@ -XXX,XX +XXX,XX @@ static bool trans_RAX1(DisasContext *s, arg_rrr_esz *a)
75
}
76
return true;
77
}
78
+
79
+static bool trans_FCVTNT_sh(DisasContext *s, arg_rpr_esz *a)
80
+{
81
+ if (!dc_isar_feature(aa64_sve2, s)) {
82
+ return false;
83
+ }
84
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve2_fcvtnt_sh);
85
+}
86
+
87
+static bool trans_FCVTNT_ds(DisasContext *s, arg_rpr_esz *a)
88
+{
89
+ if (!dc_isar_feature(aa64_sve2, s)) {
90
+ return false;
91
+ }
92
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve2_fcvtnt_ds);
93
+}
94
--
59
--
95
2.20.1
60
2.34.1
96
61
97
62
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Felipe Balbi <balbi@kernel.org>
2
2
3
For MUL, we can rely on generic support. For SMULH and UMULH,
3
Olimex makes a series of low-cost STM32 boards. This commit introduces
4
create some trivial helpers. For PMUL, back in a21bb78e5817,
4
the minimum setup to support SMT32-H405. See [1] for details
5
we organized helper_gvec_pmul_b in preparation for this use.
6
5
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
[1] https://www.olimex.com/Products/ARM/ST/STM32-H405/
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
9
Message-id: 20210525010358.152808-3-richard.henderson@linaro.org
8
Signed-off-by: Felipe Balbi <balbi@kernel.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 20221230145733.200496-3-balbi@kernel.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
target/arm/helper.h | 10 ++++
14
docs/system/arm/stm32.rst | 1 +
13
target/arm/sve.decode | 10 ++++
15
configs/devices/arm-softmmu/default.mak | 1 +
14
target/arm/translate-sve.c | 50 ++++++++++++++++++++
16
hw/arm/olimex-stm32-h405.c | 69 +++++++++++++++++++++++++
15
target/arm/vec_helper.c | 96 ++++++++++++++++++++++++++++++++++++++
17
MAINTAINERS | 6 +++
16
4 files changed, 166 insertions(+)
18
hw/arm/Kconfig | 4 ++
19
hw/arm/meson.build | 1 +
20
6 files changed, 82 insertions(+)
21
create mode 100644 hw/arm/olimex-stm32-h405.c
17
22
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
23
diff --git a/docs/system/arm/stm32.rst b/docs/system/arm/stm32.rst
19
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.h
25
--- a/docs/system/arm/stm32.rst
21
+++ b/target/arm/helper.h
26
+++ b/docs/system/arm/stm32.rst
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(gvec_cgt0_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
27
@@ -XXX,XX +XXX,XX @@ The STM32F4 series is based on ARM Cortex-M4F core. This series is pin-to-pin
23
DEF_HELPER_FLAGS_3(gvec_cge0_b, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
28
compatible with STM32F2 series. The following machines are based on this chip :
24
DEF_HELPER_FLAGS_3(gvec_cge0_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
29
25
30
- ``netduinoplus2`` Netduino Plus 2 board with STM32F405RGT6 microcontroller
26
+DEF_HELPER_FLAGS_4(gvec_smulh_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
+- ``olimex-stm32-h405`` Olimex STM32 H405 board with STM32F405RGT6 microcontroller
27
+DEF_HELPER_FLAGS_4(gvec_smulh_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
28
+DEF_HELPER_FLAGS_4(gvec_smulh_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
There are many other STM32 series that are currently not supported by QEMU.
29
+DEF_HELPER_FLAGS_4(gvec_smulh_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
30
+
35
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
31
+DEF_HELPER_FLAGS_4(gvec_umulh_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(gvec_umulh_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_4(gvec_umulh_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_4(gvec_umulh_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
35
+
36
DEF_HELPER_FLAGS_4(gvec_sshl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
37
DEF_HELPER_FLAGS_4(gvec_sshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
38
DEF_HELPER_FLAGS_4(gvec_ushl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
39
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
40
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/sve.decode
37
--- a/configs/devices/arm-softmmu/default.mak
42
+++ b/target/arm/sve.decode
38
+++ b/configs/devices/arm-softmmu/default.mak
43
@@ -XXX,XX +XXX,XX @@ ST1_zprz 1110010 .. 00 ..... 100 ... ..... ..... \
39
@@ -XXX,XX +XXX,XX @@ CONFIG_COLLIE=y
44
@rprr_scatter_store xs=0 esz=3 scale=0
40
CONFIG_ASPEED_SOC=y
45
ST1_zprz 1110010 .. 00 ..... 110 ... ..... ..... \
41
CONFIG_NETDUINO2=y
46
@rprr_scatter_store xs=1 esz=3 scale=0
42
CONFIG_NETDUINOPLUS2=y
47
+
43
+CONFIG_OLIMEX_STM32_H405=y
48
+#### SVE2 Support
44
CONFIG_MPS2=y
49
+
45
CONFIG_RASPI=y
50
+### SVE2 Integer Multiply - Unpredicated
46
CONFIG_DIGIC=y
51
+
47
diff --git a/hw/arm/olimex-stm32-h405.c b/hw/arm/olimex-stm32-h405.c
52
+# SVE2 integer multiply vectors (unpredicated)
48
new file mode 100644
53
+MUL_zzz 00000100 .. 1 ..... 0110 00 ..... ..... @rd_rn_rm
49
index XXXXXXX..XXXXXXX
54
+SMULH_zzz 00000100 .. 1 ..... 0110 10 ..... ..... @rd_rn_rm
50
--- /dev/null
55
+UMULH_zzz 00000100 .. 1 ..... 0110 11 ..... ..... @rd_rn_rm
51
+++ b/hw/arm/olimex-stm32-h405.c
56
+PMUL_zzz 00000100 00 1 ..... 0110 01 ..... ..... @rd_rn_rm_e0
52
@@ -XXX,XX +XXX,XX @@
57
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/translate-sve.c
60
+++ b/target/arm/translate-sve.c
61
@@ -XXX,XX +XXX,XX @@ static bool trans_MOVPRFX_z(DisasContext *s, arg_rpr_esz *a)
62
{
63
return do_movz_zpz(s, a->rd, a->rn, a->pg, a->esz, false);
64
}
65
+
66
+/*
53
+/*
67
+ * SVE2 Integer Multiply - Unpredicated
54
+ * ST STM32VLDISCOVERY machine
55
+ * Olimex STM32-H405 machine
56
+ *
57
+ * Copyright (c) 2022 Felipe Balbi <balbi@kernel.org>
58
+ *
59
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
60
+ * of this software and associated documentation files (the "Software"), to deal
61
+ * in the Software without restriction, including without limitation the rights
62
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
63
+ * copies of the Software, and to permit persons to whom the Software is
64
+ * furnished to do so, subject to the following conditions:
65
+ *
66
+ * The above copyright notice and this permission notice shall be included in
67
+ * all copies or substantial portions of the Software.
68
+ *
69
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
70
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
71
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
72
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
73
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
74
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
75
+ * THE SOFTWARE.
68
+ */
76
+ */
69
+
77
+
70
+static bool trans_MUL_zzz(DisasContext *s, arg_rrr_esz *a)
78
+#include "qemu/osdep.h"
79
+#include "qapi/error.h"
80
+#include "hw/boards.h"
81
+#include "hw/qdev-properties.h"
82
+#include "hw/qdev-clock.h"
83
+#include "qemu/error-report.h"
84
+#include "hw/arm/stm32f405_soc.h"
85
+#include "hw/arm/boot.h"
86
+
87
+/* olimex-stm32-h405 implementation is derived from netduinoplus2 */
88
+
89
+/* Main SYSCLK frequency in Hz (168MHz) */
90
+#define SYSCLK_FRQ 168000000ULL
91
+
92
+static void olimex_stm32_h405_init(MachineState *machine)
71
+{
93
+{
72
+ if (!dc_isar_feature(aa64_sve2, s)) {
94
+ DeviceState *dev;
73
+ return false;
95
+ Clock *sysclk;
74
+ }
96
+
75
+ if (sve_access_check(s)) {
97
+ /* This clock doesn't need migration because it is fixed-frequency */
76
+ gen_gvec_fn_zzz(s, tcg_gen_gvec_mul, a->esz, a->rd, a->rn, a->rm);
98
+ sysclk = clock_new(OBJECT(machine), "SYSCLK");
77
+ }
99
+ clock_set_hz(sysclk, SYSCLK_FRQ);
78
+ return true;
100
+
101
+ dev = qdev_new(TYPE_STM32F405_SOC);
102
+ qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
103
+ qdev_connect_clock_in(dev, "sysclk", sysclk);
104
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
105
+
106
+ armv7m_load_kernel(ARM_CPU(first_cpu),
107
+ machine->kernel_filename,
108
+ 0, FLASH_SIZE);
79
+}
109
+}
80
+
110
+
81
+static bool do_sve2_zzz_ool(DisasContext *s, arg_rrr_esz *a,
111
+static void olimex_stm32_h405_machine_init(MachineClass *mc)
82
+ gen_helper_gvec_3 *fn)
83
+{
112
+{
84
+ if (fn == NULL || !dc_isar_feature(aa64_sve2, s)) {
113
+ mc->desc = "Olimex STM32-H405 (Cortex-M4)";
85
+ return false;
114
+ mc->init = olimex_stm32_h405_init;
86
+ }
115
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m4");
87
+ if (sve_access_check(s)) {
116
+
88
+ gen_gvec_ool_zzz(s, fn, a->rd, a->rn, a->rm, 0);
117
+ /* SRAM pre-allocated as part of the SoC instantiation */
89
+ }
118
+ mc->default_ram_size = 0;
90
+ return true;
91
+}
119
+}
92
+
120
+
93
+static bool trans_SMULH_zzz(DisasContext *s, arg_rrr_esz *a)
121
+DEFINE_MACHINE("olimex-stm32-h405", olimex_stm32_h405_machine_init)
94
+{
122
diff --git a/MAINTAINERS b/MAINTAINERS
95
+ static gen_helper_gvec_3 * const fns[4] = {
123
index XXXXXXX..XXXXXXX 100644
96
+ gen_helper_gvec_smulh_b, gen_helper_gvec_smulh_h,
124
--- a/MAINTAINERS
97
+ gen_helper_gvec_smulh_s, gen_helper_gvec_smulh_d,
125
+++ b/MAINTAINERS
98
+ };
126
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
99
+ return do_sve2_zzz_ool(s, a, fns[a->esz]);
127
S: Maintained
100
+}
128
F: hw/arm/netduinoplus2.c
129
130
+Olimex STM32 H405
131
+M: Felipe Balbi <balbi@kernel.org>
132
+L: qemu-arm@nongnu.org
133
+S: Maintained
134
+F: hw/arm/olimex-stm32-h405.c
101
+
135
+
102
+static bool trans_UMULH_zzz(DisasContext *s, arg_rrr_esz *a)
136
SmartFusion2
103
+{
137
M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
104
+ static gen_helper_gvec_3 * const fns[4] = {
138
M: Peter Maydell <peter.maydell@linaro.org>
105
+ gen_helper_gvec_umulh_b, gen_helper_gvec_umulh_h,
139
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
106
+ gen_helper_gvec_umulh_s, gen_helper_gvec_umulh_d,
140
index XXXXXXX..XXXXXXX 100644
107
+ };
141
--- a/hw/arm/Kconfig
108
+ return do_sve2_zzz_ool(s, a, fns[a->esz]);
142
+++ b/hw/arm/Kconfig
109
+}
143
@@ -XXX,XX +XXX,XX @@ config NETDUINOPLUS2
144
bool
145
select STM32F405_SOC
146
147
+config OLIMEX_STM32_H405
148
+ bool
149
+ select STM32F405_SOC
110
+
150
+
111
+static bool trans_PMUL_zzz(DisasContext *s, arg_rrr_esz *a)
151
config NSERIES
112
+{
152
bool
113
+ return do_sve2_zzz_ool(s, a, gen_helper_gvec_pmul_b);
153
select OMAP
114
+}
154
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
115
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
116
index XXXXXXX..XXXXXXX 100644
155
index XXXXXXX..XXXXXXX 100644
117
--- a/target/arm/vec_helper.c
156
--- a/hw/arm/meson.build
118
+++ b/target/arm/vec_helper.c
157
+++ b/hw/arm/meson.build
119
@@ -XXX,XX +XXX,XX @@ void HELPER(simd_tblx)(void *vd, void *vm, void *venv, uint32_t desc)
158
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_MICROBIT', if_true: files('microbit.c'))
120
clear_tail(vd, oprsz, simd_maxsz(desc));
159
arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
121
}
160
arm_ss.add(when: 'CONFIG_NETDUINO2', if_true: files('netduino2.c'))
122
#endif
161
arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c'))
123
+
162
+arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c'))
124
+/*
163
arm_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx.c', 'npcm7xx_boards.c'))
125
+ * NxN -> N highpart multiply
164
arm_ss.add(when: 'CONFIG_NSERIES', if_true: files('nseries.c'))
126
+ *
165
arm_ss.add(when: 'CONFIG_SX1', if_true: files('omap_sx1.c'))
127
+ * TODO: expose this as a generic vector operation.
128
+ */
129
+
130
+void HELPER(gvec_smulh_b)(void *vd, void *vn, void *vm, uint32_t desc)
131
+{
132
+ intptr_t i, opr_sz = simd_oprsz(desc);
133
+ int8_t *d = vd, *n = vn, *m = vm;
134
+
135
+ for (i = 0; i < opr_sz; ++i) {
136
+ d[i] = ((int32_t)n[i] * m[i]) >> 8;
137
+ }
138
+ clear_tail(d, opr_sz, simd_maxsz(desc));
139
+}
140
+
141
+void HELPER(gvec_smulh_h)(void *vd, void *vn, void *vm, uint32_t desc)
142
+{
143
+ intptr_t i, opr_sz = simd_oprsz(desc);
144
+ int16_t *d = vd, *n = vn, *m = vm;
145
+
146
+ for (i = 0; i < opr_sz / 2; ++i) {
147
+ d[i] = ((int32_t)n[i] * m[i]) >> 16;
148
+ }
149
+ clear_tail(d, opr_sz, simd_maxsz(desc));
150
+}
151
+
152
+void HELPER(gvec_smulh_s)(void *vd, void *vn, void *vm, uint32_t desc)
153
+{
154
+ intptr_t i, opr_sz = simd_oprsz(desc);
155
+ int32_t *d = vd, *n = vn, *m = vm;
156
+
157
+ for (i = 0; i < opr_sz / 4; ++i) {
158
+ d[i] = ((int64_t)n[i] * m[i]) >> 32;
159
+ }
160
+ clear_tail(d, opr_sz, simd_maxsz(desc));
161
+}
162
+
163
+void HELPER(gvec_smulh_d)(void *vd, void *vn, void *vm, uint32_t desc)
164
+{
165
+ intptr_t i, opr_sz = simd_oprsz(desc);
166
+ uint64_t *d = vd, *n = vn, *m = vm;
167
+ uint64_t discard;
168
+
169
+ for (i = 0; i < opr_sz / 8; ++i) {
170
+ muls64(&discard, &d[i], n[i], m[i]);
171
+ }
172
+ clear_tail(d, opr_sz, simd_maxsz(desc));
173
+}
174
+
175
+void HELPER(gvec_umulh_b)(void *vd, void *vn, void *vm, uint32_t desc)
176
+{
177
+ intptr_t i, opr_sz = simd_oprsz(desc);
178
+ uint8_t *d = vd, *n = vn, *m = vm;
179
+
180
+ for (i = 0; i < opr_sz; ++i) {
181
+ d[i] = ((uint32_t)n[i] * m[i]) >> 8;
182
+ }
183
+ clear_tail(d, opr_sz, simd_maxsz(desc));
184
+}
185
+
186
+void HELPER(gvec_umulh_h)(void *vd, void *vn, void *vm, uint32_t desc)
187
+{
188
+ intptr_t i, opr_sz = simd_oprsz(desc);
189
+ uint16_t *d = vd, *n = vn, *m = vm;
190
+
191
+ for (i = 0; i < opr_sz / 2; ++i) {
192
+ d[i] = ((uint32_t)n[i] * m[i]) >> 16;
193
+ }
194
+ clear_tail(d, opr_sz, simd_maxsz(desc));
195
+}
196
+
197
+void HELPER(gvec_umulh_s)(void *vd, void *vn, void *vm, uint32_t desc)
198
+{
199
+ intptr_t i, opr_sz = simd_oprsz(desc);
200
+ uint32_t *d = vd, *n = vn, *m = vm;
201
+
202
+ for (i = 0; i < opr_sz / 4; ++i) {
203
+ d[i] = ((uint64_t)n[i] * m[i]) >> 32;
204
+ }
205
+ clear_tail(d, opr_sz, simd_maxsz(desc));
206
+}
207
+
208
+void HELPER(gvec_umulh_d)(void *vd, void *vn, void *vm, uint32_t desc)
209
+{
210
+ intptr_t i, opr_sz = simd_oprsz(desc);
211
+ uint64_t *d = vd, *n = vn, *m = vm;
212
+ uint64_t discard;
213
+
214
+ for (i = 0; i < opr_sz / 8; ++i) {
215
+ mulu64(&discard, &d[i], n[i], m[i]);
216
+ }
217
+ clear_tail(d, opr_sz, simd_maxsz(desc));
218
+}
219
--
166
--
220
2.20.1
167
2.34.1
221
168
222
169
diff view generated by jsdifflib
1
From: Rebecca Cran <rebecca@nuviainc.com>
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
2
2
3
ARMv8.4 adds the mandatory FEAT_TLBIRANGE. It provides TLBI
3
During SPL boot several Clock Controller Module (CCM) registers are
4
maintenance instructions that apply to a range of input addresses.
4
read, most important are PLL and Tuning, as well as divisor registers.
5
5
6
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
6
This patch adds these registers and initializes reset values from user's
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
guide.
8
Message-id: 20210512182337.18563-2-rebecca@nuviainc.com
8
9
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
10
11
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
12
Message-id: 20221226220303.14420-2-strahinja.p.jankovic@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
target/arm/cpu.h | 5 +
15
include/hw/arm/allwinner-a10.h | 2 +
12
target/arm/helper.c | 281 ++++++++++++++++++++++++++++++++++++++++++++
16
include/hw/misc/allwinner-a10-ccm.h | 67 +++++++++
13
2 files changed, 286 insertions(+)
17
hw/arm/allwinner-a10.c | 7 +
18
hw/misc/allwinner-a10-ccm.c | 224 ++++++++++++++++++++++++++++
19
hw/arm/Kconfig | 1 +
20
hw/misc/Kconfig | 3 +
21
hw/misc/meson.build | 1 +
22
7 files changed, 305 insertions(+)
23
create mode 100644 include/hw/misc/allwinner-a10-ccm.h
24
create mode 100644 hw/misc/allwinner-a10-ccm.c
14
25
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
16
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
28
--- a/include/hw/arm/allwinner-a10.h
18
+++ b/target/arm/cpu.h
29
+++ b/include/hw/arm/allwinner-a10.h
19
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_pauth_arch(const ARMISARegisters *id)
30
@@ -XXX,XX +XXX,XX @@
20
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) != 0;
31
#include "hw/usb/hcd-ohci.h"
21
}
32
#include "hw/usb/hcd-ehci.h"
22
33
#include "hw/rtc/allwinner-rtc.h"
23
+static inline bool isar_feature_aa64_tlbirange(const ARMISARegisters *id)
34
+#include "hw/misc/allwinner-a10-ccm.h"
24
+{
35
25
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) == 2;
36
#include "target/arm/cpu.h"
26
+}
37
#include "qom/object.h"
27
+
38
@@ -XXX,XX +XXX,XX @@ struct AwA10State {
28
static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
39
/*< public >*/
29
{
40
30
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
41
ARMCPU cpu;
31
diff --git a/target/arm/helper.c b/target/arm/helper.c
42
+ AwA10ClockCtlState ccm;
43
AwA10PITState timer;
44
AwA10PICState intc;
45
AwEmacState emac;
46
diff --git a/include/hw/misc/allwinner-a10-ccm.h b/include/hw/misc/allwinner-a10-ccm.h
47
new file mode 100644
48
index XXXXXXX..XXXXXXX
49
--- /dev/null
50
+++ b/include/hw/misc/allwinner-a10-ccm.h
51
@@ -XXX,XX +XXX,XX @@
52
+/*
53
+ * Allwinner A10 Clock Control Module emulation
54
+ *
55
+ * Copyright (C) 2022 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
56
+ *
57
+ * This file is derived from Allwinner H3 CCU,
58
+ * by Niek Linnenbank.
59
+ *
60
+ * This program is free software: you can redistribute it and/or modify
61
+ * it under the terms of the GNU General Public License as published by
62
+ * the Free Software Foundation, either version 2 of the License, or
63
+ * (at your option) any later version.
64
+ *
65
+ * This program is distributed in the hope that it will be useful,
66
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
67
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
68
+ * GNU General Public License for more details.
69
+ *
70
+ * You should have received a copy of the GNU General Public License
71
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
72
+ */
73
+
74
+#ifndef HW_MISC_ALLWINNER_A10_CCM_H
75
+#define HW_MISC_ALLWINNER_A10_CCM_H
76
+
77
+#include "qom/object.h"
78
+#include "hw/sysbus.h"
79
+
80
+/**
81
+ * @name Constants
82
+ * @{
83
+ */
84
+
85
+/** Size of register I/O address space used by CCM device */
86
+#define AW_A10_CCM_IOSIZE (0x400)
87
+
88
+/** Total number of known registers */
89
+#define AW_A10_CCM_REGS_NUM (AW_A10_CCM_IOSIZE / sizeof(uint32_t))
90
+
91
+/** @} */
92
+
93
+/**
94
+ * @name Object model
95
+ * @{
96
+ */
97
+
98
+#define TYPE_AW_A10_CCM "allwinner-a10-ccm"
99
+OBJECT_DECLARE_SIMPLE_TYPE(AwA10ClockCtlState, AW_A10_CCM)
100
+
101
+/** @} */
102
+
103
+/**
104
+ * Allwinner A10 CCM object instance state.
105
+ */
106
+struct AwA10ClockCtlState {
107
+ /*< private >*/
108
+ SysBusDevice parent_obj;
109
+ /*< public >*/
110
+
111
+ /** Maps I/O registers in physical memory */
112
+ MemoryRegion iomem;
113
+
114
+ /** Array of hardware registers */
115
+ uint32_t regs[AW_A10_CCM_REGS_NUM];
116
+};
117
+
118
+#endif /* HW_MISC_ALLWINNER_H3_CCU_H */
119
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
32
index XXXXXXX..XXXXXXX 100644
120
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/helper.c
121
--- a/hw/arm/allwinner-a10.c
34
+++ b/target/arm/helper.c
122
+++ b/hw/arm/allwinner-a10.c
35
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
123
@@ -XXX,XX +XXX,XX @@
36
ARMMMUIdxBit_SE3, bits);
124
#include "hw/usb/hcd-ohci.h"
37
}
125
38
126
#define AW_A10_MMC0_BASE 0x01c0f000
39
+#ifdef TARGET_AARCH64
127
+#define AW_A10_CCM_BASE 0x01c20000
40
+static uint64_t tlbi_aa64_range_get_length(CPUARMState *env,
128
#define AW_A10_PIC_REG_BASE 0x01c20400
41
+ uint64_t value)
129
#define AW_A10_PIT_REG_BASE 0x01c20c00
42
+{
130
#define AW_A10_UART0_REG_BASE 0x01c28000
43
+ unsigned int page_shift;
131
@@ -XXX,XX +XXX,XX @@ static void aw_a10_init(Object *obj)
44
+ unsigned int page_size_granule;
132
45
+ uint64_t num;
133
object_initialize_child(obj, "timer", &s->timer, TYPE_AW_A10_PIT);
46
+ uint64_t scale;
134
47
+ uint64_t exponent;
135
+ object_initialize_child(obj, "ccm", &s->ccm, TYPE_AW_A10_CCM);
48
+ uint64_t length;
136
+
49
+
137
object_initialize_child(obj, "emac", &s->emac, TYPE_AW_EMAC);
50
+ num = extract64(value, 39, 4);
138
51
+ scale = extract64(value, 44, 2);
139
object_initialize_child(obj, "sata", &s->sata, TYPE_ALLWINNER_AHCI);
52
+ page_size_granule = extract64(value, 46, 2);
140
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
53
+
141
memory_region_add_subregion(get_system_memory(), 0x00000000, &s->sram_a);
54
+ page_shift = page_size_granule * 2 + 12;
142
create_unimplemented_device("a10-sram-ctrl", 0x01c00000, 4 * KiB);
55
+
143
56
+ if (page_size_granule == 0) {
144
+ /* Clock Control Module */
57
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
145
+ sysbus_realize(SYS_BUS_DEVICE(&s->ccm), &error_fatal);
58
+ page_size_granule);
146
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, AW_A10_CCM_BASE);
147
+
148
/* FIXME use qdev NIC properties instead of nd_table[] */
149
if (nd_table[0].used) {
150
qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC);
151
diff --git a/hw/misc/allwinner-a10-ccm.c b/hw/misc/allwinner-a10-ccm.c
152
new file mode 100644
153
index XXXXXXX..XXXXXXX
154
--- /dev/null
155
+++ b/hw/misc/allwinner-a10-ccm.c
156
@@ -XXX,XX +XXX,XX @@
157
+/*
158
+ * Allwinner A10 Clock Control Module emulation
159
+ *
160
+ * Copyright (C) 2022 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
161
+ *
162
+ * This file is derived from Allwinner H3 CCU,
163
+ * by Niek Linnenbank.
164
+ *
165
+ * This program is free software: you can redistribute it and/or modify
166
+ * it under the terms of the GNU General Public License as published by
167
+ * the Free Software Foundation, either version 2 of the License, or
168
+ * (at your option) any later version.
169
+ *
170
+ * This program is distributed in the hope that it will be useful,
171
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
172
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
173
+ * GNU General Public License for more details.
174
+ *
175
+ * You should have received a copy of the GNU General Public License
176
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
177
+ */
178
+
179
+#include "qemu/osdep.h"
180
+#include "qemu/units.h"
181
+#include "hw/sysbus.h"
182
+#include "migration/vmstate.h"
183
+#include "qemu/log.h"
184
+#include "qemu/module.h"
185
+#include "hw/misc/allwinner-a10-ccm.h"
186
+
187
+/* CCM register offsets */
188
+enum {
189
+ REG_PLL1_CFG = 0x0000, /* PLL1 Control */
190
+ REG_PLL1_TUN = 0x0004, /* PLL1 Tuning */
191
+ REG_PLL2_CFG = 0x0008, /* PLL2 Control */
192
+ REG_PLL2_TUN = 0x000C, /* PLL2 Tuning */
193
+ REG_PLL3_CFG = 0x0010, /* PLL3 Control */
194
+ REG_PLL4_CFG = 0x0018, /* PLL4 Control */
195
+ REG_PLL5_CFG = 0x0020, /* PLL5 Control */
196
+ REG_PLL5_TUN = 0x0024, /* PLL5 Tuning */
197
+ REG_PLL6_CFG = 0x0028, /* PLL6 Control */
198
+ REG_PLL6_TUN = 0x002C, /* PLL6 Tuning */
199
+ REG_PLL7_CFG = 0x0030, /* PLL7 Control */
200
+ REG_PLL1_TUN2 = 0x0038, /* PLL1 Tuning2 */
201
+ REG_PLL5_TUN2 = 0x003C, /* PLL5 Tuning2 */
202
+ REG_PLL8_CFG = 0x0040, /* PLL8 Control */
203
+ REG_OSC24M_CFG = 0x0050, /* OSC24M Control */
204
+ REG_CPU_AHB_APB0_CFG = 0x0054, /* CPU, AHB and APB0 Divide Ratio */
205
+};
206
+
207
+#define REG_INDEX(offset) (offset / sizeof(uint32_t))
208
+
209
+/* CCM register reset values */
210
+enum {
211
+ REG_PLL1_CFG_RST = 0x21005000,
212
+ REG_PLL1_TUN_RST = 0x0A101000,
213
+ REG_PLL2_CFG_RST = 0x08100010,
214
+ REG_PLL2_TUN_RST = 0x00000000,
215
+ REG_PLL3_CFG_RST = 0x0010D063,
216
+ REG_PLL4_CFG_RST = 0x21009911,
217
+ REG_PLL5_CFG_RST = 0x11049280,
218
+ REG_PLL5_TUN_RST = 0x14888000,
219
+ REG_PLL6_CFG_RST = 0x21009911,
220
+ REG_PLL6_TUN_RST = 0x00000000,
221
+ REG_PLL7_CFG_RST = 0x0010D063,
222
+ REG_PLL1_TUN2_RST = 0x00000000,
223
+ REG_PLL5_TUN2_RST = 0x00000000,
224
+ REG_PLL8_CFG_RST = 0x21009911,
225
+ REG_OSC24M_CFG_RST = 0x00138013,
226
+ REG_CPU_AHB_APB0_CFG_RST = 0x00010010,
227
+};
228
+
229
+static uint64_t allwinner_a10_ccm_read(void *opaque, hwaddr offset,
230
+ unsigned size)
231
+{
232
+ const AwA10ClockCtlState *s = AW_A10_CCM(opaque);
233
+ const uint32_t idx = REG_INDEX(offset);
234
+
235
+ switch (offset) {
236
+ case REG_PLL1_CFG:
237
+ case REG_PLL1_TUN:
238
+ case REG_PLL2_CFG:
239
+ case REG_PLL2_TUN:
240
+ case REG_PLL3_CFG:
241
+ case REG_PLL4_CFG:
242
+ case REG_PLL5_CFG:
243
+ case REG_PLL5_TUN:
244
+ case REG_PLL6_CFG:
245
+ case REG_PLL6_TUN:
246
+ case REG_PLL7_CFG:
247
+ case REG_PLL1_TUN2:
248
+ case REG_PLL5_TUN2:
249
+ case REG_PLL8_CFG:
250
+ case REG_OSC24M_CFG:
251
+ case REG_CPU_AHB_APB0_CFG:
252
+ break;
253
+ case 0x158 ... AW_A10_CCM_IOSIZE:
254
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
255
+ __func__, (uint32_t)offset);
256
+ return 0;
257
+ default:
258
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented read offset 0x%04x\n",
259
+ __func__, (uint32_t)offset);
59
+ return 0;
260
+ return 0;
60
+ }
261
+ }
61
+
262
+
62
+ exponent = (5 * scale) + 1;
263
+ return s->regs[idx];
63
+ length = (num + 1) << (exponent + page_shift);
264
+}
64
+
265
+
65
+ return length;
266
+static void allwinner_a10_ccm_write(void *opaque, hwaddr offset,
66
+}
267
+ uint64_t val, unsigned size)
67
+
268
+{
68
+static uint64_t tlbi_aa64_range_get_base(CPUARMState *env, uint64_t value,
269
+ AwA10ClockCtlState *s = AW_A10_CCM(opaque);
69
+ bool two_ranges)
270
+ const uint32_t idx = REG_INDEX(offset);
70
+{
271
+
71
+ /* TODO: ARMv8.7 FEAT_LPA2 */
272
+ switch (offset) {
72
+ uint64_t pageaddr;
273
+ case REG_PLL1_CFG:
73
+
274
+ case REG_PLL1_TUN:
74
+ if (two_ranges) {
275
+ case REG_PLL2_CFG:
75
+ pageaddr = sextract64(value, 0, 37) << TARGET_PAGE_BITS;
276
+ case REG_PLL2_TUN:
76
+ } else {
277
+ case REG_PLL3_CFG:
77
+ pageaddr = extract64(value, 0, 37) << TARGET_PAGE_BITS;
278
+ case REG_PLL4_CFG:
279
+ case REG_PLL5_CFG:
280
+ case REG_PLL5_TUN:
281
+ case REG_PLL6_CFG:
282
+ case REG_PLL6_TUN:
283
+ case REG_PLL7_CFG:
284
+ case REG_PLL1_TUN2:
285
+ case REG_PLL5_TUN2:
286
+ case REG_PLL8_CFG:
287
+ case REG_OSC24M_CFG:
288
+ case REG_CPU_AHB_APB0_CFG:
289
+ break;
290
+ case 0x158 ... AW_A10_CCM_IOSIZE:
291
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
292
+ __func__, (uint32_t)offset);
293
+ break;
294
+ default:
295
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented write offset 0x%04x\n",
296
+ __func__, (uint32_t)offset);
297
+ break;
78
+ }
298
+ }
79
+
299
+
80
+ return pageaddr;
300
+ s->regs[idx] = (uint32_t) val;
81
+}
301
+}
82
+
302
+
83
+static void do_rvae_write(CPUARMState *env, uint64_t value,
303
+static const MemoryRegionOps allwinner_a10_ccm_ops = {
84
+ int idxmap, bool synced)
304
+ .read = allwinner_a10_ccm_read,
85
+{
305
+ .write = allwinner_a10_ccm_write,
86
+ ARMMMUIdx one_idx = ARM_MMU_IDX_A | ctz32(idxmap);
306
+ .endianness = DEVICE_NATIVE_ENDIAN,
87
+ bool two_ranges = regime_has_2_ranges(one_idx);
307
+ .valid = {
88
+ uint64_t baseaddr, length;
308
+ .min_access_size = 4,
89
+ int bits;
309
+ .max_access_size = 4,
90
+
310
+ },
91
+ baseaddr = tlbi_aa64_range_get_base(env, value, two_ranges);
311
+ .impl.min_access_size = 4,
92
+ length = tlbi_aa64_range_get_length(env, value);
312
+};
93
+ bits = tlbbits_for_regime(env, one_idx, baseaddr);
313
+
94
+
314
+static void allwinner_a10_ccm_reset_enter(Object *obj, ResetType type)
95
+ if (synced) {
315
+{
96
+ tlb_flush_range_by_mmuidx_all_cpus_synced(env_cpu(env),
316
+ AwA10ClockCtlState *s = AW_A10_CCM(obj);
97
+ baseaddr,
317
+
98
+ length,
318
+ /* Set default values for registers */
99
+ idxmap,
319
+ s->regs[REG_INDEX(REG_PLL1_CFG)] = REG_PLL1_CFG_RST;
100
+ bits);
320
+ s->regs[REG_INDEX(REG_PLL1_TUN)] = REG_PLL1_TUN_RST;
101
+ } else {
321
+ s->regs[REG_INDEX(REG_PLL2_CFG)] = REG_PLL2_CFG_RST;
102
+ tlb_flush_range_by_mmuidx(env_cpu(env), baseaddr,
322
+ s->regs[REG_INDEX(REG_PLL2_TUN)] = REG_PLL2_TUN_RST;
103
+ length, idxmap, bits);
323
+ s->regs[REG_INDEX(REG_PLL3_CFG)] = REG_PLL3_CFG_RST;
324
+ s->regs[REG_INDEX(REG_PLL4_CFG)] = REG_PLL4_CFG_RST;
325
+ s->regs[REG_INDEX(REG_PLL5_CFG)] = REG_PLL5_CFG_RST;
326
+ s->regs[REG_INDEX(REG_PLL5_TUN)] = REG_PLL5_TUN_RST;
327
+ s->regs[REG_INDEX(REG_PLL6_CFG)] = REG_PLL6_CFG_RST;
328
+ s->regs[REG_INDEX(REG_PLL6_TUN)] = REG_PLL6_TUN_RST;
329
+ s->regs[REG_INDEX(REG_PLL7_CFG)] = REG_PLL7_CFG_RST;
330
+ s->regs[REG_INDEX(REG_PLL1_TUN2)] = REG_PLL1_TUN2_RST;
331
+ s->regs[REG_INDEX(REG_PLL5_TUN2)] = REG_PLL5_TUN2_RST;
332
+ s->regs[REG_INDEX(REG_PLL8_CFG)] = REG_PLL8_CFG_RST;
333
+ s->regs[REG_INDEX(REG_OSC24M_CFG)] = REG_OSC24M_CFG_RST;
334
+ s->regs[REG_INDEX(REG_CPU_AHB_APB0_CFG)] = REG_CPU_AHB_APB0_CFG_RST;
335
+}
336
+
337
+static void allwinner_a10_ccm_init(Object *obj)
338
+{
339
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
340
+ AwA10ClockCtlState *s = AW_A10_CCM(obj);
341
+
342
+ /* Memory mapping */
343
+ memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_a10_ccm_ops, s,
344
+ TYPE_AW_A10_CCM, AW_A10_CCM_IOSIZE);
345
+ sysbus_init_mmio(sbd, &s->iomem);
346
+}
347
+
348
+static const VMStateDescription allwinner_a10_ccm_vmstate = {
349
+ .name = "allwinner-a10-ccm",
350
+ .version_id = 1,
351
+ .minimum_version_id = 1,
352
+ .fields = (VMStateField[]) {
353
+ VMSTATE_UINT32_ARRAY(regs, AwA10ClockCtlState, AW_A10_CCM_REGS_NUM),
354
+ VMSTATE_END_OF_LIST()
104
+ }
355
+ }
105
+}
356
+};
106
+
357
+
107
+static void tlbi_aa64_rvae1_write(CPUARMState *env,
358
+static void allwinner_a10_ccm_class_init(ObjectClass *klass, void *data)
108
+ const ARMCPRegInfo *ri,
359
+{
109
+ uint64_t value)
360
+ DeviceClass *dc = DEVICE_CLASS(klass);
110
+{
361
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
111
+ /*
362
+
112
+ * Invalidate by VA range, EL1&0.
363
+ rc->phases.enter = allwinner_a10_ccm_reset_enter;
113
+ * Currently handles all of RVAE1, RVAAE1, RVAALE1 and RVALE1,
364
+ dc->vmsd = &allwinner_a10_ccm_vmstate;
114
+ * since we don't support flush-for-specific-ASID-only or
365
+}
115
+ * flush-last-level-only.
366
+
116
+ */
367
+static const TypeInfo allwinner_a10_ccm_info = {
117
+
368
+ .name = TYPE_AW_A10_CCM,
118
+ do_rvae_write(env, value, vae1_tlbmask(env),
369
+ .parent = TYPE_SYS_BUS_DEVICE,
119
+ tlb_force_broadcast(env));
370
+ .instance_init = allwinner_a10_ccm_init,
120
+}
371
+ .instance_size = sizeof(AwA10ClockCtlState),
121
+
372
+ .class_init = allwinner_a10_ccm_class_init,
122
+static void tlbi_aa64_rvae1is_write(CPUARMState *env,
373
+};
123
+ const ARMCPRegInfo *ri,
374
+
124
+ uint64_t value)
375
+static void allwinner_a10_ccm_register(void)
125
+{
376
+{
126
+ /*
377
+ type_register_static(&allwinner_a10_ccm_info);
127
+ * Invalidate by VA range, Inner/Outer Shareable EL1&0.
378
+}
128
+ * Currently handles all of RVAE1IS, RVAE1OS, RVAAE1IS, RVAAE1OS,
379
+
129
+ * RVAALE1IS, RVAALE1OS, RVALE1IS and RVALE1OS, since we don't support
380
+type_init(allwinner_a10_ccm_register)
130
+ * flush-for-specific-ASID-only, flush-last-level-only or inner/outer
381
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
131
+ * shareable specific flushes.
382
index XXXXXXX..XXXXXXX 100644
132
+ */
383
--- a/hw/arm/Kconfig
133
+
384
+++ b/hw/arm/Kconfig
134
+ do_rvae_write(env, value, vae1_tlbmask(env), true);
385
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_A10
135
+}
386
select AHCI
136
+
387
select ALLWINNER_A10_PIT
137
+static int vae2_tlbmask(CPUARMState *env)
388
select ALLWINNER_A10_PIC
138
+{
389
+ select ALLWINNER_A10_CCM
139
+ return (arm_is_secure_below_el3(env)
390
select ALLWINNER_EMAC
140
+ ? ARMMMUIdxBit_SE2 : ARMMMUIdxBit_E2);
391
select SERIAL
141
+}
392
select UNIMP
142
+
393
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
143
+static void tlbi_aa64_rvae2_write(CPUARMState *env,
394
index XXXXXXX..XXXXXXX 100644
144
+ const ARMCPRegInfo *ri,
395
--- a/hw/misc/Kconfig
145
+ uint64_t value)
396
+++ b/hw/misc/Kconfig
146
+{
397
@@ -XXX,XX +XXX,XX @@ config VIRT_CTRL
147
+ /*
398
config LASI
148
+ * Invalidate by VA range, EL2.
399
bool
149
+ * Currently handles all of RVAE2 and RVALE2,
400
150
+ * since we don't support flush-for-specific-ASID-only or
401
+config ALLWINNER_A10_CCM
151
+ * flush-last-level-only.
402
+ bool
152
+ */
403
+
153
+
404
source macio/Kconfig
154
+ do_rvae_write(env, value, vae2_tlbmask(env),
405
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
155
+ tlb_force_broadcast(env));
406
index XXXXXXX..XXXXXXX 100644
156
+
407
--- a/hw/misc/meson.build
157
+
408
+++ b/hw/misc/meson.build
158
+}
409
@@ -XXX,XX +XXX,XX @@ subdir('macio')
159
+
410
160
+static void tlbi_aa64_rvae2is_write(CPUARMState *env,
411
softmmu_ss.add(when: 'CONFIG_IVSHMEM_DEVICE', if_true: files('ivshmem.c'))
161
+ const ARMCPRegInfo *ri,
412
162
+ uint64_t value)
413
+softmmu_ss.add(when: 'CONFIG_ALLWINNER_A10_CCM', if_true: files('allwinner-a10-ccm.c'))
163
+{
414
softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-ccu.c'))
164
+ /*
415
specific_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-cpucfg.c'))
165
+ * Invalidate by VA range, Inner/Outer Shareable, EL2.
416
softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-dramc.c'))
166
+ * Currently handles all of RVAE2IS, RVAE2OS, RVALE2IS and RVALE2OS,
167
+ * since we don't support flush-for-specific-ASID-only,
168
+ * flush-last-level-only or inner/outer shareable specific flushes.
169
+ */
170
+
171
+ do_rvae_write(env, value, vae2_tlbmask(env), true);
172
+
173
+}
174
+
175
+static void tlbi_aa64_rvae3_write(CPUARMState *env,
176
+ const ARMCPRegInfo *ri,
177
+ uint64_t value)
178
+{
179
+ /*
180
+ * Invalidate by VA range, EL3.
181
+ * Currently handles all of RVAE3 and RVALE3,
182
+ * since we don't support flush-for-specific-ASID-only or
183
+ * flush-last-level-only.
184
+ */
185
+
186
+ do_rvae_write(env, value, ARMMMUIdxBit_SE3,
187
+ tlb_force_broadcast(env));
188
+}
189
+
190
+static void tlbi_aa64_rvae3is_write(CPUARMState *env,
191
+ const ARMCPRegInfo *ri,
192
+ uint64_t value)
193
+{
194
+ /*
195
+ * Invalidate by VA range, EL3, Inner/Outer Shareable.
196
+ * Currently handles all of RVAE3IS, RVAE3OS, RVALE3IS and RVALE3OS,
197
+ * since we don't support flush-for-specific-ASID-only,
198
+ * flush-last-level-only or inner/outer specific flushes.
199
+ */
200
+
201
+ do_rvae_write(env, value, ARMMMUIdxBit_SE3, true);
202
+}
203
+#endif
204
+
205
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
206
bool isread)
207
{
208
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pauth_reginfo[] = {
209
REGINFO_SENTINEL
210
};
211
212
+static const ARMCPRegInfo tlbirange_reginfo[] = {
213
+ { .name = "TLBI_RVAE1IS", .state = ARM_CP_STATE_AA64,
214
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 1,
215
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
216
+ .writefn = tlbi_aa64_rvae1is_write },
217
+ { .name = "TLBI_RVAAE1IS", .state = ARM_CP_STATE_AA64,
218
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 3,
219
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
220
+ .writefn = tlbi_aa64_rvae1is_write },
221
+ { .name = "TLBI_RVALE1IS", .state = ARM_CP_STATE_AA64,
222
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 5,
223
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
224
+ .writefn = tlbi_aa64_rvae1is_write },
225
+ { .name = "TLBI_RVAALE1IS", .state = ARM_CP_STATE_AA64,
226
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 2, .opc2 = 7,
227
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
228
+ .writefn = tlbi_aa64_rvae1is_write },
229
+ { .name = "TLBI_RVAE1OS", .state = ARM_CP_STATE_AA64,
230
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 1,
231
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
232
+ .writefn = tlbi_aa64_rvae1is_write },
233
+ { .name = "TLBI_RVAAE1OS", .state = ARM_CP_STATE_AA64,
234
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 3,
235
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
236
+ .writefn = tlbi_aa64_rvae1is_write },
237
+ { .name = "TLBI_RVALE1OS", .state = ARM_CP_STATE_AA64,
238
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 5,
239
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
240
+ .writefn = tlbi_aa64_rvae1is_write },
241
+ { .name = "TLBI_RVAALE1OS", .state = ARM_CP_STATE_AA64,
242
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 5, .opc2 = 7,
243
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
244
+ .writefn = tlbi_aa64_rvae1is_write },
245
+ { .name = "TLBI_RVAE1", .state = ARM_CP_STATE_AA64,
246
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 1,
247
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
248
+ .writefn = tlbi_aa64_rvae1_write },
249
+ { .name = "TLBI_RVAAE1", .state = ARM_CP_STATE_AA64,
250
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 3,
251
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
252
+ .writefn = tlbi_aa64_rvae1_write },
253
+ { .name = "TLBI_RVALE1", .state = ARM_CP_STATE_AA64,
254
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 5,
255
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
256
+ .writefn = tlbi_aa64_rvae1_write },
257
+ { .name = "TLBI_RVAALE1", .state = ARM_CP_STATE_AA64,
258
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 6, .opc2 = 7,
259
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
260
+ .writefn = tlbi_aa64_rvae1_write },
261
+ { .name = "TLBI_RIPAS2E1IS", .state = ARM_CP_STATE_AA64,
262
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 2,
263
+ .access = PL2_W, .type = ARM_CP_NOP },
264
+ { .name = "TLBI_RIPAS2LE1IS", .state = ARM_CP_STATE_AA64,
265
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 6,
266
+ .access = PL2_W, .type = ARM_CP_NOP },
267
+ { .name = "TLBI_RVAE2IS", .state = ARM_CP_STATE_AA64,
268
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 1,
269
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
270
+ .writefn = tlbi_aa64_rvae2is_write },
271
+ { .name = "TLBI_RVALE2IS", .state = ARM_CP_STATE_AA64,
272
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 2, .opc2 = 5,
273
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
274
+ .writefn = tlbi_aa64_rvae2is_write },
275
+ { .name = "TLBI_RIPAS2E1", .state = ARM_CP_STATE_AA64,
276
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 2,
277
+ .access = PL2_W, .type = ARM_CP_NOP },
278
+ { .name = "TLBI_RIPAS2LE1", .state = ARM_CP_STATE_AA64,
279
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 6,
280
+ .access = PL2_W, .type = ARM_CP_NOP },
281
+ { .name = "TLBI_RVAE2OS", .state = ARM_CP_STATE_AA64,
282
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 1,
283
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
284
+ .writefn = tlbi_aa64_rvae2is_write },
285
+ { .name = "TLBI_RVALE2OS", .state = ARM_CP_STATE_AA64,
286
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 5, .opc2 = 5,
287
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
288
+ .writefn = tlbi_aa64_rvae2is_write },
289
+ { .name = "TLBI_RVAE2", .state = ARM_CP_STATE_AA64,
290
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 6, .opc2 = 1,
291
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
292
+ .writefn = tlbi_aa64_rvae2_write },
293
+ { .name = "TLBI_RVALE2", .state = ARM_CP_STATE_AA64,
294
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 6, .opc2 = 5,
295
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
296
+ .writefn = tlbi_aa64_rvae2_write },
297
+ { .name = "TLBI_RVAE3IS", .state = ARM_CP_STATE_AA64,
298
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 2, .opc2 = 1,
299
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
300
+ .writefn = tlbi_aa64_rvae3is_write },
301
+ { .name = "TLBI_RVALE3IS", .state = ARM_CP_STATE_AA64,
302
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 2, .opc2 = 5,
303
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
304
+ .writefn = tlbi_aa64_rvae3is_write },
305
+ { .name = "TLBI_RVAE3OS", .state = ARM_CP_STATE_AA64,
306
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 5, .opc2 = 1,
307
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
308
+ .writefn = tlbi_aa64_rvae3is_write },
309
+ { .name = "TLBI_RVALE3OS", .state = ARM_CP_STATE_AA64,
310
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 5, .opc2 = 5,
311
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
312
+ .writefn = tlbi_aa64_rvae3is_write },
313
+ { .name = "TLBI_RVAE3", .state = ARM_CP_STATE_AA64,
314
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 6, .opc2 = 1,
315
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
316
+ .writefn = tlbi_aa64_rvae3_write },
317
+ { .name = "TLBI_RVALE3", .state = ARM_CP_STATE_AA64,
318
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 6, .opc2 = 5,
319
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
320
+ .writefn = tlbi_aa64_rvae3_write },
321
+ REGINFO_SENTINEL
322
+};
323
+
324
static uint64_t rndr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
325
{
326
Error *err = NULL;
327
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
328
if (cpu_isar_feature(aa64_rndr, cpu)) {
329
define_arm_cp_regs(cpu, rndr_reginfo);
330
}
331
+ if (cpu_isar_feature(aa64_tlbirange, cpu)) {
332
+ define_arm_cp_regs(cpu, tlbirange_reginfo);
333
+ }
334
#ifndef CONFIG_USER_ONLY
335
/* Data Cache clean instructions up to PoP */
336
if (cpu_isar_feature(aa64_dcpop, cpu)) {
337
--
417
--
338
2.20.1
418
2.34.1
339
340
diff view generated by jsdifflib
1
From: Stephen Long <steplong@quicinc.com>
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
During SPL boot several DRAM Controller registers are used. Most
4
Signed-off-by: Stephen Long <steplong@quicinc.com>
4
important registers are those related to DRAM initialization and
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
calibration, where SPL initiates process and waits until certain bit is
6
Message-id: 20210525010358.152808-72-richard.henderson@linaro.org
6
set/cleared.
7
Message-Id: <20200428144352.9275-1-steplong@quicinc.com>
7
8
[rth: rearrange the macros a little and rebase]
8
This patch adds these registers, initializes reset values from user's
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
guide and updates state of registers as SPL expects it.
10
11
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
12
13
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
14
Message-id: 20221226220303.14420-3-strahinja.p.jankovic@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
16
---
12
target/arm/helper-sve.h | 10 +++++
17
include/hw/arm/allwinner-a10.h | 2 +
13
target/arm/sve.decode | 5 +++
18
include/hw/misc/allwinner-a10-dramc.h | 68 ++++++++++
14
target/arm/sve_helper.c | 90 ++++++++++++++++++++++++++++++--------
19
hw/arm/allwinner-a10.c | 7 +
15
target/arm/translate-sve.c | 33 ++++++++++++++
20
hw/misc/allwinner-a10-dramc.c | 179 ++++++++++++++++++++++++++
16
4 files changed, 119 insertions(+), 19 deletions(-)
21
hw/arm/Kconfig | 1 +
17
22
hw/misc/Kconfig | 3 +
18
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
23
hw/misc/meson.build | 1 +
19
index XXXXXXX..XXXXXXX 100644
24
7 files changed, 261 insertions(+)
20
--- a/target/arm/helper-sve.h
25
create mode 100644 include/hw/misc/allwinner-a10-dramc.h
21
+++ b/target/arm/helper-sve.h
26
create mode 100644 hw/misc/allwinner-a10-dramc.c
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_tbl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
23
DEF_HELPER_FLAGS_4(sve_tbl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
24
DEF_HELPER_FLAGS_4(sve_tbl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
index XXXXXXX..XXXXXXX 100644
25
30
--- a/include/hw/arm/allwinner-a10.h
26
+DEF_HELPER_FLAGS_5(sve2_tbl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
31
+++ b/include/hw/arm/allwinner-a10.h
27
+DEF_HELPER_FLAGS_5(sve2_tbl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
32
@@ -XXX,XX +XXX,XX @@
28
+DEF_HELPER_FLAGS_5(sve2_tbl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
33
#include "hw/usb/hcd-ehci.h"
29
+DEF_HELPER_FLAGS_5(sve2_tbl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
34
#include "hw/rtc/allwinner-rtc.h"
30
+
35
#include "hw/misc/allwinner-a10-ccm.h"
31
+DEF_HELPER_FLAGS_4(sve2_tbx_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
+#include "hw/misc/allwinner-a10-dramc.h"
32
+DEF_HELPER_FLAGS_4(sve2_tbx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
37
33
+DEF_HELPER_FLAGS_4(sve2_tbx_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
38
#include "target/arm/cpu.h"
34
+DEF_HELPER_FLAGS_4(sve2_tbx_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
39
#include "qom/object.h"
35
+
40
@@ -XXX,XX +XXX,XX @@ struct AwA10State {
36
DEF_HELPER_FLAGS_3(sve_sunpk_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
41
37
DEF_HELPER_FLAGS_3(sve_sunpk_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
42
ARMCPU cpu;
38
DEF_HELPER_FLAGS_3(sve_sunpk_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
43
AwA10ClockCtlState ccm;
39
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
44
+ AwA10DramControllerState dramc;
40
index XXXXXXX..XXXXXXX 100644
45
AwA10PITState timer;
41
--- a/target/arm/sve.decode
46
AwA10PICState intc;
42
+++ b/target/arm/sve.decode
47
AwEmacState emac;
43
@@ -XXX,XX +XXX,XX @@ TBL 00000101 .. 1 ..... 001100 ..... ..... @rd_rn_rm
48
diff --git a/include/hw/misc/allwinner-a10-dramc.h b/include/hw/misc/allwinner-a10-dramc.h
44
# SVE unpack vector elements
49
new file mode 100644
45
UNPK 00000101 esz:2 1100 u:1 h:1 001110 rn:5 rd:5
50
index XXXXXXX..XXXXXXX
46
51
--- /dev/null
47
+# SVE2 Table Lookup (three sources)
52
+++ b/include/hw/misc/allwinner-a10-dramc.h
48
+
53
@@ -XXX,XX +XXX,XX @@
49
+TBL_sve2 00000101 .. 1 ..... 001010 ..... ..... @rd_rn_rm
54
+/*
50
+TBX 00000101 .. 1 ..... 001011 ..... ..... @rd_rn_rm
55
+ * Allwinner A10 DRAM Controller emulation
51
+
56
+ *
52
### SVE Permute - Predicates Group
57
+ * Copyright (C) 2022 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
53
58
+ *
54
# SVE permute predicate elements
59
+ * This file is derived from Allwinner H3 DRAMC,
55
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
60
+ * by Niek Linnenbank.
56
index XXXXXXX..XXXXXXX 100644
61
+ *
57
--- a/target/arm/sve_helper.c
62
+ * This program is free software: you can redistribute it and/or modify
58
+++ b/target/arm/sve_helper.c
63
+ * it under the terms of the GNU General Public License as published by
59
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_rev_d)(void *vd, void *vn, uint32_t desc)
64
+ * the Free Software Foundation, either version 2 of the License, or
60
}
65
+ * (at your option) any later version.
61
}
66
+ *
62
67
+ * This program is distributed in the hope that it will be useful,
63
-#define DO_TBL(NAME, TYPE, H) \
68
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
64
-void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
69
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
65
-{ \
70
+ * GNU General Public License for more details.
66
- intptr_t i, opr_sz = simd_oprsz(desc); \
71
+ *
67
- uintptr_t elem = opr_sz / sizeof(TYPE); \
72
+ * You should have received a copy of the GNU General Public License
68
- TYPE *d = vd, *n = vn, *m = vm; \
73
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
69
- ARMVectorReg tmp; \
74
+ */
70
- if (unlikely(vd == vn)) { \
75
+
71
- n = memcpy(&tmp, vn, opr_sz); \
76
+#ifndef HW_MISC_ALLWINNER_A10_DRAMC_H
72
- } \
77
+#define HW_MISC_ALLWINNER_A10_DRAMC_H
73
- for (i = 0; i < elem; i++) { \
78
+
74
- TYPE j = m[H(i)]; \
79
+#include "qom/object.h"
75
- d[H(i)] = j < elem ? n[H(j)] : 0; \
80
+#include "hw/sysbus.h"
76
- } \
81
+#include "hw/register.h"
77
+typedef void tb_impl_fn(void *, void *, void *, void *, uintptr_t, bool);
82
+
78
+
83
+/**
79
+static inline void do_tbl1(void *vd, void *vn, void *vm, uint32_t desc,
84
+ * @name Constants
80
+ bool is_tbx, tb_impl_fn *fn)
85
+ * @{
81
+{
86
+ */
82
+ ARMVectorReg scratch;
87
+
83
+ uintptr_t oprsz = simd_oprsz(desc);
88
+/** Size of register I/O address space used by DRAMC device */
84
+
89
+#define AW_A10_DRAMC_IOSIZE (0x1000)
85
+ if (unlikely(vd == vn)) {
90
+
86
+ vn = memcpy(&scratch, vn, oprsz);
91
+/** Total number of known registers */
92
+#define AW_A10_DRAMC_REGS_NUM (AW_A10_DRAMC_IOSIZE / sizeof(uint32_t))
93
+
94
+/** @} */
95
+
96
+/**
97
+ * @name Object model
98
+ * @{
99
+ */
100
+
101
+#define TYPE_AW_A10_DRAMC "allwinner-a10-dramc"
102
+OBJECT_DECLARE_SIMPLE_TYPE(AwA10DramControllerState, AW_A10_DRAMC)
103
+
104
+/** @} */
105
+
106
+/**
107
+ * Allwinner A10 DRAMC object instance state.
108
+ */
109
+struct AwA10DramControllerState {
110
+ /*< private >*/
111
+ SysBusDevice parent_obj;
112
+ /*< public >*/
113
+
114
+ /** Maps I/O registers in physical memory */
115
+ MemoryRegion iomem;
116
+
117
+ /** Array of hardware registers */
118
+ uint32_t regs[AW_A10_DRAMC_REGS_NUM];
119
+};
120
+
121
+#endif /* HW_MISC_ALLWINNER_A10_DRAMC_H */
122
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/hw/arm/allwinner-a10.c
125
+++ b/hw/arm/allwinner-a10.c
126
@@ -XXX,XX +XXX,XX @@
127
#include "hw/boards.h"
128
#include "hw/usb/hcd-ohci.h"
129
130
+#define AW_A10_DRAMC_BASE 0x01c01000
131
#define AW_A10_MMC0_BASE 0x01c0f000
132
#define AW_A10_CCM_BASE 0x01c20000
133
#define AW_A10_PIC_REG_BASE 0x01c20400
134
@@ -XXX,XX +XXX,XX @@ static void aw_a10_init(Object *obj)
135
136
object_initialize_child(obj, "ccm", &s->ccm, TYPE_AW_A10_CCM);
137
138
+ object_initialize_child(obj, "dramc", &s->dramc, TYPE_AW_A10_DRAMC);
139
+
140
object_initialize_child(obj, "emac", &s->emac, TYPE_AW_EMAC);
141
142
object_initialize_child(obj, "sata", &s->sata, TYPE_ALLWINNER_AHCI);
143
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
144
sysbus_realize(SYS_BUS_DEVICE(&s->ccm), &error_fatal);
145
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, AW_A10_CCM_BASE);
146
147
+ /* DRAM Control Module */
148
+ sysbus_realize(SYS_BUS_DEVICE(&s->dramc), &error_fatal);
149
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->dramc), 0, AW_A10_DRAMC_BASE);
150
+
151
/* FIXME use qdev NIC properties instead of nd_table[] */
152
if (nd_table[0].used) {
153
qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC);
154
diff --git a/hw/misc/allwinner-a10-dramc.c b/hw/misc/allwinner-a10-dramc.c
155
new file mode 100644
156
index XXXXXXX..XXXXXXX
157
--- /dev/null
158
+++ b/hw/misc/allwinner-a10-dramc.c
159
@@ -XXX,XX +XXX,XX @@
160
+/*
161
+ * Allwinner A10 DRAM Controller emulation
162
+ *
163
+ * Copyright (C) 2022 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
164
+ *
165
+ * This file is derived from Allwinner H3 DRAMC,
166
+ * by Niek Linnenbank.
167
+ *
168
+ * This program is free software: you can redistribute it and/or modify
169
+ * it under the terms of the GNU General Public License as published by
170
+ * the Free Software Foundation, either version 2 of the License, or
171
+ * (at your option) any later version.
172
+ *
173
+ * This program is distributed in the hope that it will be useful,
174
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
175
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
176
+ * GNU General Public License for more details.
177
+ *
178
+ * You should have received a copy of the GNU General Public License
179
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
180
+ */
181
+
182
+#include "qemu/osdep.h"
183
+#include "qemu/units.h"
184
+#include "hw/sysbus.h"
185
+#include "migration/vmstate.h"
186
+#include "qemu/log.h"
187
+#include "qemu/module.h"
188
+#include "hw/misc/allwinner-a10-dramc.h"
189
+
190
+/* DRAMC register offsets */
191
+enum {
192
+ REG_SDR_CCR = 0x0000,
193
+ REG_SDR_ZQCR0 = 0x00a8,
194
+ REG_SDR_ZQSR = 0x00b0
195
+};
196
+
197
+#define REG_INDEX(offset) (offset / sizeof(uint32_t))
198
+
199
+/* DRAMC register flags */
200
+enum {
201
+ REG_SDR_CCR_DATA_TRAINING = (1 << 30),
202
+ REG_SDR_CCR_DRAM_INIT = (1 << 31),
203
+};
204
+enum {
205
+ REG_SDR_ZQSR_ZCAL = (1 << 31),
206
+};
207
+
208
+/* DRAMC register reset values */
209
+enum {
210
+ REG_SDR_CCR_RESET = 0x80020000,
211
+ REG_SDR_ZQCR0_RESET = 0x07b00000,
212
+ REG_SDR_ZQSR_RESET = 0x80000000
213
+};
214
+
215
+static uint64_t allwinner_a10_dramc_read(void *opaque, hwaddr offset,
216
+ unsigned size)
217
+{
218
+ const AwA10DramControllerState *s = AW_A10_DRAMC(opaque);
219
+ const uint32_t idx = REG_INDEX(offset);
220
+
221
+ switch (offset) {
222
+ case REG_SDR_CCR:
223
+ case REG_SDR_ZQCR0:
224
+ case REG_SDR_ZQSR:
225
+ break;
226
+ case 0x2e4 ... AW_A10_DRAMC_IOSIZE:
227
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
228
+ __func__, (uint32_t)offset);
229
+ return 0;
230
+ default:
231
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented read offset 0x%04x\n",
232
+ __func__, (uint32_t)offset);
233
+ return 0;
87
+ }
234
+ }
88
+
235
+
89
+ fn(vd, vn, NULL, vm, oprsz, is_tbx);
236
+ return s->regs[idx];
90
}
237
+}
91
238
+
92
-DO_TBL(sve_tbl_b, uint8_t, H1)
239
+static void allwinner_a10_dramc_write(void *opaque, hwaddr offset,
93
-DO_TBL(sve_tbl_h, uint16_t, H2)
240
+ uint64_t val, unsigned size)
94
-DO_TBL(sve_tbl_s, uint32_t, H4)
241
+{
95
-DO_TBL(sve_tbl_d, uint64_t, )
242
+ AwA10DramControllerState *s = AW_A10_DRAMC(opaque);
96
+static inline void do_tbl2(void *vd, void *vn0, void *vn1, void *vm,
243
+ const uint32_t idx = REG_INDEX(offset);
97
+ uint32_t desc, bool is_tbx, tb_impl_fn *fn)
244
+
98
+{
245
+ switch (offset) {
99
+ ARMVectorReg scratch;
246
+ case REG_SDR_CCR:
100
+ uintptr_t oprsz = simd_oprsz(desc);
247
+ if (val & REG_SDR_CCR_DRAM_INIT) {
101
248
+ /* Clear DRAM_INIT to indicate process is done. */
102
-#undef TBL
249
+ val &= ~REG_SDR_CCR_DRAM_INIT;
103
+ if (unlikely(vd == vn0)) {
104
+ vn0 = memcpy(&scratch, vn0, oprsz);
105
+ if (vd == vn1) {
106
+ vn1 = vn0;
107
+ }
250
+ }
108
+ } else if (unlikely(vd == vn1)) {
251
+ if (val & REG_SDR_CCR_DATA_TRAINING) {
109
+ vn1 = memcpy(&scratch, vn1, oprsz);
252
+ /* Clear DATA_TRAINING to indicate process is done. */
253
+ val &= ~REG_SDR_CCR_DATA_TRAINING;
254
+ }
255
+ break;
256
+ case REG_SDR_ZQCR0:
257
+ /* Set ZCAL in ZQSR to indicate calibration is done. */
258
+ s->regs[REG_INDEX(REG_SDR_ZQSR)] |= REG_SDR_ZQSR_ZCAL;
259
+ break;
260
+ case 0x2e4 ... AW_A10_DRAMC_IOSIZE:
261
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: out-of-bounds offset 0x%04x\n",
262
+ __func__, (uint32_t)offset);
263
+ break;
264
+ default:
265
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented write offset 0x%04x\n",
266
+ __func__, (uint32_t)offset);
267
+ break;
110
+ }
268
+ }
111
+
269
+
112
+ fn(vd, vn0, vn1, vm, oprsz, is_tbx);
270
+ s->regs[idx] = (uint32_t) val;
113
+}
271
+}
114
+
272
+
115
+#define DO_TB(SUFF, TYPE, H) \
273
+static const MemoryRegionOps allwinner_a10_dramc_ops = {
116
+static inline void do_tb_##SUFF(void *vd, void *vt0, void *vt1, \
274
+ .read = allwinner_a10_dramc_read,
117
+ void *vm, uintptr_t oprsz, bool is_tbx) \
275
+ .write = allwinner_a10_dramc_write,
118
+{ \
276
+ .endianness = DEVICE_NATIVE_ENDIAN,
119
+ TYPE *d = vd, *tbl0 = vt0, *tbl1 = vt1, *indexes = vm; \
277
+ .valid = {
120
+ uintptr_t i, nelem = oprsz / sizeof(TYPE); \
278
+ .min_access_size = 4,
121
+ for (i = 0; i < nelem; ++i) { \
279
+ .max_access_size = 4,
122
+ TYPE index = indexes[H1(i)], val = 0; \
280
+ },
123
+ if (index < nelem) { \
281
+ .impl.min_access_size = 4,
124
+ val = tbl0[H(index)]; \
282
+};
125
+ } else { \
283
+
126
+ index -= nelem; \
284
+static void allwinner_a10_dramc_reset_enter(Object *obj, ResetType type)
127
+ if (tbl1 && index < nelem) { \
285
+{
128
+ val = tbl1[H(index)]; \
286
+ AwA10DramControllerState *s = AW_A10_DRAMC(obj);
129
+ } else if (is_tbx) { \
287
+
130
+ continue; \
288
+ /* Set default values for registers */
131
+ } \
289
+ s->regs[REG_INDEX(REG_SDR_CCR)] = REG_SDR_CCR_RESET;
132
+ } \
290
+ s->regs[REG_INDEX(REG_SDR_ZQCR0)] = REG_SDR_ZQCR0_RESET;
133
+ d[H(i)] = val; \
291
+ s->regs[REG_INDEX(REG_SDR_ZQSR)] = REG_SDR_ZQSR_RESET;
134
+ } \
292
+}
135
+} \
293
+
136
+void HELPER(sve_tbl_##SUFF)(void *vd, void *vn, void *vm, uint32_t desc) \
294
+static void allwinner_a10_dramc_init(Object *obj)
137
+{ \
295
+{
138
+ do_tbl1(vd, vn, vm, desc, false, do_tb_##SUFF); \
296
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
139
+} \
297
+ AwA10DramControllerState *s = AW_A10_DRAMC(obj);
140
+void HELPER(sve2_tbl_##SUFF)(void *vd, void *vn0, void *vn1, \
298
+
141
+ void *vm, uint32_t desc) \
299
+ /* Memory mapping */
142
+{ \
300
+ memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_a10_dramc_ops, s,
143
+ do_tbl2(vd, vn0, vn1, vm, desc, false, do_tb_##SUFF); \
301
+ TYPE_AW_A10_DRAMC, AW_A10_DRAMC_IOSIZE);
144
+} \
302
+ sysbus_init_mmio(sbd, &s->iomem);
145
+void HELPER(sve2_tbx_##SUFF)(void *vd, void *vn, void *vm, uint32_t desc) \
303
+}
146
+{ \
304
+
147
+ do_tbl1(vd, vn, vm, desc, true, do_tb_##SUFF); \
305
+static const VMStateDescription allwinner_a10_dramc_vmstate = {
148
+}
306
+ .name = "allwinner-a10-dramc",
149
+
307
+ .version_id = 1,
150
+DO_TB(b, uint8_t, H1)
308
+ .minimum_version_id = 1,
151
+DO_TB(h, uint16_t, H2)
309
+ .fields = (VMStateField[]) {
152
+DO_TB(s, uint32_t, H4)
310
+ VMSTATE_UINT32_ARRAY(regs, AwA10DramControllerState,
153
+DO_TB(d, uint64_t, )
311
+ AW_A10_DRAMC_REGS_NUM),
154
+
312
+ VMSTATE_END_OF_LIST()
155
+#undef DO_TB
156
157
#define DO_UNPK(NAME, TYPED, TYPES, HD, HS) \
158
void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
159
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/target/arm/translate-sve.c
162
+++ b/target/arm/translate-sve.c
163
@@ -XXX,XX +XXX,XX @@ static bool trans_TBL(DisasContext *s, arg_rrr_esz *a)
164
return true;
165
}
166
167
+static bool trans_TBL_sve2(DisasContext *s, arg_rrr_esz *a)
168
+{
169
+ static gen_helper_gvec_4 * const fns[4] = {
170
+ gen_helper_sve2_tbl_b, gen_helper_sve2_tbl_h,
171
+ gen_helper_sve2_tbl_s, gen_helper_sve2_tbl_d
172
+ };
173
+
174
+ if (!dc_isar_feature(aa64_sve2, s)) {
175
+ return false;
176
+ }
313
+ }
177
+ if (sve_access_check(s)) {
314
+};
178
+ gen_gvec_ool_zzzz(s, fns[a->esz], a->rd, a->rn,
315
+
179
+ (a->rn + 1) % 32, a->rm, 0);
316
+static void allwinner_a10_dramc_class_init(ObjectClass *klass, void *data)
180
+ }
317
+{
181
+ return true;
318
+ DeviceClass *dc = DEVICE_CLASS(klass);
182
+}
319
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
183
+
320
+
184
+static bool trans_TBX(DisasContext *s, arg_rrr_esz *a)
321
+ rc->phases.enter = allwinner_a10_dramc_reset_enter;
185
+{
322
+ dc->vmsd = &allwinner_a10_dramc_vmstate;
186
+ static gen_helper_gvec_3 * const fns[4] = {
323
+}
187
+ gen_helper_sve2_tbx_b, gen_helper_sve2_tbx_h,
324
+
188
+ gen_helper_sve2_tbx_s, gen_helper_sve2_tbx_d
325
+static const TypeInfo allwinner_a10_dramc_info = {
189
+ };
326
+ .name = TYPE_AW_A10_DRAMC,
190
+
327
+ .parent = TYPE_SYS_BUS_DEVICE,
191
+ if (!dc_isar_feature(aa64_sve2, s)) {
328
+ .instance_init = allwinner_a10_dramc_init,
192
+ return false;
329
+ .instance_size = sizeof(AwA10DramControllerState),
193
+ }
330
+ .class_init = allwinner_a10_dramc_class_init,
194
+ if (sve_access_check(s)) {
331
+};
195
+ gen_gvec_ool_zzz(s, fns[a->esz], a->rd, a->rn, a->rm, 0);
332
+
196
+ }
333
+static void allwinner_a10_dramc_register(void)
197
+ return true;
334
+{
198
+}
335
+ type_register_static(&allwinner_a10_dramc_info);
199
+
336
+}
200
static bool trans_UNPK(DisasContext *s, arg_UNPK *a)
337
+
201
{
338
+type_init(allwinner_a10_dramc_register)
202
static gen_helper_gvec_2 * const fns[4][2] = {
339
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
340
index XXXXXXX..XXXXXXX 100644
341
--- a/hw/arm/Kconfig
342
+++ b/hw/arm/Kconfig
343
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_A10
344
select ALLWINNER_A10_PIT
345
select ALLWINNER_A10_PIC
346
select ALLWINNER_A10_CCM
347
+ select ALLWINNER_A10_DRAMC
348
select ALLWINNER_EMAC
349
select SERIAL
350
select UNIMP
351
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
352
index XXXXXXX..XXXXXXX 100644
353
--- a/hw/misc/Kconfig
354
+++ b/hw/misc/Kconfig
355
@@ -XXX,XX +XXX,XX @@ config LASI
356
config ALLWINNER_A10_CCM
357
bool
358
359
+config ALLWINNER_A10_DRAMC
360
+ bool
361
+
362
source macio/Kconfig
363
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
364
index XXXXXXX..XXXXXXX 100644
365
--- a/hw/misc/meson.build
366
+++ b/hw/misc/meson.build
367
@@ -XXX,XX +XXX,XX @@ subdir('macio')
368
softmmu_ss.add(when: 'CONFIG_IVSHMEM_DEVICE', if_true: files('ivshmem.c'))
369
370
softmmu_ss.add(when: 'CONFIG_ALLWINNER_A10_CCM', if_true: files('allwinner-a10-ccm.c'))
371
+softmmu_ss.add(when: 'CONFIG_ALLWINNER_A10_DRAMC', if_true: files('allwinner-a10-dramc.c'))
372
softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-ccu.c'))
373
specific_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-cpucfg.c'))
374
softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-dramc.c'))
203
--
375
--
204
2.20.1
376
2.34.1
205
206
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
This patch implements Allwinner TWI/I2C controller emulation. Only
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
master-mode functionality is implemented.
5
Message-id: 20210525010358.152808-59-richard.henderson@linaro.org
5
6
The SPL boot for Cubieboard expects AXP209 PMIC on TWI0/I2C0 bus, so this is
7
first part enabling the TWI/I2C bus operation.
8
9
Since both Allwinner A10 and H3 use the same module, it is added for
10
both boards.
11
12
Docs are also updated for Cubieboard and Orangepi-PC board to indicate
13
I2C availability.
14
15
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
16
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
17
Message-id: 20221226220303.14420-4-strahinja.p.jankovic@gmail.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
19
---
8
target/arm/helper.h | 10 +++++
20
docs/system/arm/cubieboard.rst | 1 +
9
target/arm/sve.decode | 4 ++
21
docs/system/arm/orangepi.rst | 1 +
10
target/arm/translate-sve.c | 18 ++++++++
22
include/hw/arm/allwinner-a10.h | 2 +
11
target/arm/vec_helper.c | 84 ++++++++++++++++++++++++++++++++++++++
23
include/hw/arm/allwinner-h3.h | 3 +
12
4 files changed, 116 insertions(+)
24
include/hw/i2c/allwinner-i2c.h | 55 ++++
25
hw/arm/allwinner-a10.c | 8 +
26
hw/arm/allwinner-h3.c | 11 +-
27
hw/i2c/allwinner-i2c.c | 459 +++++++++++++++++++++++++++++++++
28
hw/arm/Kconfig | 2 +
29
hw/i2c/Kconfig | 4 +
30
hw/i2c/meson.build | 1 +
31
hw/i2c/trace-events | 5 +
32
12 files changed, 551 insertions(+), 1 deletion(-)
33
create mode 100644 include/hw/i2c/allwinner-i2c.h
34
create mode 100644 hw/i2c/allwinner-i2c.c
13
35
14
diff --git a/target/arm/helper.h b/target/arm/helper.h
36
diff --git a/docs/system/arm/cubieboard.rst b/docs/system/arm/cubieboard.rst
15
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.h
38
--- a/docs/system/arm/cubieboard.rst
17
+++ b/target/arm/helper.h
39
+++ b/docs/system/arm/cubieboard.rst
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(neon_sqrdmulh_h, TCG_CALL_NO_RWG,
40
@@ -XXX,XX +XXX,XX @@ Emulated devices:
19
DEF_HELPER_FLAGS_5(neon_sqrdmulh_s, TCG_CALL_NO_RWG,
41
- SDHCI
20
void, ptr, ptr, ptr, ptr, i32)
42
- USB controller
21
43
- SATA controller
22
+DEF_HELPER_FLAGS_4(sve2_sqdmulh_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
44
+- TWI (I2C) controller
23
+DEF_HELPER_FLAGS_4(sve2_sqdmulh_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
45
diff --git a/docs/system/arm/orangepi.rst b/docs/system/arm/orangepi.rst
24
+DEF_HELPER_FLAGS_4(sve2_sqdmulh_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
46
index XXXXXXX..XXXXXXX 100644
25
+DEF_HELPER_FLAGS_4(sve2_sqdmulh_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
47
--- a/docs/system/arm/orangepi.rst
26
+
48
+++ b/docs/system/arm/orangepi.rst
27
+DEF_HELPER_FLAGS_4(sve2_sqrdmulh_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
49
@@ -XXX,XX +XXX,XX @@ The Orange Pi PC machine supports the following devices:
28
+DEF_HELPER_FLAGS_4(sve2_sqrdmulh_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
50
* Clock Control Unit
29
+DEF_HELPER_FLAGS_4(sve2_sqrdmulh_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
51
* System Control module
30
+DEF_HELPER_FLAGS_4(sve2_sqrdmulh_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
52
* Security Identifier device
31
+
53
+ * TWI (I2C)
32
DEF_HELPER_FLAGS_4(gvec_xar_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
54
33
55
Limitations
34
#ifdef TARGET_AARCH64
56
"""""""""""
35
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
57
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
36
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/sve.decode
59
--- a/include/hw/arm/allwinner-a10.h
38
+++ b/target/arm/sve.decode
60
+++ b/include/hw/arm/allwinner-a10.h
39
@@ -XXX,XX +XXX,XX @@ SMULH_zzz 00000100 .. 1 ..... 0110 10 ..... ..... @rd_rn_rm
61
@@ -XXX,XX +XXX,XX @@
40
UMULH_zzz 00000100 .. 1 ..... 0110 11 ..... ..... @rd_rn_rm
62
#include "hw/rtc/allwinner-rtc.h"
41
PMUL_zzz 00000100 00 1 ..... 0110 01 ..... ..... @rd_rn_rm_e0
63
#include "hw/misc/allwinner-a10-ccm.h"
42
64
#include "hw/misc/allwinner-a10-dramc.h"
43
+# SVE2 signed saturating doubling multiply high (unpredicated)
65
+#include "hw/i2c/allwinner-i2c.h"
44
+SQDMULH_zzz 00000100 .. 1 ..... 0111 00 ..... ..... @rd_rn_rm
66
45
+SQRDMULH_zzz 00000100 .. 1 ..... 0111 01 ..... ..... @rd_rn_rm
67
#include "target/arm/cpu.h"
46
+
68
#include "qom/object.h"
47
### SVE2 Integer - Predicated
69
@@ -XXX,XX +XXX,XX @@ struct AwA10State {
48
70
AwEmacState emac;
49
SADALP_zpzz 01000100 .. 000 100 101 ... ..... ..... @rdm_pg_rn
71
AllwinnerAHCIState sata;
50
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
72
AwSdHostState mmc0;
51
index XXXXXXX..XXXXXXX 100644
73
+ AWI2CState i2c0;
52
--- a/target/arm/translate-sve.c
74
AwRtcState rtc;
53
+++ b/target/arm/translate-sve.c
75
MemoryRegion sram_a;
54
@@ -XXX,XX +XXX,XX @@ static bool trans_PMUL_zzz(DisasContext *s, arg_rrr_esz *a)
76
EHCISysBusState ehci[AW_A10_NUM_USB];
55
return do_sve2_zzz_ool(s, a, gen_helper_gvec_pmul_b);
77
diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
78
index XXXXXXX..XXXXXXX 100644
79
--- a/include/hw/arm/allwinner-h3.h
80
+++ b/include/hw/arm/allwinner-h3.h
81
@@ -XXX,XX +XXX,XX @@
82
#include "hw/sd/allwinner-sdhost.h"
83
#include "hw/net/allwinner-sun8i-emac.h"
84
#include "hw/rtc/allwinner-rtc.h"
85
+#include "hw/i2c/allwinner-i2c.h"
86
#include "target/arm/cpu.h"
87
#include "sysemu/block-backend.h"
88
89
@@ -XXX,XX +XXX,XX @@ enum {
90
AW_H3_DEV_UART2,
91
AW_H3_DEV_UART3,
92
AW_H3_DEV_EMAC,
93
+ AW_H3_DEV_TWI0,
94
AW_H3_DEV_DRAMCOM,
95
AW_H3_DEV_DRAMCTL,
96
AW_H3_DEV_DRAMPHY,
97
@@ -XXX,XX +XXX,XX @@ struct AwH3State {
98
AwH3SysCtrlState sysctrl;
99
AwSidState sid;
100
AwSdHostState mmc0;
101
+ AWI2CState i2c0;
102
AwSun8iEmacState emac;
103
AwRtcState rtc;
104
GICState gic;
105
diff --git a/include/hw/i2c/allwinner-i2c.h b/include/hw/i2c/allwinner-i2c.h
106
new file mode 100644
107
index XXXXXXX..XXXXXXX
108
--- /dev/null
109
+++ b/include/hw/i2c/allwinner-i2c.h
110
@@ -XXX,XX +XXX,XX @@
111
+/*
112
+ * Allwinner I2C Bus Serial Interface registers definition
113
+ *
114
+ * Copyright (C) 2022 Strahinja Jankovic. <strahinja.p.jankovic@gmail.com>
115
+ *
116
+ * This file is derived from IMX I2C controller,
117
+ * by Jean-Christophe DUBOIS .
118
+ *
119
+ * This program is free software; you can redistribute it and/or modify it
120
+ * under the terms of the GNU General Public License as published by the
121
+ * Free Software Foundation; either version 2 of the License, or
122
+ * (at your option) any later version.
123
+ *
124
+ * This program is distributed in the hope that it will be useful, but WITHOUT
125
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
126
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
127
+ * for more details.
128
+ *
129
+ * You should have received a copy of the GNU General Public License along
130
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
131
+ *
132
+ */
133
+
134
+#ifndef ALLWINNER_I2C_H
135
+#define ALLWINNER_I2C_H
136
+
137
+#include "hw/sysbus.h"
138
+#include "qom/object.h"
139
+
140
+#define TYPE_AW_I2C "allwinner.i2c"
141
+OBJECT_DECLARE_SIMPLE_TYPE(AWI2CState, AW_I2C)
142
+
143
+#define AW_I2C_MEM_SIZE 0x24
144
+
145
+struct AWI2CState {
146
+ /*< private >*/
147
+ SysBusDevice parent_obj;
148
+
149
+ /*< public >*/
150
+ MemoryRegion iomem;
151
+ I2CBus *bus;
152
+ qemu_irq irq;
153
+
154
+ uint8_t addr;
155
+ uint8_t xaddr;
156
+ uint8_t data;
157
+ uint8_t cntr;
158
+ uint8_t stat;
159
+ uint8_t ccr;
160
+ uint8_t srst;
161
+ uint8_t efr;
162
+ uint8_t lcr;
163
+};
164
+
165
+#endif /* ALLWINNER_I2C_H */
166
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/hw/arm/allwinner-a10.c
169
+++ b/hw/arm/allwinner-a10.c
170
@@ -XXX,XX +XXX,XX @@
171
#define AW_A10_OHCI_BASE 0x01c14400
172
#define AW_A10_SATA_BASE 0x01c18000
173
#define AW_A10_RTC_BASE 0x01c20d00
174
+#define AW_A10_I2C0_BASE 0x01c2ac00
175
176
static void aw_a10_init(Object *obj)
177
{
178
@@ -XXX,XX +XXX,XX @@ static void aw_a10_init(Object *obj)
179
180
object_initialize_child(obj, "sata", &s->sata, TYPE_ALLWINNER_AHCI);
181
182
+ object_initialize_child(obj, "i2c0", &s->i2c0, TYPE_AW_I2C);
183
+
184
if (machine_usb(current_machine)) {
185
int i;
186
187
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
188
/* RTC */
189
sysbus_realize(SYS_BUS_DEVICE(&s->rtc), &error_fatal);
190
sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->rtc), 0, AW_A10_RTC_BASE, 10);
191
+
192
+ /* I2C */
193
+ sysbus_realize(SYS_BUS_DEVICE(&s->i2c0), &error_fatal);
194
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c0), 0, AW_A10_I2C0_BASE);
195
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c0), 0, qdev_get_gpio_in(dev, 7));
56
}
196
}
57
197
58
+static bool trans_SQDMULH_zzz(DisasContext *s, arg_rrr_esz *a)
198
static void aw_a10_class_init(ObjectClass *oc, void *data)
59
+{
199
diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c
60
+ static gen_helper_gvec_3 * const fns[4] = {
200
index XXXXXXX..XXXXXXX 100644
61
+ gen_helper_sve2_sqdmulh_b, gen_helper_sve2_sqdmulh_h,
201
--- a/hw/arm/allwinner-h3.c
62
+ gen_helper_sve2_sqdmulh_s, gen_helper_sve2_sqdmulh_d,
202
+++ b/hw/arm/allwinner-h3.c
63
+ };
203
@@ -XXX,XX +XXX,XX @@ const hwaddr allwinner_h3_memmap[] = {
64
+ return do_sve2_zzz_ool(s, a, fns[a->esz]);
204
[AW_H3_DEV_UART1] = 0x01c28400,
65
+}
205
[AW_H3_DEV_UART2] = 0x01c28800,
66
+
206
[AW_H3_DEV_UART3] = 0x01c28c00,
67
+static bool trans_SQRDMULH_zzz(DisasContext *s, arg_rrr_esz *a)
207
+ [AW_H3_DEV_TWI0] = 0x01c2ac00,
68
+{
208
[AW_H3_DEV_EMAC] = 0x01c30000,
69
+ static gen_helper_gvec_3 * const fns[4] = {
209
[AW_H3_DEV_DRAMCOM] = 0x01c62000,
70
+ gen_helper_sve2_sqrdmulh_b, gen_helper_sve2_sqrdmulh_h,
210
[AW_H3_DEV_DRAMCTL] = 0x01c63000,
71
+ gen_helper_sve2_sqrdmulh_s, gen_helper_sve2_sqrdmulh_d,
211
@@ -XXX,XX +XXX,XX @@ struct AwH3Unimplemented {
72
+ };
212
{ "uart1", 0x01c28400, 1 * KiB },
73
+ return do_sve2_zzz_ool(s, a, fns[a->esz]);
213
{ "uart2", 0x01c28800, 1 * KiB },
74
+}
214
{ "uart3", 0x01c28c00, 1 * KiB },
75
+
215
- { "twi0", 0x01c2ac00, 1 * KiB },
76
/*
216
{ "twi1", 0x01c2b000, 1 * KiB },
77
* SVE2 Integer - Predicated
217
{ "twi2", 0x01c2b400, 1 * KiB },
78
*/
218
{ "scr", 0x01c2c400, 1 * KiB },
79
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
219
@@ -XXX,XX +XXX,XX @@ enum {
80
index XXXXXXX..XXXXXXX 100644
220
AW_H3_GIC_SPI_UART1 = 1,
81
--- a/target/arm/vec_helper.c
221
AW_H3_GIC_SPI_UART2 = 2,
82
+++ b/target/arm/vec_helper.c
222
AW_H3_GIC_SPI_UART3 = 3,
83
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_sqrdmlsh_b)(void *vd, void *vn, void *vm,
223
+ AW_H3_GIC_SPI_TWI0 = 6,
84
}
224
AW_H3_GIC_SPI_TIMER0 = 18,
225
AW_H3_GIC_SPI_TIMER1 = 19,
226
AW_H3_GIC_SPI_MMC0 = 60,
227
@@ -XXX,XX +XXX,XX @@ static void allwinner_h3_init(Object *obj)
228
"ram-size");
229
230
object_initialize_child(obj, "rtc", &s->rtc, TYPE_AW_RTC_SUN6I);
231
+
232
+ object_initialize_child(obj, "twi0", &s->i2c0, TYPE_AW_I2C);
85
}
233
}
86
234
87
+void HELPER(sve2_sqdmulh_b)(void *vd, void *vn, void *vm, uint32_t desc)
235
static void allwinner_h3_realize(DeviceState *dev, Error **errp)
88
+{
236
@@ -XXX,XX +XXX,XX @@ static void allwinner_h3_realize(DeviceState *dev, Error **errp)
89
+ intptr_t i, opr_sz = simd_oprsz(desc);
237
sysbus_realize(SYS_BUS_DEVICE(&s->rtc), &error_fatal);
90
+ int8_t *d = vd, *n = vn, *m = vm;
238
sysbus_mmio_map(SYS_BUS_DEVICE(&s->rtc), 0, s->memmap[AW_H3_DEV_RTC]);
91
+
239
92
+ for (i = 0; i < opr_sz; ++i) {
240
+ /* I2C */
93
+ d[i] = do_sqrdmlah_b(n[i], m[i], 0, false, false);
241
+ sysbus_realize(SYS_BUS_DEVICE(&s->i2c0), &error_fatal);
242
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c0), 0, s->memmap[AW_H3_DEV_TWI0]);
243
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c0), 0,
244
+ qdev_get_gpio_in(DEVICE(&s->gic), AW_H3_GIC_SPI_TWI0));
245
+
246
/* Unimplemented devices */
247
for (i = 0; i < ARRAY_SIZE(unimplemented); i++) {
248
create_unimplemented_device(unimplemented[i].device_name,
249
diff --git a/hw/i2c/allwinner-i2c.c b/hw/i2c/allwinner-i2c.c
250
new file mode 100644
251
index XXXXXXX..XXXXXXX
252
--- /dev/null
253
+++ b/hw/i2c/allwinner-i2c.c
254
@@ -XXX,XX +XXX,XX @@
255
+/*
256
+ * Allwinner I2C Bus Serial Interface Emulation
257
+ *
258
+ * Copyright (C) 2022 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
259
+ *
260
+ * This file is derived from IMX I2C controller,
261
+ * by Jean-Christophe DUBOIS .
262
+ *
263
+ * This program is free software; you can redistribute it and/or modify it
264
+ * under the terms of the GNU General Public License as published by the
265
+ * Free Software Foundation; either version 2 of the License, or
266
+ * (at your option) any later version.
267
+ *
268
+ * This program is distributed in the hope that it will be useful, but WITHOUT
269
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
270
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
271
+ * for more details.
272
+ *
273
+ * You should have received a copy of the GNU General Public License along
274
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
275
+ *
276
+ * SPDX-License-Identifier: MIT
277
+ */
278
+
279
+#include "qemu/osdep.h"
280
+#include "hw/i2c/allwinner-i2c.h"
281
+#include "hw/irq.h"
282
+#include "migration/vmstate.h"
283
+#include "hw/i2c/i2c.h"
284
+#include "qemu/log.h"
285
+#include "trace.h"
286
+#include "qemu/module.h"
287
+
288
+/* Allwinner I2C memory map */
289
+#define TWI_ADDR_REG 0x00 /* slave address register */
290
+#define TWI_XADDR_REG 0x04 /* extended slave address register */
291
+#define TWI_DATA_REG 0x08 /* data register */
292
+#define TWI_CNTR_REG 0x0c /* control register */
293
+#define TWI_STAT_REG 0x10 /* status register */
294
+#define TWI_CCR_REG 0x14 /* clock control register */
295
+#define TWI_SRST_REG 0x18 /* software reset register */
296
+#define TWI_EFR_REG 0x1c /* enhance feature register */
297
+#define TWI_LCR_REG 0x20 /* line control register */
298
+
299
+/* Used only in slave mode, do not set */
300
+#define TWI_ADDR_RESET 0
301
+#define TWI_XADDR_RESET 0
302
+
303
+/* Data register */
304
+#define TWI_DATA_MASK 0xFF
305
+#define TWI_DATA_RESET 0
306
+
307
+/* Control register */
308
+#define TWI_CNTR_INT_EN (1 << 7)
309
+#define TWI_CNTR_BUS_EN (1 << 6)
310
+#define TWI_CNTR_M_STA (1 << 5)
311
+#define TWI_CNTR_M_STP (1 << 4)
312
+#define TWI_CNTR_INT_FLAG (1 << 3)
313
+#define TWI_CNTR_A_ACK (1 << 2)
314
+#define TWI_CNTR_MASK 0xFC
315
+#define TWI_CNTR_RESET 0
316
+
317
+/* Status register */
318
+#define TWI_STAT_MASK 0xF8
319
+#define TWI_STAT_RESET 0xF8
320
+
321
+/* Clock register */
322
+#define TWI_CCR_CLK_M_MASK 0x78
323
+#define TWI_CCR_CLK_N_MASK 0x07
324
+#define TWI_CCR_MASK 0x7F
325
+#define TWI_CCR_RESET 0
326
+
327
+/* Soft reset */
328
+#define TWI_SRST_MASK 0x01
329
+#define TWI_SRST_RESET 0
330
+
331
+/* Enhance feature */
332
+#define TWI_EFR_MASK 0x03
333
+#define TWI_EFR_RESET 0
334
+
335
+/* Line control */
336
+#define TWI_LCR_SCL_STATE (1 << 5)
337
+#define TWI_LCR_SDA_STATE (1 << 4)
338
+#define TWI_LCR_SCL_CTL (1 << 3)
339
+#define TWI_LCR_SCL_CTL_EN (1 << 2)
340
+#define TWI_LCR_SDA_CTL (1 << 1)
341
+#define TWI_LCR_SDA_CTL_EN (1 << 0)
342
+#define TWI_LCR_MASK 0x3F
343
+#define TWI_LCR_RESET 0x3A
344
+
345
+/* Status value in STAT register is shifted by 3 bits */
346
+#define TWI_STAT_SHIFT 3
347
+#define STAT_FROM_STA(x) ((x) << TWI_STAT_SHIFT)
348
+#define STAT_TO_STA(x) ((x) >> TWI_STAT_SHIFT)
349
+
350
+enum {
351
+ STAT_BUS_ERROR = 0,
352
+ /* Master mode */
353
+ STAT_M_STA_TX,
354
+ STAT_M_RSTA_TX,
355
+ STAT_M_ADDR_WR_ACK,
356
+ STAT_M_ADDR_WR_NACK,
357
+ STAT_M_DATA_TX_ACK,
358
+ STAT_M_DATA_TX_NACK,
359
+ STAT_M_ARB_LOST,
360
+ STAT_M_ADDR_RD_ACK,
361
+ STAT_M_ADDR_RD_NACK,
362
+ STAT_M_DATA_RX_ACK,
363
+ STAT_M_DATA_RX_NACK,
364
+ /* Slave mode */
365
+ STAT_S_ADDR_WR_ACK,
366
+ STAT_S_ARB_LOST_AW_ACK,
367
+ STAT_S_GCA_ACK,
368
+ STAT_S_ARB_LOST_GCA_ACK,
369
+ STAT_S_DATA_RX_SA_ACK,
370
+ STAT_S_DATA_RX_SA_NACK,
371
+ STAT_S_DATA_RX_GCA_ACK,
372
+ STAT_S_DATA_RX_GCA_NACK,
373
+ STAT_S_STP_RSTA,
374
+ STAT_S_ADDR_RD_ACK,
375
+ STAT_S_ARB_LOST_AR_ACK,
376
+ STAT_S_DATA_TX_ACK,
377
+ STAT_S_DATA_TX_NACK,
378
+ STAT_S_LB_TX_ACK,
379
+ /* Master mode, 10-bit */
380
+ STAT_M_2ND_ADDR_WR_ACK,
381
+ STAT_M_2ND_ADDR_WR_NACK,
382
+ /* Idle */
383
+ STAT_IDLE = 0x1f
384
+} TWI_STAT_STA;
385
+
386
+static const char *allwinner_i2c_get_regname(unsigned offset)
387
+{
388
+ switch (offset) {
389
+ case TWI_ADDR_REG:
390
+ return "ADDR";
391
+ case TWI_XADDR_REG:
392
+ return "XADDR";
393
+ case TWI_DATA_REG:
394
+ return "DATA";
395
+ case TWI_CNTR_REG:
396
+ return "CNTR";
397
+ case TWI_STAT_REG:
398
+ return "STAT";
399
+ case TWI_CCR_REG:
400
+ return "CCR";
401
+ case TWI_SRST_REG:
402
+ return "SRST";
403
+ case TWI_EFR_REG:
404
+ return "EFR";
405
+ case TWI_LCR_REG:
406
+ return "LCR";
407
+ default:
408
+ return "[?]";
94
+ }
409
+ }
95
+}
410
+}
96
+
411
+
97
+void HELPER(sve2_sqrdmulh_b)(void *vd, void *vn, void *vm, uint32_t desc)
412
+static inline bool allwinner_i2c_is_reset(AWI2CState *s)
98
+{
413
+{
99
+ intptr_t i, opr_sz = simd_oprsz(desc);
414
+ return s->srst & TWI_SRST_MASK;
100
+ int8_t *d = vd, *n = vn, *m = vm;
415
+}
101
+
416
+
102
+ for (i = 0; i < opr_sz; ++i) {
417
+static inline bool allwinner_i2c_bus_is_enabled(AWI2CState *s)
103
+ d[i] = do_sqrdmlah_b(n[i], m[i], 0, false, true);
418
+{
419
+ return s->cntr & TWI_CNTR_BUS_EN;
420
+}
421
+
422
+static inline bool allwinner_i2c_interrupt_is_enabled(AWI2CState *s)
423
+{
424
+ return s->cntr & TWI_CNTR_INT_EN;
425
+}
426
+
427
+static void allwinner_i2c_reset_hold(Object *obj)
428
+{
429
+ AWI2CState *s = AW_I2C(obj);
430
+
431
+ if (STAT_TO_STA(s->stat) != STAT_IDLE) {
432
+ i2c_end_transfer(s->bus);
104
+ }
433
+ }
105
+}
434
+
106
+
435
+ s->addr = TWI_ADDR_RESET;
107
/* Signed saturating rounding doubling multiply-accumulate high half, 16-bit */
436
+ s->xaddr = TWI_XADDR_RESET;
108
int16_t do_sqrdmlah_h(int16_t src1, int16_t src2, int16_t src3,
437
+ s->data = TWI_DATA_RESET;
109
bool neg, bool round, uint32_t *sat)
438
+ s->cntr = TWI_CNTR_RESET;
110
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_sqrdmlsh_h)(void *vd, void *vn, void *vm,
439
+ s->stat = TWI_STAT_RESET;
111
}
440
+ s->ccr = TWI_CCR_RESET;
112
}
441
+ s->srst = TWI_SRST_RESET;
113
442
+ s->efr = TWI_EFR_RESET;
114
+void HELPER(sve2_sqdmulh_h)(void *vd, void *vn, void *vm, uint32_t desc)
443
+ s->lcr = TWI_LCR_RESET;
115
+{
444
+}
116
+ intptr_t i, opr_sz = simd_oprsz(desc);
445
+
117
+ int16_t *d = vd, *n = vn, *m = vm;
446
+static inline void allwinner_i2c_raise_interrupt(AWI2CState *s)
118
+ uint32_t discard;
447
+{
119
+
448
+ /*
120
+ for (i = 0; i < opr_sz / 2; ++i) {
449
+ * Raise an interrupt if the device is not reset and it is configured
121
+ d[i] = do_sqrdmlah_h(n[i], m[i], 0, false, false, &discard);
450
+ * to generate some interrupts.
451
+ */
452
+ if (!allwinner_i2c_is_reset(s) && allwinner_i2c_bus_is_enabled(s)) {
453
+ if (STAT_TO_STA(s->stat) != STAT_IDLE) {
454
+ s->cntr |= TWI_CNTR_INT_FLAG;
455
+ if (allwinner_i2c_interrupt_is_enabled(s)) {
456
+ qemu_irq_raise(s->irq);
457
+ }
458
+ }
122
+ }
459
+ }
123
+}
460
+}
124
+
461
+
125
+void HELPER(sve2_sqrdmulh_h)(void *vd, void *vn, void *vm, uint32_t desc)
462
+static uint64_t allwinner_i2c_read(void *opaque, hwaddr offset,
126
+{
463
+ unsigned size)
127
+ intptr_t i, opr_sz = simd_oprsz(desc);
464
+{
128
+ int16_t *d = vd, *n = vn, *m = vm;
465
+ uint16_t value;
129
+ uint32_t discard;
466
+ AWI2CState *s = AW_I2C(opaque);
130
+
467
+
131
+ for (i = 0; i < opr_sz / 2; ++i) {
468
+ switch (offset) {
132
+ d[i] = do_sqrdmlah_h(n[i], m[i], 0, false, true, &discard);
469
+ case TWI_ADDR_REG:
470
+ value = s->addr;
471
+ break;
472
+ case TWI_XADDR_REG:
473
+ value = s->xaddr;
474
+ break;
475
+ case TWI_DATA_REG:
476
+ if ((STAT_TO_STA(s->stat) == STAT_M_ADDR_RD_ACK) ||
477
+ (STAT_TO_STA(s->stat) == STAT_M_DATA_RX_ACK) ||
478
+ (STAT_TO_STA(s->stat) == STAT_M_DATA_RX_NACK)) {
479
+ /* Get the next byte */
480
+ s->data = i2c_recv(s->bus);
481
+
482
+ if (s->cntr & TWI_CNTR_A_ACK) {
483
+ s->stat = STAT_FROM_STA(STAT_M_DATA_RX_ACK);
484
+ } else {
485
+ s->stat = STAT_FROM_STA(STAT_M_DATA_RX_NACK);
486
+ }
487
+ allwinner_i2c_raise_interrupt(s);
488
+ }
489
+ value = s->data;
490
+ break;
491
+ case TWI_CNTR_REG:
492
+ value = s->cntr;
493
+ break;
494
+ case TWI_STAT_REG:
495
+ value = s->stat;
496
+ /*
497
+ * If polling when reading then change state to indicate data
498
+ * is available
499
+ */
500
+ if (STAT_TO_STA(s->stat) == STAT_M_ADDR_RD_ACK) {
501
+ if (s->cntr & TWI_CNTR_A_ACK) {
502
+ s->stat = STAT_FROM_STA(STAT_M_DATA_RX_ACK);
503
+ } else {
504
+ s->stat = STAT_FROM_STA(STAT_M_DATA_RX_NACK);
505
+ }
506
+ allwinner_i2c_raise_interrupt(s);
507
+ }
508
+ break;
509
+ case TWI_CCR_REG:
510
+ value = s->ccr;
511
+ break;
512
+ case TWI_SRST_REG:
513
+ value = s->srst;
514
+ break;
515
+ case TWI_EFR_REG:
516
+ value = s->efr;
517
+ break;
518
+ case TWI_LCR_REG:
519
+ value = s->lcr;
520
+ break;
521
+ default:
522
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
523
+ HWADDR_PRIx "\n", TYPE_AW_I2C, __func__, offset);
524
+ value = 0;
525
+ break;
133
+ }
526
+ }
134
+}
527
+
135
+
528
+ trace_allwinner_i2c_read(allwinner_i2c_get_regname(offset), offset, value);
136
/* Signed saturating rounding doubling multiply-accumulate high half, 32-bit */
529
+
137
int32_t do_sqrdmlah_s(int32_t src1, int32_t src2, int32_t src3,
530
+ return (uint64_t)value;
138
bool neg, bool round, uint32_t *sat)
531
+}
139
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_sqrdmlsh_s)(void *vd, void *vn, void *vm,
532
+
140
}
533
+static void allwinner_i2c_write(void *opaque, hwaddr offset,
141
}
534
+ uint64_t value, unsigned size)
142
535
+{
143
+void HELPER(sve2_sqdmulh_s)(void *vd, void *vn, void *vm, uint32_t desc)
536
+ AWI2CState *s = AW_I2C(opaque);
144
+{
537
+
145
+ intptr_t i, opr_sz = simd_oprsz(desc);
538
+ value &= 0xff;
146
+ int32_t *d = vd, *n = vn, *m = vm;
539
+
147
+ uint32_t discard;
540
+ trace_allwinner_i2c_write(allwinner_i2c_get_regname(offset), offset, value);
148
+
541
+
149
+ for (i = 0; i < opr_sz / 4; ++i) {
542
+ switch (offset) {
150
+ d[i] = do_sqrdmlah_s(n[i], m[i], 0, false, false, &discard);
543
+ case TWI_ADDR_REG:
544
+ s->addr = (uint8_t)value;
545
+ break;
546
+ case TWI_XADDR_REG:
547
+ s->xaddr = (uint8_t)value;
548
+ break;
549
+ case TWI_DATA_REG:
550
+ /* If the device is in reset or not enabled, nothing to do */
551
+ if (allwinner_i2c_is_reset(s) || (!allwinner_i2c_bus_is_enabled(s))) {
552
+ break;
553
+ }
554
+
555
+ s->data = value & TWI_DATA_MASK;
556
+
557
+ switch (STAT_TO_STA(s->stat)) {
558
+ case STAT_M_STA_TX:
559
+ case STAT_M_RSTA_TX:
560
+ /* Send address */
561
+ if (i2c_start_transfer(s->bus, extract32(s->data, 1, 7),
562
+ extract32(s->data, 0, 1))) {
563
+ /* If non zero is returned, the address is not valid */
564
+ s->stat = STAT_FROM_STA(STAT_M_ADDR_WR_NACK);
565
+ } else {
566
+ /* Determine if read of write */
567
+ if (extract32(s->data, 0, 1)) {
568
+ s->stat = STAT_FROM_STA(STAT_M_ADDR_RD_ACK);
569
+ } else {
570
+ s->stat = STAT_FROM_STA(STAT_M_ADDR_WR_ACK);
571
+ }
572
+ allwinner_i2c_raise_interrupt(s);
573
+ }
574
+ break;
575
+ case STAT_M_ADDR_WR_ACK:
576
+ case STAT_M_DATA_TX_ACK:
577
+ if (i2c_send(s->bus, s->data)) {
578
+ /* If the target return non zero then end the transfer */
579
+ s->stat = STAT_FROM_STA(STAT_M_DATA_TX_NACK);
580
+ i2c_end_transfer(s->bus);
581
+ } else {
582
+ s->stat = STAT_FROM_STA(STAT_M_DATA_TX_ACK);
583
+ allwinner_i2c_raise_interrupt(s);
584
+ }
585
+ break;
586
+ default:
587
+ break;
588
+ }
589
+ break;
590
+ case TWI_CNTR_REG:
591
+ if (!allwinner_i2c_is_reset(s)) {
592
+ /* Do something only if not in software reset */
593
+ s->cntr = value & TWI_CNTR_MASK;
594
+
595
+ /* Check if start condition should be sent */
596
+ if (s->cntr & TWI_CNTR_M_STA) {
597
+ /* Update status */
598
+ if (STAT_TO_STA(s->stat) == STAT_IDLE) {
599
+ /* Send start condition */
600
+ s->stat = STAT_FROM_STA(STAT_M_STA_TX);
601
+ } else {
602
+ /* Send repeated start condition */
603
+ s->stat = STAT_FROM_STA(STAT_M_RSTA_TX);
604
+ }
605
+ /* Clear start condition */
606
+ s->cntr &= ~TWI_CNTR_M_STA;
607
+ }
608
+ if (s->cntr & TWI_CNTR_M_STP) {
609
+ /* Update status */
610
+ i2c_end_transfer(s->bus);
611
+ s->stat = STAT_FROM_STA(STAT_IDLE);
612
+ s->cntr &= ~TWI_CNTR_M_STP;
613
+ }
614
+ if ((s->cntr & TWI_CNTR_INT_FLAG) == 0) {
615
+ /* Interrupt flag cleared */
616
+ qemu_irq_lower(s->irq);
617
+ }
618
+ if ((s->cntr & TWI_CNTR_A_ACK) == 0) {
619
+ if (STAT_TO_STA(s->stat) == STAT_M_DATA_RX_ACK) {
620
+ s->stat = STAT_FROM_STA(STAT_M_DATA_RX_NACK);
621
+ }
622
+ } else {
623
+ if (STAT_TO_STA(s->stat) == STAT_M_DATA_RX_NACK) {
624
+ s->stat = STAT_FROM_STA(STAT_M_DATA_RX_ACK);
625
+ }
626
+ }
627
+ allwinner_i2c_raise_interrupt(s);
628
+
629
+ }
630
+ break;
631
+ case TWI_CCR_REG:
632
+ s->ccr = value & TWI_CCR_MASK;
633
+ break;
634
+ case TWI_SRST_REG:
635
+ if (((value & TWI_SRST_MASK) == 0) && (s->srst & TWI_SRST_MASK)) {
636
+ /* Perform reset */
637
+ allwinner_i2c_reset_hold(OBJECT(s));
638
+ }
639
+ s->srst = value & TWI_SRST_MASK;
640
+ break;
641
+ case TWI_EFR_REG:
642
+ s->efr = value & TWI_EFR_MASK;
643
+ break;
644
+ case TWI_LCR_REG:
645
+ s->lcr = value & TWI_LCR_MASK;
646
+ break;
647
+ default:
648
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
649
+ HWADDR_PRIx "\n", TYPE_AW_I2C, __func__, offset);
650
+ break;
151
+ }
651
+ }
152
+}
652
+}
153
+
653
+
154
+void HELPER(sve2_sqrdmulh_s)(void *vd, void *vn, void *vm, uint32_t desc)
654
+static const MemoryRegionOps allwinner_i2c_ops = {
155
+{
655
+ .read = allwinner_i2c_read,
156
+ intptr_t i, opr_sz = simd_oprsz(desc);
656
+ .write = allwinner_i2c_write,
157
+ int32_t *d = vd, *n = vn, *m = vm;
657
+ .valid.min_access_size = 1,
158
+ uint32_t discard;
658
+ .valid.max_access_size = 4,
159
+
659
+ .endianness = DEVICE_NATIVE_ENDIAN,
160
+ for (i = 0; i < opr_sz / 4; ++i) {
660
+};
161
+ d[i] = do_sqrdmlah_s(n[i], m[i], 0, false, true, &discard);
661
+
662
+static const VMStateDescription allwinner_i2c_vmstate = {
663
+ .name = TYPE_AW_I2C,
664
+ .version_id = 1,
665
+ .minimum_version_id = 1,
666
+ .fields = (VMStateField[]) {
667
+ VMSTATE_UINT8(addr, AWI2CState),
668
+ VMSTATE_UINT8(xaddr, AWI2CState),
669
+ VMSTATE_UINT8(data, AWI2CState),
670
+ VMSTATE_UINT8(cntr, AWI2CState),
671
+ VMSTATE_UINT8(ccr, AWI2CState),
672
+ VMSTATE_UINT8(srst, AWI2CState),
673
+ VMSTATE_UINT8(efr, AWI2CState),
674
+ VMSTATE_UINT8(lcr, AWI2CState),
675
+ VMSTATE_END_OF_LIST()
162
+ }
676
+ }
163
+}
677
+};
164
+
678
+
165
/* Signed saturating rounding doubling multiply-accumulate high half, 64-bit */
679
+static void allwinner_i2c_realize(DeviceState *dev, Error **errp)
166
static int64_t do_sat128_d(Int128 r)
680
+{
167
{
681
+ AWI2CState *s = AW_I2C(dev);
168
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_sqrdmlsh_d)(void *vd, void *vn, void *vm,
682
+
169
}
683
+ memory_region_init_io(&s->iomem, OBJECT(s), &allwinner_i2c_ops, s,
170
}
684
+ TYPE_AW_I2C, AW_I2C_MEM_SIZE);
171
685
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
172
+void HELPER(sve2_sqdmulh_d)(void *vd, void *vn, void *vm, uint32_t desc)
686
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
173
+{
687
+ s->bus = i2c_init_bus(dev, "i2c");
174
+ intptr_t i, opr_sz = simd_oprsz(desc);
688
+}
175
+ int64_t *d = vd, *n = vn, *m = vm;
689
+
176
+
690
+static void allwinner_i2c_class_init(ObjectClass *klass, void *data)
177
+ for (i = 0; i < opr_sz / 8; ++i) {
691
+{
178
+ d[i] = do_sqrdmlah_d(n[i], m[i], 0, false, false);
692
+ DeviceClass *dc = DEVICE_CLASS(klass);
179
+ }
693
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
180
+}
694
+
181
+
695
+ rc->phases.hold = allwinner_i2c_reset_hold;
182
+void HELPER(sve2_sqrdmulh_d)(void *vd, void *vn, void *vm, uint32_t desc)
696
+ dc->vmsd = &allwinner_i2c_vmstate;
183
+{
697
+ dc->realize = allwinner_i2c_realize;
184
+ intptr_t i, opr_sz = simd_oprsz(desc);
698
+ dc->desc = "Allwinner I2C Controller";
185
+ int64_t *d = vd, *n = vn, *m = vm;
699
+}
186
+
700
+
187
+ for (i = 0; i < opr_sz / 8; ++i) {
701
+static const TypeInfo allwinner_i2c_type_info = {
188
+ d[i] = do_sqrdmlah_d(n[i], m[i], 0, false, true);
702
+ .name = TYPE_AW_I2C,
189
+ }
703
+ .parent = TYPE_SYS_BUS_DEVICE,
190
+}
704
+ .instance_size = sizeof(AWI2CState),
191
+
705
+ .class_init = allwinner_i2c_class_init,
192
/* Integer 8 and 16-bit dot-product.
706
+};
193
*
707
+
194
* Note that for the loops herein, host endianness does not matter
708
+static void allwinner_i2c_register_types(void)
709
+{
710
+ type_register_static(&allwinner_i2c_type_info);
711
+}
712
+
713
+type_init(allwinner_i2c_register_types)
714
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
715
index XXXXXXX..XXXXXXX 100644
716
--- a/hw/arm/Kconfig
717
+++ b/hw/arm/Kconfig
718
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_A10
719
select ALLWINNER_A10_CCM
720
select ALLWINNER_A10_DRAMC
721
select ALLWINNER_EMAC
722
+ select ALLWINNER_I2C
723
select SERIAL
724
select UNIMP
725
726
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_H3
727
bool
728
select ALLWINNER_A10_PIT
729
select ALLWINNER_SUN8I_EMAC
730
+ select ALLWINNER_I2C
731
select SERIAL
732
select ARM_TIMER
733
select ARM_GIC
734
diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig
735
index XXXXXXX..XXXXXXX 100644
736
--- a/hw/i2c/Kconfig
737
+++ b/hw/i2c/Kconfig
738
@@ -XXX,XX +XXX,XX @@ config MPC_I2C
739
bool
740
select I2C
741
742
+config ALLWINNER_I2C
743
+ bool
744
+ select I2C
745
+
746
config PCA954X
747
bool
748
select I2C
749
diff --git a/hw/i2c/meson.build b/hw/i2c/meson.build
750
index XXXXXXX..XXXXXXX 100644
751
--- a/hw/i2c/meson.build
752
+++ b/hw/i2c/meson.build
753
@@ -XXX,XX +XXX,XX @@ i2c_ss.add(when: 'CONFIG_BITBANG_I2C', if_true: files('bitbang_i2c.c'))
754
i2c_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_i2c.c'))
755
i2c_ss.add(when: 'CONFIG_IMX_I2C', if_true: files('imx_i2c.c'))
756
i2c_ss.add(when: 'CONFIG_MPC_I2C', if_true: files('mpc_i2c.c'))
757
+i2c_ss.add(when: 'CONFIG_ALLWINNER_I2C', if_true: files('allwinner-i2c.c'))
758
i2c_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('microbit_i2c.c'))
759
i2c_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_smbus.c'))
760
i2c_ss.add(when: 'CONFIG_SMBUS_EEPROM', if_true: files('smbus_eeprom.c'))
761
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
762
index XXXXXXX..XXXXXXX 100644
763
--- a/hw/i2c/trace-events
764
+++ b/hw/i2c/trace-events
765
@@ -XXX,XX +XXX,XX @@ i2c_send_async(uint8_t address, uint8_t data) "send_async(addr:0x%02x) data:0x%0
766
i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x"
767
i2c_ack(void) ""
768
769
+# allwinner_i2c.c
770
+
771
+allwinner_i2c_read(const char* reg_name, uint64_t offset, uint64_t value) "read %s [0x%" PRIx64 "]: -> 0x%" PRIx64
772
+allwinner_i2c_write(const char* reg_name, uint64_t offset, uint64_t value) "write %s [0x%" PRIx64 "]: <- 0x%" PRIx64
773
+
774
# aspeed_i2c.c
775
776
aspeed_i2c_bus_cmd(uint32_t cmd, const char *cmd_flags, uint32_t count, uint32_t intr_status) "handling cmd=0x%x %s count=%d intr=0x%x"
195
--
777
--
196
2.20.1
778
2.34.1
197
198
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
2
2
3
Rename the existing sve_while (less-than) helper to sve_whilel
3
This patch adds minimal support for AXP-209 PMU.
4
to make room for a new sve_whileg helper for greater-than.
4
Most important is chip ID since U-Boot SPL expects version 0x1. Besides
5
the chip ID register, reset values for two more registers used by A10
6
U-Boot SPL are covered.
5
7
8
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
9
Message-id: 20221226220303.14420-5-strahinja.p.jankovic@gmail.com
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210525010358.152808-31-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/helper-sve.h | 3 +-
13
hw/misc/axp209.c | 238 +++++++++++++++++++++++++++++++++++++++++++
12
target/arm/sve.decode | 2 +-
14
MAINTAINERS | 2 +
13
target/arm/sve_helper.c | 38 +++++++++++++++++++++++++-
15
hw/misc/Kconfig | 4 +
14
target/arm/translate-sve.c | 56 ++++++++++++++++++++++++++++----------
16
hw/misc/meson.build | 1 +
15
4 files changed, 82 insertions(+), 17 deletions(-)
17
hw/misc/trace-events | 5 +
18
5 files changed, 250 insertions(+)
19
create mode 100644 hw/misc/axp209.c
16
20
17
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
21
diff --git a/hw/misc/axp209.c b/hw/misc/axp209.c
18
index XXXXXXX..XXXXXXX 100644
22
new file mode 100644
19
--- a/target/arm/helper-sve.h
23
index XXXXXXX..XXXXXXX
20
+++ b/target/arm/helper-sve.h
24
--- /dev/null
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_brkns, TCG_CALL_NO_RWG, i32, ptr, ptr, ptr, i32)
25
+++ b/hw/misc/axp209.c
22
26
@@ -XXX,XX +XXX,XX @@
23
DEF_HELPER_FLAGS_3(sve_cntp, TCG_CALL_NO_RWG, i64, ptr, ptr, i32)
27
+/*
24
28
+ * AXP-209 PMU Emulation
25
-DEF_HELPER_FLAGS_3(sve_while, TCG_CALL_NO_RWG, i32, ptr, i32, i32)
29
+ *
26
+DEF_HELPER_FLAGS_3(sve_whilel, TCG_CALL_NO_RWG, i32, ptr, i32, i32)
30
+ * Copyright (C) 2022 Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
27
+DEF_HELPER_FLAGS_3(sve_whileg, TCG_CALL_NO_RWG, i32, ptr, i32, i32)
31
+ *
28
32
+ * Permission is hereby granted, free of charge, to any person obtaining a
29
DEF_HELPER_FLAGS_4(sve_subri_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
33
+ * copy of this software and associated documentation files (the "Software"),
30
DEF_HELPER_FLAGS_4(sve_subri_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
34
+ * to deal in the Software without restriction, including without limitation
31
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
35
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
32
index XXXXXXX..XXXXXXX 100644
36
+ * and/or sell copies of the Software, and to permit persons to whom the
33
--- a/target/arm/sve.decode
37
+ * Software is furnished to do so, subject to the following conditions:
34
+++ b/target/arm/sve.decode
38
+ *
35
@@ -XXX,XX +XXX,XX @@ SINCDECP_z 00100101 .. 1010 d:1 u:1 10000 00 .... ..... @incdec2_pred
39
+ * The above copyright notice and this permission notice shall be included in
36
CTERM 00100101 1 sf:1 1 rm:5 001000 rn:5 ne:1 0000
40
+ * all copies or substantial portions of the Software.
37
41
+ *
38
# SVE integer compare scalar count and limit
42
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39
-WHILE 00100101 esz:2 1 rm:5 000 sf:1 u:1 1 rn:5 eq:1 rd:4
43
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40
+WHILE 00100101 esz:2 1 rm:5 000 sf:1 u:1 lt:1 rn:5 eq:1 rd:4
44
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41
45
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42
### SVE Integer Wide Immediate - Unpredicated Group
46
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
43
47
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
44
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
48
+ * DEALINGS IN THE SOFTWARE.
45
index XXXXXXX..XXXXXXX 100644
49
+ *
46
--- a/target/arm/sve_helper.c
50
+ * SPDX-License-Identifier: MIT
47
+++ b/target/arm/sve_helper.c
51
+ */
48
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(sve_cntp)(void *vn, void *vg, uint32_t pred_desc)
52
+
49
return sum;
53
+#include "qemu/osdep.h"
50
}
54
+#include "qemu/log.h"
51
55
+#include "trace.h"
52
-uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
56
+#include "hw/i2c/i2c.h"
53
+uint32_t HELPER(sve_whilel)(void *vd, uint32_t count, uint32_t pred_desc)
57
+#include "migration/vmstate.h"
54
{
58
+
55
intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
59
+#define TYPE_AXP209_PMU "axp209_pmu"
56
intptr_t esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
60
+
57
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
61
+#define AXP209(obj) \
58
return predtest_ones(d, oprsz, esz_mask);
62
+ OBJECT_CHECK(AXP209I2CState, (obj), TYPE_AXP209_PMU)
59
}
63
+
60
64
+/* registers */
61
+uint32_t HELPER(sve_whileg)(void *vd, uint32_t count, uint32_t pred_desc)
65
+enum {
62
+{
66
+ REG_POWER_STATUS = 0x0u,
63
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
67
+ REG_OPERATING_MODE,
64
+ intptr_t esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
68
+ REG_OTG_VBUS_STATUS,
65
+ uint64_t esz_mask = pred_esz_masks[esz];
69
+ REG_CHIP_VERSION,
66
+ ARMPredicateReg *d = vd;
70
+ REG_DATA_CACHE_0,
67
+ intptr_t i, invcount, oprbits;
71
+ REG_DATA_CACHE_1,
68
+ uint64_t bits;
72
+ REG_DATA_CACHE_2,
69
+
73
+ REG_DATA_CACHE_3,
70
+ if (count == 0) {
74
+ REG_DATA_CACHE_4,
71
+ return do_zero(d, oprsz);
75
+ REG_DATA_CACHE_5,
76
+ REG_DATA_CACHE_6,
77
+ REG_DATA_CACHE_7,
78
+ REG_DATA_CACHE_8,
79
+ REG_DATA_CACHE_9,
80
+ REG_DATA_CACHE_A,
81
+ REG_DATA_CACHE_B,
82
+ REG_POWER_OUTPUT_CTRL = 0x12u,
83
+ REG_DC_DC2_OUT_V_CTRL = 0x23u,
84
+ REG_DC_DC2_DVS_CTRL = 0x25u,
85
+ REG_DC_DC3_OUT_V_CTRL = 0x27u,
86
+ REG_LDO2_4_OUT_V_CTRL,
87
+ REG_LDO3_OUT_V_CTRL,
88
+ REG_VBUS_CH_MGMT = 0x30u,
89
+ REG_SHUTDOWN_V_CTRL,
90
+ REG_SHUTDOWN_CTRL,
91
+ REG_CHARGE_CTRL_1,
92
+ REG_CHARGE_CTRL_2,
93
+ REG_SPARE_CHARGE_CTRL,
94
+ REG_PEK_KEY_CTRL,
95
+ REG_DC_DC_FREQ_SET,
96
+ REG_CHR_TEMP_TH_SET,
97
+ REG_CHR_HIGH_TEMP_TH_CTRL,
98
+ REG_IPSOUT_WARN_L1,
99
+ REG_IPSOUT_WARN_L2,
100
+ REG_DISCHR_TEMP_TH_SET,
101
+ REG_DISCHR_HIGH_TEMP_TH_CTRL,
102
+ REG_IRQ_BANK_1_CTRL = 0x40u,
103
+ REG_IRQ_BANK_2_CTRL,
104
+ REG_IRQ_BANK_3_CTRL,
105
+ REG_IRQ_BANK_4_CTRL,
106
+ REG_IRQ_BANK_5_CTRL,
107
+ REG_IRQ_BANK_1_STAT = 0x48u,
108
+ REG_IRQ_BANK_2_STAT,
109
+ REG_IRQ_BANK_3_STAT,
110
+ REG_IRQ_BANK_4_STAT,
111
+ REG_IRQ_BANK_5_STAT,
112
+ REG_ADC_ACIN_V_H = 0x56u,
113
+ REG_ADC_ACIN_V_L,
114
+ REG_ADC_ACIN_CURR_H,
115
+ REG_ADC_ACIN_CURR_L,
116
+ REG_ADC_VBUS_V_H,
117
+ REG_ADC_VBUS_V_L,
118
+ REG_ADC_VBUS_CURR_H,
119
+ REG_ADC_VBUS_CURR_L,
120
+ REG_ADC_INT_TEMP_H,
121
+ REG_ADC_INT_TEMP_L,
122
+ REG_ADC_TEMP_SENS_V_H = 0x62u,
123
+ REG_ADC_TEMP_SENS_V_L,
124
+ REG_ADC_BAT_V_H = 0x78u,
125
+ REG_ADC_BAT_V_L,
126
+ REG_ADC_BAT_DISCHR_CURR_H,
127
+ REG_ADC_BAT_DISCHR_CURR_L,
128
+ REG_ADC_BAT_CHR_CURR_H,
129
+ REG_ADC_BAT_CHR_CURR_L,
130
+ REG_ADC_IPSOUT_V_H,
131
+ REG_ADC_IPSOUT_V_L,
132
+ REG_DC_DC_MOD_SEL = 0x80u,
133
+ REG_ADC_EN_1,
134
+ REG_ADC_EN_2,
135
+ REG_ADC_SR_CTRL,
136
+ REG_ADC_IN_RANGE,
137
+ REG_GPIO1_ADC_IRQ_RISING_TH,
138
+ REG_GPIO1_ADC_IRQ_FALLING_TH,
139
+ REG_TIMER_CTRL = 0x8au,
140
+ REG_VBUS_CTRL_MON_SRP,
141
+ REG_OVER_TEMP_SHUTDOWN = 0x8fu,
142
+ REG_GPIO0_FEAT_SET,
143
+ REG_GPIO_OUT_HIGH_SET,
144
+ REG_GPIO1_FEAT_SET,
145
+ REG_GPIO2_FEAT_SET,
146
+ REG_GPIO_SIG_STATE_SET_MON,
147
+ REG_GPIO3_SET,
148
+ REG_COULOMB_CNTR_CTRL = 0xb8u,
149
+ REG_POWER_MEAS_RES,
150
+ NR_REGS
151
+};
152
+
153
+#define AXP209_CHIP_VERSION_ID (0x01)
154
+#define AXP209_DC_DC2_OUT_V_CTRL_RESET (0x16)
155
+#define AXP209_IRQ_BANK_1_CTRL_RESET (0xd8)
156
+
157
+/* A simple I2C slave which returns values of ID or CNT register. */
158
+typedef struct AXP209I2CState {
159
+ /*< private >*/
160
+ I2CSlave i2c;
161
+ /*< public >*/
162
+ uint8_t regs[NR_REGS]; /* peripheral registers */
163
+ uint8_t ptr; /* current register index */
164
+ uint8_t count; /* counter used for tx/rx */
165
+} AXP209I2CState;
166
+
167
+/* Reset all counters and load ID register */
168
+static void axp209_reset_enter(Object *obj, ResetType type)
169
+{
170
+ AXP209I2CState *s = AXP209(obj);
171
+
172
+ memset(s->regs, 0, NR_REGS);
173
+ s->ptr = 0;
174
+ s->count = 0;
175
+ s->regs[REG_CHIP_VERSION] = AXP209_CHIP_VERSION_ID;
176
+ s->regs[REG_DC_DC2_OUT_V_CTRL] = AXP209_DC_DC2_OUT_V_CTRL_RESET;
177
+ s->regs[REG_IRQ_BANK_1_CTRL] = AXP209_IRQ_BANK_1_CTRL_RESET;
178
+}
179
+
180
+/* Handle events from master. */
181
+static int axp209_event(I2CSlave *i2c, enum i2c_event event)
182
+{
183
+ AXP209I2CState *s = AXP209(i2c);
184
+
185
+ s->count = 0;
186
+
187
+ return 0;
188
+}
189
+
190
+/* Called when master requests read */
191
+static uint8_t axp209_rx(I2CSlave *i2c)
192
+{
193
+ AXP209I2CState *s = AXP209(i2c);
194
+ uint8_t ret = 0xff;
195
+
196
+ if (s->ptr < NR_REGS) {
197
+ ret = s->regs[s->ptr++];
72
+ }
198
+ }
73
+
199
+
74
+ oprbits = oprsz * 8;
200
+ trace_axp209_rx(s->ptr - 1, ret);
75
+ tcg_debug_assert(count <= oprbits);
201
+
76
+
202
+ return ret;
77
+ bits = esz_mask;
203
+}
78
+ if (oprbits & 63) {
204
+
79
+ bits &= MAKE_64BIT_MASK(0, oprbits & 63);
205
+/*
80
+ }
206
+ * Called when master sends write.
81
+
207
+ * Update ptr with byte 0, then perform write with second byte.
82
+ invcount = oprbits - count;
208
+ */
83
+ for (i = (oprsz - 1) / 8; i > invcount / 64; --i) {
209
+static int axp209_tx(I2CSlave *i2c, uint8_t data)
84
+ d->p[i] = bits;
210
+{
85
+ bits = esz_mask;
211
+ AXP209I2CState *s = AXP209(i2c);
86
+ }
212
+
87
+
213
+ if (s->count == 0) {
88
+ d->p[i] = bits & MAKE_64BIT_MASK(invcount & 63, 64);
214
+ /* Store register address */
89
+
215
+ s->ptr = data;
90
+ while (--i >= 0) {
216
+ s->count++;
91
+ d->p[i] = 0;
217
+ trace_axp209_select(data);
92
+ }
93
+
94
+ return predtest_ones(d, oprsz, esz_mask);
95
+}
96
+
97
/* Recursive reduction on a function;
98
* C.f. the ARM ARM function ReducePredicated.
99
*
100
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/translate-sve.c
103
+++ b/target/arm/translate-sve.c
104
@@ -XXX,XX +XXX,XX @@ static bool trans_WHILE(DisasContext *s, arg_WHILE *a)
105
unsigned vsz = vec_full_reg_size(s);
106
unsigned desc = 0;
107
TCGCond cond;
108
+ uint64_t maxval;
109
+ /* Note that GE/HS has a->eq == 0 and GT/HI has a->eq == 1. */
110
+ bool eq = a->eq == a->lt;
111
112
+ /* The greater-than conditions are all SVE2. */
113
+ if (!a->lt && !dc_isar_feature(aa64_sve2, s)) {
114
+ return false;
115
+ }
116
if (!sve_access_check(s)) {
117
return true;
118
}
119
@@ -XXX,XX +XXX,XX @@ static bool trans_WHILE(DisasContext *s, arg_WHILE *a)
120
*/
121
t0 = tcg_temp_new_i64();
122
t1 = tcg_temp_new_i64();
123
- tcg_gen_sub_i64(t0, op1, op0);
124
+
125
+ if (a->lt) {
126
+ tcg_gen_sub_i64(t0, op1, op0);
127
+ if (a->u) {
128
+ maxval = a->sf ? UINT64_MAX : UINT32_MAX;
129
+ cond = eq ? TCG_COND_LEU : TCG_COND_LTU;
130
+ } else {
131
+ maxval = a->sf ? INT64_MAX : INT32_MAX;
132
+ cond = eq ? TCG_COND_LE : TCG_COND_LT;
133
+ }
134
+ } else {
218
+ } else {
135
+ tcg_gen_sub_i64(t0, op0, op1);
219
+ trace_axp209_tx(s->ptr, data);
136
+ if (a->u) {
220
+ if (s->ptr == REG_DC_DC2_OUT_V_CTRL) {
137
+ maxval = 0;
221
+ s->regs[s->ptr++] = data;
138
+ cond = eq ? TCG_COND_GEU : TCG_COND_GTU;
139
+ } else {
140
+ maxval = a->sf ? INT64_MIN : INT32_MIN;
141
+ cond = eq ? TCG_COND_GE : TCG_COND_GT;
142
+ }
222
+ }
143
+ }
223
+ }
144
224
+
145
tmax = tcg_const_i64(vsz >> a->esz);
225
+ return 0;
146
- if (a->eq) {
226
+}
147
+ if (eq) {
227
+
148
/* Equality means one more iteration. */
228
+static const VMStateDescription vmstate_axp209 = {
149
tcg_gen_addi_i64(t0, t0, 1);
229
+ .name = TYPE_AXP209_PMU,
150
230
+ .version_id = 1,
151
- /* If op1 is max (un)signed integer (and the only time the addition
231
+ .fields = (VMStateField[]) {
152
- * above could overflow), then we produce an all-true predicate by
232
+ VMSTATE_UINT8_ARRAY(regs, AXP209I2CState, NR_REGS),
153
- * setting the count to the vector length. This is because the
233
+ VMSTATE_UINT8(count, AXP209I2CState),
154
- * pseudocode is described as an increment + compare loop, and the
234
+ VMSTATE_UINT8(ptr, AXP209I2CState),
155
- * max integer would always compare true.
235
+ VMSTATE_END_OF_LIST()
156
+ /*
157
+ * For the less-than while, if op1 is maxval (and the only time
158
+ * the addition above could overflow), then we produce an all-true
159
+ * predicate by setting the count to the vector length. This is
160
+ * because the pseudocode is described as an increment + compare
161
+ * loop, and the maximum integer would always compare true.
162
+ * Similarly, the greater-than while has the same issue with the
163
+ * minimum integer due to the decrement + compare loop.
164
*/
165
- tcg_gen_movi_i64(t1, (a->sf
166
- ? (a->u ? UINT64_MAX : INT64_MAX)
167
- : (a->u ? UINT32_MAX : INT32_MAX)));
168
+ tcg_gen_movi_i64(t1, maxval);
169
tcg_gen_movcond_i64(TCG_COND_EQ, t0, op1, t1, tmax, t0);
170
}
171
172
@@ -XXX,XX +XXX,XX @@ static bool trans_WHILE(DisasContext *s, arg_WHILE *a)
173
tcg_temp_free_i64(tmax);
174
175
/* Set the count to zero if the condition is false. */
176
- cond = (a->u
177
- ? (a->eq ? TCG_COND_LEU : TCG_COND_LTU)
178
- : (a->eq ? TCG_COND_LE : TCG_COND_LT));
179
tcg_gen_movi_i64(t1, 0);
180
tcg_gen_movcond_i64(cond, t0, op0, op1, t0, t1);
181
tcg_temp_free_i64(t1);
182
@@ -XXX,XX +XXX,XX @@ static bool trans_WHILE(DisasContext *s, arg_WHILE *a)
183
ptr = tcg_temp_new_ptr();
184
tcg_gen_addi_ptr(ptr, cpu_env, pred_full_reg_offset(s, a->rd));
185
186
- gen_helper_sve_while(t2, ptr, t2, t3);
187
+ if (a->lt) {
188
+ gen_helper_sve_whilel(t2, ptr, t2, t3);
189
+ } else {
190
+ gen_helper_sve_whileg(t2, ptr, t2, t3);
191
+ }
236
+ }
192
do_pred_flags(t2);
237
+};
193
238
+
194
tcg_temp_free_ptr(ptr);
239
+static void axp209_class_init(ObjectClass *oc, void *data)
240
+{
241
+ DeviceClass *dc = DEVICE_CLASS(oc);
242
+ I2CSlaveClass *isc = I2C_SLAVE_CLASS(oc);
243
+ ResettableClass *rc = RESETTABLE_CLASS(oc);
244
+
245
+ rc->phases.enter = axp209_reset_enter;
246
+ dc->vmsd = &vmstate_axp209;
247
+ isc->event = axp209_event;
248
+ isc->recv = axp209_rx;
249
+ isc->send = axp209_tx;
250
+}
251
+
252
+static const TypeInfo axp209_info = {
253
+ .name = TYPE_AXP209_PMU,
254
+ .parent = TYPE_I2C_SLAVE,
255
+ .instance_size = sizeof(AXP209I2CState),
256
+ .class_init = axp209_class_init
257
+};
258
+
259
+static void axp209_register_devices(void)
260
+{
261
+ type_register_static(&axp209_info);
262
+}
263
+
264
+type_init(axp209_register_devices);
265
diff --git a/MAINTAINERS b/MAINTAINERS
266
index XXXXXXX..XXXXXXX 100644
267
--- a/MAINTAINERS
268
+++ b/MAINTAINERS
269
@@ -XXX,XX +XXX,XX @@ ARM Machines
270
Allwinner-a10
271
M: Beniamino Galvani <b.galvani@gmail.com>
272
M: Peter Maydell <peter.maydell@linaro.org>
273
+R: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
274
L: qemu-arm@nongnu.org
275
S: Odd Fixes
276
F: hw/*/allwinner*
277
F: include/hw/*/allwinner*
278
F: hw/arm/cubieboard.c
279
F: docs/system/arm/cubieboard.rst
280
+F: hw/misc/axp209.c
281
282
Allwinner-h3
283
M: Niek Linnenbank <nieklinnenbank@gmail.com>
284
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
285
index XXXXXXX..XXXXXXX 100644
286
--- a/hw/misc/Kconfig
287
+++ b/hw/misc/Kconfig
288
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_A10_CCM
289
config ALLWINNER_A10_DRAMC
290
bool
291
292
+config AXP209_PMU
293
+ bool
294
+ depends on I2C
295
+
296
source macio/Kconfig
297
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
298
index XXXXXXX..XXXXXXX 100644
299
--- a/hw/misc/meson.build
300
+++ b/hw/misc/meson.build
301
@@ -XXX,XX +XXX,XX @@ specific_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-cpucfg.c'
302
softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-dramc.c'))
303
softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-sysctrl.c'))
304
softmmu_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-sid.c'))
305
+softmmu_ss.add(when: 'CONFIG_AXP209_PMU', if_true: files('axp209.c'))
306
softmmu_ss.add(when: 'CONFIG_REALVIEW', if_true: files('arm_sysctl.c'))
307
softmmu_ss.add(when: 'CONFIG_NSERIES', if_true: files('cbus.c'))
308
softmmu_ss.add(when: 'CONFIG_ECCMEMCTL', if_true: files('eccmemctl.c'))
309
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
310
index XXXXXXX..XXXXXXX 100644
311
--- a/hw/misc/trace-events
312
+++ b/hw/misc/trace-events
313
@@ -XXX,XX +XXX,XX @@ allwinner_sid_write(uint64_t offset, uint64_t data, unsigned size) "offset 0x%"
314
avr_power_read(uint8_t value) "power_reduc read value:%u"
315
avr_power_write(uint8_t value) "power_reduc write value:%u"
316
317
+# axp209.c
318
+axp209_rx(uint8_t reg, uint8_t data) "Read reg 0x%" PRIx8 " : 0x%" PRIx8
319
+axp209_select(uint8_t reg) "Accessing reg 0x%" PRIx8
320
+axp209_tx(uint8_t reg, uint8_t data) "Write reg 0x%" PRIx8 " : 0x%" PRIx8
321
+
322
# eccmemctl.c
323
ecc_mem_writel_mer(uint32_t val) "Write memory enable 0x%08x"
324
ecc_mem_writel_mdr(uint32_t val) "Write memory delay 0x%08x"
195
--
325
--
196
2.20.1
326
2.34.1
197
198
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
2
2
3
6d9cd115b9 ("hw/arm/smmuv3: Enforce invalidation on a power of two range")
3
SPL Boot for Cubieboard expects AXP209 connected to I2C0 bus.
4
failed to completely fix misalignment issues with range
5
invalidation. For instance invalidations patterns like "invalidate 32
6
4kB pages starting from 0xff395000 are not correctly handled" due
7
to the fact the previous fix only made sure the number of invalidated
8
pages were a power of 2 but did not properly handle the start
9
address was not aligned with the range. This can be noticed when
10
boothing a fedora 33 with protected virtio-blk-pci.
11
4
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
5
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
13
Fixes: 6d9cd115b9 ("hw/arm/smmuv3: Enforce invalidation on a power of two range")
6
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20221226220303.14420-6-strahinja.p.jankovic@gmail.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
10
---
17
hw/arm/smmuv3.c | 50 +++++++++++++++++++++++++------------------------
11
hw/arm/cubieboard.c | 6 ++++++
18
1 file changed, 26 insertions(+), 24 deletions(-)
12
hw/arm/Kconfig | 1 +
13
2 files changed, 7 insertions(+)
19
14
20
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
15
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/smmuv3.c
17
--- a/hw/arm/cubieboard.c
23
+++ b/hw/arm/smmuv3.c
18
+++ b/hw/arm/cubieboard.c
24
@@ -XXX,XX +XXX,XX @@ static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova,
19
@@ -XXX,XX +XXX,XX @@
25
20
#include "hw/boards.h"
26
static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
21
#include "hw/qdev-properties.h"
27
{
22
#include "hw/arm/allwinner-a10.h"
28
- uint8_t scale = 0, num = 0, ttl = 0;
23
+#include "hw/i2c/i2c.h"
29
- dma_addr_t addr = CMD_ADDR(cmd);
24
30
+ dma_addr_t end, addr = CMD_ADDR(cmd);
25
static struct arm_boot_info cubieboard_binfo = {
31
uint8_t type = CMD_TYPE(cmd);
26
.loader_start = AW_A10_SDRAM_BASE,
32
uint16_t vmid = CMD_VMID(cmd);
27
@@ -XXX,XX +XXX,XX @@ static void cubieboard_init(MachineState *machine)
33
+ uint8_t scale = CMD_SCALE(cmd);
28
BlockBackend *blk;
34
+ uint8_t num = CMD_NUM(cmd);
29
BusState *bus;
35
+ uint8_t ttl = CMD_TTL(cmd);
30
DeviceState *carddev;
36
bool leaf = CMD_LEAF(cmd);
31
+ I2CBus *i2c;
37
uint8_t tg = CMD_TG(cmd);
32
38
- uint64_t first_page = 0, last_page;
33
/* BIOS is not supported by this board */
39
- uint64_t num_pages = 1;
34
if (machine->firmware) {
40
+ uint64_t num_pages;
35
@@ -XXX,XX +XXX,XX @@ static void cubieboard_init(MachineState *machine)
41
+ uint8_t granule;
36
exit(1);
42
int asid = -1;
43
44
- if (tg) {
45
- scale = CMD_SCALE(cmd);
46
- num = CMD_NUM(cmd);
47
- ttl = CMD_TTL(cmd);
48
- num_pages = (num + 1) * BIT_ULL(scale);
49
- }
50
-
51
if (type == SMMU_CMD_TLBI_NH_VA) {
52
asid = CMD_ASID(cmd);
53
}
37
}
54
38
55
+ if (!tg) {
39
+ /* Connect AXP 209 */
56
+ trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, 1, ttl, leaf);
40
+ i2c = I2C_BUS(qdev_get_child_bus(DEVICE(&a10->i2c0), "i2c"));
57
+ smmuv3_inv_notifiers_iova(s, asid, addr, tg, 1);
41
+ i2c_slave_create_simple(i2c, "axp209_pmu", 0x34);
58
+ smmu_iotlb_inv_iova(s, asid, addr, tg, 1, ttl);
59
+ return;
60
+ }
61
+
42
+
62
+ /* RIL in use */
43
/* Retrieve SD bus */
63
+
44
di = drive_get(IF_SD, 0, 0);
64
+ num_pages = (num + 1) * BIT_ULL(scale);
45
blk = di ? blk_by_legacy_dinfo(di) : NULL;
65
+ granule = tg * 2 + 10;
46
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
66
+
47
index XXXXXXX..XXXXXXX 100644
67
/* Split invalidations into ^2 range invalidations */
48
--- a/hw/arm/Kconfig
68
- last_page = num_pages - 1;
49
+++ b/hw/arm/Kconfig
69
- while (num_pages) {
50
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_A10
70
- uint8_t granule = tg * 2 + 10;
51
select ALLWINNER_A10_DRAMC
71
- uint64_t mask, count;
52
select ALLWINNER_EMAC
72
+ end = addr + (num_pages << granule) - 1;
53
select ALLWINNER_I2C
73
54
+ select AXP209_PMU
74
- mask = dma_aligned_pow2_mask(first_page, last_page, 64 - granule);
55
select SERIAL
75
- count = mask + 1;
56
select UNIMP
76
+ while (addr != end + 1) {
77
+ uint64_t mask = dma_aligned_pow2_mask(addr, end, 64);
78
79
- trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, count, ttl, leaf);
80
- smmuv3_inv_notifiers_iova(s, asid, addr, tg, count);
81
- smmu_iotlb_inv_iova(s, asid, addr, tg, count, ttl);
82
-
83
- num_pages -= count;
84
- first_page += count;
85
- addr += count * BIT_ULL(granule);
86
+ num_pages = (mask + 1) >> granule;
87
+ trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, num_pages, ttl, leaf);
88
+ smmuv3_inv_notifiers_iova(s, asid, addr, tg, num_pages);
89
+ smmu_iotlb_inv_iova(s, asid, addr, tg, num_pages, ttl);
90
+ addr += mask + 1;
91
}
92
}
93
57
94
--
58
--
95
2.20.1
59
2.34.1
96
60
97
61
diff view generated by jsdifflib
Deleted patch
1
In icc_eoir_write() we assume that we can identify the group of the
2
IRQ being completed based purely on which register is being written
3
to and the current CPU state, and that "CPU state matches group
4
indicated by register" is the only necessary access check.
5
1
6
This isn't correct: if the CPU is not in Secure state then EOIR1 will
7
only complete Group 1 NS IRQs, but if the CPU is in EL3 it can
8
complete both Group 1 S and Group 1 NS IRQs. (The pseudocode
9
ICC_EOIR1_EL1 makes this clear.) We were also missing the logic to
10
prevent EOIR0 writes completing G0 IRQs when they should not.
11
12
Rearrange the logic to first identify the group of the current
13
highest priority interrupt and then look at whether we should
14
complete it or ignore the access based on which register was accessed
15
and the state of the CPU. The resulting behavioural change is:
16
* EL3 can now complete G1NS interrupts
17
* G0 interrupt completion is now ignored if the GIC
18
and the CPU have the security extension enabled and
19
the CPU is not secure
20
21
Reported-by: Chan Kim <ckim@etri.re.kr>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20210510150016.24910-1-peter.maydell@linaro.org
26
---
27
hw/intc/arm_gicv3_cpuif.c | 48 ++++++++++++++++++++++++++-------------
28
1 file changed, 32 insertions(+), 16 deletions(-)
29
30
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/intc/arm_gicv3_cpuif.c
33
+++ b/hw/intc/arm_gicv3_cpuif.c
34
@@ -XXX,XX +XXX,XX @@ static void icc_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
35
GICv3CPUState *cs = icc_cs_from_env(env);
36
int irq = value & 0xffffff;
37
int grp;
38
+ bool is_eoir0 = ri->crm == 8;
39
40
- if (icv_access(env, ri->crm == 8 ? HCR_FMO : HCR_IMO)) {
41
+ if (icv_access(env, is_eoir0 ? HCR_FMO : HCR_IMO)) {
42
icv_eoir_write(env, ri, value);
43
return;
44
}
45
46
- trace_gicv3_icc_eoir_write(ri->crm == 8 ? 0 : 1,
47
+ trace_gicv3_icc_eoir_write(is_eoir0 ? 0 : 1,
48
gicv3_redist_affid(cs), value);
49
50
- if (ri->crm == 8) {
51
- /* EOIR0 */
52
- grp = GICV3_G0;
53
- } else {
54
- /* EOIR1 */
55
- if (arm_is_secure(env)) {
56
- grp = GICV3_G1;
57
- } else {
58
- grp = GICV3_G1NS;
59
- }
60
- }
61
-
62
if (irq >= cs->gic->num_irq) {
63
/* This handles two cases:
64
* 1. If software writes the ID of a spurious interrupt [ie 1020-1023]
65
@@ -XXX,XX +XXX,XX @@ static void icc_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
66
return;
67
}
68
69
- if (icc_highest_active_group(cs) != grp) {
70
- return;
71
+ grp = icc_highest_active_group(cs);
72
+ switch (grp) {
73
+ case GICV3_G0:
74
+ if (!is_eoir0) {
75
+ return;
76
+ }
77
+ if (!(cs->gic->gicd_ctlr & GICD_CTLR_DS)
78
+ && arm_feature(env, ARM_FEATURE_EL3) && !arm_is_secure(env)) {
79
+ return;
80
+ }
81
+ break;
82
+ case GICV3_G1:
83
+ if (is_eoir0) {
84
+ return;
85
+ }
86
+ if (!arm_is_secure(env)) {
87
+ return;
88
+ }
89
+ break;
90
+ case GICV3_G1NS:
91
+ if (is_eoir0) {
92
+ return;
93
+ }
94
+ if (!arm_is_el3_or_mon(env) && arm_is_secure(env)) {
95
+ return;
96
+ }
97
+ break;
98
+ default:
99
+ g_assert_not_reached();
100
}
101
102
icc_drop_prio(cs, grp);
103
--
104
2.20.1
105
106
diff view generated by jsdifflib
Deleted patch
1
The SRAM at 0x2000_0000 is part of the SSE-200 itself, and we model
2
it that way in hw/arm/armsse.c (along with the associated MPCs). We
3
incorrectly also added an entry to the RAMInfo array for the AN524 in
4
hw/arm/mps2-tz.c, which was pointless because the CPU would never see
5
it. Delete it.
6
1
7
The bug had no guest-visible effect because devices in the SSE-200
8
take priority over those in the board model (armsse.c maps
9
s->board_memory at priority -2).
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20210510190844.17799-2-peter.maydell@linaro.org
14
---
15
hw/arm/mps2-tz.c | 8 +-------
16
1 file changed, 1 insertion(+), 7 deletions(-)
17
18
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/mps2-tz.c
21
+++ b/hw/arm/mps2-tz.c
22
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an524_raminfo[] = { {
23
.size = 512 * KiB,
24
.mpc = 0,
25
.mrindex = 0,
26
- }, {
27
- .name = "sram",
28
- .base = 0x20000000,
29
- .size = 32 * 4 * KiB,
30
- .mpc = -1,
31
- .mrindex = 1,
32
}, {
33
/* We don't model QSPI flash yet; for now expose it as simple ROM */
34
.name = "QSPI",
35
.base = 0x28000000,
36
.size = 8 * MiB,
37
.mpc = 1,
38
- .mrindex = 2,
39
+ .mrindex = 1,
40
.flags = IS_ROM,
41
}, {
42
.name = "DDR",
43
--
44
2.20.1
45
46
diff view generated by jsdifflib
Deleted patch
1
The AN547 sets the SRAM_ADDR_WIDTH for the SSE-300 to 21;
2
since this is not the default value for the SSE-300, model this
3
in mps2-tz.c as a per-board value.
4
1
5
Reported-by: Devaraj Ranganna <devaraj.ranganna@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210510190844.17799-3-peter.maydell@linaro.org
9
---
10
hw/arm/mps2-tz.c | 6 ++++++
11
1 file changed, 6 insertions(+)
12
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
16
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
18
int numirq; /* Number of external interrupts */
19
int uart_overflow_irq; /* number of the combined UART overflow IRQ */
20
uint32_t init_svtor; /* init-svtor setting for SSE */
21
+ uint32_t sram_addr_width; /* SRAM_ADDR_WIDTH setting for SSE */
22
const RAMInfo *raminfo;
23
const char *armsse_type;
24
};
25
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
26
OBJECT(system_memory), &error_abort);
27
qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", mmc->numirq);
28
qdev_prop_set_uint32(iotkitdev, "init-svtor", mmc->init_svtor);
29
+ qdev_prop_set_uint32(iotkitdev, "SRAM_ADDR_WIDTH", mmc->sram_addr_width);
30
qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
31
qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
32
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
33
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
34
mmc->numirq = 92;
35
mmc->uart_overflow_irq = 47;
36
mmc->init_svtor = 0x10000000;
37
+ mmc->sram_addr_width = 15;
38
mmc->raminfo = an505_raminfo;
39
mmc->armsse_type = TYPE_IOTKIT;
40
mps2tz_set_default_ram_info(mmc);
41
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
42
mmc->numirq = 92;
43
mmc->uart_overflow_irq = 47;
44
mmc->init_svtor = 0x10000000;
45
+ mmc->sram_addr_width = 15;
46
mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
47
mmc->armsse_type = TYPE_SSE200;
48
mps2tz_set_default_ram_info(mmc);
49
@@ -XXX,XX +XXX,XX @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
50
mmc->numirq = 95;
51
mmc->uart_overflow_irq = 47;
52
mmc->init_svtor = 0x10000000;
53
+ mmc->sram_addr_width = 15;
54
mmc->raminfo = an524_raminfo;
55
mmc->armsse_type = TYPE_SSE200;
56
mps2tz_set_default_ram_info(mmc);
57
@@ -XXX,XX +XXX,XX @@ static void mps3tz_an547_class_init(ObjectClass *oc, void *data)
58
mmc->numirq = 96;
59
mmc->uart_overflow_irq = 48;
60
mmc->init_svtor = 0x00000000;
61
+ mmc->sram_addr_width = 21;
62
mmc->raminfo = an547_raminfo;
63
mmc->armsse_type = TYPE_SSE300;
64
mps2tz_set_default_ram_info(mmc);
65
--
66
2.20.1
67
68
diff view generated by jsdifflib
Deleted patch
1
The SSE-300 was not correctly modelling its internal SRAMs:
2
* the SRAM address width default is 18
3
* the SRAM is mapped at 0x2100_0000, not 0x2000_0000 like
4
the SSE-200 and IoTKit
5
1
6
The default address width is no longer guest-visible since
7
our only SSE-300 board sets it explicitly to a non-default
8
value, but following the hardware's default will help for
9
any future boards we need to model.
10
11
Reported-by: Devaraj Ranganna <devaraj.ranganna@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210510190844.17799-4-peter.maydell@linaro.org
15
---
16
hw/arm/armsse.c | 8 ++++++--
17
1 file changed, 6 insertions(+), 2 deletions(-)
18
19
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/armsse.c
22
+++ b/hw/arm/armsse.c
23
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
24
const char *cpu_type;
25
uint32_t sse_version;
26
int sram_banks;
27
+ uint32_t sram_bank_base;
28
int num_cpus;
29
uint32_t sys_version;
30
uint32_t iidr;
31
@@ -XXX,XX +XXX,XX @@ static Property sse300_properties[] = {
32
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
33
MemoryRegion *),
34
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
35
- DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
36
+ DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 18),
37
DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
38
DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
39
DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
40
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
41
.sse_version = ARMSSE_IOTKIT,
42
.cpu_type = ARM_CPU_TYPE_NAME("cortex-m33"),
43
.sram_banks = 1,
44
+ .sram_bank_base = 0x20000000,
45
.num_cpus = 1,
46
.sys_version = 0x41743,
47
.iidr = 0,
48
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
49
.sse_version = ARMSSE_SSE200,
50
.cpu_type = ARM_CPU_TYPE_NAME("cortex-m33"),
51
.sram_banks = 4,
52
+ .sram_bank_base = 0x20000000,
53
.num_cpus = 2,
54
.sys_version = 0x22041743,
55
.iidr = 0,
56
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
57
.sse_version = ARMSSE_SSE300,
58
.cpu_type = ARM_CPU_TYPE_NAME("cortex-m55"),
59
.sram_banks = 2,
60
+ .sram_bank_base = 0x21000000,
61
.num_cpus = 1,
62
.sys_version = 0x7e00043b,
63
.iidr = 0x74a0043b,
64
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
65
/* Map the upstream end of the MPC into the right place... */
66
sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
67
memory_region_add_subregion(&s->container,
68
- 0x20000000 + i * sram_bank_size,
69
+ info->sram_bank_base + i * sram_bank_size,
70
sysbus_mmio_get_region(sbd_mpc, 1));
71
/* ...and its register interface */
72
memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
73
--
74
2.20.1
75
76
diff view generated by jsdifflib
Deleted patch
1
Convert armsse_realize() to use ERRP_GUARD(), following
2
the rules in include/qapi/error.h.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210510190844.17799-5-peter.maydell@linaro.org
7
---
8
hw/arm/armsse.c | 8 ++++----
9
1 file changed, 4 insertions(+), 4 deletions(-)
10
11
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/armsse.c
14
+++ b/hw/arm/armsse.c
15
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
16
const ARMSSEDeviceInfo *devinfo;
17
int i;
18
MemoryRegion *mr;
19
- Error *err = NULL;
20
SysBusDevice *sbd_apb_ppc0;
21
SysBusDevice *sbd_secctl;
22
DeviceState *dev_apb_ppc0;
23
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
24
DeviceState *dev_splitter;
25
uint32_t addr_width_max;
26
27
+ ERRP_GUARD();
28
+
29
if (!s->board_memory) {
30
error_setg(errp, "memory property was not set");
31
return;
32
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
33
uint32_t sram_bank_size = 1 << s->sram_addr_width;
34
35
memory_region_init_ram(&s->sram[i], NULL, ramname,
36
- sram_bank_size, &err);
37
+ sram_bank_size, errp);
38
g_free(ramname);
39
- if (err) {
40
- error_propagate(errp, err);
41
+ if (*errp) {
42
return;
43
}
44
object_property_set_link(OBJECT(&s->mpc[i]), "downstream",
45
--
46
2.20.1
47
48
diff view generated by jsdifflib
1
From: Stephen Long <steplong@quicinc.com>
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
This patch enables copying of SPL from MMC if `-kernel` parameter is not
4
Signed-off-by: Stephen Long <steplong@quicinc.com>
4
passed when starting QEMU. SPL is copied to SRAM_A.
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
6
Message-id: 20210525010358.152808-43-richard.henderson@linaro.org
6
The approach is reused from Allwinner H3 implementation.
7
Message-Id: <20200416173109.8856-1-steplong@quicinc.com>
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested with Armbian and custom Yocto image.
9
10
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
11
12
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
13
Message-id: 20221226220303.14420-7-strahinja.p.jankovic@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
15
---
11
target/arm/helper-sve.h | 7 ++
16
include/hw/arm/allwinner-a10.h | 21 +++++++++++++++++++++
12
target/arm/sve.decode | 6 ++
17
hw/arm/allwinner-a10.c | 18 ++++++++++++++++++
13
target/arm/sve_helper.c | 131 +++++++++++++++++++++++++++++++++++++
18
hw/arm/cubieboard.c | 5 +++++
14
target/arm/translate-sve.c | 19 ++++++
19
3 files changed, 44 insertions(+)
15
4 files changed, 163 insertions(+)
16
20
17
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
21
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
18
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper-sve.h
23
--- a/include/hw/arm/allwinner-a10.h
20
+++ b/target/arm/helper-sve.h
24
+++ b/include/hw/arm/allwinner-a10.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_nmatch_ppzz_b, TCG_CALL_NO_RWG,
25
@@ -XXX,XX +XXX,XX @@
22
DEF_HELPER_FLAGS_5(sve2_nmatch_ppzz_h, TCG_CALL_NO_RWG,
26
#include "hw/misc/allwinner-a10-ccm.h"
23
i32, ptr, ptr, ptr, ptr, i32)
27
#include "hw/misc/allwinner-a10-dramc.h"
24
28
#include "hw/i2c/allwinner-i2c.h"
25
+DEF_HELPER_FLAGS_5(sve2_histcnt_s, TCG_CALL_NO_RWG,
29
+#include "sysemu/block-backend.h"
26
+ void, ptr, ptr, ptr, ptr, i32)
30
27
+DEF_HELPER_FLAGS_5(sve2_histcnt_d, TCG_CALL_NO_RWG,
31
#include "target/arm/cpu.h"
28
+ void, ptr, ptr, ptr, ptr, i32)
32
#include "qom/object.h"
33
@@ -XXX,XX +XXX,XX @@ struct AwA10State {
34
OHCISysBusState ohci[AW_A10_NUM_USB];
35
};
36
37
+/**
38
+ * Emulate Boot ROM firmware setup functionality.
39
+ *
40
+ * A real Allwinner A10 SoC contains a Boot ROM
41
+ * which is the first code that runs right after
42
+ * the SoC is powered on. The Boot ROM is responsible
43
+ * for loading user code (e.g. a bootloader) from any
44
+ * of the supported external devices and writing the
45
+ * downloaded code to internal SRAM. After loading the SoC
46
+ * begins executing the code written to SRAM.
47
+ *
48
+ * This function emulates the Boot ROM by copying 32 KiB
49
+ * of data at offset 8 KiB from the given block device and writes it to
50
+ * the start of the first internal SRAM memory.
51
+ *
52
+ * @s: Allwinner A10 state object pointer
53
+ * @blk: Block backend device object pointer
54
+ */
55
+void allwinner_a10_bootrom_setup(AwA10State *s, BlockBackend *blk);
29
+
56
+
30
+DEF_HELPER_FLAGS_4(sve2_histseg, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
57
#endif
58
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/hw/arm/allwinner-a10.c
61
+++ b/hw/arm/allwinner-a10.c
62
@@ -XXX,XX +XXX,XX @@
63
#include "sysemu/sysemu.h"
64
#include "hw/boards.h"
65
#include "hw/usb/hcd-ohci.h"
66
+#include "hw/loader.h"
67
68
+#define AW_A10_SRAM_A_BASE 0x00000000
69
#define AW_A10_DRAMC_BASE 0x01c01000
70
#define AW_A10_MMC0_BASE 0x01c0f000
71
#define AW_A10_CCM_BASE 0x01c20000
72
@@ -XXX,XX +XXX,XX @@
73
#define AW_A10_RTC_BASE 0x01c20d00
74
#define AW_A10_I2C0_BASE 0x01c2ac00
75
76
+void allwinner_a10_bootrom_setup(AwA10State *s, BlockBackend *blk)
77
+{
78
+ const int64_t rom_size = 32 * KiB;
79
+ g_autofree uint8_t *buffer = g_new0(uint8_t, rom_size);
31
+
80
+
32
DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_h, TCG_CALL_NO_RWG,
81
+ if (blk_pread(blk, 8 * KiB, rom_size, buffer, 0) < 0) {
33
void, ptr, ptr, ptr, ptr, ptr, i32)
82
+ error_setg(&error_fatal, "%s: failed to read BlockBackend data",
34
DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_s, TCG_CALL_NO_RWG,
83
+ __func__);
35
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
84
+ return;
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/sve.decode
38
+++ b/target/arm/sve.decode
39
@@ -XXX,XX +XXX,XX @@
40
&rprrr_esz rn=%reg_movprfx
41
@rdn_pg_rm_ra ........ esz:2 . ra:5 ... pg:3 rm:5 rd:5 \
42
&rprrr_esz rn=%reg_movprfx
43
+@rd_pg_rn_rm ........ esz:2 . rm:5 ... pg:3 rn:5 rd:5 &rprr_esz
44
45
# One register operand, with governing predicate, vector element size
46
@rd_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 rd:5 &rpr_esz
47
@@ -XXX,XX +XXX,XX @@ RSUBHNT 01000101 .. 1 ..... 011 111 ..... ..... @rd_rn_rm
48
MATCH 01000101 .. 1 ..... 100 ... ..... 0 .... @pd_pg_rn_rm
49
NMATCH 01000101 .. 1 ..... 100 ... ..... 1 .... @pd_pg_rn_rm
50
51
+### SVE2 Histogram Computation
52
+
53
+HISTCNT 01000101 .. 1 ..... 110 ... ..... ..... @rd_pg_rn_rm
54
+HISTSEG 01000101 .. 1 ..... 101 000 ..... ..... @rd_rn_rm
55
+
56
## SVE2 floating-point pairwise operations
57
58
FADDP 01100100 .. 010 00 0 100 ... ..... ..... @rdn_pg_rm
59
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/arm/sve_helper.c
62
+++ b/target/arm/sve_helper.c
63
@@ -XXX,XX +XXX,XX @@ DO_PPZZ_MATCH(sve2_nmatch_ppzz_b, MO_8, true)
64
DO_PPZZ_MATCH(sve2_nmatch_ppzz_h, MO_16, true)
65
66
#undef DO_PPZZ_MATCH
67
+
68
+void HELPER(sve2_histcnt_s)(void *vd, void *vn, void *vm, void *vg,
69
+ uint32_t desc)
70
+{
71
+ ARMVectorReg scratch;
72
+ intptr_t i, j;
73
+ intptr_t opr_sz = simd_oprsz(desc);
74
+ uint32_t *d = vd, *n = vn, *m = vm;
75
+ uint8_t *pg = vg;
76
+
77
+ if (d == n) {
78
+ n = memcpy(&scratch, n, opr_sz);
79
+ if (d == m) {
80
+ m = n;
81
+ }
82
+ } else if (d == m) {
83
+ m = memcpy(&scratch, m, opr_sz);
84
+ }
85
+ }
85
+
86
+
86
+ for (i = 0; i < opr_sz; i += 4) {
87
+ rom_add_blob("allwinner-a10.bootrom", buffer, rom_size,
87
+ uint64_t count = 0;
88
+ rom_size, AW_A10_SRAM_A_BASE,
88
+ uint8_t pred;
89
+ NULL, NULL, NULL, NULL, false);
89
+
90
+ pred = pg[H1(i >> 3)] >> (i & 7);
91
+ if (pred & 1) {
92
+ uint32_t nn = n[H4(i >> 2)];
93
+
94
+ for (j = 0; j <= i; j += 4) {
95
+ pred = pg[H1(j >> 3)] >> (j & 7);
96
+ if ((pred & 1) && nn == m[H4(j >> 2)]) {
97
+ ++count;
98
+ }
99
+ }
100
+ }
101
+ d[H4(i >> 2)] = count;
102
+ }
103
+}
90
+}
104
+
91
+
105
+void HELPER(sve2_histcnt_d)(void *vd, void *vn, void *vm, void *vg,
92
static void aw_a10_init(Object *obj)
106
+ uint32_t desc)
93
{
107
+{
94
AwA10State *s = AW_A10(obj);
108
+ ARMVectorReg scratch;
95
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
109
+ intptr_t i, j;
96
index XXXXXXX..XXXXXXX 100644
110
+ intptr_t opr_sz = simd_oprsz(desc);
97
--- a/hw/arm/cubieboard.c
111
+ uint64_t *d = vd, *n = vn, *m = vm;
98
+++ b/hw/arm/cubieboard.c
112
+ uint8_t *pg = vg;
99
@@ -XXX,XX +XXX,XX @@ static void cubieboard_init(MachineState *machine)
113
+
100
memory_region_add_subregion(get_system_memory(), AW_A10_SDRAM_BASE,
114
+ if (d == n) {
101
machine->ram);
115
+ n = memcpy(&scratch, n, opr_sz);
102
116
+ if (d == m) {
103
+ /* Load target kernel or start using BootROM */
117
+ m = n;
104
+ if (!machine->kernel_filename && blk && blk_is_available(blk)) {
118
+ }
105
+ /* Use Boot ROM to copy data from SD card to SRAM */
119
+ } else if (d == m) {
106
+ allwinner_a10_bootrom_setup(a10, blk);
120
+ m = memcpy(&scratch, m, opr_sz);
121
+ }
107
+ }
122
+
108
/* TODO create and connect IDE devices for ide_drive_get() */
123
+ for (i = 0; i < opr_sz / 8; ++i) {
109
124
+ uint64_t count = 0;
110
cubieboard_binfo.ram_size = machine->ram_size;
125
+ if (pg[H1(i)] & 1) {
126
+ uint64_t nn = n[i];
127
+ for (j = 0; j <= i; ++j) {
128
+ if ((pg[H1(j)] & 1) && nn == m[j]) {
129
+ ++count;
130
+ }
131
+ }
132
+ }
133
+ d[i] = count;
134
+ }
135
+}
136
+
137
+/*
138
+ * Returns the number of bytes in m0 and m1 that match n.
139
+ * Unlike do_match2 we don't just need true/false, we need an exact count.
140
+ * This requires two extra logical operations.
141
+ */
142
+static inline uint64_t do_histseg_cnt(uint8_t n, uint64_t m0, uint64_t m1)
143
+{
144
+ const uint64_t mask = dup_const(MO_8, 0x7f);
145
+ uint64_t cmp0, cmp1;
146
+
147
+ cmp1 = dup_const(MO_8, n);
148
+ cmp0 = cmp1 ^ m0;
149
+ cmp1 = cmp1 ^ m1;
150
+
151
+ /*
152
+ * 1: clear msb of each byte to avoid carry to next byte (& mask)
153
+ * 2: carry in to msb if byte != 0 (+ mask)
154
+ * 3: set msb if cmp has msb set (| cmp)
155
+ * 4: set ~msb to ignore them (| mask)
156
+ * We now have 0xff for byte != 0 or 0x7f for byte == 0.
157
+ * 5: invert, resulting in 0x80 if and only if byte == 0.
158
+ */
159
+ cmp0 = ~(((cmp0 & mask) + mask) | cmp0 | mask);
160
+ cmp1 = ~(((cmp1 & mask) + mask) | cmp1 | mask);
161
+
162
+ /*
163
+ * Combine the two compares in a way that the bits do
164
+ * not overlap, and so preserves the count of set bits.
165
+ * If the host has an efficient instruction for ctpop,
166
+ * then ctpop(x) + ctpop(y) has the same number of
167
+ * operations as ctpop(x | (y >> 1)). If the host does
168
+ * not have an efficient ctpop, then we only want to
169
+ * use it once.
170
+ */
171
+ return ctpop64(cmp0 | (cmp1 >> 1));
172
+}
173
+
174
+void HELPER(sve2_histseg)(void *vd, void *vn, void *vm, uint32_t desc)
175
+{
176
+ intptr_t i, j;
177
+ intptr_t opr_sz = simd_oprsz(desc);
178
+
179
+ for (i = 0; i < opr_sz; i += 16) {
180
+ uint64_t n0 = *(uint64_t *)(vn + i);
181
+ uint64_t m0 = *(uint64_t *)(vm + i);
182
+ uint64_t n1 = *(uint64_t *)(vn + i + 8);
183
+ uint64_t m1 = *(uint64_t *)(vm + i + 8);
184
+ uint64_t out0 = 0;
185
+ uint64_t out1 = 0;
186
+
187
+ for (j = 0; j < 64; j += 8) {
188
+ uint64_t cnt0 = do_histseg_cnt(n0 >> j, m0, m1);
189
+ uint64_t cnt1 = do_histseg_cnt(n1 >> j, m0, m1);
190
+ out0 |= cnt0 << j;
191
+ out1 |= cnt1 << j;
192
+ }
193
+
194
+ *(uint64_t *)(vd + i) = out0;
195
+ *(uint64_t *)(vd + i + 8) = out1;
196
+ }
197
+}
198
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
199
index XXXXXXX..XXXXXXX 100644
200
--- a/target/arm/translate-sve.c
201
+++ b/target/arm/translate-sve.c
202
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rprr_esz *a) \
203
DO_SVE2_PPZZ_MATCH(MATCH, match)
204
DO_SVE2_PPZZ_MATCH(NMATCH, nmatch)
205
206
+static bool trans_HISTCNT(DisasContext *s, arg_rprr_esz *a)
207
+{
208
+ static gen_helper_gvec_4 * const fns[2] = {
209
+ gen_helper_sve2_histcnt_s, gen_helper_sve2_histcnt_d
210
+ };
211
+ if (a->esz < 2) {
212
+ return false;
213
+ }
214
+ return do_sve2_zpzz_ool(s, a, fns[a->esz - 2]);
215
+}
216
+
217
+static bool trans_HISTSEG(DisasContext *s, arg_rrr_esz *a)
218
+{
219
+ if (a->esz != 0) {
220
+ return false;
221
+ }
222
+ return do_sve2_zzz_ool(s, a, gen_helper_sve2_histseg);
223
+}
224
+
225
static bool do_sve2_zpzz_fp(DisasContext *s, arg_rprr_esz *a,
226
gen_helper_gvec_4_ptr *fn)
227
{
228
--
111
--
229
2.20.1
112
2.34.1
230
231
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Strahinja Jankovic <strahinjapjankovic@gmail.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Cubieboard now can boot directly from SD card, without the need to pass
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
`-kernel` parameter. Update Avocado tests to cover this functionality.
5
Message-id: 20210525010358.152808-71-richard.henderson@linaro.org
5
6
Signed-off-by: Strahinja Jankovic <strahinja.p.jankovic@gmail.com>
7
Reviewed-by: Niek Linnenbank <nieklinnenbank@gmail.com>
8
Tested-by: Niek Linnenbank <nieklinnenbank@gmail.com>
9
Message-id: 20221226220303.14420-8-strahinja.p.jankovic@gmail.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/cpu.h | 5 +++++
12
tests/avocado/boot_linux_console.py | 47 +++++++++++++++++++++++++++++
9
target/arm/sve.decode | 4 ++++
13
1 file changed, 47 insertions(+)
10
target/arm/translate-sve.c | 16 ++++++++++++++++
11
3 files changed, 25 insertions(+)
12
14
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
17
--- a/tests/avocado/boot_linux_console.py
16
+++ b/target/arm/cpu.h
18
+++ b/tests/avocado/boot_linux_console.py
17
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sve2_bitperm(const ARMISARegisters *id)
19
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_sata(self):
18
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BITPERM) != 0;
20
'sda')
19
}
21
# cubieboard's reboot is not functioning; omit reboot test.
20
22
21
+static inline bool isar_feature_aa64_sve2_sha3(const ARMISARegisters *id)
23
+ @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
22
+{
24
+ def test_arm_cubieboard_openwrt_22_03_2(self):
23
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SHA3) != 0;
25
+ """
24
+}
26
+ :avocado: tags=arch:arm
27
+ :avocado: tags=machine:cubieboard
28
+ :avocado: tags=device:sd
29
+ """
25
+
30
+
26
static inline bool isar_feature_aa64_sve2_sm4(const ARMISARegisters *id)
31
+ # This test download a 7.5 MiB compressed image and expand it
27
{
32
+ # to 126 MiB.
28
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SM4) != 0;
33
+ image_url = ('https://downloads.openwrt.org/releases/22.03.2/targets/'
29
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
34
+ 'sunxi/cortexa8/openwrt-22.03.2-sunxi-cortexa8-'
30
index XXXXXXX..XXXXXXX 100644
35
+ 'cubietech_a10-cubieboard-ext4-sdcard.img.gz')
31
--- a/target/arm/sve.decode
36
+ image_hash = ('94b5ecbfbc0b3b56276e5146b899eafa'
32
+++ b/target/arm/sve.decode
37
+ '2ac5dc2d08733d6705af9f144f39f554')
33
@@ -XXX,XX +XXX,XX @@ AESMC 01000101 00 10000011100 decrypt:1 00000 rd:5
38
+ image_path_gz = self.fetch_asset(image_url, asset_hash=image_hash,
34
AESE 01000101 00 10001 0 11100 0 ..... ..... @rdn_rm_e0
39
+ algorithm='sha256')
35
AESD 01000101 00 10001 0 11100 1 ..... ..... @rdn_rm_e0
40
+ image_path = archive.extract(image_path_gz, self.workdir)
36
SM4E 01000101 00 10001 1 11100 0 ..... ..... @rdn_rm_e0
41
+ image_pow2ceil_expand(image_path)
37
+
42
+
38
+# SVE2 crypto constructive binary operations
43
+ self.vm.set_console()
39
+SM4EKEY 01000101 00 1 ..... 11110 0 ..... ..... @rd_rn_rm_e0
44
+ self.vm.add_args('-drive', 'file=' + image_path + ',if=sd,format=raw',
40
+RAX1 01000101 00 1 ..... 11110 1 ..... ..... @rd_rn_rm_e0
45
+ '-nic', 'user',
41
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
46
+ '-no-reboot')
42
index XXXXXXX..XXXXXXX 100644
47
+ self.vm.launch()
43
--- a/target/arm/translate-sve.c
44
+++ b/target/arm/translate-sve.c
45
@@ -XXX,XX +XXX,XX @@ static bool trans_SM4E(DisasContext *s, arg_rrr_esz *a)
46
{
47
return do_sm4(s, a, gen_helper_crypto_sm4e);
48
}
49
+
48
+
50
+static bool trans_SM4EKEY(DisasContext *s, arg_rrr_esz *a)
49
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
51
+{
50
+ 'usbcore.nousb '
52
+ return do_sm4(s, a, gen_helper_crypto_sm4ekey);
51
+ 'noreboot')
53
+}
54
+
52
+
55
+static bool trans_RAX1(DisasContext *s, arg_rrr_esz *a)
53
+ self.wait_for_console_pattern('U-Boot SPL')
56
+{
54
+
57
+ if (!dc_isar_feature(aa64_sve2_sha3, s)) {
55
+ interrupt_interactive_console_until_pattern(
58
+ return false;
56
+ self, 'Hit any key to stop autoboot:', '=>')
59
+ }
57
+ exec_command_and_wait_for_pattern(self, "setenv extraargs '" +
60
+ if (sve_access_check(s)) {
58
+ kernel_command_line + "'", '=>')
61
+ gen_gvec_fn_zzz(s, gen_gvec_rax1, MO_64, a->rd, a->rn, a->rm);
59
+ exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...');
62
+ }
60
+
63
+ return true;
61
+ self.wait_for_console_pattern(
64
+}
62
+ 'Please press Enter to activate this console.')
63
+
64
+ exec_command_and_wait_for_pattern(self, ' ', 'root@')
65
+
66
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
67
+ 'Allwinner sun4i/sun5i')
68
+ # cubieboard's reboot is not functioning; omit reboot test.
69
+
70
@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
71
def test_arm_quanta_gsj(self):
72
"""
65
--
73
--
66
2.20.1
74
2.34.1
67
68
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Don't dereference CPUTLBEntryFull until we verify that
4
the page is valid. Move the other user-only info field
5
updates after the valid check to match.
6
7
Cc: qemu-stable@nongnu.org
8
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1412
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20210525010358.152808-64-richard.henderson@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20230104190056.305143-1-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
13
---
8
target/arm/helper-sve.h | 10 ++++
14
target/arm/sve_helper.c | 14 +++++++++-----
9
target/arm/sve.decode | 9 ++++
15
1 file changed, 9 insertions(+), 5 deletions(-)
10
target/arm/sve_helper.c | 99 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 17 +++++++
12
4 files changed, 135 insertions(+)
13
16
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_sqrdcmlah_idx_h, TCG_CALL_NO_RWG,
19
void, ptr, ptr, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_5(sve2_sqrdcmlah_idx_s, TCG_CALL_NO_RWG,
21
void, ptr, ptr, ptr, ptr, i32)
22
+
23
+DEF_HELPER_FLAGS_5(sve2_cdot_zzzz_s, TCG_CALL_NO_RWG,
24
+ void, ptr, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_5(sve2_cdot_zzzz_d, TCG_CALL_NO_RWG,
26
+ void, ptr, ptr, ptr, ptr, i32)
27
+
28
+DEF_HELPER_FLAGS_5(sve2_cdot_idx_s, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_5(sve2_cdot_idx_d, TCG_CALL_NO_RWG,
31
+ void, ptr, ptr, ptr, ptr, i32)
32
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/sve.decode
35
+++ b/target/arm/sve.decode
36
@@ -XXX,XX +XXX,XX @@ MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
37
DOT_zzzz 01000100 1 sz:1 0 rm:5 00000 u:1 rn:5 rd:5 \
38
ra=%reg_movprfx
39
40
+# SVE2 complex dot product (vectors)
41
+CDOT_zzzz 01000100 esz:2 0 rm:5 0001 rot:2 rn:5 rd:5 ra=%reg_movprfx
42
+
43
#### SVE Multiply - Indexed
44
45
# SVE integer dot product (indexed)
46
@@ -XXX,XX +XXX,XX @@ SQDMLSLB_zzxw_d 01000100 11 1 ..... 0011.0 ..... ..... @rrxr_2a esz=3
47
SQDMLSLT_zzxw_s 01000100 10 1 ..... 0011.1 ..... ..... @rrxr_3a esz=2
48
SQDMLSLT_zzxw_d 01000100 11 1 ..... 0011.1 ..... ..... @rrxr_2a esz=3
49
50
+# SVE2 complex integer dot product (indexed)
51
+CDOT_zzxw_s 01000100 10 1 index:2 rm:3 0100 rot:2 rn:5 rd:5 \
52
+ ra=%reg_movprfx
53
+CDOT_zzxw_d 01000100 11 1 index:1 rm:4 0100 rot:2 rn:5 rd:5 \
54
+ ra=%reg_movprfx
55
+
56
# SVE2 complex integer multiply-add (indexed)
57
CMLA_zzxz_h 01000100 10 1 index:2 rm:3 0110 rot:2 rn:5 rd:5 \
58
ra=%reg_movprfx
59
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
17
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
60
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
61
--- a/target/arm/sve_helper.c
19
--- a/target/arm/sve_helper.c
62
+++ b/target/arm/sve_helper.c
20
+++ b/target/arm/sve_helper.c
63
@@ -XXX,XX +XXX,XX @@ DO_CMLA_IDX_FUNC(sve2_sqrdcmlah_idx_s, int32_t, H4, DO_SQRDMLAH_S)
21
@@ -XXX,XX +XXX,XX @@ bool sve_probe_page(SVEHostPage *info, bool nofault, CPUARMState *env,
64
#undef DO_SQRDMLAH_S
22
#ifdef CONFIG_USER_ONLY
65
#undef DO_SQRDMLAH_D
23
flags = probe_access_flags(env, addr, access_type, mmu_idx, nofault,
66
24
&info->host, retaddr);
67
+/* Note N and M are 4 elements bundled into one unit. */
25
- memset(&info->attrs, 0, sizeof(info->attrs));
68
+static int32_t do_cdot_s(uint32_t n, uint32_t m, int32_t a,
26
- /* Require both ANON and MTE; see allocation_tag_mem(). */
69
+ int sel_a, int sel_b, int sub_i)
27
- info->tagged = (flags & PAGE_ANON) && (flags & PAGE_MTE);
70
+{
28
#else
71
+ for (int i = 0; i <= 1; i++) {
29
CPUTLBEntryFull *full;
72
+ int32_t elt1_r = (int8_t)(n >> (16 * i));
30
flags = probe_access_full(env, addr, access_type, mmu_idx, nofault,
73
+ int32_t elt1_i = (int8_t)(n >> (16 * i + 8));
31
&info->host, &full, retaddr);
74
+ int32_t elt2_a = (int8_t)(m >> (16 * i + 8 * sel_a));
32
- info->attrs = full->attrs;
75
+ int32_t elt2_b = (int8_t)(m >> (16 * i + 8 * sel_b));
33
- info->tagged = full->pte_attrs == 0xf0;
34
#endif
35
info->flags = flags;
36
37
@@ -XXX,XX +XXX,XX @@ bool sve_probe_page(SVEHostPage *info, bool nofault, CPUARMState *env,
38
return false;
39
}
40
41
+#ifdef CONFIG_USER_ONLY
42
+ memset(&info->attrs, 0, sizeof(info->attrs));
43
+ /* Require both ANON and MTE; see allocation_tag_mem(). */
44
+ info->tagged = (flags & PAGE_ANON) && (flags & PAGE_MTE);
45
+#else
46
+ info->attrs = full->attrs;
47
+ info->tagged = full->pte_attrs == 0xf0;
48
+#endif
76
+
49
+
77
+ a += elt1_r * elt2_a + elt1_i * elt2_b * sub_i;
50
/* Ensure that info->host[] is relative to addr, not addr + mem_off. */
78
+ }
51
info->host -= mem_off;
79
+ return a;
80
+}
81
+
82
+static int64_t do_cdot_d(uint64_t n, uint64_t m, int64_t a,
83
+ int sel_a, int sel_b, int sub_i)
84
+{
85
+ for (int i = 0; i <= 1; i++) {
86
+ int64_t elt1_r = (int16_t)(n >> (32 * i + 0));
87
+ int64_t elt1_i = (int16_t)(n >> (32 * i + 16));
88
+ int64_t elt2_a = (int16_t)(m >> (32 * i + 16 * sel_a));
89
+ int64_t elt2_b = (int16_t)(m >> (32 * i + 16 * sel_b));
90
+
91
+ a += elt1_r * elt2_a + elt1_i * elt2_b * sub_i;
92
+ }
93
+ return a;
94
+}
95
+
96
+void HELPER(sve2_cdot_zzzz_s)(void *vd, void *vn, void *vm,
97
+ void *va, uint32_t desc)
98
+{
99
+ int opr_sz = simd_oprsz(desc);
100
+ int rot = simd_data(desc);
101
+ int sel_a = rot & 1;
102
+ int sel_b = sel_a ^ 1;
103
+ int sub_i = (rot == 0 || rot == 3 ? -1 : 1);
104
+ uint32_t *d = vd, *n = vn, *m = vm, *a = va;
105
+
106
+ for (int e = 0; e < opr_sz / 4; e++) {
107
+ d[e] = do_cdot_s(n[e], m[e], a[e], sel_a, sel_b, sub_i);
108
+ }
109
+}
110
+
111
+void HELPER(sve2_cdot_zzzz_d)(void *vd, void *vn, void *vm,
112
+ void *va, uint32_t desc)
113
+{
114
+ int opr_sz = simd_oprsz(desc);
115
+ int rot = simd_data(desc);
116
+ int sel_a = rot & 1;
117
+ int sel_b = sel_a ^ 1;
118
+ int sub_i = (rot == 0 || rot == 3 ? -1 : 1);
119
+ uint64_t *d = vd, *n = vn, *m = vm, *a = va;
120
+
121
+ for (int e = 0; e < opr_sz / 8; e++) {
122
+ d[e] = do_cdot_d(n[e], m[e], a[e], sel_a, sel_b, sub_i);
123
+ }
124
+}
125
+
126
+void HELPER(sve2_cdot_idx_s)(void *vd, void *vn, void *vm,
127
+ void *va, uint32_t desc)
128
+{
129
+ int opr_sz = simd_oprsz(desc);
130
+ int rot = extract32(desc, SIMD_DATA_SHIFT, 2);
131
+ int idx = H4(extract32(desc, SIMD_DATA_SHIFT + 2, 2));
132
+ int sel_a = rot & 1;
133
+ int sel_b = sel_a ^ 1;
134
+ int sub_i = (rot == 0 || rot == 3 ? -1 : 1);
135
+ uint32_t *d = vd, *n = vn, *m = vm, *a = va;
136
+
137
+ for (int seg = 0; seg < opr_sz / 4; seg += 4) {
138
+ uint32_t seg_m = m[seg + idx];
139
+ for (int e = 0; e < 4; e++) {
140
+ d[seg + e] = do_cdot_s(n[seg + e], seg_m, a[seg + e],
141
+ sel_a, sel_b, sub_i);
142
+ }
143
+ }
144
+}
145
+
146
+void HELPER(sve2_cdot_idx_d)(void *vd, void *vn, void *vm,
147
+ void *va, uint32_t desc)
148
+{
149
+ int seg, opr_sz = simd_oprsz(desc);
150
+ int rot = extract32(desc, SIMD_DATA_SHIFT, 2);
151
+ int idx = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
152
+ int sel_a = rot & 1;
153
+ int sel_b = sel_a ^ 1;
154
+ int sub_i = (rot == 0 || rot == 3 ? -1 : 1);
155
+ uint64_t *d = vd, *n = vn, *m = vm, *a = va;
156
+
157
+ for (seg = 0; seg < opr_sz / 8; seg += 2) {
158
+ uint64_t seg_m = m[seg + idx];
159
+ for (int e = 0; e < 2; e++) {
160
+ d[seg + e] = do_cdot_d(n[seg + e], seg_m, a[seg + e],
161
+ sel_a, sel_b, sub_i);
162
+ }
163
+ }
164
+}
165
+
166
#define DO_ZZXZ(NAME, TYPE, H, OP) \
167
void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, uint32_t desc) \
168
{ \
169
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
170
index XXXXXXX..XXXXXXX 100644
171
--- a/target/arm/translate-sve.c
172
+++ b/target/arm/translate-sve.c
173
@@ -XXX,XX +XXX,XX @@ DO_SVE2_RRXR_ROT(CMLA_zzxz_s, gen_helper_sve2_cmla_idx_s)
174
DO_SVE2_RRXR_ROT(SQRDCMLAH_zzxz_h, gen_helper_sve2_sqrdcmlah_idx_h)
175
DO_SVE2_RRXR_ROT(SQRDCMLAH_zzxz_s, gen_helper_sve2_sqrdcmlah_idx_s)
176
177
+DO_SVE2_RRXR_ROT(CDOT_zzxw_s, gen_helper_sve2_cdot_idx_s)
178
+DO_SVE2_RRXR_ROT(CDOT_zzxw_d, gen_helper_sve2_cdot_idx_d)
179
+
180
#undef DO_SVE2_RRXR_ROT
181
182
/*
183
@@ -XXX,XX +XXX,XX @@ static bool trans_CMLA_zzzz(DisasContext *s, arg_CMLA_zzzz *a)
184
return true;
52
return true;
185
}
186
187
+static bool trans_CDOT_zzzz(DisasContext *s, arg_CMLA_zzzz *a)
188
+{
189
+ if (!dc_isar_feature(aa64_sve2, s) || a->esz < MO_32) {
190
+ return false;
191
+ }
192
+ if (sve_access_check(s)) {
193
+ gen_helper_gvec_4 *fn = (a->esz == MO_32
194
+ ? gen_helper_sve2_cdot_zzzz_s
195
+ : gen_helper_sve2_cdot_zzzz_d);
196
+ gen_gvec_ool_zzzz(s, fn, a->rd, a->rn, a->rm, a->ra, a->rot);
197
+ }
198
+ return true;
199
+}
200
+
201
static bool trans_SQRDCMLAH_zzzz(DisasContext *s, arg_SQRDCMLAH_zzzz *a)
202
{
203
static gen_helper_gvec_4 * const fns[] = {
204
--
53
--
205
2.20.1
54
2.34.1
206
55
207
56
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Since pxa255_init() must map the device in the system memory,
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
there is no point in passing get_system_memory() by argument.
5
Message-id: 20210525010358.152808-70-richard.henderson@linaro.org
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230109115316.2235-2-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/cpu.h | 5 +++++
11
include/hw/arm/pxa.h | 2 +-
9
target/arm/sve.decode | 7 +++++++
12
hw/arm/gumstix.c | 3 +--
10
target/arm/translate-sve.c | 38 ++++++++++++++++++++++++++++++++++++++
13
hw/arm/pxa2xx.c | 4 +++-
11
3 files changed, 50 insertions(+)
14
hw/arm/tosa.c | 2 +-
15
4 files changed, 6 insertions(+), 5 deletions(-)
12
16
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
19
--- a/include/hw/arm/pxa.h
16
+++ b/target/arm/cpu.h
20
+++ b/include/hw/arm/pxa.h
17
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sve2_bitperm(const ARMISARegisters *id)
21
@@ -XXX,XX +XXX,XX @@ struct PXA2xxI2SState {
18
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BITPERM) != 0;
22
23
PXA2xxState *pxa270_init(MemoryRegion *address_space, unsigned int sdram_size,
24
const char *revision);
25
-PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size);
26
+PXA2xxState *pxa255_init(unsigned int sdram_size);
27
28
#endif /* PXA_H */
29
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/gumstix.c
32
+++ b/hw/arm/gumstix.c
33
@@ -XXX,XX +XXX,XX @@ static void connex_init(MachineState *machine)
34
{
35
PXA2xxState *cpu;
36
DriveInfo *dinfo;
37
- MemoryRegion *address_space_mem = get_system_memory();
38
39
uint32_t connex_rom = 0x01000000;
40
uint32_t connex_ram = 0x04000000;
41
42
- cpu = pxa255_init(address_space_mem, connex_ram);
43
+ cpu = pxa255_init(connex_ram);
44
45
dinfo = drive_get(IF_PFLASH, 0, 0);
46
if (!dinfo && !qtest_enabled()) {
47
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/pxa2xx.c
50
+++ b/hw/arm/pxa2xx.c
51
@@ -XXX,XX +XXX,XX @@
52
#include "qemu/error-report.h"
53
#include "qemu/module.h"
54
#include "qapi/error.h"
55
+#include "exec/address-spaces.h"
56
#include "cpu.h"
57
#include "hw/sysbus.h"
58
#include "migration/vmstate.h"
59
@@ -XXX,XX +XXX,XX @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
19
}
60
}
20
61
21
+static inline bool isar_feature_aa64_sve2_sm4(const ARMISARegisters *id)
62
/* Initialise a PXA255 integrated chip (ARM based core). */
22
+{
63
-PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
23
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SM4) != 0;
64
+PXA2xxState *pxa255_init(unsigned int sdram_size)
24
+}
25
+
26
static inline bool isar_feature_aa64_sve_i8mm(const ARMISARegisters *id)
27
{
65
{
28
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, I8MM) != 0;
66
+ MemoryRegion *address_space = get_system_memory();
29
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
67
PXA2xxState *s;
68
int i;
69
DriveInfo *dinfo;
70
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
30
index XXXXXXX..XXXXXXX 100644
71
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/sve.decode
72
--- a/hw/arm/tosa.c
32
+++ b/target/arm/sve.decode
73
+++ b/hw/arm/tosa.c
33
@@ -XXX,XX +XXX,XX @@
74
@@ -XXX,XX +XXX,XX @@ static void tosa_init(MachineState *machine)
34
@pd_pn_pm ........ esz:2 .. rm:4 ....... rn:4 . rd:4 &rrr_esz
75
TC6393xbState *tmio;
35
@rdn_rm ........ esz:2 ...... ...... rm:5 rd:5 \
76
DeviceState *scp0, *scp1;
36
&rrr_esz rn=%reg_movprfx
77
37
+@rdn_rm_e0 ........ .. ...... ...... rm:5 rd:5 \
78
- mpu = pxa255_init(address_space_mem, tosa_binfo.ram_size);
38
+ &rrr_esz rn=%reg_movprfx esz=0
79
+ mpu = pxa255_init(tosa_binfo.ram_size);
39
@rdn_sh_i8u ........ esz:2 ...... ...... ..... rd:5 \
80
40
&rri_esz rn=%reg_movprfx imm=%sh8_i8u
81
memory_region_init_rom(rom, NULL, "tosa.rom", TOSA_ROM, &error_fatal);
41
@rdn_i8u ........ esz:2 ...... ... imm:8 rd:5 \
82
memory_region_add_subregion(address_space_mem, 0, rom);
42
@@ -XXX,XX +XXX,XX @@ STNT1_zprz 1110010 .. 10 ..... 001 ... ..... ..... \
43
# SVE2 crypto unary operations
44
# AESMC and AESIMC
45
AESMC 01000101 00 10000011100 decrypt:1 00000 rd:5
46
+
47
+# SVE2 crypto destructive binary operations
48
+AESE 01000101 00 10001 0 11100 0 ..... ..... @rdn_rm_e0
49
+AESD 01000101 00 10001 0 11100 1 ..... ..... @rdn_rm_e0
50
+SM4E 01000101 00 10001 1 11100 0 ..... ..... @rdn_rm_e0
51
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/translate-sve.c
54
+++ b/target/arm/translate-sve.c
55
@@ -XXX,XX +XXX,XX @@ static bool trans_AESMC(DisasContext *s, arg_AESMC *a)
56
}
57
return true;
58
}
59
+
60
+static bool do_aese(DisasContext *s, arg_rrr_esz *a, bool decrypt)
61
+{
62
+ if (!dc_isar_feature(aa64_sve2_aes, s)) {
63
+ return false;
64
+ }
65
+ if (sve_access_check(s)) {
66
+ gen_gvec_ool_zzz(s, gen_helper_crypto_aese,
67
+ a->rd, a->rn, a->rm, decrypt);
68
+ }
69
+ return true;
70
+}
71
+
72
+static bool trans_AESE(DisasContext *s, arg_rrr_esz *a)
73
+{
74
+ return do_aese(s, a, false);
75
+}
76
+
77
+static bool trans_AESD(DisasContext *s, arg_rrr_esz *a)
78
+{
79
+ return do_aese(s, a, true);
80
+}
81
+
82
+static bool do_sm4(DisasContext *s, arg_rrr_esz *a, gen_helper_gvec_3 *fn)
83
+{
84
+ if (!dc_isar_feature(aa64_sve2_sm4, s)) {
85
+ return false;
86
+ }
87
+ if (sve_access_check(s)) {
88
+ gen_gvec_ool_zzz(s, fn, a->rd, a->rn, a->rm, 0);
89
+ }
90
+ return true;
91
+}
92
+
93
+static bool trans_SM4E(DisasContext *s, arg_rrr_esz *a)
94
+{
95
+ return do_sm4(s, a, gen_helper_crypto_sm4e);
96
+}
97
--
83
--
98
2.20.1
84
2.34.1
99
85
100
86
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Since pxa270_init() must map the device in the system memory,
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
there is no point in passing get_system_memory() by argument.
5
Message-id: 20210525010358.152808-28-richard.henderson@linaro.org
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230109115316.2235-3-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/helper-sve.h | 16 +++++++
11
include/hw/arm/pxa.h | 3 +--
9
target/arm/sve.decode | 4 ++
12
hw/arm/gumstix.c | 3 +--
10
target/arm/sve_helper.c | 35 ++++++++++++++
13
hw/arm/mainstone.c | 10 ++++------
11
target/arm/translate-sve.c | 98 ++++++++++++++++++++++++++++++++++++++
14
hw/arm/pxa2xx.c | 4 ++--
12
4 files changed, 153 insertions(+)
15
hw/arm/spitz.c | 6 ++----
16
hw/arm/z2.c | 3 +--
17
6 files changed, 11 insertions(+), 18 deletions(-)
13
18
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
19
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
21
--- a/include/hw/arm/pxa.h
17
+++ b/target/arm/helper-sve.h
22
+++ b/include/hw/arm/pxa.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve2_rshrnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
23
@@ -XXX,XX +XXX,XX @@ struct PXA2xxI2SState {
19
DEF_HELPER_FLAGS_3(sve2_rshrnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
24
20
DEF_HELPER_FLAGS_3(sve2_rshrnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
25
# define PA_FMT            "0x%08lx"
21
26
22
+DEF_HELPER_FLAGS_3(sve2_sqshrunb_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
27
-PXA2xxState *pxa270_init(MemoryRegion *address_space, unsigned int sdram_size,
23
+DEF_HELPER_FLAGS_3(sve2_sqshrunb_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
28
- const char *revision);
24
+DEF_HELPER_FLAGS_3(sve2_sqshrunb_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
29
+PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision);
25
+
30
PXA2xxState *pxa255_init(unsigned int sdram_size);
26
+DEF_HELPER_FLAGS_3(sve2_sqshrunt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
31
27
+DEF_HELPER_FLAGS_3(sve2_sqshrunt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
32
#endif /* PXA_H */
28
+DEF_HELPER_FLAGS_3(sve2_sqshrunt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
33
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
29
+
30
+DEF_HELPER_FLAGS_3(sve2_sqrshrunb_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_3(sve2_sqrshrunb_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_3(sve2_sqrshrunb_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
33
+
34
+DEF_HELPER_FLAGS_3(sve2_sqrshrunt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_3(sve2_sqrshrunt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_3(sve2_sqrshrunt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
37
+
38
DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_h, TCG_CALL_NO_RWG,
39
void, ptr, ptr, ptr, ptr, ptr, i32)
40
DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_s, TCG_CALL_NO_RWG,
41
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
42
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/sve.decode
35
--- a/hw/arm/gumstix.c
44
+++ b/target/arm/sve.decode
36
+++ b/hw/arm/gumstix.c
45
@@ -XXX,XX +XXX,XX @@ SQXTUNT 01000101 .. 1 ..... 010 101 ..... ..... @rd_rn_tszimm_shl
37
@@ -XXX,XX +XXX,XX @@ static void verdex_init(MachineState *machine)
46
## SVE2 bitwise shift right narrow
38
{
47
39
PXA2xxState *cpu;
48
# Bit 23 == 0 is handled by esz > 0 in the translator.
40
DriveInfo *dinfo;
49
+SQSHRUNB 01000101 .. 1 ..... 00 0000 ..... ..... @rd_rn_tszimm_shr
41
- MemoryRegion *address_space_mem = get_system_memory();
50
+SQSHRUNT 01000101 .. 1 ..... 00 0001 ..... ..... @rd_rn_tszimm_shr
42
51
+SQRSHRUNB 01000101 .. 1 ..... 00 0010 ..... ..... @rd_rn_tszimm_shr
43
uint32_t verdex_rom = 0x02000000;
52
+SQRSHRUNT 01000101 .. 1 ..... 00 0011 ..... ..... @rd_rn_tszimm_shr
44
uint32_t verdex_ram = 0x10000000;
53
SHRNB 01000101 .. 1 ..... 00 0100 ..... ..... @rd_rn_tszimm_shr
45
54
SHRNT 01000101 .. 1 ..... 00 0101 ..... ..... @rd_rn_tszimm_shr
46
- cpu = pxa270_init(address_space_mem, verdex_ram, machine->cpu_type);
55
RSHRNB 01000101 .. 1 ..... 00 0110 ..... ..... @rd_rn_tszimm_shr
47
+ cpu = pxa270_init(verdex_ram, machine->cpu_type);
56
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
48
49
dinfo = drive_get(IF_PFLASH, 0, 0);
50
if (!dinfo && !qtest_enabled()) {
51
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
57
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/sve_helper.c
53
--- a/hw/arm/mainstone.c
59
+++ b/target/arm/sve_helper.c
54
+++ b/hw/arm/mainstone.c
60
@@ -XXX,XX +XXX,XX @@ static inline uint64_t do_urshr(uint64_t x, unsigned sh)
55
@@ -XXX,XX +XXX,XX @@ static struct arm_boot_info mainstone_binfo = {
61
}
56
.ram_size = 0x04000000,
57
};
58
59
-static void mainstone_common_init(MemoryRegion *address_space_mem,
60
- MachineState *machine,
61
+static void mainstone_common_init(MachineState *machine,
62
enum mainstone_model_e model, int arm_id)
63
{
64
uint32_t sector_len = 256 * 1024;
65
@@ -XXX,XX +XXX,XX @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
66
MemoryRegion *rom = g_new(MemoryRegion, 1);
67
68
/* Setup CPU & memory */
69
- mpu = pxa270_init(address_space_mem, mainstone_binfo.ram_size,
70
- machine->cpu_type);
71
+ mpu = pxa270_init(mainstone_binfo.ram_size, machine->cpu_type);
72
memory_region_init_rom(rom, NULL, "mainstone.rom", MAINSTONE_ROM,
73
&error_fatal);
74
- memory_region_add_subregion(address_space_mem, 0, rom);
75
+ memory_region_add_subregion(get_system_memory(), 0x00000000, rom);
76
77
/* There are two 32MiB flash devices on the board */
78
for (i = 0; i < 2; i ++) {
79
@@ -XXX,XX +XXX,XX @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
80
81
static void mainstone_init(MachineState *machine)
82
{
83
- mainstone_common_init(get_system_memory(), machine, mainstone, 0x196);
84
+ mainstone_common_init(machine, mainstone, 0x196);
62
}
85
}
63
86
64
+static inline int64_t do_srshr(int64_t x, unsigned sh)
87
static void mainstone2_machine_init(MachineClass *mc)
65
+{
88
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
66
+ if (likely(sh < 64)) {
67
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
68
+ } else {
69
+ /* Rounding the sign bit always produces 0. */
70
+ return 0;
71
+ }
72
+}
73
+
74
DO_ZPZI(sve_asr_zpzi_b, int8_t, H1, DO_SHR)
75
DO_ZPZI(sve_asr_zpzi_h, int16_t, H1_2, DO_SHR)
76
DO_ZPZI(sve_asr_zpzi_s, int32_t, H1_4, DO_SHR)
77
@@ -XXX,XX +XXX,XX @@ DO_SHRNT(sve2_rshrnt_h, uint16_t, uint8_t, H1_2, H1, do_urshr)
78
DO_SHRNT(sve2_rshrnt_s, uint32_t, uint16_t, H1_4, H1_2, do_urshr)
79
DO_SHRNT(sve2_rshrnt_d, uint64_t, uint32_t, , H1_4, do_urshr)
80
81
+#define DO_SQSHRUN_H(x, sh) do_sat_bhs((int64_t)(x) >> sh, 0, UINT8_MAX)
82
+#define DO_SQSHRUN_S(x, sh) do_sat_bhs((int64_t)(x) >> sh, 0, UINT16_MAX)
83
+#define DO_SQSHRUN_D(x, sh) \
84
+ do_sat_bhs((int64_t)(x) >> (sh < 64 ? sh : 63), 0, UINT32_MAX)
85
+
86
+DO_SHRNB(sve2_sqshrunb_h, int16_t, uint8_t, DO_SQSHRUN_H)
87
+DO_SHRNB(sve2_sqshrunb_s, int32_t, uint16_t, DO_SQSHRUN_S)
88
+DO_SHRNB(sve2_sqshrunb_d, int64_t, uint32_t, DO_SQSHRUN_D)
89
+
90
+DO_SHRNT(sve2_sqshrunt_h, int16_t, uint8_t, H1_2, H1, DO_SQSHRUN_H)
91
+DO_SHRNT(sve2_sqshrunt_s, int32_t, uint16_t, H1_4, H1_2, DO_SQSHRUN_S)
92
+DO_SHRNT(sve2_sqshrunt_d, int64_t, uint32_t, , H1_4, DO_SQSHRUN_D)
93
+
94
+#define DO_SQRSHRUN_H(x, sh) do_sat_bhs(do_srshr(x, sh), 0, UINT8_MAX)
95
+#define DO_SQRSHRUN_S(x, sh) do_sat_bhs(do_srshr(x, sh), 0, UINT16_MAX)
96
+#define DO_SQRSHRUN_D(x, sh) do_sat_bhs(do_srshr(x, sh), 0, UINT32_MAX)
97
+
98
+DO_SHRNB(sve2_sqrshrunb_h, int16_t, uint8_t, DO_SQRSHRUN_H)
99
+DO_SHRNB(sve2_sqrshrunb_s, int32_t, uint16_t, DO_SQRSHRUN_S)
100
+DO_SHRNB(sve2_sqrshrunb_d, int64_t, uint32_t, DO_SQRSHRUN_D)
101
+
102
+DO_SHRNT(sve2_sqrshrunt_h, int16_t, uint8_t, H1_2, H1, DO_SQRSHRUN_H)
103
+DO_SHRNT(sve2_sqrshrunt_s, int32_t, uint16_t, H1_4, H1_2, DO_SQRSHRUN_S)
104
+DO_SHRNT(sve2_sqrshrunt_d, int64_t, uint32_t, , H1_4, DO_SQRSHRUN_D)
105
+
106
#undef DO_SHRNB
107
#undef DO_SHRNT
108
109
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
110
index XXXXXXX..XXXXXXX 100644
89
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/translate-sve.c
90
--- a/hw/arm/pxa2xx.c
112
+++ b/target/arm/translate-sve.c
91
+++ b/hw/arm/pxa2xx.c
113
@@ -XXX,XX +XXX,XX @@ static bool trans_RSHRNT(DisasContext *s, arg_rri_esz *a)
92
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_reset(void *opaque, int line, int level)
114
return do_sve2_shr_narrow(s, a, ops);
115
}
93
}
116
94
117
+static void gen_sqshrunb_vec(unsigned vece, TCGv_vec d,
95
/* Initialise a PXA270 integrated chip (ARM based core). */
118
+ TCGv_vec n, int64_t shr)
96
-PXA2xxState *pxa270_init(MemoryRegion *address_space,
119
+{
97
- unsigned int sdram_size, const char *cpu_type)
120
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
98
+PXA2xxState *pxa270_init(unsigned int sdram_size, const char *cpu_type)
121
+ int halfbits = 4 << vece;
122
+
123
+ tcg_gen_sari_vec(vece, n, n, shr);
124
+ tcg_gen_dupi_vec(vece, t, 0);
125
+ tcg_gen_smax_vec(vece, n, n, t);
126
+ tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(0, halfbits));
127
+ tcg_gen_umin_vec(vece, d, n, t);
128
+ tcg_temp_free_vec(t);
129
+}
130
+
131
+static bool trans_SQSHRUNB(DisasContext *s, arg_rri_esz *a)
132
+{
133
+ static const TCGOpcode vec_list[] = {
134
+ INDEX_op_sari_vec, INDEX_op_smax_vec, INDEX_op_umin_vec, 0
135
+ };
136
+ static const GVecGen2i ops[3] = {
137
+ { .fniv = gen_sqshrunb_vec,
138
+ .opt_opc = vec_list,
139
+ .fno = gen_helper_sve2_sqshrunb_h,
140
+ .vece = MO_16 },
141
+ { .fniv = gen_sqshrunb_vec,
142
+ .opt_opc = vec_list,
143
+ .fno = gen_helper_sve2_sqshrunb_s,
144
+ .vece = MO_32 },
145
+ { .fniv = gen_sqshrunb_vec,
146
+ .opt_opc = vec_list,
147
+ .fno = gen_helper_sve2_sqshrunb_d,
148
+ .vece = MO_64 },
149
+ };
150
+ return do_sve2_shr_narrow(s, a, ops);
151
+}
152
+
153
+static void gen_sqshrunt_vec(unsigned vece, TCGv_vec d,
154
+ TCGv_vec n, int64_t shr)
155
+{
156
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
157
+ int halfbits = 4 << vece;
158
+
159
+ tcg_gen_sari_vec(vece, n, n, shr);
160
+ tcg_gen_dupi_vec(vece, t, 0);
161
+ tcg_gen_smax_vec(vece, n, n, t);
162
+ tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(0, halfbits));
163
+ tcg_gen_umin_vec(vece, n, n, t);
164
+ tcg_gen_shli_vec(vece, n, n, halfbits);
165
+ tcg_gen_bitsel_vec(vece, d, t, d, n);
166
+ tcg_temp_free_vec(t);
167
+}
168
+
169
+static bool trans_SQSHRUNT(DisasContext *s, arg_rri_esz *a)
170
+{
171
+ static const TCGOpcode vec_list[] = {
172
+ INDEX_op_shli_vec, INDEX_op_sari_vec,
173
+ INDEX_op_smax_vec, INDEX_op_umin_vec, 0
174
+ };
175
+ static const GVecGen2i ops[3] = {
176
+ { .fniv = gen_sqshrunt_vec,
177
+ .opt_opc = vec_list,
178
+ .load_dest = true,
179
+ .fno = gen_helper_sve2_sqshrunt_h,
180
+ .vece = MO_16 },
181
+ { .fniv = gen_sqshrunt_vec,
182
+ .opt_opc = vec_list,
183
+ .load_dest = true,
184
+ .fno = gen_helper_sve2_sqshrunt_s,
185
+ .vece = MO_32 },
186
+ { .fniv = gen_sqshrunt_vec,
187
+ .opt_opc = vec_list,
188
+ .load_dest = true,
189
+ .fno = gen_helper_sve2_sqshrunt_d,
190
+ .vece = MO_64 },
191
+ };
192
+ return do_sve2_shr_narrow(s, a, ops);
193
+}
194
+
195
+static bool trans_SQRSHRUNB(DisasContext *s, arg_rri_esz *a)
196
+{
197
+ static const GVecGen2i ops[3] = {
198
+ { .fno = gen_helper_sve2_sqrshrunb_h },
199
+ { .fno = gen_helper_sve2_sqrshrunb_s },
200
+ { .fno = gen_helper_sve2_sqrshrunb_d },
201
+ };
202
+ return do_sve2_shr_narrow(s, a, ops);
203
+}
204
+
205
+static bool trans_SQRSHRUNT(DisasContext *s, arg_rri_esz *a)
206
+{
207
+ static const GVecGen2i ops[3] = {
208
+ { .fno = gen_helper_sve2_sqrshrunt_h },
209
+ { .fno = gen_helper_sve2_sqrshrunt_s },
210
+ { .fno = gen_helper_sve2_sqrshrunt_d },
211
+ };
212
+ return do_sve2_shr_narrow(s, a, ops);
213
+}
214
+
215
static bool do_sve2_zpzz_fp(DisasContext *s, arg_rprr_esz *a,
216
gen_helper_gvec_4_ptr *fn)
217
{
99
{
100
+ MemoryRegion *address_space = get_system_memory();
101
PXA2xxState *s;
102
int i;
103
DriveInfo *dinfo;
104
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/hw/arm/spitz.c
107
+++ b/hw/arm/spitz.c
108
@@ -XXX,XX +XXX,XX @@ static void spitz_common_init(MachineState *machine)
109
SpitzMachineState *sms = SPITZ_MACHINE(machine);
110
enum spitz_model_e model = smc->model;
111
PXA2xxState *mpu;
112
- MemoryRegion *address_space_mem = get_system_memory();
113
MemoryRegion *rom = g_new(MemoryRegion, 1);
114
115
/* Setup CPU & memory */
116
- mpu = pxa270_init(address_space_mem, spitz_binfo.ram_size,
117
- machine->cpu_type);
118
+ mpu = pxa270_init(spitz_binfo.ram_size, machine->cpu_type);
119
sms->mpu = mpu;
120
121
sl_flash_register(mpu, (model == spitz) ? FLASH_128M : FLASH_1024M);
122
123
memory_region_init_rom(rom, NULL, "spitz.rom", SPITZ_ROM, &error_fatal);
124
- memory_region_add_subregion(address_space_mem, 0, rom);
125
+ memory_region_add_subregion(get_system_memory(), 0, rom);
126
127
/* Setup peripherals */
128
spitz_keyboard_register(mpu);
129
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/hw/arm/z2.c
132
+++ b/hw/arm/z2.c
133
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aer915_info = {
134
135
static void z2_init(MachineState *machine)
136
{
137
- MemoryRegion *address_space_mem = get_system_memory();
138
uint32_t sector_len = 0x10000;
139
PXA2xxState *mpu;
140
DriveInfo *dinfo;
141
@@ -XXX,XX +XXX,XX @@ static void z2_init(MachineState *machine)
142
DeviceState *wm;
143
144
/* Setup CPU & memory */
145
- mpu = pxa270_init(address_space_mem, z2_binfo.ram_size, machine->cpu_type);
146
+ mpu = pxa270_init(z2_binfo.ram_size, machine->cpu_type);
147
148
dinfo = drive_get(IF_PFLASH, 0, 0);
149
if (!pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
218
--
150
--
219
2.20.1
151
2.34.1
220
152
221
153
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Split these operations out into a header that can be shared
3
IEC binary prefixes ease code review: the unit is explicit.
4
between neon and sve. The "sat" pointer acts both as a boolean
5
for control of saturating behavior and controls the difference
6
in behavior between neon and sve -- QC bit or no QC bit.
7
4
8
Widen the shift operand in the new helpers, as the SVE2 insns treat
5
Add definitions for RAM / Flash / Flash blocksize.
9
the whole input element as significant. For the neon uses, truncate
10
the shift to int8_t while passing the parameter.
11
6
12
Implement right-shift rounding as
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
tmp = src >> (shift - 1);
9
Message-id: 20230109115316.2235-4-philmd@linaro.org
15
dst = (tmp >> 1) + (tmp & 1);
16
17
This is the same number of instructions as the current
18
19
tmp = 1 << (shift - 1);
20
dst = (src + tmp) >> shift;
21
22
without any possibility of intermediate overflow.
23
24
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20210525010358.152808-6-richard.henderson@linaro.org
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
---
11
---
29
target/arm/vec_internal.h | 138 +++++++++++
12
hw/arm/collie.c | 16 ++++++++++------
30
target/arm/neon_helper.c | 507 +++++++-------------------------------
13
1 file changed, 10 insertions(+), 6 deletions(-)
31
2 files changed, 221 insertions(+), 424 deletions(-)
32
14
33
diff --git a/target/arm/vec_internal.h b/target/arm/vec_internal.h
15
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
34
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/vec_internal.h
17
--- a/hw/arm/collie.c
36
+++ b/target/arm/vec_internal.h
18
+++ b/hw/arm/collie.c
37
@@ -XXX,XX +XXX,XX @@ static inline void clear_tail(void *vd, uintptr_t opr_sz, uintptr_t max_sz)
38
}
39
}
40
41
+static inline int32_t do_sqrshl_bhs(int32_t src, int32_t shift, int bits,
42
+ bool round, uint32_t *sat)
43
+{
44
+ if (shift <= -bits) {
45
+ /* Rounding the sign bit always produces 0. */
46
+ if (round) {
47
+ return 0;
48
+ }
49
+ return src >> 31;
50
+ } else if (shift < 0) {
51
+ if (round) {
52
+ src >>= -shift - 1;
53
+ return (src >> 1) + (src & 1);
54
+ }
55
+ return src >> -shift;
56
+ } else if (shift < bits) {
57
+ int32_t val = src << shift;
58
+ if (bits == 32) {
59
+ if (!sat || val >> shift == src) {
60
+ return val;
61
+ }
62
+ } else {
63
+ int32_t extval = sextract32(val, 0, bits);
64
+ if (!sat || val == extval) {
65
+ return extval;
66
+ }
67
+ }
68
+ } else if (!sat || src == 0) {
69
+ return 0;
70
+ }
71
+
72
+ *sat = 1;
73
+ return (1u << (bits - 1)) - (src >= 0);
74
+}
75
+
76
+static inline uint32_t do_uqrshl_bhs(uint32_t src, int32_t shift, int bits,
77
+ bool round, uint32_t *sat)
78
+{
79
+ if (shift <= -(bits + round)) {
80
+ return 0;
81
+ } else if (shift < 0) {
82
+ if (round) {
83
+ src >>= -shift - 1;
84
+ return (src >> 1) + (src & 1);
85
+ }
86
+ return src >> -shift;
87
+ } else if (shift < bits) {
88
+ uint32_t val = src << shift;
89
+ if (bits == 32) {
90
+ if (!sat || val >> shift == src) {
91
+ return val;
92
+ }
93
+ } else {
94
+ uint32_t extval = extract32(val, 0, bits);
95
+ if (!sat || val == extval) {
96
+ return extval;
97
+ }
98
+ }
99
+ } else if (!sat || src == 0) {
100
+ return 0;
101
+ }
102
+
103
+ *sat = 1;
104
+ return MAKE_64BIT_MASK(0, bits);
105
+}
106
+
107
+static inline int32_t do_suqrshl_bhs(int32_t src, int32_t shift, int bits,
108
+ bool round, uint32_t *sat)
109
+{
110
+ if (sat && src < 0) {
111
+ *sat = 1;
112
+ return 0;
113
+ }
114
+ return do_uqrshl_bhs(src, shift, bits, round, sat);
115
+}
116
+
117
+static inline int64_t do_sqrshl_d(int64_t src, int64_t shift,
118
+ bool round, uint32_t *sat)
119
+{
120
+ if (shift <= -64) {
121
+ /* Rounding the sign bit always produces 0. */
122
+ if (round) {
123
+ return 0;
124
+ }
125
+ return src >> 63;
126
+ } else if (shift < 0) {
127
+ if (round) {
128
+ src >>= -shift - 1;
129
+ return (src >> 1) + (src & 1);
130
+ }
131
+ return src >> -shift;
132
+ } else if (shift < 64) {
133
+ int64_t val = src << shift;
134
+ if (!sat || val >> shift == src) {
135
+ return val;
136
+ }
137
+ } else if (!sat || src == 0) {
138
+ return 0;
139
+ }
140
+
141
+ *sat = 1;
142
+ return src < 0 ? INT64_MIN : INT64_MAX;
143
+}
144
+
145
+static inline uint64_t do_uqrshl_d(uint64_t src, int64_t shift,
146
+ bool round, uint32_t *sat)
147
+{
148
+ if (shift <= -(64 + round)) {
149
+ return 0;
150
+ } else if (shift < 0) {
151
+ if (round) {
152
+ src >>= -shift - 1;
153
+ return (src >> 1) + (src & 1);
154
+ }
155
+ return src >> -shift;
156
+ } else if (shift < 64) {
157
+ uint64_t val = src << shift;
158
+ if (!sat || val >> shift == src) {
159
+ return val;
160
+ }
161
+ } else if (!sat || src == 0) {
162
+ return 0;
163
+ }
164
+
165
+ *sat = 1;
166
+ return UINT64_MAX;
167
+}
168
+
169
+static inline int64_t do_suqrshl_d(int64_t src, int64_t shift,
170
+ bool round, uint32_t *sat)
171
+{
172
+ if (sat && src < 0) {
173
+ *sat = 1;
174
+ return 0;
175
+ }
176
+ return do_uqrshl_d(src, shift, round, sat);
177
+}
178
+
179
#endif /* TARGET_ARM_VEC_INTERNALS_H */
180
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
181
index XXXXXXX..XXXXXXX 100644
182
--- a/target/arm/neon_helper.c
183
+++ b/target/arm/neon_helper.c
184
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
185
#include "cpu.h"
20
#include "cpu.h"
186
#include "exec/helper-proto.h"
21
#include "qom/object.h"
187
#include "fpu/softfloat.h"
22
188
+#include "vec_internal.h"
23
+#define RAM_SIZE (512 * MiB)
189
24
+#define FLASH_SIZE (32 * MiB)
190
#define SIGNBIT (uint32_t)0x80000000
25
+#define FLASH_SECTOR_SIZE (64 * KiB)
191
#define SIGNBIT64 ((uint64_t)1 << 63)
192
@@ -XXX,XX +XXX,XX @@ NEON_POP(pmax_s16, neon_s16, 2)
193
NEON_POP(pmax_u16, neon_u16, 2)
194
#undef NEON_FN
195
196
-#define NEON_FN(dest, src1, src2) do { \
197
- int8_t tmp; \
198
- tmp = (int8_t)src2; \
199
- if (tmp >= (ssize_t)sizeof(src1) * 8 || \
200
- tmp <= -(ssize_t)sizeof(src1) * 8) { \
201
- dest = 0; \
202
- } else if (tmp < 0) { \
203
- dest = src1 >> -tmp; \
204
- } else { \
205
- dest = src1 << tmp; \
206
- }} while (0)
207
+#define NEON_FN(dest, src1, src2) \
208
+ (dest = do_uqrshl_bhs(src1, (int8_t)src2, 16, false, NULL))
209
NEON_VOP(shl_u16, neon_u16, 2)
210
#undef NEON_FN
211
212
-#define NEON_FN(dest, src1, src2) do { \
213
- int8_t tmp; \
214
- tmp = (int8_t)src2; \
215
- if (tmp >= (ssize_t)sizeof(src1) * 8) { \
216
- dest = 0; \
217
- } else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \
218
- dest = src1 >> (sizeof(src1) * 8 - 1); \
219
- } else if (tmp < 0) { \
220
- dest = src1 >> -tmp; \
221
- } else { \
222
- dest = src1 << tmp; \
223
- }} while (0)
224
+#define NEON_FN(dest, src1, src2) \
225
+ (dest = do_sqrshl_bhs(src1, (int8_t)src2, 16, false, NULL))
226
NEON_VOP(shl_s16, neon_s16, 2)
227
#undef NEON_FN
228
229
-#define NEON_FN(dest, src1, src2) do { \
230
- int8_t tmp; \
231
- tmp = (int8_t)src2; \
232
- if ((tmp >= (ssize_t)sizeof(src1) * 8) \
233
- || (tmp <= -(ssize_t)sizeof(src1) * 8)) { \
234
- dest = 0; \
235
- } else if (tmp < 0) { \
236
- dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
237
- } else { \
238
- dest = src1 << tmp; \
239
- }} while (0)
240
+#define NEON_FN(dest, src1, src2) \
241
+ (dest = do_sqrshl_bhs(src1, (int8_t)src2, 8, true, NULL))
242
NEON_VOP(rshl_s8, neon_s8, 4)
243
+#undef NEON_FN
244
+
26
+
245
+#define NEON_FN(dest, src1, src2) \
27
struct CollieMachineState {
246
+ (dest = do_sqrshl_bhs(src1, (int8_t)src2, 16, true, NULL))
28
MachineState parent;
247
NEON_VOP(rshl_s16, neon_s16, 2)
29
248
#undef NEON_FN
30
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(CollieMachineState, COLLIE_MACHINE)
249
31
250
-/* The addition of the rounding constant may overflow, so we use an
32
static struct arm_boot_info collie_binfo = {
251
- * intermediate 64 bit accumulator. */
33
.loader_start = SA_SDCS0,
252
-uint32_t HELPER(neon_rshl_s32)(uint32_t valop, uint32_t shiftop)
34
- .ram_size = 0x20000000,
253
+uint32_t HELPER(neon_rshl_s32)(uint32_t val, uint32_t shift)
35
+ .ram_size = RAM_SIZE,
254
{
36
};
255
- int32_t dest;
37
256
- int32_t val = (int32_t)valop;
38
static void collie_init(MachineState *machine)
257
- int8_t shift = (int8_t)shiftop;
39
@@ -XXX,XX +XXX,XX @@ static void collie_init(MachineState *machine)
258
- if ((shift >= 32) || (shift <= -32)) {
40
memory_region_add_subregion(get_system_memory(), SA_SDCS0, machine->ram);
259
- dest = 0;
41
260
- } else if (shift < 0) {
42
dinfo = drive_get(IF_PFLASH, 0, 0);
261
- int64_t big_dest = ((int64_t)val + (1 << (-1 - shift)));
43
- pflash_cfi01_register(SA_CS0, "collie.fl1", 0x02000000,
262
- dest = big_dest >> -shift;
44
+ pflash_cfi01_register(SA_CS0, "collie.fl1", FLASH_SIZE,
263
- } else {
45
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
264
- dest = val << shift;
46
- 64 * KiB, 4, 0x00, 0x00, 0x00, 0x00, 0);
265
- }
47
+ FLASH_SECTOR_SIZE, 4, 0x00, 0x00, 0x00, 0x00, 0);
266
- return dest;
48
267
+ return do_sqrshl_bhs(val, (int8_t)shift, 32, true, NULL);
49
dinfo = drive_get(IF_PFLASH, 0, 1);
50
- pflash_cfi01_register(SA_CS1, "collie.fl2", 0x02000000,
51
+ pflash_cfi01_register(SA_CS1, "collie.fl2", FLASH_SIZE,
52
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
53
- 64 * KiB, 4, 0x00, 0x00, 0x00, 0x00, 0);
54
+ FLASH_SECTOR_SIZE, 4, 0x00, 0x00, 0x00, 0x00, 0);
55
56
sysbus_create_simple("scoop", 0x40800000, NULL);
57
58
@@ -XXX,XX +XXX,XX @@ static void collie_machine_class_init(ObjectClass *oc, void *data)
59
mc->init = collie_init;
60
mc->ignore_memory_transaction_failures = true;
61
mc->default_cpu_type = ARM_CPU_TYPE_NAME("sa1110");
62
- mc->default_ram_size = 0x20000000;
63
+ mc->default_ram_size = RAM_SIZE;
64
mc->default_ram_id = "strongarm.sdram";
268
}
65
}
269
66
270
-/* Handling addition overflow with 64 bit input values is more
271
- * tricky than with 32 bit values. */
272
-uint64_t HELPER(neon_rshl_s64)(uint64_t valop, uint64_t shiftop)
273
+uint64_t HELPER(neon_rshl_s64)(uint64_t val, uint64_t shift)
274
{
275
- int8_t shift = (int8_t)shiftop;
276
- int64_t val = valop;
277
- if ((shift >= 64) || (shift <= -64)) {
278
- val = 0;
279
- } else if (shift < 0) {
280
- val >>= (-shift - 1);
281
- if (val == INT64_MAX) {
282
- /* In this case, it means that the rounding constant is 1,
283
- * and the addition would overflow. Return the actual
284
- * result directly. */
285
- val = 0x4000000000000000LL;
286
- } else {
287
- val++;
288
- val >>= 1;
289
- }
290
- } else {
291
- val <<= shift;
292
- }
293
- return val;
294
+ return do_sqrshl_d(val, (int8_t)shift, true, NULL);
295
}
296
297
-#define NEON_FN(dest, src1, src2) do { \
298
- int8_t tmp; \
299
- tmp = (int8_t)src2; \
300
- if (tmp >= (ssize_t)sizeof(src1) * 8 || \
301
- tmp < -(ssize_t)sizeof(src1) * 8) { \
302
- dest = 0; \
303
- } else if (tmp == -(ssize_t)sizeof(src1) * 8) { \
304
- dest = src1 >> (-tmp - 1); \
305
- } else if (tmp < 0) { \
306
- dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
307
- } else { \
308
- dest = src1 << tmp; \
309
- }} while (0)
310
+#define NEON_FN(dest, src1, src2) \
311
+ (dest = do_uqrshl_bhs(src1, (int8_t)src2, 8, true, NULL))
312
NEON_VOP(rshl_u8, neon_u8, 4)
313
+#undef NEON_FN
314
+
315
+#define NEON_FN(dest, src1, src2) \
316
+ (dest = do_uqrshl_bhs(src1, (int8_t)src2, 16, true, NULL))
317
NEON_VOP(rshl_u16, neon_u16, 2)
318
#undef NEON_FN
319
320
-/* The addition of the rounding constant may overflow, so we use an
321
- * intermediate 64 bit accumulator. */
322
-uint32_t HELPER(neon_rshl_u32)(uint32_t val, uint32_t shiftop)
323
+uint32_t HELPER(neon_rshl_u32)(uint32_t val, uint32_t shift)
324
{
325
- uint32_t dest;
326
- int8_t shift = (int8_t)shiftop;
327
- if (shift >= 32 || shift < -32) {
328
- dest = 0;
329
- } else if (shift == -32) {
330
- dest = val >> 31;
331
- } else if (shift < 0) {
332
- uint64_t big_dest = ((uint64_t)val + (1 << (-1 - shift)));
333
- dest = big_dest >> -shift;
334
- } else {
335
- dest = val << shift;
336
- }
337
- return dest;
338
+ return do_uqrshl_bhs(val, (int8_t)shift, 32, true, NULL);
339
}
340
341
-/* Handling addition overflow with 64 bit input values is more
342
- * tricky than with 32 bit values. */
343
-uint64_t HELPER(neon_rshl_u64)(uint64_t val, uint64_t shiftop)
344
+uint64_t HELPER(neon_rshl_u64)(uint64_t val, uint64_t shift)
345
{
346
- int8_t shift = (uint8_t)shiftop;
347
- if (shift >= 64 || shift < -64) {
348
- val = 0;
349
- } else if (shift == -64) {
350
- /* Rounding a 1-bit result just preserves that bit. */
351
- val >>= 63;
352
- } else if (shift < 0) {
353
- val >>= (-shift - 1);
354
- if (val == UINT64_MAX) {
355
- /* In this case, it means that the rounding constant is 1,
356
- * and the addition would overflow. Return the actual
357
- * result directly. */
358
- val = 0x8000000000000000ULL;
359
- } else {
360
- val++;
361
- val >>= 1;
362
- }
363
- } else {
364
- val <<= shift;
365
- }
366
- return val;
367
+ return do_uqrshl_d(val, (int8_t)shift, true, NULL);
368
}
369
370
-#define NEON_FN(dest, src1, src2) do { \
371
- int8_t tmp; \
372
- tmp = (int8_t)src2; \
373
- if (tmp >= (ssize_t)sizeof(src1) * 8) { \
374
- if (src1) { \
375
- SET_QC(); \
376
- dest = ~0; \
377
- } else { \
378
- dest = 0; \
379
- } \
380
- } else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \
381
- dest = 0; \
382
- } else if (tmp < 0) { \
383
- dest = src1 >> -tmp; \
384
- } else { \
385
- dest = src1 << tmp; \
386
- if ((dest >> tmp) != src1) { \
387
- SET_QC(); \
388
- dest = ~0; \
389
- } \
390
- }} while (0)
391
+#define NEON_FN(dest, src1, src2) \
392
+ (dest = do_uqrshl_bhs(src1, (int8_t)src2, 8, false, env->vfp.qc))
393
NEON_VOP_ENV(qshl_u8, neon_u8, 4)
394
+#undef NEON_FN
395
+
396
+#define NEON_FN(dest, src1, src2) \
397
+ (dest = do_uqrshl_bhs(src1, (int8_t)src2, 16, false, env->vfp.qc))
398
NEON_VOP_ENV(qshl_u16, neon_u16, 2)
399
-NEON_VOP_ENV(qshl_u32, neon_u32, 1)
400
#undef NEON_FN
401
402
-uint64_t HELPER(neon_qshl_u64)(CPUARMState *env, uint64_t val, uint64_t shiftop)
403
+uint32_t HELPER(neon_qshl_u32)(CPUARMState *env, uint32_t val, uint32_t shift)
404
{
405
- int8_t shift = (int8_t)shiftop;
406
- if (shift >= 64) {
407
- if (val) {
408
- val = ~(uint64_t)0;
409
- SET_QC();
410
- }
411
- } else if (shift <= -64) {
412
- val = 0;
413
- } else if (shift < 0) {
414
- val >>= -shift;
415
- } else {
416
- uint64_t tmp = val;
417
- val <<= shift;
418
- if ((val >> shift) != tmp) {
419
- SET_QC();
420
- val = ~(uint64_t)0;
421
- }
422
- }
423
- return val;
424
+ return do_uqrshl_bhs(val, (int8_t)shift, 32, false, env->vfp.qc);
425
}
426
427
-#define NEON_FN(dest, src1, src2) do { \
428
- int8_t tmp; \
429
- tmp = (int8_t)src2; \
430
- if (tmp >= (ssize_t)sizeof(src1) * 8) { \
431
- if (src1) { \
432
- SET_QC(); \
433
- dest = (uint32_t)(1 << (sizeof(src1) * 8 - 1)); \
434
- if (src1 > 0) { \
435
- dest--; \
436
- } \
437
- } else { \
438
- dest = src1; \
439
- } \
440
- } else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \
441
- dest = src1 >> 31; \
442
- } else if (tmp < 0) { \
443
- dest = src1 >> -tmp; \
444
- } else { \
445
- dest = src1 << tmp; \
446
- if ((dest >> tmp) != src1) { \
447
- SET_QC(); \
448
- dest = (uint32_t)(1 << (sizeof(src1) * 8 - 1)); \
449
- if (src1 > 0) { \
450
- dest--; \
451
- } \
452
- } \
453
- }} while (0)
454
+uint64_t HELPER(neon_qshl_u64)(CPUARMState *env, uint64_t val, uint64_t shift)
455
+{
456
+ return do_uqrshl_d(val, (int8_t)shift, false, env->vfp.qc);
457
+}
458
+
459
+#define NEON_FN(dest, src1, src2) \
460
+ (dest = do_sqrshl_bhs(src1, (int8_t)src2, 8, false, env->vfp.qc))
461
NEON_VOP_ENV(qshl_s8, neon_s8, 4)
462
+#undef NEON_FN
463
+
464
+#define NEON_FN(dest, src1, src2) \
465
+ (dest = do_sqrshl_bhs(src1, (int8_t)src2, 16, false, env->vfp.qc))
466
NEON_VOP_ENV(qshl_s16, neon_s16, 2)
467
-NEON_VOP_ENV(qshl_s32, neon_s32, 1)
468
#undef NEON_FN
469
470
-uint64_t HELPER(neon_qshl_s64)(CPUARMState *env, uint64_t valop, uint64_t shiftop)
471
+uint32_t HELPER(neon_qshl_s32)(CPUARMState *env, uint32_t val, uint32_t shift)
472
{
473
- int8_t shift = (uint8_t)shiftop;
474
- int64_t val = valop;
475
- if (shift >= 64) {
476
- if (val) {
477
- SET_QC();
478
- val = (val >> 63) ^ ~SIGNBIT64;
479
- }
480
- } else if (shift <= -64) {
481
- val >>= 63;
482
- } else if (shift < 0) {
483
- val >>= -shift;
484
- } else {
485
- int64_t tmp = val;
486
- val <<= shift;
487
- if ((val >> shift) != tmp) {
488
- SET_QC();
489
- val = (tmp >> 63) ^ ~SIGNBIT64;
490
- }
491
- }
492
- return val;
493
+ return do_sqrshl_bhs(val, (int8_t)shift, 32, false, env->vfp.qc);
494
}
495
496
-#define NEON_FN(dest, src1, src2) do { \
497
- if (src1 & (1 << (sizeof(src1) * 8 - 1))) { \
498
- SET_QC(); \
499
- dest = 0; \
500
- } else { \
501
- int8_t tmp; \
502
- tmp = (int8_t)src2; \
503
- if (tmp >= (ssize_t)sizeof(src1) * 8) { \
504
- if (src1) { \
505
- SET_QC(); \
506
- dest = ~0; \
507
- } else { \
508
- dest = 0; \
509
- } \
510
- } else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \
511
- dest = 0; \
512
- } else if (tmp < 0) { \
513
- dest = src1 >> -tmp; \
514
- } else { \
515
- dest = src1 << tmp; \
516
- if ((dest >> tmp) != src1) { \
517
- SET_QC(); \
518
- dest = ~0; \
519
- } \
520
- } \
521
- }} while (0)
522
-NEON_VOP_ENV(qshlu_s8, neon_u8, 4)
523
-NEON_VOP_ENV(qshlu_s16, neon_u16, 2)
524
+uint64_t HELPER(neon_qshl_s64)(CPUARMState *env, uint64_t val, uint64_t shift)
525
+{
526
+ return do_sqrshl_d(val, (int8_t)shift, false, env->vfp.qc);
527
+}
528
+
529
+#define NEON_FN(dest, src1, src2) \
530
+ (dest = do_suqrshl_bhs(src1, (int8_t)src2, 8, false, env->vfp.qc))
531
+NEON_VOP_ENV(qshlu_s8, neon_s8, 4)
532
#undef NEON_FN
533
534
-uint32_t HELPER(neon_qshlu_s32)(CPUARMState *env, uint32_t valop, uint32_t shiftop)
535
+#define NEON_FN(dest, src1, src2) \
536
+ (dest = do_suqrshl_bhs(src1, (int8_t)src2, 16, false, env->vfp.qc))
537
+NEON_VOP_ENV(qshlu_s16, neon_s16, 2)
538
+#undef NEON_FN
539
+
540
+uint32_t HELPER(neon_qshlu_s32)(CPUARMState *env, uint32_t val, uint32_t shift)
541
{
542
- if ((int32_t)valop < 0) {
543
- SET_QC();
544
- return 0;
545
- }
546
- return helper_neon_qshl_u32(env, valop, shiftop);
547
+ return do_suqrshl_bhs(val, (int8_t)shift, 32, false, env->vfp.qc);
548
}
549
550
-uint64_t HELPER(neon_qshlu_s64)(CPUARMState *env, uint64_t valop, uint64_t shiftop)
551
+uint64_t HELPER(neon_qshlu_s64)(CPUARMState *env, uint64_t val, uint64_t shift)
552
{
553
- if ((int64_t)valop < 0) {
554
- SET_QC();
555
- return 0;
556
- }
557
- return helper_neon_qshl_u64(env, valop, shiftop);
558
+ return do_suqrshl_d(val, (int8_t)shift, false, env->vfp.qc);
559
}
560
561
-#define NEON_FN(dest, src1, src2) do { \
562
- int8_t tmp; \
563
- tmp = (int8_t)src2; \
564
- if (tmp >= (ssize_t)sizeof(src1) * 8) { \
565
- if (src1) { \
566
- SET_QC(); \
567
- dest = ~0; \
568
- } else { \
569
- dest = 0; \
570
- } \
571
- } else if (tmp < -(ssize_t)sizeof(src1) * 8) { \
572
- dest = 0; \
573
- } else if (tmp == -(ssize_t)sizeof(src1) * 8) { \
574
- dest = src1 >> (sizeof(src1) * 8 - 1); \
575
- } else if (tmp < 0) { \
576
- dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
577
- } else { \
578
- dest = src1 << tmp; \
579
- if ((dest >> tmp) != src1) { \
580
- SET_QC(); \
581
- dest = ~0; \
582
- } \
583
- }} while (0)
584
+#define NEON_FN(dest, src1, src2) \
585
+ (dest = do_uqrshl_bhs(src1, (int8_t)src2, 8, true, env->vfp.qc))
586
NEON_VOP_ENV(qrshl_u8, neon_u8, 4)
587
+#undef NEON_FN
588
+
589
+#define NEON_FN(dest, src1, src2) \
590
+ (dest = do_uqrshl_bhs(src1, (int8_t)src2, 16, true, env->vfp.qc))
591
NEON_VOP_ENV(qrshl_u16, neon_u16, 2)
592
#undef NEON_FN
593
594
-/* The addition of the rounding constant may overflow, so we use an
595
- * intermediate 64 bit accumulator. */
596
-uint32_t HELPER(neon_qrshl_u32)(CPUARMState *env, uint32_t val, uint32_t shiftop)
597
+uint32_t HELPER(neon_qrshl_u32)(CPUARMState *env, uint32_t val, uint32_t shift)
598
{
599
- uint32_t dest;
600
- int8_t shift = (int8_t)shiftop;
601
- if (shift >= 32) {
602
- if (val) {
603
- SET_QC();
604
- dest = ~0;
605
- } else {
606
- dest = 0;
607
- }
608
- } else if (shift < -32) {
609
- dest = 0;
610
- } else if (shift == -32) {
611
- dest = val >> 31;
612
- } else if (shift < 0) {
613
- uint64_t big_dest = ((uint64_t)val + (1 << (-1 - shift)));
614
- dest = big_dest >> -shift;
615
- } else {
616
- dest = val << shift;
617
- if ((dest >> shift) != val) {
618
- SET_QC();
619
- dest = ~0;
620
- }
621
- }
622
- return dest;
623
+ return do_uqrshl_bhs(val, (int8_t)shift, 32, true, env->vfp.qc);
624
}
625
626
-/* Handling addition overflow with 64 bit input values is more
627
- * tricky than with 32 bit values. */
628
-uint64_t HELPER(neon_qrshl_u64)(CPUARMState *env, uint64_t val, uint64_t shiftop)
629
+uint64_t HELPER(neon_qrshl_u64)(CPUARMState *env, uint64_t val, uint64_t shift)
630
{
631
- int8_t shift = (int8_t)shiftop;
632
- if (shift >= 64) {
633
- if (val) {
634
- SET_QC();
635
- val = ~0;
636
- }
637
- } else if (shift < -64) {
638
- val = 0;
639
- } else if (shift == -64) {
640
- val >>= 63;
641
- } else if (shift < 0) {
642
- val >>= (-shift - 1);
643
- if (val == UINT64_MAX) {
644
- /* In this case, it means that the rounding constant is 1,
645
- * and the addition would overflow. Return the actual
646
- * result directly. */
647
- val = 0x8000000000000000ULL;
648
- } else {
649
- val++;
650
- val >>= 1;
651
- }
652
- } else { \
653
- uint64_t tmp = val;
654
- val <<= shift;
655
- if ((val >> shift) != tmp) {
656
- SET_QC();
657
- val = ~0;
658
- }
659
- }
660
- return val;
661
+ return do_uqrshl_d(val, (int8_t)shift, true, env->vfp.qc);
662
}
663
664
-#define NEON_FN(dest, src1, src2) do { \
665
- int8_t tmp; \
666
- tmp = (int8_t)src2; \
667
- if (tmp >= (ssize_t)sizeof(src1) * 8) { \
668
- if (src1) { \
669
- SET_QC(); \
670
- dest = (typeof(dest))(1 << (sizeof(src1) * 8 - 1)); \
671
- if (src1 > 0) { \
672
- dest--; \
673
- } \
674
- } else { \
675
- dest = 0; \
676
- } \
677
- } else if (tmp <= -(ssize_t)sizeof(src1) * 8) { \
678
- dest = 0; \
679
- } else if (tmp < 0) { \
680
- dest = (src1 + (1 << (-1 - tmp))) >> -tmp; \
681
- } else { \
682
- dest = src1 << tmp; \
683
- if ((dest >> tmp) != src1) { \
684
- SET_QC(); \
685
- dest = (uint32_t)(1 << (sizeof(src1) * 8 - 1)); \
686
- if (src1 > 0) { \
687
- dest--; \
688
- } \
689
- } \
690
- }} while (0)
691
+#define NEON_FN(dest, src1, src2) \
692
+ (dest = do_sqrshl_bhs(src1, (int8_t)src2, 8, true, env->vfp.qc))
693
NEON_VOP_ENV(qrshl_s8, neon_s8, 4)
694
+#undef NEON_FN
695
+
696
+#define NEON_FN(dest, src1, src2) \
697
+ (dest = do_sqrshl_bhs(src1, (int8_t)src2, 16, true, env->vfp.qc))
698
NEON_VOP_ENV(qrshl_s16, neon_s16, 2)
699
#undef NEON_FN
700
701
-/* The addition of the rounding constant may overflow, so we use an
702
- * intermediate 64 bit accumulator. */
703
-uint32_t HELPER(neon_qrshl_s32)(CPUARMState *env, uint32_t valop, uint32_t shiftop)
704
+uint32_t HELPER(neon_qrshl_s32)(CPUARMState *env, uint32_t val, uint32_t shift)
705
{
706
- int32_t dest;
707
- int32_t val = (int32_t)valop;
708
- int8_t shift = (int8_t)shiftop;
709
- if (shift >= 32) {
710
- if (val) {
711
- SET_QC();
712
- dest = (val >> 31) ^ ~SIGNBIT;
713
- } else {
714
- dest = 0;
715
- }
716
- } else if (shift <= -32) {
717
- dest = 0;
718
- } else if (shift < 0) {
719
- int64_t big_dest = ((int64_t)val + (1 << (-1 - shift)));
720
- dest = big_dest >> -shift;
721
- } else {
722
- dest = val << shift;
723
- if ((dest >> shift) != val) {
724
- SET_QC();
725
- dest = (val >> 31) ^ ~SIGNBIT;
726
- }
727
- }
728
- return dest;
729
+ return do_sqrshl_bhs(val, (int8_t)shift, 32, true, env->vfp.qc);
730
}
731
732
-/* Handling addition overflow with 64 bit input values is more
733
- * tricky than with 32 bit values. */
734
-uint64_t HELPER(neon_qrshl_s64)(CPUARMState *env, uint64_t valop, uint64_t shiftop)
735
+uint64_t HELPER(neon_qrshl_s64)(CPUARMState *env, uint64_t val, uint64_t shift)
736
{
737
- int8_t shift = (uint8_t)shiftop;
738
- int64_t val = valop;
739
-
740
- if (shift >= 64) {
741
- if (val) {
742
- SET_QC();
743
- val = (val >> 63) ^ ~SIGNBIT64;
744
- }
745
- } else if (shift <= -64) {
746
- val = 0;
747
- } else if (shift < 0) {
748
- val >>= (-shift - 1);
749
- if (val == INT64_MAX) {
750
- /* In this case, it means that the rounding constant is 1,
751
- * and the addition would overflow. Return the actual
752
- * result directly. */
753
- val = 0x4000000000000000ULL;
754
- } else {
755
- val++;
756
- val >>= 1;
757
- }
758
- } else {
759
- int64_t tmp = val;
760
- val <<= shift;
761
- if ((val >> shift) != tmp) {
762
- SET_QC();
763
- val = (tmp >> 63) ^ ~SIGNBIT64;
764
- }
765
- }
766
- return val;
767
+ return do_sqrshl_d(val, (int8_t)shift, true, env->vfp.qc);
768
}
769
770
uint32_t HELPER(neon_add_u8)(uint32_t a, uint32_t b)
771
--
67
--
772
2.20.1
68
2.34.1
773
69
774
70
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-68-richard.henderson@linaro.org
5
Message-id: 20230109115316.2235-5-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
target/arm/helper.h | 1 +
8
hw/arm/collie.c | 17 +++++++----------
9
target/arm/sve.decode | 4 ++++
9
1 file changed, 7 insertions(+), 10 deletions(-)
10
target/arm/translate-sve.c | 16 ++++++++++++++++
11
target/arm/vec_helper.c | 1 +
12
4 files changed, 22 insertions(+)
13
10
14
diff --git a/target/arm/helper.h b/target/arm/helper.h
11
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.h
13
--- a/hw/arm/collie.c
17
+++ b/target/arm/helper.h
14
+++ b/hw/arm/collie.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_sdot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
15
@@ -XXX,XX +XXX,XX @@ static struct arm_boot_info collie_binfo = {
19
DEF_HELPER_FLAGS_5(gvec_udot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
16
20
DEF_HELPER_FLAGS_5(gvec_sdot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
17
static void collie_init(MachineState *machine)
21
DEF_HELPER_FLAGS_5(gvec_udot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
18
{
22
+DEF_HELPER_FLAGS_5(gvec_usdot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
19
- DriveInfo *dinfo;
23
20
MachineClass *mc = MACHINE_GET_CLASS(machine);
24
DEF_HELPER_FLAGS_5(gvec_sdot_idx_b, TCG_CALL_NO_RWG,
21
CollieMachineState *cms = COLLIE_MACHINE(machine);
25
void, ptr, ptr, ptr, ptr, i32)
22
26
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
23
@@ -XXX,XX +XXX,XX @@ static void collie_init(MachineState *machine)
27
index XXXXXXX..XXXXXXX 100644
24
28
--- a/target/arm/sve.decode
25
memory_region_add_subregion(get_system_memory(), SA_SDCS0, machine->ram);
29
+++ b/target/arm/sve.decode
26
30
@@ -XXX,XX +XXX,XX @@ UMLSLT_zzzw 01000100 .. 0 ..... 010 111 ..... ..... @rda_rn_rm
27
- dinfo = drive_get(IF_PFLASH, 0, 0);
31
CMLA_zzzz 01000100 esz:2 0 rm:5 0010 rot:2 rn:5 rd:5 ra=%reg_movprfx
28
- pflash_cfi01_register(SA_CS0, "collie.fl1", FLASH_SIZE,
32
SQRDCMLAH_zzzz 01000100 esz:2 0 rm:5 0011 rot:2 rn:5 rd:5 ra=%reg_movprfx
29
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
33
30
- FLASH_SECTOR_SIZE, 4, 0x00, 0x00, 0x00, 0x00, 0);
34
+## SVE mixed sign dot product
31
-
35
+
32
- dinfo = drive_get(IF_PFLASH, 0, 1);
36
+USDOT_zzzz 01000100 .. 0 ..... 011 110 ..... ..... @rda_rn_rm
33
- pflash_cfi01_register(SA_CS1, "collie.fl2", FLASH_SIZE,
37
+
34
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
38
### SVE2 floating point matrix multiply accumulate
35
- FLASH_SECTOR_SIZE, 4, 0x00, 0x00, 0x00, 0x00, 0);
39
36
+ for (unsigned i = 0; i < 2; i++) {
40
FMMLA 01100100 .. 1 ..... 111001 ..... ..... @rda_rn_rm
37
+ DriveInfo *dinfo = drive_get(IF_PFLASH, 0, i);
41
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
38
+ pflash_cfi01_register(i ? SA_CS1 : SA_CS0,
42
index XXXXXXX..XXXXXXX 100644
39
+ i ? "collie.fl2" : "collie.fl1", FLASH_SIZE,
43
--- a/target/arm/translate-sve.c
40
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
44
+++ b/target/arm/translate-sve.c
41
+ FLASH_SECTOR_SIZE, 4, 0x00, 0x00, 0x00, 0x00, 0);
45
@@ -XXX,XX +XXX,XX @@ static bool trans_SQRDCMLAH_zzzz(DisasContext *s, arg_SQRDCMLAH_zzzz *a)
46
}
47
return true;
48
}
49
+
50
+static bool trans_USDOT_zzzz(DisasContext *s, arg_USDOT_zzzz *a)
51
+{
52
+ if (a->esz != 2 || !dc_isar_feature(aa64_sve_i8mm, s)) {
53
+ return false;
54
+ }
42
+ }
55
+ if (sve_access_check(s)) {
43
56
+ unsigned vsz = vec_full_reg_size(s);
44
sysbus_create_simple("scoop", 0x40800000, NULL);
57
+ tcg_gen_gvec_4_ool(vec_full_reg_offset(s, a->rd),
58
+ vec_full_reg_offset(s, a->rn),
59
+ vec_full_reg_offset(s, a->rm),
60
+ vec_full_reg_offset(s, a->ra),
61
+ vsz, vsz, 0, gen_helper_gvec_usdot_b);
62
+ }
63
+ return true;
64
+}
65
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/vec_helper.c
68
+++ b/target/arm/vec_helper.c
69
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, uint32_t desc) \
70
71
DO_DOT(gvec_sdot_b, int32_t, int8_t, int8_t)
72
DO_DOT(gvec_udot_b, uint32_t, uint8_t, uint8_t)
73
+DO_DOT(gvec_usdot_b, uint32_t, uint8_t, int8_t)
74
DO_DOT(gvec_sdot_h, int64_t, int16_t, int16_t)
75
DO_DOT(gvec_udot_h, uint64_t, uint16_t, uint16_t)
76
45
77
--
46
--
78
2.20.1
47
2.34.1
79
48
80
49
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
In addition, use the same vector generator interface for AdvSIMD.
3
Add a comment describing the Connex uses a Numonyx RC28F128J3F75
4
This fixes a bug in which the AdvSIMD insn failed to clear the
4
flash, and the Verdex uses a Micron RC28F256P30TFA.
5
high bits of the SVE register.
6
5
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Correct the Verdex machine description (we model the 'Pro' board).
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
9
Message-id: 20210525010358.152808-44-richard.henderson@linaro.org
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20230109115316.2235-6-philmd@linaro.org
11
Message-Id: <20200223231044.8003-3-philmd@redhat.com>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
target/arm/helper-sve.h | 4 ++
14
hw/arm/gumstix.c | 6 ++++--
13
target/arm/helper.h | 2 +
15
1 file changed, 4 insertions(+), 2 deletions(-)
14
target/arm/translate-a64.h | 3 ++
15
target/arm/sve.decode | 4 ++
16
target/arm/sve_helper.c | 39 ++++++++++++++
17
target/arm/translate-a64.c | 25 ++-------
18
target/arm/translate-sve.c | 104 +++++++++++++++++++++++++++++++++++++
19
target/arm/vec_helper.c | 12 +++++
20
8 files changed, 172 insertions(+), 21 deletions(-)
21
16
22
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
17
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
23
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper-sve.h
19
--- a/hw/arm/gumstix.c
25
+++ b/target/arm/helper-sve.h
20
+++ b/hw/arm/gumstix.c
26
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_histcnt_d, TCG_CALL_NO_RWG,
21
@@ -XXX,XX +XXX,XX @@
27
22
* Contributions after 2012-01-13 are licensed under the terms of the
28
DEF_HELPER_FLAGS_4(sve2_histseg, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
* GNU GPL, version 2 or (at your option) any later version.
29
24
*/
30
+DEF_HELPER_FLAGS_4(sve2_xar_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
-
31
+DEF_HELPER_FLAGS_4(sve2_xar_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(sve2_xar_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
+
26
+
34
DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_h, TCG_CALL_NO_RWG,
27
/*
35
void, ptr, ptr, ptr, ptr, ptr, i32)
28
* Example usage:
36
DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_s, TCG_CALL_NO_RWG,
29
*
37
diff --git a/target/arm/helper.h b/target/arm/helper.h
30
@@ -XXX,XX +XXX,XX @@ static void connex_init(MachineState *machine)
38
index XXXXXXX..XXXXXXX 100644
31
exit(1);
39
--- a/target/arm/helper.h
40
+++ b/target/arm/helper.h
41
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(neon_sqrdmulh_h, TCG_CALL_NO_RWG,
42
DEF_HELPER_FLAGS_5(neon_sqrdmulh_s, TCG_CALL_NO_RWG,
43
void, ptr, ptr, ptr, ptr, i32)
44
45
+DEF_HELPER_FLAGS_4(gvec_xar_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
46
+
47
#ifdef TARGET_AARCH64
48
#include "helper-a64.h"
49
#include "helper-sve.h"
50
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/translate-a64.h
53
+++ b/target/arm/translate-a64.h
54
@@ -XXX,XX +XXX,XX @@ bool disas_sve(DisasContext *, uint32_t);
55
56
void gen_gvec_rax1(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
57
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
58
+void gen_gvec_xar(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
59
+ uint32_t rm_ofs, int64_t shift,
60
+ uint32_t opr_sz, uint32_t max_sz);
61
62
#endif /* TARGET_ARM_TRANSLATE_A64_H */
63
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/sve.decode
66
+++ b/target/arm/sve.decode
67
@@ -XXX,XX +XXX,XX @@
68
&rr_dbm rd rn dbm
69
&rrri rd rn rm imm
70
&rri_esz rd rn imm esz
71
+&rrri_esz rd rn rm imm esz
72
&rrr_esz rd rn rm esz
73
&rpr_esz rd pg rn esz
74
&rpr_s rd pg rn s
75
@@ -XXX,XX +XXX,XX @@ ORR_zzz 00000100 01 1 ..... 001 100 ..... ..... @rd_rn_rm_e0
76
EOR_zzz 00000100 10 1 ..... 001 100 ..... ..... @rd_rn_rm_e0
77
BIC_zzz 00000100 11 1 ..... 001 100 ..... ..... @rd_rn_rm_e0
78
79
+XAR 00000100 .. 1 ..... 001 101 rm:5 rd:5 &rrri_esz \
80
+ rn=%reg_movprfx esz=%tszimm16_esz imm=%tszimm16_shr
81
+
82
# SVE2 bitwise ternary operations
83
EOR3 00000100 00 1 ..... 001 110 ..... ..... @rdn_ra_rm_e0
84
BSL 00000100 00 1 ..... 001 111 ..... ..... @rdn_ra_rm_e0
85
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/arm/sve_helper.c
88
+++ b/target/arm/sve_helper.c
89
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_histseg)(void *vd, void *vn, void *vm, uint32_t desc)
90
*(uint64_t *)(vd + i + 8) = out1;
91
}
32
}
92
}
33
93
+
34
+ /* Numonyx RC28F128J3F75 */
94
+void HELPER(sve2_xar_b)(void *vd, void *vn, void *vm, uint32_t desc)
35
if (!pflash_cfi01_register(0x00000000, "connext.rom", connex_rom,
95
+{
36
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
96
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
37
sector_len, 2, 0, 0, 0, 0, 0)) {
97
+ int shr = simd_data(desc);
38
@@ -XXX,XX +XXX,XX @@ static void verdex_init(MachineState *machine)
98
+ int shl = 8 - shr;
39
exit(1);
99
+ uint64_t mask = dup_const(MO_8, 0xff >> shr);
100
+ uint64_t *d = vd, *n = vn, *m = vm;
101
+
102
+ for (i = 0; i < opr_sz; ++i) {
103
+ uint64_t t = n[i] ^ m[i];
104
+ d[i] = ((t >> shr) & mask) | ((t << shl) & ~mask);
105
+ }
106
+}
107
+
108
+void HELPER(sve2_xar_h)(void *vd, void *vn, void *vm, uint32_t desc)
109
+{
110
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
111
+ int shr = simd_data(desc);
112
+ int shl = 16 - shr;
113
+ uint64_t mask = dup_const(MO_16, 0xffff >> shr);
114
+ uint64_t *d = vd, *n = vn, *m = vm;
115
+
116
+ for (i = 0; i < opr_sz; ++i) {
117
+ uint64_t t = n[i] ^ m[i];
118
+ d[i] = ((t >> shr) & mask) | ((t << shl) & ~mask);
119
+ }
120
+}
121
+
122
+void HELPER(sve2_xar_s)(void *vd, void *vn, void *vm, uint32_t desc)
123
+{
124
+ intptr_t i, opr_sz = simd_oprsz(desc) / 4;
125
+ int shr = simd_data(desc);
126
+ uint32_t *d = vd, *n = vn, *m = vm;
127
+
128
+ for (i = 0; i < opr_sz; ++i) {
129
+ d[i] = ror32(n[i] ^ m[i], shr);
130
+ }
131
+}
132
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/target/arm/translate-a64.c
135
+++ b/target/arm/translate-a64.c
136
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_xar(DisasContext *s, uint32_t insn)
137
int imm6 = extract32(insn, 10, 6);
138
int rn = extract32(insn, 5, 5);
139
int rd = extract32(insn, 0, 5);
140
- TCGv_i64 tcg_op1, tcg_op2, tcg_res[2];
141
- int pass;
142
143
if (!dc_isar_feature(aa64_sha3, s)) {
144
unallocated_encoding(s);
145
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_xar(DisasContext *s, uint32_t insn)
146
return;
147
}
40
}
148
41
149
- tcg_op1 = tcg_temp_new_i64();
42
+ /* Micron RC28F256P30TFA */
150
- tcg_op2 = tcg_temp_new_i64();
43
if (!pflash_cfi01_register(0x00000000, "verdex.rom", verdex_rom,
151
- tcg_res[0] = tcg_temp_new_i64();
44
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
152
- tcg_res[1] = tcg_temp_new_i64();
45
sector_len, 2, 0, 0, 0, 0, 0)) {
153
-
46
@@ -XXX,XX +XXX,XX @@ static void verdex_class_init(ObjectClass *oc, void *data)
154
- for (pass = 0; pass < 2; pass++) {
155
- read_vec_element(s, tcg_op1, rn, pass, MO_64);
156
- read_vec_element(s, tcg_op2, rm, pass, MO_64);
157
-
158
- tcg_gen_xor_i64(tcg_res[pass], tcg_op1, tcg_op2);
159
- tcg_gen_rotri_i64(tcg_res[pass], tcg_res[pass], imm6);
160
- }
161
- write_vec_element(s, tcg_res[0], rd, 0, MO_64);
162
- write_vec_element(s, tcg_res[1], rd, 1, MO_64);
163
-
164
- tcg_temp_free_i64(tcg_op1);
165
- tcg_temp_free_i64(tcg_op2);
166
- tcg_temp_free_i64(tcg_res[0]);
167
- tcg_temp_free_i64(tcg_res[1]);
168
+ gen_gvec_xar(MO_64, vec_full_reg_offset(s, rd),
169
+ vec_full_reg_offset(s, rn),
170
+ vec_full_reg_offset(s, rm), imm6, 16,
171
+ vec_full_reg_size(s));
172
}
173
174
/* Crypto three-reg imm2
175
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
176
index XXXXXXX..XXXXXXX 100644
177
--- a/target/arm/translate-sve.c
178
+++ b/target/arm/translate-sve.c
179
@@ -XXX,XX +XXX,XX @@ static bool trans_BIC_zzz(DisasContext *s, arg_rrr_esz *a)
180
return do_zzz_fn(s, a, tcg_gen_gvec_andc);
181
}
182
183
+static void gen_xar8_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, int64_t sh)
184
+{
185
+ TCGv_i64 t = tcg_temp_new_i64();
186
+ uint64_t mask = dup_const(MO_8, 0xff >> sh);
187
+
188
+ tcg_gen_xor_i64(t, n, m);
189
+ tcg_gen_shri_i64(d, t, sh);
190
+ tcg_gen_shli_i64(t, t, 8 - sh);
191
+ tcg_gen_andi_i64(d, d, mask);
192
+ tcg_gen_andi_i64(t, t, ~mask);
193
+ tcg_gen_or_i64(d, d, t);
194
+ tcg_temp_free_i64(t);
195
+}
196
+
197
+static void gen_xar16_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, int64_t sh)
198
+{
199
+ TCGv_i64 t = tcg_temp_new_i64();
200
+ uint64_t mask = dup_const(MO_16, 0xffff >> sh);
201
+
202
+ tcg_gen_xor_i64(t, n, m);
203
+ tcg_gen_shri_i64(d, t, sh);
204
+ tcg_gen_shli_i64(t, t, 16 - sh);
205
+ tcg_gen_andi_i64(d, d, mask);
206
+ tcg_gen_andi_i64(t, t, ~mask);
207
+ tcg_gen_or_i64(d, d, t);
208
+ tcg_temp_free_i64(t);
209
+}
210
+
211
+static void gen_xar_i32(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, int32_t sh)
212
+{
213
+ tcg_gen_xor_i32(d, n, m);
214
+ tcg_gen_rotri_i32(d, d, sh);
215
+}
216
+
217
+static void gen_xar_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, int64_t sh)
218
+{
219
+ tcg_gen_xor_i64(d, n, m);
220
+ tcg_gen_rotri_i64(d, d, sh);
221
+}
222
+
223
+static void gen_xar_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
224
+ TCGv_vec m, int64_t sh)
225
+{
226
+ tcg_gen_xor_vec(vece, d, n, m);
227
+ tcg_gen_rotri_vec(vece, d, d, sh);
228
+}
229
+
230
+void gen_gvec_xar(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
231
+ uint32_t rm_ofs, int64_t shift,
232
+ uint32_t opr_sz, uint32_t max_sz)
233
+{
234
+ static const TCGOpcode vecop[] = { INDEX_op_rotli_vec, 0 };
235
+ static const GVecGen3i ops[4] = {
236
+ { .fni8 = gen_xar8_i64,
237
+ .fniv = gen_xar_vec,
238
+ .fno = gen_helper_sve2_xar_b,
239
+ .opt_opc = vecop,
240
+ .vece = MO_8 },
241
+ { .fni8 = gen_xar16_i64,
242
+ .fniv = gen_xar_vec,
243
+ .fno = gen_helper_sve2_xar_h,
244
+ .opt_opc = vecop,
245
+ .vece = MO_16 },
246
+ { .fni4 = gen_xar_i32,
247
+ .fniv = gen_xar_vec,
248
+ .fno = gen_helper_sve2_xar_s,
249
+ .opt_opc = vecop,
250
+ .vece = MO_32 },
251
+ { .fni8 = gen_xar_i64,
252
+ .fniv = gen_xar_vec,
253
+ .fno = gen_helper_gvec_xar_d,
254
+ .opt_opc = vecop,
255
+ .vece = MO_64 }
256
+ };
257
+ int esize = 8 << vece;
258
+
259
+ /* The SVE2 range is 1 .. esize; the AdvSIMD range is 0 .. esize-1. */
260
+ tcg_debug_assert(shift >= 0);
261
+ tcg_debug_assert(shift <= esize);
262
+ shift &= esize - 1;
263
+
264
+ if (shift == 0) {
265
+ /* xar with no rotate devolves to xor. */
266
+ tcg_gen_gvec_xor(vece, rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz);
267
+ } else {
268
+ tcg_gen_gvec_3i(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz,
269
+ shift, &ops[vece]);
270
+ }
271
+}
272
+
273
+static bool trans_XAR(DisasContext *s, arg_rrri_esz *a)
274
+{
275
+ if (a->esz < 0 || !dc_isar_feature(aa64_sve2, s)) {
276
+ return false;
277
+ }
278
+ if (sve_access_check(s)) {
279
+ unsigned vsz = vec_full_reg_size(s);
280
+ gen_gvec_xar(a->esz, vec_full_reg_offset(s, a->rd),
281
+ vec_full_reg_offset(s, a->rn),
282
+ vec_full_reg_offset(s, a->rm), a->imm, vsz, vsz);
283
+ }
284
+ return true;
285
+}
286
+
287
static bool do_sve2_zzzz_fn(DisasContext *s, arg_rrrr_esz *a, GVecGen4Fn *fn)
288
{
47
{
289
if (!dc_isar_feature(aa64_sve2, s)) {
48
MachineClass *mc = MACHINE_CLASS(oc);
290
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
49
291
index XXXXXXX..XXXXXXX 100644
50
- mc->desc = "Gumstix Verdex (PXA270)";
292
--- a/target/arm/vec_helper.c
51
+ mc->desc = "Gumstix Verdex Pro XL6P COMs (PXA270)";
293
+++ b/target/arm/vec_helper.c
52
mc->init = verdex_init;
294
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_umulh_d)(void *vd, void *vn, void *vm, uint32_t desc)
53
mc->ignore_memory_transaction_failures = true;
295
}
54
mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c0");
296
clear_tail(d, opr_sz, simd_maxsz(desc));
297
}
298
+
299
+void HELPER(gvec_xar_d)(void *vd, void *vn, void *vm, uint32_t desc)
300
+{
301
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
302
+ int shr = simd_data(desc);
303
+ uint64_t *d = vd, *n = vn, *m = vm;
304
+
305
+ for (i = 0; i < opr_sz; ++i) {
306
+ d[i] = ror64(n[i] ^ m[i], shr);
307
+ }
308
+ clear_tail(d, opr_sz * 8, simd_maxsz(desc));
309
+}
310
--
55
--
311
2.20.1
56
2.34.1
312
57
313
58
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
When selecting an ARM target on Debian unstable, we get:
3
IEC binary prefixes ease code review: the unit is explicit.
4
4
5
Compiling C++ object libcommon.fa.p/disas_libvixl_vixl_utils.cc.o
5
Add definitions for RAM / Flash / Flash blocksize.
6
FAILED: libcommon.fa.p/disas_libvixl_vixl_utils.cc.o
7
c++ -Ilibcommon.fa.p -I. -I.. [...] -o libcommon.fa.p/disas_libvixl_vixl_utils.cc.o -c ../disas/libvixl/vixl/utils.cc
8
In file included from /home/philmd/qemu/disas/libvixl/vixl/utils.h:30,
9
from ../disas/libvixl/vixl/utils.cc:27:
10
/usr/include/string.h:36:43: error: missing binary operator before token "("
11
36 | #if defined __cplusplus && (__GNUC_PREREQ (4, 4) \
12
| ^
13
/usr/include/string.h:53:62: error: missing binary operator before token "("
14
53 | #if defined __USE_MISC || defined __USE_XOPEN || __GLIBC_USE (ISOC2X)
15
| ^
16
/usr/include/string.h:165:21: error: missing binary operator before token "("
17
165 | || __GLIBC_USE (LIB_EXT2) || __GLIBC_USE (ISOC2X))
18
| ^
19
/usr/include/string.h:174:43: error: missing binary operator before token "("
20
174 | #if defined __USE_XOPEN2K8 || __GLIBC_USE (LIB_EXT2) || __GLIBC_USE (ISOC2X)
21
| ^
22
/usr/include/string.h:492:19: error: missing binary operator before token "("
23
492 | #if __GNUC_PREREQ (3,4)
24
| ^
25
6
26
Relevant information from the host:
27
28
$ lsb_release -d
29
Description: Debian GNU/Linux 11 (bullseye)
30
$ gcc --version
31
gcc (Debian 10.2.1-6) 10.2.1 20210110
32
$ dpkg -S /usr/include/string.h
33
libc6-dev: /usr/include/string.h
34
$ apt-cache show libc6-dev
35
Package: libc6-dev
36
Version: 2.31-11
37
38
Partially cherry-pick vixl commit 78973f258039f6e96 [*]:
39
40
Refactor VIXL to use `extern` block when including C header
41
that do not have a C++ counterpart.
42
43
which is similar to commit 875df03b221 ('osdep: protect qemu/osdep.h
44
with extern "C"').
45
46
[*] https://git.linaro.org/arm/vixl.git/commit/?id=78973f258039f6e96
47
48
Buglink: https://bugs.launchpad.net/qemu/+bug/1914870
49
Suggested-by: Thomas Huth <thuth@redhat.com>
50
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
51
Reviewed-by: Thomas Huth <thuth@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
52
Message-id: 20210516171023.510778-1-f4bug@amsat.org
9
Message-id: 20230109115316.2235-7-philmd@linaro.org
10
Message-Id: <20200223231044.8003-3-philmd@redhat.com>
53
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
54
---
12
---
55
disas/libvixl/vixl/code-buffer.h | 2 +-
13
hw/arm/gumstix.c | 27 ++++++++++++++-------------
56
disas/libvixl/vixl/globals.h | 16 +++++++++-------
14
1 file changed, 14 insertions(+), 13 deletions(-)
57
disas/libvixl/vixl/invalset.h | 2 +-
58
disas/libvixl/vixl/platform.h | 2 ++
59
disas/libvixl/vixl/utils.h | 2 +-
60
disas/libvixl/vixl/utils.cc | 2 +-
61
6 files changed, 15 insertions(+), 11 deletions(-)
62
15
63
diff --git a/disas/libvixl/vixl/code-buffer.h b/disas/libvixl/vixl/code-buffer.h
16
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
64
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
65
--- a/disas/libvixl/vixl/code-buffer.h
18
--- a/hw/arm/gumstix.c
66
+++ b/disas/libvixl/vixl/code-buffer.h
19
+++ b/hw/arm/gumstix.c
67
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
68
#ifndef VIXL_CODE_BUFFER_H
21
*/
69
#define VIXL_CODE_BUFFER_H
22
70
23
#include "qemu/osdep.h"
71
-#include <string.h>
24
+#include "qemu/units.h"
72
+#include <cstring>
25
#include "qemu/error-report.h"
73
#include "vixl/globals.h"
26
#include "hw/arm/pxa.h"
74
27
#include "net/net.h"
75
namespace vixl {
76
diff --git a/disas/libvixl/vixl/globals.h b/disas/libvixl/vixl/globals.h
77
index XXXXXXX..XXXXXXX 100644
78
--- a/disas/libvixl/vixl/globals.h
79
+++ b/disas/libvixl/vixl/globals.h
80
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
81
#define __STDC_FORMAT_MACROS
29
#include "sysemu/qtest.h"
82
#endif
30
#include "cpu.h"
83
31
84
-#include <stdint.h>
32
-static const int sector_len = 128 * 1024;
85
+extern "C" {
33
+#define CONNEX_FLASH_SIZE (16 * MiB)
86
#include <inttypes.h>
34
+#define CONNEX_RAM_SIZE (64 * MiB)
35
+
36
+#define VERDEX_FLASH_SIZE (32 * MiB)
37
+#define VERDEX_RAM_SIZE (256 * MiB)
38
+
39
+#define FLASH_SECTOR_SIZE (128 * KiB)
40
41
static void connex_init(MachineState *machine)
42
{
43
PXA2xxState *cpu;
44
DriveInfo *dinfo;
45
46
- uint32_t connex_rom = 0x01000000;
47
- uint32_t connex_ram = 0x04000000;
87
-
48
-
88
-#include <assert.h>
49
- cpu = pxa255_init(connex_ram);
89
-#include <stdarg.h>
50
+ cpu = pxa255_init(CONNEX_RAM_SIZE);
90
-#include <stdio.h>
51
91
#include <stdint.h>
52
dinfo = drive_get(IF_PFLASH, 0, 0);
92
-#include <stdlib.h>
53
if (!dinfo && !qtest_enabled()) {
93
-#include <stddef.h>
54
@@ -XXX,XX +XXX,XX @@ static void connex_init(MachineState *machine)
94
+}
55
}
95
+
56
96
+#include <cassert>
57
/* Numonyx RC28F128J3F75 */
97
+#include <cstdarg>
58
- if (!pflash_cfi01_register(0x00000000, "connext.rom", connex_rom,
98
+#include <cstddef>
59
+ if (!pflash_cfi01_register(0x00000000, "connext.rom", CONNEX_FLASH_SIZE,
99
+#include <cstdio>
60
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
100
+#include <cstdlib>
61
- sector_len, 2, 0, 0, 0, 0, 0)) {
101
+
62
+ FLASH_SECTOR_SIZE, 2, 0, 0, 0, 0, 0)) {
102
#include "vixl/platform.h"
63
error_report("Error registering flash memory");
103
64
exit(1);
104
65
}
105
diff --git a/disas/libvixl/vixl/invalset.h b/disas/libvixl/vixl/invalset.h
66
@@ -XXX,XX +XXX,XX @@ static void verdex_init(MachineState *machine)
106
index XXXXXXX..XXXXXXX 100644
67
PXA2xxState *cpu;
107
--- a/disas/libvixl/vixl/invalset.h
68
DriveInfo *dinfo;
108
+++ b/disas/libvixl/vixl/invalset.h
69
109
@@ -XXX,XX +XXX,XX @@
70
- uint32_t verdex_rom = 0x02000000;
110
#ifndef VIXL_INVALSET_H_
71
- uint32_t verdex_ram = 0x10000000;
111
#define VIXL_INVALSET_H_
72
-
112
73
- cpu = pxa270_init(verdex_ram, machine->cpu_type);
113
-#include <string.h>
74
+ cpu = pxa270_init(VERDEX_RAM_SIZE, machine->cpu_type);
114
+#include <cstring>
75
115
76
dinfo = drive_get(IF_PFLASH, 0, 0);
116
#include <algorithm>
77
if (!dinfo && !qtest_enabled()) {
117
#include <vector>
78
@@ -XXX,XX +XXX,XX @@ static void verdex_init(MachineState *machine)
118
diff --git a/disas/libvixl/vixl/platform.h b/disas/libvixl/vixl/platform.h
79
}
119
index XXXXXXX..XXXXXXX 100644
80
120
--- a/disas/libvixl/vixl/platform.h
81
/* Micron RC28F256P30TFA */
121
+++ b/disas/libvixl/vixl/platform.h
82
- if (!pflash_cfi01_register(0x00000000, "verdex.rom", verdex_rom,
122
@@ -XXX,XX +XXX,XX @@
83
+ if (!pflash_cfi01_register(0x00000000, "verdex.rom", VERDEX_FLASH_SIZE,
123
#define PLATFORM_H
84
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
124
85
- sector_len, 2, 0, 0, 0, 0, 0)) {
125
// Define platform specific functionalities.
86
+ FLASH_SECTOR_SIZE, 2, 0, 0, 0, 0, 0)) {
126
+extern "C" {
87
error_report("Error registering flash memory");
127
#include <signal.h>
88
exit(1);
128
+}
89
}
129
130
namespace vixl {
131
inline void HostBreakpoint() { raise(SIGINT); }
132
diff --git a/disas/libvixl/vixl/utils.h b/disas/libvixl/vixl/utils.h
133
index XXXXXXX..XXXXXXX 100644
134
--- a/disas/libvixl/vixl/utils.h
135
+++ b/disas/libvixl/vixl/utils.h
136
@@ -XXX,XX +XXX,XX @@
137
#ifndef VIXL_UTILS_H
138
#define VIXL_UTILS_H
139
140
-#include <string.h>
141
#include <cmath>
142
+#include <cstring>
143
#include "vixl/globals.h"
144
#include "vixl/compiler-intrinsics.h"
145
146
diff --git a/disas/libvixl/vixl/utils.cc b/disas/libvixl/vixl/utils.cc
147
index XXXXXXX..XXXXXXX 100644
148
--- a/disas/libvixl/vixl/utils.cc
149
+++ b/disas/libvixl/vixl/utils.cc
150
@@ -XXX,XX +XXX,XX @@
151
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
152
153
#include "vixl/utils.h"
154
-#include <stdio.h>
155
+#include <cstdio>
156
157
namespace vixl {
158
159
--
90
--
160
2.20.1
91
2.34.1
161
92
162
93
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
IEC binary prefixes ease code review: the unit is explicit.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
5
Message-id: 20210525010358.152808-69-richard.henderson@linaro.org
5
Add the FLASH_SECTOR_SIZE definition.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230109115316.2235-8-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/sve.decode | 6 ++++++
12
hw/arm/mainstone.c | 18 ++++++++++--------
9
target/arm/translate-sve.c | 11 +++++++++++
13
1 file changed, 10 insertions(+), 8 deletions(-)
10
2 files changed, 17 insertions(+)
11
14
12
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
15
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/sve.decode
17
--- a/hw/arm/mainstone.c
15
+++ b/target/arm/sve.decode
18
+++ b/hw/arm/mainstone.c
16
@@ -XXX,XX +XXX,XX @@ STNT1_zprz 1110010 .. 00 ..... 001 ... ..... ..... \
19
@@ -XXX,XX +XXX,XX @@
17
# SVE2 32-bit scatter non-temporal store (vector plus scalar)
20
* GNU GPL, version 2 or (at your option) any later version.
18
STNT1_zprz 1110010 .. 10 ..... 001 ... ..... ..... \
21
*/
19
@rprr_scatter_store xs=0 esz=2 scale=0
22
#include "qemu/osdep.h"
23
+#include "qemu/units.h"
24
#include "qemu/error-report.h"
25
#include "qapi/error.h"
26
#include "hw/arm/pxa.h"
27
@@ -XXX,XX +XXX,XX @@ static const struct keymap map[0xE0] = {
28
29
enum mainstone_model_e { mainstone };
30
31
-#define MAINSTONE_RAM    0x04000000
32
-#define MAINSTONE_ROM    0x00800000
33
-#define MAINSTONE_FLASH    0x02000000
34
+#define MAINSTONE_RAM_SIZE (64 * MiB)
35
+#define MAINSTONE_ROM_SIZE (8 * MiB)
36
+#define MAINSTONE_FLASH_SIZE (32 * MiB)
37
38
static struct arm_boot_info mainstone_binfo = {
39
.loader_start = PXA2XX_SDRAM_BASE,
40
- .ram_size = 0x04000000,
41
+ .ram_size = MAINSTONE_RAM_SIZE,
42
};
43
44
+#define FLASH_SECTOR_SIZE (256 * KiB)
20
+
45
+
21
+### SVE2 Crypto Extensions
46
static void mainstone_common_init(MachineState *machine,
22
+
47
enum mainstone_model_e model, int arm_id)
23
+# SVE2 crypto unary operations
48
{
24
+# AESMC and AESIMC
49
- uint32_t sector_len = 256 * 1024;
25
+AESMC 01000101 00 10000011100 decrypt:1 00000 rd:5
50
hwaddr mainstone_flash_base[] = { MST_FLASH_0, MST_FLASH_1 };
26
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
51
PXA2xxState *mpu;
27
index XXXXXXX..XXXXXXX 100644
52
DeviceState *mst_irq;
28
--- a/target/arm/translate-sve.c
53
@@ -XXX,XX +XXX,XX @@ static void mainstone_common_init(MachineState *machine,
29
+++ b/target/arm/translate-sve.c
54
30
@@ -XXX,XX +XXX,XX @@ static bool trans_USDOT_zzzz(DisasContext *s, arg_USDOT_zzzz *a)
55
/* Setup CPU & memory */
31
}
56
mpu = pxa270_init(mainstone_binfo.ram_size, machine->cpu_type);
32
return true;
57
- memory_region_init_rom(rom, NULL, "mainstone.rom", MAINSTONE_ROM,
33
}
58
+ memory_region_init_rom(rom, NULL, "mainstone.rom", MAINSTONE_ROM_SIZE,
34
+
59
&error_fatal);
35
+static bool trans_AESMC(DisasContext *s, arg_AESMC *a)
60
memory_region_add_subregion(get_system_memory(), 0x00000000, rom);
36
+{
61
37
+ if (!dc_isar_feature(aa64_sve2_aes, s)) {
62
@@ -XXX,XX +XXX,XX @@ static void mainstone_common_init(MachineState *machine,
38
+ return false;
63
dinfo = drive_get(IF_PFLASH, 0, i);
39
+ }
64
if (!pflash_cfi01_register(mainstone_flash_base[i],
40
+ if (sve_access_check(s)) {
65
i ? "mainstone.flash1" : "mainstone.flash0",
41
+ gen_gvec_ool_zz(s, gen_helper_crypto_aesmc, a->rd, a->rd, a->decrypt);
66
- MAINSTONE_FLASH,
42
+ }
67
+ MAINSTONE_FLASH_SIZE,
43
+ return true;
68
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
44
+}
69
- sector_len, 4, 0, 0, 0, 0, 0)) {
70
+ FLASH_SECTOR_SIZE, 4, 0, 0, 0, 0, 0)) {
71
error_report("Error registering flash memory");
72
exit(1);
73
}
45
--
74
--
46
2.20.1
75
2.34.1
47
76
48
77
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
We're about to add more variations on this theme.
3
IEC binary prefixes ease code review: the unit is explicit.
4
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Add the FLASH_SECTOR_SIZE definition.
6
Message-id: 20210525010358.152808-65-richard.henderson@linaro.org
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230109115316.2235-9-philmd@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
target/arm/vec_helper.c | 82 ++++++++++-------------------------------
12
hw/arm/musicpal.c | 9 ++++++---
11
1 file changed, 20 insertions(+), 62 deletions(-)
13
1 file changed, 6 insertions(+), 3 deletions(-)
12
14
13
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
15
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/vec_helper.c
17
--- a/hw/arm/musicpal.c
16
+++ b/target/arm/vec_helper.c
18
+++ b/hw/arm/musicpal.c
17
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_sqrdmulh_idx_d)(void *vd, void *vn, void *vm, uint32_t desc)
19
@@ -XXX,XX +XXX,XX @@
18
/* Integer 8 and 16-bit dot-product.
19
*
20
* Note that for the loops herein, host endianness does not matter
21
- * with respect to the ordering of data within the 64-bit lanes.
22
+ * with respect to the ordering of data within the quad-width lanes.
23
* All elements are treated equally, no matter where they are.
24
*/
20
*/
25
21
26
-void HELPER(gvec_sdot_b)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
22
#include "qemu/osdep.h"
27
-{
23
+#include "qemu/units.h"
28
- intptr_t i, opr_sz = simd_oprsz(desc);
24
#include "qapi/error.h"
29
- int32_t *d = vd, *a = va;
25
#include "cpu.h"
30
- int8_t *n = vn, *m = vm;
26
#include "hw/sysbus.h"
31
-
27
@@ -XXX,XX +XXX,XX @@ static const TypeInfo musicpal_key_info = {
32
- for (i = 0; i < opr_sz / 4; ++i) {
28
.class_init = musicpal_key_class_init,
33
- d[i] = (a[i] +
29
};
34
- n[i * 4 + 0] * m[i * 4 + 0] +
30
35
- n[i * 4 + 1] * m[i * 4 + 1] +
31
+#define FLASH_SECTOR_SIZE (64 * KiB)
36
- n[i * 4 + 2] * m[i * 4 + 2] +
32
+
37
- n[i * 4 + 3] * m[i * 4 + 3]);
33
static struct arm_boot_info musicpal_binfo = {
38
- }
34
.loader_start = 0x0,
39
- clear_tail(d, opr_sz, simd_maxsz(desc));
35
.board_id = 0x20e,
40
+#define DO_DOT(NAME, TYPED, TYPEN, TYPEM) \
36
@@ -XXX,XX +XXX,XX @@ static void musicpal_init(MachineState *machine)
41
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, uint32_t desc) \
37
BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
42
+{ \
38
43
+ intptr_t i, opr_sz = simd_oprsz(desc); \
39
flash_size = blk_getlength(blk);
44
+ TYPED *d = vd, *a = va; \
40
- if (flash_size != 8*1024*1024 && flash_size != 16*1024*1024 &&
45
+ TYPEN *n = vn; \
41
- flash_size != 32*1024*1024) {
46
+ TYPEM *m = vm; \
42
+ if (flash_size != 8 * MiB && flash_size != 16 * MiB &&
47
+ for (i = 0; i < opr_sz / sizeof(TYPED); ++i) { \
43
+ flash_size != 32 * MiB) {
48
+ d[i] = (a[i] + \
44
error_report("Invalid flash image size");
49
+ (TYPED)n[i * 4 + 0] * m[i * 4 + 0] + \
45
exit(1);
50
+ (TYPED)n[i * 4 + 1] * m[i * 4 + 1] + \
46
}
51
+ (TYPED)n[i * 4 + 2] * m[i * 4 + 2] + \
47
@@ -XXX,XX +XXX,XX @@ static void musicpal_init(MachineState *machine)
52
+ (TYPED)n[i * 4 + 3] * m[i * 4 + 3]); \
48
*/
53
+ } \
49
pflash_cfi02_register(0x100000000ULL - MP_FLASH_SIZE_MAX,
54
+ clear_tail(d, opr_sz, simd_maxsz(desc)); \
50
"musicpal.flash", flash_size,
55
}
51
- blk, 0x10000,
56
52
+ blk, FLASH_SECTOR_SIZE,
57
-void HELPER(gvec_udot_b)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
53
MP_FLASH_SIZE_MAX / flash_size,
58
-{
54
2, 0x00BF, 0x236D, 0x0000, 0x0000,
59
- intptr_t i, opr_sz = simd_oprsz(desc);
55
0x5555, 0x2AAA, 0);
60
- uint32_t *d = vd, *a = va;
61
- uint8_t *n = vn, *m = vm;
62
-
63
- for (i = 0; i < opr_sz / 4; ++i) {
64
- d[i] = (a[i] +
65
- n[i * 4 + 0] * m[i * 4 + 0] +
66
- n[i * 4 + 1] * m[i * 4 + 1] +
67
- n[i * 4 + 2] * m[i * 4 + 2] +
68
- n[i * 4 + 3] * m[i * 4 + 3]);
69
- }
70
- clear_tail(d, opr_sz, simd_maxsz(desc));
71
-}
72
-
73
-void HELPER(gvec_sdot_h)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
74
-{
75
- intptr_t i, opr_sz = simd_oprsz(desc);
76
- int64_t *d = vd, *a = va;
77
- int16_t *n = vn, *m = vm;
78
-
79
- for (i = 0; i < opr_sz / 8; ++i) {
80
- d[i] = (a[i] +
81
- (int64_t)n[i * 4 + 0] * m[i * 4 + 0] +
82
- (int64_t)n[i * 4 + 1] * m[i * 4 + 1] +
83
- (int64_t)n[i * 4 + 2] * m[i * 4 + 2] +
84
- (int64_t)n[i * 4 + 3] * m[i * 4 + 3]);
85
- }
86
- clear_tail(d, opr_sz, simd_maxsz(desc));
87
-}
88
-
89
-void HELPER(gvec_udot_h)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
90
-{
91
- intptr_t i, opr_sz = simd_oprsz(desc);
92
- uint64_t *d = vd, *a = va;
93
- uint16_t *n = vn, *m = vm;
94
-
95
- for (i = 0; i < opr_sz / 8; ++i) {
96
- d[i] = (a[i] +
97
- (uint64_t)n[i * 4 + 0] * m[i * 4 + 0] +
98
- (uint64_t)n[i * 4 + 1] * m[i * 4 + 1] +
99
- (uint64_t)n[i * 4 + 2] * m[i * 4 + 2] +
100
- (uint64_t)n[i * 4 + 3] * m[i * 4 + 3]);
101
- }
102
- clear_tail(d, opr_sz, simd_maxsz(desc));
103
-}
104
+DO_DOT(gvec_sdot_b, int32_t, int8_t, int8_t)
105
+DO_DOT(gvec_udot_b, uint32_t, uint8_t, uint8_t)
106
+DO_DOT(gvec_sdot_h, int64_t, int16_t, int16_t)
107
+DO_DOT(gvec_udot_h, uint64_t, uint16_t, uint16_t)
108
109
void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm,
110
void *va, uint32_t desc)
111
--
56
--
112
2.20.1
57
2.34.1
113
58
114
59
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
The total_ram_v1/total_ram_v2 definitions were never used.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
5
Message-id: 20210525010358.152808-67-richard.henderson@linaro.org
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20230109115316.2235-10-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
9
---
8
target/arm/cpu.h | 5 +++++
10
hw/arm/omap_sx1.c | 2 --
9
target/arm/helper.h | 4 ++++
11
1 file changed, 2 deletions(-)
10
target/arm/sve.decode | 4 ++++
11
target/arm/translate-sve.c | 16 ++++++++++++++++
12
target/arm/vec_helper.c | 2 ++
13
5 files changed, 31 insertions(+)
14
12
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
15
--- a/hw/arm/omap_sx1.c
18
+++ b/target/arm/cpu.h
16
+++ b/hw/arm/omap_sx1.c
19
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sve2_bitperm(const ARMISARegisters *id)
17
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps static_ops = {
20
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BITPERM) != 0;
18
#define flash0_size    (16 * 1024 * 1024)
21
}
19
#define flash1_size    ( 8 * 1024 * 1024)
22
20
#define flash2_size    (32 * 1024 * 1024)
23
+static inline bool isar_feature_aa64_sve_i8mm(const ARMISARegisters *id)
21
-#define total_ram_v1    (sdram_size + flash0_size + flash1_size + OMAP15XX_SRAM_SIZE)
24
+{
22
-#define total_ram_v2    (sdram_size + flash2_size + OMAP15XX_SRAM_SIZE)
25
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, I8MM) != 0;
23
26
+}
24
static struct arm_boot_info sx1_binfo = {
27
+
25
.loader_start = OMAP_EMIFF_BASE,
28
static inline bool isar_feature_aa64_sve_f32mm(const ARMISARegisters *id)
29
{
30
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, F32MM) != 0;
31
diff --git a/target/arm/helper.h b/target/arm/helper.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/helper.h
34
+++ b/target/arm/helper.h
35
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_sdot_idx_h, TCG_CALL_NO_RWG,
36
void, ptr, ptr, ptr, ptr, i32)
37
DEF_HELPER_FLAGS_5(gvec_udot_idx_h, TCG_CALL_NO_RWG,
38
void, ptr, ptr, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_5(gvec_sudot_idx_b, TCG_CALL_NO_RWG,
40
+ void, ptr, ptr, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_5(gvec_usdot_idx_b, TCG_CALL_NO_RWG,
42
+ void, ptr, ptr, ptr, ptr, i32)
43
44
DEF_HELPER_FLAGS_5(gvec_fcaddh, TCG_CALL_NO_RWG,
45
void, ptr, ptr, ptr, ptr, i32)
46
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/sve.decode
49
+++ b/target/arm/sve.decode
50
@@ -XXX,XX +XXX,XX @@ SQRDMLSH_zzxz_h 01000100 0. 1 ..... 000101 ..... ..... @rrxr_3 esz=1
51
SQRDMLSH_zzxz_s 01000100 10 1 ..... 000101 ..... ..... @rrxr_2 esz=2
52
SQRDMLSH_zzxz_d 01000100 11 1 ..... 000101 ..... ..... @rrxr_1 esz=3
53
54
+# SVE mixed sign dot product (indexed)
55
+USDOT_zzxw_s 01000100 10 1 ..... 000110 ..... ..... @rrxr_2 esz=2
56
+SUDOT_zzxw_s 01000100 10 1 ..... 000111 ..... ..... @rrxr_2 esz=2
57
+
58
# SVE2 saturating multiply-add (indexed)
59
SQDMLALB_zzxw_s 01000100 10 1 ..... 0010.0 ..... ..... @rrxr_3a esz=2
60
SQDMLALB_zzxw_d 01000100 11 1 ..... 0010.0 ..... ..... @rrxr_2a esz=3
61
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/translate-sve.c
64
+++ b/target/arm/translate-sve.c
65
@@ -XXX,XX +XXX,XX @@ DO_RRXR(trans_SDOT_zzxw_d, gen_helper_gvec_sdot_idx_h)
66
DO_RRXR(trans_UDOT_zzxw_s, gen_helper_gvec_udot_idx_b)
67
DO_RRXR(trans_UDOT_zzxw_d, gen_helper_gvec_udot_idx_h)
68
69
+static bool trans_SUDOT_zzxw_s(DisasContext *s, arg_rrxr_esz *a)
70
+{
71
+ if (!dc_isar_feature(aa64_sve_i8mm, s)) {
72
+ return false;
73
+ }
74
+ return do_zzxz_ool(s, a, gen_helper_gvec_sudot_idx_b);
75
+}
76
+
77
+static bool trans_USDOT_zzxw_s(DisasContext *s, arg_rrxr_esz *a)
78
+{
79
+ if (!dc_isar_feature(aa64_sve_i8mm, s)) {
80
+ return false;
81
+ }
82
+ return do_zzxz_ool(s, a, gen_helper_gvec_usdot_idx_b);
83
+}
84
+
85
#undef DO_RRXR
86
87
static bool do_sve2_zzz_data(DisasContext *s, int rd, int rn, int rm, int data,
88
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/vec_helper.c
91
+++ b/target/arm/vec_helper.c
92
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, uint32_t desc) \
93
94
DO_DOT_IDX(gvec_sdot_idx_b, int32_t, int8_t, int8_t, H4)
95
DO_DOT_IDX(gvec_udot_idx_b, uint32_t, uint8_t, uint8_t, H4)
96
+DO_DOT_IDX(gvec_sudot_idx_b, int32_t, int8_t, uint8_t, H4)
97
+DO_DOT_IDX(gvec_usdot_idx_b, int32_t, uint8_t, int8_t, H4)
98
DO_DOT_IDX(gvec_sdot_idx_h, int64_t, int16_t, int16_t, )
99
DO_DOT_IDX(gvec_udot_idx_h, uint64_t, uint16_t, uint16_t, )
100
101
--
26
--
102
2.20.1
27
2.34.1
103
28
104
29
diff view generated by jsdifflib
1
From: Stephen Long <steplong@quicinc.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
IEC binary prefixes ease code review: the unit is explicit.
4
Signed-off-by: Stephen Long <steplong@quicinc.com>
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20210525010358.152808-48-richard.henderson@linaro.org
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-Id: <20200423180347.9403-1-steplong@quicinc.com>
7
Message-id: 20230109115316.2235-11-philmd@linaro.org
8
[rth: Rename the trans_* functions to *_sve2.]
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
target/arm/sve.decode | 11 +++++++++--
10
hw/arm/omap_sx1.c | 33 +++++++++++++++++----------------
13
target/arm/translate-sve.c | 35 ++++++++++++++++++++++++++++++-----
11
1 file changed, 17 insertions(+), 16 deletions(-)
14
2 files changed, 39 insertions(+), 7 deletions(-)
15
12
16
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
13
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/sve.decode
15
--- a/hw/arm/omap_sx1.c
19
+++ b/target/arm/sve.decode
16
+++ b/hw/arm/omap_sx1.c
20
@@ -XXX,XX +XXX,XX @@ CPY_z_i 00000101 .. 01 .... 00 . ........ ..... @rdn_pg4 imm=%sh8_i8s
17
@@ -XXX,XX +XXX,XX @@
21
18
* with this program; if not, see <http://www.gnu.org/licenses/>.
22
### SVE Permute - Extract Group
23
24
-# SVE extract vector (immediate offset)
25
+# SVE extract vector (destructive)
26
EXT 00000101 001 ..... 000 ... rm:5 rd:5 \
27
&rrri rn=%reg_movprfx imm=%imm8_16_10
28
29
+# SVE2 extract vector (constructive)
30
+EXT_sve2 00000101 011 ..... 000 ... rn:5 rd:5 \
31
+ &rri imm=%imm8_16_10
32
+
33
### SVE Permute - Unpredicated Group
34
35
# SVE broadcast general register
36
@@ -XXX,XX +XXX,XX @@ REVH 00000101 .. 1001 01 100 ... ..... ..... @rd_pg_rn
37
REVW 00000101 .. 1001 10 100 ... ..... ..... @rd_pg_rn
38
RBIT 00000101 .. 1001 11 100 ... ..... ..... @rd_pg_rn
39
40
-# SVE vector splice (predicated)
41
+# SVE vector splice (predicated, destructive)
42
SPLICE 00000101 .. 101 100 100 ... ..... ..... @rdn_pg_rm
43
44
+# SVE2 vector splice (predicated, constructive)
45
+SPLICE_sve2 00000101 .. 101 101 100 ... ..... ..... @rd_pg_rn
46
+
47
### SVE Select Vectors Group
48
49
# SVE select vector elements (predicated)
50
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/translate-sve.c
53
+++ b/target/arm/translate-sve.c
54
@@ -XXX,XX +XXX,XX @@ static bool trans_CPY_z_i(DisasContext *s, arg_CPY_z_i *a)
55
*** SVE Permute Extract Group
56
*/
19
*/
57
20
#include "qemu/osdep.h"
58
-static bool trans_EXT(DisasContext *s, arg_EXT *a)
21
+#include "qemu/units.h"
59
+static bool do_EXT(DisasContext *s, int rd, int rn, int rm, int imm)
22
#include "qapi/error.h"
60
{
23
#include "ui/console.h"
61
if (!sve_access_check(s)) {
24
#include "hw/arm/omap.h"
62
return true;
25
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps static_ops = {
26
.endianness = DEVICE_NATIVE_ENDIAN,
27
};
28
29
-#define sdram_size    0x02000000
30
-#define sector_size    (128 * 1024)
31
-#define flash0_size    (16 * 1024 * 1024)
32
-#define flash1_size    ( 8 * 1024 * 1024)
33
-#define flash2_size    (32 * 1024 * 1024)
34
+#define SDRAM_SIZE (32 * MiB)
35
+#define SECTOR_SIZE (128 * KiB)
36
+#define FLASH0_SIZE (16 * MiB)
37
+#define FLASH1_SIZE (8 * MiB)
38
+#define FLASH2_SIZE (32 * MiB)
39
40
static struct arm_boot_info sx1_binfo = {
41
.loader_start = OMAP_EMIFF_BASE,
42
- .ram_size = sdram_size,
43
+ .ram_size = SDRAM_SIZE,
44
.board_id = 0x265,
45
};
46
47
@@ -XXX,XX +XXX,XX @@ static void sx1_init(MachineState *machine, const int version)
48
static uint32_t cs3val = 0x00001139;
49
DriveInfo *dinfo;
50
int fl_idx;
51
- uint32_t flash_size = flash0_size;
52
+ uint32_t flash_size = FLASH0_SIZE;
53
54
if (machine->ram_size != mc->default_ram_size) {
55
char *sz = size_to_str(mc->default_ram_size);
56
@@ -XXX,XX +XXX,XX @@ static void sx1_init(MachineState *machine, const int version)
63
}
57
}
64
58
65
unsigned vsz = vec_full_reg_size(s);
59
if (version == 2) {
66
- unsigned n_ofs = a->imm >= vsz ? 0 : a->imm;
60
- flash_size = flash2_size;
67
+ unsigned n_ofs = imm >= vsz ? 0 : imm;
61
+ flash_size = FLASH2_SIZE;
68
unsigned n_siz = vsz - n_ofs;
62
}
69
- unsigned d = vec_full_reg_offset(s, a->rd);
63
70
- unsigned n = vec_full_reg_offset(s, a->rn);
64
memory_region_add_subregion(address_space, OMAP_EMIFF_BASE, machine->ram);
71
- unsigned m = vec_full_reg_offset(s, a->rm);
65
@@ -XXX,XX +XXX,XX @@ static void sx1_init(MachineState *machine, const int version)
72
+ unsigned d = vec_full_reg_offset(s, rd);
66
if (!pflash_cfi01_register(OMAP_CS0_BASE,
73
+ unsigned n = vec_full_reg_offset(s, rn);
67
"omap_sx1.flash0-1", flash_size,
74
+ unsigned m = vec_full_reg_offset(s, rm);
68
blk_by_legacy_dinfo(dinfo),
75
69
- sector_size, 4, 0, 0, 0, 0, 0)) {
76
/* Use host vector move insns if we have appropriate sizes
70
+ SECTOR_SIZE, 4, 0, 0, 0, 0, 0)) {
77
* and no unfortunate overlap.
71
fprintf(stderr, "qemu: Error registering flash memory %d.\n",
78
@@ -XXX,XX +XXX,XX @@ static bool trans_EXT(DisasContext *s, arg_EXT *a)
72
fl_idx);
79
return true;
73
}
74
@@ -XXX,XX +XXX,XX @@ static void sx1_init(MachineState *machine, const int version)
75
(dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
76
MemoryRegion *flash_1 = g_new(MemoryRegion, 1);
77
memory_region_init_rom(flash_1, NULL, "omap_sx1.flash1-0",
78
- flash1_size, &error_fatal);
79
+ FLASH1_SIZE, &error_fatal);
80
memory_region_add_subregion(address_space, OMAP_CS1_BASE, flash_1);
81
82
memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val,
83
- "sx1.cs1", OMAP_CS1_SIZE - flash1_size);
84
+ "sx1.cs1", OMAP_CS1_SIZE - FLASH1_SIZE);
85
memory_region_add_subregion(address_space,
86
- OMAP_CS1_BASE + flash1_size, &cs[1]);
87
+ OMAP_CS1_BASE + FLASH1_SIZE, &cs[1]);
88
89
if (!pflash_cfi01_register(OMAP_CS1_BASE,
90
- "omap_sx1.flash1-1", flash1_size,
91
+ "omap_sx1.flash1-1", FLASH1_SIZE,
92
blk_by_legacy_dinfo(dinfo),
93
- sector_size, 4, 0, 0, 0, 0, 0)) {
94
+ SECTOR_SIZE, 4, 0, 0, 0, 0, 0)) {
95
fprintf(stderr, "qemu: Error registering flash memory %d.\n",
96
fl_idx);
97
}
98
@@ -XXX,XX +XXX,XX @@ static void sx1_machine_v2_class_init(ObjectClass *oc, void *data)
99
mc->init = sx1_init_v2;
100
mc->ignore_memory_transaction_failures = true;
101
mc->default_cpu_type = ARM_CPU_TYPE_NAME("ti925t");
102
- mc->default_ram_size = sdram_size;
103
+ mc->default_ram_size = SDRAM_SIZE;
104
mc->default_ram_id = "omap1.dram";
80
}
105
}
81
106
82
+static bool trans_EXT(DisasContext *s, arg_EXT *a)
107
@@ -XXX,XX +XXX,XX @@ static void sx1_machine_v1_class_init(ObjectClass *oc, void *data)
83
+{
108
mc->init = sx1_init_v1;
84
+ return do_EXT(s, a->rd, a->rn, a->rm, a->imm);
109
mc->ignore_memory_transaction_failures = true;
85
+}
110
mc->default_cpu_type = ARM_CPU_TYPE_NAME("ti925t");
86
+
111
- mc->default_ram_size = sdram_size;
87
+static bool trans_EXT_sve2(DisasContext *s, arg_rri *a)
112
+ mc->default_ram_size = SDRAM_SIZE;
88
+{
113
mc->default_ram_id = "omap1.dram";
89
+ if (!dc_isar_feature(aa64_sve2, s)) {
90
+ return false;
91
+ }
92
+ return do_EXT(s, a->rd, a->rn, (a->rn + 1) % 32, a->imm);
93
+}
94
+
95
/*
96
*** SVE Permute - Unpredicated Group
97
*/
98
@@ -XXX,XX +XXX,XX @@ static bool trans_SPLICE(DisasContext *s, arg_rprr_esz *a)
99
return true;
100
}
114
}
101
115
102
+static bool trans_SPLICE_sve2(DisasContext *s, arg_rpr_esz *a)
103
+{
104
+ if (!dc_isar_feature(aa64_sve2, s)) {
105
+ return false;
106
+ }
107
+ if (sve_access_check(s)) {
108
+ gen_gvec_ool_zzzp(s, gen_helper_sve_splice,
109
+ a->rd, a->rn, (a->rn + 1) % 32, a->pg, a->esz);
110
+ }
111
+ return true;
112
+}
113
+
114
/*
115
*** SVE Integer Compare - Vectors Group
116
*/
117
--
116
--
118
2.20.1
117
2.34.1
119
118
120
119
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Using g_memdup is a bit more compact than g_new + memcpy.
3
IEC binary prefixes ease code review: the unit is explicit.
4
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Add the FLASH_SECTOR_SIZE definition.
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
7
Message-id: 20210509151618.2331764-2-f4bug@amsat.org
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-Id: <20210508201640.1045808-1-richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
[PMD: Split from bigger patch]
9
Message-id: 20230109115316.2235-12-philmd@linaro.org
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
accel/tcg/cputlb.c | 15 ++++-----------
12
hw/arm/z2.c | 6 ++++--
15
1 file changed, 4 insertions(+), 11 deletions(-)
13
1 file changed, 4 insertions(+), 2 deletions(-)
16
14
17
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
15
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/accel/tcg/cputlb.c
17
--- a/hw/arm/z2.c
20
+++ b/accel/tcg/cputlb.c
18
+++ b/hw/arm/z2.c
21
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
19
@@ -XXX,XX +XXX,XX @@
22
} else if (encode_pbm_to_runon(&runon, d)) {
20
*/
23
async_run_on_cpu(cpu, tlb_flush_page_bits_by_mmuidx_async_1, runon);
21
24
} else {
22
#include "qemu/osdep.h"
25
- TLBFlushPageBitsByMMUIdxData *p
23
+#include "qemu/units.h"
26
- = g_new(TLBFlushPageBitsByMMUIdxData, 1);
24
#include "hw/arm/pxa.h"
27
-
25
#include "hw/arm/boot.h"
28
/* Otherwise allocate a structure, freed by the worker. */
26
#include "hw/i2c/i2c.h"
29
- *p = d;
27
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aer915_info = {
30
+ TLBFlushPageBitsByMMUIdxData *p = g_memdup(&d, sizeof(d));
28
.class_init = aer915_class_init,
31
async_run_on_cpu(cpu, tlb_flush_page_bits_by_mmuidx_async_2,
29
};
32
RUN_ON_CPU_HOST_PTR(p));
30
33
}
31
+#define FLASH_SECTOR_SIZE (64 * KiB)
34
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
32
+
35
flush_all_helper(src_cpu, tlb_flush_page_bits_by_mmuidx_async_1, runon);
33
static void z2_init(MachineState *machine)
36
} else {
34
{
37
CPUState *dst_cpu;
35
- uint32_t sector_len = 0x10000;
38
- TLBFlushPageBitsByMMUIdxData *p;
36
PXA2xxState *mpu;
39
37
DriveInfo *dinfo;
40
/* Allocate a separate data block for each destination cpu. */
38
void *z2_lcd;
41
CPU_FOREACH(dst_cpu) {
39
@@ -XXX,XX +XXX,XX @@ static void z2_init(MachineState *machine)
42
if (dst_cpu != src_cpu) {
40
dinfo = drive_get(IF_PFLASH, 0, 0);
43
- p = g_new(TLBFlushPageBitsByMMUIdxData, 1);
41
if (!pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
44
- *p = d;
42
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
45
+ TLBFlushPageBitsByMMUIdxData *p = g_memdup(&d, sizeof(d));
43
- sector_len, 4, 0, 0, 0, 0, 0)) {
46
async_run_on_cpu(dst_cpu,
44
+ FLASH_SECTOR_SIZE, 4, 0, 0, 0, 0, 0)) {
47
tlb_flush_page_bits_by_mmuidx_async_2,
45
error_report("Error registering flash memory");
48
RUN_ON_CPU_HOST_PTR(p));
46
exit(1);
49
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
50
/* Allocate a separate data block for each destination cpu. */
51
CPU_FOREACH(dst_cpu) {
52
if (dst_cpu != src_cpu) {
53
- p = g_new(TLBFlushPageBitsByMMUIdxData, 1);
54
- *p = d;
55
+ p = g_memdup(&d, sizeof(d));
56
async_run_on_cpu(dst_cpu, tlb_flush_page_bits_by_mmuidx_async_2,
57
RUN_ON_CPU_HOST_PTR(p));
58
}
59
}
60
61
- p = g_new(TLBFlushPageBitsByMMUIdxData, 1);
62
- *p = d;
63
+ p = g_memdup(&d, sizeof(d));
64
async_safe_run_on_cpu(src_cpu, tlb_flush_page_bits_by_mmuidx_async_2,
65
RUN_ON_CPU_HOST_PTR(p));
66
}
47
}
67
--
48
--
68
2.20.1
49
2.34.1
69
50
70
51
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Rename to match tlb_flush_range_locked.
3
Upon introduction in commit b8433303fb ("Set proper device-width
4
for vexpress flash"), ve_pflash_cfi01_register() was calling
5
qdev_init_nofail() which can not fail. This call was later
6
converted with a script to use &error_fatal, still unable to
7
fail. Remove the unreachable code.
4
8
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210509151618.2331764-8-f4bug@amsat.org
11
Message-id: 20230109115316.2235-13-philmd@linaro.org
8
Message-Id: <20210508201640.1045808-1-richard.henderson@linaro.org>
9
[PMD: Split from bigger patch]
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
accel/tcg/cputlb.c | 11 +++++------
14
hw/arm/vexpress.c | 10 +---------
15
1 file changed, 5 insertions(+), 6 deletions(-)
15
1 file changed, 1 insertion(+), 9 deletions(-)
16
16
17
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
17
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/accel/tcg/cputlb.c
19
--- a/hw/arm/vexpress.c
20
+++ b/accel/tcg/cputlb.c
20
+++ b/hw/arm/vexpress.c
21
@@ -XXX,XX +XXX,XX @@ typedef struct {
21
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
22
uint16_t bits;
22
dinfo = drive_get(IF_PFLASH, 0, 0);
23
} TLBFlushRangeData;
23
pflash0 = ve_pflash_cfi01_register(map[VE_NORFLASH0], "vexpress.flash0",
24
24
dinfo);
25
-static void
25
- if (!pflash0) {
26
-tlb_flush_page_bits_by_mmuidx_async_0(CPUState *cpu,
26
- error_report("vexpress: error registering flash 0");
27
- TLBFlushRangeData d)
27
- exit(1);
28
+static void tlb_flush_range_by_mmuidx_async_0(CPUState *cpu,
28
- }
29
+ TLBFlushRangeData d)
29
30
{
30
if (map[VE_NORFLASHALIAS] != -1) {
31
CPUArchState *env = cpu->env_ptr;
31
/* Map flash 0 as an alias into low memory */
32
int mmu_idx;
32
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
33
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_bits_by_mmuidx_async_2(CPUState *cpu,
34
run_on_cpu_data data)
35
{
36
TLBFlushRangeData *d = data.host_ptr;
37
- tlb_flush_page_bits_by_mmuidx_async_0(cpu, *d);
38
+ tlb_flush_range_by_mmuidx_async_0(cpu, *d);
39
g_free(d);
40
}
41
42
@@ -XXX,XX +XXX,XX @@ void tlb_flush_range_by_mmuidx(CPUState *cpu, target_ulong addr,
43
d.bits = bits;
44
45
if (qemu_cpu_is_self(cpu)) {
46
- tlb_flush_page_bits_by_mmuidx_async_0(cpu, d);
47
+ tlb_flush_range_by_mmuidx_async_0(cpu, d);
48
} else {
49
/* Otherwise allocate a structure, freed by the worker. */
50
TLBFlushRangeData *p = g_memdup(&d, sizeof(d));
51
@@ -XXX,XX +XXX,XX @@ void tlb_flush_range_by_mmuidx_all_cpus(CPUState *src_cpu,
52
}
53
}
33
}
54
34
55
- tlb_flush_page_bits_by_mmuidx_async_0(src_cpu, d);
35
dinfo = drive_get(IF_PFLASH, 0, 1);
56
+ tlb_flush_range_by_mmuidx_async_0(src_cpu, d);
36
- if (!ve_pflash_cfi01_register(map[VE_NORFLASH1], "vexpress.flash1",
57
}
37
- dinfo)) {
58
38
- error_report("vexpress: error registering flash 1");
59
void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
39
- exit(1);
40
- }
41
+ ve_pflash_cfi01_register(map[VE_NORFLASH1], "vexpress.flash1", dinfo);
42
43
sram_size = 0x2000000;
44
memory_region_init_ram(sram, NULL, "vexpress.sram", sram_size,
60
--
45
--
61
2.20.1
46
2.34.1
62
47
63
48
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Rename tlb_flush_page_bits_locked() -> tlb_flush_range_locked(), and
3
Since its QOM'ification in commit 368a354f02 ("pflash_cfi0x:
4
have callers pass a length argument (currently TARGET_PAGE_SIZE) via
4
QOMified") the pflash_cfi01_register() function does not fail.
5
the TLBFlushPageBitsByMMUIdxData structure.
6
5
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
This call was later converted with a script to use &error_fatal,
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
still unable to fail. Remove the unreachable code.
9
Message-id: 20210509151618.2331764-3-f4bug@amsat.org
8
10
Message-Id: <20210508201640.1045808-1-richard.henderson@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
[PMD: Split from bigger patch]
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20230109115316.2235-14-philmd@linaro.org
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
13
---
16
accel/tcg/cputlb.c | 48 +++++++++++++++++++++++++++++++---------------
14
hw/arm/gumstix.c | 18 ++++++------------
17
1 file changed, 33 insertions(+), 15 deletions(-)
15
hw/arm/mainstone.c | 13 +++++--------
16
hw/arm/omap_sx1.c | 22 ++++++++--------------
17
hw/arm/versatilepb.c | 6 ++----
18
hw/arm/z2.c | 9 +++------
19
5 files changed, 24 insertions(+), 44 deletions(-)
18
20
19
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
21
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
20
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
21
--- a/accel/tcg/cputlb.c
23
--- a/hw/arm/gumstix.c
22
+++ b/accel/tcg/cputlb.c
24
+++ b/hw/arm/gumstix.c
23
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_all_cpus_synced(CPUState *src, target_ulong addr)
25
@@ -XXX,XX +XXX,XX @@ static void connex_init(MachineState *machine)
24
tlb_flush_page_by_mmuidx_all_cpus_synced(src, addr, ALL_MMUIDX_BITS);
25
}
26
27
-static void tlb_flush_page_bits_locked(CPUArchState *env, int midx,
28
- target_ulong page, unsigned bits)
29
+static void tlb_flush_range_locked(CPUArchState *env, int midx,
30
+ target_ulong addr, target_ulong len,
31
+ unsigned bits)
32
{
33
CPUTLBDesc *d = &env_tlb(env)->d[midx];
34
CPUTLBDescFast *f = &env_tlb(env)->f[midx];
35
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_bits_locked(CPUArchState *env, int midx,
36
* If @bits is smaller than the tlb size, there may be multiple entries
37
* within the TLB; otherwise all addresses that match under @mask hit
38
* the same TLB entry.
39
- *
40
* TODO: Perhaps allow bits to be a few bits less than the size.
41
* For now, just flush the entire TLB.
42
+ *
43
+ * If @len is larger than the tlb size, then it will take longer to
44
+ * test all of the entries in the TLB than it will to flush it all.
45
*/
46
- if (mask < f->mask) {
47
+ if (mask < f->mask || len > f->mask) {
48
tlb_debug("forcing full flush midx %d ("
49
- TARGET_FMT_lx "/" TARGET_FMT_lx ")\n",
50
- midx, page, mask);
51
+ TARGET_FMT_lx "/" TARGET_FMT_lx "+" TARGET_FMT_lx ")\n",
52
+ midx, addr, mask, len);
53
tlb_flush_one_mmuidx_locked(env, midx, get_clock_realtime());
54
return;
55
}
26
}
56
27
57
- /* Check if we need to flush due to large pages. */
28
/* Numonyx RC28F128J3F75 */
58
- if ((page & d->large_page_mask) == d->large_page_addr) {
29
- if (!pflash_cfi01_register(0x00000000, "connext.rom", CONNEX_FLASH_SIZE,
59
+ /*
30
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
60
+ * Check if we need to flush due to large pages.
31
- FLASH_SECTOR_SIZE, 2, 0, 0, 0, 0, 0)) {
61
+ * Because large_page_mask contains all 1's from the msb,
32
- error_report("Error registering flash memory");
62
+ * we only need to test the end of the range.
33
- exit(1);
63
+ */
34
- }
64
+ if (((addr + len - 1) & d->large_page_mask) == d->large_page_addr) {
35
+ pflash_cfi01_register(0x00000000, "connext.rom", CONNEX_FLASH_SIZE,
65
tlb_debug("forcing full flush midx %d ("
36
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
66
TARGET_FMT_lx "/" TARGET_FMT_lx ")\n",
37
+ FLASH_SECTOR_SIZE, 2, 0, 0, 0, 0, 0);
67
midx, d->large_page_addr, d->large_page_mask);
38
68
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_bits_locked(CPUArchState *env, int midx,
39
/* Interrupt line of NIC is connected to GPIO line 36 */
69
return;
40
smc91c111_init(&nd_table[0], 0x04000300,
41
@@ -XXX,XX +XXX,XX @@ static void verdex_init(MachineState *machine)
70
}
42
}
71
43
72
- if (tlb_flush_entry_mask_locked(tlb_entry(env, midx, page), page, mask)) {
44
/* Micron RC28F256P30TFA */
73
- tlb_n_used_entries_dec(env, midx);
45
- if (!pflash_cfi01_register(0x00000000, "verdex.rom", VERDEX_FLASH_SIZE,
74
+ for (target_ulong i = 0; i < len; i += TARGET_PAGE_SIZE) {
46
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
75
+ target_ulong page = addr + i;
47
- FLASH_SECTOR_SIZE, 2, 0, 0, 0, 0, 0)) {
76
+ CPUTLBEntry *entry = tlb_entry(env, midx, page);
48
- error_report("Error registering flash memory");
77
+
49
- exit(1);
78
+ if (tlb_flush_entry_mask_locked(entry, page, mask)) {
50
- }
79
+ tlb_n_used_entries_dec(env, midx);
51
+ pflash_cfi01_register(0x00000000, "verdex.rom", VERDEX_FLASH_SIZE,
80
+ }
52
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
81
+ tlb_flush_vtlb_page_mask_locked(env, midx, page, mask);
53
+ FLASH_SECTOR_SIZE, 2, 0, 0, 0, 0, 0);
54
55
/* Interrupt line of NIC is connected to GPIO line 99 */
56
smc91c111_init(&nd_table[0], 0x04000300,
57
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/arm/mainstone.c
60
+++ b/hw/arm/mainstone.c
61
@@ -XXX,XX +XXX,XX @@ static void mainstone_common_init(MachineState *machine,
62
/* There are two 32MiB flash devices on the board */
63
for (i = 0; i < 2; i ++) {
64
dinfo = drive_get(IF_PFLASH, 0, i);
65
- if (!pflash_cfi01_register(mainstone_flash_base[i],
66
- i ? "mainstone.flash1" : "mainstone.flash0",
67
- MAINSTONE_FLASH_SIZE,
68
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
69
- FLASH_SECTOR_SIZE, 4, 0, 0, 0, 0, 0)) {
70
- error_report("Error registering flash memory");
71
- exit(1);
72
- }
73
+ pflash_cfi01_register(mainstone_flash_base[i],
74
+ i ? "mainstone.flash1" : "mainstone.flash0",
75
+ MAINSTONE_FLASH_SIZE,
76
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
77
+ FLASH_SECTOR_SIZE, 4, 0, 0, 0, 0, 0);
82
}
78
}
83
- tlb_flush_vtlb_page_mask_locked(env, midx, page, mask);
79
84
}
80
mst_irq = sysbus_create_simple("mainstone-fpga", MST_FPGA_PHYS,
85
81
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
86
typedef struct {
82
index XXXXXXX..XXXXXXX 100644
87
target_ulong addr;
83
--- a/hw/arm/omap_sx1.c
88
+ target_ulong len;
84
+++ b/hw/arm/omap_sx1.c
89
uint16_t idxmap;
85
@@ -XXX,XX +XXX,XX @@ static void sx1_init(MachineState *machine, const int version)
90
uint16_t bits;
86
91
} TLBFlushPageBitsByMMUIdxData;
87
fl_idx = 0;
92
@@ -XXX,XX +XXX,XX @@ tlb_flush_page_bits_by_mmuidx_async_0(CPUState *cpu,
88
if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
93
89
- if (!pflash_cfi01_register(OMAP_CS0_BASE,
94
assert_cpu_is_self(cpu);
90
- "omap_sx1.flash0-1", flash_size,
95
91
- blk_by_legacy_dinfo(dinfo),
96
- tlb_debug("page addr:" TARGET_FMT_lx "/%u mmu_map:0x%x\n",
92
- SECTOR_SIZE, 4, 0, 0, 0, 0, 0)) {
97
- d.addr, d.bits, d.idxmap);
93
- fprintf(stderr, "qemu: Error registering flash memory %d.\n",
98
+ tlb_debug("range:" TARGET_FMT_lx "/%u+" TARGET_FMT_lx " mmu_map:0x%x\n",
94
- fl_idx);
99
+ d.addr, d.bits, d.len, d.idxmap);
95
- }
100
96
+ pflash_cfi01_register(OMAP_CS0_BASE,
101
qemu_spin_lock(&env_tlb(env)->c.lock);
97
+ "omap_sx1.flash0-1", flash_size,
102
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
98
+ blk_by_legacy_dinfo(dinfo),
103
if ((d.idxmap >> mmu_idx) & 1) {
99
+ SECTOR_SIZE, 4, 0, 0, 0, 0, 0);
104
- tlb_flush_page_bits_locked(env, mmu_idx, d.addr, d.bits);
100
fl_idx++;
105
+ tlb_flush_range_locked(env, mmu_idx, d.addr, d.len, d.bits);
106
}
107
}
101
}
108
qemu_spin_unlock(&env_tlb(env)->c.lock);
102
109
103
@@ -XXX,XX +XXX,XX @@ static void sx1_init(MachineState *machine, const int version)
110
- tb_flush_jmp_cache(cpu, d.addr);
104
memory_region_add_subregion(address_space,
111
+ for (target_ulong i = 0; i < d.len; i += TARGET_PAGE_SIZE) {
105
OMAP_CS1_BASE + FLASH1_SIZE, &cs[1]);
112
+ tb_flush_jmp_cache(cpu, d.addr + i);
106
113
+ }
107
- if (!pflash_cfi01_register(OMAP_CS1_BASE,
114
}
108
- "omap_sx1.flash1-1", FLASH1_SIZE,
115
109
- blk_by_legacy_dinfo(dinfo),
116
static bool encode_pbm_to_runon(run_on_cpu_data *out,
110
- SECTOR_SIZE, 4, 0, 0, 0, 0, 0)) {
117
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
111
- fprintf(stderr, "qemu: Error registering flash memory %d.\n",
118
112
- fl_idx);
119
/* This should already be page aligned */
113
- }
120
d.addr = addr & TARGET_PAGE_MASK;
114
+ pflash_cfi01_register(OMAP_CS1_BASE,
121
+ d.len = TARGET_PAGE_SIZE;
115
+ "omap_sx1.flash1-1", FLASH1_SIZE,
122
d.idxmap = idxmap;
116
+ blk_by_legacy_dinfo(dinfo),
123
d.bits = bits;
117
+ SECTOR_SIZE, 4, 0, 0, 0, 0, 0);
124
118
fl_idx++;
125
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
119
} else {
126
120
memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val,
127
/* This should already be page aligned */
121
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
128
d.addr = addr & TARGET_PAGE_MASK;
122
index XXXXXXX..XXXXXXX 100644
129
+ d.len = TARGET_PAGE_SIZE;
123
--- a/hw/arm/versatilepb.c
130
d.idxmap = idxmap;
124
+++ b/hw/arm/versatilepb.c
131
d.bits = bits;
125
@@ -XXX,XX +XXX,XX @@ static void versatile_init(MachineState *machine, int board_id)
132
126
/* 0x34000000 NOR Flash */
133
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
127
134
128
dinfo = drive_get(IF_PFLASH, 0, 0);
135
/* This should already be page aligned */
129
- if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, "versatile.flash",
136
d.addr = addr & TARGET_PAGE_MASK;
130
+ pflash_cfi01_register(VERSATILE_FLASH_ADDR, "versatile.flash",
137
+ d.len = TARGET_PAGE_SIZE;
131
VERSATILE_FLASH_SIZE,
138
d.idxmap = idxmap;
132
dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
139
d.bits = bits;
133
VERSATILE_FLASH_SECT_SIZE,
140
134
- 4, 0x0089, 0x0018, 0x0000, 0x0, 0)) {
135
- fprintf(stderr, "qemu: Error registering flash memory.\n");
136
- }
137
+ 4, 0x0089, 0x0018, 0x0000, 0x0, 0);
138
139
versatile_binfo.ram_size = machine->ram_size;
140
versatile_binfo.board_id = board_id;
141
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
142
index XXXXXXX..XXXXXXX 100644
143
--- a/hw/arm/z2.c
144
+++ b/hw/arm/z2.c
145
@@ -XXX,XX +XXX,XX @@ static void z2_init(MachineState *machine)
146
mpu = pxa270_init(z2_binfo.ram_size, machine->cpu_type);
147
148
dinfo = drive_get(IF_PFLASH, 0, 0);
149
- if (!pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
150
- dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
151
- FLASH_SECTOR_SIZE, 4, 0, 0, 0, 0, 0)) {
152
- error_report("Error registering flash memory");
153
- exit(1);
154
- }
155
+ pflash_cfi01_register(Z2_FLASH_BASE, "z2.flash0", Z2_FLASH_SIZE,
156
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
157
+ FLASH_SECTOR_SIZE, 4, 0, 0, 0, 0, 0);
158
159
/* setup keypad */
160
pxa27x_register_keypad(mpu->kp, map, 0x100);
141
--
161
--
142
2.20.1
162
2.34.1
143
163
144
164
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
We're about to add more variations on this theme.
3
To avoid forward-declaring PXA2xxI2CState, declare
4
Accept the inner loop for the _h variants, rather
4
PXA2XX_I2C before its use in pxa2xx_i2c_init() prototype.
5
than keep it unrolled.
6
5
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20210525010358.152808-66-richard.henderson@linaro.org
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20230109140306.23161-2-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
target/arm/vec_helper.c | 160 ++++++++--------------------------------
11
include/hw/arm/pxa.h | 6 +++---
13
1 file changed, 29 insertions(+), 131 deletions(-)
12
1 file changed, 3 insertions(+), 3 deletions(-)
14
13
15
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
14
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/vec_helper.c
16
--- a/include/hw/arm/pxa.h
18
+++ b/target/arm/vec_helper.c
17
+++ b/include/hw/arm/pxa.h
19
@@ -XXX,XX +XXX,XX @@ DO_DOT(gvec_udot_b, uint32_t, uint8_t, uint8_t)
18
@@ -XXX,XX +XXX,XX @@ void pxa27x_register_keypad(PXA2xxKeyPadState *kp,
20
DO_DOT(gvec_sdot_h, int64_t, int16_t, int16_t)
19
const struct keymap *map, int size);
21
DO_DOT(gvec_udot_h, uint64_t, uint16_t, uint16_t)
20
22
21
/* pxa2xx.c */
23
-void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm,
22
-typedef struct PXA2xxI2CState PXA2xxI2CState;
24
- void *va, uint32_t desc)
23
+#define TYPE_PXA2XX_I2C "pxa2xx_i2c"
25
-{
24
+OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxI2CState, PXA2XX_I2C)
26
- intptr_t i, segend, opr_sz = simd_oprsz(desc), opr_sz_4 = opr_sz / 4;
25
+
27
- intptr_t index = simd_data(desc);
26
PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
28
- int32_t *d = vd, *a = va;
27
qemu_irq irq, uint32_t page_size);
29
- int8_t *n = vn;
28
I2CBus *pxa2xx_i2c_bus(PXA2xxI2CState *s);
30
- int8_t *m_indexed = (int8_t *)vm + H4(index) * 4;
29
31
-
30
-#define TYPE_PXA2XX_I2C "pxa2xx_i2c"
32
- /* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
31
typedef struct PXA2xxI2SState PXA2xxI2SState;
33
- * Otherwise opr_sz is a multiple of 16.
32
-OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxI2CState, PXA2XX_I2C)
34
- */
33
35
- segend = MIN(4, opr_sz_4);
34
#define TYPE_PXA2XX_FIR "pxa2xx-fir"
36
- i = 0;
35
OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxFIrState, PXA2XX_FIR)
37
- do {
38
- int8_t m0 = m_indexed[i * 4 + 0];
39
- int8_t m1 = m_indexed[i * 4 + 1];
40
- int8_t m2 = m_indexed[i * 4 + 2];
41
- int8_t m3 = m_indexed[i * 4 + 3];
42
-
43
- do {
44
- d[i] = (a[i] +
45
- n[i * 4 + 0] * m0 +
46
- n[i * 4 + 1] * m1 +
47
- n[i * 4 + 2] * m2 +
48
- n[i * 4 + 3] * m3);
49
- } while (++i < segend);
50
- segend = i + 4;
51
- } while (i < opr_sz_4);
52
-
53
- clear_tail(d, opr_sz, simd_maxsz(desc));
54
+#define DO_DOT_IDX(NAME, TYPED, TYPEN, TYPEM, HD) \
55
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, uint32_t desc) \
56
+{ \
57
+ intptr_t i = 0, opr_sz = simd_oprsz(desc); \
58
+ intptr_t opr_sz_n = opr_sz / sizeof(TYPED); \
59
+ intptr_t segend = MIN(16 / sizeof(TYPED), opr_sz_n); \
60
+ intptr_t index = simd_data(desc); \
61
+ TYPED *d = vd, *a = va; \
62
+ TYPEN *n = vn; \
63
+ TYPEM *m_indexed = (TYPEM *)vm + HD(index) * 4; \
64
+ do { \
65
+ TYPED m0 = m_indexed[i * 4 + 0]; \
66
+ TYPED m1 = m_indexed[i * 4 + 1]; \
67
+ TYPED m2 = m_indexed[i * 4 + 2]; \
68
+ TYPED m3 = m_indexed[i * 4 + 3]; \
69
+ do { \
70
+ d[i] = (a[i] + \
71
+ n[i * 4 + 0] * m0 + \
72
+ n[i * 4 + 1] * m1 + \
73
+ n[i * 4 + 2] * m2 + \
74
+ n[i * 4 + 3] * m3); \
75
+ } while (++i < segend); \
76
+ segend = i + 4; \
77
+ } while (i < opr_sz_n); \
78
+ clear_tail(d, opr_sz, simd_maxsz(desc)); \
79
}
80
81
-void HELPER(gvec_udot_idx_b)(void *vd, void *vn, void *vm,
82
- void *va, uint32_t desc)
83
-{
84
- intptr_t i, segend, opr_sz = simd_oprsz(desc), opr_sz_4 = opr_sz / 4;
85
- intptr_t index = simd_data(desc);
86
- uint32_t *d = vd, *a = va;
87
- uint8_t *n = vn;
88
- uint8_t *m_indexed = (uint8_t *)vm + H4(index) * 4;
89
-
90
- /* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
91
- * Otherwise opr_sz is a multiple of 16.
92
- */
93
- segend = MIN(4, opr_sz_4);
94
- i = 0;
95
- do {
96
- uint8_t m0 = m_indexed[i * 4 + 0];
97
- uint8_t m1 = m_indexed[i * 4 + 1];
98
- uint8_t m2 = m_indexed[i * 4 + 2];
99
- uint8_t m3 = m_indexed[i * 4 + 3];
100
-
101
- do {
102
- d[i] = (a[i] +
103
- n[i * 4 + 0] * m0 +
104
- n[i * 4 + 1] * m1 +
105
- n[i * 4 + 2] * m2 +
106
- n[i * 4 + 3] * m3);
107
- } while (++i < segend);
108
- segend = i + 4;
109
- } while (i < opr_sz_4);
110
-
111
- clear_tail(d, opr_sz, simd_maxsz(desc));
112
-}
113
-
114
-void HELPER(gvec_sdot_idx_h)(void *vd, void *vn, void *vm,
115
- void *va, uint32_t desc)
116
-{
117
- intptr_t i, opr_sz = simd_oprsz(desc), opr_sz_8 = opr_sz / 8;
118
- intptr_t index = simd_data(desc);
119
- int64_t *d = vd, *a = va;
120
- int16_t *n = vn;
121
- int16_t *m_indexed = (int16_t *)vm + index * 4;
122
-
123
- /* This is supported by SVE only, so opr_sz is always a multiple of 16.
124
- * Process the entire segment all at once, writing back the results
125
- * only after we've consumed all of the inputs.
126
- */
127
- for (i = 0; i < opr_sz_8; i += 2) {
128
- int64_t d0, d1;
129
-
130
- d0 = a[i + 0];
131
- d0 += n[i * 4 + 0] * (int64_t)m_indexed[i * 4 + 0];
132
- d0 += n[i * 4 + 1] * (int64_t)m_indexed[i * 4 + 1];
133
- d0 += n[i * 4 + 2] * (int64_t)m_indexed[i * 4 + 2];
134
- d0 += n[i * 4 + 3] * (int64_t)m_indexed[i * 4 + 3];
135
-
136
- d1 = a[i + 1];
137
- d1 += n[i * 4 + 4] * (int64_t)m_indexed[i * 4 + 0];
138
- d1 += n[i * 4 + 5] * (int64_t)m_indexed[i * 4 + 1];
139
- d1 += n[i * 4 + 6] * (int64_t)m_indexed[i * 4 + 2];
140
- d1 += n[i * 4 + 7] * (int64_t)m_indexed[i * 4 + 3];
141
-
142
- d[i + 0] = d0;
143
- d[i + 1] = d1;
144
- }
145
- clear_tail(d, opr_sz, simd_maxsz(desc));
146
-}
147
-
148
-void HELPER(gvec_udot_idx_h)(void *vd, void *vn, void *vm,
149
- void *va, uint32_t desc)
150
-{
151
- intptr_t i, opr_sz = simd_oprsz(desc), opr_sz_8 = opr_sz / 8;
152
- intptr_t index = simd_data(desc);
153
- uint64_t *d = vd, *a = va;
154
- uint16_t *n = vn;
155
- uint16_t *m_indexed = (uint16_t *)vm + index * 4;
156
-
157
- /* This is supported by SVE only, so opr_sz is always a multiple of 16.
158
- * Process the entire segment all at once, writing back the results
159
- * only after we've consumed all of the inputs.
160
- */
161
- for (i = 0; i < opr_sz_8; i += 2) {
162
- uint64_t d0, d1;
163
-
164
- d0 = a[i + 0];
165
- d0 += n[i * 4 + 0] * (uint64_t)m_indexed[i * 4 + 0];
166
- d0 += n[i * 4 + 1] * (uint64_t)m_indexed[i * 4 + 1];
167
- d0 += n[i * 4 + 2] * (uint64_t)m_indexed[i * 4 + 2];
168
- d0 += n[i * 4 + 3] * (uint64_t)m_indexed[i * 4 + 3];
169
-
170
- d1 = a[i + 1];
171
- d1 += n[i * 4 + 4] * (uint64_t)m_indexed[i * 4 + 0];
172
- d1 += n[i * 4 + 5] * (uint64_t)m_indexed[i * 4 + 1];
173
- d1 += n[i * 4 + 6] * (uint64_t)m_indexed[i * 4 + 2];
174
- d1 += n[i * 4 + 7] * (uint64_t)m_indexed[i * 4 + 3];
175
-
176
- d[i + 0] = d0;
177
- d[i + 1] = d1;
178
- }
179
- clear_tail(d, opr_sz, simd_maxsz(desc));
180
-}
181
+DO_DOT_IDX(gvec_sdot_idx_b, int32_t, int8_t, int8_t, H4)
182
+DO_DOT_IDX(gvec_udot_idx_b, uint32_t, uint8_t, uint8_t, H4)
183
+DO_DOT_IDX(gvec_sdot_idx_h, int64_t, int16_t, int16_t, )
184
+DO_DOT_IDX(gvec_udot_idx_h, uint64_t, uint16_t, uint16_t, )
185
186
void HELPER(gvec_fcaddh)(void *vd, void *vn, void *vm,
187
void *vfpst, uint32_t desc)
188
--
36
--
189
2.20.1
37
2.34.1
190
38
191
39
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Add a local 'struct omap_gpif_s *' variable to improve readability.
4
Message-id: 20210525010358.152808-63-richard.henderson@linaro.org
4
(This also eases next commit conversion).
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230109140306.23161-3-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/helper-sve.h | 9 +++++++++
11
hw/gpio/omap_gpio.c | 3 ++-
9
target/arm/sve.decode | 12 ++++++++++++
12
1 file changed, 2 insertions(+), 1 deletion(-)
10
target/arm/sve_helper.c | 28 ++++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 15 +++++++++++++++
12
4 files changed, 64 insertions(+)
13
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
14
diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
16
--- a/hw/gpio/omap_gpio.c
17
+++ b/target/arm/helper-sve.h
17
+++ b/hw/gpio/omap_gpio.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve2_smull_idx_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
18
@@ -XXX,XX +XXX,XX @@ struct omap_gpif_s {
19
DEF_HELPER_FLAGS_4(sve2_smull_idx_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
19
/* General-Purpose I/O of OMAP1 */
20
DEF_HELPER_FLAGS_4(sve2_umull_idx_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
20
static void omap_gpio_set(void *opaque, int line, int level)
21
DEF_HELPER_FLAGS_4(sve2_umull_idx_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
{
22
+
22
- struct omap_gpio_s *s = &((struct omap_gpif_s *) opaque)->omap1;
23
+DEF_HELPER_FLAGS_5(sve2_cmla_idx_h, TCG_CALL_NO_RWG,
23
+ struct omap_gpif_s *p = opaque;
24
+ void, ptr, ptr, ptr, ptr, i32)
24
+ struct omap_gpio_s *s = &p->omap1;
25
+DEF_HELPER_FLAGS_5(sve2_cmla_idx_s, TCG_CALL_NO_RWG,
25
uint16_t prev = s->inputs;
26
+ void, ptr, ptr, ptr, ptr, i32)
26
27
+DEF_HELPER_FLAGS_5(sve2_sqrdcmlah_idx_h, TCG_CALL_NO_RWG,
27
if (level)
28
+ void, ptr, ptr, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_5(sve2_sqrdcmlah_idx_s, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, i32)
31
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/sve.decode
34
+++ b/target/arm/sve.decode
35
@@ -XXX,XX +XXX,XX @@ SQDMLSLB_zzxw_d 01000100 11 1 ..... 0011.0 ..... ..... @rrxr_2a esz=3
36
SQDMLSLT_zzxw_s 01000100 10 1 ..... 0011.1 ..... ..... @rrxr_3a esz=2
37
SQDMLSLT_zzxw_d 01000100 11 1 ..... 0011.1 ..... ..... @rrxr_2a esz=3
38
39
+# SVE2 complex integer multiply-add (indexed)
40
+CMLA_zzxz_h 01000100 10 1 index:2 rm:3 0110 rot:2 rn:5 rd:5 \
41
+ ra=%reg_movprfx
42
+CMLA_zzxz_s 01000100 11 1 index:1 rm:4 0110 rot:2 rn:5 rd:5 \
43
+ ra=%reg_movprfx
44
+
45
+# SVE2 complex saturating integer multiply-add (indexed)
46
+SQRDCMLAH_zzxz_h 01000100 10 1 index:2 rm:3 0111 rot:2 rn:5 rd:5 \
47
+ ra=%reg_movprfx
48
+SQRDCMLAH_zzxz_s 01000100 11 1 index:1 rm:4 0111 rot:2 rn:5 rd:5 \
49
+ ra=%reg_movprfx
50
+
51
# SVE2 multiply-add long (indexed)
52
SMLALB_zzxw_s 01000100 10 1 ..... 1000.0 ..... ..... @rrxr_3a esz=2
53
SMLALB_zzxw_d 01000100 11 1 ..... 1000.0 ..... ..... @rrxr_2a esz=3
54
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/sve_helper.c
57
+++ b/target/arm/sve_helper.c
58
@@ -XXX,XX +XXX,XX @@ DO_CMLA_FUNC(sve2_sqrdcmlah_zzzz_h, int16_t, H2, DO_SQRDMLAH_H)
59
DO_CMLA_FUNC(sve2_sqrdcmlah_zzzz_s, int32_t, H4, DO_SQRDMLAH_S)
60
DO_CMLA_FUNC(sve2_sqrdcmlah_zzzz_d, int64_t, , DO_SQRDMLAH_D)
61
62
+#define DO_CMLA_IDX_FUNC(NAME, TYPE, H, OP) \
63
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, uint32_t desc) \
64
+{ \
65
+ intptr_t i, j, oprsz = simd_oprsz(desc); \
66
+ int rot = extract32(desc, SIMD_DATA_SHIFT, 2); \
67
+ int idx = extract32(desc, SIMD_DATA_SHIFT + 2, 2) * 2; \
68
+ int sel_a = rot & 1, sel_b = sel_a ^ 1; \
69
+ bool sub_r = rot == 1 || rot == 2; \
70
+ bool sub_i = rot >= 2; \
71
+ TYPE *d = vd, *n = vn, *m = vm, *a = va; \
72
+ for (i = 0; i < oprsz / sizeof(TYPE); i += 16 / sizeof(TYPE)) { \
73
+ TYPE elt2_a = m[H(i + idx + sel_a)]; \
74
+ TYPE elt2_b = m[H(i + idx + sel_b)]; \
75
+ for (j = 0; j < 16 / sizeof(TYPE); j += 2) { \
76
+ TYPE elt1_a = n[H(i + j + sel_a)]; \
77
+ d[H2(i + j)] = OP(elt1_a, elt2_a, a[H(i + j)], sub_r); \
78
+ d[H2(i + j + 1)] = OP(elt1_a, elt2_b, a[H(i + j + 1)], sub_i); \
79
+ } \
80
+ } \
81
+}
82
+
83
+DO_CMLA_IDX_FUNC(sve2_cmla_idx_h, int16_t, H2, DO_CMLA)
84
+DO_CMLA_IDX_FUNC(sve2_cmla_idx_s, int32_t, H4, DO_CMLA)
85
+
86
+DO_CMLA_IDX_FUNC(sve2_sqrdcmlah_idx_h, int16_t, H2, DO_SQRDMLAH_H)
87
+DO_CMLA_IDX_FUNC(sve2_sqrdcmlah_idx_s, int32_t, H4, DO_SQRDMLAH_S)
88
+
89
#undef DO_CMLA
90
#undef DO_CMLA_FUNC
91
+#undef DO_CMLA_IDX_FUNC
92
#undef DO_SQRDMLAH_B
93
#undef DO_SQRDMLAH_H
94
#undef DO_SQRDMLAH_S
95
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
96
index XXXXXXX..XXXXXXX 100644
97
--- a/target/arm/translate-sve.c
98
+++ b/target/arm/translate-sve.c
99
@@ -XXX,XX +XXX,XX @@ DO_SVE2_RRXR_TB(trans_UMLSLT_zzxw_d, gen_helper_sve2_umlsl_idx_d, true)
100
101
#undef DO_SVE2_RRXR_TB
102
103
+#define DO_SVE2_RRXR_ROT(NAME, FUNC) \
104
+ static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
105
+ { \
106
+ return do_sve2_zzzz_data(s, a->rd, a->rn, a->rm, a->ra, \
107
+ (a->index << 2) | a->rot, FUNC); \
108
+ }
109
+
110
+DO_SVE2_RRXR_ROT(CMLA_zzxz_h, gen_helper_sve2_cmla_idx_h)
111
+DO_SVE2_RRXR_ROT(CMLA_zzxz_s, gen_helper_sve2_cmla_idx_s)
112
+
113
+DO_SVE2_RRXR_ROT(SQRDCMLAH_zzxz_h, gen_helper_sve2_sqrdcmlah_idx_h)
114
+DO_SVE2_RRXR_ROT(SQRDCMLAH_zzxz_s, gen_helper_sve2_sqrdcmlah_idx_s)
115
+
116
+#undef DO_SVE2_RRXR_ROT
117
+
118
/*
119
*** SVE Floating Point Multiply-Add Indexed Group
120
*/
121
--
28
--
122
2.20.1
29
2.34.1
123
30
124
31
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-10-richard.henderson@linaro.org
5
Message-id: 20230109140306.23161-4-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
target/arm/helper-sve.h | 54 +++++++++++
8
hw/arm/omap1.c | 115 ++++++++++++++++++--------------------
9
target/arm/sve.decode | 11 +++
9
hw/arm/omap2.c | 40 ++++++-------
10
target/arm/sve_helper.c | 194 ++++++++++++++++++++++++++-----------
10
hw/arm/omap_sx1.c | 2 +-
11
target/arm/translate-sve.c | 7 ++
11
hw/arm/palm.c | 2 +-
12
4 files changed, 210 insertions(+), 56 deletions(-)
12
hw/char/omap_uart.c | 7 +--
13
hw/display/omap_dss.c | 15 +++--
14
hw/display/omap_lcdc.c | 9 ++-
15
hw/dma/omap_dma.c | 15 +++--
16
hw/gpio/omap_gpio.c | 15 +++--
17
hw/intc/omap_intc.c | 12 ++--
18
hw/misc/omap_gpmc.c | 12 ++--
19
hw/misc/omap_l4.c | 7 +--
20
hw/misc/omap_sdrc.c | 7 +--
21
hw/misc/omap_tap.c | 5 +-
22
hw/sd/omap_mmc.c | 9 ++-
23
hw/ssi/omap_spi.c | 7 +--
24
hw/timer/omap_gptimer.c | 22 ++++----
25
hw/timer/omap_synctimer.c | 4 +-
26
18 files changed, 142 insertions(+), 163 deletions(-)
13
27
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
28
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
15
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
30
--- a/hw/arm/omap1.c
17
+++ b/target/arm/helper-sve.h
31
+++ b/hw/arm/omap1.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_uminp_zpzz_s, TCG_CALL_NO_RWG,
32
@@ -XXX,XX +XXX,XX @@ static void omap_timer_fire(void *opaque)
19
DEF_HELPER_FLAGS_5(sve2_uminp_zpzz_d, TCG_CALL_NO_RWG,
33
20
void, ptr, ptr, ptr, ptr, i32)
34
static void omap_timer_tick(void *opaque)
21
35
{
22
+DEF_HELPER_FLAGS_5(sve2_sqadd_zpzz_b, TCG_CALL_NO_RWG,
36
- struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
23
+ void, ptr, ptr, ptr, ptr, i32)
37
+ struct omap_mpu_timer_s *timer = opaque;
24
+DEF_HELPER_FLAGS_5(sve2_sqadd_zpzz_h, TCG_CALL_NO_RWG,
38
25
+ void, ptr, ptr, ptr, ptr, i32)
39
omap_timer_sync(timer);
26
+DEF_HELPER_FLAGS_5(sve2_sqadd_zpzz_s, TCG_CALL_NO_RWG,
40
omap_timer_fire(timer);
27
+ void, ptr, ptr, ptr, ptr, i32)
41
@@ -XXX,XX +XXX,XX @@ static void omap_timer_tick(void *opaque)
28
+DEF_HELPER_FLAGS_5(sve2_sqadd_zpzz_d, TCG_CALL_NO_RWG,
42
29
+ void, ptr, ptr, ptr, ptr, i32)
43
static void omap_timer_clk_update(void *opaque, int line, int on)
30
+
44
{
31
+DEF_HELPER_FLAGS_5(sve2_uqadd_zpzz_b, TCG_CALL_NO_RWG,
45
- struct omap_mpu_timer_s *timer = (struct omap_mpu_timer_s *) opaque;
32
+ void, ptr, ptr, ptr, ptr, i32)
46
+ struct omap_mpu_timer_s *timer = opaque;
33
+DEF_HELPER_FLAGS_5(sve2_uqadd_zpzz_h, TCG_CALL_NO_RWG,
47
34
+ void, ptr, ptr, ptr, ptr, i32)
48
omap_timer_sync(timer);
35
+DEF_HELPER_FLAGS_5(sve2_uqadd_zpzz_s, TCG_CALL_NO_RWG,
49
timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
36
+ void, ptr, ptr, ptr, ptr, i32)
50
@@ -XXX,XX +XXX,XX @@ static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)
37
+DEF_HELPER_FLAGS_5(sve2_uqadd_zpzz_d, TCG_CALL_NO_RWG,
51
static uint64_t omap_mpu_timer_read(void *opaque, hwaddr addr,
38
+ void, ptr, ptr, ptr, ptr, i32)
52
unsigned size)
39
+
53
{
40
+DEF_HELPER_FLAGS_5(sve2_sqsub_zpzz_b, TCG_CALL_NO_RWG,
54
- struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
41
+ void, ptr, ptr, ptr, ptr, i32)
55
+ struct omap_mpu_timer_s *s = opaque;
42
+DEF_HELPER_FLAGS_5(sve2_sqsub_zpzz_h, TCG_CALL_NO_RWG,
56
43
+ void, ptr, ptr, ptr, ptr, i32)
57
if (size != 4) {
44
+DEF_HELPER_FLAGS_5(sve2_sqsub_zpzz_s, TCG_CALL_NO_RWG,
58
return omap_badwidth_read32(opaque, addr);
45
+ void, ptr, ptr, ptr, ptr, i32)
59
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_mpu_timer_read(void *opaque, hwaddr addr,
46
+DEF_HELPER_FLAGS_5(sve2_sqsub_zpzz_d, TCG_CALL_NO_RWG,
60
static void omap_mpu_timer_write(void *opaque, hwaddr addr,
47
+ void, ptr, ptr, ptr, ptr, i32)
61
uint64_t value, unsigned size)
48
+
62
{
49
+DEF_HELPER_FLAGS_5(sve2_uqsub_zpzz_b, TCG_CALL_NO_RWG,
63
- struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *) opaque;
50
+ void, ptr, ptr, ptr, ptr, i32)
64
+ struct omap_mpu_timer_s *s = opaque;
51
+DEF_HELPER_FLAGS_5(sve2_uqsub_zpzz_h, TCG_CALL_NO_RWG,
65
52
+ void, ptr, ptr, ptr, ptr, i32)
66
if (size != 4) {
53
+DEF_HELPER_FLAGS_5(sve2_uqsub_zpzz_s, TCG_CALL_NO_RWG,
67
omap_badwidth_write32(opaque, addr, value);
54
+ void, ptr, ptr, ptr, ptr, i32)
68
@@ -XXX,XX +XXX,XX @@ struct omap_watchdog_timer_s {
55
+DEF_HELPER_FLAGS_5(sve2_uqsub_zpzz_d, TCG_CALL_NO_RWG,
69
static uint64_t omap_wd_timer_read(void *opaque, hwaddr addr,
56
+ void, ptr, ptr, ptr, ptr, i32)
70
unsigned size)
57
+
71
{
58
+DEF_HELPER_FLAGS_5(sve2_suqadd_zpzz_b, TCG_CALL_NO_RWG,
72
- struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
59
+ void, ptr, ptr, ptr, ptr, i32)
73
+ struct omap_watchdog_timer_s *s = opaque;
60
+DEF_HELPER_FLAGS_5(sve2_suqadd_zpzz_h, TCG_CALL_NO_RWG,
74
61
+ void, ptr, ptr, ptr, ptr, i32)
75
if (size != 2) {
62
+DEF_HELPER_FLAGS_5(sve2_suqadd_zpzz_s, TCG_CALL_NO_RWG,
76
return omap_badwidth_read16(opaque, addr);
63
+ void, ptr, ptr, ptr, ptr, i32)
77
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_wd_timer_read(void *opaque, hwaddr addr,
64
+DEF_HELPER_FLAGS_5(sve2_suqadd_zpzz_d, TCG_CALL_NO_RWG,
78
static void omap_wd_timer_write(void *opaque, hwaddr addr,
65
+ void, ptr, ptr, ptr, ptr, i32)
79
uint64_t value, unsigned size)
66
+
80
{
67
+DEF_HELPER_FLAGS_5(sve2_usqadd_zpzz_b, TCG_CALL_NO_RWG,
81
- struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *) opaque;
68
+ void, ptr, ptr, ptr, ptr, i32)
82
+ struct omap_watchdog_timer_s *s = opaque;
69
+DEF_HELPER_FLAGS_5(sve2_usqadd_zpzz_h, TCG_CALL_NO_RWG,
83
70
+ void, ptr, ptr, ptr, ptr, i32)
84
if (size != 2) {
71
+DEF_HELPER_FLAGS_5(sve2_usqadd_zpzz_s, TCG_CALL_NO_RWG,
85
omap_badwidth_write16(opaque, addr, value);
72
+ void, ptr, ptr, ptr, ptr, i32)
86
@@ -XXX,XX +XXX,XX @@ struct omap_32khz_timer_s {
73
+DEF_HELPER_FLAGS_5(sve2_usqadd_zpzz_d, TCG_CALL_NO_RWG,
87
static uint64_t omap_os_timer_read(void *opaque, hwaddr addr,
74
+ void, ptr, ptr, ptr, ptr, i32)
88
unsigned size)
75
+
89
{
76
DEF_HELPER_FLAGS_5(sve_asr_zpzw_b, TCG_CALL_NO_RWG,
90
- struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
77
void, ptr, ptr, ptr, ptr, i32)
91
+ struct omap_32khz_timer_s *s = opaque;
78
DEF_HELPER_FLAGS_5(sve_asr_zpzw_h, TCG_CALL_NO_RWG,
92
int offset = addr & OMAP_MPUI_REG_MASK;
79
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
93
80
index XXXXXXX..XXXXXXX 100644
94
if (size != 4) {
81
--- a/target/arm/sve.decode
95
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_os_timer_read(void *opaque, hwaddr addr,
82
+++ b/target/arm/sve.decode
96
static void omap_os_timer_write(void *opaque, hwaddr addr,
83
@@ -XXX,XX +XXX,XX @@ SMAXP 01000100 .. 010 100 101 ... ..... ..... @rdn_pg_rm
97
uint64_t value, unsigned size)
84
UMAXP 01000100 .. 010 101 101 ... ..... ..... @rdn_pg_rm
98
{
85
SMINP 01000100 .. 010 110 101 ... ..... ..... @rdn_pg_rm
99
- struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *) opaque;
86
UMINP 01000100 .. 010 111 101 ... ..... ..... @rdn_pg_rm
100
+ struct omap_32khz_timer_s *s = opaque;
87
+
101
int offset = addr & OMAP_MPUI_REG_MASK;
88
+### SVE2 saturating add/subtract (predicated)
102
89
+
103
if (size != 4) {
90
+SQADD_zpzz 01000100 .. 011 000 100 ... ..... ..... @rdn_pg_rm
104
@@ -XXX,XX +XXX,XX @@ static struct omap_32khz_timer_s *omap_os_timer_init(MemoryRegion *memory,
91
+UQADD_zpzz 01000100 .. 011 001 100 ... ..... ..... @rdn_pg_rm
105
static uint64_t omap_ulpd_pm_read(void *opaque, hwaddr addr,
92
+SQSUB_zpzz 01000100 .. 011 010 100 ... ..... ..... @rdn_pg_rm
106
unsigned size)
93
+UQSUB_zpzz 01000100 .. 011 011 100 ... ..... ..... @rdn_pg_rm
107
{
94
+SUQADD 01000100 .. 011 100 100 ... ..... ..... @rdn_pg_rm
108
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
95
+USQADD 01000100 .. 011 101 100 ... ..... ..... @rdn_pg_rm
109
+ struct omap_mpu_state_s *s = opaque;
96
+SQSUB_zpzz 01000100 .. 011 110 100 ... ..... ..... @rdm_pg_rn # SQSUBR
110
uint16_t ret;
97
+UQSUB_zpzz 01000100 .. 011 111 100 ... ..... ..... @rdm_pg_rn # UQSUBR
111
98
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
112
if (size != 2) {
99
index XXXXXXX..XXXXXXX 100644
113
@@ -XXX,XX +XXX,XX @@ static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s,
100
--- a/target/arm/sve_helper.c
114
static void omap_ulpd_pm_write(void *opaque, hwaddr addr,
101
+++ b/target/arm/sve_helper.c
115
uint64_t value, unsigned size)
102
@@ -XXX,XX +XXX,XX @@ DO_ZPZZ(sve2_uhsub_zpzz_h, uint16_t, H1_2, DO_HSUB_BHS)
116
{
103
DO_ZPZZ(sve2_uhsub_zpzz_s, uint32_t, H1_4, DO_HSUB_BHS)
117
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
104
DO_ZPZZ_D(sve2_uhsub_zpzz_d, uint64_t, DO_HSUB_D)
118
+ struct omap_mpu_state_s *s = opaque;
105
119
int64_t now, ticks;
106
+static inline int32_t do_sat_bhs(int64_t val, int64_t min, int64_t max)
120
int div, mult;
107
+{
121
static const int bypass_div[4] = { 1, 2, 4, 4 };
108
+ return val >= max ? max : val <= min ? min : val;
122
@@ -XXX,XX +XXX,XX @@ static void omap_ulpd_pm_init(MemoryRegion *system_memory,
109
+}
123
static uint64_t omap_pin_cfg_read(void *opaque, hwaddr addr,
110
+
124
unsigned size)
111
+#define DO_SQADD_B(n, m) do_sat_bhs((int64_t)n + m, INT8_MIN, INT8_MAX)
125
{
112
+#define DO_SQADD_H(n, m) do_sat_bhs((int64_t)n + m, INT16_MIN, INT16_MAX)
126
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
113
+#define DO_SQADD_S(n, m) do_sat_bhs((int64_t)n + m, INT32_MIN, INT32_MAX)
127
+ struct omap_mpu_state_s *s = opaque;
114
+
128
115
+static inline int64_t do_sqadd_d(int64_t n, int64_t m)
129
if (size != 4) {
116
+{
130
return omap_badwidth_read32(opaque, addr);
117
+ int64_t r = n + m;
131
@@ -XXX,XX +XXX,XX @@ static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s,
118
+ if (((r ^ n) & ~(n ^ m)) < 0) {
132
static void omap_pin_cfg_write(void *opaque, hwaddr addr,
119
+ /* Signed overflow. */
133
uint64_t value, unsigned size)
120
+ return r < 0 ? INT64_MAX : INT64_MIN;
134
{
121
+ }
135
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
122
+ return r;
136
+ struct omap_mpu_state_s *s = opaque;
123
+}
137
uint32_t diff;
124
+
138
125
+DO_ZPZZ(sve2_sqadd_zpzz_b, int8_t, H1, DO_SQADD_B)
139
if (size != 4) {
126
+DO_ZPZZ(sve2_sqadd_zpzz_h, int16_t, H1_2, DO_SQADD_H)
140
@@ -XXX,XX +XXX,XX @@ static void omap_pin_cfg_init(MemoryRegion *system_memory,
127
+DO_ZPZZ(sve2_sqadd_zpzz_s, int32_t, H1_4, DO_SQADD_S)
141
static uint64_t omap_id_read(void *opaque, hwaddr addr,
128
+DO_ZPZZ_D(sve2_sqadd_zpzz_d, int64_t, do_sqadd_d)
142
unsigned size)
129
+
143
{
130
+#define DO_UQADD_B(n, m) do_sat_bhs((int64_t)n + m, 0, UINT8_MAX)
144
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
131
+#define DO_UQADD_H(n, m) do_sat_bhs((int64_t)n + m, 0, UINT16_MAX)
145
+ struct omap_mpu_state_s *s = opaque;
132
+#define DO_UQADD_S(n, m) do_sat_bhs((int64_t)n + m, 0, UINT32_MAX)
146
133
+
147
if (size != 4) {
134
+static inline uint64_t do_uqadd_d(uint64_t n, uint64_t m)
148
return omap_badwidth_read32(opaque, addr);
135
+{
149
@@ -XXX,XX +XXX,XX @@ static void omap_id_init(MemoryRegion *memory, struct omap_mpu_state_s *mpu)
136
+ uint64_t r = n + m;
150
static uint64_t omap_mpui_read(void *opaque, hwaddr addr,
137
+ return r < n ? UINT64_MAX : r;
151
unsigned size)
138
+}
152
{
139
+
153
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
140
+DO_ZPZZ(sve2_uqadd_zpzz_b, uint8_t, H1, DO_UQADD_B)
154
+ struct omap_mpu_state_s *s = opaque;
141
+DO_ZPZZ(sve2_uqadd_zpzz_h, uint16_t, H1_2, DO_UQADD_H)
155
142
+DO_ZPZZ(sve2_uqadd_zpzz_s, uint32_t, H1_4, DO_UQADD_S)
156
if (size != 4) {
143
+DO_ZPZZ_D(sve2_uqadd_zpzz_d, uint64_t, do_uqadd_d)
157
return omap_badwidth_read32(opaque, addr);
144
+
158
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_mpui_read(void *opaque, hwaddr addr,
145
+#define DO_SQSUB_B(n, m) do_sat_bhs((int64_t)n - m, INT8_MIN, INT8_MAX)
159
static void omap_mpui_write(void *opaque, hwaddr addr,
146
+#define DO_SQSUB_H(n, m) do_sat_bhs((int64_t)n - m, INT16_MIN, INT16_MAX)
160
uint64_t value, unsigned size)
147
+#define DO_SQSUB_S(n, m) do_sat_bhs((int64_t)n - m, INT32_MIN, INT32_MAX)
161
{
148
+
162
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
149
+static inline int64_t do_sqsub_d(int64_t n, int64_t m)
163
+ struct omap_mpu_state_s *s = opaque;
150
+{
164
151
+ int64_t r = n - m;
165
if (size != 4) {
152
+ if (((r ^ n) & (n ^ m)) < 0) {
166
omap_badwidth_write32(opaque, addr, value);
153
+ /* Signed overflow. */
167
@@ -XXX,XX +XXX,XX @@ struct omap_tipb_bridge_s {
154
+ return r < 0 ? INT64_MAX : INT64_MIN;
168
static uint64_t omap_tipb_bridge_read(void *opaque, hwaddr addr,
155
+ }
169
unsigned size)
156
+ return r;
170
{
157
+}
171
- struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
158
+
172
+ struct omap_tipb_bridge_s *s = opaque;
159
+DO_ZPZZ(sve2_sqsub_zpzz_b, int8_t, H1, DO_SQSUB_B)
173
160
+DO_ZPZZ(sve2_sqsub_zpzz_h, int16_t, H1_2, DO_SQSUB_H)
174
if (size < 2) {
161
+DO_ZPZZ(sve2_sqsub_zpzz_s, int32_t, H1_4, DO_SQSUB_S)
175
return omap_badwidth_read16(opaque, addr);
162
+DO_ZPZZ_D(sve2_sqsub_zpzz_d, int64_t, do_sqsub_d)
176
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_tipb_bridge_read(void *opaque, hwaddr addr,
163
+
177
static void omap_tipb_bridge_write(void *opaque, hwaddr addr,
164
+#define DO_UQSUB_B(n, m) do_sat_bhs((int64_t)n - m, 0, UINT8_MAX)
178
uint64_t value, unsigned size)
165
+#define DO_UQSUB_H(n, m) do_sat_bhs((int64_t)n - m, 0, UINT16_MAX)
179
{
166
+#define DO_UQSUB_S(n, m) do_sat_bhs((int64_t)n - m, 0, UINT32_MAX)
180
- struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque;
167
+
181
+ struct omap_tipb_bridge_s *s = opaque;
168
+static inline uint64_t do_uqsub_d(uint64_t n, uint64_t m)
182
169
+{
183
if (size < 2) {
170
+ return n > m ? n - m : 0;
184
omap_badwidth_write16(opaque, addr, value);
171
+}
185
@@ -XXX,XX +XXX,XX @@ static struct omap_tipb_bridge_s *omap_tipb_bridge_init(
172
+
186
static uint64_t omap_tcmi_read(void *opaque, hwaddr addr,
173
+DO_ZPZZ(sve2_uqsub_zpzz_b, uint8_t, H1, DO_UQSUB_B)
187
unsigned size)
174
+DO_ZPZZ(sve2_uqsub_zpzz_h, uint16_t, H1_2, DO_UQSUB_H)
188
{
175
+DO_ZPZZ(sve2_uqsub_zpzz_s, uint32_t, H1_4, DO_UQSUB_S)
189
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
176
+DO_ZPZZ_D(sve2_uqsub_zpzz_d, uint64_t, do_uqsub_d)
190
+ struct omap_mpu_state_s *s = opaque;
177
+
191
uint32_t ret;
178
+#define DO_SUQADD_B(n, m) \
192
179
+ do_sat_bhs((int64_t)(int8_t)n + m, INT8_MIN, INT8_MAX)
193
if (size != 4) {
180
+#define DO_SUQADD_H(n, m) \
194
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_tcmi_read(void *opaque, hwaddr addr,
181
+ do_sat_bhs((int64_t)(int16_t)n + m, INT16_MIN, INT16_MAX)
195
static void omap_tcmi_write(void *opaque, hwaddr addr,
182
+#define DO_SUQADD_S(n, m) \
196
uint64_t value, unsigned size)
183
+ do_sat_bhs((int64_t)(int32_t)n + m, INT32_MIN, INT32_MAX)
197
{
184
+
198
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
185
+static inline int64_t do_suqadd_d(int64_t n, uint64_t m)
199
+ struct omap_mpu_state_s *s = opaque;
186
+{
200
187
+ uint64_t r = n + m;
201
if (size != 4) {
188
+
202
omap_badwidth_write32(opaque, addr, value);
189
+ if (n < 0) {
203
@@ -XXX,XX +XXX,XX @@ struct dpll_ctl_s {
190
+ /* Note that m - abs(n) cannot underflow. */
204
static uint64_t omap_dpll_read(void *opaque, hwaddr addr,
191
+ if (r > INT64_MAX) {
205
unsigned size)
192
+ /* Result is either very large positive or negative. */
206
{
193
+ if (m > -n) {
207
- struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
194
+ /* m > abs(n), so r is a very large positive. */
208
+ struct dpll_ctl_s *s = opaque;
195
+ return INT64_MAX;
209
196
+ }
210
if (size != 2) {
197
+ /* Result is negative. */
211
return omap_badwidth_read16(opaque, addr);
198
+ }
212
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_dpll_read(void *opaque, hwaddr addr,
199
+ } else {
213
static void omap_dpll_write(void *opaque, hwaddr addr,
200
+ /* Both inputs are positive: check for overflow. */
214
uint64_t value, unsigned size)
201
+ if (r < m || r > INT64_MAX) {
215
{
202
+ return INT64_MAX;
216
- struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque;
203
+ }
217
+ struct dpll_ctl_s *s = opaque;
204
+ }
218
uint16_t diff;
205
+ return r;
219
static const int bypass_div[4] = { 1, 2, 4, 4 };
206
+}
220
int div, mult;
207
+
221
@@ -XXX,XX +XXX,XX @@ static struct dpll_ctl_s *omap_dpll_init(MemoryRegion *memory,
208
+DO_ZPZZ(sve2_suqadd_zpzz_b, uint8_t, H1, DO_SUQADD_B)
222
static uint64_t omap_clkm_read(void *opaque, hwaddr addr,
209
+DO_ZPZZ(sve2_suqadd_zpzz_h, uint16_t, H1_2, DO_SUQADD_H)
223
unsigned size)
210
+DO_ZPZZ(sve2_suqadd_zpzz_s, uint32_t, H1_4, DO_SUQADD_S)
224
{
211
+DO_ZPZZ_D(sve2_suqadd_zpzz_d, uint64_t, do_suqadd_d)
225
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
212
+
226
+ struct omap_mpu_state_s *s = opaque;
213
+#define DO_USQADD_B(n, m) \
227
214
+ do_sat_bhs((int64_t)n + (int8_t)m, 0, UINT8_MAX)
228
if (size != 2) {
215
+#define DO_USQADD_H(n, m) \
229
return omap_badwidth_read16(opaque, addr);
216
+ do_sat_bhs((int64_t)n + (int16_t)m, 0, UINT16_MAX)
230
@@ -XXX,XX +XXX,XX @@ static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s,
217
+#define DO_USQADD_S(n, m) \
231
static void omap_clkm_write(void *opaque, hwaddr addr,
218
+ do_sat_bhs((int64_t)n + (int32_t)m, 0, UINT32_MAX)
232
uint64_t value, unsigned size)
219
+
233
{
220
+static inline uint64_t do_usqadd_d(uint64_t n, int64_t m)
234
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
221
+{
235
+ struct omap_mpu_state_s *s = opaque;
222
+ uint64_t r = n + m;
236
uint16_t diff;
223
+
237
omap_clk clk;
224
+ if (m < 0) {
238
static const char *clkschemename[8] = {
225
+ return n < -m ? 0 : r;
239
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap_clkm_ops = {
226
+ }
240
static uint64_t omap_clkdsp_read(void *opaque, hwaddr addr,
227
+ return r < n ? UINT64_MAX : r;
241
unsigned size)
228
+}
242
{
229
+
243
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
230
+DO_ZPZZ(sve2_usqadd_zpzz_b, uint8_t, H1, DO_USQADD_B)
244
+ struct omap_mpu_state_s *s = opaque;
231
+DO_ZPZZ(sve2_usqadd_zpzz_h, uint16_t, H1_2, DO_USQADD_H)
245
CPUState *cpu = CPU(s->cpu);
232
+DO_ZPZZ(sve2_usqadd_zpzz_s, uint32_t, H1_4, DO_USQADD_S)
246
233
+DO_ZPZZ_D(sve2_usqadd_zpzz_d, uint64_t, do_usqadd_d)
247
if (size != 2) {
234
+
248
@@ -XXX,XX +XXX,XX @@ static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s,
235
#undef DO_ZPZZ
249
static void omap_clkdsp_write(void *opaque, hwaddr addr,
236
#undef DO_ZPZZ_D
250
uint64_t value, unsigned size)
237
251
{
238
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_sqaddi_b)(void *d, void *a, int32_t b, uint32_t desc)
252
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
239
intptr_t i, oprsz = simd_oprsz(desc);
253
+ struct omap_mpu_state_s *s = opaque;
240
254
uint16_t diff;
241
for (i = 0; i < oprsz; i += sizeof(int8_t)) {
255
242
- int r = *(int8_t *)(a + i) + b;
256
if (size != 2) {
243
- if (r > INT8_MAX) {
257
@@ -XXX,XX +XXX,XX @@ struct omap_mpuio_s {
244
- r = INT8_MAX;
258
245
- } else if (r < INT8_MIN) {
259
static void omap_mpuio_set(void *opaque, int line, int level)
246
- r = INT8_MIN;
260
{
247
- }
261
- struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
248
- *(int8_t *)(d + i) = r;
262
+ struct omap_mpuio_s *s = opaque;
249
+ *(int8_t *)(d + i) = DO_SQADD_B(b, *(int8_t *)(a + i));
263
uint16_t prev = s->inputs;
264
265
if (level)
266
@@ -XXX,XX +XXX,XX @@ static void omap_mpuio_kbd_update(struct omap_mpuio_s *s)
267
static uint64_t omap_mpuio_read(void *opaque, hwaddr addr,
268
unsigned size)
269
{
270
- struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
271
+ struct omap_mpuio_s *s = opaque;
272
int offset = addr & OMAP_MPUI_REG_MASK;
273
uint16_t ret;
274
275
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_mpuio_read(void *opaque, hwaddr addr,
276
static void omap_mpuio_write(void *opaque, hwaddr addr,
277
uint64_t value, unsigned size)
278
{
279
- struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
280
+ struct omap_mpuio_s *s = opaque;
281
int offset = addr & OMAP_MPUI_REG_MASK;
282
uint16_t diff;
283
int ln;
284
@@ -XXX,XX +XXX,XX @@ static void omap_mpuio_reset(struct omap_mpuio_s *s)
285
286
static void omap_mpuio_onoff(void *opaque, int line, int on)
287
{
288
- struct omap_mpuio_s *s = (struct omap_mpuio_s *) opaque;
289
+ struct omap_mpuio_s *s = opaque;
290
291
s->clk = on;
292
if (on)
293
@@ -XXX,XX +XXX,XX @@ static void omap_uwire_transfer_start(struct omap_uwire_s *s)
250
}
294
}
251
}
295
}
252
296
253
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_sqaddi_h)(void *d, void *a, int32_t b, uint32_t desc)
297
-static uint64_t omap_uwire_read(void *opaque, hwaddr addr,
254
intptr_t i, oprsz = simd_oprsz(desc);
298
- unsigned size)
255
299
+static uint64_t omap_uwire_read(void *opaque, hwaddr addr, unsigned size)
256
for (i = 0; i < oprsz; i += sizeof(int16_t)) {
300
{
257
- int r = *(int16_t *)(a + i) + b;
301
- struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
258
- if (r > INT16_MAX) {
302
+ struct omap_uwire_s *s = opaque;
259
- r = INT16_MAX;
303
int offset = addr & OMAP_MPUI_REG_MASK;
260
- } else if (r < INT16_MIN) {
304
261
- r = INT16_MIN;
305
if (size != 2) {
262
- }
306
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_uwire_read(void *opaque, hwaddr addr,
263
- *(int16_t *)(d + i) = r;
307
static void omap_uwire_write(void *opaque, hwaddr addr,
264
+ *(int16_t *)(d + i) = DO_SQADD_H(b, *(int16_t *)(a + i));
308
uint64_t value, unsigned size)
309
{
310
- struct omap_uwire_s *s = (struct omap_uwire_s *) opaque;
311
+ struct omap_uwire_s *s = opaque;
312
int offset = addr & OMAP_MPUI_REG_MASK;
313
314
if (size != 2) {
315
@@ -XXX,XX +XXX,XX @@ static void omap_pwl_update(struct omap_pwl_s *s)
265
}
316
}
266
}
317
}
267
318
268
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_sqaddi_s)(void *d, void *a, int64_t b, uint32_t desc)
319
-static uint64_t omap_pwl_read(void *opaque, hwaddr addr,
269
intptr_t i, oprsz = simd_oprsz(desc);
320
- unsigned size)
270
321
+static uint64_t omap_pwl_read(void *opaque, hwaddr addr, unsigned size)
271
for (i = 0; i < oprsz; i += sizeof(int32_t)) {
322
{
272
- int64_t r = *(int32_t *)(a + i) + b;
323
- struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
273
- if (r > INT32_MAX) {
324
+ struct omap_pwl_s *s = opaque;
274
- r = INT32_MAX;
325
int offset = addr & OMAP_MPUI_REG_MASK;
275
- } else if (r < INT32_MIN) {
326
276
- r = INT32_MIN;
327
if (size != 1) {
277
- }
328
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_pwl_read(void *opaque, hwaddr addr,
278
- *(int32_t *)(d + i) = r;
329
static void omap_pwl_write(void *opaque, hwaddr addr,
279
+ *(int32_t *)(d + i) = DO_SQADD_S(b, *(int32_t *)(a + i));
330
uint64_t value, unsigned size)
331
{
332
- struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
333
+ struct omap_pwl_s *s = opaque;
334
int offset = addr & OMAP_MPUI_REG_MASK;
335
336
if (size != 1) {
337
@@ -XXX,XX +XXX,XX @@ static void omap_pwl_reset(struct omap_pwl_s *s)
338
339
static void omap_pwl_clk_update(void *opaque, int line, int on)
340
{
341
- struct omap_pwl_s *s = (struct omap_pwl_s *) opaque;
342
+ struct omap_pwl_s *s = opaque;
343
344
s->clk = on;
345
omap_pwl_update(s);
346
@@ -XXX,XX +XXX,XX @@ struct omap_pwt_s {
347
omap_clk clk;
348
};
349
350
-static uint64_t omap_pwt_read(void *opaque, hwaddr addr,
351
- unsigned size)
352
+static uint64_t omap_pwt_read(void *opaque, hwaddr addr, unsigned size)
353
{
354
- struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
355
+ struct omap_pwt_s *s = opaque;
356
int offset = addr & OMAP_MPUI_REG_MASK;
357
358
if (size != 1) {
359
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_pwt_read(void *opaque, hwaddr addr,
360
static void omap_pwt_write(void *opaque, hwaddr addr,
361
uint64_t value, unsigned size)
362
{
363
- struct omap_pwt_s *s = (struct omap_pwt_s *) opaque;
364
+ struct omap_pwt_s *s = opaque;
365
int offset = addr & OMAP_MPUI_REG_MASK;
366
367
if (size != 1) {
368
@@ -XXX,XX +XXX,XX @@ static void omap_rtc_alarm_update(struct omap_rtc_s *s)
369
printf("%s: conversion failed\n", __func__);
370
}
371
372
-static uint64_t omap_rtc_read(void *opaque, hwaddr addr,
373
- unsigned size)
374
+static uint64_t omap_rtc_read(void *opaque, hwaddr addr, unsigned size)
375
{
376
- struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
377
+ struct omap_rtc_s *s = opaque;
378
int offset = addr & OMAP_MPUI_REG_MASK;
379
uint8_t i;
380
381
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_rtc_read(void *opaque, hwaddr addr,
382
static void omap_rtc_write(void *opaque, hwaddr addr,
383
uint64_t value, unsigned size)
384
{
385
- struct omap_rtc_s *s = (struct omap_rtc_s *) opaque;
386
+ struct omap_rtc_s *s = opaque;
387
int offset = addr & OMAP_MPUI_REG_MASK;
388
struct tm new_tm;
389
time_t ti[2];
390
@@ -XXX,XX +XXX,XX @@ static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s)
391
392
static void omap_mcbsp_source_tick(void *opaque)
393
{
394
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
395
+ struct omap_mcbsp_s *s = opaque;
396
static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
397
398
if (!s->rx_rate)
399
@@ -XXX,XX +XXX,XX @@ static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s)
400
401
static void omap_mcbsp_sink_tick(void *opaque)
402
{
403
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
404
+ struct omap_mcbsp_s *s = opaque;
405
static const int bps[8] = { 0, 1, 1, 2, 2, 2, -255, -255 };
406
407
if (!s->tx_rate)
408
@@ -XXX,XX +XXX,XX @@ static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
409
static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr,
410
unsigned size)
411
{
412
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
413
+ struct omap_mcbsp_s *s = opaque;
414
int offset = addr & OMAP_MPUI_REG_MASK;
415
uint16_t ret;
416
417
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr,
418
static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
419
uint32_t value)
420
{
421
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
422
+ struct omap_mcbsp_s *s = opaque;
423
int offset = addr & OMAP_MPUI_REG_MASK;
424
425
switch (offset) {
426
@@ -XXX,XX +XXX,XX @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr,
427
static void omap_mcbsp_writew(void *opaque, hwaddr addr,
428
uint32_t value)
429
{
430
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
431
+ struct omap_mcbsp_s *s = opaque;
432
int offset = addr & OMAP_MPUI_REG_MASK;
433
434
if (offset == 0x04) {                /* DXR */
435
@@ -XXX,XX +XXX,XX @@ static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
436
437
static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
438
{
439
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
440
+ struct omap_mcbsp_s *s = opaque;
441
442
if (s->rx_rate) {
443
s->rx_req = s->codec->in.len;
444
@@ -XXX,XX +XXX,XX @@ static void omap_mcbsp_i2s_swallow(void *opaque, int line, int level)
445
446
static void omap_mcbsp_i2s_start(void *opaque, int line, int level)
447
{
448
- struct omap_mcbsp_s *s = (struct omap_mcbsp_s *) opaque;
449
+ struct omap_mcbsp_s *s = opaque;
450
451
if (s->tx_rate) {
452
s->tx_req = s->codec->out.size;
453
@@ -XXX,XX +XXX,XX @@ static void omap_lpg_reset(struct omap_lpg_s *s)
454
omap_lpg_update(s);
455
}
456
457
-static uint64_t omap_lpg_read(void *opaque, hwaddr addr,
458
- unsigned size)
459
+static uint64_t omap_lpg_read(void *opaque, hwaddr addr, unsigned size)
460
{
461
- struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
462
+ struct omap_lpg_s *s = opaque;
463
int offset = addr & OMAP_MPUI_REG_MASK;
464
465
if (size != 1) {
466
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_lpg_read(void *opaque, hwaddr addr,
467
static void omap_lpg_write(void *opaque, hwaddr addr,
468
uint64_t value, unsigned size)
469
{
470
- struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
471
+ struct omap_lpg_s *s = opaque;
472
int offset = addr & OMAP_MPUI_REG_MASK;
473
474
if (size != 1) {
475
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap_lpg_ops = {
476
477
static void omap_lpg_clk_update(void *opaque, int line, int on)
478
{
479
- struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;
480
+ struct omap_lpg_s *s = opaque;
481
482
s->clk = on;
483
omap_lpg_update(s);
484
@@ -XXX,XX +XXX,XX @@ static void omap_setup_mpui_io(MemoryRegion *system_memory,
485
/* General chip reset */
486
static void omap1_mpu_reset(void *opaque)
487
{
488
- struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
489
+ struct omap_mpu_state_s *mpu = opaque;
490
491
omap_dma_reset(mpu->dma);
492
omap_mpu_timer_reset(mpu->timer[0]);
493
@@ -XXX,XX +XXX,XX @@ static void omap_setup_dsp_mapping(MemoryRegion *system_memory,
494
495
void omap_mpu_wakeup(void *opaque, int irq, int req)
496
{
497
- struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
498
+ struct omap_mpu_state_s *mpu = opaque;
499
CPUState *cpu = CPU(mpu->cpu);
500
501
if (cpu->halted) {
502
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
503
index XXXXXXX..XXXXXXX 100644
504
--- a/hw/arm/omap2.c
505
+++ b/hw/arm/omap2.c
506
@@ -XXX,XX +XXX,XX @@ static inline void omap_eac_out_empty(struct omap_eac_s *s)
507
508
static void omap_eac_in_cb(void *opaque, int avail_b)
509
{
510
- struct omap_eac_s *s = (struct omap_eac_s *) opaque;
511
+ struct omap_eac_s *s = opaque;
512
513
s->codec.rxavail = avail_b >> 2;
514
omap_eac_in_refill(s);
515
@@ -XXX,XX +XXX,XX @@ static void omap_eac_in_cb(void *opaque, int avail_b)
516
517
static void omap_eac_out_cb(void *opaque, int free_b)
518
{
519
- struct omap_eac_s *s = (struct omap_eac_s *) opaque;
520
+ struct omap_eac_s *s = opaque;
521
522
s->codec.txavail = free_b >> 2;
523
if (s->codec.txlen)
524
@@ -XXX,XX +XXX,XX @@ static void omap_eac_reset(struct omap_eac_s *s)
525
omap_eac_interrupt_update(s);
526
}
527
528
-static uint64_t omap_eac_read(void *opaque, hwaddr addr,
529
- unsigned size)
530
+static uint64_t omap_eac_read(void *opaque, hwaddr addr, unsigned size)
531
{
532
- struct omap_eac_s *s = (struct omap_eac_s *) opaque;
533
+ struct omap_eac_s *s = opaque;
534
uint32_t ret;
535
536
if (size != 2) {
537
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_eac_read(void *opaque, hwaddr addr,
538
static void omap_eac_write(void *opaque, hwaddr addr,
539
uint64_t value, unsigned size)
540
{
541
- struct omap_eac_s *s = (struct omap_eac_s *) opaque;
542
+ struct omap_eac_s *s = opaque;
543
544
if (size != 2) {
545
omap_badwidth_write16(opaque, addr, value);
546
@@ -XXX,XX +XXX,XX @@ static void omap_sti_reset(struct omap_sti_s *s)
547
static uint64_t omap_sti_read(void *opaque, hwaddr addr,
548
unsigned size)
549
{
550
- struct omap_sti_s *s = (struct omap_sti_s *) opaque;
551
+ struct omap_sti_s *s = opaque;
552
553
if (size != 4) {
554
return omap_badwidth_read32(opaque, addr);
555
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_sti_read(void *opaque, hwaddr addr,
556
static void omap_sti_write(void *opaque, hwaddr addr,
557
uint64_t value, unsigned size)
558
{
559
- struct omap_sti_s *s = (struct omap_sti_s *) opaque;
560
+ struct omap_sti_s *s = opaque;
561
562
if (size != 4) {
563
omap_badwidth_write32(opaque, addr, value);
564
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap_sti_ops = {
565
.endianness = DEVICE_NATIVE_ENDIAN,
566
};
567
568
-static uint64_t omap_sti_fifo_read(void *opaque, hwaddr addr,
569
- unsigned size)
570
+static uint64_t omap_sti_fifo_read(void *opaque, hwaddr addr, unsigned size)
571
{
572
OMAP_BAD_REG(addr);
573
return 0;
574
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_sti_fifo_read(void *opaque, hwaddr addr,
575
static void omap_sti_fifo_write(void *opaque, hwaddr addr,
576
uint64_t value, unsigned size)
577
{
578
- struct omap_sti_s *s = (struct omap_sti_s *) opaque;
579
+ struct omap_sti_s *s = opaque;
580
int ch = addr >> 6;
581
uint8_t byte = value;
582
583
@@ -XXX,XX +XXX,XX @@ static void omap_prcm_int_update(struct omap_prcm_s *s, int dom)
584
static uint64_t omap_prcm_read(void *opaque, hwaddr addr,
585
unsigned size)
586
{
587
- struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
588
+ struct omap_prcm_s *s = opaque;
589
uint32_t ret;
590
591
if (size != 4) {
592
@@ -XXX,XX +XXX,XX @@ static void omap_prcm_dpll_update(struct omap_prcm_s *s)
593
static void omap_prcm_write(void *opaque, hwaddr addr,
594
uint64_t value, unsigned size)
595
{
596
- struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
597
+ struct omap_prcm_s *s = opaque;
598
599
if (size != 4) {
600
omap_badwidth_write32(opaque, addr, value);
601
@@ -XXX,XX +XXX,XX @@ struct omap_sysctl_s {
602
static uint32_t omap_sysctl_read8(void *opaque, hwaddr addr)
603
{
604
605
- struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
606
+ struct omap_sysctl_s *s = opaque;
607
int pad_offset, byte_offset;
608
int value;
609
610
@@ -XXX,XX +XXX,XX @@ static uint32_t omap_sysctl_read8(void *opaque, hwaddr addr)
611
612
static uint32_t omap_sysctl_read(void *opaque, hwaddr addr)
613
{
614
- struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
615
+ struct omap_sysctl_s *s = opaque;
616
617
switch (addr) {
618
case 0x000:    /* CONTROL_REVISION */
619
@@ -XXX,XX +XXX,XX @@ static uint32_t omap_sysctl_read(void *opaque, hwaddr addr)
620
return 0;
621
}
622
623
-static void omap_sysctl_write8(void *opaque, hwaddr addr,
624
- uint32_t value)
625
+static void omap_sysctl_write8(void *opaque, hwaddr addr, uint32_t value)
626
{
627
- struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
628
+ struct omap_sysctl_s *s = opaque;
629
int pad_offset, byte_offset;
630
int prev_value;
631
632
@@ -XXX,XX +XXX,XX @@ static void omap_sysctl_write8(void *opaque, hwaddr addr,
280
}
633
}
281
}
634
}
282
635
283
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_sqaddi_d)(void *d, void *a, int64_t b, uint32_t desc)
636
-static void omap_sysctl_write(void *opaque, hwaddr addr,
284
intptr_t i, oprsz = simd_oprsz(desc);
637
- uint32_t value)
285
638
+static void omap_sysctl_write(void *opaque, hwaddr addr, uint32_t value)
286
for (i = 0; i < oprsz; i += sizeof(int64_t)) {
639
{
287
- int64_t ai = *(int64_t *)(a + i);
640
- struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
288
- int64_t r = ai + b;
641
+ struct omap_sysctl_s *s = opaque;
289
- if (((r ^ ai) & ~(ai ^ b)) < 0) {
642
290
- /* Signed overflow. */
643
switch (addr) {
291
- r = (r < 0 ? INT64_MAX : INT64_MIN);
644
case 0x000:    /* CONTROL_REVISION */
292
- }
645
@@ -XXX,XX +XXX,XX @@ static struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
293
- *(int64_t *)(d + i) = r;
646
/* General chip reset */
294
+ *(int64_t *)(d + i) = do_sqadd_d(b, *(int64_t *)(a + i));
647
static void omap2_mpu_reset(void *opaque)
648
{
649
- struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
650
+ struct omap_mpu_state_s *mpu = opaque;
651
652
omap_dma_reset(mpu->dma);
653
omap_prcm_reset(mpu->prcm);
654
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
655
index XXXXXXX..XXXXXXX 100644
656
--- a/hw/arm/omap_sx1.c
657
+++ b/hw/arm/omap_sx1.c
658
@@ -XXX,XX +XXX,XX @@
659
static uint64_t static_read(void *opaque, hwaddr offset,
660
unsigned size)
661
{
662
- uint32_t *val = (uint32_t *) opaque;
663
+ uint32_t *val = opaque;
664
uint32_t mask = (4 / size) - 1;
665
666
return *val >> ((offset & mask) << 3);
667
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
668
index XXXXXXX..XXXXXXX 100644
669
--- a/hw/arm/palm.c
670
+++ b/hw/arm/palm.c
671
@@ -XXX,XX +XXX,XX @@ static struct {
672
673
static void palmte_button_event(void *opaque, int keycode)
674
{
675
- struct omap_mpu_state_s *cpu = (struct omap_mpu_state_s *) opaque;
676
+ struct omap_mpu_state_s *cpu = opaque;
677
678
if (palmte_keymap[keycode & 0x7f].row != -1)
679
omap_mpuio_key(cpu->mpuio,
680
diff --git a/hw/char/omap_uart.c b/hw/char/omap_uart.c
681
index XXXXXXX..XXXXXXX 100644
682
--- a/hw/char/omap_uart.c
683
+++ b/hw/char/omap_uart.c
684
@@ -XXX,XX +XXX,XX @@ struct omap_uart_s *omap_uart_init(hwaddr base,
685
return s;
686
}
687
688
-static uint64_t omap_uart_read(void *opaque, hwaddr addr,
689
- unsigned size)
690
+static uint64_t omap_uart_read(void *opaque, hwaddr addr, unsigned size)
691
{
692
- struct omap_uart_s *s = (struct omap_uart_s *) opaque;
693
+ struct omap_uart_s *s = opaque;
694
695
if (size == 4) {
696
return omap_badwidth_read8(opaque, addr);
697
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_uart_read(void *opaque, hwaddr addr,
698
static void omap_uart_write(void *opaque, hwaddr addr,
699
uint64_t value, unsigned size)
700
{
701
- struct omap_uart_s *s = (struct omap_uart_s *) opaque;
702
+ struct omap_uart_s *s = opaque;
703
704
if (size == 4) {
705
omap_badwidth_write8(opaque, addr, value);
706
diff --git a/hw/display/omap_dss.c b/hw/display/omap_dss.c
707
index XXXXXXX..XXXXXXX 100644
708
--- a/hw/display/omap_dss.c
709
+++ b/hw/display/omap_dss.c
710
@@ -XXX,XX +XXX,XX @@ void omap_dss_reset(struct omap_dss_s *s)
711
static uint64_t omap_diss_read(void *opaque, hwaddr addr,
712
unsigned size)
713
{
714
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
715
+ struct omap_dss_s *s = opaque;
716
717
if (size != 4) {
718
return omap_badwidth_read32(opaque, addr);
719
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_diss_read(void *opaque, hwaddr addr,
720
static void omap_diss_write(void *opaque, hwaddr addr,
721
uint64_t value, unsigned size)
722
{
723
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
724
+ struct omap_dss_s *s = opaque;
725
726
if (size != 4) {
727
omap_badwidth_write32(opaque, addr, value);
728
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap_diss_ops = {
729
static uint64_t omap_disc_read(void *opaque, hwaddr addr,
730
unsigned size)
731
{
732
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
733
+ struct omap_dss_s *s = opaque;
734
735
if (size != 4) {
736
return omap_badwidth_read32(opaque, addr);
737
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_disc_read(void *opaque, hwaddr addr,
738
static void omap_disc_write(void *opaque, hwaddr addr,
739
uint64_t value, unsigned size)
740
{
741
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
742
+ struct omap_dss_s *s = opaque;
743
744
if (size != 4) {
745
omap_badwidth_write32(opaque, addr, value);
746
@@ -XXX,XX +XXX,XX @@ static void omap_rfbi_transfer_start(struct omap_dss_s *s)
747
omap_dispc_interrupt_update(s);
748
}
749
750
-static uint64_t omap_rfbi_read(void *opaque, hwaddr addr,
751
- unsigned size)
752
+static uint64_t omap_rfbi_read(void *opaque, hwaddr addr, unsigned size)
753
{
754
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
755
+ struct omap_dss_s *s = opaque;
756
757
if (size != 4) {
758
return omap_badwidth_read32(opaque, addr);
759
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_rfbi_read(void *opaque, hwaddr addr,
760
static void omap_rfbi_write(void *opaque, hwaddr addr,
761
uint64_t value, unsigned size)
762
{
763
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
764
+ struct omap_dss_s *s = opaque;
765
766
if (size != 4) {
767
omap_badwidth_write32(opaque, addr, value);
768
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
769
index XXXXXXX..XXXXXXX 100644
770
--- a/hw/display/omap_lcdc.c
771
+++ b/hw/display/omap_lcdc.c
772
@@ -XXX,XX +XXX,XX @@ static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
773
774
static void omap_update_display(void *opaque)
775
{
776
- struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
777
+ struct omap_lcd_panel_s *omap_lcd = opaque;
778
DisplaySurface *surface;
779
drawfn draw_line;
780
int size, height, first, last;
781
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_update(struct omap_lcd_panel_s *s) {
295
}
782
}
296
}
783
}
297
784
298
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_uqaddi_b)(void *d, void *a, int32_t b, uint32_t desc)
785
-static uint64_t omap_lcdc_read(void *opaque, hwaddr addr,
299
intptr_t i, oprsz = simd_oprsz(desc);
786
- unsigned size)
300
787
+static uint64_t omap_lcdc_read(void *opaque, hwaddr addr, unsigned size)
301
for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
788
{
302
- int r = *(uint8_t *)(a + i) + b;
789
- struct omap_lcd_panel_s *s = (struct omap_lcd_panel_s *) opaque;
303
- if (r > UINT8_MAX) {
790
+ struct omap_lcd_panel_s *s = opaque;
304
- r = UINT8_MAX;
791
305
- } else if (r < 0) {
792
switch (addr) {
306
- r = 0;
793
case 0x00:    /* LCD_CONTROL */
307
- }
794
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_lcdc_read(void *opaque, hwaddr addr,
308
- *(uint8_t *)(d + i) = r;
795
static void omap_lcdc_write(void *opaque, hwaddr addr,
309
+ *(uint8_t *)(d + i) = DO_UQADD_B(b, *(uint8_t *)(a + i));
796
uint64_t value, unsigned size)
797
{
798
- struct omap_lcd_panel_s *s = (struct omap_lcd_panel_s *) opaque;
799
+ struct omap_lcd_panel_s *s = opaque;
800
801
switch (addr) {
802
case 0x00:    /* LCD_CONTROL */
803
diff --git a/hw/dma/omap_dma.c b/hw/dma/omap_dma.c
804
index XXXXXXX..XXXXXXX 100644
805
--- a/hw/dma/omap_dma.c
806
+++ b/hw/dma/omap_dma.c
807
@@ -XXX,XX +XXX,XX @@ static int omap_dma_sys_read(struct omap_dma_s *s, int offset,
808
return 0;
809
}
810
811
-static uint64_t omap_dma_read(void *opaque, hwaddr addr,
812
- unsigned size)
813
+static uint64_t omap_dma_read(void *opaque, hwaddr addr, unsigned size)
814
{
815
- struct omap_dma_s *s = (struct omap_dma_s *) opaque;
816
+ struct omap_dma_s *s = opaque;
817
int reg, ch;
818
uint16_t ret;
819
820
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_dma_read(void *opaque, hwaddr addr,
821
static void omap_dma_write(void *opaque, hwaddr addr,
822
uint64_t value, unsigned size)
823
{
824
- struct omap_dma_s *s = (struct omap_dma_s *) opaque;
825
+ struct omap_dma_s *s = opaque;
826
int reg, ch;
827
828
if (size != 2) {
829
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap_dma_ops = {
830
831
static void omap_dma_request(void *opaque, int drq, int req)
832
{
833
- struct omap_dma_s *s = (struct omap_dma_s *) opaque;
834
+ struct omap_dma_s *s = opaque;
835
/* The request pins are level triggered in QEMU. */
836
if (req) {
837
if (~s->dma->drqbmp & (1ULL << drq)) {
838
@@ -XXX,XX +XXX,XX @@ static void omap_dma_request(void *opaque, int drq, int req)
839
/* XXX: this won't be needed once soc_dma knows about clocks. */
840
static void omap_dma_clk_update(void *opaque, int line, int on)
841
{
842
- struct omap_dma_s *s = (struct omap_dma_s *) opaque;
843
+ struct omap_dma_s *s = opaque;
844
int i;
845
846
s->dma->freq = omap_clk_getrate(s->clk);
847
@@ -XXX,XX +XXX,XX @@ static void omap_dma_interrupts_4_update(struct omap_dma_s *s)
848
static uint64_t omap_dma4_read(void *opaque, hwaddr addr,
849
unsigned size)
850
{
851
- struct omap_dma_s *s = (struct omap_dma_s *) opaque;
852
+ struct omap_dma_s *s = opaque;
853
int irqn = 0, chnum;
854
struct omap_dma_channel_s *ch;
855
856
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_dma4_read(void *opaque, hwaddr addr,
857
static void omap_dma4_write(void *opaque, hwaddr addr,
858
uint64_t value, unsigned size)
859
{
860
- struct omap_dma_s *s = (struct omap_dma_s *) opaque;
861
+ struct omap_dma_s *s = opaque;
862
int chnum, irqn = 0;
863
struct omap_dma_channel_s *ch;
864
865
diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c
866
index XXXXXXX..XXXXXXX 100644
867
--- a/hw/gpio/omap_gpio.c
868
+++ b/hw/gpio/omap_gpio.c
869
@@ -XXX,XX +XXX,XX @@ static void omap_gpio_set(void *opaque, int line, int level)
870
static uint64_t omap_gpio_read(void *opaque, hwaddr addr,
871
unsigned size)
872
{
873
- struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
874
+ struct omap_gpio_s *s = opaque;
875
int offset = addr & OMAP_MPUI_REG_MASK;
876
877
if (size != 2) {
878
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_gpio_read(void *opaque, hwaddr addr,
879
static void omap_gpio_write(void *opaque, hwaddr addr,
880
uint64_t value, unsigned size)
881
{
882
- struct omap_gpio_s *s = (struct omap_gpio_s *) opaque;
883
+ struct omap_gpio_s *s = opaque;
884
int offset = addr & OMAP_MPUI_REG_MASK;
885
uint16_t diff;
886
int ln;
887
@@ -XXX,XX +XXX,XX @@ static void omap2_gpio_module_reset(struct omap2_gpio_s *s)
888
889
static uint32_t omap2_gpio_module_read(void *opaque, hwaddr addr)
890
{
891
- struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
892
+ struct omap2_gpio_s *s = opaque;
893
894
switch (addr) {
895
case 0x00:    /* GPIO_REVISION */
896
@@ -XXX,XX +XXX,XX @@ static uint32_t omap2_gpio_module_read(void *opaque, hwaddr addr)
897
static void omap2_gpio_module_write(void *opaque, hwaddr addr,
898
uint32_t value)
899
{
900
- struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
901
+ struct omap2_gpio_s *s = opaque;
902
uint32_t diff;
903
int ln;
904
905
@@ -XXX,XX +XXX,XX @@ static void omap2_gpif_reset(DeviceState *dev)
906
s->gpo = 0;
907
}
908
909
-static uint64_t omap2_gpif_top_read(void *opaque, hwaddr addr,
910
- unsigned size)
911
+static uint64_t omap2_gpif_top_read(void *opaque, hwaddr addr, unsigned size)
912
{
913
- struct omap2_gpif_s *s = (struct omap2_gpif_s *) opaque;
914
+ struct omap2_gpif_s *s = opaque;
915
916
switch (addr) {
917
case 0x00:    /* IPGENERICOCPSPL_REVISION */
918
@@ -XXX,XX +XXX,XX @@ static uint64_t omap2_gpif_top_read(void *opaque, hwaddr addr,
919
static void omap2_gpif_top_write(void *opaque, hwaddr addr,
920
uint64_t value, unsigned size)
921
{
922
- struct omap2_gpif_s *s = (struct omap2_gpif_s *) opaque;
923
+ struct omap2_gpif_s *s = opaque;
924
925
switch (addr) {
926
case 0x00:    /* IPGENERICOCPSPL_REVISION */
927
diff --git a/hw/intc/omap_intc.c b/hw/intc/omap_intc.c
928
index XXXXXXX..XXXXXXX 100644
929
--- a/hw/intc/omap_intc.c
930
+++ b/hw/intc/omap_intc.c
931
@@ -XXX,XX +XXX,XX @@ static inline void omap_inth_update(struct omap_intr_handler_s *s, int is_fiq)
932
933
static void omap_set_intr(void *opaque, int irq, int req)
934
{
935
- struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
936
+ struct omap_intr_handler_s *ih = opaque;
937
uint32_t rise;
938
939
struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5];
940
@@ -XXX,XX +XXX,XX @@ static void omap_set_intr(void *opaque, int irq, int req)
941
/* Simplified version with no edge detection */
942
static void omap_set_intr_noedge(void *opaque, int irq, int req)
943
{
944
- struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
945
+ struct omap_intr_handler_s *ih = opaque;
946
uint32_t rise;
947
948
struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5];
949
@@ -XXX,XX +XXX,XX @@ static void omap_set_intr_noedge(void *opaque, int irq, int req)
950
static uint64_t omap_inth_read(void *opaque, hwaddr addr,
951
unsigned size)
952
{
953
- struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
954
+ struct omap_intr_handler_s *s = opaque;
955
int i, offset = addr;
956
int bank_no = offset >> 8;
957
int line_no;
958
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_inth_read(void *opaque, hwaddr addr,
959
static void omap_inth_write(void *opaque, hwaddr addr,
960
uint64_t value, unsigned size)
961
{
962
- struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
963
+ struct omap_intr_handler_s *s = opaque;
964
int i, offset = addr;
965
int bank_no = offset >> 8;
966
struct omap_intr_handler_bank_s *bank = &s->bank[bank_no];
967
@@ -XXX,XX +XXX,XX @@ static const TypeInfo omap_intc_info = {
968
static uint64_t omap2_inth_read(void *opaque, hwaddr addr,
969
unsigned size)
970
{
971
- struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
972
+ struct omap_intr_handler_s *s = opaque;
973
int offset = addr;
974
int bank_no, line_no;
975
struct omap_intr_handler_bank_s *bank = NULL;
976
@@ -XXX,XX +XXX,XX @@ static uint64_t omap2_inth_read(void *opaque, hwaddr addr,
977
static void omap2_inth_write(void *opaque, hwaddr addr,
978
uint64_t value, unsigned size)
979
{
980
- struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
981
+ struct omap_intr_handler_s *s = opaque;
982
int offset = addr;
983
int bank_no, line_no;
984
struct omap_intr_handler_bank_s *bank = NULL;
985
diff --git a/hw/misc/omap_gpmc.c b/hw/misc/omap_gpmc.c
986
index XXXXXXX..XXXXXXX 100644
987
--- a/hw/misc/omap_gpmc.c
988
+++ b/hw/misc/omap_gpmc.c
989
@@ -XXX,XX +XXX,XX @@ static void omap_gpmc_dma_update(struct omap_gpmc_s *s, int value)
990
static uint64_t omap_nand_read(void *opaque, hwaddr addr,
991
unsigned size)
992
{
993
- struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
994
+ struct omap_gpmc_cs_file_s *f = opaque;
995
uint64_t v;
996
nand_setpins(f->dev, 0, 0, 0, 1, 0);
997
switch (omap_gpmc_devsize(f)) {
998
@@ -XXX,XX +XXX,XX @@ static void omap_nand_setio(DeviceState *dev, uint64_t value,
999
static void omap_nand_write(void *opaque, hwaddr addr,
1000
uint64_t value, unsigned size)
1001
{
1002
- struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
1003
+ struct omap_gpmc_cs_file_s *f = opaque;
1004
nand_setpins(f->dev, 0, 0, 0, 1, 0);
1005
omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
1006
}
1007
@@ -XXX,XX +XXX,XX @@ static void fill_prefetch_fifo(struct omap_gpmc_s *s)
1008
static uint64_t omap_gpmc_prefetch_read(void *opaque, hwaddr addr,
1009
unsigned size)
1010
{
1011
- struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
1012
+ struct omap_gpmc_s *s = opaque;
1013
uint32_t data;
1014
if (s->prefetch.config1 & 1) {
1015
/* The TRM doesn't define the behaviour if you read from the
1016
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_gpmc_prefetch_read(void *opaque, hwaddr addr,
1017
static void omap_gpmc_prefetch_write(void *opaque, hwaddr addr,
1018
uint64_t value, unsigned size)
1019
{
1020
- struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
1021
+ struct omap_gpmc_s *s = opaque;
1022
int cs = prefetch_cs(s->prefetch.config1);
1023
if ((s->prefetch.config1 & 1) == 0) {
1024
/* The TRM doesn't define the behaviour of writing to the
1025
@@ -XXX,XX +XXX,XX @@ static int gpmc_wordaccess_only(hwaddr addr)
1026
static uint64_t omap_gpmc_read(void *opaque, hwaddr addr,
1027
unsigned size)
1028
{
1029
- struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
1030
+ struct omap_gpmc_s *s = opaque;
1031
int cs;
1032
struct omap_gpmc_cs_file_s *f;
1033
1034
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_gpmc_read(void *opaque, hwaddr addr,
1035
static void omap_gpmc_write(void *opaque, hwaddr addr,
1036
uint64_t value, unsigned size)
1037
{
1038
- struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
1039
+ struct omap_gpmc_s *s = opaque;
1040
int cs;
1041
struct omap_gpmc_cs_file_s *f;
1042
1043
diff --git a/hw/misc/omap_l4.c b/hw/misc/omap_l4.c
1044
index XXXXXXX..XXXXXXX 100644
1045
--- a/hw/misc/omap_l4.c
1046
+++ b/hw/misc/omap_l4.c
1047
@@ -XXX,XX +XXX,XX @@ hwaddr omap_l4_region_size(struct omap_target_agent_s *ta,
1048
return ta->start[region].size;
1049
}
1050
1051
-static uint64_t omap_l4ta_read(void *opaque, hwaddr addr,
1052
- unsigned size)
1053
+static uint64_t omap_l4ta_read(void *opaque, hwaddr addr, unsigned size)
1054
{
1055
- struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
1056
+ struct omap_target_agent_s *s = opaque;
1057
1058
if (size != 2) {
1059
return omap_badwidth_read16(opaque, addr);
1060
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_l4ta_read(void *opaque, hwaddr addr,
1061
static void omap_l4ta_write(void *opaque, hwaddr addr,
1062
uint64_t value, unsigned size)
1063
{
1064
- struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
1065
+ struct omap_target_agent_s *s = opaque;
1066
1067
if (size != 4) {
1068
omap_badwidth_write32(opaque, addr, value);
1069
diff --git a/hw/misc/omap_sdrc.c b/hw/misc/omap_sdrc.c
1070
index XXXXXXX..XXXXXXX 100644
1071
--- a/hw/misc/omap_sdrc.c
1072
+++ b/hw/misc/omap_sdrc.c
1073
@@ -XXX,XX +XXX,XX @@ void omap_sdrc_reset(struct omap_sdrc_s *s)
1074
s->config = 0x10;
1075
}
1076
1077
-static uint64_t omap_sdrc_read(void *opaque, hwaddr addr,
1078
- unsigned size)
1079
+static uint64_t omap_sdrc_read(void *opaque, hwaddr addr, unsigned size)
1080
{
1081
- struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
1082
+ struct omap_sdrc_s *s = opaque;
1083
1084
if (size != 4) {
1085
return omap_badwidth_read32(opaque, addr);
1086
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_sdrc_read(void *opaque, hwaddr addr,
1087
static void omap_sdrc_write(void *opaque, hwaddr addr,
1088
uint64_t value, unsigned size)
1089
{
1090
- struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
1091
+ struct omap_sdrc_s *s = opaque;
1092
1093
if (size != 4) {
1094
omap_badwidth_write32(opaque, addr, value);
1095
diff --git a/hw/misc/omap_tap.c b/hw/misc/omap_tap.c
1096
index XXXXXXX..XXXXXXX 100644
1097
--- a/hw/misc/omap_tap.c
1098
+++ b/hw/misc/omap_tap.c
1099
@@ -XXX,XX +XXX,XX @@
1100
#include "hw/arm/omap.h"
1101
1102
/* TEST-Chip-level TAP */
1103
-static uint64_t omap_tap_read(void *opaque, hwaddr addr,
1104
- unsigned size)
1105
+static uint64_t omap_tap_read(void *opaque, hwaddr addr, unsigned size)
1106
{
1107
- struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
1108
+ struct omap_mpu_state_s *s = opaque;
1109
1110
if (size != 4) {
1111
return omap_badwidth_read32(opaque, addr);
1112
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
1113
index XXXXXXX..XXXXXXX 100644
1114
--- a/hw/sd/omap_mmc.c
1115
+++ b/hw/sd/omap_mmc.c
1116
@@ -XXX,XX +XXX,XX @@ void omap_mmc_reset(struct omap_mmc_s *host)
1117
device_cold_reset(DEVICE(host->card));
1118
}
1119
1120
-static uint64_t omap_mmc_read(void *opaque, hwaddr offset,
1121
- unsigned size)
1122
+static uint64_t omap_mmc_read(void *opaque, hwaddr offset, unsigned size)
1123
{
1124
uint16_t i;
1125
- struct omap_mmc_s *s = (struct omap_mmc_s *) opaque;
1126
+ struct omap_mmc_s *s = opaque;
1127
1128
if (size != 2) {
1129
return omap_badwidth_read16(opaque, offset);
1130
@@ -XXX,XX +XXX,XX @@ static void omap_mmc_write(void *opaque, hwaddr offset,
1131
uint64_t value, unsigned size)
1132
{
1133
int i;
1134
- struct omap_mmc_s *s = (struct omap_mmc_s *) opaque;
1135
+ struct omap_mmc_s *s = opaque;
1136
1137
if (size != 2) {
1138
omap_badwidth_write16(opaque, offset, value);
1139
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap_mmc_ops = {
1140
1141
static void omap_mmc_cover_cb(void *opaque, int line, int level)
1142
{
1143
- struct omap_mmc_s *host = (struct omap_mmc_s *) opaque;
1144
+ struct omap_mmc_s *host = opaque;
1145
1146
if (!host->cdet_state && level) {
1147
host->status |= 0x0002;
1148
diff --git a/hw/ssi/omap_spi.c b/hw/ssi/omap_spi.c
1149
index XXXXXXX..XXXXXXX 100644
1150
--- a/hw/ssi/omap_spi.c
1151
+++ b/hw/ssi/omap_spi.c
1152
@@ -XXX,XX +XXX,XX @@ void omap_mcspi_reset(struct omap_mcspi_s *s)
1153
omap_mcspi_interrupt_update(s);
1154
}
1155
1156
-static uint64_t omap_mcspi_read(void *opaque, hwaddr addr,
1157
- unsigned size)
1158
+static uint64_t omap_mcspi_read(void *opaque, hwaddr addr, unsigned size)
1159
{
1160
- struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
1161
+ struct omap_mcspi_s *s = opaque;
1162
int ch = 0;
1163
uint32_t ret;
1164
1165
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_mcspi_read(void *opaque, hwaddr addr,
1166
static void omap_mcspi_write(void *opaque, hwaddr addr,
1167
uint64_t value, unsigned size)
1168
{
1169
- struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
1170
+ struct omap_mcspi_s *s = opaque;
1171
int ch = 0;
1172
1173
if (size != 4) {
1174
diff --git a/hw/timer/omap_gptimer.c b/hw/timer/omap_gptimer.c
1175
index XXXXXXX..XXXXXXX 100644
1176
--- a/hw/timer/omap_gptimer.c
1177
+++ b/hw/timer/omap_gptimer.c
1178
@@ -XXX,XX +XXX,XX @@ static inline void omap_gp_timer_trigger(struct omap_gp_timer_s *timer)
1179
1180
static void omap_gp_timer_tick(void *opaque)
1181
{
1182
- struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
1183
+ struct omap_gp_timer_s *timer = opaque;
1184
1185
if (!timer->ar) {
1186
timer->st = 0;
1187
@@ -XXX,XX +XXX,XX @@ static void omap_gp_timer_tick(void *opaque)
1188
1189
static void omap_gp_timer_match(void *opaque)
1190
{
1191
- struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
1192
+ struct omap_gp_timer_s *timer = opaque;
1193
1194
if (timer->trigger == gpt_trigger_both)
1195
omap_gp_timer_trigger(timer);
1196
@@ -XXX,XX +XXX,XX @@ static void omap_gp_timer_match(void *opaque)
1197
1198
static void omap_gp_timer_input(void *opaque, int line, int on)
1199
{
1200
- struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
1201
+ struct omap_gp_timer_s *s = opaque;
1202
int trigger;
1203
1204
switch (s->capture) {
1205
@@ -XXX,XX +XXX,XX @@ static void omap_gp_timer_input(void *opaque, int line, int on)
1206
1207
static void omap_gp_timer_clk_update(void *opaque, int line, int on)
1208
{
1209
- struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
1210
+ struct omap_gp_timer_s *timer = opaque;
1211
1212
omap_gp_timer_sync(timer);
1213
timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
1214
@@ -XXX,XX +XXX,XX @@ void omap_gp_timer_reset(struct omap_gp_timer_s *s)
1215
1216
static uint32_t omap_gp_timer_readw(void *opaque, hwaddr addr)
1217
{
1218
- struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
1219
+ struct omap_gp_timer_s *s = opaque;
1220
1221
switch (addr) {
1222
case 0x00:    /* TIDR */
1223
@@ -XXX,XX +XXX,XX @@ static uint32_t omap_gp_timer_readw(void *opaque, hwaddr addr)
1224
1225
static uint32_t omap_gp_timer_readh(void *opaque, hwaddr addr)
1226
{
1227
- struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
1228
+ struct omap_gp_timer_s *s = opaque;
1229
uint32_t ret;
1230
1231
if (addr & 2)
1232
@@ -XXX,XX +XXX,XX @@ static uint32_t omap_gp_timer_readh(void *opaque, hwaddr addr)
310
}
1233
}
311
}
1234
}
312
1235
313
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_uqaddi_h)(void *d, void *a, int32_t b, uint32_t desc)
1236
-static void omap_gp_timer_write(void *opaque, hwaddr addr,
314
intptr_t i, oprsz = simd_oprsz(desc);
1237
- uint32_t value)
315
1238
+static void omap_gp_timer_write(void *opaque, hwaddr addr, uint32_t value)
316
for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
1239
{
317
- int r = *(uint16_t *)(a + i) + b;
1240
- struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
318
- if (r > UINT16_MAX) {
1241
+ struct omap_gp_timer_s *s = opaque;
319
- r = UINT16_MAX;
1242
320
- } else if (r < 0) {
1243
switch (addr) {
321
- r = 0;
1244
case 0x00:    /* TIDR */
322
- }
1245
@@ -XXX,XX +XXX,XX @@ static void omap_gp_timer_write(void *opaque, hwaddr addr,
323
- *(uint16_t *)(d + i) = r;
324
+ *(uint16_t *)(d + i) = DO_UQADD_H(b, *(uint16_t *)(a + i));
325
}
1246
}
326
}
1247
}
327
1248
328
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_uqaddi_s)(void *d, void *a, int64_t b, uint32_t desc)
1249
-static void omap_gp_timer_writeh(void *opaque, hwaddr addr,
329
intptr_t i, oprsz = simd_oprsz(desc);
1250
- uint32_t value)
330
1251
+static void omap_gp_timer_writeh(void *opaque, hwaddr addr, uint32_t value)
331
for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
1252
{
332
- int64_t r = *(uint32_t *)(a + i) + b;
1253
- struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
333
- if (r > UINT32_MAX) {
1254
+ struct omap_gp_timer_s *s = opaque;
334
- r = UINT32_MAX;
1255
335
- } else if (r < 0) {
1256
if (addr & 2)
336
- r = 0;
1257
omap_gp_timer_write(opaque, addr, (value << 16) | s->writeh);
337
- }
1258
diff --git a/hw/timer/omap_synctimer.c b/hw/timer/omap_synctimer.c
338
- *(uint32_t *)(d + i) = r;
1259
index XXXXXXX..XXXXXXX 100644
339
+ *(uint32_t *)(d + i) = DO_UQADD_S(b, *(uint32_t *)(a + i));
1260
--- a/hw/timer/omap_synctimer.c
340
}
1261
+++ b/hw/timer/omap_synctimer.c
341
}
1262
@@ -XXX,XX +XXX,XX @@ void omap_synctimer_reset(struct omap_synctimer_s *s)
342
1263
343
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_uqaddi_d)(void *d, void *a, uint64_t b, uint32_t desc)
1264
static uint32_t omap_synctimer_readw(void *opaque, hwaddr addr)
344
intptr_t i, oprsz = simd_oprsz(desc);
1265
{
345
1266
- struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
346
for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
1267
+ struct omap_synctimer_s *s = opaque;
347
- uint64_t r = *(uint64_t *)(a + i) + b;
1268
348
- if (r < b) {
1269
switch (addr) {
349
- r = UINT64_MAX;
1270
case 0x00:    /* 32KSYNCNT_REV */
350
- }
1271
@@ -XXX,XX +XXX,XX @@ static uint32_t omap_synctimer_readw(void *opaque, hwaddr addr)
351
- *(uint64_t *)(d + i) = r;
1272
352
+ *(uint64_t *)(d + i) = do_uqadd_d(b, *(uint64_t *)(a + i));
1273
static uint32_t omap_synctimer_readh(void *opaque, hwaddr addr)
353
}
1274
{
354
}
1275
- struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
355
1276
+ struct omap_synctimer_s *s = opaque;
356
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_uqsubi_d)(void *d, void *a, uint64_t b, uint32_t desc)
1277
uint32_t ret;
357
intptr_t i, oprsz = simd_oprsz(desc);
1278
358
1279
if (addr & 2)
359
for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
360
- uint64_t ai = *(uint64_t *)(a + i);
361
- *(uint64_t *)(d + i) = (ai < b ? 0 : ai - b);
362
+ *(uint64_t *)(d + i) = do_uqsub_d(*(uint64_t *)(a + i), b);
363
}
364
}
365
366
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
367
index XXXXXXX..XXXXXXX 100644
368
--- a/target/arm/translate-sve.c
369
+++ b/target/arm/translate-sve.c
370
@@ -XXX,XX +XXX,XX @@ DO_SVE2_ZPZZ(SMAXP, smaxp)
371
DO_SVE2_ZPZZ(UMAXP, umaxp)
372
DO_SVE2_ZPZZ(SMINP, sminp)
373
DO_SVE2_ZPZZ(UMINP, uminp)
374
+
375
+DO_SVE2_ZPZZ(SQADD_zpzz, sqadd)
376
+DO_SVE2_ZPZZ(UQADD_zpzz, uqadd)
377
+DO_SVE2_ZPZZ(SQSUB_zpzz, sqsub)
378
+DO_SVE2_ZPZZ(UQSUB_zpzz, uqsub)
379
+DO_SVE2_ZPZZ(SUQADD, suqadd)
380
+DO_SVE2_ZPZZ(USQADD, usqadd)
381
--
1280
--
382
2.20.1
1281
2.34.1
383
1282
384
1283
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Following docs/devel/style.rst guidelines, rename omap_gpif_s ->
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Omap1GpioState. This also remove a use of 'struct' in the
5
Message-id: 20210525010358.152808-60-richard.henderson@linaro.org
5
DECLARE_INSTANCE_CHECKER() macro call.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230109140306.23161-5-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/helper.h | 14 ++++++
12
include/hw/arm/omap.h | 6 +++---
9
target/arm/sve.decode | 8 ++++
13
hw/gpio/omap_gpio.c | 16 ++++++++--------
10
target/arm/translate-sve.c | 8 ++++
14
2 files changed, 11 insertions(+), 11 deletions(-)
11
target/arm/vec_helper.c | 88 ++++++++++++++++++++++++++++++++++++++
12
4 files changed, 118 insertions(+)
13
15
14
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.h
18
--- a/include/hw/arm/omap.h
17
+++ b/target/arm/helper.h
19
+++ b/include/hw/arm/omap.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve2_sqrdmulh_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
20
@@ -XXX,XX +XXX,XX @@ void omap_i2c_set_fclk(OMAPI2CState *i2c, omap_clk clk);
19
DEF_HELPER_FLAGS_4(sve2_sqrdmulh_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
20
DEF_HELPER_FLAGS_4(sve2_sqrdmulh_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
22
/* omap_gpio.c */
21
23
#define TYPE_OMAP1_GPIO "omap-gpio"
22
+DEF_HELPER_FLAGS_4(sve2_sqdmulh_idx_h, TCG_CALL_NO_RWG,
24
-DECLARE_INSTANCE_CHECKER(struct omap_gpif_s, OMAP1_GPIO,
23
+ void, ptr, ptr, ptr, i32)
25
+typedef struct Omap1GpioState Omap1GpioState;
24
+DEF_HELPER_FLAGS_4(sve2_sqdmulh_idx_s, TCG_CALL_NO_RWG,
26
+DECLARE_INSTANCE_CHECKER(Omap1GpioState, OMAP1_GPIO,
25
+ void, ptr, ptr, ptr, i32)
27
TYPE_OMAP1_GPIO)
26
+DEF_HELPER_FLAGS_4(sve2_sqdmulh_idx_d, TCG_CALL_NO_RWG,
28
27
+ void, ptr, ptr, ptr, i32)
29
#define TYPE_OMAP2_GPIO "omap2-gpio"
28
+
30
DECLARE_INSTANCE_CHECKER(struct omap2_gpif_s, OMAP2_GPIO,
29
+DEF_HELPER_FLAGS_4(sve2_sqrdmulh_idx_h, TCG_CALL_NO_RWG,
31
TYPE_OMAP2_GPIO)
30
+ void, ptr, ptr, ptr, i32)
32
31
+DEF_HELPER_FLAGS_4(sve2_sqrdmulh_idx_s, TCG_CALL_NO_RWG,
33
-typedef struct omap_gpif_s omap_gpif;
32
+ void, ptr, ptr, ptr, i32)
34
typedef struct omap2_gpif_s omap2_gpif;
33
+DEF_HELPER_FLAGS_4(sve2_sqrdmulh_idx_d, TCG_CALL_NO_RWG,
35
34
+ void, ptr, ptr, ptr, i32)
36
/* TODO: clock framework (see above) */
35
+
37
-void omap_gpio_set_clk(omap_gpif *gpio, omap_clk clk);
36
DEF_HELPER_FLAGS_4(gvec_xar_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
38
+void omap_gpio_set_clk(Omap1GpioState *gpio, omap_clk clk);
37
39
38
#ifdef TARGET_AARCH64
40
void omap2_gpio_set_iclk(omap2_gpif *gpio, omap_clk clk);
39
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
41
void omap2_gpio_set_fclk(omap2_gpif *gpio, uint8_t i, omap_clk clk);
42
diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c
40
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/sve.decode
44
--- a/hw/gpio/omap_gpio.c
42
+++ b/target/arm/sve.decode
45
+++ b/hw/gpio/omap_gpio.c
43
@@ -XXX,XX +XXX,XX @@ SQDMULLB_zzx_d 01000100 11 1 ..... 1110.0 ..... ..... @rrx_2a esz=3
46
@@ -XXX,XX +XXX,XX @@ struct omap_gpio_s {
44
SQDMULLT_zzx_s 01000100 10 1 ..... 1110.1 ..... ..... @rrx_3a esz=2
47
uint16_t pins;
45
SQDMULLT_zzx_d 01000100 11 1 ..... 1110.1 ..... ..... @rrx_2a esz=3
48
};
46
49
47
+# SVE2 saturating multiply high (indexed)
50
-struct omap_gpif_s {
48
+SQDMULH_zzx_h 01000100 0. 1 ..... 111100 ..... ..... @rrx_3 esz=1
51
+struct Omap1GpioState {
49
+SQDMULH_zzx_s 01000100 10 1 ..... 111100 ..... ..... @rrx_2 esz=2
52
SysBusDevice parent_obj;
50
+SQDMULH_zzx_d 01000100 11 1 ..... 111100 ..... ..... @rrx_1 esz=3
53
51
+SQRDMULH_zzx_h 01000100 0. 1 ..... 111101 ..... ..... @rrx_3 esz=1
54
MemoryRegion iomem;
52
+SQRDMULH_zzx_s 01000100 10 1 ..... 111101 ..... ..... @rrx_2 esz=2
55
@@ -XXX,XX +XXX,XX @@ struct omap_gpif_s {
53
+SQRDMULH_zzx_d 01000100 11 1 ..... 111101 ..... ..... @rrx_1 esz=3
56
/* General-Purpose I/O of OMAP1 */
54
+
57
static void omap_gpio_set(void *opaque, int line, int level)
55
# SVE2 integer multiply (indexed)
58
{
56
MUL_zzx_h 01000100 0. 1 ..... 111110 ..... ..... @rrx_3 esz=1
59
- struct omap_gpif_s *p = opaque;
57
MUL_zzx_s 01000100 10 1 ..... 111110 ..... ..... @rrx_2 esz=2
60
+ Omap1GpioState *p = opaque;
58
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
61
struct omap_gpio_s *s = &p->omap1;
59
index XXXXXXX..XXXXXXX 100644
62
uint16_t prev = s->inputs;
60
--- a/target/arm/translate-sve.c
63
61
+++ b/target/arm/translate-sve.c
64
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap2_gpio_module_ops = {
62
@@ -XXX,XX +XXX,XX @@ DO_SVE2_RRX(trans_MUL_zzx_h, gen_helper_gvec_mul_idx_h)
65
63
DO_SVE2_RRX(trans_MUL_zzx_s, gen_helper_gvec_mul_idx_s)
66
static void omap_gpif_reset(DeviceState *dev)
64
DO_SVE2_RRX(trans_MUL_zzx_d, gen_helper_gvec_mul_idx_d)
67
{
65
68
- struct omap_gpif_s *s = OMAP1_GPIO(dev);
66
+DO_SVE2_RRX(trans_SQDMULH_zzx_h, gen_helper_sve2_sqdmulh_idx_h)
69
+ Omap1GpioState *s = OMAP1_GPIO(dev);
67
+DO_SVE2_RRX(trans_SQDMULH_zzx_s, gen_helper_sve2_sqdmulh_idx_s)
70
68
+DO_SVE2_RRX(trans_SQDMULH_zzx_d, gen_helper_sve2_sqdmulh_idx_d)
71
omap_gpio_reset(&s->omap1);
69
+
72
}
70
+DO_SVE2_RRX(trans_SQRDMULH_zzx_h, gen_helper_sve2_sqrdmulh_idx_h)
73
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap2_gpif_top_ops = {
71
+DO_SVE2_RRX(trans_SQRDMULH_zzx_s, gen_helper_sve2_sqrdmulh_idx_s)
74
static void omap_gpio_init(Object *obj)
72
+DO_SVE2_RRX(trans_SQRDMULH_zzx_d, gen_helper_sve2_sqrdmulh_idx_d)
75
{
73
+
76
DeviceState *dev = DEVICE(obj);
74
#undef DO_SVE2_RRX
77
- struct omap_gpif_s *s = OMAP1_GPIO(obj);
75
78
+ Omap1GpioState *s = OMAP1_GPIO(obj);
76
#define DO_SVE2_RRX_TB(NAME, FUNC, TOP) \
79
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
77
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
80
78
index XXXXXXX..XXXXXXX 100644
81
qdev_init_gpio_in(dev, omap_gpio_set, 16);
79
--- a/target/arm/vec_helper.c
82
@@ -XXX,XX +XXX,XX @@ static void omap_gpio_init(Object *obj)
80
+++ b/target/arm/vec_helper.c
83
81
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_sqrdmulh_h)(void *vd, void *vn, void *vm, uint32_t desc)
84
static void omap_gpio_realize(DeviceState *dev, Error **errp)
85
{
86
- struct omap_gpif_s *s = OMAP1_GPIO(dev);
87
+ Omap1GpioState *s = OMAP1_GPIO(dev);
88
89
if (!s->clk) {
90
error_setg(errp, "omap-gpio: clk not connected");
91
@@ -XXX,XX +XXX,XX @@ static void omap2_gpio_realize(DeviceState *dev, Error **errp)
82
}
92
}
83
}
93
}
84
94
85
+void HELPER(sve2_sqdmulh_idx_h)(void *vd, void *vn, void *vm, uint32_t desc)
95
-void omap_gpio_set_clk(omap_gpif *gpio, omap_clk clk)
86
+{
96
+void omap_gpio_set_clk(Omap1GpioState *gpio, omap_clk clk)
87
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
97
{
88
+ int idx = simd_data(desc);
98
gpio->clk = clk;
89
+ int16_t *d = vd, *n = vn, *m = (int16_t *)vm + H2(idx);
90
+ uint32_t discard;
91
+
92
+ for (i = 0; i < opr_sz / 2; i += 16 / 2) {
93
+ int16_t mm = m[i];
94
+ for (j = 0; j < 16 / 2; ++j) {
95
+ d[i + j] = do_sqrdmlah_h(n[i + j], mm, 0, false, false, &discard);
96
+ }
97
+ }
98
+}
99
+
100
+void HELPER(sve2_sqrdmulh_idx_h)(void *vd, void *vn, void *vm, uint32_t desc)
101
+{
102
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
103
+ int idx = simd_data(desc);
104
+ int16_t *d = vd, *n = vn, *m = (int16_t *)vm + H2(idx);
105
+ uint32_t discard;
106
+
107
+ for (i = 0; i < opr_sz / 2; i += 16 / 2) {
108
+ int16_t mm = m[i];
109
+ for (j = 0; j < 16 / 2; ++j) {
110
+ d[i + j] = do_sqrdmlah_h(n[i + j], mm, 0, false, true, &discard);
111
+ }
112
+ }
113
+}
114
+
115
/* Signed saturating rounding doubling multiply-accumulate high half, 32-bit */
116
int32_t do_sqrdmlah_s(int32_t src1, int32_t src2, int32_t src3,
117
bool neg, bool round, uint32_t *sat)
118
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_sqrdmulh_s)(void *vd, void *vn, void *vm, uint32_t desc)
119
}
120
}
99
}
121
100
122
+void HELPER(sve2_sqdmulh_idx_s)(void *vd, void *vn, void *vm, uint32_t desc)
101
static Property omap_gpio_properties[] = {
123
+{
102
- DEFINE_PROP_INT32("mpu_model", struct omap_gpif_s, mpu_model, 0),
124
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
103
+ DEFINE_PROP_INT32("mpu_model", Omap1GpioState, mpu_model, 0),
125
+ int idx = simd_data(desc);
104
DEFINE_PROP_END_OF_LIST(),
126
+ int32_t *d = vd, *n = vn, *m = (int32_t *)vm + H4(idx);
105
};
127
+ uint32_t discard;
106
128
+
107
@@ -XXX,XX +XXX,XX @@ static void omap_gpio_class_init(ObjectClass *klass, void *data)
129
+ for (i = 0; i < opr_sz / 4; i += 16 / 4) {
108
static const TypeInfo omap_gpio_info = {
130
+ int32_t mm = m[i];
109
.name = TYPE_OMAP1_GPIO,
131
+ for (j = 0; j < 16 / 4; ++j) {
110
.parent = TYPE_SYS_BUS_DEVICE,
132
+ d[i + j] = do_sqrdmlah_s(n[i + j], mm, 0, false, false, &discard);
111
- .instance_size = sizeof(struct omap_gpif_s),
133
+ }
112
+ .instance_size = sizeof(Omap1GpioState),
134
+ }
113
.instance_init = omap_gpio_init,
135
+}
114
.class_init = omap_gpio_class_init,
136
+
115
};
137
+void HELPER(sve2_sqrdmulh_idx_s)(void *vd, void *vn, void *vm, uint32_t desc)
138
+{
139
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
140
+ int idx = simd_data(desc);
141
+ int32_t *d = vd, *n = vn, *m = (int32_t *)vm + H4(idx);
142
+ uint32_t discard;
143
+
144
+ for (i = 0; i < opr_sz / 4; i += 16 / 4) {
145
+ int32_t mm = m[i];
146
+ for (j = 0; j < 16 / 4; ++j) {
147
+ d[i + j] = do_sqrdmlah_s(n[i + j], mm, 0, false, true, &discard);
148
+ }
149
+ }
150
+}
151
+
152
/* Signed saturating rounding doubling multiply-accumulate high half, 64-bit */
153
static int64_t do_sat128_d(Int128 r)
154
{
155
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_sqrdmulh_d)(void *vd, void *vn, void *vm, uint32_t desc)
156
}
157
}
158
159
+void HELPER(sve2_sqdmulh_idx_d)(void *vd, void *vn, void *vm, uint32_t desc)
160
+{
161
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
162
+ int idx = simd_data(desc);
163
+ int64_t *d = vd, *n = vn, *m = (int64_t *)vm + idx;
164
+
165
+ for (i = 0; i < opr_sz / 8; i += 16 / 8) {
166
+ int64_t mm = m[i];
167
+ for (j = 0; j < 16 / 8; ++j) {
168
+ d[i + j] = do_sqrdmlah_d(n[i + j], mm, 0, false, false);
169
+ }
170
+ }
171
+}
172
+
173
+void HELPER(sve2_sqrdmulh_idx_d)(void *vd, void *vn, void *vm, uint32_t desc)
174
+{
175
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
176
+ int idx = simd_data(desc);
177
+ int64_t *d = vd, *n = vn, *m = (int64_t *)vm + idx;
178
+
179
+ for (i = 0; i < opr_sz / 8; i += 16 / 8) {
180
+ int64_t mm = m[i];
181
+ for (j = 0; j < 16 / 8; ++j) {
182
+ d[i + j] = do_sqrdmlah_d(n[i + j], mm, 0, false, true);
183
+ }
184
+ }
185
+}
186
+
187
/* Integer 8 and 16-bit dot-product.
188
*
189
* Note that for the loops herein, host endianness does not matter
190
--
116
--
191
2.20.1
117
2.34.1
192
118
193
119
diff view generated by jsdifflib
1
Currently we model the ITCM in the AN547's RAMInfo list. This is incorrect
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
because this RAM is really a part of the SSE-300. We can't just delete
3
it from the RAMInfo list, though, because this would make boot_ram_size()
4
assert because it wouldn't be able to find an entry in the list covering
5
guest address 0.
6
2
7
Allow a board to specify a boot RAM size manually if it doesn't have
3
Following docs/devel/style.rst guidelines, rename omap2_gpif_s ->
8
any RAM itself at address 0 and is relying on the SSE for that, and
4
Omap2GpioState. This also remove a use of 'struct' in the
9
set the correct value for the AN547. The other boards can continue
5
DECLARE_INSTANCE_CHECKER() macro call.
10
to use the "look it up from the RAMInfo list" logic.
11
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230109140306.23161-6-philmd@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210510190844.17799-6-peter.maydell@linaro.org
15
---
11
---
16
hw/arm/mps2-tz.c | 13 +++++++++++++
12
include/hw/arm/omap.h | 9 ++++-----
17
1 file changed, 13 insertions(+)
13
hw/gpio/omap_gpio.c | 20 ++++++++++----------
14
2 files changed, 14 insertions(+), 15 deletions(-)
18
15
19
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/mps2-tz.c
18
--- a/include/hw/arm/omap.h
22
+++ b/hw/arm/mps2-tz.c
19
+++ b/include/hw/arm/omap.h
23
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
20
@@ -XXX,XX +XXX,XX @@ DECLARE_INSTANCE_CHECKER(Omap1GpioState, OMAP1_GPIO,
24
uint32_t sram_addr_width; /* SRAM_ADDR_WIDTH setting for SSE */
21
TYPE_OMAP1_GPIO)
25
const RAMInfo *raminfo;
22
26
const char *armsse_type;
23
#define TYPE_OMAP2_GPIO "omap2-gpio"
27
+ uint32_t boot_ram_size; /* size of ram at address 0; 0 == find in raminfo */
24
-DECLARE_INSTANCE_CHECKER(struct omap2_gpif_s, OMAP2_GPIO,
25
+typedef struct Omap2GpioState Omap2GpioState;
26
+DECLARE_INSTANCE_CHECKER(Omap2GpioState, OMAP2_GPIO,
27
TYPE_OMAP2_GPIO)
28
29
-typedef struct omap2_gpif_s omap2_gpif;
30
-
31
/* TODO: clock framework (see above) */
32
void omap_gpio_set_clk(Omap1GpioState *gpio, omap_clk clk);
33
34
-void omap2_gpio_set_iclk(omap2_gpif *gpio, omap_clk clk);
35
-void omap2_gpio_set_fclk(omap2_gpif *gpio, uint8_t i, omap_clk clk);
36
+void omap2_gpio_set_iclk(Omap2GpioState *gpio, omap_clk clk);
37
+void omap2_gpio_set_fclk(Omap2GpioState *gpio, uint8_t i, omap_clk clk);
38
39
/* OMAP2 l4 Interconnect */
40
struct omap_l4_s;
41
diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/gpio/omap_gpio.c
44
+++ b/hw/gpio/omap_gpio.c
45
@@ -XXX,XX +XXX,XX @@ struct omap2_gpio_s {
46
uint8_t delay;
28
};
47
};
29
48
30
struct MPS2TZMachineState {
49
-struct omap2_gpif_s {
31
@@ -XXX,XX +XXX,XX @@ static uint32_t boot_ram_size(MPS2TZMachineState *mms)
50
+struct Omap2GpioState {
32
const RAMInfo *p;
51
SysBusDevice parent_obj;
33
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
52
34
53
MemoryRegion iomem;
35
+ /*
54
@@ -XXX,XX +XXX,XX @@ static inline void omap2_gpio_module_int(struct omap2_gpio_s *s, int line)
36
+ * Use a per-board specification (for when the boot RAM is in
55
37
+ * the SSE and so doesn't have a RAMInfo list entry)
56
static void omap2_gpio_set(void *opaque, int line, int level)
38
+ */
57
{
39
+ if (mmc->boot_ram_size) {
58
- struct omap2_gpif_s *p = opaque;
40
+ return mmc->boot_ram_size;
59
+ Omap2GpioState *p = opaque;
41
+ }
60
struct omap2_gpio_s *s = &p->modules[line >> 5];
42
+
61
43
for (p = mmc->raminfo; p->name; p++) {
62
line &= 31;
44
if (p->base == boot_mem_base(mms)) {
63
@@ -XXX,XX +XXX,XX @@ static void omap_gpif_reset(DeviceState *dev)
45
return p->size;
64
46
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
65
static void omap2_gpif_reset(DeviceState *dev)
47
mmc->sram_addr_width = 15;
66
{
48
mmc->raminfo = an505_raminfo;
67
- struct omap2_gpif_s *s = OMAP2_GPIO(dev);
49
mmc->armsse_type = TYPE_IOTKIT;
68
+ Omap2GpioState *s = OMAP2_GPIO(dev);
50
+ mmc->boot_ram_size = 0;
69
int i;
51
mps2tz_set_default_ram_info(mmc);
70
71
for (i = 0; i < s->modulecount; i++) {
72
@@ -XXX,XX +XXX,XX @@ static void omap2_gpif_reset(DeviceState *dev)
73
74
static uint64_t omap2_gpif_top_read(void *opaque, hwaddr addr, unsigned size)
75
{
76
- struct omap2_gpif_s *s = opaque;
77
+ Omap2GpioState *s = opaque;
78
79
switch (addr) {
80
case 0x00:    /* IPGENERICOCPSPL_REVISION */
81
@@ -XXX,XX +XXX,XX @@ static uint64_t omap2_gpif_top_read(void *opaque, hwaddr addr, unsigned size)
82
static void omap2_gpif_top_write(void *opaque, hwaddr addr,
83
uint64_t value, unsigned size)
84
{
85
- struct omap2_gpif_s *s = opaque;
86
+ Omap2GpioState *s = opaque;
87
88
switch (addr) {
89
case 0x00:    /* IPGENERICOCPSPL_REVISION */
90
@@ -XXX,XX +XXX,XX @@ static void omap_gpio_realize(DeviceState *dev, Error **errp)
91
92
static void omap2_gpio_realize(DeviceState *dev, Error **errp)
93
{
94
- struct omap2_gpif_s *s = OMAP2_GPIO(dev);
95
+ Omap2GpioState *s = OMAP2_GPIO(dev);
96
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
97
int i;
98
99
@@ -XXX,XX +XXX,XX @@ static const TypeInfo omap_gpio_info = {
100
.class_init = omap_gpio_class_init,
101
};
102
103
-void omap2_gpio_set_iclk(omap2_gpif *gpio, omap_clk clk)
104
+void omap2_gpio_set_iclk(Omap2GpioState *gpio, omap_clk clk)
105
{
106
gpio->iclk = clk;
52
}
107
}
53
108
54
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
109
-void omap2_gpio_set_fclk(omap2_gpif *gpio, uint8_t i, omap_clk clk)
55
mmc->sram_addr_width = 15;
110
+void omap2_gpio_set_fclk(Omap2GpioState *gpio, uint8_t i, omap_clk clk)
56
mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
111
{
57
mmc->armsse_type = TYPE_SSE200;
112
assert(i <= 5);
58
+ mmc->boot_ram_size = 0;
113
gpio->fclk[i] = clk;
59
mps2tz_set_default_ram_info(mmc);
60
}
114
}
61
115
62
@@ -XXX,XX +XXX,XX @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
116
static Property omap2_gpio_properties[] = {
63
mmc->sram_addr_width = 15;
117
- DEFINE_PROP_INT32("mpu_model", struct omap2_gpif_s, mpu_model, 0),
64
mmc->raminfo = an524_raminfo;
118
+ DEFINE_PROP_INT32("mpu_model", Omap2GpioState, mpu_model, 0),
65
mmc->armsse_type = TYPE_SSE200;
119
DEFINE_PROP_END_OF_LIST(),
66
+ mmc->boot_ram_size = 0;
120
};
67
mps2tz_set_default_ram_info(mmc);
121
68
122
@@ -XXX,XX +XXX,XX @@ static void omap2_gpio_class_init(ObjectClass *klass, void *data)
69
object_class_property_add_str(oc, "remap", mps2_get_remap, mps2_set_remap);
123
static const TypeInfo omap2_gpio_info = {
70
@@ -XXX,XX +XXX,XX @@ static void mps3tz_an547_class_init(ObjectClass *oc, void *data)
124
.name = TYPE_OMAP2_GPIO,
71
mmc->sram_addr_width = 21;
125
.parent = TYPE_SYS_BUS_DEVICE,
72
mmc->raminfo = an547_raminfo;
126
- .instance_size = sizeof(struct omap2_gpif_s),
73
mmc->armsse_type = TYPE_SSE300;
127
+ .instance_size = sizeof(Omap2GpioState),
74
+ mmc->boot_ram_size = 512 * KiB;
128
.class_init = omap2_gpio_class_init,
75
mps2tz_set_default_ram_info(mmc);
129
};
76
}
77
130
78
--
131
--
79
2.20.1
132
2.34.1
80
133
81
134
diff view generated by jsdifflib
Deleted patch
1
The SSE-300 has an ITCM at 0x0000_0000 and a DTCM at 0x2000_0000.
2
Currently we model these in the AN547 board, but this is conceptually
3
wrong, because they are a part of the SSE-300 itself. Move the
4
modelling of the TCMs out of mps2-tz.c into sse300.c.
5
1
6
This has no guest-visible effects.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210510190844.17799-7-peter.maydell@linaro.org
11
---
12
include/hw/arm/armsse.h | 2 ++
13
hw/arm/armsse.c | 19 +++++++++++++++++++
14
hw/arm/mps2-tz.c | 12 ------------
15
3 files changed, 21 insertions(+), 12 deletions(-)
16
17
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/armsse.h
20
+++ b/include/hw/arm/armsse.h
21
@@ -XXX,XX +XXX,XX @@ struct ARMSSE {
22
MemoryRegion alias2;
23
MemoryRegion alias3[SSE_MAX_CPUS];
24
MemoryRegion sram[MAX_SRAM_BANKS];
25
+ MemoryRegion itcm;
26
+ MemoryRegion dtcm;
27
28
qemu_irq *exp_irqs[SSE_MAX_CPUS];
29
qemu_irq ppc0_irq;
30
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/arm/armsse.c
33
+++ b/hw/arm/armsse.c
34
@@ -XXX,XX +XXX,XX @@
35
#include "qemu/log.h"
36
#include "qemu/module.h"
37
#include "qemu/bitops.h"
38
+#include "qemu/units.h"
39
#include "qapi/error.h"
40
#include "trace.h"
41
#include "hw/sysbus.h"
42
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
43
bool has_cpuid;
44
bool has_cpu_pwrctrl;
45
bool has_sse_counter;
46
+ bool has_tcms;
47
Property *props;
48
const ARMSSEDeviceInfo *devinfo;
49
const bool *irq_is_common;
50
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
51
.has_cpuid = false,
52
.has_cpu_pwrctrl = false,
53
.has_sse_counter = false,
54
+ .has_tcms = false,
55
.props = iotkit_properties,
56
.devinfo = iotkit_devices,
57
.irq_is_common = sse200_irq_is_common,
58
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
59
.has_cpuid = true,
60
.has_cpu_pwrctrl = false,
61
.has_sse_counter = false,
62
+ .has_tcms = false,
63
.props = sse200_properties,
64
.devinfo = sse200_devices,
65
.irq_is_common = sse200_irq_is_common,
66
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
67
.has_cpuid = true,
68
.has_cpu_pwrctrl = true,
69
.has_sse_counter = true,
70
+ .has_tcms = true,
71
.props = sse300_properties,
72
.devinfo = sse300_devices,
73
.irq_is_common = sse300_irq_is_common,
74
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
75
sysbus_mmio_get_region(sbd, 1));
76
}
77
78
+ if (info->has_tcms) {
79
+ /* The SSE-300 has an ITCM at 0x0000_0000 and a DTCM at 0x2000_0000 */
80
+ memory_region_init_ram(&s->itcm, NULL, "sse300-itcm", 512 * KiB, errp);
81
+ if (*errp) {
82
+ return;
83
+ }
84
+ memory_region_init_ram(&s->dtcm, NULL, "sse300-dtcm", 512 * KiB, errp);
85
+ if (*errp) {
86
+ return;
87
+ }
88
+ memory_region_add_subregion(&s->container, 0x00000000, &s->itcm);
89
+ memory_region_add_subregion(&s->container, 0x20000000, &s->dtcm);
90
+ }
91
+
92
/* Devices behind APB PPC0:
93
* 0x40000000: timer0
94
* 0x40001000: timer1
95
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
96
index XXXXXXX..XXXXXXX 100644
97
--- a/hw/arm/mps2-tz.c
98
+++ b/hw/arm/mps2-tz.c
99
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an524_raminfo[] = { {
100
};
101
102
static const RAMInfo an547_raminfo[] = { {
103
- .name = "itcm",
104
- .base = 0x00000000,
105
- .size = 512 * KiB,
106
- .mpc = -1,
107
- .mrindex = 0,
108
- }, {
109
.name = "sram",
110
.base = 0x01000000,
111
.size = 2 * MiB,
112
.mpc = 0,
113
.mrindex = 1,
114
- }, {
115
- .name = "dtcm",
116
- .base = 0x20000000,
117
- .size = 4 * 128 * KiB,
118
- .mpc = -1,
119
- .mrindex = 2,
120
}, {
121
.name = "sram 2",
122
.base = 0x21000000,
123
--
124
2.20.1
125
126
diff view generated by jsdifflib
Deleted patch
1
When an M-profile CPU is restoring registers from the stack on
2
exception return, the stack pointer to use is determined based on
3
bits in the magic exception return type value. We were not getting
4
this logic entirely correct.
5
1
6
Whether we use one of the Secure stack pointers or one of the
7
Non-Secure stack pointers depends on the EXCRET.S bit. However,
8
whether we use the MSP or the PSP then depends on the SPSEL bit in
9
either the CONTROL_S or CONTROL_NS register. We were incorrectly
10
selecting MSP vs PSP based on the EXCRET.SPSEL bit.
11
12
(In the pseudocode this is in the PopStack() function, which calls
13
LookUpSp_with_security_mode() which in turn looks at the relevant
14
CONTROL.SPSEL bit.)
15
16
The buggy behaviour wasn't noticeable in most cases, because we write
17
EXCRET.SPSEL to the CONTROL.SPSEL bit for the S/NS register selected
18
by EXCRET.ES, so we only do the wrong thing when EXCRET.S and
19
EXCRET.ES are different. This will happen when secure code takes a
20
secure exception, which then tail-chains to a non-secure exception
21
which finally returns to the original secure code.
22
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20210520130905.2049-1-peter.maydell@linaro.org
26
---
27
target/arm/m_helper.c | 3 ++-
28
1 file changed, 2 insertions(+), 1 deletion(-)
29
30
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/m_helper.c
33
+++ b/target/arm/m_helper.c
34
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
35
* We use this limited C variable scope so we don't accidentally
36
* use 'frame_sp_p' after we do something that makes it invalid.
37
*/
38
+ bool spsel = env->v7m.control[return_to_secure] & R_V7M_CONTROL_SPSEL_MASK;
39
uint32_t *frame_sp_p = get_v7m_sp_ptr(env,
40
return_to_secure,
41
!return_to_handler,
42
- return_to_sp_process);
43
+ spsel);
44
uint32_t frameptr = *frame_sp_p;
45
bool pop_ok = true;
46
ARMMMUIdx mmu_idx;
47
--
48
2.20.1
49
50
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Rename the structure to match the rename of tlb_flush_range_locked.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210509151618.2331764-4-f4bug@amsat.org
8
Message-Id: <20210508201640.1045808-1-richard.henderson@linaro.org>
9
[PMD: Split from bigger patch]
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
accel/tcg/cputlb.c | 24 ++++++++++++------------
15
1 file changed, 12 insertions(+), 12 deletions(-)
16
17
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/accel/tcg/cputlb.c
20
+++ b/accel/tcg/cputlb.c
21
@@ -XXX,XX +XXX,XX @@ typedef struct {
22
target_ulong len;
23
uint16_t idxmap;
24
uint16_t bits;
25
-} TLBFlushPageBitsByMMUIdxData;
26
+} TLBFlushRangeData;
27
28
static void
29
tlb_flush_page_bits_by_mmuidx_async_0(CPUState *cpu,
30
- TLBFlushPageBitsByMMUIdxData d)
31
+ TLBFlushRangeData d)
32
{
33
CPUArchState *env = cpu->env_ptr;
34
int mmu_idx;
35
@@ -XXX,XX +XXX,XX @@ tlb_flush_page_bits_by_mmuidx_async_0(CPUState *cpu,
36
}
37
38
static bool encode_pbm_to_runon(run_on_cpu_data *out,
39
- TLBFlushPageBitsByMMUIdxData d)
40
+ TLBFlushRangeData d)
41
{
42
/* We need 6 bits to hold to hold @bits up to 63. */
43
if (d.idxmap <= MAKE_64BIT_MASK(0, TARGET_PAGE_BITS - 6)) {
44
@@ -XXX,XX +XXX,XX @@ static bool encode_pbm_to_runon(run_on_cpu_data *out,
45
return false;
46
}
47
48
-static TLBFlushPageBitsByMMUIdxData
49
+static TLBFlushRangeData
50
decode_runon_to_pbm(run_on_cpu_data data)
51
{
52
target_ulong addr_map_bits = (target_ulong) data.target_ptr;
53
- return (TLBFlushPageBitsByMMUIdxData){
54
+ return (TLBFlushRangeData){
55
.addr = addr_map_bits & TARGET_PAGE_MASK,
56
.idxmap = (addr_map_bits & ~TARGET_PAGE_MASK) >> 6,
57
.bits = addr_map_bits & 0x3f
58
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_bits_by_mmuidx_async_1(CPUState *cpu,
59
static void tlb_flush_page_bits_by_mmuidx_async_2(CPUState *cpu,
60
run_on_cpu_data data)
61
{
62
- TLBFlushPageBitsByMMUIdxData *d = data.host_ptr;
63
+ TLBFlushRangeData *d = data.host_ptr;
64
tlb_flush_page_bits_by_mmuidx_async_0(cpu, *d);
65
g_free(d);
66
}
67
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_bits_by_mmuidx_async_2(CPUState *cpu,
68
void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
69
uint16_t idxmap, unsigned bits)
70
{
71
- TLBFlushPageBitsByMMUIdxData d;
72
+ TLBFlushRangeData d;
73
run_on_cpu_data runon;
74
75
/* If all bits are significant, this devolves to tlb_flush_page. */
76
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
77
async_run_on_cpu(cpu, tlb_flush_page_bits_by_mmuidx_async_1, runon);
78
} else {
79
/* Otherwise allocate a structure, freed by the worker. */
80
- TLBFlushPageBitsByMMUIdxData *p = g_memdup(&d, sizeof(d));
81
+ TLBFlushRangeData *p = g_memdup(&d, sizeof(d));
82
async_run_on_cpu(cpu, tlb_flush_page_bits_by_mmuidx_async_2,
83
RUN_ON_CPU_HOST_PTR(p));
84
}
85
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
86
uint16_t idxmap,
87
unsigned bits)
88
{
89
- TLBFlushPageBitsByMMUIdxData d;
90
+ TLBFlushRangeData d;
91
run_on_cpu_data runon;
92
93
/* If all bits are significant, this devolves to tlb_flush_page. */
94
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
95
/* Allocate a separate data block for each destination cpu. */
96
CPU_FOREACH(dst_cpu) {
97
if (dst_cpu != src_cpu) {
98
- TLBFlushPageBitsByMMUIdxData *p = g_memdup(&d, sizeof(d));
99
+ TLBFlushRangeData *p = g_memdup(&d, sizeof(d));
100
async_run_on_cpu(dst_cpu,
101
tlb_flush_page_bits_by_mmuidx_async_2,
102
RUN_ON_CPU_HOST_PTR(p));
103
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
104
uint16_t idxmap,
105
unsigned bits)
106
{
107
- TLBFlushPageBitsByMMUIdxData d;
108
+ TLBFlushRangeData d;
109
run_on_cpu_data runon;
110
111
/* If all bits are significant, this devolves to tlb_flush_page. */
112
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
113
runon);
114
} else {
115
CPUState *dst_cpu;
116
- TLBFlushPageBitsByMMUIdxData *p;
117
+ TLBFlushRangeData *p;
118
119
/* Allocate a separate data block for each destination cpu. */
120
CPU_FOREACH(dst_cpu) {
121
--
122
2.20.1
123
124
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
We will not be able to fit address + length into a 64-bit packet.
4
Drop this optimization before re-organizing this code.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210509151618.2331764-10-f4bug@amsat.org
9
Message-Id: <20210508201640.1045808-1-richard.henderson@linaro.org>
10
[PMD: Split from bigger patch]
11
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
[PMM: Moved patch earlier in the series]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
accel/tcg/cputlb.c | 86 +++++++++++-----------------------------------
16
1 file changed, 20 insertions(+), 66 deletions(-)
17
18
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/accel/tcg/cputlb.c
21
+++ b/accel/tcg/cputlb.c
22
@@ -XXX,XX +XXX,XX @@ tlb_flush_page_bits_by_mmuidx_async_0(CPUState *cpu,
23
}
24
}
25
26
-static bool encode_pbm_to_runon(run_on_cpu_data *out,
27
- TLBFlushRangeData d)
28
-{
29
- /* We need 6 bits to hold to hold @bits up to 63. */
30
- if (d.idxmap <= MAKE_64BIT_MASK(0, TARGET_PAGE_BITS - 6)) {
31
- *out = RUN_ON_CPU_TARGET_PTR(d.addr | (d.idxmap << 6) | d.bits);
32
- return true;
33
- }
34
- return false;
35
-}
36
-
37
-static TLBFlushRangeData
38
-decode_runon_to_pbm(run_on_cpu_data data)
39
-{
40
- target_ulong addr_map_bits = (target_ulong) data.target_ptr;
41
- return (TLBFlushRangeData){
42
- .addr = addr_map_bits & TARGET_PAGE_MASK,
43
- .idxmap = (addr_map_bits & ~TARGET_PAGE_MASK) >> 6,
44
- .bits = addr_map_bits & 0x3f
45
- };
46
-}
47
-
48
-static void tlb_flush_page_bits_by_mmuidx_async_1(CPUState *cpu,
49
- run_on_cpu_data runon)
50
-{
51
- tlb_flush_page_bits_by_mmuidx_async_0(cpu, decode_runon_to_pbm(runon));
52
-}
53
-
54
static void tlb_flush_page_bits_by_mmuidx_async_2(CPUState *cpu,
55
run_on_cpu_data data)
56
{
57
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
58
uint16_t idxmap, unsigned bits)
59
{
60
TLBFlushRangeData d;
61
- run_on_cpu_data runon;
62
63
/* If all bits are significant, this devolves to tlb_flush_page. */
64
if (bits >= TARGET_LONG_BITS) {
65
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
66
67
if (qemu_cpu_is_self(cpu)) {
68
tlb_flush_page_bits_by_mmuidx_async_0(cpu, d);
69
- } else if (encode_pbm_to_runon(&runon, d)) {
70
- async_run_on_cpu(cpu, tlb_flush_page_bits_by_mmuidx_async_1, runon);
71
} else {
72
/* Otherwise allocate a structure, freed by the worker. */
73
TLBFlushRangeData *p = g_memdup(&d, sizeof(d));
74
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
75
unsigned bits)
76
{
77
TLBFlushRangeData d;
78
- run_on_cpu_data runon;
79
+ CPUState *dst_cpu;
80
81
/* If all bits are significant, this devolves to tlb_flush_page. */
82
if (bits >= TARGET_LONG_BITS) {
83
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
84
d.idxmap = idxmap;
85
d.bits = bits;
86
87
- if (encode_pbm_to_runon(&runon, d)) {
88
- flush_all_helper(src_cpu, tlb_flush_page_bits_by_mmuidx_async_1, runon);
89
- } else {
90
- CPUState *dst_cpu;
91
-
92
- /* Allocate a separate data block for each destination cpu. */
93
- CPU_FOREACH(dst_cpu) {
94
- if (dst_cpu != src_cpu) {
95
- TLBFlushRangeData *p = g_memdup(&d, sizeof(d));
96
- async_run_on_cpu(dst_cpu,
97
- tlb_flush_page_bits_by_mmuidx_async_2,
98
- RUN_ON_CPU_HOST_PTR(p));
99
- }
100
+ /* Allocate a separate data block for each destination cpu. */
101
+ CPU_FOREACH(dst_cpu) {
102
+ if (dst_cpu != src_cpu) {
103
+ TLBFlushRangeData *p = g_memdup(&d, sizeof(d));
104
+ async_run_on_cpu(dst_cpu,
105
+ tlb_flush_page_bits_by_mmuidx_async_2,
106
+ RUN_ON_CPU_HOST_PTR(p));
107
}
108
}
109
110
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
111
uint16_t idxmap,
112
unsigned bits)
113
{
114
- TLBFlushRangeData d;
115
- run_on_cpu_data runon;
116
+ TLBFlushRangeData d, *p;
117
+ CPUState *dst_cpu;
118
119
/* If all bits are significant, this devolves to tlb_flush_page. */
120
if (bits >= TARGET_LONG_BITS) {
121
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
122
d.idxmap = idxmap;
123
d.bits = bits;
124
125
- if (encode_pbm_to_runon(&runon, d)) {
126
- flush_all_helper(src_cpu, tlb_flush_page_bits_by_mmuidx_async_1, runon);
127
- async_safe_run_on_cpu(src_cpu, tlb_flush_page_bits_by_mmuidx_async_1,
128
- runon);
129
- } else {
130
- CPUState *dst_cpu;
131
- TLBFlushRangeData *p;
132
-
133
- /* Allocate a separate data block for each destination cpu. */
134
- CPU_FOREACH(dst_cpu) {
135
- if (dst_cpu != src_cpu) {
136
- p = g_memdup(&d, sizeof(d));
137
- async_run_on_cpu(dst_cpu, tlb_flush_page_bits_by_mmuidx_async_2,
138
- RUN_ON_CPU_HOST_PTR(p));
139
- }
140
+ /* Allocate a separate data block for each destination cpu. */
141
+ CPU_FOREACH(dst_cpu) {
142
+ if (dst_cpu != src_cpu) {
143
+ p = g_memdup(&d, sizeof(d));
144
+ async_run_on_cpu(dst_cpu, tlb_flush_page_bits_by_mmuidx_async_2,
145
+ RUN_ON_CPU_HOST_PTR(p));
146
}
147
-
148
- p = g_memdup(&d, sizeof(d));
149
- async_safe_run_on_cpu(src_cpu, tlb_flush_page_bits_by_mmuidx_async_2,
150
- RUN_ON_CPU_HOST_PTR(p));
151
}
152
+
153
+ p = g_memdup(&d, sizeof(d));
154
+ async_safe_run_on_cpu(src_cpu, tlb_flush_page_bits_by_mmuidx_async_2,
155
+ RUN_ON_CPU_HOST_PTR(p));
156
}
157
158
/* update the TLBs so that writes to code in the virtual page 'addr'
159
--
160
2.20.1
161
162
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Rename to match tlb_flush_range_locked.
3
Following docs/devel/style.rst guidelines, rename
4
4
omap_intr_handler_s -> OMAPIntcState. This also remove a
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
use of 'struct' in the DECLARE_INSTANCE_CHECKER() macro call.
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
7
Message-id: 20210509151618.2331764-9-f4bug@amsat.org
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-Id: <20210508201640.1045808-1-richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
[PMD: Split from bigger patch]
9
Message-id: 20230109140306.23161-7-philmd@linaro.org
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
accel/tcg/cputlb.c | 12 ++++++------
12
include/hw/arm/omap.h | 9 ++++-----
15
1 file changed, 6 insertions(+), 6 deletions(-)
13
hw/intc/omap_intc.c | 38 +++++++++++++++++++-------------------
16
14
2 files changed, 23 insertions(+), 24 deletions(-)
17
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
15
16
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/accel/tcg/cputlb.c
18
--- a/include/hw/arm/omap.h
20
+++ b/accel/tcg/cputlb.c
19
+++ b/include/hw/arm/omap.h
21
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_range_by_mmuidx_async_0(CPUState *cpu,
20
@@ -XXX,XX +XXX,XX @@ void omap_clk_reparent(omap_clk clk, omap_clk parent);
21
22
/* omap_intc.c */
23
#define TYPE_OMAP_INTC "common-omap-intc"
24
-typedef struct omap_intr_handler_s omap_intr_handler;
25
-DECLARE_INSTANCE_CHECKER(omap_intr_handler, OMAP_INTC,
26
- TYPE_OMAP_INTC)
27
+typedef struct OMAPIntcState OMAPIntcState;
28
+DECLARE_INSTANCE_CHECKER(OMAPIntcState, OMAP_INTC, TYPE_OMAP_INTC)
29
30
31
/*
32
@@ -XXX,XX +XXX,XX @@ DECLARE_INSTANCE_CHECKER(omap_intr_handler, OMAP_INTC,
33
* (ie the struct omap_mpu_state_s*) to do the clockname to pointer
34
* translation.)
35
*/
36
-void omap_intc_set_iclk(omap_intr_handler *intc, omap_clk clk);
37
-void omap_intc_set_fclk(omap_intr_handler *intc, omap_clk clk);
38
+void omap_intc_set_iclk(OMAPIntcState *intc, omap_clk clk);
39
+void omap_intc_set_fclk(OMAPIntcState *intc, omap_clk clk);
40
41
/* omap_i2c.c */
42
#define TYPE_OMAP_I2C "omap_i2c"
43
diff --git a/hw/intc/omap_intc.c b/hw/intc/omap_intc.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/intc/omap_intc.c
46
+++ b/hw/intc/omap_intc.c
47
@@ -XXX,XX +XXX,XX @@ struct omap_intr_handler_bank_s {
48
unsigned char priority[32];
49
};
50
51
-struct omap_intr_handler_s {
52
+struct OMAPIntcState {
53
SysBusDevice parent_obj;
54
55
qemu_irq *pins;
56
@@ -XXX,XX +XXX,XX @@ struct omap_intr_handler_s {
57
struct omap_intr_handler_bank_s bank[3];
58
};
59
60
-static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq)
61
+static void omap_inth_sir_update(OMAPIntcState *s, int is_fiq)
62
{
63
int i, j, sir_intr, p_intr, p;
64
uint32_t level;
65
@@ -XXX,XX +XXX,XX @@ static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq)
66
s->sir_intr[is_fiq] = sir_intr;
67
}
68
69
-static inline void omap_inth_update(struct omap_intr_handler_s *s, int is_fiq)
70
+static inline void omap_inth_update(OMAPIntcState *s, int is_fiq)
71
{
72
int i;
73
uint32_t has_intr = 0;
74
@@ -XXX,XX +XXX,XX @@ static inline void omap_inth_update(struct omap_intr_handler_s *s, int is_fiq)
75
76
static void omap_set_intr(void *opaque, int irq, int req)
77
{
78
- struct omap_intr_handler_s *ih = opaque;
79
+ OMAPIntcState *ih = opaque;
80
uint32_t rise;
81
82
struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5];
83
@@ -XXX,XX +XXX,XX @@ static void omap_set_intr(void *opaque, int irq, int req)
84
/* Simplified version with no edge detection */
85
static void omap_set_intr_noedge(void *opaque, int irq, int req)
86
{
87
- struct omap_intr_handler_s *ih = opaque;
88
+ OMAPIntcState *ih = opaque;
89
uint32_t rise;
90
91
struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5];
92
@@ -XXX,XX +XXX,XX @@ static void omap_set_intr_noedge(void *opaque, int irq, int req)
93
static uint64_t omap_inth_read(void *opaque, hwaddr addr,
94
unsigned size)
95
{
96
- struct omap_intr_handler_s *s = opaque;
97
+ OMAPIntcState *s = opaque;
98
int i, offset = addr;
99
int bank_no = offset >> 8;
100
int line_no;
101
@@ -XXX,XX +XXX,XX @@ static uint64_t omap_inth_read(void *opaque, hwaddr addr,
102
static void omap_inth_write(void *opaque, hwaddr addr,
103
uint64_t value, unsigned size)
104
{
105
- struct omap_intr_handler_s *s = opaque;
106
+ OMAPIntcState *s = opaque;
107
int i, offset = addr;
108
int bank_no = offset >> 8;
109
struct omap_intr_handler_bank_s *bank = &s->bank[bank_no];
110
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap_inth_mem_ops = {
111
112
static void omap_inth_reset(DeviceState *dev)
113
{
114
- struct omap_intr_handler_s *s = OMAP_INTC(dev);
115
+ OMAPIntcState *s = OMAP_INTC(dev);
116
int i;
117
118
for (i = 0; i < s->nbanks; ++i){
119
@@ -XXX,XX +XXX,XX @@ static void omap_inth_reset(DeviceState *dev)
120
static void omap_intc_init(Object *obj)
121
{
122
DeviceState *dev = DEVICE(obj);
123
- struct omap_intr_handler_s *s = OMAP_INTC(obj);
124
+ OMAPIntcState *s = OMAP_INTC(obj);
125
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
126
127
s->nbanks = 1;
128
@@ -XXX,XX +XXX,XX @@ static void omap_intc_init(Object *obj)
129
130
static void omap_intc_realize(DeviceState *dev, Error **errp)
131
{
132
- struct omap_intr_handler_s *s = OMAP_INTC(dev);
133
+ OMAPIntcState *s = OMAP_INTC(dev);
134
135
if (!s->iclk) {
136
error_setg(errp, "omap-intc: clk not connected");
22
}
137
}
23
}
138
}
24
139
25
-static void tlb_flush_page_bits_by_mmuidx_async_2(CPUState *cpu,
140
-void omap_intc_set_iclk(omap_intr_handler *intc, omap_clk clk)
26
- run_on_cpu_data data)
141
+void omap_intc_set_iclk(OMAPIntcState *intc, omap_clk clk)
27
+static void tlb_flush_range_by_mmuidx_async_1(CPUState *cpu,
142
{
28
+ run_on_cpu_data data)
143
intc->iclk = clk;
29
{
144
}
30
TLBFlushRangeData *d = data.host_ptr;
145
31
tlb_flush_range_by_mmuidx_async_0(cpu, *d);
146
-void omap_intc_set_fclk(omap_intr_handler *intc, omap_clk clk)
32
@@ -XXX,XX +XXX,XX @@ void tlb_flush_range_by_mmuidx(CPUState *cpu, target_ulong addr,
147
+void omap_intc_set_fclk(OMAPIntcState *intc, omap_clk clk)
33
} else {
148
{
34
/* Otherwise allocate a structure, freed by the worker. */
149
intc->fclk = clk;
35
TLBFlushRangeData *p = g_memdup(&d, sizeof(d));
150
}
36
- async_run_on_cpu(cpu, tlb_flush_page_bits_by_mmuidx_async_2,
151
37
+ async_run_on_cpu(cpu, tlb_flush_range_by_mmuidx_async_1,
152
static Property omap_intc_properties[] = {
38
RUN_ON_CPU_HOST_PTR(p));
153
- DEFINE_PROP_UINT32("size", struct omap_intr_handler_s, size, 0x100),
39
}
154
+ DEFINE_PROP_UINT32("size", OMAPIntcState, size, 0x100),
40
}
155
DEFINE_PROP_END_OF_LIST(),
41
@@ -XXX,XX +XXX,XX @@ void tlb_flush_range_by_mmuidx_all_cpus(CPUState *src_cpu,
156
};
42
if (dst_cpu != src_cpu) {
157
43
TLBFlushRangeData *p = g_memdup(&d, sizeof(d));
158
@@ -XXX,XX +XXX,XX @@ static const TypeInfo omap_intc_info = {
44
async_run_on_cpu(dst_cpu,
159
static uint64_t omap2_inth_read(void *opaque, hwaddr addr,
45
- tlb_flush_page_bits_by_mmuidx_async_2,
160
unsigned size)
46
+ tlb_flush_range_by_mmuidx_async_1,
161
{
47
RUN_ON_CPU_HOST_PTR(p));
162
- struct omap_intr_handler_s *s = opaque;
48
}
163
+ OMAPIntcState *s = opaque;
49
}
164
int offset = addr;
50
@@ -XXX,XX +XXX,XX @@ void tlb_flush_range_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
165
int bank_no, line_no;
51
CPU_FOREACH(dst_cpu) {
166
struct omap_intr_handler_bank_s *bank = NULL;
52
if (dst_cpu != src_cpu) {
167
@@ -XXX,XX +XXX,XX @@ static uint64_t omap2_inth_read(void *opaque, hwaddr addr,
53
p = g_memdup(&d, sizeof(d));
168
static void omap2_inth_write(void *opaque, hwaddr addr,
54
- async_run_on_cpu(dst_cpu, tlb_flush_page_bits_by_mmuidx_async_2,
169
uint64_t value, unsigned size)
55
+ async_run_on_cpu(dst_cpu, tlb_flush_range_by_mmuidx_async_1,
170
{
56
RUN_ON_CPU_HOST_PTR(p));
171
- struct omap_intr_handler_s *s = opaque;
57
}
172
+ OMAPIntcState *s = opaque;
58
}
173
int offset = addr;
59
174
int bank_no, line_no;
60
p = g_memdup(&d, sizeof(d));
175
struct omap_intr_handler_bank_s *bank = NULL;
61
- async_safe_run_on_cpu(src_cpu, tlb_flush_page_bits_by_mmuidx_async_2,
176
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps omap2_inth_mem_ops = {
62
+ async_safe_run_on_cpu(src_cpu, tlb_flush_range_by_mmuidx_async_1,
177
static void omap2_intc_init(Object *obj)
63
RUN_ON_CPU_HOST_PTR(p));
178
{
64
}
179
DeviceState *dev = DEVICE(obj);
180
- struct omap_intr_handler_s *s = OMAP_INTC(obj);
181
+ OMAPIntcState *s = OMAP_INTC(obj);
182
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
183
184
s->level_only = 1;
185
@@ -XXX,XX +XXX,XX @@ static void omap2_intc_init(Object *obj)
186
187
static void omap2_intc_realize(DeviceState *dev, Error **errp)
188
{
189
- struct omap_intr_handler_s *s = OMAP_INTC(dev);
190
+ OMAPIntcState *s = OMAP_INTC(dev);
191
192
if (!s->iclk) {
193
error_setg(errp, "omap2-intc: iclk not connected");
194
@@ -XXX,XX +XXX,XX @@ static void omap2_intc_realize(DeviceState *dev, Error **errp)
195
}
196
197
static Property omap2_intc_properties[] = {
198
- DEFINE_PROP_UINT8("revision", struct omap_intr_handler_s,
199
+ DEFINE_PROP_UINT8("revision", OMAPIntcState,
200
revision, 0x21),
201
DEFINE_PROP_END_OF_LIST(),
202
};
203
@@ -XXX,XX +XXX,XX @@ static const TypeInfo omap2_intc_info = {
204
static const TypeInfo omap_intc_type_info = {
205
.name = TYPE_OMAP_INTC,
206
.parent = TYPE_SYS_BUS_DEVICE,
207
- .instance_size = sizeof(omap_intr_handler),
208
+ .instance_size = sizeof(OMAPIntcState),
209
.abstract = true,
210
};
65
211
66
--
212
--
67
2.20.1
213
2.34.1
68
214
69
215
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Message-id: 20210525010358.152808-62-richard.henderson@linaro.org
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20230109140306.23161-8-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
target/arm/helper-sve.h | 5 +++++
8
hw/arm/stellaris.c | 6 +++---
9
target/arm/sve.decode | 10 ++++++++++
9
1 file changed, 3 insertions(+), 3 deletions(-)
10
target/arm/sve_helper.c | 6 ++++++
11
target/arm/translate-sve.c | 10 ++++++++++
12
4 files changed, 31 insertions(+)
13
10
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
13
--- a/hw/arm/stellaris.c
17
+++ b/target/arm/helper-sve.h
14
+++ b/hw/arm/stellaris.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_umlsl_idx_s, TCG_CALL_NO_RWG,
15
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_update(stellaris_adc_state *s)
19
void, ptr, ptr, ptr, ptr, i32)
16
20
DEF_HELPER_FLAGS_5(sve2_umlsl_idx_d, TCG_CALL_NO_RWG,
17
static void stellaris_adc_trigger(void *opaque, int irq, int level)
21
void, ptr, ptr, ptr, ptr, i32)
18
{
22
+
19
- stellaris_adc_state *s = (stellaris_adc_state *)opaque;
23
+DEF_HELPER_FLAGS_4(sve2_smull_idx_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
20
+ stellaris_adc_state *s = opaque;
24
+DEF_HELPER_FLAGS_4(sve2_smull_idx_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
int n;
25
+DEF_HELPER_FLAGS_4(sve2_umull_idx_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
22
26
+DEF_HELPER_FLAGS_4(sve2_umull_idx_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
for (n = 0; n < 4; n++) {
27
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
24
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_reset(stellaris_adc_state *s)
28
index XXXXXXX..XXXXXXX 100644
25
static uint64_t stellaris_adc_read(void *opaque, hwaddr offset,
29
--- a/target/arm/sve.decode
26
unsigned size)
30
+++ b/target/arm/sve.decode
27
{
31
@@ -XXX,XX +XXX,XX @@ UMLSLB_zzxw_d 01000100 11 1 ..... 1011.0 ..... ..... @rrxr_2a esz=3
28
- stellaris_adc_state *s = (stellaris_adc_state *)opaque;
32
UMLSLT_zzxw_s 01000100 10 1 ..... 1011.1 ..... ..... @rrxr_3a esz=2
29
+ stellaris_adc_state *s = opaque;
33
UMLSLT_zzxw_d 01000100 11 1 ..... 1011.1 ..... ..... @rrxr_2a esz=3
30
34
31
/* TODO: Implement this. */
35
+# SVE2 integer multiply long (indexed)
32
if (offset >= 0x40 && offset < 0xc0) {
36
+SMULLB_zzx_s 01000100 10 1 ..... 1100.0 ..... ..... @rrx_3a esz=2
33
@@ -XXX,XX +XXX,XX @@ static uint64_t stellaris_adc_read(void *opaque, hwaddr offset,
37
+SMULLB_zzx_d 01000100 11 1 ..... 1100.0 ..... ..... @rrx_2a esz=3
34
static void stellaris_adc_write(void *opaque, hwaddr offset,
38
+SMULLT_zzx_s 01000100 10 1 ..... 1100.1 ..... ..... @rrx_3a esz=2
35
uint64_t value, unsigned size)
39
+SMULLT_zzx_d 01000100 11 1 ..... 1100.1 ..... ..... @rrx_2a esz=3
36
{
40
+UMULLB_zzx_s 01000100 10 1 ..... 1101.0 ..... ..... @rrx_3a esz=2
37
- stellaris_adc_state *s = (stellaris_adc_state *)opaque;
41
+UMULLB_zzx_d 01000100 11 1 ..... 1101.0 ..... ..... @rrx_2a esz=3
38
+ stellaris_adc_state *s = opaque;
42
+UMULLT_zzx_s 01000100 10 1 ..... 1101.1 ..... ..... @rrx_3a esz=2
39
43
+UMULLT_zzx_d 01000100 11 1 ..... 1101.1 ..... ..... @rrx_2a esz=3
40
/* TODO: Implement this. */
44
+
41
if (offset >= 0x40 && offset < 0xc0) {
45
# SVE2 saturating multiply (indexed)
46
SQDMULLB_zzx_s 01000100 10 1 ..... 1110.0 ..... ..... @rrx_3a esz=2
47
SQDMULLB_zzx_d 01000100 11 1 ..... 1110.0 ..... ..... @rrx_2a esz=3
48
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/sve_helper.c
51
+++ b/target/arm/sve_helper.c
52
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
53
DO_ZZX(sve2_sqdmull_idx_s, int32_t, int16_t, H1_4, H1_2, do_sqdmull_s)
54
DO_ZZX(sve2_sqdmull_idx_d, int64_t, int32_t, , H1_4, do_sqdmull_d)
55
56
+DO_ZZX(sve2_smull_idx_s, int32_t, int16_t, H1_4, H1_2, DO_MUL)
57
+DO_ZZX(sve2_smull_idx_d, int64_t, int32_t, , H1_4, DO_MUL)
58
+
59
+DO_ZZX(sve2_umull_idx_s, uint32_t, uint16_t, H1_4, H1_2, DO_MUL)
60
+DO_ZZX(sve2_umull_idx_d, uint64_t, uint32_t, , H1_4, DO_MUL)
61
+
62
#undef DO_ZZX
63
64
#define DO_BITPERM(NAME, TYPE, OP) \
65
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/translate-sve.c
68
+++ b/target/arm/translate-sve.c
69
@@ -XXX,XX +XXX,XX @@ DO_SVE2_RRX_TB(trans_SQDMULLB_zzx_d, gen_helper_sve2_sqdmull_idx_d, false)
70
DO_SVE2_RRX_TB(trans_SQDMULLT_zzx_s, gen_helper_sve2_sqdmull_idx_s, true)
71
DO_SVE2_RRX_TB(trans_SQDMULLT_zzx_d, gen_helper_sve2_sqdmull_idx_d, true)
72
73
+DO_SVE2_RRX_TB(trans_SMULLB_zzx_s, gen_helper_sve2_smull_idx_s, false)
74
+DO_SVE2_RRX_TB(trans_SMULLB_zzx_d, gen_helper_sve2_smull_idx_d, false)
75
+DO_SVE2_RRX_TB(trans_SMULLT_zzx_s, gen_helper_sve2_smull_idx_s, true)
76
+DO_SVE2_RRX_TB(trans_SMULLT_zzx_d, gen_helper_sve2_smull_idx_d, true)
77
+
78
+DO_SVE2_RRX_TB(trans_UMULLB_zzx_s, gen_helper_sve2_umull_idx_s, false)
79
+DO_SVE2_RRX_TB(trans_UMULLB_zzx_d, gen_helper_sve2_umull_idx_d, false)
80
+DO_SVE2_RRX_TB(trans_UMULLT_zzx_s, gen_helper_sve2_umull_idx_s, true)
81
+DO_SVE2_RRX_TB(trans_UMULLT_zzx_d, gen_helper_sve2_umull_idx_d, true)
82
+
83
#undef DO_SVE2_RRX_TB
84
85
static bool do_sve2_zzzz_data(DisasContext *s, int rd, int rn, int rm, int ra,
86
--
42
--
87
2.20.1
43
2.34.1
88
44
89
45
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Forward tlb_flush_page_bits_by_mmuidx to tlb_flush_range_by_mmuidx
3
Following docs/devel/style.rst guidelines, rename
4
passing TARGET_PAGE_SIZE.
4
stellaris_adc_state -> StellarisADCState. This also remove a
5
use of 'struct' in the DECLARE_INSTANCE_CHECKER() macro call.
5
6
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210509151618.2331764-5-f4bug@amsat.org
9
Message-id: 20230109140306.23161-9-philmd@linaro.org
9
Message-Id: <20210508201640.1045808-1-richard.henderson@linaro.org>
10
[PMD: Split from bigger patch]
11
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
11
---
15
include/exec/exec-all.h | 19 +++++++++++++++++++
12
hw/arm/stellaris.c | 73 +++++++++++++++++++++++-----------------------
16
accel/tcg/cputlb.c | 20 +++++++++++++++-----
13
1 file changed, 36 insertions(+), 37 deletions(-)
17
2 files changed, 34 insertions(+), 5 deletions(-)
18
14
19
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
15
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/include/exec/exec-all.h
17
--- a/hw/arm/stellaris.c
22
+++ b/include/exec/exec-all.h
18
+++ b/hw/arm/stellaris.c
23
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *cpu, target_ulong addr,
19
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_init(Object *obj)
24
void tlb_flush_page_bits_by_mmuidx_all_cpus_synced
20
#define STELLARIS_ADC_FIFO_FULL 0x1000
25
(CPUState *cpu, target_ulong addr, uint16_t idxmap, unsigned bits);
21
26
22
#define TYPE_STELLARIS_ADC "stellaris-adc"
27
+/**
23
-typedef struct StellarisADCState stellaris_adc_state;
28
+ * tlb_flush_range_by_mmuidx
24
-DECLARE_INSTANCE_CHECKER(stellaris_adc_state, STELLARIS_ADC,
29
+ * @cpu: CPU whose TLB should be flushed
25
- TYPE_STELLARIS_ADC)
30
+ * @addr: virtual address of the start of the range to be flushed
26
+typedef struct StellarisADCState StellarisADCState;
31
+ * @len: length of range to be flushed
27
+DECLARE_INSTANCE_CHECKER(StellarisADCState, STELLARIS_ADC, TYPE_STELLARIS_ADC)
32
+ * @idxmap: bitmap of mmu indexes to flush
28
33
+ * @bits: number of significant bits in address
29
struct StellarisADCState {
34
+ *
30
SysBusDevice parent_obj;
35
+ * For each mmuidx in @idxmap, flush all pages within [@addr,@addr+@len),
31
@@ -XXX,XX +XXX,XX @@ struct StellarisADCState {
36
+ * comparing only the low @bits worth of each virtual page.
32
qemu_irq irq[4];
37
+ */
33
};
38
+void tlb_flush_range_by_mmuidx(CPUState *cpu, target_ulong addr,
34
39
+ target_ulong len, uint16_t idxmap,
35
-static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
40
+ unsigned bits);
36
+static uint32_t stellaris_adc_fifo_read(StellarisADCState *s, int n)
41
/**
42
* tlb_set_page_with_attrs:
43
* @cpu: CPU to add this TLB entry for
44
@@ -XXX,XX +XXX,XX @@ tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *cpu, target_ulong addr,
45
uint16_t idxmap, unsigned bits)
46
{
37
{
38
int tail;
39
40
@@ -XXX,XX +XXX,XX @@ static uint32_t stellaris_adc_fifo_read(stellaris_adc_state *s, int n)
41
return s->fifo[n].data[tail];
47
}
42
}
48
+static inline void tlb_flush_range_by_mmuidx(CPUState *cpu, target_ulong addr,
43
49
+ target_ulong len, uint16_t idxmap,
44
-static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
50
+ unsigned bits)
45
+static void stellaris_adc_fifo_write(StellarisADCState *s, int n,
51
+{
46
uint32_t value)
52
+}
47
{
53
#endif
48
int head;
54
/**
49
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_fifo_write(stellaris_adc_state *s, int n,
55
* probe_access:
50
s->fifo[n].state |= STELLARIS_ADC_FIFO_FULL;
56
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/accel/tcg/cputlb.c
59
+++ b/accel/tcg/cputlb.c
60
@@ -XXX,XX +XXX,XX @@ static void tlb_flush_page_bits_by_mmuidx_async_2(CPUState *cpu,
61
g_free(d);
62
}
51
}
63
52
64
-void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
53
-static void stellaris_adc_update(stellaris_adc_state *s)
65
- uint16_t idxmap, unsigned bits)
54
+static void stellaris_adc_update(StellarisADCState *s)
66
+void tlb_flush_range_by_mmuidx(CPUState *cpu, target_ulong addr,
67
+ target_ulong len, uint16_t idxmap,
68
+ unsigned bits)
69
{
55
{
70
TLBFlushRangeData d;
56
int level;
71
57
int n;
72
- /* If all bits are significant, this devolves to tlb_flush_page. */
58
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_update(stellaris_adc_state *s)
73
- if (bits >= TARGET_LONG_BITS) {
59
74
+ /*
60
static void stellaris_adc_trigger(void *opaque, int irq, int level)
75
+ * If all bits are significant, and len is small,
61
{
76
+ * this devolves to tlb_flush_page.
62
- stellaris_adc_state *s = opaque;
77
+ */
63
+ StellarisADCState *s = opaque;
78
+ if (bits >= TARGET_LONG_BITS && len <= TARGET_PAGE_SIZE) {
64
int n;
79
tlb_flush_page_by_mmuidx(cpu, addr, idxmap);
65
80
return;
66
for (n = 0; n < 4; n++) {
81
}
67
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_trigger(void *opaque, int irq, int level)
82
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
83
84
/* This should already be page aligned */
85
d.addr = addr & TARGET_PAGE_MASK;
86
- d.len = TARGET_PAGE_SIZE;
87
+ d.len = len;
88
d.idxmap = idxmap;
89
d.bits = bits;
90
91
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
92
}
68
}
93
}
69
}
94
70
95
+void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
71
-static void stellaris_adc_reset(stellaris_adc_state *s)
96
+ uint16_t idxmap, unsigned bits)
72
+static void stellaris_adc_reset(StellarisADCState *s)
97
+{
73
{
98
+ tlb_flush_range_by_mmuidx(cpu, addr, TARGET_PAGE_SIZE, idxmap, bits);
74
int n;
99
+}
75
100
+
76
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_reset(stellaris_adc_state *s)
101
void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
77
static uint64_t stellaris_adc_read(void *opaque, hwaddr offset,
102
target_ulong addr,
78
unsigned size)
103
uint16_t idxmap,
79
{
80
- stellaris_adc_state *s = opaque;
81
+ StellarisADCState *s = opaque;
82
83
/* TODO: Implement this. */
84
if (offset >= 0x40 && offset < 0xc0) {
85
@@ -XXX,XX +XXX,XX @@ static uint64_t stellaris_adc_read(void *opaque, hwaddr offset,
86
static void stellaris_adc_write(void *opaque, hwaddr offset,
87
uint64_t value, unsigned size)
88
{
89
- stellaris_adc_state *s = opaque;
90
+ StellarisADCState *s = opaque;
91
92
/* TODO: Implement this. */
93
if (offset >= 0x40 && offset < 0xc0) {
94
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_stellaris_adc = {
95
.version_id = 1,
96
.minimum_version_id = 1,
97
.fields = (VMStateField[]) {
98
- VMSTATE_UINT32(actss, stellaris_adc_state),
99
- VMSTATE_UINT32(ris, stellaris_adc_state),
100
- VMSTATE_UINT32(im, stellaris_adc_state),
101
- VMSTATE_UINT32(emux, stellaris_adc_state),
102
- VMSTATE_UINT32(ostat, stellaris_adc_state),
103
- VMSTATE_UINT32(ustat, stellaris_adc_state),
104
- VMSTATE_UINT32(sspri, stellaris_adc_state),
105
- VMSTATE_UINT32(sac, stellaris_adc_state),
106
- VMSTATE_UINT32(fifo[0].state, stellaris_adc_state),
107
- VMSTATE_UINT32_ARRAY(fifo[0].data, stellaris_adc_state, 16),
108
- VMSTATE_UINT32(ssmux[0], stellaris_adc_state),
109
- VMSTATE_UINT32(ssctl[0], stellaris_adc_state),
110
- VMSTATE_UINT32(fifo[1].state, stellaris_adc_state),
111
- VMSTATE_UINT32_ARRAY(fifo[1].data, stellaris_adc_state, 16),
112
- VMSTATE_UINT32(ssmux[1], stellaris_adc_state),
113
- VMSTATE_UINT32(ssctl[1], stellaris_adc_state),
114
- VMSTATE_UINT32(fifo[2].state, stellaris_adc_state),
115
- VMSTATE_UINT32_ARRAY(fifo[2].data, stellaris_adc_state, 16),
116
- VMSTATE_UINT32(ssmux[2], stellaris_adc_state),
117
- VMSTATE_UINT32(ssctl[2], stellaris_adc_state),
118
- VMSTATE_UINT32(fifo[3].state, stellaris_adc_state),
119
- VMSTATE_UINT32_ARRAY(fifo[3].data, stellaris_adc_state, 16),
120
- VMSTATE_UINT32(ssmux[3], stellaris_adc_state),
121
- VMSTATE_UINT32(ssctl[3], stellaris_adc_state),
122
- VMSTATE_UINT32(noise, stellaris_adc_state),
123
+ VMSTATE_UINT32(actss, StellarisADCState),
124
+ VMSTATE_UINT32(ris, StellarisADCState),
125
+ VMSTATE_UINT32(im, StellarisADCState),
126
+ VMSTATE_UINT32(emux, StellarisADCState),
127
+ VMSTATE_UINT32(ostat, StellarisADCState),
128
+ VMSTATE_UINT32(ustat, StellarisADCState),
129
+ VMSTATE_UINT32(sspri, StellarisADCState),
130
+ VMSTATE_UINT32(sac, StellarisADCState),
131
+ VMSTATE_UINT32(fifo[0].state, StellarisADCState),
132
+ VMSTATE_UINT32_ARRAY(fifo[0].data, StellarisADCState, 16),
133
+ VMSTATE_UINT32(ssmux[0], StellarisADCState),
134
+ VMSTATE_UINT32(ssctl[0], StellarisADCState),
135
+ VMSTATE_UINT32(fifo[1].state, StellarisADCState),
136
+ VMSTATE_UINT32_ARRAY(fifo[1].data, StellarisADCState, 16),
137
+ VMSTATE_UINT32(ssmux[1], StellarisADCState),
138
+ VMSTATE_UINT32(ssctl[1], StellarisADCState),
139
+ VMSTATE_UINT32(fifo[2].state, StellarisADCState),
140
+ VMSTATE_UINT32_ARRAY(fifo[2].data, StellarisADCState, 16),
141
+ VMSTATE_UINT32(ssmux[2], StellarisADCState),
142
+ VMSTATE_UINT32(ssctl[2], StellarisADCState),
143
+ VMSTATE_UINT32(fifo[3].state, StellarisADCState),
144
+ VMSTATE_UINT32_ARRAY(fifo[3].data, StellarisADCState, 16),
145
+ VMSTATE_UINT32(ssmux[3], StellarisADCState),
146
+ VMSTATE_UINT32(ssctl[3], StellarisADCState),
147
+ VMSTATE_UINT32(noise, StellarisADCState),
148
VMSTATE_END_OF_LIST()
149
}
150
};
151
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_stellaris_adc = {
152
static void stellaris_adc_init(Object *obj)
153
{
154
DeviceState *dev = DEVICE(obj);
155
- stellaris_adc_state *s = STELLARIS_ADC(obj);
156
+ StellarisADCState *s = STELLARIS_ADC(obj);
157
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
158
int n;
159
160
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_class_init(ObjectClass *klass, void *data)
161
static const TypeInfo stellaris_adc_info = {
162
.name = TYPE_STELLARIS_ADC,
163
.parent = TYPE_SYS_BUS_DEVICE,
164
- .instance_size = sizeof(stellaris_adc_state),
165
+ .instance_size = sizeof(StellarisADCState),
166
.instance_init = stellaris_adc_init,
167
.class_init = stellaris_adc_class_init,
168
};
104
--
169
--
105
2.20.1
170
2.34.1
106
171
107
172
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Forward tlb_flush_page_bits_by_mmuidx_all_cpus to
4
tlb_flush_range_by_mmuidx_all_cpus passing TARGET_PAGE_SIZE.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210509151618.2331764-6-f4bug@amsat.org
9
Message-Id: <20210508201640.1045808-1-richard.henderson@linaro.org>
10
[PMD: Split from bigger patch]
11
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
include/exec/exec-all.h | 13 +++++++++++++
16
accel/tcg/cputlb.c | 24 +++++++++++++++++-------
17
2 files changed, 30 insertions(+), 7 deletions(-)
18
19
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/exec/exec-all.h
22
+++ b/include/exec/exec-all.h
23
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus_synced
24
void tlb_flush_range_by_mmuidx(CPUState *cpu, target_ulong addr,
25
target_ulong len, uint16_t idxmap,
26
unsigned bits);
27
+
28
+/* Similarly, with broadcast and syncing. */
29
+void tlb_flush_range_by_mmuidx_all_cpus(CPUState *cpu, target_ulong addr,
30
+ target_ulong len, uint16_t idxmap,
31
+ unsigned bits);
32
+
33
/**
34
* tlb_set_page_with_attrs:
35
* @cpu: CPU to add this TLB entry for
36
@@ -XXX,XX +XXX,XX @@ static inline void tlb_flush_range_by_mmuidx(CPUState *cpu, target_ulong addr,
37
unsigned bits)
38
{
39
}
40
+static inline void tlb_flush_range_by_mmuidx_all_cpus(CPUState *cpu,
41
+ target_ulong addr,
42
+ target_ulong len,
43
+ uint16_t idxmap,
44
+ unsigned bits)
45
+{
46
+}
47
#endif
48
/**
49
* probe_access:
50
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/accel/tcg/cputlb.c
53
+++ b/accel/tcg/cputlb.c
54
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx(CPUState *cpu, target_ulong addr,
55
tlb_flush_range_by_mmuidx(cpu, addr, TARGET_PAGE_SIZE, idxmap, bits);
56
}
57
58
-void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
59
- target_ulong addr,
60
- uint16_t idxmap,
61
- unsigned bits)
62
+void tlb_flush_range_by_mmuidx_all_cpus(CPUState *src_cpu,
63
+ target_ulong addr, target_ulong len,
64
+ uint16_t idxmap, unsigned bits)
65
{
66
TLBFlushRangeData d;
67
CPUState *dst_cpu;
68
69
- /* If all bits are significant, this devolves to tlb_flush_page. */
70
- if (bits >= TARGET_LONG_BITS) {
71
+ /*
72
+ * If all bits are significant, and len is small,
73
+ * this devolves to tlb_flush_page.
74
+ */
75
+ if (bits >= TARGET_LONG_BITS && len <= TARGET_PAGE_SIZE) {
76
tlb_flush_page_by_mmuidx_all_cpus(src_cpu, addr, idxmap);
77
return;
78
}
79
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
80
81
/* This should already be page aligned */
82
d.addr = addr & TARGET_PAGE_MASK;
83
- d.len = TARGET_PAGE_SIZE;
84
+ d.len = len;
85
d.idxmap = idxmap;
86
d.bits = bits;
87
88
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
89
tlb_flush_page_bits_by_mmuidx_async_0(src_cpu, d);
90
}
91
92
+void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
93
+ target_ulong addr,
94
+ uint16_t idxmap, unsigned bits)
95
+{
96
+ tlb_flush_range_by_mmuidx_all_cpus(src_cpu, addr, TARGET_PAGE_SIZE,
97
+ idxmap, bits);
98
+}
99
+
100
void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
101
target_ulong addr,
102
uint16_t idxmap,
103
--
104
2.20.1
105
106
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
The typedef and definitions are generated by the OBJECT_DECLARE_TYPE
4
Message-id: 20210525010358.152808-61-richard.henderson@linaro.org
4
macro in "hw/arm/bcm2836.h":
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
6
20 #define TYPE_BCM283X "bcm283x"
7
21 OBJECT_DECLARE_TYPE(BCM283XState, BCM283XClass, BCM283X)
8
9
The script ran in commit a489d1951c ("Use OBJECT_DECLARE_TYPE when
10
possible") missed them because they are declared in a different
11
file unit. Remove them.
12
13
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20230109140306.23161-10-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
17
---
8
target/arm/helper-sve.h | 17 +++++++++++++++++
18
hw/arm/bcm2836.c | 9 ++-------
9
target/arm/sve.decode | 18 ++++++++++++++++++
19
1 file changed, 2 insertions(+), 7 deletions(-)
10
target/arm/sve_helper.c | 16 ++++++++++++++++
11
target/arm/translate-sve.c | 20 ++++++++++++++++++++
12
4 files changed, 71 insertions(+)
13
20
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
21
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
23
--- a/hw/arm/bcm2836.c
17
+++ b/target/arm/helper-sve.h
24
+++ b/hw/arm/bcm2836.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve2_sqdmull_idx_s, TCG_CALL_NO_RWG,
25
@@ -XXX,XX +XXX,XX @@
19
void, ptr, ptr, ptr, i32)
26
#include "hw/arm/raspi_platform.h"
20
DEF_HELPER_FLAGS_4(sve2_sqdmull_idx_d, TCG_CALL_NO_RWG,
27
#include "hw/sysbus.h"
21
void, ptr, ptr, ptr, i32)
28
22
+
29
-typedef struct BCM283XClass {
23
+DEF_HELPER_FLAGS_5(sve2_smlal_idx_s, TCG_CALL_NO_RWG,
30
+struct BCM283XClass {
24
+ void, ptr, ptr, ptr, ptr, i32)
31
/*< private >*/
25
+DEF_HELPER_FLAGS_5(sve2_smlal_idx_d, TCG_CALL_NO_RWG,
32
DeviceClass parent_class;
26
+ void, ptr, ptr, ptr, ptr, i32)
33
/*< public >*/
27
+DEF_HELPER_FLAGS_5(sve2_smlsl_idx_s, TCG_CALL_NO_RWG,
34
@@ -XXX,XX +XXX,XX @@ typedef struct BCM283XClass {
28
+ void, ptr, ptr, ptr, ptr, i32)
35
hwaddr peri_base; /* Peripheral base address seen by the CPU */
29
+DEF_HELPER_FLAGS_5(sve2_smlsl_idx_d, TCG_CALL_NO_RWG,
36
hwaddr ctrl_base; /* Interrupt controller and mailboxes etc. */
30
+ void, ptr, ptr, ptr, ptr, i32)
37
int clusterid;
31
+DEF_HELPER_FLAGS_5(sve2_umlal_idx_s, TCG_CALL_NO_RWG,
38
-} BCM283XClass;
32
+ void, ptr, ptr, ptr, ptr, i32)
39
-
33
+DEF_HELPER_FLAGS_5(sve2_umlal_idx_d, TCG_CALL_NO_RWG,
40
-#define BCM283X_CLASS(klass) \
34
+ void, ptr, ptr, ptr, ptr, i32)
41
- OBJECT_CLASS_CHECK(BCM283XClass, (klass), TYPE_BCM283X)
35
+DEF_HELPER_FLAGS_5(sve2_umlsl_idx_s, TCG_CALL_NO_RWG,
42
-#define BCM283X_GET_CLASS(obj) \
36
+ void, ptr, ptr, ptr, ptr, i32)
43
- OBJECT_GET_CLASS(BCM283XClass, (obj), TYPE_BCM283X)
37
+DEF_HELPER_FLAGS_5(sve2_umlsl_idx_d, TCG_CALL_NO_RWG,
44
+};
38
+ void, ptr, ptr, ptr, ptr, i32)
45
39
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
46
static Property bcm2836_enabled_cores_property =
40
index XXXXXXX..XXXXXXX 100644
47
DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus, 0);
41
--- a/target/arm/sve.decode
42
+++ b/target/arm/sve.decode
43
@@ -XXX,XX +XXX,XX @@ SQDMLSLB_zzxw_d 01000100 11 1 ..... 0011.0 ..... ..... @rrxr_2a esz=3
44
SQDMLSLT_zzxw_s 01000100 10 1 ..... 0011.1 ..... ..... @rrxr_3a esz=2
45
SQDMLSLT_zzxw_d 01000100 11 1 ..... 0011.1 ..... ..... @rrxr_2a esz=3
46
47
+# SVE2 multiply-add long (indexed)
48
+SMLALB_zzxw_s 01000100 10 1 ..... 1000.0 ..... ..... @rrxr_3a esz=2
49
+SMLALB_zzxw_d 01000100 11 1 ..... 1000.0 ..... ..... @rrxr_2a esz=3
50
+SMLALT_zzxw_s 01000100 10 1 ..... 1000.1 ..... ..... @rrxr_3a esz=2
51
+SMLALT_zzxw_d 01000100 11 1 ..... 1000.1 ..... ..... @rrxr_2a esz=3
52
+UMLALB_zzxw_s 01000100 10 1 ..... 1001.0 ..... ..... @rrxr_3a esz=2
53
+UMLALB_zzxw_d 01000100 11 1 ..... 1001.0 ..... ..... @rrxr_2a esz=3
54
+UMLALT_zzxw_s 01000100 10 1 ..... 1001.1 ..... ..... @rrxr_3a esz=2
55
+UMLALT_zzxw_d 01000100 11 1 ..... 1001.1 ..... ..... @rrxr_2a esz=3
56
+SMLSLB_zzxw_s 01000100 10 1 ..... 1010.0 ..... ..... @rrxr_3a esz=2
57
+SMLSLB_zzxw_d 01000100 11 1 ..... 1010.0 ..... ..... @rrxr_2a esz=3
58
+SMLSLT_zzxw_s 01000100 10 1 ..... 1010.1 ..... ..... @rrxr_3a esz=2
59
+SMLSLT_zzxw_d 01000100 11 1 ..... 1010.1 ..... ..... @rrxr_2a esz=3
60
+UMLSLB_zzxw_s 01000100 10 1 ..... 1011.0 ..... ..... @rrxr_3a esz=2
61
+UMLSLB_zzxw_d 01000100 11 1 ..... 1011.0 ..... ..... @rrxr_2a esz=3
62
+UMLSLT_zzxw_s 01000100 10 1 ..... 1011.1 ..... ..... @rrxr_3a esz=2
63
+UMLSLT_zzxw_d 01000100 11 1 ..... 1011.1 ..... ..... @rrxr_2a esz=3
64
+
65
# SVE2 saturating multiply (indexed)
66
SQDMULLB_zzx_s 01000100 10 1 ..... 1110.0 ..... ..... @rrx_3a esz=2
67
SQDMULLB_zzx_d 01000100 11 1 ..... 1110.0 ..... ..... @rrx_2a esz=3
68
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/sve_helper.c
71
+++ b/target/arm/sve_helper.c
72
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, uint32_t desc) \
73
} \
74
}
75
76
+#define DO_MLA(N, M, A) (A + N * M)
77
+
78
+DO_ZZXW(sve2_smlal_idx_s, int32_t, int16_t, H1_4, H1_2, DO_MLA)
79
+DO_ZZXW(sve2_smlal_idx_d, int64_t, int32_t, , H1_4, DO_MLA)
80
+DO_ZZXW(sve2_umlal_idx_s, uint32_t, uint16_t, H1_4, H1_2, DO_MLA)
81
+DO_ZZXW(sve2_umlal_idx_d, uint64_t, uint32_t, , H1_4, DO_MLA)
82
+
83
+#define DO_MLS(N, M, A) (A - N * M)
84
+
85
+DO_ZZXW(sve2_smlsl_idx_s, int32_t, int16_t, H1_4, H1_2, DO_MLS)
86
+DO_ZZXW(sve2_smlsl_idx_d, int64_t, int32_t, , H1_4, DO_MLS)
87
+DO_ZZXW(sve2_umlsl_idx_s, uint32_t, uint16_t, H1_4, H1_2, DO_MLS)
88
+DO_ZZXW(sve2_umlsl_idx_d, uint64_t, uint32_t, , H1_4, DO_MLS)
89
+
90
#define DO_SQDMLAL_S(N, M, A) DO_SQADD_S(A, do_sqdmull_s(N, M))
91
#define DO_SQDMLAL_D(N, M, A) do_sqadd_d(A, do_sqdmull_d(N, M))
92
93
@@ -XXX,XX +XXX,XX @@ DO_ZZXW(sve2_sqdmlal_idx_d, int64_t, int32_t, , H1_4, DO_SQDMLAL_D)
94
DO_ZZXW(sve2_sqdmlsl_idx_s, int32_t, int16_t, H1_4, H1_2, DO_SQDMLSL_S)
95
DO_ZZXW(sve2_sqdmlsl_idx_d, int64_t, int32_t, , H1_4, DO_SQDMLSL_D)
96
97
+#undef DO_MLA
98
+#undef DO_MLS
99
#undef DO_ZZXW
100
101
#define DO_ZZX(NAME, TYPEW, TYPEN, HW, HN, OP) \
102
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/translate-sve.c
105
+++ b/target/arm/translate-sve.c
106
@@ -XXX,XX +XXX,XX @@ DO_SVE2_RRXR_TB(trans_SQDMLSLB_zzxw_d, gen_helper_sve2_sqdmlsl_idx_d, false)
107
DO_SVE2_RRXR_TB(trans_SQDMLSLT_zzxw_s, gen_helper_sve2_sqdmlsl_idx_s, true)
108
DO_SVE2_RRXR_TB(trans_SQDMLSLT_zzxw_d, gen_helper_sve2_sqdmlsl_idx_d, true)
109
110
+DO_SVE2_RRXR_TB(trans_SMLALB_zzxw_s, gen_helper_sve2_smlal_idx_s, false)
111
+DO_SVE2_RRXR_TB(trans_SMLALB_zzxw_d, gen_helper_sve2_smlal_idx_d, false)
112
+DO_SVE2_RRXR_TB(trans_SMLALT_zzxw_s, gen_helper_sve2_smlal_idx_s, true)
113
+DO_SVE2_RRXR_TB(trans_SMLALT_zzxw_d, gen_helper_sve2_smlal_idx_d, true)
114
+
115
+DO_SVE2_RRXR_TB(trans_UMLALB_zzxw_s, gen_helper_sve2_umlal_idx_s, false)
116
+DO_SVE2_RRXR_TB(trans_UMLALB_zzxw_d, gen_helper_sve2_umlal_idx_d, false)
117
+DO_SVE2_RRXR_TB(trans_UMLALT_zzxw_s, gen_helper_sve2_umlal_idx_s, true)
118
+DO_SVE2_RRXR_TB(trans_UMLALT_zzxw_d, gen_helper_sve2_umlal_idx_d, true)
119
+
120
+DO_SVE2_RRXR_TB(trans_SMLSLB_zzxw_s, gen_helper_sve2_smlsl_idx_s, false)
121
+DO_SVE2_RRXR_TB(trans_SMLSLB_zzxw_d, gen_helper_sve2_smlsl_idx_d, false)
122
+DO_SVE2_RRXR_TB(trans_SMLSLT_zzxw_s, gen_helper_sve2_smlsl_idx_s, true)
123
+DO_SVE2_RRXR_TB(trans_SMLSLT_zzxw_d, gen_helper_sve2_smlsl_idx_d, true)
124
+
125
+DO_SVE2_RRXR_TB(trans_UMLSLB_zzxw_s, gen_helper_sve2_umlsl_idx_s, false)
126
+DO_SVE2_RRXR_TB(trans_UMLSLB_zzxw_d, gen_helper_sve2_umlsl_idx_d, false)
127
+DO_SVE2_RRXR_TB(trans_UMLSLT_zzxw_s, gen_helper_sve2_umlsl_idx_s, true)
128
+DO_SVE2_RRXR_TB(trans_UMLSLT_zzxw_d, gen_helper_sve2_umlsl_idx_d, true)
129
+
130
#undef DO_SVE2_RRXR_TB
131
132
/*
133
--
48
--
134
2.20.1
49
2.34.1
135
50
136
51
diff view generated by jsdifflib
1
From: Rebecca Cran <rebecca@nuviainc.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
ARMv8.4 adds the mandatory FEAT_TLBIOS. It provides TLBI
3
NPCM7XX models have been commited after the conversion from
4
maintenance instructions that extend to the Outer Shareable domain.
4
commit 8063396bf3 ("Use OBJECT_DECLARE_SIMPLE_TYPE when possible").
5
5
Manually convert them.
6
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210512182337.18563-3-rebecca@nuviainc.com
9
Message-id: 20230109140306.23161-11-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/cpu.h | 5 +++++
12
include/hw/adc/npcm7xx_adc.h | 7 +++----
12
target/arm/helper.c | 43 +++++++++++++++++++++++++++++++++++++++++++
13
include/hw/arm/npcm7xx.h | 18 ++++++------------
13
2 files changed, 48 insertions(+)
14
include/hw/i2c/npcm7xx_smbus.h | 7 +++----
14
15
include/hw/misc/npcm7xx_clk.h | 2 +-
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
include/hw/misc/npcm7xx_gcr.h | 6 +++---
16
index XXXXXXX..XXXXXXX 100644
17
include/hw/misc/npcm7xx_mft.h | 7 +++----
17
--- a/target/arm/cpu.h
18
include/hw/misc/npcm7xx_pwm.h | 3 +--
18
+++ b/target/arm/cpu.h
19
include/hw/misc/npcm7xx_rng.h | 6 +++---
19
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_tlbirange(const ARMISARegisters *id)
20
include/hw/net/npcm7xx_emc.h | 5 +----
20
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) == 2;
21
include/hw/sd/npcm7xx_sdhci.h | 4 ++--
21
}
22
10 files changed, 26 insertions(+), 39 deletions(-)
22
23
23
+static inline bool isar_feature_aa64_tlbios(const ARMISARegisters *id)
24
diff --git a/include/hw/adc/npcm7xx_adc.h b/include/hw/adc/npcm7xx_adc.h
24
+{
25
index XXXXXXX..XXXXXXX 100644
25
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) != 0;
26
--- a/include/hw/adc/npcm7xx_adc.h
26
+}
27
+++ b/include/hw/adc/npcm7xx_adc.h
27
+
28
@@ -XXX,XX +XXX,XX @@
28
static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
29
* @iref: The internal reference voltage, initialized at launch time.
29
{
30
* @rv: The calibrated output values of 0.5V and 1.5V for the ADC.
30
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
31
*/
31
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
-typedef struct {
32
index XXXXXXX..XXXXXXX 100644
33
+struct NPCM7xxADCState {
33
--- a/target/arm/helper.c
34
SysBusDevice parent;
34
+++ b/target/arm/helper.c
35
35
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo tlbirange_reginfo[] = {
36
MemoryRegion iomem;
36
REGINFO_SENTINEL
37
@@ -XXX,XX +XXX,XX @@ typedef struct {
38
uint32_t iref;
39
40
uint16_t calibration_r_values[NPCM7XX_ADC_NUM_CALIB];
41
-} NPCM7xxADCState;
42
+};
43
44
#define TYPE_NPCM7XX_ADC "npcm7xx-adc"
45
-#define NPCM7XX_ADC(obj) \
46
- OBJECT_CHECK(NPCM7xxADCState, (obj), TYPE_NPCM7XX_ADC)
47
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxADCState, NPCM7XX_ADC)
48
49
#endif /* NPCM7XX_ADC_H */
50
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/include/hw/arm/npcm7xx.h
53
+++ b/include/hw/arm/npcm7xx.h
54
@@ -XXX,XX +XXX,XX @@
55
56
#define NPCM7XX_NR_PWM_MODULES 2
57
58
-typedef struct NPCM7xxMachine {
59
+struct NPCM7xxMachine {
60
MachineState parent;
61
/*
62
* PWM fan splitter. each splitter connects to one PWM output and
63
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxMachine {
64
*/
65
SplitIRQ fan_splitter[NPCM7XX_NR_PWM_MODULES *
66
NPCM7XX_PWM_PER_MODULE];
67
-} NPCM7xxMachine;
68
+};
69
70
#define TYPE_NPCM7XX_MACHINE MACHINE_TYPE_NAME("npcm7xx")
71
-#define NPCM7XX_MACHINE(obj) \
72
- OBJECT_CHECK(NPCM7xxMachine, (obj), TYPE_NPCM7XX_MACHINE)
73
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxMachine, NPCM7XX_MACHINE)
74
75
typedef struct NPCM7xxMachineClass {
76
MachineClass parent;
77
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxMachineClass {
78
#define NPCM7XX_MACHINE_GET_CLASS(obj) \
79
OBJECT_GET_CLASS(NPCM7xxMachineClass, (obj), TYPE_NPCM7XX_MACHINE)
80
81
-typedef struct NPCM7xxState {
82
+struct NPCM7xxState {
83
DeviceState parent;
84
85
ARMCPU cpu[NPCM7XX_MAX_NUM_CPUS];
86
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxState {
87
NPCM7xxFIUState fiu[2];
88
NPCM7xxEMCState emc[2];
89
NPCM7xxSDHCIState mmc;
90
-} NPCM7xxState;
91
+};
92
93
#define TYPE_NPCM7XX "npcm7xx"
94
-#define NPCM7XX(obj) OBJECT_CHECK(NPCM7xxState, (obj), TYPE_NPCM7XX)
95
+OBJECT_DECLARE_TYPE(NPCM7xxState, NPCM7xxClass, NPCM7XX)
96
97
#define TYPE_NPCM730 "npcm730"
98
#define TYPE_NPCM750 "npcm750"
99
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxClass {
100
uint32_t num_cpus;
101
} NPCM7xxClass;
102
103
-#define NPCM7XX_CLASS(klass) \
104
- OBJECT_CLASS_CHECK(NPCM7xxClass, (klass), TYPE_NPCM7XX)
105
-#define NPCM7XX_GET_CLASS(obj) \
106
- OBJECT_GET_CLASS(NPCM7xxClass, (obj), TYPE_NPCM7XX)
107
-
108
/**
109
* npcm7xx_load_kernel - Loads memory with everything needed to boot
110
* @machine - The machine containing the SoC to be booted.
111
diff --git a/include/hw/i2c/npcm7xx_smbus.h b/include/hw/i2c/npcm7xx_smbus.h
112
index XXXXXXX..XXXXXXX 100644
113
--- a/include/hw/i2c/npcm7xx_smbus.h
114
+++ b/include/hw/i2c/npcm7xx_smbus.h
115
@@ -XXX,XX +XXX,XX @@ typedef enum NPCM7xxSMBusStatus {
116
* @rx_cur: The current position of rx_fifo.
117
* @status: The current status of the SMBus.
118
*/
119
-typedef struct NPCM7xxSMBusState {
120
+struct NPCM7xxSMBusState {
121
SysBusDevice parent;
122
123
MemoryRegion iomem;
124
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxSMBusState {
125
uint8_t rx_cur;
126
127
NPCM7xxSMBusStatus status;
128
-} NPCM7xxSMBusState;
129
+};
130
131
#define TYPE_NPCM7XX_SMBUS "npcm7xx-smbus"
132
-#define NPCM7XX_SMBUS(obj) OBJECT_CHECK(NPCM7xxSMBusState, (obj), \
133
- TYPE_NPCM7XX_SMBUS)
134
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxSMBusState, NPCM7XX_SMBUS)
135
136
#endif /* NPCM7XX_SMBUS_H */
137
diff --git a/include/hw/misc/npcm7xx_clk.h b/include/hw/misc/npcm7xx_clk.h
138
index XXXXXXX..XXXXXXX 100644
139
--- a/include/hw/misc/npcm7xx_clk.h
140
+++ b/include/hw/misc/npcm7xx_clk.h
141
@@ -XXX,XX +XXX,XX @@ struct NPCM7xxCLKState {
37
};
142
};
38
143
39
+static const ARMCPRegInfo tlbios_reginfo[] = {
144
#define TYPE_NPCM7XX_CLK "npcm7xx-clk"
40
+ { .name = "TLBI_VMALLE1OS", .state = ARM_CP_STATE_AA64,
145
-#define NPCM7XX_CLK(obj) OBJECT_CHECK(NPCM7xxCLKState, (obj), TYPE_NPCM7XX_CLK)
41
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 0,
146
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxCLKState, NPCM7XX_CLK)
42
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
147
43
+ .writefn = tlbi_aa64_vmalle1is_write },
148
#endif /* NPCM7XX_CLK_H */
44
+ { .name = "TLBI_ASIDE1OS", .state = ARM_CP_STATE_AA64,
149
diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
45
+ .opc0 = 1, .opc1 = 0, .crn = 8, .crm = 1, .opc2 = 2,
150
index XXXXXXX..XXXXXXX 100644
46
+ .access = PL1_W, .type = ARM_CP_NO_RAW,
151
--- a/include/hw/misc/npcm7xx_gcr.h
47
+ .writefn = tlbi_aa64_vmalle1is_write },
152
+++ b/include/hw/misc/npcm7xx_gcr.h
48
+ { .name = "TLBI_ALLE2OS", .state = ARM_CP_STATE_AA64,
153
@@ -XXX,XX +XXX,XX @@
49
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 0,
154
*/
50
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
155
#define NPCM7XX_GCR_NR_REGS (0x148 / sizeof(uint32_t))
51
+ .writefn = tlbi_aa64_alle2is_write },
156
52
+ { .name = "TLBI_ALLE1OS", .state = ARM_CP_STATE_AA64,
157
-typedef struct NPCM7xxGCRState {
53
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 4,
158
+struct NPCM7xxGCRState {
54
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
159
SysBusDevice parent;
55
+ .writefn = tlbi_aa64_alle1is_write },
160
56
+ { .name = "TLBI_VMALLS12E1OS", .state = ARM_CP_STATE_AA64,
161
MemoryRegion iomem;
57
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 1, .opc2 = 6,
162
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxGCRState {
58
+ .access = PL2_W, .type = ARM_CP_NO_RAW,
163
uint32_t reset_pwron;
59
+ .writefn = tlbi_aa64_alle1is_write },
164
uint32_t reset_mdlr;
60
+ { .name = "TLBI_IPAS2E1OS", .state = ARM_CP_STATE_AA64,
165
uint32_t reset_intcr3;
61
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 0,
166
-} NPCM7xxGCRState;
62
+ .access = PL2_W, .type = ARM_CP_NOP },
167
+};
63
+ { .name = "TLBI_RIPAS2E1OS", .state = ARM_CP_STATE_AA64,
168
64
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 3,
169
#define TYPE_NPCM7XX_GCR "npcm7xx-gcr"
65
+ .access = PL2_W, .type = ARM_CP_NOP },
170
-#define NPCM7XX_GCR(obj) OBJECT_CHECK(NPCM7xxGCRState, (obj), TYPE_NPCM7XX_GCR)
66
+ { .name = "TLBI_IPAS2LE1OS", .state = ARM_CP_STATE_AA64,
171
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxGCRState, NPCM7XX_GCR)
67
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 4,
172
68
+ .access = PL2_W, .type = ARM_CP_NOP },
173
#endif /* NPCM7XX_GCR_H */
69
+ { .name = "TLBI_RIPAS2LE1OS", .state = ARM_CP_STATE_AA64,
174
diff --git a/include/hw/misc/npcm7xx_mft.h b/include/hw/misc/npcm7xx_mft.h
70
+ .opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 7,
175
index XXXXXXX..XXXXXXX 100644
71
+ .access = PL2_W, .type = ARM_CP_NOP },
176
--- a/include/hw/misc/npcm7xx_mft.h
72
+ { .name = "TLBI_ALLE3OS", .state = ARM_CP_STATE_AA64,
177
+++ b/include/hw/misc/npcm7xx_mft.h
73
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 0,
178
@@ -XXX,XX +XXX,XX @@
74
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
179
* @max_rpm: The maximum rpm for fans. Order: A0, B0, A1, B1.
75
+ .writefn = tlbi_aa64_alle3is_write },
180
* @duty: The duty cycles for fans, relative to NPCM7XX_PWM_MAX_DUTY.
76
+ REGINFO_SENTINEL
181
*/
77
+};
182
-typedef struct NPCM7xxMFTState {
78
+
183
+struct NPCM7xxMFTState {
79
static uint64_t rndr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
184
SysBusDevice parent;
80
{
185
81
Error *err = NULL;
186
MemoryRegion iomem;
82
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
187
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxMFTState {
83
if (cpu_isar_feature(aa64_tlbirange, cpu)) {
188
84
define_arm_cp_regs(cpu, tlbirange_reginfo);
189
uint32_t max_rpm[NPCM7XX_MFT_FANIN_COUNT];
85
}
190
uint32_t duty[NPCM7XX_MFT_FANIN_COUNT];
86
+ if (cpu_isar_feature(aa64_tlbios, cpu)) {
191
-} NPCM7xxMFTState;
87
+ define_arm_cp_regs(cpu, tlbios_reginfo);
192
+};
88
+ }
193
89
#ifndef CONFIG_USER_ONLY
194
#define TYPE_NPCM7XX_MFT "npcm7xx-mft"
90
/* Data Cache clean instructions up to PoP */
195
-#define NPCM7XX_MFT(obj) \
91
if (cpu_isar_feature(aa64_dcpop, cpu)) {
196
- OBJECT_CHECK(NPCM7xxMFTState, (obj), TYPE_NPCM7XX_MFT)
197
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxMFTState, NPCM7XX_MFT)
198
199
#endif /* NPCM7XX_MFT_H */
200
diff --git a/include/hw/misc/npcm7xx_pwm.h b/include/hw/misc/npcm7xx_pwm.h
201
index XXXXXXX..XXXXXXX 100644
202
--- a/include/hw/misc/npcm7xx_pwm.h
203
+++ b/include/hw/misc/npcm7xx_pwm.h
204
@@ -XXX,XX +XXX,XX @@ struct NPCM7xxPWMState {
205
};
206
207
#define TYPE_NPCM7XX_PWM "npcm7xx-pwm"
208
-#define NPCM7XX_PWM(obj) \
209
- OBJECT_CHECK(NPCM7xxPWMState, (obj), TYPE_NPCM7XX_PWM)
210
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxPWMState, NPCM7XX_PWM)
211
212
#endif /* NPCM7XX_PWM_H */
213
diff --git a/include/hw/misc/npcm7xx_rng.h b/include/hw/misc/npcm7xx_rng.h
214
index XXXXXXX..XXXXXXX 100644
215
--- a/include/hw/misc/npcm7xx_rng.h
216
+++ b/include/hw/misc/npcm7xx_rng.h
217
@@ -XXX,XX +XXX,XX @@
218
219
#include "hw/sysbus.h"
220
221
-typedef struct NPCM7xxRNGState {
222
+struct NPCM7xxRNGState {
223
SysBusDevice parent;
224
225
MemoryRegion iomem;
226
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxRNGState {
227
uint8_t rngcs;
228
uint8_t rngd;
229
uint8_t rngmode;
230
-} NPCM7xxRNGState;
231
+};
232
233
#define TYPE_NPCM7XX_RNG "npcm7xx-rng"
234
-#define NPCM7XX_RNG(obj) OBJECT_CHECK(NPCM7xxRNGState, (obj), TYPE_NPCM7XX_RNG)
235
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxRNGState, NPCM7XX_RNG)
236
237
#endif /* NPCM7XX_RNG_H */
238
diff --git a/include/hw/net/npcm7xx_emc.h b/include/hw/net/npcm7xx_emc.h
239
index XXXXXXX..XXXXXXX 100644
240
--- a/include/hw/net/npcm7xx_emc.h
241
+++ b/include/hw/net/npcm7xx_emc.h
242
@@ -XXX,XX +XXX,XX @@ struct NPCM7xxEMCState {
243
bool rx_active;
244
};
245
246
-typedef struct NPCM7xxEMCState NPCM7xxEMCState;
247
-
248
#define TYPE_NPCM7XX_EMC "npcm7xx-emc"
249
-#define NPCM7XX_EMC(obj) \
250
- OBJECT_CHECK(NPCM7xxEMCState, (obj), TYPE_NPCM7XX_EMC)
251
+OBJECT_DECLARE_SIMPLE_TYPE(NPCM7xxEMCState, NPCM7XX_EMC)
252
253
#endif /* NPCM7XX_EMC_H */
254
diff --git a/include/hw/sd/npcm7xx_sdhci.h b/include/hw/sd/npcm7xx_sdhci.h
255
index XXXXXXX..XXXXXXX 100644
256
--- a/include/hw/sd/npcm7xx_sdhci.h
257
+++ b/include/hw/sd/npcm7xx_sdhci.h
258
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxRegs {
259
uint32_t boottoctrl;
260
} NPCM7xxRegisters;
261
262
-typedef struct NPCM7xxSDHCIState {
263
+struct NPCM7xxSDHCIState {
264
SysBusDevice parent;
265
266
MemoryRegion container;
267
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxSDHCIState {
268
NPCM7xxRegisters regs;
269
270
SDHCIState sdhci;
271
-} NPCM7xxSDHCIState;
272
+};
273
274
#endif /* NPCM7XX_SDHCI_H */
92
--
275
--
93
2.20.1
276
2.34.1
94
277
95
278
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
For SVE, we potentially have a 4th argument coming from the
3
The structure is named SECUREECState. Rename the type accordingly.
4
movprfx instruction. Currently we do not optimize movprfx,
5
so the problem is not visible.
6
4
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210525010358.152808-51-richard.henderson@linaro.org
7
Message-id: 20230109140306.23161-12-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
target/arm/helper.h | 20 +++++++--------
10
hw/misc/sbsa_ec.c | 13 +++++++------
13
target/arm/translate-a64.c | 28 +++++++++++++++++----
11
1 file changed, 7 insertions(+), 6 deletions(-)
14
target/arm/translate-neon.c | 10 +++++---
15
target/arm/translate-sve.c | 5 ++--
16
target/arm/vec_helper.c | 50 +++++++++++++++----------------------
17
5 files changed, 62 insertions(+), 51 deletions(-)
18
12
19
diff --git a/target/arm/helper.h b/target/arm/helper.h
13
diff --git a/hw/misc/sbsa_ec.c b/hw/misc/sbsa_ec.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.h
15
--- a/hw/misc/sbsa_ec.c
22
+++ b/target/arm/helper.h
16
+++ b/hw/misc/sbsa_ec.c
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_fcadds, TCG_CALL_NO_RWG,
17
@@ -XXX,XX +XXX,XX @@
24
DEF_HELPER_FLAGS_5(gvec_fcaddd, TCG_CALL_NO_RWG,
18
#include "hw/sysbus.h"
25
void, ptr, ptr, ptr, ptr, i32)
19
#include "sysemu/runstate.h"
26
20
27
-DEF_HELPER_FLAGS_5(gvec_fcmlah, TCG_CALL_NO_RWG,
21
-typedef struct {
28
- void, ptr, ptr, ptr, ptr, i32)
22
+typedef struct SECUREECState {
29
-DEF_HELPER_FLAGS_5(gvec_fcmlah_idx, TCG_CALL_NO_RWG,
23
SysBusDevice parent_obj;
30
- void, ptr, ptr, ptr, ptr, i32)
24
MemoryRegion iomem;
31
-DEF_HELPER_FLAGS_5(gvec_fcmlas, TCG_CALL_NO_RWG,
25
} SECUREECState;
32
- void, ptr, ptr, ptr, ptr, i32)
26
33
-DEF_HELPER_FLAGS_5(gvec_fcmlas_idx, TCG_CALL_NO_RWG,
27
-#define TYPE_SBSA_EC "sbsa-ec"
34
- void, ptr, ptr, ptr, ptr, i32)
28
-#define SECURE_EC(obj) OBJECT_CHECK(SECUREECState, (obj), TYPE_SBSA_EC)
35
-DEF_HELPER_FLAGS_5(gvec_fcmlad, TCG_CALL_NO_RWG,
29
+#define TYPE_SBSA_SECURE_EC "sbsa-ec"
36
- void, ptr, ptr, ptr, ptr, i32)
30
+#define SBSA_SECURE_EC(obj) \
37
+DEF_HELPER_FLAGS_6(gvec_fcmlah, TCG_CALL_NO_RWG,
31
+ OBJECT_CHECK(SECUREECState, (obj), TYPE_SBSA_SECURE_EC)
38
+ void, ptr, ptr, ptr, ptr, ptr, i32)
32
39
+DEF_HELPER_FLAGS_6(gvec_fcmlah_idx, TCG_CALL_NO_RWG,
33
enum sbsa_ec_powerstates {
40
+ void, ptr, ptr, ptr, ptr, ptr, i32)
34
SBSA_EC_CMD_POWEROFF = 0x01,
41
+DEF_HELPER_FLAGS_6(gvec_fcmlas, TCG_CALL_NO_RWG,
35
@@ -XXX,XX +XXX,XX @@ static uint64_t sbsa_ec_read(void *opaque, hwaddr offset, unsigned size)
42
+ void, ptr, ptr, ptr, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_6(gvec_fcmlas_idx, TCG_CALL_NO_RWG,
44
+ void, ptr, ptr, ptr, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_6(gvec_fcmlad, TCG_CALL_NO_RWG,
46
+ void, ptr, ptr, ptr, ptr, ptr, i32)
47
48
DEF_HELPER_FLAGS_5(neon_paddh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
49
DEF_HELPER_FLAGS_5(neon_pmaxh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
50
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/translate-a64.c
53
+++ b/target/arm/translate-a64.c
54
@@ -XXX,XX +XXX,XX @@ static void gen_gvec_op4_ool(DisasContext *s, bool is_q, int rd, int rn,
55
is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
56
}
36
}
57
37
58
+/*
38
static void sbsa_ec_write(void *opaque, hwaddr offset,
59
+ * Expand a 4-operand + fpstatus pointer + simd data value operation using
39
- uint64_t value, unsigned size)
60
+ * an out-of-line helper.
40
+ uint64_t value, unsigned size)
61
+ */
62
+static void gen_gvec_op4_fpst(DisasContext *s, bool is_q, int rd, int rn,
63
+ int rm, int ra, bool is_fp16, int data,
64
+ gen_helper_gvec_4_ptr *fn)
65
+{
66
+ TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR);
67
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, rd),
68
+ vec_full_reg_offset(s, rn),
69
+ vec_full_reg_offset(s, rm),
70
+ vec_full_reg_offset(s, ra), fpst,
71
+ is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
72
+ tcg_temp_free_ptr(fpst);
73
+}
74
+
75
/* Set ZF and NF based on a 64 bit result. This is alas fiddlier
76
* than the 32 bit equivalent.
77
*/
78
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
79
rot = extract32(opcode, 0, 2);
80
switch (size) {
81
case 1:
82
- gen_gvec_op3_fpst(s, is_q, rd, rn, rm, true, rot,
83
+ gen_gvec_op4_fpst(s, is_q, rd, rn, rm, rd, true, rot,
84
gen_helper_gvec_fcmlah);
85
break;
86
case 2:
87
- gen_gvec_op3_fpst(s, is_q, rd, rn, rm, false, rot,
88
+ gen_gvec_op4_fpst(s, is_q, rd, rn, rm, rd, false, rot,
89
gen_helper_gvec_fcmlas);
90
break;
91
case 3:
92
- gen_gvec_op3_fpst(s, is_q, rd, rn, rm, false, rot,
93
+ gen_gvec_op4_fpst(s, is_q, rd, rn, rm, rd, false, rot,
94
gen_helper_gvec_fcmlad);
95
break;
96
default:
97
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
98
{
99
int rot = extract32(insn, 13, 2);
100
int data = (index << 2) | rot;
101
- tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
102
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, rd),
103
vec_full_reg_offset(s, rn),
104
- vec_full_reg_offset(s, rm), fpst,
105
+ vec_full_reg_offset(s, rm),
106
+ vec_full_reg_offset(s, rd), fpst,
107
is_q ? 16 : 8, vec_full_reg_size(s), data,
108
size == MO_64
109
? gen_helper_gvec_fcmlas_idx
110
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/target/arm/translate-neon.c
113
+++ b/target/arm/translate-neon.c
114
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
115
{
41
{
116
int opr_sz;
42
if (offset == 0) { /* PSCI machine power command register */
117
TCGv_ptr fpst;
43
switch (value) {
118
- gen_helper_gvec_3_ptr *fn_gvec_ptr;
44
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps sbsa_ec_ops = {
119
+ gen_helper_gvec_4_ptr *fn_gvec_ptr;
45
120
46
static void sbsa_ec_init(Object *obj)
121
if (!dc_isar_feature(aa32_vcma, s)
122
|| (a->size == MO_16 && !dc_isar_feature(aa32_fp16_arith, s))) {
123
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
124
fpst = fpstatus_ptr(a->size == MO_16 ? FPST_STD_F16 : FPST_STD);
125
fn_gvec_ptr = (a->size == MO_16) ?
126
gen_helper_gvec_fcmlah : gen_helper_gvec_fcmlas;
127
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
128
+ tcg_gen_gvec_4_ptr(vfp_reg_offset(1, a->vd),
129
vfp_reg_offset(1, a->vn),
130
vfp_reg_offset(1, a->vm),
131
+ vfp_reg_offset(1, a->vd),
132
fpst, opr_sz, opr_sz, a->rot,
133
fn_gvec_ptr);
134
tcg_temp_free_ptr(fpst);
135
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML(DisasContext *s, arg_VFML *a)
136
137
static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
138
{
47
{
139
- gen_helper_gvec_3_ptr *fn_gvec_ptr;
48
- SECUREECState *s = SECURE_EC(obj);
140
+ gen_helper_gvec_4_ptr *fn_gvec_ptr;
49
+ SECUREECState *s = SBSA_SECURE_EC(obj);
141
int opr_sz;
50
SysBusDevice *dev = SYS_BUS_DEVICE(obj);
142
TCGv_ptr fpst;
51
143
52
memory_region_init_io(&s->iomem, obj, &sbsa_ec_ops, s, "sbsa-ec",
144
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
53
@@ -XXX,XX +XXX,XX @@ static void sbsa_ec_class_init(ObjectClass *klass, void *data)
145
gen_helper_gvec_fcmlah_idx : gen_helper_gvec_fcmlas_idx;
146
opr_sz = (1 + a->q) * 8;
147
fpst = fpstatus_ptr(a->size == MO_16 ? FPST_STD_F16 : FPST_STD);
148
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
149
+ tcg_gen_gvec_4_ptr(vfp_reg_offset(1, a->vd),
150
vfp_reg_offset(1, a->vn),
151
vfp_reg_offset(1, a->vm),
152
+ vfp_reg_offset(1, a->vd),
153
fpst, opr_sz, opr_sz,
154
(a->index << 2) | a->rot, fn_gvec_ptr);
155
tcg_temp_free_ptr(fpst);
156
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
157
index XXXXXXX..XXXXXXX 100644
158
--- a/target/arm/translate-sve.c
159
+++ b/target/arm/translate-sve.c
160
@@ -XXX,XX +XXX,XX @@ static bool trans_FCMLA_zpzzz(DisasContext *s, arg_FCMLA_zpzzz *a)
161
162
static bool trans_FCMLA_zzxz(DisasContext *s, arg_FCMLA_zzxz *a)
163
{
164
- static gen_helper_gvec_3_ptr * const fns[2] = {
165
+ static gen_helper_gvec_4_ptr * const fns[2] = {
166
gen_helper_gvec_fcmlah_idx,
167
gen_helper_gvec_fcmlas_idx,
168
};
169
@@ -XXX,XX +XXX,XX @@ static bool trans_FCMLA_zzxz(DisasContext *s, arg_FCMLA_zzxz *a)
170
if (sve_access_check(s)) {
171
unsigned vsz = vec_full_reg_size(s);
172
TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
173
- tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
174
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
175
vec_full_reg_offset(s, a->rn),
176
vec_full_reg_offset(s, a->rm),
177
+ vec_full_reg_offset(s, a->ra),
178
status, vsz, vsz,
179
a->index * 4 + a->rot,
180
fns[a->esz - 1]);
181
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/target/arm/vec_helper.c
184
+++ b/target/arm/vec_helper.c
185
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcaddd)(void *vd, void *vn, void *vm,
186
clear_tail(d, opr_sz, simd_maxsz(desc));
187
}
54
}
188
55
189
-void HELPER(gvec_fcmlah)(void *vd, void *vn, void *vm,
56
static const TypeInfo sbsa_ec_info = {
190
+void HELPER(gvec_fcmlah)(void *vd, void *vn, void *vm, void *va,
57
- .name = TYPE_SBSA_EC,
191
void *vfpst, uint32_t desc)
58
+ .name = TYPE_SBSA_SECURE_EC,
192
{
59
.parent = TYPE_SYS_BUS_DEVICE,
193
uintptr_t opr_sz = simd_oprsz(desc);
60
.instance_size = sizeof(SECUREECState),
194
- float16 *d = vd;
61
.instance_init = sbsa_ec_init,
195
- float16 *n = vn;
196
- float16 *m = vm;
197
+ float16 *d = vd, *n = vn, *m = vm, *a = va;
198
float_status *fpst = vfpst;
199
intptr_t flip = extract32(desc, SIMD_DATA_SHIFT, 1);
200
uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
201
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlah)(void *vd, void *vn, void *vm,
202
float16 e4 = e2;
203
float16 e3 = m[H2(i + 1 - flip)] ^ neg_imag;
204
205
- d[H2(i)] = float16_muladd(e2, e1, d[H2(i)], 0, fpst);
206
- d[H2(i + 1)] = float16_muladd(e4, e3, d[H2(i + 1)], 0, fpst);
207
+ d[H2(i)] = float16_muladd(e2, e1, a[H2(i)], 0, fpst);
208
+ d[H2(i + 1)] = float16_muladd(e4, e3, a[H2(i + 1)], 0, fpst);
209
}
210
clear_tail(d, opr_sz, simd_maxsz(desc));
211
}
212
213
-void HELPER(gvec_fcmlah_idx)(void *vd, void *vn, void *vm,
214
+void HELPER(gvec_fcmlah_idx)(void *vd, void *vn, void *vm, void *va,
215
void *vfpst, uint32_t desc)
216
{
217
uintptr_t opr_sz = simd_oprsz(desc);
218
- float16 *d = vd;
219
- float16 *n = vn;
220
- float16 *m = vm;
221
+ float16 *d = vd, *n = vn, *m = vm, *a = va;
222
float_status *fpst = vfpst;
223
intptr_t flip = extract32(desc, SIMD_DATA_SHIFT, 1);
224
uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
225
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlah_idx)(void *vd, void *vn, void *vm,
226
float16 e2 = n[H2(j + flip)];
227
float16 e4 = e2;
228
229
- d[H2(j)] = float16_muladd(e2, e1, d[H2(j)], 0, fpst);
230
- d[H2(j + 1)] = float16_muladd(e4, e3, d[H2(j + 1)], 0, fpst);
231
+ d[H2(j)] = float16_muladd(e2, e1, a[H2(j)], 0, fpst);
232
+ d[H2(j + 1)] = float16_muladd(e4, e3, a[H2(j + 1)], 0, fpst);
233
}
234
}
235
clear_tail(d, opr_sz, simd_maxsz(desc));
236
}
237
238
-void HELPER(gvec_fcmlas)(void *vd, void *vn, void *vm,
239
+void HELPER(gvec_fcmlas)(void *vd, void *vn, void *vm, void *va,
240
void *vfpst, uint32_t desc)
241
{
242
uintptr_t opr_sz = simd_oprsz(desc);
243
- float32 *d = vd;
244
- float32 *n = vn;
245
- float32 *m = vm;
246
+ float32 *d = vd, *n = vn, *m = vm, *a = va;
247
float_status *fpst = vfpst;
248
intptr_t flip = extract32(desc, SIMD_DATA_SHIFT, 1);
249
uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
250
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlas)(void *vd, void *vn, void *vm,
251
float32 e4 = e2;
252
float32 e3 = m[H4(i + 1 - flip)] ^ neg_imag;
253
254
- d[H4(i)] = float32_muladd(e2, e1, d[H4(i)], 0, fpst);
255
- d[H4(i + 1)] = float32_muladd(e4, e3, d[H4(i + 1)], 0, fpst);
256
+ d[H4(i)] = float32_muladd(e2, e1, a[H4(i)], 0, fpst);
257
+ d[H4(i + 1)] = float32_muladd(e4, e3, a[H4(i + 1)], 0, fpst);
258
}
259
clear_tail(d, opr_sz, simd_maxsz(desc));
260
}
261
262
-void HELPER(gvec_fcmlas_idx)(void *vd, void *vn, void *vm,
263
+void HELPER(gvec_fcmlas_idx)(void *vd, void *vn, void *vm, void *va,
264
void *vfpst, uint32_t desc)
265
{
266
uintptr_t opr_sz = simd_oprsz(desc);
267
- float32 *d = vd;
268
- float32 *n = vn;
269
- float32 *m = vm;
270
+ float32 *d = vd, *n = vn, *m = vm, *a = va;
271
float_status *fpst = vfpst;
272
intptr_t flip = extract32(desc, SIMD_DATA_SHIFT, 1);
273
uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
274
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlas_idx)(void *vd, void *vn, void *vm,
275
float32 e2 = n[H4(j + flip)];
276
float32 e4 = e2;
277
278
- d[H4(j)] = float32_muladd(e2, e1, d[H4(j)], 0, fpst);
279
- d[H4(j + 1)] = float32_muladd(e4, e3, d[H4(j + 1)], 0, fpst);
280
+ d[H4(j)] = float32_muladd(e2, e1, a[H4(j)], 0, fpst);
281
+ d[H4(j + 1)] = float32_muladd(e4, e3, a[H4(j + 1)], 0, fpst);
282
}
283
}
284
clear_tail(d, opr_sz, simd_maxsz(desc));
285
}
286
287
-void HELPER(gvec_fcmlad)(void *vd, void *vn, void *vm,
288
+void HELPER(gvec_fcmlad)(void *vd, void *vn, void *vm, void *va,
289
void *vfpst, uint32_t desc)
290
{
291
uintptr_t opr_sz = simd_oprsz(desc);
292
- float64 *d = vd;
293
- float64 *n = vn;
294
- float64 *m = vm;
295
+ float64 *d = vd, *n = vn, *m = vm, *a = va;
296
float_status *fpst = vfpst;
297
intptr_t flip = extract32(desc, SIMD_DATA_SHIFT, 1);
298
uint64_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
299
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlad)(void *vd, void *vn, void *vm,
300
float64 e4 = e2;
301
float64 e3 = m[i + 1 - flip] ^ neg_imag;
302
303
- d[i] = float64_muladd(e2, e1, d[i], 0, fpst);
304
- d[i + 1] = float64_muladd(e4, e3, d[i + 1], 0, fpst);
305
+ d[i] = float64_muladd(e2, e1, a[i], 0, fpst);
306
+ d[i + 1] = float64_muladd(e4, e3, a[i + 1], 0, fpst);
307
}
308
clear_tail(d, opr_sz, simd_maxsz(desc));
309
}
310
--
62
--
311
2.20.1
63
2.34.1
312
64
313
65
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
This model was merged few days before the QOM cleanup from
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
commit 8063396bf3 ("Use OBJECT_DECLARE_SIMPLE_TYPE when possible")
5
Message-id: 20210525010358.152808-58-richard.henderson@linaro.org
5
was pulled and merged. Manually adapt.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230109140306.23161-13-philmd@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/helper-sve.h | 5 +++++
12
hw/misc/sbsa_ec.c | 3 +--
9
target/arm/sve.decode | 12 ++++++++++++
13
1 file changed, 1 insertion(+), 2 deletions(-)
10
target/arm/sve_helper.c | 20 ++++++++++++++++++++
11
target/arm/translate-sve.c | 14 ++++++++++++++
12
4 files changed, 51 insertions(+)
13
14
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
diff --git a/hw/misc/sbsa_ec.c b/hw/misc/sbsa_ec.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
--- a/hw/misc/sbsa_ec.c
17
+++ b/target/arm/helper-sve.h
18
+++ b/hw/misc/sbsa_ec.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_sqdmlsl_idx_s, TCG_CALL_NO_RWG,
19
@@ -XXX,XX +XXX,XX @@ typedef struct SECUREECState {
19
void, ptr, ptr, ptr, ptr, i32)
20
} SECUREECState;
20
DEF_HELPER_FLAGS_5(sve2_sqdmlsl_idx_d, TCG_CALL_NO_RWG,
21
21
void, ptr, ptr, ptr, ptr, i32)
22
#define TYPE_SBSA_SECURE_EC "sbsa-ec"
22
+
23
-#define SBSA_SECURE_EC(obj) \
23
+DEF_HELPER_FLAGS_4(sve2_sqdmull_idx_s, TCG_CALL_NO_RWG,
24
- OBJECT_CHECK(SECUREECState, (obj), TYPE_SBSA_SECURE_EC)
24
+ void, ptr, ptr, ptr, i32)
25
+OBJECT_DECLARE_SIMPLE_TYPE(SECUREECState, SBSA_SECURE_EC)
25
+DEF_HELPER_FLAGS_4(sve2_sqdmull_idx_d, TCG_CALL_NO_RWG,
26
26
+ void, ptr, ptr, ptr, i32)
27
enum sbsa_ec_powerstates {
27
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
28
SBSA_EC_CMD_POWEROFF = 0x01,
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/sve.decode
30
+++ b/target/arm/sve.decode
31
@@ -XXX,XX +XXX,XX @@
32
@rrx_2 ........ .. . index:2 rm:3 ...... rn:5 rd:5 &rrx_esz
33
@rrx_1 ........ .. . index:1 rm:4 ...... rn:5 rd:5 &rrx_esz
34
35
+# Two registers and a scalar by N-bit index, alternate
36
+@rrx_3a ........ .. . .. rm:3 ...... rn:5 rd:5 \
37
+ &rrx_esz index=%index3_19_11
38
+@rrx_2a ........ .. . . rm:4 ...... rn:5 rd:5 \
39
+ &rrx_esz index=%index2_20_11
40
+
41
# Three registers and a scalar by N-bit index
42
@rrxr_3 ........ .. . .. rm:3 ...... rn:5 rd:5 \
43
&rrxr_esz ra=%reg_movprfx index=%index3_22_19
44
@@ -XXX,XX +XXX,XX @@ SQDMLSLB_zzxw_d 01000100 11 1 ..... 0011.0 ..... ..... @rrxr_2a esz=3
45
SQDMLSLT_zzxw_s 01000100 10 1 ..... 0011.1 ..... ..... @rrxr_3a esz=2
46
SQDMLSLT_zzxw_d 01000100 11 1 ..... 0011.1 ..... ..... @rrxr_2a esz=3
47
48
+# SVE2 saturating multiply (indexed)
49
+SQDMULLB_zzx_s 01000100 10 1 ..... 1110.0 ..... ..... @rrx_3a esz=2
50
+SQDMULLB_zzx_d 01000100 11 1 ..... 1110.0 ..... ..... @rrx_2a esz=3
51
+SQDMULLT_zzx_s 01000100 10 1 ..... 1110.1 ..... ..... @rrx_3a esz=2
52
+SQDMULLT_zzx_d 01000100 11 1 ..... 1110.1 ..... ..... @rrx_2a esz=3
53
+
54
# SVE2 integer multiply (indexed)
55
MUL_zzx_h 01000100 0. 1 ..... 111110 ..... ..... @rrx_3 esz=1
56
MUL_zzx_s 01000100 10 1 ..... 111110 ..... ..... @rrx_2 esz=2
57
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/sve_helper.c
60
+++ b/target/arm/sve_helper.c
61
@@ -XXX,XX +XXX,XX @@ DO_ZZXW(sve2_sqdmlsl_idx_d, int64_t, int32_t, , H1_4, DO_SQDMLSL_D)
62
63
#undef DO_ZZXW
64
65
+#define DO_ZZX(NAME, TYPEW, TYPEN, HW, HN, OP) \
66
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
67
+{ \
68
+ intptr_t i, j, oprsz = simd_oprsz(desc); \
69
+ intptr_t sel = extract32(desc, SIMD_DATA_SHIFT, 1) * sizeof(TYPEN); \
70
+ intptr_t idx = extract32(desc, SIMD_DATA_SHIFT + 1, 3) * sizeof(TYPEN); \
71
+ for (i = 0; i < oprsz; i += 16) { \
72
+ TYPEW mm = *(TYPEN *)(vm + HN(i + idx)); \
73
+ for (j = 0; j < 16; j += sizeof(TYPEW)) { \
74
+ TYPEW nn = *(TYPEN *)(vn + HN(i + j + sel)); \
75
+ *(TYPEW *)(vd + HW(i + j)) = OP(nn, mm); \
76
+ } \
77
+ } \
78
+}
79
+
80
+DO_ZZX(sve2_sqdmull_idx_s, int32_t, int16_t, H1_4, H1_2, do_sqdmull_s)
81
+DO_ZZX(sve2_sqdmull_idx_d, int64_t, int32_t, , H1_4, do_sqdmull_d)
82
+
83
+#undef DO_ZZX
84
+
85
#define DO_BITPERM(NAME, TYPE, OP) \
86
void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
87
{ \
88
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/translate-sve.c
91
+++ b/target/arm/translate-sve.c
92
@@ -XXX,XX +XXX,XX @@ DO_SVE2_RRX(trans_MUL_zzx_d, gen_helper_gvec_mul_idx_d)
93
94
#undef DO_SVE2_RRX
95
96
+#define DO_SVE2_RRX_TB(NAME, FUNC, TOP) \
97
+ static bool NAME(DisasContext *s, arg_rrx_esz *a) \
98
+ { \
99
+ return do_sve2_zzz_data(s, a->rd, a->rn, a->rm, \
100
+ (a->index << 1) | TOP, FUNC); \
101
+ }
102
+
103
+DO_SVE2_RRX_TB(trans_SQDMULLB_zzx_s, gen_helper_sve2_sqdmull_idx_s, false)
104
+DO_SVE2_RRX_TB(trans_SQDMULLB_zzx_d, gen_helper_sve2_sqdmull_idx_d, false)
105
+DO_SVE2_RRX_TB(trans_SQDMULLT_zzx_s, gen_helper_sve2_sqdmull_idx_s, true)
106
+DO_SVE2_RRX_TB(trans_SQDMULLT_zzx_d, gen_helper_sve2_sqdmull_idx_d, true)
107
+
108
+#undef DO_SVE2_RRX_TB
109
+
110
static bool do_sve2_zzzz_data(DisasContext *s, int rd, int rn, int rm, int ra,
111
int data, gen_helper_gvec_4 *fn)
112
{
113
--
29
--
114
2.20.1
30
2.34.1
115
31
116
32
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Used by FMLA and DOT, but will shortly be used more.
3
This remove a use of 'struct' in the DECLARE_INSTANCE_CHECKER()
4
Split FMLA from FMLS to avoid an extra sub field;
4
macro call, to avoid after a QOM refactor:
5
similarly for SDOT from UDOT.
6
5
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
hw/intc/xilinx_intc.c:45:1: error: declaration of anonymous struct must be a definition
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
DECLARE_INSTANCE_CHECKER(struct xlx_pic, XILINX_INTC,
9
Message-id: 20210525010358.152808-53-richard.henderson@linaro.org
8
^
9
10
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Edgar E. Iglesias <edgar@zeroasic.com>
13
Message-id: 20230109140306.23161-14-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
15
---
12
target/arm/sve.decode | 29 +++++++++++++++++++----------
16
hw/intc/xilinx_intc.c | 28 +++++++++++++---------------
13
target/arm/translate-sve.c | 38 ++++++++++++++++++++++++++++----------
17
1 file changed, 13 insertions(+), 15 deletions(-)
14
2 files changed, 47 insertions(+), 20 deletions(-)
15
18
16
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
19
diff --git a/hw/intc/xilinx_intc.c b/hw/intc/xilinx_intc.c
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/sve.decode
21
--- a/hw/intc/xilinx_intc.c
19
+++ b/target/arm/sve.decode
22
+++ b/hw/intc/xilinx_intc.c
20
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
21
&rprr_s rd pg rn rm s
24
#define R_MAX 8
22
&rprr_esz rd pg rn rm esz
25
23
&rrrr_esz rd ra rn rm esz
26
#define TYPE_XILINX_INTC "xlnx.xps-intc"
24
+&rrxr_esz rd rn rm ra index esz
27
-DECLARE_INSTANCE_CHECKER(struct xlx_pic, XILINX_INTC,
25
&rprrr_esz rd pg rn rm ra esz
28
- TYPE_XILINX_INTC)
26
&rpri_esz rd pg rn imm esz
29
+typedef struct XpsIntc XpsIntc;
27
&ptrue rd esz pat s
30
+DECLARE_INSTANCE_CHECKER(XpsIntc, XILINX_INTC, TYPE_XILINX_INTC)
28
@@ -XXX,XX +XXX,XX @@
31
29
@rrx_2 ........ .. . index:2 rm:3 ...... rn:5 rd:5 &rrx_esz
32
-struct xlx_pic
30
@rrx_1 ........ .. . index:1 rm:4 ...... rn:5 rd:5 &rrx_esz
33
+struct XpsIntc
31
34
{
32
+# Three registers and a scalar by N-bit index
35
SysBusDevice parent_obj;
33
+@rrxr_3 ........ .. . .. rm:3 ...... rn:5 rd:5 \
36
34
+ &rrxr_esz ra=%reg_movprfx index=%index3_22_19
37
@@ -XXX,XX +XXX,XX @@ struct xlx_pic
35
+@rrxr_2 ........ .. . index:2 rm:3 ...... rn:5 rd:5 \
38
uint32_t irq_pin_state;
36
+ &rrxr_esz ra=%reg_movprfx
39
};
37
+@rrxr_1 ........ .. . index:1 rm:4 ...... rn:5 rd:5 \
40
38
+ &rrxr_esz ra=%reg_movprfx
41
-static void update_irq(struct xlx_pic *p)
39
+
42
+static void update_irq(XpsIntc *p)
40
###########################################################################
43
{
41
# Instruction patterns. Grouped according to the SVE encodingindex.xhtml.
44
uint32_t i;
42
45
43
@@ -XXX,XX +XXX,XX @@ DOT_zzzz 01000100 1 sz:1 0 rm:5 00000 u:1 rn:5 rd:5 \
46
@@ -XXX,XX +XXX,XX @@ static void update_irq(struct xlx_pic *p)
44
ra=%reg_movprfx
47
qemu_set_irq(p->parent_irq, (p->regs[R_MER] & 1) && p->regs[R_IPR]);
45
46
# SVE integer dot product (indexed)
47
-DOT_zzxw 01000100 101 index:2 rm:3 00000 u:1 rn:5 rd:5 \
48
- sz=0 ra=%reg_movprfx
49
-DOT_zzxw 01000100 111 index:1 rm:4 00000 u:1 rn:5 rd:5 \
50
- sz=1 ra=%reg_movprfx
51
+SDOT_zzxw_s 01000100 10 1 ..... 000000 ..... ..... @rrxr_2 esz=2
52
+SDOT_zzxw_d 01000100 11 1 ..... 000000 ..... ..... @rrxr_1 esz=3
53
+UDOT_zzxw_s 01000100 10 1 ..... 000001 ..... ..... @rrxr_2 esz=2
54
+UDOT_zzxw_d 01000100 11 1 ..... 000001 ..... ..... @rrxr_1 esz=3
55
56
# SVE floating-point complex add (predicated)
57
FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \
58
@@ -XXX,XX +XXX,XX @@ FCMLA_zzxz 01100100 11 1 index:1 rm:4 0001 rot:2 rn:5 rd:5 \
59
### SVE FP Multiply-Add Indexed Group
60
61
# SVE floating-point multiply-add (indexed)
62
-FMLA_zzxz 01100100 0.1 .. rm:3 00000 sub:1 rn:5 rd:5 \
63
- ra=%reg_movprfx index=%index3_22_19 esz=1
64
-FMLA_zzxz 01100100 101 index:2 rm:3 00000 sub:1 rn:5 rd:5 \
65
- ra=%reg_movprfx esz=2
66
-FMLA_zzxz 01100100 111 index:1 rm:4 00000 sub:1 rn:5 rd:5 \
67
- ra=%reg_movprfx esz=3
68
+FMLA_zzxz 01100100 0. 1 ..... 000000 ..... ..... @rrxr_3 esz=1
69
+FMLA_zzxz 01100100 10 1 ..... 000000 ..... ..... @rrxr_2 esz=2
70
+FMLA_zzxz 01100100 11 1 ..... 000000 ..... ..... @rrxr_1 esz=3
71
+FMLS_zzxz 01100100 0. 1 ..... 000001 ..... ..... @rrxr_3 esz=1
72
+FMLS_zzxz 01100100 10 1 ..... 000001 ..... ..... @rrxr_2 esz=2
73
+FMLS_zzxz 01100100 11 1 ..... 000001 ..... ..... @rrxr_1 esz=3
74
75
### SVE FP Multiply Indexed Group
76
77
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/translate-sve.c
80
+++ b/target/arm/translate-sve.c
81
@@ -XXX,XX +XXX,XX @@ static bool trans_DOT_zzzz(DisasContext *s, arg_DOT_zzzz *a)
82
return true;
83
}
48
}
84
49
85
-static bool trans_DOT_zzxw(DisasContext *s, arg_DOT_zzxw *a)
50
-static uint64_t
86
+static bool do_zzxz_ool(DisasContext *s, arg_rrxr_esz *a,
51
-pic_read(void *opaque, hwaddr addr, unsigned int size)
87
+ gen_helper_gvec_4 *fn)
52
+static uint64_t pic_read(void *opaque, hwaddr addr, unsigned int size)
88
{
53
{
89
- static gen_helper_gvec_4 * const fns[2][2] = {
54
- struct xlx_pic *p = opaque;
90
- { gen_helper_gvec_sdot_idx_b, gen_helper_gvec_sdot_idx_h },
55
+ XpsIntc *p = opaque;
91
- { gen_helper_gvec_udot_idx_b, gen_helper_gvec_udot_idx_h }
56
uint32_t r = 0;
92
- };
57
93
-
58
addr >>= 2;
94
+ if (fn == NULL) {
59
@@ -XXX,XX +XXX,XX @@ pic_read(void *opaque, hwaddr addr, unsigned int size)
95
+ return false;
60
return r;
96
+ }
97
if (sve_access_check(s)) {
98
- gen_gvec_ool_zzzz(s, fns[a->u][a->sz], a->rd, a->rn, a->rm,
99
- a->ra, a->index);
100
+ gen_gvec_ool_zzzz(s, fn, a->rd, a->rn, a->rm, a->ra, a->index);
101
}
102
return true;
103
}
61
}
104
62
105
+#define DO_RRXR(NAME, FUNC) \
63
-static void
106
+ static bool NAME(DisasContext *s, arg_rrxr_esz *a) \
64
-pic_write(void *opaque, hwaddr addr,
107
+ { return do_zzxz_ool(s, a, FUNC); }
65
- uint64_t val64, unsigned int size)
108
+
66
+static void pic_write(void *opaque, hwaddr addr,
109
+DO_RRXR(trans_SDOT_zzxw_s, gen_helper_gvec_sdot_idx_b)
67
+ uint64_t val64, unsigned int size)
110
+DO_RRXR(trans_SDOT_zzxw_d, gen_helper_gvec_sdot_idx_h)
111
+DO_RRXR(trans_UDOT_zzxw_s, gen_helper_gvec_udot_idx_b)
112
+DO_RRXR(trans_UDOT_zzxw_d, gen_helper_gvec_udot_idx_h)
113
+
114
+#undef DO_RRXR
115
116
/*
117
*** SVE Floating Point Multiply-Add Indexed Group
118
*/
119
120
-static bool trans_FMLA_zzxz(DisasContext *s, arg_FMLA_zzxz *a)
121
+static bool do_FMLA_zzxz(DisasContext *s, arg_rrxr_esz *a, bool sub)
122
{
68
{
123
static gen_helper_gvec_4_ptr * const fns[3] = {
69
- struct xlx_pic *p = opaque;
124
gen_helper_gvec_fmla_idx_h,
70
+ XpsIntc *p = opaque;
125
@@ -XXX,XX +XXX,XX @@ static bool trans_FMLA_zzxz(DisasContext *s, arg_FMLA_zzxz *a)
71
uint32_t value = val64;
126
vec_full_reg_offset(s, a->rn),
72
127
vec_full_reg_offset(s, a->rm),
73
addr >>= 2;
128
vec_full_reg_offset(s, a->ra),
74
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps pic_ops = {
129
- status, vsz, vsz, (a->index << 1) | a->sub,
75
130
+ status, vsz, vsz, (a->index << 1) | sub,
76
static void irq_handler(void *opaque, int irq, int level)
131
fns[a->esz - 1]);
77
{
132
tcg_temp_free_ptr(status);
78
- struct xlx_pic *p = opaque;
133
}
79
+ XpsIntc *p = opaque;
134
return true;
80
81
/* edge triggered interrupt */
82
if (p->c_kind_of_intr & (1 << irq) && p->regs[R_MER] & 2) {
83
@@ -XXX,XX +XXX,XX @@ static void irq_handler(void *opaque, int irq, int level)
84
85
static void xilinx_intc_init(Object *obj)
86
{
87
- struct xlx_pic *p = XILINX_INTC(obj);
88
+ XpsIntc *p = XILINX_INTC(obj);
89
90
qdev_init_gpio_in(DEVICE(obj), irq_handler, 32);
91
sysbus_init_irq(SYS_BUS_DEVICE(obj), &p->parent_irq);
92
@@ -XXX,XX +XXX,XX @@ static void xilinx_intc_init(Object *obj)
135
}
93
}
136
94
137
+static bool trans_FMLA_zzxz(DisasContext *s, arg_FMLA_zzxz *a)
95
static Property xilinx_intc_properties[] = {
138
+{
96
- DEFINE_PROP_UINT32("kind-of-intr", struct xlx_pic, c_kind_of_intr, 0),
139
+ return do_FMLA_zzxz(s, a, false);
97
+ DEFINE_PROP_UINT32("kind-of-intr", XpsIntc, c_kind_of_intr, 0),
140
+}
98
DEFINE_PROP_END_OF_LIST(),
141
+
99
};
142
+static bool trans_FMLS_zzxz(DisasContext *s, arg_FMLA_zzxz *a)
100
143
+{
101
@@ -XXX,XX +XXX,XX @@ static void xilinx_intc_class_init(ObjectClass *klass, void *data)
144
+ return do_FMLA_zzxz(s, a, true);
102
static const TypeInfo xilinx_intc_info = {
145
+}
103
.name = TYPE_XILINX_INTC,
146
+
104
.parent = TYPE_SYS_BUS_DEVICE,
147
/*
105
- .instance_size = sizeof(struct xlx_pic),
148
*** SVE Floating Point Multiply Indexed Group
106
+ .instance_size = sizeof(XpsIntc),
149
*/
107
.instance_init = xilinx_intc_init,
108
.class_init = xilinx_intc_class_init,
109
};
150
--
110
--
151
2.20.1
111
2.34.1
152
112
153
113
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Forward tlb_flush_page_bits_by_mmuidx_all_cpus_synced to
3
This remove a use of 'struct' in the DECLARE_INSTANCE_CHECKER()
4
tlb_flush_range_by_mmuidx_all_cpus_synced passing TARGET_PAGE_SIZE.
4
macro call, to avoid after a QOM refactor:
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
hw/timer/xilinx_timer.c:65:1: error: declaration of anonymous struct must be a definition
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
DECLARE_INSTANCE_CHECKER(struct timerblock, XILINX_TIMER,
8
Message-id: 20210509151618.2331764-7-f4bug@amsat.org
8
^
9
Message-Id: <20210508201640.1045808-1-richard.henderson@linaro.org>
9
10
[PMD: Split from bigger patch]
10
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Edgar E. Iglesias <edgar@zeroasic.com>
13
Message-id: 20230109140306.23161-15-philmd@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
---
15
include/exec/exec-all.h | 12 ++++++++++++
16
hw/timer/xilinx_timer.c | 27 +++++++++++++--------------
16
accel/tcg/cputlb.c | 27 ++++++++++++++++++++-------
17
1 file changed, 13 insertions(+), 14 deletions(-)
17
2 files changed, 32 insertions(+), 7 deletions(-)
18
18
19
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
19
diff --git a/hw/timer/xilinx_timer.c b/hw/timer/xilinx_timer.c
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/exec/exec-all.h
21
--- a/hw/timer/xilinx_timer.c
22
+++ b/include/exec/exec-all.h
22
+++ b/hw/timer/xilinx_timer.c
23
@@ -XXX,XX +XXX,XX @@ void tlb_flush_range_by_mmuidx(CPUState *cpu, target_ulong addr,
23
@@ -XXX,XX +XXX,XX @@ struct xlx_timer
24
void tlb_flush_range_by_mmuidx_all_cpus(CPUState *cpu, target_ulong addr,
24
};
25
target_ulong len, uint16_t idxmap,
25
26
unsigned bits);
26
#define TYPE_XILINX_TIMER "xlnx.xps-timer"
27
+void tlb_flush_range_by_mmuidx_all_cpus_synced(CPUState *cpu,
27
-DECLARE_INSTANCE_CHECKER(struct timerblock, XILINX_TIMER,
28
+ target_ulong addr,
28
- TYPE_XILINX_TIMER)
29
+ target_ulong len,
29
+typedef struct XpsTimerState XpsTimerState;
30
+ uint16_t idxmap,
30
+DECLARE_INSTANCE_CHECKER(XpsTimerState, XILINX_TIMER, TYPE_XILINX_TIMER)
31
+ unsigned bits);
31
32
32
-struct timerblock
33
/**
33
+struct XpsTimerState
34
* tlb_set_page_with_attrs:
35
@@ -XXX,XX +XXX,XX @@ static inline void tlb_flush_range_by_mmuidx_all_cpus(CPUState *cpu,
36
unsigned bits)
37
{
34
{
35
SysBusDevice parent_obj;
36
37
@@ -XXX,XX +XXX,XX @@ struct timerblock
38
struct xlx_timer *timers;
39
};
40
41
-static inline unsigned int num_timers(struct timerblock *t)
42
+static inline unsigned int num_timers(XpsTimerState *t)
43
{
44
return 2 - t->one_timer_only;
38
}
45
}
39
+static inline void tlb_flush_range_by_mmuidx_all_cpus_synced(CPUState *cpu,
46
@@ -XXX,XX +XXX,XX @@ static inline unsigned int timer_from_addr(hwaddr addr)
40
+ target_ulong addr,
47
return addr >> 2;
41
+ target_long len,
42
+ uint16_t idxmap,
43
+ unsigned bits)
44
+{
45
+}
46
#endif
47
/**
48
* probe_access:
49
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/accel/tcg/cputlb.c
52
+++ b/accel/tcg/cputlb.c
53
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus(CPUState *src_cpu,
54
idxmap, bits);
55
}
48
}
56
49
57
-void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
50
-static void timer_update_irq(struct timerblock *t)
58
- target_ulong addr,
51
+static void timer_update_irq(XpsTimerState *t)
59
- uint16_t idxmap,
60
- unsigned bits)
61
+void tlb_flush_range_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
62
+ target_ulong addr,
63
+ target_ulong len,
64
+ uint16_t idxmap,
65
+ unsigned bits)
66
{
52
{
67
TLBFlushRangeData d, *p;
53
unsigned int i, irq = 0;
68
CPUState *dst_cpu;
54
uint32_t csr;
69
55
@@ -XXX,XX +XXX,XX @@ static void timer_update_irq(struct timerblock *t)
70
- /* If all bits are significant, this devolves to tlb_flush_page. */
56
static uint64_t
71
- if (bits >= TARGET_LONG_BITS) {
57
timer_read(void *opaque, hwaddr addr, unsigned int size)
72
+ /*
58
{
73
+ * If all bits are significant, and len is small,
59
- struct timerblock *t = opaque;
74
+ * this devolves to tlb_flush_page.
60
+ XpsTimerState *t = opaque;
75
+ */
61
struct xlx_timer *xt;
76
+ if (bits >= TARGET_LONG_BITS && len <= TARGET_PAGE_SIZE) {
62
uint32_t r = 0;
77
tlb_flush_page_by_mmuidx_all_cpus_synced(src_cpu, addr, idxmap);
63
unsigned int timer;
78
return;
64
@@ -XXX,XX +XXX,XX @@ static void
79
}
65
timer_write(void *opaque, hwaddr addr,
80
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
66
uint64_t val64, unsigned int size)
81
67
{
82
/* This should already be page aligned */
68
- struct timerblock *t = opaque;
83
d.addr = addr & TARGET_PAGE_MASK;
69
+ XpsTimerState *t = opaque;
84
- d.len = TARGET_PAGE_SIZE;
70
struct xlx_timer *xt;
85
+ d.len = len;
71
unsigned int timer;
86
d.idxmap = idxmap;
72
uint32_t value = val64;
87
d.bits = bits;
73
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps timer_ops = {
88
74
static void timer_hit(void *opaque)
89
@@ -XXX,XX +XXX,XX @@ void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
75
{
90
RUN_ON_CPU_HOST_PTR(p));
76
struct xlx_timer *xt = opaque;
77
- struct timerblock *t = xt->parent;
78
+ XpsTimerState *t = xt->parent;
79
D(fprintf(stderr, "%s %d\n", __func__, xt->nr));
80
xt->regs[R_TCSR] |= TCSR_TINT;
81
82
@@ -XXX,XX +XXX,XX @@ static void timer_hit(void *opaque)
83
84
static void xilinx_timer_realize(DeviceState *dev, Error **errp)
85
{
86
- struct timerblock *t = XILINX_TIMER(dev);
87
+ XpsTimerState *t = XILINX_TIMER(dev);
88
unsigned int i;
89
90
/* Init all the ptimers. */
91
@@ -XXX,XX +XXX,XX @@ static void xilinx_timer_realize(DeviceState *dev, Error **errp)
92
93
static void xilinx_timer_init(Object *obj)
94
{
95
- struct timerblock *t = XILINX_TIMER(obj);
96
+ XpsTimerState *t = XILINX_TIMER(obj);
97
98
/* All timers share a single irq line. */
99
sysbus_init_irq(SYS_BUS_DEVICE(obj), &t->irq);
91
}
100
}
92
101
93
+void tlb_flush_page_bits_by_mmuidx_all_cpus_synced(CPUState *src_cpu,
102
static Property xilinx_timer_properties[] = {
94
+ target_ulong addr,
103
- DEFINE_PROP_UINT32("clock-frequency", struct timerblock, freq_hz,
95
+ uint16_t idxmap,
104
- 62 * 1000000),
96
+ unsigned bits)
105
- DEFINE_PROP_UINT8("one-timer-only", struct timerblock, one_timer_only, 0),
97
+{
106
+ DEFINE_PROP_UINT32("clock-frequency", XpsTimerState, freq_hz, 62 * 1000000),
98
+ tlb_flush_range_by_mmuidx_all_cpus_synced(src_cpu, addr, TARGET_PAGE_SIZE,
107
+ DEFINE_PROP_UINT8("one-timer-only", XpsTimerState, one_timer_only, 0),
99
+ idxmap, bits);
108
DEFINE_PROP_END_OF_LIST(),
100
+}
109
};
101
+
110
102
/* update the TLBs so that writes to code in the virtual page 'addr'
111
@@ -XXX,XX +XXX,XX @@ static void xilinx_timer_class_init(ObjectClass *klass, void *data)
103
can be detected */
112
static const TypeInfo xilinx_timer_info = {
104
void tlb_protect_code(ram_addr_t ram_addr)
113
.name = TYPE_XILINX_TIMER,
114
.parent = TYPE_SYS_BUS_DEVICE,
115
- .instance_size = sizeof(struct timerblock),
116
+ .instance_size = sizeof(XpsTimerState),
117
.instance_init = xilinx_timer_init,
118
.class_init = xilinx_timer_class_init,
119
};
105
--
120
--
106
2.20.1
121
2.34.1
107
122
108
123
diff view generated by jsdifflib
Deleted patch
1
From: Rebecca Cran <rebecca@nuviainc.com>
2
1
3
Indicate support for FEAT_TLBIOS and FEAT_TLBIRANGE by setting
4
ID_AA64ISAR0.TLB to 2 for the max AARCH64 CPU type.
5
6
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210512182337.18563-4-rebecca@nuviainc.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/cpu64.c | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu64.c
17
+++ b/target/arm/cpu64.c
18
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
19
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
20
t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
21
t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */
22
+ t = FIELD_DP64(t, ID_AA64ISAR0, TLB, 2); /* FEAT_TLBIRANGE */
23
t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1);
24
cpu->isar.id_aa64isar0 = t;
25
26
--
27
2.20.1
28
29
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
2
2
3
Will be used for SVE2 isa subset enablement.
3
ARM trusted firmware, when built with FEAT_HCX support, sets SCR_EL3.HXEn bit
4
to allow EL2 to modify HCRX_EL2 register without trapping it in EL3. Qemu
5
uses a valid mask to clear unsupported SCR_EL3 bits when emulating SCR_EL3
6
write, and that mask doesn't include SCR_EL3.HXEn bit even if FEAT_HCX is
7
enabled and exposed to the guest. As a result EL3 writes of that bit are
8
ignored.
4
9
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Cc: qemu-stable@nongnu.org
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Evgeny Iakovlev <eiakovlev@linux.microsoft.com>
7
Message-id: 20210525010358.152808-2-richard.henderson@linaro.org
12
Message-id: 20230105221251.17896-4-eiakovlev@linux.microsoft.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
15
---
11
target/arm/cpu.h | 16 ++++++++++++++++
16
target/arm/helper.c | 3 +++
12
target/arm/helper.c | 3 +--
17
1 file changed, 3 insertions(+)
13
target/arm/kvm64.c | 21 +++++++++++++++------
14
3 files changed, 32 insertions(+), 8 deletions(-)
15
18
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
21
uint64_t id_aa64mmfr2;
22
uint64_t id_aa64dfr0;
23
uint64_t id_aa64dfr1;
24
+ uint64_t id_aa64zfr0;
25
} isar;
26
uint64_t midr;
27
uint32_t revidr;
28
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64DFR0, DOUBLELOCK, 36, 4)
29
FIELD(ID_AA64DFR0, TRACEFILT, 40, 4)
30
FIELD(ID_AA64DFR0, MTPMU, 48, 4)
31
32
+FIELD(ID_AA64ZFR0, SVEVER, 0, 4)
33
+FIELD(ID_AA64ZFR0, AES, 4, 4)
34
+FIELD(ID_AA64ZFR0, BITPERM, 16, 4)
35
+FIELD(ID_AA64ZFR0, BFLOAT16, 20, 4)
36
+FIELD(ID_AA64ZFR0, SHA3, 32, 4)
37
+FIELD(ID_AA64ZFR0, SM4, 40, 4)
38
+FIELD(ID_AA64ZFR0, I8MM, 44, 4)
39
+FIELD(ID_AA64ZFR0, F32MM, 52, 4)
40
+FIELD(ID_AA64ZFR0, F64MM, 56, 4)
41
+
42
FIELD(ID_DFR0, COPDBG, 0, 4)
43
FIELD(ID_DFR0, COPSDBG, 4, 4)
44
FIELD(ID_DFR0, MMAPDBG, 8, 4)
45
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
46
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
47
}
48
49
+static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id)
50
+{
51
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SVEVER) != 0;
52
+}
53
+
54
/*
55
* Feature tests for "does this exist in either 32-bit or 64-bit?"
56
*/
57
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
58
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/helper.c
21
--- a/target/arm/helper.c
60
+++ b/target/arm/helper.c
22
+++ b/target/arm/helper.c
61
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
23
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
62
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 4,
24
if (cpu_isar_feature(aa64_sme, cpu)) {
63
.access = PL1_R, .type = ARM_CP_CONST,
25
valid_mask |= SCR_ENTP2;
64
.accessfn = access_aa64_tid3,
26
}
65
- /* At present, only SVEver == 0 is defined anyway. */
27
+ if (cpu_isar_feature(aa64_hcx, cpu)) {
66
- .resetvalue = 0 },
28
+ valid_mask |= SCR_HXEN;
67
+ .resetvalue = cpu->isar.id_aa64zfr0 },
29
+ }
68
{ .name = "ID_AA64PFR5_EL1_RESERVED", .state = ARM_CP_STATE_AA64,
30
} else {
69
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 4, .opc2 = 5,
31
valid_mask &= ~(SCR_RW | SCR_ST);
70
.access = PL1_R, .type = ARM_CP_CONST,
32
if (cpu_isar_feature(aa32_ras, cpu)) {
71
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/kvm64.c
74
+++ b/target/arm/kvm64.c
75
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
76
77
sve_supported = ioctl(fdarray[0], KVM_CHECK_EXTENSION, KVM_CAP_ARM_SVE) > 0;
78
79
- kvm_arm_destroy_scratch_host_vcpu(fdarray);
80
-
81
- if (err < 0) {
82
- return false;
83
- }
84
-
85
/* Add feature bits that can't appear until after VCPU init. */
86
if (sve_supported) {
87
t = ahcf->isar.id_aa64pfr0;
88
t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
89
ahcf->isar.id_aa64pfr0 = t;
90
+
91
+ /*
92
+ * Before v5.1, KVM did not support SVE and did not expose
93
+ * ID_AA64ZFR0_EL1 even as RAZ. After v5.1, KVM still does
94
+ * not expose the register to "user" requests like this
95
+ * unless the host supports SVE.
96
+ */
97
+ err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64zfr0,
98
+ ARM64_SYS_REG(3, 0, 0, 4, 4));
99
+ }
100
+
101
+ kvm_arm_destroy_scratch_host_vcpu(fdarray);
102
+
103
+ if (err < 0) {
104
+ return false;
105
}
106
107
/*
108
--
33
--
109
2.20.1
34
2.34.1
110
111
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-4-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 14 ++++++++++++
9
target/arm/sve.decode | 5 +++++
10
target/arm/sve_helper.c | 44 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 39 +++++++++++++++++++++++++++++++++
12
4 files changed, 102 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_umulh_zpzz_s, TCG_CALL_NO_RWG,
19
DEF_HELPER_FLAGS_5(sve_umulh_zpzz_d, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_5(sve2_sadalp_zpzz_h, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_5(sve2_sadalp_zpzz_s, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_5(sve2_sadalp_zpzz_d, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, i32)
28
+
29
+DEF_HELPER_FLAGS_5(sve2_uadalp_zpzz_h, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_5(sve2_uadalp_zpzz_s, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_5(sve2_uadalp_zpzz_d, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, i32)
35
+
36
DEF_HELPER_FLAGS_5(sve_sdiv_zpzz_s, TCG_CALL_NO_RWG,
37
void, ptr, ptr, ptr, ptr, i32)
38
DEF_HELPER_FLAGS_5(sve_sdiv_zpzz_d, TCG_CALL_NO_RWG,
39
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/sve.decode
42
+++ b/target/arm/sve.decode
43
@@ -XXX,XX +XXX,XX @@ MUL_zzz 00000100 .. 1 ..... 0110 00 ..... ..... @rd_rn_rm
44
SMULH_zzz 00000100 .. 1 ..... 0110 10 ..... ..... @rd_rn_rm
45
UMULH_zzz 00000100 .. 1 ..... 0110 11 ..... ..... @rd_rn_rm
46
PMUL_zzz 00000100 00 1 ..... 0110 01 ..... ..... @rd_rn_rm_e0
47
+
48
+### SVE2 Integer - Predicated
49
+
50
+SADALP_zpzz 01000100 .. 000 100 101 ... ..... ..... @rdm_pg_rn
51
+UADALP_zpzz 01000100 .. 000 101 101 ... ..... ..... @rdm_pg_rn
52
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/sve_helper.c
55
+++ b/target/arm/sve_helper.c
56
@@ -XXX,XX +XXX,XX @@ DO_ZPZZ_D(sve_asr_zpzz_d, int64_t, DO_ASR)
57
DO_ZPZZ_D(sve_lsr_zpzz_d, uint64_t, DO_LSR)
58
DO_ZPZZ_D(sve_lsl_zpzz_d, uint64_t, DO_LSL)
59
60
+static inline uint16_t do_sadalp_h(int16_t n, int16_t m)
61
+{
62
+ int8_t n1 = n, n2 = n >> 8;
63
+ return m + n1 + n2;
64
+}
65
+
66
+static inline uint32_t do_sadalp_s(int32_t n, int32_t m)
67
+{
68
+ int16_t n1 = n, n2 = n >> 16;
69
+ return m + n1 + n2;
70
+}
71
+
72
+static inline uint64_t do_sadalp_d(int64_t n, int64_t m)
73
+{
74
+ int32_t n1 = n, n2 = n >> 32;
75
+ return m + n1 + n2;
76
+}
77
+
78
+DO_ZPZZ(sve2_sadalp_zpzz_h, int16_t, H1_2, do_sadalp_h)
79
+DO_ZPZZ(sve2_sadalp_zpzz_s, int32_t, H1_4, do_sadalp_s)
80
+DO_ZPZZ_D(sve2_sadalp_zpzz_d, int64_t, do_sadalp_d)
81
+
82
+static inline uint16_t do_uadalp_h(uint16_t n, uint16_t m)
83
+{
84
+ uint8_t n1 = n, n2 = n >> 8;
85
+ return m + n1 + n2;
86
+}
87
+
88
+static inline uint32_t do_uadalp_s(uint32_t n, uint32_t m)
89
+{
90
+ uint16_t n1 = n, n2 = n >> 16;
91
+ return m + n1 + n2;
92
+}
93
+
94
+static inline uint64_t do_uadalp_d(uint64_t n, uint64_t m)
95
+{
96
+ uint32_t n1 = n, n2 = n >> 32;
97
+ return m + n1 + n2;
98
+}
99
+
100
+DO_ZPZZ(sve2_uadalp_zpzz_h, uint16_t, H1_2, do_uadalp_h)
101
+DO_ZPZZ(sve2_uadalp_zpzz_s, uint32_t, H1_4, do_uadalp_s)
102
+DO_ZPZZ_D(sve2_uadalp_zpzz_d, uint64_t, do_uadalp_d)
103
+
104
#undef DO_ZPZZ
105
#undef DO_ZPZZ_D
106
107
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/target/arm/translate-sve.c
110
+++ b/target/arm/translate-sve.c
111
@@ -XXX,XX +XXX,XX @@ static bool trans_PMUL_zzz(DisasContext *s, arg_rrr_esz *a)
112
{
113
return do_sve2_zzz_ool(s, a, gen_helper_gvec_pmul_b);
114
}
115
+
116
+/*
117
+ * SVE2 Integer - Predicated
118
+ */
119
+
120
+static bool do_sve2_zpzz_ool(DisasContext *s, arg_rprr_esz *a,
121
+ gen_helper_gvec_4 *fn)
122
+{
123
+ if (!dc_isar_feature(aa64_sve2, s)) {
124
+ return false;
125
+ }
126
+ return do_zpzz_ool(s, a, fn);
127
+}
128
+
129
+static bool trans_SADALP_zpzz(DisasContext *s, arg_rprr_esz *a)
130
+{
131
+ static gen_helper_gvec_4 * const fns[3] = {
132
+ gen_helper_sve2_sadalp_zpzz_h,
133
+ gen_helper_sve2_sadalp_zpzz_s,
134
+ gen_helper_sve2_sadalp_zpzz_d,
135
+ };
136
+ if (a->esz == 0) {
137
+ return false;
138
+ }
139
+ return do_sve2_zpzz_ool(s, a, fns[a->esz - 1]);
140
+}
141
+
142
+static bool trans_UADALP_zpzz(DisasContext *s, arg_rprr_esz *a)
143
+{
144
+ static gen_helper_gvec_4 * const fns[3] = {
145
+ gen_helper_sve2_uadalp_zpzz_h,
146
+ gen_helper_sve2_uadalp_zpzz_s,
147
+ gen_helper_sve2_uadalp_zpzz_d,
148
+ };
149
+ if (a->esz == 0) {
150
+ return false;
151
+ }
152
+ return do_sve2_zpzz_ool(s, a, fns[a->esz - 1]);
153
+}
154
--
155
2.20.1
156
157
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-5-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 13 +++++++++++
9
target/arm/sve.decode | 7 ++++++
10
target/arm/sve_helper.c | 21 +++++++++++++++++
11
target/arm/translate-sve.c | 47 ++++++++++++++++++++++++++++++++++++++
12
4 files changed, 88 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_rbit_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
19
DEF_HELPER_FLAGS_4(sve_rbit_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_4(sve_rbit_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_4(sve2_sqabs_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
+DEF_HELPER_FLAGS_4(sve2_sqabs_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_4(sve2_sqabs_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_4(sve2_sqabs_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
+
27
+DEF_HELPER_FLAGS_4(sve2_sqneg_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(sve2_sqneg_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(sve2_sqneg_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(sve2_sqneg_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
+
32
+DEF_HELPER_FLAGS_4(sve2_urecpe_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_4(sve2_ursqrte_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
+
35
DEF_HELPER_FLAGS_5(sve_splice, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
36
37
DEF_HELPER_FLAGS_5(sve_cmpeq_ppzz_b, TCG_CALL_NO_RWG,
38
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/sve.decode
41
+++ b/target/arm/sve.decode
42
@@ -XXX,XX +XXX,XX @@ PMUL_zzz 00000100 00 1 ..... 0110 01 ..... ..... @rd_rn_rm_e0
43
44
SADALP_zpzz 01000100 .. 000 100 101 ... ..... ..... @rdm_pg_rn
45
UADALP_zpzz 01000100 .. 000 101 101 ... ..... ..... @rdm_pg_rn
46
+
47
+### SVE2 integer unary operations (predicated)
48
+
49
+URECPE 01000100 .. 000 000 101 ... ..... ..... @rd_pg_rn
50
+URSQRTE 01000100 .. 000 001 101 ... ..... ..... @rd_pg_rn
51
+SQABS 01000100 .. 001 000 101 ... ..... ..... @rd_pg_rn
52
+SQNEG 01000100 .. 001 001 101 ... ..... ..... @rd_pg_rn
53
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/sve_helper.c
56
+++ b/target/arm/sve_helper.c
57
@@ -XXX,XX +XXX,XX @@ DO_ZPZ(sve_rbit_h, uint16_t, H1_2, revbit16)
58
DO_ZPZ(sve_rbit_s, uint32_t, H1_4, revbit32)
59
DO_ZPZ_D(sve_rbit_d, uint64_t, revbit64)
60
61
+#define DO_SQABS(X) \
62
+ ({ __typeof(X) x_ = (X), min_ = 1ull << (sizeof(X) * 8 - 1); \
63
+ x_ >= 0 ? x_ : x_ == min_ ? -min_ - 1 : -x_; })
64
+
65
+DO_ZPZ(sve2_sqabs_b, int8_t, H1, DO_SQABS)
66
+DO_ZPZ(sve2_sqabs_h, int16_t, H1_2, DO_SQABS)
67
+DO_ZPZ(sve2_sqabs_s, int32_t, H1_4, DO_SQABS)
68
+DO_ZPZ_D(sve2_sqabs_d, int64_t, DO_SQABS)
69
+
70
+#define DO_SQNEG(X) \
71
+ ({ __typeof(X) x_ = (X), min_ = 1ull << (sizeof(X) * 8 - 1); \
72
+ x_ == min_ ? -min_ - 1 : -x_; })
73
+
74
+DO_ZPZ(sve2_sqneg_b, uint8_t, H1, DO_SQNEG)
75
+DO_ZPZ(sve2_sqneg_h, uint16_t, H1_2, DO_SQNEG)
76
+DO_ZPZ(sve2_sqneg_s, uint32_t, H1_4, DO_SQNEG)
77
+DO_ZPZ_D(sve2_sqneg_d, uint64_t, DO_SQNEG)
78
+
79
+DO_ZPZ(sve2_urecpe_s, uint32_t, H1_4, helper_recpe_u32)
80
+DO_ZPZ(sve2_ursqrte_s, uint32_t, H1_4, helper_rsqrte_u32)
81
+
82
/* Three-operand expander, unpredicated, in which the third operand is "wide".
83
*/
84
#define DO_ZZW(NAME, TYPE, TYPEW, H, OP) \
85
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/arm/translate-sve.c
88
+++ b/target/arm/translate-sve.c
89
@@ -XXX,XX +XXX,XX @@ static bool trans_UADALP_zpzz(DisasContext *s, arg_rprr_esz *a)
90
}
91
return do_sve2_zpzz_ool(s, a, fns[a->esz - 1]);
92
}
93
+
94
+/*
95
+ * SVE2 integer unary operations (predicated)
96
+ */
97
+
98
+static bool do_sve2_zpz_ool(DisasContext *s, arg_rpr_esz *a,
99
+ gen_helper_gvec_3 *fn)
100
+{
101
+ if (!dc_isar_feature(aa64_sve2, s)) {
102
+ return false;
103
+ }
104
+ return do_zpz_ool(s, a, fn);
105
+}
106
+
107
+static bool trans_URECPE(DisasContext *s, arg_rpr_esz *a)
108
+{
109
+ if (a->esz != 2) {
110
+ return false;
111
+ }
112
+ return do_sve2_zpz_ool(s, a, gen_helper_sve2_urecpe_s);
113
+}
114
+
115
+static bool trans_URSQRTE(DisasContext *s, arg_rpr_esz *a)
116
+{
117
+ if (a->esz != 2) {
118
+ return false;
119
+ }
120
+ return do_sve2_zpz_ool(s, a, gen_helper_sve2_ursqrte_s);
121
+}
122
+
123
+static bool trans_SQABS(DisasContext *s, arg_rpr_esz *a)
124
+{
125
+ static gen_helper_gvec_3 * const fns[4] = {
126
+ gen_helper_sve2_sqabs_b, gen_helper_sve2_sqabs_h,
127
+ gen_helper_sve2_sqabs_s, gen_helper_sve2_sqabs_d,
128
+ };
129
+ return do_sve2_zpz_ool(s, a, fns[a->esz]);
130
+}
131
+
132
+static bool trans_SQNEG(DisasContext *s, arg_rpr_esz *a)
133
+{
134
+ static gen_helper_gvec_3 * const fns[4] = {
135
+ gen_helper_sve2_sqneg_b, gen_helper_sve2_sqneg_h,
136
+ gen_helper_sve2_sqneg_s, gen_helper_sve2_sqneg_d,
137
+ };
138
+ return do_sve2_zpz_ool(s, a, fns[a->esz]);
139
+}
140
--
141
2.20.1
142
143
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20210525010358.152808-7-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 54 +++++++++++++++++++++++
9
target/arm/sve.decode | 17 ++++++++
10
target/arm/sve_helper.c | 87 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 18 ++++++++
12
4 files changed, 176 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_uadalp_zpzz_s, TCG_CALL_NO_RWG,
19
DEF_HELPER_FLAGS_5(sve2_uadalp_zpzz_d, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_5(sve2_srshl_zpzz_b, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_5(sve2_srshl_zpzz_h, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_5(sve2_srshl_zpzz_s, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_5(sve2_srshl_zpzz_d, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
+
31
+DEF_HELPER_FLAGS_5(sve2_urshl_zpzz_b, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_5(sve2_urshl_zpzz_h, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_5(sve2_urshl_zpzz_s, TCG_CALL_NO_RWG,
36
+ void, ptr, ptr, ptr, ptr, i32)
37
+DEF_HELPER_FLAGS_5(sve2_urshl_zpzz_d, TCG_CALL_NO_RWG,
38
+ void, ptr, ptr, ptr, ptr, i32)
39
+
40
+DEF_HELPER_FLAGS_5(sve2_sqshl_zpzz_b, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, ptr, i32)
42
+DEF_HELPER_FLAGS_5(sve2_sqshl_zpzz_h, TCG_CALL_NO_RWG,
43
+ void, ptr, ptr, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_5(sve2_sqshl_zpzz_s, TCG_CALL_NO_RWG,
45
+ void, ptr, ptr, ptr, ptr, i32)
46
+DEF_HELPER_FLAGS_5(sve2_sqshl_zpzz_d, TCG_CALL_NO_RWG,
47
+ void, ptr, ptr, ptr, ptr, i32)
48
+
49
+DEF_HELPER_FLAGS_5(sve2_uqshl_zpzz_b, TCG_CALL_NO_RWG,
50
+ void, ptr, ptr, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_5(sve2_uqshl_zpzz_h, TCG_CALL_NO_RWG,
52
+ void, ptr, ptr, ptr, ptr, i32)
53
+DEF_HELPER_FLAGS_5(sve2_uqshl_zpzz_s, TCG_CALL_NO_RWG,
54
+ void, ptr, ptr, ptr, ptr, i32)
55
+DEF_HELPER_FLAGS_5(sve2_uqshl_zpzz_d, TCG_CALL_NO_RWG,
56
+ void, ptr, ptr, ptr, ptr, i32)
57
+
58
+DEF_HELPER_FLAGS_5(sve2_sqrshl_zpzz_b, TCG_CALL_NO_RWG,
59
+ void, ptr, ptr, ptr, ptr, i32)
60
+DEF_HELPER_FLAGS_5(sve2_sqrshl_zpzz_h, TCG_CALL_NO_RWG,
61
+ void, ptr, ptr, ptr, ptr, i32)
62
+DEF_HELPER_FLAGS_5(sve2_sqrshl_zpzz_s, TCG_CALL_NO_RWG,
63
+ void, ptr, ptr, ptr, ptr, i32)
64
+DEF_HELPER_FLAGS_5(sve2_sqrshl_zpzz_d, TCG_CALL_NO_RWG,
65
+ void, ptr, ptr, ptr, ptr, i32)
66
+
67
+DEF_HELPER_FLAGS_5(sve2_uqrshl_zpzz_b, TCG_CALL_NO_RWG,
68
+ void, ptr, ptr, ptr, ptr, i32)
69
+DEF_HELPER_FLAGS_5(sve2_uqrshl_zpzz_h, TCG_CALL_NO_RWG,
70
+ void, ptr, ptr, ptr, ptr, i32)
71
+DEF_HELPER_FLAGS_5(sve2_uqrshl_zpzz_s, TCG_CALL_NO_RWG,
72
+ void, ptr, ptr, ptr, ptr, i32)
73
+DEF_HELPER_FLAGS_5(sve2_uqrshl_zpzz_d, TCG_CALL_NO_RWG,
74
+ void, ptr, ptr, ptr, ptr, i32)
75
+
76
DEF_HELPER_FLAGS_5(sve_sdiv_zpzz_s, TCG_CALL_NO_RWG,
77
void, ptr, ptr, ptr, ptr, i32)
78
DEF_HELPER_FLAGS_5(sve_sdiv_zpzz_d, TCG_CALL_NO_RWG,
79
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/arm/sve.decode
82
+++ b/target/arm/sve.decode
83
@@ -XXX,XX +XXX,XX @@ URECPE 01000100 .. 000 000 101 ... ..... ..... @rd_pg_rn
84
URSQRTE 01000100 .. 000 001 101 ... ..... ..... @rd_pg_rn
85
SQABS 01000100 .. 001 000 101 ... ..... ..... @rd_pg_rn
86
SQNEG 01000100 .. 001 001 101 ... ..... ..... @rd_pg_rn
87
+
88
+### SVE2 saturating/rounding bitwise shift left (predicated)
89
+
90
+SRSHL 01000100 .. 000 010 100 ... ..... ..... @rdn_pg_rm
91
+URSHL 01000100 .. 000 011 100 ... ..... ..... @rdn_pg_rm
92
+SRSHL 01000100 .. 000 110 100 ... ..... ..... @rdm_pg_rn # SRSHLR
93
+URSHL 01000100 .. 000 111 100 ... ..... ..... @rdm_pg_rn # URSHLR
94
+
95
+SQSHL 01000100 .. 001 000 100 ... ..... ..... @rdn_pg_rm
96
+UQSHL 01000100 .. 001 001 100 ... ..... ..... @rdn_pg_rm
97
+SQSHL 01000100 .. 001 100 100 ... ..... ..... @rdm_pg_rn # SQSHLR
98
+UQSHL 01000100 .. 001 101 100 ... ..... ..... @rdm_pg_rn # UQSHLR
99
+
100
+SQRSHL 01000100 .. 001 010 100 ... ..... ..... @rdn_pg_rm
101
+UQRSHL 01000100 .. 001 011 100 ... ..... ..... @rdn_pg_rm
102
+SQRSHL 01000100 .. 001 110 100 ... ..... ..... @rdm_pg_rn # SQRSHLR
103
+UQRSHL 01000100 .. 001 111 100 ... ..... ..... @rdm_pg_rn # UQRSHLR
104
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/target/arm/sve_helper.c
107
+++ b/target/arm/sve_helper.c
108
@@ -XXX,XX +XXX,XX @@
109
#include "tcg/tcg-gvec-desc.h"
110
#include "fpu/softfloat.h"
111
#include "tcg/tcg.h"
112
+#include "vec_internal.h"
113
114
115
/* Note that vector data is stored in host-endian 64-bit chunks,
116
@@ -XXX,XX +XXX,XX @@ DO_ZPZZ(sve2_uadalp_zpzz_h, uint16_t, H1_2, do_uadalp_h)
117
DO_ZPZZ(sve2_uadalp_zpzz_s, uint32_t, H1_4, do_uadalp_s)
118
DO_ZPZZ_D(sve2_uadalp_zpzz_d, uint64_t, do_uadalp_d)
119
120
+#define do_srshl_b(n, m) do_sqrshl_bhs(n, m, 8, true, NULL)
121
+#define do_srshl_h(n, m) do_sqrshl_bhs(n, m, 16, true, NULL)
122
+#define do_srshl_s(n, m) do_sqrshl_bhs(n, m, 32, true, NULL)
123
+#define do_srshl_d(n, m) do_sqrshl_d(n, m, true, NULL)
124
+
125
+DO_ZPZZ(sve2_srshl_zpzz_b, int8_t, H1, do_srshl_b)
126
+DO_ZPZZ(sve2_srshl_zpzz_h, int16_t, H1_2, do_srshl_h)
127
+DO_ZPZZ(sve2_srshl_zpzz_s, int32_t, H1_4, do_srshl_s)
128
+DO_ZPZZ_D(sve2_srshl_zpzz_d, int64_t, do_srshl_d)
129
+
130
+#define do_urshl_b(n, m) do_uqrshl_bhs(n, (int8_t)m, 8, true, NULL)
131
+#define do_urshl_h(n, m) do_uqrshl_bhs(n, (int16_t)m, 16, true, NULL)
132
+#define do_urshl_s(n, m) do_uqrshl_bhs(n, m, 32, true, NULL)
133
+#define do_urshl_d(n, m) do_uqrshl_d(n, m, true, NULL)
134
+
135
+DO_ZPZZ(sve2_urshl_zpzz_b, uint8_t, H1, do_urshl_b)
136
+DO_ZPZZ(sve2_urshl_zpzz_h, uint16_t, H1_2, do_urshl_h)
137
+DO_ZPZZ(sve2_urshl_zpzz_s, uint32_t, H1_4, do_urshl_s)
138
+DO_ZPZZ_D(sve2_urshl_zpzz_d, uint64_t, do_urshl_d)
139
+
140
+/*
141
+ * Unlike the NEON and AdvSIMD versions, there is no QC bit to set.
142
+ * We pass in a pointer to a dummy saturation field to trigger
143
+ * the saturating arithmetic but discard the information about
144
+ * whether it has occurred.
145
+ */
146
+#define do_sqshl_b(n, m) \
147
+ ({ uint32_t discard; do_sqrshl_bhs(n, m, 8, false, &discard); })
148
+#define do_sqshl_h(n, m) \
149
+ ({ uint32_t discard; do_sqrshl_bhs(n, m, 16, false, &discard); })
150
+#define do_sqshl_s(n, m) \
151
+ ({ uint32_t discard; do_sqrshl_bhs(n, m, 32, false, &discard); })
152
+#define do_sqshl_d(n, m) \
153
+ ({ uint32_t discard; do_sqrshl_d(n, m, false, &discard); })
154
+
155
+DO_ZPZZ(sve2_sqshl_zpzz_b, int8_t, H1_2, do_sqshl_b)
156
+DO_ZPZZ(sve2_sqshl_zpzz_h, int16_t, H1_2, do_sqshl_h)
157
+DO_ZPZZ(sve2_sqshl_zpzz_s, int32_t, H1_4, do_sqshl_s)
158
+DO_ZPZZ_D(sve2_sqshl_zpzz_d, int64_t, do_sqshl_d)
159
+
160
+#define do_uqshl_b(n, m) \
161
+ ({ uint32_t discard; do_uqrshl_bhs(n, (int8_t)m, 8, false, &discard); })
162
+#define do_uqshl_h(n, m) \
163
+ ({ uint32_t discard; do_uqrshl_bhs(n, (int16_t)m, 16, false, &discard); })
164
+#define do_uqshl_s(n, m) \
165
+ ({ uint32_t discard; do_uqrshl_bhs(n, m, 32, false, &discard); })
166
+#define do_uqshl_d(n, m) \
167
+ ({ uint32_t discard; do_uqrshl_d(n, m, false, &discard); })
168
+
169
+DO_ZPZZ(sve2_uqshl_zpzz_b, uint8_t, H1_2, do_uqshl_b)
170
+DO_ZPZZ(sve2_uqshl_zpzz_h, uint16_t, H1_2, do_uqshl_h)
171
+DO_ZPZZ(sve2_uqshl_zpzz_s, uint32_t, H1_4, do_uqshl_s)
172
+DO_ZPZZ_D(sve2_uqshl_zpzz_d, uint64_t, do_uqshl_d)
173
+
174
+#define do_sqrshl_b(n, m) \
175
+ ({ uint32_t discard; do_sqrshl_bhs(n, m, 8, true, &discard); })
176
+#define do_sqrshl_h(n, m) \
177
+ ({ uint32_t discard; do_sqrshl_bhs(n, m, 16, true, &discard); })
178
+#define do_sqrshl_s(n, m) \
179
+ ({ uint32_t discard; do_sqrshl_bhs(n, m, 32, true, &discard); })
180
+#define do_sqrshl_d(n, m) \
181
+ ({ uint32_t discard; do_sqrshl_d(n, m, true, &discard); })
182
+
183
+DO_ZPZZ(sve2_sqrshl_zpzz_b, int8_t, H1_2, do_sqrshl_b)
184
+DO_ZPZZ(sve2_sqrshl_zpzz_h, int16_t, H1_2, do_sqrshl_h)
185
+DO_ZPZZ(sve2_sqrshl_zpzz_s, int32_t, H1_4, do_sqrshl_s)
186
+DO_ZPZZ_D(sve2_sqrshl_zpzz_d, int64_t, do_sqrshl_d)
187
+
188
+#undef do_sqrshl_d
189
+
190
+#define do_uqrshl_b(n, m) \
191
+ ({ uint32_t discard; do_uqrshl_bhs(n, (int8_t)m, 8, true, &discard); })
192
+#define do_uqrshl_h(n, m) \
193
+ ({ uint32_t discard; do_uqrshl_bhs(n, (int16_t)m, 16, true, &discard); })
194
+#define do_uqrshl_s(n, m) \
195
+ ({ uint32_t discard; do_uqrshl_bhs(n, m, 32, true, &discard); })
196
+#define do_uqrshl_d(n, m) \
197
+ ({ uint32_t discard; do_uqrshl_d(n, m, true, &discard); })
198
+
199
+DO_ZPZZ(sve2_uqrshl_zpzz_b, uint8_t, H1_2, do_uqrshl_b)
200
+DO_ZPZZ(sve2_uqrshl_zpzz_h, uint16_t, H1_2, do_uqrshl_h)
201
+DO_ZPZZ(sve2_uqrshl_zpzz_s, uint32_t, H1_4, do_uqrshl_s)
202
+DO_ZPZZ_D(sve2_uqrshl_zpzz_d, uint64_t, do_uqrshl_d)
203
+
204
+#undef do_uqrshl_d
205
+
206
#undef DO_ZPZZ
207
#undef DO_ZPZZ_D
208
209
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
210
index XXXXXXX..XXXXXXX 100644
211
--- a/target/arm/translate-sve.c
212
+++ b/target/arm/translate-sve.c
213
@@ -XXX,XX +XXX,XX @@ static bool trans_SQNEG(DisasContext *s, arg_rpr_esz *a)
214
};
215
return do_sve2_zpz_ool(s, a, fns[a->esz]);
216
}
217
+
218
+#define DO_SVE2_ZPZZ(NAME, name) \
219
+static bool trans_##NAME(DisasContext *s, arg_rprr_esz *a) \
220
+{ \
221
+ static gen_helper_gvec_4 * const fns[4] = { \
222
+ gen_helper_sve2_##name##_zpzz_b, gen_helper_sve2_##name##_zpzz_h, \
223
+ gen_helper_sve2_##name##_zpzz_s, gen_helper_sve2_##name##_zpzz_d, \
224
+ }; \
225
+ return do_sve2_zpzz_ool(s, a, fns[a->esz]); \
226
+}
227
+
228
+DO_SVE2_ZPZZ(SQSHL, sqshl)
229
+DO_SVE2_ZPZZ(SQRSHL, sqrshl)
230
+DO_SVE2_ZPZZ(SRSHL, srshl)
231
+
232
+DO_SVE2_ZPZZ(UQSHL, uqshl)
233
+DO_SVE2_ZPZZ(UQRSHL, uqrshl)
234
+DO_SVE2_ZPZZ(URSHL, urshl)
235
--
236
2.20.1
237
238
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-8-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 54 ++++++++++++++++++++++++++++++++++++++
9
target/arm/sve.decode | 11 ++++++++
10
target/arm/sve_helper.c | 39 +++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 8 ++++++
12
4 files changed, 112 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_uqrshl_zpzz_s, TCG_CALL_NO_RWG,
19
DEF_HELPER_FLAGS_5(sve2_uqrshl_zpzz_d, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_5(sve2_shadd_zpzz_b, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_5(sve2_shadd_zpzz_h, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_5(sve2_shadd_zpzz_s, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_5(sve2_shadd_zpzz_d, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
+
31
+DEF_HELPER_FLAGS_5(sve2_uhadd_zpzz_b, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_5(sve2_uhadd_zpzz_h, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_5(sve2_uhadd_zpzz_s, TCG_CALL_NO_RWG,
36
+ void, ptr, ptr, ptr, ptr, i32)
37
+DEF_HELPER_FLAGS_5(sve2_uhadd_zpzz_d, TCG_CALL_NO_RWG,
38
+ void, ptr, ptr, ptr, ptr, i32)
39
+
40
+DEF_HELPER_FLAGS_5(sve2_srhadd_zpzz_b, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, ptr, i32)
42
+DEF_HELPER_FLAGS_5(sve2_srhadd_zpzz_h, TCG_CALL_NO_RWG,
43
+ void, ptr, ptr, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_5(sve2_srhadd_zpzz_s, TCG_CALL_NO_RWG,
45
+ void, ptr, ptr, ptr, ptr, i32)
46
+DEF_HELPER_FLAGS_5(sve2_srhadd_zpzz_d, TCG_CALL_NO_RWG,
47
+ void, ptr, ptr, ptr, ptr, i32)
48
+
49
+DEF_HELPER_FLAGS_5(sve2_urhadd_zpzz_b, TCG_CALL_NO_RWG,
50
+ void, ptr, ptr, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_5(sve2_urhadd_zpzz_h, TCG_CALL_NO_RWG,
52
+ void, ptr, ptr, ptr, ptr, i32)
53
+DEF_HELPER_FLAGS_5(sve2_urhadd_zpzz_s, TCG_CALL_NO_RWG,
54
+ void, ptr, ptr, ptr, ptr, i32)
55
+DEF_HELPER_FLAGS_5(sve2_urhadd_zpzz_d, TCG_CALL_NO_RWG,
56
+ void, ptr, ptr, ptr, ptr, i32)
57
+
58
+DEF_HELPER_FLAGS_5(sve2_shsub_zpzz_b, TCG_CALL_NO_RWG,
59
+ void, ptr, ptr, ptr, ptr, i32)
60
+DEF_HELPER_FLAGS_5(sve2_shsub_zpzz_h, TCG_CALL_NO_RWG,
61
+ void, ptr, ptr, ptr, ptr, i32)
62
+DEF_HELPER_FLAGS_5(sve2_shsub_zpzz_s, TCG_CALL_NO_RWG,
63
+ void, ptr, ptr, ptr, ptr, i32)
64
+DEF_HELPER_FLAGS_5(sve2_shsub_zpzz_d, TCG_CALL_NO_RWG,
65
+ void, ptr, ptr, ptr, ptr, i32)
66
+
67
+DEF_HELPER_FLAGS_5(sve2_uhsub_zpzz_b, TCG_CALL_NO_RWG,
68
+ void, ptr, ptr, ptr, ptr, i32)
69
+DEF_HELPER_FLAGS_5(sve2_uhsub_zpzz_h, TCG_CALL_NO_RWG,
70
+ void, ptr, ptr, ptr, ptr, i32)
71
+DEF_HELPER_FLAGS_5(sve2_uhsub_zpzz_s, TCG_CALL_NO_RWG,
72
+ void, ptr, ptr, ptr, ptr, i32)
73
+DEF_HELPER_FLAGS_5(sve2_uhsub_zpzz_d, TCG_CALL_NO_RWG,
74
+ void, ptr, ptr, ptr, ptr, i32)
75
+
76
DEF_HELPER_FLAGS_5(sve_sdiv_zpzz_s, TCG_CALL_NO_RWG,
77
void, ptr, ptr, ptr, ptr, i32)
78
DEF_HELPER_FLAGS_5(sve_sdiv_zpzz_d, TCG_CALL_NO_RWG,
79
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/arm/sve.decode
82
+++ b/target/arm/sve.decode
83
@@ -XXX,XX +XXX,XX @@ SQRSHL 01000100 .. 001 010 100 ... ..... ..... @rdn_pg_rm
84
UQRSHL 01000100 .. 001 011 100 ... ..... ..... @rdn_pg_rm
85
SQRSHL 01000100 .. 001 110 100 ... ..... ..... @rdm_pg_rn # SQRSHLR
86
UQRSHL 01000100 .. 001 111 100 ... ..... ..... @rdm_pg_rn # UQRSHLR
87
+
88
+### SVE2 integer halving add/subtract (predicated)
89
+
90
+SHADD 01000100 .. 010 000 100 ... ..... ..... @rdn_pg_rm
91
+UHADD 01000100 .. 010 001 100 ... ..... ..... @rdn_pg_rm
92
+SHSUB 01000100 .. 010 010 100 ... ..... ..... @rdn_pg_rm
93
+UHSUB 01000100 .. 010 011 100 ... ..... ..... @rdn_pg_rm
94
+SRHADD 01000100 .. 010 100 100 ... ..... ..... @rdn_pg_rm
95
+URHADD 01000100 .. 010 101 100 ... ..... ..... @rdn_pg_rm
96
+SHSUB 01000100 .. 010 110 100 ... ..... ..... @rdm_pg_rn # SHSUBR
97
+UHSUB 01000100 .. 010 111 100 ... ..... ..... @rdm_pg_rn # UHSUBR
98
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/sve_helper.c
101
+++ b/target/arm/sve_helper.c
102
@@ -XXX,XX +XXX,XX @@ DO_ZPZZ_D(sve2_uqrshl_zpzz_d, uint64_t, do_uqrshl_d)
103
104
#undef do_uqrshl_d
105
106
+#define DO_HADD_BHS(n, m) (((int64_t)n + m) >> 1)
107
+#define DO_HADD_D(n, m) ((n >> 1) + (m >> 1) + (n & m & 1))
108
+
109
+DO_ZPZZ(sve2_shadd_zpzz_b, int8_t, H1, DO_HADD_BHS)
110
+DO_ZPZZ(sve2_shadd_zpzz_h, int16_t, H1_2, DO_HADD_BHS)
111
+DO_ZPZZ(sve2_shadd_zpzz_s, int32_t, H1_4, DO_HADD_BHS)
112
+DO_ZPZZ_D(sve2_shadd_zpzz_d, int64_t, DO_HADD_D)
113
+
114
+DO_ZPZZ(sve2_uhadd_zpzz_b, uint8_t, H1, DO_HADD_BHS)
115
+DO_ZPZZ(sve2_uhadd_zpzz_h, uint16_t, H1_2, DO_HADD_BHS)
116
+DO_ZPZZ(sve2_uhadd_zpzz_s, uint32_t, H1_4, DO_HADD_BHS)
117
+DO_ZPZZ_D(sve2_uhadd_zpzz_d, uint64_t, DO_HADD_D)
118
+
119
+#define DO_RHADD_BHS(n, m) (((int64_t)n + m + 1) >> 1)
120
+#define DO_RHADD_D(n, m) ((n >> 1) + (m >> 1) + ((n | m) & 1))
121
+
122
+DO_ZPZZ(sve2_srhadd_zpzz_b, int8_t, H1, DO_RHADD_BHS)
123
+DO_ZPZZ(sve2_srhadd_zpzz_h, int16_t, H1_2, DO_RHADD_BHS)
124
+DO_ZPZZ(sve2_srhadd_zpzz_s, int32_t, H1_4, DO_RHADD_BHS)
125
+DO_ZPZZ_D(sve2_srhadd_zpzz_d, int64_t, DO_RHADD_D)
126
+
127
+DO_ZPZZ(sve2_urhadd_zpzz_b, uint8_t, H1, DO_RHADD_BHS)
128
+DO_ZPZZ(sve2_urhadd_zpzz_h, uint16_t, H1_2, DO_RHADD_BHS)
129
+DO_ZPZZ(sve2_urhadd_zpzz_s, uint32_t, H1_4, DO_RHADD_BHS)
130
+DO_ZPZZ_D(sve2_urhadd_zpzz_d, uint64_t, DO_RHADD_D)
131
+
132
+#define DO_HSUB_BHS(n, m) (((int64_t)n - m) >> 1)
133
+#define DO_HSUB_D(n, m) ((n >> 1) - (m >> 1) - (~n & m & 1))
134
+
135
+DO_ZPZZ(sve2_shsub_zpzz_b, int8_t, H1, DO_HSUB_BHS)
136
+DO_ZPZZ(sve2_shsub_zpzz_h, int16_t, H1_2, DO_HSUB_BHS)
137
+DO_ZPZZ(sve2_shsub_zpzz_s, int32_t, H1_4, DO_HSUB_BHS)
138
+DO_ZPZZ_D(sve2_shsub_zpzz_d, int64_t, DO_HSUB_D)
139
+
140
+DO_ZPZZ(sve2_uhsub_zpzz_b, uint8_t, H1, DO_HSUB_BHS)
141
+DO_ZPZZ(sve2_uhsub_zpzz_h, uint16_t, H1_2, DO_HSUB_BHS)
142
+DO_ZPZZ(sve2_uhsub_zpzz_s, uint32_t, H1_4, DO_HSUB_BHS)
143
+DO_ZPZZ_D(sve2_uhsub_zpzz_d, uint64_t, DO_HSUB_D)
144
+
145
#undef DO_ZPZZ
146
#undef DO_ZPZZ_D
147
148
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/target/arm/translate-sve.c
151
+++ b/target/arm/translate-sve.c
152
@@ -XXX,XX +XXX,XX @@ DO_SVE2_ZPZZ(SRSHL, srshl)
153
DO_SVE2_ZPZZ(UQSHL, uqshl)
154
DO_SVE2_ZPZZ(UQRSHL, uqrshl)
155
DO_SVE2_ZPZZ(URSHL, urshl)
156
+
157
+DO_SVE2_ZPZZ(SHADD, shadd)
158
+DO_SVE2_ZPZZ(SRHADD, srhadd)
159
+DO_SVE2_ZPZZ(SHSUB, shsub)
160
+
161
+DO_SVE2_ZPZZ(UHADD, uhadd)
162
+DO_SVE2_ZPZZ(URHADD, urhadd)
163
+DO_SVE2_ZPZZ(UHSUB, uhsub)
164
--
165
2.20.1
166
167
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-9-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 45 ++++++++++++++++++++++
9
target/arm/sve.decode | 8 ++++
10
target/arm/sve_helper.c | 76 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 6 +++
12
4 files changed, 135 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_sel_zpzz_s, TCG_CALL_NO_RWG,
19
DEF_HELPER_FLAGS_5(sve_sel_zpzz_d, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_5(sve2_addp_zpzz_b, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_5(sve2_addp_zpzz_h, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_5(sve2_addp_zpzz_s, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_5(sve2_addp_zpzz_d, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
+
31
+DEF_HELPER_FLAGS_5(sve2_smaxp_zpzz_b, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_5(sve2_smaxp_zpzz_h, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_5(sve2_smaxp_zpzz_s, TCG_CALL_NO_RWG,
36
+ void, ptr, ptr, ptr, ptr, i32)
37
+DEF_HELPER_FLAGS_5(sve2_smaxp_zpzz_d, TCG_CALL_NO_RWG,
38
+ void, ptr, ptr, ptr, ptr, i32)
39
+
40
+DEF_HELPER_FLAGS_5(sve2_umaxp_zpzz_b, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, ptr, i32)
42
+DEF_HELPER_FLAGS_5(sve2_umaxp_zpzz_h, TCG_CALL_NO_RWG,
43
+ void, ptr, ptr, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_5(sve2_umaxp_zpzz_s, TCG_CALL_NO_RWG,
45
+ void, ptr, ptr, ptr, ptr, i32)
46
+DEF_HELPER_FLAGS_5(sve2_umaxp_zpzz_d, TCG_CALL_NO_RWG,
47
+ void, ptr, ptr, ptr, ptr, i32)
48
+
49
+DEF_HELPER_FLAGS_5(sve2_sminp_zpzz_b, TCG_CALL_NO_RWG,
50
+ void, ptr, ptr, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_5(sve2_sminp_zpzz_h, TCG_CALL_NO_RWG,
52
+ void, ptr, ptr, ptr, ptr, i32)
53
+DEF_HELPER_FLAGS_5(sve2_sminp_zpzz_s, TCG_CALL_NO_RWG,
54
+ void, ptr, ptr, ptr, ptr, i32)
55
+DEF_HELPER_FLAGS_5(sve2_sminp_zpzz_d, TCG_CALL_NO_RWG,
56
+ void, ptr, ptr, ptr, ptr, i32)
57
+
58
+DEF_HELPER_FLAGS_5(sve2_uminp_zpzz_b, TCG_CALL_NO_RWG,
59
+ void, ptr, ptr, ptr, ptr, i32)
60
+DEF_HELPER_FLAGS_5(sve2_uminp_zpzz_h, TCG_CALL_NO_RWG,
61
+ void, ptr, ptr, ptr, ptr, i32)
62
+DEF_HELPER_FLAGS_5(sve2_uminp_zpzz_s, TCG_CALL_NO_RWG,
63
+ void, ptr, ptr, ptr, ptr, i32)
64
+DEF_HELPER_FLAGS_5(sve2_uminp_zpzz_d, TCG_CALL_NO_RWG,
65
+ void, ptr, ptr, ptr, ptr, i32)
66
+
67
DEF_HELPER_FLAGS_5(sve_asr_zpzw_b, TCG_CALL_NO_RWG,
68
void, ptr, ptr, ptr, ptr, i32)
69
DEF_HELPER_FLAGS_5(sve_asr_zpzw_h, TCG_CALL_NO_RWG,
70
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/sve.decode
73
+++ b/target/arm/sve.decode
74
@@ -XXX,XX +XXX,XX @@ SRHADD 01000100 .. 010 100 100 ... ..... ..... @rdn_pg_rm
75
URHADD 01000100 .. 010 101 100 ... ..... ..... @rdn_pg_rm
76
SHSUB 01000100 .. 010 110 100 ... ..... ..... @rdm_pg_rn # SHSUBR
77
UHSUB 01000100 .. 010 111 100 ... ..... ..... @rdm_pg_rn # UHSUBR
78
+
79
+### SVE2 integer pairwise arithmetic
80
+
81
+ADDP 01000100 .. 010 001 101 ... ..... ..... @rdn_pg_rm
82
+SMAXP 01000100 .. 010 100 101 ... ..... ..... @rdn_pg_rm
83
+UMAXP 01000100 .. 010 101 101 ... ..... ..... @rdn_pg_rm
84
+SMINP 01000100 .. 010 110 101 ... ..... ..... @rdn_pg_rm
85
+UMINP 01000100 .. 010 111 101 ... ..... ..... @rdn_pg_rm
86
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/arm/sve_helper.c
89
+++ b/target/arm/sve_helper.c
90
@@ -XXX,XX +XXX,XX @@ DO_ZPZZ_D(sve2_uhsub_zpzz_d, uint64_t, DO_HSUB_D)
91
#undef DO_ZPZZ
92
#undef DO_ZPZZ_D
93
94
+/*
95
+ * Three operand expander, operating on element pairs.
96
+ * If the slot I is even, the elements from from VN {I, I+1}.
97
+ * If the slot I is odd, the elements from from VM {I-1, I}.
98
+ * Load all of the input elements in each pair before overwriting output.
99
+ */
100
+#define DO_ZPZZ_PAIR(NAME, TYPE, H, OP) \
101
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, uint32_t desc) \
102
+{ \
103
+ intptr_t i, opr_sz = simd_oprsz(desc); \
104
+ for (i = 0; i < opr_sz; ) { \
105
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
106
+ do { \
107
+ TYPE n0 = *(TYPE *)(vn + H(i)); \
108
+ TYPE m0 = *(TYPE *)(vm + H(i)); \
109
+ TYPE n1 = *(TYPE *)(vn + H(i + sizeof(TYPE))); \
110
+ TYPE m1 = *(TYPE *)(vm + H(i + sizeof(TYPE))); \
111
+ if (pg & 1) { \
112
+ *(TYPE *)(vd + H(i)) = OP(n0, n1); \
113
+ } \
114
+ i += sizeof(TYPE), pg >>= sizeof(TYPE); \
115
+ if (pg & 1) { \
116
+ *(TYPE *)(vd + H(i)) = OP(m0, m1); \
117
+ } \
118
+ i += sizeof(TYPE), pg >>= sizeof(TYPE); \
119
+ } while (i & 15); \
120
+ } \
121
+}
122
+
123
+/* Similarly, specialized for 64-bit operands. */
124
+#define DO_ZPZZ_PAIR_D(NAME, TYPE, OP) \
125
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, uint32_t desc) \
126
+{ \
127
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8; \
128
+ TYPE *d = vd, *n = vn, *m = vm; \
129
+ uint8_t *pg = vg; \
130
+ for (i = 0; i < opr_sz; i += 2) { \
131
+ TYPE n0 = n[i], n1 = n[i + 1]; \
132
+ TYPE m0 = m[i], m1 = m[i + 1]; \
133
+ if (pg[H1(i)] & 1) { \
134
+ d[i] = OP(n0, n1); \
135
+ } \
136
+ if (pg[H1(i + 1)] & 1) { \
137
+ d[i + 1] = OP(m0, m1); \
138
+ } \
139
+ } \
140
+}
141
+
142
+DO_ZPZZ_PAIR(sve2_addp_zpzz_b, uint8_t, H1, DO_ADD)
143
+DO_ZPZZ_PAIR(sve2_addp_zpzz_h, uint16_t, H1_2, DO_ADD)
144
+DO_ZPZZ_PAIR(sve2_addp_zpzz_s, uint32_t, H1_4, DO_ADD)
145
+DO_ZPZZ_PAIR_D(sve2_addp_zpzz_d, uint64_t, DO_ADD)
146
+
147
+DO_ZPZZ_PAIR(sve2_umaxp_zpzz_b, uint8_t, H1, DO_MAX)
148
+DO_ZPZZ_PAIR(sve2_umaxp_zpzz_h, uint16_t, H1_2, DO_MAX)
149
+DO_ZPZZ_PAIR(sve2_umaxp_zpzz_s, uint32_t, H1_4, DO_MAX)
150
+DO_ZPZZ_PAIR_D(sve2_umaxp_zpzz_d, uint64_t, DO_MAX)
151
+
152
+DO_ZPZZ_PAIR(sve2_uminp_zpzz_b, uint8_t, H1, DO_MIN)
153
+DO_ZPZZ_PAIR(sve2_uminp_zpzz_h, uint16_t, H1_2, DO_MIN)
154
+DO_ZPZZ_PAIR(sve2_uminp_zpzz_s, uint32_t, H1_4, DO_MIN)
155
+DO_ZPZZ_PAIR_D(sve2_uminp_zpzz_d, uint64_t, DO_MIN)
156
+
157
+DO_ZPZZ_PAIR(sve2_smaxp_zpzz_b, int8_t, H1, DO_MAX)
158
+DO_ZPZZ_PAIR(sve2_smaxp_zpzz_h, int16_t, H1_2, DO_MAX)
159
+DO_ZPZZ_PAIR(sve2_smaxp_zpzz_s, int32_t, H1_4, DO_MAX)
160
+DO_ZPZZ_PAIR_D(sve2_smaxp_zpzz_d, int64_t, DO_MAX)
161
+
162
+DO_ZPZZ_PAIR(sve2_sminp_zpzz_b, int8_t, H1, DO_MIN)
163
+DO_ZPZZ_PAIR(sve2_sminp_zpzz_h, int16_t, H1_2, DO_MIN)
164
+DO_ZPZZ_PAIR(sve2_sminp_zpzz_s, int32_t, H1_4, DO_MIN)
165
+DO_ZPZZ_PAIR_D(sve2_sminp_zpzz_d, int64_t, DO_MIN)
166
+
167
+#undef DO_ZPZZ_PAIR
168
+#undef DO_ZPZZ_PAIR_D
169
+
170
/* Three-operand expander, controlled by a predicate, in which the
171
* third operand is "wide". That is, for D = N op M, the same 64-bit
172
* value of M is used with all of the narrower values of N.
173
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
174
index XXXXXXX..XXXXXXX 100644
175
--- a/target/arm/translate-sve.c
176
+++ b/target/arm/translate-sve.c
177
@@ -XXX,XX +XXX,XX @@ DO_SVE2_ZPZZ(SHSUB, shsub)
178
DO_SVE2_ZPZZ(UHADD, uhadd)
179
DO_SVE2_ZPZZ(URHADD, urhadd)
180
DO_SVE2_ZPZZ(UHSUB, uhsub)
181
+
182
+DO_SVE2_ZPZZ(ADDP, addp)
183
+DO_SVE2_ZPZZ(SMAXP, smaxp)
184
+DO_SVE2_ZPZZ(UMAXP, umaxp)
185
+DO_SVE2_ZPZZ(SMINP, sminp)
186
+DO_SVE2_ZPZZ(UMINP, uminp)
187
--
188
2.20.1
189
190
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-11-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 24 ++++++++++++++++++++
9
target/arm/sve.decode | 19 ++++++++++++++++
10
target/arm/sve_helper.c | 43 +++++++++++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 46 ++++++++++++++++++++++++++++++++++++++
12
4 files changed, 132 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_ftmad_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
19
DEF_HELPER_FLAGS_5(sve_ftmad_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_5(sve_ftmad_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_4(sve2_saddl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
+DEF_HELPER_FLAGS_4(sve2_saddl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_4(sve2_saddl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
+
26
+DEF_HELPER_FLAGS_4(sve2_ssubl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(sve2_ssubl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(sve2_ssubl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
+
30
+DEF_HELPER_FLAGS_4(sve2_sabdl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(sve2_sabdl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(sve2_sabdl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
+
34
+DEF_HELPER_FLAGS_4(sve2_uaddl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_4(sve2_uaddl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_4(sve2_uaddl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
37
+
38
+DEF_HELPER_FLAGS_4(sve2_usubl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_4(sve2_usubl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_4(sve2_usubl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
41
+
42
+DEF_HELPER_FLAGS_4(sve2_uabdl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_4(sve2_uabdl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_4(sve2_uabdl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
45
+
46
DEF_HELPER_FLAGS_4(sve_ld1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
47
DEF_HELPER_FLAGS_4(sve_ld2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
48
DEF_HELPER_FLAGS_4(sve_ld3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
49
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/sve.decode
52
+++ b/target/arm/sve.decode
53
@@ -XXX,XX +XXX,XX @@ SUQADD 01000100 .. 011 100 100 ... ..... ..... @rdn_pg_rm
54
USQADD 01000100 .. 011 101 100 ... ..... ..... @rdn_pg_rm
55
SQSUB_zpzz 01000100 .. 011 110 100 ... ..... ..... @rdm_pg_rn # SQSUBR
56
UQSUB_zpzz 01000100 .. 011 111 100 ... ..... ..... @rdm_pg_rn # UQSUBR
57
+
58
+#### SVE2 Widening Integer Arithmetic
59
+
60
+## SVE2 integer add/subtract long
61
+
62
+SADDLB 01000101 .. 0 ..... 00 0000 ..... ..... @rd_rn_rm
63
+SADDLT 01000101 .. 0 ..... 00 0001 ..... ..... @rd_rn_rm
64
+UADDLB 01000101 .. 0 ..... 00 0010 ..... ..... @rd_rn_rm
65
+UADDLT 01000101 .. 0 ..... 00 0011 ..... ..... @rd_rn_rm
66
+
67
+SSUBLB 01000101 .. 0 ..... 00 0100 ..... ..... @rd_rn_rm
68
+SSUBLT 01000101 .. 0 ..... 00 0101 ..... ..... @rd_rn_rm
69
+USUBLB 01000101 .. 0 ..... 00 0110 ..... ..... @rd_rn_rm
70
+USUBLT 01000101 .. 0 ..... 00 0111 ..... ..... @rd_rn_rm
71
+
72
+SABDLB 01000101 .. 0 ..... 00 1100 ..... ..... @rd_rn_rm
73
+SABDLT 01000101 .. 0 ..... 00 1101 ..... ..... @rd_rn_rm
74
+UABDLB 01000101 .. 0 ..... 00 1110 ..... ..... @rd_rn_rm
75
+UABDLT 01000101 .. 0 ..... 00 1111 ..... ..... @rd_rn_rm
76
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/sve_helper.c
79
+++ b/target/arm/sve_helper.c
80
@@ -XXX,XX +XXX,XX @@ DO_ZZW(sve_lsl_zzw_s, uint32_t, uint64_t, H1_4, DO_LSL)
81
#undef DO_ZPZ
82
#undef DO_ZPZ_D
83
84
+/*
85
+ * Three-operand expander, unpredicated, in which the two inputs are
86
+ * selected from the top or bottom half of the wide column.
87
+ */
88
+#define DO_ZZZ_TB(NAME, TYPEW, TYPEN, HW, HN, OP) \
89
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
90
+{ \
91
+ intptr_t i, opr_sz = simd_oprsz(desc); \
92
+ int sel1 = extract32(desc, SIMD_DATA_SHIFT, 1) * sizeof(TYPEN); \
93
+ int sel2 = extract32(desc, SIMD_DATA_SHIFT + 1, 1) * sizeof(TYPEN); \
94
+ for (i = 0; i < opr_sz; i += sizeof(TYPEW)) { \
95
+ TYPEW nn = *(TYPEN *)(vn + HN(i + sel1)); \
96
+ TYPEW mm = *(TYPEN *)(vm + HN(i + sel2)); \
97
+ *(TYPEW *)(vd + HW(i)) = OP(nn, mm); \
98
+ } \
99
+}
100
+
101
+DO_ZZZ_TB(sve2_saddl_h, int16_t, int8_t, H1_2, H1, DO_ADD)
102
+DO_ZZZ_TB(sve2_saddl_s, int32_t, int16_t, H1_4, H1_2, DO_ADD)
103
+DO_ZZZ_TB(sve2_saddl_d, int64_t, int32_t, , H1_4, DO_ADD)
104
+
105
+DO_ZZZ_TB(sve2_ssubl_h, int16_t, int8_t, H1_2, H1, DO_SUB)
106
+DO_ZZZ_TB(sve2_ssubl_s, int32_t, int16_t, H1_4, H1_2, DO_SUB)
107
+DO_ZZZ_TB(sve2_ssubl_d, int64_t, int32_t, , H1_4, DO_SUB)
108
+
109
+DO_ZZZ_TB(sve2_sabdl_h, int16_t, int8_t, H1_2, H1, DO_ABD)
110
+DO_ZZZ_TB(sve2_sabdl_s, int32_t, int16_t, H1_4, H1_2, DO_ABD)
111
+DO_ZZZ_TB(sve2_sabdl_d, int64_t, int32_t, , H1_4, DO_ABD)
112
+
113
+DO_ZZZ_TB(sve2_uaddl_h, uint16_t, uint8_t, H1_2, H1, DO_ADD)
114
+DO_ZZZ_TB(sve2_uaddl_s, uint32_t, uint16_t, H1_4, H1_2, DO_ADD)
115
+DO_ZZZ_TB(sve2_uaddl_d, uint64_t, uint32_t, , H1_4, DO_ADD)
116
+
117
+DO_ZZZ_TB(sve2_usubl_h, uint16_t, uint8_t, H1_2, H1, DO_SUB)
118
+DO_ZZZ_TB(sve2_usubl_s, uint32_t, uint16_t, H1_4, H1_2, DO_SUB)
119
+DO_ZZZ_TB(sve2_usubl_d, uint64_t, uint32_t, , H1_4, DO_SUB)
120
+
121
+DO_ZZZ_TB(sve2_uabdl_h, uint16_t, uint8_t, H1_2, H1, DO_ABD)
122
+DO_ZZZ_TB(sve2_uabdl_s, uint32_t, uint16_t, H1_4, H1_2, DO_ABD)
123
+DO_ZZZ_TB(sve2_uabdl_d, uint64_t, uint32_t, , H1_4, DO_ABD)
124
+
125
+#undef DO_ZZZ_TB
126
+
127
/* Two-operand reduction expander, controlled by a predicate.
128
* The difference between TYPERED and TYPERET has to do with
129
* sign-extension. E.g. for SMAX, TYPERED must be signed,
130
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/target/arm/translate-sve.c
133
+++ b/target/arm/translate-sve.c
134
@@ -XXX,XX +XXX,XX @@ DO_SVE2_ZPZZ(SQSUB_zpzz, sqsub)
135
DO_SVE2_ZPZZ(UQSUB_zpzz, uqsub)
136
DO_SVE2_ZPZZ(SUQADD, suqadd)
137
DO_SVE2_ZPZZ(USQADD, usqadd)
138
+
139
+/*
140
+ * SVE2 Widening Integer Arithmetic
141
+ */
142
+
143
+static bool do_sve2_zzw_ool(DisasContext *s, arg_rrr_esz *a,
144
+ gen_helper_gvec_3 *fn, int data)
145
+{
146
+ if (fn == NULL || !dc_isar_feature(aa64_sve2, s)) {
147
+ return false;
148
+ }
149
+ if (sve_access_check(s)) {
150
+ unsigned vsz = vec_full_reg_size(s);
151
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
152
+ vec_full_reg_offset(s, a->rn),
153
+ vec_full_reg_offset(s, a->rm),
154
+ vsz, vsz, data, fn);
155
+ }
156
+ return true;
157
+}
158
+
159
+#define DO_SVE2_ZZZ_TB(NAME, name, SEL1, SEL2) \
160
+static bool trans_##NAME(DisasContext *s, arg_rrr_esz *a) \
161
+{ \
162
+ static gen_helper_gvec_3 * const fns[4] = { \
163
+ NULL, gen_helper_sve2_##name##_h, \
164
+ gen_helper_sve2_##name##_s, gen_helper_sve2_##name##_d, \
165
+ }; \
166
+ return do_sve2_zzw_ool(s, a, fns[a->esz], (SEL2 << 1) | SEL1); \
167
+}
168
+
169
+DO_SVE2_ZZZ_TB(SADDLB, saddl, false, false)
170
+DO_SVE2_ZZZ_TB(SSUBLB, ssubl, false, false)
171
+DO_SVE2_ZZZ_TB(SABDLB, sabdl, false, false)
172
+
173
+DO_SVE2_ZZZ_TB(UADDLB, uaddl, false, false)
174
+DO_SVE2_ZZZ_TB(USUBLB, usubl, false, false)
175
+DO_SVE2_ZZZ_TB(UABDLB, uabdl, false, false)
176
+
177
+DO_SVE2_ZZZ_TB(SADDLT, saddl, true, true)
178
+DO_SVE2_ZZZ_TB(SSUBLT, ssubl, true, true)
179
+DO_SVE2_ZZZ_TB(SABDLT, sabdl, true, true)
180
+
181
+DO_SVE2_ZZZ_TB(UADDLT, uaddl, true, true)
182
+DO_SVE2_ZZZ_TB(USUBLT, usubl, true, true)
183
+DO_SVE2_ZZZ_TB(UABDLT, uabdl, true, true)
184
--
185
2.20.1
186
187
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-12-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/sve.decode | 6 ++++++
9
target/arm/translate-sve.c | 4 ++++
10
2 files changed, 10 insertions(+)
11
12
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/sve.decode
15
+++ b/target/arm/sve.decode
16
@@ -XXX,XX +XXX,XX @@ SABDLB 01000101 .. 0 ..... 00 1100 ..... ..... @rd_rn_rm
17
SABDLT 01000101 .. 0 ..... 00 1101 ..... ..... @rd_rn_rm
18
UABDLB 01000101 .. 0 ..... 00 1110 ..... ..... @rd_rn_rm
19
UABDLT 01000101 .. 0 ..... 00 1111 ..... ..... @rd_rn_rm
20
+
21
+## SVE2 integer add/subtract interleaved long
22
+
23
+SADDLBT 01000101 .. 0 ..... 1000 00 ..... ..... @rd_rn_rm
24
+SSUBLBT 01000101 .. 0 ..... 1000 10 ..... ..... @rd_rn_rm
25
+SSUBLTB 01000101 .. 0 ..... 1000 11 ..... ..... @rd_rn_rm
26
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/translate-sve.c
29
+++ b/target/arm/translate-sve.c
30
@@ -XXX,XX +XXX,XX @@ DO_SVE2_ZZZ_TB(SABDLT, sabdl, true, true)
31
DO_SVE2_ZZZ_TB(UADDLT, uaddl, true, true)
32
DO_SVE2_ZZZ_TB(USUBLT, usubl, true, true)
33
DO_SVE2_ZZZ_TB(UABDLT, uabdl, true, true)
34
+
35
+DO_SVE2_ZZZ_TB(SADDLBT, saddl, false, true)
36
+DO_SVE2_ZZZ_TB(SSUBLBT, ssubl, false, true)
37
+DO_SVE2_ZZZ_TB(SSUBLTB, ssubl, true, false)
38
--
39
2.20.1
40
41
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-13-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 16 ++++++++++++++++
9
target/arm/sve.decode | 12 ++++++++++++
10
target/arm/sve_helper.c | 30 ++++++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 20 ++++++++++++++++++++
12
4 files changed, 78 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve2_uabdl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
19
DEF_HELPER_FLAGS_4(sve2_uabdl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_4(sve2_uabdl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_4(sve2_saddw_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
+DEF_HELPER_FLAGS_4(sve2_saddw_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_4(sve2_saddw_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
+
26
+DEF_HELPER_FLAGS_4(sve2_ssubw_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(sve2_ssubw_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(sve2_ssubw_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
+
30
+DEF_HELPER_FLAGS_4(sve2_uaddw_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(sve2_uaddw_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(sve2_uaddw_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
+
34
+DEF_HELPER_FLAGS_4(sve2_usubw_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_4(sve2_usubw_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_4(sve2_usubw_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
37
+
38
DEF_HELPER_FLAGS_4(sve_ld1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
39
DEF_HELPER_FLAGS_4(sve_ld2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
40
DEF_HELPER_FLAGS_4(sve_ld3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
41
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/sve.decode
44
+++ b/target/arm/sve.decode
45
@@ -XXX,XX +XXX,XX @@ UABDLT 01000101 .. 0 ..... 00 1111 ..... ..... @rd_rn_rm
46
SADDLBT 01000101 .. 0 ..... 1000 00 ..... ..... @rd_rn_rm
47
SSUBLBT 01000101 .. 0 ..... 1000 10 ..... ..... @rd_rn_rm
48
SSUBLTB 01000101 .. 0 ..... 1000 11 ..... ..... @rd_rn_rm
49
+
50
+## SVE2 integer add/subtract wide
51
+
52
+SADDWB 01000101 .. 0 ..... 010 000 ..... ..... @rd_rn_rm
53
+SADDWT 01000101 .. 0 ..... 010 001 ..... ..... @rd_rn_rm
54
+UADDWB 01000101 .. 0 ..... 010 010 ..... ..... @rd_rn_rm
55
+UADDWT 01000101 .. 0 ..... 010 011 ..... ..... @rd_rn_rm
56
+
57
+SSUBWB 01000101 .. 0 ..... 010 100 ..... ..... @rd_rn_rm
58
+SSUBWT 01000101 .. 0 ..... 010 101 ..... ..... @rd_rn_rm
59
+USUBWB 01000101 .. 0 ..... 010 110 ..... ..... @rd_rn_rm
60
+USUBWT 01000101 .. 0 ..... 010 111 ..... ..... @rd_rn_rm
61
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/sve_helper.c
64
+++ b/target/arm/sve_helper.c
65
@@ -XXX,XX +XXX,XX @@ DO_ZZZ_TB(sve2_uabdl_d, uint64_t, uint32_t, , H1_4, DO_ABD)
66
67
#undef DO_ZZZ_TB
68
69
+#define DO_ZZZ_WTB(NAME, TYPEW, TYPEN, HW, HN, OP) \
70
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
71
+{ \
72
+ intptr_t i, opr_sz = simd_oprsz(desc); \
73
+ int sel2 = extract32(desc, SIMD_DATA_SHIFT, 1) * sizeof(TYPEN); \
74
+ for (i = 0; i < opr_sz; i += sizeof(TYPEW)) { \
75
+ TYPEW nn = *(TYPEW *)(vn + HW(i)); \
76
+ TYPEW mm = *(TYPEN *)(vm + HN(i + sel2)); \
77
+ *(TYPEW *)(vd + HW(i)) = OP(nn, mm); \
78
+ } \
79
+}
80
+
81
+DO_ZZZ_WTB(sve2_saddw_h, int16_t, int8_t, H1_2, H1, DO_ADD)
82
+DO_ZZZ_WTB(sve2_saddw_s, int32_t, int16_t, H1_4, H1_2, DO_ADD)
83
+DO_ZZZ_WTB(sve2_saddw_d, int64_t, int32_t, , H1_4, DO_ADD)
84
+
85
+DO_ZZZ_WTB(sve2_ssubw_h, int16_t, int8_t, H1_2, H1, DO_SUB)
86
+DO_ZZZ_WTB(sve2_ssubw_s, int32_t, int16_t, H1_4, H1_2, DO_SUB)
87
+DO_ZZZ_WTB(sve2_ssubw_d, int64_t, int32_t, , H1_4, DO_SUB)
88
+
89
+DO_ZZZ_WTB(sve2_uaddw_h, uint16_t, uint8_t, H1_2, H1, DO_ADD)
90
+DO_ZZZ_WTB(sve2_uaddw_s, uint32_t, uint16_t, H1_4, H1_2, DO_ADD)
91
+DO_ZZZ_WTB(sve2_uaddw_d, uint64_t, uint32_t, , H1_4, DO_ADD)
92
+
93
+DO_ZZZ_WTB(sve2_usubw_h, uint16_t, uint8_t, H1_2, H1, DO_SUB)
94
+DO_ZZZ_WTB(sve2_usubw_s, uint32_t, uint16_t, H1_4, H1_2, DO_SUB)
95
+DO_ZZZ_WTB(sve2_usubw_d, uint64_t, uint32_t, , H1_4, DO_SUB)
96
+
97
+#undef DO_ZZZ_WTB
98
+
99
/* Two-operand reduction expander, controlled by a predicate.
100
* The difference between TYPERED and TYPERET has to do with
101
* sign-extension. E.g. for SMAX, TYPERED must be signed,
102
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/translate-sve.c
105
+++ b/target/arm/translate-sve.c
106
@@ -XXX,XX +XXX,XX @@ DO_SVE2_ZZZ_TB(UABDLT, uabdl, true, true)
107
DO_SVE2_ZZZ_TB(SADDLBT, saddl, false, true)
108
DO_SVE2_ZZZ_TB(SSUBLBT, ssubl, false, true)
109
DO_SVE2_ZZZ_TB(SSUBLTB, ssubl, true, false)
110
+
111
+#define DO_SVE2_ZZZ_WTB(NAME, name, SEL2) \
112
+static bool trans_##NAME(DisasContext *s, arg_rrr_esz *a) \
113
+{ \
114
+ static gen_helper_gvec_3 * const fns[4] = { \
115
+ NULL, gen_helper_sve2_##name##_h, \
116
+ gen_helper_sve2_##name##_s, gen_helper_sve2_##name##_d, \
117
+ }; \
118
+ return do_sve2_zzw_ool(s, a, fns[a->esz], SEL2); \
119
+}
120
+
121
+DO_SVE2_ZZZ_WTB(SADDWB, saddw, false)
122
+DO_SVE2_ZZZ_WTB(SADDWT, saddw, true)
123
+DO_SVE2_ZZZ_WTB(SSUBWB, ssubw, false)
124
+DO_SVE2_ZZZ_WTB(SSUBWT, ssubw, true)
125
+
126
+DO_SVE2_ZZZ_WTB(UADDWB, uaddw, false)
127
+DO_SVE2_ZZZ_WTB(UADDWT, uaddw, true)
128
+DO_SVE2_ZZZ_WTB(USUBWB, usubw, false)
129
+DO_SVE2_ZZZ_WTB(USUBWT, usubw, true)
130
--
131
2.20.1
132
133
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Exclude PMULL from this category for the moment.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210525010358.152808-14-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper-sve.h | 15 +++++++++++++++
11
target/arm/sve.decode | 9 +++++++++
12
target/arm/sve_helper.c | 31 +++++++++++++++++++++++++++++++
13
target/arm/translate-sve.c | 9 +++++++++
14
4 files changed, 64 insertions(+)
15
16
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-sve.h
19
+++ b/target/arm/helper-sve.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_stdd_le_zd_mte, TCG_CALL_NO_WG,
21
DEF_HELPER_FLAGS_6(sve_stdd_be_zd_mte, TCG_CALL_NO_WG,
22
void, env, ptr, ptr, ptr, tl, i32)
23
24
+DEF_HELPER_FLAGS_4(sve2_sqdmull_zzz_h, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(sve2_sqdmull_zzz_s, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(sve2_sqdmull_zzz_d, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, i32)
30
+
31
+DEF_HELPER_FLAGS_4(sve2_smull_zzz_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(sve2_smull_zzz_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_4(sve2_smull_zzz_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
+
35
+DEF_HELPER_FLAGS_4(sve2_umull_zzz_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_4(sve2_umull_zzz_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
37
+DEF_HELPER_FLAGS_4(sve2_umull_zzz_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
38
+
39
DEF_HELPER_FLAGS_4(sve2_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
40
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/sve.decode
43
+++ b/target/arm/sve.decode
44
@@ -XXX,XX +XXX,XX @@ SSUBWB 01000101 .. 0 ..... 010 100 ..... ..... @rd_rn_rm
45
SSUBWT 01000101 .. 0 ..... 010 101 ..... ..... @rd_rn_rm
46
USUBWB 01000101 .. 0 ..... 010 110 ..... ..... @rd_rn_rm
47
USUBWT 01000101 .. 0 ..... 010 111 ..... ..... @rd_rn_rm
48
+
49
+## SVE2 integer multiply long
50
+
51
+SQDMULLB_zzz 01000101 .. 0 ..... 011 000 ..... ..... @rd_rn_rm
52
+SQDMULLT_zzz 01000101 .. 0 ..... 011 001 ..... ..... @rd_rn_rm
53
+SMULLB_zzz 01000101 .. 0 ..... 011 100 ..... ..... @rd_rn_rm
54
+SMULLT_zzz 01000101 .. 0 ..... 011 101 ..... ..... @rd_rn_rm
55
+UMULLB_zzz 01000101 .. 0 ..... 011 110 ..... ..... @rd_rn_rm
56
+UMULLT_zzz 01000101 .. 0 ..... 011 111 ..... ..... @rd_rn_rm
57
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/sve_helper.c
60
+++ b/target/arm/sve_helper.c
61
@@ -XXX,XX +XXX,XX @@ DO_ZZZ_TB(sve2_uabdl_h, uint16_t, uint8_t, H1_2, H1, DO_ABD)
62
DO_ZZZ_TB(sve2_uabdl_s, uint32_t, uint16_t, H1_4, H1_2, DO_ABD)
63
DO_ZZZ_TB(sve2_uabdl_d, uint64_t, uint32_t, , H1_4, DO_ABD)
64
65
+DO_ZZZ_TB(sve2_smull_zzz_h, int16_t, int8_t, H1_2, H1, DO_MUL)
66
+DO_ZZZ_TB(sve2_smull_zzz_s, int32_t, int16_t, H1_4, H1_2, DO_MUL)
67
+DO_ZZZ_TB(sve2_smull_zzz_d, int64_t, int32_t, , H1_4, DO_MUL)
68
+
69
+DO_ZZZ_TB(sve2_umull_zzz_h, uint16_t, uint8_t, H1_2, H1, DO_MUL)
70
+DO_ZZZ_TB(sve2_umull_zzz_s, uint32_t, uint16_t, H1_4, H1_2, DO_MUL)
71
+DO_ZZZ_TB(sve2_umull_zzz_d, uint64_t, uint32_t, , H1_4, DO_MUL)
72
+
73
+/* Note that the multiply cannot overflow, but the doubling can. */
74
+static inline int16_t do_sqdmull_h(int16_t n, int16_t m)
75
+{
76
+ int16_t val = n * m;
77
+ return DO_SQADD_H(val, val);
78
+}
79
+
80
+static inline int32_t do_sqdmull_s(int32_t n, int32_t m)
81
+{
82
+ int32_t val = n * m;
83
+ return DO_SQADD_S(val, val);
84
+}
85
+
86
+static inline int64_t do_sqdmull_d(int64_t n, int64_t m)
87
+{
88
+ int64_t val = n * m;
89
+ return do_sqadd_d(val, val);
90
+}
91
+
92
+DO_ZZZ_TB(sve2_sqdmull_zzz_h, int16_t, int8_t, H1_2, H1, do_sqdmull_h)
93
+DO_ZZZ_TB(sve2_sqdmull_zzz_s, int32_t, int16_t, H1_4, H1_2, do_sqdmull_s)
94
+DO_ZZZ_TB(sve2_sqdmull_zzz_d, int64_t, int32_t, , H1_4, do_sqdmull_d)
95
+
96
#undef DO_ZZZ_TB
97
98
#define DO_ZZZ_WTB(NAME, TYPEW, TYPEN, HW, HN, OP) \
99
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/target/arm/translate-sve.c
102
+++ b/target/arm/translate-sve.c
103
@@ -XXX,XX +XXX,XX @@ DO_SVE2_ZZZ_TB(SADDLBT, saddl, false, true)
104
DO_SVE2_ZZZ_TB(SSUBLBT, ssubl, false, true)
105
DO_SVE2_ZZZ_TB(SSUBLTB, ssubl, true, false)
106
107
+DO_SVE2_ZZZ_TB(SQDMULLB_zzz, sqdmull_zzz, false, false)
108
+DO_SVE2_ZZZ_TB(SQDMULLT_zzz, sqdmull_zzz, true, true)
109
+
110
+DO_SVE2_ZZZ_TB(SMULLB_zzz, smull_zzz, false, false)
111
+DO_SVE2_ZZZ_TB(SMULLT_zzz, smull_zzz, true, true)
112
+
113
+DO_SVE2_ZZZ_TB(UMULLB_zzz, umull_zzz, false, false)
114
+DO_SVE2_ZZZ_TB(UMULLT_zzz, umull_zzz, true, true)
115
+
116
#define DO_SVE2_ZZZ_WTB(NAME, name, SEL2) \
117
static bool trans_##NAME(DisasContext *s, arg_rrr_esz *a) \
118
{ \
119
--
120
2.20.1
121
122
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-15-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/cpu.h | 10 ++++++++++
9
target/arm/helper-sve.h | 1 +
10
target/arm/sve.decode | 2 ++
11
target/arm/translate-sve.c | 22 ++++++++++++++++++++++
12
target/arm/vec_helper.c | 24 ++++++++++++++++++++++++
13
5 files changed, 59 insertions(+)
14
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id)
20
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SVEVER) != 0;
21
}
22
23
+static inline bool isar_feature_aa64_sve2_aes(const ARMISARegisters *id)
24
+{
25
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, AES) != 0;
26
+}
27
+
28
+static inline bool isar_feature_aa64_sve2_pmull128(const ARMISARegisters *id)
29
+{
30
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, AES) >= 2;
31
+}
32
+
33
/*
34
* Feature tests for "does this exist in either 32-bit or 64-bit?"
35
*/
36
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/helper-sve.h
39
+++ b/target/arm/helper-sve.h
40
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve2_umull_zzz_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
41
DEF_HELPER_FLAGS_4(sve2_umull_zzz_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
42
43
DEF_HELPER_FLAGS_4(sve2_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_4(sve2_pmull_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
45
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/sve.decode
48
+++ b/target/arm/sve.decode
49
@@ -XXX,XX +XXX,XX @@ USUBWT 01000101 .. 0 ..... 010 111 ..... ..... @rd_rn_rm
50
51
SQDMULLB_zzz 01000101 .. 0 ..... 011 000 ..... ..... @rd_rn_rm
52
SQDMULLT_zzz 01000101 .. 0 ..... 011 001 ..... ..... @rd_rn_rm
53
+PMULLB 01000101 .. 0 ..... 011 010 ..... ..... @rd_rn_rm
54
+PMULLT 01000101 .. 0 ..... 011 011 ..... ..... @rd_rn_rm
55
SMULLB_zzz 01000101 .. 0 ..... 011 100 ..... ..... @rd_rn_rm
56
SMULLT_zzz 01000101 .. 0 ..... 011 101 ..... ..... @rd_rn_rm
57
UMULLB_zzz 01000101 .. 0 ..... 011 110 ..... ..... @rd_rn_rm
58
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/translate-sve.c
61
+++ b/target/arm/translate-sve.c
62
@@ -XXX,XX +XXX,XX @@ DO_SVE2_ZZZ_TB(SMULLT_zzz, smull_zzz, true, true)
63
DO_SVE2_ZZZ_TB(UMULLB_zzz, umull_zzz, false, false)
64
DO_SVE2_ZZZ_TB(UMULLT_zzz, umull_zzz, true, true)
65
66
+static bool do_trans_pmull(DisasContext *s, arg_rrr_esz *a, bool sel)
67
+{
68
+ static gen_helper_gvec_3 * const fns[4] = {
69
+ gen_helper_gvec_pmull_q, gen_helper_sve2_pmull_h,
70
+ NULL, gen_helper_sve2_pmull_d,
71
+ };
72
+ if (a->esz == 0 && !dc_isar_feature(aa64_sve2_pmull128, s)) {
73
+ return false;
74
+ }
75
+ return do_sve2_zzw_ool(s, a, fns[a->esz], sel);
76
+}
77
+
78
+static bool trans_PMULLB(DisasContext *s, arg_rrr_esz *a)
79
+{
80
+ return do_trans_pmull(s, a, false);
81
+}
82
+
83
+static bool trans_PMULLT(DisasContext *s, arg_rrr_esz *a)
84
+{
85
+ return do_trans_pmull(s, a, true);
86
+}
87
+
88
#define DO_SVE2_ZZZ_WTB(NAME, name, SEL2) \
89
static bool trans_##NAME(DisasContext *s, arg_rrr_esz *a) \
90
{ \
91
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/target/arm/vec_helper.c
94
+++ b/target/arm/vec_helper.c
95
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_pmull_h)(void *vd, void *vn, void *vm, uint32_t desc)
96
d[i] = pmull_h(nn, mm);
97
}
98
}
99
+
100
+static uint64_t pmull_d(uint64_t op1, uint64_t op2)
101
+{
102
+ uint64_t result = 0;
103
+ int i;
104
+
105
+ for (i = 0; i < 32; ++i) {
106
+ uint64_t mask = -((op1 >> i) & 1);
107
+ result ^= (op2 << i) & mask;
108
+ }
109
+ return result;
110
+}
111
+
112
+void HELPER(sve2_pmull_d)(void *vd, void *vn, void *vm, uint32_t desc)
113
+{
114
+ intptr_t sel = H4(simd_data(desc));
115
+ intptr_t i, opr_sz = simd_oprsz(desc);
116
+ uint32_t *n = vn, *m = vm;
117
+ uint64_t *d = vd;
118
+
119
+ for (i = 0; i < opr_sz / 8; ++i) {
120
+ d[i] = pmull_d(n[2 * i + sel], m[2 * i + sel]);
121
+ }
122
+}
123
#endif
124
125
#define DO_CMP0(NAME, TYPE, OP) \
126
--
127
2.20.1
128
129
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-16-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 8 ++
9
target/arm/sve.decode | 8 ++
10
target/arm/sve_helper.c | 22 +++++
11
target/arm/translate-sve.c | 159 +++++++++++++++++++++++++++++++++++++
12
4 files changed, 197 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve2_umull_zzz_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
19
20
DEF_HELPER_FLAGS_4(sve2_pmull_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_4(sve2_pmull_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
22
+
23
+DEF_HELPER_FLAGS_3(sve2_sshll_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_3(sve2_sshll_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_3(sve2_sshll_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
26
+
27
+DEF_HELPER_FLAGS_3(sve2_ushll_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_3(sve2_ushll_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_3(sve2_ushll_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
30
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/sve.decode
33
+++ b/target/arm/sve.decode
34
@@ -XXX,XX +XXX,XX @@ SMULLB_zzz 01000101 .. 0 ..... 011 100 ..... ..... @rd_rn_rm
35
SMULLT_zzz 01000101 .. 0 ..... 011 101 ..... ..... @rd_rn_rm
36
UMULLB_zzz 01000101 .. 0 ..... 011 110 ..... ..... @rd_rn_rm
37
UMULLT_zzz 01000101 .. 0 ..... 011 111 ..... ..... @rd_rn_rm
38
+
39
+## SVE2 bitwise shift left long
40
+
41
+# Note bit23 == 0 is handled by esz > 0 in do_sve2_shll_tb.
42
+SSHLLB 01000101 .. 0 ..... 1010 00 ..... ..... @rd_rn_tszimm_shl
43
+SSHLLT 01000101 .. 0 ..... 1010 01 ..... ..... @rd_rn_tszimm_shl
44
+USHLLB 01000101 .. 0 ..... 1010 10 ..... ..... @rd_rn_tszimm_shl
45
+USHLLT 01000101 .. 0 ..... 1010 11 ..... ..... @rd_rn_tszimm_shl
46
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/sve_helper.c
49
+++ b/target/arm/sve_helper.c
50
@@ -XXX,XX +XXX,XX @@ DO_ZZZ_WTB(sve2_usubw_d, uint64_t, uint32_t, , H1_4, DO_SUB)
51
52
#undef DO_ZZZ_WTB
53
54
+#define DO_ZZI_SHLL(NAME, TYPEW, TYPEN, HW, HN) \
55
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
56
+{ \
57
+ intptr_t i, opr_sz = simd_oprsz(desc); \
58
+ intptr_t sel = (simd_data(desc) & 1) * sizeof(TYPEN); \
59
+ int shift = simd_data(desc) >> 1; \
60
+ for (i = 0; i < opr_sz; i += sizeof(TYPEW)) { \
61
+ TYPEW nn = *(TYPEN *)(vn + HN(i + sel)); \
62
+ *(TYPEW *)(vd + HW(i)) = nn << shift; \
63
+ } \
64
+}
65
+
66
+DO_ZZI_SHLL(sve2_sshll_h, int16_t, int8_t, H1_2, H1)
67
+DO_ZZI_SHLL(sve2_sshll_s, int32_t, int16_t, H1_4, H1_2)
68
+DO_ZZI_SHLL(sve2_sshll_d, int64_t, int32_t, , H1_4)
69
+
70
+DO_ZZI_SHLL(sve2_ushll_h, uint16_t, uint8_t, H1_2, H1)
71
+DO_ZZI_SHLL(sve2_ushll_s, uint32_t, uint16_t, H1_4, H1_2)
72
+DO_ZZI_SHLL(sve2_ushll_d, uint64_t, uint32_t, , H1_4)
73
+
74
+#undef DO_ZZI_SHLL
75
+
76
/* Two-operand reduction expander, controlled by a predicate.
77
* The difference between TYPERED and TYPERET has to do with
78
* sign-extension. E.g. for SMAX, TYPERED must be signed,
79
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/arm/translate-sve.c
82
+++ b/target/arm/translate-sve.c
83
@@ -XXX,XX +XXX,XX @@ DO_SVE2_ZZZ_WTB(UADDWB, uaddw, false)
84
DO_SVE2_ZZZ_WTB(UADDWT, uaddw, true)
85
DO_SVE2_ZZZ_WTB(USUBWB, usubw, false)
86
DO_SVE2_ZZZ_WTB(USUBWT, usubw, true)
87
+
88
+static void gen_sshll_vec(unsigned vece, TCGv_vec d, TCGv_vec n, int64_t imm)
89
+{
90
+ int top = imm & 1;
91
+ int shl = imm >> 1;
92
+ int halfbits = 4 << vece;
93
+
94
+ if (top) {
95
+ if (shl == halfbits) {
96
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
97
+ tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(halfbits, halfbits));
98
+ tcg_gen_and_vec(vece, d, n, t);
99
+ tcg_temp_free_vec(t);
100
+ } else {
101
+ tcg_gen_sari_vec(vece, d, n, halfbits);
102
+ tcg_gen_shli_vec(vece, d, d, shl);
103
+ }
104
+ } else {
105
+ tcg_gen_shli_vec(vece, d, n, halfbits);
106
+ tcg_gen_sari_vec(vece, d, d, halfbits - shl);
107
+ }
108
+}
109
+
110
+static void gen_ushll_i64(unsigned vece, TCGv_i64 d, TCGv_i64 n, int imm)
111
+{
112
+ int halfbits = 4 << vece;
113
+ int top = imm & 1;
114
+ int shl = (imm >> 1);
115
+ int shift;
116
+ uint64_t mask;
117
+
118
+ mask = MAKE_64BIT_MASK(0, halfbits);
119
+ mask <<= shl;
120
+ mask = dup_const(vece, mask);
121
+
122
+ shift = shl - top * halfbits;
123
+ if (shift < 0) {
124
+ tcg_gen_shri_i64(d, n, -shift);
125
+ } else {
126
+ tcg_gen_shli_i64(d, n, shift);
127
+ }
128
+ tcg_gen_andi_i64(d, d, mask);
129
+}
130
+
131
+static void gen_ushll16_i64(TCGv_i64 d, TCGv_i64 n, int64_t imm)
132
+{
133
+ gen_ushll_i64(MO_16, d, n, imm);
134
+}
135
+
136
+static void gen_ushll32_i64(TCGv_i64 d, TCGv_i64 n, int64_t imm)
137
+{
138
+ gen_ushll_i64(MO_32, d, n, imm);
139
+}
140
+
141
+static void gen_ushll64_i64(TCGv_i64 d, TCGv_i64 n, int64_t imm)
142
+{
143
+ gen_ushll_i64(MO_64, d, n, imm);
144
+}
145
+
146
+static void gen_ushll_vec(unsigned vece, TCGv_vec d, TCGv_vec n, int64_t imm)
147
+{
148
+ int halfbits = 4 << vece;
149
+ int top = imm & 1;
150
+ int shl = imm >> 1;
151
+
152
+ if (top) {
153
+ if (shl == halfbits) {
154
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
155
+ tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(halfbits, halfbits));
156
+ tcg_gen_and_vec(vece, d, n, t);
157
+ tcg_temp_free_vec(t);
158
+ } else {
159
+ tcg_gen_shri_vec(vece, d, n, halfbits);
160
+ tcg_gen_shli_vec(vece, d, d, shl);
161
+ }
162
+ } else {
163
+ if (shl == 0) {
164
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
165
+ tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(0, halfbits));
166
+ tcg_gen_and_vec(vece, d, n, t);
167
+ tcg_temp_free_vec(t);
168
+ } else {
169
+ tcg_gen_shli_vec(vece, d, n, halfbits);
170
+ tcg_gen_shri_vec(vece, d, d, halfbits - shl);
171
+ }
172
+ }
173
+}
174
+
175
+static bool do_sve2_shll_tb(DisasContext *s, arg_rri_esz *a,
176
+ bool sel, bool uns)
177
+{
178
+ static const TCGOpcode sshll_list[] = {
179
+ INDEX_op_shli_vec, INDEX_op_sari_vec, 0
180
+ };
181
+ static const TCGOpcode ushll_list[] = {
182
+ INDEX_op_shli_vec, INDEX_op_shri_vec, 0
183
+ };
184
+ static const GVecGen2i ops[2][3] = {
185
+ { { .fniv = gen_sshll_vec,
186
+ .opt_opc = sshll_list,
187
+ .fno = gen_helper_sve2_sshll_h,
188
+ .vece = MO_16 },
189
+ { .fniv = gen_sshll_vec,
190
+ .opt_opc = sshll_list,
191
+ .fno = gen_helper_sve2_sshll_s,
192
+ .vece = MO_32 },
193
+ { .fniv = gen_sshll_vec,
194
+ .opt_opc = sshll_list,
195
+ .fno = gen_helper_sve2_sshll_d,
196
+ .vece = MO_64 } },
197
+ { { .fni8 = gen_ushll16_i64,
198
+ .fniv = gen_ushll_vec,
199
+ .opt_opc = ushll_list,
200
+ .fno = gen_helper_sve2_ushll_h,
201
+ .vece = MO_16 },
202
+ { .fni8 = gen_ushll32_i64,
203
+ .fniv = gen_ushll_vec,
204
+ .opt_opc = ushll_list,
205
+ .fno = gen_helper_sve2_ushll_s,
206
+ .vece = MO_32 },
207
+ { .fni8 = gen_ushll64_i64,
208
+ .fniv = gen_ushll_vec,
209
+ .opt_opc = ushll_list,
210
+ .fno = gen_helper_sve2_ushll_d,
211
+ .vece = MO_64 } },
212
+ };
213
+
214
+ if (a->esz < 0 || a->esz > 2 || !dc_isar_feature(aa64_sve2, s)) {
215
+ return false;
216
+ }
217
+ if (sve_access_check(s)) {
218
+ unsigned vsz = vec_full_reg_size(s);
219
+ tcg_gen_gvec_2i(vec_full_reg_offset(s, a->rd),
220
+ vec_full_reg_offset(s, a->rn),
221
+ vsz, vsz, (a->imm << 1) | sel,
222
+ &ops[uns][a->esz]);
223
+ }
224
+ return true;
225
+}
226
+
227
+static bool trans_SSHLLB(DisasContext *s, arg_rri_esz *a)
228
+{
229
+ return do_sve2_shll_tb(s, a, false, false);
230
+}
231
+
232
+static bool trans_SSHLLT(DisasContext *s, arg_rri_esz *a)
233
+{
234
+ return do_sve2_shll_tb(s, a, true, false);
235
+}
236
+
237
+static bool trans_USHLLB(DisasContext *s, arg_rri_esz *a)
238
+{
239
+ return do_sve2_shll_tb(s, a, false, true);
240
+}
241
+
242
+static bool trans_USHLLT(DisasContext *s, arg_rri_esz *a)
243
+{
244
+ return do_sve2_shll_tb(s, a, true, true);
245
+}
246
--
247
2.20.1
248
249
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-17-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 5 +++++
9
target/arm/sve.decode | 5 +++++
10
target/arm/sve_helper.c | 20 ++++++++++++++++++++
11
target/arm/translate-sve.c | 19 +++++++++++++++++++
12
4 files changed, 49 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve2_sshll_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
19
DEF_HELPER_FLAGS_3(sve2_ushll_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_3(sve2_ushll_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_3(sve2_ushll_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
22
+
23
+DEF_HELPER_FLAGS_4(sve2_eoril_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_4(sve2_eoril_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_4(sve2_eoril_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(sve2_eoril_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/sve.decode
30
+++ b/target/arm/sve.decode
31
@@ -XXX,XX +XXX,XX @@ SSHLLB 01000101 .. 0 ..... 1010 00 ..... ..... @rd_rn_tszimm_shl
32
SSHLLT 01000101 .. 0 ..... 1010 01 ..... ..... @rd_rn_tszimm_shl
33
USHLLB 01000101 .. 0 ..... 1010 10 ..... ..... @rd_rn_tszimm_shl
34
USHLLT 01000101 .. 0 ..... 1010 11 ..... ..... @rd_rn_tszimm_shl
35
+
36
+## SVE2 bitwise exclusive-or interleaved
37
+
38
+EORBT 01000101 .. 0 ..... 10010 0 ..... ..... @rd_rn_rm
39
+EORTB 01000101 .. 0 ..... 10010 1 ..... ..... @rd_rn_rm
40
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/sve_helper.c
43
+++ b/target/arm/sve_helper.c
44
@@ -XXX,XX +XXX,XX @@ DO_ZZZ_WTB(sve2_usubw_d, uint64_t, uint32_t, , H1_4, DO_SUB)
45
46
#undef DO_ZZZ_WTB
47
48
+#define DO_ZZZ_NTB(NAME, TYPE, H, OP) \
49
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
50
+{ \
51
+ intptr_t i, opr_sz = simd_oprsz(desc); \
52
+ intptr_t sel1 = extract32(desc, SIMD_DATA_SHIFT, 1) * sizeof(TYPE); \
53
+ intptr_t sel2 = extract32(desc, SIMD_DATA_SHIFT + 1, 1) * sizeof(TYPE); \
54
+ for (i = 0; i < opr_sz; i += 2 * sizeof(TYPE)) { \
55
+ TYPE nn = *(TYPE *)(vn + H(i + sel1)); \
56
+ TYPE mm = *(TYPE *)(vm + H(i + sel2)); \
57
+ *(TYPE *)(vd + H(i + sel1)) = OP(nn, mm); \
58
+ } \
59
+}
60
+
61
+DO_ZZZ_NTB(sve2_eoril_b, uint8_t, H1, DO_EOR)
62
+DO_ZZZ_NTB(sve2_eoril_h, uint16_t, H1_2, DO_EOR)
63
+DO_ZZZ_NTB(sve2_eoril_s, uint32_t, H1_4, DO_EOR)
64
+DO_ZZZ_NTB(sve2_eoril_d, uint64_t, , DO_EOR)
65
+
66
+#undef DO_ZZZ_NTB
67
+
68
#define DO_ZZI_SHLL(NAME, TYPEW, TYPEN, HW, HN) \
69
void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
70
{ \
71
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/translate-sve.c
74
+++ b/target/arm/translate-sve.c
75
@@ -XXX,XX +XXX,XX @@ DO_SVE2_ZZZ_TB(SMULLT_zzz, smull_zzz, true, true)
76
DO_SVE2_ZZZ_TB(UMULLB_zzz, umull_zzz, false, false)
77
DO_SVE2_ZZZ_TB(UMULLT_zzz, umull_zzz, true, true)
78
79
+static bool do_eor_tb(DisasContext *s, arg_rrr_esz *a, bool sel1)
80
+{
81
+ static gen_helper_gvec_3 * const fns[4] = {
82
+ gen_helper_sve2_eoril_b, gen_helper_sve2_eoril_h,
83
+ gen_helper_sve2_eoril_s, gen_helper_sve2_eoril_d,
84
+ };
85
+ return do_sve2_zzw_ool(s, a, fns[a->esz], (!sel1 << 1) | sel1);
86
+}
87
+
88
+static bool trans_EORBT(DisasContext *s, arg_rrr_esz *a)
89
+{
90
+ return do_eor_tb(s, a, false);
91
+}
92
+
93
+static bool trans_EORTB(DisasContext *s, arg_rrr_esz *a)
94
+{
95
+ return do_eor_tb(s, a, true);
96
+}
97
+
98
static bool do_trans_pmull(DisasContext *s, arg_rrr_esz *a, bool sel)
99
{
100
static gen_helper_gvec_3 * const fns[4] = {
101
--
102
2.20.1
103
104
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-18-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/cpu.h | 5 +++
9
target/arm/helper-sve.h | 15 ++++++++
10
target/arm/sve.decode | 6 ++++
11
target/arm/sve_helper.c | 73 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate-sve.c | 36 +++++++++++++++++++
13
5 files changed, 135 insertions(+)
14
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sve2_pmull128(const ARMISARegisters *id)
20
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, AES) >= 2;
21
}
22
23
+static inline bool isar_feature_aa64_sve2_bitperm(const ARMISARegisters *id)
24
+{
25
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BITPERM) != 0;
26
+}
27
+
28
/*
29
* Feature tests for "does this exist in either 32-bit or 64-bit?"
30
*/
31
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/helper-sve.h
34
+++ b/target/arm/helper-sve.h
35
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve2_eoril_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
DEF_HELPER_FLAGS_4(sve2_eoril_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
37
DEF_HELPER_FLAGS_4(sve2_eoril_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
38
DEF_HELPER_FLAGS_4(sve2_eoril_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
39
+
40
+DEF_HELPER_FLAGS_4(sve2_bext_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_4(sve2_bext_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
42
+DEF_HELPER_FLAGS_4(sve2_bext_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_4(sve2_bext_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
44
+
45
+DEF_HELPER_FLAGS_4(sve2_bdep_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
46
+DEF_HELPER_FLAGS_4(sve2_bdep_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_4(sve2_bdep_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
48
+DEF_HELPER_FLAGS_4(sve2_bdep_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
49
+
50
+DEF_HELPER_FLAGS_4(sve2_bgrp_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_4(sve2_bgrp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
52
+DEF_HELPER_FLAGS_4(sve2_bgrp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
53
+DEF_HELPER_FLAGS_4(sve2_bgrp_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
54
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/sve.decode
57
+++ b/target/arm/sve.decode
58
@@ -XXX,XX +XXX,XX @@ USHLLT 01000101 .. 0 ..... 1010 11 ..... ..... @rd_rn_tszimm_shl
59
60
EORBT 01000101 .. 0 ..... 10010 0 ..... ..... @rd_rn_rm
61
EORTB 01000101 .. 0 ..... 10010 1 ..... ..... @rd_rn_rm
62
+
63
+## SVE2 bitwise permute
64
+
65
+BEXT 01000101 .. 0 ..... 1011 00 ..... ..... @rd_rn_rm
66
+BDEP 01000101 .. 0 ..... 1011 01 ..... ..... @rd_rn_rm
67
+BGRP 01000101 .. 0 ..... 1011 10 ..... ..... @rd_rn_rm
68
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/sve_helper.c
71
+++ b/target/arm/sve_helper.c
72
@@ -XXX,XX +XXX,XX @@ DO_ZZZ_NTB(sve2_eoril_d, uint64_t, , DO_EOR)
73
74
#undef DO_ZZZ_NTB
75
76
+#define DO_BITPERM(NAME, TYPE, OP) \
77
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
78
+{ \
79
+ intptr_t i, opr_sz = simd_oprsz(desc); \
80
+ for (i = 0; i < opr_sz; i += sizeof(TYPE)) { \
81
+ TYPE nn = *(TYPE *)(vn + i); \
82
+ TYPE mm = *(TYPE *)(vm + i); \
83
+ *(TYPE *)(vd + i) = OP(nn, mm, sizeof(TYPE) * 8); \
84
+ } \
85
+}
86
+
87
+static uint64_t bitextract(uint64_t data, uint64_t mask, int n)
88
+{
89
+ uint64_t res = 0;
90
+ int db, rb = 0;
91
+
92
+ for (db = 0; db < n; ++db) {
93
+ if ((mask >> db) & 1) {
94
+ res |= ((data >> db) & 1) << rb;
95
+ ++rb;
96
+ }
97
+ }
98
+ return res;
99
+}
100
+
101
+DO_BITPERM(sve2_bext_b, uint8_t, bitextract)
102
+DO_BITPERM(sve2_bext_h, uint16_t, bitextract)
103
+DO_BITPERM(sve2_bext_s, uint32_t, bitextract)
104
+DO_BITPERM(sve2_bext_d, uint64_t, bitextract)
105
+
106
+static uint64_t bitdeposit(uint64_t data, uint64_t mask, int n)
107
+{
108
+ uint64_t res = 0;
109
+ int rb, db = 0;
110
+
111
+ for (rb = 0; rb < n; ++rb) {
112
+ if ((mask >> rb) & 1) {
113
+ res |= ((data >> db) & 1) << rb;
114
+ ++db;
115
+ }
116
+ }
117
+ return res;
118
+}
119
+
120
+DO_BITPERM(sve2_bdep_b, uint8_t, bitdeposit)
121
+DO_BITPERM(sve2_bdep_h, uint16_t, bitdeposit)
122
+DO_BITPERM(sve2_bdep_s, uint32_t, bitdeposit)
123
+DO_BITPERM(sve2_bdep_d, uint64_t, bitdeposit)
124
+
125
+static uint64_t bitgroup(uint64_t data, uint64_t mask, int n)
126
+{
127
+ uint64_t resm = 0, resu = 0;
128
+ int db, rbm = 0, rbu = 0;
129
+
130
+ for (db = 0; db < n; ++db) {
131
+ uint64_t val = (data >> db) & 1;
132
+ if ((mask >> db) & 1) {
133
+ resm |= val << rbm++;
134
+ } else {
135
+ resu |= val << rbu++;
136
+ }
137
+ }
138
+
139
+ return resm | (resu << rbm);
140
+}
141
+
142
+DO_BITPERM(sve2_bgrp_b, uint8_t, bitgroup)
143
+DO_BITPERM(sve2_bgrp_h, uint16_t, bitgroup)
144
+DO_BITPERM(sve2_bgrp_s, uint32_t, bitgroup)
145
+DO_BITPERM(sve2_bgrp_d, uint64_t, bitgroup)
146
+
147
+#undef DO_BITPERM
148
+
149
#define DO_ZZI_SHLL(NAME, TYPEW, TYPEN, HW, HN) \
150
void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
151
{ \
152
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/target/arm/translate-sve.c
155
+++ b/target/arm/translate-sve.c
156
@@ -XXX,XX +XXX,XX @@ static bool trans_USHLLT(DisasContext *s, arg_rri_esz *a)
157
{
158
return do_sve2_shll_tb(s, a, true, true);
159
}
160
+
161
+static bool trans_BEXT(DisasContext *s, arg_rrr_esz *a)
162
+{
163
+ static gen_helper_gvec_3 * const fns[4] = {
164
+ gen_helper_sve2_bext_b, gen_helper_sve2_bext_h,
165
+ gen_helper_sve2_bext_s, gen_helper_sve2_bext_d,
166
+ };
167
+ if (!dc_isar_feature(aa64_sve2_bitperm, s)) {
168
+ return false;
169
+ }
170
+ return do_sve2_zzw_ool(s, a, fns[a->esz], 0);
171
+}
172
+
173
+static bool trans_BDEP(DisasContext *s, arg_rrr_esz *a)
174
+{
175
+ static gen_helper_gvec_3 * const fns[4] = {
176
+ gen_helper_sve2_bdep_b, gen_helper_sve2_bdep_h,
177
+ gen_helper_sve2_bdep_s, gen_helper_sve2_bdep_d,
178
+ };
179
+ if (!dc_isar_feature(aa64_sve2_bitperm, s)) {
180
+ return false;
181
+ }
182
+ return do_sve2_zzw_ool(s, a, fns[a->esz], 0);
183
+}
184
+
185
+static bool trans_BGRP(DisasContext *s, arg_rrr_esz *a)
186
+{
187
+ static gen_helper_gvec_3 * const fns[4] = {
188
+ gen_helper_sve2_bgrp_b, gen_helper_sve2_bgrp_h,
189
+ gen_helper_sve2_bgrp_s, gen_helper_sve2_bgrp_d,
190
+ };
191
+ if (!dc_isar_feature(aa64_sve2_bitperm, s)) {
192
+ return false;
193
+ }
194
+ return do_sve2_zzw_ool(s, a, fns[a->esz], 0);
195
+}
196
--
197
2.20.1
198
199
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-19-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 10 +++++++++
9
target/arm/sve.decode | 9 ++++++++
10
target/arm/sve_helper.c | 42 ++++++++++++++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 31 ++++++++++++++++++++++++++++
12
4 files changed, 92 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve2_bgrp_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
19
DEF_HELPER_FLAGS_4(sve2_bgrp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_4(sve2_bgrp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_4(sve2_bgrp_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
22
+
23
+DEF_HELPER_FLAGS_4(sve2_cadd_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_4(sve2_cadd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_4(sve2_cadd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(sve2_cadd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
+
28
+DEF_HELPER_FLAGS_4(sve2_sqcadd_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(sve2_sqcadd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(sve2_sqcadd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(sve2_sqcadd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/sve.decode
35
+++ b/target/arm/sve.decode
36
@@ -XXX,XX +XXX,XX @@ EORTB 01000101 .. 0 ..... 10010 1 ..... ..... @rd_rn_rm
37
BEXT 01000101 .. 0 ..... 1011 00 ..... ..... @rd_rn_rm
38
BDEP 01000101 .. 0 ..... 1011 01 ..... ..... @rd_rn_rm
39
BGRP 01000101 .. 0 ..... 1011 10 ..... ..... @rd_rn_rm
40
+
41
+#### SVE2 Accumulate
42
+
43
+## SVE2 complex integer add
44
+
45
+CADD_rot90 01000101 .. 00000 0 11011 0 ..... ..... @rdn_rm
46
+CADD_rot270 01000101 .. 00000 0 11011 1 ..... ..... @rdn_rm
47
+SQCADD_rot90 01000101 .. 00000 1 11011 0 ..... ..... @rdn_rm
48
+SQCADD_rot270 01000101 .. 00000 1 11011 1 ..... ..... @rdn_rm
49
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/sve_helper.c
52
+++ b/target/arm/sve_helper.c
53
@@ -XXX,XX +XXX,XX @@ DO_BITPERM(sve2_bgrp_d, uint64_t, bitgroup)
54
55
#undef DO_BITPERM
56
57
+#define DO_CADD(NAME, TYPE, H, ADD_OP, SUB_OP) \
58
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
59
+{ \
60
+ intptr_t i, opr_sz = simd_oprsz(desc); \
61
+ int sub_r = simd_data(desc); \
62
+ if (sub_r) { \
63
+ for (i = 0; i < opr_sz; i += 2 * sizeof(TYPE)) { \
64
+ TYPE acc_r = *(TYPE *)(vn + H(i)); \
65
+ TYPE acc_i = *(TYPE *)(vn + H(i + sizeof(TYPE))); \
66
+ TYPE el2_r = *(TYPE *)(vm + H(i)); \
67
+ TYPE el2_i = *(TYPE *)(vm + H(i + sizeof(TYPE))); \
68
+ acc_r = ADD_OP(acc_r, el2_i); \
69
+ acc_i = SUB_OP(acc_i, el2_r); \
70
+ *(TYPE *)(vd + H(i)) = acc_r; \
71
+ *(TYPE *)(vd + H(i + sizeof(TYPE))) = acc_i; \
72
+ } \
73
+ } else { \
74
+ for (i = 0; i < opr_sz; i += 2 * sizeof(TYPE)) { \
75
+ TYPE acc_r = *(TYPE *)(vn + H(i)); \
76
+ TYPE acc_i = *(TYPE *)(vn + H(i + sizeof(TYPE))); \
77
+ TYPE el2_r = *(TYPE *)(vm + H(i)); \
78
+ TYPE el2_i = *(TYPE *)(vm + H(i + sizeof(TYPE))); \
79
+ acc_r = SUB_OP(acc_r, el2_i); \
80
+ acc_i = ADD_OP(acc_i, el2_r); \
81
+ *(TYPE *)(vd + H(i)) = acc_r; \
82
+ *(TYPE *)(vd + H(i + sizeof(TYPE))) = acc_i; \
83
+ } \
84
+ } \
85
+}
86
+
87
+DO_CADD(sve2_cadd_b, int8_t, H1, DO_ADD, DO_SUB)
88
+DO_CADD(sve2_cadd_h, int16_t, H1_2, DO_ADD, DO_SUB)
89
+DO_CADD(sve2_cadd_s, int32_t, H1_4, DO_ADD, DO_SUB)
90
+DO_CADD(sve2_cadd_d, int64_t, , DO_ADD, DO_SUB)
91
+
92
+DO_CADD(sve2_sqcadd_b, int8_t, H1, DO_SQADD_B, DO_SQSUB_B)
93
+DO_CADD(sve2_sqcadd_h, int16_t, H1_2, DO_SQADD_H, DO_SQSUB_H)
94
+DO_CADD(sve2_sqcadd_s, int32_t, H1_4, DO_SQADD_S, DO_SQSUB_S)
95
+DO_CADD(sve2_sqcadd_d, int64_t, , do_sqadd_d, do_sqsub_d)
96
+
97
+#undef DO_CADD
98
+
99
#define DO_ZZI_SHLL(NAME, TYPEW, TYPEN, HW, HN) \
100
void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
101
{ \
102
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/translate-sve.c
105
+++ b/target/arm/translate-sve.c
106
@@ -XXX,XX +XXX,XX @@ static bool trans_BGRP(DisasContext *s, arg_rrr_esz *a)
107
}
108
return do_sve2_zzw_ool(s, a, fns[a->esz], 0);
109
}
110
+
111
+static bool do_cadd(DisasContext *s, arg_rrr_esz *a, bool sq, bool rot)
112
+{
113
+ static gen_helper_gvec_3 * const fns[2][4] = {
114
+ { gen_helper_sve2_cadd_b, gen_helper_sve2_cadd_h,
115
+ gen_helper_sve2_cadd_s, gen_helper_sve2_cadd_d },
116
+ { gen_helper_sve2_sqcadd_b, gen_helper_sve2_sqcadd_h,
117
+ gen_helper_sve2_sqcadd_s, gen_helper_sve2_sqcadd_d },
118
+ };
119
+ return do_sve2_zzw_ool(s, a, fns[sq][a->esz], rot);
120
+}
121
+
122
+static bool trans_CADD_rot90(DisasContext *s, arg_rrr_esz *a)
123
+{
124
+ return do_cadd(s, a, false, false);
125
+}
126
+
127
+static bool trans_CADD_rot270(DisasContext *s, arg_rrr_esz *a)
128
+{
129
+ return do_cadd(s, a, false, true);
130
+}
131
+
132
+static bool trans_SQCADD_rot90(DisasContext *s, arg_rrr_esz *a)
133
+{
134
+ return do_cadd(s, a, true, false);
135
+}
136
+
137
+static bool trans_SQCADD_rot270(DisasContext *s, arg_rrr_esz *a)
138
+{
139
+ return do_cadd(s, a, true, true);
140
+}
141
--
142
2.20.1
143
144
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-20-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 14 ++++++++++
9
target/arm/sve.decode | 12 +++++++++
10
target/arm/sve_helper.c | 23 ++++++++++++++++
11
target/arm/translate-sve.c | 55 ++++++++++++++++++++++++++++++++++++++
12
4 files changed, 104 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve2_sqcadd_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
19
DEF_HELPER_FLAGS_4(sve2_sqcadd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_4(sve2_sqcadd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_4(sve2_sqcadd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
22
+
23
+DEF_HELPER_FLAGS_5(sve2_sabal_h, TCG_CALL_NO_RWG,
24
+ void, ptr, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_5(sve2_sabal_s, TCG_CALL_NO_RWG,
26
+ void, ptr, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_5(sve2_sabal_d, TCG_CALL_NO_RWG,
28
+ void, ptr, ptr, ptr, ptr, i32)
29
+
30
+DEF_HELPER_FLAGS_5(sve2_uabal_h, TCG_CALL_NO_RWG,
31
+ void, ptr, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_5(sve2_uabal_s, TCG_CALL_NO_RWG,
33
+ void, ptr, ptr, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_5(sve2_uabal_d, TCG_CALL_NO_RWG,
35
+ void, ptr, ptr, ptr, ptr, i32)
36
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/sve.decode
39
+++ b/target/arm/sve.decode
40
@@ -XXX,XX +XXX,XX @@
41
&rpr_s rd pg rn s
42
&rprr_s rd pg rn rm s
43
&rprr_esz rd pg rn rm esz
44
+&rrrr_esz rd ra rn rm esz
45
&rprrr_esz rd pg rn rm ra esz
46
&rpri_esz rd pg rn imm esz
47
&ptrue rd esz pat s
48
@@ -XXX,XX +XXX,XX @@
49
@rdn_i8s ........ esz:2 ...... ... imm:s8 rd:5 \
50
&rri_esz rn=%reg_movprfx
51
52
+# Four operand, vector element size
53
+@rda_rn_rm ........ esz:2 . rm:5 ... ... rn:5 rd:5 \
54
+ &rrrr_esz ra=%reg_movprfx
55
+
56
# Three operand with "memory" size, aka immediate left shift
57
@rd_rn_msz_rm ........ ... rm:5 .... imm:2 rn:5 rd:5 &rrri
58
59
@@ -XXX,XX +XXX,XX @@ CADD_rot90 01000101 .. 00000 0 11011 0 ..... ..... @rdn_rm
60
CADD_rot270 01000101 .. 00000 0 11011 1 ..... ..... @rdn_rm
61
SQCADD_rot90 01000101 .. 00000 1 11011 0 ..... ..... @rdn_rm
62
SQCADD_rot270 01000101 .. 00000 1 11011 1 ..... ..... @rdn_rm
63
+
64
+## SVE2 integer absolute difference and accumulate long
65
+
66
+SABALB 01000101 .. 0 ..... 1100 00 ..... ..... @rda_rn_rm
67
+SABALT 01000101 .. 0 ..... 1100 01 ..... ..... @rda_rn_rm
68
+UABALB 01000101 .. 0 ..... 1100 10 ..... ..... @rda_rn_rm
69
+UABALT 01000101 .. 0 ..... 1100 11 ..... ..... @rda_rn_rm
70
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/sve_helper.c
73
+++ b/target/arm/sve_helper.c
74
@@ -XXX,XX +XXX,XX @@ DO_ZZZ_NTB(sve2_eoril_d, uint64_t, , DO_EOR)
75
76
#undef DO_ZZZ_NTB
77
78
+#define DO_ZZZW_ACC(NAME, TYPEW, TYPEN, HW, HN, OP) \
79
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, uint32_t desc) \
80
+{ \
81
+ intptr_t i, opr_sz = simd_oprsz(desc); \
82
+ intptr_t sel1 = simd_data(desc) * sizeof(TYPEN); \
83
+ for (i = 0; i < opr_sz; i += sizeof(TYPEW)) { \
84
+ TYPEW nn = *(TYPEN *)(vn + HN(i + sel1)); \
85
+ TYPEW mm = *(TYPEN *)(vm + HN(i + sel1)); \
86
+ TYPEW aa = *(TYPEW *)(va + HW(i)); \
87
+ *(TYPEW *)(vd + HW(i)) = OP(nn, mm) + aa; \
88
+ } \
89
+}
90
+
91
+DO_ZZZW_ACC(sve2_sabal_h, int16_t, int8_t, H1_2, H1, DO_ABD)
92
+DO_ZZZW_ACC(sve2_sabal_s, int32_t, int16_t, H1_4, H1_2, DO_ABD)
93
+DO_ZZZW_ACC(sve2_sabal_d, int64_t, int32_t, , H1_4, DO_ABD)
94
+
95
+DO_ZZZW_ACC(sve2_uabal_h, uint16_t, uint8_t, H1_2, H1, DO_ABD)
96
+DO_ZZZW_ACC(sve2_uabal_s, uint32_t, uint16_t, H1_4, H1_2, DO_ABD)
97
+DO_ZZZW_ACC(sve2_uabal_d, uint64_t, uint32_t, , H1_4, DO_ABD)
98
+
99
+#undef DO_ZZZW_ACC
100
+
101
#define DO_BITPERM(NAME, TYPE, OP) \
102
void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
103
{ \
104
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/target/arm/translate-sve.c
107
+++ b/target/arm/translate-sve.c
108
@@ -XXX,XX +XXX,XX @@ static void gen_gvec_ool_zzz(DisasContext *s, gen_helper_gvec_3 *fn,
109
vsz, vsz, data, fn);
110
}
111
112
+/* Invoke an out-of-line helper on 4 Zregs. */
113
+static void gen_gvec_ool_zzzz(DisasContext *s, gen_helper_gvec_4 *fn,
114
+ int rd, int rn, int rm, int ra, int data)
115
+{
116
+ unsigned vsz = vec_full_reg_size(s);
117
+ tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
118
+ vec_full_reg_offset(s, rn),
119
+ vec_full_reg_offset(s, rm),
120
+ vec_full_reg_offset(s, ra),
121
+ vsz, vsz, data, fn);
122
+}
123
+
124
/* Invoke an out-of-line helper on 2 Zregs and a predicate. */
125
static void gen_gvec_ool_zzp(DisasContext *s, gen_helper_gvec_3 *fn,
126
int rd, int rn, int pg, int data)
127
@@ -XXX,XX +XXX,XX @@ static bool trans_SQCADD_rot270(DisasContext *s, arg_rrr_esz *a)
128
{
129
return do_cadd(s, a, true, true);
130
}
131
+
132
+static bool do_sve2_zzzz_ool(DisasContext *s, arg_rrrr_esz *a,
133
+ gen_helper_gvec_4 *fn, int data)
134
+{
135
+ if (fn == NULL || !dc_isar_feature(aa64_sve2, s)) {
136
+ return false;
137
+ }
138
+ if (sve_access_check(s)) {
139
+ gen_gvec_ool_zzzz(s, fn, a->rd, a->rn, a->rm, a->ra, data);
140
+ }
141
+ return true;
142
+}
143
+
144
+static bool do_abal(DisasContext *s, arg_rrrr_esz *a, bool uns, bool sel)
145
+{
146
+ static gen_helper_gvec_4 * const fns[2][4] = {
147
+ { NULL, gen_helper_sve2_sabal_h,
148
+ gen_helper_sve2_sabal_s, gen_helper_sve2_sabal_d },
149
+ { NULL, gen_helper_sve2_uabal_h,
150
+ gen_helper_sve2_uabal_s, gen_helper_sve2_uabal_d },
151
+ };
152
+ return do_sve2_zzzz_ool(s, a, fns[uns][a->esz], sel);
153
+}
154
+
155
+static bool trans_SABALB(DisasContext *s, arg_rrrr_esz *a)
156
+{
157
+ return do_abal(s, a, false, false);
158
+}
159
+
160
+static bool trans_SABALT(DisasContext *s, arg_rrrr_esz *a)
161
+{
162
+ return do_abal(s, a, false, true);
163
+}
164
+
165
+static bool trans_UABALB(DisasContext *s, arg_rrrr_esz *a)
166
+{
167
+ return do_abal(s, a, true, false);
168
+}
169
+
170
+static bool trans_UABALT(DisasContext *s, arg_rrrr_esz *a)
171
+{
172
+ return do_abal(s, a, true, true);
173
+}
174
--
175
2.20.1
176
177
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-21-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 3 +++
9
target/arm/sve.decode | 6 ++++++
10
target/arm/sve_helper.c | 34 ++++++++++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 23 +++++++++++++++++++++++
12
4 files changed, 66 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_uabal_s, TCG_CALL_NO_RWG,
19
void, ptr, ptr, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_5(sve2_uabal_d, TCG_CALL_NO_RWG,
21
void, ptr, ptr, ptr, ptr, i32)
22
+
23
+DEF_HELPER_FLAGS_5(sve2_adcl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_5(sve2_adcl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
25
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/sve.decode
28
+++ b/target/arm/sve.decode
29
@@ -XXX,XX +XXX,XX @@ SABALB 01000101 .. 0 ..... 1100 00 ..... ..... @rda_rn_rm
30
SABALT 01000101 .. 0 ..... 1100 01 ..... ..... @rda_rn_rm
31
UABALB 01000101 .. 0 ..... 1100 10 ..... ..... @rda_rn_rm
32
UABALT 01000101 .. 0 ..... 1100 11 ..... ..... @rda_rn_rm
33
+
34
+## SVE2 integer add/subtract long with carry
35
+
36
+# ADC and SBC decoded via size in helper dispatch.
37
+ADCLB 01000101 .. 0 ..... 11010 0 ..... ..... @rda_rn_rm
38
+ADCLT 01000101 .. 0 ..... 11010 1 ..... ..... @rda_rn_rm
39
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/sve_helper.c
42
+++ b/target/arm/sve_helper.c
43
@@ -XXX,XX +XXX,XX @@ DO_ZZZW_ACC(sve2_uabal_d, uint64_t, uint32_t, , H1_4, DO_ABD)
44
45
#undef DO_ZZZW_ACC
46
47
+void HELPER(sve2_adcl_s)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
48
+{
49
+ intptr_t i, opr_sz = simd_oprsz(desc);
50
+ int sel = H4(extract32(desc, SIMD_DATA_SHIFT, 1));
51
+ uint32_t inv = -extract32(desc, SIMD_DATA_SHIFT + 1, 1);
52
+ uint32_t *a = va, *n = vn;
53
+ uint64_t *d = vd, *m = vm;
54
+
55
+ for (i = 0; i < opr_sz / 8; ++i) {
56
+ uint32_t e1 = a[2 * i + H4(0)];
57
+ uint32_t e2 = n[2 * i + sel] ^ inv;
58
+ uint64_t c = extract64(m[i], 32, 1);
59
+ /* Compute and store the entire 33-bit result at once. */
60
+ d[i] = c + e1 + e2;
61
+ }
62
+}
63
+
64
+void HELPER(sve2_adcl_d)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
65
+{
66
+ intptr_t i, opr_sz = simd_oprsz(desc);
67
+ int sel = extract32(desc, SIMD_DATA_SHIFT, 1);
68
+ uint64_t inv = -(uint64_t)extract32(desc, SIMD_DATA_SHIFT + 1, 1);
69
+ uint64_t *d = vd, *a = va, *n = vn, *m = vm;
70
+
71
+ for (i = 0; i < opr_sz / 8; i += 2) {
72
+ Int128 e1 = int128_make64(a[i]);
73
+ Int128 e2 = int128_make64(n[i + sel] ^ inv);
74
+ Int128 c = int128_make64(m[i + 1] & 1);
75
+ Int128 r = int128_add(int128_add(e1, e2), c);
76
+ d[i + 0] = int128_getlo(r);
77
+ d[i + 1] = int128_gethi(r);
78
+ }
79
+}
80
+
81
#define DO_BITPERM(NAME, TYPE, OP) \
82
void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
83
{ \
84
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/translate-sve.c
87
+++ b/target/arm/translate-sve.c
88
@@ -XXX,XX +XXX,XX @@ static bool trans_UABALT(DisasContext *s, arg_rrrr_esz *a)
89
{
90
return do_abal(s, a, true, true);
91
}
92
+
93
+static bool do_adcl(DisasContext *s, arg_rrrr_esz *a, bool sel)
94
+{
95
+ static gen_helper_gvec_4 * const fns[2] = {
96
+ gen_helper_sve2_adcl_s,
97
+ gen_helper_sve2_adcl_d,
98
+ };
99
+ /*
100
+ * Note that in this case the ESZ field encodes both size and sign.
101
+ * Split out 'subtract' into bit 1 of the data field for the helper.
102
+ */
103
+ return do_sve2_zzzz_ool(s, a, fns[a->esz & 1], (a->esz & 2) | sel);
104
+}
105
+
106
+static bool trans_ADCLB(DisasContext *s, arg_rrrr_esz *a)
107
+{
108
+ return do_adcl(s, a, false);
109
+}
110
+
111
+static bool trans_ADCLT(DisasContext *s, arg_rrrr_esz *a)
112
+{
113
+ return do_adcl(s, a, true);
114
+}
115
--
116
2.20.1
117
118
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-22-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/sve.decode | 8 ++++++++
9
target/arm/translate-sve.c | 34 ++++++++++++++++++++++++++++++++++
10
2 files changed, 42 insertions(+)
11
12
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/sve.decode
15
+++ b/target/arm/sve.decode
16
@@ -XXX,XX +XXX,XX @@ UABALT 01000101 .. 0 ..... 1100 11 ..... ..... @rda_rn_rm
17
# ADC and SBC decoded via size in helper dispatch.
18
ADCLB 01000101 .. 0 ..... 11010 0 ..... ..... @rda_rn_rm
19
ADCLT 01000101 .. 0 ..... 11010 1 ..... ..... @rda_rn_rm
20
+
21
+## SVE2 bitwise shift right and accumulate
22
+
23
+# TODO: Use @rda and %reg_movprfx here.
24
+SSRA 01000101 .. 0 ..... 1110 00 ..... ..... @rd_rn_tszimm_shr
25
+USRA 01000101 .. 0 ..... 1110 01 ..... ..... @rd_rn_tszimm_shr
26
+SRSRA 01000101 .. 0 ..... 1110 10 ..... ..... @rd_rn_tszimm_shr
27
+URSRA 01000101 .. 0 ..... 1110 11 ..... ..... @rd_rn_tszimm_shr
28
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/translate-sve.c
31
+++ b/target/arm/translate-sve.c
32
@@ -XXX,XX +XXX,XX @@ static bool trans_ADCLT(DisasContext *s, arg_rrrr_esz *a)
33
{
34
return do_adcl(s, a, true);
35
}
36
+
37
+static bool do_sve2_fn2i(DisasContext *s, arg_rri_esz *a, GVecGen2iFn *fn)
38
+{
39
+ if (a->esz < 0 || !dc_isar_feature(aa64_sve2, s)) {
40
+ return false;
41
+ }
42
+ if (sve_access_check(s)) {
43
+ unsigned vsz = vec_full_reg_size(s);
44
+ unsigned rd_ofs = vec_full_reg_offset(s, a->rd);
45
+ unsigned rn_ofs = vec_full_reg_offset(s, a->rn);
46
+ fn(a->esz, rd_ofs, rn_ofs, a->imm, vsz, vsz);
47
+ }
48
+ return true;
49
+}
50
+
51
+static bool trans_SSRA(DisasContext *s, arg_rri_esz *a)
52
+{
53
+ return do_sve2_fn2i(s, a, gen_gvec_ssra);
54
+}
55
+
56
+static bool trans_USRA(DisasContext *s, arg_rri_esz *a)
57
+{
58
+ return do_sve2_fn2i(s, a, gen_gvec_usra);
59
+}
60
+
61
+static bool trans_SRSRA(DisasContext *s, arg_rri_esz *a)
62
+{
63
+ return do_sve2_fn2i(s, a, gen_gvec_srsra);
64
+}
65
+
66
+static bool trans_URSRA(DisasContext *s, arg_rri_esz *a)
67
+{
68
+ return do_sve2_fn2i(s, a, gen_gvec_ursra);
69
+}
70
--
71
2.20.1
72
73
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-23-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/sve.decode | 5 +++++
9
target/arm/translate-sve.c | 10 ++++++++++
10
2 files changed, 15 insertions(+)
11
12
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/sve.decode
15
+++ b/target/arm/sve.decode
16
@@ -XXX,XX +XXX,XX @@ SSRA 01000101 .. 0 ..... 1110 00 ..... ..... @rd_rn_tszimm_shr
17
USRA 01000101 .. 0 ..... 1110 01 ..... ..... @rd_rn_tszimm_shr
18
SRSRA 01000101 .. 0 ..... 1110 10 ..... ..... @rd_rn_tszimm_shr
19
URSRA 01000101 .. 0 ..... 1110 11 ..... ..... @rd_rn_tszimm_shr
20
+
21
+## SVE2 bitwise shift and insert
22
+
23
+SRI 01000101 .. 0 ..... 11110 0 ..... ..... @rd_rn_tszimm_shr
24
+SLI 01000101 .. 0 ..... 11110 1 ..... ..... @rd_rn_tszimm_shl
25
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/translate-sve.c
28
+++ b/target/arm/translate-sve.c
29
@@ -XXX,XX +XXX,XX @@ static bool trans_URSRA(DisasContext *s, arg_rri_esz *a)
30
{
31
return do_sve2_fn2i(s, a, gen_gvec_ursra);
32
}
33
+
34
+static bool trans_SRI(DisasContext *s, arg_rri_esz *a)
35
+{
36
+ return do_sve2_fn2i(s, a, gen_gvec_sri);
37
+}
38
+
39
+static bool trans_SLI(DisasContext *s, arg_rri_esz *a)
40
+{
41
+ return do_sve2_fn2i(s, a, gen_gvec_sli);
42
+}
43
--
44
2.20.1
45
46
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-24-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/sve.decode | 6 ++++++
9
target/arm/translate-sve.c | 21 +++++++++++++++++++++
10
2 files changed, 27 insertions(+)
11
12
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/sve.decode
15
+++ b/target/arm/sve.decode
16
@@ -XXX,XX +XXX,XX @@ URSRA 01000101 .. 0 ..... 1110 11 ..... ..... @rd_rn_tszimm_shr
17
18
SRI 01000101 .. 0 ..... 11110 0 ..... ..... @rd_rn_tszimm_shr
19
SLI 01000101 .. 0 ..... 11110 1 ..... ..... @rd_rn_tszimm_shl
20
+
21
+## SVE2 integer absolute difference and accumulate
22
+
23
+# TODO: Use @rda and %reg_movprfx here.
24
+SABA 01000101 .. 0 ..... 11111 0 ..... ..... @rd_rn_rm
25
+UABA 01000101 .. 0 ..... 11111 1 ..... ..... @rd_rn_rm
26
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/translate-sve.c
29
+++ b/target/arm/translate-sve.c
30
@@ -XXX,XX +XXX,XX @@ static bool trans_SLI(DisasContext *s, arg_rri_esz *a)
31
{
32
return do_sve2_fn2i(s, a, gen_gvec_sli);
33
}
34
+
35
+static bool do_sve2_fn_zzz(DisasContext *s, arg_rrr_esz *a, GVecGen3Fn *fn)
36
+{
37
+ if (!dc_isar_feature(aa64_sve2, s)) {
38
+ return false;
39
+ }
40
+ if (sve_access_check(s)) {
41
+ gen_gvec_fn_zzz(s, fn, a->esz, a->rd, a->rn, a->rm);
42
+ }
43
+ return true;
44
+}
45
+
46
+static bool trans_SABA(DisasContext *s, arg_rrr_esz *a)
47
+{
48
+ return do_sve2_fn_zzz(s, a, gen_gvec_saba);
49
+}
50
+
51
+static bool trans_UABA(DisasContext *s, arg_rrr_esz *a)
52
+{
53
+ return do_sve2_fn_zzz(s, a, gen_gvec_uaba);
54
+}
55
--
56
2.20.1
57
58
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-25-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 24 ++++
9
target/arm/sve.decode | 12 ++
10
target/arm/sve_helper.c | 56 +++++++++
11
target/arm/translate-sve.c | 238 +++++++++++++++++++++++++++++++++++++
12
4 files changed, 330 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_uabal_d, TCG_CALL_NO_RWG,
19
20
DEF_HELPER_FLAGS_5(sve2_adcl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_5(sve2_adcl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
22
+
23
+DEF_HELPER_FLAGS_3(sve2_sqxtnb_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_3(sve2_sqxtnb_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_3(sve2_sqxtnb_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
26
+
27
+DEF_HELPER_FLAGS_3(sve2_uqxtnb_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_3(sve2_uqxtnb_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_3(sve2_uqxtnb_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
30
+
31
+DEF_HELPER_FLAGS_3(sve2_sqxtunb_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_3(sve2_sqxtunb_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_3(sve2_sqxtunb_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
34
+
35
+DEF_HELPER_FLAGS_3(sve2_sqxtnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_3(sve2_sqxtnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
37
+DEF_HELPER_FLAGS_3(sve2_sqxtnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
38
+
39
+DEF_HELPER_FLAGS_3(sve2_uqxtnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_3(sve2_uqxtnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_3(sve2_uqxtnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
42
+
43
+DEF_HELPER_FLAGS_3(sve2_sqxtunt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_3(sve2_sqxtunt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_3(sve2_sqxtunt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
46
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/sve.decode
49
+++ b/target/arm/sve.decode
50
@@ -XXX,XX +XXX,XX @@ SLI 01000101 .. 0 ..... 11110 1 ..... ..... @rd_rn_tszimm_shl
51
# TODO: Use @rda and %reg_movprfx here.
52
SABA 01000101 .. 0 ..... 11111 0 ..... ..... @rd_rn_rm
53
UABA 01000101 .. 0 ..... 11111 1 ..... ..... @rd_rn_rm
54
+
55
+#### SVE2 Narrowing
56
+
57
+## SVE2 saturating extract narrow
58
+
59
+# Bits 23, 18-16 are zero, limited in the translator via esz < 3 & imm == 0.
60
+SQXTNB 01000101 .. 1 ..... 010 000 ..... ..... @rd_rn_tszimm_shl
61
+SQXTNT 01000101 .. 1 ..... 010 001 ..... ..... @rd_rn_tszimm_shl
62
+UQXTNB 01000101 .. 1 ..... 010 010 ..... ..... @rd_rn_tszimm_shl
63
+UQXTNT 01000101 .. 1 ..... 010 011 ..... ..... @rd_rn_tszimm_shl
64
+SQXTUNB 01000101 .. 1 ..... 010 100 ..... ..... @rd_rn_tszimm_shl
65
+SQXTUNT 01000101 .. 1 ..... 010 101 ..... ..... @rd_rn_tszimm_shl
66
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/sve_helper.c
69
+++ b/target/arm/sve_helper.c
70
@@ -XXX,XX +XXX,XX @@ DO_ZZZW_ACC(sve2_uabal_d, uint64_t, uint32_t, , H1_4, DO_ABD)
71
72
#undef DO_ZZZW_ACC
73
74
+#define DO_XTNB(NAME, TYPE, OP) \
75
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
76
+{ \
77
+ intptr_t i, opr_sz = simd_oprsz(desc); \
78
+ for (i = 0; i < opr_sz; i += sizeof(TYPE)) { \
79
+ TYPE nn = *(TYPE *)(vn + i); \
80
+ nn = OP(nn) & MAKE_64BIT_MASK(0, sizeof(TYPE) * 4); \
81
+ *(TYPE *)(vd + i) = nn; \
82
+ } \
83
+}
84
+
85
+#define DO_XTNT(NAME, TYPE, TYPEN, H, OP) \
86
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
87
+{ \
88
+ intptr_t i, opr_sz = simd_oprsz(desc), odd = H(sizeof(TYPEN)); \
89
+ for (i = 0; i < opr_sz; i += sizeof(TYPE)) { \
90
+ TYPE nn = *(TYPE *)(vn + i); \
91
+ *(TYPEN *)(vd + i + odd) = OP(nn); \
92
+ } \
93
+}
94
+
95
+#define DO_SQXTN_H(n) do_sat_bhs(n, INT8_MIN, INT8_MAX)
96
+#define DO_SQXTN_S(n) do_sat_bhs(n, INT16_MIN, INT16_MAX)
97
+#define DO_SQXTN_D(n) do_sat_bhs(n, INT32_MIN, INT32_MAX)
98
+
99
+DO_XTNB(sve2_sqxtnb_h, int16_t, DO_SQXTN_H)
100
+DO_XTNB(sve2_sqxtnb_s, int32_t, DO_SQXTN_S)
101
+DO_XTNB(sve2_sqxtnb_d, int64_t, DO_SQXTN_D)
102
+
103
+DO_XTNT(sve2_sqxtnt_h, int16_t, int8_t, H1, DO_SQXTN_H)
104
+DO_XTNT(sve2_sqxtnt_s, int32_t, int16_t, H1_2, DO_SQXTN_S)
105
+DO_XTNT(sve2_sqxtnt_d, int64_t, int32_t, H1_4, DO_SQXTN_D)
106
+
107
+#define DO_UQXTN_H(n) do_sat_bhs(n, 0, UINT8_MAX)
108
+#define DO_UQXTN_S(n) do_sat_bhs(n, 0, UINT16_MAX)
109
+#define DO_UQXTN_D(n) do_sat_bhs(n, 0, UINT32_MAX)
110
+
111
+DO_XTNB(sve2_uqxtnb_h, uint16_t, DO_UQXTN_H)
112
+DO_XTNB(sve2_uqxtnb_s, uint32_t, DO_UQXTN_S)
113
+DO_XTNB(sve2_uqxtnb_d, uint64_t, DO_UQXTN_D)
114
+
115
+DO_XTNT(sve2_uqxtnt_h, uint16_t, uint8_t, H1, DO_UQXTN_H)
116
+DO_XTNT(sve2_uqxtnt_s, uint32_t, uint16_t, H1_2, DO_UQXTN_S)
117
+DO_XTNT(sve2_uqxtnt_d, uint64_t, uint32_t, H1_4, DO_UQXTN_D)
118
+
119
+DO_XTNB(sve2_sqxtunb_h, int16_t, DO_UQXTN_H)
120
+DO_XTNB(sve2_sqxtunb_s, int32_t, DO_UQXTN_S)
121
+DO_XTNB(sve2_sqxtunb_d, int64_t, DO_UQXTN_D)
122
+
123
+DO_XTNT(sve2_sqxtunt_h, int16_t, int8_t, H1, DO_UQXTN_H)
124
+DO_XTNT(sve2_sqxtunt_s, int32_t, int16_t, H1_2, DO_UQXTN_S)
125
+DO_XTNT(sve2_sqxtunt_d, int64_t, int32_t, H1_4, DO_UQXTN_D)
126
+
127
+#undef DO_XTNB
128
+#undef DO_XTNT
129
+
130
void HELPER(sve2_adcl_s)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
131
{
132
intptr_t i, opr_sz = simd_oprsz(desc);
133
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/target/arm/translate-sve.c
136
+++ b/target/arm/translate-sve.c
137
@@ -XXX,XX +XXX,XX @@ static bool trans_UABA(DisasContext *s, arg_rrr_esz *a)
138
{
139
return do_sve2_fn_zzz(s, a, gen_gvec_uaba);
140
}
141
+
142
+static bool do_sve2_narrow_extract(DisasContext *s, arg_rri_esz *a,
143
+ const GVecGen2 ops[3])
144
+{
145
+ if (a->esz < 0 || a->esz > MO_32 || a->imm != 0 ||
146
+ !dc_isar_feature(aa64_sve2, s)) {
147
+ return false;
148
+ }
149
+ if (sve_access_check(s)) {
150
+ unsigned vsz = vec_full_reg_size(s);
151
+ tcg_gen_gvec_2(vec_full_reg_offset(s, a->rd),
152
+ vec_full_reg_offset(s, a->rn),
153
+ vsz, vsz, &ops[a->esz]);
154
+ }
155
+ return true;
156
+}
157
+
158
+static const TCGOpcode sqxtn_list[] = {
159
+ INDEX_op_shli_vec, INDEX_op_smin_vec, INDEX_op_smax_vec, 0
160
+};
161
+
162
+static void gen_sqxtnb_vec(unsigned vece, TCGv_vec d, TCGv_vec n)
163
+{
164
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
165
+ int halfbits = 4 << vece;
166
+ int64_t mask = (1ull << halfbits) - 1;
167
+ int64_t min = -1ull << (halfbits - 1);
168
+ int64_t max = -min - 1;
169
+
170
+ tcg_gen_dupi_vec(vece, t, min);
171
+ tcg_gen_smax_vec(vece, d, n, t);
172
+ tcg_gen_dupi_vec(vece, t, max);
173
+ tcg_gen_smin_vec(vece, d, d, t);
174
+ tcg_gen_dupi_vec(vece, t, mask);
175
+ tcg_gen_and_vec(vece, d, d, t);
176
+ tcg_temp_free_vec(t);
177
+}
178
+
179
+static bool trans_SQXTNB(DisasContext *s, arg_rri_esz *a)
180
+{
181
+ static const GVecGen2 ops[3] = {
182
+ { .fniv = gen_sqxtnb_vec,
183
+ .opt_opc = sqxtn_list,
184
+ .fno = gen_helper_sve2_sqxtnb_h,
185
+ .vece = MO_16 },
186
+ { .fniv = gen_sqxtnb_vec,
187
+ .opt_opc = sqxtn_list,
188
+ .fno = gen_helper_sve2_sqxtnb_s,
189
+ .vece = MO_32 },
190
+ { .fniv = gen_sqxtnb_vec,
191
+ .opt_opc = sqxtn_list,
192
+ .fno = gen_helper_sve2_sqxtnb_d,
193
+ .vece = MO_64 },
194
+ };
195
+ return do_sve2_narrow_extract(s, a, ops);
196
+}
197
+
198
+static void gen_sqxtnt_vec(unsigned vece, TCGv_vec d, TCGv_vec n)
199
+{
200
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
201
+ int halfbits = 4 << vece;
202
+ int64_t mask = (1ull << halfbits) - 1;
203
+ int64_t min = -1ull << (halfbits - 1);
204
+ int64_t max = -min - 1;
205
+
206
+ tcg_gen_dupi_vec(vece, t, min);
207
+ tcg_gen_smax_vec(vece, n, n, t);
208
+ tcg_gen_dupi_vec(vece, t, max);
209
+ tcg_gen_smin_vec(vece, n, n, t);
210
+ tcg_gen_shli_vec(vece, n, n, halfbits);
211
+ tcg_gen_dupi_vec(vece, t, mask);
212
+ tcg_gen_bitsel_vec(vece, d, t, d, n);
213
+ tcg_temp_free_vec(t);
214
+}
215
+
216
+static bool trans_SQXTNT(DisasContext *s, arg_rri_esz *a)
217
+{
218
+ static const GVecGen2 ops[3] = {
219
+ { .fniv = gen_sqxtnt_vec,
220
+ .opt_opc = sqxtn_list,
221
+ .load_dest = true,
222
+ .fno = gen_helper_sve2_sqxtnt_h,
223
+ .vece = MO_16 },
224
+ { .fniv = gen_sqxtnt_vec,
225
+ .opt_opc = sqxtn_list,
226
+ .load_dest = true,
227
+ .fno = gen_helper_sve2_sqxtnt_s,
228
+ .vece = MO_32 },
229
+ { .fniv = gen_sqxtnt_vec,
230
+ .opt_opc = sqxtn_list,
231
+ .load_dest = true,
232
+ .fno = gen_helper_sve2_sqxtnt_d,
233
+ .vece = MO_64 },
234
+ };
235
+ return do_sve2_narrow_extract(s, a, ops);
236
+}
237
+
238
+static const TCGOpcode uqxtn_list[] = {
239
+ INDEX_op_shli_vec, INDEX_op_umin_vec, 0
240
+};
241
+
242
+static void gen_uqxtnb_vec(unsigned vece, TCGv_vec d, TCGv_vec n)
243
+{
244
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
245
+ int halfbits = 4 << vece;
246
+ int64_t max = (1ull << halfbits) - 1;
247
+
248
+ tcg_gen_dupi_vec(vece, t, max);
249
+ tcg_gen_umin_vec(vece, d, n, t);
250
+ tcg_temp_free_vec(t);
251
+}
252
+
253
+static bool trans_UQXTNB(DisasContext *s, arg_rri_esz *a)
254
+{
255
+ static const GVecGen2 ops[3] = {
256
+ { .fniv = gen_uqxtnb_vec,
257
+ .opt_opc = uqxtn_list,
258
+ .fno = gen_helper_sve2_uqxtnb_h,
259
+ .vece = MO_16 },
260
+ { .fniv = gen_uqxtnb_vec,
261
+ .opt_opc = uqxtn_list,
262
+ .fno = gen_helper_sve2_uqxtnb_s,
263
+ .vece = MO_32 },
264
+ { .fniv = gen_uqxtnb_vec,
265
+ .opt_opc = uqxtn_list,
266
+ .fno = gen_helper_sve2_uqxtnb_d,
267
+ .vece = MO_64 },
268
+ };
269
+ return do_sve2_narrow_extract(s, a, ops);
270
+}
271
+
272
+static void gen_uqxtnt_vec(unsigned vece, TCGv_vec d, TCGv_vec n)
273
+{
274
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
275
+ int halfbits = 4 << vece;
276
+ int64_t max = (1ull << halfbits) - 1;
277
+
278
+ tcg_gen_dupi_vec(vece, t, max);
279
+ tcg_gen_umin_vec(vece, n, n, t);
280
+ tcg_gen_shli_vec(vece, n, n, halfbits);
281
+ tcg_gen_bitsel_vec(vece, d, t, d, n);
282
+ tcg_temp_free_vec(t);
283
+}
284
+
285
+static bool trans_UQXTNT(DisasContext *s, arg_rri_esz *a)
286
+{
287
+ static const GVecGen2 ops[3] = {
288
+ { .fniv = gen_uqxtnt_vec,
289
+ .opt_opc = uqxtn_list,
290
+ .load_dest = true,
291
+ .fno = gen_helper_sve2_uqxtnt_h,
292
+ .vece = MO_16 },
293
+ { .fniv = gen_uqxtnt_vec,
294
+ .opt_opc = uqxtn_list,
295
+ .load_dest = true,
296
+ .fno = gen_helper_sve2_uqxtnt_s,
297
+ .vece = MO_32 },
298
+ { .fniv = gen_uqxtnt_vec,
299
+ .opt_opc = uqxtn_list,
300
+ .load_dest = true,
301
+ .fno = gen_helper_sve2_uqxtnt_d,
302
+ .vece = MO_64 },
303
+ };
304
+ return do_sve2_narrow_extract(s, a, ops);
305
+}
306
+
307
+static const TCGOpcode sqxtun_list[] = {
308
+ INDEX_op_shli_vec, INDEX_op_umin_vec, INDEX_op_smax_vec, 0
309
+};
310
+
311
+static void gen_sqxtunb_vec(unsigned vece, TCGv_vec d, TCGv_vec n)
312
+{
313
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
314
+ int halfbits = 4 << vece;
315
+ int64_t max = (1ull << halfbits) - 1;
316
+
317
+ tcg_gen_dupi_vec(vece, t, 0);
318
+ tcg_gen_smax_vec(vece, d, n, t);
319
+ tcg_gen_dupi_vec(vece, t, max);
320
+ tcg_gen_umin_vec(vece, d, d, t);
321
+ tcg_temp_free_vec(t);
322
+}
323
+
324
+static bool trans_SQXTUNB(DisasContext *s, arg_rri_esz *a)
325
+{
326
+ static const GVecGen2 ops[3] = {
327
+ { .fniv = gen_sqxtunb_vec,
328
+ .opt_opc = sqxtun_list,
329
+ .fno = gen_helper_sve2_sqxtunb_h,
330
+ .vece = MO_16 },
331
+ { .fniv = gen_sqxtunb_vec,
332
+ .opt_opc = sqxtun_list,
333
+ .fno = gen_helper_sve2_sqxtunb_s,
334
+ .vece = MO_32 },
335
+ { .fniv = gen_sqxtunb_vec,
336
+ .opt_opc = sqxtun_list,
337
+ .fno = gen_helper_sve2_sqxtunb_d,
338
+ .vece = MO_64 },
339
+ };
340
+ return do_sve2_narrow_extract(s, a, ops);
341
+}
342
+
343
+static void gen_sqxtunt_vec(unsigned vece, TCGv_vec d, TCGv_vec n)
344
+{
345
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
346
+ int halfbits = 4 << vece;
347
+ int64_t max = (1ull << halfbits) - 1;
348
+
349
+ tcg_gen_dupi_vec(vece, t, 0);
350
+ tcg_gen_smax_vec(vece, n, n, t);
351
+ tcg_gen_dupi_vec(vece, t, max);
352
+ tcg_gen_umin_vec(vece, n, n, t);
353
+ tcg_gen_shli_vec(vece, n, n, halfbits);
354
+ tcg_gen_bitsel_vec(vece, d, t, d, n);
355
+ tcg_temp_free_vec(t);
356
+}
357
+
358
+static bool trans_SQXTUNT(DisasContext *s, arg_rri_esz *a)
359
+{
360
+ static const GVecGen2 ops[3] = {
361
+ { .fniv = gen_sqxtunt_vec,
362
+ .opt_opc = sqxtun_list,
363
+ .load_dest = true,
364
+ .fno = gen_helper_sve2_sqxtunt_h,
365
+ .vece = MO_16 },
366
+ { .fniv = gen_sqxtunt_vec,
367
+ .opt_opc = sqxtun_list,
368
+ .load_dest = true,
369
+ .fno = gen_helper_sve2_sqxtunt_s,
370
+ .vece = MO_32 },
371
+ { .fniv = gen_sqxtunt_vec,
372
+ .opt_opc = sqxtun_list,
373
+ .load_dest = true,
374
+ .fno = gen_helper_sve2_sqxtunt_d,
375
+ .vece = MO_64 },
376
+ };
377
+ return do_sve2_narrow_extract(s, a, ops);
378
+}
379
--
380
2.20.1
381
382
diff view generated by jsdifflib
Deleted patch
1
From: Stephen Long <steplong@quicinc.com>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Stephen Long <steplong@quicinc.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210525010358.152808-26-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper-sve.h | 35 +++++++++++++++++++++++++++++
11
target/arm/sve.decode | 8 +++++++
12
target/arm/sve_helper.c | 46 ++++++++++++++++++++++++++++++++++++++
13
target/arm/translate-sve.c | 25 +++++++++++++++++++++
14
4 files changed, 114 insertions(+)
15
16
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-sve.h
19
+++ b/target/arm/helper-sve.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve2_uqxtnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_3(sve2_sqxtunt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
22
DEF_HELPER_FLAGS_3(sve2_sqxtunt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
23
DEF_HELPER_FLAGS_3(sve2_sqxtunt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
24
+
25
+DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_h, TCG_CALL_NO_RWG,
26
+ void, ptr, ptr, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_s, TCG_CALL_NO_RWG,
28
+ void, ptr, ptr, ptr, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_d, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, ptr, i32)
31
+
32
+DEF_HELPER_FLAGS_6(sve2_fmaxnmp_zpzz_h, TCG_CALL_NO_RWG,
33
+ void, ptr, ptr, ptr, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_6(sve2_fmaxnmp_zpzz_s, TCG_CALL_NO_RWG,
35
+ void, ptr, ptr, ptr, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_6(sve2_fmaxnmp_zpzz_d, TCG_CALL_NO_RWG,
37
+ void, ptr, ptr, ptr, ptr, ptr, i32)
38
+
39
+DEF_HELPER_FLAGS_6(sve2_fminnmp_zpzz_h, TCG_CALL_NO_RWG,
40
+ void, ptr, ptr, ptr, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_6(sve2_fminnmp_zpzz_s, TCG_CALL_NO_RWG,
42
+ void, ptr, ptr, ptr, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_6(sve2_fminnmp_zpzz_d, TCG_CALL_NO_RWG,
44
+ void, ptr, ptr, ptr, ptr, ptr, i32)
45
+
46
+DEF_HELPER_FLAGS_6(sve2_fmaxp_zpzz_h, TCG_CALL_NO_RWG,
47
+ void, ptr, ptr, ptr, ptr, ptr, i32)
48
+DEF_HELPER_FLAGS_6(sve2_fmaxp_zpzz_s, TCG_CALL_NO_RWG,
49
+ void, ptr, ptr, ptr, ptr, ptr, i32)
50
+DEF_HELPER_FLAGS_6(sve2_fmaxp_zpzz_d, TCG_CALL_NO_RWG,
51
+ void, ptr, ptr, ptr, ptr, ptr, i32)
52
+
53
+DEF_HELPER_FLAGS_6(sve2_fminp_zpzz_h, TCG_CALL_NO_RWG,
54
+ void, ptr, ptr, ptr, ptr, ptr, i32)
55
+DEF_HELPER_FLAGS_6(sve2_fminp_zpzz_s, TCG_CALL_NO_RWG,
56
+ void, ptr, ptr, ptr, ptr, ptr, i32)
57
+DEF_HELPER_FLAGS_6(sve2_fminp_zpzz_d, TCG_CALL_NO_RWG,
58
+ void, ptr, ptr, ptr, ptr, ptr, i32)
59
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/arm/sve.decode
62
+++ b/target/arm/sve.decode
63
@@ -XXX,XX +XXX,XX @@ UQXTNB 01000101 .. 1 ..... 010 010 ..... ..... @rd_rn_tszimm_shl
64
UQXTNT 01000101 .. 1 ..... 010 011 ..... ..... @rd_rn_tszimm_shl
65
SQXTUNB 01000101 .. 1 ..... 010 100 ..... ..... @rd_rn_tszimm_shl
66
SQXTUNT 01000101 .. 1 ..... 010 101 ..... ..... @rd_rn_tszimm_shl
67
+
68
+## SVE2 floating-point pairwise operations
69
+
70
+FADDP 01100100 .. 010 00 0 100 ... ..... ..... @rdn_pg_rm
71
+FMAXNMP 01100100 .. 010 10 0 100 ... ..... ..... @rdn_pg_rm
72
+FMINNMP 01100100 .. 010 10 1 100 ... ..... ..... @rdn_pg_rm
73
+FMAXP 01100100 .. 010 11 0 100 ... ..... ..... @rdn_pg_rm
74
+FMINP 01100100 .. 010 11 1 100 ... ..... ..... @rdn_pg_rm
75
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/sve_helper.c
78
+++ b/target/arm/sve_helper.c
79
@@ -XXX,XX +XXX,XX @@ DO_ZPZZ_PAIR_D(sve2_sminp_zpzz_d, int64_t, DO_MIN)
80
#undef DO_ZPZZ_PAIR
81
#undef DO_ZPZZ_PAIR_D
82
83
+#define DO_ZPZZ_PAIR_FP(NAME, TYPE, H, OP) \
84
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, \
85
+ void *status, uint32_t desc) \
86
+{ \
87
+ intptr_t i, opr_sz = simd_oprsz(desc); \
88
+ for (i = 0; i < opr_sz; ) { \
89
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
90
+ do { \
91
+ TYPE n0 = *(TYPE *)(vn + H(i)); \
92
+ TYPE m0 = *(TYPE *)(vm + H(i)); \
93
+ TYPE n1 = *(TYPE *)(vn + H(i + sizeof(TYPE))); \
94
+ TYPE m1 = *(TYPE *)(vm + H(i + sizeof(TYPE))); \
95
+ if (pg & 1) { \
96
+ *(TYPE *)(vd + H(i)) = OP(n0, n1, status); \
97
+ } \
98
+ i += sizeof(TYPE), pg >>= sizeof(TYPE); \
99
+ if (pg & 1) { \
100
+ *(TYPE *)(vd + H(i)) = OP(m0, m1, status); \
101
+ } \
102
+ i += sizeof(TYPE), pg >>= sizeof(TYPE); \
103
+ } while (i & 15); \
104
+ } \
105
+}
106
+
107
+DO_ZPZZ_PAIR_FP(sve2_faddp_zpzz_h, float16, H1_2, float16_add)
108
+DO_ZPZZ_PAIR_FP(sve2_faddp_zpzz_s, float32, H1_4, float32_add)
109
+DO_ZPZZ_PAIR_FP(sve2_faddp_zpzz_d, float64, , float64_add)
110
+
111
+DO_ZPZZ_PAIR_FP(sve2_fmaxnmp_zpzz_h, float16, H1_2, float16_maxnum)
112
+DO_ZPZZ_PAIR_FP(sve2_fmaxnmp_zpzz_s, float32, H1_4, float32_maxnum)
113
+DO_ZPZZ_PAIR_FP(sve2_fmaxnmp_zpzz_d, float64, , float64_maxnum)
114
+
115
+DO_ZPZZ_PAIR_FP(sve2_fminnmp_zpzz_h, float16, H1_2, float16_minnum)
116
+DO_ZPZZ_PAIR_FP(sve2_fminnmp_zpzz_s, float32, H1_4, float32_minnum)
117
+DO_ZPZZ_PAIR_FP(sve2_fminnmp_zpzz_d, float64, , float64_minnum)
118
+
119
+DO_ZPZZ_PAIR_FP(sve2_fmaxp_zpzz_h, float16, H1_2, float16_max)
120
+DO_ZPZZ_PAIR_FP(sve2_fmaxp_zpzz_s, float32, H1_4, float32_max)
121
+DO_ZPZZ_PAIR_FP(sve2_fmaxp_zpzz_d, float64, , float64_max)
122
+
123
+DO_ZPZZ_PAIR_FP(sve2_fminp_zpzz_h, float16, H1_2, float16_min)
124
+DO_ZPZZ_PAIR_FP(sve2_fminp_zpzz_s, float32, H1_4, float32_min)
125
+DO_ZPZZ_PAIR_FP(sve2_fminp_zpzz_d, float64, , float64_min)
126
+
127
+#undef DO_ZPZZ_PAIR_FP
128
+
129
/* Three-operand expander, controlled by a predicate, in which the
130
* third operand is "wide". That is, for D = N op M, the same 64-bit
131
* value of M is used with all of the narrower values of N.
132
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/target/arm/translate-sve.c
135
+++ b/target/arm/translate-sve.c
136
@@ -XXX,XX +XXX,XX @@ static bool trans_SQXTUNT(DisasContext *s, arg_rri_esz *a)
137
};
138
return do_sve2_narrow_extract(s, a, ops);
139
}
140
+
141
+static bool do_sve2_zpzz_fp(DisasContext *s, arg_rprr_esz *a,
142
+ gen_helper_gvec_4_ptr *fn)
143
+{
144
+ if (!dc_isar_feature(aa64_sve2, s)) {
145
+ return false;
146
+ }
147
+ return do_zpzz_fp(s, a, fn);
148
+}
149
+
150
+#define DO_SVE2_ZPZZ_FP(NAME, name) \
151
+static bool trans_##NAME(DisasContext *s, arg_rprr_esz *a) \
152
+{ \
153
+ static gen_helper_gvec_4_ptr * const fns[4] = { \
154
+ NULL, gen_helper_sve2_##name##_zpzz_h, \
155
+ gen_helper_sve2_##name##_zpzz_s, gen_helper_sve2_##name##_zpzz_d \
156
+ }; \
157
+ return do_sve2_zpzz_fp(s, a, fns[a->esz]); \
158
+}
159
+
160
+DO_SVE2_ZPZZ_FP(FADDP, faddp)
161
+DO_SVE2_ZPZZ_FP(FMAXNMP, fmaxnmp)
162
+DO_SVE2_ZPZZ_FP(FMINNMP, fminnmp)
163
+DO_SVE2_ZPZZ_FP(FMAXP, fmaxp)
164
+DO_SVE2_ZPZZ_FP(FMINP, fminp)
165
--
166
2.20.1
167
168
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-27-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 16 ++++
9
target/arm/sve.decode | 8 ++
10
target/arm/sve_helper.c | 54 ++++++++++++-
11
target/arm/translate-sve.c | 160 +++++++++++++++++++++++++++++++++++++
12
4 files changed, 236 insertions(+), 2 deletions(-)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve2_sqxtunt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
19
DEF_HELPER_FLAGS_3(sve2_sqxtunt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_3(sve2_sqxtunt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_3(sve2_shrnb_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
23
+DEF_HELPER_FLAGS_3(sve2_shrnb_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_3(sve2_shrnb_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
25
+
26
+DEF_HELPER_FLAGS_3(sve2_shrnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_3(sve2_shrnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_3(sve2_shrnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
29
+
30
+DEF_HELPER_FLAGS_3(sve2_rshrnb_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_3(sve2_rshrnb_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_3(sve2_rshrnb_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
33
+
34
+DEF_HELPER_FLAGS_3(sve2_rshrnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_3(sve2_rshrnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_3(sve2_rshrnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
37
+
38
DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_h, TCG_CALL_NO_RWG,
39
void, ptr, ptr, ptr, ptr, ptr, i32)
40
DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_s, TCG_CALL_NO_RWG,
41
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/sve.decode
44
+++ b/target/arm/sve.decode
45
@@ -XXX,XX +XXX,XX @@ UQXTNT 01000101 .. 1 ..... 010 011 ..... ..... @rd_rn_tszimm_shl
46
SQXTUNB 01000101 .. 1 ..... 010 100 ..... ..... @rd_rn_tszimm_shl
47
SQXTUNT 01000101 .. 1 ..... 010 101 ..... ..... @rd_rn_tszimm_shl
48
49
+## SVE2 bitwise shift right narrow
50
+
51
+# Bit 23 == 0 is handled by esz > 0 in the translator.
52
+SHRNB 01000101 .. 1 ..... 00 0100 ..... ..... @rd_rn_tszimm_shr
53
+SHRNT 01000101 .. 1 ..... 00 0101 ..... ..... @rd_rn_tszimm_shr
54
+RSHRNB 01000101 .. 1 ..... 00 0110 ..... ..... @rd_rn_tszimm_shr
55
+RSHRNT 01000101 .. 1 ..... 00 0111 ..... ..... @rd_rn_tszimm_shr
56
+
57
## SVE2 floating-point pairwise operations
58
59
FADDP 01100100 .. 010 00 0 100 ... ..... ..... @rdn_pg_rm
60
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/sve_helper.c
63
+++ b/target/arm/sve_helper.c
64
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vg, uint32_t desc) \
65
when N is negative, add 2**M-1. */
66
#define DO_ASRD(N, M) ((N + (N < 0 ? ((__typeof(N))1 << M) - 1 : 0)) >> M)
67
68
+static inline uint64_t do_urshr(uint64_t x, unsigned sh)
69
+{
70
+ if (likely(sh < 64)) {
71
+ return (x >> sh) + ((x >> (sh - 1)) & 1);
72
+ } else if (sh == 64) {
73
+ return x >> 63;
74
+ } else {
75
+ return 0;
76
+ }
77
+}
78
+
79
DO_ZPZI(sve_asr_zpzi_b, int8_t, H1, DO_SHR)
80
DO_ZPZI(sve_asr_zpzi_h, int16_t, H1_2, DO_SHR)
81
DO_ZPZI(sve_asr_zpzi_s, int32_t, H1_4, DO_SHR)
82
@@ -XXX,XX +XXX,XX @@ DO_ZPZI(sve_asrd_h, int16_t, H1_2, DO_ASRD)
83
DO_ZPZI(sve_asrd_s, int32_t, H1_4, DO_ASRD)
84
DO_ZPZI_D(sve_asrd_d, int64_t, DO_ASRD)
85
86
-#undef DO_SHR
87
-#undef DO_SHL
88
#undef DO_ASRD
89
#undef DO_ZPZI
90
#undef DO_ZPZI_D
91
92
+#define DO_SHRNB(NAME, TYPEW, TYPEN, OP) \
93
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
94
+{ \
95
+ intptr_t i, opr_sz = simd_oprsz(desc); \
96
+ int shift = simd_data(desc); \
97
+ for (i = 0; i < opr_sz; i += sizeof(TYPEW)) { \
98
+ TYPEW nn = *(TYPEW *)(vn + i); \
99
+ *(TYPEW *)(vd + i) = (TYPEN)OP(nn, shift); \
100
+ } \
101
+}
102
+
103
+#define DO_SHRNT(NAME, TYPEW, TYPEN, HW, HN, OP) \
104
+void HELPER(NAME)(void *vd, void *vn, uint32_t desc) \
105
+{ \
106
+ intptr_t i, opr_sz = simd_oprsz(desc); \
107
+ int shift = simd_data(desc); \
108
+ for (i = 0; i < opr_sz; i += sizeof(TYPEW)) { \
109
+ TYPEW nn = *(TYPEW *)(vn + HW(i)); \
110
+ *(TYPEN *)(vd + HN(i + sizeof(TYPEN))) = OP(nn, shift); \
111
+ } \
112
+}
113
+
114
+DO_SHRNB(sve2_shrnb_h, uint16_t, uint8_t, DO_SHR)
115
+DO_SHRNB(sve2_shrnb_s, uint32_t, uint16_t, DO_SHR)
116
+DO_SHRNB(sve2_shrnb_d, uint64_t, uint32_t, DO_SHR)
117
+
118
+DO_SHRNT(sve2_shrnt_h, uint16_t, uint8_t, H1_2, H1, DO_SHR)
119
+DO_SHRNT(sve2_shrnt_s, uint32_t, uint16_t, H1_4, H1_2, DO_SHR)
120
+DO_SHRNT(sve2_shrnt_d, uint64_t, uint32_t, , H1_4, DO_SHR)
121
+
122
+DO_SHRNB(sve2_rshrnb_h, uint16_t, uint8_t, do_urshr)
123
+DO_SHRNB(sve2_rshrnb_s, uint32_t, uint16_t, do_urshr)
124
+DO_SHRNB(sve2_rshrnb_d, uint64_t, uint32_t, do_urshr)
125
+
126
+DO_SHRNT(sve2_rshrnt_h, uint16_t, uint8_t, H1_2, H1, do_urshr)
127
+DO_SHRNT(sve2_rshrnt_s, uint32_t, uint16_t, H1_4, H1_2, do_urshr)
128
+DO_SHRNT(sve2_rshrnt_d, uint64_t, uint32_t, , H1_4, do_urshr)
129
+
130
+#undef DO_SHRNB
131
+#undef DO_SHRNT
132
+
133
/* Fully general four-operand expander, controlled by a predicate.
134
*/
135
#define DO_ZPZZZ(NAME, TYPE, H, OP) \
136
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
137
index XXXXXXX..XXXXXXX 100644
138
--- a/target/arm/translate-sve.c
139
+++ b/target/arm/translate-sve.c
140
@@ -XXX,XX +XXX,XX @@ static bool trans_SQXTUNT(DisasContext *s, arg_rri_esz *a)
141
return do_sve2_narrow_extract(s, a, ops);
142
}
143
144
+static bool do_sve2_shr_narrow(DisasContext *s, arg_rri_esz *a,
145
+ const GVecGen2i ops[3])
146
+{
147
+ if (a->esz < 0 || a->esz > MO_32 || !dc_isar_feature(aa64_sve2, s)) {
148
+ return false;
149
+ }
150
+ assert(a->imm > 0 && a->imm <= (8 << a->esz));
151
+ if (sve_access_check(s)) {
152
+ unsigned vsz = vec_full_reg_size(s);
153
+ tcg_gen_gvec_2i(vec_full_reg_offset(s, a->rd),
154
+ vec_full_reg_offset(s, a->rn),
155
+ vsz, vsz, a->imm, &ops[a->esz]);
156
+ }
157
+ return true;
158
+}
159
+
160
+static void gen_shrnb_i64(unsigned vece, TCGv_i64 d, TCGv_i64 n, int shr)
161
+{
162
+ int halfbits = 4 << vece;
163
+ uint64_t mask = dup_const(vece, MAKE_64BIT_MASK(0, halfbits));
164
+
165
+ tcg_gen_shri_i64(d, n, shr);
166
+ tcg_gen_andi_i64(d, d, mask);
167
+}
168
+
169
+static void gen_shrnb16_i64(TCGv_i64 d, TCGv_i64 n, int64_t shr)
170
+{
171
+ gen_shrnb_i64(MO_16, d, n, shr);
172
+}
173
+
174
+static void gen_shrnb32_i64(TCGv_i64 d, TCGv_i64 n, int64_t shr)
175
+{
176
+ gen_shrnb_i64(MO_32, d, n, shr);
177
+}
178
+
179
+static void gen_shrnb64_i64(TCGv_i64 d, TCGv_i64 n, int64_t shr)
180
+{
181
+ gen_shrnb_i64(MO_64, d, n, shr);
182
+}
183
+
184
+static void gen_shrnb_vec(unsigned vece, TCGv_vec d, TCGv_vec n, int64_t shr)
185
+{
186
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
187
+ int halfbits = 4 << vece;
188
+ uint64_t mask = MAKE_64BIT_MASK(0, halfbits);
189
+
190
+ tcg_gen_shri_vec(vece, n, n, shr);
191
+ tcg_gen_dupi_vec(vece, t, mask);
192
+ tcg_gen_and_vec(vece, d, n, t);
193
+ tcg_temp_free_vec(t);
194
+}
195
+
196
+static bool trans_SHRNB(DisasContext *s, arg_rri_esz *a)
197
+{
198
+ static const TCGOpcode vec_list[] = { INDEX_op_shri_vec, 0 };
199
+ static const GVecGen2i ops[3] = {
200
+ { .fni8 = gen_shrnb16_i64,
201
+ .fniv = gen_shrnb_vec,
202
+ .opt_opc = vec_list,
203
+ .fno = gen_helper_sve2_shrnb_h,
204
+ .vece = MO_16 },
205
+ { .fni8 = gen_shrnb32_i64,
206
+ .fniv = gen_shrnb_vec,
207
+ .opt_opc = vec_list,
208
+ .fno = gen_helper_sve2_shrnb_s,
209
+ .vece = MO_32 },
210
+ { .fni8 = gen_shrnb64_i64,
211
+ .fniv = gen_shrnb_vec,
212
+ .opt_opc = vec_list,
213
+ .fno = gen_helper_sve2_shrnb_d,
214
+ .vece = MO_64 },
215
+ };
216
+ return do_sve2_shr_narrow(s, a, ops);
217
+}
218
+
219
+static void gen_shrnt_i64(unsigned vece, TCGv_i64 d, TCGv_i64 n, int shr)
220
+{
221
+ int halfbits = 4 << vece;
222
+ uint64_t mask = dup_const(vece, MAKE_64BIT_MASK(0, halfbits));
223
+
224
+ tcg_gen_shli_i64(n, n, halfbits - shr);
225
+ tcg_gen_andi_i64(n, n, ~mask);
226
+ tcg_gen_andi_i64(d, d, mask);
227
+ tcg_gen_or_i64(d, d, n);
228
+}
229
+
230
+static void gen_shrnt16_i64(TCGv_i64 d, TCGv_i64 n, int64_t shr)
231
+{
232
+ gen_shrnt_i64(MO_16, d, n, shr);
233
+}
234
+
235
+static void gen_shrnt32_i64(TCGv_i64 d, TCGv_i64 n, int64_t shr)
236
+{
237
+ gen_shrnt_i64(MO_32, d, n, shr);
238
+}
239
+
240
+static void gen_shrnt64_i64(TCGv_i64 d, TCGv_i64 n, int64_t shr)
241
+{
242
+ tcg_gen_shri_i64(n, n, shr);
243
+ tcg_gen_deposit_i64(d, d, n, 32, 32);
244
+}
245
+
246
+static void gen_shrnt_vec(unsigned vece, TCGv_vec d, TCGv_vec n, int64_t shr)
247
+{
248
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
249
+ int halfbits = 4 << vece;
250
+ uint64_t mask = MAKE_64BIT_MASK(0, halfbits);
251
+
252
+ tcg_gen_shli_vec(vece, n, n, halfbits - shr);
253
+ tcg_gen_dupi_vec(vece, t, mask);
254
+ tcg_gen_bitsel_vec(vece, d, t, d, n);
255
+ tcg_temp_free_vec(t);
256
+}
257
+
258
+static bool trans_SHRNT(DisasContext *s, arg_rri_esz *a)
259
+{
260
+ static const TCGOpcode vec_list[] = { INDEX_op_shli_vec, 0 };
261
+ static const GVecGen2i ops[3] = {
262
+ { .fni8 = gen_shrnt16_i64,
263
+ .fniv = gen_shrnt_vec,
264
+ .opt_opc = vec_list,
265
+ .load_dest = true,
266
+ .fno = gen_helper_sve2_shrnt_h,
267
+ .vece = MO_16 },
268
+ { .fni8 = gen_shrnt32_i64,
269
+ .fniv = gen_shrnt_vec,
270
+ .opt_opc = vec_list,
271
+ .load_dest = true,
272
+ .fno = gen_helper_sve2_shrnt_s,
273
+ .vece = MO_32 },
274
+ { .fni8 = gen_shrnt64_i64,
275
+ .fniv = gen_shrnt_vec,
276
+ .opt_opc = vec_list,
277
+ .load_dest = true,
278
+ .fno = gen_helper_sve2_shrnt_d,
279
+ .vece = MO_64 },
280
+ };
281
+ return do_sve2_shr_narrow(s, a, ops);
282
+}
283
+
284
+static bool trans_RSHRNB(DisasContext *s, arg_rri_esz *a)
285
+{
286
+ static const GVecGen2i ops[3] = {
287
+ { .fno = gen_helper_sve2_rshrnb_h },
288
+ { .fno = gen_helper_sve2_rshrnb_s },
289
+ { .fno = gen_helper_sve2_rshrnb_d },
290
+ };
291
+ return do_sve2_shr_narrow(s, a, ops);
292
+}
293
+
294
+static bool trans_RSHRNT(DisasContext *s, arg_rri_esz *a)
295
+{
296
+ static const GVecGen2i ops[3] = {
297
+ { .fno = gen_helper_sve2_rshrnt_h },
298
+ { .fno = gen_helper_sve2_rshrnt_s },
299
+ { .fno = gen_helper_sve2_rshrnt_d },
300
+ };
301
+ return do_sve2_shr_narrow(s, a, ops);
302
+}
303
+
304
static bool do_sve2_zpzz_fp(DisasContext *s, arg_rprr_esz *a,
305
gen_helper_gvec_4_ptr *fn)
306
{
307
--
308
2.20.1
309
310
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-29-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 16 +++++++
9
target/arm/sve.decode | 4 ++
10
target/arm/sve_helper.c | 24 ++++++++++
11
target/arm/translate-sve.c | 93 ++++++++++++++++++++++++++++++++++++++
12
4 files changed, 137 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve2_sqrshrunt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
19
DEF_HELPER_FLAGS_3(sve2_sqrshrunt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_3(sve2_sqrshrunt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_3(sve2_uqshrnb_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
23
+DEF_HELPER_FLAGS_3(sve2_uqshrnb_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_3(sve2_uqshrnb_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
25
+
26
+DEF_HELPER_FLAGS_3(sve2_uqshrnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_3(sve2_uqshrnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_3(sve2_uqshrnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
29
+
30
+DEF_HELPER_FLAGS_3(sve2_uqrshrnb_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_3(sve2_uqrshrnb_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_3(sve2_uqrshrnb_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
33
+
34
+DEF_HELPER_FLAGS_3(sve2_uqrshrnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_3(sve2_uqrshrnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_3(sve2_uqrshrnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
37
+
38
DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_h, TCG_CALL_NO_RWG,
39
void, ptr, ptr, ptr, ptr, ptr, i32)
40
DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_s, TCG_CALL_NO_RWG,
41
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/sve.decode
44
+++ b/target/arm/sve.decode
45
@@ -XXX,XX +XXX,XX @@ SHRNB 01000101 .. 1 ..... 00 0100 ..... ..... @rd_rn_tszimm_shr
46
SHRNT 01000101 .. 1 ..... 00 0101 ..... ..... @rd_rn_tszimm_shr
47
RSHRNB 01000101 .. 1 ..... 00 0110 ..... ..... @rd_rn_tszimm_shr
48
RSHRNT 01000101 .. 1 ..... 00 0111 ..... ..... @rd_rn_tszimm_shr
49
+UQSHRNB 01000101 .. 1 ..... 00 1100 ..... ..... @rd_rn_tszimm_shr
50
+UQSHRNT 01000101 .. 1 ..... 00 1101 ..... ..... @rd_rn_tszimm_shr
51
+UQRSHRNB 01000101 .. 1 ..... 00 1110 ..... ..... @rd_rn_tszimm_shr
52
+UQRSHRNT 01000101 .. 1 ..... 00 1111 ..... ..... @rd_rn_tszimm_shr
53
54
## SVE2 floating-point pairwise operations
55
56
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/sve_helper.c
59
+++ b/target/arm/sve_helper.c
60
@@ -XXX,XX +XXX,XX @@ DO_SHRNT(sve2_sqrshrunt_h, int16_t, uint8_t, H1_2, H1, DO_SQRSHRUN_H)
61
DO_SHRNT(sve2_sqrshrunt_s, int32_t, uint16_t, H1_4, H1_2, DO_SQRSHRUN_S)
62
DO_SHRNT(sve2_sqrshrunt_d, int64_t, uint32_t, , H1_4, DO_SQRSHRUN_D)
63
64
+#define DO_UQSHRN_H(x, sh) MIN(x >> sh, UINT8_MAX)
65
+#define DO_UQSHRN_S(x, sh) MIN(x >> sh, UINT16_MAX)
66
+#define DO_UQSHRN_D(x, sh) MIN(x >> sh, UINT32_MAX)
67
+
68
+DO_SHRNB(sve2_uqshrnb_h, uint16_t, uint8_t, DO_UQSHRN_H)
69
+DO_SHRNB(sve2_uqshrnb_s, uint32_t, uint16_t, DO_UQSHRN_S)
70
+DO_SHRNB(sve2_uqshrnb_d, uint64_t, uint32_t, DO_UQSHRN_D)
71
+
72
+DO_SHRNT(sve2_uqshrnt_h, uint16_t, uint8_t, H1_2, H1, DO_UQSHRN_H)
73
+DO_SHRNT(sve2_uqshrnt_s, uint32_t, uint16_t, H1_4, H1_2, DO_UQSHRN_S)
74
+DO_SHRNT(sve2_uqshrnt_d, uint64_t, uint32_t, , H1_4, DO_UQSHRN_D)
75
+
76
+#define DO_UQRSHRN_H(x, sh) MIN(do_urshr(x, sh), UINT8_MAX)
77
+#define DO_UQRSHRN_S(x, sh) MIN(do_urshr(x, sh), UINT16_MAX)
78
+#define DO_UQRSHRN_D(x, sh) MIN(do_urshr(x, sh), UINT32_MAX)
79
+
80
+DO_SHRNB(sve2_uqrshrnb_h, uint16_t, uint8_t, DO_UQRSHRN_H)
81
+DO_SHRNB(sve2_uqrshrnb_s, uint32_t, uint16_t, DO_UQRSHRN_S)
82
+DO_SHRNB(sve2_uqrshrnb_d, uint64_t, uint32_t, DO_UQRSHRN_D)
83
+
84
+DO_SHRNT(sve2_uqrshrnt_h, uint16_t, uint8_t, H1_2, H1, DO_UQRSHRN_H)
85
+DO_SHRNT(sve2_uqrshrnt_s, uint32_t, uint16_t, H1_4, H1_2, DO_UQRSHRN_S)
86
+DO_SHRNT(sve2_uqrshrnt_d, uint64_t, uint32_t, , H1_4, DO_UQRSHRN_D)
87
+
88
#undef DO_SHRNB
89
#undef DO_SHRNT
90
91
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/target/arm/translate-sve.c
94
+++ b/target/arm/translate-sve.c
95
@@ -XXX,XX +XXX,XX @@ static bool trans_SQRSHRUNT(DisasContext *s, arg_rri_esz *a)
96
return do_sve2_shr_narrow(s, a, ops);
97
}
98
99
+static void gen_uqshrnb_vec(unsigned vece, TCGv_vec d,
100
+ TCGv_vec n, int64_t shr)
101
+{
102
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
103
+ int halfbits = 4 << vece;
104
+
105
+ tcg_gen_shri_vec(vece, n, n, shr);
106
+ tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(0, halfbits));
107
+ tcg_gen_umin_vec(vece, d, n, t);
108
+ tcg_temp_free_vec(t);
109
+}
110
+
111
+static bool trans_UQSHRNB(DisasContext *s, arg_rri_esz *a)
112
+{
113
+ static const TCGOpcode vec_list[] = {
114
+ INDEX_op_shri_vec, INDEX_op_umin_vec, 0
115
+ };
116
+ static const GVecGen2i ops[3] = {
117
+ { .fniv = gen_uqshrnb_vec,
118
+ .opt_opc = vec_list,
119
+ .fno = gen_helper_sve2_uqshrnb_h,
120
+ .vece = MO_16 },
121
+ { .fniv = gen_uqshrnb_vec,
122
+ .opt_opc = vec_list,
123
+ .fno = gen_helper_sve2_uqshrnb_s,
124
+ .vece = MO_32 },
125
+ { .fniv = gen_uqshrnb_vec,
126
+ .opt_opc = vec_list,
127
+ .fno = gen_helper_sve2_uqshrnb_d,
128
+ .vece = MO_64 },
129
+ };
130
+ return do_sve2_shr_narrow(s, a, ops);
131
+}
132
+
133
+static void gen_uqshrnt_vec(unsigned vece, TCGv_vec d,
134
+ TCGv_vec n, int64_t shr)
135
+{
136
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
137
+ int halfbits = 4 << vece;
138
+
139
+ tcg_gen_shri_vec(vece, n, n, shr);
140
+ tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(0, halfbits));
141
+ tcg_gen_umin_vec(vece, n, n, t);
142
+ tcg_gen_shli_vec(vece, n, n, halfbits);
143
+ tcg_gen_bitsel_vec(vece, d, t, d, n);
144
+ tcg_temp_free_vec(t);
145
+}
146
+
147
+static bool trans_UQSHRNT(DisasContext *s, arg_rri_esz *a)
148
+{
149
+ static const TCGOpcode vec_list[] = {
150
+ INDEX_op_shli_vec, INDEX_op_shri_vec, INDEX_op_umin_vec, 0
151
+ };
152
+ static const GVecGen2i ops[3] = {
153
+ { .fniv = gen_uqshrnt_vec,
154
+ .opt_opc = vec_list,
155
+ .load_dest = true,
156
+ .fno = gen_helper_sve2_uqshrnt_h,
157
+ .vece = MO_16 },
158
+ { .fniv = gen_uqshrnt_vec,
159
+ .opt_opc = vec_list,
160
+ .load_dest = true,
161
+ .fno = gen_helper_sve2_uqshrnt_s,
162
+ .vece = MO_32 },
163
+ { .fniv = gen_uqshrnt_vec,
164
+ .opt_opc = vec_list,
165
+ .load_dest = true,
166
+ .fno = gen_helper_sve2_uqshrnt_d,
167
+ .vece = MO_64 },
168
+ };
169
+ return do_sve2_shr_narrow(s, a, ops);
170
+}
171
+
172
+static bool trans_UQRSHRNB(DisasContext *s, arg_rri_esz *a)
173
+{
174
+ static const GVecGen2i ops[3] = {
175
+ { .fno = gen_helper_sve2_uqrshrnb_h },
176
+ { .fno = gen_helper_sve2_uqrshrnb_s },
177
+ { .fno = gen_helper_sve2_uqrshrnb_d },
178
+ };
179
+ return do_sve2_shr_narrow(s, a, ops);
180
+}
181
+
182
+static bool trans_UQRSHRNT(DisasContext *s, arg_rri_esz *a)
183
+{
184
+ static const GVecGen2i ops[3] = {
185
+ { .fno = gen_helper_sve2_uqrshrnt_h },
186
+ { .fno = gen_helper_sve2_uqrshrnt_s },
187
+ { .fno = gen_helper_sve2_uqrshrnt_d },
188
+ };
189
+ return do_sve2_shr_narrow(s, a, ops);
190
+}
191
+
192
static bool do_sve2_zpzz_fp(DisasContext *s, arg_rprr_esz *a,
193
gen_helper_gvec_4_ptr *fn)
194
{
195
--
196
2.20.1
197
198
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This completes the section "SVE2 bitwise shift right narrow".
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210525010358.152808-30-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper-sve.h | 16 ++++++
11
target/arm/sve.decode | 4 ++
12
target/arm/sve_helper.c | 24 +++++++++
13
target/arm/translate-sve.c | 105 +++++++++++++++++++++++++++++++++++++
14
4 files changed, 149 insertions(+)
15
16
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-sve.h
19
+++ b/target/arm/helper-sve.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve2_sqrshrunt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_3(sve2_sqrshrunt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
22
DEF_HELPER_FLAGS_3(sve2_sqrshrunt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
23
24
+DEF_HELPER_FLAGS_3(sve2_sqshrnb_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_3(sve2_sqshrnb_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_3(sve2_sqshrnb_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
27
+
28
+DEF_HELPER_FLAGS_3(sve2_sqshrnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_3(sve2_sqshrnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_3(sve2_sqshrnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
31
+
32
+DEF_HELPER_FLAGS_3(sve2_sqrshrnb_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_3(sve2_sqrshrnb_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_3(sve2_sqrshrnb_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
35
+
36
+DEF_HELPER_FLAGS_3(sve2_sqrshrnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
37
+DEF_HELPER_FLAGS_3(sve2_sqrshrnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_3(sve2_sqrshrnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
39
+
40
DEF_HELPER_FLAGS_3(sve2_uqshrnb_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
41
DEF_HELPER_FLAGS_3(sve2_uqshrnb_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
42
DEF_HELPER_FLAGS_3(sve2_uqshrnb_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
43
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/sve.decode
46
+++ b/target/arm/sve.decode
47
@@ -XXX,XX +XXX,XX @@ SHRNB 01000101 .. 1 ..... 00 0100 ..... ..... @rd_rn_tszimm_shr
48
SHRNT 01000101 .. 1 ..... 00 0101 ..... ..... @rd_rn_tszimm_shr
49
RSHRNB 01000101 .. 1 ..... 00 0110 ..... ..... @rd_rn_tszimm_shr
50
RSHRNT 01000101 .. 1 ..... 00 0111 ..... ..... @rd_rn_tszimm_shr
51
+SQSHRNB 01000101 .. 1 ..... 00 1000 ..... ..... @rd_rn_tszimm_shr
52
+SQSHRNT 01000101 .. 1 ..... 00 1001 ..... ..... @rd_rn_tszimm_shr
53
+SQRSHRNB 01000101 .. 1 ..... 00 1010 ..... ..... @rd_rn_tszimm_shr
54
+SQRSHRNT 01000101 .. 1 ..... 00 1011 ..... ..... @rd_rn_tszimm_shr
55
UQSHRNB 01000101 .. 1 ..... 00 1100 ..... ..... @rd_rn_tszimm_shr
56
UQSHRNT 01000101 .. 1 ..... 00 1101 ..... ..... @rd_rn_tszimm_shr
57
UQRSHRNB 01000101 .. 1 ..... 00 1110 ..... ..... @rd_rn_tszimm_shr
58
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/sve_helper.c
61
+++ b/target/arm/sve_helper.c
62
@@ -XXX,XX +XXX,XX @@ DO_SHRNT(sve2_sqrshrunt_h, int16_t, uint8_t, H1_2, H1, DO_SQRSHRUN_H)
63
DO_SHRNT(sve2_sqrshrunt_s, int32_t, uint16_t, H1_4, H1_2, DO_SQRSHRUN_S)
64
DO_SHRNT(sve2_sqrshrunt_d, int64_t, uint32_t, , H1_4, DO_SQRSHRUN_D)
65
66
+#define DO_SQSHRN_H(x, sh) do_sat_bhs(x >> sh, INT8_MIN, INT8_MAX)
67
+#define DO_SQSHRN_S(x, sh) do_sat_bhs(x >> sh, INT16_MIN, INT16_MAX)
68
+#define DO_SQSHRN_D(x, sh) do_sat_bhs(x >> sh, INT32_MIN, INT32_MAX)
69
+
70
+DO_SHRNB(sve2_sqshrnb_h, int16_t, uint8_t, DO_SQSHRN_H)
71
+DO_SHRNB(sve2_sqshrnb_s, int32_t, uint16_t, DO_SQSHRN_S)
72
+DO_SHRNB(sve2_sqshrnb_d, int64_t, uint32_t, DO_SQSHRN_D)
73
+
74
+DO_SHRNT(sve2_sqshrnt_h, int16_t, uint8_t, H1_2, H1, DO_SQSHRN_H)
75
+DO_SHRNT(sve2_sqshrnt_s, int32_t, uint16_t, H1_4, H1_2, DO_SQSHRN_S)
76
+DO_SHRNT(sve2_sqshrnt_d, int64_t, uint32_t, , H1_4, DO_SQSHRN_D)
77
+
78
+#define DO_SQRSHRN_H(x, sh) do_sat_bhs(do_srshr(x, sh), INT8_MIN, INT8_MAX)
79
+#define DO_SQRSHRN_S(x, sh) do_sat_bhs(do_srshr(x, sh), INT16_MIN, INT16_MAX)
80
+#define DO_SQRSHRN_D(x, sh) do_sat_bhs(do_srshr(x, sh), INT32_MIN, INT32_MAX)
81
+
82
+DO_SHRNB(sve2_sqrshrnb_h, int16_t, uint8_t, DO_SQRSHRN_H)
83
+DO_SHRNB(sve2_sqrshrnb_s, int32_t, uint16_t, DO_SQRSHRN_S)
84
+DO_SHRNB(sve2_sqrshrnb_d, int64_t, uint32_t, DO_SQRSHRN_D)
85
+
86
+DO_SHRNT(sve2_sqrshrnt_h, int16_t, uint8_t, H1_2, H1, DO_SQRSHRN_H)
87
+DO_SHRNT(sve2_sqrshrnt_s, int32_t, uint16_t, H1_4, H1_2, DO_SQRSHRN_S)
88
+DO_SHRNT(sve2_sqrshrnt_d, int64_t, uint32_t, , H1_4, DO_SQRSHRN_D)
89
+
90
#define DO_UQSHRN_H(x, sh) MIN(x >> sh, UINT8_MAX)
91
#define DO_UQSHRN_S(x, sh) MIN(x >> sh, UINT16_MAX)
92
#define DO_UQSHRN_D(x, sh) MIN(x >> sh, UINT32_MAX)
93
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/target/arm/translate-sve.c
96
+++ b/target/arm/translate-sve.c
97
@@ -XXX,XX +XXX,XX @@ static bool trans_SQRSHRUNT(DisasContext *s, arg_rri_esz *a)
98
return do_sve2_shr_narrow(s, a, ops);
99
}
100
101
+static void gen_sqshrnb_vec(unsigned vece, TCGv_vec d,
102
+ TCGv_vec n, int64_t shr)
103
+{
104
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
105
+ int halfbits = 4 << vece;
106
+ int64_t max = MAKE_64BIT_MASK(0, halfbits - 1);
107
+ int64_t min = -max - 1;
108
+
109
+ tcg_gen_sari_vec(vece, n, n, shr);
110
+ tcg_gen_dupi_vec(vece, t, min);
111
+ tcg_gen_smax_vec(vece, n, n, t);
112
+ tcg_gen_dupi_vec(vece, t, max);
113
+ tcg_gen_smin_vec(vece, n, n, t);
114
+ tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(0, halfbits));
115
+ tcg_gen_and_vec(vece, d, n, t);
116
+ tcg_temp_free_vec(t);
117
+}
118
+
119
+static bool trans_SQSHRNB(DisasContext *s, arg_rri_esz *a)
120
+{
121
+ static const TCGOpcode vec_list[] = {
122
+ INDEX_op_sari_vec, INDEX_op_smax_vec, INDEX_op_smin_vec, 0
123
+ };
124
+ static const GVecGen2i ops[3] = {
125
+ { .fniv = gen_sqshrnb_vec,
126
+ .opt_opc = vec_list,
127
+ .fno = gen_helper_sve2_sqshrnb_h,
128
+ .vece = MO_16 },
129
+ { .fniv = gen_sqshrnb_vec,
130
+ .opt_opc = vec_list,
131
+ .fno = gen_helper_sve2_sqshrnb_s,
132
+ .vece = MO_32 },
133
+ { .fniv = gen_sqshrnb_vec,
134
+ .opt_opc = vec_list,
135
+ .fno = gen_helper_sve2_sqshrnb_d,
136
+ .vece = MO_64 },
137
+ };
138
+ return do_sve2_shr_narrow(s, a, ops);
139
+}
140
+
141
+static void gen_sqshrnt_vec(unsigned vece, TCGv_vec d,
142
+ TCGv_vec n, int64_t shr)
143
+{
144
+ TCGv_vec t = tcg_temp_new_vec_matching(d);
145
+ int halfbits = 4 << vece;
146
+ int64_t max = MAKE_64BIT_MASK(0, halfbits - 1);
147
+ int64_t min = -max - 1;
148
+
149
+ tcg_gen_sari_vec(vece, n, n, shr);
150
+ tcg_gen_dupi_vec(vece, t, min);
151
+ tcg_gen_smax_vec(vece, n, n, t);
152
+ tcg_gen_dupi_vec(vece, t, max);
153
+ tcg_gen_smin_vec(vece, n, n, t);
154
+ tcg_gen_shli_vec(vece, n, n, halfbits);
155
+ tcg_gen_dupi_vec(vece, t, MAKE_64BIT_MASK(0, halfbits));
156
+ tcg_gen_bitsel_vec(vece, d, t, d, n);
157
+ tcg_temp_free_vec(t);
158
+}
159
+
160
+static bool trans_SQSHRNT(DisasContext *s, arg_rri_esz *a)
161
+{
162
+ static const TCGOpcode vec_list[] = {
163
+ INDEX_op_shli_vec, INDEX_op_sari_vec,
164
+ INDEX_op_smax_vec, INDEX_op_smin_vec, 0
165
+ };
166
+ static const GVecGen2i ops[3] = {
167
+ { .fniv = gen_sqshrnt_vec,
168
+ .opt_opc = vec_list,
169
+ .load_dest = true,
170
+ .fno = gen_helper_sve2_sqshrnt_h,
171
+ .vece = MO_16 },
172
+ { .fniv = gen_sqshrnt_vec,
173
+ .opt_opc = vec_list,
174
+ .load_dest = true,
175
+ .fno = gen_helper_sve2_sqshrnt_s,
176
+ .vece = MO_32 },
177
+ { .fniv = gen_sqshrnt_vec,
178
+ .opt_opc = vec_list,
179
+ .load_dest = true,
180
+ .fno = gen_helper_sve2_sqshrnt_d,
181
+ .vece = MO_64 },
182
+ };
183
+ return do_sve2_shr_narrow(s, a, ops);
184
+}
185
+
186
+static bool trans_SQRSHRNB(DisasContext *s, arg_rri_esz *a)
187
+{
188
+ static const GVecGen2i ops[3] = {
189
+ { .fno = gen_helper_sve2_sqrshrnb_h },
190
+ { .fno = gen_helper_sve2_sqrshrnb_s },
191
+ { .fno = gen_helper_sve2_sqrshrnb_d },
192
+ };
193
+ return do_sve2_shr_narrow(s, a, ops);
194
+}
195
+
196
+static bool trans_SQRSHRNT(DisasContext *s, arg_rri_esz *a)
197
+{
198
+ static const GVecGen2i ops[3] = {
199
+ { .fno = gen_helper_sve2_sqrshrnt_h },
200
+ { .fno = gen_helper_sve2_sqrshrnt_s },
201
+ { .fno = gen_helper_sve2_sqrshrnt_d },
202
+ };
203
+ return do_sve2_shr_narrow(s, a, ops);
204
+}
205
+
206
static void gen_uqshrnb_vec(unsigned vece, TCGv_vec d,
207
TCGv_vec n, int64_t shr)
208
{
209
--
210
2.20.1
211
212
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-32-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/sve.decode | 3 ++
9
target/arm/translate-sve.c | 67 ++++++++++++++++++++++++++++++++++++++
10
2 files changed, 70 insertions(+)
11
12
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/sve.decode
15
+++ b/target/arm/sve.decode
16
@@ -XXX,XX +XXX,XX @@ CTERM 00100101 1 sf:1 1 rm:5 001000 rn:5 ne:1 0000
17
# SVE integer compare scalar count and limit
18
WHILE 00100101 esz:2 1 rm:5 000 sf:1 u:1 lt:1 rn:5 eq:1 rd:4
19
20
+# SVE2 pointer conflict compare
21
+WHILE_ptr 00100101 esz:2 1 rm:5 001 100 rn:5 rw:1 rd:4
22
+
23
### SVE Integer Wide Immediate - Unpredicated Group
24
25
# SVE broadcast floating-point immediate (unpredicated)
26
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/translate-sve.c
29
+++ b/target/arm/translate-sve.c
30
@@ -XXX,XX +XXX,XX @@ static bool trans_WHILE(DisasContext *s, arg_WHILE *a)
31
return true;
32
}
33
34
+static bool trans_WHILE_ptr(DisasContext *s, arg_WHILE_ptr *a)
35
+{
36
+ TCGv_i64 op0, op1, diff, t1, tmax;
37
+ TCGv_i32 t2, t3;
38
+ TCGv_ptr ptr;
39
+ unsigned vsz = vec_full_reg_size(s);
40
+ unsigned desc = 0;
41
+
42
+ if (!dc_isar_feature(aa64_sve2, s)) {
43
+ return false;
44
+ }
45
+ if (!sve_access_check(s)) {
46
+ return true;
47
+ }
48
+
49
+ op0 = read_cpu_reg(s, a->rn, 1);
50
+ op1 = read_cpu_reg(s, a->rm, 1);
51
+
52
+ tmax = tcg_const_i64(vsz);
53
+ diff = tcg_temp_new_i64();
54
+
55
+ if (a->rw) {
56
+ /* WHILERW */
57
+ /* diff = abs(op1 - op0), noting that op0/1 are unsigned. */
58
+ t1 = tcg_temp_new_i64();
59
+ tcg_gen_sub_i64(diff, op0, op1);
60
+ tcg_gen_sub_i64(t1, op1, op0);
61
+ tcg_gen_movcond_i64(TCG_COND_GEU, diff, op0, op1, diff, t1);
62
+ tcg_temp_free_i64(t1);
63
+ /* Round down to a multiple of ESIZE. */
64
+ tcg_gen_andi_i64(diff, diff, -1 << a->esz);
65
+ /* If op1 == op0, diff == 0, and the condition is always true. */
66
+ tcg_gen_movcond_i64(TCG_COND_EQ, diff, op0, op1, tmax, diff);
67
+ } else {
68
+ /* WHILEWR */
69
+ tcg_gen_sub_i64(diff, op1, op0);
70
+ /* Round down to a multiple of ESIZE. */
71
+ tcg_gen_andi_i64(diff, diff, -1 << a->esz);
72
+ /* If op0 >= op1, diff <= 0, the condition is always true. */
73
+ tcg_gen_movcond_i64(TCG_COND_GEU, diff, op0, op1, tmax, diff);
74
+ }
75
+
76
+ /* Bound to the maximum. */
77
+ tcg_gen_umin_i64(diff, diff, tmax);
78
+ tcg_temp_free_i64(tmax);
79
+
80
+ /* Since we're bounded, pass as a 32-bit type. */
81
+ t2 = tcg_temp_new_i32();
82
+ tcg_gen_extrl_i64_i32(t2, diff);
83
+ tcg_temp_free_i64(diff);
84
+
85
+ desc = FIELD_DP32(desc, PREDDESC, OPRSZ, vsz / 8);
86
+ desc = FIELD_DP32(desc, PREDDESC, ESZ, a->esz);
87
+ t3 = tcg_const_i32(desc);
88
+
89
+ ptr = tcg_temp_new_ptr();
90
+ tcg_gen_addi_ptr(ptr, cpu_env, pred_full_reg_offset(s, a->rd));
91
+
92
+ gen_helper_sve_whilel(t2, ptr, t2, t3);
93
+ do_pred_flags(t2);
94
+
95
+ tcg_temp_free_ptr(ptr);
96
+ tcg_temp_free_i32(t2);
97
+ tcg_temp_free_i32(t3);
98
+ return true;
99
+}
100
+
101
/*
102
*** SVE Integer Wide Immediate - Unpredicated Group
103
*/
104
--
105
2.20.1
106
107
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-33-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 6 ++
9
target/arm/sve.decode | 12 +++
10
target/arm/sve_helper.c | 50 +++++++++
11
target/arm/translate-sve.c | 213 +++++++++++++++++++++++++++++++++++++
12
4 files changed, 281 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve2_fminp_zpzz_s, TCG_CALL_NO_RWG,
19
void, ptr, ptr, ptr, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_6(sve2_fminp_zpzz_d, TCG_CALL_NO_RWG,
21
void, ptr, ptr, ptr, ptr, ptr, i32)
22
+
23
+DEF_HELPER_FLAGS_5(sve2_eor3, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_5(sve2_bcax, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_5(sve2_bsl1n, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_5(sve2_bsl2n, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_5(sve2_nbsl, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
28
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/sve.decode
31
+++ b/target/arm/sve.decode
32
@@ -XXX,XX +XXX,XX @@
33
@rda_rn_rm ........ esz:2 . rm:5 ... ... rn:5 rd:5 \
34
&rrrr_esz ra=%reg_movprfx
35
36
+# Four operand with unused vector element size
37
+@rdn_ra_rm_e0 ........ ... rm:5 ... ... ra:5 rd:5 \
38
+ &rrrr_esz esz=0 rn=%reg_movprfx
39
+
40
# Three operand with "memory" size, aka immediate left shift
41
@rd_rn_msz_rm ........ ... rm:5 .... imm:2 rn:5 rd:5 &rrri
42
43
@@ -XXX,XX +XXX,XX @@ ORR_zzz 00000100 01 1 ..... 001 100 ..... ..... @rd_rn_rm_e0
44
EOR_zzz 00000100 10 1 ..... 001 100 ..... ..... @rd_rn_rm_e0
45
BIC_zzz 00000100 11 1 ..... 001 100 ..... ..... @rd_rn_rm_e0
46
47
+# SVE2 bitwise ternary operations
48
+EOR3 00000100 00 1 ..... 001 110 ..... ..... @rdn_ra_rm_e0
49
+BSL 00000100 00 1 ..... 001 111 ..... ..... @rdn_ra_rm_e0
50
+BCAX 00000100 01 1 ..... 001 110 ..... ..... @rdn_ra_rm_e0
51
+BSL1N 00000100 01 1 ..... 001 111 ..... ..... @rdn_ra_rm_e0
52
+BSL2N 00000100 10 1 ..... 001 111 ..... ..... @rdn_ra_rm_e0
53
+NBSL 00000100 11 1 ..... 001 111 ..... ..... @rdn_ra_rm_e0
54
+
55
### SVE Index Generation Group
56
57
# SVE index generation (immediate start, immediate increment)
58
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/sve_helper.c
61
+++ b/target/arm/sve_helper.c
62
@@ -XXX,XX +XXX,XX @@ DO_ST1_ZPZ_D(dd_be, zd, MO_64)
63
64
#undef DO_ST1_ZPZ_S
65
#undef DO_ST1_ZPZ_D
66
+
67
+void HELPER(sve2_eor3)(void *vd, void *vn, void *vm, void *vk, uint32_t desc)
68
+{
69
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
70
+ uint64_t *d = vd, *n = vn, *m = vm, *k = vk;
71
+
72
+ for (i = 0; i < opr_sz; ++i) {
73
+ d[i] = n[i] ^ m[i] ^ k[i];
74
+ }
75
+}
76
+
77
+void HELPER(sve2_bcax)(void *vd, void *vn, void *vm, void *vk, uint32_t desc)
78
+{
79
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
80
+ uint64_t *d = vd, *n = vn, *m = vm, *k = vk;
81
+
82
+ for (i = 0; i < opr_sz; ++i) {
83
+ d[i] = n[i] ^ (m[i] & ~k[i]);
84
+ }
85
+}
86
+
87
+void HELPER(sve2_bsl1n)(void *vd, void *vn, void *vm, void *vk, uint32_t desc)
88
+{
89
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
90
+ uint64_t *d = vd, *n = vn, *m = vm, *k = vk;
91
+
92
+ for (i = 0; i < opr_sz; ++i) {
93
+ d[i] = (~n[i] & k[i]) | (m[i] & ~k[i]);
94
+ }
95
+}
96
+
97
+void HELPER(sve2_bsl2n)(void *vd, void *vn, void *vm, void *vk, uint32_t desc)
98
+{
99
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
100
+ uint64_t *d = vd, *n = vn, *m = vm, *k = vk;
101
+
102
+ for (i = 0; i < opr_sz; ++i) {
103
+ d[i] = (n[i] & k[i]) | (~m[i] & ~k[i]);
104
+ }
105
+}
106
+
107
+void HELPER(sve2_nbsl)(void *vd, void *vn, void *vm, void *vk, uint32_t desc)
108
+{
109
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
110
+ uint64_t *d = vd, *n = vn, *m = vm, *k = vk;
111
+
112
+ for (i = 0; i < opr_sz; ++i) {
113
+ d[i] = ~((n[i] & k[i]) | (m[i] & ~k[i]));
114
+ }
115
+}
116
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/arm/translate-sve.c
119
+++ b/target/arm/translate-sve.c
120
@@ -XXX,XX +XXX,XX @@ static void gen_gvec_fn_zzz(DisasContext *s, GVecGen3Fn *gvec_fn,
121
vec_full_reg_offset(s, rm), vsz, vsz);
122
}
123
124
+/* Invoke a vector expander on four Zregs. */
125
+static void gen_gvec_fn_zzzz(DisasContext *s, GVecGen4Fn *gvec_fn,
126
+ int esz, int rd, int rn, int rm, int ra)
127
+{
128
+ unsigned vsz = vec_full_reg_size(s);
129
+ gvec_fn(esz, vec_full_reg_offset(s, rd),
130
+ vec_full_reg_offset(s, rn),
131
+ vec_full_reg_offset(s, rm),
132
+ vec_full_reg_offset(s, ra), vsz, vsz);
133
+}
134
+
135
/* Invoke a vector move on two Zregs. */
136
static bool do_mov_z(DisasContext *s, int rd, int rn)
137
{
138
@@ -XXX,XX +XXX,XX @@ static bool trans_BIC_zzz(DisasContext *s, arg_rrr_esz *a)
139
return do_zzz_fn(s, a, tcg_gen_gvec_andc);
140
}
141
142
+static bool do_sve2_zzzz_fn(DisasContext *s, arg_rrrr_esz *a, GVecGen4Fn *fn)
143
+{
144
+ if (!dc_isar_feature(aa64_sve2, s)) {
145
+ return false;
146
+ }
147
+ if (sve_access_check(s)) {
148
+ gen_gvec_fn_zzzz(s, fn, a->esz, a->rd, a->rn, a->rm, a->ra);
149
+ }
150
+ return true;
151
+}
152
+
153
+static void gen_eor3_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
154
+{
155
+ tcg_gen_xor_i64(d, n, m);
156
+ tcg_gen_xor_i64(d, d, k);
157
+}
158
+
159
+static void gen_eor3_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
160
+ TCGv_vec m, TCGv_vec k)
161
+{
162
+ tcg_gen_xor_vec(vece, d, n, m);
163
+ tcg_gen_xor_vec(vece, d, d, k);
164
+}
165
+
166
+static void gen_eor3(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
167
+ uint32_t a, uint32_t oprsz, uint32_t maxsz)
168
+{
169
+ static const GVecGen4 op = {
170
+ .fni8 = gen_eor3_i64,
171
+ .fniv = gen_eor3_vec,
172
+ .fno = gen_helper_sve2_eor3,
173
+ .vece = MO_64,
174
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
175
+ };
176
+ tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &op);
177
+}
178
+
179
+static bool trans_EOR3(DisasContext *s, arg_rrrr_esz *a)
180
+{
181
+ return do_sve2_zzzz_fn(s, a, gen_eor3);
182
+}
183
+
184
+static void gen_bcax_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
185
+{
186
+ tcg_gen_andc_i64(d, m, k);
187
+ tcg_gen_xor_i64(d, d, n);
188
+}
189
+
190
+static void gen_bcax_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
191
+ TCGv_vec m, TCGv_vec k)
192
+{
193
+ tcg_gen_andc_vec(vece, d, m, k);
194
+ tcg_gen_xor_vec(vece, d, d, n);
195
+}
196
+
197
+static void gen_bcax(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
198
+ uint32_t a, uint32_t oprsz, uint32_t maxsz)
199
+{
200
+ static const GVecGen4 op = {
201
+ .fni8 = gen_bcax_i64,
202
+ .fniv = gen_bcax_vec,
203
+ .fno = gen_helper_sve2_bcax,
204
+ .vece = MO_64,
205
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
206
+ };
207
+ tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &op);
208
+}
209
+
210
+static bool trans_BCAX(DisasContext *s, arg_rrrr_esz *a)
211
+{
212
+ return do_sve2_zzzz_fn(s, a, gen_bcax);
213
+}
214
+
215
+static void gen_bsl(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
216
+ uint32_t a, uint32_t oprsz, uint32_t maxsz)
217
+{
218
+ /* BSL differs from the generic bitsel in argument ordering. */
219
+ tcg_gen_gvec_bitsel(vece, d, a, n, m, oprsz, maxsz);
220
+}
221
+
222
+static bool trans_BSL(DisasContext *s, arg_rrrr_esz *a)
223
+{
224
+ return do_sve2_zzzz_fn(s, a, gen_bsl);
225
+}
226
+
227
+static void gen_bsl1n_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
228
+{
229
+ tcg_gen_andc_i64(n, k, n);
230
+ tcg_gen_andc_i64(m, m, k);
231
+ tcg_gen_or_i64(d, n, m);
232
+}
233
+
234
+static void gen_bsl1n_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
235
+ TCGv_vec m, TCGv_vec k)
236
+{
237
+ if (TCG_TARGET_HAS_bitsel_vec) {
238
+ tcg_gen_not_vec(vece, n, n);
239
+ tcg_gen_bitsel_vec(vece, d, k, n, m);
240
+ } else {
241
+ tcg_gen_andc_vec(vece, n, k, n);
242
+ tcg_gen_andc_vec(vece, m, m, k);
243
+ tcg_gen_or_vec(vece, d, n, m);
244
+ }
245
+}
246
+
247
+static void gen_bsl1n(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
248
+ uint32_t a, uint32_t oprsz, uint32_t maxsz)
249
+{
250
+ static const GVecGen4 op = {
251
+ .fni8 = gen_bsl1n_i64,
252
+ .fniv = gen_bsl1n_vec,
253
+ .fno = gen_helper_sve2_bsl1n,
254
+ .vece = MO_64,
255
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
256
+ };
257
+ tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &op);
258
+}
259
+
260
+static bool trans_BSL1N(DisasContext *s, arg_rrrr_esz *a)
261
+{
262
+ return do_sve2_zzzz_fn(s, a, gen_bsl1n);
263
+}
264
+
265
+static void gen_bsl2n_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
266
+{
267
+ /*
268
+ * Z[dn] = (n & k) | (~m & ~k)
269
+ * = | ~(m | k)
270
+ */
271
+ tcg_gen_and_i64(n, n, k);
272
+ if (TCG_TARGET_HAS_orc_i64) {
273
+ tcg_gen_or_i64(m, m, k);
274
+ tcg_gen_orc_i64(d, n, m);
275
+ } else {
276
+ tcg_gen_nor_i64(m, m, k);
277
+ tcg_gen_or_i64(d, n, m);
278
+ }
279
+}
280
+
281
+static void gen_bsl2n_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
282
+ TCGv_vec m, TCGv_vec k)
283
+{
284
+ if (TCG_TARGET_HAS_bitsel_vec) {
285
+ tcg_gen_not_vec(vece, m, m);
286
+ tcg_gen_bitsel_vec(vece, d, k, n, m);
287
+ } else {
288
+ tcg_gen_and_vec(vece, n, n, k);
289
+ tcg_gen_or_vec(vece, m, m, k);
290
+ tcg_gen_orc_vec(vece, d, n, m);
291
+ }
292
+}
293
+
294
+static void gen_bsl2n(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
295
+ uint32_t a, uint32_t oprsz, uint32_t maxsz)
296
+{
297
+ static const GVecGen4 op = {
298
+ .fni8 = gen_bsl2n_i64,
299
+ .fniv = gen_bsl2n_vec,
300
+ .fno = gen_helper_sve2_bsl2n,
301
+ .vece = MO_64,
302
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
303
+ };
304
+ tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &op);
305
+}
306
+
307
+static bool trans_BSL2N(DisasContext *s, arg_rrrr_esz *a)
308
+{
309
+ return do_sve2_zzzz_fn(s, a, gen_bsl2n);
310
+}
311
+
312
+static void gen_nbsl_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
313
+{
314
+ tcg_gen_and_i64(n, n, k);
315
+ tcg_gen_andc_i64(m, m, k);
316
+ tcg_gen_nor_i64(d, n, m);
317
+}
318
+
319
+static void gen_nbsl_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
320
+ TCGv_vec m, TCGv_vec k)
321
+{
322
+ tcg_gen_bitsel_vec(vece, d, k, n, m);
323
+ tcg_gen_not_vec(vece, d, d);
324
+}
325
+
326
+static void gen_nbsl(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
327
+ uint32_t a, uint32_t oprsz, uint32_t maxsz)
328
+{
329
+ static const GVecGen4 op = {
330
+ .fni8 = gen_nbsl_i64,
331
+ .fniv = gen_nbsl_vec,
332
+ .fno = gen_helper_sve2_nbsl,
333
+ .vece = MO_64,
334
+ .prefer_i64 = TCG_TARGET_REG_BITS == 64,
335
+ };
336
+ tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, &op);
337
+}
338
+
339
+static bool trans_NBSL(DisasContext *s, arg_rrrr_esz *a)
340
+{
341
+ return do_sve2_zzzz_fn(s, a, gen_nbsl);
342
+}
343
+
344
/*
345
*** SVE Integer Arithmetic - Unpredicated Group
346
*/
347
--
348
2.20.1
349
350
diff view generated by jsdifflib
Deleted patch
1
From: Stephen Long <steplong@quicinc.com>
2
1
3
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Signed-off-by: Stephen Long <steplong@quicinc.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210525010358.152808-34-richard.henderson@linaro.org
7
Message-Id: <20200415145915.2859-1-steplong@quicinc.com>
8
[rth: Expanded comment for do_match2]
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/helper-sve.h | 10 ++++++
13
target/arm/sve.decode | 5 +++
14
target/arm/sve_helper.c | 64 ++++++++++++++++++++++++++++++++++++++
15
target/arm/translate-sve.c | 22 +++++++++++++
16
4 files changed, 101 insertions(+)
17
18
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper-sve.h
21
+++ b/target/arm/helper-sve.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve2_uqrshrnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
23
DEF_HELPER_FLAGS_3(sve2_uqrshrnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
24
DEF_HELPER_FLAGS_3(sve2_uqrshrnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
25
26
+DEF_HELPER_FLAGS_5(sve2_match_ppzz_b, TCG_CALL_NO_RWG,
27
+ i32, ptr, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_5(sve2_match_ppzz_h, TCG_CALL_NO_RWG,
29
+ i32, ptr, ptr, ptr, ptr, i32)
30
+
31
+DEF_HELPER_FLAGS_5(sve2_nmatch_ppzz_b, TCG_CALL_NO_RWG,
32
+ i32, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_5(sve2_nmatch_ppzz_h, TCG_CALL_NO_RWG,
34
+ i32, ptr, ptr, ptr, ptr, i32)
35
+
36
DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_h, TCG_CALL_NO_RWG,
37
void, ptr, ptr, ptr, ptr, ptr, i32)
38
DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_s, TCG_CALL_NO_RWG,
39
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/sve.decode
42
+++ b/target/arm/sve.decode
43
@@ -XXX,XX +XXX,XX @@ UQSHRNT 01000101 .. 1 ..... 00 1101 ..... ..... @rd_rn_tszimm_shr
44
UQRSHRNB 01000101 .. 1 ..... 00 1110 ..... ..... @rd_rn_tszimm_shr
45
UQRSHRNT 01000101 .. 1 ..... 00 1111 ..... ..... @rd_rn_tszimm_shr
46
47
+### SVE2 Character Match
48
+
49
+MATCH 01000101 .. 1 ..... 100 ... ..... 0 .... @pd_pg_rn_rm
50
+NMATCH 01000101 .. 1 ..... 100 ... ..... 1 .... @pd_pg_rn_rm
51
+
52
## SVE2 floating-point pairwise operations
53
54
FADDP 01100100 .. 010 00 0 100 ... ..... ..... @rdn_pg_rm
55
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/sve_helper.c
58
+++ b/target/arm/sve_helper.c
59
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_nbsl)(void *vd, void *vn, void *vm, void *vk, uint32_t desc)
60
d[i] = ~((n[i] & k[i]) | (m[i] & ~k[i]));
61
}
62
}
63
+
64
+/*
65
+ * Returns true if m0 or m1 contains the low uint8_t/uint16_t in n.
66
+ * See hasless(v,1) from
67
+ * https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
68
+ */
69
+static inline bool do_match2(uint64_t n, uint64_t m0, uint64_t m1, int esz)
70
+{
71
+ int bits = 8 << esz;
72
+ uint64_t ones = dup_const(esz, 1);
73
+ uint64_t signs = ones << (bits - 1);
74
+ uint64_t cmp0, cmp1;
75
+
76
+ cmp1 = dup_const(esz, n);
77
+ cmp0 = cmp1 ^ m0;
78
+ cmp1 = cmp1 ^ m1;
79
+ cmp0 = (cmp0 - ones) & ~cmp0;
80
+ cmp1 = (cmp1 - ones) & ~cmp1;
81
+ return (cmp0 | cmp1) & signs;
82
+}
83
+
84
+static inline uint32_t do_match(void *vd, void *vn, void *vm, void *vg,
85
+ uint32_t desc, int esz, bool nmatch)
86
+{
87
+ uint16_t esz_mask = pred_esz_masks[esz];
88
+ intptr_t opr_sz = simd_oprsz(desc);
89
+ uint32_t flags = PREDTEST_INIT;
90
+ intptr_t i, j, k;
91
+
92
+ for (i = 0; i < opr_sz; i += 16) {
93
+ uint64_t m0 = *(uint64_t *)(vm + i);
94
+ uint64_t m1 = *(uint64_t *)(vm + i + 8);
95
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)) & esz_mask;
96
+ uint16_t out = 0;
97
+
98
+ for (j = 0; j < 16; j += 8) {
99
+ uint64_t n = *(uint64_t *)(vn + i + j);
100
+
101
+ for (k = 0; k < 8; k += 1 << esz) {
102
+ if (pg & (1 << (j + k))) {
103
+ bool o = do_match2(n >> (k * 8), m0, m1, esz);
104
+ out |= (o ^ nmatch) << (j + k);
105
+ }
106
+ }
107
+ }
108
+ *(uint16_t *)(vd + H1_2(i >> 3)) = out;
109
+ flags = iter_predtest_fwd(out, pg, flags);
110
+ }
111
+ return flags;
112
+}
113
+
114
+#define DO_PPZZ_MATCH(NAME, ESZ, INV) \
115
+uint32_t HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, uint32_t desc) \
116
+{ \
117
+ return do_match(vd, vn, vm, vg, desc, ESZ, INV); \
118
+}
119
+
120
+DO_PPZZ_MATCH(sve2_match_ppzz_b, MO_8, false)
121
+DO_PPZZ_MATCH(sve2_match_ppzz_h, MO_16, false)
122
+
123
+DO_PPZZ_MATCH(sve2_nmatch_ppzz_b, MO_8, true)
124
+DO_PPZZ_MATCH(sve2_nmatch_ppzz_h, MO_16, true)
125
+
126
+#undef DO_PPZZ_MATCH
127
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
128
index XXXXXXX..XXXXXXX 100644
129
--- a/target/arm/translate-sve.c
130
+++ b/target/arm/translate-sve.c
131
@@ -XXX,XX +XXX,XX @@ static bool trans_UQRSHRNT(DisasContext *s, arg_rri_esz *a)
132
return do_sve2_shr_narrow(s, a, ops);
133
}
134
135
+static bool do_sve2_ppzz_flags(DisasContext *s, arg_rprr_esz *a,
136
+ gen_helper_gvec_flags_4 *fn)
137
+{
138
+ if (!dc_isar_feature(aa64_sve2, s)) {
139
+ return false;
140
+ }
141
+ return do_ppzz_flags(s, a, fn);
142
+}
143
+
144
+#define DO_SVE2_PPZZ_MATCH(NAME, name) \
145
+static bool trans_##NAME(DisasContext *s, arg_rprr_esz *a) \
146
+{ \
147
+ static gen_helper_gvec_flags_4 * const fns[4] = { \
148
+ gen_helper_sve2_##name##_ppzz_b, gen_helper_sve2_##name##_ppzz_h, \
149
+ NULL, NULL \
150
+ }; \
151
+ return do_sve2_ppzz_flags(s, a, fns[a->esz]); \
152
+}
153
+
154
+DO_SVE2_PPZZ_MATCH(MATCH, match)
155
+DO_SVE2_PPZZ_MATCH(NMATCH, nmatch)
156
+
157
static bool do_sve2_zpzz_fp(DisasContext *s, arg_rprr_esz *a,
158
gen_helper_gvec_4_ptr *fn)
159
{
160
--
161
2.20.1
162
163
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-35-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 14 ++++++++++
9
target/arm/sve.decode | 14 ++++++++++
10
target/arm/sve_helper.c | 30 +++++++++++++++++++++
11
target/arm/translate-sve.c | 54 ++++++++++++++++++++++++++++++++++++++
12
4 files changed, 112 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_bcax, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
19
DEF_HELPER_FLAGS_5(sve2_bsl1n, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_5(sve2_bsl2n, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_5(sve2_nbsl, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
22
+
23
+DEF_HELPER_FLAGS_5(sve2_sqdmlal_zzzw_h, TCG_CALL_NO_RWG,
24
+ void, ptr, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_5(sve2_sqdmlal_zzzw_s, TCG_CALL_NO_RWG,
26
+ void, ptr, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_5(sve2_sqdmlal_zzzw_d, TCG_CALL_NO_RWG,
28
+ void, ptr, ptr, ptr, ptr, i32)
29
+
30
+DEF_HELPER_FLAGS_5(sve2_sqdmlsl_zzzw_h, TCG_CALL_NO_RWG,
31
+ void, ptr, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_5(sve2_sqdmlsl_zzzw_s, TCG_CALL_NO_RWG,
33
+ void, ptr, ptr, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_5(sve2_sqdmlsl_zzzw_d, TCG_CALL_NO_RWG,
35
+ void, ptr, ptr, ptr, ptr, i32)
36
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/sve.decode
39
+++ b/target/arm/sve.decode
40
@@ -XXX,XX +XXX,XX @@ FMAXNMP 01100100 .. 010 10 0 100 ... ..... ..... @rdn_pg_rm
41
FMINNMP 01100100 .. 010 10 1 100 ... ..... ..... @rdn_pg_rm
42
FMAXP 01100100 .. 010 11 0 100 ... ..... ..... @rdn_pg_rm
43
FMINP 01100100 .. 010 11 1 100 ... ..... ..... @rdn_pg_rm
44
+
45
+#### SVE Integer Multiply-Add (unpredicated)
46
+
47
+## SVE2 saturating multiply-add long
48
+
49
+SQDMLALB_zzzw 01000100 .. 0 ..... 0110 00 ..... ..... @rda_rn_rm
50
+SQDMLALT_zzzw 01000100 .. 0 ..... 0110 01 ..... ..... @rda_rn_rm
51
+SQDMLSLB_zzzw 01000100 .. 0 ..... 0110 10 ..... ..... @rda_rn_rm
52
+SQDMLSLT_zzzw 01000100 .. 0 ..... 0110 11 ..... ..... @rda_rn_rm
53
+
54
+## SVE2 saturating multiply-add interleaved long
55
+
56
+SQDMLALBT 01000100 .. 0 ..... 00001 0 ..... ..... @rda_rn_rm
57
+SQDMLSLBT 01000100 .. 0 ..... 00001 1 ..... ..... @rda_rn_rm
58
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/sve_helper.c
61
+++ b/target/arm/sve_helper.c
62
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_adcl_d)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
63
}
64
}
65
66
+#define DO_SQDMLAL(NAME, TYPEW, TYPEN, HW, HN, DMUL_OP, SUM_OP) \
67
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, uint32_t desc) \
68
+{ \
69
+ intptr_t i, opr_sz = simd_oprsz(desc); \
70
+ int sel1 = extract32(desc, SIMD_DATA_SHIFT, 1) * sizeof(TYPEN); \
71
+ int sel2 = extract32(desc, SIMD_DATA_SHIFT + 1, 1) * sizeof(TYPEN); \
72
+ for (i = 0; i < opr_sz; i += sizeof(TYPEW)) { \
73
+ TYPEW nn = *(TYPEN *)(vn + HN(i + sel1)); \
74
+ TYPEW mm = *(TYPEN *)(vm + HN(i + sel2)); \
75
+ TYPEW aa = *(TYPEW *)(va + HW(i)); \
76
+ *(TYPEW *)(vd + HW(i)) = SUM_OP(aa, DMUL_OP(nn, mm)); \
77
+ } \
78
+}
79
+
80
+DO_SQDMLAL(sve2_sqdmlal_zzzw_h, int16_t, int8_t, H1_2, H1,
81
+ do_sqdmull_h, DO_SQADD_H)
82
+DO_SQDMLAL(sve2_sqdmlal_zzzw_s, int32_t, int16_t, H1_4, H1_2,
83
+ do_sqdmull_s, DO_SQADD_S)
84
+DO_SQDMLAL(sve2_sqdmlal_zzzw_d, int64_t, int32_t, , H1_4,
85
+ do_sqdmull_d, do_sqadd_d)
86
+
87
+DO_SQDMLAL(sve2_sqdmlsl_zzzw_h, int16_t, int8_t, H1_2, H1,
88
+ do_sqdmull_h, DO_SQSUB_H)
89
+DO_SQDMLAL(sve2_sqdmlsl_zzzw_s, int32_t, int16_t, H1_4, H1_2,
90
+ do_sqdmull_s, DO_SQSUB_S)
91
+DO_SQDMLAL(sve2_sqdmlsl_zzzw_d, int64_t, int32_t, , H1_4,
92
+ do_sqdmull_d, do_sqsub_d)
93
+
94
+#undef DO_SQDMLAL
95
+
96
#define DO_BITPERM(NAME, TYPE, OP) \
97
void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
98
{ \
99
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/target/arm/translate-sve.c
102
+++ b/target/arm/translate-sve.c
103
@@ -XXX,XX +XXX,XX @@ DO_SVE2_ZPZZ_FP(FMAXNMP, fmaxnmp)
104
DO_SVE2_ZPZZ_FP(FMINNMP, fminnmp)
105
DO_SVE2_ZPZZ_FP(FMAXP, fmaxp)
106
DO_SVE2_ZPZZ_FP(FMINP, fminp)
107
+
108
+/*
109
+ * SVE Integer Multiply-Add (unpredicated)
110
+ */
111
+
112
+static bool do_sqdmlal_zzzw(DisasContext *s, arg_rrrr_esz *a,
113
+ bool sel1, bool sel2)
114
+{
115
+ static gen_helper_gvec_4 * const fns[] = {
116
+ NULL, gen_helper_sve2_sqdmlal_zzzw_h,
117
+ gen_helper_sve2_sqdmlal_zzzw_s, gen_helper_sve2_sqdmlal_zzzw_d,
118
+ };
119
+ return do_sve2_zzzz_ool(s, a, fns[a->esz], (sel2 << 1) | sel1);
120
+}
121
+
122
+static bool do_sqdmlsl_zzzw(DisasContext *s, arg_rrrr_esz *a,
123
+ bool sel1, bool sel2)
124
+{
125
+ static gen_helper_gvec_4 * const fns[] = {
126
+ NULL, gen_helper_sve2_sqdmlsl_zzzw_h,
127
+ gen_helper_sve2_sqdmlsl_zzzw_s, gen_helper_sve2_sqdmlsl_zzzw_d,
128
+ };
129
+ return do_sve2_zzzz_ool(s, a, fns[a->esz], (sel2 << 1) | sel1);
130
+}
131
+
132
+static bool trans_SQDMLALB_zzzw(DisasContext *s, arg_rrrr_esz *a)
133
+{
134
+ return do_sqdmlal_zzzw(s, a, false, false);
135
+}
136
+
137
+static bool trans_SQDMLALT_zzzw(DisasContext *s, arg_rrrr_esz *a)
138
+{
139
+ return do_sqdmlal_zzzw(s, a, true, true);
140
+}
141
+
142
+static bool trans_SQDMLALBT(DisasContext *s, arg_rrrr_esz *a)
143
+{
144
+ return do_sqdmlal_zzzw(s, a, false, true);
145
+}
146
+
147
+static bool trans_SQDMLSLB_zzzw(DisasContext *s, arg_rrrr_esz *a)
148
+{
149
+ return do_sqdmlsl_zzzw(s, a, false, false);
150
+}
151
+
152
+static bool trans_SQDMLSLT_zzzw(DisasContext *s, arg_rrrr_esz *a)
153
+{
154
+ return do_sqdmlsl_zzzw(s, a, true, true);
155
+}
156
+
157
+static bool trans_SQDMLSLBT(DisasContext *s, arg_rrrr_esz *a)
158
+{
159
+ return do_sqdmlsl_zzzw(s, a, false, true);
160
+}
161
--
162
2.20.1
163
164
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
SVE2 has two additional sizes of the operation and unlike NEON,
4
there is no saturation flag. Create new entry points for SVE2
5
that do not set QC.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210525010358.152808-36-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/helper.h | 17 ++++
13
target/arm/sve.decode | 5 ++
14
target/arm/translate-sve.c | 18 +++++
15
target/arm/vec_helper.c | 161 +++++++++++++++++++++++++++++++++++--
16
4 files changed, 195 insertions(+), 6 deletions(-)
17
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.h
21
+++ b/target/arm/helper.h
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_qrdmlah_s32, TCG_CALL_NO_RWG,
23
DEF_HELPER_FLAGS_5(gvec_qrdmlsh_s32, TCG_CALL_NO_RWG,
24
void, ptr, ptr, ptr, ptr, i32)
25
26
+DEF_HELPER_FLAGS_5(sve2_sqrdmlah_b, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_5(sve2_sqrdmlsh_b, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_5(sve2_sqrdmlah_h, TCG_CALL_NO_RWG,
31
+ void, ptr, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_5(sve2_sqrdmlsh_h, TCG_CALL_NO_RWG,
33
+ void, ptr, ptr, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_5(sve2_sqrdmlah_s, TCG_CALL_NO_RWG,
35
+ void, ptr, ptr, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_5(sve2_sqrdmlsh_s, TCG_CALL_NO_RWG,
37
+ void, ptr, ptr, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_5(sve2_sqrdmlah_d, TCG_CALL_NO_RWG,
39
+ void, ptr, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_5(sve2_sqrdmlsh_d, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, ptr, i32)
42
+
43
DEF_HELPER_FLAGS_4(gvec_sdot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
44
DEF_HELPER_FLAGS_4(gvec_udot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
45
DEF_HELPER_FLAGS_4(gvec_sdot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
46
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/sve.decode
49
+++ b/target/arm/sve.decode
50
@@ -XXX,XX +XXX,XX @@ SQDMLSLT_zzzw 01000100 .. 0 ..... 0110 11 ..... ..... @rda_rn_rm
51
52
SQDMLALBT 01000100 .. 0 ..... 00001 0 ..... ..... @rda_rn_rm
53
SQDMLSLBT 01000100 .. 0 ..... 00001 1 ..... ..... @rda_rn_rm
54
+
55
+## SVE2 saturating multiply-add high
56
+
57
+SQRDMLAH_zzzz 01000100 .. 0 ..... 01110 0 ..... ..... @rda_rn_rm
58
+SQRDMLSH_zzzz 01000100 .. 0 ..... 01110 1 ..... ..... @rda_rn_rm
59
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/arm/translate-sve.c
62
+++ b/target/arm/translate-sve.c
63
@@ -XXX,XX +XXX,XX @@ static bool trans_SQDMLSLBT(DisasContext *s, arg_rrrr_esz *a)
64
{
65
return do_sqdmlsl_zzzw(s, a, false, true);
66
}
67
+
68
+static bool trans_SQRDMLAH_zzzz(DisasContext *s, arg_rrrr_esz *a)
69
+{
70
+ static gen_helper_gvec_4 * const fns[] = {
71
+ gen_helper_sve2_sqrdmlah_b, gen_helper_sve2_sqrdmlah_h,
72
+ gen_helper_sve2_sqrdmlah_s, gen_helper_sve2_sqrdmlah_d,
73
+ };
74
+ return do_sve2_zzzz_ool(s, a, fns[a->esz], 0);
75
+}
76
+
77
+static bool trans_SQRDMLSH_zzzz(DisasContext *s, arg_rrrr_esz *a)
78
+{
79
+ static gen_helper_gvec_4 * const fns[] = {
80
+ gen_helper_sve2_sqrdmlsh_b, gen_helper_sve2_sqrdmlsh_h,
81
+ gen_helper_sve2_sqrdmlsh_s, gen_helper_sve2_sqrdmlsh_d,
82
+ };
83
+ return do_sve2_zzzz_ool(s, a, fns[a->esz], 0);
84
+}
85
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/arm/vec_helper.c
88
+++ b/target/arm/vec_helper.c
89
@@ -XXX,XX +XXX,XX @@
90
#include "exec/helper-proto.h"
91
#include "tcg/tcg-gvec-desc.h"
92
#include "fpu/softfloat.h"
93
+#include "qemu/int128.h"
94
#include "vec_internal.h"
95
96
/* Note that vector data is stored in host-endian 64-bit chunks,
97
@@ -XXX,XX +XXX,XX @@
98
#define H4(x) (x)
99
#endif
100
101
+/* Signed saturating rounding doubling multiply-accumulate high half, 8-bit */
102
+static int8_t do_sqrdmlah_b(int8_t src1, int8_t src2, int8_t src3,
103
+ bool neg, bool round)
104
+{
105
+ /*
106
+ * Simplify:
107
+ * = ((a3 << 8) + ((e1 * e2) << 1) + (round << 7)) >> 8
108
+ * = ((a3 << 7) + (e1 * e2) + (round << 6)) >> 7
109
+ */
110
+ int32_t ret = (int32_t)src1 * src2;
111
+ if (neg) {
112
+ ret = -ret;
113
+ }
114
+ ret += ((int32_t)src3 << 7) + (round << 6);
115
+ ret >>= 7;
116
+
117
+ if (ret != (int8_t)ret) {
118
+ ret = (ret < 0 ? INT8_MIN : INT8_MAX);
119
+ }
120
+ return ret;
121
+}
122
+
123
+void HELPER(sve2_sqrdmlah_b)(void *vd, void *vn, void *vm,
124
+ void *va, uint32_t desc)
125
+{
126
+ intptr_t i, opr_sz = simd_oprsz(desc);
127
+ int8_t *d = vd, *n = vn, *m = vm, *a = va;
128
+
129
+ for (i = 0; i < opr_sz; ++i) {
130
+ d[i] = do_sqrdmlah_b(n[i], m[i], a[i], false, true);
131
+ }
132
+}
133
+
134
+void HELPER(sve2_sqrdmlsh_b)(void *vd, void *vn, void *vm,
135
+ void *va, uint32_t desc)
136
+{
137
+ intptr_t i, opr_sz = simd_oprsz(desc);
138
+ int8_t *d = vd, *n = vn, *m = vm, *a = va;
139
+
140
+ for (i = 0; i < opr_sz; ++i) {
141
+ d[i] = do_sqrdmlah_b(n[i], m[i], a[i], true, true);
142
+ }
143
+}
144
+
145
/* Signed saturating rounding doubling multiply-accumulate high half, 16-bit */
146
static int16_t do_sqrdmlah_h(int16_t src1, int16_t src2, int16_t src3,
147
bool neg, bool round, uint32_t *sat)
148
{
149
- /*
150
- * Simplify:
151
- * = ((a3 << 16) + ((e1 * e2) << 1) + (1 << 15)) >> 16
152
- * = ((a3 << 15) + (e1 * e2) + (1 << 14)) >> 15
153
- */
154
+ /* Simplify similarly to do_sqrdmlah_b above. */
155
int32_t ret = (int32_t)src1 * src2;
156
if (neg) {
157
ret = -ret;
158
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_sqrdmulh_h)(void *vd, void *vn, void *vm,
159
clear_tail(d, opr_sz, simd_maxsz(desc));
160
}
161
162
+void HELPER(sve2_sqrdmlah_h)(void *vd, void *vn, void *vm,
163
+ void *va, uint32_t desc)
164
+{
165
+ intptr_t i, opr_sz = simd_oprsz(desc);
166
+ int16_t *d = vd, *n = vn, *m = vm, *a = va;
167
+ uint32_t discard;
168
+
169
+ for (i = 0; i < opr_sz / 2; ++i) {
170
+ d[i] = do_sqrdmlah_h(n[i], m[i], a[i], false, true, &discard);
171
+ }
172
+}
173
+
174
+void HELPER(sve2_sqrdmlsh_h)(void *vd, void *vn, void *vm,
175
+ void *va, uint32_t desc)
176
+{
177
+ intptr_t i, opr_sz = simd_oprsz(desc);
178
+ int16_t *d = vd, *n = vn, *m = vm, *a = va;
179
+ uint32_t discard;
180
+
181
+ for (i = 0; i < opr_sz / 2; ++i) {
182
+ d[i] = do_sqrdmlah_h(n[i], m[i], a[i], true, true, &discard);
183
+ }
184
+}
185
+
186
/* Signed saturating rounding doubling multiply-accumulate high half, 32-bit */
187
static int32_t do_sqrdmlah_s(int32_t src1, int32_t src2, int32_t src3,
188
bool neg, bool round, uint32_t *sat)
189
{
190
- /* Simplify similarly to int_qrdmlah_s16 above. */
191
+ /* Simplify similarly to do_sqrdmlah_b above. */
192
int64_t ret = (int64_t)src1 * src2;
193
if (neg) {
194
ret = -ret;
195
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_sqrdmulh_s)(void *vd, void *vn, void *vm,
196
clear_tail(d, opr_sz, simd_maxsz(desc));
197
}
198
199
+void HELPER(sve2_sqrdmlah_s)(void *vd, void *vn, void *vm,
200
+ void *va, uint32_t desc)
201
+{
202
+ intptr_t i, opr_sz = simd_oprsz(desc);
203
+ int32_t *d = vd, *n = vn, *m = vm, *a = va;
204
+ uint32_t discard;
205
+
206
+ for (i = 0; i < opr_sz / 4; ++i) {
207
+ d[i] = do_sqrdmlah_s(n[i], m[i], a[i], false, true, &discard);
208
+ }
209
+}
210
+
211
+void HELPER(sve2_sqrdmlsh_s)(void *vd, void *vn, void *vm,
212
+ void *va, uint32_t desc)
213
+{
214
+ intptr_t i, opr_sz = simd_oprsz(desc);
215
+ int32_t *d = vd, *n = vn, *m = vm, *a = va;
216
+ uint32_t discard;
217
+
218
+ for (i = 0; i < opr_sz / 4; ++i) {
219
+ d[i] = do_sqrdmlah_s(n[i], m[i], a[i], true, true, &discard);
220
+ }
221
+}
222
+
223
+/* Signed saturating rounding doubling multiply-accumulate high half, 64-bit */
224
+static int64_t do_sat128_d(Int128 r)
225
+{
226
+ int64_t ls = int128_getlo(r);
227
+ int64_t hs = int128_gethi(r);
228
+
229
+ if (unlikely(hs != (ls >> 63))) {
230
+ return hs < 0 ? INT64_MIN : INT64_MAX;
231
+ }
232
+ return ls;
233
+}
234
+
235
+static int64_t do_sqrdmlah_d(int64_t n, int64_t m, int64_t a,
236
+ bool neg, bool round)
237
+{
238
+ uint64_t l, h;
239
+ Int128 r, t;
240
+
241
+ /* As in do_sqrdmlah_b, but with 128-bit arithmetic. */
242
+ muls64(&l, &h, m, n);
243
+ r = int128_make128(l, h);
244
+ if (neg) {
245
+ r = int128_neg(r);
246
+ }
247
+ if (a) {
248
+ t = int128_exts64(a);
249
+ t = int128_lshift(t, 63);
250
+ r = int128_add(r, t);
251
+ }
252
+ if (round) {
253
+ t = int128_exts64(1ll << 62);
254
+ r = int128_add(r, t);
255
+ }
256
+ r = int128_rshift(r, 63);
257
+
258
+ return do_sat128_d(r);
259
+}
260
+
261
+void HELPER(sve2_sqrdmlah_d)(void *vd, void *vn, void *vm,
262
+ void *va, uint32_t desc)
263
+{
264
+ intptr_t i, opr_sz = simd_oprsz(desc);
265
+ int64_t *d = vd, *n = vn, *m = vm, *a = va;
266
+
267
+ for (i = 0; i < opr_sz / 8; ++i) {
268
+ d[i] = do_sqrdmlah_d(n[i], m[i], a[i], false, true);
269
+ }
270
+}
271
+
272
+void HELPER(sve2_sqrdmlsh_d)(void *vd, void *vn, void *vm,
273
+ void *va, uint32_t desc)
274
+{
275
+ intptr_t i, opr_sz = simd_oprsz(desc);
276
+ int64_t *d = vd, *n = vn, *m = vm, *a = va;
277
+
278
+ for (i = 0; i < opr_sz / 8; ++i) {
279
+ d[i] = do_sqrdmlah_d(n[i], m[i], a[i], true, true);
280
+ }
281
+}
282
+
283
/* Integer 8 and 16-bit dot-product.
284
*
285
* Note that for the loops herein, host endianness does not matter
286
--
287
2.20.1
288
289
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-37-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 28 ++++++++++++++
9
target/arm/sve.decode | 11 ++++++
10
target/arm/sve_helper.c | 18 +++++++++
11
target/arm/translate-sve.c | 76 ++++++++++++++++++++++++++++++++++++++
12
4 files changed, 133 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_sqdmlsl_zzzw_s, TCG_CALL_NO_RWG,
19
void, ptr, ptr, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_5(sve2_sqdmlsl_zzzw_d, TCG_CALL_NO_RWG,
21
void, ptr, ptr, ptr, ptr, i32)
22
+
23
+DEF_HELPER_FLAGS_5(sve2_smlal_zzzw_h, TCG_CALL_NO_RWG,
24
+ void, ptr, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_5(sve2_smlal_zzzw_s, TCG_CALL_NO_RWG,
26
+ void, ptr, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_5(sve2_smlal_zzzw_d, TCG_CALL_NO_RWG,
28
+ void, ptr, ptr, ptr, ptr, i32)
29
+
30
+DEF_HELPER_FLAGS_5(sve2_umlal_zzzw_h, TCG_CALL_NO_RWG,
31
+ void, ptr, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_5(sve2_umlal_zzzw_s, TCG_CALL_NO_RWG,
33
+ void, ptr, ptr, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_5(sve2_umlal_zzzw_d, TCG_CALL_NO_RWG,
35
+ void, ptr, ptr, ptr, ptr, i32)
36
+
37
+DEF_HELPER_FLAGS_5(sve2_smlsl_zzzw_h, TCG_CALL_NO_RWG,
38
+ void, ptr, ptr, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_5(sve2_smlsl_zzzw_s, TCG_CALL_NO_RWG,
40
+ void, ptr, ptr, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_5(sve2_smlsl_zzzw_d, TCG_CALL_NO_RWG,
42
+ void, ptr, ptr, ptr, ptr, i32)
43
+
44
+DEF_HELPER_FLAGS_5(sve2_umlsl_zzzw_h, TCG_CALL_NO_RWG,
45
+ void, ptr, ptr, ptr, ptr, i32)
46
+DEF_HELPER_FLAGS_5(sve2_umlsl_zzzw_s, TCG_CALL_NO_RWG,
47
+ void, ptr, ptr, ptr, ptr, i32)
48
+DEF_HELPER_FLAGS_5(sve2_umlsl_zzzw_d, TCG_CALL_NO_RWG,
49
+ void, ptr, ptr, ptr, ptr, i32)
50
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/sve.decode
53
+++ b/target/arm/sve.decode
54
@@ -XXX,XX +XXX,XX @@ SQDMLSLBT 01000100 .. 0 ..... 00001 1 ..... ..... @rda_rn_rm
55
56
SQRDMLAH_zzzz 01000100 .. 0 ..... 01110 0 ..... ..... @rda_rn_rm
57
SQRDMLSH_zzzz 01000100 .. 0 ..... 01110 1 ..... ..... @rda_rn_rm
58
+
59
+## SVE2 integer multiply-add long
60
+
61
+SMLALB_zzzw 01000100 .. 0 ..... 010 000 ..... ..... @rda_rn_rm
62
+SMLALT_zzzw 01000100 .. 0 ..... 010 001 ..... ..... @rda_rn_rm
63
+UMLALB_zzzw 01000100 .. 0 ..... 010 010 ..... ..... @rda_rn_rm
64
+UMLALT_zzzw 01000100 .. 0 ..... 010 011 ..... ..... @rda_rn_rm
65
+SMLSLB_zzzw 01000100 .. 0 ..... 010 100 ..... ..... @rda_rn_rm
66
+SMLSLT_zzzw 01000100 .. 0 ..... 010 101 ..... ..... @rda_rn_rm
67
+UMLSLB_zzzw 01000100 .. 0 ..... 010 110 ..... ..... @rda_rn_rm
68
+UMLSLT_zzzw 01000100 .. 0 ..... 010 111 ..... ..... @rda_rn_rm
69
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/sve_helper.c
72
+++ b/target/arm/sve_helper.c
73
@@ -XXX,XX +XXX,XX @@ DO_ZZZW_ACC(sve2_uabal_h, uint16_t, uint8_t, H1_2, H1, DO_ABD)
74
DO_ZZZW_ACC(sve2_uabal_s, uint32_t, uint16_t, H1_4, H1_2, DO_ABD)
75
DO_ZZZW_ACC(sve2_uabal_d, uint64_t, uint32_t, , H1_4, DO_ABD)
76
77
+DO_ZZZW_ACC(sve2_smlal_zzzw_h, int16_t, int8_t, H1_2, H1, DO_MUL)
78
+DO_ZZZW_ACC(sve2_smlal_zzzw_s, int32_t, int16_t, H1_4, H1_2, DO_MUL)
79
+DO_ZZZW_ACC(sve2_smlal_zzzw_d, int64_t, int32_t, , H1_4, DO_MUL)
80
+
81
+DO_ZZZW_ACC(sve2_umlal_zzzw_h, uint16_t, uint8_t, H1_2, H1, DO_MUL)
82
+DO_ZZZW_ACC(sve2_umlal_zzzw_s, uint32_t, uint16_t, H1_4, H1_2, DO_MUL)
83
+DO_ZZZW_ACC(sve2_umlal_zzzw_d, uint64_t, uint32_t, , H1_4, DO_MUL)
84
+
85
+#define DO_NMUL(N, M) -(N * M)
86
+
87
+DO_ZZZW_ACC(sve2_smlsl_zzzw_h, int16_t, int8_t, H1_2, H1, DO_NMUL)
88
+DO_ZZZW_ACC(sve2_smlsl_zzzw_s, int32_t, int16_t, H1_4, H1_2, DO_NMUL)
89
+DO_ZZZW_ACC(sve2_smlsl_zzzw_d, int64_t, int32_t, , H1_4, DO_NMUL)
90
+
91
+DO_ZZZW_ACC(sve2_umlsl_zzzw_h, uint16_t, uint8_t, H1_2, H1, DO_NMUL)
92
+DO_ZZZW_ACC(sve2_umlsl_zzzw_s, uint32_t, uint16_t, H1_4, H1_2, DO_NMUL)
93
+DO_ZZZW_ACC(sve2_umlsl_zzzw_d, uint64_t, uint32_t, , H1_4, DO_NMUL)
94
+
95
#undef DO_ZZZW_ACC
96
97
#define DO_XTNB(NAME, TYPE, OP) \
98
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/arm/translate-sve.c
101
+++ b/target/arm/translate-sve.c
102
@@ -XXX,XX +XXX,XX @@ static bool trans_SQRDMLSH_zzzz(DisasContext *s, arg_rrrr_esz *a)
103
};
104
return do_sve2_zzzz_ool(s, a, fns[a->esz], 0);
105
}
106
+
107
+static bool do_smlal_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel)
108
+{
109
+ static gen_helper_gvec_4 * const fns[] = {
110
+ NULL, gen_helper_sve2_smlal_zzzw_h,
111
+ gen_helper_sve2_smlal_zzzw_s, gen_helper_sve2_smlal_zzzw_d,
112
+ };
113
+ return do_sve2_zzzz_ool(s, a, fns[a->esz], sel);
114
+}
115
+
116
+static bool trans_SMLALB_zzzw(DisasContext *s, arg_rrrr_esz *a)
117
+{
118
+ return do_smlal_zzzw(s, a, false);
119
+}
120
+
121
+static bool trans_SMLALT_zzzw(DisasContext *s, arg_rrrr_esz *a)
122
+{
123
+ return do_smlal_zzzw(s, a, true);
124
+}
125
+
126
+static bool do_umlal_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel)
127
+{
128
+ static gen_helper_gvec_4 * const fns[] = {
129
+ NULL, gen_helper_sve2_umlal_zzzw_h,
130
+ gen_helper_sve2_umlal_zzzw_s, gen_helper_sve2_umlal_zzzw_d,
131
+ };
132
+ return do_sve2_zzzz_ool(s, a, fns[a->esz], sel);
133
+}
134
+
135
+static bool trans_UMLALB_zzzw(DisasContext *s, arg_rrrr_esz *a)
136
+{
137
+ return do_umlal_zzzw(s, a, false);
138
+}
139
+
140
+static bool trans_UMLALT_zzzw(DisasContext *s, arg_rrrr_esz *a)
141
+{
142
+ return do_umlal_zzzw(s, a, true);
143
+}
144
+
145
+static bool do_smlsl_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel)
146
+{
147
+ static gen_helper_gvec_4 * const fns[] = {
148
+ NULL, gen_helper_sve2_smlsl_zzzw_h,
149
+ gen_helper_sve2_smlsl_zzzw_s, gen_helper_sve2_smlsl_zzzw_d,
150
+ };
151
+ return do_sve2_zzzz_ool(s, a, fns[a->esz], sel);
152
+}
153
+
154
+static bool trans_SMLSLB_zzzw(DisasContext *s, arg_rrrr_esz *a)
155
+{
156
+ return do_smlsl_zzzw(s, a, false);
157
+}
158
+
159
+static bool trans_SMLSLT_zzzw(DisasContext *s, arg_rrrr_esz *a)
160
+{
161
+ return do_smlsl_zzzw(s, a, true);
162
+}
163
+
164
+static bool do_umlsl_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel)
165
+{
166
+ static gen_helper_gvec_4 * const fns[] = {
167
+ NULL, gen_helper_sve2_umlsl_zzzw_h,
168
+ gen_helper_sve2_umlsl_zzzw_s, gen_helper_sve2_umlsl_zzzw_d,
169
+ };
170
+ return do_sve2_zzzz_ool(s, a, fns[a->esz], sel);
171
+}
172
+
173
+static bool trans_UMLSLB_zzzw(DisasContext *s, arg_rrrr_esz *a)
174
+{
175
+ return do_umlsl_zzzw(s, a, false);
176
+}
177
+
178
+static bool trans_UMLSLT_zzzw(DisasContext *s, arg_rrrr_esz *a)
179
+{
180
+ return do_umlsl_zzzw(s, a, true);
181
+}
182
--
183
2.20.1
184
185
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-38-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 18 +++++++++++++++
9
target/arm/vec_internal.h | 5 +++++
10
target/arm/sve.decode | 5 +++++
11
target/arm/sve_helper.c | 46 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate-sve.c | 32 ++++++++++++++++++++++++++
13
target/arm/vec_helper.c | 15 ++++++-------
14
6 files changed, 113 insertions(+), 8 deletions(-)
15
16
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-sve.h
19
+++ b/target/arm/helper-sve.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_umlsl_zzzw_s, TCG_CALL_NO_RWG,
21
void, ptr, ptr, ptr, ptr, i32)
22
DEF_HELPER_FLAGS_5(sve2_umlsl_zzzw_d, TCG_CALL_NO_RWG,
23
void, ptr, ptr, ptr, ptr, i32)
24
+
25
+DEF_HELPER_FLAGS_5(sve2_cmla_zzzz_b, TCG_CALL_NO_RWG,
26
+ void, ptr, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_5(sve2_cmla_zzzz_h, TCG_CALL_NO_RWG,
28
+ void, ptr, ptr, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_5(sve2_cmla_zzzz_s, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_5(sve2_cmla_zzzz_d, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, i32)
33
+
34
+DEF_HELPER_FLAGS_5(sve2_sqrdcmlah_zzzz_b, TCG_CALL_NO_RWG,
35
+ void, ptr, ptr, ptr, ptr, i32)
36
+DEF_HELPER_FLAGS_5(sve2_sqrdcmlah_zzzz_h, TCG_CALL_NO_RWG,
37
+ void, ptr, ptr, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_5(sve2_sqrdcmlah_zzzz_s, TCG_CALL_NO_RWG,
39
+ void, ptr, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_5(sve2_sqrdcmlah_zzzz_d, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, ptr, i32)
42
diff --git a/target/arm/vec_internal.h b/target/arm/vec_internal.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/vec_internal.h
45
+++ b/target/arm/vec_internal.h
46
@@ -XXX,XX +XXX,XX @@ static inline int64_t do_suqrshl_d(int64_t src, int64_t shift,
47
return do_uqrshl_d(src, shift, round, sat);
48
}
49
50
+int8_t do_sqrdmlah_b(int8_t, int8_t, int8_t, bool, bool);
51
+int16_t do_sqrdmlah_h(int16_t, int16_t, int16_t, bool, bool, uint32_t *);
52
+int32_t do_sqrdmlah_s(int32_t, int32_t, int32_t, bool, bool, uint32_t *);
53
+int64_t do_sqrdmlah_d(int64_t, int64_t, int64_t, bool, bool);
54
+
55
#endif /* TARGET_ARM_VEC_INTERNALS_H */
56
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/sve.decode
59
+++ b/target/arm/sve.decode
60
@@ -XXX,XX +XXX,XX @@ SMLSLB_zzzw 01000100 .. 0 ..... 010 100 ..... ..... @rda_rn_rm
61
SMLSLT_zzzw 01000100 .. 0 ..... 010 101 ..... ..... @rda_rn_rm
62
UMLSLB_zzzw 01000100 .. 0 ..... 010 110 ..... ..... @rda_rn_rm
63
UMLSLT_zzzw 01000100 .. 0 ..... 010 111 ..... ..... @rda_rn_rm
64
+
65
+## SVE2 complex integer multiply-add
66
+
67
+CMLA_zzzz 01000100 esz:2 0 rm:5 0010 rot:2 rn:5 rd:5 ra=%reg_movprfx
68
+SQRDCMLAH_zzzz 01000100 esz:2 0 rm:5 0011 rot:2 rn:5 rd:5 ra=%reg_movprfx
69
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/sve_helper.c
72
+++ b/target/arm/sve_helper.c
73
@@ -XXX,XX +XXX,XX @@ DO_SQDMLAL(sve2_sqdmlsl_zzzw_d, int64_t, int32_t, , H1_4,
74
75
#undef DO_SQDMLAL
76
77
+#define DO_CMLA_FUNC(NAME, TYPE, H, OP) \
78
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, uint32_t desc) \
79
+{ \
80
+ intptr_t i, opr_sz = simd_oprsz(desc) / sizeof(TYPE); \
81
+ int rot = simd_data(desc); \
82
+ int sel_a = rot & 1, sel_b = sel_a ^ 1; \
83
+ bool sub_r = rot == 1 || rot == 2; \
84
+ bool sub_i = rot >= 2; \
85
+ TYPE *d = vd, *n = vn, *m = vm, *a = va; \
86
+ for (i = 0; i < opr_sz; i += 2) { \
87
+ TYPE elt1_a = n[H(i + sel_a)]; \
88
+ TYPE elt2_a = m[H(i + sel_a)]; \
89
+ TYPE elt2_b = m[H(i + sel_b)]; \
90
+ d[H(i)] = OP(elt1_a, elt2_a, a[H(i)], sub_r); \
91
+ d[H(i + 1)] = OP(elt1_a, elt2_b, a[H(i + 1)], sub_i); \
92
+ } \
93
+}
94
+
95
+#define DO_CMLA(N, M, A, S) (A + (N * M) * (S ? -1 : 1))
96
+
97
+DO_CMLA_FUNC(sve2_cmla_zzzz_b, uint8_t, H1, DO_CMLA)
98
+DO_CMLA_FUNC(sve2_cmla_zzzz_h, uint16_t, H2, DO_CMLA)
99
+DO_CMLA_FUNC(sve2_cmla_zzzz_s, uint32_t, H4, DO_CMLA)
100
+DO_CMLA_FUNC(sve2_cmla_zzzz_d, uint64_t, , DO_CMLA)
101
+
102
+#define DO_SQRDMLAH_B(N, M, A, S) \
103
+ do_sqrdmlah_b(N, M, A, S, true)
104
+#define DO_SQRDMLAH_H(N, M, A, S) \
105
+ ({ uint32_t discard; do_sqrdmlah_h(N, M, A, S, true, &discard); })
106
+#define DO_SQRDMLAH_S(N, M, A, S) \
107
+ ({ uint32_t discard; do_sqrdmlah_s(N, M, A, S, true, &discard); })
108
+#define DO_SQRDMLAH_D(N, M, A, S) \
109
+ do_sqrdmlah_d(N, M, A, S, true)
110
+
111
+DO_CMLA_FUNC(sve2_sqrdcmlah_zzzz_b, int8_t, H1, DO_SQRDMLAH_B)
112
+DO_CMLA_FUNC(sve2_sqrdcmlah_zzzz_h, int16_t, H2, DO_SQRDMLAH_H)
113
+DO_CMLA_FUNC(sve2_sqrdcmlah_zzzz_s, int32_t, H4, DO_SQRDMLAH_S)
114
+DO_CMLA_FUNC(sve2_sqrdcmlah_zzzz_d, int64_t, , DO_SQRDMLAH_D)
115
+
116
+#undef DO_CMLA
117
+#undef DO_CMLA_FUNC
118
+#undef DO_SQRDMLAH_B
119
+#undef DO_SQRDMLAH_H
120
+#undef DO_SQRDMLAH_S
121
+#undef DO_SQRDMLAH_D
122
+
123
#define DO_BITPERM(NAME, TYPE, OP) \
124
void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
125
{ \
126
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/target/arm/translate-sve.c
129
+++ b/target/arm/translate-sve.c
130
@@ -XXX,XX +XXX,XX @@ static bool trans_UMLSLT_zzzw(DisasContext *s, arg_rrrr_esz *a)
131
{
132
return do_umlsl_zzzw(s, a, true);
133
}
134
+
135
+static bool trans_CMLA_zzzz(DisasContext *s, arg_CMLA_zzzz *a)
136
+{
137
+ static gen_helper_gvec_4 * const fns[] = {
138
+ gen_helper_sve2_cmla_zzzz_b, gen_helper_sve2_cmla_zzzz_h,
139
+ gen_helper_sve2_cmla_zzzz_s, gen_helper_sve2_cmla_zzzz_d,
140
+ };
141
+
142
+ if (!dc_isar_feature(aa64_sve2, s)) {
143
+ return false;
144
+ }
145
+ if (sve_access_check(s)) {
146
+ gen_gvec_ool_zzzz(s, fns[a->esz], a->rd, a->rn, a->rm, a->ra, a->rot);
147
+ }
148
+ return true;
149
+}
150
+
151
+static bool trans_SQRDCMLAH_zzzz(DisasContext *s, arg_SQRDCMLAH_zzzz *a)
152
+{
153
+ static gen_helper_gvec_4 * const fns[] = {
154
+ gen_helper_sve2_sqrdcmlah_zzzz_b, gen_helper_sve2_sqrdcmlah_zzzz_h,
155
+ gen_helper_sve2_sqrdcmlah_zzzz_s, gen_helper_sve2_sqrdcmlah_zzzz_d,
156
+ };
157
+
158
+ if (!dc_isar_feature(aa64_sve2, s)) {
159
+ return false;
160
+ }
161
+ if (sve_access_check(s)) {
162
+ gen_gvec_ool_zzzz(s, fns[a->esz], a->rd, a->rn, a->rm, a->ra, a->rot);
163
+ }
164
+ return true;
165
+}
166
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/target/arm/vec_helper.c
169
+++ b/target/arm/vec_helper.c
170
@@ -XXX,XX +XXX,XX @@
171
#endif
172
173
/* Signed saturating rounding doubling multiply-accumulate high half, 8-bit */
174
-static int8_t do_sqrdmlah_b(int8_t src1, int8_t src2, int8_t src3,
175
- bool neg, bool round)
176
+int8_t do_sqrdmlah_b(int8_t src1, int8_t src2, int8_t src3,
177
+ bool neg, bool round)
178
{
179
/*
180
* Simplify:
181
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_sqrdmlsh_b)(void *vd, void *vn, void *vm,
182
}
183
184
/* Signed saturating rounding doubling multiply-accumulate high half, 16-bit */
185
-static int16_t do_sqrdmlah_h(int16_t src1, int16_t src2, int16_t src3,
186
- bool neg, bool round, uint32_t *sat)
187
+int16_t do_sqrdmlah_h(int16_t src1, int16_t src2, int16_t src3,
188
+ bool neg, bool round, uint32_t *sat)
189
{
190
/* Simplify similarly to do_sqrdmlah_b above. */
191
int32_t ret = (int32_t)src1 * src2;
192
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_sqrdmlsh_h)(void *vd, void *vn, void *vm,
193
}
194
195
/* Signed saturating rounding doubling multiply-accumulate high half, 32-bit */
196
-static int32_t do_sqrdmlah_s(int32_t src1, int32_t src2, int32_t src3,
197
- bool neg, bool round, uint32_t *sat)
198
+int32_t do_sqrdmlah_s(int32_t src1, int32_t src2, int32_t src3,
199
+ bool neg, bool round, uint32_t *sat)
200
{
201
/* Simplify similarly to do_sqrdmlah_b above. */
202
int64_t ret = (int64_t)src1 * src2;
203
@@ -XXX,XX +XXX,XX @@ static int64_t do_sat128_d(Int128 r)
204
return ls;
205
}
206
207
-static int64_t do_sqrdmlah_d(int64_t n, int64_t m, int64_t a,
208
- bool neg, bool round)
209
+int64_t do_sqrdmlah_d(int64_t n, int64_t m, int64_t a, bool neg, bool round)
210
{
211
uint64_t l, h;
212
Int128 r, t;
213
--
214
2.20.1
215
216
diff view generated by jsdifflib
Deleted patch
1
From: Stephen Long <steplong@quicinc.com>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Stephen Long <steplong@quicinc.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210525010358.152808-39-richard.henderson@linaro.org
7
Message-Id: <20200417162231.10374-2-steplong@quicinc.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper-sve.h | 8 ++++++++
12
target/arm/sve.decode | 5 +++++
13
target/arm/sve_helper.c | 36 ++++++++++++++++++++++++++++++++++++
14
target/arm/translate-sve.c | 13 +++++++++++++
15
4 files changed, 62 insertions(+)
16
17
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper-sve.h
20
+++ b/target/arm/helper-sve.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve2_uqrshrnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
22
DEF_HELPER_FLAGS_3(sve2_uqrshrnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
23
DEF_HELPER_FLAGS_3(sve2_uqrshrnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
24
25
+DEF_HELPER_FLAGS_4(sve2_addhnb_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(sve2_addhnb_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(sve2_addhnb_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
+
29
+DEF_HELPER_FLAGS_4(sve2_addhnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(sve2_addhnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(sve2_addhnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
+
33
DEF_HELPER_FLAGS_5(sve2_match_ppzz_b, TCG_CALL_NO_RWG,
34
i32, ptr, ptr, ptr, ptr, i32)
35
DEF_HELPER_FLAGS_5(sve2_match_ppzz_h, TCG_CALL_NO_RWG,
36
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/sve.decode
39
+++ b/target/arm/sve.decode
40
@@ -XXX,XX +XXX,XX @@ UQSHRNT 01000101 .. 1 ..... 00 1101 ..... ..... @rd_rn_tszimm_shr
41
UQRSHRNB 01000101 .. 1 ..... 00 1110 ..... ..... @rd_rn_tszimm_shr
42
UQRSHRNT 01000101 .. 1 ..... 00 1111 ..... ..... @rd_rn_tszimm_shr
43
44
+## SVE2 integer add/subtract narrow high part
45
+
46
+ADDHNB 01000101 .. 1 ..... 011 000 ..... ..... @rd_rn_rm
47
+ADDHNT 01000101 .. 1 ..... 011 001 ..... ..... @rd_rn_rm
48
+
49
### SVE2 Character Match
50
51
MATCH 01000101 .. 1 ..... 100 ... ..... 0 .... @pd_pg_rn_rm
52
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/sve_helper.c
55
+++ b/target/arm/sve_helper.c
56
@@ -XXX,XX +XXX,XX @@ DO_SHRNT(sve2_uqrshrnt_d, uint64_t, uint32_t, , H1_4, DO_UQRSHRN_D)
57
#undef DO_SHRNB
58
#undef DO_SHRNT
59
60
+#define DO_BINOPNB(NAME, TYPEW, TYPEN, SHIFT, OP) \
61
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
62
+{ \
63
+ intptr_t i, opr_sz = simd_oprsz(desc); \
64
+ for (i = 0; i < opr_sz; i += sizeof(TYPEW)) { \
65
+ TYPEW nn = *(TYPEW *)(vn + i); \
66
+ TYPEW mm = *(TYPEW *)(vm + i); \
67
+ *(TYPEW *)(vd + i) = (TYPEN)OP(nn, mm, SHIFT); \
68
+ } \
69
+}
70
+
71
+#define DO_BINOPNT(NAME, TYPEW, TYPEN, SHIFT, HW, HN, OP) \
72
+void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
73
+{ \
74
+ intptr_t i, opr_sz = simd_oprsz(desc); \
75
+ for (i = 0; i < opr_sz; i += sizeof(TYPEW)) { \
76
+ TYPEW nn = *(TYPEW *)(vn + HW(i)); \
77
+ TYPEW mm = *(TYPEW *)(vm + HW(i)); \
78
+ *(TYPEN *)(vd + HN(i + sizeof(TYPEN))) = OP(nn, mm, SHIFT); \
79
+ } \
80
+}
81
+
82
+#define DO_ADDHN(N, M, SH) ((N + M) >> SH)
83
+
84
+DO_BINOPNB(sve2_addhnb_h, uint16_t, uint8_t, 8, DO_ADDHN)
85
+DO_BINOPNB(sve2_addhnb_s, uint32_t, uint16_t, 16, DO_ADDHN)
86
+DO_BINOPNB(sve2_addhnb_d, uint64_t, uint32_t, 32, DO_ADDHN)
87
+
88
+DO_BINOPNT(sve2_addhnt_h, uint16_t, uint8_t, 8, H1_2, H1, DO_ADDHN)
89
+DO_BINOPNT(sve2_addhnt_s, uint32_t, uint16_t, 16, H1_4, H1_2, DO_ADDHN)
90
+DO_BINOPNT(sve2_addhnt_d, uint64_t, uint32_t, 32, , H1_4, DO_ADDHN)
91
+
92
+#undef DO_ADDHN
93
+
94
+#undef DO_BINOPNB
95
+
96
/* Fully general four-operand expander, controlled by a predicate.
97
*/
98
#define DO_ZPZZZ(NAME, TYPE, H, OP) \
99
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/target/arm/translate-sve.c
102
+++ b/target/arm/translate-sve.c
103
@@ -XXX,XX +XXX,XX @@ static bool trans_UQRSHRNT(DisasContext *s, arg_rri_esz *a)
104
return do_sve2_shr_narrow(s, a, ops);
105
}
106
107
+#define DO_SVE2_ZZZ_NARROW(NAME, name) \
108
+static bool trans_##NAME(DisasContext *s, arg_rrr_esz *a) \
109
+{ \
110
+ static gen_helper_gvec_3 * const fns[4] = { \
111
+ NULL, gen_helper_sve2_##name##_h, \
112
+ gen_helper_sve2_##name##_s, gen_helper_sve2_##name##_d, \
113
+ }; \
114
+ return do_sve2_zzz_ool(s, a, fns[a->esz]); \
115
+}
116
+
117
+DO_SVE2_ZZZ_NARROW(ADDHNB, addhnb)
118
+DO_SVE2_ZZZ_NARROW(ADDHNT, addhnt)
119
+
120
static bool do_sve2_ppzz_flags(DisasContext *s, arg_rprr_esz *a,
121
gen_helper_gvec_flags_4 *fn)
122
{
123
--
124
2.20.1
125
126
diff view generated by jsdifflib
Deleted patch
1
From: Stephen Long <steplong@quicinc.com>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Stephen Long <steplong@quicinc.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210525010358.152808-40-richard.henderson@linaro.org
7
Message-Id: <20200417162231.10374-3-steplong@quicinc.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper-sve.h | 8 ++++++++
12
target/arm/sve.decode | 2 ++
13
target/arm/sve_helper.c | 10 ++++++++++
14
target/arm/translate-sve.c | 2 ++
15
4 files changed, 22 insertions(+)
16
17
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper-sve.h
20
+++ b/target/arm/helper-sve.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve2_addhnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
22
DEF_HELPER_FLAGS_4(sve2_addhnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
DEF_HELPER_FLAGS_4(sve2_addhnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
25
+DEF_HELPER_FLAGS_4(sve2_raddhnb_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(sve2_raddhnb_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(sve2_raddhnb_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
+
29
+DEF_HELPER_FLAGS_4(sve2_raddhnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(sve2_raddhnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(sve2_raddhnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
+
33
DEF_HELPER_FLAGS_5(sve2_match_ppzz_b, TCG_CALL_NO_RWG,
34
i32, ptr, ptr, ptr, ptr, i32)
35
DEF_HELPER_FLAGS_5(sve2_match_ppzz_h, TCG_CALL_NO_RWG,
36
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/sve.decode
39
+++ b/target/arm/sve.decode
40
@@ -XXX,XX +XXX,XX @@ UQRSHRNT 01000101 .. 1 ..... 00 1111 ..... ..... @rd_rn_tszimm_shr
41
42
ADDHNB 01000101 .. 1 ..... 011 000 ..... ..... @rd_rn_rm
43
ADDHNT 01000101 .. 1 ..... 011 001 ..... ..... @rd_rn_rm
44
+RADDHNB 01000101 .. 1 ..... 011 010 ..... ..... @rd_rn_rm
45
+RADDHNT 01000101 .. 1 ..... 011 011 ..... ..... @rd_rn_rm
46
47
### SVE2 Character Match
48
49
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/sve_helper.c
52
+++ b/target/arm/sve_helper.c
53
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
54
}
55
56
#define DO_ADDHN(N, M, SH) ((N + M) >> SH)
57
+#define DO_RADDHN(N, M, SH) ((N + M + ((__typeof(N))1 << (SH - 1))) >> SH)
58
59
DO_BINOPNB(sve2_addhnb_h, uint16_t, uint8_t, 8, DO_ADDHN)
60
DO_BINOPNB(sve2_addhnb_s, uint32_t, uint16_t, 16, DO_ADDHN)
61
@@ -XXX,XX +XXX,XX @@ DO_BINOPNT(sve2_addhnt_h, uint16_t, uint8_t, 8, H1_2, H1, DO_ADDHN)
62
DO_BINOPNT(sve2_addhnt_s, uint32_t, uint16_t, 16, H1_4, H1_2, DO_ADDHN)
63
DO_BINOPNT(sve2_addhnt_d, uint64_t, uint32_t, 32, , H1_4, DO_ADDHN)
64
65
+DO_BINOPNB(sve2_raddhnb_h, uint16_t, uint8_t, 8, DO_RADDHN)
66
+DO_BINOPNB(sve2_raddhnb_s, uint32_t, uint16_t, 16, DO_RADDHN)
67
+DO_BINOPNB(sve2_raddhnb_d, uint64_t, uint32_t, 32, DO_RADDHN)
68
+
69
+DO_BINOPNT(sve2_raddhnt_h, uint16_t, uint8_t, 8, H1_2, H1, DO_RADDHN)
70
+DO_BINOPNT(sve2_raddhnt_s, uint32_t, uint16_t, 16, H1_4, H1_2, DO_RADDHN)
71
+DO_BINOPNT(sve2_raddhnt_d, uint64_t, uint32_t, 32, , H1_4, DO_RADDHN)
72
+
73
+#undef DO_RADDHN
74
#undef DO_ADDHN
75
76
#undef DO_BINOPNB
77
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/translate-sve.c
80
+++ b/target/arm/translate-sve.c
81
@@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_rrr_esz *a) \
82
83
DO_SVE2_ZZZ_NARROW(ADDHNB, addhnb)
84
DO_SVE2_ZZZ_NARROW(ADDHNT, addhnt)
85
+DO_SVE2_ZZZ_NARROW(RADDHNB, raddhnb)
86
+DO_SVE2_ZZZ_NARROW(RADDHNT, raddhnt)
87
88
static bool do_sve2_ppzz_flags(DisasContext *s, arg_rprr_esz *a,
89
gen_helper_gvec_flags_4 *fn)
90
--
91
2.20.1
92
93
diff view generated by jsdifflib
Deleted patch
1
From: Stephen Long <steplong@quicinc.com>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Stephen Long <steplong@quicinc.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210525010358.152808-41-richard.henderson@linaro.org
7
Message-Id: <20200417162231.10374-4-steplong@quicinc.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper-sve.h | 8 ++++++++
12
target/arm/sve.decode | 2 ++
13
target/arm/sve_helper.c | 10 ++++++++++
14
target/arm/translate-sve.c | 3 +++
15
4 files changed, 23 insertions(+)
16
17
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper-sve.h
20
+++ b/target/arm/helper-sve.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve2_raddhnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
22
DEF_HELPER_FLAGS_4(sve2_raddhnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
DEF_HELPER_FLAGS_4(sve2_raddhnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
25
+DEF_HELPER_FLAGS_4(sve2_subhnb_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_4(sve2_subhnb_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_4(sve2_subhnb_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
+
29
+DEF_HELPER_FLAGS_4(sve2_subhnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_4(sve2_subhnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_4(sve2_subhnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
+
33
DEF_HELPER_FLAGS_5(sve2_match_ppzz_b, TCG_CALL_NO_RWG,
34
i32, ptr, ptr, ptr, ptr, i32)
35
DEF_HELPER_FLAGS_5(sve2_match_ppzz_h, TCG_CALL_NO_RWG,
36
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/sve.decode
39
+++ b/target/arm/sve.decode
40
@@ -XXX,XX +XXX,XX @@ ADDHNB 01000101 .. 1 ..... 011 000 ..... ..... @rd_rn_rm
41
ADDHNT 01000101 .. 1 ..... 011 001 ..... ..... @rd_rn_rm
42
RADDHNB 01000101 .. 1 ..... 011 010 ..... ..... @rd_rn_rm
43
RADDHNT 01000101 .. 1 ..... 011 011 ..... ..... @rd_rn_rm
44
+SUBHNB 01000101 .. 1 ..... 011 100 ..... ..... @rd_rn_rm
45
+SUBHNT 01000101 .. 1 ..... 011 101 ..... ..... @rd_rn_rm
46
47
### SVE2 Character Match
48
49
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/sve_helper.c
52
+++ b/target/arm/sve_helper.c
53
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
54
55
#define DO_ADDHN(N, M, SH) ((N + M) >> SH)
56
#define DO_RADDHN(N, M, SH) ((N + M + ((__typeof(N))1 << (SH - 1))) >> SH)
57
+#define DO_SUBHN(N, M, SH) ((N - M) >> SH)
58
59
DO_BINOPNB(sve2_addhnb_h, uint16_t, uint8_t, 8, DO_ADDHN)
60
DO_BINOPNB(sve2_addhnb_s, uint32_t, uint16_t, 16, DO_ADDHN)
61
@@ -XXX,XX +XXX,XX @@ DO_BINOPNT(sve2_raddhnt_h, uint16_t, uint8_t, 8, H1_2, H1, DO_RADDHN)
62
DO_BINOPNT(sve2_raddhnt_s, uint32_t, uint16_t, 16, H1_4, H1_2, DO_RADDHN)
63
DO_BINOPNT(sve2_raddhnt_d, uint64_t, uint32_t, 32, , H1_4, DO_RADDHN)
64
65
+DO_BINOPNB(sve2_subhnb_h, uint16_t, uint8_t, 8, DO_SUBHN)
66
+DO_BINOPNB(sve2_subhnb_s, uint32_t, uint16_t, 16, DO_SUBHN)
67
+DO_BINOPNB(sve2_subhnb_d, uint64_t, uint32_t, 32, DO_SUBHN)
68
+
69
+DO_BINOPNT(sve2_subhnt_h, uint16_t, uint8_t, 8, H1_2, H1, DO_SUBHN)
70
+DO_BINOPNT(sve2_subhnt_s, uint32_t, uint16_t, 16, H1_4, H1_2, DO_SUBHN)
71
+DO_BINOPNT(sve2_subhnt_d, uint64_t, uint32_t, 32, , H1_4, DO_SUBHN)
72
+
73
+#undef DO_SUBHN
74
#undef DO_RADDHN
75
#undef DO_ADDHN
76
77
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/translate-sve.c
80
+++ b/target/arm/translate-sve.c
81
@@ -XXX,XX +XXX,XX @@ DO_SVE2_ZZZ_NARROW(ADDHNT, addhnt)
82
DO_SVE2_ZZZ_NARROW(RADDHNB, raddhnb)
83
DO_SVE2_ZZZ_NARROW(RADDHNT, raddhnt)
84
85
+DO_SVE2_ZZZ_NARROW(SUBHNB, subhnb)
86
+DO_SVE2_ZZZ_NARROW(SUBHNT, subhnt)
87
+
88
static bool do_sve2_ppzz_flags(DisasContext *s, arg_rprr_esz *a,
89
gen_helper_gvec_flags_4 *fn)
90
{
91
--
92
2.20.1
93
94
diff view generated by jsdifflib
Deleted patch
1
From: Stephen Long <steplong@quicinc.com>
2
1
3
This completes the section 'SVE2 integer add/subtract narrow high part'
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Stephen Long <steplong@quicinc.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210525010358.152808-42-richard.henderson@linaro.org
9
Message-Id: <20200417162231.10374-5-steplong@quicinc.com>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/helper-sve.h | 8 ++++++++
14
target/arm/sve.decode | 2 ++
15
target/arm/sve_helper.c | 10 ++++++++++
16
target/arm/translate-sve.c | 2 ++
17
4 files changed, 22 insertions(+)
18
19
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper-sve.h
22
+++ b/target/arm/helper-sve.h
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve2_subhnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
DEF_HELPER_FLAGS_4(sve2_subhnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
DEF_HELPER_FLAGS_4(sve2_subhnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
27
+DEF_HELPER_FLAGS_4(sve2_rsubhnb_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_4(sve2_rsubhnb_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_4(sve2_rsubhnb_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
30
+
31
+DEF_HELPER_FLAGS_4(sve2_rsubhnt_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_4(sve2_rsubhnt_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_4(sve2_rsubhnt_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
+
35
DEF_HELPER_FLAGS_5(sve2_match_ppzz_b, TCG_CALL_NO_RWG,
36
i32, ptr, ptr, ptr, ptr, i32)
37
DEF_HELPER_FLAGS_5(sve2_match_ppzz_h, TCG_CALL_NO_RWG,
38
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/sve.decode
41
+++ b/target/arm/sve.decode
42
@@ -XXX,XX +XXX,XX @@ RADDHNB 01000101 .. 1 ..... 011 010 ..... ..... @rd_rn_rm
43
RADDHNT 01000101 .. 1 ..... 011 011 ..... ..... @rd_rn_rm
44
SUBHNB 01000101 .. 1 ..... 011 100 ..... ..... @rd_rn_rm
45
SUBHNT 01000101 .. 1 ..... 011 101 ..... ..... @rd_rn_rm
46
+RSUBHNB 01000101 .. 1 ..... 011 110 ..... ..... @rd_rn_rm
47
+RSUBHNT 01000101 .. 1 ..... 011 111 ..... ..... @rd_rn_rm
48
49
### SVE2 Character Match
50
51
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/sve_helper.c
54
+++ b/target/arm/sve_helper.c
55
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
56
#define DO_ADDHN(N, M, SH) ((N + M) >> SH)
57
#define DO_RADDHN(N, M, SH) ((N + M + ((__typeof(N))1 << (SH - 1))) >> SH)
58
#define DO_SUBHN(N, M, SH) ((N - M) >> SH)
59
+#define DO_RSUBHN(N, M, SH) ((N - M + ((__typeof(N))1 << (SH - 1))) >> SH)
60
61
DO_BINOPNB(sve2_addhnb_h, uint16_t, uint8_t, 8, DO_ADDHN)
62
DO_BINOPNB(sve2_addhnb_s, uint32_t, uint16_t, 16, DO_ADDHN)
63
@@ -XXX,XX +XXX,XX @@ DO_BINOPNT(sve2_subhnt_h, uint16_t, uint8_t, 8, H1_2, H1, DO_SUBHN)
64
DO_BINOPNT(sve2_subhnt_s, uint32_t, uint16_t, 16, H1_4, H1_2, DO_SUBHN)
65
DO_BINOPNT(sve2_subhnt_d, uint64_t, uint32_t, 32, , H1_4, DO_SUBHN)
66
67
+DO_BINOPNB(sve2_rsubhnb_h, uint16_t, uint8_t, 8, DO_RSUBHN)
68
+DO_BINOPNB(sve2_rsubhnb_s, uint32_t, uint16_t, 16, DO_RSUBHN)
69
+DO_BINOPNB(sve2_rsubhnb_d, uint64_t, uint32_t, 32, DO_RSUBHN)
70
+
71
+DO_BINOPNT(sve2_rsubhnt_h, uint16_t, uint8_t, 8, H1_2, H1, DO_RSUBHN)
72
+DO_BINOPNT(sve2_rsubhnt_s, uint32_t, uint16_t, 16, H1_4, H1_2, DO_RSUBHN)
73
+DO_BINOPNT(sve2_rsubhnt_d, uint64_t, uint32_t, 32, , H1_4, DO_RSUBHN)
74
+
75
+#undef DO_RSUBHN
76
#undef DO_SUBHN
77
#undef DO_RADDHN
78
#undef DO_ADDHN
79
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/arm/translate-sve.c
82
+++ b/target/arm/translate-sve.c
83
@@ -XXX,XX +XXX,XX @@ DO_SVE2_ZZZ_NARROW(RADDHNT, raddhnt)
84
85
DO_SVE2_ZZZ_NARROW(SUBHNB, subhnb)
86
DO_SVE2_ZZZ_NARROW(SUBHNT, subhnt)
87
+DO_SVE2_ZZZ_NARROW(RSUBHNB, rsubhnb)
88
+DO_SVE2_ZZZ_NARROW(RSUBHNT, rsubhnt)
89
90
static bool do_sve2_ppzz_flags(DisasContext *s, arg_rprr_esz *a,
91
gen_helper_gvec_flags_4 *fn)
92
--
93
2.20.1
94
95
diff view generated by jsdifflib
Deleted patch
1
From: Stephen Long <steplong@quicinc.com>
2
1
3
Add decoding logic for SVE2 64-bit/32-bit scatter non-temporal
4
store insns.
5
6
64-bit
7
* STNT1B (vector plus scalar)
8
* STNT1H (vector plus scalar)
9
* STNT1W (vector plus scalar)
10
* STNT1D (vector plus scalar)
11
12
32-bit
13
* STNT1B (vector plus scalar)
14
* STNT1H (vector plus scalar)
15
* STNT1W (vector plus scalar)
16
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Stephen Long <steplong@quicinc.com>
19
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20210525010358.152808-45-richard.henderson@linaro.org
21
Message-Id: <20200422141553.8037-1-steplong@quicinc.com>
22
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
25
target/arm/sve.decode | 10 ++++++++++
26
target/arm/translate-sve.c | 8 ++++++++
27
2 files changed, 18 insertions(+)
28
29
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/sve.decode
32
+++ b/target/arm/sve.decode
33
@@ -XXX,XX +XXX,XX @@ UMLSLT_zzzw 01000100 .. 0 ..... 010 111 ..... ..... @rda_rn_rm
34
35
CMLA_zzzz 01000100 esz:2 0 rm:5 0010 rot:2 rn:5 rd:5 ra=%reg_movprfx
36
SQRDCMLAH_zzzz 01000100 esz:2 0 rm:5 0011 rot:2 rn:5 rd:5 ra=%reg_movprfx
37
+
38
+### SVE2 Memory Store Group
39
+
40
+# SVE2 64-bit scatter non-temporal store (vector plus scalar)
41
+STNT1_zprz 1110010 .. 00 ..... 001 ... ..... ..... \
42
+ @rprr_scatter_store xs=2 esz=3 scale=0
43
+
44
+# SVE2 32-bit scatter non-temporal store (vector plus scalar)
45
+STNT1_zprz 1110010 .. 10 ..... 001 ... ..... ..... \
46
+ @rprr_scatter_store xs=0 esz=2 scale=0
47
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/translate-sve.c
50
+++ b/target/arm/translate-sve.c
51
@@ -XXX,XX +XXX,XX @@ static bool trans_ST1_zpiz(DisasContext *s, arg_ST1_zpiz *a)
52
return true;
53
}
54
55
+static bool trans_STNT1_zprz(DisasContext *s, arg_ST1_zprz *a)
56
+{
57
+ if (!dc_isar_feature(aa64_sve2, s)) {
58
+ return false;
59
+ }
60
+ return trans_ST1_zprz(s, a);
61
+}
62
+
63
/*
64
* Prefetches
65
*/
66
--
67
2.20.1
68
69
diff view generated by jsdifflib
Deleted patch
1
From: Stephen Long <steplong@quicinc.com>
2
1
3
Add decoding logic for SVE2 64-bit/32-bit gather non-temporal
4
load insns.
5
6
64-bit
7
* LDNT1SB
8
* LDNT1B (vector plus scalar)
9
* LDNT1SH
10
* LDNT1H (vector plus scalar)
11
* LDNT1SW
12
* LDNT1W (vector plus scalar)
13
* LDNT1D (vector plus scalar)
14
15
32-bit
16
* LDNT1SB
17
* LDNT1B (vector plus scalar)
18
* LDNT1SH
19
* LDNT1H (vector plus scalar)
20
* LDNT1W (vector plus scalar)
21
22
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Stephen Long <steplong@quicinc.com>
24
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20210525010358.152808-46-richard.henderson@linaro.org
26
Message-Id: <20200422152343.12493-1-steplong@quicinc.com>
27
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
---
30
target/arm/sve.decode | 11 +++++++++++
31
target/arm/translate-sve.c | 8 ++++++++
32
2 files changed, 19 insertions(+)
33
34
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/sve.decode
37
+++ b/target/arm/sve.decode
38
@@ -XXX,XX +XXX,XX @@ UMLSLT_zzzw 01000100 .. 0 ..... 010 111 ..... ..... @rda_rn_rm
39
CMLA_zzzz 01000100 esz:2 0 rm:5 0010 rot:2 rn:5 rd:5 ra=%reg_movprfx
40
SQRDCMLAH_zzzz 01000100 esz:2 0 rm:5 0011 rot:2 rn:5 rd:5 ra=%reg_movprfx
41
42
+### SVE2 Memory Gather Load Group
43
+
44
+# SVE2 64-bit gather non-temporal load
45
+# (scalar plus unpacked 32-bit unscaled offsets)
46
+LDNT1_zprz 1100010 msz:2 00 rm:5 1 u:1 0 pg:3 rn:5 rd:5 \
47
+ &rprr_gather_load xs=0 esz=3 scale=0 ff=0
48
+
49
+# SVE2 32-bit gather non-temporal load (scalar plus 32-bit unscaled offsets)
50
+LDNT1_zprz 1000010 msz:2 00 rm:5 10 u:1 pg:3 rn:5 rd:5 \
51
+ &rprr_gather_load xs=0 esz=2 scale=0 ff=0
52
+
53
### SVE2 Memory Store Group
54
55
# SVE2 64-bit scatter non-temporal store (vector plus scalar)
56
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate-sve.c
59
+++ b/target/arm/translate-sve.c
60
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1_zpiz(DisasContext *s, arg_LD1_zpiz *a)
61
return true;
62
}
63
64
+static bool trans_LDNT1_zprz(DisasContext *s, arg_LD1_zprz *a)
65
+{
66
+ if (!dc_isar_feature(aa64_sve2, s)) {
67
+ return false;
68
+ }
69
+ return trans_LD1_zprz(s, a);
70
+}
71
+
72
/* Indexed by [mte][be][xs][msz]. */
73
static gen_helper_gvec_mem_scatter * const scatter_store_fn32[2][2][2][3] = {
74
{ /* MTE Inactive */
75
--
76
2.20.1
77
78
diff view generated by jsdifflib
Deleted patch
1
From: Stephen Long <steplong@quicinc.com>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Stephen Long <steplong@quicinc.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210525010358.152808-47-richard.henderson@linaro.org
7
Message-Id: <20200422165503.13511-1-steplong@quicinc.com>
8
[rth: Fix indexing in helpers, expand macro to straight functions.]
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 10 ++++++
13
target/arm/helper-sve.h | 3 ++
14
target/arm/sve.decode | 4 +++
15
target/arm/sve_helper.c | 74 ++++++++++++++++++++++++++++++++++++++
16
target/arm/translate-sve.c | 34 ++++++++++++++++++
17
5 files changed, 125 insertions(+)
18
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sve2_bitperm(const ARMISARegisters *id)
24
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BITPERM) != 0;
25
}
26
27
+static inline bool isar_feature_aa64_sve_f32mm(const ARMISARegisters *id)
28
+{
29
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, F32MM) != 0;
30
+}
31
+
32
+static inline bool isar_feature_aa64_sve_f64mm(const ARMISARegisters *id)
33
+{
34
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, F64MM) != 0;
35
+}
36
+
37
/*
38
* Feature tests for "does this exist in either 32-bit or 64-bit?"
39
*/
40
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/helper-sve.h
43
+++ b/target/arm/helper-sve.h
44
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_sqrdcmlah_zzzz_s, TCG_CALL_NO_RWG,
45
void, ptr, ptr, ptr, ptr, i32)
46
DEF_HELPER_FLAGS_5(sve2_sqrdcmlah_zzzz_d, TCG_CALL_NO_RWG,
47
void, ptr, ptr, ptr, ptr, i32)
48
+
49
+DEF_HELPER_FLAGS_6(fmmla_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, ptr, i32)
50
+DEF_HELPER_FLAGS_6(fmmla_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, ptr, i32)
51
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/sve.decode
54
+++ b/target/arm/sve.decode
55
@@ -XXX,XX +XXX,XX @@ UMLSLT_zzzw 01000100 .. 0 ..... 010 111 ..... ..... @rda_rn_rm
56
CMLA_zzzz 01000100 esz:2 0 rm:5 0010 rot:2 rn:5 rd:5 ra=%reg_movprfx
57
SQRDCMLAH_zzzz 01000100 esz:2 0 rm:5 0011 rot:2 rn:5 rd:5 ra=%reg_movprfx
58
59
+### SVE2 floating point matrix multiply accumulate
60
+
61
+FMMLA 01100100 .. 1 ..... 111001 ..... ..... @rda_rn_rm
62
+
63
### SVE2 Memory Gather Load Group
64
65
# SVE2 64-bit gather non-temporal load
66
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/sve_helper.c
69
+++ b/target/arm/sve_helper.c
70
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_xar_s)(void *vd, void *vn, void *vm, uint32_t desc)
71
d[i] = ror32(n[i] ^ m[i], shr);
72
}
73
}
74
+
75
+void HELPER(fmmla_s)(void *vd, void *vn, void *vm, void *va,
76
+ void *status, uint32_t desc)
77
+{
78
+ intptr_t s, opr_sz = simd_oprsz(desc) / (sizeof(float32) * 4);
79
+
80
+ for (s = 0; s < opr_sz; ++s) {
81
+ float32 *n = vn + s * sizeof(float32) * 4;
82
+ float32 *m = vm + s * sizeof(float32) * 4;
83
+ float32 *a = va + s * sizeof(float32) * 4;
84
+ float32 *d = vd + s * sizeof(float32) * 4;
85
+ float32 n00 = n[H4(0)], n01 = n[H4(1)];
86
+ float32 n10 = n[H4(2)], n11 = n[H4(3)];
87
+ float32 m00 = m[H4(0)], m01 = m[H4(1)];
88
+ float32 m10 = m[H4(2)], m11 = m[H4(3)];
89
+ float32 p0, p1;
90
+
91
+ /* i = 0, j = 0 */
92
+ p0 = float32_mul(n00, m00, status);
93
+ p1 = float32_mul(n01, m01, status);
94
+ d[H4(0)] = float32_add(a[H4(0)], float32_add(p0, p1, status), status);
95
+
96
+ /* i = 0, j = 1 */
97
+ p0 = float32_mul(n00, m10, status);
98
+ p1 = float32_mul(n01, m11, status);
99
+ d[H4(1)] = float32_add(a[H4(1)], float32_add(p0, p1, status), status);
100
+
101
+ /* i = 1, j = 0 */
102
+ p0 = float32_mul(n10, m00, status);
103
+ p1 = float32_mul(n11, m01, status);
104
+ d[H4(2)] = float32_add(a[H4(2)], float32_add(p0, p1, status), status);
105
+
106
+ /* i = 1, j = 1 */
107
+ p0 = float32_mul(n10, m10, status);
108
+ p1 = float32_mul(n11, m11, status);
109
+ d[H4(3)] = float32_add(a[H4(3)], float32_add(p0, p1, status), status);
110
+ }
111
+}
112
+
113
+void HELPER(fmmla_d)(void *vd, void *vn, void *vm, void *va,
114
+ void *status, uint32_t desc)
115
+{
116
+ intptr_t s, opr_sz = simd_oprsz(desc) / (sizeof(float64) * 4);
117
+
118
+ for (s = 0; s < opr_sz; ++s) {
119
+ float64 *n = vn + s * sizeof(float64) * 4;
120
+ float64 *m = vm + s * sizeof(float64) * 4;
121
+ float64 *a = va + s * sizeof(float64) * 4;
122
+ float64 *d = vd + s * sizeof(float64) * 4;
123
+ float64 n00 = n[0], n01 = n[1], n10 = n[2], n11 = n[3];
124
+ float64 m00 = m[0], m01 = m[1], m10 = m[2], m11 = m[3];
125
+ float64 p0, p1;
126
+
127
+ /* i = 0, j = 0 */
128
+ p0 = float64_mul(n00, m00, status);
129
+ p1 = float64_mul(n01, m01, status);
130
+ d[0] = float64_add(a[0], float64_add(p0, p1, status), status);
131
+
132
+ /* i = 0, j = 1 */
133
+ p0 = float64_mul(n00, m10, status);
134
+ p1 = float64_mul(n01, m11, status);
135
+ d[1] = float64_add(a[1], float64_add(p0, p1, status), status);
136
+
137
+ /* i = 1, j = 0 */
138
+ p0 = float64_mul(n10, m00, status);
139
+ p1 = float64_mul(n11, m01, status);
140
+ d[2] = float64_add(a[2], float64_add(p0, p1, status), status);
141
+
142
+ /* i = 1, j = 1 */
143
+ p0 = float64_mul(n10, m10, status);
144
+ p1 = float64_mul(n11, m11, status);
145
+ d[3] = float64_add(a[3], float64_add(p0, p1, status), status);
146
+ }
147
+}
148
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
149
index XXXXXXX..XXXXXXX 100644
150
--- a/target/arm/translate-sve.c
151
+++ b/target/arm/translate-sve.c
152
@@ -XXX,XX +XXX,XX @@ DO_SVE2_ZPZZ_FP(FMINP, fminp)
153
* SVE Integer Multiply-Add (unpredicated)
154
*/
155
156
+static bool trans_FMMLA(DisasContext *s, arg_rrrr_esz *a)
157
+{
158
+ gen_helper_gvec_4_ptr *fn;
159
+
160
+ switch (a->esz) {
161
+ case MO_32:
162
+ if (!dc_isar_feature(aa64_sve_f32mm, s)) {
163
+ return false;
164
+ }
165
+ fn = gen_helper_fmmla_s;
166
+ break;
167
+ case MO_64:
168
+ if (!dc_isar_feature(aa64_sve_f64mm, s)) {
169
+ return false;
170
+ }
171
+ fn = gen_helper_fmmla_d;
172
+ break;
173
+ default:
174
+ return false;
175
+ }
176
+
177
+ if (sve_access_check(s)) {
178
+ unsigned vsz = vec_full_reg_size(s);
179
+ TCGv_ptr status = fpstatus_ptr(FPST_FPCR);
180
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
181
+ vec_full_reg_offset(s, a->rn),
182
+ vec_full_reg_offset(s, a->rm),
183
+ vec_full_reg_offset(s, a->ra),
184
+ status, vsz, vsz, 0, fn);
185
+ tcg_temp_free_ptr(status);
186
+ }
187
+ return true;
188
+}
189
+
190
static bool do_sqdmlal_zzzw(DisasContext *s, arg_rrrr_esz *a,
191
bool sel1, bool sel2)
192
{
193
--
194
2.20.1
195
196
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The signed dot product routines produce a signed result.
4
Since we use -fwrapv, there is no functional change.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210525010358.152808-49-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/vec_helper.c | 8 ++++----
12
1 file changed, 4 insertions(+), 4 deletions(-)
13
14
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/vec_helper.c
17
+++ b/target/arm/vec_helper.c
18
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_sqrdmlsh_d)(void *vd, void *vn, void *vm,
19
void HELPER(gvec_sdot_b)(void *vd, void *vn, void *vm, uint32_t desc)
20
{
21
intptr_t i, opr_sz = simd_oprsz(desc);
22
- uint32_t *d = vd;
23
+ int32_t *d = vd;
24
int8_t *n = vn, *m = vm;
25
26
for (i = 0; i < opr_sz / 4; ++i) {
27
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_udot_b)(void *vd, void *vn, void *vm, uint32_t desc)
28
void HELPER(gvec_sdot_h)(void *vd, void *vn, void *vm, uint32_t desc)
29
{
30
intptr_t i, opr_sz = simd_oprsz(desc);
31
- uint64_t *d = vd;
32
+ int64_t *d = vd;
33
int16_t *n = vn, *m = vm;
34
35
for (i = 0; i < opr_sz / 8; ++i) {
36
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
37
{
38
intptr_t i, segend, opr_sz = simd_oprsz(desc), opr_sz_4 = opr_sz / 4;
39
intptr_t index = simd_data(desc);
40
- uint32_t *d = vd;
41
+ int32_t *d = vd;
42
int8_t *n = vn;
43
int8_t *m_indexed = (int8_t *)vm + H4(index) * 4;
44
45
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_sdot_idx_h)(void *vd, void *vn, void *vm, uint32_t desc)
46
{
47
intptr_t i, opr_sz = simd_oprsz(desc), opr_sz_8 = opr_sz / 8;
48
intptr_t index = simd_data(desc);
49
- uint64_t *d = vd;
50
+ int64_t *d = vd;
51
int16_t *n = vn;
52
int16_t *m_indexed = (int16_t *)vm + index * 4;
53
54
--
55
2.20.1
56
57
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
For SVE, we potentially have a 4th argument coming from the
4
movprfx instruction. Currently we do not optimize movprfx,
5
so the problem is not visible.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210525010358.152808-50-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/helper.h | 20 +++---
13
target/arm/sve.decode | 7 ++-
14
target/arm/translate-a64.c | 15 ++++-
15
target/arm/translate-neon.c | 10 +--
16
target/arm/translate-sve.c | 13 ++--
17
target/arm/vec_helper.c | 120 ++++++++++++++++++++----------------
18
6 files changed, 109 insertions(+), 76 deletions(-)
19
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.h
23
+++ b/target/arm/helper.h
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_sqrdmlah_d, TCG_CALL_NO_RWG,
25
DEF_HELPER_FLAGS_5(sve2_sqrdmlsh_d, TCG_CALL_NO_RWG,
26
void, ptr, ptr, ptr, ptr, i32)
27
28
-DEF_HELPER_FLAGS_4(gvec_sdot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
-DEF_HELPER_FLAGS_4(gvec_udot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
30
-DEF_HELPER_FLAGS_4(gvec_sdot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
31
-DEF_HELPER_FLAGS_4(gvec_udot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_5(gvec_sdot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_5(gvec_udot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_5(gvec_sdot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_5(gvec_udot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
36
37
-DEF_HELPER_FLAGS_4(gvec_sdot_idx_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
38
-DEF_HELPER_FLAGS_4(gvec_udot_idx_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
39
-DEF_HELPER_FLAGS_4(gvec_sdot_idx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
40
-DEF_HELPER_FLAGS_4(gvec_udot_idx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
41
+DEF_HELPER_FLAGS_5(gvec_sdot_idx_b, TCG_CALL_NO_RWG,
42
+ void, ptr, ptr, ptr, ptr, i32)
43
+DEF_HELPER_FLAGS_5(gvec_udot_idx_b, TCG_CALL_NO_RWG,
44
+ void, ptr, ptr, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_5(gvec_sdot_idx_h, TCG_CALL_NO_RWG,
46
+ void, ptr, ptr, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_5(gvec_udot_idx_h, TCG_CALL_NO_RWG,
48
+ void, ptr, ptr, ptr, ptr, i32)
49
50
DEF_HELPER_FLAGS_5(gvec_fcaddh, TCG_CALL_NO_RWG,
51
void, ptr, ptr, ptr, ptr, i32)
52
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/sve.decode
55
+++ b/target/arm/sve.decode
56
@@ -XXX,XX +XXX,XX @@ UMIN_zzi 00100101 .. 101 011 110 ........ ..... @rdn_i8u
57
MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
58
59
# SVE integer dot product (unpredicated)
60
-DOT_zzz 01000100 1 sz:1 0 rm:5 00000 u:1 rn:5 rd:5 ra=%reg_movprfx
61
+DOT_zzzz 01000100 1 sz:1 0 rm:5 00000 u:1 rn:5 rd:5 \
62
+ ra=%reg_movprfx
63
64
# SVE integer dot product (indexed)
65
-DOT_zzx 01000100 101 index:2 rm:3 00000 u:1 rn:5 rd:5 \
66
+DOT_zzxw 01000100 101 index:2 rm:3 00000 u:1 rn:5 rd:5 \
67
sz=0 ra=%reg_movprfx
68
-DOT_zzx 01000100 111 index:1 rm:4 00000 u:1 rn:5 rd:5 \
69
+DOT_zzxw 01000100 111 index:1 rm:4 00000 u:1 rn:5 rd:5 \
70
sz=1 ra=%reg_movprfx
71
72
# SVE floating-point complex add (predicated)
73
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/target/arm/translate-a64.c
76
+++ b/target/arm/translate-a64.c
77
@@ -XXX,XX +XXX,XX @@ static void gen_gvec_op3_qc(DisasContext *s, bool is_q, int rd, int rn,
78
tcg_temp_free_ptr(qc_ptr);
79
}
80
81
+/* Expand a 4-operand operation using an out-of-line helper. */
82
+static void gen_gvec_op4_ool(DisasContext *s, bool is_q, int rd, int rn,
83
+ int rm, int ra, int data, gen_helper_gvec_4 *fn)
84
+{
85
+ tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
86
+ vec_full_reg_offset(s, rn),
87
+ vec_full_reg_offset(s, rm),
88
+ vec_full_reg_offset(s, ra),
89
+ is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
90
+}
91
+
92
/* Set ZF and NF based on a 64 bit result. This is alas fiddlier
93
* than the 32 bit equivalent.
94
*/
95
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
96
return;
97
98
case 0x2: /* SDOT / UDOT */
99
- gen_gvec_op3_ool(s, is_q, rd, rn, rm, 0,
100
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0,
101
u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b);
102
return;
103
104
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
105
switch (16 * u + opcode) {
106
case 0x0e: /* SDOT */
107
case 0x1e: /* UDOT */
108
- gen_gvec_op3_ool(s, is_q, rd, rn, rm, index,
109
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
110
u ? gen_helper_gvec_udot_idx_b
111
: gen_helper_gvec_sdot_idx_b);
112
return;
113
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/arm/translate-neon.c
116
+++ b/target/arm/translate-neon.c
117
@@ -XXX,XX +XXX,XX @@ static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
118
static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
119
{
120
int opr_sz;
121
- gen_helper_gvec_3 *fn_gvec;
122
+ gen_helper_gvec_4 *fn_gvec;
123
124
if (!dc_isar_feature(aa32_dp, s)) {
125
return false;
126
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
127
128
opr_sz = (1 + a->q) * 8;
129
fn_gvec = a->u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
130
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
131
+ tcg_gen_gvec_4_ool(vfp_reg_offset(1, a->vd),
132
vfp_reg_offset(1, a->vn),
133
vfp_reg_offset(1, a->vm),
134
+ vfp_reg_offset(1, a->vd),
135
opr_sz, opr_sz, 0, fn_gvec);
136
return true;
137
}
138
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
139
140
static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
141
{
142
- gen_helper_gvec_3 *fn_gvec;
143
+ gen_helper_gvec_4 *fn_gvec;
144
int opr_sz;
145
TCGv_ptr fpst;
146
147
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
148
fn_gvec = a->u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
149
opr_sz = (1 + a->q) * 8;
150
fpst = fpstatus_ptr(FPST_STD);
151
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
152
+ tcg_gen_gvec_4_ool(vfp_reg_offset(1, a->vd),
153
vfp_reg_offset(1, a->vn),
154
vfp_reg_offset(1, a->rm),
155
+ vfp_reg_offset(1, a->vd),
156
opr_sz, opr_sz, a->index, fn_gvec);
157
tcg_temp_free_ptr(fpst);
158
return true;
159
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/target/arm/translate-sve.c
162
+++ b/target/arm/translate-sve.c
163
@@ -XXX,XX +XXX,XX @@ DO_ZZI(UMIN, umin)
164
165
#undef DO_ZZI
166
167
-static bool trans_DOT_zzz(DisasContext *s, arg_DOT_zzz *a)
168
+static bool trans_DOT_zzzz(DisasContext *s, arg_DOT_zzzz *a)
169
{
170
- static gen_helper_gvec_3 * const fns[2][2] = {
171
+ static gen_helper_gvec_4 * const fns[2][2] = {
172
{ gen_helper_gvec_sdot_b, gen_helper_gvec_sdot_h },
173
{ gen_helper_gvec_udot_b, gen_helper_gvec_udot_h }
174
};
175
176
if (sve_access_check(s)) {
177
- gen_gvec_ool_zzz(s, fns[a->u][a->sz], a->rd, a->rn, a->rm, 0);
178
+ gen_gvec_ool_zzzz(s, fns[a->u][a->sz], a->rd, a->rn, a->rm, a->ra, 0);
179
}
180
return true;
181
}
182
183
-static bool trans_DOT_zzx(DisasContext *s, arg_DOT_zzx *a)
184
+static bool trans_DOT_zzxw(DisasContext *s, arg_DOT_zzxw *a)
185
{
186
- static gen_helper_gvec_3 * const fns[2][2] = {
187
+ static gen_helper_gvec_4 * const fns[2][2] = {
188
{ gen_helper_gvec_sdot_idx_b, gen_helper_gvec_sdot_idx_h },
189
{ gen_helper_gvec_udot_idx_b, gen_helper_gvec_udot_idx_h }
190
};
191
192
if (sve_access_check(s)) {
193
- gen_gvec_ool_zzz(s, fns[a->u][a->sz], a->rd, a->rn, a->rm, a->index);
194
+ gen_gvec_ool_zzzz(s, fns[a->u][a->sz], a->rd, a->rn, a->rm,
195
+ a->ra, a->index);
196
}
197
return true;
198
}
199
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/target/arm/vec_helper.c
202
+++ b/target/arm/vec_helper.c
203
@@ -XXX,XX +XXX,XX @@ void HELPER(sve2_sqrdmlsh_d)(void *vd, void *vn, void *vm,
204
* All elements are treated equally, no matter where they are.
205
*/
206
207
-void HELPER(gvec_sdot_b)(void *vd, void *vn, void *vm, uint32_t desc)
208
+void HELPER(gvec_sdot_b)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
209
{
210
intptr_t i, opr_sz = simd_oprsz(desc);
211
- int32_t *d = vd;
212
+ int32_t *d = vd, *a = va;
213
int8_t *n = vn, *m = vm;
214
215
for (i = 0; i < opr_sz / 4; ++i) {
216
- d[i] += n[i * 4 + 0] * m[i * 4 + 0]
217
- + n[i * 4 + 1] * m[i * 4 + 1]
218
- + n[i * 4 + 2] * m[i * 4 + 2]
219
- + n[i * 4 + 3] * m[i * 4 + 3];
220
+ d[i] = (a[i] +
221
+ n[i * 4 + 0] * m[i * 4 + 0] +
222
+ n[i * 4 + 1] * m[i * 4 + 1] +
223
+ n[i * 4 + 2] * m[i * 4 + 2] +
224
+ n[i * 4 + 3] * m[i * 4 + 3]);
225
}
226
clear_tail(d, opr_sz, simd_maxsz(desc));
227
}
228
229
-void HELPER(gvec_udot_b)(void *vd, void *vn, void *vm, uint32_t desc)
230
+void HELPER(gvec_udot_b)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
231
{
232
intptr_t i, opr_sz = simd_oprsz(desc);
233
- uint32_t *d = vd;
234
+ uint32_t *d = vd, *a = va;
235
uint8_t *n = vn, *m = vm;
236
237
for (i = 0; i < opr_sz / 4; ++i) {
238
- d[i] += n[i * 4 + 0] * m[i * 4 + 0]
239
- + n[i * 4 + 1] * m[i * 4 + 1]
240
- + n[i * 4 + 2] * m[i * 4 + 2]
241
- + n[i * 4 + 3] * m[i * 4 + 3];
242
+ d[i] = (a[i] +
243
+ n[i * 4 + 0] * m[i * 4 + 0] +
244
+ n[i * 4 + 1] * m[i * 4 + 1] +
245
+ n[i * 4 + 2] * m[i * 4 + 2] +
246
+ n[i * 4 + 3] * m[i * 4 + 3]);
247
}
248
clear_tail(d, opr_sz, simd_maxsz(desc));
249
}
250
251
-void HELPER(gvec_sdot_h)(void *vd, void *vn, void *vm, uint32_t desc)
252
+void HELPER(gvec_sdot_h)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
253
{
254
intptr_t i, opr_sz = simd_oprsz(desc);
255
- int64_t *d = vd;
256
+ int64_t *d = vd, *a = va;
257
int16_t *n = vn, *m = vm;
258
259
for (i = 0; i < opr_sz / 8; ++i) {
260
- d[i] += (int64_t)n[i * 4 + 0] * m[i * 4 + 0]
261
- + (int64_t)n[i * 4 + 1] * m[i * 4 + 1]
262
- + (int64_t)n[i * 4 + 2] * m[i * 4 + 2]
263
- + (int64_t)n[i * 4 + 3] * m[i * 4 + 3];
264
+ d[i] = (a[i] +
265
+ (int64_t)n[i * 4 + 0] * m[i * 4 + 0] +
266
+ (int64_t)n[i * 4 + 1] * m[i * 4 + 1] +
267
+ (int64_t)n[i * 4 + 2] * m[i * 4 + 2] +
268
+ (int64_t)n[i * 4 + 3] * m[i * 4 + 3]);
269
}
270
clear_tail(d, opr_sz, simd_maxsz(desc));
271
}
272
273
-void HELPER(gvec_udot_h)(void *vd, void *vn, void *vm, uint32_t desc)
274
+void HELPER(gvec_udot_h)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
275
{
276
intptr_t i, opr_sz = simd_oprsz(desc);
277
- uint64_t *d = vd;
278
+ uint64_t *d = vd, *a = va;
279
uint16_t *n = vn, *m = vm;
280
281
for (i = 0; i < opr_sz / 8; ++i) {
282
- d[i] += (uint64_t)n[i * 4 + 0] * m[i * 4 + 0]
283
- + (uint64_t)n[i * 4 + 1] * m[i * 4 + 1]
284
- + (uint64_t)n[i * 4 + 2] * m[i * 4 + 2]
285
- + (uint64_t)n[i * 4 + 3] * m[i * 4 + 3];
286
+ d[i] = (a[i] +
287
+ (uint64_t)n[i * 4 + 0] * m[i * 4 + 0] +
288
+ (uint64_t)n[i * 4 + 1] * m[i * 4 + 1] +
289
+ (uint64_t)n[i * 4 + 2] * m[i * 4 + 2] +
290
+ (uint64_t)n[i * 4 + 3] * m[i * 4 + 3]);
291
}
292
clear_tail(d, opr_sz, simd_maxsz(desc));
293
}
294
295
-void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
296
+void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm,
297
+ void *va, uint32_t desc)
298
{
299
intptr_t i, segend, opr_sz = simd_oprsz(desc), opr_sz_4 = opr_sz / 4;
300
intptr_t index = simd_data(desc);
301
- int32_t *d = vd;
302
+ int32_t *d = vd, *a = va;
303
int8_t *n = vn;
304
int8_t *m_indexed = (int8_t *)vm + H4(index) * 4;
305
306
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
307
int8_t m3 = m_indexed[i * 4 + 3];
308
309
do {
310
- d[i] += n[i * 4 + 0] * m0
311
- + n[i * 4 + 1] * m1
312
- + n[i * 4 + 2] * m2
313
- + n[i * 4 + 3] * m3;
314
+ d[i] = (a[i] +
315
+ n[i * 4 + 0] * m0 +
316
+ n[i * 4 + 1] * m1 +
317
+ n[i * 4 + 2] * m2 +
318
+ n[i * 4 + 3] * m3);
319
} while (++i < segend);
320
segend = i + 4;
321
} while (i < opr_sz_4);
322
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
323
clear_tail(d, opr_sz, simd_maxsz(desc));
324
}
325
326
-void HELPER(gvec_udot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
327
+void HELPER(gvec_udot_idx_b)(void *vd, void *vn, void *vm,
328
+ void *va, uint32_t desc)
329
{
330
intptr_t i, segend, opr_sz = simd_oprsz(desc), opr_sz_4 = opr_sz / 4;
331
intptr_t index = simd_data(desc);
332
- uint32_t *d = vd;
333
+ uint32_t *d = vd, *a = va;
334
uint8_t *n = vn;
335
uint8_t *m_indexed = (uint8_t *)vm + H4(index) * 4;
336
337
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_udot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
338
uint8_t m3 = m_indexed[i * 4 + 3];
339
340
do {
341
- d[i] += n[i * 4 + 0] * m0
342
- + n[i * 4 + 1] * m1
343
- + n[i * 4 + 2] * m2
344
- + n[i * 4 + 3] * m3;
345
+ d[i] = (a[i] +
346
+ n[i * 4 + 0] * m0 +
347
+ n[i * 4 + 1] * m1 +
348
+ n[i * 4 + 2] * m2 +
349
+ n[i * 4 + 3] * m3);
350
} while (++i < segend);
351
segend = i + 4;
352
} while (i < opr_sz_4);
353
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_udot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
354
clear_tail(d, opr_sz, simd_maxsz(desc));
355
}
356
357
-void HELPER(gvec_sdot_idx_h)(void *vd, void *vn, void *vm, uint32_t desc)
358
+void HELPER(gvec_sdot_idx_h)(void *vd, void *vn, void *vm,
359
+ void *va, uint32_t desc)
360
{
361
intptr_t i, opr_sz = simd_oprsz(desc), opr_sz_8 = opr_sz / 8;
362
intptr_t index = simd_data(desc);
363
- int64_t *d = vd;
364
+ int64_t *d = vd, *a = va;
365
int16_t *n = vn;
366
int16_t *m_indexed = (int16_t *)vm + index * 4;
367
368
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_sdot_idx_h)(void *vd, void *vn, void *vm, uint32_t desc)
369
* Process the entire segment all at once, writing back the results
370
* only after we've consumed all of the inputs.
371
*/
372
- for (i = 0; i < opr_sz_8 ; i += 2) {
373
- uint64_t d0, d1;
374
+ for (i = 0; i < opr_sz_8; i += 2) {
375
+ int64_t d0, d1;
376
377
- d0 = n[i * 4 + 0] * (int64_t)m_indexed[i * 4 + 0];
378
+ d0 = a[i + 0];
379
+ d0 += n[i * 4 + 0] * (int64_t)m_indexed[i * 4 + 0];
380
d0 += n[i * 4 + 1] * (int64_t)m_indexed[i * 4 + 1];
381
d0 += n[i * 4 + 2] * (int64_t)m_indexed[i * 4 + 2];
382
d0 += n[i * 4 + 3] * (int64_t)m_indexed[i * 4 + 3];
383
- d1 = n[i * 4 + 4] * (int64_t)m_indexed[i * 4 + 0];
384
+
385
+ d1 = a[i + 1];
386
+ d1 += n[i * 4 + 4] * (int64_t)m_indexed[i * 4 + 0];
387
d1 += n[i * 4 + 5] * (int64_t)m_indexed[i * 4 + 1];
388
d1 += n[i * 4 + 6] * (int64_t)m_indexed[i * 4 + 2];
389
d1 += n[i * 4 + 7] * (int64_t)m_indexed[i * 4 + 3];
390
391
- d[i + 0] += d0;
392
- d[i + 1] += d1;
393
+ d[i + 0] = d0;
394
+ d[i + 1] = d1;
395
}
396
-
397
clear_tail(d, opr_sz, simd_maxsz(desc));
398
}
399
400
-void HELPER(gvec_udot_idx_h)(void *vd, void *vn, void *vm, uint32_t desc)
401
+void HELPER(gvec_udot_idx_h)(void *vd, void *vn, void *vm,
402
+ void *va, uint32_t desc)
403
{
404
intptr_t i, opr_sz = simd_oprsz(desc), opr_sz_8 = opr_sz / 8;
405
intptr_t index = simd_data(desc);
406
- uint64_t *d = vd;
407
+ uint64_t *d = vd, *a = va;
408
uint16_t *n = vn;
409
uint16_t *m_indexed = (uint16_t *)vm + index * 4;
410
411
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_udot_idx_h)(void *vd, void *vn, void *vm, uint32_t desc)
412
* Process the entire segment all at once, writing back the results
413
* only after we've consumed all of the inputs.
414
*/
415
- for (i = 0; i < opr_sz_8 ; i += 2) {
416
+ for (i = 0; i < opr_sz_8; i += 2) {
417
uint64_t d0, d1;
418
419
- d0 = n[i * 4 + 0] * (uint64_t)m_indexed[i * 4 + 0];
420
+ d0 = a[i + 0];
421
+ d0 += n[i * 4 + 0] * (uint64_t)m_indexed[i * 4 + 0];
422
d0 += n[i * 4 + 1] * (uint64_t)m_indexed[i * 4 + 1];
423
d0 += n[i * 4 + 2] * (uint64_t)m_indexed[i * 4 + 2];
424
d0 += n[i * 4 + 3] * (uint64_t)m_indexed[i * 4 + 3];
425
- d1 = n[i * 4 + 4] * (uint64_t)m_indexed[i * 4 + 0];
426
+
427
+ d1 = a[i + 1];
428
+ d1 += n[i * 4 + 4] * (uint64_t)m_indexed[i * 4 + 0];
429
d1 += n[i * 4 + 5] * (uint64_t)m_indexed[i * 4 + 1];
430
d1 += n[i * 4 + 6] * (uint64_t)m_indexed[i * 4 + 2];
431
d1 += n[i * 4 + 7] * (uint64_t)m_indexed[i * 4 + 3];
432
433
- d[i + 0] += d0;
434
- d[i + 1] += d1;
435
+ d[i + 0] = d0;
436
+ d[i + 1] = d1;
437
}
438
-
439
clear_tail(d, opr_sz, simd_maxsz(desc));
440
}
441
442
--
443
2.20.1
444
445
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Currently only used by FMUL, but will shortly be used more.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210525010358.152808-52-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/sve.decode | 14 ++++++++++----
11
1 file changed, 10 insertions(+), 4 deletions(-)
12
13
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/sve.decode
16
+++ b/target/arm/sve.decode
17
@@ -XXX,XX +XXX,XX @@
18
&rri_esz rd rn imm esz
19
&rrri_esz rd rn rm imm esz
20
&rrr_esz rd rn rm esz
21
+&rrx_esz rd rn rm index esz
22
&rpr_esz rd pg rn esz
23
&rpr_s rd pg rn s
24
&rprr_s rd pg rn rm s
25
@@ -XXX,XX +XXX,XX @@
26
@rpri_scatter_store ....... msz:2 .. imm:5 ... pg:3 rn:5 rd:5 \
27
&rpri_scatter_store
28
29
+# Two registers and a scalar by N-bit index
30
+@rrx_3 ........ .. . .. rm:3 ...... rn:5 rd:5 \
31
+ &rrx_esz index=%index3_22_19
32
+@rrx_2 ........ .. . index:2 rm:3 ...... rn:5 rd:5 &rrx_esz
33
+@rrx_1 ........ .. . index:1 rm:4 ...... rn:5 rd:5 &rrx_esz
34
+
35
###########################################################################
36
# Instruction patterns. Grouped according to the SVE encodingindex.xhtml.
37
38
@@ -XXX,XX +XXX,XX @@ FMLA_zzxz 01100100 111 index:1 rm:4 00000 sub:1 rn:5 rd:5 \
39
### SVE FP Multiply Indexed Group
40
41
# SVE floating-point multiply (indexed)
42
-FMUL_zzx 01100100 0.1 .. rm:3 001000 rn:5 rd:5 \
43
- index=%index3_22_19 esz=1
44
-FMUL_zzx 01100100 101 index:2 rm:3 001000 rn:5 rd:5 esz=2
45
-FMUL_zzx 01100100 111 index:1 rm:4 001000 rn:5 rd:5 esz=3
46
+FMUL_zzx 01100100 0. 1 ..... 001000 ..... ..... @rrx_3 esz=1
47
+FMUL_zzx 01100100 10 1 ..... 001000 ..... ..... @rrx_2 esz=2
48
+FMUL_zzx 01100100 11 1 ..... 001000 ..... ..... @rrx_1 esz=3
49
50
### SVE FP Fast Reduction Group
51
52
--
53
2.20.1
54
55
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-54-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/sve.decode | 7 +++++++
9
target/arm/translate-sve.c | 30 ++++++++++++++++++++++++++++++
10
2 files changed, 37 insertions(+)
11
12
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/sve.decode
15
+++ b/target/arm/sve.decode
16
@@ -XXX,XX +XXX,XX @@ MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
17
DOT_zzzz 01000100 1 sz:1 0 rm:5 00000 u:1 rn:5 rd:5 \
18
ra=%reg_movprfx
19
20
+#### SVE Multiply - Indexed
21
+
22
# SVE integer dot product (indexed)
23
SDOT_zzxw_s 01000100 10 1 ..... 000000 ..... ..... @rrxr_2 esz=2
24
SDOT_zzxw_d 01000100 11 1 ..... 000000 ..... ..... @rrxr_1 esz=3
25
UDOT_zzxw_s 01000100 10 1 ..... 000001 ..... ..... @rrxr_2 esz=2
26
UDOT_zzxw_d 01000100 11 1 ..... 000001 ..... ..... @rrxr_1 esz=3
27
28
+# SVE2 integer multiply (indexed)
29
+MUL_zzx_h 01000100 0. 1 ..... 111110 ..... ..... @rrx_3 esz=1
30
+MUL_zzx_s 01000100 10 1 ..... 111110 ..... ..... @rrx_2 esz=2
31
+MUL_zzx_d 01000100 11 1 ..... 111110 ..... ..... @rrx_1 esz=3
32
+
33
# SVE floating-point complex add (predicated)
34
FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \
35
rn=%reg_movprfx
36
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-sve.c
39
+++ b/target/arm/translate-sve.c
40
@@ -XXX,XX +XXX,XX @@ static bool trans_DOT_zzzz(DisasContext *s, arg_DOT_zzzz *a)
41
return true;
42
}
43
44
+/*
45
+ * SVE Multiply - Indexed
46
+ */
47
+
48
static bool do_zzxz_ool(DisasContext *s, arg_rrxr_esz *a,
49
gen_helper_gvec_4 *fn)
50
{
51
@@ -XXX,XX +XXX,XX @@ DO_RRXR(trans_UDOT_zzxw_d, gen_helper_gvec_udot_idx_h)
52
53
#undef DO_RRXR
54
55
+static bool do_sve2_zzz_data(DisasContext *s, int rd, int rn, int rm, int data,
56
+ gen_helper_gvec_3 *fn)
57
+{
58
+ if (fn == NULL || !dc_isar_feature(aa64_sve2, s)) {
59
+ return false;
60
+ }
61
+ if (sve_access_check(s)) {
62
+ unsigned vsz = vec_full_reg_size(s);
63
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
64
+ vec_full_reg_offset(s, rn),
65
+ vec_full_reg_offset(s, rm),
66
+ vsz, vsz, data, fn);
67
+ }
68
+ return true;
69
+}
70
+
71
+#define DO_SVE2_RRX(NAME, FUNC) \
72
+ static bool NAME(DisasContext *s, arg_rrx_esz *a) \
73
+ { return do_sve2_zzz_data(s, a->rd, a->rn, a->rm, a->index, FUNC); }
74
+
75
+DO_SVE2_RRX(trans_MUL_zzx_h, gen_helper_gvec_mul_idx_h)
76
+DO_SVE2_RRX(trans_MUL_zzx_s, gen_helper_gvec_mul_idx_s)
77
+DO_SVE2_RRX(trans_MUL_zzx_d, gen_helper_gvec_mul_idx_d)
78
+
79
+#undef DO_SVE2_RRX
80
+
81
/*
82
*** SVE Floating Point Multiply-Add Indexed Group
83
*/
84
--
85
2.20.1
86
87
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-55-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/sve.decode | 8 ++++++++
9
target/arm/translate-sve.c | 31 +++++++++++++++++++++++++++++++
10
2 files changed, 39 insertions(+)
11
12
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/sve.decode
15
+++ b/target/arm/sve.decode
16
@@ -XXX,XX +XXX,XX @@ SDOT_zzxw_d 01000100 11 1 ..... 000000 ..... ..... @rrxr_1 esz=3
17
UDOT_zzxw_s 01000100 10 1 ..... 000001 ..... ..... @rrxr_2 esz=2
18
UDOT_zzxw_d 01000100 11 1 ..... 000001 ..... ..... @rrxr_1 esz=3
19
20
+# SVE2 integer multiply-add (indexed)
21
+MLA_zzxz_h 01000100 0. 1 ..... 000010 ..... ..... @rrxr_3 esz=1
22
+MLA_zzxz_s 01000100 10 1 ..... 000010 ..... ..... @rrxr_2 esz=2
23
+MLA_zzxz_d 01000100 11 1 ..... 000010 ..... ..... @rrxr_1 esz=3
24
+MLS_zzxz_h 01000100 0. 1 ..... 000011 ..... ..... @rrxr_3 esz=1
25
+MLS_zzxz_s 01000100 10 1 ..... 000011 ..... ..... @rrxr_2 esz=2
26
+MLS_zzxz_d 01000100 11 1 ..... 000011 ..... ..... @rrxr_1 esz=3
27
+
28
# SVE2 integer multiply (indexed)
29
MUL_zzx_h 01000100 0. 1 ..... 111110 ..... ..... @rrx_3 esz=1
30
MUL_zzx_s 01000100 10 1 ..... 111110 ..... ..... @rrx_2 esz=2
31
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate-sve.c
34
+++ b/target/arm/translate-sve.c
35
@@ -XXX,XX +XXX,XX @@ DO_SVE2_RRX(trans_MUL_zzx_d, gen_helper_gvec_mul_idx_d)
36
37
#undef DO_SVE2_RRX
38
39
+static bool do_sve2_zzzz_data(DisasContext *s, int rd, int rn, int rm, int ra,
40
+ int data, gen_helper_gvec_4 *fn)
41
+{
42
+ if (fn == NULL || !dc_isar_feature(aa64_sve2, s)) {
43
+ return false;
44
+ }
45
+ if (sve_access_check(s)) {
46
+ unsigned vsz = vec_full_reg_size(s);
47
+ tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
48
+ vec_full_reg_offset(s, rn),
49
+ vec_full_reg_offset(s, rm),
50
+ vec_full_reg_offset(s, ra),
51
+ vsz, vsz, data, fn);
52
+ }
53
+ return true;
54
+}
55
+
56
+#define DO_SVE2_RRXR(NAME, FUNC) \
57
+ static bool NAME(DisasContext *s, arg_rrxr_esz *a) \
58
+ { return do_sve2_zzzz_data(s, a->rd, a->rn, a->rm, a->ra, a->index, FUNC); }
59
+
60
+DO_SVE2_RRXR(trans_MLA_zzxz_h, gen_helper_gvec_mla_idx_h)
61
+DO_SVE2_RRXR(trans_MLA_zzxz_s, gen_helper_gvec_mla_idx_s)
62
+DO_SVE2_RRXR(trans_MLA_zzxz_d, gen_helper_gvec_mla_idx_d)
63
+
64
+DO_SVE2_RRXR(trans_MLS_zzxz_h, gen_helper_gvec_mls_idx_h)
65
+DO_SVE2_RRXR(trans_MLS_zzxz_s, gen_helper_gvec_mls_idx_s)
66
+DO_SVE2_RRXR(trans_MLS_zzxz_d, gen_helper_gvec_mls_idx_d)
67
+
68
+#undef DO_SVE2_RRXR
69
+
70
/*
71
*** SVE Floating Point Multiply-Add Indexed Group
72
*/
73
--
74
2.20.1
75
76
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-56-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 14 ++++++++++++++
9
target/arm/sve.decode | 8 ++++++++
10
target/arm/sve_helper.c | 36 ++++++++++++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 8 ++++++++
12
4 files changed, 66 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_sqrdcmlah_zzzz_d, TCG_CALL_NO_RWG,
19
20
DEF_HELPER_FLAGS_6(fmmla_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, ptr, i32)
21
DEF_HELPER_FLAGS_6(fmmla_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, ptr, i32)
22
+
23
+DEF_HELPER_FLAGS_5(sve2_sqrdmlah_idx_h, TCG_CALL_NO_RWG,
24
+ void, ptr, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_5(sve2_sqrdmlah_idx_s, TCG_CALL_NO_RWG,
26
+ void, ptr, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_5(sve2_sqrdmlah_idx_d, TCG_CALL_NO_RWG,
28
+ void, ptr, ptr, ptr, ptr, i32)
29
+
30
+DEF_HELPER_FLAGS_5(sve2_sqrdmlsh_idx_h, TCG_CALL_NO_RWG,
31
+ void, ptr, ptr, ptr, ptr, i32)
32
+DEF_HELPER_FLAGS_5(sve2_sqrdmlsh_idx_s, TCG_CALL_NO_RWG,
33
+ void, ptr, ptr, ptr, ptr, i32)
34
+DEF_HELPER_FLAGS_5(sve2_sqrdmlsh_idx_d, TCG_CALL_NO_RWG,
35
+ void, ptr, ptr, ptr, ptr, i32)
36
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/sve.decode
39
+++ b/target/arm/sve.decode
40
@@ -XXX,XX +XXX,XX @@ MLS_zzxz_h 01000100 0. 1 ..... 000011 ..... ..... @rrxr_3 esz=1
41
MLS_zzxz_s 01000100 10 1 ..... 000011 ..... ..... @rrxr_2 esz=2
42
MLS_zzxz_d 01000100 11 1 ..... 000011 ..... ..... @rrxr_1 esz=3
43
44
+# SVE2 saturating multiply-add high (indexed)
45
+SQRDMLAH_zzxz_h 01000100 0. 1 ..... 000100 ..... ..... @rrxr_3 esz=1
46
+SQRDMLAH_zzxz_s 01000100 10 1 ..... 000100 ..... ..... @rrxr_2 esz=2
47
+SQRDMLAH_zzxz_d 01000100 11 1 ..... 000100 ..... ..... @rrxr_1 esz=3
48
+SQRDMLSH_zzxz_h 01000100 0. 1 ..... 000101 ..... ..... @rrxr_3 esz=1
49
+SQRDMLSH_zzxz_s 01000100 10 1 ..... 000101 ..... ..... @rrxr_2 esz=2
50
+SQRDMLSH_zzxz_d 01000100 11 1 ..... 000101 ..... ..... @rrxr_1 esz=3
51
+
52
# SVE2 integer multiply (indexed)
53
MUL_zzx_h 01000100 0. 1 ..... 111110 ..... ..... @rrx_3 esz=1
54
MUL_zzx_s 01000100 10 1 ..... 111110 ..... ..... @rrx_2 esz=2
55
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/sve_helper.c
58
+++ b/target/arm/sve_helper.c
59
@@ -XXX,XX +XXX,XX @@ DO_CMLA_FUNC(sve2_sqrdcmlah_zzzz_d, int64_t, , DO_SQRDMLAH_D)
60
#undef DO_SQRDMLAH_S
61
#undef DO_SQRDMLAH_D
62
63
+#define DO_ZZXZ(NAME, TYPE, H, OP) \
64
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, uint32_t desc) \
65
+{ \
66
+ intptr_t oprsz = simd_oprsz(desc), segment = 16 / sizeof(TYPE); \
67
+ intptr_t i, j, idx = simd_data(desc); \
68
+ TYPE *d = vd, *a = va, *n = vn, *m = (TYPE *)vm + H(idx); \
69
+ for (i = 0; i < oprsz / sizeof(TYPE); i += segment) { \
70
+ TYPE mm = m[i]; \
71
+ for (j = 0; j < segment; j++) { \
72
+ d[i + j] = OP(n[i + j], mm, a[i + j]); \
73
+ } \
74
+ } \
75
+}
76
+
77
+#define DO_SQRDMLAH_H(N, M, A) \
78
+ ({ uint32_t discard; do_sqrdmlah_h(N, M, A, false, true, &discard); })
79
+#define DO_SQRDMLAH_S(N, M, A) \
80
+ ({ uint32_t discard; do_sqrdmlah_s(N, M, A, false, true, &discard); })
81
+#define DO_SQRDMLAH_D(N, M, A) do_sqrdmlah_d(N, M, A, false, true)
82
+
83
+DO_ZZXZ(sve2_sqrdmlah_idx_h, int16_t, H2, DO_SQRDMLAH_H)
84
+DO_ZZXZ(sve2_sqrdmlah_idx_s, int32_t, H4, DO_SQRDMLAH_S)
85
+DO_ZZXZ(sve2_sqrdmlah_idx_d, int64_t, , DO_SQRDMLAH_D)
86
+
87
+#define DO_SQRDMLSH_H(N, M, A) \
88
+ ({ uint32_t discard; do_sqrdmlah_h(N, M, A, true, true, &discard); })
89
+#define DO_SQRDMLSH_S(N, M, A) \
90
+ ({ uint32_t discard; do_sqrdmlah_s(N, M, A, true, true, &discard); })
91
+#define DO_SQRDMLSH_D(N, M, A) do_sqrdmlah_d(N, M, A, true, true)
92
+
93
+DO_ZZXZ(sve2_sqrdmlsh_idx_h, int16_t, H2, DO_SQRDMLSH_H)
94
+DO_ZZXZ(sve2_sqrdmlsh_idx_s, int32_t, H4, DO_SQRDMLSH_S)
95
+DO_ZZXZ(sve2_sqrdmlsh_idx_d, int64_t, , DO_SQRDMLSH_D)
96
+
97
+#undef DO_ZZXZ
98
+
99
#define DO_BITPERM(NAME, TYPE, OP) \
100
void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
101
{ \
102
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/translate-sve.c
105
+++ b/target/arm/translate-sve.c
106
@@ -XXX,XX +XXX,XX @@ DO_SVE2_RRXR(trans_MLS_zzxz_h, gen_helper_gvec_mls_idx_h)
107
DO_SVE2_RRXR(trans_MLS_zzxz_s, gen_helper_gvec_mls_idx_s)
108
DO_SVE2_RRXR(trans_MLS_zzxz_d, gen_helper_gvec_mls_idx_d)
109
110
+DO_SVE2_RRXR(trans_SQRDMLAH_zzxz_h, gen_helper_sve2_sqrdmlah_idx_h)
111
+DO_SVE2_RRXR(trans_SQRDMLAH_zzxz_s, gen_helper_sve2_sqrdmlah_idx_s)
112
+DO_SVE2_RRXR(trans_SQRDMLAH_zzxz_d, gen_helper_sve2_sqrdmlah_idx_d)
113
+
114
+DO_SVE2_RRXR(trans_SQRDMLSH_zzxz_h, gen_helper_sve2_sqrdmlsh_idx_h)
115
+DO_SVE2_RRXR(trans_SQRDMLSH_zzxz_s, gen_helper_sve2_sqrdmlsh_idx_s)
116
+DO_SVE2_RRXR(trans_SQRDMLSH_zzxz_d, gen_helper_sve2_sqrdmlsh_idx_d)
117
+
118
#undef DO_SVE2_RRXR
119
120
/*
121
--
122
2.20.1
123
124
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210525010358.152808-57-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 9 +++++++++
9
target/arm/sve.decode | 18 ++++++++++++++++++
10
target/arm/sve_helper.c | 30 ++++++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 19 +++++++++++++++++++
12
4 files changed, 76 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_sqrdmlsh_idx_s, TCG_CALL_NO_RWG,
19
void, ptr, ptr, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_5(sve2_sqrdmlsh_idx_d, TCG_CALL_NO_RWG,
21
void, ptr, ptr, ptr, ptr, i32)
22
+
23
+DEF_HELPER_FLAGS_5(sve2_sqdmlal_idx_s, TCG_CALL_NO_RWG,
24
+ void, ptr, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_5(sve2_sqdmlal_idx_d, TCG_CALL_NO_RWG,
26
+ void, ptr, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_5(sve2_sqdmlsl_idx_s, TCG_CALL_NO_RWG,
28
+ void, ptr, ptr, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_5(sve2_sqdmlsl_idx_d, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, i32)
31
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/sve.decode
34
+++ b/target/arm/sve.decode
35
@@ -XXX,XX +XXX,XX @@
36
%size_23 23:2
37
%dtype_23_13 23:2 13:2
38
%index3_22_19 22:1 19:2
39
+%index3_19_11 19:2 11:1
40
+%index2_20_11 20:1 11:1
41
42
# A combination of tsz:imm3 -- extract esize.
43
%tszimm_esz 22:2 5:5 !function=tszimm_esz
44
@@ -XXX,XX +XXX,XX @@
45
@rrxr_1 ........ .. . index:1 rm:4 ...... rn:5 rd:5 \
46
&rrxr_esz ra=%reg_movprfx
47
48
+# Three registers and a scalar by N-bit index, alternate
49
+@rrxr_3a ........ .. ... rm:3 ...... rn:5 rd:5 \
50
+ &rrxr_esz ra=%reg_movprfx index=%index3_19_11
51
+@rrxr_2a ........ .. .. rm:4 ...... rn:5 rd:5 \
52
+ &rrxr_esz ra=%reg_movprfx index=%index2_20_11
53
+
54
###########################################################################
55
# Instruction patterns. Grouped according to the SVE encodingindex.xhtml.
56
57
@@ -XXX,XX +XXX,XX @@ SQRDMLSH_zzxz_h 01000100 0. 1 ..... 000101 ..... ..... @rrxr_3 esz=1
58
SQRDMLSH_zzxz_s 01000100 10 1 ..... 000101 ..... ..... @rrxr_2 esz=2
59
SQRDMLSH_zzxz_d 01000100 11 1 ..... 000101 ..... ..... @rrxr_1 esz=3
60
61
+# SVE2 saturating multiply-add (indexed)
62
+SQDMLALB_zzxw_s 01000100 10 1 ..... 0010.0 ..... ..... @rrxr_3a esz=2
63
+SQDMLALB_zzxw_d 01000100 11 1 ..... 0010.0 ..... ..... @rrxr_2a esz=3
64
+SQDMLALT_zzxw_s 01000100 10 1 ..... 0010.1 ..... ..... @rrxr_3a esz=2
65
+SQDMLALT_zzxw_d 01000100 11 1 ..... 0010.1 ..... ..... @rrxr_2a esz=3
66
+SQDMLSLB_zzxw_s 01000100 10 1 ..... 0011.0 ..... ..... @rrxr_3a esz=2
67
+SQDMLSLB_zzxw_d 01000100 11 1 ..... 0011.0 ..... ..... @rrxr_2a esz=3
68
+SQDMLSLT_zzxw_s 01000100 10 1 ..... 0011.1 ..... ..... @rrxr_3a esz=2
69
+SQDMLSLT_zzxw_d 01000100 11 1 ..... 0011.1 ..... ..... @rrxr_2a esz=3
70
+
71
# SVE2 integer multiply (indexed)
72
MUL_zzx_h 01000100 0. 1 ..... 111110 ..... ..... @rrx_3 esz=1
73
MUL_zzx_s 01000100 10 1 ..... 111110 ..... ..... @rrx_2 esz=2
74
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/sve_helper.c
77
+++ b/target/arm/sve_helper.c
78
@@ -XXX,XX +XXX,XX @@ DO_ZZXZ(sve2_sqrdmlsh_idx_d, int64_t, , DO_SQRDMLSH_D)
79
80
#undef DO_ZZXZ
81
82
+#define DO_ZZXW(NAME, TYPEW, TYPEN, HW, HN, OP) \
83
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, uint32_t desc) \
84
+{ \
85
+ intptr_t i, j, oprsz = simd_oprsz(desc); \
86
+ intptr_t sel = extract32(desc, SIMD_DATA_SHIFT, 1) * sizeof(TYPEN); \
87
+ intptr_t idx = extract32(desc, SIMD_DATA_SHIFT + 1, 3) * sizeof(TYPEN); \
88
+ for (i = 0; i < oprsz; i += 16) { \
89
+ TYPEW mm = *(TYPEN *)(vm + HN(i + idx)); \
90
+ for (j = 0; j < 16; j += sizeof(TYPEW)) { \
91
+ TYPEW nn = *(TYPEN *)(vn + HN(i + j + sel)); \
92
+ TYPEW aa = *(TYPEW *)(va + HW(i + j)); \
93
+ *(TYPEW *)(vd + HW(i + j)) = OP(nn, mm, aa); \
94
+ } \
95
+ } \
96
+}
97
+
98
+#define DO_SQDMLAL_S(N, M, A) DO_SQADD_S(A, do_sqdmull_s(N, M))
99
+#define DO_SQDMLAL_D(N, M, A) do_sqadd_d(A, do_sqdmull_d(N, M))
100
+
101
+DO_ZZXW(sve2_sqdmlal_idx_s, int32_t, int16_t, H1_4, H1_2, DO_SQDMLAL_S)
102
+DO_ZZXW(sve2_sqdmlal_idx_d, int64_t, int32_t, , H1_4, DO_SQDMLAL_D)
103
+
104
+#define DO_SQDMLSL_S(N, M, A) DO_SQSUB_S(A, do_sqdmull_s(N, M))
105
+#define DO_SQDMLSL_D(N, M, A) do_sqsub_d(A, do_sqdmull_d(N, M))
106
+
107
+DO_ZZXW(sve2_sqdmlsl_idx_s, int32_t, int16_t, H1_4, H1_2, DO_SQDMLSL_S)
108
+DO_ZZXW(sve2_sqdmlsl_idx_d, int64_t, int32_t, , H1_4, DO_SQDMLSL_D)
109
+
110
+#undef DO_ZZXW
111
+
112
#define DO_BITPERM(NAME, TYPE, OP) \
113
void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc) \
114
{ \
115
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
116
index XXXXXXX..XXXXXXX 100644
117
--- a/target/arm/translate-sve.c
118
+++ b/target/arm/translate-sve.c
119
@@ -XXX,XX +XXX,XX @@ DO_SVE2_RRXR(trans_SQRDMLSH_zzxz_d, gen_helper_sve2_sqrdmlsh_idx_d)
120
121
#undef DO_SVE2_RRXR
122
123
+#define DO_SVE2_RRXR_TB(NAME, FUNC, TOP) \
124
+ static bool NAME(DisasContext *s, arg_rrxr_esz *a) \
125
+ { \
126
+ return do_sve2_zzzz_data(s, a->rd, a->rn, a->rm, a->rd, \
127
+ (a->index << 1) | TOP, FUNC); \
128
+ }
129
+
130
+DO_SVE2_RRXR_TB(trans_SQDMLALB_zzxw_s, gen_helper_sve2_sqdmlal_idx_s, false)
131
+DO_SVE2_RRXR_TB(trans_SQDMLALB_zzxw_d, gen_helper_sve2_sqdmlal_idx_d, false)
132
+DO_SVE2_RRXR_TB(trans_SQDMLALT_zzxw_s, gen_helper_sve2_sqdmlal_idx_s, true)
133
+DO_SVE2_RRXR_TB(trans_SQDMLALT_zzxw_d, gen_helper_sve2_sqdmlal_idx_d, true)
134
+
135
+DO_SVE2_RRXR_TB(trans_SQDMLSLB_zzxw_s, gen_helper_sve2_sqdmlsl_idx_s, false)
136
+DO_SVE2_RRXR_TB(trans_SQDMLSLB_zzxw_d, gen_helper_sve2_sqdmlsl_idx_d, false)
137
+DO_SVE2_RRXR_TB(trans_SQDMLSLT_zzxw_s, gen_helper_sve2_sqdmlsl_idx_s, true)
138
+DO_SVE2_RRXR_TB(trans_SQDMLSLT_zzxw_d, gen_helper_sve2_sqdmlsl_idx_d, true)
139
+
140
+#undef DO_SVE2_RRXR_TB
141
+
142
/*
143
*** SVE Floating Point Multiply-Add Indexed Group
144
*/
145
--
146
2.20.1
147
148
diff view generated by jsdifflib