1
The following changes since commit b6d32a06fc0984e537091cba08f2e1ed9f775d74:
1
First arm pullreq of the cycle; this is mostly my softfloat NaN
2
handling series. (Lots more in my to-review queue, but I don't
3
like pullreqs growing too close to a hundred patches at a time :-))
2
4
3
Merge tag 'pull-trivial-patches' of https://gitlab.com/mjt0k/qemu into staging (2024-06-30 16:12:24 -0700)
5
thanks
6
-- PMM
7
8
The following changes since commit 97f2796a3736ed37a1b85dc1c76a6c45b829dd17:
9
10
Open 10.0 development tree (2024-12-10 17:41:17 +0000)
4
11
5
are available in the Git repository at:
12
are available in the Git repository at:
6
13
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240701
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20241211
8
15
9
for you to fetch changes up to 58c782de557beb496bfb4c5ade721bbbd2480c72:
16
for you to fetch changes up to 1abe28d519239eea5cf9620bb13149423e5665f8:
10
17
11
tests/qtest: Ensure STM32L4x5 EXTI state is correct at the end of QTests (2024-07-01 15:40:54 +0100)
18
MAINTAINERS: Add correct email address for Vikram Garhwal (2024-12-11 15:31:09 +0000)
12
19
13
----------------------------------------------------------------
20
----------------------------------------------------------------
14
target-arm queue:
21
target-arm queue:
15
* tests/avocado: update firmware for sbsa-ref and use all cores
22
* hw/net/lan9118: Extract PHY model, reuse with imx_fec, fix bugs
16
* hw/arm/smmu-common: Replace smmu_iommu_mr with smmu_find_sdev
23
* fpu: Make muladd NaN handling runtime-selected, not compile-time
17
* arm: Fix VCMLA Dd, Dn, Dm[idx]
24
* fpu: Make default NaN pattern runtime-selected, not compile-time
18
* arm: Fix SQDMULH (by element) with Q=0
25
* fpu: Minor NaN-related cleanups
19
* arm: Fix FJCVTZS vs flush-to-zero
26
* MAINTAINERS: email address updates
20
* arm: More conversion of A64 AdvSIMD to decodetree
21
* arm: Enable FEAT_Debugv8p8 for -cpu max
22
* MAINTAINERS: Update family name for Patrick Leis
23
* hw/arm/xilinx_zynq: Add boot-mode property
24
* docs/system/arm: Add a doc for zynq board
25
* hw/misc: In STM32L4x5 EXTI, correct configurable interrupts
26
* tests/qtest: fix minor issues in STM32L4x5 tests
27
27
28
----------------------------------------------------------------
28
----------------------------------------------------------------
29
Gustavo Romero (3):
29
Bernhard Beschow (5):
30
target/arm: Fix indentation
30
hw/net/lan9118: Extract lan9118_phy
31
target/arm: Move initialization of debug ID registers
31
hw/net/lan9118_phy: Reuse in imx_fec and consolidate implementations
32
target/arm: Enable FEAT_Debugv8p8 for -cpu max
32
hw/net/lan9118_phy: Fix off-by-one error in MII_ANLPAR register
33
hw/net/lan9118_phy: Reuse MII constants
34
hw/net/lan9118_phy: Add missing 100 mbps full duplex advertisement
33
35
34
Inès Varhol (3):
36
Leif Lindholm (1):
35
tests/qtest: Fix STM32L4x5 SYSCFG irq line 15 state assumption
37
MAINTAINERS: update email address for Leif Lindholm
36
hw/misc: In STM32L4x5 EXTI, correct configurable interrupts
37
tests/qtest: Ensure STM32L4x5 EXTI state is correct at the end of QTests
38
38
39
Marcin Juszkiewicz (2):
39
Peter Maydell (54):
40
tests/avocado: update firmware for sbsa-ref
40
fpu: handle raising Invalid for infzero in pick_nan_muladd
41
tests/avocado: use default amount of cores on sbsa-ref
41
fpu: Check for default_nan_mode before calling pickNaNMulAdd
42
softfloat: Allow runtime choice of inf * 0 + NaN result
43
tests/fp: Explicitly set inf-zero-nan rule
44
target/arm: Set FloatInfZeroNaNRule explicitly
45
target/s390: Set FloatInfZeroNaNRule explicitly
46
target/ppc: Set FloatInfZeroNaNRule explicitly
47
target/mips: Set FloatInfZeroNaNRule explicitly
48
target/sparc: Set FloatInfZeroNaNRule explicitly
49
target/xtensa: Set FloatInfZeroNaNRule explicitly
50
target/x86: Set FloatInfZeroNaNRule explicitly
51
target/loongarch: Set FloatInfZeroNaNRule explicitly
52
target/hppa: Set FloatInfZeroNaNRule explicitly
53
softfloat: Pass have_snan to pickNaNMulAdd
54
softfloat: Allow runtime choice of NaN propagation for muladd
55
tests/fp: Explicitly set 3-NaN propagation rule
56
target/arm: Set Float3NaNPropRule explicitly
57
target/loongarch: Set Float3NaNPropRule explicitly
58
target/ppc: Set Float3NaNPropRule explicitly
59
target/s390x: Set Float3NaNPropRule explicitly
60
target/sparc: Set Float3NaNPropRule explicitly
61
target/mips: Set Float3NaNPropRule explicitly
62
target/xtensa: Set Float3NaNPropRule explicitly
63
target/i386: Set Float3NaNPropRule explicitly
64
target/hppa: Set Float3NaNPropRule explicitly
65
fpu: Remove use_first_nan field from float_status
66
target/m68k: Don't pass NULL float_status to floatx80_default_nan()
67
softfloat: Create floatx80 default NaN from parts64_default_nan
68
target/loongarch: Use normal float_status in fclass_s and fclass_d helpers
69
target/m68k: In frem helper, initialize local float_status from env->fp_status
70
target/m68k: Init local float_status from env fp_status in gdb get/set reg
71
target/sparc: Initialize local scratch float_status from env->fp_status
72
target/ppc: Use env->fp_status in helper_compute_fprf functions
73
fpu: Allow runtime choice of default NaN value
74
tests/fp: Set default NaN pattern explicitly
75
target/microblaze: Set default NaN pattern explicitly
76
target/i386: Set default NaN pattern explicitly
77
target/hppa: Set default NaN pattern explicitly
78
target/alpha: Set default NaN pattern explicitly
79
target/arm: Set default NaN pattern explicitly
80
target/loongarch: Set default NaN pattern explicitly
81
target/m68k: Set default NaN pattern explicitly
82
target/mips: Set default NaN pattern explicitly
83
target/openrisc: Set default NaN pattern explicitly
84
target/ppc: Set default NaN pattern explicitly
85
target/sh4: Set default NaN pattern explicitly
86
target/rx: Set default NaN pattern explicitly
87
target/s390x: Set default NaN pattern explicitly
88
target/sparc: Set default NaN pattern explicitly
89
target/xtensa: Set default NaN pattern explicitly
90
target/hexagon: Set default NaN pattern explicitly
91
target/riscv: Set default NaN pattern explicitly
92
target/tricore: Set default NaN pattern explicitly
93
fpu: Remove default handling for dnan_pattern
42
94
43
Nicolin Chen (1):
95
Richard Henderson (11):
44
hw/arm/smmu-common: Replace smmu_iommu_mr with smmu_find_sdev
96
target/arm: Copy entire float_status in is_ebf
97
softfloat: Inline pickNaNMulAdd
98
softfloat: Use goto for default nan case in pick_nan_muladd
99
softfloat: Remove which from parts_pick_nan_muladd
100
softfloat: Pad array size in pick_nan_muladd
101
softfloat: Move propagateFloatx80NaN to softfloat.c
102
softfloat: Use parts_pick_nan in propagateFloatx80NaN
103
softfloat: Inline pickNaN
104
softfloat: Share code between parts_pick_nan cases
105
softfloat: Sink frac_cmp in parts_pick_nan until needed
106
softfloat: Replace WHICH with RET in parts_pick_nan
45
107
46
Patrick Leis (1):
108
Vikram Garhwal (1):
47
MAINTAINERS: Update my family name
109
MAINTAINERS: Add correct email address for Vikram Garhwal
48
110
49
Rayhan Faizel (3):
111
MAINTAINERS | 4 +-
50
hw/nvram: Add BCM2835 OTP device
112
include/fpu/softfloat-helpers.h | 38 +++-
51
hw/arm: Connect OTP device to BCM2835
113
include/fpu/softfloat-types.h | 89 +++++++-
52
hw/misc: Implement mailbox properties for customer OTP and device specific private keys
114
include/hw/net/imx_fec.h | 9 +-
53
115
include/hw/net/lan9118_phy.h | 37 ++++
54
Richard Henderson (13):
116
include/hw/net/mii.h | 6 +
55
target/arm: Fix VCMLA Dd, Dn, Dm[idx]
117
target/mips/fpu_helper.h | 20 ++
56
target/arm: Fix SQDMULH (by element) with Q=0
118
target/sparc/helper.h | 4 +-
57
target/arm: Fix FJCVTZS vs flush-to-zero
119
fpu/softfloat.c | 19 ++
58
target/arm: Convert SQRDMLAH, SQRDMLSH to decodetree
120
hw/net/imx_fec.c | 146 ++------------
59
target/arm: Convert SDOT, UDOT to decodetree
121
hw/net/lan9118.c | 137 ++-----------
60
target/arm: Convert SUDOT, USDOT to decodetree
122
hw/net/lan9118_phy.c | 222 ++++++++++++++++++++
61
target/arm: Convert BFDOT to decodetree
123
linux-user/arm/nwfpe/fpa11.c | 5 +
62
target/arm: Convert BFMLALB, BFMLALT to decodetree
124
target/alpha/cpu.c | 2 +
63
target/arm: Convert BFMMLA, SMMLA, UMMLA, USMMLA to decodetree
125
target/arm/cpu.c | 10 +
64
target/arm: Add data argument to do_fp3_vector
126
target/arm/tcg/vec_helper.c | 20 +-
65
target/arm: Convert FCADD to decodetree
127
target/hexagon/cpu.c | 2 +
66
target/arm: Convert FCMLA to decodetree
128
target/hppa/fpu_helper.c | 12 ++
67
target/arm: Delete dead code from disas_simd_indexed
129
target/i386/tcg/fpu_helper.c | 12 ++
68
130
target/loongarch/tcg/fpu_helper.c | 14 +-
69
Sai Pavan Boddu (3):
131
target/m68k/cpu.c | 14 +-
70
hw/misc/zynq_slcr: Add boot-mode property
132
target/m68k/fpu_helper.c | 6 +-
71
hw/arm/xilinx_zynq: Add boot-mode property
133
target/m68k/helper.c | 6 +-
72
docs/system/arm: Add a doc for zynq board
134
target/microblaze/cpu.c | 2 +
73
135
target/mips/msa.c | 10 +
74
MAINTAINERS | 3 +-
136
target/openrisc/cpu.c | 2 +
75
docs/system/arm/emulation.rst | 1 +
137
target/ppc/cpu_init.c | 19 ++
76
docs/system/arm/xlnx-zynq.rst | 47 ++
138
target/ppc/fpu_helper.c | 3 +-
77
docs/system/target-arm.rst | 1 +
139
target/riscv/cpu.c | 2 +
78
include/hw/arm/bcm2835_peripherals.h | 3 +-
140
target/rx/cpu.c | 2 +
79
include/hw/arm/raspberrypi-fw-defs.h | 2 +
141
target/s390x/cpu.c | 5 +
80
include/hw/arm/smmu-common.h | 4 +-
142
target/sh4/cpu.c | 2 +
81
include/hw/misc/bcm2835_property.h | 2 +
143
target/sparc/cpu.c | 6 +
82
include/hw/misc/stm32l4x5_exti.h | 2 +
144
target/sparc/fop_helper.c | 8 +-
83
include/hw/nvram/bcm2835_otp.h | 68 +++
145
target/sparc/translate.c | 4 +-
84
target/arm/cpu.h | 2 +
146
target/tricore/helper.c | 2 +
85
target/arm/helper.h | 10 +
147
target/xtensa/cpu.c | 4 +
86
target/arm/tcg/a64.decode | 43 ++
148
target/xtensa/fpu_helper.c | 3 +-
87
hw/arm/bcm2835_peripherals.c | 15 +-
149
tests/fp/fp-bench.c | 7 +
88
hw/arm/smmu-common.c | 8 +-
150
tests/fp/fp-test-log2.c | 1 +
89
hw/arm/smmuv3.c | 12 +-
151
tests/fp/fp-test.c | 7 +
90
hw/arm/xilinx_zynq.c | 31 ++
152
fpu/softfloat-parts.c.inc | 152 +++++++++++---
91
hw/misc/bcm2835_property.c | 87 ++++
153
fpu/softfloat-specialize.c.inc | 412 ++------------------------------------
92
hw/misc/stm32l4x5_exti.c | 28 +-
154
.mailmap | 5 +-
93
hw/misc/zynq_slcr.c | 22 +-
155
hw/net/Kconfig | 5 +
94
hw/nvram/bcm2835_otp.c | 187 +++++++
156
hw/net/meson.build | 1 +
95
target/arm/tcg/cpu32.c | 35 +-
157
hw/net/trace-events | 10 +-
96
target/arm/tcg/cpu64.c | 4 +-
158
47 files changed, 778 insertions(+), 730 deletions(-)
97
target/arm/tcg/translate-a64.c | 808 ++++++++++---------------------
159
create mode 100644 include/hw/net/lan9118_phy.h
98
target/arm/tcg/vec_helper.c | 100 +++-
160
create mode 100644 hw/net/lan9118_phy.c
99
target/arm/vfp_helper.c | 18 +-
100
tests/qtest/stm32l4x5_exti-test.c | 8 +
101
tests/qtest/stm32l4x5_syscfg-test.c | 16 +-
102
tests/tcg/aarch64/test-2375.c | 21 +
103
hw/nvram/meson.build | 1 +
104
tests/avocado/machine_aarch64_sbsaref.py | 16 +-
105
tests/tcg/aarch64/Makefile.target | 3 +-
106
32 files changed, 967 insertions(+), 641 deletions(-)
107
create mode 100644 docs/system/arm/xlnx-zynq.rst
108
create mode 100644 include/hw/nvram/bcm2835_otp.h
109
create mode 100644 hw/nvram/bcm2835_otp.c
110
create mode 100644 tests/tcg/aarch64/test-2375.c
111
diff view generated by jsdifflib
1
From: Rayhan Faizel <rayhan.faizel@gmail.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
The OTP device registers are currently stubbed. For now, the device
3
A very similar implementation of the same device exists in imx_fec. Prepare for
4
houses the OTP rows which will be accessed directly by other peripherals.
4
a common implementation by extracting a device model into its own files.
5
5
6
Signed-off-by: Rayhan Faizel <rayhan.faizel@gmail.com>
6
Some migration state has been moved into the new device model which breaks
7
migration compatibility for the following machines:
8
* smdkc210
9
* realview-*
10
* vexpress-*
11
* kzm
12
* mps2-*
13
14
While breaking migration ABI, fix the size of the MII registers to be 16 bit,
15
as defined by IEEE 802.3u.
16
17
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
18
Tested-by: Guenter Roeck <linux@roeck-us.net>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Message-id: 20241102125724.532843-2-shentey@gmail.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
22
---
10
include/hw/nvram/bcm2835_otp.h | 68 ++++++++++++
23
include/hw/net/lan9118_phy.h | 37 ++++++++
11
hw/nvram/bcm2835_otp.c | 187 +++++++++++++++++++++++++++++++++
24
hw/net/lan9118.c | 137 +++++-----------------------
12
hw/nvram/meson.build | 1 +
25
hw/net/lan9118_phy.c | 169 +++++++++++++++++++++++++++++++++++
13
3 files changed, 256 insertions(+)
26
hw/net/Kconfig | 4 +
14
create mode 100644 include/hw/nvram/bcm2835_otp.h
27
hw/net/meson.build | 1 +
15
create mode 100644 hw/nvram/bcm2835_otp.c
28
5 files changed, 233 insertions(+), 115 deletions(-)
29
create mode 100644 include/hw/net/lan9118_phy.h
30
create mode 100644 hw/net/lan9118_phy.c
16
31
17
diff --git a/include/hw/nvram/bcm2835_otp.h b/include/hw/nvram/bcm2835_otp.h
32
diff --git a/include/hw/net/lan9118_phy.h b/include/hw/net/lan9118_phy.h
18
new file mode 100644
33
new file mode 100644
19
index XXXXXXX..XXXXXXX
34
index XXXXXXX..XXXXXXX
20
--- /dev/null
35
--- /dev/null
21
+++ b/include/hw/nvram/bcm2835_otp.h
36
+++ b/include/hw/net/lan9118_phy.h
22
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
23
+/*
38
+/*
24
+ * BCM2835 One-Time Programmable (OTP) Memory
39
+ * SMSC LAN9118 PHY emulation
25
+ *
40
+ *
26
+ * Copyright (c) 2024 Rayhan Faizel <rayhan.faizel@gmail.com>
41
+ * Copyright (c) 2009 CodeSourcery, LLC.
42
+ * Written by Paul Brook
27
+ *
43
+ *
28
+ * SPDX-License-Identifier: MIT
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
45
+ * See the COPYING file in the top-level directory.
29
+ */
46
+ */
30
+
47
+
31
+#ifndef BCM2835_OTP_H
48
+#ifndef HW_NET_LAN9118_PHY_H
32
+#define BCM2835_OTP_H
49
+#define HW_NET_LAN9118_PHY_H
33
+
50
+
51
+#include "qom/object.h"
34
+#include "hw/sysbus.h"
52
+#include "hw/sysbus.h"
35
+#include "qom/object.h"
53
+
36
+
54
+#define TYPE_LAN9118_PHY "lan9118-phy"
37
+#define TYPE_BCM2835_OTP "bcm2835-otp"
55
+OBJECT_DECLARE_SIMPLE_TYPE(Lan9118PhyState, LAN9118_PHY)
38
+OBJECT_DECLARE_SIMPLE_TYPE(BCM2835OTPState, BCM2835_OTP)
56
+
39
+
57
+typedef struct Lan9118PhyState {
40
+#define BCM2835_OTP_ROW_COUNT 66
41
+
42
+/* https://elinux.org/BCM2835_registers#OTP */
43
+#define BCM2835_OTP_BOOTMODE_REG 0x00
44
+#define BCM2835_OTP_CONFIG_REG 0x04
45
+#define BCM2835_OTP_CTRL_LO_REG 0x08
46
+#define BCM2835_OTP_CTRL_HI_REG 0x0c
47
+#define BCM2835_OTP_STATUS_REG 0x10
48
+#define BCM2835_OTP_BITSEL_REG 0x14
49
+#define BCM2835_OTP_DATA_REG 0x18
50
+#define BCM2835_OTP_ADDR_REG 0x1c
51
+#define BCM2835_OTP_WRITE_DATA_READ_REG 0x20
52
+#define BCM2835_OTP_INIT_STATUS_REG 0x24
53
+
54
+
55
+/* -- Row 32: Undocumented -- */
56
+
57
+#define BCM2835_OTP_ROW_32 32
58
+
59
+/* Lock OTP Programming (Customer OTP and private key) */
60
+#define BCM2835_OTP_ROW_32_LOCK BIT(6)
61
+
62
+/* -- Row 36-43: Customer OTP -- */
63
+
64
+#define BCM2835_OTP_CUSTOMER_OTP 36
65
+#define BCM2835_OTP_CUSTOMER_OTP_LEN 8
66
+
67
+/* Magic numbers to lock programming of customer OTP and private key */
68
+#define BCM2835_OTP_LOCK_NUM1 0xffffffff
69
+#define BCM2835_OTP_LOCK_NUM2 0xaffe0000
70
+
71
+/* -- Row 56-63: Device-specific private key -- */
72
+
73
+#define BCM2835_OTP_PRIVATE_KEY 56
74
+#define BCM2835_OTP_PRIVATE_KEY_LEN 8
75
+
76
+
77
+struct BCM2835OTPState {
78
+ /* <private> */
79
+ SysBusDevice parent_obj;
58
+ SysBusDevice parent_obj;
80
+
59
+
81
+ /* <public> */
60
+ uint16_t status;
82
+ MemoryRegion iomem;
61
+ uint16_t control;
83
+ uint32_t otp_rows[BCM2835_OTP_ROW_COUNT];
62
+ uint16_t advertise;
84
+};
63
+ uint16_t ints;
85
+
64
+ uint16_t int_mask;
86
+
65
+ qemu_irq irq;
87
+uint32_t bcm2835_otp_get_row(BCM2835OTPState *s, unsigned int row);
66
+ bool link_down;
88
+void bcm2835_otp_set_row(BCM2835OTPState *s, unsigned int row, uint32_t value);
67
+} Lan9118PhyState;
68
+
69
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down);
70
+void lan9118_phy_reset(Lan9118PhyState *s);
71
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg);
72
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val);
89
+
73
+
90
+#endif
74
+#endif
91
diff --git a/hw/nvram/bcm2835_otp.c b/hw/nvram/bcm2835_otp.c
75
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/net/lan9118.c
78
+++ b/hw/net/lan9118.c
79
@@ -XXX,XX +XXX,XX @@
80
#include "net/net.h"
81
#include "net/eth.h"
82
#include "hw/irq.h"
83
+#include "hw/net/lan9118_phy.h"
84
#include "hw/net/lan9118.h"
85
#include "hw/ptimer.h"
86
#include "hw/qdev-properties.h"
87
@@ -XXX,XX +XXX,XX @@ do { printf("lan9118: " fmt , ## __VA_ARGS__); } while (0)
88
#define MAC_CR_RXEN 0x00000004
89
#define MAC_CR_RESERVED 0x7f404213
90
91
-#define PHY_INT_ENERGYON 0x80
92
-#define PHY_INT_AUTONEG_COMPLETE 0x40
93
-#define PHY_INT_FAULT 0x20
94
-#define PHY_INT_DOWN 0x10
95
-#define PHY_INT_AUTONEG_LP 0x08
96
-#define PHY_INT_PARFAULT 0x04
97
-#define PHY_INT_AUTONEG_PAGE 0x02
98
-
99
#define GPT_TIMER_EN 0x20000000
100
101
/*
102
@@ -XXX,XX +XXX,XX @@ struct lan9118_state {
103
uint32_t mac_mii_data;
104
uint32_t mac_flow;
105
106
- uint32_t phy_status;
107
- uint32_t phy_control;
108
- uint32_t phy_advertise;
109
- uint32_t phy_int;
110
- uint32_t phy_int_mask;
111
+ Lan9118PhyState mii;
112
+ IRQState mii_irq;
113
114
int32_t eeprom_writable;
115
uint8_t eeprom[128];
116
@@ -XXX,XX +XXX,XX @@ struct lan9118_state {
117
118
static const VMStateDescription vmstate_lan9118 = {
119
.name = "lan9118",
120
- .version_id = 2,
121
- .minimum_version_id = 1,
122
+ .version_id = 3,
123
+ .minimum_version_id = 3,
124
.fields = (const VMStateField[]) {
125
VMSTATE_PTIMER(timer, lan9118_state),
126
VMSTATE_UINT32(irq_cfg, lan9118_state),
127
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118 = {
128
VMSTATE_UINT32(mac_mii_acc, lan9118_state),
129
VMSTATE_UINT32(mac_mii_data, lan9118_state),
130
VMSTATE_UINT32(mac_flow, lan9118_state),
131
- VMSTATE_UINT32(phy_status, lan9118_state),
132
- VMSTATE_UINT32(phy_control, lan9118_state),
133
- VMSTATE_UINT32(phy_advertise, lan9118_state),
134
- VMSTATE_UINT32(phy_int, lan9118_state),
135
- VMSTATE_UINT32(phy_int_mask, lan9118_state),
136
VMSTATE_INT32(eeprom_writable, lan9118_state),
137
VMSTATE_UINT8_ARRAY(eeprom, lan9118_state, 128),
138
VMSTATE_INT32(tx_fifo_size, lan9118_state),
139
@@ -XXX,XX +XXX,XX @@ static void lan9118_reload_eeprom(lan9118_state *s)
140
lan9118_mac_changed(s);
141
}
142
143
-static void phy_update_irq(lan9118_state *s)
144
+static void lan9118_update_irq(void *opaque, int n, int level)
145
{
146
- if (s->phy_int & s->phy_int_mask) {
147
+ lan9118_state *s = opaque;
148
+
149
+ if (level) {
150
s->int_sts |= PHY_INT;
151
} else {
152
s->int_sts &= ~PHY_INT;
153
@@ -XXX,XX +XXX,XX @@ static void phy_update_irq(lan9118_state *s)
154
lan9118_update(s);
155
}
156
157
-static void phy_update_link(lan9118_state *s)
158
-{
159
- /* Autonegotiation status mirrors link status. */
160
- if (qemu_get_queue(s->nic)->link_down) {
161
- s->phy_status &= ~0x0024;
162
- s->phy_int |= PHY_INT_DOWN;
163
- } else {
164
- s->phy_status |= 0x0024;
165
- s->phy_int |= PHY_INT_ENERGYON;
166
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
167
- }
168
- phy_update_irq(s);
169
-}
170
-
171
static void lan9118_set_link(NetClientState *nc)
172
{
173
- phy_update_link(qemu_get_nic_opaque(nc));
174
-}
175
-
176
-static void phy_reset(lan9118_state *s)
177
-{
178
- s->phy_status = 0x7809;
179
- s->phy_control = 0x3000;
180
- s->phy_advertise = 0x01e1;
181
- s->phy_int_mask = 0;
182
- s->phy_int = 0;
183
- phy_update_link(s);
184
+ lan9118_phy_update_link(&LAN9118(qemu_get_nic_opaque(nc))->mii,
185
+ nc->link_down);
186
}
187
188
static void lan9118_reset(DeviceState *d)
189
@@ -XXX,XX +XXX,XX @@ static void lan9118_reset(DeviceState *d)
190
s->read_word_n = 0;
191
s->write_word_n = 0;
192
193
- phy_reset(s);
194
-
195
s->eeprom_writable = 0;
196
lan9118_reload_eeprom(s);
197
}
198
@@ -XXX,XX +XXX,XX @@ static void do_tx_packet(lan9118_state *s)
199
uint32_t status;
200
201
/* FIXME: Honor TX disable, and allow queueing of packets. */
202
- if (s->phy_control & 0x4000) {
203
+ if (s->mii.control & 0x4000) {
204
/* This assumes the receive routine doesn't touch the VLANClient. */
205
qemu_receive_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
206
} else {
207
@@ -XXX,XX +XXX,XX @@ static void tx_fifo_push(lan9118_state *s, uint32_t val)
208
}
209
}
210
211
-static uint32_t do_phy_read(lan9118_state *s, int reg)
212
-{
213
- uint32_t val;
214
-
215
- switch (reg) {
216
- case 0: /* Basic Control */
217
- return s->phy_control;
218
- case 1: /* Basic Status */
219
- return s->phy_status;
220
- case 2: /* ID1 */
221
- return 0x0007;
222
- case 3: /* ID2 */
223
- return 0xc0d1;
224
- case 4: /* Auto-neg advertisement */
225
- return s->phy_advertise;
226
- case 5: /* Auto-neg Link Partner Ability */
227
- return 0x0f71;
228
- case 6: /* Auto-neg Expansion */
229
- return 1;
230
- /* TODO 17, 18, 27, 29, 30, 31 */
231
- case 29: /* Interrupt source. */
232
- val = s->phy_int;
233
- s->phy_int = 0;
234
- phy_update_irq(s);
235
- return val;
236
- case 30: /* Interrupt mask */
237
- return s->phy_int_mask;
238
- default:
239
- qemu_log_mask(LOG_GUEST_ERROR,
240
- "do_phy_read: PHY read reg %d\n", reg);
241
- return 0;
242
- }
243
-}
244
-
245
-static void do_phy_write(lan9118_state *s, int reg, uint32_t val)
246
-{
247
- switch (reg) {
248
- case 0: /* Basic Control */
249
- if (val & 0x8000) {
250
- phy_reset(s);
251
- break;
252
- }
253
- s->phy_control = val & 0x7980;
254
- /* Complete autonegotiation immediately. */
255
- if (val & 0x1000) {
256
- s->phy_status |= 0x0020;
257
- }
258
- break;
259
- case 4: /* Auto-neg advertisement */
260
- s->phy_advertise = (val & 0x2d7f) | 0x80;
261
- break;
262
- /* TODO 17, 18, 27, 31 */
263
- case 30: /* Interrupt mask */
264
- s->phy_int_mask = val & 0xff;
265
- phy_update_irq(s);
266
- break;
267
- default:
268
- qemu_log_mask(LOG_GUEST_ERROR,
269
- "do_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
270
- }
271
-}
272
-
273
static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
274
{
275
switch (reg) {
276
@@ -XXX,XX +XXX,XX @@ static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
277
if (val & 2) {
278
DPRINTF("PHY write %d = 0x%04x\n",
279
(val >> 6) & 0x1f, s->mac_mii_data);
280
- do_phy_write(s, (val >> 6) & 0x1f, s->mac_mii_data);
281
+ lan9118_phy_write(&s->mii, (val >> 6) & 0x1f, s->mac_mii_data);
282
} else {
283
- s->mac_mii_data = do_phy_read(s, (val >> 6) & 0x1f);
284
+ s->mac_mii_data = lan9118_phy_read(&s->mii, (val >> 6) & 0x1f);
285
DPRINTF("PHY read %d = 0x%04x\n",
286
(val >> 6) & 0x1f, s->mac_mii_data);
287
}
288
@@ -XXX,XX +XXX,XX @@ static void lan9118_writel(void *opaque, hwaddr offset,
289
break;
290
case CSR_PMT_CTRL:
291
if (val & 0x400) {
292
- phy_reset(s);
293
+ lan9118_phy_reset(&s->mii);
294
}
295
s->pmt_ctrl &= ~0x34e;
296
s->pmt_ctrl |= (val & 0x34e);
297
@@ -XXX,XX +XXX,XX @@ static void lan9118_realize(DeviceState *dev, Error **errp)
298
const MemoryRegionOps *mem_ops =
299
s->mode_16bit ? &lan9118_16bit_mem_ops : &lan9118_mem_ops;
300
301
+ qemu_init_irq(&s->mii_irq, lan9118_update_irq, s, 0);
302
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
303
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
304
+ return;
305
+ }
306
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
307
+
308
memory_region_init_io(&s->mmio, OBJECT(dev), mem_ops, s,
309
"lan9118-mmio", 0x100);
310
sysbus_init_mmio(sbd, &s->mmio);
311
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
92
new file mode 100644
312
new file mode 100644
93
index XXXXXXX..XXXXXXX
313
index XXXXXXX..XXXXXXX
94
--- /dev/null
314
--- /dev/null
95
+++ b/hw/nvram/bcm2835_otp.c
315
+++ b/hw/net/lan9118_phy.c
96
@@ -XXX,XX +XXX,XX @@
316
@@ -XXX,XX +XXX,XX @@
97
+/*
317
+/*
98
+ * BCM2835 One-Time Programmable (OTP) Memory
318
+ * SMSC LAN9118 PHY emulation
99
+ *
319
+ *
100
+ * The OTP implementation is mostly a stub except for the OTP rows
320
+ * Copyright (c) 2009 CodeSourcery, LLC.
101
+ * which are accessed directly by other peripherals such as the mailbox.
321
+ * Written by Paul Brook
102
+ *
322
+ *
103
+ * The OTP registers are unimplemented due to lack of documentation.
323
+ * This code is licensed under the GNU GPL v2
104
+ *
324
+ *
105
+ * Copyright (c) 2024 Rayhan Faizel <rayhan.faizel@gmail.com>
325
+ * Contributions after 2012-01-13 are licensed under the terms of the
106
+ *
326
+ * GNU GPL, version 2 or (at your option) any later version.
107
+ * SPDX-License-Identifier: MIT
108
+ */
327
+ */
109
+
328
+
110
+#include "qemu/osdep.h"
329
+#include "qemu/osdep.h"
330
+#include "hw/net/lan9118_phy.h"
331
+#include "hw/irq.h"
332
+#include "hw/resettable.h"
333
+#include "migration/vmstate.h"
111
+#include "qemu/log.h"
334
+#include "qemu/log.h"
112
+#include "hw/nvram/bcm2835_otp.h"
335
+
113
+#include "migration/vmstate.h"
336
+#define PHY_INT_ENERGYON (1 << 7)
114
+
337
+#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
115
+/* OTP rows are 1-indexed */
338
+#define PHY_INT_FAULT (1 << 5)
116
+uint32_t bcm2835_otp_get_row(BCM2835OTPState *s, unsigned int row)
339
+#define PHY_INT_DOWN (1 << 4)
117
+{
340
+#define PHY_INT_AUTONEG_LP (1 << 3)
118
+ assert(row <= BCM2835_OTP_ROW_COUNT && row >= 1);
341
+#define PHY_INT_PARFAULT (1 << 2)
119
+
342
+#define PHY_INT_AUTONEG_PAGE (1 << 1)
120
+ return s->otp_rows[row - 1];
343
+
121
+}
344
+static void lan9118_phy_update_irq(Lan9118PhyState *s)
122
+
345
+{
123
+void bcm2835_otp_set_row(BCM2835OTPState *s, unsigned int row,
346
+ qemu_set_irq(s->irq, !!(s->ints & s->int_mask));
124
+ uint32_t value)
347
+}
125
+{
348
+
126
+ assert(row <= BCM2835_OTP_ROW_COUNT && row >= 1);
349
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
127
+
350
+{
128
+ /* Real OTP rows work as e-fuses */
351
+ uint16_t val;
129
+ s->otp_rows[row - 1] |= value;
352
+
130
+}
353
+ switch (reg) {
131
+
354
+ case 0: /* Basic Control */
132
+static uint64_t bcm2835_otp_read(void *opaque, hwaddr addr, unsigned size)
355
+ return s->control;
133
+{
356
+ case 1: /* Basic Status */
134
+ switch (addr) {
357
+ return s->status;
135
+ case BCM2835_OTP_BOOTMODE_REG:
358
+ case 2: /* ID1 */
136
+ qemu_log_mask(LOG_UNIMP,
359
+ return 0x0007;
137
+ "bcm2835_otp: BCM2835_OTP_BOOTMODE_REG\n");
360
+ case 3: /* ID2 */
361
+ return 0xc0d1;
362
+ case 4: /* Auto-neg advertisement */
363
+ return s->advertise;
364
+ case 5: /* Auto-neg Link Partner Ability */
365
+ return 0x0f71;
366
+ case 6: /* Auto-neg Expansion */
367
+ return 1;
368
+ /* TODO 17, 18, 27, 29, 30, 31 */
369
+ case 29: /* Interrupt source. */
370
+ val = s->ints;
371
+ s->ints = 0;
372
+ lan9118_phy_update_irq(s);
373
+ return val;
374
+ case 30: /* Interrupt mask */
375
+ return s->int_mask;
376
+ default:
377
+ qemu_log_mask(LOG_GUEST_ERROR,
378
+ "lan9118_phy_read: PHY read reg %d\n", reg);
379
+ return 0;
380
+ }
381
+}
382
+
383
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
384
+{
385
+ switch (reg) {
386
+ case 0: /* Basic Control */
387
+ if (val & 0x8000) {
388
+ lan9118_phy_reset(s);
389
+ break;
390
+ }
391
+ s->control = val & 0x7980;
392
+ /* Complete autonegotiation immediately. */
393
+ if (val & 0x1000) {
394
+ s->status |= 0x0020;
395
+ }
138
+ break;
396
+ break;
139
+ case BCM2835_OTP_CONFIG_REG:
397
+ case 4: /* Auto-neg advertisement */
140
+ qemu_log_mask(LOG_UNIMP,
398
+ s->advertise = (val & 0x2d7f) | 0x80;
141
+ "bcm2835_otp: BCM2835_OTP_CONFIG_REG\n");
142
+ break;
399
+ break;
143
+ case BCM2835_OTP_CTRL_LO_REG:
400
+ /* TODO 17, 18, 27, 31 */
144
+ qemu_log_mask(LOG_UNIMP,
401
+ case 30: /* Interrupt mask */
145
+ "bcm2835_otp: BCM2835_OTP_CTRL_LO_REG\n");
402
+ s->int_mask = val & 0xff;
146
+ break;
403
+ lan9118_phy_update_irq(s);
147
+ case BCM2835_OTP_CTRL_HI_REG:
148
+ qemu_log_mask(LOG_UNIMP,
149
+ "bcm2835_otp: BCM2835_OTP_CTRL_HI_REG\n");
150
+ break;
151
+ case BCM2835_OTP_STATUS_REG:
152
+ qemu_log_mask(LOG_UNIMP,
153
+ "bcm2835_otp: BCM2835_OTP_STATUS_REG\n");
154
+ break;
155
+ case BCM2835_OTP_BITSEL_REG:
156
+ qemu_log_mask(LOG_UNIMP,
157
+ "bcm2835_otp: BCM2835_OTP_BITSEL_REG\n");
158
+ break;
159
+ case BCM2835_OTP_DATA_REG:
160
+ qemu_log_mask(LOG_UNIMP,
161
+ "bcm2835_otp: BCM2835_OTP_DATA_REG\n");
162
+ break;
163
+ case BCM2835_OTP_ADDR_REG:
164
+ qemu_log_mask(LOG_UNIMP,
165
+ "bcm2835_otp: BCM2835_OTP_ADDR_REG\n");
166
+ break;
167
+ case BCM2835_OTP_WRITE_DATA_READ_REG:
168
+ qemu_log_mask(LOG_UNIMP,
169
+ "bcm2835_otp: BCM2835_OTP_WRITE_DATA_READ_REG\n");
170
+ break;
171
+ case BCM2835_OTP_INIT_STATUS_REG:
172
+ qemu_log_mask(LOG_UNIMP,
173
+ "bcm2835_otp: BCM2835_OTP_INIT_STATUS_REG\n");
174
+ break;
404
+ break;
175
+ default:
405
+ default:
176
+ qemu_log_mask(LOG_GUEST_ERROR,
406
+ qemu_log_mask(LOG_GUEST_ERROR,
177
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
407
+ "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
178
+ }
408
+ }
179
+
409
+}
180
+ return 0;
410
+
181
+}
411
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
182
+
412
+{
183
+static void bcm2835_otp_write(void *opaque, hwaddr addr,
413
+ s->link_down = link_down;
184
+ uint64_t value, unsigned int size)
414
+
185
+{
415
+ /* Autonegotiation status mirrors link status. */
186
+ switch (addr) {
416
+ if (link_down) {
187
+ case BCM2835_OTP_BOOTMODE_REG:
417
+ s->status &= ~0x0024;
188
+ qemu_log_mask(LOG_UNIMP,
418
+ s->ints |= PHY_INT_DOWN;
189
+ "bcm2835_otp: BCM2835_OTP_BOOTMODE_REG\n");
419
+ } else {
190
+ break;
420
+ s->status |= 0x0024;
191
+ case BCM2835_OTP_CONFIG_REG:
421
+ s->ints |= PHY_INT_ENERGYON;
192
+ qemu_log_mask(LOG_UNIMP,
422
+ s->ints |= PHY_INT_AUTONEG_COMPLETE;
193
+ "bcm2835_otp: BCM2835_OTP_CONFIG_REG\n");
194
+ break;
195
+ case BCM2835_OTP_CTRL_LO_REG:
196
+ qemu_log_mask(LOG_UNIMP,
197
+ "bcm2835_otp: BCM2835_OTP_CTRL_LO_REG\n");
198
+ break;
199
+ case BCM2835_OTP_CTRL_HI_REG:
200
+ qemu_log_mask(LOG_UNIMP,
201
+ "bcm2835_otp: BCM2835_OTP_CTRL_HI_REG\n");
202
+ break;
203
+ case BCM2835_OTP_STATUS_REG:
204
+ qemu_log_mask(LOG_UNIMP,
205
+ "bcm2835_otp: BCM2835_OTP_STATUS_REG\n");
206
+ break;
207
+ case BCM2835_OTP_BITSEL_REG:
208
+ qemu_log_mask(LOG_UNIMP,
209
+ "bcm2835_otp: BCM2835_OTP_BITSEL_REG\n");
210
+ break;
211
+ case BCM2835_OTP_DATA_REG:
212
+ qemu_log_mask(LOG_UNIMP,
213
+ "bcm2835_otp: BCM2835_OTP_DATA_REG\n");
214
+ break;
215
+ case BCM2835_OTP_ADDR_REG:
216
+ qemu_log_mask(LOG_UNIMP,
217
+ "bcm2835_otp: BCM2835_OTP_ADDR_REG\n");
218
+ break;
219
+ case BCM2835_OTP_WRITE_DATA_READ_REG:
220
+ qemu_log_mask(LOG_UNIMP,
221
+ "bcm2835_otp: BCM2835_OTP_WRITE_DATA_READ_REG\n");
222
+ break;
223
+ case BCM2835_OTP_INIT_STATUS_REG:
224
+ qemu_log_mask(LOG_UNIMP,
225
+ "bcm2835_otp: BCM2835_OTP_INIT_STATUS_REG\n");
226
+ break;
227
+ default:
228
+ qemu_log_mask(LOG_GUEST_ERROR,
229
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
230
+ }
423
+ }
231
+}
424
+ lan9118_phy_update_irq(s);
232
+
425
+}
233
+static const MemoryRegionOps bcm2835_otp_ops = {
426
+
234
+ .read = bcm2835_otp_read,
427
+void lan9118_phy_reset(Lan9118PhyState *s)
235
+ .write = bcm2835_otp_write,
428
+{
236
+ .endianness = DEVICE_NATIVE_ENDIAN,
429
+ s->control = 0x3000;
237
+ .impl = {
430
+ s->status = 0x7809;
238
+ .min_access_size = 4,
431
+ s->advertise = 0x01e1;
239
+ .max_access_size = 4,
432
+ s->int_mask = 0;
240
+ },
433
+ s->ints = 0;
241
+};
434
+ lan9118_phy_update_link(s, s->link_down);
242
+
435
+}
243
+static void bcm2835_otp_realize(DeviceState *dev, Error **errp)
436
+
244
+{
437
+static void lan9118_phy_reset_hold(Object *obj, ResetType type)
245
+ BCM2835OTPState *s = BCM2835_OTP(dev);
438
+{
246
+ memory_region_init_io(&s->iomem, OBJECT(dev), &bcm2835_otp_ops, s,
439
+ Lan9118PhyState *s = LAN9118_PHY(obj);
247
+ TYPE_BCM2835_OTP, 0x80);
440
+
248
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
441
+ lan9118_phy_reset(s);
249
+
442
+}
250
+ memset(s->otp_rows, 0x00, sizeof(s->otp_rows));
443
+
251
+}
444
+static void lan9118_phy_init(Object *obj)
252
+
445
+{
253
+static const VMStateDescription vmstate_bcm2835_otp = {
446
+ Lan9118PhyState *s = LAN9118_PHY(obj);
254
+ .name = TYPE_BCM2835_OTP,
447
+
448
+ qdev_init_gpio_out(DEVICE(s), &s->irq, 1);
449
+}
450
+
451
+static const VMStateDescription vmstate_lan9118_phy = {
452
+ .name = "lan9118-phy",
255
+ .version_id = 1,
453
+ .version_id = 1,
256
+ .minimum_version_id = 1,
454
+ .minimum_version_id = 1,
257
+ .fields = (const VMStateField[]) {
455
+ .fields = (const VMStateField[]) {
258
+ VMSTATE_UINT32_ARRAY(otp_rows, BCM2835OTPState, BCM2835_OTP_ROW_COUNT),
456
+ VMSTATE_UINT16(control, Lan9118PhyState),
457
+ VMSTATE_UINT16(status, Lan9118PhyState),
458
+ VMSTATE_UINT16(advertise, Lan9118PhyState),
459
+ VMSTATE_UINT16(ints, Lan9118PhyState),
460
+ VMSTATE_UINT16(int_mask, Lan9118PhyState),
461
+ VMSTATE_BOOL(link_down, Lan9118PhyState),
259
+ VMSTATE_END_OF_LIST()
462
+ VMSTATE_END_OF_LIST()
260
+ }
463
+ }
261
+};
464
+};
262
+
465
+
263
+static void bcm2835_otp_class_init(ObjectClass *klass, void *data)
466
+static void lan9118_phy_class_init(ObjectClass *klass, void *data)
264
+{
467
+{
468
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
265
+ DeviceClass *dc = DEVICE_CLASS(klass);
469
+ DeviceClass *dc = DEVICE_CLASS(klass);
266
+
470
+
267
+ dc->realize = bcm2835_otp_realize;
471
+ rc->phases.hold = lan9118_phy_reset_hold;
268
+ dc->vmsd = &vmstate_bcm2835_otp;
472
+ dc->vmsd = &vmstate_lan9118_phy;
269
+}
473
+}
270
+
474
+
271
+static const TypeInfo bcm2835_otp_info = {
475
+static const TypeInfo types[] = {
272
+ .name = TYPE_BCM2835_OTP,
476
+ {
273
+ .parent = TYPE_SYS_BUS_DEVICE,
477
+ .name = TYPE_LAN9118_PHY,
274
+ .instance_size = sizeof(BCM2835OTPState),
478
+ .parent = TYPE_SYS_BUS_DEVICE,
275
+ .class_init = bcm2835_otp_class_init,
479
+ .instance_size = sizeof(Lan9118PhyState),
480
+ .instance_init = lan9118_phy_init,
481
+ .class_init = lan9118_phy_class_init,
482
+ }
276
+};
483
+};
277
+
484
+
278
+static void bcm2835_otp_register_types(void)
485
+DEFINE_TYPES(types)
279
+{
486
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
280
+ type_register_static(&bcm2835_otp_info);
281
+}
282
+
283
+type_init(bcm2835_otp_register_types)
284
diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build
285
index XXXXXXX..XXXXXXX 100644
487
index XXXXXXX..XXXXXXX 100644
286
--- a/hw/nvram/meson.build
488
--- a/hw/net/Kconfig
287
+++ b/hw/nvram/meson.build
489
+++ b/hw/net/Kconfig
288
@@ -XXX,XX +XXX,XX @@
490
@@ -XXX,XX +XXX,XX @@ config VMXNET3_PCI
289
system_ss.add(files('fw_cfg-interface.c'))
491
config SMC91C111
290
system_ss.add(files('fw_cfg.c'))
492
bool
291
+system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_otp.c'))
493
292
system_ss.add(when: 'CONFIG_CHRP_NVRAM', if_true: files('chrp_nvram.c'))
494
+config LAN9118_PHY
293
system_ss.add(when: 'CONFIG_DS1225Y', if_true: files('ds1225y.c'))
495
+ bool
294
system_ss.add(when: 'CONFIG_NMC93XX_EEPROM', if_true: files('eeprom93xx.c'))
496
+
497
config LAN9118
498
bool
499
+ select LAN9118_PHY
500
select PTIMER
501
502
config NE2000_ISA
503
diff --git a/hw/net/meson.build b/hw/net/meson.build
504
index XXXXXXX..XXXXXXX 100644
505
--- a/hw/net/meson.build
506
+++ b/hw/net/meson.build
507
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_VMXNET3_PCI', if_true: files('vmxnet3.c'))
508
509
system_ss.add(when: 'CONFIG_SMC91C111', if_true: files('smc91c111.c'))
510
system_ss.add(when: 'CONFIG_LAN9118', if_true: files('lan9118.c'))
511
+system_ss.add(when: 'CONFIG_LAN9118_PHY', if_true: files('lan9118_phy.c'))
512
system_ss.add(when: 'CONFIG_NE2000_ISA', if_true: files('ne2000-isa.c'))
513
system_ss.add(when: 'CONFIG_OPENCORES_ETH', if_true: files('opencores_eth.c'))
514
system_ss.add(when: 'CONFIG_XGMAC', if_true: files('xgmac.c'))
295
--
515
--
296
2.34.1
516
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
imx_fec models the same PHY as lan9118_phy. The code is almost the same with
4
imx_fec having more logging and tracing. Merge these improvements into
5
lan9118_phy and reuse in imx_fec to fix the code duplication.
6
7
Some migration state how resides in the new device model which breaks migration
8
compatibility for the following machines:
9
* imx25-pdk
10
* sabrelite
11
* mcimx7d-sabre
12
* mcimx6ul-evk
13
14
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
15
Tested-by: Guenter Roeck <linux@roeck-us.net>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20241102125724.532843-3-shentey@gmail.com
5
Message-id: 20240625183536.1672454-8-richard.henderson@linaro.org
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/tcg/a64.decode | 2 ++
20
include/hw/net/imx_fec.h | 9 ++-
9
target/arm/tcg/translate-a64.c | 20 +++++---------------
21
hw/net/imx_fec.c | 146 ++++-----------------------------------
10
2 files changed, 7 insertions(+), 15 deletions(-)
22
hw/net/lan9118_phy.c | 82 ++++++++++++++++------
23
hw/net/Kconfig | 1 +
24
hw/net/trace-events | 10 +--
25
5 files changed, 85 insertions(+), 163 deletions(-)
11
26
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
27
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
13
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/a64.decode
29
--- a/include/hw/net/imx_fec.h
15
+++ b/target/arm/tcg/a64.decode
30
+++ b/include/hw/net/imx_fec.h
16
@@ -XXX,XX +XXX,XX @@ SQRDMLSH_v 0.10 1110 ..0 ..... 10001 1 ..... ..... @qrrr_e
31
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(IMXFECState, IMX_FEC)
17
SDOT_v 0.00 1110 100 ..... 10010 1 ..... ..... @qrrr_s
32
#define TYPE_IMX_ENET "imx.enet"
18
UDOT_v 0.10 1110 100 ..... 10010 1 ..... ..... @qrrr_s
33
19
USDOT_v 0.00 1110 100 ..... 10011 1 ..... ..... @qrrr_s
34
#include "hw/sysbus.h"
20
+BFDOT_v 0.10 1110 010 ..... 11111 1 ..... ..... @qrrr_s
35
+#include "hw/net/lan9118_phy.h"
21
36
+#include "hw/irq.h"
22
### Advanced SIMD scalar x indexed element
37
#include "net/net.h"
23
38
24
@@ -XXX,XX +XXX,XX @@ SDOT_vi 0.00 1111 10 .. .... 1110 . 0 ..... ..... @qrrx_s
39
#define ENET_EIR 1
25
UDOT_vi 0.10 1111 10 .. .... 1110 . 0 ..... ..... @qrrx_s
40
@@ -XXX,XX +XXX,XX @@ struct IMXFECState {
26
SUDOT_vi 0.00 1111 00 .. .... 1111 . 0 ..... ..... @qrrx_s
41
uint32_t tx_descriptor[ENET_TX_RING_NUM];
27
USDOT_vi 0.00 1111 10 .. .... 1111 . 0 ..... ..... @qrrx_s
42
uint32_t tx_ring_num;
28
+BFDOT_vi 0.00 1111 01 .. .... 1111 . 0 ..... ..... @qrrx_s
43
29
44
- uint32_t phy_status;
30
# Floating-point conditional select
45
- uint32_t phy_control;
31
46
- uint32_t phy_advertise;
32
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
47
- uint32_t phy_int;
48
- uint32_t phy_int_mask;
49
+ Lan9118PhyState mii;
50
+ IRQState mii_irq;
51
uint32_t phy_num;
52
bool phy_connected;
53
struct IMXFECState *phy_consumer;
54
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
33
index XXXXXXX..XXXXXXX 100644
55
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/tcg/translate-a64.c
56
--- a/hw/net/imx_fec.c
35
+++ b/target/arm/tcg/translate-a64.c
57
+++ b/hw/net/imx_fec.c
36
@@ -XXX,XX +XXX,XX @@ static bool do_dot_vector(DisasContext *s, arg_qrrr_e *a,
58
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth_txdescs = {
37
TRANS_FEAT(SDOT_v, aa64_dp, do_dot_vector, a, gen_helper_gvec_sdot_b)
59
38
TRANS_FEAT(UDOT_v, aa64_dp, do_dot_vector, a, gen_helper_gvec_udot_b)
60
static const VMStateDescription vmstate_imx_eth = {
39
TRANS_FEAT(USDOT_v, aa64_i8mm, do_dot_vector, a, gen_helper_gvec_usdot_b)
61
.name = TYPE_IMX_FEC,
40
+TRANS_FEAT(BFDOT_v, aa64_bf16, do_dot_vector, a, gen_helper_gvec_bfdot)
62
- .version_id = 2,
63
- .minimum_version_id = 2,
64
+ .version_id = 3,
65
+ .minimum_version_id = 3,
66
.fields = (const VMStateField[]) {
67
VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
68
VMSTATE_UINT32(rx_descriptor, IMXFECState),
69
VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
70
- VMSTATE_UINT32(phy_status, IMXFECState),
71
- VMSTATE_UINT32(phy_control, IMXFECState),
72
- VMSTATE_UINT32(phy_advertise, IMXFECState),
73
- VMSTATE_UINT32(phy_int, IMXFECState),
74
- VMSTATE_UINT32(phy_int_mask, IMXFECState),
75
VMSTATE_END_OF_LIST()
76
},
77
.subsections = (const VMStateDescription * const []) {
78
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth = {
79
},
80
};
81
82
-#define PHY_INT_ENERGYON (1 << 7)
83
-#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
84
-#define PHY_INT_FAULT (1 << 5)
85
-#define PHY_INT_DOWN (1 << 4)
86
-#define PHY_INT_AUTONEG_LP (1 << 3)
87
-#define PHY_INT_PARFAULT (1 << 2)
88
-#define PHY_INT_AUTONEG_PAGE (1 << 1)
89
-
90
static void imx_eth_update(IMXFECState *s);
41
91
42
/*
92
/*
43
* Advanced SIMD scalar/vector x indexed element
93
@@ -XXX,XX +XXX,XX @@ static void imx_eth_update(IMXFECState *s);
44
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(SUDOT_vi, aa64_i8mm, do_dot_vector_idx, a,
94
* For now we don't handle any GPIO/interrupt line, so the OS will
45
gen_helper_gvec_sudot_idx_b)
95
* have to poll for the PHY status.
46
TRANS_FEAT(USDOT_vi, aa64_i8mm, do_dot_vector_idx, a,
96
*/
47
gen_helper_gvec_usdot_idx_b)
97
-static void imx_phy_update_irq(IMXFECState *s)
48
+TRANS_FEAT(BFDOT_vi, aa64_bf16, do_dot_vector_idx, a,
98
+static void imx_phy_update_irq(void *opaque, int n, int level)
49
+ gen_helper_gvec_bfdot_idx)
99
{
50
100
- imx_eth_update(s);
51
/*
101
-}
52
* Advanced SIMD scalar pairwise
102
-
53
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
103
-static void imx_phy_update_link(IMXFECState *s)
104
-{
105
- /* Autonegotiation status mirrors link status. */
106
- if (qemu_get_queue(s->nic)->link_down) {
107
- trace_imx_phy_update_link("down");
108
- s->phy_status &= ~0x0024;
109
- s->phy_int |= PHY_INT_DOWN;
110
- } else {
111
- trace_imx_phy_update_link("up");
112
- s->phy_status |= 0x0024;
113
- s->phy_int |= PHY_INT_ENERGYON;
114
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
115
- }
116
- imx_phy_update_irq(s);
117
+ imx_eth_update(opaque);
118
}
119
120
static void imx_eth_set_link(NetClientState *nc)
121
{
122
- imx_phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
123
-}
124
-
125
-static void imx_phy_reset(IMXFECState *s)
126
-{
127
- trace_imx_phy_reset();
128
-
129
- s->phy_status = 0x7809;
130
- s->phy_control = 0x3000;
131
- s->phy_advertise = 0x01e1;
132
- s->phy_int_mask = 0;
133
- s->phy_int = 0;
134
- imx_phy_update_link(s);
135
+ lan9118_phy_update_link(&IMX_FEC(qemu_get_nic_opaque(nc))->mii,
136
+ nc->link_down);
137
}
138
139
static uint32_t imx_phy_read(IMXFECState *s, int reg)
140
{
141
- uint32_t val;
142
uint32_t phy = reg / 32;
143
144
if (!s->phy_connected) {
145
@@ -XXX,XX +XXX,XX @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
146
147
reg %= 32;
148
149
- switch (reg) {
150
- case 0: /* Basic Control */
151
- val = s->phy_control;
152
- break;
153
- case 1: /* Basic Status */
154
- val = s->phy_status;
155
- break;
156
- case 2: /* ID1 */
157
- val = 0x0007;
158
- break;
159
- case 3: /* ID2 */
160
- val = 0xc0d1;
161
- break;
162
- case 4: /* Auto-neg advertisement */
163
- val = s->phy_advertise;
164
- break;
165
- case 5: /* Auto-neg Link Partner Ability */
166
- val = 0x0f71;
167
- break;
168
- case 6: /* Auto-neg Expansion */
169
- val = 1;
170
- break;
171
- case 29: /* Interrupt source. */
172
- val = s->phy_int;
173
- s->phy_int = 0;
174
- imx_phy_update_irq(s);
175
- break;
176
- case 30: /* Interrupt mask */
177
- val = s->phy_int_mask;
178
- break;
179
- case 17:
180
- case 18:
181
- case 27:
182
- case 31:
183
- qemu_log_mask(LOG_UNIMP, "[%s.phy]%s: reg %d not implemented\n",
184
- TYPE_IMX_FEC, __func__, reg);
185
- val = 0;
186
- break;
187
- default:
188
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
189
- TYPE_IMX_FEC, __func__, reg);
190
- val = 0;
191
- break;
192
- }
193
-
194
- trace_imx_phy_read(val, phy, reg);
195
-
196
- return val;
197
+ return lan9118_phy_read(&s->mii, reg);
198
}
199
200
static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
201
@@ -XXX,XX +XXX,XX @@ static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
202
203
reg %= 32;
204
205
- trace_imx_phy_write(val, phy, reg);
206
-
207
- switch (reg) {
208
- case 0: /* Basic Control */
209
- if (val & 0x8000) {
210
- imx_phy_reset(s);
211
- } else {
212
- s->phy_control = val & 0x7980;
213
- /* Complete autonegotiation immediately. */
214
- if (val & 0x1000) {
215
- s->phy_status |= 0x0020;
216
- }
217
- }
218
- break;
219
- case 4: /* Auto-neg advertisement */
220
- s->phy_advertise = (val & 0x2d7f) | 0x80;
221
- break;
222
- case 30: /* Interrupt mask */
223
- s->phy_int_mask = val & 0xff;
224
- imx_phy_update_irq(s);
225
- break;
226
- case 17:
227
- case 18:
228
- case 27:
229
- case 31:
230
- qemu_log_mask(LOG_UNIMP, "[%s.phy)%s: reg %d not implemented\n",
231
- TYPE_IMX_FEC, __func__, reg);
232
- break;
233
- default:
234
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
235
- TYPE_IMX_FEC, __func__, reg);
236
- break;
237
- }
238
+ lan9118_phy_write(&s->mii, reg, val);
239
}
240
241
static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr)
242
@@ -XXX,XX +XXX,XX @@ static void imx_eth_reset(DeviceState *d)
243
244
s->rx_descriptor = 0;
245
memset(s->tx_descriptor, 0, sizeof(s->tx_descriptor));
246
-
247
- /* We also reset the PHY */
248
- imx_phy_reset(s);
249
}
250
251
static uint32_t imx_default_read(IMXFECState *s, uint32_t index)
252
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
253
sysbus_init_irq(sbd, &s->irq[0]);
254
sysbus_init_irq(sbd, &s->irq[1]);
255
256
+ qemu_init_irq(&s->mii_irq, imx_phy_update_irq, s, 0);
257
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
258
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
259
+ return;
260
+ }
261
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
262
+
263
qemu_macaddr_default_if_unset(&s->conf.macaddr);
264
265
s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
266
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
267
index XXXXXXX..XXXXXXX 100644
268
--- a/hw/net/lan9118_phy.c
269
+++ b/hw/net/lan9118_phy.c
270
@@ -XXX,XX +XXX,XX @@
271
* Copyright (c) 2009 CodeSourcery, LLC.
272
* Written by Paul Brook
273
*
274
+ * Copyright (c) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
275
+ *
276
* This code is licensed under the GNU GPL v2
277
*
278
* Contributions after 2012-01-13 are licensed under the terms of the
279
@@ -XXX,XX +XXX,XX @@
280
#include "hw/resettable.h"
281
#include "migration/vmstate.h"
282
#include "qemu/log.h"
283
+#include "trace.h"
284
285
#define PHY_INT_ENERGYON (1 << 7)
286
#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
287
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
288
289
switch (reg) {
290
case 0: /* Basic Control */
291
- return s->control;
292
+ val = s->control;
293
+ break;
294
case 1: /* Basic Status */
295
- return s->status;
296
+ val = s->status;
297
+ break;
298
case 2: /* ID1 */
299
- return 0x0007;
300
+ val = 0x0007;
301
+ break;
302
case 3: /* ID2 */
303
- return 0xc0d1;
304
+ val = 0xc0d1;
305
+ break;
306
case 4: /* Auto-neg advertisement */
307
- return s->advertise;
308
+ val = s->advertise;
309
+ break;
310
case 5: /* Auto-neg Link Partner Ability */
311
- return 0x0f71;
312
+ val = 0x0f71;
313
+ break;
314
case 6: /* Auto-neg Expansion */
315
- return 1;
316
- /* TODO 17, 18, 27, 29, 30, 31 */
317
+ val = 1;
318
+ break;
319
case 29: /* Interrupt source. */
320
val = s->ints;
321
s->ints = 0;
322
lan9118_phy_update_irq(s);
323
- return val;
324
+ break;
325
case 30: /* Interrupt mask */
326
- return s->int_mask;
327
+ val = s->int_mask;
328
+ break;
329
+ case 17:
330
+ case 18:
331
+ case 27:
332
+ case 31:
333
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
334
+ __func__, reg);
335
+ val = 0;
336
+ break;
337
default:
338
- qemu_log_mask(LOG_GUEST_ERROR,
339
- "lan9118_phy_read: PHY read reg %d\n", reg);
340
- return 0;
341
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
342
+ __func__, reg);
343
+ val = 0;
344
+ break;
345
}
346
+
347
+ trace_lan9118_phy_read(val, reg);
348
+
349
+ return val;
350
}
351
352
void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
353
{
354
+ trace_lan9118_phy_write(val, reg);
355
+
356
switch (reg) {
357
case 0: /* Basic Control */
358
if (val & 0x8000) {
359
lan9118_phy_reset(s);
360
- break;
361
- }
362
- s->control = val & 0x7980;
363
- /* Complete autonegotiation immediately. */
364
- if (val & 0x1000) {
365
- s->status |= 0x0020;
366
+ } else {
367
+ s->control = val & 0x7980;
368
+ /* Complete autonegotiation immediately. */
369
+ if (val & 0x1000) {
370
+ s->status |= 0x0020;
371
+ }
372
}
54
break;
373
break;
55
case 0x1f:
374
case 4: /* Auto-neg advertisement */
56
switch (size) {
375
s->advertise = (val & 0x2d7f) | 0x80;
57
- case 1: /* BFDOT */
58
case 3: /* BFMLAL{B,T} */
59
feature = dc_isar_feature(aa64_bf16, s);
60
break;
61
default:
62
+ case 1: /* BFDOT */
63
unallocated_encoding(s);
64
return;
65
}
66
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
67
return;
68
case 0xf:
69
switch (size) {
70
- case 1: /* BFDOT */
71
- gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfdot);
72
- break;
73
case 3: /* BFMLAL{B,T} */
74
gen_gvec_op4_fpst(s, 1, rd, rn, rm, rd, false, is_q,
75
gen_helper_gvec_bfmlal);
76
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
77
break;
376
break;
78
case 0x0f:
377
- /* TODO 17, 18, 27, 31 */
79
switch (size) {
378
case 30: /* Interrupt mask */
80
- case 1: /* BFDOT */
379
s->int_mask = val & 0xff;
81
- if (is_scalar || !dc_isar_feature(aa64_bf16, s)) {
380
lan9118_phy_update_irq(s);
82
- unallocated_encoding(s);
381
break;
83
- return;
382
+ case 17:
84
- }
383
+ case 18:
85
- size = MO_32;
384
+ case 27:
86
- break;
385
+ case 31:
87
case 3: /* BFMLAL{B,T} */
386
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
88
if (is_scalar || !dc_isar_feature(aa64_bf16, s)) {
387
+ __func__, reg);
89
unallocated_encoding(s);
388
+ break;
90
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
389
default:
91
break;
390
- qemu_log_mask(LOG_GUEST_ERROR,
92
default:
391
- "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
93
case 0: /* SUDOT */
392
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
94
+ case 1: /* BFDOT */
393
+ __func__, reg);
95
case 2: /* USDOT */
394
+ break;
96
unallocated_encoding(s);
395
}
97
return;
396
}
98
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
397
99
switch (16 * u + opcode) {
398
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
100
case 0x0f:
399
101
switch (extract32(insn, 22, 2)) {
400
/* Autonegotiation status mirrors link status. */
102
- case 1: /* BFDOT */
401
if (link_down) {
103
- gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
402
+ trace_lan9118_phy_update_link("down");
104
- gen_helper_gvec_bfdot_idx);
403
s->status &= ~0x0024;
105
- return;
404
s->ints |= PHY_INT_DOWN;
106
case 3: /* BFMLAL{B,T} */
405
} else {
107
gen_gvec_op4_fpst(s, 1, rd, rn, rm, rd, 0, (index << 1) | is_q,
406
+ trace_lan9118_phy_update_link("up");
108
gen_helper_gvec_bfmlal_idx);
407
s->status |= 0x0024;
408
s->ints |= PHY_INT_ENERGYON;
409
s->ints |= PHY_INT_AUTONEG_COMPLETE;
410
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
411
412
void lan9118_phy_reset(Lan9118PhyState *s)
413
{
414
+ trace_lan9118_phy_reset();
415
+
416
s->control = 0x3000;
417
s->status = 0x7809;
418
s->advertise = 0x01e1;
419
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_phy = {
420
.version_id = 1,
421
.minimum_version_id = 1,
422
.fields = (const VMStateField[]) {
423
- VMSTATE_UINT16(control, Lan9118PhyState),
424
VMSTATE_UINT16(status, Lan9118PhyState),
425
+ VMSTATE_UINT16(control, Lan9118PhyState),
426
VMSTATE_UINT16(advertise, Lan9118PhyState),
427
VMSTATE_UINT16(ints, Lan9118PhyState),
428
VMSTATE_UINT16(int_mask, Lan9118PhyState),
429
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
430
index XXXXXXX..XXXXXXX 100644
431
--- a/hw/net/Kconfig
432
+++ b/hw/net/Kconfig
433
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_SUN8I_EMAC
434
435
config IMX_FEC
436
bool
437
+ select LAN9118_PHY
438
439
config CADENCE
440
bool
441
diff --git a/hw/net/trace-events b/hw/net/trace-events
442
index XXXXXXX..XXXXXXX 100644
443
--- a/hw/net/trace-events
444
+++ b/hw/net/trace-events
445
@@ -XXX,XX +XXX,XX @@ allwinner_sun8i_emac_set_link(bool active) "Set link: active=%u"
446
allwinner_sun8i_emac_read(uint64_t offset, uint64_t val) "MMIO read: offset=0x%" PRIx64 " value=0x%" PRIx64
447
allwinner_sun8i_emac_write(uint64_t offset, uint64_t val) "MMIO write: offset=0x%" PRIx64 " value=0x%" PRIx64
448
449
+# lan9118_phy.c
450
+lan9118_phy_read(uint16_t val, int reg) "[0x%02x] -> 0x%04" PRIx16
451
+lan9118_phy_write(uint16_t val, int reg) "[0x%02x] <- 0x%04" PRIx16
452
+lan9118_phy_update_link(const char *s) "%s"
453
+lan9118_phy_reset(void) ""
454
+
455
# lance.c
456
lance_mem_readw(uint64_t addr, uint32_t ret) "addr=0x%"PRIx64"val=0x%04x"
457
lance_mem_writew(uint64_t addr, uint32_t val) "addr=0x%"PRIx64"val=0x%04x"
458
@@ -XXX,XX +XXX,XX @@ i82596_set_multicast(uint16_t count) "Added %d multicast entries"
459
i82596_channel_attention(void *s) "%p: Received CHANNEL ATTENTION"
460
461
# imx_fec.c
462
-imx_phy_read(uint32_t val, int phy, int reg) "0x%04"PRIx32" <= phy[%d].reg[%d]"
463
imx_phy_read_num(int phy, int configured) "read request from unconfigured phy %d (configured %d)"
464
-imx_phy_write(uint32_t val, int phy, int reg) "0x%04"PRIx32" => phy[%d].reg[%d]"
465
imx_phy_write_num(int phy, int configured) "write request to unconfigured phy %d (configured %d)"
466
-imx_phy_update_link(const char *s) "%s"
467
-imx_phy_reset(void) ""
468
imx_fec_read_bd(uint64_t addr, int flags, int len, int data) "tx_bd 0x%"PRIx64" flags 0x%04x len %d data 0x%08x"
469
imx_enet_read_bd(uint64_t addr, int flags, int len, int data, int options, int status) "tx_bd 0x%"PRIx64" flags 0x%04x len %d data 0x%08x option 0x%04x status 0x%04x"
470
imx_eth_tx_bd_busy(void) "tx_bd ran out of descriptors to transmit"
109
--
471
--
110
2.34.1
472
2.34.1
diff view generated by jsdifflib
1
From: Gustavo Romero <gustavo.romero@linaro.org>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Fix comment indentation adding a missing space.
3
Turns 0x70 into 0xe0 (== 0x70 << 1) which adds the missing MII_ANLPAR_TX and
4
fixes the MSB of selector field to be zero, as specified in the datasheet.
4
5
5
Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
6
Fixes: 2a424990170b "LAN9118 emulation"
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
7
Message-id: 20240624180915.4528-2-gustavo.romero@linaro.org
8
Tested-by: Guenter Roeck <linux@roeck-us.net>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20241102125724.532843-4-shentey@gmail.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
12
---
10
target/arm/tcg/cpu64.c | 2 +-
13
hw/net/lan9118_phy.c | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
12
15
13
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/tcg/cpu64.c
18
--- a/hw/net/lan9118_phy.c
16
+++ b/target/arm/tcg/cpu64.c
19
+++ b/hw/net/lan9118_phy.c
17
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
20
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
18
21
val = s->advertise;
19
t = cpu->isar.id_aa64isar2;
22
break;
20
t = FIELD_DP64(t, ID_AA64ISAR2, MOPS, 1); /* FEAT_MOPS */
23
case 5: /* Auto-neg Link Partner Ability */
21
- t = FIELD_DP64(t, ID_AA64ISAR2, BC, 1); /* FEAT_HBC */
24
- val = 0x0f71;
22
+ t = FIELD_DP64(t, ID_AA64ISAR2, BC, 1); /* FEAT_HBC */
25
+ val = 0x0fe1;
23
t = FIELD_DP64(t, ID_AA64ISAR2, WFXT, 2); /* FEAT_WFxT */
26
break;
24
cpu->isar.id_aa64isar2 = t;
27
case 6: /* Auto-neg Expansion */
25
28
val = 1;
26
--
29
--
27
2.34.1
30
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Bernhard Beschow <shentey@gmail.com>
2
3
Prefer named constants over magic values for better readability.
2
4
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
5
Message-id: 20240625183536.1672454-6-richard.henderson@linaro.org
7
Tested-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: 20241102125724.532843-5-shentey@gmail.com
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/tcg/a64.decode | 7 +++++
11
include/hw/net/mii.h | 6 +++++
9
target/arm/tcg/translate-a64.c | 54 ++++++++++++++++++----------------
12
hw/net/lan9118_phy.c | 63 ++++++++++++++++++++++++++++----------------
10
2 files changed, 35 insertions(+), 26 deletions(-)
13
2 files changed, 46 insertions(+), 23 deletions(-)
11
14
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
15
diff --git a/include/hw/net/mii.h b/include/hw/net/mii.h
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/a64.decode
17
--- a/include/hw/net/mii.h
15
+++ b/target/arm/tcg/a64.decode
18
+++ b/include/hw/net/mii.h
16
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
17
20
#define MII_BMSR_JABBER (1 << 1) /* Jabber detected */
18
@qrrr_b . q:1 ...... ... rm:5 ...... rn:5 rd:5 &qrrr_e esz=0
21
#define MII_BMSR_EXTCAP (1 << 0) /* Ext-reg capability */
19
@qrrr_h . q:1 ...... ... rm:5 ...... rn:5 rd:5 &qrrr_e esz=1
22
20
+@qrrr_s . q:1 ...... ... rm:5 ...... rn:5 rd:5 &qrrr_e esz=2
23
+#define MII_ANAR_RFAULT (1 << 13) /* Say we can detect faults */
21
@qrrr_sd . q:1 ...... ... rm:5 ...... rn:5 rd:5 &qrrr_e esz=%esz_sd
24
#define MII_ANAR_PAUSE_ASYM (1 << 11) /* Try for asymmetric pause */
22
@qrrr_e . q:1 ...... esz:2 . rm:5 ...... rn:5 rd:5 &qrrr_e
25
#define MII_ANAR_PAUSE (1 << 10) /* Try for pause */
23
@qr2r_e . q:1 ...... esz:2 . ..... ...... rm:5 rd:5 &qrrr_e rn=%rd
26
#define MII_ANAR_TXFD (1 << 8)
24
@@ -XXX,XX +XXX,XX @@ SQRDMULH_v 0.10 1110 ..1 ..... 10110 1 ..... ..... @qrrr_e
27
@@ -XXX,XX +XXX,XX @@
25
SQRDMLAH_v 0.10 1110 ..0 ..... 10000 1 ..... ..... @qrrr_e
28
#define MII_ANAR_10FD (1 << 6)
26
SQRDMLSH_v 0.10 1110 ..0 ..... 10001 1 ..... ..... @qrrr_e
29
#define MII_ANAR_10 (1 << 5)
27
30
#define MII_ANAR_CSMACD (1 << 0)
28
+SDOT_v 0.00 1110 100 ..... 10010 1 ..... ..... @qrrr_s
31
+#define MII_ANAR_SELECT (0x001f) /* Selector bits */
29
+UDOT_v 0.10 1110 100 ..... 10010 1 ..... ..... @qrrr_s
32
33
#define MII_ANLPAR_ACK (1 << 14)
34
#define MII_ANLPAR_PAUSEASY (1 << 11) /* can pause asymmetrically */
35
@@ -XXX,XX +XXX,XX @@
36
#define RTL8201CP_PHYID1 0x0000
37
#define RTL8201CP_PHYID2 0x8201
38
39
+/* SMSC LAN9118 */
40
+#define SMSCLAN9118_PHYID1 0x0007
41
+#define SMSCLAN9118_PHYID2 0xc0d1
30
+
42
+
31
### Advanced SIMD scalar x indexed element
43
/* RealTek 8211E */
32
44
#define RTL8211E_PHYID1 0x001c
33
FMUL_si 0101 1111 00 .. .... 1001 . 0 ..... ..... @rrx_h
45
#define RTL8211E_PHYID2 0xc915
34
@@ -XXX,XX +XXX,XX @@ SQRDMLAH_vi 0.10 1111 10 .. .... 1101 . 0 ..... ..... @qrrx_s
46
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
35
SQRDMLSH_vi 0.10 1111 01 .. .... 1111 . 0 ..... ..... @qrrx_h
36
SQRDMLSH_vi 0.10 1111 10 .. .... 1111 . 0 ..... ..... @qrrx_s
37
38
+SDOT_vi 0.00 1111 10 .. .... 1110 . 0 ..... ..... @qrrx_s
39
+UDOT_vi 0.10 1111 10 .. .... 1110 . 0 ..... ..... @qrrx_s
40
+
41
# Floating-point conditional select
42
43
FCSEL 0001 1110 .. 1 rm:5 cond:4 11 rn:5 rd:5 esz=%esz_hsd
44
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
45
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/tcg/translate-a64.c
48
--- a/hw/net/lan9118_phy.c
47
+++ b/target/arm/tcg/translate-a64.c
49
+++ b/hw/net/lan9118_phy.c
48
@@ -XXX,XX +XXX,XX @@ TRANS(SQRDMULH_v, do_gvec_fn3_no8_no64, a, gen_gvec_sqrdmulh_qc)
50
@@ -XXX,XX +XXX,XX @@
49
TRANS_FEAT(SQRDMLAH_v, aa64_rdm, do_gvec_fn3_no8_no64, a, gen_gvec_sqrdmlah_qc)
51
50
TRANS_FEAT(SQRDMLSH_v, aa64_rdm, do_gvec_fn3_no8_no64, a, gen_gvec_sqrdmlsh_qc)
52
#include "qemu/osdep.h"
51
53
#include "hw/net/lan9118_phy.h"
52
+static bool do_dot_vector(DisasContext *s, arg_qrrr_e *a,
54
+#include "hw/net/mii.h"
53
+ gen_helper_gvec_4 *fn)
55
#include "hw/irq.h"
54
+{
56
#include "hw/resettable.h"
55
+ if (fp_access_check(s)) {
57
#include "migration/vmstate.h"
56
+ gen_gvec_op4_ool(s, a->q, a->rd, a->rn, a->rm, a->rd, 0, fn);
58
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
57
+ }
59
uint16_t val;
58
+ return true;
60
59
+}
61
switch (reg) {
60
+
62
- case 0: /* Basic Control */
61
+TRANS_FEAT(SDOT_v, aa64_dp, do_dot_vector, a, gen_helper_gvec_sdot_b)
63
+ case MII_BMCR:
62
+TRANS_FEAT(UDOT_v, aa64_dp, do_dot_vector, a, gen_helper_gvec_udot_b)
64
val = s->control;
63
+
65
break;
64
/*
66
- case 1: /* Basic Status */
65
* Advanced SIMD scalar/vector x indexed element
67
+ case MII_BMSR:
66
*/
68
val = s->status;
67
@@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_4 * const f_vector_idx_sqrdmlsh[2] = {
69
break;
68
TRANS_FEAT(SQRDMLSH_vi, aa64_rdm, do_int3_qc_vector_idx, a,
70
- case 2: /* ID1 */
69
f_vector_idx_sqrdmlsh)
71
- val = 0x0007;
70
72
+ case MII_PHYID1:
71
+static bool do_dot_vector_idx(DisasContext *s, arg_qrrx_e *a,
73
+ val = SMSCLAN9118_PHYID1;
72
+ gen_helper_gvec_4 *fn)
74
break;
73
+{
75
- case 3: /* ID2 */
74
+ if (fp_access_check(s)) {
76
- val = 0xc0d1;
75
+ gen_gvec_op4_ool(s, a->q, a->rd, a->rn, a->rm, a->rd, a->idx, fn);
77
+ case MII_PHYID2:
76
+ }
78
+ val = SMSCLAN9118_PHYID2;
77
+ return true;
79
break;
78
+}
80
- case 4: /* Auto-neg advertisement */
79
+
81
+ case MII_ANAR:
80
+TRANS_FEAT(SDOT_vi, aa64_dp, do_dot_vector_idx, a, gen_helper_gvec_sdot_idx_b)
82
val = s->advertise;
81
+TRANS_FEAT(UDOT_vi, aa64_dp, do_dot_vector_idx, a, gen_helper_gvec_udot_idx_b)
83
break;
82
+
84
- case 5: /* Auto-neg Link Partner Ability */
83
/*
85
- val = 0x0fe1;
84
* Advanced SIMD scalar pairwise
86
+ case MII_ANLPAR:
85
*/
87
+ val = MII_ANLPAR_PAUSEASY | MII_ANLPAR_PAUSE | MII_ANLPAR_T4 |
86
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
88
+ MII_ANLPAR_TXFD | MII_ANLPAR_TX | MII_ANLPAR_10FD |
87
int rot;
89
+ MII_ANLPAR_10 | MII_ANLPAR_CSMACD;
88
90
break;
89
switch (u * 16 + opcode) {
91
- case 6: /* Auto-neg Expansion */
90
- case 0x02: /* SDOT (vector) */
92
- val = 1;
91
- case 0x12: /* UDOT (vector) */
93
+ case MII_ANER:
92
- if (size != MO_32) {
94
+ val = MII_ANER_NWAY;
93
- unallocated_encoding(s);
95
break;
94
- return;
96
case 29: /* Interrupt source. */
95
- }
97
val = s->ints;
96
- feature = dc_isar_feature(aa64_dp, s);
98
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
97
- break;
99
trace_lan9118_phy_write(val, reg);
98
case 0x03: /* USDOT */
100
99
if (size != MO_32) {
101
switch (reg) {
100
unallocated_encoding(s);
102
- case 0: /* Basic Control */
101
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
103
- if (val & 0x8000) {
104
+ case MII_BMCR:
105
+ if (val & MII_BMCR_RESET) {
106
lan9118_phy_reset(s);
107
} else {
108
- s->control = val & 0x7980;
109
+ s->control = val & (MII_BMCR_LOOPBACK | MII_BMCR_SPEED100 |
110
+ MII_BMCR_AUTOEN | MII_BMCR_PDOWN | MII_BMCR_FD |
111
+ MII_BMCR_CTST);
112
/* Complete autonegotiation immediately. */
113
- if (val & 0x1000) {
114
- s->status |= 0x0020;
115
+ if (val & MII_BMCR_AUTOEN) {
116
+ s->status |= MII_BMSR_AN_COMP;
117
}
102
}
118
}
103
break;
119
break;
104
default:
120
- case 4: /* Auto-neg advertisement */
105
+ case 0x02: /* SDOT (vector) */
121
- s->advertise = (val & 0x2d7f) | 0x80;
106
case 0x10: /* SQRDMLAH (vector) */
122
+ case MII_ANAR:
107
case 0x11: /* SQRDMLSH (vector) */
123
+ s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
108
+ case 0x12: /* UDOT (vector) */
124
+ MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
109
unallocated_encoding(s);
125
+ MII_ANAR_SELECT))
110
return;
126
+ | MII_ANAR_TX;
127
break;
128
case 30: /* Interrupt mask */
129
s->int_mask = val & 0xff;
130
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
131
/* Autonegotiation status mirrors link status. */
132
if (link_down) {
133
trace_lan9118_phy_update_link("down");
134
- s->status &= ~0x0024;
135
+ s->status &= ~(MII_BMSR_AN_COMP | MII_BMSR_LINK_ST);
136
s->ints |= PHY_INT_DOWN;
137
} else {
138
trace_lan9118_phy_update_link("up");
139
- s->status |= 0x0024;
140
+ s->status |= MII_BMSR_AN_COMP | MII_BMSR_LINK_ST;
141
s->ints |= PHY_INT_ENERGYON;
142
s->ints |= PHY_INT_AUTONEG_COMPLETE;
111
}
143
}
112
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
144
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_reset(Lan9118PhyState *s)
113
}
145
{
114
146
trace_lan9118_phy_reset();
115
switch (opcode) {
147
116
- case 0x2: /* SDOT / UDOT */
148
- s->control = 0x3000;
117
- gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0,
149
- s->status = 0x7809;
118
- u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b);
150
- s->advertise = 0x01e1;
119
- return;
151
+ s->control = MII_BMCR_AUTOEN | MII_BMCR_SPEED100;
120
-
152
+ s->status = MII_BMSR_100TX_FD
121
case 0x3: /* USDOT */
153
+ | MII_BMSR_100TX_HD
122
gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_usdot_b);
154
+ | MII_BMSR_10T_FD
123
return;
155
+ | MII_BMSR_10T_HD
124
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
156
+ | MII_BMSR_AUTONEG
125
case 0x0b: /* SQDMULL, SQDMULL2 */
157
+ | MII_BMSR_EXTCAP;
126
is_long = true;
158
+ s->advertise = MII_ANAR_TXFD
127
break;
159
+ | MII_ANAR_TX
128
- case 0x0e: /* SDOT */
160
+ | MII_ANAR_10FD
129
- case 0x1e: /* UDOT */
161
+ | MII_ANAR_10
130
- if (is_scalar || size != MO_32 || !dc_isar_feature(aa64_dp, s)) {
162
+ | MII_ANAR_CSMACD;
131
- unallocated_encoding(s);
163
s->int_mask = 0;
132
- return;
164
s->ints = 0;
133
- }
165
lan9118_phy_update_link(s, s->link_down);
134
- break;
135
case 0x0f:
136
switch (size) {
137
case 0: /* SUDOT */
138
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
139
case 0x09: /* FMUL */
140
case 0x0c: /* SQDMULH */
141
case 0x0d: /* SQRDMULH */
142
+ case 0x0e: /* SDOT */
143
case 0x10: /* MLA */
144
case 0x14: /* MLS */
145
case 0x18: /* FMLAL2 */
146
case 0x19: /* FMULX */
147
case 0x1c: /* FMLSL2 */
148
case 0x1d: /* SQRDMLAH */
149
+ case 0x1e: /* UDOT */
150
case 0x1f: /* SQRDMLSH */
151
unallocated_encoding(s);
152
return;
153
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
154
}
155
156
switch (16 * u + opcode) {
157
- case 0x0e: /* SDOT */
158
- case 0x1e: /* UDOT */
159
- gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
160
- u ? gen_helper_gvec_udot_idx_b
161
- : gen_helper_gvec_sdot_idx_b);
162
- return;
163
case 0x0f:
164
switch (extract32(insn, 22, 2)) {
165
case 0: /* SUDOT */
166
--
166
--
167
2.34.1
167
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Bernhard Beschow <shentey@gmail.com>
2
3
The real device advertises this mode and the device model already advertises
4
100 mbps half duplex and 10 mbps full+half duplex. So advertise this mode to
5
make the model more realistic.
2
6
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
5
Message-id: 20240625183536.1672454-11-richard.henderson@linaro.org
9
Tested-by: Guenter Roeck <linux@roeck-us.net>
10
Message-id: 20241102125724.532843-6-shentey@gmail.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
target/arm/tcg/translate-a64.c | 52 +++++++++++++++++-----------------
13
hw/net/lan9118_phy.c | 4 ++--
9
1 file changed, 26 insertions(+), 26 deletions(-)
14
1 file changed, 2 insertions(+), 2 deletions(-)
10
15
11
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/tcg/translate-a64.c
18
--- a/hw/net/lan9118_phy.c
14
+++ b/target/arm/tcg/translate-a64.c
19
+++ b/hw/net/lan9118_phy.c
15
@@ -XXX,XX +XXX,XX @@ TRANS(CMHS_s, do_cmop_d, a, TCG_COND_GEU)
20
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
16
TRANS(CMEQ_s, do_cmop_d, a, TCG_COND_EQ)
21
break;
17
TRANS(CMTST_s, do_cmop_d, a, TCG_COND_TSTNE)
22
case MII_ANAR:
18
23
s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
19
-static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a,
24
- MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
20
+static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a, int data,
25
- MII_ANAR_SELECT))
21
gen_helper_gvec_3_ptr * const fns[3])
26
+ MII_ANAR_PAUSE | MII_ANAR_TXFD | MII_ANAR_10FD |
22
{
27
+ MII_ANAR_10 | MII_ANAR_SELECT))
23
MemOp esz = a->esz;
28
| MII_ANAR_TX;
24
@@ -XXX,XX +XXX,XX @@ static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a,
29
break;
25
}
30
case 30: /* Interrupt mask */
26
if (fp_access_check(s)) {
27
gen_gvec_op3_fpst(s, a->q, a->rd, a->rn, a->rm,
28
- esz == MO_16, 0, fns[esz - 1]);
29
+ esz == MO_16, data, fns[esz - 1]);
30
}
31
return true;
32
}
33
@@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3_ptr * const f_vector_fadd[3] = {
34
gen_helper_gvec_fadd_s,
35
gen_helper_gvec_fadd_d,
36
};
37
-TRANS(FADD_v, do_fp3_vector, a, f_vector_fadd)
38
+TRANS(FADD_v, do_fp3_vector, a, 0, f_vector_fadd)
39
40
static gen_helper_gvec_3_ptr * const f_vector_fsub[3] = {
41
gen_helper_gvec_fsub_h,
42
gen_helper_gvec_fsub_s,
43
gen_helper_gvec_fsub_d,
44
};
45
-TRANS(FSUB_v, do_fp3_vector, a, f_vector_fsub)
46
+TRANS(FSUB_v, do_fp3_vector, a, 0, f_vector_fsub)
47
48
static gen_helper_gvec_3_ptr * const f_vector_fdiv[3] = {
49
gen_helper_gvec_fdiv_h,
50
gen_helper_gvec_fdiv_s,
51
gen_helper_gvec_fdiv_d,
52
};
53
-TRANS(FDIV_v, do_fp3_vector, a, f_vector_fdiv)
54
+TRANS(FDIV_v, do_fp3_vector, a, 0, f_vector_fdiv)
55
56
static gen_helper_gvec_3_ptr * const f_vector_fmul[3] = {
57
gen_helper_gvec_fmul_h,
58
gen_helper_gvec_fmul_s,
59
gen_helper_gvec_fmul_d,
60
};
61
-TRANS(FMUL_v, do_fp3_vector, a, f_vector_fmul)
62
+TRANS(FMUL_v, do_fp3_vector, a, 0, f_vector_fmul)
63
64
static gen_helper_gvec_3_ptr * const f_vector_fmax[3] = {
65
gen_helper_gvec_fmax_h,
66
gen_helper_gvec_fmax_s,
67
gen_helper_gvec_fmax_d,
68
};
69
-TRANS(FMAX_v, do_fp3_vector, a, f_vector_fmax)
70
+TRANS(FMAX_v, do_fp3_vector, a, 0, f_vector_fmax)
71
72
static gen_helper_gvec_3_ptr * const f_vector_fmin[3] = {
73
gen_helper_gvec_fmin_h,
74
gen_helper_gvec_fmin_s,
75
gen_helper_gvec_fmin_d,
76
};
77
-TRANS(FMIN_v, do_fp3_vector, a, f_vector_fmin)
78
+TRANS(FMIN_v, do_fp3_vector, a, 0, f_vector_fmin)
79
80
static gen_helper_gvec_3_ptr * const f_vector_fmaxnm[3] = {
81
gen_helper_gvec_fmaxnum_h,
82
gen_helper_gvec_fmaxnum_s,
83
gen_helper_gvec_fmaxnum_d,
84
};
85
-TRANS(FMAXNM_v, do_fp3_vector, a, f_vector_fmaxnm)
86
+TRANS(FMAXNM_v, do_fp3_vector, a, 0, f_vector_fmaxnm)
87
88
static gen_helper_gvec_3_ptr * const f_vector_fminnm[3] = {
89
gen_helper_gvec_fminnum_h,
90
gen_helper_gvec_fminnum_s,
91
gen_helper_gvec_fminnum_d,
92
};
93
-TRANS(FMINNM_v, do_fp3_vector, a, f_vector_fminnm)
94
+TRANS(FMINNM_v, do_fp3_vector, a, 0, f_vector_fminnm)
95
96
static gen_helper_gvec_3_ptr * const f_vector_fmulx[3] = {
97
gen_helper_gvec_fmulx_h,
98
gen_helper_gvec_fmulx_s,
99
gen_helper_gvec_fmulx_d,
100
};
101
-TRANS(FMULX_v, do_fp3_vector, a, f_vector_fmulx)
102
+TRANS(FMULX_v, do_fp3_vector, a, 0, f_vector_fmulx)
103
104
static gen_helper_gvec_3_ptr * const f_vector_fmla[3] = {
105
gen_helper_gvec_vfma_h,
106
gen_helper_gvec_vfma_s,
107
gen_helper_gvec_vfma_d,
108
};
109
-TRANS(FMLA_v, do_fp3_vector, a, f_vector_fmla)
110
+TRANS(FMLA_v, do_fp3_vector, a, 0, f_vector_fmla)
111
112
static gen_helper_gvec_3_ptr * const f_vector_fmls[3] = {
113
gen_helper_gvec_vfms_h,
114
gen_helper_gvec_vfms_s,
115
gen_helper_gvec_vfms_d,
116
};
117
-TRANS(FMLS_v, do_fp3_vector, a, f_vector_fmls)
118
+TRANS(FMLS_v, do_fp3_vector, a, 0, f_vector_fmls)
119
120
static gen_helper_gvec_3_ptr * const f_vector_fcmeq[3] = {
121
gen_helper_gvec_fceq_h,
122
gen_helper_gvec_fceq_s,
123
gen_helper_gvec_fceq_d,
124
};
125
-TRANS(FCMEQ_v, do_fp3_vector, a, f_vector_fcmeq)
126
+TRANS(FCMEQ_v, do_fp3_vector, a, 0, f_vector_fcmeq)
127
128
static gen_helper_gvec_3_ptr * const f_vector_fcmge[3] = {
129
gen_helper_gvec_fcge_h,
130
gen_helper_gvec_fcge_s,
131
gen_helper_gvec_fcge_d,
132
};
133
-TRANS(FCMGE_v, do_fp3_vector, a, f_vector_fcmge)
134
+TRANS(FCMGE_v, do_fp3_vector, a, 0, f_vector_fcmge)
135
136
static gen_helper_gvec_3_ptr * const f_vector_fcmgt[3] = {
137
gen_helper_gvec_fcgt_h,
138
gen_helper_gvec_fcgt_s,
139
gen_helper_gvec_fcgt_d,
140
};
141
-TRANS(FCMGT_v, do_fp3_vector, a, f_vector_fcmgt)
142
+TRANS(FCMGT_v, do_fp3_vector, a, 0, f_vector_fcmgt)
143
144
static gen_helper_gvec_3_ptr * const f_vector_facge[3] = {
145
gen_helper_gvec_facge_h,
146
gen_helper_gvec_facge_s,
147
gen_helper_gvec_facge_d,
148
};
149
-TRANS(FACGE_v, do_fp3_vector, a, f_vector_facge)
150
+TRANS(FACGE_v, do_fp3_vector, a, 0, f_vector_facge)
151
152
static gen_helper_gvec_3_ptr * const f_vector_facgt[3] = {
153
gen_helper_gvec_facgt_h,
154
gen_helper_gvec_facgt_s,
155
gen_helper_gvec_facgt_d,
156
};
157
-TRANS(FACGT_v, do_fp3_vector, a, f_vector_facgt)
158
+TRANS(FACGT_v, do_fp3_vector, a, 0, f_vector_facgt)
159
160
static gen_helper_gvec_3_ptr * const f_vector_fabd[3] = {
161
gen_helper_gvec_fabd_h,
162
gen_helper_gvec_fabd_s,
163
gen_helper_gvec_fabd_d,
164
};
165
-TRANS(FABD_v, do_fp3_vector, a, f_vector_fabd)
166
+TRANS(FABD_v, do_fp3_vector, a, 0, f_vector_fabd)
167
168
static gen_helper_gvec_3_ptr * const f_vector_frecps[3] = {
169
gen_helper_gvec_recps_h,
170
gen_helper_gvec_recps_s,
171
gen_helper_gvec_recps_d,
172
};
173
-TRANS(FRECPS_v, do_fp3_vector, a, f_vector_frecps)
174
+TRANS(FRECPS_v, do_fp3_vector, a, 0, f_vector_frecps)
175
176
static gen_helper_gvec_3_ptr * const f_vector_frsqrts[3] = {
177
gen_helper_gvec_rsqrts_h,
178
gen_helper_gvec_rsqrts_s,
179
gen_helper_gvec_rsqrts_d,
180
};
181
-TRANS(FRSQRTS_v, do_fp3_vector, a, f_vector_frsqrts)
182
+TRANS(FRSQRTS_v, do_fp3_vector, a, 0, f_vector_frsqrts)
183
184
static gen_helper_gvec_3_ptr * const f_vector_faddp[3] = {
185
gen_helper_gvec_faddp_h,
186
gen_helper_gvec_faddp_s,
187
gen_helper_gvec_faddp_d,
188
};
189
-TRANS(FADDP_v, do_fp3_vector, a, f_vector_faddp)
190
+TRANS(FADDP_v, do_fp3_vector, a, 0, f_vector_faddp)
191
192
static gen_helper_gvec_3_ptr * const f_vector_fmaxp[3] = {
193
gen_helper_gvec_fmaxp_h,
194
gen_helper_gvec_fmaxp_s,
195
gen_helper_gvec_fmaxp_d,
196
};
197
-TRANS(FMAXP_v, do_fp3_vector, a, f_vector_fmaxp)
198
+TRANS(FMAXP_v, do_fp3_vector, a, 0, f_vector_fmaxp)
199
200
static gen_helper_gvec_3_ptr * const f_vector_fminp[3] = {
201
gen_helper_gvec_fminp_h,
202
gen_helper_gvec_fminp_s,
203
gen_helper_gvec_fminp_d,
204
};
205
-TRANS(FMINP_v, do_fp3_vector, a, f_vector_fminp)
206
+TRANS(FMINP_v, do_fp3_vector, a, 0, f_vector_fminp)
207
208
static gen_helper_gvec_3_ptr * const f_vector_fmaxnmp[3] = {
209
gen_helper_gvec_fmaxnump_h,
210
gen_helper_gvec_fmaxnump_s,
211
gen_helper_gvec_fmaxnump_d,
212
};
213
-TRANS(FMAXNMP_v, do_fp3_vector, a, f_vector_fmaxnmp)
214
+TRANS(FMAXNMP_v, do_fp3_vector, a, 0, f_vector_fmaxnmp)
215
216
static gen_helper_gvec_3_ptr * const f_vector_fminnmp[3] = {
217
gen_helper_gvec_fminnump_h,
218
gen_helper_gvec_fminnump_s,
219
gen_helper_gvec_fminnump_d,
220
};
221
-TRANS(FMINNMP_v, do_fp3_vector, a, f_vector_fminnmp)
222
+TRANS(FMINNMP_v, do_fp3_vector, a, 0, f_vector_fminnmp)
223
224
static bool do_fmlal(DisasContext *s, arg_qrrr_e *a, bool is_s, bool is_2)
225
{
226
--
31
--
227
2.34.1
32
2.34.1
diff view generated by jsdifflib
New patch
1
For IEEE fused multiply-add, the (0 * inf) + NaN case should raise
2
Invalid for the multiplication of 0 by infinity. Currently we handle
3
this in the per-architecture ifdef ladder in pickNaNMulAdd().
4
However, since this isn't really architecture specific we can hoist
5
it up to the generic code.
1
6
7
For the cases where the infzero test in pickNaNMulAdd was
8
returning 2, we can delete the check entirely and allow the
9
code to fall into the normal pick-a-NaN handling, because this
10
will return 2 anyway (input 'c' being the only NaN in this case).
11
For the cases where infzero was returning 3 to indicate "return
12
the default NaN", we must retain that "return 3".
13
14
For Arm, this looks like it might be a behaviour change because we
15
used to set float_flag_invalid | float_flag_invalid_imz only if C is
16
a quiet NaN. However, it is not, because Arm target code never looks
17
at float_flag_invalid_imz, and for the (0 * inf) + SNaN case we
18
already raised float_flag_invalid via the "abc_mask &
19
float_cmask_snan" check in pick_nan_muladd.
20
21
For any target architecture using the "default implementation" at the
22
bottom of the ifdef, this is a behaviour change but will be fixing a
23
bug (where we failed to raise the Invalid exception for (0 * inf +
24
QNaN). The architectures using the default case are:
25
* hppa
26
* i386
27
* sh4
28
* tricore
29
30
The x86, Tricore and SH4 CPU architecture manuals are clear that this
31
should have raised Invalid; HPPA is a bit vaguer but still seems
32
clear enough.
33
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
36
Message-id: 20241202131347.498124-2-peter.maydell@linaro.org
37
---
38
fpu/softfloat-parts.c.inc | 13 +++++++------
39
fpu/softfloat-specialize.c.inc | 29 +----------------------------
40
2 files changed, 8 insertions(+), 34 deletions(-)
41
42
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
43
index XXXXXXX..XXXXXXX 100644
44
--- a/fpu/softfloat-parts.c.inc
45
+++ b/fpu/softfloat-parts.c.inc
46
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
47
int ab_mask, int abc_mask)
48
{
49
int which;
50
+ bool infzero = (ab_mask == float_cmask_infzero);
51
52
if (unlikely(abc_mask & float_cmask_snan)) {
53
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
54
}
55
56
- which = pickNaNMulAdd(a->cls, b->cls, c->cls,
57
- ab_mask == float_cmask_infzero, s);
58
+ if (infzero) {
59
+ /* This is (0 * inf) + NaN or (inf * 0) + NaN */
60
+ float_raise(float_flag_invalid | float_flag_invalid_imz, s);
61
+ }
62
+
63
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
64
65
if (s->default_nan_mode || which == 3) {
66
- /*
67
- * Note that this check is after pickNaNMulAdd so that function
68
- * has an opportunity to set the Invalid flag for infzero.
69
- */
70
parts_default_nan(a, s);
71
return a;
72
}
73
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
74
index XXXXXXX..XXXXXXX 100644
75
--- a/fpu/softfloat-specialize.c.inc
76
+++ b/fpu/softfloat-specialize.c.inc
77
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
78
* the default NaN
79
*/
80
if (infzero && is_qnan(c_cls)) {
81
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
82
return 3;
83
}
84
85
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
86
* case sets InvalidOp and returns the default NaN
87
*/
88
if (infzero) {
89
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
90
return 3;
91
}
92
/* Prefer sNaN over qNaN, in the a, b, c order. */
93
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
94
* For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
95
* case sets InvalidOp and returns the input value 'c'
96
*/
97
- if (infzero) {
98
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
99
- return 2;
100
- }
101
/* Prefer sNaN over qNaN, in the c, a, b order. */
102
if (is_snan(c_cls)) {
103
return 2;
104
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
105
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
106
* case sets InvalidOp and returns the input value 'c'
107
*/
108
- if (infzero) {
109
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
110
- return 2;
111
- }
112
+
113
/* Prefer sNaN over qNaN, in the c, a, b order. */
114
if (is_snan(c_cls)) {
115
return 2;
116
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
117
* to return an input NaN if we have one (ie c) rather than generating
118
* a default NaN
119
*/
120
- if (infzero) {
121
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
122
- return 2;
123
- }
124
125
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
126
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
127
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
128
return 1;
129
}
130
#elif defined(TARGET_RISCV)
131
- /* For RISC-V, InvalidOp is set when multiplicands are Inf and zero */
132
- if (infzero) {
133
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
134
- }
135
return 3; /* default NaN */
136
#elif defined(TARGET_S390X)
137
if (infzero) {
138
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
139
return 3;
140
}
141
142
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
143
return 2;
144
}
145
#elif defined(TARGET_SPARC)
146
- /* For (inf,0,nan) return c. */
147
- if (infzero) {
148
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
149
- return 2;
150
- }
151
/* Prefer SNaN over QNaN, order C, B, A. */
152
if (is_snan(c_cls)) {
153
return 2;
154
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
155
* For Xtensa, the (inf,zero,nan) case sets InvalidOp and returns
156
* an input NaN if we have one (ie c).
157
*/
158
- if (infzero) {
159
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
160
- return 2;
161
- }
162
if (status->use_first_nan) {
163
if (is_nan(a_cls)) {
164
return 0;
165
--
166
2.34.1
diff view generated by jsdifflib
New patch
1
If the target sets default_nan_mode then we're always going to return
2
the default NaN, and pickNaNMulAdd() no longer has any side effects.
3
For consistency with pickNaN(), check for default_nan_mode before
4
calling pickNaNMulAdd().
1
5
6
When we convert pickNaNMulAdd() to allow runtime selection of the NaN
7
propagation rule, this means we won't have to make the targets which
8
use default_nan_mode also set a propagation rule.
9
10
Since RiscV always uses default_nan_mode, this allows us to remove
11
its ifdef case from pickNaNMulAdd().
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20241202131347.498124-3-peter.maydell@linaro.org
16
---
17
fpu/softfloat-parts.c.inc | 8 ++++++--
18
fpu/softfloat-specialize.c.inc | 9 +++++++--
19
2 files changed, 13 insertions(+), 4 deletions(-)
20
21
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
22
index XXXXXXX..XXXXXXX 100644
23
--- a/fpu/softfloat-parts.c.inc
24
+++ b/fpu/softfloat-parts.c.inc
25
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
26
float_raise(float_flag_invalid | float_flag_invalid_imz, s);
27
}
28
29
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
30
+ if (s->default_nan_mode) {
31
+ which = 3;
32
+ } else {
33
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
34
+ }
35
36
- if (s->default_nan_mode || which == 3) {
37
+ if (which == 3) {
38
parts_default_nan(a, s);
39
return a;
40
}
41
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
42
index XXXXXXX..XXXXXXX 100644
43
--- a/fpu/softfloat-specialize.c.inc
44
+++ b/fpu/softfloat-specialize.c.inc
45
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
46
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
47
bool infzero, float_status *status)
48
{
49
+ /*
50
+ * We guarantee not to require the target to tell us how to
51
+ * pick a NaN if we're always returning the default NaN.
52
+ * But if we're not in default-NaN mode then the target must
53
+ * specify.
54
+ */
55
+ assert(!status->default_nan_mode);
56
#if defined(TARGET_ARM)
57
/* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
58
* the default NaN
59
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
60
} else {
61
return 1;
62
}
63
-#elif defined(TARGET_RISCV)
64
- return 3; /* default NaN */
65
#elif defined(TARGET_S390X)
66
if (infzero) {
67
return 3;
68
--
69
2.34.1
diff view generated by jsdifflib
New patch
1
1
IEEE 758 does not define a fixed rule for what NaN to return in
2
the case of a fused multiply-add of inf * 0 + NaN. Different
3
architectures thus do different things:
4
* some return the default NaN
5
* some return the input NaN
6
* Arm returns the default NaN if the input NaN is quiet,
7
and the input NaN if it is signalling
8
9
We want to make this logic be runtime selected rather than
10
hardcoded into the binary, because:
11
* this will let us have multiple targets in one QEMU binary
12
* the Arm FEAT_AFP architectural feature includes letting
13
the guest select a NaN propagation rule at runtime
14
15
In this commit we add an enum for the propagation rule, the field in
16
float_status, and the corresponding getters and setters. We change
17
pickNaNMulAdd to honour this, but because all targets still leave
18
this field at its default 0 value, the fallback logic will pick the
19
rule type with the old ifdef ladder.
20
21
Note that four architectures both use the muladd softfloat functions
22
and did not have a branch of the ifdef ladder to specify their
23
behaviour (and so were ending up with the "default" case, probably
24
wrongly): i386, HPPA, SH4 and Tricore. SH4 and Tricore both set
25
default_nan_mode, and so will never get into pickNaNMulAdd(). For
26
HPPA and i386 we retain the same behaviour as the old default-case,
27
which is to not ever return the default NaN. This might not be
28
correct but it is not a behaviour change.
29
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
Message-id: 20241202131347.498124-4-peter.maydell@linaro.org
33
---
34
include/fpu/softfloat-helpers.h | 11 ++++
35
include/fpu/softfloat-types.h | 23 +++++++++
36
fpu/softfloat-specialize.c.inc | 91 ++++++++++++++++++++++-----------
37
3 files changed, 95 insertions(+), 30 deletions(-)
38
39
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/include/fpu/softfloat-helpers.h
42
+++ b/include/fpu/softfloat-helpers.h
43
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
44
status->float_2nan_prop_rule = rule;
45
}
46
47
+static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
48
+ float_status *status)
49
+{
50
+ status->float_infzeronan_rule = rule;
51
+}
52
+
53
static inline void set_flush_to_zero(bool val, float_status *status)
54
{
55
status->flush_to_zero = val;
56
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
57
return status->float_2nan_prop_rule;
58
}
59
60
+static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
61
+{
62
+ return status->float_infzeronan_rule;
63
+}
64
+
65
static inline bool get_flush_to_zero(float_status *status)
66
{
67
return status->flush_to_zero;
68
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
69
index XXXXXXX..XXXXXXX 100644
70
--- a/include/fpu/softfloat-types.h
71
+++ b/include/fpu/softfloat-types.h
72
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
73
float_2nan_prop_x87,
74
} Float2NaNPropRule;
75
76
+/*
77
+ * Rule for result of fused multiply-add 0 * Inf + NaN.
78
+ * This must be a NaN, but implementations differ on whether this
79
+ * is the input NaN or the default NaN.
80
+ *
81
+ * You don't need to set this if default_nan_mode is enabled.
82
+ * When not in default-NaN mode, it is an error for the target
83
+ * not to set the rule in float_status if it uses muladd, and we
84
+ * will assert if we need to handle an input NaN and no rule was
85
+ * selected.
86
+ */
87
+typedef enum __attribute__((__packed__)) {
88
+ /* No propagation rule specified */
89
+ float_infzeronan_none = 0,
90
+ /* Result is never the default NaN (so always the input NaN) */
91
+ float_infzeronan_dnan_never,
92
+ /* Result is always the default NaN */
93
+ float_infzeronan_dnan_always,
94
+ /* Result is the default NaN if the input NaN is quiet */
95
+ float_infzeronan_dnan_if_qnan,
96
+} FloatInfZeroNaNRule;
97
+
98
/*
99
* Floating Point Status. Individual architectures may maintain
100
* several versions of float_status for different functions. The
101
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
102
FloatRoundMode float_rounding_mode;
103
FloatX80RoundPrec floatx80_rounding_precision;
104
Float2NaNPropRule float_2nan_prop_rule;
105
+ FloatInfZeroNaNRule float_infzeronan_rule;
106
bool tininess_before_rounding;
107
/* should denormalised results go to zero and set the inexact flag? */
108
bool flush_to_zero;
109
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
110
index XXXXXXX..XXXXXXX 100644
111
--- a/fpu/softfloat-specialize.c.inc
112
+++ b/fpu/softfloat-specialize.c.inc
113
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
114
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
115
bool infzero, float_status *status)
116
{
117
+ FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
118
+
119
/*
120
* We guarantee not to require the target to tell us how to
121
* pick a NaN if we're always returning the default NaN.
122
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
123
* specify.
124
*/
125
assert(!status->default_nan_mode);
126
+
127
+ if (rule == float_infzeronan_none) {
128
+ /*
129
+ * Temporarily fall back to ifdef ladder
130
+ */
131
#if defined(TARGET_ARM)
132
- /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
133
- * the default NaN
134
- */
135
- if (infzero && is_qnan(c_cls)) {
136
- return 3;
137
+ /*
138
+ * For ARM, the (inf,zero,qnan) case returns the default NaN,
139
+ * but (inf,zero,snan) returns the input NaN.
140
+ */
141
+ rule = float_infzeronan_dnan_if_qnan;
142
+#elif defined(TARGET_MIPS)
143
+ if (snan_bit_is_one(status)) {
144
+ /*
145
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
146
+ * case sets InvalidOp and returns the default NaN
147
+ */
148
+ rule = float_infzeronan_dnan_always;
149
+ } else {
150
+ /*
151
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
152
+ * case sets InvalidOp and returns the input value 'c'
153
+ */
154
+ rule = float_infzeronan_dnan_never;
155
+ }
156
+#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
157
+ defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
158
+ defined(TARGET_I386) || defined(TARGET_LOONGARCH)
159
+ /*
160
+ * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
161
+ * case sets InvalidOp and returns the input value 'c'
162
+ */
163
+ /*
164
+ * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
165
+ * to return an input NaN if we have one (ie c) rather than generating
166
+ * a default NaN
167
+ */
168
+ rule = float_infzeronan_dnan_never;
169
+#elif defined(TARGET_S390X)
170
+ rule = float_infzeronan_dnan_always;
171
+#endif
172
}
173
174
+ if (infzero) {
175
+ /*
176
+ * Inf * 0 + NaN -- some implementations return the default NaN here,
177
+ * and some return the input NaN.
178
+ */
179
+ switch (rule) {
180
+ case float_infzeronan_dnan_never:
181
+ return 2;
182
+ case float_infzeronan_dnan_always:
183
+ return 3;
184
+ case float_infzeronan_dnan_if_qnan:
185
+ return is_qnan(c_cls) ? 3 : 2;
186
+ default:
187
+ g_assert_not_reached();
188
+ }
189
+ }
190
+
191
+#if defined(TARGET_ARM)
192
+
193
/* This looks different from the ARM ARM pseudocode, because the ARM ARM
194
* puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
195
*/
196
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
197
}
198
#elif defined(TARGET_MIPS)
199
if (snan_bit_is_one(status)) {
200
- /*
201
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
202
- * case sets InvalidOp and returns the default NaN
203
- */
204
- if (infzero) {
205
- return 3;
206
- }
207
/* Prefer sNaN over qNaN, in the a, b, c order. */
208
if (is_snan(a_cls)) {
209
return 0;
210
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
211
return 2;
212
}
213
} else {
214
- /*
215
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
216
- * case sets InvalidOp and returns the input value 'c'
217
- */
218
/* Prefer sNaN over qNaN, in the c, a, b order. */
219
if (is_snan(c_cls)) {
220
return 2;
221
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
222
}
223
}
224
#elif defined(TARGET_LOONGARCH64)
225
- /*
226
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
227
- * case sets InvalidOp and returns the input value 'c'
228
- */
229
-
230
/* Prefer sNaN over qNaN, in the c, a, b order. */
231
if (is_snan(c_cls)) {
232
return 2;
233
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
234
return 1;
235
}
236
#elif defined(TARGET_PPC)
237
- /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
238
- * to return an input NaN if we have one (ie c) rather than generating
239
- * a default NaN
240
- */
241
-
242
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
243
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
244
*/
245
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
246
return 1;
247
}
248
#elif defined(TARGET_S390X)
249
- if (infzero) {
250
- return 3;
251
- }
252
-
253
if (is_snan(a_cls)) {
254
return 0;
255
} else if (is_snan(b_cls)) {
256
--
257
2.34.1
diff view generated by jsdifflib
New patch
1
Explicitly set a rule in the softfloat tests for the inf-zero-nan
2
muladd special case. In meson.build we put -DTARGET_ARM in fpcflags,
3
and so we should select here the Arm rule of
4
float_infzeronan_dnan_if_qnan.
1
5
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20241202131347.498124-5-peter.maydell@linaro.org
9
---
10
tests/fp/fp-bench.c | 5 +++++
11
tests/fp/fp-test.c | 5 +++++
12
2 files changed, 10 insertions(+)
13
14
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/fp/fp-bench.c
17
+++ b/tests/fp/fp-bench.c
18
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
19
{
20
bench_func_t f;
21
22
+ /*
23
+ * These implementation-defined choices for various things IEEE
24
+ * doesn't specify match those used by the Arm architecture.
25
+ */
26
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
27
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
28
29
f = bench_funcs[operation][precision];
30
g_assert(f);
31
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/tests/fp/fp-test.c
34
+++ b/tests/fp/fp-test.c
35
@@ -XXX,XX +XXX,XX @@ void run_test(void)
36
{
37
unsigned int i;
38
39
+ /*
40
+ * These implementation-defined choices for various things IEEE
41
+ * doesn't specify match those used by the Arm architecture.
42
+ */
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
44
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
45
46
genCases_setLevel(test_level);
47
verCases_maxErrorCount = n_max_errors;
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the Arm target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-6-peter.maydell@linaro.org
7
---
8
target/arm/cpu.c | 3 +++
9
fpu/softfloat-specialize.c.inc | 8 +-------
10
2 files changed, 4 insertions(+), 7 deletions(-)
11
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
16
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
17
* * tininess-before-rounding
18
* * 2-input NaN propagation prefers SNaN over QNaN, and then
19
* operand A over operand B (see FPProcessNaNs() pseudocode)
20
+ * * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
21
+ * and the input NaN if it is signalling
22
*/
23
static void arm_set_default_fp_behaviours(float_status *s)
24
{
25
set_float_detect_tininess(float_tininess_before_rounding, s);
26
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
27
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
28
}
29
30
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
31
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
32
index XXXXXXX..XXXXXXX 100644
33
--- a/fpu/softfloat-specialize.c.inc
34
+++ b/fpu/softfloat-specialize.c.inc
35
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
36
/*
37
* Temporarily fall back to ifdef ladder
38
*/
39
-#if defined(TARGET_ARM)
40
- /*
41
- * For ARM, the (inf,zero,qnan) case returns the default NaN,
42
- * but (inf,zero,snan) returns the input NaN.
43
- */
44
- rule = float_infzeronan_dnan_if_qnan;
45
-#elif defined(TARGET_MIPS)
46
+#if defined(TARGET_MIPS)
47
if (snan_bit_is_one(status)) {
48
/*
49
* For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
50
--
51
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for s390, so we
2
can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-7-peter.maydell@linaro.org
7
---
8
target/s390x/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/s390x/cpu.c
15
+++ b/target/s390x/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
17
set_float_detect_tininess(float_tininess_before_rounding,
18
&env->fpu_status);
19
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fpu_status);
20
+ set_float_infzeronan_rule(float_infzeronan_dnan_always,
21
+ &env->fpu_status);
22
/* fall through */
23
case RESET_TYPE_S390_CPU_NORMAL:
24
env->psw.mask &= ~PSW_MASK_RI;
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
* a default NaN
31
*/
32
rule = float_infzeronan_dnan_never;
33
-#elif defined(TARGET_S390X)
34
- rule = float_infzeronan_dnan_always;
35
#endif
36
}
37
38
--
39
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the PPC target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-8-peter.maydell@linaro.org
7
---
8
target/ppc/cpu_init.c | 7 +++++++
9
fpu/softfloat-specialize.c.inc | 7 +------
10
2 files changed, 8 insertions(+), 6 deletions(-)
11
12
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/ppc/cpu_init.c
15
+++ b/target/ppc/cpu_init.c
16
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->vec_status);
20
+ /*
21
+ * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
22
+ * to return an input NaN if we have one (ie c) rather than generating
23
+ * a default NaN
24
+ */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
26
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
27
28
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
29
ppc_spr_t *spr = &env->spr_cb[i];
30
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
31
index XXXXXXX..XXXXXXX 100644
32
--- a/fpu/softfloat-specialize.c.inc
33
+++ b/fpu/softfloat-specialize.c.inc
34
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
35
*/
36
rule = float_infzeronan_dnan_never;
37
}
38
-#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
39
+#elif defined(TARGET_SPARC) || \
40
defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
41
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
42
/*
43
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
44
* case sets InvalidOp and returns the input value 'c'
45
*/
46
- /*
47
- * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
48
- * to return an input NaN if we have one (ie c) rather than generating
49
- * a default NaN
50
- */
51
rule = float_infzeronan_dnan_never;
52
#endif
53
}
54
--
55
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the MIPS target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-9-peter.maydell@linaro.org
7
---
8
target/mips/fpu_helper.h | 9 +++++++++
9
target/mips/msa.c | 4 ++++
10
fpu/softfloat-specialize.c.inc | 16 +---------------
11
3 files changed, 14 insertions(+), 15 deletions(-)
12
13
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/mips/fpu_helper.h
16
+++ b/target/mips/fpu_helper.h
17
@@ -XXX,XX +XXX,XX @@ static inline void restore_flush_mode(CPUMIPSState *env)
18
static inline void restore_snan_bit_mode(CPUMIPSState *env)
19
{
20
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
21
+ FloatInfZeroNaNRule izn_rule;
22
23
/*
24
* With nan2008, SNaNs are silenced in the usual way.
25
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
26
*/
27
set_snan_bit_is_one(!nan2008, &env->active_fpu.fp_status);
28
set_default_nan_mode(!nan2008, &env->active_fpu.fp_status);
29
+ /*
30
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
31
+ * case sets InvalidOp and returns the default NaN.
32
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
33
+ * case sets InvalidOp and returns the input value 'c'.
34
+ */
35
+ izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
36
+ set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
37
}
38
39
static inline void restore_fp_status(CPUMIPSState *env)
40
diff --git a/target/mips/msa.c b/target/mips/msa.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/mips/msa.c
43
+++ b/target/mips/msa.c
44
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
45
46
/* set proper signanling bit meaning ("1" means "quiet") */
47
set_snan_bit_is_one(0, &env->active_tc.msa_fp_status);
48
+
49
+ /* Inf * 0 + NaN returns the input NaN */
50
+ set_float_infzeronan_rule(float_infzeronan_dnan_never,
51
+ &env->active_tc.msa_fp_status);
52
}
53
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
54
index XXXXXXX..XXXXXXX 100644
55
--- a/fpu/softfloat-specialize.c.inc
56
+++ b/fpu/softfloat-specialize.c.inc
57
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
58
/*
59
* Temporarily fall back to ifdef ladder
60
*/
61
-#if defined(TARGET_MIPS)
62
- if (snan_bit_is_one(status)) {
63
- /*
64
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
65
- * case sets InvalidOp and returns the default NaN
66
- */
67
- rule = float_infzeronan_dnan_always;
68
- } else {
69
- /*
70
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
71
- * case sets InvalidOp and returns the input value 'c'
72
- */
73
- rule = float_infzeronan_dnan_never;
74
- }
75
-#elif defined(TARGET_SPARC) || \
76
+#if defined(TARGET_SPARC) || \
77
defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
78
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
79
/*
80
--
81
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the SPARC target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-10-peter.maydell@linaro.org
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 +--
10
2 files changed, 3 insertions(+), 2 deletions(-)
11
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sparc/cpu.c
15
+++ b/target/sparc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
17
* the CPU state struct so it won't get zeroed on reset.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &env->fp_status);
20
+ /* For inf * 0 + NaN, return the input NaN */
21
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
23
cpu_exec_realizefn(cs, &local_err);
24
if (local_err != NULL) {
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
/*
31
* Temporarily fall back to ifdef ladder
32
*/
33
-#if defined(TARGET_SPARC) || \
34
- defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
35
+#if defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
36
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
37
/*
38
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the xtensa target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-11-peter.maydell@linaro.org
7
---
8
target/xtensa/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 +-
10
2 files changed, 3 insertions(+), 1 deletion(-)
11
12
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/xtensa/cpu.c
15
+++ b/target/xtensa/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
17
reset_mmu(env);
18
cs->halted = env->runstall;
19
#endif
20
+ /* For inf * 0 + NaN, return the input NaN */
21
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
set_no_signaling_nans(!dfpu, &env->fp_status);
23
xtensa_use_first_nan(env, !dfpu);
24
}
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
/*
31
* Temporarily fall back to ifdef ladder
32
*/
33
-#if defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
34
+#if defined(TARGET_HPPA) || \
35
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
36
/*
37
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
38
--
39
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the x86 target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-12-peter.maydell@linaro.org
6
---
7
target/i386/tcg/fpu_helper.c | 7 +++++++
8
fpu/softfloat-specialize.c.inc | 2 +-
9
2 files changed, 8 insertions(+), 1 deletion(-)
10
11
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/i386/tcg/fpu_helper.c
14
+++ b/target/i386/tcg/fpu_helper.c
15
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
16
*/
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->mmx_status);
18
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->sse_status);
19
+ /*
20
+ * Only SSE has multiply-add instructions. In the SDM Section 14.5.2
21
+ * "Fused-Multiply-ADD (FMA) Numeric Behavior" the NaN handling is
22
+ * specified -- for 0 * inf + NaN the input NaN is selected, and if
23
+ * there are multiple input NaNs they are selected in the order a, b, c.
24
+ */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
26
}
27
28
static inline uint8_t save_exception_flags(CPUX86State *env)
29
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
30
index XXXXXXX..XXXXXXX 100644
31
--- a/fpu/softfloat-specialize.c.inc
32
+++ b/fpu/softfloat-specialize.c.inc
33
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
34
* Temporarily fall back to ifdef ladder
35
*/
36
#if defined(TARGET_HPPA) || \
37
- defined(TARGET_I386) || defined(TARGET_LOONGARCH)
38
+ defined(TARGET_LOONGARCH)
39
/*
40
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
41
* case sets InvalidOp and returns the input value 'c'
42
--
43
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the loongarch target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-13-peter.maydell@linaro.org
6
---
7
target/loongarch/tcg/fpu_helper.c | 5 +++++
8
fpu/softfloat-specialize.c.inc | 7 +------
9
2 files changed, 6 insertions(+), 6 deletions(-)
10
11
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/loongarch/tcg/fpu_helper.c
14
+++ b/target/loongarch/tcg/fpu_helper.c
15
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
16
&env->fp_status);
17
set_flush_to_zero(0, &env->fp_status);
18
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
19
+ /*
20
+ * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
21
+ * case sets InvalidOp and returns the input value 'c'
22
+ */
23
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
}
25
26
int ieee_ex_to_loongarch(int xcpt)
27
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
28
index XXXXXXX..XXXXXXX 100644
29
--- a/fpu/softfloat-specialize.c.inc
30
+++ b/fpu/softfloat-specialize.c.inc
31
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
32
/*
33
* Temporarily fall back to ifdef ladder
34
*/
35
-#if defined(TARGET_HPPA) || \
36
- defined(TARGET_LOONGARCH)
37
- /*
38
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
39
- * case sets InvalidOp and returns the input value 'c'
40
- */
41
+#if defined(TARGET_HPPA)
42
rule = float_infzeronan_dnan_never;
43
#endif
44
}
45
--
46
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the HPPA target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
As this is the last target to be converted to explicitly setting
5
the rule, we can remove the fallback code in pickNaNMulAdd()
6
entirely.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20241202131347.498124-14-peter.maydell@linaro.org
11
---
12
target/hppa/fpu_helper.c | 2 ++
13
fpu/softfloat-specialize.c.inc | 13 +------------
14
2 files changed, 3 insertions(+), 12 deletions(-)
15
16
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/hppa/fpu_helper.c
19
+++ b/target/hppa/fpu_helper.c
20
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
21
* HPPA does note implement a CPU reset method at all...
22
*/
23
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
24
+ /* For inf * 0 + NaN, return the input NaN */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
26
}
27
28
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
29
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
30
index XXXXXXX..XXXXXXX 100644
31
--- a/fpu/softfloat-specialize.c.inc
32
+++ b/fpu/softfloat-specialize.c.inc
33
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
34
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
35
bool infzero, float_status *status)
36
{
37
- FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
38
-
39
/*
40
* We guarantee not to require the target to tell us how to
41
* pick a NaN if we're always returning the default NaN.
42
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
43
*/
44
assert(!status->default_nan_mode);
45
46
- if (rule == float_infzeronan_none) {
47
- /*
48
- * Temporarily fall back to ifdef ladder
49
- */
50
-#if defined(TARGET_HPPA)
51
- rule = float_infzeronan_dnan_never;
52
-#endif
53
- }
54
-
55
if (infzero) {
56
/*
57
* Inf * 0 + NaN -- some implementations return the default NaN here,
58
* and some return the input NaN.
59
*/
60
- switch (rule) {
61
+ switch (status->float_infzeronan_rule) {
62
case float_infzeronan_dnan_never:
63
return 2;
64
case float_infzeronan_dnan_always:
65
--
66
2.34.1
diff view generated by jsdifflib
New patch
1
The new implementation of pickNaNMulAdd() will find it convenient
2
to know whether at least one of the three arguments to the muladd
3
was a signaling NaN. We already calculate that in the caller,
4
so pass it in as a new bool have_snan.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-15-peter.maydell@linaro.org
9
---
10
fpu/softfloat-parts.c.inc | 5 +++--
11
fpu/softfloat-specialize.c.inc | 2 +-
12
2 files changed, 4 insertions(+), 3 deletions(-)
13
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
15
index XXXXXXX..XXXXXXX 100644
16
--- a/fpu/softfloat-parts.c.inc
17
+++ b/fpu/softfloat-parts.c.inc
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
19
{
20
int which;
21
bool infzero = (ab_mask == float_cmask_infzero);
22
+ bool have_snan = (abc_mask & float_cmask_snan);
23
24
- if (unlikely(abc_mask & float_cmask_snan)) {
25
+ if (unlikely(have_snan)) {
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
27
}
28
29
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
30
if (s->default_nan_mode) {
31
which = 3;
32
} else {
33
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
34
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, have_snan, s);
35
}
36
37
if (which == 3) {
38
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
39
index XXXXXXX..XXXXXXX 100644
40
--- a/fpu/softfloat-specialize.c.inc
41
+++ b/fpu/softfloat-specialize.c.inc
42
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
43
| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
44
*----------------------------------------------------------------------------*/
45
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
46
- bool infzero, float_status *status)
47
+ bool infzero, bool have_snan, float_status *status)
48
{
49
/*
50
* We guarantee not to require the target to tell us how to
51
--
52
2.34.1
diff view generated by jsdifflib
1
From: Rayhan Faizel <rayhan.faizel@gmail.com>
1
IEEE 758 does not define a fixed rule for which NaN to pick as the
2
2
result if both operands of a 3-operand fused multiply-add operation
3
Replace stubbed OTP memory region with the new OTP device.
3
are NaNs. As a result different architectures have ended up with
4
4
different rules for propagating NaNs.
5
Signed-off-by: Rayhan Faizel <rayhan.faizel@gmail.com>
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
QEMU currently hardcodes the NaN propagation logic into the binary
7
because pickNaNMulAdd() has an ifdef ladder for different targets.
8
We want to make the propagation rule instead be selectable at
9
runtime, because:
10
* this will let us have multiple targets in one QEMU binary
11
* the Arm FEAT_AFP architectural feature includes letting
12
the guest select a NaN propagation rule at runtime
13
14
In this commit we add an enum for the propagation rule, the field in
15
float_status, and the corresponding getters and setters. We change
16
pickNaNMulAdd to honour this, but because all targets still leave
17
this field at its default 0 value, the fallback logic will pick the
18
rule type with the old ifdef ladder.
19
20
It's valid not to set a propagation rule if default_nan_mode is
21
enabled, because in that case there's no need to pick a NaN; all the
22
callers of pickNaNMulAdd() catch this case and skip calling it.
23
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20241202131347.498124-16-peter.maydell@linaro.org
8
---
27
---
9
include/hw/arm/bcm2835_peripherals.h | 3 ++-
28
include/fpu/softfloat-helpers.h | 11 +++
10
hw/arm/bcm2835_peripherals.c | 13 ++++++++++++-
29
include/fpu/softfloat-types.h | 55 +++++++++++
11
2 files changed, 14 insertions(+), 2 deletions(-)
30
fpu/softfloat-specialize.c.inc | 167 ++++++++------------------------
12
31
3 files changed, 107 insertions(+), 126 deletions(-)
13
diff --git a/include/hw/arm/bcm2835_peripherals.h b/include/hw/arm/bcm2835_peripherals.h
32
33
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
14
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/bcm2835_peripherals.h
35
--- a/include/fpu/softfloat-helpers.h
16
+++ b/include/hw/arm/bcm2835_peripherals.h
36
+++ b/include/fpu/softfloat-helpers.h
17
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
18
#include "hw/usb/hcd-dwc2.h"
38
status->float_2nan_prop_rule = rule;
19
#include "hw/ssi/bcm2835_spi.h"
39
}
20
#include "hw/i2c/bcm2835_i2c.h"
40
21
+#include "hw/nvram/bcm2835_otp.h"
41
+static inline void set_float_3nan_prop_rule(Float3NaNPropRule rule,
22
#include "hw/misc/unimp.h"
42
+ float_status *status)
23
#include "qom/object.h"
43
+{
24
44
+ status->float_3nan_prop_rule = rule;
25
@@ -XXX,XX +XXX,XX @@ struct BCMSocPeripheralBaseState {
45
+}
26
BCM2835SPIState spi[1];
46
+
27
BCM2835I2CState i2c[3];
47
static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
28
OrIRQState orgated_i2c_irq;
48
float_status *status)
29
- UnimplementedDeviceState otp;
49
{
30
+ BCM2835OTPState otp;
50
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
31
UnimplementedDeviceState dbus;
51
return status->float_2nan_prop_rule;
32
UnimplementedDeviceState ave0;
52
}
33
UnimplementedDeviceState v3d;
53
34
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
54
+static inline Float3NaNPropRule get_float_3nan_prop_rule(float_status *status)
55
+{
56
+ return status->float_3nan_prop_rule;
57
+}
58
+
59
static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
60
{
61
return status->float_infzeronan_rule;
62
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
35
index XXXXXXX..XXXXXXX 100644
63
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/bcm2835_peripherals.c
64
--- a/include/fpu/softfloat-types.h
37
+++ b/hw/arm/bcm2835_peripherals.c
65
+++ b/include/fpu/softfloat-types.h
38
@@ -XXX,XX +XXX,XX @@ static void raspi_peripherals_base_init(Object *obj)
66
@@ -XXX,XX +XXX,XX @@ this code that are retained.
39
object_property_add_const_link(OBJECT(&s->fb), "dma-mr",
67
#ifndef SOFTFLOAT_TYPES_H
40
OBJECT(&s->gpu_bus_mr));
68
#define SOFTFLOAT_TYPES_H
41
69
42
+ /* OTP */
70
+#include "hw/registerfields.h"
43
+ object_initialize_child(obj, "bcm2835-otp", &s->otp,
71
+
44
+ TYPE_BCM2835_OTP);
72
/*
45
+
73
* Software IEC/IEEE floating-point types.
46
/* Property channel */
74
*/
47
object_initialize_child(obj, "property", &s->property,
75
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
48
TYPE_BCM2835_PROPERTY);
76
float_2nan_prop_x87,
49
@@ -XXX,XX +XXX,XX @@ void bcm_soc_peripherals_common_realize(DeviceState *dev, Error **errp)
77
} Float2NaNPropRule;
50
sysbus_connect_irq(SYS_BUS_DEVICE(&s->fb), 0,
78
51
qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_FB));
79
+/*
52
80
+ * 3-input NaN propagation rule, for fused multiply-add. Individual
53
+ /* OTP */
81
+ * architectures have different rules for which input NaN is
54
+ if (!sysbus_realize(SYS_BUS_DEVICE(&s->otp), errp)) {
82
+ * propagated to the output when there is more than one NaN on the
55
+ return;
83
+ * input.
84
+ *
85
+ * If default_nan_mode is enabled then it is valid not to set a NaN
86
+ * propagation rule, because the softfloat code guarantees not to try
87
+ * to pick a NaN to propagate in default NaN mode. When not in
88
+ * default-NaN mode, it is an error for the target not to set the rule
89
+ * in float_status if it uses a muladd, and we will assert if we need
90
+ * to handle an input NaN and no rule was selected.
91
+ *
92
+ * The naming scheme for Float3NaNPropRule values is:
93
+ * float_3nan_prop_s_abc:
94
+ * = "Prefer SNaN over QNaN, then operand A over B over C"
95
+ * float_3nan_prop_abc:
96
+ * = "Prefer A over B over C regardless of SNaN vs QNAN"
97
+ *
98
+ * For QEMU, the multiply-add operation is A * B + C.
99
+ */
100
+
101
+/*
102
+ * We set the Float3NaNPropRule enum values up so we can select the
103
+ * right value in pickNaNMulAdd in a data driven way.
104
+ */
105
+FIELD(3NAN, 1ST, 0, 2) /* which operand is most preferred ? */
106
+FIELD(3NAN, 2ND, 2, 2) /* which operand is next most preferred ? */
107
+FIELD(3NAN, 3RD, 4, 2) /* which operand is least preferred ? */
108
+FIELD(3NAN, SNAN, 6, 1) /* do we prefer SNaN over QNaN ? */
109
+
110
+#define PROPRULE(X, Y, Z) \
111
+ ((X << R_3NAN_1ST_SHIFT) | (Y << R_3NAN_2ND_SHIFT) | (Z << R_3NAN_3RD_SHIFT))
112
+
113
+typedef enum __attribute__((__packed__)) {
114
+ float_3nan_prop_none = 0, /* No propagation rule specified */
115
+ float_3nan_prop_abc = PROPRULE(0, 1, 2),
116
+ float_3nan_prop_acb = PROPRULE(0, 2, 1),
117
+ float_3nan_prop_bac = PROPRULE(1, 0, 2),
118
+ float_3nan_prop_bca = PROPRULE(1, 2, 0),
119
+ float_3nan_prop_cab = PROPRULE(2, 0, 1),
120
+ float_3nan_prop_cba = PROPRULE(2, 1, 0),
121
+ float_3nan_prop_s_abc = float_3nan_prop_abc | R_3NAN_SNAN_MASK,
122
+ float_3nan_prop_s_acb = float_3nan_prop_acb | R_3NAN_SNAN_MASK,
123
+ float_3nan_prop_s_bac = float_3nan_prop_bac | R_3NAN_SNAN_MASK,
124
+ float_3nan_prop_s_bca = float_3nan_prop_bca | R_3NAN_SNAN_MASK,
125
+ float_3nan_prop_s_cab = float_3nan_prop_cab | R_3NAN_SNAN_MASK,
126
+ float_3nan_prop_s_cba = float_3nan_prop_cba | R_3NAN_SNAN_MASK,
127
+} Float3NaNPropRule;
128
+
129
+#undef PROPRULE
130
+
131
/*
132
* Rule for result of fused multiply-add 0 * Inf + NaN.
133
* This must be a NaN, but implementations differ on whether this
134
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
135
FloatRoundMode float_rounding_mode;
136
FloatX80RoundPrec floatx80_rounding_precision;
137
Float2NaNPropRule float_2nan_prop_rule;
138
+ Float3NaNPropRule float_3nan_prop_rule;
139
FloatInfZeroNaNRule float_infzeronan_rule;
140
bool tininess_before_rounding;
141
/* should denormalised results go to zero and set the inexact flag? */
142
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
143
index XXXXXXX..XXXXXXX 100644
144
--- a/fpu/softfloat-specialize.c.inc
145
+++ b/fpu/softfloat-specialize.c.inc
146
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
147
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
148
bool infzero, bool have_snan, float_status *status)
149
{
150
+ FloatClass cls[3] = { a_cls, b_cls, c_cls };
151
+ Float3NaNPropRule rule = status->float_3nan_prop_rule;
152
+ int which;
153
+
154
/*
155
* We guarantee not to require the target to tell us how to
156
* pick a NaN if we're always returning the default NaN.
157
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
158
}
159
}
160
161
+ if (rule == float_3nan_prop_none) {
162
#if defined(TARGET_ARM)
163
-
164
- /* This looks different from the ARM ARM pseudocode, because the ARM ARM
165
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
166
- */
167
- if (is_snan(c_cls)) {
168
- return 2;
169
- } else if (is_snan(a_cls)) {
170
- return 0;
171
- } else if (is_snan(b_cls)) {
172
- return 1;
173
- } else if (is_qnan(c_cls)) {
174
- return 2;
175
- } else if (is_qnan(a_cls)) {
176
- return 0;
177
- } else {
178
- return 1;
179
- }
180
+ /*
181
+ * This looks different from the ARM ARM pseudocode, because the ARM ARM
182
+ * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
183
+ */
184
+ rule = float_3nan_prop_s_cab;
185
#elif defined(TARGET_MIPS)
186
- if (snan_bit_is_one(status)) {
187
- /* Prefer sNaN over qNaN, in the a, b, c order. */
188
- if (is_snan(a_cls)) {
189
- return 0;
190
- } else if (is_snan(b_cls)) {
191
- return 1;
192
- } else if (is_snan(c_cls)) {
193
- return 2;
194
- } else if (is_qnan(a_cls)) {
195
- return 0;
196
- } else if (is_qnan(b_cls)) {
197
- return 1;
198
+ if (snan_bit_is_one(status)) {
199
+ rule = float_3nan_prop_s_abc;
200
} else {
201
- return 2;
202
+ rule = float_3nan_prop_s_cab;
203
}
204
- } else {
205
- /* Prefer sNaN over qNaN, in the c, a, b order. */
206
- if (is_snan(c_cls)) {
207
- return 2;
208
- } else if (is_snan(a_cls)) {
209
- return 0;
210
- } else if (is_snan(b_cls)) {
211
- return 1;
212
- } else if (is_qnan(c_cls)) {
213
- return 2;
214
- } else if (is_qnan(a_cls)) {
215
- return 0;
216
- } else {
217
- return 1;
218
- }
219
- }
220
#elif defined(TARGET_LOONGARCH64)
221
- /* Prefer sNaN over qNaN, in the c, a, b order. */
222
- if (is_snan(c_cls)) {
223
- return 2;
224
- } else if (is_snan(a_cls)) {
225
- return 0;
226
- } else if (is_snan(b_cls)) {
227
- return 1;
228
- } else if (is_qnan(c_cls)) {
229
- return 2;
230
- } else if (is_qnan(a_cls)) {
231
- return 0;
232
- } else {
233
- return 1;
234
- }
235
+ rule = float_3nan_prop_s_cab;
236
#elif defined(TARGET_PPC)
237
- /* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
238
- * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
239
- */
240
- if (is_nan(a_cls)) {
241
- return 0;
242
- } else if (is_nan(c_cls)) {
243
- return 2;
244
- } else {
245
- return 1;
246
- }
247
+ /*
248
+ * If fRA is a NaN return it; otherwise if fRB is a NaN return it;
249
+ * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
250
+ */
251
+ rule = float_3nan_prop_acb;
252
#elif defined(TARGET_S390X)
253
- if (is_snan(a_cls)) {
254
- return 0;
255
- } else if (is_snan(b_cls)) {
256
- return 1;
257
- } else if (is_snan(c_cls)) {
258
- return 2;
259
- } else if (is_qnan(a_cls)) {
260
- return 0;
261
- } else if (is_qnan(b_cls)) {
262
- return 1;
263
- } else {
264
- return 2;
265
- }
266
+ rule = float_3nan_prop_s_abc;
267
#elif defined(TARGET_SPARC)
268
- /* Prefer SNaN over QNaN, order C, B, A. */
269
- if (is_snan(c_cls)) {
270
- return 2;
271
- } else if (is_snan(b_cls)) {
272
- return 1;
273
- } else if (is_snan(a_cls)) {
274
- return 0;
275
- } else if (is_qnan(c_cls)) {
276
- return 2;
277
- } else if (is_qnan(b_cls)) {
278
- return 1;
279
- } else {
280
- return 0;
281
- }
282
+ rule = float_3nan_prop_s_cba;
283
#elif defined(TARGET_XTENSA)
284
- /*
285
- * For Xtensa, the (inf,zero,nan) case sets InvalidOp and returns
286
- * an input NaN if we have one (ie c).
287
- */
288
- if (status->use_first_nan) {
289
- if (is_nan(a_cls)) {
290
- return 0;
291
- } else if (is_nan(b_cls)) {
292
- return 1;
293
+ if (status->use_first_nan) {
294
+ rule = float_3nan_prop_abc;
295
} else {
296
- return 2;
297
+ rule = float_3nan_prop_cba;
298
}
299
- } else {
300
- if (is_nan(c_cls)) {
301
- return 2;
302
- } else if (is_nan(b_cls)) {
303
- return 1;
304
- } else {
305
- return 0;
306
- }
307
- }
308
#else
309
- /* A default implementation: prefer a to b to c.
310
- * This is unlikely to actually match any real implementation.
311
- */
312
- if (is_nan(a_cls)) {
313
- return 0;
314
- } else if (is_nan(b_cls)) {
315
- return 1;
316
- } else {
317
- return 2;
318
- }
319
+ rule = float_3nan_prop_abc;
320
#endif
56
+ }
321
+ }
57
+
322
+
58
+ memory_region_add_subregion(&s->peri_mr, OTP_OFFSET,
323
+ assert(rule != float_3nan_prop_none);
59
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->otp), 0));
324
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
60
+
325
+ /* We have at least one SNaN input and should prefer it */
61
/* Property channel */
326
+ do {
62
if (!sysbus_realize(SYS_BUS_DEVICE(&s->property), errp)) {
327
+ which = rule & R_3NAN_1ST_MASK;
63
return;
328
+ rule >>= R_3NAN_1ST_LENGTH;
64
@@ -XXX,XX +XXX,XX @@ void bcm_soc_peripherals_common_realize(DeviceState *dev, Error **errp)
329
+ } while (!is_snan(cls[which]));
65
create_unimp(s, &s->i2s, "bcm2835-i2s", I2S_OFFSET, 0x100);
330
+ } else {
66
create_unimp(s, &s->smi, "bcm2835-smi", SMI_OFFSET, 0x100);
331
+ do {
67
create_unimp(s, &s->bscsl, "bcm2835-spis", BSC_SL_OFFSET, 0x100);
332
+ which = rule & R_3NAN_1ST_MASK;
68
- create_unimp(s, &s->otp, "bcm2835-otp", OTP_OFFSET, 0x80);
333
+ rule >>= R_3NAN_1ST_LENGTH;
69
create_unimp(s, &s->dbus, "bcm2835-dbus", DBUS_OFFSET, 0x8000);
334
+ } while (!is_nan(cls[which]));
70
create_unimp(s, &s->ave0, "bcm2835-ave0", AVE0_OFFSET, 0x8000);
335
+ }
71
create_unimp(s, &s->v3d, "bcm2835-v3d", V3D_OFFSET, 0x1000);
336
+ return which;
337
}
338
339
/*----------------------------------------------------------------------------
72
--
340
--
73
2.34.1
341
2.34.1
diff view generated by jsdifflib
New patch
1
Explicitly set a rule in the softfloat tests for propagating NaNs in
2
the muladd case. In meson.build we put -DTARGET_ARM in fpcflags, and
3
so we should select here the Arm rule of float_3nan_prop_s_cab.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20241202131347.498124-17-peter.maydell@linaro.org
8
---
9
tests/fp/fp-bench.c | 1 +
10
tests/fp/fp-test.c | 1 +
11
2 files changed, 2 insertions(+)
12
13
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/fp/fp-bench.c
16
+++ b/tests/fp/fp-bench.c
17
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
18
* doesn't specify match those used by the Arm architecture.
19
*/
20
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
21
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
22
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
23
24
f = bench_funcs[operation][precision];
25
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/fp/fp-test.c
28
+++ b/tests/fp/fp-test.c
29
@@ -XXX,XX +XXX,XX @@ void run_test(void)
30
* doesn't specify match those used by the Arm architecture.
31
*/
32
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
33
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
34
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
35
36
genCases_setLevel(test_level);
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-18-peter.maydell@linaro.org
7
---
8
target/arm/cpu.c | 5 +++++
9
fpu/softfloat-specialize.c.inc | 8 +-------
10
2 files changed, 6 insertions(+), 7 deletions(-)
11
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
16
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
17
* * tininess-before-rounding
18
* * 2-input NaN propagation prefers SNaN over QNaN, and then
19
* operand A over operand B (see FPProcessNaNs() pseudocode)
20
+ * * 3-input NaN propagation prefers SNaN over QNaN, and then
21
+ * operand C over A over B (see FPProcessNaNs3() pseudocode,
22
+ * but note that for QEMU muladd is a * b + c, whereas for
23
+ * the pseudocode function the arguments are in the order c, a, b.
24
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
25
* and the input NaN if it is signalling
26
*/
27
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
28
{
29
set_float_detect_tininess(float_tininess_before_rounding, s);
30
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
31
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
32
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
33
}
34
35
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
36
index XXXXXXX..XXXXXXX 100644
37
--- a/fpu/softfloat-specialize.c.inc
38
+++ b/fpu/softfloat-specialize.c.inc
39
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
40
}
41
42
if (rule == float_3nan_prop_none) {
43
-#if defined(TARGET_ARM)
44
- /*
45
- * This looks different from the ARM ARM pseudocode, because the ARM ARM
46
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
47
- */
48
- rule = float_3nan_prop_s_cab;
49
-#elif defined(TARGET_MIPS)
50
+#if defined(TARGET_MIPS)
51
if (snan_bit_is_one(status)) {
52
rule = float_3nan_prop_s_abc;
53
} else {
54
--
55
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for loongarch, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-19-peter.maydell@linaro.org
7
---
8
target/loongarch/tcg/fpu_helper.c | 1 +
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 1 insertion(+), 2 deletions(-)
11
12
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/loongarch/tcg/fpu_helper.c
15
+++ b/target/loongarch/tcg/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
17
* case sets InvalidOp and returns the input value 'c'
18
*/
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
21
}
22
23
int ieee_ex_to_loongarch(int xcpt)
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
29
} else {
30
rule = float_3nan_prop_s_cab;
31
}
32
-#elif defined(TARGET_LOONGARCH64)
33
- rule = float_3nan_prop_s_cab;
34
#elif defined(TARGET_PPC)
35
/*
36
* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for PPC, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-20-peter.maydell@linaro.org
7
---
8
target/ppc/cpu_init.c | 8 ++++++++
9
fpu/softfloat-specialize.c.inc | 6 ------
10
2 files changed, 8 insertions(+), 6 deletions(-)
11
12
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/ppc/cpu_init.c
15
+++ b/target/ppc/cpu_init.c
16
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->vec_status);
20
+ /*
21
+ * NaN propagation for fused multiply-add:
22
+ * if fRA is a NaN return it; otherwise if fRB is a NaN return it;
23
+ * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
24
+ * whereas QEMU labels the operands as (a * b) + c.
25
+ */
26
+ set_float_3nan_prop_rule(float_3nan_prop_acb, &env->fp_status);
27
+ set_float_3nan_prop_rule(float_3nan_prop_acb, &env->vec_status);
28
/*
29
* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
30
* to return an input NaN if we have one (ie c) rather than generating
31
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
32
index XXXXXXX..XXXXXXX 100644
33
--- a/fpu/softfloat-specialize.c.inc
34
+++ b/fpu/softfloat-specialize.c.inc
35
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
36
} else {
37
rule = float_3nan_prop_s_cab;
38
}
39
-#elif defined(TARGET_PPC)
40
- /*
41
- * If fRA is a NaN return it; otherwise if fRB is a NaN return it;
42
- * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
43
- */
44
- rule = float_3nan_prop_acb;
45
#elif defined(TARGET_S390X)
46
rule = float_3nan_prop_s_abc;
47
#elif defined(TARGET_SPARC)
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for s390x, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-21-peter.maydell@linaro.org
7
---
8
target/s390x/cpu.c | 1 +
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 1 insertion(+), 2 deletions(-)
11
12
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/s390x/cpu.c
15
+++ b/target/s390x/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
17
set_float_detect_tininess(float_tininess_before_rounding,
18
&env->fpu_status);
19
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fpu_status);
20
+ set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
21
set_float_infzeronan_rule(float_infzeronan_dnan_always,
22
&env->fpu_status);
23
/* fall through */
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
29
} else {
30
rule = float_3nan_prop_s_cab;
31
}
32
-#elif defined(TARGET_S390X)
33
- rule = float_3nan_prop_s_abc;
34
#elif defined(TARGET_SPARC)
35
rule = float_3nan_prop_s_cba;
36
#elif defined(TARGET_XTENSA)
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for SPARC, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-22-peter.maydell@linaro.org
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sparc/cpu.c
15
+++ b/target/sparc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
17
* the CPU state struct so it won't get zeroed on reset.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &env->fp_status);
20
+ /* For fused-multiply add, prefer SNaN over QNaN, then C->B->A */
21
+ set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
22
/* For inf * 0 + NaN, return the input NaN */
23
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
} else {
31
rule = float_3nan_prop_s_cab;
32
}
33
-#elif defined(TARGET_SPARC)
34
- rule = float_3nan_prop_s_cba;
35
#elif defined(TARGET_XTENSA)
36
if (status->use_first_nan) {
37
rule = float_3nan_prop_abc;
38
--
39
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-23-peter.maydell@linaro.org
7
---
8
target/mips/fpu_helper.h | 4 ++++
9
target/mips/msa.c | 3 +++
10
fpu/softfloat-specialize.c.inc | 8 +-------
11
3 files changed, 8 insertions(+), 7 deletions(-)
12
13
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/mips/fpu_helper.h
16
+++ b/target/mips/fpu_helper.h
17
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
18
{
19
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
20
FloatInfZeroNaNRule izn_rule;
21
+ Float3NaNPropRule nan3_rule;
22
23
/*
24
* With nan2008, SNaNs are silenced in the usual way.
25
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
26
*/
27
izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
28
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
29
+ nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
30
+ set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
31
+
32
}
33
34
static inline void restore_fp_status(CPUMIPSState *env)
35
diff --git a/target/mips/msa.c b/target/mips/msa.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/mips/msa.c
38
+++ b/target/mips/msa.c
39
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
40
set_float_2nan_prop_rule(float_2nan_prop_s_ab,
41
&env->active_tc.msa_fp_status);
42
43
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab,
44
+ &env->active_tc.msa_fp_status);
45
+
46
/* clear float_status exception flags */
47
set_float_exception_flags(0, &env->active_tc.msa_fp_status);
48
49
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
50
index XXXXXXX..XXXXXXX 100644
51
--- a/fpu/softfloat-specialize.c.inc
52
+++ b/fpu/softfloat-specialize.c.inc
53
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
54
}
55
56
if (rule == float_3nan_prop_none) {
57
-#if defined(TARGET_MIPS)
58
- if (snan_bit_is_one(status)) {
59
- rule = float_3nan_prop_s_abc;
60
- } else {
61
- rule = float_3nan_prop_s_cab;
62
- }
63
-#elif defined(TARGET_XTENSA)
64
+#if defined(TARGET_XTENSA)
65
if (status->use_first_nan) {
66
rule = float_3nan_prop_abc;
67
} else {
68
--
69
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for xtensa, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-24-peter.maydell@linaro.org
7
---
8
target/xtensa/fpu_helper.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 8 --------
10
2 files changed, 2 insertions(+), 8 deletions(-)
11
12
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/xtensa/fpu_helper.c
15
+++ b/target/xtensa/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
17
set_use_first_nan(use_first, &env->fp_status);
18
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
19
&env->fp_status);
20
+ set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
21
+ &env->fp_status);
22
}
23
24
void HELPER(wur_fpu2k_fcr)(CPUXtensaState *env, uint32_t v)
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
}
31
32
if (rule == float_3nan_prop_none) {
33
-#if defined(TARGET_XTENSA)
34
- if (status->use_first_nan) {
35
- rule = float_3nan_prop_abc;
36
- } else {
37
- rule = float_3nan_prop_cba;
38
- }
39
-#else
40
rule = float_3nan_prop_abc;
41
-#endif
42
}
43
44
assert(rule != float_3nan_prop_none);
45
--
46
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for i386. We had no
2
i386-specific behaviour in the old ifdef ladder, so we were using the
3
default "prefer a then b then c" fallback; this is actually the
4
correct per-the-spec handling for i386.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-25-peter.maydell@linaro.org
9
---
10
target/i386/tcg/fpu_helper.c | 1 +
11
1 file changed, 1 insertion(+)
12
13
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/i386/tcg/fpu_helper.c
16
+++ b/target/i386/tcg/fpu_helper.c
17
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
18
* there are multiple input NaNs they are selected in the order a, b, c.
19
*/
20
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
21
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
22
}
23
24
static inline uint8_t save_exception_flags(CPUX86State *env)
25
--
26
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for HPPA, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
HPPA is the only target that was using the default branch of the
5
ifdef ladder (other targets either do not use muladd or set
6
default_nan_mode), so we can remove the ifdef fallback entirely now
7
(allowing the "rule not set" case to fall into the default of the
8
switch statement and assert).
9
10
We add a TODO note that the HPPA rule is probably wrong; this is
11
not a behavioural change for this refactoring.
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20241202131347.498124-26-peter.maydell@linaro.org
16
---
17
target/hppa/fpu_helper.c | 8 ++++++++
18
fpu/softfloat-specialize.c.inc | 4 ----
19
2 files changed, 8 insertions(+), 4 deletions(-)
20
21
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/hppa/fpu_helper.c
24
+++ b/target/hppa/fpu_helper.c
25
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
26
* HPPA does note implement a CPU reset method at all...
27
*/
28
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
29
+ /*
30
+ * TODO: The HPPA architecture reference only documents its NaN
31
+ * propagation rule for 2-operand operations. Testing on real hardware
32
+ * might be necessary to confirm whether this order for muladd is correct.
33
+ * Not preferring the SNaN is almost certainly incorrect as it diverges
34
+ * from the documented rules for 2-operand operations.
35
+ */
36
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
37
/* For inf * 0 + NaN, return the input NaN */
38
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
39
}
40
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
41
index XXXXXXX..XXXXXXX 100644
42
--- a/fpu/softfloat-specialize.c.inc
43
+++ b/fpu/softfloat-specialize.c.inc
44
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
45
}
46
}
47
48
- if (rule == float_3nan_prop_none) {
49
- rule = float_3nan_prop_abc;
50
- }
51
-
52
assert(rule != float_3nan_prop_none);
53
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
54
/* We have at least one SNaN input and should prefer it */
55
--
56
2.34.1
diff view generated by jsdifflib
New patch
1
The use_first_nan field in float_status was an xtensa-specific way to
2
select at runtime from two different NaN propagation rules. Now that
3
xtensa is using the target-agnostic NaN propagation rule selection
4
that we've just added, we can remove use_first_nan, because there is
5
no longer any code that reads it.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20241202131347.498124-27-peter.maydell@linaro.org
10
---
11
include/fpu/softfloat-helpers.h | 5 -----
12
include/fpu/softfloat-types.h | 1 -
13
target/xtensa/fpu_helper.c | 1 -
14
3 files changed, 7 deletions(-)
15
16
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/fpu/softfloat-helpers.h
19
+++ b/include/fpu/softfloat-helpers.h
20
@@ -XXX,XX +XXX,XX @@ static inline void set_snan_bit_is_one(bool val, float_status *status)
21
status->snan_bit_is_one = val;
22
}
23
24
-static inline void set_use_first_nan(bool val, float_status *status)
25
-{
26
- status->use_first_nan = val;
27
-}
28
-
29
static inline void set_no_signaling_nans(bool val, float_status *status)
30
{
31
status->no_signaling_nans = val;
32
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/include/fpu/softfloat-types.h
35
+++ b/include/fpu/softfloat-types.h
36
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
37
* softfloat-specialize.inc.c)
38
*/
39
bool snan_bit_is_one;
40
- bool use_first_nan;
41
bool no_signaling_nans;
42
/* should overflowed results subtract re_bias to its exponent? */
43
bool rebias_overflow;
44
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/xtensa/fpu_helper.c
47
+++ b/target/xtensa/fpu_helper.c
48
@@ -XXX,XX +XXX,XX @@ static const struct {
49
50
void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
51
{
52
- set_use_first_nan(use_first, &env->fp_status);
53
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
54
&env->fp_status);
55
set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
56
--
57
2.34.1
diff view generated by jsdifflib
New patch
1
Currently m68k_cpu_reset_hold() calls floatx80_default_nan(NULL)
2
to get the NaN bit pattern to reset the FPU registers. This
3
works because it happens that our implementation of
4
floatx80_default_nan() doesn't actually look at the float_status
5
pointer except for TARGET_MIPS. However, this isn't guaranteed,
6
and to be able to remove the ifdef in floatx80_default_nan()
7
we're going to need a real float_status here.
1
8
9
Rearrange m68k_cpu_reset_hold() so that we initialize env->fp_status
10
earlier, and thus can pass it to floatx80_default_nan().
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20241202131347.498124-28-peter.maydell@linaro.org
15
---
16
target/m68k/cpu.c | 12 +++++++-----
17
1 file changed, 7 insertions(+), 5 deletions(-)
18
19
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/m68k/cpu.c
22
+++ b/target/m68k/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
24
CPUState *cs = CPU(obj);
25
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(obj);
26
CPUM68KState *env = cpu_env(cs);
27
- floatx80 nan = floatx80_default_nan(NULL);
28
+ floatx80 nan;
29
int i;
30
31
if (mcc->parent_phases.hold) {
32
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
33
#else
34
cpu_m68k_set_sr(env, SR_S | SR_I);
35
#endif
36
- for (i = 0; i < 8; i++) {
37
- env->fregs[i].d = nan;
38
- }
39
- cpu_m68k_set_fpcr(env, 0);
40
/*
41
* M68000 FAMILY PROGRAMMER'S REFERENCE MANUAL
42
* 3.4 FLOATING-POINT INSTRUCTION DETAILS
43
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
44
* preceding paragraph for nonsignaling NaNs.
45
*/
46
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
47
+
48
+ nan = floatx80_default_nan(&env->fp_status);
49
+ for (i = 0; i < 8; i++) {
50
+ env->fregs[i].d = nan;
51
+ }
52
+ cpu_m68k_set_fpcr(env, 0);
53
env->fpsr = 0;
54
55
/* TODO: We should set PC from the interrupt vector. */
56
--
57
2.34.1
diff view generated by jsdifflib
New patch
1
We create our 128-bit default NaN by calling parts64_default_nan()
2
and then adjusting the result. We can do the same trick for creating
3
the floatx80 default NaN, which lets us drop a target ifdef.
1
4
5
floatx80 is used only by:
6
i386
7
m68k
8
arm nwfpe old floating-point emulation emulation support
9
(which is essentially dead, especially the parts involving floatx80)
10
PPC (only in the xsrqpxp instruction, which just rounds an input
11
value by converting to floatx80 and back, so will never generate
12
the default NaN)
13
14
The floatx80 default NaN as currently implemented is:
15
m68k: sign = 0, exp = 1...1, int = 1, frac = 1....1
16
i386: sign = 1, exp = 1...1, int = 1, frac = 10...0
17
18
These are the same as the parts64_default_nan for these architectures.
19
20
This is technically a possible behaviour change for arm linux-user
21
nwfpe emulation emulation, because the default NaN will now have the
22
sign bit clear. But we were already generating a different floatx80
23
default NaN from the real kernel emulation we are supposedly
24
following, which appears to use an all-bits-1 value:
25
https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L267
26
27
This won't affect the only "real" use of the nwfpe emulation, which
28
is ancient binaries that used it as part of the old floating point
29
calling convention; that only uses loads and stores of 32 and 64 bit
30
floats, not any of the floatx80 behaviour the original hardware had.
31
We also get the nwfpe float64 default NaN value wrong:
32
https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L166
33
so if we ever cared about this obscure corner the right fix would be
34
to correct that so nwfpe used its own default-NaN setting rather
35
than the Arm VFP one.
36
37
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
38
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
39
Message-id: 20241202131347.498124-29-peter.maydell@linaro.org
40
---
41
fpu/softfloat-specialize.c.inc | 20 ++++++++++----------
42
1 file changed, 10 insertions(+), 10 deletions(-)
43
44
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
45
index XXXXXXX..XXXXXXX 100644
46
--- a/fpu/softfloat-specialize.c.inc
47
+++ b/fpu/softfloat-specialize.c.inc
48
@@ -XXX,XX +XXX,XX @@ static void parts128_silence_nan(FloatParts128 *p, float_status *status)
49
floatx80 floatx80_default_nan(float_status *status)
50
{
51
floatx80 r;
52
+ /*
53
+ * Extrapolate from the choices made by parts64_default_nan to fill
54
+ * in the floatx80 format. We assume that floatx80's explicit
55
+ * integer bit is always set (this is true for i386 and m68k,
56
+ * which are the only real users of this format).
57
+ */
58
+ FloatParts64 p64;
59
+ parts64_default_nan(&p64, status);
60
61
- /* None of the targets that have snan_bit_is_one use floatx80. */
62
- assert(!snan_bit_is_one(status));
63
-#if defined(TARGET_M68K)
64
- r.low = UINT64_C(0xFFFFFFFFFFFFFFFF);
65
- r.high = 0x7FFF;
66
-#else
67
- /* X86 */
68
- r.low = UINT64_C(0xC000000000000000);
69
- r.high = 0xFFFF;
70
-#endif
71
+ r.high = 0x7FFF | (p64.sign << 15);
72
+ r.low = (1ULL << DECOMPOSED_BINARY_POINT) | p64.frac;
73
return r;
74
}
75
76
--
77
2.34.1
diff view generated by jsdifflib
New patch
1
In target/loongarch's helper_fclass_s() and helper_fclass_d() we pass
2
a zero-initialized float_status struct to float32_is_quiet_nan() and
3
float64_is_quiet_nan(), with the cryptic comment "for
4
snan_bit_is_one".
1
5
6
This pattern appears to have been copied from target/riscv, where it
7
is used because the functions there do not have ready access to the
8
CPU state struct. The comment presumably refers to the fact that the
9
main reason the is_quiet_nan() functions want the float_state is
10
because they want to know about the snan_bit_is_one config.
11
12
In the loongarch helpers, though, we have the CPU state struct
13
to hand. Use the usual env->fp_status here. This avoids our needing
14
to track that we need to update the initializer of the local
15
float_status structs when the core softfloat code adds new
16
options for targets to configure their behaviour.
17
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20241202131347.498124-30-peter.maydell@linaro.org
21
---
22
target/loongarch/tcg/fpu_helper.c | 6 ++----
23
1 file changed, 2 insertions(+), 4 deletions(-)
24
25
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/loongarch/tcg/fpu_helper.c
28
+++ b/target/loongarch/tcg/fpu_helper.c
29
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fclass_s(CPULoongArchState *env, uint64_t fj)
30
} else if (float32_is_zero_or_denormal(f)) {
31
return sign ? 1 << 4 : 1 << 8;
32
} else if (float32_is_any_nan(f)) {
33
- float_status s = { }; /* for snan_bit_is_one */
34
- return float32_is_quiet_nan(f, &s) ? 1 << 1 : 1 << 0;
35
+ return float32_is_quiet_nan(f, &env->fp_status) ? 1 << 1 : 1 << 0;
36
} else {
37
return sign ? 1 << 3 : 1 << 7;
38
}
39
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fclass_d(CPULoongArchState *env, uint64_t fj)
40
} else if (float64_is_zero_or_denormal(f)) {
41
return sign ? 1 << 4 : 1 << 8;
42
} else if (float64_is_any_nan(f)) {
43
- float_status s = { }; /* for snan_bit_is_one */
44
- return float64_is_quiet_nan(f, &s) ? 1 << 1 : 1 << 0;
45
+ return float64_is_quiet_nan(f, &env->fp_status) ? 1 << 1 : 1 << 0;
46
} else {
47
return sign ? 1 << 3 : 1 << 7;
48
}
49
--
50
2.34.1
diff view generated by jsdifflib
New patch
1
In the frem helper, we have a local float_status because we want to
2
execute the floatx80_div() with a custom rounding mode. Instead of
3
zero-initializing the local float_status and then having to set it up
4
with the m68k standard behaviour (including the NaN propagation rule
5
and copying the rounding precision from env->fp_status), initialize
6
it as a complete copy of env->fp_status. This will avoid our having
7
to add new code in this function for every new config knob we add
8
to fp_status.
1
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20241202131347.498124-31-peter.maydell@linaro.org
13
---
14
target/m68k/fpu_helper.c | 6 ++----
15
1 file changed, 2 insertions(+), 4 deletions(-)
16
17
diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/m68k/fpu_helper.c
20
+++ b/target/m68k/fpu_helper.c
21
@@ -XXX,XX +XXX,XX @@ void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
22
23
fp_rem = floatx80_rem(val1->d, val0->d, &env->fp_status);
24
if (!floatx80_is_any_nan(fp_rem)) {
25
- float_status fp_status = { };
26
+ /* Use local temporary fp_status to set different rounding mode */
27
+ float_status fp_status = env->fp_status;
28
uint32_t quotient;
29
int sign;
30
31
/* Calculate quotient directly using round to nearest mode */
32
- set_float_2nan_prop_rule(float_2nan_prop_ab, &fp_status);
33
set_float_rounding_mode(float_round_nearest_even, &fp_status);
34
- set_floatx80_rounding_precision(
35
- get_floatx80_rounding_precision(&env->fp_status), &fp_status);
36
fp_quot.d = floatx80_div(val1->d, val0->d, &fp_status);
37
38
sign = extractFloatx80Sign(fp_quot.d);
39
--
40
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
In cf_fpu_gdb_get_reg() and cf_fpu_gdb_set_reg() we do the conversion
2
from float64 to floatx80 using a scratch float_status, because we
3
don't want the conversion to affect the CPU's floating point exception
4
status. Currently we use a zero-initialized float_status. This will
5
get steadily more awkward as we add config knobs to float_status
6
that the target must initialize. Avoid having to add any of that
7
configuration here by instead initializing our local float_status
8
from the env->fp_status.
2
9
3
The inner loop, bounded by eltspersegment, must not be
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
larger than the outer loop, bounded by elements.
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20241202131347.498124-32-peter.maydell@linaro.org
13
---
14
target/m68k/helper.c | 6 ++++--
15
1 file changed, 4 insertions(+), 2 deletions(-)
5
16
6
Cc: qemu-stable@nongnu.org
17
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20240625183536.1672454-3-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/tcg/vec_helper.c | 24 ++++++++++++++++--------
13
1 file changed, 16 insertions(+), 8 deletions(-)
14
15
diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/tcg/vec_helper.c
19
--- a/target/m68k/helper.c
18
+++ b/target/arm/tcg/vec_helper.c
20
+++ b/target/m68k/helper.c
19
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_sqdmulh_idx_h)(void *vd, void *vn, void *vm,
21
@@ -XXX,XX +XXX,XX @@ static int cf_fpu_gdb_get_reg(CPUState *cs, GByteArray *mem_buf, int n)
20
intptr_t i, j, opr_sz = simd_oprsz(desc);
22
CPUM68KState *env = &cpu->env;
21
int idx = simd_data(desc);
23
22
int16_t *d = vd, *n = vn, *m = (int16_t *)vm + H2(idx);
24
if (n < 8) {
23
+ intptr_t elements = opr_sz / 2;
25
- float_status s = {};
24
+ intptr_t eltspersegment = MIN(16 / 2, elements);
26
+ /* Use scratch float_status so any exceptions don't change CPU state */
25
27
+ float_status s = env->fp_status;
26
- for (i = 0; i < opr_sz / 2; i += 16 / 2) {
28
return gdb_get_reg64(mem_buf, floatx80_to_float64(env->fregs[n].d, &s));
27
+ for (i = 0; i < elements; i += 16 / 2) {
28
int16_t mm = m[i];
29
- for (j = 0; j < 16 / 2; ++j) {
30
+ for (j = 0; j < eltspersegment; ++j) {
31
d[i + j] = do_sqrdmlah_h(n[i + j], mm, 0, false, false, vq);
32
}
33
}
29
}
34
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_sqrdmulh_idx_h)(void *vd, void *vn, void *vm,
30
switch (n) {
35
intptr_t i, j, opr_sz = simd_oprsz(desc);
31
@@ -XXX,XX +XXX,XX @@ static int cf_fpu_gdb_set_reg(CPUState *cs, uint8_t *mem_buf, int n)
36
int idx = simd_data(desc);
32
CPUM68KState *env = &cpu->env;
37
int16_t *d = vd, *n = vn, *m = (int16_t *)vm + H2(idx);
33
38
+ intptr_t elements = opr_sz / 2;
34
if (n < 8) {
39
+ intptr_t eltspersegment = MIN(16 / 2, elements);
35
- float_status s = {};
40
36
+ /* Use scratch float_status so any exceptions don't change CPU state */
41
- for (i = 0; i < opr_sz / 2; i += 16 / 2) {
37
+ float_status s = env->fp_status;
42
+ for (i = 0; i < elements; i += 16 / 2) {
38
env->fregs[n].d = float64_to_floatx80(ldq_be_p(mem_buf), &s);
43
int16_t mm = m[i];
39
return 8;
44
- for (j = 0; j < 16 / 2; ++j) {
45
+ for (j = 0; j < eltspersegment; ++j) {
46
d[i + j] = do_sqrdmlah_h(n[i + j], mm, 0, false, true, vq);
47
}
48
}
49
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_sqdmulh_idx_s)(void *vd, void *vn, void *vm,
50
intptr_t i, j, opr_sz = simd_oprsz(desc);
51
int idx = simd_data(desc);
52
int32_t *d = vd, *n = vn, *m = (int32_t *)vm + H4(idx);
53
+ intptr_t elements = opr_sz / 4;
54
+ intptr_t eltspersegment = MIN(16 / 4, elements);
55
56
- for (i = 0; i < opr_sz / 4; i += 16 / 4) {
57
+ for (i = 0; i < elements; i += 16 / 4) {
58
int32_t mm = m[i];
59
- for (j = 0; j < 16 / 4; ++j) {
60
+ for (j = 0; j < eltspersegment; ++j) {
61
d[i + j] = do_sqrdmlah_s(n[i + j], mm, 0, false, false, vq);
62
}
63
}
64
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_sqrdmulh_idx_s)(void *vd, void *vn, void *vm,
65
intptr_t i, j, opr_sz = simd_oprsz(desc);
66
int idx = simd_data(desc);
67
int32_t *d = vd, *n = vn, *m = (int32_t *)vm + H4(idx);
68
+ intptr_t elements = opr_sz / 4;
69
+ intptr_t eltspersegment = MIN(16 / 4, elements);
70
71
- for (i = 0; i < opr_sz / 4; i += 16 / 4) {
72
+ for (i = 0; i < elements; i += 16 / 4) {
73
int32_t mm = m[i];
74
- for (j = 0; j < 16 / 4; ++j) {
75
+ for (j = 0; j < eltspersegment; ++j) {
76
d[i + j] = do_sqrdmlah_s(n[i + j], mm, 0, false, true, vq);
77
}
78
}
40
}
79
--
41
--
80
2.34.1
42
2.34.1
diff view generated by jsdifflib
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
1
In the helper functions flcmps and flcmpd we use a scratch float_status
2
so that we don't change the CPU state if the comparison raises any
3
floating point exception flags. Instead of zero-initializing this
4
scratch float_status, initialize it as a copy of env->fp_status. This
5
avoids the need to explicitly initialize settings like the NaN
6
propagation rule or others we might add to softfloat in future.
2
7
3
EXTI's new field `irq_levels` tracks irq levels between tests when using
8
To do this we need to pass the CPU env pointer in to the helper.
4
`global_qtest`.
5
This happens in `stm32l4x5_exti-test.c`, `stm32l4x5_syscfg-test.c` and
6
`stm32l4x5_gpio-test.c` (`dm163.c` doesn't use `global_qtest`).
7
9
8
To ensure that `irq_levels` has the same value before and after each
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
QTest, this commit toggles back the irq lines that were changed at the
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
end of each problematic test. Most QTests were already doing this.
12
Message-id: 20241202131347.498124-33-peter.maydell@linaro.org
13
---
14
target/sparc/helper.h | 4 ++--
15
target/sparc/fop_helper.c | 8 ++++----
16
target/sparc/translate.c | 4 ++--
17
3 files changed, 8 insertions(+), 8 deletions(-)
11
18
12
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
19
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
13
Message-id: 20240629110800.539969-3-ines.varhol@telecom-paris.fr
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
tests/qtest/stm32l4x5_exti-test.c | 8 ++++++++
18
tests/qtest/stm32l4x5_syscfg-test.c | 2 +-
19
2 files changed, 9 insertions(+), 1 deletion(-)
20
21
diff --git a/tests/qtest/stm32l4x5_exti-test.c b/tests/qtest/stm32l4x5_exti-test.c
22
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
23
--- a/tests/qtest/stm32l4x5_exti-test.c
21
--- a/target/sparc/helper.h
24
+++ b/tests/qtest/stm32l4x5_exti-test.c
22
+++ b/target/sparc/helper.h
25
@@ -XXX,XX +XXX,XX @@ static void test_masked_interrupt(void)
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, i32, env, f64, f64)
26
g_assert_cmphex(exti_readl(EXTI_PR1), ==, 0x00000000);
24
DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, i32, env, f64, f64)
27
/* Check that the interrupt isn't pending in NVIC */
25
DEF_HELPER_FLAGS_3(fcmpq, TCG_CALL_NO_WG, i32, env, i128, i128)
28
g_assert_false(check_nvic_pending(EXTI1_IRQ));
26
DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_WG, i32, env, i128, i128)
29
+
27
-DEF_HELPER_FLAGS_2(flcmps, TCG_CALL_NO_RWG_SE, i32, f32, f32)
30
+ /* Clean EXTI */
28
-DEF_HELPER_FLAGS_2(flcmpd, TCG_CALL_NO_RWG_SE, i32, f64, f64)
31
+ exti_set_irq(1, 0);
29
+DEF_HELPER_FLAGS_3(flcmps, TCG_CALL_NO_RWG_SE, i32, env, f32, f32)
30
+DEF_HELPER_FLAGS_3(flcmpd, TCG_CALL_NO_RWG_SE, i32, env, f64, f64)
31
DEF_HELPER_2(raise_exception, noreturn, env, int)
32
33
DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
34
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/sparc/fop_helper.c
37
+++ b/target/sparc/fop_helper.c
38
@@ -XXX,XX +XXX,XX @@ uint32_t helper_fcmpeq(CPUSPARCState *env, Int128 src1, Int128 src2)
39
return finish_fcmp(env, r, GETPC());
32
}
40
}
33
41
34
static void test_interrupt(void)
42
-uint32_t helper_flcmps(float32 src1, float32 src2)
35
@@ -XXX,XX +XXX,XX @@ static void test_interrupt(void)
43
+uint32_t helper_flcmps(CPUSPARCState *env, float32 src1, float32 src2)
36
/* Clean NVIC */
44
{
37
unpend_nvic_irq(EXTI1_IRQ);
45
/*
38
g_assert_false(check_nvic_pending(EXTI1_IRQ));
46
* FLCMP never raises an exception nor modifies any FSR fields.
39
+
47
* Perform the comparison with a dummy fp environment.
40
+ /* Clean EXTI */
48
*/
41
+ exti_set_irq(1, 0);
49
- float_status discard = { };
50
+ float_status discard = env->fp_status;
51
FloatRelation r;
52
53
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
54
@@ -XXX,XX +XXX,XX @@ uint32_t helper_flcmps(float32 src1, float32 src2)
55
g_assert_not_reached();
42
}
56
}
43
57
44
static void test_orred_interrupts(void)
58
-uint32_t helper_flcmpd(float64 src1, float64 src2)
45
@@ -XXX,XX +XXX,XX @@ static void test_orred_interrupts(void)
59
+uint32_t helper_flcmpd(CPUSPARCState *env, float64 src1, float64 src2)
46
60
{
47
unpend_nvic_irq(EXTI5_9_IRQ);
61
- float_status discard = { };
48
g_assert_false(check_nvic_pending(EXTI5_9_IRQ));
62
+ float_status discard = env->fp_status;
49
+
63
FloatRelation r;
50
+ exti_set_irq(i, 0);
64
51
}
65
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
66
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/sparc/translate.c
69
+++ b/target/sparc/translate.c
70
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPs(DisasContext *dc, arg_FLCMPs *a)
71
72
src1 = gen_load_fpr_F(dc, a->rs1);
73
src2 = gen_load_fpr_F(dc, a->rs2);
74
- gen_helper_flcmps(cpu_fcc[a->cc], src1, src2);
75
+ gen_helper_flcmps(cpu_fcc[a->cc], tcg_env, src1, src2);
76
return advance_pc(dc);
52
}
77
}
53
78
54
diff --git a/tests/qtest/stm32l4x5_syscfg-test.c b/tests/qtest/stm32l4x5_syscfg-test.c
79
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPd(DisasContext *dc, arg_FLCMPd *a)
55
index XXXXXXX..XXXXXXX 100644
80
56
--- a/tests/qtest/stm32l4x5_syscfg-test.c
81
src1 = gen_load_fpr_D(dc, a->rs1);
57
+++ b/tests/qtest/stm32l4x5_syscfg-test.c
82
src2 = gen_load_fpr_D(dc, a->rs2);
58
@@ -XXX,XX +XXX,XX @@ static void test_interrupt(void)
83
- gen_helper_flcmpd(cpu_fcc[a->cc], src1, src2);
59
g_assert_true(get_irq(1));
84
+ gen_helper_flcmpd(cpu_fcc[a->cc], tcg_env, src1, src2);
60
85
return advance_pc(dc);
61
/* Clean the test */
62
- syscfg_writel(SYSCFG_EXTICR1, 0x00000000);
63
syscfg_set_irq(0, 0);
64
/* irq 15 is high at reset because GPIOA15 is high at reset */
65
syscfg_set_irq(17, 0);
66
+ syscfg_writel(SYSCFG_EXTICR1, 0x00000000);
67
}
86
}
68
87
69
static void test_irq_pin_multiplexer(void)
70
--
88
--
71
2.34.1
89
2.34.1
72
73
diff view generated by jsdifflib
New patch
1
In the helper_compute_fprf functions, we pass a dummy float_status
2
in to the is_signaling_nan() function. This is unnecessary, because
3
we have convenient access to the CPU env pointer here and that
4
is already set up with the correct values for the snan_bit_is_one
5
and no_signaling_nans config settings. is_signaling_nan() doesn't
6
ever update the fp_status with any exception flags, so there is
7
no reason not to use env->fp_status here.
1
8
9
Use env->fp_status instead of the dummy fp_status.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20241202131347.498124-34-peter.maydell@linaro.org
14
---
15
target/ppc/fpu_helper.c | 3 +--
16
1 file changed, 1 insertion(+), 2 deletions(-)
17
18
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/ppc/fpu_helper.c
21
+++ b/target/ppc/fpu_helper.c
22
@@ -XXX,XX +XXX,XX @@ void helper_compute_fprf_##tp(CPUPPCState *env, tp arg) \
23
} else if (tp##_is_infinity(arg)) { \
24
fprf = neg ? 0x09 << FPSCR_FPRF : 0x05 << FPSCR_FPRF; \
25
} else { \
26
- float_status dummy = { }; /* snan_bit_is_one = 0 */ \
27
- if (tp##_is_signaling_nan(arg, &dummy)) { \
28
+ if (tp##_is_signaling_nan(arg, &env->fp_status)) { \
29
fprf = 0x00 << FPSCR_FPRF; \
30
} else { \
31
fprf = 0x11 << FPSCR_FPRF; \
32
--
33
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The inner loop, bounded by eltspersegment, must not be
3
Now that float_status has a bunch of fp parameters,
4
larger than the outer loop, bounded by elements.
4
it is easier to copy an existing structure than create
5
one from scratch. Begin by copying the structure that
6
corresponds to the FPSR and make only the adjustments
7
required for BFloat16 semantics.
5
8
6
Cc: qemu-stable@nongnu.org
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Fixes: 18fc2405781 ("target/arm: Implement SVE fp complex multiply add (indexed)")
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2376
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20241203203949.483774-2-richard.henderson@linaro.org
11
Message-id: 20240625183536.1672454-2-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
---
14
target/arm/tcg/vec_helper.c | 4 ++--
15
target/arm/tcg/vec_helper.c | 20 +++++++-------------
15
1 file changed, 2 insertions(+), 2 deletions(-)
16
1 file changed, 7 insertions(+), 13 deletions(-)
16
17
17
diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c
18
diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/tcg/vec_helper.c
20
--- a/target/arm/tcg/vec_helper.c
20
+++ b/target/arm/tcg/vec_helper.c
21
+++ b/target/arm/tcg/vec_helper.c
21
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlah_idx)(void *vd, void *vn, void *vm, void *va,
22
@@ -XXX,XX +XXX,XX @@ bool is_ebf(CPUARMState *env, float_status *statusp, float_status *oddstatusp)
22
intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
23
* no effect on AArch32 instructions.
23
uint32_t neg_real = flip ^ neg_imag;
24
*/
24
intptr_t elements = opr_sz / sizeof(float16);
25
bool ebf = is_a64(env) && env->vfp.fpcr & FPCR_EBF;
25
- intptr_t eltspersegment = 16 / sizeof(float16);
26
- *statusp = (float_status){
26
+ intptr_t eltspersegment = MIN(16 / sizeof(float16), elements);
27
- .tininess_before_rounding = float_tininess_before_rounding,
27
intptr_t i, j;
28
- .float_rounding_mode = float_round_to_odd_inf,
28
29
- .flush_to_zero = true,
29
/* Shift boolean to the sign bit so we can xor to negate. */
30
- .flush_inputs_to_zero = true,
30
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlas_idx)(void *vd, void *vn, void *vm, void *va,
31
- .default_nan_mode = true,
31
intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
32
- };
32
uint32_t neg_real = flip ^ neg_imag;
33
+
33
intptr_t elements = opr_sz / sizeof(float32);
34
+ *statusp = env->vfp.fp_status;
34
- intptr_t eltspersegment = 16 / sizeof(float32);
35
+ set_default_nan_mode(true, statusp);
35
+ intptr_t eltspersegment = MIN(16 / sizeof(float32), elements);
36
36
intptr_t i, j;
37
if (ebf) {
37
38
- float_status *fpst = &env->vfp.fp_status;
38
/* Shift boolean to the sign bit so we can xor to negate. */
39
- set_flush_to_zero(get_flush_to_zero(fpst), statusp);
40
- set_flush_inputs_to_zero(get_flush_inputs_to_zero(fpst), statusp);
41
- set_float_rounding_mode(get_float_rounding_mode(fpst), statusp);
42
-
43
/* EBF=1 needs to do a step with round-to-odd semantics */
44
*oddstatusp = *statusp;
45
set_float_rounding_mode(float_round_to_odd, oddstatusp);
46
+ } else {
47
+ set_flush_to_zero(true, statusp);
48
+ set_flush_inputs_to_zero(true, statusp);
49
+ set_float_rounding_mode(float_round_to_odd_inf, statusp);
50
}
51
-
52
return ebf;
53
}
54
39
--
55
--
40
2.34.1
56
2.34.1
57
58
diff view generated by jsdifflib
1
From: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
1
Currently we hardcode the default NaN value in parts64_default_nan()
2
using a compile-time ifdef ladder. This is awkward for two cases:
3
* for single-QEMU-binary we can't hard-code target-specifics like this
4
* for Arm FEAT_AFP the default NaN value depends on FPCR.AH
5
(specifically the sign bit is different)
2
6
3
Read boot-mode value as machine property and propagate that to
7
Add a field to float_status to specify the default NaN value; fall
4
SLCR.BOOT_MODE register.
8
back to the old ifdef behaviour if these are not set.
5
9
6
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
10
The default NaN value is specified by setting a uint8_t to a
7
Acked-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
11
pattern corresponding to the sign and upper fraction parts of
8
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
12
the NaN; the lower bits of the fraction are set from bit 0 of
9
Message-id: 20240621125906.1300995-3-sai.pavan.boddu@amd.com
13
the pattern.
14
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20241202131347.498124-35-peter.maydell@linaro.org
11
---
18
---
12
hw/arm/xilinx_zynq.c | 31 +++++++++++++++++++++++++++++++
19
include/fpu/softfloat-helpers.h | 11 +++++++
13
1 file changed, 31 insertions(+)
20
include/fpu/softfloat-types.h | 10 ++++++
21
fpu/softfloat-specialize.c.inc | 55 ++++++++++++++++++++-------------
22
3 files changed, 54 insertions(+), 22 deletions(-)
14
23
15
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
24
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
16
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/xilinx_zynq.c
26
--- a/include/fpu/softfloat-helpers.h
18
+++ b/hw/arm/xilinx_zynq.c
27
+++ b/include/fpu/softfloat-helpers.h
19
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@ static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
20
#include "qom/object.h"
29
status->float_infzeronan_rule = rule;
21
#include "exec/tswap.h"
22
#include "target/arm/cpu-qom.h"
23
+#include "qapi/visitor.h"
24
25
#define TYPE_ZYNQ_MACHINE MACHINE_TYPE_NAME("xilinx-zynq-a9")
26
OBJECT_DECLARE_SIMPLE_TYPE(ZynqMachineState, ZYNQ_MACHINE)
27
@@ -XXX,XX +XXX,XX @@ struct ZynqMachineState {
28
MachineState parent;
29
Clock *ps_clk;
30
ARMCPU *cpu[ZYNQ_MAX_CPUS];
31
+ uint8_t boot_mode;
32
};
33
34
static void zynq_write_board_setup(ARMCPU *cpu,
35
@@ -XXX,XX +XXX,XX @@ static inline int zynq_init_spi_flashes(uint32_t base_addr, qemu_irq irq,
36
return unit;
37
}
30
}
38
31
39
+static void zynq_set_boot_mode(Object *obj, const char *str,
32
+static inline void set_float_default_nan_pattern(uint8_t dnan_pattern,
40
+ Error **errp)
33
+ float_status *status)
41
+{
34
+{
42
+ ZynqMachineState *m = ZYNQ_MACHINE(obj);
35
+ status->default_nan_pattern = dnan_pattern;
43
+ uint8_t mode = 0;
44
+
45
+ if (!strncasecmp(str, "qspi", 4)) {
46
+ mode = 1;
47
+ } else if (!strncasecmp(str, "sd", 2)) {
48
+ mode = 5;
49
+ } else if (!strncasecmp(str, "nor", 3)) {
50
+ mode = 2;
51
+ } else if (!strncasecmp(str, "jtag", 4)) {
52
+ mode = 0;
53
+ } else {
54
+ error_setg(errp, "%s boot mode not supported", str);
55
+ return;
56
+ }
57
+ m->boot_mode = mode;
58
+}
36
+}
59
+
37
+
60
static void zynq_init(MachineState *machine)
38
static inline void set_flush_to_zero(bool val, float_status *status)
61
{
39
{
62
ZynqMachineState *zynq_machine = ZYNQ_MACHINE(machine);
40
status->flush_to_zero = val;
63
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
41
@@ -XXX,XX +XXX,XX @@ static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status
64
/* Create slcr, keep a pointer to connect clocks */
42
return status->float_infzeronan_rule;
65
slcr = qdev_new("xilinx-zynq_slcr");
66
qdev_connect_clock_in(slcr, "ps_clk", zynq_machine->ps_clk);
67
+ qdev_prop_set_uint8(slcr, "boot-mode", zynq_machine->boot_mode);
68
sysbus_realize_and_unref(SYS_BUS_DEVICE(slcr), &error_fatal);
69
sysbus_mmio_map(SYS_BUS_DEVICE(slcr), 0, 0xF8000000);
70
71
@@ -XXX,XX +XXX,XX @@ static void zynq_machine_class_init(ObjectClass *oc, void *data)
72
NULL
73
};
74
MachineClass *mc = MACHINE_CLASS(oc);
75
+ ObjectProperty *prop;
76
mc->desc = "Xilinx Zynq Platform Baseboard for Cortex-A9";
77
mc->init = zynq_init;
78
mc->max_cpus = ZYNQ_MAX_CPUS;
79
@@ -XXX,XX +XXX,XX @@ static void zynq_machine_class_init(ObjectClass *oc, void *data)
80
mc->ignore_memory_transaction_failures = true;
81
mc->valid_cpu_types = valid_cpu_types;
82
mc->default_ram_id = "zynq.ext_ram";
83
+ prop = object_class_property_add_str(oc, "boot-mode", NULL,
84
+ zynq_set_boot_mode);
85
+ object_class_property_set_description(oc, "boot-mode",
86
+ "Supported boot modes:"
87
+ " jtag qspi sd nor");
88
+ object_property_set_default_str(prop, "qspi");
89
}
43
}
90
44
91
static const TypeInfo zynq_machine_type = {
45
+static inline uint8_t get_float_default_nan_pattern(float_status *status)
46
+{
47
+ return status->default_nan_pattern;
48
+}
49
+
50
static inline bool get_flush_to_zero(float_status *status)
51
{
52
return status->flush_to_zero;
53
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/include/fpu/softfloat-types.h
56
+++ b/include/fpu/softfloat-types.h
57
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
58
/* should denormalised inputs go to zero and set the input_denormal flag? */
59
bool flush_inputs_to_zero;
60
bool default_nan_mode;
61
+ /*
62
+ * The pattern to use for the default NaN. Here the high bit specifies
63
+ * the default NaN's sign bit, and bits 6..0 specify the high bits of the
64
+ * fractional part. The low bits of the fractional part are copies of bit 0.
65
+ * The exponent of the default NaN is (as for any NaN) always all 1s.
66
+ * Note that a value of 0 here is not a valid NaN. The target must set
67
+ * this to the correct non-zero value, or we will assert when trying to
68
+ * create a default NaN.
69
+ */
70
+ uint8_t default_nan_pattern;
71
/*
72
* The flags below are not used on all specializations and may
73
* constant fold away (see snan_bit_is_one()/no_signalling_nans() in
74
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
75
index XXXXXXX..XXXXXXX 100644
76
--- a/fpu/softfloat-specialize.c.inc
77
+++ b/fpu/softfloat-specialize.c.inc
78
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
79
{
80
bool sign = 0;
81
uint64_t frac;
82
+ uint8_t dnan_pattern = status->default_nan_pattern;
83
84
+ if (dnan_pattern == 0) {
85
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
86
- /* !snan_bit_is_one, set all bits */
87
- frac = (1ULL << DECOMPOSED_BINARY_POINT) - 1;
88
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
89
+ /* Sign bit clear, all frac bits set */
90
+ dnan_pattern = 0b01111111;
91
+#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
92
|| defined(TARGET_MICROBLAZE)
93
- /* !snan_bit_is_one, set sign and msb */
94
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
95
- sign = 1;
96
+ /* Sign bit set, most significant frac bit set */
97
+ dnan_pattern = 0b11000000;
98
#elif defined(TARGET_HPPA)
99
- /* snan_bit_is_one, set msb-1. */
100
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 2);
101
+ /* Sign bit clear, msb-1 frac bit set */
102
+ dnan_pattern = 0b00100000;
103
#elif defined(TARGET_HEXAGON)
104
- sign = 1;
105
- frac = ~0ULL;
106
+ /* Sign bit set, all frac bits set. */
107
+ dnan_pattern = 0b11111111;
108
#else
109
- /*
110
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
111
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
112
- * do not have floating-point.
113
- */
114
- if (snan_bit_is_one(status)) {
115
- /* set all bits other than msb */
116
- frac = (1ULL << (DECOMPOSED_BINARY_POINT - 1)) - 1;
117
- } else {
118
- /* set msb */
119
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
120
- }
121
+ /*
122
+ * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
123
+ * S390, SH4, TriCore, and Xtensa. Our other supported targets
124
+ * do not have floating-point.
125
+ */
126
+ if (snan_bit_is_one(status)) {
127
+ /* sign bit clear, set all frac bits other than msb */
128
+ dnan_pattern = 0b00111111;
129
+ } else {
130
+ /* sign bit clear, set frac msb */
131
+ dnan_pattern = 0b01000000;
132
+ }
133
#endif
134
+ }
135
+ assert(dnan_pattern != 0);
136
+
137
+ sign = dnan_pattern >> 7;
138
+ /*
139
+ * Place default_nan_pattern [6:0] into bits [62:56],
140
+ * and replecate bit [0] down into [55:0]
141
+ */
142
+ frac = deposit64(0, DECOMPOSED_BINARY_POINT - 7, 7, dnan_pattern);
143
+ frac = deposit64(frac, 0, DECOMPOSED_BINARY_POINT - 7, -(dnan_pattern & 1));
144
145
*p = (FloatParts64) {
146
.cls = float_class_qnan,
92
--
147
--
93
2.34.1
148
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for the tests/fp code.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-36-peter.maydell@linaro.org
6
---
7
tests/fp/fp-bench.c | 1 +
8
tests/fp/fp-test-log2.c | 1 +
9
tests/fp/fp-test.c | 1 +
10
3 files changed, 3 insertions(+)
11
12
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/fp/fp-bench.c
15
+++ b/tests/fp/fp-bench.c
16
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
17
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
18
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
19
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
20
+ set_float_default_nan_pattern(0b01000000, &soft_status);
21
22
f = bench_funcs[operation][precision];
23
g_assert(f);
24
diff --git a/tests/fp/fp-test-log2.c b/tests/fp/fp-test-log2.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/tests/fp/fp-test-log2.c
27
+++ b/tests/fp/fp-test-log2.c
28
@@ -XXX,XX +XXX,XX @@ int main(int ac, char **av)
29
int i;
30
31
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
32
+ set_float_default_nan_pattern(0b01000000, &qsf);
33
set_float_rounding_mode(float_round_nearest_even, &qsf);
34
35
test.d = 0.0;
36
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/tests/fp/fp-test.c
39
+++ b/tests/fp/fp-test.c
40
@@ -XXX,XX +XXX,XX @@ void run_test(void)
41
*/
42
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
43
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
44
+ set_float_default_nan_pattern(0b01000000, &qsf);
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
46
47
genCases_setLevel(test_level);
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-37-peter.maydell@linaro.org
7
---
8
target/microblaze/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 +--
10
2 files changed, 3 insertions(+), 2 deletions(-)
11
12
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/microblaze/cpu.c
15
+++ b/target/microblaze/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void mb_cpu_reset_hold(Object *obj, ResetType type)
17
* this architecture.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
20
+ /* Default NaN: sign bit set, most significant frac bit set */
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
22
23
#if defined(CONFIG_USER_ONLY)
24
/* start in user mode with interrupts enabled. */
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
31
/* Sign bit clear, all frac bits set */
32
dnan_pattern = 0b01111111;
33
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
34
- || defined(TARGET_MICROBLAZE)
35
+#elif defined(TARGET_I386) || defined(TARGET_X86_64)
36
/* Sign bit set, most significant frac bit set */
37
dnan_pattern = 0b11000000;
38
#elif defined(TARGET_HPPA)
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-38-peter.maydell@linaro.org
7
---
8
target/i386/tcg/fpu_helper.c | 4 ++++
9
fpu/softfloat-specialize.c.inc | 3 ---
10
2 files changed, 4 insertions(+), 3 deletions(-)
11
12
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/i386/tcg/fpu_helper.c
15
+++ b/target/i386/tcg/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
17
*/
18
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
19
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
20
+ /* Default NaN: sign bit set, most significant frac bit set */
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
22
+ set_float_default_nan_pattern(0b11000000, &env->mmx_status);
23
+ set_float_default_nan_pattern(0b11000000, &env->sse_status);
24
}
25
26
static inline uint8_t save_exception_flags(CPUX86State *env)
27
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
28
index XXXXXXX..XXXXXXX 100644
29
--- a/fpu/softfloat-specialize.c.inc
30
+++ b/fpu/softfloat-specialize.c.inc
31
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
32
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
33
/* Sign bit clear, all frac bits set */
34
dnan_pattern = 0b01111111;
35
-#elif defined(TARGET_I386) || defined(TARGET_X86_64)
36
- /* Sign bit set, most significant frac bit set */
37
- dnan_pattern = 0b11000000;
38
#elif defined(TARGET_HPPA)
39
/* Sign bit clear, msb-1 frac bit set */
40
dnan_pattern = 0b00100000;
41
--
42
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-39-peter.maydell@linaro.org
7
---
8
target/hppa/fpu_helper.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 ---
10
2 files changed, 2 insertions(+), 3 deletions(-)
11
12
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/hppa/fpu_helper.c
15
+++ b/target/hppa/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
17
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
18
/* For inf * 0 + NaN, return the input NaN */
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
+ /* Default NaN: sign bit clear, msb-1 frac bit set */
21
+ set_float_default_nan_pattern(0b00100000, &env->fp_status);
22
}
23
24
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
31
/* Sign bit clear, all frac bits set */
32
dnan_pattern = 0b01111111;
33
-#elif defined(TARGET_HPPA)
34
- /* Sign bit clear, msb-1 frac bit set */
35
- dnan_pattern = 0b00100000;
36
#elif defined(TARGET_HEXAGON)
37
/* Sign bit set, all frac bits set. */
38
dnan_pattern = 0b11111111;
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for the alpha target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-40-peter.maydell@linaro.org
6
---
7
target/alpha/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/alpha/cpu.c
13
+++ b/target/alpha/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void alpha_cpu_initfn(Object *obj)
15
* operand in Fa. That is float_2nan_prop_ba.
16
*/
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
18
+ /* Default NaN: sign bit clear, msb frac bit set */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
#if defined(CONFIG_USER_ONLY)
21
env->flags = ENV_FLAG_PS_USER | ENV_FLAG_FEN;
22
cpu_alpha_store_fpcr(env, (uint64_t)(FPCR_INVD | FPCR_DZED | FPCR_OVFD
23
--
24
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for the arm target.
2
This includes setting it for the old linux-user nwfpe emulation.
3
For nwfpe, our default doesn't match the real kernel, but we
4
avoid making a behaviour change in this commit.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-41-peter.maydell@linaro.org
9
---
10
linux-user/arm/nwfpe/fpa11.c | 5 +++++
11
target/arm/cpu.c | 2 ++
12
2 files changed, 7 insertions(+)
13
14
diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/linux-user/arm/nwfpe/fpa11.c
17
+++ b/linux-user/arm/nwfpe/fpa11.c
18
@@ -XXX,XX +XXX,XX @@ void resetFPA11(void)
19
* this late date.
20
*/
21
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &fpa11->fp_status);
22
+ /*
23
+ * Use the same default NaN value as Arm VFP. This doesn't match
24
+ * the Linux kernel's nwfpe emulation, which uses an all-1s value.
25
+ */
26
+ set_float_default_nan_pattern(0b01000000, &fpa11->fp_status);
27
}
28
29
void SetRoundingMode(const unsigned int opcode)
30
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu.c
33
+++ b/target/arm/cpu.c
34
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
35
* the pseudocode function the arguments are in the order c, a, b.
36
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
37
* and the input NaN if it is signalling
38
+ * * Default NaN has sign bit clear, msb frac bit set
39
*/
40
static void arm_set_default_fp_behaviours(float_status *s)
41
{
42
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
44
set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
46
+ set_float_default_nan_pattern(0b01000000, s);
47
}
48
49
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
50
--
51
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for loongarch.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-42-peter.maydell@linaro.org
6
---
7
target/loongarch/tcg/fpu_helper.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/loongarch/tcg/fpu_helper.c
13
+++ b/target/loongarch/tcg/fpu_helper.c
14
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
15
*/
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
17
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
18
+ /* Default NaN: sign bit clear, msb frac bit set */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
}
21
22
int ieee_ex_to_loongarch(int xcpt)
23
--
24
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for m68k.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-43-peter.maydell@linaro.org
6
---
7
target/m68k/cpu.c | 2 ++
8
fpu/softfloat-specialize.c.inc | 2 +-
9
2 files changed, 3 insertions(+), 1 deletion(-)
10
11
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/m68k/cpu.c
14
+++ b/target/m68k/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
16
* preceding paragraph for nonsignaling NaNs.
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
+ /* Default NaN: sign bit clear, all frac bits set */
20
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
21
22
nan = floatx80_default_nan(&env->fp_status);
23
for (i = 0; i < 8; i++) {
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
29
uint8_t dnan_pattern = status->default_nan_pattern;
30
31
if (dnan_pattern == 0) {
32
-#if defined(TARGET_SPARC) || defined(TARGET_M68K)
33
+#if defined(TARGET_SPARC)
34
/* Sign bit clear, all frac bits set */
35
dnan_pattern = 0b01111111;
36
#elif defined(TARGET_HEXAGON)
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for MIPS. Note that this
2
is our only target which currently changes the default NaN
3
at runtime (which it was previously doing indirectly when it
4
changed the snan_bit_is_one setting).
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-44-peter.maydell@linaro.org
9
---
10
target/mips/fpu_helper.h | 7 +++++++
11
target/mips/msa.c | 3 +++
12
2 files changed, 10 insertions(+)
13
14
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/mips/fpu_helper.h
17
+++ b/target/mips/fpu_helper.h
18
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
19
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
20
nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
21
set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
22
+ /*
23
+ * With nan2008, the default NaN value has the sign bit clear and the
24
+ * frac msb set; with the older mode, the sign bit is clear, and all
25
+ * frac bits except the msb are set.
26
+ */
27
+ set_float_default_nan_pattern(nan2008 ? 0b01000000 : 0b00111111,
28
+ &env->active_fpu.fp_status);
29
30
}
31
32
diff --git a/target/mips/msa.c b/target/mips/msa.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/mips/msa.c
35
+++ b/target/mips/msa.c
36
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
37
/* Inf * 0 + NaN returns the input NaN */
38
set_float_infzeronan_rule(float_infzeronan_dnan_never,
39
&env->active_tc.msa_fp_status);
40
+ /* Default NaN: sign bit clear, frac msb set */
41
+ set_float_default_nan_pattern(0b01000000,
42
+ &env->active_tc.msa_fp_status);
43
}
44
--
45
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for openrisc.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-45-peter.maydell@linaro.org
6
---
7
target/openrisc/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/openrisc/cpu.c
13
+++ b/target/openrisc/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_reset_hold(Object *obj, ResetType type)
15
*/
16
set_float_2nan_prop_rule(float_2nan_prop_x87, &cpu->env.fp_status);
17
18
+ /* Default NaN: sign bit clear, frac msb set */
19
+ set_float_default_nan_pattern(0b01000000, &cpu->env.fp_status);
20
21
#ifndef CONFIG_USER_ONLY
22
cpu->env.picmr = 0x00000000;
23
--
24
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for ppc.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-46-peter.maydell@linaro.org
6
---
7
target/ppc/cpu_init.c | 4 ++++
8
1 file changed, 4 insertions(+)
9
10
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/ppc/cpu_init.c
13
+++ b/target/ppc/cpu_init.c
14
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
15
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
17
18
+ /* Default NaN: sign bit clear, set frac msb */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
+ set_float_default_nan_pattern(0b01000000, &env->vec_status);
21
+
22
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
23
ppc_spr_t *spr = &env->spr_cb[i];
24
25
--
26
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for sh4. Note that sh4
2
is one of the only three targets (the others being HPPA and
3
sometimes MIPS) that has snan_bit_is_one set.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20241202131347.498124-47-peter.maydell@linaro.org
8
---
9
target/sh4/cpu.c | 2 ++
10
1 file changed, 2 insertions(+)
11
12
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sh4/cpu.c
15
+++ b/target/sh4/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_reset_hold(Object *obj, ResetType type)
17
set_flush_to_zero(1, &env->fp_status);
18
#endif
19
set_default_nan_mode(1, &env->fp_status);
20
+ /* sign bit clear, set all frac bits other than msb */
21
+ set_float_default_nan_pattern(0b00111111, &env->fp_status);
22
}
23
24
static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
25
--
26
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for rx.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-48-peter.maydell@linaro.org
6
---
7
target/rx/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/rx/cpu.c
13
+++ b/target/rx/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void rx_cpu_reset_hold(Object *obj, ResetType type)
15
* then prefer dest over source", which is float_2nan_prop_s_ab.
16
*/
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
18
+ /* Default NaN value: sign bit clear, set frac msb */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
}
21
22
static ObjectClass *rx_cpu_class_by_name(const char *cpu_model)
23
--
24
2.34.1
diff view generated by jsdifflib
1
From: Gustavo Romero <gustavo.romero@linaro.org>
1
Set the default NaN pattern explicitly for s390x.
2
2
3
Enable FEAT_Debugv8p8 for max CPU. This feature is out of scope for QEMU
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
since it concerns the external debug interface for JTAG, but is
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
mandatory in Armv8.8 implementations, hence it is reported as supported
5
Message-id: 20241202131347.498124-49-peter.maydell@linaro.org
6
in the ID registers.
6
---
7
target/s390x/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
7
9
8
Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
10
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20240624180915.4528-4-gustavo.romero@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
docs/system/arm/emulation.rst | 1 +
14
target/arm/tcg/cpu32.c | 6 +++---
15
target/arm/tcg/cpu64.c | 2 +-
16
3 files changed, 5 insertions(+), 4 deletions(-)
17
18
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
19
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
20
--- a/docs/system/arm/emulation.rst
12
--- a/target/s390x/cpu.c
21
+++ b/docs/system/arm/emulation.rst
13
+++ b/target/s390x/cpu.c
22
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
14
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
23
- FEAT_Debugv8p1 (Debug with VHE)
15
set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
24
- FEAT_Debugv8p2 (Debug changes for v8.2)
16
set_float_infzeronan_rule(float_infzeronan_dnan_always,
25
- FEAT_Debugv8p4 (Debug changes for v8.4)
17
&env->fpu_status);
26
+- FEAT_Debugv8p8 (Debug changes for v8.8)
18
+ /* Default NaN value: sign bit clear, frac msb set */
27
- FEAT_DotProd (Advanced SIMD dot product instructions)
19
+ set_float_default_nan_pattern(0b01000000, &env->fpu_status);
28
- FEAT_DoubleFault (Double Fault Extension)
20
/* fall through */
29
- FEAT_E0PD (Preventing EL0 access to halves of address maps)
21
case RESET_TYPE_S390_CPU_NORMAL:
30
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
22
env->psw.mask &= ~PSW_MASK_RI;
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/tcg/cpu32.c
33
+++ b/target/arm/tcg/cpu32.c
34
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
35
cpu->isar.id_pfr2 = t;
36
37
t = cpu->isar.id_dfr0;
38
- t = FIELD_DP32(t, ID_DFR0, COPDBG, 9); /* FEAT_Debugv8p4 */
39
- t = FIELD_DP32(t, ID_DFR0, COPSDBG, 9); /* FEAT_Debugv8p4 */
40
+ t = FIELD_DP32(t, ID_DFR0, COPDBG, 10); /* FEAT_Debugv8p8 */
41
+ t = FIELD_DP32(t, ID_DFR0, COPSDBG, 10); /* FEAT_Debugv8p8 */
42
t = FIELD_DP32(t, ID_DFR0, PERFMON, 6); /* FEAT_PMUv3p5 */
43
cpu->isar.id_dfr0 = t;
44
45
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
46
t = 0x00008000;
47
t = FIELD_DP32(t, DBGDIDR, SE_IMP, 1);
48
t = FIELD_DP32(t, DBGDIDR, NSUHD_IMP, 1);
49
- t = FIELD_DP32(t, DBGDIDR, VERSION, 6); /* Armv8 debug */
50
+ t = FIELD_DP32(t, DBGDIDR, VERSION, 10); /* FEAT_Debugv8p8 */
51
t = FIELD_DP32(t, DBGDIDR, CTX_CMPS, 1);
52
t = FIELD_DP32(t, DBGDIDR, BRPS, 5);
53
t = FIELD_DP32(t, DBGDIDR, WRPS, 3);
54
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/tcg/cpu64.c
57
+++ b/target/arm/tcg/cpu64.c
58
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
59
cpu->isar.id_aa64zfr0 = t;
60
61
t = cpu->isar.id_aa64dfr0;
62
- t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 9); /* FEAT_Debugv8p4 */
63
+ t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 10); /* FEAT_Debugv8p8 */
64
t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 6); /* FEAT_PMUv3p5 */
65
t = FIELD_DP64(t, ID_AA64DFR0, HPMN0, 1); /* FEAT_HPMN0 */
66
cpu->isar.id_aa64dfr0 = t;
67
--
23
--
68
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
From: Gustavo Romero <gustavo.romero@linaro.org>
1
Set the default NaN pattern explicitly for SPARC, and remove
2
the ifdef from parts64_default_nan.
2
3
3
Move the initialization of the debug ID registers to aa32_max_features,
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
which is used to set the 32-bit ID registers. This ensures that the
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
debug ID registers are consistently set for the max CPU in a single
6
Message-id: 20241202131347.498124-50-peter.maydell@linaro.org
6
place.
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 5 +----
10
2 files changed, 3 insertions(+), 4 deletions(-)
7
11
8
Signed-off-by: Gustavo Romero <gustavo.romero@linaro.org>
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20240624180915.4528-3-gustavo.romero@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/cpu.h | 2 ++
14
target/arm/tcg/cpu32.c | 31 ++++++++++++++++++++++++++++---
15
2 files changed, 30 insertions(+), 3 deletions(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
14
--- a/target/sparc/cpu.c
20
+++ b/target/arm/cpu.h
15
+++ b/target/sparc/cpu.c
21
@@ -XXX,XX +XXX,XX @@ FIELD(DBGDEVID, DOUBLELOCK, 20, 4)
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
22
FIELD(DBGDEVID, AUXREGS, 24, 4)
17
set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
23
FIELD(DBGDEVID, CIDMASK, 28, 4)
18
/* For inf * 0 + NaN, return the input NaN */
24
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
25
+FIELD(DBGDEVID1, PCSROFFSET, 0, 4)
20
+ /* Default NaN value: sign bit clear, all frac bits set */
26
+
21
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
27
FIELD(MVFR0, SIMDREG, 0, 4)
22
28
FIELD(MVFR0, FPSP, 4, 4)
23
cpu_exec_realizefn(cs, &local_err);
29
FIELD(MVFR0, FPDP, 8, 4)
24
if (local_err != NULL) {
30
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
31
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/tcg/cpu32.c
27
--- a/fpu/softfloat-specialize.c.inc
33
+++ b/target/arm/tcg/cpu32.c
28
+++ b/fpu/softfloat-specialize.c.inc
34
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
35
t = FIELD_DP32(t, ID_DFR0, PERFMON, 6); /* FEAT_PMUv3p5 */
30
uint8_t dnan_pattern = status->default_nan_pattern;
36
cpu->isar.id_dfr0 = t;
31
37
32
if (dnan_pattern == 0) {
38
+ /* Debug ID registers. */
33
-#if defined(TARGET_SPARC)
39
+
34
- /* Sign bit clear, all frac bits set */
40
+ /* Bit[15] is RES1, Bit[13] and Bits[11:0] are RES0. */
35
- dnan_pattern = 0b01111111;
41
+ t = 0x00008000;
36
-#elif defined(TARGET_HEXAGON)
42
+ t = FIELD_DP32(t, DBGDIDR, SE_IMP, 1);
37
+#if defined(TARGET_HEXAGON)
43
+ t = FIELD_DP32(t, DBGDIDR, NSUHD_IMP, 1);
38
/* Sign bit set, all frac bits set. */
44
+ t = FIELD_DP32(t, DBGDIDR, VERSION, 6); /* Armv8 debug */
39
dnan_pattern = 0b11111111;
45
+ t = FIELD_DP32(t, DBGDIDR, CTX_CMPS, 1);
40
#else
46
+ t = FIELD_DP32(t, DBGDIDR, BRPS, 5);
47
+ t = FIELD_DP32(t, DBGDIDR, WRPS, 3);
48
+ cpu->isar.dbgdidr = t;
49
+
50
+ t = 0;
51
+ t = FIELD_DP32(t, DBGDEVID, PCSAMPLE, 3);
52
+ t = FIELD_DP32(t, DBGDEVID, WPADDRMASK, 1);
53
+ t = FIELD_DP32(t, DBGDEVID, BPADDRMASK, 15);
54
+ t = FIELD_DP32(t, DBGDEVID, VECTORCATCH, 0);
55
+ t = FIELD_DP32(t, DBGDEVID, VIRTEXTNS, 1);
56
+ t = FIELD_DP32(t, DBGDEVID, DOUBLELOCK, 1);
57
+ t = FIELD_DP32(t, DBGDEVID, AUXREGS, 0);
58
+ t = FIELD_DP32(t, DBGDEVID, CIDMASK, 0);
59
+ cpu->isar.dbgdevid = t;
60
+
61
+ /* Bits[31:4] are RES0. */
62
+ t = 0;
63
+ t = FIELD_DP32(t, DBGDEVID1, PCSROFFSET, 2);
64
+ cpu->isar.dbgdevid1 = t;
65
+
66
t = cpu->isar.id_dfr1;
67
t = FIELD_DP32(t, ID_DFR1, HPMN0, 1); /* FEAT_HPMN0 */
68
cpu->isar.id_dfr1 = t;
69
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
70
cpu->isar.id_isar4 = 0x00011142;
71
cpu->isar.id_isar5 = 0x00011121;
72
cpu->isar.id_isar6 = 0;
73
- cpu->isar.dbgdidr = 0x3516d000;
74
- cpu->isar.dbgdevid = 0x00110f13;
75
- cpu->isar.dbgdevid1 = 0x2;
76
cpu->isar.reset_pmcr_el0 = 0x41013000;
77
cpu->clidr = 0x0a200023;
78
cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */
79
--
41
--
80
2.34.1
42
2.34.1
diff view generated by jsdifflib
1
From: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
1
Set the default NaN pattern explicitly for xtensa.
2
2
3
boot-mode property sets user values into BOOT_MODE register, on hardware
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
these are derived from board switches.
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-51-peter.maydell@linaro.org
6
---
7
target/xtensa/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
5
9
6
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
10
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
8
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
9
Message-id: 20240621125906.1300995-2-sai.pavan.boddu@amd.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/misc/zynq_slcr.c | 22 +++++++++++++++++++++-
13
1 file changed, 21 insertions(+), 1 deletion(-)
14
15
diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/misc/zynq_slcr.c
12
--- a/target/xtensa/cpu.c
18
+++ b/hw/misc/zynq_slcr.c
13
+++ b/target/xtensa/cpu.c
19
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
20
#include "hw/registerfields.h"
15
/* For inf * 0 + NaN, return the input NaN */
21
#include "hw/qdev-clock.h"
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
#include "qom/object.h"
17
set_no_signaling_nans(!dfpu, &env->fp_status);
23
+#include "hw/qdev-properties.h"
18
+ /* Default NaN value: sign bit clear, set frac msb */
24
+#include "qapi/error.h"
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
25
20
xtensa_use_first_nan(env, !dfpu);
26
#ifndef ZYNQ_SLCR_ERR_DEBUG
27
#define ZYNQ_SLCR_ERR_DEBUG 0
28
@@ -XXX,XX +XXX,XX @@ REG32(RST_REASON, 0x250)
29
30
REG32(REBOOT_STATUS, 0x258)
31
REG32(BOOT_MODE, 0x25c)
32
+ FIELD(BOOT_MODE, BOOT_MODE, 0, 4)
33
34
REG32(APU_CTRL, 0x300)
35
REG32(WDT_CLK_SEL, 0x304)
36
@@ -XXX,XX +XXX,XX @@ struct ZynqSLCRState {
37
Clock *ps_clk;
38
Clock *uart0_ref_clk;
39
Clock *uart1_ref_clk;
40
+ uint8_t boot_mode;
41
};
42
43
/*
44
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_reset_init(Object *obj, ResetType type)
45
s->regs[R_FPGA_RST_CTRL] = 0x01F33F0F;
46
s->regs[R_RST_REASON] = 0x00000040;
47
48
- s->regs[R_BOOT_MODE] = 0x00000001;
49
+ s->regs[R_BOOT_MODE] = s->boot_mode & R_BOOT_MODE_BOOT_MODE_MASK;
50
51
/* 0x700 - 0x7D4 */
52
for (i = 0; i < 54; i++) {
53
@@ -XXX,XX +XXX,XX @@ static const ClockPortInitArray zynq_slcr_clocks = {
54
QDEV_CLOCK_END
55
};
56
57
+static void zynq_slcr_realize(DeviceState *dev, Error **errp)
58
+{
59
+ ZynqSLCRState *s = ZYNQ_SLCR(dev);
60
+
61
+ if (s->boot_mode > 0xF) {
62
+ error_setg(errp, "Invalid boot mode %d specified", s->boot_mode);
63
+ }
64
+}
65
+
66
static void zynq_slcr_init(Object *obj)
67
{
68
ZynqSLCRState *s = ZYNQ_SLCR(obj);
69
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_zynq_slcr = {
70
}
71
};
72
73
+static Property zynq_slcr_props[] = {
74
+ DEFINE_PROP_UINT8("boot-mode", ZynqSLCRState, boot_mode, 1),
75
+ DEFINE_PROP_END_OF_LIST(),
76
+};
77
+
78
static void zynq_slcr_class_init(ObjectClass *klass, void *data)
79
{
80
DeviceClass *dc = DEVICE_CLASS(klass);
81
ResettableClass *rc = RESETTABLE_CLASS(klass);
82
83
dc->vmsd = &vmstate_zynq_slcr;
84
+ dc->realize = zynq_slcr_realize;
85
rc->phases.enter = zynq_slcr_reset_init;
86
rc->phases.hold = zynq_slcr_reset_hold;
87
rc->phases.exit = zynq_slcr_reset_exit;
88
+ device_class_set_props(dc, zynq_slcr_props);
89
}
21
}
90
22
91
static const TypeInfo zynq_slcr_info = {
92
--
23
--
93
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
From: Rayhan Faizel <rayhan.faizel@gmail.com>
1
Set the default NaN pattern explicitly for hexagon.
2
Remove the ifdef from parts64_default_nan(); the only
3
remaining unconverted targets all use the default case.
2
4
3
Four mailbox properties are implemented as follows:
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
1. Customer OTP: GET_CUSTOMER_OTP and SET_CUSTOMER_OTP
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
2. Device-specific private key: GET_PRIVATE_KEY and
7
Message-id: 20241202131347.498124-52-peter.maydell@linaro.org
6
SET_PRIVATE_KEY.
8
---
9
target/hexagon/cpu.c | 2 ++
10
fpu/softfloat-specialize.c.inc | 5 -----
11
2 files changed, 2 insertions(+), 5 deletions(-)
7
12
8
The customer OTP is located in the rows 36-43. The device-specific private key
13
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
9
is located in the rows 56-63.
10
11
The customer OTP can be locked with the magic numbers 0xffffffff 0xaffe0000
12
when running the SET_CUSTOMER_OTP mailbox command. Bit 6 of row 32 indicates
13
this lock, which is undocumented. The lock also applies to the device-specific
14
private key.
15
16
Signed-off-by: Rayhan Faizel <rayhan.faizel@gmail.com>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
include/hw/arm/raspberrypi-fw-defs.h | 2 +
21
include/hw/misc/bcm2835_property.h | 2 +
22
hw/arm/bcm2835_peripherals.c | 2 +
23
hw/misc/bcm2835_property.c | 87 ++++++++++++++++++++++++++++
24
4 files changed, 93 insertions(+)
25
26
diff --git a/include/hw/arm/raspberrypi-fw-defs.h b/include/hw/arm/raspberrypi-fw-defs.h
27
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/arm/raspberrypi-fw-defs.h
15
--- a/target/hexagon/cpu.c
29
+++ b/include/hw/arm/raspberrypi-fw-defs.h
16
+++ b/target/hexagon/cpu.c
30
@@ -XXX,XX +XXX,XX @@ enum rpi_firmware_property_tag {
17
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
31
RPI_FWREQ_GET_THROTTLED = 0x00030046,
18
32
RPI_FWREQ_GET_CLOCK_MEASURED = 0x00030047,
19
set_default_nan_mode(1, &env->fp_status);
33
RPI_FWREQ_NOTIFY_REBOOT = 0x00030048,
20
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
34
+ RPI_FWREQ_GET_PRIVATE_KEY = 0x00030081,
21
+ /* Default NaN value: sign bit set, all frac bits set */
35
RPI_FWREQ_SET_CLOCK_STATE = 0x00038001,
22
+ set_float_default_nan_pattern(0b11111111, &env->fp_status);
36
RPI_FWREQ_SET_CLOCK_RATE = 0x00038002,
23
}
37
RPI_FWREQ_SET_VOLTAGE = 0x00038003,
24
38
@@ -XXX,XX +XXX,XX @@ enum rpi_firmware_property_tag {
25
static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info)
39
RPI_FWREQ_SET_PERIPH_REG = 0x00038045,
26
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
40
RPI_FWREQ_GET_POE_HAT_VAL = 0x00030049,
41
RPI_FWREQ_SET_POE_HAT_VAL = 0x00038049,
42
+ RPI_FWREQ_SET_PRIVATE_KEY = 0x00038081,
43
RPI_FWREQ_SET_POE_HAT_VAL_OLD = 0x00030050,
44
RPI_FWREQ_NOTIFY_XHCI_RESET = 0x00030058,
45
RPI_FWREQ_GET_REBOOT_FLAGS = 0x00030064,
46
diff --git a/include/hw/misc/bcm2835_property.h b/include/hw/misc/bcm2835_property.h
47
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
48
--- a/include/hw/misc/bcm2835_property.h
28
--- a/fpu/softfloat-specialize.c.inc
49
+++ b/include/hw/misc/bcm2835_property.h
29
+++ b/fpu/softfloat-specialize.c.inc
50
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
51
#include "hw/sysbus.h"
31
uint8_t dnan_pattern = status->default_nan_pattern;
52
#include "net/net.h"
32
53
#include "hw/display/bcm2835_fb.h"
33
if (dnan_pattern == 0) {
54
+#include "hw/nvram/bcm2835_otp.h"
34
-#if defined(TARGET_HEXAGON)
55
#include "qom/object.h"
35
- /* Sign bit set, all frac bits set. */
56
36
- dnan_pattern = 0b11111111;
57
#define TYPE_BCM2835_PROPERTY "bcm2835-property"
37
-#else
58
@@ -XXX,XX +XXX,XX @@ struct BCM2835PropertyState {
38
/*
59
MemoryRegion iomem;
39
* This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
60
qemu_irq mbox_irq;
40
* S390, SH4, TriCore, and Xtensa. Our other supported targets
61
BCM2835FBState *fbdev;
41
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
62
+ BCM2835OTPState *otp;
42
/* sign bit clear, set frac msb */
63
43
dnan_pattern = 0b01000000;
64
MACAddr macaddr;
44
}
65
uint32_t board_rev;
45
-#endif
66
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
46
}
67
index XXXXXXX..XXXXXXX 100644
47
assert(dnan_pattern != 0);
68
--- a/hw/arm/bcm2835_peripherals.c
69
+++ b/hw/arm/bcm2835_peripherals.c
70
@@ -XXX,XX +XXX,XX @@ static void raspi_peripherals_base_init(Object *obj)
71
OBJECT(&s->fb));
72
object_property_add_const_link(OBJECT(&s->property), "dma-mr",
73
OBJECT(&s->gpu_bus_mr));
74
+ object_property_add_const_link(OBJECT(&s->property), "otp",
75
+ OBJECT(&s->otp));
76
77
/* Extended Mass Media Controller */
78
object_initialize_child(obj, "sdhci", &s->sdhci, TYPE_SYSBUS_SDHCI);
79
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/misc/bcm2835_property.c
82
+++ b/hw/misc/bcm2835_property.c
83
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
84
uint32_t tmp;
85
int n;
86
uint32_t offset, length, color;
87
+ uint32_t start_num, number, otp_row;
88
89
/*
90
* Copy the current state of the framebuffer config; we will update
91
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)
92
0);
93
resplen = VCHI_BUSADDR_SIZE;
94
break;
95
+
96
+ /* Customer OTP */
97
+
98
+ case RPI_FWREQ_GET_CUSTOMER_OTP:
99
+ start_num = ldl_le_phys(&s->dma_as, value + 12);
100
+ number = ldl_le_phys(&s->dma_as, value + 16);
101
+
102
+ resplen = 8 + 4 * number;
103
+
104
+ for (n = start_num; n < start_num + number &&
105
+ n < BCM2835_OTP_CUSTOMER_OTP_LEN; n++) {
106
+ otp_row = bcm2835_otp_get_row(s->otp,
107
+ BCM2835_OTP_CUSTOMER_OTP + n);
108
+ stl_le_phys(&s->dma_as,
109
+ value + 20 + ((n - start_num) << 2), otp_row);
110
+ }
111
+ break;
112
+ case RPI_FWREQ_SET_CUSTOMER_OTP:
113
+ start_num = ldl_le_phys(&s->dma_as, value + 12);
114
+ number = ldl_le_phys(&s->dma_as, value + 16);
115
+
116
+ resplen = 4;
117
+
118
+ /* Magic numbers to permanently lock customer OTP */
119
+ if (start_num == BCM2835_OTP_LOCK_NUM1 &&
120
+ number == BCM2835_OTP_LOCK_NUM2) {
121
+ bcm2835_otp_set_row(s->otp,
122
+ BCM2835_OTP_ROW_32,
123
+ BCM2835_OTP_ROW_32_LOCK);
124
+ break;
125
+ }
126
+
127
+ /* If row 32 has the lock bit, don't allow further writes */
128
+ if (bcm2835_otp_get_row(s->otp, BCM2835_OTP_ROW_32) &
129
+ BCM2835_OTP_ROW_32_LOCK) {
130
+ break;
131
+ }
132
+
133
+ for (n = start_num; n < start_num + number &&
134
+ n < BCM2835_OTP_CUSTOMER_OTP_LEN; n++) {
135
+ otp_row = ldl_le_phys(&s->dma_as,
136
+ value + 20 + ((n - start_num) << 2));
137
+ bcm2835_otp_set_row(s->otp,
138
+ BCM2835_OTP_CUSTOMER_OTP + n, otp_row);
139
+ }
140
+ break;
141
+
142
+ /* Device-specific private key */
143
+
144
+ case RPI_FWREQ_GET_PRIVATE_KEY:
145
+ start_num = ldl_le_phys(&s->dma_as, value + 12);
146
+ number = ldl_le_phys(&s->dma_as, value + 16);
147
+
148
+ resplen = 8 + 4 * number;
149
+
150
+ for (n = start_num; n < start_num + number &&
151
+ n < BCM2835_OTP_PRIVATE_KEY_LEN; n++) {
152
+ otp_row = bcm2835_otp_get_row(s->otp,
153
+ BCM2835_OTP_PRIVATE_KEY + n);
154
+ stl_le_phys(&s->dma_as,
155
+ value + 20 + ((n - start_num) << 2), otp_row);
156
+ }
157
+ break;
158
+ case RPI_FWREQ_SET_PRIVATE_KEY:
159
+ start_num = ldl_le_phys(&s->dma_as, value + 12);
160
+ number = ldl_le_phys(&s->dma_as, value + 16);
161
+
162
+ resplen = 4;
163
+
164
+ /* If row 32 has the lock bit, don't allow further writes */
165
+ if (bcm2835_otp_get_row(s->otp, BCM2835_OTP_ROW_32) &
166
+ BCM2835_OTP_ROW_32_LOCK) {
167
+ break;
168
+ }
169
+
170
+ for (n = start_num; n < start_num + number &&
171
+ n < BCM2835_OTP_PRIVATE_KEY_LEN; n++) {
172
+ otp_row = ldl_le_phys(&s->dma_as,
173
+ value + 20 + ((n - start_num) << 2));
174
+ bcm2835_otp_set_row(s->otp,
175
+ BCM2835_OTP_PRIVATE_KEY + n, otp_row);
176
+ }
177
+ break;
178
default:
179
qemu_log_mask(LOG_UNIMP,
180
"bcm2835_property: unhandled tag 0x%08x\n", tag);
181
@@ -XXX,XX +XXX,XX @@ static void bcm2835_property_realize(DeviceState *dev, Error **errp)
182
s->dma_mr = MEMORY_REGION(obj);
183
address_space_init(&s->dma_as, s->dma_mr, TYPE_BCM2835_PROPERTY "-memory");
184
185
+ obj = object_property_get_link(OBJECT(dev), "otp", &error_abort);
186
+ s->otp = BCM2835_OTP(obj);
187
+
188
/* TODO: connect to MAC address of USB NIC device, once we emulate it */
189
qemu_macaddr_default_if_unset(&s->macaddr);
190
48
191
--
49
--
192
2.34.1
50
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Set the default NaN pattern explicitly for riscv.
2
2
3
Input denormals cause the Javascript inexact bit
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
(output to Z) to be set.
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-53-peter.maydell@linaro.org
6
---
7
target/riscv/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
5
9
6
Cc: qemu-stable@nongnu.org
10
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
7
Fixes: 6c1f6f2733a ("target/arm: Implement ARMv8.3-JSConv")
8
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2375
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20240625183536.1672454-4-richard.henderson@linaro.org
12
[PMM: fixed hardcoded tab in test case]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/vfp_helper.c | 18 +++++++++---------
16
tests/tcg/aarch64/test-2375.c | 21 +++++++++++++++++++++
17
tests/tcg/aarch64/Makefile.target | 3 ++-
18
3 files changed, 32 insertions(+), 10 deletions(-)
19
create mode 100644 tests/tcg/aarch64/test-2375.c
20
21
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
22
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/vfp_helper.c
12
--- a/target/riscv/cpu.c
24
+++ b/target/arm/vfp_helper.c
13
+++ b/target/riscv/cpu.c
25
@@ -XXX,XX +XXX,XX @@ const FloatRoundMode arm_rmode_to_sf_map[] = {
14
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
26
uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus)
15
cs->exception_index = RISCV_EXCP_NONE;
27
{
16
env->load_res = -1;
28
float_status *status = vstatus;
17
set_default_nan_mode(1, &env->fp_status);
29
- uint32_t inexact, frac;
18
+ /* Default NaN value: sign bit clear, frac msb set */
30
- uint32_t e_old, e_new;
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
31
+ uint32_t frac, e_old, e_new;
20
env->vill = true;
32
+ bool inexact;
21
33
22
#ifndef CONFIG_USER_ONLY
34
e_old = get_float_exception_flags(status);
35
set_float_exception_flags(0, status);
36
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus)
37
e_new = get_float_exception_flags(status);
38
set_float_exception_flags(e_old | e_new, status);
39
40
- if (value == float64_chs(float64_zero)) {
41
- /* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
42
- inexact = 1;
43
- } else {
44
- /* Normal inexact or overflow or NaN */
45
- inexact = e_new & (float_flag_inexact | float_flag_invalid);
46
- }
47
+ /* Normal inexact, denormal with flush-to-zero, or overflow or NaN */
48
+ inexact = e_new & (float_flag_inexact |
49
+ float_flag_input_denormal |
50
+ float_flag_invalid);
51
+
52
+ /* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
53
+ inexact |= value == float64_chs(float64_zero);
54
55
/* Pack the result and the env->ZF representation of Z together. */
56
return deposit64(frac, 32, 32, inexact);
57
diff --git a/tests/tcg/aarch64/test-2375.c b/tests/tcg/aarch64/test-2375.c
58
new file mode 100644
59
index XXXXXXX..XXXXXXX
60
--- /dev/null
61
+++ b/tests/tcg/aarch64/test-2375.c
62
@@ -XXX,XX +XXX,XX @@
63
+/* SPDX-License-Identifier: GPL-2.0-or-later */
64
+/* Copyright (c) 2024 Linaro Ltd */
65
+/* See https://gitlab.com/qemu-project/qemu/-/issues/2375 */
66
+
67
+#include <assert.h>
68
+
69
+int main(void)
70
+{
71
+ int r, z;
72
+
73
+ asm("msr fpcr, %2\n\t"
74
+ "fjcvtzs %w0, %d3\n\t"
75
+ "cset %1, eq"
76
+ : "=r"(r), "=r"(z)
77
+ : "r"(0x01000000L), /* FZ = 1 */
78
+ "w"(0xfcff00L)); /* denormal */
79
+
80
+ assert(r == 0);
81
+ assert(z == 0);
82
+ return 0;
83
+}
84
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
85
index XXXXXXX..XXXXXXX 100644
86
--- a/tests/tcg/aarch64/Makefile.target
87
+++ b/tests/tcg/aarch64/Makefile.target
88
@@ -XXX,XX +XXX,XX @@ endif
89
90
# Pauth Tests
91
ifneq ($(CROSS_CC_HAS_ARMV8_3),)
92
-AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5
93
+AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5 test-2375
94
pauth-%: CFLAGS += -march=armv8.3-a
95
+test-2375: CFLAGS += -march=armv8.3-a
96
run-pauth-1: QEMU_OPTS += -cpu max
97
run-pauth-2: QEMU_OPTS += -cpu max
98
# Choose a cpu with FEAT_Pauth but without FEAT_FPAC for pauth-[45].
99
--
23
--
100
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Set the default NaN pattern explicitly for tricore.
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20240625183536.1672454-12-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-54-peter.maydell@linaro.org
7
---
6
---
8
target/arm/tcg/a64.decode | 3 +++
7
target/tricore/helper.c | 2 ++
9
target/arm/tcg/translate-a64.c | 33 ++++++++++-----------------------
8
1 file changed, 2 insertions(+)
10
2 files changed, 13 insertions(+), 23 deletions(-)
11
9
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
10
diff --git a/target/tricore/helper.c b/target/tricore/helper.c
13
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/a64.decode
12
--- a/target/tricore/helper.c
15
+++ b/target/arm/tcg/a64.decode
13
+++ b/target/tricore/helper.c
16
@@ -XXX,XX +XXX,XX @@ SMMLA 0100 1110 100 ..... 10100 1 ..... ..... @rrr_q1e0
14
@@ -XXX,XX +XXX,XX @@ void fpu_set_state(CPUTriCoreState *env)
17
UMMLA 0110 1110 100 ..... 10100 1 ..... ..... @rrr_q1e0
15
set_flush_to_zero(1, &env->fp_status);
18
USMMLA 0100 1110 100 ..... 10101 1 ..... ..... @rrr_q1e0
16
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
19
17
set_default_nan_mode(1, &env->fp_status);
20
+FCADD_90 0.10 1110 ..0 ..... 11100 1 ..... ..... @qrrr_e
18
+ /* Default NaN pattern: sign bit clear, frac msb set */
21
+FCADD_270 0.10 1110 ..0 ..... 11110 1 ..... ..... @qrrr_e
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
22
+
23
### Advanced SIMD scalar x indexed element
24
25
FMUL_si 0101 1111 00 .. .... 1001 . 0 ..... ..... @rrx_h
26
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/tcg/translate-a64.c
29
+++ b/target/arm/tcg/translate-a64.c
30
@@ -XXX,XX +XXX,XX @@ static bool trans_BFMLAL_v(DisasContext *s, arg_qrrr_e *a)
31
return true;
32
}
20
}
33
21
34
+static gen_helper_gvec_3_ptr * const f_vector_fcadd[3] = {
22
uint32_t psw_read(CPUTriCoreState *env)
35
+ gen_helper_gvec_fcaddh,
36
+ gen_helper_gvec_fcadds,
37
+ gen_helper_gvec_fcaddd,
38
+};
39
+TRANS_FEAT(FCADD_90, aa64_fcma, do_fp3_vector, a, 0, f_vector_fcadd)
40
+TRANS_FEAT(FCADD_270, aa64_fcma, do_fp3_vector, a, 1, f_vector_fcadd)
41
+
42
/*
43
* Advanced SIMD scalar/vector x indexed element
44
*/
45
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
46
case 0x19: /* FCMLA, #90 */
47
case 0x1a: /* FCMLA, #180 */
48
case 0x1b: /* FCMLA, #270 */
49
- case 0x1c: /* FCADD, #90 */
50
- case 0x1e: /* FCADD, #270 */
51
if (size == 0
52
|| (size == 1 && !dc_isar_feature(aa64_fp16, s))
53
|| (size == 3 && !is_q)) {
54
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
55
case 0x11: /* SQRDMLSH (vector) */
56
case 0x12: /* UDOT (vector) */
57
case 0x14: /* UMMLA */
58
+ case 0x1c: /* FCADD, #90 */
59
case 0x1d: /* BFMMLA */
60
+ case 0x1e: /* FCADD, #270 */
61
case 0x1f: /* BFDOT / BFMLAL */
62
unallocated_encoding(s);
63
return;
64
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
65
}
66
return;
67
68
- case 0xc: /* FCADD, #90 */
69
- case 0xe: /* FCADD, #270 */
70
- rot = extract32(opcode, 1, 1);
71
- switch (size) {
72
- case 1:
73
- gen_gvec_op3_fpst(s, is_q, rd, rn, rm, size == 1, rot,
74
- gen_helper_gvec_fcaddh);
75
- break;
76
- case 2:
77
- gen_gvec_op3_fpst(s, is_q, rd, rn, rm, size == 1, rot,
78
- gen_helper_gvec_fcadds);
79
- break;
80
- case 3:
81
- gen_gvec_op3_fpst(s, is_q, rd, rn, rm, size == 1, rot,
82
- gen_helper_gvec_fcaddd);
83
- break;
84
- default:
85
- g_assert_not_reached();
86
- }
87
- return;
88
-
89
default:
90
g_assert_not_reached();
91
}
92
--
23
--
93
2.34.1
24
2.34.1
diff view generated by jsdifflib
1
From: Nicolin Chen <nicolinc@nvidia.com>
1
Now that all our targets have bene converted to explicitly specify
2
their pattern for the default NaN value we can remove the remaining
3
fallback code in parts64_default_nan().
2
4
3
The caller of smmu_iommu_mr wants to get sdev for smmuv3_flush_config().
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20241202131347.498124-55-peter.maydell@linaro.org
8
---
9
fpu/softfloat-specialize.c.inc | 14 --------------
10
1 file changed, 14 deletions(-)
4
11
5
Do it directly instead of bridging with an iommu mr pointer.
12
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
6
7
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
8
Message-id: 20240619002218.926674-1-nicolinc@nvidia.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/smmu-common.h | 4 ++--
13
hw/arm/smmu-common.c | 8 ++------
14
hw/arm/smmuv3.c | 12 ++++--------
15
3 files changed, 8 insertions(+), 16 deletions(-)
16
17
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/smmu-common.h
14
--- a/fpu/softfloat-specialize.c.inc
20
+++ b/include/hw/arm/smmu-common.h
15
+++ b/fpu/softfloat-specialize.c.inc
21
@@ -XXX,XX +XXX,XX @@ int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
16
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
22
*/
17
uint64_t frac;
23
SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova);
18
uint8_t dnan_pattern = status->default_nan_pattern;
24
19
25
-/* Return the iommu mr associated to @sid, or NULL if none */
20
- if (dnan_pattern == 0) {
26
-IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid);
21
- /*
27
+/* Return the SMMUDevice associated to @sid, or NULL if none */
22
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
28
+SMMUDevice *smmu_find_sdev(SMMUState *s, uint32_t sid);
23
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
29
24
- * do not have floating-point.
30
#define SMMU_IOTLB_MAX_SIZE 256
25
- */
31
26
- if (snan_bit_is_one(status)) {
32
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
27
- /* sign bit clear, set all frac bits other than msb */
33
index XXXXXXX..XXXXXXX 100644
28
- dnan_pattern = 0b00111111;
34
--- a/hw/arm/smmu-common.c
29
- } else {
35
+++ b/hw/arm/smmu-common.c
30
- /* sign bit clear, set frac msb */
36
@@ -XXX,XX +XXX,XX @@ static const PCIIOMMUOps smmu_ops = {
31
- dnan_pattern = 0b01000000;
37
.get_address_space = smmu_find_add_as,
38
};
39
40
-IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid)
41
+SMMUDevice *smmu_find_sdev(SMMUState *s, uint32_t sid)
42
{
43
uint8_t bus_n, devfn;
44
SMMUPciBus *smmu_bus;
45
- SMMUDevice *smmu;
46
47
bus_n = PCI_BUS_NUM(sid);
48
smmu_bus = smmu_find_smmu_pcibus(s, bus_n);
49
if (smmu_bus) {
50
devfn = SMMU_PCI_DEVFN(sid);
51
- smmu = smmu_bus->pbdev[devfn];
52
- if (smmu) {
53
- return &smmu->iommu;
54
- }
32
- }
55
+ return smmu_bus->pbdev[devfn];
33
- }
56
}
34
assert(dnan_pattern != 0);
57
return NULL;
35
58
}
36
sign = dnan_pattern >> 7;
59
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/smmuv3.c
62
+++ b/hw/arm/smmuv3.c
63
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
64
case SMMU_CMD_CFGI_STE:
65
{
66
uint32_t sid = CMD_SID(&cmd);
67
- IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid);
68
- SMMUDevice *sdev;
69
+ SMMUDevice *sdev = smmu_find_sdev(bs, sid);
70
71
if (CMD_SSEC(&cmd)) {
72
cmd_error = SMMU_CERROR_ILL;
73
break;
74
}
75
76
- if (!mr) {
77
+ if (!sdev) {
78
break;
79
}
80
81
trace_smmuv3_cmdq_cfgi_ste(sid);
82
- sdev = container_of(mr, SMMUDevice, iommu);
83
smmuv3_flush_config(sdev);
84
85
break;
86
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
87
case SMMU_CMD_CFGI_CD_ALL:
88
{
89
uint32_t sid = CMD_SID(&cmd);
90
- IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid);
91
- SMMUDevice *sdev;
92
+ SMMUDevice *sdev = smmu_find_sdev(bs, sid);
93
94
if (CMD_SSEC(&cmd)) {
95
cmd_error = SMMU_CERROR_ILL;
96
break;
97
}
98
99
- if (!mr) {
100
+ if (!sdev) {
101
break;
102
}
103
104
trace_smmuv3_cmdq_cfgi_cd(sid);
105
- sdev = container_of(mr, SMMUDevice, iommu);
106
smmuv3_flush_config(sdev);
107
break;
108
}
109
--
37
--
110
2.34.1
38
2.34.1
diff view generated by jsdifflib
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The implementation of configurable interrupts (interrupts supporting
3
Inline pickNaNMulAdd into its only caller. This makes
4
edge selection) was incorrectly expecting alternating input levels :
4
one assert redundant with the immediately preceding IF.
5
this commits adds a new status field `irq_levels` to actually detect
6
edges.
7
5
8
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20240629110800.539969-2-ines.varhol@telecom-paris.fr
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20241203203949.483774-3-richard.henderson@linaro.org
9
[PMM: keep comment from old code in new location]
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
11
---
13
include/hw/misc/stm32l4x5_exti.h | 2 ++
12
fpu/softfloat-parts.c.inc | 41 +++++++++++++++++++++++++-
14
hw/misc/stm32l4x5_exti.c | 28 +++++++++++++---------------
13
fpu/softfloat-specialize.c.inc | 54 ----------------------------------
15
2 files changed, 15 insertions(+), 15 deletions(-)
14
2 files changed, 40 insertions(+), 55 deletions(-)
16
15
17
diff --git a/include/hw/misc/stm32l4x5_exti.h b/include/hw/misc/stm32l4x5_exti.h
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/misc/stm32l4x5_exti.h
18
--- a/fpu/softfloat-parts.c.inc
20
+++ b/include/hw/misc/stm32l4x5_exti.h
19
+++ b/fpu/softfloat-parts.c.inc
21
@@ -XXX,XX +XXX,XX @@ struct Stm32l4x5ExtiState {
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
22
uint32_t swier[EXTI_NUM_REGISTER];
21
}
23
uint32_t pr[EXTI_NUM_REGISTER];
22
24
23
if (s->default_nan_mode) {
25
+ /* used for edge detection */
24
+ /*
26
+ uint32_t irq_levels[EXTI_NUM_REGISTER];
25
+ * We guarantee not to require the target to tell us how to
27
qemu_irq irq[EXTI_NUM_INTERRUPT_OUT_LINES];
26
+ * pick a NaN if we're always returning the default NaN.
28
};
27
+ * But if we're not in default-NaN mode then the target must
29
28
+ * specify.
30
diff --git a/hw/misc/stm32l4x5_exti.c b/hw/misc/stm32l4x5_exti.c
29
+ */
30
which = 3;
31
+ } else if (infzero) {
32
+ /*
33
+ * Inf * 0 + NaN -- some implementations return the
34
+ * default NaN here, and some return the input NaN.
35
+ */
36
+ switch (s->float_infzeronan_rule) {
37
+ case float_infzeronan_dnan_never:
38
+ which = 2;
39
+ break;
40
+ case float_infzeronan_dnan_always:
41
+ which = 3;
42
+ break;
43
+ case float_infzeronan_dnan_if_qnan:
44
+ which = is_qnan(c->cls) ? 3 : 2;
45
+ break;
46
+ default:
47
+ g_assert_not_reached();
48
+ }
49
} else {
50
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, have_snan, s);
51
+ FloatClass cls[3] = { a->cls, b->cls, c->cls };
52
+ Float3NaNPropRule rule = s->float_3nan_prop_rule;
53
+
54
+ assert(rule != float_3nan_prop_none);
55
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
56
+ /* We have at least one SNaN input and should prefer it */
57
+ do {
58
+ which = rule & R_3NAN_1ST_MASK;
59
+ rule >>= R_3NAN_1ST_LENGTH;
60
+ } while (!is_snan(cls[which]));
61
+ } else {
62
+ do {
63
+ which = rule & R_3NAN_1ST_MASK;
64
+ rule >>= R_3NAN_1ST_LENGTH;
65
+ } while (!is_nan(cls[which]));
66
+ }
67
}
68
69
if (which == 3) {
70
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
31
index XXXXXXX..XXXXXXX 100644
71
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/misc/stm32l4x5_exti.c
72
--- a/fpu/softfloat-specialize.c.inc
33
+++ b/hw/misc/stm32l4x5_exti.c
73
+++ b/fpu/softfloat-specialize.c.inc
34
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_exti_reset_hold(Object *obj, ResetType type)
74
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
35
s->ftsr[bank] = 0x00000000;
36
s->swier[bank] = 0x00000000;
37
s->pr[bank] = 0x00000000;
38
+ s->irq_levels[bank] = 0x00000000;
39
}
75
}
40
}
76
}
41
77
42
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_exti_set_irq(void *opaque, int irq, int level)
78
-/*----------------------------------------------------------------------------
43
/* Shift the value to enable access in x2 registers. */
79
-| Select which NaN to propagate for a three-input operation.
44
irq %= EXTI_MAX_IRQ_PER_BANK;
80
-| For the moment we assume that no CPU needs the 'larger significand'
45
81
-| information.
46
+ if (level == extract32(s->irq_levels[bank], irq, 1)) {
82
-| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
47
+ /* No change in IRQ line state: do nothing */
83
-*----------------------------------------------------------------------------*/
48
+ return;
84
-static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
49
+ }
85
- bool infzero, bool have_snan, float_status *status)
50
+ s->irq_levels[bank] = deposit32(s->irq_levels[bank], irq, 1, level);
86
-{
51
+
87
- FloatClass cls[3] = { a_cls, b_cls, c_cls };
52
/* If the interrupt is masked, pr won't be raised */
88
- Float3NaNPropRule rule = status->float_3nan_prop_rule;
53
if (!extract32(s->imr[bank], irq, 1)) {
89
- int which;
54
return;
90
-
55
}
56
57
- if (((1 << irq) & s->rtsr[bank]) && level) {
58
- /* Rising Edge */
59
- s->pr[bank] |= 1 << irq;
60
- qemu_irq_pulse(s->irq[oirq]);
61
- } else if (((1 << irq) & s->ftsr[bank]) && !level) {
62
- /* Falling Edge */
63
+ if ((level && extract32(s->rtsr[bank], irq, 1)) ||
64
+ (!level && extract32(s->ftsr[bank], irq, 1))) {
65
+
66
s->pr[bank] |= 1 << irq;
67
qemu_irq_pulse(s->irq[oirq]);
68
}
69
- /*
91
- /*
70
- * In the following situations :
92
- * We guarantee not to require the target to tell us how to
71
- * - falling edge but rising trigger selected
93
- * pick a NaN if we're always returning the default NaN.
72
- * - rising edge but falling trigger selected
94
- * But if we're not in default-NaN mode then the target must
73
- * - no trigger selected
95
- * specify.
74
- * No action is required
75
- */
96
- */
76
}
97
- assert(!status->default_nan_mode);
77
98
-
78
static uint64_t stm32l4x5_exti_read(void *opaque, hwaddr addr,
99
- if (infzero) {
79
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_exti_init(Object *obj)
100
- /*
80
101
- * Inf * 0 + NaN -- some implementations return the default NaN here,
81
static const VMStateDescription vmstate_stm32l4x5_exti = {
102
- * and some return the input NaN.
82
.name = TYPE_STM32L4X5_EXTI,
103
- */
83
- .version_id = 1,
104
- switch (status->float_infzeronan_rule) {
84
- .minimum_version_id = 1,
105
- case float_infzeronan_dnan_never:
85
+ .version_id = 2,
106
- return 2;
86
+ .minimum_version_id = 2,
107
- case float_infzeronan_dnan_always:
87
.fields = (VMStateField[]) {
108
- return 3;
88
VMSTATE_UINT32_ARRAY(imr, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
109
- case float_infzeronan_dnan_if_qnan:
89
VMSTATE_UINT32_ARRAY(emr, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
110
- return is_qnan(c_cls) ? 3 : 2;
90
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_stm32l4x5_exti = {
111
- default:
91
VMSTATE_UINT32_ARRAY(ftsr, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
112
- g_assert_not_reached();
92
VMSTATE_UINT32_ARRAY(swier, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
113
- }
93
VMSTATE_UINT32_ARRAY(pr, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
114
- }
94
+ VMSTATE_UINT32_ARRAY(irq_levels, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
115
-
95
VMSTATE_END_OF_LIST()
116
- assert(rule != float_3nan_prop_none);
96
}
117
- if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
97
};
118
- /* We have at least one SNaN input and should prefer it */
119
- do {
120
- which = rule & R_3NAN_1ST_MASK;
121
- rule >>= R_3NAN_1ST_LENGTH;
122
- } while (!is_snan(cls[which]));
123
- } else {
124
- do {
125
- which = rule & R_3NAN_1ST_MASK;
126
- rule >>= R_3NAN_1ST_LENGTH;
127
- } while (!is_nan(cls[which]));
128
- }
129
- return which;
130
-}
131
-
132
/*----------------------------------------------------------------------------
133
| Returns 1 if the double-precision floating-point value `a' is a quiet
134
| NaN; otherwise returns 0.
98
--
135
--
99
2.34.1
136
2.34.1
100
137
101
138
diff view generated by jsdifflib
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The QTest `test_irq_pin_multiplexer` makes the assumption that the
3
Remove "3" as a special case for which and simply
4
reset state of irq line 15 is low, which is false since STM32L4x5 GPIO
4
branch to return the desired value.
5
was implemented (the reset state of pin GPIOA15 is high because there's
6
pull-up and it results in the irq line 15 also being high at reset).
7
5
8
It wasn't triggering an error because `test_interrupt` was mistakenly
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
"resetting" the line low.
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
8
Message-id: 20241203203949.483774-4-richard.henderson@linaro.org
11
This commit corrects these two mistakes by :
12
- not setting the line low in `test_interrupt`
13
- using an irq line in `test_irq_pin_multiplexer` which is low at reset
14
15
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
16
Message-id: 20240629104454.366283-1-ines.varhol@telecom-paris.fr
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
10
---
20
tests/qtest/stm32l4x5_syscfg-test.c | 14 +++++++-------
11
fpu/softfloat-parts.c.inc | 20 ++++++++++----------
21
1 file changed, 7 insertions(+), 7 deletions(-)
12
1 file changed, 10 insertions(+), 10 deletions(-)
22
13
23
diff --git a/tests/qtest/stm32l4x5_syscfg-test.c b/tests/qtest/stm32l4x5_syscfg-test.c
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
24
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
25
--- a/tests/qtest/stm32l4x5_syscfg-test.c
16
--- a/fpu/softfloat-parts.c.inc
26
+++ b/tests/qtest/stm32l4x5_syscfg-test.c
17
+++ b/fpu/softfloat-parts.c.inc
27
@@ -XXX,XX +XXX,XX @@ static void test_interrupt(void)
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
28
/* Clean the test */
19
* But if we're not in default-NaN mode then the target must
29
syscfg_writel(SYSCFG_EXTICR1, 0x00000000);
20
* specify.
30
syscfg_set_irq(0, 0);
21
*/
31
- syscfg_set_irq(15, 0);
22
- which = 3;
32
+ /* irq 15 is high at reset because GPIOA15 is high at reset */
23
+ goto default_nan;
33
syscfg_set_irq(17, 0);
24
} else if (infzero) {
25
/*
26
* Inf * 0 + NaN -- some implementations return the
27
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
28
*/
29
switch (s->float_infzeronan_rule) {
30
case float_infzeronan_dnan_never:
31
- which = 2;
32
break;
33
case float_infzeronan_dnan_always:
34
- which = 3;
35
- break;
36
+ goto default_nan;
37
case float_infzeronan_dnan_if_qnan:
38
- which = is_qnan(c->cls) ? 3 : 2;
39
+ if (is_qnan(c->cls)) {
40
+ goto default_nan;
41
+ }
42
break;
43
default:
44
g_assert_not_reached();
45
}
46
+ which = 2;
47
} else {
48
FloatClass cls[3] = { a->cls, b->cls, c->cls };
49
Float3NaNPropRule rule = s->float_3nan_prop_rule;
50
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
51
}
52
}
53
54
- if (which == 3) {
55
- parts_default_nan(a, s);
56
- return a;
57
- }
58
-
59
switch (which) {
60
case 0:
61
break;
62
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
63
parts_silence_nan(a, s);
64
}
65
return a;
66
+
67
+ default_nan:
68
+ parts_default_nan(a, s);
69
+ return a;
34
}
70
}
35
71
36
@@ -XXX,XX +XXX,XX @@ static void test_irq_pin_multiplexer(void)
72
/*
37
38
syscfg_set_irq(0, 1);
39
40
- /* Check that irq 0 was set and irq 15 wasn't */
41
+ /* Check that irq 0 was set and irq 2 wasn't */
42
g_assert_true(get_irq(0));
43
- g_assert_false(get_irq(15));
44
+ g_assert_false(get_irq(2));
45
46
/* Clean the test */
47
syscfg_set_irq(0, 0);
48
49
- syscfg_set_irq(15, 1);
50
+ syscfg_set_irq(2, 1);
51
52
- /* Check that irq 15 was set and irq 0 wasn't */
53
- g_assert_true(get_irq(15));
54
+ /* Check that irq 2 was set and irq 0 wasn't */
55
+ g_assert_true(get_irq(2));
56
g_assert_false(get_irq(0));
57
58
/* Clean the test */
59
- syscfg_set_irq(15, 0);
60
+ syscfg_set_irq(2, 0);
61
}
62
63
static void test_irq_gpio_multiplexer(void)
64
--
73
--
65
2.34.1
74
2.34.1
66
75
67
76
diff view generated by jsdifflib
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Update firmware to have graphics card memory fix from EDK2 commit
3
Assign the pointer return value to 'a' directly,
4
c1d1910be6e04a8b1a73090cf2881fb698947a6e:
4
rather than going through an intermediary index.
5
5
6
OvmfPkg/QemuVideoDxe: add feature PCD to remap framebuffer W/C
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
8
Some platforms (such as SBSA-QEMU on recent builds of the emulator) only
9
tolerate misaligned accesses to normal memory, and raise alignment
10
faults on such accesses to device memory, which is the default for PCIe
11
MMIO BARs.
12
13
When emulating a PCIe graphics controller, the framebuffer is typically
14
exposed via a MMIO BAR, while the disposition of the region is closer to
15
memory (no side effects on reads or writes, except for the changing
16
picture on the screen; direct random access to any pixel in the image).
17
18
In order to permit the use of such controllers on platforms that only
19
tolerate these types of accesses for normal memory, it is necessary to
20
remap the memory. Use the DXE services to set the desired capabilities
21
and attributes.
22
23
Hide this behavior under a feature PCD so only platforms that really
24
need it can enable it. (OVMF on x86 has no need for this)
25
26
With this fix enabled we can boot sbsa-ref with more than one cpu core.
27
28
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
29
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
30
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-5-richard.henderson@linaro.org
31
Message-id: 20240620-b4-new-firmware-v3-1-29a3a2f1be1e@linaro.org
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
---
10
---
34
tests/avocado/machine_aarch64_sbsaref.py | 14 +++++++-------
11
fpu/softfloat-parts.c.inc | 32 ++++++++++----------------------
35
1 file changed, 7 insertions(+), 7 deletions(-)
12
1 file changed, 10 insertions(+), 22 deletions(-)
36
13
37
diff --git a/tests/avocado/machine_aarch64_sbsaref.py b/tests/avocado/machine_aarch64_sbsaref.py
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
38
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
39
--- a/tests/avocado/machine_aarch64_sbsaref.py
16
--- a/fpu/softfloat-parts.c.inc
40
+++ b/tests/avocado/machine_aarch64_sbsaref.py
17
+++ b/fpu/softfloat-parts.c.inc
41
@@ -XXX,XX +XXX,XX @@ def fetch_firmware(self):
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
42
19
FloatPartsN *c, float_status *s,
43
Used components:
20
int ab_mask, int abc_mask)
44
21
{
45
- - Trusted Firmware 2.11.0
22
- int which;
46
- - Tianocore EDK2 stable202405
23
bool infzero = (ab_mask == float_cmask_infzero);
47
- - Tianocore EDK2-platforms commit 4bbd0ed
24
bool have_snan = (abc_mask & float_cmask_snan);
48
+ - Trusted Firmware v2.11.0
25
+ FloatPartsN *ret;
49
+ - Tianocore EDK2 4d4f569924
26
50
+ - Tianocore EDK2-platforms 3f08401
27
if (unlikely(have_snan)) {
51
28
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
52
"""
29
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
53
30
default:
54
# Secure BootRom (TF-A code)
31
g_assert_not_reached();
55
fs0_xz_url = (
32
}
56
"https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/"
33
- which = 2;
57
- "20240528-140808/edk2/SBSA_FLASH0.fd.xz"
34
+ ret = c;
58
+ "20240619-148232/edk2/SBSA_FLASH0.fd.xz"
35
} else {
59
)
36
- FloatClass cls[3] = { a->cls, b->cls, c->cls };
60
- fs0_xz_hash = "fa6004900b67172914c908b78557fec4d36a5f784f4c3dd08f49adb75e1892a9"
37
+ FloatPartsN *val[3] = { a, b, c };
61
+ fs0_xz_hash = "0c954842a590988f526984de22e21ae0ab9cb351a0c99a8a58e928f0c7359cf7"
38
Float3NaNPropRule rule = s->float_3nan_prop_rule;
62
tar_xz_path = self.fetch_asset(fs0_xz_url, asset_hash=fs0_xz_hash,
39
63
algorithm='sha256')
40
assert(rule != float_3nan_prop_none);
64
archive.extract(tar_xz_path, self.workdir)
41
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
65
@@ -XXX,XX +XXX,XX @@ def fetch_firmware(self):
42
/* We have at least one SNaN input and should prefer it */
66
# Non-secure rom (UEFI and EFI variables)
43
do {
67
fs1_xz_url = (
44
- which = rule & R_3NAN_1ST_MASK;
68
"https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/"
45
+ ret = val[rule & R_3NAN_1ST_MASK];
69
- "20240528-140808/edk2/SBSA_FLASH1.fd.xz"
46
rule >>= R_3NAN_1ST_LENGTH;
70
+ "20240619-148232/edk2/SBSA_FLASH1.fd.xz"
47
- } while (!is_snan(cls[which]));
71
)
48
+ } while (!is_snan(ret->cls));
72
- fs1_xz_hash = "5f3747d4000bc416d9641e33ff4ac60c3cc8cb74ca51b6e932e58531c62eb6f7"
49
} else {
73
+ fs1_xz_hash = "c6ec39374c4d79bb9e9cdeeb6db44732d90bb4a334cec92002b3f4b9cac4b5ee"
50
do {
74
tar_xz_path = self.fetch_asset(fs1_xz_url, asset_hash=fs1_xz_hash,
51
- which = rule & R_3NAN_1ST_MASK;
75
algorithm='sha256')
52
+ ret = val[rule & R_3NAN_1ST_MASK];
76
archive.extract(tar_xz_path, self.workdir)
53
rule >>= R_3NAN_1ST_LENGTH;
54
- } while (!is_nan(cls[which]));
55
+ } while (!is_nan(ret->cls));
56
}
57
}
58
59
- switch (which) {
60
- case 0:
61
- break;
62
- case 1:
63
- a = b;
64
- break;
65
- case 2:
66
- a = c;
67
- break;
68
- default:
69
- g_assert_not_reached();
70
+ if (is_snan(ret->cls)) {
71
+ parts_silence_nan(ret, s);
72
}
73
- if (is_snan(a->cls)) {
74
- parts_silence_nan(a, s);
75
- }
76
- return a;
77
+ return ret;
78
79
default_nan:
80
parts_default_nan(a, s);
77
--
81
--
78
2.34.1
82
2.34.1
79
83
80
84
diff view generated by jsdifflib
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The version of the sbsa-ref EDK2 firmware we used to use in this test
3
While all indices into val[] should be in [0-2], the mask
4
had a bug where it might make an unaligned access to the framebuffer,
4
applied is two bits. To help static analysis see there is
5
which causes a guest crash on newer versions of QEMU where we enforce
5
no possibility of read beyond the end of the array, pad the
6
the architectural requirement that unaligned accesses to Device memory
6
array to 4 entries, with the final being (implicitly) NULL.
7
should take an exception.
8
7
9
We happened to not notice this because our test was booting with "-smp
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
1" and through luck this didn't write the boot logo to the framebuffer
11
at an unaligned address; but trying to boot the same firmware with two
12
CPUs would result in a guest crash. Now we have updated the firmware
13
we're using for the test, we can make the test use all the cores on the
14
board, so we are testing the SMP boot path.
15
16
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20241203203949.483774-6-richard.henderson@linaro.org
19
Message-id: 20240620-b4-new-firmware-v3-2-29a3a2f1be1e@linaro.org
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
12
---
22
tests/avocado/machine_aarch64_sbsaref.py | 2 --
13
fpu/softfloat-parts.c.inc | 2 +-
23
1 file changed, 2 deletions(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
24
15
25
diff --git a/tests/avocado/machine_aarch64_sbsaref.py b/tests/avocado/machine_aarch64_sbsaref.py
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
26
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/avocado/machine_aarch64_sbsaref.py
18
--- a/fpu/softfloat-parts.c.inc
28
+++ b/tests/avocado/machine_aarch64_sbsaref.py
19
+++ b/fpu/softfloat-parts.c.inc
29
@@ -XXX,XX +XXX,XX @@ def fetch_firmware(self):
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
30
f"if=pflash,file={fs0_path},format=raw",
21
}
31
"-drive",
22
ret = c;
32
f"if=pflash,file={fs1_path},format=raw",
23
} else {
33
- "-smp",
24
- FloatPartsN *val[3] = { a, b, c };
34
- "1",
25
+ FloatPartsN *val[R_3NAN_1ST_MASK + 1] = { a, b, c };
35
"-machine",
26
Float3NaNPropRule rule = s->float_3nan_prop_rule;
36
"sbsa-ref",
27
37
)
28
assert(rule != float_3nan_prop_none);
38
--
29
--
39
2.34.1
30
2.34.1
40
31
41
32
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This function is part of the public interface and
4
is not "specialized" to any target in any way.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241203203949.483774-7-richard.henderson@linaro.org
5
Message-id: 20240625183536.1672454-5-richard.henderson@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.h | 10 ++
11
fpu/softfloat.c | 52 ++++++++++++++++++++++++++++++++++
9
target/arm/tcg/a64.decode | 16 +++
12
fpu/softfloat-specialize.c.inc | 52 ----------------------------------
10
target/arm/tcg/translate-a64.c | 206 +++++++++++++--------------------
13
2 files changed, 52 insertions(+), 52 deletions(-)
11
target/arm/tcg/vec_helper.c | 72 ++++++++++++
12
4 files changed, 180 insertions(+), 124 deletions(-)
13
14
14
diff --git a/target/arm/helper.h b/target/arm/helper.h
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.h
17
--- a/fpu/softfloat.c
17
+++ b/target/arm/helper.h
18
+++ b/fpu/softfloat.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(neon_sqrdmulh_idx_h, TCG_CALL_NO_RWG,
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
19
DEF_HELPER_FLAGS_5(neon_sqrdmulh_idx_s, TCG_CALL_NO_RWG,
20
*zExpPtr = 1 - shiftCount;
20
void, ptr, ptr, ptr, ptr, i32)
21
}
21
22
22
+DEF_HELPER_FLAGS_5(neon_sqrdmlah_idx_h, TCG_CALL_NO_RWG,
23
+/*----------------------------------------------------------------------------
23
+ void, ptr, ptr, ptr, ptr, i32)
24
+| Takes two extended double-precision floating-point values `a' and `b', one
24
+DEF_HELPER_FLAGS_5(neon_sqrdmlah_idx_s, TCG_CALL_NO_RWG,
25
+| of which is a NaN, and returns the appropriate NaN result. If either `a' or
25
+ void, ptr, ptr, ptr, ptr, i32)
26
+| `b' is a signaling NaN, the invalid exception is raised.
27
+*----------------------------------------------------------------------------*/
26
+
28
+
27
+DEF_HELPER_FLAGS_5(neon_sqrdmlsh_idx_h, TCG_CALL_NO_RWG,
29
+floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
28
+ void, ptr, ptr, ptr, ptr, i32)
30
+{
29
+DEF_HELPER_FLAGS_5(neon_sqrdmlsh_idx_s, TCG_CALL_NO_RWG,
31
+ bool aIsLargerSignificand;
30
+ void, ptr, ptr, ptr, ptr, i32)
32
+ FloatClass a_cls, b_cls;
31
+
33
+
32
DEF_HELPER_FLAGS_4(sve2_sqdmulh_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
+ /* This is not complete, but is good enough for pickNaN. */
33
DEF_HELPER_FLAGS_4(sve2_sqdmulh_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
35
+ a_cls = (!floatx80_is_any_nan(a)
34
DEF_HELPER_FLAGS_4(sve2_sqdmulh_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
36
+ ? float_class_normal
35
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
37
+ : floatx80_is_signaling_nan(a, status)
36
index XXXXXXX..XXXXXXX 100644
38
+ ? float_class_snan
37
--- a/target/arm/tcg/a64.decode
39
+ : float_class_qnan);
38
+++ b/target/arm/tcg/a64.decode
40
+ b_cls = (!floatx80_is_any_nan(b)
39
@@ -XXX,XX +XXX,XX @@ CMEQ_s 0111 1110 111 ..... 10001 1 ..... ..... @rrr_d
41
+ ? float_class_normal
40
42
+ : floatx80_is_signaling_nan(b, status)
41
SQDMULH_s 0101 1110 ..1 ..... 10110 1 ..... ..... @rrr_e
43
+ ? float_class_snan
42
SQRDMULH_s 0111 1110 ..1 ..... 10110 1 ..... ..... @rrr_e
44
+ : float_class_qnan);
43
+SQRDMLAH_s 0111 1110 ..0 ..... 10000 1 ..... ..... @rrr_e
44
+SQRDMLSH_s 0111 1110 ..0 ..... 10001 1 ..... ..... @rrr_e
45
46
### Advanced SIMD scalar pairwise
47
48
@@ -XXX,XX +XXX,XX @@ MLS_v 0.10 1110 ..1 ..... 10010 1 ..... ..... @qrrr_e
49
50
SQDMULH_v 0.00 1110 ..1 ..... 10110 1 ..... ..... @qrrr_e
51
SQRDMULH_v 0.10 1110 ..1 ..... 10110 1 ..... ..... @qrrr_e
52
+SQRDMLAH_v 0.10 1110 ..0 ..... 10000 1 ..... ..... @qrrr_e
53
+SQRDMLSH_v 0.10 1110 ..0 ..... 10001 1 ..... ..... @qrrr_e
54
55
### Advanced SIMD scalar x indexed element
56
57
@@ -XXX,XX +XXX,XX @@ SQDMULH_si 0101 1111 10 .. .... 1100 . 0 ..... ..... @rrx_s
58
SQRDMULH_si 0101 1111 01 .. .... 1101 . 0 ..... ..... @rrx_h
59
SQRDMULH_si 0101 1111 10 . ..... 1101 . 0 ..... ..... @rrx_s
60
61
+SQRDMLAH_si 0111 1111 01 .. .... 1101 . 0 ..... ..... @rrx_h
62
+SQRDMLAH_si 0111 1111 10 .. .... 1101 . 0 ..... ..... @rrx_s
63
+
45
+
64
+SQRDMLSH_si 0111 1111 01 .. .... 1111 . 0 ..... ..... @rrx_h
46
+ if (is_snan(a_cls) || is_snan(b_cls)) {
65
+SQRDMLSH_si 0111 1111 10 .. .... 1111 . 0 ..... ..... @rrx_s
47
+ float_raise(float_flag_invalid, status);
66
+
67
### Advanced SIMD vector x indexed element
68
69
FMUL_vi 0.00 1111 00 .. .... 1001 . 0 ..... ..... @qrrx_h
70
@@ -XXX,XX +XXX,XX @@ SQDMULH_vi 0.00 1111 10 . ..... 1100 . 0 ..... ..... @qrrx_s
71
SQRDMULH_vi 0.00 1111 01 .. .... 1101 . 0 ..... ..... @qrrx_h
72
SQRDMULH_vi 0.00 1111 10 . ..... 1101 . 0 ..... ..... @qrrx_s
73
74
+SQRDMLAH_vi 0.10 1111 01 .. .... 1101 . 0 ..... ..... @qrrx_h
75
+SQRDMLAH_vi 0.10 1111 10 .. .... 1101 . 0 ..... ..... @qrrx_s
76
+
77
+SQRDMLSH_vi 0.10 1111 01 .. .... 1111 . 0 ..... ..... @qrrx_h
78
+SQRDMLSH_vi 0.10 1111 10 .. .... 1111 . 0 ..... ..... @qrrx_s
79
+
80
# Floating-point conditional select
81
82
FCSEL 0001 1110 .. 1 rm:5 cond:4 11 rn:5 rd:5 esz=%esz_hsd
83
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/target/arm/tcg/translate-a64.c
86
+++ b/target/arm/tcg/translate-a64.c
87
@@ -XXX,XX +XXX,XX @@ static const ENVScalar2 f_scalar_sqrdmulh = {
88
};
89
TRANS(SQRDMULH_s, do_env_scalar2_hs, a, &f_scalar_sqrdmulh)
90
91
+typedef struct ENVScalar3 {
92
+ NeonGenThreeOpEnvFn *gen_hs[2];
93
+} ENVScalar3;
94
+
95
+static bool do_env_scalar3_hs(DisasContext *s, arg_rrr_e *a,
96
+ const ENVScalar3 *f)
97
+{
98
+ TCGv_i32 t0, t1, t2;
99
+
100
+ if (a->esz != MO_16 && a->esz != MO_32) {
101
+ return false;
102
+ }
103
+ if (!fp_access_check(s)) {
104
+ return true;
105
+ }
48
+ }
106
+
49
+
107
+ t0 = tcg_temp_new_i32();
50
+ if (status->default_nan_mode) {
108
+ t1 = tcg_temp_new_i32();
51
+ return floatx80_default_nan(status);
109
+ t2 = tcg_temp_new_i32();
52
+ }
110
+ read_vec_element_i32(s, t0, a->rn, 0, a->esz);
53
+
111
+ read_vec_element_i32(s, t1, a->rm, 0, a->esz);
54
+ if (a.low < b.low) {
112
+ read_vec_element_i32(s, t2, a->rd, 0, a->esz);
55
+ aIsLargerSignificand = 0;
113
+ f->gen_hs[a->esz - 1](t0, tcg_env, t0, t1, t2);
56
+ } else if (b.low < a.low) {
114
+ write_fp_sreg(s, a->rd, t0);
57
+ aIsLargerSignificand = 1;
115
+ return true;
58
+ } else {
59
+ aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
60
+ }
61
+
62
+ if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
63
+ if (is_snan(b_cls)) {
64
+ return floatx80_silence_nan(b, status);
65
+ }
66
+ return b;
67
+ } else {
68
+ if (is_snan(a_cls)) {
69
+ return floatx80_silence_nan(a, status);
70
+ }
71
+ return a;
72
+ }
116
+}
73
+}
117
+
74
+
118
+static const ENVScalar3 f_scalar_sqrdmlah = {
75
/*----------------------------------------------------------------------------
119
+ { gen_helper_neon_qrdmlah_s16, gen_helper_neon_qrdmlah_s32 }
76
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
120
+};
77
| and extended significand formed by the concatenation of `zSig0' and `zSig1',
121
+TRANS_FEAT(SQRDMLAH_s, aa64_rdm, do_env_scalar3_hs, a, &f_scalar_sqrdmlah)
78
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
122
+
79
index XXXXXXX..XXXXXXX 100644
123
+static const ENVScalar3 f_scalar_sqrdmlsh = {
80
--- a/fpu/softfloat-specialize.c.inc
124
+ { gen_helper_neon_qrdmlsh_s16, gen_helper_neon_qrdmlsh_s32 }
81
+++ b/fpu/softfloat-specialize.c.inc
125
+};
82
@@ -XXX,XX +XXX,XX @@ floatx80 floatx80_silence_nan(floatx80 a, float_status *status)
126
+TRANS_FEAT(SQRDMLSH_s, aa64_rdm, do_env_scalar3_hs, a, &f_scalar_sqrdmlsh)
83
return a;
127
+
128
static bool do_cmop_d(DisasContext *s, arg_rrr_e *a, TCGCond cond)
129
{
130
if (fp_access_check(s)) {
131
@@ -XXX,XX +XXX,XX @@ TRANS(CMTST_v, do_gvec_fn3, a, gen_gvec_cmtst)
132
133
TRANS(SQDMULH_v, do_gvec_fn3_no8_no64, a, gen_gvec_sqdmulh_qc)
134
TRANS(SQRDMULH_v, do_gvec_fn3_no8_no64, a, gen_gvec_sqrdmulh_qc)
135
+TRANS_FEAT(SQRDMLAH_v, aa64_rdm, do_gvec_fn3_no8_no64, a, gen_gvec_sqrdmlah_qc)
136
+TRANS_FEAT(SQRDMLSH_v, aa64_rdm, do_gvec_fn3_no8_no64, a, gen_gvec_sqrdmlsh_qc)
137
138
/*
139
* Advanced SIMD scalar/vector x indexed element
140
@@ -XXX,XX +XXX,XX @@ static bool do_env_scalar2_idx_hs(DisasContext *s, arg_rrx_e *a,
141
TRANS(SQDMULH_si, do_env_scalar2_idx_hs, a, &f_scalar_sqdmulh)
142
TRANS(SQRDMULH_si, do_env_scalar2_idx_hs, a, &f_scalar_sqrdmulh)
143
144
+static bool do_env_scalar3_idx_hs(DisasContext *s, arg_rrx_e *a,
145
+ const ENVScalar3 *f)
146
+{
147
+ if (a->esz < MO_16 || a->esz > MO_32) {
148
+ return false;
149
+ }
150
+ if (fp_access_check(s)) {
151
+ TCGv_i32 t0 = tcg_temp_new_i32();
152
+ TCGv_i32 t1 = tcg_temp_new_i32();
153
+ TCGv_i32 t2 = tcg_temp_new_i32();
154
+
155
+ read_vec_element_i32(s, t0, a->rn, 0, a->esz);
156
+ read_vec_element_i32(s, t1, a->rm, a->idx, a->esz);
157
+ read_vec_element_i32(s, t2, a->rd, 0, a->esz);
158
+ f->gen_hs[a->esz - 1](t0, tcg_env, t0, t1, t2);
159
+ write_fp_sreg(s, a->rd, t0);
160
+ }
161
+ return true;
162
+}
163
+
164
+TRANS_FEAT(SQRDMLAH_si, aa64_rdm, do_env_scalar3_idx_hs, a, &f_scalar_sqrdmlah)
165
+TRANS_FEAT(SQRDMLSH_si, aa64_rdm, do_env_scalar3_idx_hs, a, &f_scalar_sqrdmlsh)
166
+
167
static bool do_fp3_vector_idx(DisasContext *s, arg_qrrx_e *a,
168
gen_helper_gvec_3_ptr * const fns[3])
169
{
170
@@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_4 * const f_vector_idx_sqrdmulh[2] = {
171
};
172
TRANS(SQRDMULH_vi, do_int3_qc_vector_idx, a, f_vector_idx_sqrdmulh)
173
174
+static gen_helper_gvec_4 * const f_vector_idx_sqrdmlah[2] = {
175
+ gen_helper_neon_sqrdmlah_idx_h,
176
+ gen_helper_neon_sqrdmlah_idx_s,
177
+};
178
+TRANS_FEAT(SQRDMLAH_vi, aa64_rdm, do_int3_qc_vector_idx, a,
179
+ f_vector_idx_sqrdmlah)
180
+
181
+static gen_helper_gvec_4 * const f_vector_idx_sqrdmlsh[2] = {
182
+ gen_helper_neon_sqrdmlsh_idx_h,
183
+ gen_helper_neon_sqrdmlsh_idx_s,
184
+};
185
+TRANS_FEAT(SQRDMLSH_vi, aa64_rdm, do_int3_qc_vector_idx, a,
186
+ f_vector_idx_sqrdmlsh)
187
+
188
/*
189
* Advanced SIMD scalar pairwise
190
*/
191
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
192
}
193
}
84
}
194
85
195
-/* AdvSIMD scalar three same extra
86
-/*----------------------------------------------------------------------------
196
- * 31 30 29 28 24 23 22 21 20 16 15 14 11 10 9 5 4 0
87
-| Takes two extended double-precision floating-point values `a' and `b', one
197
- * +-----+---+-----------+------+---+------+---+--------+---+----+----+
88
-| of which is a NaN, and returns the appropriate NaN result. If either `a' or
198
- * | 0 1 | U | 1 1 1 1 0 | size | 0 | Rm | 1 | opcode | 1 | Rn | Rd |
89
-| `b' is a signaling NaN, the invalid exception is raised.
199
- * +-----+---+-----------+------+---+------+---+--------+---+----+----+
90
-*----------------------------------------------------------------------------*/
200
- */
91
-
201
-static void disas_simd_scalar_three_reg_same_extra(DisasContext *s,
92
-floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
202
- uint32_t insn)
203
-{
93
-{
204
- int rd = extract32(insn, 0, 5);
94
- bool aIsLargerSignificand;
205
- int rn = extract32(insn, 5, 5);
95
- FloatClass a_cls, b_cls;
206
- int opcode = extract32(insn, 11, 4);
207
- int rm = extract32(insn, 16, 5);
208
- int size = extract32(insn, 22, 2);
209
- bool u = extract32(insn, 29, 1);
210
- TCGv_i32 ele1, ele2, ele3;
211
- TCGv_i64 res;
212
- bool feature;
213
-
96
-
214
- switch (u * 16 + opcode) {
97
- /* This is not complete, but is good enough for pickNaN. */
215
- case 0x10: /* SQRDMLAH (vector) */
98
- a_cls = (!floatx80_is_any_nan(a)
216
- case 0x11: /* SQRDMLSH (vector) */
99
- ? float_class_normal
217
- if (size != 1 && size != 2) {
100
- : floatx80_is_signaling_nan(a, status)
218
- unallocated_encoding(s);
101
- ? float_class_snan
219
- return;
102
- : float_class_qnan);
220
- }
103
- b_cls = (!floatx80_is_any_nan(b)
221
- feature = dc_isar_feature(aa64_rdm, s);
104
- ? float_class_normal
222
- break;
105
- : floatx80_is_signaling_nan(b, status)
223
- default:
106
- ? float_class_snan
224
- unallocated_encoding(s);
107
- : float_class_qnan);
225
- return;
108
-
226
- }
109
- if (is_snan(a_cls) || is_snan(b_cls)) {
227
- if (!feature) {
110
- float_raise(float_flag_invalid, status);
228
- unallocated_encoding(s);
229
- return;
230
- }
231
- if (!fp_access_check(s)) {
232
- return;
233
- }
111
- }
234
-
112
-
235
- /* Do a single operation on the lowest element in the vector.
113
- if (status->default_nan_mode) {
236
- * We use the standard Neon helpers and rely on 0 OP 0 == 0
114
- return floatx80_default_nan(status);
237
- * with no side effects for all these operations.
238
- * OPTME: special-purpose helpers would avoid doing some
239
- * unnecessary work in the helper for the 16 bit cases.
240
- */
241
- ele1 = tcg_temp_new_i32();
242
- ele2 = tcg_temp_new_i32();
243
- ele3 = tcg_temp_new_i32();
244
-
245
- read_vec_element_i32(s, ele1, rn, 0, size);
246
- read_vec_element_i32(s, ele2, rm, 0, size);
247
- read_vec_element_i32(s, ele3, rd, 0, size);
248
-
249
- switch (opcode) {
250
- case 0x0: /* SQRDMLAH */
251
- if (size == 1) {
252
- gen_helper_neon_qrdmlah_s16(ele3, tcg_env, ele1, ele2, ele3);
253
- } else {
254
- gen_helper_neon_qrdmlah_s32(ele3, tcg_env, ele1, ele2, ele3);
255
- }
256
- break;
257
- case 0x1: /* SQRDMLSH */
258
- if (size == 1) {
259
- gen_helper_neon_qrdmlsh_s16(ele3, tcg_env, ele1, ele2, ele3);
260
- } else {
261
- gen_helper_neon_qrdmlsh_s32(ele3, tcg_env, ele1, ele2, ele3);
262
- }
263
- break;
264
- default:
265
- g_assert_not_reached();
266
- }
115
- }
267
-
116
-
268
- res = tcg_temp_new_i64();
117
- if (a.low < b.low) {
269
- tcg_gen_extu_i32_i64(res, ele3);
118
- aIsLargerSignificand = 0;
270
- write_fp_dreg(s, rd, res);
119
- } else if (b.low < a.low) {
120
- aIsLargerSignificand = 1;
121
- } else {
122
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
123
- }
124
-
125
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
126
- if (is_snan(b_cls)) {
127
- return floatx80_silence_nan(b, status);
128
- }
129
- return b;
130
- } else {
131
- if (is_snan(a_cls)) {
132
- return floatx80_silence_nan(a, status);
133
- }
134
- return a;
135
- }
271
-}
136
-}
272
-
137
-
273
static void handle_2misc_64(DisasContext *s, int opcode, bool u,
138
/*----------------------------------------------------------------------------
274
TCGv_i64 tcg_rd, TCGv_i64 tcg_rn,
139
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
275
TCGv_i32 tcg_rmode, TCGv_ptr tcg_fpstatus)
140
| NaN; otherwise returns 0.
276
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
277
int rot;
278
279
switch (u * 16 + opcode) {
280
- case 0x10: /* SQRDMLAH (vector) */
281
- case 0x11: /* SQRDMLSH (vector) */
282
- if (size != 1 && size != 2) {
283
- unallocated_encoding(s);
284
- return;
285
- }
286
- feature = dc_isar_feature(aa64_rdm, s);
287
- break;
288
case 0x02: /* SDOT (vector) */
289
case 0x12: /* UDOT (vector) */
290
if (size != MO_32) {
291
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
292
}
293
break;
294
default:
295
+ case 0x10: /* SQRDMLAH (vector) */
296
+ case 0x11: /* SQRDMLSH (vector) */
297
unallocated_encoding(s);
298
return;
299
}
300
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
301
}
302
303
switch (opcode) {
304
- case 0x0: /* SQRDMLAH (vector) */
305
- gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqrdmlah_qc, size);
306
- return;
307
-
308
- case 0x1: /* SQRDMLSH (vector) */
309
- gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqrdmlsh_qc, size);
310
- return;
311
-
312
case 0x2: /* SDOT / UDOT */
313
gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0,
314
u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b);
315
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
316
case 0x0b: /* SQDMULL, SQDMULL2 */
317
is_long = true;
318
break;
319
- case 0x1d: /* SQRDMLAH */
320
- case 0x1f: /* SQRDMLSH */
321
- if (!dc_isar_feature(aa64_rdm, s)) {
322
- unallocated_encoding(s);
323
- return;
324
- }
325
- break;
326
case 0x0e: /* SDOT */
327
case 0x1e: /* UDOT */
328
if (is_scalar || size != MO_32 || !dc_isar_feature(aa64_dp, s)) {
329
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
330
case 0x18: /* FMLAL2 */
331
case 0x19: /* FMULX */
332
case 0x1c: /* FMLSL2 */
333
+ case 0x1d: /* SQRDMLAH */
334
+ case 0x1f: /* SQRDMLSH */
335
unallocated_encoding(s);
336
return;
337
}
338
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
339
tcg_op, tcg_idx);
340
}
341
break;
342
- case 0x1d: /* SQRDMLAH */
343
- read_vec_element_i32(s, tcg_res, rd, pass,
344
- is_scalar ? size : MO_32);
345
- if (size == 1) {
346
- gen_helper_neon_qrdmlah_s16(tcg_res, tcg_env,
347
- tcg_op, tcg_idx, tcg_res);
348
- } else {
349
- gen_helper_neon_qrdmlah_s32(tcg_res, tcg_env,
350
- tcg_op, tcg_idx, tcg_res);
351
- }
352
- break;
353
- case 0x1f: /* SQRDMLSH */
354
- read_vec_element_i32(s, tcg_res, rd, pass,
355
- is_scalar ? size : MO_32);
356
- if (size == 1) {
357
- gen_helper_neon_qrdmlsh_s16(tcg_res, tcg_env,
358
- tcg_op, tcg_idx, tcg_res);
359
- } else {
360
- gen_helper_neon_qrdmlsh_s32(tcg_res, tcg_env,
361
- tcg_op, tcg_idx, tcg_res);
362
- }
363
- break;
364
default:
365
case 0x01: /* FMLA */
366
case 0x05: /* FMLS */
367
case 0x09: /* FMUL */
368
case 0x19: /* FMULX */
369
+ case 0x1d: /* SQRDMLAH */
370
+ case 0x1f: /* SQRDMLSH */
371
g_assert_not_reached();
372
}
373
374
@@ -XXX,XX +XXX,XX @@ static const AArch64DecodeTable data_proc_simd[] = {
375
{ 0x0e000000, 0xbf208c00, disas_simd_tb },
376
{ 0x0e000800, 0xbf208c00, disas_simd_zip_trn },
377
{ 0x2e000000, 0xbf208400, disas_simd_ext },
378
- { 0x5e008400, 0xdf208400, disas_simd_scalar_three_reg_same_extra },
379
{ 0x5e200000, 0xdf200c00, disas_simd_scalar_three_reg_diff },
380
{ 0x5e200800, 0xdf3e0c00, disas_simd_scalar_two_reg_misc },
381
{ 0x5f000000, 0xdf000400, disas_simd_indexed }, /* scalar indexed */
382
diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c
383
index XXXXXXX..XXXXXXX 100644
384
--- a/target/arm/tcg/vec_helper.c
385
+++ b/target/arm/tcg/vec_helper.c
386
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_sqrdmulh_idx_h)(void *vd, void *vn, void *vm,
387
clear_tail(d, opr_sz, simd_maxsz(desc));
388
}
389
390
+void HELPER(neon_sqrdmlah_idx_h)(void *vd, void *vn, void *vm,
391
+ void *vq, uint32_t desc)
392
+{
393
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
394
+ int idx = simd_data(desc);
395
+ int16_t *d = vd, *n = vn, *m = (int16_t *)vm + H2(idx);
396
+ intptr_t elements = opr_sz / 2;
397
+ intptr_t eltspersegment = MIN(16 / 2, elements);
398
+
399
+ for (i = 0; i < elements; i += 16 / 2) {
400
+ int16_t mm = m[i];
401
+ for (j = 0; j < eltspersegment; ++j) {
402
+ d[i + j] = do_sqrdmlah_h(n[i + j], mm, d[i + j], false, true, vq);
403
+ }
404
+ }
405
+ clear_tail(d, opr_sz, simd_maxsz(desc));
406
+}
407
+
408
+void HELPER(neon_sqrdmlsh_idx_h)(void *vd, void *vn, void *vm,
409
+ void *vq, uint32_t desc)
410
+{
411
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
412
+ int idx = simd_data(desc);
413
+ int16_t *d = vd, *n = vn, *m = (int16_t *)vm + H2(idx);
414
+ intptr_t elements = opr_sz / 2;
415
+ intptr_t eltspersegment = MIN(16 / 2, elements);
416
+
417
+ for (i = 0; i < elements; i += 16 / 2) {
418
+ int16_t mm = m[i];
419
+ for (j = 0; j < eltspersegment; ++j) {
420
+ d[i + j] = do_sqrdmlah_h(n[i + j], mm, d[i + j], true, true, vq);
421
+ }
422
+ }
423
+ clear_tail(d, opr_sz, simd_maxsz(desc));
424
+}
425
+
426
void HELPER(sve2_sqrdmlah_h)(void *vd, void *vn, void *vm,
427
void *va, uint32_t desc)
428
{
429
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_sqrdmulh_idx_s)(void *vd, void *vn, void *vm,
430
clear_tail(d, opr_sz, simd_maxsz(desc));
431
}
432
433
+void HELPER(neon_sqrdmlah_idx_s)(void *vd, void *vn, void *vm,
434
+ void *vq, uint32_t desc)
435
+{
436
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
437
+ int idx = simd_data(desc);
438
+ int32_t *d = vd, *n = vn, *m = (int32_t *)vm + H4(idx);
439
+ intptr_t elements = opr_sz / 4;
440
+ intptr_t eltspersegment = MIN(16 / 4, elements);
441
+
442
+ for (i = 0; i < elements; i += 16 / 4) {
443
+ int32_t mm = m[i];
444
+ for (j = 0; j < eltspersegment; ++j) {
445
+ d[i + j] = do_sqrdmlah_s(n[i + j], mm, d[i + j], false, true, vq);
446
+ }
447
+ }
448
+ clear_tail(d, opr_sz, simd_maxsz(desc));
449
+}
450
+
451
+void HELPER(neon_sqrdmlsh_idx_s)(void *vd, void *vn, void *vm,
452
+ void *vq, uint32_t desc)
453
+{
454
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
455
+ int idx = simd_data(desc);
456
+ int32_t *d = vd, *n = vn, *m = (int32_t *)vm + H4(idx);
457
+ intptr_t elements = opr_sz / 4;
458
+ intptr_t eltspersegment = MIN(16 / 4, elements);
459
+
460
+ for (i = 0; i < elements; i += 16 / 4) {
461
+ int32_t mm = m[i];
462
+ for (j = 0; j < eltspersegment; ++j) {
463
+ d[i + j] = do_sqrdmlah_s(n[i + j], mm, d[i + j], true, true, vq);
464
+ }
465
+ }
466
+ clear_tail(d, opr_sz, simd_maxsz(desc));
467
+}
468
+
469
void HELPER(sve2_sqrdmlah_s)(void *vd, void *vn, void *vm,
470
void *va, uint32_t desc)
471
{
472
--
141
--
473
2.34.1
142
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
MLA, MLS, SQDMULH, SQRDMULH, were converted with 8db93dcd3def
3
Unpacking and repacking the parts may be slightly more work
4
and f80701cb44d, and this code should have been removed then.
4
than we did before, but we get to reuse more code. For a
5
code path handling exceptional values, this is an improvement.
5
6
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20240625183536.1672454-14-richard.henderson@linaro.org
8
Message-id: 20241203203949.483774-8-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/tcg/translate-a64.c | 93 ----------------------------------
12
fpu/softfloat.c | 43 +++++--------------------------------------
12
1 file changed, 93 deletions(-)
13
1 file changed, 5 insertions(+), 38 deletions(-)
13
14
14
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/tcg/translate-a64.c
17
--- a/fpu/softfloat.c
17
+++ b/target/arm/tcg/translate-a64.c
18
+++ b/fpu/softfloat.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
19
int h = extract32(insn, 11, 1);
20
20
int rn = extract32(insn, 5, 5);
21
floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
21
int rd = extract32(insn, 0, 5);
22
{
22
- bool is_long = false;
23
- bool aIsLargerSignificand;
23
int index;
24
- FloatClass a_cls, b_cls;
24
25
+ FloatParts128 pa, pb, *pr;
25
switch (16 * u + opcode) {
26
26
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
27
- /* This is not complete, but is good enough for pickNaN. */
27
unallocated_encoding(s);
28
- a_cls = (!floatx80_is_any_nan(a)
28
return;
29
- ? float_class_normal
29
}
30
- : floatx80_is_signaling_nan(a, status)
30
- is_long = true;
31
- ? float_class_snan
31
break;
32
- : float_class_qnan);
32
case 0x03: /* SQDMLAL, SQDMLAL2 */
33
- b_cls = (!floatx80_is_any_nan(b)
33
case 0x07: /* SQDMLSL, SQDMLSL2 */
34
- ? float_class_normal
34
case 0x0b: /* SQDMULL, SQDMULL2 */
35
- : floatx80_is_signaling_nan(b, status)
35
- is_long = true;
36
- ? float_class_snan
36
break;
37
- : float_class_qnan);
37
default:
38
case 0x00: /* FMLAL */
39
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
40
41
if (size == 3) {
42
g_assert_not_reached();
43
- } else if (!is_long) {
44
- /* 32 bit floating point, or 16 or 32 bit integer.
45
- * For the 16 bit scalar case we use the usual Neon helpers and
46
- * rely on the fact that 0 op 0 == 0 with no side effects.
47
- */
48
- TCGv_i32 tcg_idx = tcg_temp_new_i32();
49
- int pass, maxpasses;
50
-
38
-
51
- if (is_scalar) {
39
- if (is_snan(a_cls) || is_snan(b_cls)) {
52
- maxpasses = 1;
40
- float_raise(float_flag_invalid, status);
53
- } else {
41
- }
54
- maxpasses = is_q ? 4 : 2;
42
-
43
- if (status->default_nan_mode) {
44
+ if (!floatx80_unpack_canonical(&pa, a, status) ||
45
+ !floatx80_unpack_canonical(&pb, b, status)) {
46
return floatx80_default_nan(status);
47
}
48
49
- if (a.low < b.low) {
50
- aIsLargerSignificand = 0;
51
- } else if (b.low < a.low) {
52
- aIsLargerSignificand = 1;
53
- } else {
54
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
55
- }
56
-
57
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
58
- if (is_snan(b_cls)) {
59
- return floatx80_silence_nan(b, status);
55
- }
60
- }
56
-
61
- return b;
57
- read_vec_element_i32(s, tcg_idx, rm, index, size);
62
- } else {
58
-
63
- if (is_snan(a_cls)) {
59
- if (size == 1 && !is_scalar) {
64
- return floatx80_silence_nan(a, status);
60
- /* The simplest way to handle the 16x16 indexed ops is to duplicate
61
- * the index into both halves of the 32 bit tcg_idx and then use
62
- * the usual Neon helpers.
63
- */
64
- tcg_gen_deposit_i32(tcg_idx, tcg_idx, tcg_idx, 16, 16);
65
- }
65
- }
66
-
66
- return a;
67
- for (pass = 0; pass < maxpasses; pass++) {
67
- }
68
- TCGv_i32 tcg_op = tcg_temp_new_i32();
68
+ pr = parts_pick_nan(&pa, &pb, status);
69
- TCGv_i32 tcg_res = tcg_temp_new_i32();
69
+ return floatx80_round_pack_canonical(pr, status);
70
-
70
}
71
- read_vec_element_i32(s, tcg_op, rn, pass, is_scalar ? size : MO_32);
71
72
-
72
/*----------------------------------------------------------------------------
73
- switch (16 * u + opcode) {
74
- case 0x10: /* MLA */
75
- case 0x14: /* MLS */
76
- {
77
- static NeonGenTwoOpFn * const fns[2][2] = {
78
- { gen_helper_neon_add_u16, gen_helper_neon_sub_u16 },
79
- { tcg_gen_add_i32, tcg_gen_sub_i32 },
80
- };
81
- NeonGenTwoOpFn *genfn;
82
- bool is_sub = opcode == 0x4;
83
-
84
- if (size == 1) {
85
- gen_helper_neon_mul_u16(tcg_res, tcg_op, tcg_idx);
86
- } else {
87
- tcg_gen_mul_i32(tcg_res, tcg_op, tcg_idx);
88
- }
89
- if (opcode == 0x8) {
90
- break;
91
- }
92
- read_vec_element_i32(s, tcg_op, rd, pass, MO_32);
93
- genfn = fns[size - 1][is_sub];
94
- genfn(tcg_res, tcg_op, tcg_res);
95
- break;
96
- }
97
- case 0x0c: /* SQDMULH */
98
- if (size == 1) {
99
- gen_helper_neon_qdmulh_s16(tcg_res, tcg_env,
100
- tcg_op, tcg_idx);
101
- } else {
102
- gen_helper_neon_qdmulh_s32(tcg_res, tcg_env,
103
- tcg_op, tcg_idx);
104
- }
105
- break;
106
- case 0x0d: /* SQRDMULH */
107
- if (size == 1) {
108
- gen_helper_neon_qrdmulh_s16(tcg_res, tcg_env,
109
- tcg_op, tcg_idx);
110
- } else {
111
- gen_helper_neon_qrdmulh_s32(tcg_res, tcg_env,
112
- tcg_op, tcg_idx);
113
- }
114
- break;
115
- default:
116
- case 0x01: /* FMLA */
117
- case 0x05: /* FMLS */
118
- case 0x09: /* FMUL */
119
- case 0x19: /* FMULX */
120
- case 0x1d: /* SQRDMLAH */
121
- case 0x1f: /* SQRDMLSH */
122
- g_assert_not_reached();
123
- }
124
-
125
- if (is_scalar) {
126
- write_fp_sreg(s, rd, tcg_res);
127
- } else {
128
- write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
129
- }
130
- }
131
-
132
- clear_vec_high(s, is_q, rd);
133
} else {
134
/* long ops: 16x16->32 or 32x32->64 */
135
TCGv_i64 tcg_res[2];
136
--
73
--
137
2.34.1
74
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Inline pickNaN into its only caller. This makes one assert
4
redundant with the immediately preceding IF.
5
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20240625183536.1672454-13-richard.henderson@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-9-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/tcg/a64.decode | 6 +
11
fpu/softfloat-parts.c.inc | 82 +++++++++++++++++++++++++----
9
target/arm/tcg/translate-a64.c | 238 ++++++++++-----------------------
12
fpu/softfloat-specialize.c.inc | 96 ----------------------------------
10
2 files changed, 74 insertions(+), 170 deletions(-)
13
2 files changed, 73 insertions(+), 105 deletions(-)
11
14
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
15
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/a64.decode
17
--- a/fpu/softfloat-parts.c.inc
15
+++ b/target/arm/tcg/a64.decode
18
+++ b/fpu/softfloat-parts.c.inc
16
@@ -XXX,XX +XXX,XX @@ USMMLA 0100 1110 100 ..... 10101 1 ..... ..... @rrr_q1e0
19
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
17
FCADD_90 0.10 1110 ..0 ..... 11100 1 ..... ..... @qrrr_e
20
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
18
FCADD_270 0.10 1110 ..0 ..... 11110 1 ..... ..... @qrrr_e
21
float_status *s)
19
22
{
20
+FCMLA_v 0 q:1 10 1110 esz:2 0 rm:5 110 rot:2 1 rn:5 rd:5
23
+ int cmp, which;
21
+
24
+
22
### Advanced SIMD scalar x indexed element
25
if (is_snan(a->cls) || is_snan(b->cls)) {
23
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
24
FMUL_si 0101 1111 00 .. .... 1001 . 0 ..... ..... @rrx_h
27
}
25
@@ -XXX,XX +XXX,XX @@ USDOT_vi 0.00 1111 10 .. .... 1111 . 0 ..... ..... @qrrx_s
28
26
BFDOT_vi 0.00 1111 01 .. .... 1111 . 0 ..... ..... @qrrx_s
29
if (s->default_nan_mode) {
27
BFMLAL_vi 0.00 1111 11 .. .... 1111 . 0 ..... ..... @qrrx_h
30
parts_default_nan(a, s);
28
31
- } else {
29
+FCMLA_vi 0 0 10 1111 01 idx:1 rm:5 0 rot:2 1 0 0 rn:5 rd:5 esz=1 q=0
32
- int cmp = frac_cmp(a, b);
30
+FCMLA_vi 0 1 10 1111 01 . rm:5 0 rot:2 1 . 0 rn:5 rd:5 esz=1 idx=%hl q=1
33
- if (cmp == 0) {
31
+FCMLA_vi 0 1 10 1111 10 0 rm:5 0 rot:2 1 idx:1 0 rn:5 rd:5 esz=2 q=1
34
- cmp = a->sign < b->sign;
35
- }
36
+ return a;
37
+ }
38
39
- if (pickNaN(a->cls, b->cls, cmp > 0, s)) {
40
- a = b;
41
- }
42
+ cmp = frac_cmp(a, b);
43
+ if (cmp == 0) {
44
+ cmp = a->sign < b->sign;
45
+ }
32
+
46
+
33
# Floating-point conditional select
47
+ switch (s->float_2nan_prop_rule) {
34
48
+ case float_2nan_prop_s_ab:
35
FCSEL 0001 1110 .. 1 rm:5 cond:4 11 rn:5 rd:5 esz=%esz_hsd
49
if (is_snan(a->cls)) {
36
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
50
- parts_silence_nan(a, s);
37
index XXXXXXX..XXXXXXX 100644
51
+ which = 0;
38
--- a/target/arm/tcg/translate-a64.c
52
+ } else if (is_snan(b->cls)) {
39
+++ b/target/arm/tcg/translate-a64.c
53
+ which = 1;
40
@@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_3_ptr * const f_vector_fcadd[3] = {
54
+ } else if (is_qnan(a->cls)) {
41
TRANS_FEAT(FCADD_90, aa64_fcma, do_fp3_vector, a, 0, f_vector_fcadd)
55
+ which = 0;
42
TRANS_FEAT(FCADD_270, aa64_fcma, do_fp3_vector, a, 1, f_vector_fcadd)
56
+ } else {
43
57
+ which = 1;
44
+static bool trans_FCMLA_v(DisasContext *s, arg_FCMLA_v *a)
58
}
45
+{
59
+ break;
46
+ gen_helper_gvec_4_ptr *fn;
60
+ case float_2nan_prop_s_ba:
47
+
61
+ if (is_snan(b->cls)) {
48
+ if (!dc_isar_feature(aa64_fcma, s)) {
62
+ which = 1;
49
+ return false;
63
+ } else if (is_snan(a->cls)) {
50
+ }
64
+ which = 0;
51
+ switch (a->esz) {
65
+ } else if (is_qnan(b->cls)) {
52
+ case MO_64:
66
+ which = 1;
53
+ if (!a->q) {
67
+ } else {
54
+ return false;
68
+ which = 0;
55
+ }
69
+ }
56
+ fn = gen_helper_gvec_fcmlad;
70
+ break;
57
+ break;
71
+ case float_2nan_prop_ab:
58
+ case MO_32:
72
+ which = is_nan(a->cls) ? 0 : 1;
59
+ fn = gen_helper_gvec_fcmlas;
73
+ break;
60
+ break;
74
+ case float_2nan_prop_ba:
61
+ case MO_16:
75
+ which = is_nan(b->cls) ? 1 : 0;
62
+ if (!dc_isar_feature(aa64_fp16, s)) {
76
+ break;
63
+ return false;
77
+ case float_2nan_prop_x87:
78
+ /*
79
+ * This implements x87 NaN propagation rules:
80
+ * SNaN + QNaN => return the QNaN
81
+ * two SNaNs => return the one with the larger significand, silenced
82
+ * two QNaNs => return the one with the larger significand
83
+ * SNaN and a non-NaN => return the SNaN, silenced
84
+ * QNaN and a non-NaN => return the QNaN
85
+ *
86
+ * If we get down to comparing significands and they are the same,
87
+ * return the NaN with the positive sign bit (if any).
88
+ */
89
+ if (is_snan(a->cls)) {
90
+ if (is_snan(b->cls)) {
91
+ which = cmp > 0 ? 0 : 1;
92
+ } else {
93
+ which = is_qnan(b->cls) ? 1 : 0;
94
+ }
95
+ } else if (is_qnan(a->cls)) {
96
+ if (is_snan(b->cls) || !is_qnan(b->cls)) {
97
+ which = 0;
98
+ } else {
99
+ which = cmp > 0 ? 0 : 1;
100
+ }
101
+ } else {
102
+ which = 1;
64
+ }
103
+ }
65
+ fn = gen_helper_gvec_fcmlah;
66
+ break;
67
+ default:
68
+ return false;
69
+ }
70
+ if (fp_access_check(s)) {
71
+ gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd,
72
+ a->esz == MO_16, a->rot, fn);
73
+ }
74
+ return true;
75
+}
76
+
77
/*
78
* Advanced SIMD scalar/vector x indexed element
79
*/
80
@@ -XXX,XX +XXX,XX @@ static bool trans_BFMLAL_vi(DisasContext *s, arg_qrrx_e *a)
81
return true;
82
}
83
84
+static bool trans_FCMLA_vi(DisasContext *s, arg_FCMLA_vi *a)
85
+{
86
+ gen_helper_gvec_4_ptr *fn;
87
+
88
+ if (!dc_isar_feature(aa64_fcma, s)) {
89
+ return false;
90
+ }
91
+ switch (a->esz) {
92
+ case MO_16:
93
+ if (!dc_isar_feature(aa64_fp16, s)) {
94
+ return false;
95
+ }
96
+ fn = gen_helper_gvec_fcmlah_idx;
97
+ break;
98
+ case MO_32:
99
+ fn = gen_helper_gvec_fcmlas_idx;
100
+ break;
104
+ break;
101
+ default:
105
+ default:
102
+ g_assert_not_reached();
106
+ g_assert_not_reached();
103
+ }
107
+ }
104
+ if (fp_access_check(s)) {
105
+ gen_gvec_op4_fpst(s, a->q, a->rd, a->rn, a->rm, a->rd,
106
+ a->esz == MO_16, (a->idx << 2) | a->rot, fn);
107
+ }
108
+ return true;
109
+}
110
+
108
+
111
/*
109
+ if (which) {
112
* Advanced SIMD scalar pairwise
110
+ a = b;
113
*/
111
+ }
114
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_diff(DisasContext *s, uint32_t insn)
112
+ if (is_snan(a->cls)) {
113
+ parts_silence_nan(a, s);
114
}
115
return a;
116
}
117
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
118
index XXXXXXX..XXXXXXX 100644
119
--- a/fpu/softfloat-specialize.c.inc
120
+++ b/fpu/softfloat-specialize.c.inc
121
@@ -XXX,XX +XXX,XX @@ bool float32_is_signaling_nan(float32 a_, float_status *status)
115
}
122
}
116
}
123
}
117
124
118
-/* AdvSIMD three same extra
125
-/*----------------------------------------------------------------------------
119
- * 31 30 29 28 24 23 22 21 20 16 15 14 11 10 9 5 4 0
126
-| Select which NaN to propagate for a two-input operation.
120
- * +---+---+---+-----------+------+---+------+---+--------+---+----+----+
127
-| IEEE754 doesn't specify all the details of this, so the
121
- * | 0 | Q | U | 0 1 1 1 0 | size | 0 | Rm | 1 | opcode | 1 | Rn | Rd |
128
-| algorithm is target-specific.
122
- * +---+---+---+-----------+------+---+------+---+--------+---+----+----+
129
-| The routine is passed various bits of information about the
123
- */
130
-| two NaNs and should return 0 to select NaN a and 1 for NaN b.
124
-static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
131
-| Note that signalling NaNs are always squashed to quiet NaNs
132
-| by the caller, by calling floatXX_silence_nan() before
133
-| returning them.
134
-|
135
-| aIsLargerSignificand is only valid if both a and b are NaNs
136
-| of some kind, and is true if a has the larger significand,
137
-| or if both a and b have the same significand but a is
138
-| positive but b is negative. It is only needed for the x87
139
-| tie-break rule.
140
-*----------------------------------------------------------------------------*/
141
-
142
-static int pickNaN(FloatClass a_cls, FloatClass b_cls,
143
- bool aIsLargerSignificand, float_status *status)
125
-{
144
-{
126
- int rd = extract32(insn, 0, 5);
145
- /*
127
- int rn = extract32(insn, 5, 5);
146
- * We guarantee not to require the target to tell us how to
128
- int opcode = extract32(insn, 11, 4);
147
- * pick a NaN if we're always returning the default NaN.
129
- int rm = extract32(insn, 16, 5);
148
- * But if we're not in default-NaN mode then the target must
130
- int size = extract32(insn, 22, 2);
149
- * specify via set_float_2nan_prop_rule().
131
- bool u = extract32(insn, 29, 1);
150
- */
132
- bool is_q = extract32(insn, 30, 1);
151
- assert(!status->default_nan_mode);
133
- bool feature;
134
- int rot;
135
-
152
-
136
- switch (u * 16 + opcode) {
153
- switch (status->float_2nan_prop_rule) {
137
- case 0x18: /* FCMLA, #0 */
154
- case float_2nan_prop_s_ab:
138
- case 0x19: /* FCMLA, #90 */
155
- if (is_snan(a_cls)) {
139
- case 0x1a: /* FCMLA, #180 */
156
- return 0;
140
- case 0x1b: /* FCMLA, #270 */
157
- } else if (is_snan(b_cls)) {
141
- if (size == 0
158
- return 1;
142
- || (size == 1 && !dc_isar_feature(aa64_fp16, s))
159
- } else if (is_qnan(a_cls)) {
143
- || (size == 3 && !is_q)) {
160
- return 0;
144
- unallocated_encoding(s);
161
- } else {
145
- return;
162
- return 1;
146
- }
163
- }
147
- feature = dc_isar_feature(aa64_fcma, s);
164
- break;
148
- break;
165
- case float_2nan_prop_s_ba:
149
- default:
166
- if (is_snan(b_cls)) {
150
- case 0x02: /* SDOT (vector) */
167
- return 1;
151
- case 0x03: /* USDOT */
168
- } else if (is_snan(a_cls)) {
152
- case 0x04: /* SMMLA */
169
- return 0;
153
- case 0x05: /* USMMLA */
170
- } else if (is_qnan(b_cls)) {
154
- case 0x10: /* SQRDMLAH (vector) */
171
- return 1;
155
- case 0x11: /* SQRDMLSH (vector) */
172
- } else {
156
- case 0x12: /* UDOT (vector) */
173
- return 0;
157
- case 0x14: /* UMMLA */
174
- }
158
- case 0x1c: /* FCADD, #90 */
175
- break;
159
- case 0x1d: /* BFMMLA */
176
- case float_2nan_prop_ab:
160
- case 0x1e: /* FCADD, #270 */
177
- if (is_nan(a_cls)) {
161
- case 0x1f: /* BFDOT / BFMLAL */
178
- return 0;
162
- unallocated_encoding(s);
179
- } else {
163
- return;
180
- return 1;
164
- }
181
- }
165
- if (!feature) {
182
- break;
166
- unallocated_encoding(s);
183
- case float_2nan_prop_ba:
167
- return;
184
- if (is_nan(b_cls)) {
168
- }
185
- return 1;
169
- if (!fp_access_check(s)) {
186
- } else {
170
- return;
187
- return 0;
171
- }
188
- }
172
-
189
- break;
173
- switch (opcode) {
190
- case float_2nan_prop_x87:
174
- case 0x8: /* FCMLA, #0 */
191
- /*
175
- case 0x9: /* FCMLA, #90 */
192
- * This implements x87 NaN propagation rules:
176
- case 0xa: /* FCMLA, #180 */
193
- * SNaN + QNaN => return the QNaN
177
- case 0xb: /* FCMLA, #270 */
194
- * two SNaNs => return the one with the larger significand, silenced
178
- rot = extract32(opcode, 0, 2);
195
- * two QNaNs => return the one with the larger significand
179
- switch (size) {
196
- * SNaN and a non-NaN => return the SNaN, silenced
180
- case 1:
197
- * QNaN and a non-NaN => return the QNaN
181
- gen_gvec_op4_fpst(s, is_q, rd, rn, rm, rd, true, rot,
198
- *
182
- gen_helper_gvec_fcmlah);
199
- * If we get down to comparing significands and they are the same,
183
- break;
200
- * return the NaN with the positive sign bit (if any).
184
- case 2:
201
- */
185
- gen_gvec_op4_fpst(s, is_q, rd, rn, rm, rd, false, rot,
202
- if (is_snan(a_cls)) {
186
- gen_helper_gvec_fcmlas);
203
- if (is_snan(b_cls)) {
187
- break;
204
- return aIsLargerSignificand ? 0 : 1;
188
- case 3:
205
- }
189
- gen_gvec_op4_fpst(s, is_q, rd, rn, rm, rd, false, rot,
206
- return is_qnan(b_cls) ? 1 : 0;
190
- gen_helper_gvec_fcmlad);
207
- } else if (is_qnan(a_cls)) {
191
- break;
208
- if (is_snan(b_cls) || !is_qnan(b_cls)) {
192
- default:
209
- return 0;
193
- g_assert_not_reached();
210
- } else {
194
- }
211
- return aIsLargerSignificand ? 0 : 1;
195
- return;
212
- }
196
-
213
- } else {
214
- return 1;
215
- }
197
- default:
216
- default:
198
- g_assert_not_reached();
217
- g_assert_not_reached();
199
- }
218
- }
200
-}
219
-}
201
-
220
-
202
static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q,
221
/*----------------------------------------------------------------------------
203
int size, int rn, int rd)
222
| Returns 1 if the double-precision floating-point value `a' is a quiet
204
{
223
| NaN; otherwise returns 0.
205
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
206
int rn = extract32(insn, 5, 5);
207
int rd = extract32(insn, 0, 5);
208
bool is_long = false;
209
- int is_fp = 0;
210
- bool is_fp16 = false;
211
int index;
212
- TCGv_ptr fpst;
213
214
switch (16 * u + opcode) {
215
case 0x02: /* SMLAL, SMLAL2 */
216
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
217
case 0x0b: /* SQDMULL, SQDMULL2 */
218
is_long = true;
219
break;
220
- case 0x11: /* FCMLA #0 */
221
- case 0x13: /* FCMLA #90 */
222
- case 0x15: /* FCMLA #180 */
223
- case 0x17: /* FCMLA #270 */
224
- if (is_scalar || !dc_isar_feature(aa64_fcma, s)) {
225
- unallocated_encoding(s);
226
- return;
227
- }
228
- is_fp = 2;
229
- break;
230
default:
231
case 0x00: /* FMLAL */
232
case 0x01: /* FMLA */
233
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
234
case 0x0e: /* SDOT */
235
case 0x0f: /* SUDOT / BFDOT / USDOT / BFMLAL */
236
case 0x10: /* MLA */
237
+ case 0x11: /* FCMLA #0 */
238
+ case 0x13: /* FCMLA #90 */
239
case 0x14: /* MLS */
240
+ case 0x15: /* FCMLA #180 */
241
+ case 0x17: /* FCMLA #270 */
242
case 0x18: /* FMLAL2 */
243
case 0x19: /* FMULX */
244
case 0x1c: /* FMLSL2 */
245
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
246
return;
247
}
248
249
- switch (is_fp) {
250
- case 1: /* normal fp */
251
- unallocated_encoding(s); /* in decodetree */
252
- return;
253
-
254
- case 2: /* complex fp */
255
- /* Each indexable element is a complex pair. */
256
- size += 1;
257
- switch (size) {
258
- case MO_32:
259
- if (h && !is_q) {
260
- unallocated_encoding(s);
261
- return;
262
- }
263
- is_fp16 = true;
264
- break;
265
- case MO_64:
266
- break;
267
- default:
268
- unallocated_encoding(s);
269
- return;
270
- }
271
- break;
272
-
273
- default: /* integer */
274
- switch (size) {
275
- case MO_8:
276
- case MO_64:
277
- unallocated_encoding(s);
278
- return;
279
- }
280
- break;
281
- }
282
- if (is_fp16 && !dc_isar_feature(aa64_fp16, s)) {
283
- unallocated_encoding(s);
284
- return;
285
- }
286
-
287
/* Given MemOp size, adjust register and indexing. */
288
switch (size) {
289
+ case MO_8:
290
+ case MO_64:
291
+ unallocated_encoding(s);
292
+ return;
293
case MO_16:
294
index = h << 2 | l << 1 | m;
295
break;
296
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
297
index = h << 1 | l;
298
rm |= m << 4;
299
break;
300
- case MO_64:
301
- if (l || !is_q) {
302
- unallocated_encoding(s);
303
- return;
304
- }
305
- index = h;
306
- rm |= m << 4;
307
- break;
308
default:
309
g_assert_not_reached();
310
}
311
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
312
return;
313
}
314
315
- if (is_fp) {
316
- fpst = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR);
317
- } else {
318
- fpst = NULL;
319
- }
320
-
321
- switch (16 * u + opcode) {
322
- case 0x11: /* FCMLA #0 */
323
- case 0x13: /* FCMLA #90 */
324
- case 0x15: /* FCMLA #180 */
325
- case 0x17: /* FCMLA #270 */
326
- {
327
- int rot = extract32(insn, 13, 2);
328
- int data = (index << 2) | rot;
329
- tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, rd),
330
- vec_full_reg_offset(s, rn),
331
- vec_full_reg_offset(s, rm),
332
- vec_full_reg_offset(s, rd), fpst,
333
- is_q ? 16 : 8, vec_full_reg_size(s), data,
334
- size == MO_64
335
- ? gen_helper_gvec_fcmlas_idx
336
- : gen_helper_gvec_fcmlah_idx);
337
- }
338
- return;
339
- }
340
-
341
if (size == 3) {
342
g_assert_not_reached();
343
} else if (!is_long) {
344
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
345
*/
346
static const AArch64DecodeTable data_proc_simd[] = {
347
/* pattern , mask , fn */
348
- { 0x0e008400, 0x9f208400, disas_simd_three_reg_same_extra },
349
{ 0x0e200000, 0x9f200c00, disas_simd_three_reg_diff },
350
{ 0x0e200800, 0x9f3e0c00, disas_simd_two_reg_misc },
351
{ 0x0e300800, 0x9f3e0c00, disas_simd_across_lanes },
352
--
224
--
353
2.34.1
225
2.34.1
226
227
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Remember if there was an SNaN, and use that to simplify
4
float_2nan_prop_s_{ab,ba} to only the snan component.
5
Then, fall through to the corresponding
6
float_2nan_prop_{ab,ba} case to handle any remaining
7
nans, which must be quiet.
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20241203203949.483774-10-richard.henderson@linaro.org
5
Message-id: 20240625183536.1672454-9-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/tcg/a64.decode | 2 +
14
fpu/softfloat-parts.c.inc | 32 ++++++++++++--------------------
9
target/arm/tcg/translate-a64.c | 77 +++++++++++++---------------------
15
1 file changed, 12 insertions(+), 20 deletions(-)
10
2 files changed, 31 insertions(+), 48 deletions(-)
11
16
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/a64.decode
19
--- a/fpu/softfloat-parts.c.inc
15
+++ b/target/arm/tcg/a64.decode
20
+++ b/fpu/softfloat-parts.c.inc
16
@@ -XXX,XX +XXX,XX @@ SDOT_v 0.00 1110 100 ..... 10010 1 ..... ..... @qrrr_s
21
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
17
UDOT_v 0.10 1110 100 ..... 10010 1 ..... ..... @qrrr_s
22
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
18
USDOT_v 0.00 1110 100 ..... 10011 1 ..... ..... @qrrr_s
23
float_status *s)
19
BFDOT_v 0.10 1110 010 ..... 11111 1 ..... ..... @qrrr_s
24
{
20
+BFMLAL_v 0.10 1110 110 ..... 11111 1 ..... ..... @qrrr_h
25
+ bool have_snan = false;
21
26
int cmp, which;
22
### Advanced SIMD scalar x indexed element
27
23
28
if (is_snan(a->cls) || is_snan(b->cls)) {
24
@@ -XXX,XX +XXX,XX @@ UDOT_vi 0.10 1111 10 .. .... 1110 . 0 ..... ..... @qrrx_s
29
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
25
SUDOT_vi 0.00 1111 00 .. .... 1111 . 0 ..... ..... @qrrx_s
30
+ have_snan = true;
26
USDOT_vi 0.00 1111 10 .. .... 1111 . 0 ..... ..... @qrrx_s
31
}
27
BFDOT_vi 0.00 1111 01 .. .... 1111 . 0 ..... ..... @qrrx_s
32
28
+BFMLAL_vi 0.00 1111 11 .. .... 1111 . 0 ..... ..... @qrrx_h
33
if (s->default_nan_mode) {
29
34
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
30
# Floating-point conditional select
35
31
36
switch (s->float_2nan_prop_rule) {
32
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
37
case float_2nan_prop_s_ab:
33
index XXXXXXX..XXXXXXX 100644
38
- if (is_snan(a->cls)) {
34
--- a/target/arm/tcg/translate-a64.c
39
- which = 0;
35
+++ b/target/arm/tcg/translate-a64.c
40
- } else if (is_snan(b->cls)) {
36
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(UDOT_v, aa64_dp, do_dot_vector, a, gen_helper_gvec_udot_b)
41
- which = 1;
37
TRANS_FEAT(USDOT_v, aa64_i8mm, do_dot_vector, a, gen_helper_gvec_usdot_b)
42
- } else if (is_qnan(a->cls)) {
38
TRANS_FEAT(BFDOT_v, aa64_bf16, do_dot_vector, a, gen_helper_gvec_bfdot)
43
- which = 0;
39
44
- } else {
40
+static bool trans_BFMLAL_v(DisasContext *s, arg_qrrr_e *a)
45
- which = 1;
41
+{
46
+ if (have_snan) {
42
+ if (!dc_isar_feature(aa64_bf16, s)) {
47
+ which = is_snan(a->cls) ? 0 : 1;
43
+ return false;
48
+ break;
44
+ }
45
+ if (fp_access_check(s)) {
46
+ /* Q bit selects BFMLALB vs BFMLALT. */
47
+ gen_gvec_op4_fpst(s, true, a->rd, a->rn, a->rm, a->rd, false, a->q,
48
+ gen_helper_gvec_bfmlal);
49
+ }
50
+ return true;
51
+}
52
+
53
/*
54
* Advanced SIMD scalar/vector x indexed element
55
*/
56
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(USDOT_vi, aa64_i8mm, do_dot_vector_idx, a,
57
TRANS_FEAT(BFDOT_vi, aa64_bf16, do_dot_vector_idx, a,
58
gen_helper_gvec_bfdot_idx)
59
60
+static bool trans_BFMLAL_vi(DisasContext *s, arg_qrrx_e *a)
61
+{
62
+ if (!dc_isar_feature(aa64_bf16, s)) {
63
+ return false;
64
+ }
65
+ if (fp_access_check(s)) {
66
+ /* Q bit selects BFMLALB vs BFMLALT. */
67
+ gen_gvec_op4_fpst(s, true, a->rd, a->rn, a->rm, a->rd, 0,
68
+ (a->idx << 1) | a->q,
69
+ gen_helper_gvec_bfmlal_idx);
70
+ }
71
+ return true;
72
+}
73
+
74
/*
75
* Advanced SIMD scalar pairwise
76
*/
77
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
78
}
49
}
79
feature = dc_isar_feature(aa64_bf16, s);
50
- break;
80
break;
51
- case float_2nan_prop_s_ba:
81
- case 0x1f:
52
- if (is_snan(b->cls)) {
82
- switch (size) {
53
- which = 1;
83
- case 3: /* BFMLAL{B,T} */
54
- } else if (is_snan(a->cls)) {
84
- feature = dc_isar_feature(aa64_bf16, s);
55
- which = 0;
85
- break;
56
- } else if (is_qnan(b->cls)) {
86
- default:
57
- which = 1;
87
- case 1: /* BFDOT */
58
- } else {
88
- unallocated_encoding(s);
59
- which = 0;
89
- return;
90
- }
60
- }
91
- break;
61
- break;
92
default:
62
+ /* fall through */
93
case 0x02: /* SDOT (vector) */
63
case float_2nan_prop_ab:
94
case 0x03: /* USDOT */
64
which = is_nan(a->cls) ? 0 : 1;
95
case 0x10: /* SQRDMLAH (vector) */
96
case 0x11: /* SQRDMLSH (vector) */
97
case 0x12: /* UDOT (vector) */
98
+ case 0x1f: /* BFDOT / BFMLAL */
99
unallocated_encoding(s);
100
return;
101
}
102
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
103
case 0xd: /* BFMMLA */
104
gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfmmla);
105
return;
106
- case 0xf:
107
- switch (size) {
108
- case 3: /* BFMLAL{B,T} */
109
- gen_gvec_op4_fpst(s, 1, rd, rn, rm, rd, false, is_q,
110
- gen_helper_gvec_bfmlal);
111
- break;
112
- default:
113
- g_assert_not_reached();
114
- }
115
- return;
116
-
117
default:
118
g_assert_not_reached();
119
}
120
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
121
case 0x0b: /* SQDMULL, SQDMULL2 */
122
is_long = true;
123
break;
65
break;
124
- case 0x0f:
66
+ case float_2nan_prop_s_ba:
125
- switch (size) {
67
+ if (have_snan) {
126
- case 3: /* BFMLAL{B,T} */
68
+ which = is_snan(b->cls) ? 1 : 0;
127
- if (is_scalar || !dc_isar_feature(aa64_bf16, s)) {
69
+ break;
128
- unallocated_encoding(s);
70
+ }
129
- return;
71
+ /* fall through */
130
- }
72
case float_2nan_prop_ba:
131
- /* can't set is_fp without other incorrect size checks */
73
which = is_nan(b->cls) ? 1 : 0;
132
- size = MO_16;
74
break;
133
- break;
134
- default:
135
- case 0: /* SUDOT */
136
- case 1: /* BFDOT */
137
- case 2: /* USDOT */
138
- unallocated_encoding(s);
139
- return;
140
- }
141
- break;
142
case 0x11: /* FCMLA #0 */
143
case 0x13: /* FCMLA #90 */
144
case 0x15: /* FCMLA #180 */
145
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
146
case 0x0c: /* SQDMULH */
147
case 0x0d: /* SQRDMULH */
148
case 0x0e: /* SDOT */
149
+ case 0x0f: /* SUDOT / BFDOT / USDOT / BFMLAL */
150
case 0x10: /* MLA */
151
case 0x14: /* MLS */
152
case 0x18: /* FMLAL2 */
153
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
154
}
155
156
switch (16 * u + opcode) {
157
- case 0x0f:
158
- switch (extract32(insn, 22, 2)) {
159
- case 3: /* BFMLAL{B,T} */
160
- gen_gvec_op4_fpst(s, 1, rd, rn, rm, rd, 0, (index << 1) | is_q,
161
- gen_helper_gvec_bfmlal_idx);
162
- return;
163
- }
164
- g_assert_not_reached();
165
case 0x11: /* FCMLA #0 */
166
case 0x13: /* FCMLA #90 */
167
case 0x15: /* FCMLA #180 */
168
--
75
--
169
2.34.1
76
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Move the fractional comparison to the end of the
4
float_2nan_prop_x87 case. This is not required for
5
any other 2nan propagation rule. Reorganize the
6
x87 case itself to break out of the switch when the
7
fractional comparison is not required.
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20241203203949.483774-11-richard.henderson@linaro.org
5
Message-id: 20240625183536.1672454-10-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/tcg/a64.decode | 4 ++++
14
fpu/softfloat-parts.c.inc | 19 +++++++++----------
9
target/arm/tcg/translate-a64.c | 36 ++++++++--------------------------
15
1 file changed, 9 insertions(+), 10 deletions(-)
10
2 files changed, 12 insertions(+), 28 deletions(-)
11
16
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/a64.decode
19
--- a/fpu/softfloat-parts.c.inc
15
+++ b/target/arm/tcg/a64.decode
20
+++ b/fpu/softfloat-parts.c.inc
16
@@ -XXX,XX +XXX,XX @@ UDOT_v 0.10 1110 100 ..... 10010 1 ..... ..... @qrrr_s
21
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
17
USDOT_v 0.00 1110 100 ..... 10011 1 ..... ..... @qrrr_s
22
return a;
18
BFDOT_v 0.10 1110 010 ..... 11111 1 ..... ..... @qrrr_s
23
}
19
BFMLAL_v 0.10 1110 110 ..... 11111 1 ..... ..... @qrrr_h
24
20
+BFMMLA 0110 1110 010 ..... 11101 1 ..... ..... @rrr_q1e0
25
- cmp = frac_cmp(a, b);
21
+SMMLA 0100 1110 100 ..... 10100 1 ..... ..... @rrr_q1e0
26
- if (cmp == 0) {
22
+UMMLA 0110 1110 100 ..... 10100 1 ..... ..... @rrr_q1e0
27
- cmp = a->sign < b->sign;
23
+USMMLA 0100 1110 100 ..... 10101 1 ..... ..... @rrr_q1e0
28
- }
24
29
-
25
### Advanced SIMD scalar x indexed element
30
switch (s->float_2nan_prop_rule) {
26
31
case float_2nan_prop_s_ab:
27
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
32
if (have_snan) {
28
index XXXXXXX..XXXXXXX 100644
33
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
29
--- a/target/arm/tcg/translate-a64.c
34
* return the NaN with the positive sign bit (if any).
30
+++ b/target/arm/tcg/translate-a64.c
35
*/
31
@@ -XXX,XX +XXX,XX @@ TRANS_FEAT(SDOT_v, aa64_dp, do_dot_vector, a, gen_helper_gvec_sdot_b)
36
if (is_snan(a->cls)) {
32
TRANS_FEAT(UDOT_v, aa64_dp, do_dot_vector, a, gen_helper_gvec_udot_b)
37
- if (is_snan(b->cls)) {
33
TRANS_FEAT(USDOT_v, aa64_i8mm, do_dot_vector, a, gen_helper_gvec_usdot_b)
38
- which = cmp > 0 ? 0 : 1;
34
TRANS_FEAT(BFDOT_v, aa64_bf16, do_dot_vector, a, gen_helper_gvec_bfdot)
39
- } else {
35
+TRANS_FEAT(BFMMLA, aa64_bf16, do_dot_vector, a, gen_helper_gvec_bfmmla)
40
+ if (!is_snan(b->cls)) {
36
+TRANS_FEAT(SMMLA, aa64_i8mm, do_dot_vector, a, gen_helper_gvec_smmla_b)
41
which = is_qnan(b->cls) ? 1 : 0;
37
+TRANS_FEAT(UMMLA, aa64_i8mm, do_dot_vector, a, gen_helper_gvec_ummla_b)
42
+ break;
38
+TRANS_FEAT(USMMLA, aa64_i8mm, do_dot_vector, a, gen_helper_gvec_usmmla_b)
43
}
39
44
} else if (is_qnan(a->cls)) {
40
static bool trans_BFMLAL_v(DisasContext *s, arg_qrrr_e *a)
45
if (is_snan(b->cls) || !is_qnan(b->cls)) {
41
{
46
which = 0;
42
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
47
- } else {
43
int rot;
48
- which = cmp > 0 ? 0 : 1;
44
49
+ break;
45
switch (u * 16 + opcode) {
50
}
46
- case 0x04: /* SMMLA */
51
} else {
47
- case 0x14: /* UMMLA */
52
which = 1;
48
- case 0x05: /* USMMLA */
53
+ break;
49
- if (!is_q || size != MO_32) {
50
- unallocated_encoding(s);
51
- return;
52
- }
53
- feature = dc_isar_feature(aa64_i8mm, s);
54
- break;
55
case 0x18: /* FCMLA, #0 */
56
case 0x19: /* FCMLA, #90 */
57
case 0x1a: /* FCMLA, #180 */
58
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
59
}
54
}
60
feature = dc_isar_feature(aa64_fcma, s);
55
+ cmp = frac_cmp(a, b);
56
+ if (cmp == 0) {
57
+ cmp = a->sign < b->sign;
58
+ }
59
+ which = cmp > 0 ? 0 : 1;
61
break;
60
break;
62
- case 0x1d: /* BFMMLA */
63
- if (size != MO_16 || !is_q) {
64
- unallocated_encoding(s);
65
- return;
66
- }
67
- feature = dc_isar_feature(aa64_bf16, s);
68
- break;
69
default:
70
case 0x02: /* SDOT (vector) */
71
case 0x03: /* USDOT */
72
+ case 0x04: /* SMMLA */
73
+ case 0x05: /* USMMLA */
74
case 0x10: /* SQRDMLAH (vector) */
75
case 0x11: /* SQRDMLSH (vector) */
76
case 0x12: /* UDOT (vector) */
77
+ case 0x14: /* UMMLA */
78
+ case 0x1d: /* BFMMLA */
79
case 0x1f: /* BFDOT / BFMLAL */
80
unallocated_encoding(s);
81
return;
82
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
83
}
84
85
switch (opcode) {
86
- case 0x04: /* SMMLA, UMMLA */
87
- gen_gvec_op4_ool(s, 1, rd, rn, rm, rd, 0,
88
- u ? gen_helper_gvec_ummla_b
89
- : gen_helper_gvec_smmla_b);
90
- return;
91
- case 0x05: /* USMMLA */
92
- gen_gvec_op4_ool(s, 1, rd, rn, rm, rd, 0, gen_helper_gvec_usmmla_b);
93
- return;
94
-
95
case 0x8: /* FCMLA, #0 */
96
case 0x9: /* FCMLA, #90 */
97
case 0xa: /* FCMLA, #180 */
98
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
99
}
100
return;
101
102
- case 0xd: /* BFMMLA */
103
- gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfmmla);
104
- return;
105
default:
61
default:
106
g_assert_not_reached();
62
g_assert_not_reached();
107
}
108
--
63
--
109
2.34.1
64
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Replace the "index" selecting between A and B with a result variable
4
of the proper type. This improves clarity within the function.
5
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20240625183536.1672454-7-richard.henderson@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-12-richard.henderson@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/tcg/a64.decode | 3 +++
11
fpu/softfloat-parts.c.inc | 28 +++++++++++++---------------
9
target/arm/tcg/translate-a64.c | 35 ++++++++--------------------------
12
1 file changed, 13 insertions(+), 15 deletions(-)
10
2 files changed, 11 insertions(+), 27 deletions(-)
11
13
12
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/tcg/a64.decode
16
--- a/fpu/softfloat-parts.c.inc
15
+++ b/target/arm/tcg/a64.decode
17
+++ b/fpu/softfloat-parts.c.inc
16
@@ -XXX,XX +XXX,XX @@ SQRDMLSH_v 0.10 1110 ..0 ..... 10001 1 ..... ..... @qrrr_e
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
17
19
float_status *s)
18
SDOT_v 0.00 1110 100 ..... 10010 1 ..... ..... @qrrr_s
20
{
19
UDOT_v 0.10 1110 100 ..... 10010 1 ..... ..... @qrrr_s
21
bool have_snan = false;
20
+USDOT_v 0.00 1110 100 ..... 10011 1 ..... ..... @qrrr_s
22
- int cmp, which;
21
23
+ FloatPartsN *ret;
22
### Advanced SIMD scalar x indexed element
24
+ int cmp;
23
25
24
@@ -XXX,XX +XXX,XX @@ SQRDMLSH_vi 0.10 1111 10 .. .... 1111 . 0 ..... ..... @qrrx_s
26
if (is_snan(a->cls) || is_snan(b->cls)) {
25
27
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
26
SDOT_vi 0.00 1111 10 .. .... 1110 . 0 ..... ..... @qrrx_s
28
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
27
UDOT_vi 0.10 1111 10 .. .... 1110 . 0 ..... ..... @qrrx_s
29
switch (s->float_2nan_prop_rule) {
28
+SUDOT_vi 0.00 1111 00 .. .... 1111 . 0 ..... ..... @qrrx_s
30
case float_2nan_prop_s_ab:
29
+USDOT_vi 0.00 1111 10 .. .... 1111 . 0 ..... ..... @qrrx_s
31
if (have_snan) {
30
32
- which = is_snan(a->cls) ? 0 : 1;
31
# Floating-point conditional select
33
+ ret = is_snan(a->cls) ? a : b;
32
34
break;
33
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
35
}
34
index XXXXXXX..XXXXXXX 100644
36
/* fall through */
35
--- a/target/arm/tcg/translate-a64.c
37
case float_2nan_prop_ab:
36
+++ b/target/arm/tcg/translate-a64.c
38
- which = is_nan(a->cls) ? 0 : 1;
37
@@ -XXX,XX +XXX,XX @@ static bool do_dot_vector(DisasContext *s, arg_qrrr_e *a,
39
+ ret = is_nan(a->cls) ? a : b;
38
40
break;
39
TRANS_FEAT(SDOT_v, aa64_dp, do_dot_vector, a, gen_helper_gvec_sdot_b)
41
case float_2nan_prop_s_ba:
40
TRANS_FEAT(UDOT_v, aa64_dp, do_dot_vector, a, gen_helper_gvec_udot_b)
42
if (have_snan) {
41
+TRANS_FEAT(USDOT_v, aa64_i8mm, do_dot_vector, a, gen_helper_gvec_usdot_b)
43
- which = is_snan(b->cls) ? 1 : 0;
42
44
+ ret = is_snan(b->cls) ? b : a;
43
/*
45
break;
44
* Advanced SIMD scalar/vector x indexed element
46
}
45
@@ -XXX,XX +XXX,XX @@ static bool do_dot_vector_idx(DisasContext *s, arg_qrrx_e *a,
47
/* fall through */
46
48
case float_2nan_prop_ba:
47
TRANS_FEAT(SDOT_vi, aa64_dp, do_dot_vector_idx, a, gen_helper_gvec_sdot_idx_b)
49
- which = is_nan(b->cls) ? 1 : 0;
48
TRANS_FEAT(UDOT_vi, aa64_dp, do_dot_vector_idx, a, gen_helper_gvec_udot_idx_b)
50
+ ret = is_nan(b->cls) ? b : a;
49
+TRANS_FEAT(SUDOT_vi, aa64_i8mm, do_dot_vector_idx, a,
51
break;
50
+ gen_helper_gvec_sudot_idx_b)
52
case float_2nan_prop_x87:
51
+TRANS_FEAT(USDOT_vi, aa64_i8mm, do_dot_vector_idx, a,
53
/*
52
+ gen_helper_gvec_usdot_idx_b)
54
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
53
55
*/
54
/*
56
if (is_snan(a->cls)) {
55
* Advanced SIMD scalar pairwise
57
if (!is_snan(b->cls)) {
56
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
58
- which = is_qnan(b->cls) ? 1 : 0;
57
int rot;
59
+ ret = is_qnan(b->cls) ? b : a;
58
60
break;
59
switch (u * 16 + opcode) {
61
}
60
- case 0x03: /* USDOT */
62
} else if (is_qnan(a->cls)) {
61
- if (size != MO_32) {
63
if (is_snan(b->cls) || !is_qnan(b->cls)) {
62
- unallocated_encoding(s);
64
- which = 0;
63
- return;
65
+ ret = a;
64
- }
66
break;
65
- feature = dc_isar_feature(aa64_i8mm, s);
67
}
66
- break;
68
} else {
67
case 0x04: /* SMMLA */
69
- which = 1;
68
case 0x14: /* UMMLA */
70
+ ret = b;
69
case 0x05: /* USMMLA */
71
break;
70
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
72
}
73
cmp = frac_cmp(a, b);
74
if (cmp == 0) {
75
cmp = a->sign < b->sign;
76
}
77
- which = cmp > 0 ? 0 : 1;
78
+ ret = cmp > 0 ? a : b;
71
break;
79
break;
72
default:
80
default:
73
case 0x02: /* SDOT (vector) */
81
g_assert_not_reached();
74
+ case 0x03: /* USDOT */
75
case 0x10: /* SQRDMLAH (vector) */
76
case 0x11: /* SQRDMLSH (vector) */
77
case 0x12: /* UDOT (vector) */
78
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
79
}
82
}
80
83
81
switch (opcode) {
84
- if (which) {
82
- case 0x3: /* USDOT */
85
- a = b;
83
- gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_usdot_b);
86
+ if (is_snan(ret->cls)) {
84
- return;
87
+ parts_silence_nan(ret, s);
85
-
88
}
86
case 0x04: /* SMMLA, UMMLA */
89
- if (is_snan(a->cls)) {
87
gen_gvec_op4_ool(s, 1, rd, rn, rm, rd, 0,
90
- parts_silence_nan(a, s);
88
u ? gen_helper_gvec_ummla_b
91
- }
89
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
92
- return a;
90
break;
93
+ return ret;
91
case 0x0f:
94
}
92
switch (size) {
95
93
- case 0: /* SUDOT */
96
static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
94
- case 2: /* USDOT */
95
- if (is_scalar || !dc_isar_feature(aa64_i8mm, s)) {
96
- unallocated_encoding(s);
97
- return;
98
- }
99
- size = MO_32;
100
- break;
101
case 1: /* BFDOT */
102
if (is_scalar || !dc_isar_feature(aa64_bf16, s)) {
103
unallocated_encoding(s);
104
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
105
size = MO_16;
106
break;
107
default:
108
+ case 0: /* SUDOT */
109
+ case 2: /* USDOT */
110
unallocated_encoding(s);
111
return;
112
}
113
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
114
switch (16 * u + opcode) {
115
case 0x0f:
116
switch (extract32(insn, 22, 2)) {
117
- case 0: /* SUDOT */
118
- gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
119
- gen_helper_gvec_sudot_idx_b);
120
- return;
121
case 1: /* BFDOT */
122
gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
123
gen_helper_gvec_bfdot_idx);
124
return;
125
- case 2: /* USDOT */
126
- gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
127
- gen_helper_gvec_usdot_idx_b);
128
- return;
129
case 3: /* BFMLAL{B,T} */
130
gen_gvec_op4_fpst(s, 1, rd, rn, rm, rd, 0, (index << 1) | is_q,
131
gen_helper_gvec_bfmlal_idx);
132
--
97
--
133
2.34.1
98
2.34.1
99
100
diff view generated by jsdifflib
1
From: Patrick Leis <venture@google.com>
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
2
3
Signed-off-by: Patrick Leis <venture@google.com>
3
I'm migrating to Qualcomm's new open source email infrastructure, so
4
Message-id: 20240626211623.3510701-1-venture@google.com
4
update my email address, and update the mailmap to match.
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
6
Signed-off-by: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
8
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20241205114047.1125842-1-leif.lindholm@oss.qualcomm.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
13
---
8
MAINTAINERS | 2 +-
14
MAINTAINERS | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
15
.mailmap | 5 +++--
16
2 files changed, 4 insertions(+), 3 deletions(-)
10
17
11
diff --git a/MAINTAINERS b/MAINTAINERS
18
diff --git a/MAINTAINERS b/MAINTAINERS
12
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
13
--- a/MAINTAINERS
20
--- a/MAINTAINERS
14
+++ b/MAINTAINERS
21
+++ b/MAINTAINERS
15
@@ -XXX,XX +XXX,XX @@ F: hw/net/tulip.c
22
@@ -XXX,XX +XXX,XX @@ F: include/hw/ssi/imx_spi.h
16
F: hw/net/tulip.h
23
SBSA-REF
17
24
M: Radoslaw Biernacki <rad@semihalf.com>
18
pca954x
25
M: Peter Maydell <peter.maydell@linaro.org>
19
-M: Patrick Venture <venture@google.com>
26
-R: Leif Lindholm <quic_llindhol@quicinc.com>
20
+M: Patrick Leis <venture@google.com>
27
+R: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
28
R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
29
L: qemu-arm@nongnu.org
21
S: Maintained
30
S: Maintained
22
F: hw/i2c/i2c_mux_pca954x.c
31
diff --git a/.mailmap b/.mailmap
23
F: include/hw/i2c/i2c_mux_pca954x.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/.mailmap
34
+++ b/.mailmap
35
@@ -XXX,XX +XXX,XX @@ Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
36
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
37
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
38
Juan Quintela <quintela@trasno.org> <quintela@redhat.com>
39
-Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
40
-Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
41
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <quic_llindhol@quicinc.com>
42
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif.lindholm@linaro.org>
43
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif@nuviainc.com>
44
Luc Michel <luc@lmichel.fr> <luc.michel@git.antfield.fr>
45
Luc Michel <luc@lmichel.fr> <luc.michel@greensocs.com>
46
Luc Michel <luc@lmichel.fr> <lmichel@kalray.eu>
24
--
47
--
25
2.34.1
48
2.34.1
49
50
diff view generated by jsdifflib
1
From: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
1
From: Vikram Garhwal <vikram.garhwal@bytedance.com>
2
2
3
Added the supported device list and an example command.
3
Previously, maintainer role was paused due to inactive email id. Commit id:
4
c009d715721861984c4987bcc78b7ee183e86d75.
4
5
5
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
6
Signed-off-by: Vikram Garhwal <vikram.garhwal@bytedance.com>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Message-id: 20240621125906.1300995-4-sai.pavan.boddu@amd.com
8
Message-id: 20241204184205.12952-1-vikram.garhwal@bytedance.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
MAINTAINERS | 1 +
11
MAINTAINERS | 2 ++
12
docs/system/arm/xlnx-zynq.rst | 47 +++++++++++++++++++++++++++++++++++
12
1 file changed, 2 insertions(+)
13
docs/system/target-arm.rst | 1 +
14
3 files changed, 49 insertions(+)
15
create mode 100644 docs/system/arm/xlnx-zynq.rst
16
13
17
diff --git a/MAINTAINERS b/MAINTAINERS
14
diff --git a/MAINTAINERS b/MAINTAINERS
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/MAINTAINERS
16
--- a/MAINTAINERS
20
+++ b/MAINTAINERS
17
+++ b/MAINTAINERS
21
@@ -XXX,XX +XXX,XX @@ F: hw/adc/zynq-xadc.c
18
@@ -XXX,XX +XXX,XX @@ F: tests/qtest/fuzz-sb16-test.c
22
F: include/hw/misc/zynq_slcr.h
19
23
F: include/hw/adc/zynq-xadc.h
20
Xilinx CAN
24
X: hw/ssi/xilinx_*
21
M: Francisco Iglesias <francisco.iglesias@amd.com>
25
+F: docs/system/arm/xlnx-zynq.rst
22
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
26
23
S: Maintained
27
Xilinx ZynqMP and Versal
24
F: hw/net/can/xlnx-*
28
M: Alistair Francis <alistair@alistair23.me>
25
F: include/hw/net/xlnx-*
29
diff --git a/docs/system/arm/xlnx-zynq.rst b/docs/system/arm/xlnx-zynq.rst
26
@@ -XXX,XX +XXX,XX @@ F: include/hw/rx/
30
new file mode 100644
27
CAN bus subsystem and hardware
31
index XXXXXXX..XXXXXXX
28
M: Pavel Pisa <pisa@cmp.felk.cvut.cz>
32
--- /dev/null
29
M: Francisco Iglesias <francisco.iglesias@amd.com>
33
+++ b/docs/system/arm/xlnx-zynq.rst
30
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
34
@@ -XXX,XX +XXX,XX @@
31
S: Maintained
35
+Xilinx Zynq board (``xilinx-zynq-a9``)
32
W: https://canbus.pages.fel.cvut.cz/
36
+======================================
33
F: net/can/*
37
+The Zynq 7000 family is based on the AMD SoC architecture. These products
38
+integrate a feature-rich dual or single-core Arm Cortex-A9 MPCore based
39
+processing system (PS) and AMD programmable logic (PL) in a single device.
40
+
41
+More details here:
42
+https://docs.amd.com/r/en-US/ug585-zynq-7000-SoC-TRM/Zynq-7000-SoC-Technical-Reference-Manual
43
+
44
+QEMU xilinx-zynq-a9 board supports following devices:
45
+ - A9 MPCORE
46
+ - cortex-a9
47
+ - GIC v1
48
+ - Generic timer
49
+ - wdt
50
+ - OCM 256KB
51
+ - SMC SRAM@0xe2000000 64MB
52
+ - Zynq SLCR
53
+ - SPI x2
54
+ - QSPI
55
+ - UART
56
+ - TTC x2
57
+ - Gigabit Ethernet Controller x2
58
+ - SD Controller x2
59
+ - XADC
60
+ - Arm PrimeCell DMA Controller
61
+ - DDR Memory
62
+ - USB 2.0 x2
63
+
64
+Running
65
+"""""""
66
+Direct Linux boot of a generic ARM upstream Linux kernel:
67
+
68
+.. code-block:: bash
69
+
70
+ $ qemu-system-aarch64 -M xilinx-zynq-a9 \
71
+ -dtb zynq-zc702.dtb -serial null -serial mon:stdio \
72
+ -display none -m 1024 \
73
+ -initrd rootfs.cpio.gz -kernel zImage
74
+
75
+For configuring the boot-mode provide the following on the command line:
76
+
77
+.. code-block:: bash
78
+
79
+ -machine boot-mode=qspi
80
+
81
+Supported values are jtag, sd, qspi, nor.
82
diff --git a/docs/system/target-arm.rst b/docs/system/target-arm.rst
83
index XXXXXXX..XXXXXXX 100644
84
--- a/docs/system/target-arm.rst
85
+++ b/docs/system/target-arm.rst
86
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
87
arm/virt
88
arm/xenpvh
89
arm/xlnx-versal-virt
90
+ arm/xlnx-zynq
91
92
Emulated CPU architecture support
93
=================================
94
--
34
--
95
2.34.1
35
2.34.1
diff view generated by jsdifflib