* [PULL 00/72] target-arm queue
@ 2024-12-11 16:18 Peter Maydell
2024-12-11 16:18 ` [PULL 01/72] hw/net/lan9118: Extract lan9118_phy Peter Maydell
` (72 more replies)
0 siblings, 73 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:18 UTC (permalink / raw)
To: qemu-devel
First arm pullreq of the cycle; this is mostly my softfloat NaN
handling series. (Lots more in my to-review queue, but I don't
like pullreqs growing too close to a hundred patches at a time :-))
thanks
-- PMM
The following changes since commit 97f2796a3736ed37a1b85dc1c76a6c45b829dd17:
Open 10.0 development tree (2024-12-10 17:41:17 +0000)
are available in the Git repository at:
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20241211
for you to fetch changes up to 1abe28d519239eea5cf9620bb13149423e5665f8:
MAINTAINERS: Add correct email address for Vikram Garhwal (2024-12-11 15:31:09 +0000)
----------------------------------------------------------------
target-arm queue:
* hw/net/lan9118: Extract PHY model, reuse with imx_fec, fix bugs
* fpu: Make muladd NaN handling runtime-selected, not compile-time
* fpu: Make default NaN pattern runtime-selected, not compile-time
* fpu: Minor NaN-related cleanups
* MAINTAINERS: email address updates
----------------------------------------------------------------
Bernhard Beschow (5):
hw/net/lan9118: Extract lan9118_phy
hw/net/lan9118_phy: Reuse in imx_fec and consolidate implementations
hw/net/lan9118_phy: Fix off-by-one error in MII_ANLPAR register
hw/net/lan9118_phy: Reuse MII constants
hw/net/lan9118_phy: Add missing 100 mbps full duplex advertisement
Leif Lindholm (1):
MAINTAINERS: update email address for Leif Lindholm
Peter Maydell (54):
fpu: handle raising Invalid for infzero in pick_nan_muladd
fpu: Check for default_nan_mode before calling pickNaNMulAdd
softfloat: Allow runtime choice of inf * 0 + NaN result
tests/fp: Explicitly set inf-zero-nan rule
target/arm: Set FloatInfZeroNaNRule explicitly
target/s390: Set FloatInfZeroNaNRule explicitly
target/ppc: Set FloatInfZeroNaNRule explicitly
target/mips: Set FloatInfZeroNaNRule explicitly
target/sparc: Set FloatInfZeroNaNRule explicitly
target/xtensa: Set FloatInfZeroNaNRule explicitly
target/x86: Set FloatInfZeroNaNRule explicitly
target/loongarch: Set FloatInfZeroNaNRule explicitly
target/hppa: Set FloatInfZeroNaNRule explicitly
softfloat: Pass have_snan to pickNaNMulAdd
softfloat: Allow runtime choice of NaN propagation for muladd
tests/fp: Explicitly set 3-NaN propagation rule
target/arm: Set Float3NaNPropRule explicitly
target/loongarch: Set Float3NaNPropRule explicitly
target/ppc: Set Float3NaNPropRule explicitly
target/s390x: Set Float3NaNPropRule explicitly
target/sparc: Set Float3NaNPropRule explicitly
target/mips: Set Float3NaNPropRule explicitly
target/xtensa: Set Float3NaNPropRule explicitly
target/i386: Set Float3NaNPropRule explicitly
target/hppa: Set Float3NaNPropRule explicitly
fpu: Remove use_first_nan field from float_status
target/m68k: Don't pass NULL float_status to floatx80_default_nan()
softfloat: Create floatx80 default NaN from parts64_default_nan
target/loongarch: Use normal float_status in fclass_s and fclass_d helpers
target/m68k: In frem helper, initialize local float_status from env->fp_status
target/m68k: Init local float_status from env fp_status in gdb get/set reg
target/sparc: Initialize local scratch float_status from env->fp_status
target/ppc: Use env->fp_status in helper_compute_fprf functions
fpu: Allow runtime choice of default NaN value
tests/fp: Set default NaN pattern explicitly
target/microblaze: Set default NaN pattern explicitly
target/i386: Set default NaN pattern explicitly
target/hppa: Set default NaN pattern explicitly
target/alpha: Set default NaN pattern explicitly
target/arm: Set default NaN pattern explicitly
target/loongarch: Set default NaN pattern explicitly
target/m68k: Set default NaN pattern explicitly
target/mips: Set default NaN pattern explicitly
target/openrisc: Set default NaN pattern explicitly
target/ppc: Set default NaN pattern explicitly
target/sh4: Set default NaN pattern explicitly
target/rx: Set default NaN pattern explicitly
target/s390x: Set default NaN pattern explicitly
target/sparc: Set default NaN pattern explicitly
target/xtensa: Set default NaN pattern explicitly
target/hexagon: Set default NaN pattern explicitly
target/riscv: Set default NaN pattern explicitly
target/tricore: Set default NaN pattern explicitly
fpu: Remove default handling for dnan_pattern
Richard Henderson (11):
target/arm: Copy entire float_status in is_ebf
softfloat: Inline pickNaNMulAdd
softfloat: Use goto for default nan case in pick_nan_muladd
softfloat: Remove which from parts_pick_nan_muladd
softfloat: Pad array size in pick_nan_muladd
softfloat: Move propagateFloatx80NaN to softfloat.c
softfloat: Use parts_pick_nan in propagateFloatx80NaN
softfloat: Inline pickNaN
softfloat: Share code between parts_pick_nan cases
softfloat: Sink frac_cmp in parts_pick_nan until needed
softfloat: Replace WHICH with RET in parts_pick_nan
Vikram Garhwal (1):
MAINTAINERS: Add correct email address for Vikram Garhwal
MAINTAINERS | 4 +-
include/fpu/softfloat-helpers.h | 38 +++-
include/fpu/softfloat-types.h | 89 +++++++-
include/hw/net/imx_fec.h | 9 +-
include/hw/net/lan9118_phy.h | 37 ++++
include/hw/net/mii.h | 6 +
target/mips/fpu_helper.h | 20 ++
target/sparc/helper.h | 4 +-
fpu/softfloat.c | 19 ++
hw/net/imx_fec.c | 146 ++------------
hw/net/lan9118.c | 137 ++-----------
hw/net/lan9118_phy.c | 222 ++++++++++++++++++++
linux-user/arm/nwfpe/fpa11.c | 5 +
target/alpha/cpu.c | 2 +
target/arm/cpu.c | 10 +
target/arm/tcg/vec_helper.c | 20 +-
target/hexagon/cpu.c | 2 +
target/hppa/fpu_helper.c | 12 ++
target/i386/tcg/fpu_helper.c | 12 ++
target/loongarch/tcg/fpu_helper.c | 14 +-
target/m68k/cpu.c | 14 +-
target/m68k/fpu_helper.c | 6 +-
target/m68k/helper.c | 6 +-
target/microblaze/cpu.c | 2 +
target/mips/msa.c | 10 +
target/openrisc/cpu.c | 2 +
target/ppc/cpu_init.c | 19 ++
target/ppc/fpu_helper.c | 3 +-
target/riscv/cpu.c | 2 +
target/rx/cpu.c | 2 +
target/s390x/cpu.c | 5 +
target/sh4/cpu.c | 2 +
target/sparc/cpu.c | 6 +
target/sparc/fop_helper.c | 8 +-
target/sparc/translate.c | 4 +-
target/tricore/helper.c | 2 +
target/xtensa/cpu.c | 4 +
target/xtensa/fpu_helper.c | 3 +-
tests/fp/fp-bench.c | 7 +
tests/fp/fp-test-log2.c | 1 +
tests/fp/fp-test.c | 7 +
fpu/softfloat-parts.c.inc | 152 +++++++++++---
fpu/softfloat-specialize.c.inc | 412 ++------------------------------------
.mailmap | 5 +-
hw/net/Kconfig | 5 +
hw/net/meson.build | 1 +
hw/net/trace-events | 10 +-
47 files changed, 778 insertions(+), 730 deletions(-)
create mode 100644 include/hw/net/lan9118_phy.h
create mode 100644 hw/net/lan9118_phy.c
^ permalink raw reply [flat|nested] 75+ messages in thread
* [PULL 01/72] hw/net/lan9118: Extract lan9118_phy
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
@ 2024-12-11 16:18 ` Peter Maydell
2024-12-11 16:18 ` [PULL 02/72] hw/net/lan9118_phy: Reuse in imx_fec and consolidate implementations Peter Maydell
` (71 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:18 UTC (permalink / raw)
To: qemu-devel
From: Bernhard Beschow <shentey@gmail.com>
A very similar implementation of the same device exists in imx_fec. Prepare for
a common implementation by extracting a device model into its own files.
Some migration state has been moved into the new device model which breaks
migration compatibility for the following machines:
* smdkc210
* realview-*
* vexpress-*
* kzm
* mps2-*
While breaking migration ABI, fix the size of the MII registers to be 16 bit,
as defined by IEEE 802.3u.
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20241102125724.532843-2-shentey@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
include/hw/net/lan9118_phy.h | 37 ++++++++
hw/net/lan9118.c | 137 +++++-----------------------
hw/net/lan9118_phy.c | 169 +++++++++++++++++++++++++++++++++++
hw/net/Kconfig | 4 +
hw/net/meson.build | 1 +
5 files changed, 233 insertions(+), 115 deletions(-)
create mode 100644 include/hw/net/lan9118_phy.h
create mode 100644 hw/net/lan9118_phy.c
diff --git a/include/hw/net/lan9118_phy.h b/include/hw/net/lan9118_phy.h
new file mode 100644
index 00000000000..af12fc33d5f
--- /dev/null
+++ b/include/hw/net/lan9118_phy.h
@@ -0,0 +1,37 @@
+/*
+ * SMSC LAN9118 PHY emulation
+ *
+ * Copyright (c) 2009 CodeSourcery, LLC.
+ * Written by Paul Brook
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef HW_NET_LAN9118_PHY_H
+#define HW_NET_LAN9118_PHY_H
+
+#include "qom/object.h"
+#include "hw/sysbus.h"
+
+#define TYPE_LAN9118_PHY "lan9118-phy"
+OBJECT_DECLARE_SIMPLE_TYPE(Lan9118PhyState, LAN9118_PHY)
+
+typedef struct Lan9118PhyState {
+ SysBusDevice parent_obj;
+
+ uint16_t status;
+ uint16_t control;
+ uint16_t advertise;
+ uint16_t ints;
+ uint16_t int_mask;
+ qemu_irq irq;
+ bool link_down;
+} Lan9118PhyState;
+
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down);
+void lan9118_phy_reset(Lan9118PhyState *s);
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg);
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val);
+
+#endif
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
index db28a0ef306..99e87b7178c 100644
--- a/hw/net/lan9118.c
+++ b/hw/net/lan9118.c
@@ -16,6 +16,7 @@
#include "net/net.h"
#include "net/eth.h"
#include "hw/irq.h"
+#include "hw/net/lan9118_phy.h"
#include "hw/net/lan9118.h"
#include "hw/ptimer.h"
#include "hw/qdev-properties.h"
@@ -139,14 +140,6 @@ do { printf("lan9118: " fmt , ## __VA_ARGS__); } while (0)
#define MAC_CR_RXEN 0x00000004
#define MAC_CR_RESERVED 0x7f404213
-#define PHY_INT_ENERGYON 0x80
-#define PHY_INT_AUTONEG_COMPLETE 0x40
-#define PHY_INT_FAULT 0x20
-#define PHY_INT_DOWN 0x10
-#define PHY_INT_AUTONEG_LP 0x08
-#define PHY_INT_PARFAULT 0x04
-#define PHY_INT_AUTONEG_PAGE 0x02
-
#define GPT_TIMER_EN 0x20000000
/*
@@ -228,11 +221,8 @@ struct lan9118_state {
uint32_t mac_mii_data;
uint32_t mac_flow;
- uint32_t phy_status;
- uint32_t phy_control;
- uint32_t phy_advertise;
- uint32_t phy_int;
- uint32_t phy_int_mask;
+ Lan9118PhyState mii;
+ IRQState mii_irq;
int32_t eeprom_writable;
uint8_t eeprom[128];
@@ -274,8 +264,8 @@ struct lan9118_state {
static const VMStateDescription vmstate_lan9118 = {
.name = "lan9118",
- .version_id = 2,
- .minimum_version_id = 1,
+ .version_id = 3,
+ .minimum_version_id = 3,
.fields = (const VMStateField[]) {
VMSTATE_PTIMER(timer, lan9118_state),
VMSTATE_UINT32(irq_cfg, lan9118_state),
@@ -301,11 +291,6 @@ static const VMStateDescription vmstate_lan9118 = {
VMSTATE_UINT32(mac_mii_acc, lan9118_state),
VMSTATE_UINT32(mac_mii_data, lan9118_state),
VMSTATE_UINT32(mac_flow, lan9118_state),
- VMSTATE_UINT32(phy_status, lan9118_state),
- VMSTATE_UINT32(phy_control, lan9118_state),
- VMSTATE_UINT32(phy_advertise, lan9118_state),
- VMSTATE_UINT32(phy_int, lan9118_state),
- VMSTATE_UINT32(phy_int_mask, lan9118_state),
VMSTATE_INT32(eeprom_writable, lan9118_state),
VMSTATE_UINT8_ARRAY(eeprom, lan9118_state, 128),
VMSTATE_INT32(tx_fifo_size, lan9118_state),
@@ -385,9 +370,11 @@ static void lan9118_reload_eeprom(lan9118_state *s)
lan9118_mac_changed(s);
}
-static void phy_update_irq(lan9118_state *s)
+static void lan9118_update_irq(void *opaque, int n, int level)
{
- if (s->phy_int & s->phy_int_mask) {
+ lan9118_state *s = opaque;
+
+ if (level) {
s->int_sts |= PHY_INT;
} else {
s->int_sts &= ~PHY_INT;
@@ -395,33 +382,10 @@ static void phy_update_irq(lan9118_state *s)
lan9118_update(s);
}
-static void phy_update_link(lan9118_state *s)
-{
- /* Autonegotiation status mirrors link status. */
- if (qemu_get_queue(s->nic)->link_down) {
- s->phy_status &= ~0x0024;
- s->phy_int |= PHY_INT_DOWN;
- } else {
- s->phy_status |= 0x0024;
- s->phy_int |= PHY_INT_ENERGYON;
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
- }
- phy_update_irq(s);
-}
-
static void lan9118_set_link(NetClientState *nc)
{
- phy_update_link(qemu_get_nic_opaque(nc));
-}
-
-static void phy_reset(lan9118_state *s)
-{
- s->phy_status = 0x7809;
- s->phy_control = 0x3000;
- s->phy_advertise = 0x01e1;
- s->phy_int_mask = 0;
- s->phy_int = 0;
- phy_update_link(s);
+ lan9118_phy_update_link(&LAN9118(qemu_get_nic_opaque(nc))->mii,
+ nc->link_down);
}
static void lan9118_reset(DeviceState *d)
@@ -478,8 +442,6 @@ static void lan9118_reset(DeviceState *d)
s->read_word_n = 0;
s->write_word_n = 0;
- phy_reset(s);
-
s->eeprom_writable = 0;
lan9118_reload_eeprom(s);
}
@@ -678,7 +640,7 @@ static void do_tx_packet(lan9118_state *s)
uint32_t status;
/* FIXME: Honor TX disable, and allow queueing of packets. */
- if (s->phy_control & 0x4000) {
+ if (s->mii.control & 0x4000) {
/* This assumes the receive routine doesn't touch the VLANClient. */
qemu_receive_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
} else {
@@ -834,68 +796,6 @@ static void tx_fifo_push(lan9118_state *s, uint32_t val)
}
}
-static uint32_t do_phy_read(lan9118_state *s, int reg)
-{
- uint32_t val;
-
- switch (reg) {
- case 0: /* Basic Control */
- return s->phy_control;
- case 1: /* Basic Status */
- return s->phy_status;
- case 2: /* ID1 */
- return 0x0007;
- case 3: /* ID2 */
- return 0xc0d1;
- case 4: /* Auto-neg advertisement */
- return s->phy_advertise;
- case 5: /* Auto-neg Link Partner Ability */
- return 0x0f71;
- case 6: /* Auto-neg Expansion */
- return 1;
- /* TODO 17, 18, 27, 29, 30, 31 */
- case 29: /* Interrupt source. */
- val = s->phy_int;
- s->phy_int = 0;
- phy_update_irq(s);
- return val;
- case 30: /* Interrupt mask */
- return s->phy_int_mask;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "do_phy_read: PHY read reg %d\n", reg);
- return 0;
- }
-}
-
-static void do_phy_write(lan9118_state *s, int reg, uint32_t val)
-{
- switch (reg) {
- case 0: /* Basic Control */
- if (val & 0x8000) {
- phy_reset(s);
- break;
- }
- s->phy_control = val & 0x7980;
- /* Complete autonegotiation immediately. */
- if (val & 0x1000) {
- s->phy_status |= 0x0020;
- }
- break;
- case 4: /* Auto-neg advertisement */
- s->phy_advertise = (val & 0x2d7f) | 0x80;
- break;
- /* TODO 17, 18, 27, 31 */
- case 30: /* Interrupt mask */
- s->phy_int_mask = val & 0xff;
- phy_update_irq(s);
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "do_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
- }
-}
-
static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
{
switch (reg) {
@@ -929,9 +829,9 @@ static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
if (val & 2) {
DPRINTF("PHY write %d = 0x%04x\n",
(val >> 6) & 0x1f, s->mac_mii_data);
- do_phy_write(s, (val >> 6) & 0x1f, s->mac_mii_data);
+ lan9118_phy_write(&s->mii, (val >> 6) & 0x1f, s->mac_mii_data);
} else {
- s->mac_mii_data = do_phy_read(s, (val >> 6) & 0x1f);
+ s->mac_mii_data = lan9118_phy_read(&s->mii, (val >> 6) & 0x1f);
DPRINTF("PHY read %d = 0x%04x\n",
(val >> 6) & 0x1f, s->mac_mii_data);
}
@@ -1126,7 +1026,7 @@ static void lan9118_writel(void *opaque, hwaddr offset,
break;
case CSR_PMT_CTRL:
if (val & 0x400) {
- phy_reset(s);
+ lan9118_phy_reset(&s->mii);
}
s->pmt_ctrl &= ~0x34e;
s->pmt_ctrl |= (val & 0x34e);
@@ -1373,6 +1273,13 @@ static void lan9118_realize(DeviceState *dev, Error **errp)
const MemoryRegionOps *mem_ops =
s->mode_16bit ? &lan9118_16bit_mem_ops : &lan9118_mem_ops;
+ qemu_init_irq(&s->mii_irq, lan9118_update_irq, s, 0);
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
+ return;
+ }
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
+
memory_region_init_io(&s->mmio, OBJECT(dev), mem_ops, s,
"lan9118-mmio", 0x100);
sysbus_init_mmio(sbd, &s->mmio);
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
new file mode 100644
index 00000000000..b22c3c28556
--- /dev/null
+++ b/hw/net/lan9118_phy.c
@@ -0,0 +1,169 @@
+/*
+ * SMSC LAN9118 PHY emulation
+ *
+ * Copyright (c) 2009 CodeSourcery, LLC.
+ * Written by Paul Brook
+ *
+ * This code is licensed under the GNU GPL v2
+ *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ */
+
+#include "qemu/osdep.h"
+#include "hw/net/lan9118_phy.h"
+#include "hw/irq.h"
+#include "hw/resettable.h"
+#include "migration/vmstate.h"
+#include "qemu/log.h"
+
+#define PHY_INT_ENERGYON (1 << 7)
+#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
+#define PHY_INT_FAULT (1 << 5)
+#define PHY_INT_DOWN (1 << 4)
+#define PHY_INT_AUTONEG_LP (1 << 3)
+#define PHY_INT_PARFAULT (1 << 2)
+#define PHY_INT_AUTONEG_PAGE (1 << 1)
+
+static void lan9118_phy_update_irq(Lan9118PhyState *s)
+{
+ qemu_set_irq(s->irq, !!(s->ints & s->int_mask));
+}
+
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
+{
+ uint16_t val;
+
+ switch (reg) {
+ case 0: /* Basic Control */
+ return s->control;
+ case 1: /* Basic Status */
+ return s->status;
+ case 2: /* ID1 */
+ return 0x0007;
+ case 3: /* ID2 */
+ return 0xc0d1;
+ case 4: /* Auto-neg advertisement */
+ return s->advertise;
+ case 5: /* Auto-neg Link Partner Ability */
+ return 0x0f71;
+ case 6: /* Auto-neg Expansion */
+ return 1;
+ /* TODO 17, 18, 27, 29, 30, 31 */
+ case 29: /* Interrupt source. */
+ val = s->ints;
+ s->ints = 0;
+ lan9118_phy_update_irq(s);
+ return val;
+ case 30: /* Interrupt mask */
+ return s->int_mask;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "lan9118_phy_read: PHY read reg %d\n", reg);
+ return 0;
+ }
+}
+
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
+{
+ switch (reg) {
+ case 0: /* Basic Control */
+ if (val & 0x8000) {
+ lan9118_phy_reset(s);
+ break;
+ }
+ s->control = val & 0x7980;
+ /* Complete autonegotiation immediately. */
+ if (val & 0x1000) {
+ s->status |= 0x0020;
+ }
+ break;
+ case 4: /* Auto-neg advertisement */
+ s->advertise = (val & 0x2d7f) | 0x80;
+ break;
+ /* TODO 17, 18, 27, 31 */
+ case 30: /* Interrupt mask */
+ s->int_mask = val & 0xff;
+ lan9118_phy_update_irq(s);
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
+ }
+}
+
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
+{
+ s->link_down = link_down;
+
+ /* Autonegotiation status mirrors link status. */
+ if (link_down) {
+ s->status &= ~0x0024;
+ s->ints |= PHY_INT_DOWN;
+ } else {
+ s->status |= 0x0024;
+ s->ints |= PHY_INT_ENERGYON;
+ s->ints |= PHY_INT_AUTONEG_COMPLETE;
+ }
+ lan9118_phy_update_irq(s);
+}
+
+void lan9118_phy_reset(Lan9118PhyState *s)
+{
+ s->control = 0x3000;
+ s->status = 0x7809;
+ s->advertise = 0x01e1;
+ s->int_mask = 0;
+ s->ints = 0;
+ lan9118_phy_update_link(s, s->link_down);
+}
+
+static void lan9118_phy_reset_hold(Object *obj, ResetType type)
+{
+ Lan9118PhyState *s = LAN9118_PHY(obj);
+
+ lan9118_phy_reset(s);
+}
+
+static void lan9118_phy_init(Object *obj)
+{
+ Lan9118PhyState *s = LAN9118_PHY(obj);
+
+ qdev_init_gpio_out(DEVICE(s), &s->irq, 1);
+}
+
+static const VMStateDescription vmstate_lan9118_phy = {
+ .name = "lan9118-phy",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT16(control, Lan9118PhyState),
+ VMSTATE_UINT16(status, Lan9118PhyState),
+ VMSTATE_UINT16(advertise, Lan9118PhyState),
+ VMSTATE_UINT16(ints, Lan9118PhyState),
+ VMSTATE_UINT16(int_mask, Lan9118PhyState),
+ VMSTATE_BOOL(link_down, Lan9118PhyState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static void lan9118_phy_class_init(ObjectClass *klass, void *data)
+{
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ rc->phases.hold = lan9118_phy_reset_hold;
+ dc->vmsd = &vmstate_lan9118_phy;
+}
+
+static const TypeInfo types[] = {
+ {
+ .name = TYPE_LAN9118_PHY,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(Lan9118PhyState),
+ .instance_init = lan9118_phy_init,
+ .class_init = lan9118_phy_class_init,
+ }
+};
+
+DEFINE_TYPES(types)
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
index 7fcc0d7faa2..6b2ff2f937a 100644
--- a/hw/net/Kconfig
+++ b/hw/net/Kconfig
@@ -62,8 +62,12 @@ config VMXNET3_PCI
config SMC91C111
bool
+config LAN9118_PHY
+ bool
+
config LAN9118
bool
+ select LAN9118_PHY
select PTIMER
config NE2000_ISA
diff --git a/hw/net/meson.build b/hw/net/meson.build
index 00a9e9dd515..3bb5d749a83 100644
--- a/hw/net/meson.build
+++ b/hw/net/meson.build
@@ -19,6 +19,7 @@ system_ss.add(when: 'CONFIG_VMXNET3_PCI', if_true: files('vmxnet3.c'))
system_ss.add(when: 'CONFIG_SMC91C111', if_true: files('smc91c111.c'))
system_ss.add(when: 'CONFIG_LAN9118', if_true: files('lan9118.c'))
+system_ss.add(when: 'CONFIG_LAN9118_PHY', if_true: files('lan9118_phy.c'))
system_ss.add(when: 'CONFIG_NE2000_ISA', if_true: files('ne2000-isa.c'))
system_ss.add(when: 'CONFIG_OPENCORES_ETH', if_true: files('opencores_eth.c'))
system_ss.add(when: 'CONFIG_XGMAC', if_true: files('xgmac.c'))
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 02/72] hw/net/lan9118_phy: Reuse in imx_fec and consolidate implementations
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
2024-12-11 16:18 ` [PULL 01/72] hw/net/lan9118: Extract lan9118_phy Peter Maydell
@ 2024-12-11 16:18 ` Peter Maydell
2024-12-11 16:18 ` [PULL 03/72] hw/net/lan9118_phy: Fix off-by-one error in MII_ANLPAR register Peter Maydell
` (70 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:18 UTC (permalink / raw)
To: qemu-devel
From: Bernhard Beschow <shentey@gmail.com>
imx_fec models the same PHY as lan9118_phy. The code is almost the same with
imx_fec having more logging and tracing. Merge these improvements into
lan9118_phy and reuse in imx_fec to fix the code duplication.
Some migration state how resides in the new device model which breaks migration
compatibility for the following machines:
* imx25-pdk
* sabrelite
* mcimx7d-sabre
* mcimx6ul-evk
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20241102125724.532843-3-shentey@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
include/hw/net/imx_fec.h | 9 ++-
hw/net/imx_fec.c | 146 ++++-----------------------------------
hw/net/lan9118_phy.c | 82 ++++++++++++++++------
hw/net/Kconfig | 1 +
hw/net/trace-events | 10 +--
5 files changed, 85 insertions(+), 163 deletions(-)
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
index 2d13290c787..83b21637eeb 100644
--- a/include/hw/net/imx_fec.h
+++ b/include/hw/net/imx_fec.h
@@ -31,6 +31,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(IMXFECState, IMX_FEC)
#define TYPE_IMX_ENET "imx.enet"
#include "hw/sysbus.h"
+#include "hw/net/lan9118_phy.h"
+#include "hw/irq.h"
#include "net/net.h"
#define ENET_EIR 1
@@ -264,11 +266,8 @@ struct IMXFECState {
uint32_t tx_descriptor[ENET_TX_RING_NUM];
uint32_t tx_ring_num;
- uint32_t phy_status;
- uint32_t phy_control;
- uint32_t phy_advertise;
- uint32_t phy_int;
- uint32_t phy_int_mask;
+ Lan9118PhyState mii;
+ IRQState mii_irq;
uint32_t phy_num;
bool phy_connected;
struct IMXFECState *phy_consumer;
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 6294d292023..4ee6f742063 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -203,17 +203,12 @@ static const VMStateDescription vmstate_imx_eth_txdescs = {
static const VMStateDescription vmstate_imx_eth = {
.name = TYPE_IMX_FEC,
- .version_id = 2,
- .minimum_version_id = 2,
+ .version_id = 3,
+ .minimum_version_id = 3,
.fields = (const VMStateField[]) {
VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
VMSTATE_UINT32(rx_descriptor, IMXFECState),
VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
- VMSTATE_UINT32(phy_status, IMXFECState),
- VMSTATE_UINT32(phy_control, IMXFECState),
- VMSTATE_UINT32(phy_advertise, IMXFECState),
- VMSTATE_UINT32(phy_int, IMXFECState),
- VMSTATE_UINT32(phy_int_mask, IMXFECState),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription * const []) {
@@ -222,14 +217,6 @@ static const VMStateDescription vmstate_imx_eth = {
},
};
-#define PHY_INT_ENERGYON (1 << 7)
-#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
-#define PHY_INT_FAULT (1 << 5)
-#define PHY_INT_DOWN (1 << 4)
-#define PHY_INT_AUTONEG_LP (1 << 3)
-#define PHY_INT_PARFAULT (1 << 2)
-#define PHY_INT_AUTONEG_PAGE (1 << 1)
-
static void imx_eth_update(IMXFECState *s);
/*
@@ -238,47 +225,19 @@ static void imx_eth_update(IMXFECState *s);
* For now we don't handle any GPIO/interrupt line, so the OS will
* have to poll for the PHY status.
*/
-static void imx_phy_update_irq(IMXFECState *s)
+static void imx_phy_update_irq(void *opaque, int n, int level)
{
- imx_eth_update(s);
-}
-
-static void imx_phy_update_link(IMXFECState *s)
-{
- /* Autonegotiation status mirrors link status. */
- if (qemu_get_queue(s->nic)->link_down) {
- trace_imx_phy_update_link("down");
- s->phy_status &= ~0x0024;
- s->phy_int |= PHY_INT_DOWN;
- } else {
- trace_imx_phy_update_link("up");
- s->phy_status |= 0x0024;
- s->phy_int |= PHY_INT_ENERGYON;
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
- }
- imx_phy_update_irq(s);
+ imx_eth_update(opaque);
}
static void imx_eth_set_link(NetClientState *nc)
{
- imx_phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
-}
-
-static void imx_phy_reset(IMXFECState *s)
-{
- trace_imx_phy_reset();
-
- s->phy_status = 0x7809;
- s->phy_control = 0x3000;
- s->phy_advertise = 0x01e1;
- s->phy_int_mask = 0;
- s->phy_int = 0;
- imx_phy_update_link(s);
+ lan9118_phy_update_link(&IMX_FEC(qemu_get_nic_opaque(nc))->mii,
+ nc->link_down);
}
static uint32_t imx_phy_read(IMXFECState *s, int reg)
{
- uint32_t val;
uint32_t phy = reg / 32;
if (!s->phy_connected) {
@@ -296,54 +255,7 @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
reg %= 32;
- switch (reg) {
- case 0: /* Basic Control */
- val = s->phy_control;
- break;
- case 1: /* Basic Status */
- val = s->phy_status;
- break;
- case 2: /* ID1 */
- val = 0x0007;
- break;
- case 3: /* ID2 */
- val = 0xc0d1;
- break;
- case 4: /* Auto-neg advertisement */
- val = s->phy_advertise;
- break;
- case 5: /* Auto-neg Link Partner Ability */
- val = 0x0f71;
- break;
- case 6: /* Auto-neg Expansion */
- val = 1;
- break;
- case 29: /* Interrupt source. */
- val = s->phy_int;
- s->phy_int = 0;
- imx_phy_update_irq(s);
- break;
- case 30: /* Interrupt mask */
- val = s->phy_int_mask;
- break;
- case 17:
- case 18:
- case 27:
- case 31:
- qemu_log_mask(LOG_UNIMP, "[%s.phy]%s: reg %d not implemented\n",
- TYPE_IMX_FEC, __func__, reg);
- val = 0;
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
- TYPE_IMX_FEC, __func__, reg);
- val = 0;
- break;
- }
-
- trace_imx_phy_read(val, phy, reg);
-
- return val;
+ return lan9118_phy_read(&s->mii, reg);
}
static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
@@ -365,39 +277,7 @@ static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
reg %= 32;
- trace_imx_phy_write(val, phy, reg);
-
- switch (reg) {
- case 0: /* Basic Control */
- if (val & 0x8000) {
- imx_phy_reset(s);
- } else {
- s->phy_control = val & 0x7980;
- /* Complete autonegotiation immediately. */
- if (val & 0x1000) {
- s->phy_status |= 0x0020;
- }
- }
- break;
- case 4: /* Auto-neg advertisement */
- s->phy_advertise = (val & 0x2d7f) | 0x80;
- break;
- case 30: /* Interrupt mask */
- s->phy_int_mask = val & 0xff;
- imx_phy_update_irq(s);
- break;
- case 17:
- case 18:
- case 27:
- case 31:
- qemu_log_mask(LOG_UNIMP, "[%s.phy)%s: reg %d not implemented\n",
- TYPE_IMX_FEC, __func__, reg);
- break;
- default:
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
- TYPE_IMX_FEC, __func__, reg);
- break;
- }
+ lan9118_phy_write(&s->mii, reg, val);
}
static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr)
@@ -682,9 +562,6 @@ static void imx_eth_reset(DeviceState *d)
s->rx_descriptor = 0;
memset(s->tx_descriptor, 0, sizeof(s->tx_descriptor));
-
- /* We also reset the PHY */
- imx_phy_reset(s);
}
static uint32_t imx_default_read(IMXFECState *s, uint32_t index)
@@ -1329,6 +1206,13 @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
sysbus_init_irq(sbd, &s->irq[0]);
sysbus_init_irq(sbd, &s->irq[1]);
+ qemu_init_irq(&s->mii_irq, imx_phy_update_irq, s, 0);
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
+ return;
+ }
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
+
qemu_macaddr_default_if_unset(&s->conf.macaddr);
s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
index b22c3c28556..d2dcd732ac1 100644
--- a/hw/net/lan9118_phy.c
+++ b/hw/net/lan9118_phy.c
@@ -4,6 +4,8 @@
* Copyright (c) 2009 CodeSourcery, LLC.
* Written by Paul Brook
*
+ * Copyright (c) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
+ *
* This code is licensed under the GNU GPL v2
*
* Contributions after 2012-01-13 are licensed under the terms of the
@@ -16,6 +18,7 @@
#include "hw/resettable.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
+#include "trace.h"
#define PHY_INT_ENERGYON (1 << 7)
#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
@@ -36,59 +39,88 @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
switch (reg) {
case 0: /* Basic Control */
- return s->control;
+ val = s->control;
+ break;
case 1: /* Basic Status */
- return s->status;
+ val = s->status;
+ break;
case 2: /* ID1 */
- return 0x0007;
+ val = 0x0007;
+ break;
case 3: /* ID2 */
- return 0xc0d1;
+ val = 0xc0d1;
+ break;
case 4: /* Auto-neg advertisement */
- return s->advertise;
+ val = s->advertise;
+ break;
case 5: /* Auto-neg Link Partner Ability */
- return 0x0f71;
+ val = 0x0f71;
+ break;
case 6: /* Auto-neg Expansion */
- return 1;
- /* TODO 17, 18, 27, 29, 30, 31 */
+ val = 1;
+ break;
case 29: /* Interrupt source. */
val = s->ints;
s->ints = 0;
lan9118_phy_update_irq(s);
- return val;
+ break;
case 30: /* Interrupt mask */
- return s->int_mask;
+ val = s->int_mask;
+ break;
+ case 17:
+ case 18:
+ case 27:
+ case 31:
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
+ __func__, reg);
+ val = 0;
+ break;
default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "lan9118_phy_read: PHY read reg %d\n", reg);
- return 0;
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
+ __func__, reg);
+ val = 0;
+ break;
}
+
+ trace_lan9118_phy_read(val, reg);
+
+ return val;
}
void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
{
+ trace_lan9118_phy_write(val, reg);
+
switch (reg) {
case 0: /* Basic Control */
if (val & 0x8000) {
lan9118_phy_reset(s);
- break;
- }
- s->control = val & 0x7980;
- /* Complete autonegotiation immediately. */
- if (val & 0x1000) {
- s->status |= 0x0020;
+ } else {
+ s->control = val & 0x7980;
+ /* Complete autonegotiation immediately. */
+ if (val & 0x1000) {
+ s->status |= 0x0020;
+ }
}
break;
case 4: /* Auto-neg advertisement */
s->advertise = (val & 0x2d7f) | 0x80;
break;
- /* TODO 17, 18, 27, 31 */
case 30: /* Interrupt mask */
s->int_mask = val & 0xff;
lan9118_phy_update_irq(s);
break;
+ case 17:
+ case 18:
+ case 27:
+ case 31:
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
+ __func__, reg);
+ break;
default:
- qemu_log_mask(LOG_GUEST_ERROR,
- "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
+ __func__, reg);
+ break;
}
}
@@ -98,9 +130,11 @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
/* Autonegotiation status mirrors link status. */
if (link_down) {
+ trace_lan9118_phy_update_link("down");
s->status &= ~0x0024;
s->ints |= PHY_INT_DOWN;
} else {
+ trace_lan9118_phy_update_link("up");
s->status |= 0x0024;
s->ints |= PHY_INT_ENERGYON;
s->ints |= PHY_INT_AUTONEG_COMPLETE;
@@ -110,6 +144,8 @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
void lan9118_phy_reset(Lan9118PhyState *s)
{
+ trace_lan9118_phy_reset();
+
s->control = 0x3000;
s->status = 0x7809;
s->advertise = 0x01e1;
@@ -137,8 +173,8 @@ static const VMStateDescription vmstate_lan9118_phy = {
.version_id = 1,
.minimum_version_id = 1,
.fields = (const VMStateField[]) {
- VMSTATE_UINT16(control, Lan9118PhyState),
VMSTATE_UINT16(status, Lan9118PhyState),
+ VMSTATE_UINT16(control, Lan9118PhyState),
VMSTATE_UINT16(advertise, Lan9118PhyState),
VMSTATE_UINT16(ints, Lan9118PhyState),
VMSTATE_UINT16(int_mask, Lan9118PhyState),
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
index 6b2ff2f937a..7f80218d10f 100644
--- a/hw/net/Kconfig
+++ b/hw/net/Kconfig
@@ -93,6 +93,7 @@ config ALLWINNER_SUN8I_EMAC
config IMX_FEC
bool
+ select LAN9118_PHY
config CADENCE
bool
diff --git a/hw/net/trace-events b/hw/net/trace-events
index d0f1d8c0fbe..6100ec324a7 100644
--- a/hw/net/trace-events
+++ b/hw/net/trace-events
@@ -10,6 +10,12 @@ allwinner_sun8i_emac_set_link(bool active) "Set link: active=%u"
allwinner_sun8i_emac_read(uint64_t offset, uint64_t val) "MMIO read: offset=0x%" PRIx64 " value=0x%" PRIx64
allwinner_sun8i_emac_write(uint64_t offset, uint64_t val) "MMIO write: offset=0x%" PRIx64 " value=0x%" PRIx64
+# lan9118_phy.c
+lan9118_phy_read(uint16_t val, int reg) "[0x%02x] -> 0x%04" PRIx16
+lan9118_phy_write(uint16_t val, int reg) "[0x%02x] <- 0x%04" PRIx16
+lan9118_phy_update_link(const char *s) "%s"
+lan9118_phy_reset(void) ""
+
# lance.c
lance_mem_readw(uint64_t addr, uint32_t ret) "addr=0x%"PRIx64"val=0x%04x"
lance_mem_writew(uint64_t addr, uint32_t val) "addr=0x%"PRIx64"val=0x%04x"
@@ -428,12 +434,8 @@ i82596_set_multicast(uint16_t count) "Added %d multicast entries"
i82596_channel_attention(void *s) "%p: Received CHANNEL ATTENTION"
# imx_fec.c
-imx_phy_read(uint32_t val, int phy, int reg) "0x%04"PRIx32" <= phy[%d].reg[%d]"
imx_phy_read_num(int phy, int configured) "read request from unconfigured phy %d (configured %d)"
-imx_phy_write(uint32_t val, int phy, int reg) "0x%04"PRIx32" => phy[%d].reg[%d]"
imx_phy_write_num(int phy, int configured) "write request to unconfigured phy %d (configured %d)"
-imx_phy_update_link(const char *s) "%s"
-imx_phy_reset(void) ""
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"
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"
imx_eth_tx_bd_busy(void) "tx_bd ran out of descriptors to transmit"
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 03/72] hw/net/lan9118_phy: Fix off-by-one error in MII_ANLPAR register
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
2024-12-11 16:18 ` [PULL 01/72] hw/net/lan9118: Extract lan9118_phy Peter Maydell
2024-12-11 16:18 ` [PULL 02/72] hw/net/lan9118_phy: Reuse in imx_fec and consolidate implementations Peter Maydell
@ 2024-12-11 16:18 ` Peter Maydell
2024-12-11 16:18 ` [PULL 04/72] hw/net/lan9118_phy: Reuse MII constants Peter Maydell
` (69 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:18 UTC (permalink / raw)
To: qemu-devel
From: Bernhard Beschow <shentey@gmail.com>
Turns 0x70 into 0xe0 (== 0x70 << 1) which adds the missing MII_ANLPAR_TX and
fixes the MSB of selector field to be zero, as specified in the datasheet.
Fixes: 2a424990170b "LAN9118 emulation"
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20241102125724.532843-4-shentey@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/net/lan9118_phy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
index d2dcd732ac1..d8fc9ddd3ac 100644
--- a/hw/net/lan9118_phy.c
+++ b/hw/net/lan9118_phy.c
@@ -54,7 +54,7 @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
val = s->advertise;
break;
case 5: /* Auto-neg Link Partner Ability */
- val = 0x0f71;
+ val = 0x0fe1;
break;
case 6: /* Auto-neg Expansion */
val = 1;
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 04/72] hw/net/lan9118_phy: Reuse MII constants
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (2 preceding siblings ...)
2024-12-11 16:18 ` [PULL 03/72] hw/net/lan9118_phy: Fix off-by-one error in MII_ANLPAR register Peter Maydell
@ 2024-12-11 16:18 ` Peter Maydell
2024-12-11 16:18 ` [PULL 05/72] hw/net/lan9118_phy: Add missing 100 mbps full duplex advertisement Peter Maydell
` (68 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:18 UTC (permalink / raw)
To: qemu-devel
From: Bernhard Beschow <shentey@gmail.com>
Prefer named constants over magic values for better readability.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Message-id: 20241102125724.532843-5-shentey@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
include/hw/net/mii.h | 6 +++++
hw/net/lan9118_phy.c | 63 ++++++++++++++++++++++++++++----------------
2 files changed, 46 insertions(+), 23 deletions(-)
diff --git a/include/hw/net/mii.h b/include/hw/net/mii.h
index f7feddac9bd..55bf7c92a1c 100644
--- a/include/hw/net/mii.h
+++ b/include/hw/net/mii.h
@@ -71,6 +71,7 @@
#define MII_BMSR_JABBER (1 << 1) /* Jabber detected */
#define MII_BMSR_EXTCAP (1 << 0) /* Ext-reg capability */
+#define MII_ANAR_RFAULT (1 << 13) /* Say we can detect faults */
#define MII_ANAR_PAUSE_ASYM (1 << 11) /* Try for asymmetric pause */
#define MII_ANAR_PAUSE (1 << 10) /* Try for pause */
#define MII_ANAR_TXFD (1 << 8)
@@ -78,6 +79,7 @@
#define MII_ANAR_10FD (1 << 6)
#define MII_ANAR_10 (1 << 5)
#define MII_ANAR_CSMACD (1 << 0)
+#define MII_ANAR_SELECT (0x001f) /* Selector bits */
#define MII_ANLPAR_ACK (1 << 14)
#define MII_ANLPAR_PAUSEASY (1 << 11) /* can pause asymmetrically */
@@ -112,6 +114,10 @@
#define RTL8201CP_PHYID1 0x0000
#define RTL8201CP_PHYID2 0x8201
+/* SMSC LAN9118 */
+#define SMSCLAN9118_PHYID1 0x0007
+#define SMSCLAN9118_PHYID2 0xc0d1
+
/* RealTek 8211E */
#define RTL8211E_PHYID1 0x001c
#define RTL8211E_PHYID2 0xc915
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
index d8fc9ddd3ac..874dae4155a 100644
--- a/hw/net/lan9118_phy.c
+++ b/hw/net/lan9118_phy.c
@@ -14,6 +14,7 @@
#include "qemu/osdep.h"
#include "hw/net/lan9118_phy.h"
+#include "hw/net/mii.h"
#include "hw/irq.h"
#include "hw/resettable.h"
#include "migration/vmstate.h"
@@ -38,26 +39,28 @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
uint16_t val;
switch (reg) {
- case 0: /* Basic Control */
+ case MII_BMCR:
val = s->control;
break;
- case 1: /* Basic Status */
+ case MII_BMSR:
val = s->status;
break;
- case 2: /* ID1 */
- val = 0x0007;
+ case MII_PHYID1:
+ val = SMSCLAN9118_PHYID1;
break;
- case 3: /* ID2 */
- val = 0xc0d1;
+ case MII_PHYID2:
+ val = SMSCLAN9118_PHYID2;
break;
- case 4: /* Auto-neg advertisement */
+ case MII_ANAR:
val = s->advertise;
break;
- case 5: /* Auto-neg Link Partner Ability */
- val = 0x0fe1;
+ case MII_ANLPAR:
+ val = MII_ANLPAR_PAUSEASY | MII_ANLPAR_PAUSE | MII_ANLPAR_T4 |
+ MII_ANLPAR_TXFD | MII_ANLPAR_TX | MII_ANLPAR_10FD |
+ MII_ANLPAR_10 | MII_ANLPAR_CSMACD;
break;
- case 6: /* Auto-neg Expansion */
- val = 1;
+ case MII_ANER:
+ val = MII_ANER_NWAY;
break;
case 29: /* Interrupt source. */
val = s->ints;
@@ -92,19 +95,24 @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
trace_lan9118_phy_write(val, reg);
switch (reg) {
- case 0: /* Basic Control */
- if (val & 0x8000) {
+ case MII_BMCR:
+ if (val & MII_BMCR_RESET) {
lan9118_phy_reset(s);
} else {
- s->control = val & 0x7980;
+ s->control = val & (MII_BMCR_LOOPBACK | MII_BMCR_SPEED100 |
+ MII_BMCR_AUTOEN | MII_BMCR_PDOWN | MII_BMCR_FD |
+ MII_BMCR_CTST);
/* Complete autonegotiation immediately. */
- if (val & 0x1000) {
- s->status |= 0x0020;
+ if (val & MII_BMCR_AUTOEN) {
+ s->status |= MII_BMSR_AN_COMP;
}
}
break;
- case 4: /* Auto-neg advertisement */
- s->advertise = (val & 0x2d7f) | 0x80;
+ case MII_ANAR:
+ s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
+ MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
+ MII_ANAR_SELECT))
+ | MII_ANAR_TX;
break;
case 30: /* Interrupt mask */
s->int_mask = val & 0xff;
@@ -131,11 +139,11 @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
/* Autonegotiation status mirrors link status. */
if (link_down) {
trace_lan9118_phy_update_link("down");
- s->status &= ~0x0024;
+ s->status &= ~(MII_BMSR_AN_COMP | MII_BMSR_LINK_ST);
s->ints |= PHY_INT_DOWN;
} else {
trace_lan9118_phy_update_link("up");
- s->status |= 0x0024;
+ s->status |= MII_BMSR_AN_COMP | MII_BMSR_LINK_ST;
s->ints |= PHY_INT_ENERGYON;
s->ints |= PHY_INT_AUTONEG_COMPLETE;
}
@@ -146,9 +154,18 @@ void lan9118_phy_reset(Lan9118PhyState *s)
{
trace_lan9118_phy_reset();
- s->control = 0x3000;
- s->status = 0x7809;
- s->advertise = 0x01e1;
+ s->control = MII_BMCR_AUTOEN | MII_BMCR_SPEED100;
+ s->status = MII_BMSR_100TX_FD
+ | MII_BMSR_100TX_HD
+ | MII_BMSR_10T_FD
+ | MII_BMSR_10T_HD
+ | MII_BMSR_AUTONEG
+ | MII_BMSR_EXTCAP;
+ s->advertise = MII_ANAR_TXFD
+ | MII_ANAR_TX
+ | MII_ANAR_10FD
+ | MII_ANAR_10
+ | MII_ANAR_CSMACD;
s->int_mask = 0;
s->ints = 0;
lan9118_phy_update_link(s, s->link_down);
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 05/72] hw/net/lan9118_phy: Add missing 100 mbps full duplex advertisement
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (3 preceding siblings ...)
2024-12-11 16:18 ` [PULL 04/72] hw/net/lan9118_phy: Reuse MII constants Peter Maydell
@ 2024-12-11 16:18 ` Peter Maydell
2024-12-11 16:18 ` [PULL 06/72] fpu: handle raising Invalid for infzero in pick_nan_muladd Peter Maydell
` (67 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:18 UTC (permalink / raw)
To: qemu-devel
From: Bernhard Beschow <shentey@gmail.com>
The real device advertises this mode and the device model already advertises
100 mbps half duplex and 10 mbps full+half duplex. So advertise this mode to
make the model more realistic.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Message-id: 20241102125724.532843-6-shentey@gmail.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/net/lan9118_phy.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
index 874dae4155a..5c53a4a1e3f 100644
--- a/hw/net/lan9118_phy.c
+++ b/hw/net/lan9118_phy.c
@@ -110,8 +110,8 @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
break;
case MII_ANAR:
s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
- MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
- MII_ANAR_SELECT))
+ MII_ANAR_PAUSE | MII_ANAR_TXFD | MII_ANAR_10FD |
+ MII_ANAR_10 | MII_ANAR_SELECT))
| MII_ANAR_TX;
break;
case 30: /* Interrupt mask */
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 06/72] fpu: handle raising Invalid for infzero in pick_nan_muladd
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (4 preceding siblings ...)
2024-12-11 16:18 ` [PULL 05/72] hw/net/lan9118_phy: Add missing 100 mbps full duplex advertisement Peter Maydell
@ 2024-12-11 16:18 ` Peter Maydell
2024-12-11 16:18 ` [PULL 07/72] fpu: Check for default_nan_mode before calling pickNaNMulAdd Peter Maydell
` (66 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:18 UTC (permalink / raw)
To: qemu-devel
For IEEE fused multiply-add, the (0 * inf) + NaN case should raise
Invalid for the multiplication of 0 by infinity. Currently we handle
this in the per-architecture ifdef ladder in pickNaNMulAdd().
However, since this isn't really architecture specific we can hoist
it up to the generic code.
For the cases where the infzero test in pickNaNMulAdd was
returning 2, we can delete the check entirely and allow the
code to fall into the normal pick-a-NaN handling, because this
will return 2 anyway (input 'c' being the only NaN in this case).
For the cases where infzero was returning 3 to indicate "return
the default NaN", we must retain that "return 3".
For Arm, this looks like it might be a behaviour change because we
used to set float_flag_invalid | float_flag_invalid_imz only if C is
a quiet NaN. However, it is not, because Arm target code never looks
at float_flag_invalid_imz, and for the (0 * inf) + SNaN case we
already raised float_flag_invalid via the "abc_mask &
float_cmask_snan" check in pick_nan_muladd.
For any target architecture using the "default implementation" at the
bottom of the ifdef, this is a behaviour change but will be fixing a
bug (where we failed to raise the Invalid exception for (0 * inf +
QNaN). The architectures using the default case are:
* hppa
* i386
* sh4
* tricore
The x86, Tricore and SH4 CPU architecture manuals are clear that this
should have raised Invalid; HPPA is a bit vaguer but still seems
clear enough.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-2-peter.maydell@linaro.org
---
fpu/softfloat-parts.c.inc | 13 +++++++------
fpu/softfloat-specialize.c.inc | 29 +----------------------------
2 files changed, 8 insertions(+), 34 deletions(-)
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index cc6e06b9761..d63cd957a19 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -66,19 +66,20 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
int ab_mask, int abc_mask)
{
int which;
+ bool infzero = (ab_mask == float_cmask_infzero);
if (unlikely(abc_mask & float_cmask_snan)) {
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
}
- which = pickNaNMulAdd(a->cls, b->cls, c->cls,
- ab_mask == float_cmask_infzero, s);
+ if (infzero) {
+ /* This is (0 * inf) + NaN or (inf * 0) + NaN */
+ float_raise(float_flag_invalid | float_flag_invalid_imz, s);
+ }
+
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
if (s->default_nan_mode || which == 3) {
- /*
- * Note that this check is after pickNaNMulAdd so that function
- * has an opportunity to set the Invalid flag for infzero.
- */
parts_default_nan(a, s);
return a;
}
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 9bca03c4aed..c557c41b2af 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -480,7 +480,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
* the default NaN
*/
if (infzero && is_qnan(c_cls)) {
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
return 3;
}
@@ -507,7 +506,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
* case sets InvalidOp and returns the default NaN
*/
if (infzero) {
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
return 3;
}
/* Prefer sNaN over qNaN, in the a, b, c order. */
@@ -529,10 +527,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
* For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
* case sets InvalidOp and returns the input value 'c'
*/
- if (infzero) {
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
- return 2;
- }
/* Prefer sNaN over qNaN, in the c, a, b order. */
if (is_snan(c_cls)) {
return 2;
@@ -553,10 +547,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
* case sets InvalidOp and returns the input value 'c'
*/
- if (infzero) {
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
- return 2;
- }
+
/* Prefer sNaN over qNaN, in the c, a, b order. */
if (is_snan(c_cls)) {
return 2;
@@ -576,10 +567,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
* to return an input NaN if we have one (ie c) rather than generating
* a default NaN
*/
- if (infzero) {
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
- return 2;
- }
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
@@ -592,14 +579,9 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
return 1;
}
#elif defined(TARGET_RISCV)
- /* For RISC-V, InvalidOp is set when multiplicands are Inf and zero */
- if (infzero) {
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
- }
return 3; /* default NaN */
#elif defined(TARGET_S390X)
if (infzero) {
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
return 3;
}
@@ -617,11 +599,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
return 2;
}
#elif defined(TARGET_SPARC)
- /* For (inf,0,nan) return c. */
- if (infzero) {
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
- return 2;
- }
/* Prefer SNaN over QNaN, order C, B, A. */
if (is_snan(c_cls)) {
return 2;
@@ -641,10 +618,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
* For Xtensa, the (inf,zero,nan) case sets InvalidOp and returns
* an input NaN if we have one (ie c).
*/
- if (infzero) {
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
- return 2;
- }
if (status->use_first_nan) {
if (is_nan(a_cls)) {
return 0;
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 07/72] fpu: Check for default_nan_mode before calling pickNaNMulAdd
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (5 preceding siblings ...)
2024-12-11 16:18 ` [PULL 06/72] fpu: handle raising Invalid for infzero in pick_nan_muladd Peter Maydell
@ 2024-12-11 16:18 ` Peter Maydell
2024-12-11 16:19 ` [PULL 08/72] softfloat: Allow runtime choice of inf * 0 + NaN result Peter Maydell
` (65 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:18 UTC (permalink / raw)
To: qemu-devel
If the target sets default_nan_mode then we're always going to return
the default NaN, and pickNaNMulAdd() no longer has any side effects.
For consistency with pickNaN(), check for default_nan_mode before
calling pickNaNMulAdd().
When we convert pickNaNMulAdd() to allow runtime selection of the NaN
propagation rule, this means we won't have to make the targets which
use default_nan_mode also set a propagation rule.
Since RiscV always uses default_nan_mode, this allows us to remove
its ifdef case from pickNaNMulAdd().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-3-peter.maydell@linaro.org
---
fpu/softfloat-parts.c.inc | 8 ++++++--
fpu/softfloat-specialize.c.inc | 9 +++++++--
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index d63cd957a19..aac1f9cd28c 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -77,9 +77,13 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
float_raise(float_flag_invalid | float_flag_invalid_imz, s);
}
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
+ if (s->default_nan_mode) {
+ which = 3;
+ } else {
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
+ }
- if (s->default_nan_mode || which == 3) {
+ if (which == 3) {
parts_default_nan(a, s);
return a;
}
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index c557c41b2af..81a67eb67b5 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -475,6 +475,13 @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
bool infzero, float_status *status)
{
+ /*
+ * We guarantee not to require the target to tell us how to
+ * pick a NaN if we're always returning the default NaN.
+ * But if we're not in default-NaN mode then the target must
+ * specify.
+ */
+ assert(!status->default_nan_mode);
#if defined(TARGET_ARM)
/* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
* the default NaN
@@ -578,8 +585,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
} else {
return 1;
}
-#elif defined(TARGET_RISCV)
- return 3; /* default NaN */
#elif defined(TARGET_S390X)
if (infzero) {
return 3;
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 08/72] softfloat: Allow runtime choice of inf * 0 + NaN result
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (6 preceding siblings ...)
2024-12-11 16:18 ` [PULL 07/72] fpu: Check for default_nan_mode before calling pickNaNMulAdd Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 09/72] tests/fp: Explicitly set inf-zero-nan rule Peter Maydell
` (64 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
IEEE 758 does not define a fixed rule for what NaN to return in
the case of a fused multiply-add of inf * 0 + NaN. Different
architectures thus do different things:
* some return the default NaN
* some return the input NaN
* Arm returns the default NaN if the input NaN is quiet,
and the input NaN if it is signalling
We want to make this logic be runtime selected rather than
hardcoded into the binary, because:
* this will let us have multiple targets in one QEMU binary
* the Arm FEAT_AFP architectural feature includes letting
the guest select a NaN propagation rule at runtime
In this commit we add an enum for the propagation rule, the field in
float_status, and the corresponding getters and setters. We change
pickNaNMulAdd to honour this, but because all targets still leave
this field at its default 0 value, the fallback logic will pick the
rule type with the old ifdef ladder.
Note that four architectures both use the muladd softfloat functions
and did not have a branch of the ifdef ladder to specify their
behaviour (and so were ending up with the "default" case, probably
wrongly): i386, HPPA, SH4 and Tricore. SH4 and Tricore both set
default_nan_mode, and so will never get into pickNaNMulAdd(). For
HPPA and i386 we retain the same behaviour as the old default-case,
which is to not ever return the default NaN. This might not be
correct but it is not a behaviour change.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-4-peter.maydell@linaro.org
---
include/fpu/softfloat-helpers.h | 11 ++++
include/fpu/softfloat-types.h | 23 +++++++++
fpu/softfloat-specialize.c.inc | 91 ++++++++++++++++++++++-----------
3 files changed, 95 insertions(+), 30 deletions(-)
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
index 453188de70b..0bf44dc6087 100644
--- a/include/fpu/softfloat-helpers.h
+++ b/include/fpu/softfloat-helpers.h
@@ -81,6 +81,12 @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
status->float_2nan_prop_rule = rule;
}
+static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
+ float_status *status)
+{
+ status->float_infzeronan_rule = rule;
+}
+
static inline void set_flush_to_zero(bool val, float_status *status)
{
status->flush_to_zero = val;
@@ -137,6 +143,11 @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
return status->float_2nan_prop_rule;
}
+static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
+{
+ return status->float_infzeronan_rule;
+}
+
static inline bool get_flush_to_zero(float_status *status)
{
return status->flush_to_zero;
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 8f39691dfd0..47bb22c4e25 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -207,6 +207,28 @@ typedef enum __attribute__((__packed__)) {
float_2nan_prop_x87,
} Float2NaNPropRule;
+/*
+ * Rule for result of fused multiply-add 0 * Inf + NaN.
+ * This must be a NaN, but implementations differ on whether this
+ * is the input NaN or the default NaN.
+ *
+ * You don't need to set this if default_nan_mode is enabled.
+ * When not in default-NaN mode, it is an error for the target
+ * not to set the rule in float_status if it uses muladd, and we
+ * will assert if we need to handle an input NaN and no rule was
+ * selected.
+ */
+typedef enum __attribute__((__packed__)) {
+ /* No propagation rule specified */
+ float_infzeronan_none = 0,
+ /* Result is never the default NaN (so always the input NaN) */
+ float_infzeronan_dnan_never,
+ /* Result is always the default NaN */
+ float_infzeronan_dnan_always,
+ /* Result is the default NaN if the input NaN is quiet */
+ float_infzeronan_dnan_if_qnan,
+} FloatInfZeroNaNRule;
+
/*
* Floating Point Status. Individual architectures may maintain
* several versions of float_status for different functions. The
@@ -219,6 +241,7 @@ typedef struct float_status {
FloatRoundMode float_rounding_mode;
FloatX80RoundPrec floatx80_rounding_precision;
Float2NaNPropRule float_2nan_prop_rule;
+ FloatInfZeroNaNRule float_infzeronan_rule;
bool tininess_before_rounding;
/* should denormalised results go to zero and set the inexact flag? */
bool flush_to_zero;
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 81a67eb67b5..f5b422e07b5 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -475,6 +475,8 @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
bool infzero, float_status *status)
{
+ FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
+
/*
* We guarantee not to require the target to tell us how to
* pick a NaN if we're always returning the default NaN.
@@ -482,14 +484,68 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
* specify.
*/
assert(!status->default_nan_mode);
+
+ if (rule == float_infzeronan_none) {
+ /*
+ * Temporarily fall back to ifdef ladder
+ */
#if defined(TARGET_ARM)
- /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
- * the default NaN
- */
- if (infzero && is_qnan(c_cls)) {
- return 3;
+ /*
+ * For ARM, the (inf,zero,qnan) case returns the default NaN,
+ * but (inf,zero,snan) returns the input NaN.
+ */
+ rule = float_infzeronan_dnan_if_qnan;
+#elif defined(TARGET_MIPS)
+ if (snan_bit_is_one(status)) {
+ /*
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
+ * case sets InvalidOp and returns the default NaN
+ */
+ rule = float_infzeronan_dnan_always;
+ } else {
+ /*
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
+ * case sets InvalidOp and returns the input value 'c'
+ */
+ rule = float_infzeronan_dnan_never;
+ }
+#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
+ defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
+ defined(TARGET_I386) || defined(TARGET_LOONGARCH)
+ /*
+ * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
+ * case sets InvalidOp and returns the input value 'c'
+ */
+ /*
+ * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
+ * to return an input NaN if we have one (ie c) rather than generating
+ * a default NaN
+ */
+ rule = float_infzeronan_dnan_never;
+#elif defined(TARGET_S390X)
+ rule = float_infzeronan_dnan_always;
+#endif
}
+ if (infzero) {
+ /*
+ * Inf * 0 + NaN -- some implementations return the default NaN here,
+ * and some return the input NaN.
+ */
+ switch (rule) {
+ case float_infzeronan_dnan_never:
+ return 2;
+ case float_infzeronan_dnan_always:
+ return 3;
+ case float_infzeronan_dnan_if_qnan:
+ return is_qnan(c_cls) ? 3 : 2;
+ default:
+ g_assert_not_reached();
+ }
+ }
+
+#if defined(TARGET_ARM)
+
/* This looks different from the ARM ARM pseudocode, because the ARM ARM
* puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
*/
@@ -508,13 +564,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
}
#elif defined(TARGET_MIPS)
if (snan_bit_is_one(status)) {
- /*
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
- * case sets InvalidOp and returns the default NaN
- */
- if (infzero) {
- return 3;
- }
/* Prefer sNaN over qNaN, in the a, b, c order. */
if (is_snan(a_cls)) {
return 0;
@@ -530,10 +579,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
return 2;
}
} else {
- /*
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
- * case sets InvalidOp and returns the input value 'c'
- */
/* Prefer sNaN over qNaN, in the c, a, b order. */
if (is_snan(c_cls)) {
return 2;
@@ -550,11 +595,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
}
}
#elif defined(TARGET_LOONGARCH64)
- /*
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
- * case sets InvalidOp and returns the input value 'c'
- */
-
/* Prefer sNaN over qNaN, in the c, a, b order. */
if (is_snan(c_cls)) {
return 2;
@@ -570,11 +610,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
return 1;
}
#elif defined(TARGET_PPC)
- /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
- * to return an input NaN if we have one (ie c) rather than generating
- * a default NaN
- */
-
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
*/
@@ -586,10 +621,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
return 1;
}
#elif defined(TARGET_S390X)
- if (infzero) {
- return 3;
- }
-
if (is_snan(a_cls)) {
return 0;
} else if (is_snan(b_cls)) {
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 09/72] tests/fp: Explicitly set inf-zero-nan rule
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (7 preceding siblings ...)
2024-12-11 16:19 ` [PULL 08/72] softfloat: Allow runtime choice of inf * 0 + NaN result Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 10/72] target/arm: Set FloatInfZeroNaNRule explicitly Peter Maydell
` (63 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Explicitly set a rule in the softfloat tests for the inf-zero-nan
muladd special case. In meson.build we put -DTARGET_ARM in fpcflags,
and so we should select here the Arm rule of
float_infzeronan_dnan_if_qnan.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20241202131347.498124-5-peter.maydell@linaro.org
---
tests/fp/fp-bench.c | 5 +++++
tests/fp/fp-test.c | 5 +++++
2 files changed, 10 insertions(+)
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
index 75c07d5d1f1..fde64836194 100644
--- a/tests/fp/fp-bench.c
+++ b/tests/fp/fp-bench.c
@@ -488,7 +488,12 @@ static void run_bench(void)
{
bench_func_t f;
+ /*
+ * These implementation-defined choices for various things IEEE
+ * doesn't specify match those used by the Arm architecture.
+ */
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
f = bench_funcs[operation][precision];
g_assert(f);
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
index 5f6f25c8821..251c278ede9 100644
--- a/tests/fp/fp-test.c
+++ b/tests/fp/fp-test.c
@@ -935,7 +935,12 @@ void run_test(void)
{
unsigned int i;
+ /*
+ * These implementation-defined choices for various things IEEE
+ * doesn't specify match those used by the Arm architecture.
+ */
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
genCases_setLevel(test_level);
verCases_maxErrorCount = n_max_errors;
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 10/72] target/arm: Set FloatInfZeroNaNRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (8 preceding siblings ...)
2024-12-11 16:19 ` [PULL 09/72] tests/fp: Explicitly set inf-zero-nan rule Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 11/72] target/s390: " Peter Maydell
` (62 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the FloatInfZeroNaNRule explicitly for the Arm target,
so we can remove the ifdef from pickNaNMulAdd().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-6-peter.maydell@linaro.org
---
target/arm/cpu.c | 3 +++
fpu/softfloat-specialize.c.inc | 8 +-------
2 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 6938161b954..ead39793985 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -173,11 +173,14 @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
* * tininess-before-rounding
* * 2-input NaN propagation prefers SNaN over QNaN, and then
* operand A over operand B (see FPProcessNaNs() pseudocode)
+ * * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
+ * and the input NaN if it is signalling
*/
static void arm_set_default_fp_behaviours(float_status *s)
{
set_float_detect_tininess(float_tininess_before_rounding, s);
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
}
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index f5b422e07b5..b3ffa54f368 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -489,13 +489,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
/*
* Temporarily fall back to ifdef ladder
*/
-#if defined(TARGET_ARM)
- /*
- * For ARM, the (inf,zero,qnan) case returns the default NaN,
- * but (inf,zero,snan) returns the input NaN.
- */
- rule = float_infzeronan_dnan_if_qnan;
-#elif defined(TARGET_MIPS)
+#if defined(TARGET_MIPS)
if (snan_bit_is_one(status)) {
/*
* For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 11/72] target/s390: Set FloatInfZeroNaNRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (9 preceding siblings ...)
2024-12-11 16:19 ` [PULL 10/72] target/arm: Set FloatInfZeroNaNRule explicitly Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 12/72] target/ppc: " Peter Maydell
` (61 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the FloatInfZeroNaNRule explicitly for s390, so we
can remove the ifdef from pickNaNMulAdd().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-7-peter.maydell@linaro.org
---
target/s390x/cpu.c | 2 ++
fpu/softfloat-specialize.c.inc | 2 --
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 514c70f3010..d5941b5b9df 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -206,6 +206,8 @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
set_float_detect_tininess(float_tininess_before_rounding,
&env->fpu_status);
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fpu_status);
+ set_float_infzeronan_rule(float_infzeronan_dnan_always,
+ &env->fpu_status);
/* fall through */
case RESET_TYPE_S390_CPU_NORMAL:
env->psw.mask &= ~PSW_MASK_RI;
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index b3ffa54f368..db914ddbb1c 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -516,8 +516,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
* a default NaN
*/
rule = float_infzeronan_dnan_never;
-#elif defined(TARGET_S390X)
- rule = float_infzeronan_dnan_always;
#endif
}
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 12/72] target/ppc: Set FloatInfZeroNaNRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (10 preceding siblings ...)
2024-12-11 16:19 ` [PULL 11/72] target/s390: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 13/72] target/mips: " Peter Maydell
` (60 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the FloatInfZeroNaNRule explicitly for the PPC target,
so we can remove the ifdef from pickNaNMulAdd().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-8-peter.maydell@linaro.org
---
target/ppc/cpu_init.c | 7 +++++++
fpu/softfloat-specialize.c.inc | 7 +------
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index efcb80d1c25..f18908a643a 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -7270,6 +7270,13 @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
*/
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->vec_status);
+ /*
+ * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
+ * to return an input NaN if we have one (ie c) rather than generating
+ * a default NaN
+ */
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
ppc_spr_t *spr = &env->spr_cb[i];
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index db914ddbb1c..2023b2bd632 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -503,18 +503,13 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
*/
rule = float_infzeronan_dnan_never;
}
-#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
+#elif defined(TARGET_SPARC) || \
defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
/*
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
* case sets InvalidOp and returns the input value 'c'
*/
- /*
- * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
- * to return an input NaN if we have one (ie c) rather than generating
- * a default NaN
- */
rule = float_infzeronan_dnan_never;
#endif
}
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 13/72] target/mips: Set FloatInfZeroNaNRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (11 preceding siblings ...)
2024-12-11 16:19 ` [PULL 12/72] target/ppc: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 14/72] target/sparc: " Peter Maydell
` (59 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the FloatInfZeroNaNRule explicitly for the MIPS target,
so we can remove the ifdef from pickNaNMulAdd().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-9-peter.maydell@linaro.org
---
target/mips/fpu_helper.h | 9 +++++++++
target/mips/msa.c | 4 ++++
fpu/softfloat-specialize.c.inc | 16 +---------------
3 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
index 7c3c7897b45..be66f2f813a 100644
--- a/target/mips/fpu_helper.h
+++ b/target/mips/fpu_helper.h
@@ -28,6 +28,7 @@ static inline void restore_flush_mode(CPUMIPSState *env)
static inline void restore_snan_bit_mode(CPUMIPSState *env)
{
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
+ FloatInfZeroNaNRule izn_rule;
/*
* With nan2008, SNaNs are silenced in the usual way.
@@ -35,6 +36,14 @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
*/
set_snan_bit_is_one(!nan2008, &env->active_fpu.fp_status);
set_default_nan_mode(!nan2008, &env->active_fpu.fp_status);
+ /*
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
+ * case sets InvalidOp and returns the default NaN.
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
+ * case sets InvalidOp and returns the input value 'c'.
+ */
+ izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
+ set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
}
static inline void restore_fp_status(CPUMIPSState *env)
diff --git a/target/mips/msa.c b/target/mips/msa.c
index 9dffc428f5c..cc152db27f9 100644
--- a/target/mips/msa.c
+++ b/target/mips/msa.c
@@ -74,4 +74,8 @@ void msa_reset(CPUMIPSState *env)
/* set proper signanling bit meaning ("1" means "quiet") */
set_snan_bit_is_one(0, &env->active_tc.msa_fp_status);
+
+ /* Inf * 0 + NaN returns the input NaN */
+ set_float_infzeronan_rule(float_infzeronan_dnan_never,
+ &env->active_tc.msa_fp_status);
}
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 2023b2bd632..db9a466e05b 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -489,21 +489,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
/*
* Temporarily fall back to ifdef ladder
*/
-#if defined(TARGET_MIPS)
- if (snan_bit_is_one(status)) {
- /*
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
- * case sets InvalidOp and returns the default NaN
- */
- rule = float_infzeronan_dnan_always;
- } else {
- /*
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
- * case sets InvalidOp and returns the input value 'c'
- */
- rule = float_infzeronan_dnan_never;
- }
-#elif defined(TARGET_SPARC) || \
+#if defined(TARGET_SPARC) || \
defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 14/72] target/sparc: Set FloatInfZeroNaNRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (12 preceding siblings ...)
2024-12-11 16:19 ` [PULL 13/72] target/mips: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 15/72] target/xtensa: " Peter Maydell
` (58 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the FloatInfZeroNaNRule explicitly for the SPARC target,
so we can remove the ifdef from pickNaNMulAdd().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-10-peter.maydell@linaro.org
---
target/sparc/cpu.c | 2 ++
fpu/softfloat-specialize.c.inc | 3 +--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index dd7af86de73..61f2d3fbf23 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -814,6 +814,8 @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
* the CPU state struct so it won't get zeroed on reset.
*/
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &env->fp_status);
+ /* For inf * 0 + NaN, return the input NaN */
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
cpu_exec_realizefn(cs, &local_err);
if (local_err != NULL) {
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index db9a466e05b..7e57e85348b 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -489,8 +489,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
/*
* Temporarily fall back to ifdef ladder
*/
-#if defined(TARGET_SPARC) || \
- defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
+#if defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
/*
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 15/72] target/xtensa: Set FloatInfZeroNaNRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (13 preceding siblings ...)
2024-12-11 16:19 ` [PULL 14/72] target/sparc: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 16/72] target/x86: " Peter Maydell
` (57 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the FloatInfZeroNaNRule explicitly for the xtensa target,
so we can remove the ifdef from pickNaNMulAdd().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-11-peter.maydell@linaro.org
---
target/xtensa/cpu.c | 2 ++
fpu/softfloat-specialize.c.inc | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 6f9039abaee..3163b758235 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -133,6 +133,8 @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
reset_mmu(env);
cs->halted = env->runstall;
#endif
+ /* For inf * 0 + NaN, return the input NaN */
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
set_no_signaling_nans(!dfpu, &env->fp_status);
xtensa_use_first_nan(env, !dfpu);
}
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 7e57e85348b..3062d19402d 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -489,7 +489,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
/*
* Temporarily fall back to ifdef ladder
*/
-#if defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
+#if defined(TARGET_HPPA) || \
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
/*
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 16/72] target/x86: Set FloatInfZeroNaNRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (14 preceding siblings ...)
2024-12-11 16:19 ` [PULL 15/72] target/xtensa: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 17/72] target/loongarch: " Peter Maydell
` (56 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the FloatInfZeroNaNRule explicitly for the x86 target.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-12-peter.maydell@linaro.org
---
target/i386/tcg/fpu_helper.c | 7 +++++++
fpu/softfloat-specialize.c.inc | 2 +-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index 53b49bb2977..3295753e075 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -173,6 +173,13 @@ void cpu_init_fp_statuses(CPUX86State *env)
*/
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->mmx_status);
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->sse_status);
+ /*
+ * Only SSE has multiply-add instructions. In the SDM Section 14.5.2
+ * "Fused-Multiply-ADD (FMA) Numeric Behavior" the NaN handling is
+ * specified -- for 0 * inf + NaN the input NaN is selected, and if
+ * there are multiple input NaNs they are selected in the order a, b, c.
+ */
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
}
static inline uint8_t save_exception_flags(CPUX86State *env)
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 3062d19402d..ad4f7096d09 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -490,7 +490,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
* Temporarily fall back to ifdef ladder
*/
#if defined(TARGET_HPPA) || \
- defined(TARGET_I386) || defined(TARGET_LOONGARCH)
+ defined(TARGET_LOONGARCH)
/*
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
* case sets InvalidOp and returns the input value 'c'
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 17/72] target/loongarch: Set FloatInfZeroNaNRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (15 preceding siblings ...)
2024-12-11 16:19 ` [PULL 16/72] target/x86: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 18/72] target/hppa: " Peter Maydell
` (55 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the FloatInfZeroNaNRule explicitly for the loongarch target.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-13-peter.maydell@linaro.org
---
target/loongarch/tcg/fpu_helper.c | 5 +++++
fpu/softfloat-specialize.c.inc | 7 +------
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
index 21bc3b04a96..6a2c4b5b1db 100644
--- a/target/loongarch/tcg/fpu_helper.c
+++ b/target/loongarch/tcg/fpu_helper.c
@@ -32,6 +32,11 @@ void restore_fp_status(CPULoongArchState *env)
&env->fp_status);
set_flush_to_zero(0, &env->fp_status);
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
+ /*
+ * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
+ * case sets InvalidOp and returns the input value 'c'
+ */
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
}
int ieee_ex_to_loongarch(int xcpt)
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index ad4f7096d09..05dec2fcb4c 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -489,12 +489,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
/*
* Temporarily fall back to ifdef ladder
*/
-#if defined(TARGET_HPPA) || \
- defined(TARGET_LOONGARCH)
- /*
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
- * case sets InvalidOp and returns the input value 'c'
- */
+#if defined(TARGET_HPPA)
rule = float_infzeronan_dnan_never;
#endif
}
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 18/72] target/hppa: Set FloatInfZeroNaNRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (16 preceding siblings ...)
2024-12-11 16:19 ` [PULL 17/72] target/loongarch: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 19/72] softfloat: Pass have_snan to pickNaNMulAdd Peter Maydell
` (54 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the FloatInfZeroNaNRule explicitly for the HPPA target,
so we can remove the ifdef from pickNaNMulAdd().
As this is the last target to be converted to explicitly setting
the rule, we can remove the fallback code in pickNaNMulAdd()
entirely.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-14-peter.maydell@linaro.org
---
target/hppa/fpu_helper.c | 2 ++
fpu/softfloat-specialize.c.inc | 13 +------------
2 files changed, 3 insertions(+), 12 deletions(-)
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
index 0e44074ba82..393cae33bf9 100644
--- a/target/hppa/fpu_helper.c
+++ b/target/hppa/fpu_helper.c
@@ -55,6 +55,8 @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
* HPPA does note implement a CPU reset method at all...
*/
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
+ /* For inf * 0 + NaN, return the input NaN */
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
}
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 05dec2fcb4c..3e4ec938b25 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -475,8 +475,6 @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
bool infzero, float_status *status)
{
- FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
-
/*
* We guarantee not to require the target to tell us how to
* pick a NaN if we're always returning the default NaN.
@@ -485,21 +483,12 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
*/
assert(!status->default_nan_mode);
- if (rule == float_infzeronan_none) {
- /*
- * Temporarily fall back to ifdef ladder
- */
-#if defined(TARGET_HPPA)
- rule = float_infzeronan_dnan_never;
-#endif
- }
-
if (infzero) {
/*
* Inf * 0 + NaN -- some implementations return the default NaN here,
* and some return the input NaN.
*/
- switch (rule) {
+ switch (status->float_infzeronan_rule) {
case float_infzeronan_dnan_never:
return 2;
case float_infzeronan_dnan_always:
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 19/72] softfloat: Pass have_snan to pickNaNMulAdd
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (17 preceding siblings ...)
2024-12-11 16:19 ` [PULL 18/72] target/hppa: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 20/72] softfloat: Allow runtime choice of NaN propagation for muladd Peter Maydell
` (53 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
The new implementation of pickNaNMulAdd() will find it convenient
to know whether at least one of the three arguments to the muladd
was a signaling NaN. We already calculate that in the caller,
so pass it in as a new bool have_snan.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-15-peter.maydell@linaro.org
---
fpu/softfloat-parts.c.inc | 5 +++--
fpu/softfloat-specialize.c.inc | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index aac1f9cd28c..655b7d9da51 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -67,8 +67,9 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
{
int which;
bool infzero = (ab_mask == float_cmask_infzero);
+ bool have_snan = (abc_mask & float_cmask_snan);
- if (unlikely(abc_mask & float_cmask_snan)) {
+ if (unlikely(have_snan)) {
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
}
@@ -80,7 +81,7 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
if (s->default_nan_mode) {
which = 3;
} else {
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, have_snan, s);
}
if (which == 3) {
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 3e4ec938b25..a769c71f545 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -473,7 +473,7 @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
*----------------------------------------------------------------------------*/
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
- bool infzero, float_status *status)
+ bool infzero, bool have_snan, float_status *status)
{
/*
* We guarantee not to require the target to tell us how to
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 20/72] softfloat: Allow runtime choice of NaN propagation for muladd
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (18 preceding siblings ...)
2024-12-11 16:19 ` [PULL 19/72] softfloat: Pass have_snan to pickNaNMulAdd Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 21/72] tests/fp: Explicitly set 3-NaN propagation rule Peter Maydell
` (52 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
IEEE 758 does not define a fixed rule for which NaN to pick as the
result if both operands of a 3-operand fused multiply-add operation
are NaNs. As a result different architectures have ended up with
different rules for propagating NaNs.
QEMU currently hardcodes the NaN propagation logic into the binary
because pickNaNMulAdd() has an ifdef ladder for different targets.
We want to make the propagation rule instead be selectable at
runtime, because:
* this will let us have multiple targets in one QEMU binary
* the Arm FEAT_AFP architectural feature includes letting
the guest select a NaN propagation rule at runtime
In this commit we add an enum for the propagation rule, the field in
float_status, and the corresponding getters and setters. We change
pickNaNMulAdd to honour this, but because all targets still leave
this field at its default 0 value, the fallback logic will pick the
rule type with the old ifdef ladder.
It's valid not to set a propagation rule if default_nan_mode is
enabled, because in that case there's no need to pick a NaN; all the
callers of pickNaNMulAdd() catch this case and skip calling it.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-16-peter.maydell@linaro.org
---
include/fpu/softfloat-helpers.h | 11 +++
include/fpu/softfloat-types.h | 55 +++++++++++
fpu/softfloat-specialize.c.inc | 167 ++++++++------------------------
3 files changed, 107 insertions(+), 126 deletions(-)
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
index 0bf44dc6087..cf06b4e16bf 100644
--- a/include/fpu/softfloat-helpers.h
+++ b/include/fpu/softfloat-helpers.h
@@ -81,6 +81,12 @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
status->float_2nan_prop_rule = rule;
}
+static inline void set_float_3nan_prop_rule(Float3NaNPropRule rule,
+ float_status *status)
+{
+ status->float_3nan_prop_rule = rule;
+}
+
static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
float_status *status)
{
@@ -143,6 +149,11 @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
return status->float_2nan_prop_rule;
}
+static inline Float3NaNPropRule get_float_3nan_prop_rule(float_status *status)
+{
+ return status->float_3nan_prop_rule;
+}
+
static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
{
return status->float_infzeronan_rule;
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 47bb22c4e25..d9f0797edaf 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -80,6 +80,8 @@ this code that are retained.
#ifndef SOFTFLOAT_TYPES_H
#define SOFTFLOAT_TYPES_H
+#include "hw/registerfields.h"
+
/*
* Software IEC/IEEE floating-point types.
*/
@@ -207,6 +209,58 @@ typedef enum __attribute__((__packed__)) {
float_2nan_prop_x87,
} Float2NaNPropRule;
+/*
+ * 3-input NaN propagation rule, for fused multiply-add. Individual
+ * architectures have different rules for which input NaN is
+ * propagated to the output when there is more than one NaN on the
+ * input.
+ *
+ * If default_nan_mode is enabled then it is valid not to set a NaN
+ * propagation rule, because the softfloat code guarantees not to try
+ * to pick a NaN to propagate in default NaN mode. When not in
+ * default-NaN mode, it is an error for the target not to set the rule
+ * in float_status if it uses a muladd, and we will assert if we need
+ * to handle an input NaN and no rule was selected.
+ *
+ * The naming scheme for Float3NaNPropRule values is:
+ * float_3nan_prop_s_abc:
+ * = "Prefer SNaN over QNaN, then operand A over B over C"
+ * float_3nan_prop_abc:
+ * = "Prefer A over B over C regardless of SNaN vs QNAN"
+ *
+ * For QEMU, the multiply-add operation is A * B + C.
+ */
+
+/*
+ * We set the Float3NaNPropRule enum values up so we can select the
+ * right value in pickNaNMulAdd in a data driven way.
+ */
+FIELD(3NAN, 1ST, 0, 2) /* which operand is most preferred ? */
+FIELD(3NAN, 2ND, 2, 2) /* which operand is next most preferred ? */
+FIELD(3NAN, 3RD, 4, 2) /* which operand is least preferred ? */
+FIELD(3NAN, SNAN, 6, 1) /* do we prefer SNaN over QNaN ? */
+
+#define PROPRULE(X, Y, Z) \
+ ((X << R_3NAN_1ST_SHIFT) | (Y << R_3NAN_2ND_SHIFT) | (Z << R_3NAN_3RD_SHIFT))
+
+typedef enum __attribute__((__packed__)) {
+ float_3nan_prop_none = 0, /* No propagation rule specified */
+ float_3nan_prop_abc = PROPRULE(0, 1, 2),
+ float_3nan_prop_acb = PROPRULE(0, 2, 1),
+ float_3nan_prop_bac = PROPRULE(1, 0, 2),
+ float_3nan_prop_bca = PROPRULE(1, 2, 0),
+ float_3nan_prop_cab = PROPRULE(2, 0, 1),
+ float_3nan_prop_cba = PROPRULE(2, 1, 0),
+ float_3nan_prop_s_abc = float_3nan_prop_abc | R_3NAN_SNAN_MASK,
+ float_3nan_prop_s_acb = float_3nan_prop_acb | R_3NAN_SNAN_MASK,
+ float_3nan_prop_s_bac = float_3nan_prop_bac | R_3NAN_SNAN_MASK,
+ float_3nan_prop_s_bca = float_3nan_prop_bca | R_3NAN_SNAN_MASK,
+ float_3nan_prop_s_cab = float_3nan_prop_cab | R_3NAN_SNAN_MASK,
+ float_3nan_prop_s_cba = float_3nan_prop_cba | R_3NAN_SNAN_MASK,
+} Float3NaNPropRule;
+
+#undef PROPRULE
+
/*
* Rule for result of fused multiply-add 0 * Inf + NaN.
* This must be a NaN, but implementations differ on whether this
@@ -241,6 +295,7 @@ typedef struct float_status {
FloatRoundMode float_rounding_mode;
FloatX80RoundPrec floatx80_rounding_precision;
Float2NaNPropRule float_2nan_prop_rule;
+ Float3NaNPropRule float_3nan_prop_rule;
FloatInfZeroNaNRule float_infzeronan_rule;
bool tininess_before_rounding;
/* should denormalised results go to zero and set the inexact flag? */
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index a769c71f545..b4f3f0efa82 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -475,6 +475,10 @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
bool infzero, bool have_snan, float_status *status)
{
+ FloatClass cls[3] = { a_cls, b_cls, c_cls };
+ Float3NaNPropRule rule = status->float_3nan_prop_rule;
+ int which;
+
/*
* We guarantee not to require the target to tell us how to
* pick a NaN if we're always returning the default NaN.
@@ -500,145 +504,56 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
}
}
+ if (rule == float_3nan_prop_none) {
#if defined(TARGET_ARM)
-
- /* This looks different from the ARM ARM pseudocode, because the ARM ARM
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
- */
- if (is_snan(c_cls)) {
- return 2;
- } else if (is_snan(a_cls)) {
- return 0;
- } else if (is_snan(b_cls)) {
- return 1;
- } else if (is_qnan(c_cls)) {
- return 2;
- } else if (is_qnan(a_cls)) {
- return 0;
- } else {
- return 1;
- }
+ /*
+ * This looks different from the ARM ARM pseudocode, because the ARM ARM
+ * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
+ */
+ rule = float_3nan_prop_s_cab;
#elif defined(TARGET_MIPS)
- if (snan_bit_is_one(status)) {
- /* Prefer sNaN over qNaN, in the a, b, c order. */
- if (is_snan(a_cls)) {
- return 0;
- } else if (is_snan(b_cls)) {
- return 1;
- } else if (is_snan(c_cls)) {
- return 2;
- } else if (is_qnan(a_cls)) {
- return 0;
- } else if (is_qnan(b_cls)) {
- return 1;
+ if (snan_bit_is_one(status)) {
+ rule = float_3nan_prop_s_abc;
} else {
- return 2;
+ rule = float_3nan_prop_s_cab;
}
- } else {
- /* Prefer sNaN over qNaN, in the c, a, b order. */
- if (is_snan(c_cls)) {
- return 2;
- } else if (is_snan(a_cls)) {
- return 0;
- } else if (is_snan(b_cls)) {
- return 1;
- } else if (is_qnan(c_cls)) {
- return 2;
- } else if (is_qnan(a_cls)) {
- return 0;
- } else {
- return 1;
- }
- }
#elif defined(TARGET_LOONGARCH64)
- /* Prefer sNaN over qNaN, in the c, a, b order. */
- if (is_snan(c_cls)) {
- return 2;
- } else if (is_snan(a_cls)) {
- return 0;
- } else if (is_snan(b_cls)) {
- return 1;
- } else if (is_qnan(c_cls)) {
- return 2;
- } else if (is_qnan(a_cls)) {
- return 0;
- } else {
- return 1;
- }
+ rule = float_3nan_prop_s_cab;
#elif defined(TARGET_PPC)
- /* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
- * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
- */
- if (is_nan(a_cls)) {
- return 0;
- } else if (is_nan(c_cls)) {
- return 2;
- } else {
- return 1;
- }
+ /*
+ * If fRA is a NaN return it; otherwise if fRB is a NaN return it;
+ * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
+ */
+ rule = float_3nan_prop_acb;
#elif defined(TARGET_S390X)
- if (is_snan(a_cls)) {
- return 0;
- } else if (is_snan(b_cls)) {
- return 1;
- } else if (is_snan(c_cls)) {
- return 2;
- } else if (is_qnan(a_cls)) {
- return 0;
- } else if (is_qnan(b_cls)) {
- return 1;
- } else {
- return 2;
- }
+ rule = float_3nan_prop_s_abc;
#elif defined(TARGET_SPARC)
- /* Prefer SNaN over QNaN, order C, B, A. */
- if (is_snan(c_cls)) {
- return 2;
- } else if (is_snan(b_cls)) {
- return 1;
- } else if (is_snan(a_cls)) {
- return 0;
- } else if (is_qnan(c_cls)) {
- return 2;
- } else if (is_qnan(b_cls)) {
- return 1;
- } else {
- return 0;
- }
+ rule = float_3nan_prop_s_cba;
#elif defined(TARGET_XTENSA)
- /*
- * For Xtensa, the (inf,zero,nan) case sets InvalidOp and returns
- * an input NaN if we have one (ie c).
- */
- if (status->use_first_nan) {
- if (is_nan(a_cls)) {
- return 0;
- } else if (is_nan(b_cls)) {
- return 1;
+ if (status->use_first_nan) {
+ rule = float_3nan_prop_abc;
} else {
- return 2;
+ rule = float_3nan_prop_cba;
}
- } else {
- if (is_nan(c_cls)) {
- return 2;
- } else if (is_nan(b_cls)) {
- return 1;
- } else {
- return 0;
- }
- }
#else
- /* A default implementation: prefer a to b to c.
- * This is unlikely to actually match any real implementation.
- */
- if (is_nan(a_cls)) {
- return 0;
- } else if (is_nan(b_cls)) {
- return 1;
- } else {
- return 2;
- }
+ rule = float_3nan_prop_abc;
#endif
+ }
+
+ assert(rule != float_3nan_prop_none);
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
+ /* We have at least one SNaN input and should prefer it */
+ do {
+ which = rule & R_3NAN_1ST_MASK;
+ rule >>= R_3NAN_1ST_LENGTH;
+ } while (!is_snan(cls[which]));
+ } else {
+ do {
+ which = rule & R_3NAN_1ST_MASK;
+ rule >>= R_3NAN_1ST_LENGTH;
+ } while (!is_nan(cls[which]));
+ }
+ return which;
}
/*----------------------------------------------------------------------------
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 21/72] tests/fp: Explicitly set 3-NaN propagation rule
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (19 preceding siblings ...)
2024-12-11 16:19 ` [PULL 20/72] softfloat: Allow runtime choice of NaN propagation for muladd Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 22/72] target/arm: Set Float3NaNPropRule explicitly Peter Maydell
` (51 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Explicitly set a rule in the softfloat tests for propagating NaNs in
the muladd case. In meson.build we put -DTARGET_ARM in fpcflags, and
so we should select here the Arm rule of float_3nan_prop_s_cab.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-17-peter.maydell@linaro.org
---
tests/fp/fp-bench.c | 1 +
tests/fp/fp-test.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
index fde64836194..39d80c9038f 100644
--- a/tests/fp/fp-bench.c
+++ b/tests/fp/fp-bench.c
@@ -493,6 +493,7 @@ static void run_bench(void)
* doesn't specify match those used by the Arm architecture.
*/
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
f = bench_funcs[operation][precision];
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
index 251c278ede9..f290d523ab1 100644
--- a/tests/fp/fp-test.c
+++ b/tests/fp/fp-test.c
@@ -940,6 +940,7 @@ void run_test(void)
* doesn't specify match those used by the Arm architecture.
*/
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
genCases_setLevel(test_level);
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 22/72] target/arm: Set Float3NaNPropRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (20 preceding siblings ...)
2024-12-11 16:19 ` [PULL 21/72] tests/fp: Explicitly set 3-NaN propagation rule Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 23/72] target/loongarch: " Peter Maydell
` (50 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the Float3NaNPropRule explicitly for Arm, and remove the
ifdef from pickNaNMulAdd().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-18-peter.maydell@linaro.org
---
target/arm/cpu.c | 5 +++++
fpu/softfloat-specialize.c.inc | 8 +-------
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index ead39793985..c81f6df3fca 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -173,6 +173,10 @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
* * tininess-before-rounding
* * 2-input NaN propagation prefers SNaN over QNaN, and then
* operand A over operand B (see FPProcessNaNs() pseudocode)
+ * * 3-input NaN propagation prefers SNaN over QNaN, and then
+ * operand C over A over B (see FPProcessNaNs3() pseudocode,
+ * but note that for QEMU muladd is a * b + c, whereas for
+ * the pseudocode function the arguments are in the order c, a, b.
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
* and the input NaN if it is signalling
*/
@@ -180,6 +184,7 @@ static void arm_set_default_fp_behaviours(float_status *s)
{
set_float_detect_tininess(float_tininess_before_rounding, s);
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
}
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index b4f3f0efa82..3a2d0444475 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -505,13 +505,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
}
if (rule == float_3nan_prop_none) {
-#if defined(TARGET_ARM)
- /*
- * This looks different from the ARM ARM pseudocode, because the ARM ARM
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
- */
- rule = float_3nan_prop_s_cab;
-#elif defined(TARGET_MIPS)
+#if defined(TARGET_MIPS)
if (snan_bit_is_one(status)) {
rule = float_3nan_prop_s_abc;
} else {
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 23/72] target/loongarch: Set Float3NaNPropRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (21 preceding siblings ...)
2024-12-11 16:19 ` [PULL 22/72] target/arm: Set Float3NaNPropRule explicitly Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 24/72] target/ppc: " Peter Maydell
` (49 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the Float3NaNPropRule explicitly for loongarch, and remove the
ifdef from pickNaNMulAdd().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-19-peter.maydell@linaro.org
---
target/loongarch/tcg/fpu_helper.c | 1 +
fpu/softfloat-specialize.c.inc | 2 --
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
index 6a2c4b5b1db..37a48599366 100644
--- a/target/loongarch/tcg/fpu_helper.c
+++ b/target/loongarch/tcg/fpu_helper.c
@@ -37,6 +37,7 @@ void restore_fp_status(CPULoongArchState *env)
* case sets InvalidOp and returns the input value 'c'
*/
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
}
int ieee_ex_to_loongarch(int xcpt)
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 3a2d0444475..d610f460026 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -511,8 +511,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
} else {
rule = float_3nan_prop_s_cab;
}
-#elif defined(TARGET_LOONGARCH64)
- rule = float_3nan_prop_s_cab;
#elif defined(TARGET_PPC)
/*
* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 24/72] target/ppc: Set Float3NaNPropRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (22 preceding siblings ...)
2024-12-11 16:19 ` [PULL 23/72] target/loongarch: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 25/72] target/s390x: " Peter Maydell
` (48 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the Float3NaNPropRule explicitly for PPC, and remove the
ifdef from pickNaNMulAdd().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-20-peter.maydell@linaro.org
---
target/ppc/cpu_init.c | 8 ++++++++
fpu/softfloat-specialize.c.inc | 6 ------
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index f18908a643a..eb9d7b13701 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -7270,6 +7270,14 @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
*/
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->vec_status);
+ /*
+ * NaN propagation for fused multiply-add:
+ * if fRA is a NaN return it; otherwise if fRB is a NaN return it;
+ * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
+ * whereas QEMU labels the operands as (a * b) + c.
+ */
+ set_float_3nan_prop_rule(float_3nan_prop_acb, &env->fp_status);
+ set_float_3nan_prop_rule(float_3nan_prop_acb, &env->vec_status);
/*
* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
* to return an input NaN if we have one (ie c) rather than generating
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index d610f460026..173b9eadb57 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -511,12 +511,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
} else {
rule = float_3nan_prop_s_cab;
}
-#elif defined(TARGET_PPC)
- /*
- * If fRA is a NaN return it; otherwise if fRB is a NaN return it;
- * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
- */
- rule = float_3nan_prop_acb;
#elif defined(TARGET_S390X)
rule = float_3nan_prop_s_abc;
#elif defined(TARGET_SPARC)
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 25/72] target/s390x: Set Float3NaNPropRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (23 preceding siblings ...)
2024-12-11 16:19 ` [PULL 24/72] target/ppc: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 26/72] target/sparc: " Peter Maydell
` (47 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the Float3NaNPropRule explicitly for s390x, and remove the
ifdef from pickNaNMulAdd().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-21-peter.maydell@linaro.org
---
target/s390x/cpu.c | 1 +
fpu/softfloat-specialize.c.inc | 2 --
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index d5941b5b9df..e74055bad79 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -206,6 +206,7 @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
set_float_detect_tininess(float_tininess_before_rounding,
&env->fpu_status);
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fpu_status);
+ set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
set_float_infzeronan_rule(float_infzeronan_dnan_always,
&env->fpu_status);
/* fall through */
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 173b9eadb57..8a36280df1a 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -511,8 +511,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
} else {
rule = float_3nan_prop_s_cab;
}
-#elif defined(TARGET_S390X)
- rule = float_3nan_prop_s_abc;
#elif defined(TARGET_SPARC)
rule = float_3nan_prop_s_cba;
#elif defined(TARGET_XTENSA)
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 26/72] target/sparc: Set Float3NaNPropRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (24 preceding siblings ...)
2024-12-11 16:19 ` [PULL 25/72] target/s390x: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 27/72] target/mips: " Peter Maydell
` (46 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the Float3NaNPropRule explicitly for SPARC, and remove the
ifdef from pickNaNMulAdd().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-22-peter.maydell@linaro.org
---
target/sparc/cpu.c | 2 ++
fpu/softfloat-specialize.c.inc | 2 --
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 61f2d3fbf23..0f2997a85e6 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -814,6 +814,8 @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
* the CPU state struct so it won't get zeroed on reset.
*/
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &env->fp_status);
+ /* For fused-multiply add, prefer SNaN over QNaN, then C->B->A */
+ set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
/* For inf * 0 + NaN, return the input NaN */
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 8a36280df1a..c4d8d085a98 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -511,8 +511,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
} else {
rule = float_3nan_prop_s_cab;
}
-#elif defined(TARGET_SPARC)
- rule = float_3nan_prop_s_cba;
#elif defined(TARGET_XTENSA)
if (status->use_first_nan) {
rule = float_3nan_prop_abc;
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 27/72] target/mips: Set Float3NaNPropRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (25 preceding siblings ...)
2024-12-11 16:19 ` [PULL 26/72] target/sparc: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 28/72] target/xtensa: " Peter Maydell
` (45 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the Float3NaNPropRule explicitly for Arm, and remove the
ifdef from pickNaNMulAdd().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-23-peter.maydell@linaro.org
---
target/mips/fpu_helper.h | 4 ++++
target/mips/msa.c | 3 +++
fpu/softfloat-specialize.c.inc | 8 +-------
3 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
index be66f2f813a..8ca0ca7ea39 100644
--- a/target/mips/fpu_helper.h
+++ b/target/mips/fpu_helper.h
@@ -29,6 +29,7 @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
{
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
FloatInfZeroNaNRule izn_rule;
+ Float3NaNPropRule nan3_rule;
/*
* With nan2008, SNaNs are silenced in the usual way.
@@ -44,6 +45,9 @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
*/
izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
+ nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
+ set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
+
}
static inline void restore_fp_status(CPUMIPSState *env)
diff --git a/target/mips/msa.c b/target/mips/msa.c
index cc152db27f9..93a9a87d76d 100644
--- a/target/mips/msa.c
+++ b/target/mips/msa.c
@@ -66,6 +66,9 @@ void msa_reset(CPUMIPSState *env)
set_float_2nan_prop_rule(float_2nan_prop_s_ab,
&env->active_tc.msa_fp_status);
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab,
+ &env->active_tc.msa_fp_status);
+
/* clear float_status exception flags */
set_float_exception_flags(0, &env->active_tc.msa_fp_status);
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index c4d8d085a98..28db409d22c 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -505,13 +505,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
}
if (rule == float_3nan_prop_none) {
-#if defined(TARGET_MIPS)
- if (snan_bit_is_one(status)) {
- rule = float_3nan_prop_s_abc;
- } else {
- rule = float_3nan_prop_s_cab;
- }
-#elif defined(TARGET_XTENSA)
+#if defined(TARGET_XTENSA)
if (status->use_first_nan) {
rule = float_3nan_prop_abc;
} else {
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 28/72] target/xtensa: Set Float3NaNPropRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (26 preceding siblings ...)
2024-12-11 16:19 ` [PULL 27/72] target/mips: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 29/72] target/i386: " Peter Maydell
` (44 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the Float3NaNPropRule explicitly for xtensa, and remove the
ifdef from pickNaNMulAdd().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-24-peter.maydell@linaro.org
---
target/xtensa/fpu_helper.c | 2 ++
fpu/softfloat-specialize.c.inc | 8 --------
2 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
index f2d212d05df..4b1b021d824 100644
--- a/target/xtensa/fpu_helper.c
+++ b/target/xtensa/fpu_helper.c
@@ -62,6 +62,8 @@ void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
set_use_first_nan(use_first, &env->fp_status);
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
&env->fp_status);
+ set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
+ &env->fp_status);
}
void HELPER(wur_fpu2k_fcr)(CPUXtensaState *env, uint32_t v)
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 28db409d22c..67428dab98a 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -505,15 +505,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
}
if (rule == float_3nan_prop_none) {
-#if defined(TARGET_XTENSA)
- if (status->use_first_nan) {
- rule = float_3nan_prop_abc;
- } else {
- rule = float_3nan_prop_cba;
- }
-#else
rule = float_3nan_prop_abc;
-#endif
}
assert(rule != float_3nan_prop_none);
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 29/72] target/i386: Set Float3NaNPropRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (27 preceding siblings ...)
2024-12-11 16:19 ` [PULL 28/72] target/xtensa: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 30/72] target/hppa: " Peter Maydell
` (43 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the Float3NaNPropRule explicitly for i386. We had no
i386-specific behaviour in the old ifdef ladder, so we were using the
default "prefer a then b then c" fallback; this is actually the
correct per-the-spec handling for i386.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-25-peter.maydell@linaro.org
---
target/i386/tcg/fpu_helper.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index 3295753e075..4303b3356aa 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -180,6 +180,7 @@ void cpu_init_fp_statuses(CPUX86State *env)
* there are multiple input NaNs they are selected in the order a, b, c.
*/
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
}
static inline uint8_t save_exception_flags(CPUX86State *env)
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 30/72] target/hppa: Set Float3NaNPropRule explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (28 preceding siblings ...)
2024-12-11 16:19 ` [PULL 29/72] target/i386: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 31/72] fpu: Remove use_first_nan field from float_status Peter Maydell
` (42 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the Float3NaNPropRule explicitly for HPPA, and remove the
ifdef from pickNaNMulAdd().
HPPA is the only target that was using the default branch of the
ifdef ladder (other targets either do not use muladd or set
default_nan_mode), so we can remove the ifdef fallback entirely now
(allowing the "rule not set" case to fall into the default of the
switch statement and assert).
We add a TODO note that the HPPA rule is probably wrong; this is
not a behavioural change for this refactoring.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-26-peter.maydell@linaro.org
---
target/hppa/fpu_helper.c | 8 ++++++++
fpu/softfloat-specialize.c.inc | 4 ----
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
index 393cae33bf9..69c4ce37835 100644
--- a/target/hppa/fpu_helper.c
+++ b/target/hppa/fpu_helper.c
@@ -55,6 +55,14 @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
* HPPA does note implement a CPU reset method at all...
*/
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
+ /*
+ * TODO: The HPPA architecture reference only documents its NaN
+ * propagation rule for 2-operand operations. Testing on real hardware
+ * might be necessary to confirm whether this order for muladd is correct.
+ * Not preferring the SNaN is almost certainly incorrect as it diverges
+ * from the documented rules for 2-operand operations.
+ */
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
/* For inf * 0 + NaN, return the input NaN */
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
}
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 67428dab98a..5fbc953e71e 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -504,10 +504,6 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
}
}
- if (rule == float_3nan_prop_none) {
- rule = float_3nan_prop_abc;
- }
-
assert(rule != float_3nan_prop_none);
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
/* We have at least one SNaN input and should prefer it */
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 31/72] fpu: Remove use_first_nan field from float_status
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (29 preceding siblings ...)
2024-12-11 16:19 ` [PULL 30/72] target/hppa: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 32/72] target/m68k: Don't pass NULL float_status to floatx80_default_nan() Peter Maydell
` (41 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
The use_first_nan field in float_status was an xtensa-specific way to
select at runtime from two different NaN propagation rules. Now that
xtensa is using the target-agnostic NaN propagation rule selection
that we've just added, we can remove use_first_nan, because there is
no longer any code that reads it.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-27-peter.maydell@linaro.org
---
include/fpu/softfloat-helpers.h | 5 -----
include/fpu/softfloat-types.h | 1 -
target/xtensa/fpu_helper.c | 1 -
3 files changed, 7 deletions(-)
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
index cf06b4e16bf..10a6763532c 100644
--- a/include/fpu/softfloat-helpers.h
+++ b/include/fpu/softfloat-helpers.h
@@ -113,11 +113,6 @@ static inline void set_snan_bit_is_one(bool val, float_status *status)
status->snan_bit_is_one = val;
}
-static inline void set_use_first_nan(bool val, float_status *status)
-{
- status->use_first_nan = val;
-}
-
static inline void set_no_signaling_nans(bool val, float_status *status)
{
status->no_signaling_nans = val;
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index d9f0797edaf..84ba4ed20e6 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -309,7 +309,6 @@ typedef struct float_status {
* softfloat-specialize.inc.c)
*/
bool snan_bit_is_one;
- bool use_first_nan;
bool no_signaling_nans;
/* should overflowed results subtract re_bias to its exponent? */
bool rebias_overflow;
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
index 4b1b021d824..53fc7cfd2af 100644
--- a/target/xtensa/fpu_helper.c
+++ b/target/xtensa/fpu_helper.c
@@ -59,7 +59,6 @@ static const struct {
void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
{
- set_use_first_nan(use_first, &env->fp_status);
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
&env->fp_status);
set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 32/72] target/m68k: Don't pass NULL float_status to floatx80_default_nan()
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (30 preceding siblings ...)
2024-12-11 16:19 ` [PULL 31/72] fpu: Remove use_first_nan field from float_status Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 33/72] softfloat: Create floatx80 default NaN from parts64_default_nan Peter Maydell
` (40 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Currently m68k_cpu_reset_hold() calls floatx80_default_nan(NULL)
to get the NaN bit pattern to reset the FPU registers. This
works because it happens that our implementation of
floatx80_default_nan() doesn't actually look at the float_status
pointer except for TARGET_MIPS. However, this isn't guaranteed,
and to be able to remove the ifdef in floatx80_default_nan()
we're going to need a real float_status here.
Rearrange m68k_cpu_reset_hold() so that we initialize env->fp_status
earlier, and thus can pass it to floatx80_default_nan().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-28-peter.maydell@linaro.org
---
target/m68k/cpu.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 5fe335558aa..13b76e22488 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -76,7 +76,7 @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
CPUState *cs = CPU(obj);
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(obj);
CPUM68KState *env = cpu_env(cs);
- floatx80 nan = floatx80_default_nan(NULL);
+ floatx80 nan;
int i;
if (mcc->parent_phases.hold) {
@@ -89,10 +89,6 @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
#else
cpu_m68k_set_sr(env, SR_S | SR_I);
#endif
- for (i = 0; i < 8; i++) {
- env->fregs[i].d = nan;
- }
- cpu_m68k_set_fpcr(env, 0);
/*
* M68000 FAMILY PROGRAMMER'S REFERENCE MANUAL
* 3.4 FLOATING-POINT INSTRUCTION DETAILS
@@ -109,6 +105,12 @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
* preceding paragraph for nonsignaling NaNs.
*/
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
+
+ nan = floatx80_default_nan(&env->fp_status);
+ for (i = 0; i < 8; i++) {
+ env->fregs[i].d = nan;
+ }
+ cpu_m68k_set_fpcr(env, 0);
env->fpsr = 0;
/* TODO: We should set PC from the interrupt vector. */
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 33/72] softfloat: Create floatx80 default NaN from parts64_default_nan
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (31 preceding siblings ...)
2024-12-11 16:19 ` [PULL 32/72] target/m68k: Don't pass NULL float_status to floatx80_default_nan() Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 34/72] target/loongarch: Use normal float_status in fclass_s and fclass_d helpers Peter Maydell
` (39 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
We create our 128-bit default NaN by calling parts64_default_nan()
and then adjusting the result. We can do the same trick for creating
the floatx80 default NaN, which lets us drop a target ifdef.
floatx80 is used only by:
i386
m68k
arm nwfpe old floating-point emulation emulation support
(which is essentially dead, especially the parts involving floatx80)
PPC (only in the xsrqpxp instruction, which just rounds an input
value by converting to floatx80 and back, so will never generate
the default NaN)
The floatx80 default NaN as currently implemented is:
m68k: sign = 0, exp = 1...1, int = 1, frac = 1....1
i386: sign = 1, exp = 1...1, int = 1, frac = 10...0
These are the same as the parts64_default_nan for these architectures.
This is technically a possible behaviour change for arm linux-user
nwfpe emulation emulation, because the default NaN will now have the
sign bit clear. But we were already generating a different floatx80
default NaN from the real kernel emulation we are supposedly
following, which appears to use an all-bits-1 value:
https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L267
This won't affect the only "real" use of the nwfpe emulation, which
is ancient binaries that used it as part of the old floating point
calling convention; that only uses loads and stores of 32 and 64 bit
floats, not any of the floatx80 behaviour the original hardware had.
We also get the nwfpe float64 default NaN value wrong:
https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L166
so if we ever cared about this obscure corner the right fix would be
to correct that so nwfpe used its own default-NaN setting rather
than the Arm VFP one.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-29-peter.maydell@linaro.org
---
fpu/softfloat-specialize.c.inc | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 5fbc953e71e..9f913ce20ab 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -227,17 +227,17 @@ static void parts128_silence_nan(FloatParts128 *p, float_status *status)
floatx80 floatx80_default_nan(float_status *status)
{
floatx80 r;
+ /*
+ * Extrapolate from the choices made by parts64_default_nan to fill
+ * in the floatx80 format. We assume that floatx80's explicit
+ * integer bit is always set (this is true for i386 and m68k,
+ * which are the only real users of this format).
+ */
+ FloatParts64 p64;
+ parts64_default_nan(&p64, status);
- /* None of the targets that have snan_bit_is_one use floatx80. */
- assert(!snan_bit_is_one(status));
-#if defined(TARGET_M68K)
- r.low = UINT64_C(0xFFFFFFFFFFFFFFFF);
- r.high = 0x7FFF;
-#else
- /* X86 */
- r.low = UINT64_C(0xC000000000000000);
- r.high = 0xFFFF;
-#endif
+ r.high = 0x7FFF | (p64.sign << 15);
+ r.low = (1ULL << DECOMPOSED_BINARY_POINT) | p64.frac;
return r;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 34/72] target/loongarch: Use normal float_status in fclass_s and fclass_d helpers
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (32 preceding siblings ...)
2024-12-11 16:19 ` [PULL 33/72] softfloat: Create floatx80 default NaN from parts64_default_nan Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 35/72] target/m68k: In frem helper, initialize local float_status from env->fp_status Peter Maydell
` (38 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
In target/loongarch's helper_fclass_s() and helper_fclass_d() we pass
a zero-initialized float_status struct to float32_is_quiet_nan() and
float64_is_quiet_nan(), with the cryptic comment "for
snan_bit_is_one".
This pattern appears to have been copied from target/riscv, where it
is used because the functions there do not have ready access to the
CPU state struct. The comment presumably refers to the fact that the
main reason the is_quiet_nan() functions want the float_state is
because they want to know about the snan_bit_is_one config.
In the loongarch helpers, though, we have the CPU state struct
to hand. Use the usual env->fp_status here. This avoids our needing
to track that we need to update the initializer of the local
float_status structs when the core softfloat code adds new
options for targets to configure their behaviour.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-30-peter.maydell@linaro.org
---
target/loongarch/tcg/fpu_helper.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
index 37a48599366..aea5e0fe5e6 100644
--- a/target/loongarch/tcg/fpu_helper.c
+++ b/target/loongarch/tcg/fpu_helper.c
@@ -359,8 +359,7 @@ uint64_t helper_fclass_s(CPULoongArchState *env, uint64_t fj)
} else if (float32_is_zero_or_denormal(f)) {
return sign ? 1 << 4 : 1 << 8;
} else if (float32_is_any_nan(f)) {
- float_status s = { }; /* for snan_bit_is_one */
- return float32_is_quiet_nan(f, &s) ? 1 << 1 : 1 << 0;
+ return float32_is_quiet_nan(f, &env->fp_status) ? 1 << 1 : 1 << 0;
} else {
return sign ? 1 << 3 : 1 << 7;
}
@@ -378,8 +377,7 @@ uint64_t helper_fclass_d(CPULoongArchState *env, uint64_t fj)
} else if (float64_is_zero_or_denormal(f)) {
return sign ? 1 << 4 : 1 << 8;
} else if (float64_is_any_nan(f)) {
- float_status s = { }; /* for snan_bit_is_one */
- return float64_is_quiet_nan(f, &s) ? 1 << 1 : 1 << 0;
+ return float64_is_quiet_nan(f, &env->fp_status) ? 1 << 1 : 1 << 0;
} else {
return sign ? 1 << 3 : 1 << 7;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 35/72] target/m68k: In frem helper, initialize local float_status from env->fp_status
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (33 preceding siblings ...)
2024-12-11 16:19 ` [PULL 34/72] target/loongarch: Use normal float_status in fclass_s and fclass_d helpers Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 36/72] target/m68k: Init local float_status from env fp_status in gdb get/set reg Peter Maydell
` (37 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
In the frem helper, we have a local float_status because we want to
execute the floatx80_div() with a custom rounding mode. Instead of
zero-initializing the local float_status and then having to set it up
with the m68k standard behaviour (including the NaN propagation rule
and copying the rounding precision from env->fp_status), initialize
it as a complete copy of env->fp_status. This will avoid our having
to add new code in this function for every new config knob we add
to fp_status.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-31-peter.maydell@linaro.org
---
target/m68k/fpu_helper.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index a605162b71f..e3f4a188501 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -615,15 +615,13 @@ void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
fp_rem = floatx80_rem(val1->d, val0->d, &env->fp_status);
if (!floatx80_is_any_nan(fp_rem)) {
- float_status fp_status = { };
+ /* Use local temporary fp_status to set different rounding mode */
+ float_status fp_status = env->fp_status;
uint32_t quotient;
int sign;
/* Calculate quotient directly using round to nearest mode */
- set_float_2nan_prop_rule(float_2nan_prop_ab, &fp_status);
set_float_rounding_mode(float_round_nearest_even, &fp_status);
- set_floatx80_rounding_precision(
- get_floatx80_rounding_precision(&env->fp_status), &fp_status);
fp_quot.d = floatx80_div(val1->d, val0->d, &fp_status);
sign = extractFloatx80Sign(fp_quot.d);
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 36/72] target/m68k: Init local float_status from env fp_status in gdb get/set reg
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (34 preceding siblings ...)
2024-12-11 16:19 ` [PULL 35/72] target/m68k: In frem helper, initialize local float_status from env->fp_status Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 37/72] target/sparc: Initialize local scratch float_status from env->fp_status Peter Maydell
` (36 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
In cf_fpu_gdb_get_reg() and cf_fpu_gdb_set_reg() we do the conversion
from float64 to floatx80 using a scratch float_status, because we
don't want the conversion to affect the CPU's floating point exception
status. Currently we use a zero-initialized float_status. This will
get steadily more awkward as we add config knobs to float_status
that the target must initialize. Avoid having to add any of that
configuration here by instead initializing our local float_status
from the env->fp_status.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-32-peter.maydell@linaro.org
---
target/m68k/helper.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
index 9bfc6ae97c0..beefeb7069c 100644
--- a/target/m68k/helper.c
+++ b/target/m68k/helper.c
@@ -36,7 +36,8 @@ static int cf_fpu_gdb_get_reg(CPUState *cs, GByteArray *mem_buf, int n)
CPUM68KState *env = &cpu->env;
if (n < 8) {
- float_status s = {};
+ /* Use scratch float_status so any exceptions don't change CPU state */
+ float_status s = env->fp_status;
return gdb_get_reg64(mem_buf, floatx80_to_float64(env->fregs[n].d, &s));
}
switch (n) {
@@ -56,7 +57,8 @@ static int cf_fpu_gdb_set_reg(CPUState *cs, uint8_t *mem_buf, int n)
CPUM68KState *env = &cpu->env;
if (n < 8) {
- float_status s = {};
+ /* Use scratch float_status so any exceptions don't change CPU state */
+ float_status s = env->fp_status;
env->fregs[n].d = float64_to_floatx80(ldq_be_p(mem_buf), &s);
return 8;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 37/72] target/sparc: Initialize local scratch float_status from env->fp_status
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (35 preceding siblings ...)
2024-12-11 16:19 ` [PULL 36/72] target/m68k: Init local float_status from env fp_status in gdb get/set reg Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 38/72] target/ppc: Use env->fp_status in helper_compute_fprf functions Peter Maydell
` (35 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
In the helper functions flcmps and flcmpd we use a scratch float_status
so that we don't change the CPU state if the comparison raises any
floating point exception flags. Instead of zero-initializing this
scratch float_status, initialize it as a copy of env->fp_status. This
avoids the need to explicitly initialize settings like the NaN
propagation rule or others we might add to softfloat in future.
To do this we need to pass the CPU env pointer in to the helper.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-33-peter.maydell@linaro.org
---
target/sparc/helper.h | 4 ++--
target/sparc/fop_helper.c | 8 ++++----
target/sparc/translate.c | 4 ++--
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
index 134e519a377..1ae3f0c467d 100644
--- a/target/sparc/helper.h
+++ b/target/sparc/helper.h
@@ -51,8 +51,8 @@ DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, i32, env, f64, f64)
DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, i32, env, f64, f64)
DEF_HELPER_FLAGS_3(fcmpq, TCG_CALL_NO_WG, i32, env, i128, i128)
DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_WG, i32, env, i128, i128)
-DEF_HELPER_FLAGS_2(flcmps, TCG_CALL_NO_RWG_SE, i32, f32, f32)
-DEF_HELPER_FLAGS_2(flcmpd, TCG_CALL_NO_RWG_SE, i32, f64, f64)
+DEF_HELPER_FLAGS_3(flcmps, TCG_CALL_NO_RWG_SE, i32, env, f32, f32)
+DEF_HELPER_FLAGS_3(flcmpd, TCG_CALL_NO_RWG_SE, i32, env, f64, f64)
DEF_HELPER_2(raise_exception, noreturn, env, int)
DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index 6f9ccc008a0..236d27b19c1 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -490,13 +490,13 @@ uint32_t helper_fcmpeq(CPUSPARCState *env, Int128 src1, Int128 src2)
return finish_fcmp(env, r, GETPC());
}
-uint32_t helper_flcmps(float32 src1, float32 src2)
+uint32_t helper_flcmps(CPUSPARCState *env, float32 src1, float32 src2)
{
/*
* FLCMP never raises an exception nor modifies any FSR fields.
* Perform the comparison with a dummy fp environment.
*/
- float_status discard = { };
+ float_status discard = env->fp_status;
FloatRelation r;
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
@@ -518,9 +518,9 @@ uint32_t helper_flcmps(float32 src1, float32 src2)
g_assert_not_reached();
}
-uint32_t helper_flcmpd(float64 src1, float64 src2)
+uint32_t helper_flcmpd(CPUSPARCState *env, float64 src1, float64 src2)
{
- float_status discard = { };
+ float_status discard = env->fp_status;
FloatRelation r;
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
index cdd0a95c03d..322319a1288 100644
--- a/target/sparc/translate.c
+++ b/target/sparc/translate.c
@@ -5584,7 +5584,7 @@ static bool trans_FLCMPs(DisasContext *dc, arg_FLCMPs *a)
src1 = gen_load_fpr_F(dc, a->rs1);
src2 = gen_load_fpr_F(dc, a->rs2);
- gen_helper_flcmps(cpu_fcc[a->cc], src1, src2);
+ gen_helper_flcmps(cpu_fcc[a->cc], tcg_env, src1, src2);
return advance_pc(dc);
}
@@ -5601,7 +5601,7 @@ static bool trans_FLCMPd(DisasContext *dc, arg_FLCMPd *a)
src1 = gen_load_fpr_D(dc, a->rs1);
src2 = gen_load_fpr_D(dc, a->rs2);
- gen_helper_flcmpd(cpu_fcc[a->cc], src1, src2);
+ gen_helper_flcmpd(cpu_fcc[a->cc], tcg_env, src1, src2);
return advance_pc(dc);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 38/72] target/ppc: Use env->fp_status in helper_compute_fprf functions
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (36 preceding siblings ...)
2024-12-11 16:19 ` [PULL 37/72] target/sparc: Initialize local scratch float_status from env->fp_status Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 39/72] target/arm: Copy entire float_status in is_ebf Peter Maydell
` (34 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
In the helper_compute_fprf functions, we pass a dummy float_status
in to the is_signaling_nan() function. This is unnecessary, because
we have convenient access to the CPU env pointer here and that
is already set up with the correct values for the snan_bit_is_one
and no_signaling_nans config settings. is_signaling_nan() doesn't
ever update the fp_status with any exception flags, so there is
no reason not to use env->fp_status here.
Use env->fp_status instead of the dummy fp_status.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-34-peter.maydell@linaro.org
---
target/ppc/fpu_helper.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 230466a87f3..d93cfed17b4 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -155,8 +155,7 @@ void helper_compute_fprf_##tp(CPUPPCState *env, tp arg) \
} else if (tp##_is_infinity(arg)) { \
fprf = neg ? 0x09 << FPSCR_FPRF : 0x05 << FPSCR_FPRF; \
} else { \
- float_status dummy = { }; /* snan_bit_is_one = 0 */ \
- if (tp##_is_signaling_nan(arg, &dummy)) { \
+ if (tp##_is_signaling_nan(arg, &env->fp_status)) { \
fprf = 0x00 << FPSCR_FPRF; \
} else { \
fprf = 0x11 << FPSCR_FPRF; \
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 39/72] target/arm: Copy entire float_status in is_ebf
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (37 preceding siblings ...)
2024-12-11 16:19 ` [PULL 38/72] target/ppc: Use env->fp_status in helper_compute_fprf functions Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 40/72] fpu: Allow runtime choice of default NaN value Peter Maydell
` (33 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
From: Richard Henderson <richard.henderson@linaro.org>
Now that float_status has a bunch of fp parameters,
it is easier to copy an existing structure than create
one from scratch. Begin by copying the structure that
corresponds to the FPSR and make only the adjustments
required for BFloat16 semantics.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20241203203949.483774-2-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
target/arm/tcg/vec_helper.c | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)
diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c
index e825d501a22..ad6f26545ac 100644
--- a/target/arm/tcg/vec_helper.c
+++ b/target/arm/tcg/vec_helper.c
@@ -2813,25 +2813,19 @@ bool is_ebf(CPUARMState *env, float_status *statusp, float_status *oddstatusp)
* no effect on AArch32 instructions.
*/
bool ebf = is_a64(env) && env->vfp.fpcr & FPCR_EBF;
- *statusp = (float_status){
- .tininess_before_rounding = float_tininess_before_rounding,
- .float_rounding_mode = float_round_to_odd_inf,
- .flush_to_zero = true,
- .flush_inputs_to_zero = true,
- .default_nan_mode = true,
- };
+
+ *statusp = env->vfp.fp_status;
+ set_default_nan_mode(true, statusp);
if (ebf) {
- float_status *fpst = &env->vfp.fp_status;
- set_flush_to_zero(get_flush_to_zero(fpst), statusp);
- set_flush_inputs_to_zero(get_flush_inputs_to_zero(fpst), statusp);
- set_float_rounding_mode(get_float_rounding_mode(fpst), statusp);
-
/* EBF=1 needs to do a step with round-to-odd semantics */
*oddstatusp = *statusp;
set_float_rounding_mode(float_round_to_odd, oddstatusp);
+ } else {
+ set_flush_to_zero(true, statusp);
+ set_flush_inputs_to_zero(true, statusp);
+ set_float_rounding_mode(float_round_to_odd_inf, statusp);
}
-
return ebf;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 40/72] fpu: Allow runtime choice of default NaN value
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (38 preceding siblings ...)
2024-12-11 16:19 ` [PULL 39/72] target/arm: Copy entire float_status in is_ebf Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 41/72] tests/fp: Set default NaN pattern explicitly Peter Maydell
` (32 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Currently we hardcode the default NaN value in parts64_default_nan()
using a compile-time ifdef ladder. This is awkward for two cases:
* for single-QEMU-binary we can't hard-code target-specifics like this
* for Arm FEAT_AFP the default NaN value depends on FPCR.AH
(specifically the sign bit is different)
Add a field to float_status to specify the default NaN value; fall
back to the old ifdef behaviour if these are not set.
The default NaN value is specified by setting a uint8_t to a
pattern corresponding to the sign and upper fraction parts of
the NaN; the lower bits of the fraction are set from bit 0 of
the pattern.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-35-peter.maydell@linaro.org
---
include/fpu/softfloat-helpers.h | 11 +++++++
include/fpu/softfloat-types.h | 10 ++++++
fpu/softfloat-specialize.c.inc | 55 ++++++++++++++++++++-------------
3 files changed, 54 insertions(+), 22 deletions(-)
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
index 10a6763532c..dceee23c823 100644
--- a/include/fpu/softfloat-helpers.h
+++ b/include/fpu/softfloat-helpers.h
@@ -93,6 +93,12 @@ static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
status->float_infzeronan_rule = rule;
}
+static inline void set_float_default_nan_pattern(uint8_t dnan_pattern,
+ float_status *status)
+{
+ status->default_nan_pattern = dnan_pattern;
+}
+
static inline void set_flush_to_zero(bool val, float_status *status)
{
status->flush_to_zero = val;
@@ -154,6 +160,11 @@ static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status
return status->float_infzeronan_rule;
}
+static inline uint8_t get_float_default_nan_pattern(float_status *status)
+{
+ return status->default_nan_pattern;
+}
+
static inline bool get_flush_to_zero(float_status *status)
{
return status->flush_to_zero;
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 84ba4ed20e6..79ca44dcc30 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -303,6 +303,16 @@ typedef struct float_status {
/* should denormalised inputs go to zero and set the input_denormal flag? */
bool flush_inputs_to_zero;
bool default_nan_mode;
+ /*
+ * The pattern to use for the default NaN. Here the high bit specifies
+ * the default NaN's sign bit, and bits 6..0 specify the high bits of the
+ * fractional part. The low bits of the fractional part are copies of bit 0.
+ * The exponent of the default NaN is (as for any NaN) always all 1s.
+ * Note that a value of 0 here is not a valid NaN. The target must set
+ * this to the correct non-zero value, or we will assert when trying to
+ * create a default NaN.
+ */
+ uint8_t default_nan_pattern;
/*
* The flags below are not used on all specializations and may
* constant fold away (see snan_bit_is_one()/no_signalling_nans() in
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 9f913ce20ab..b1ec534983c 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -133,35 +133,46 @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
{
bool sign = 0;
uint64_t frac;
+ uint8_t dnan_pattern = status->default_nan_pattern;
+ if (dnan_pattern == 0) {
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
- /* !snan_bit_is_one, set all bits */
- frac = (1ULL << DECOMPOSED_BINARY_POINT) - 1;
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
+ /* Sign bit clear, all frac bits set */
+ dnan_pattern = 0b01111111;
+#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
|| defined(TARGET_MICROBLAZE)
- /* !snan_bit_is_one, set sign and msb */
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
- sign = 1;
+ /* Sign bit set, most significant frac bit set */
+ dnan_pattern = 0b11000000;
#elif defined(TARGET_HPPA)
- /* snan_bit_is_one, set msb-1. */
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 2);
+ /* Sign bit clear, msb-1 frac bit set */
+ dnan_pattern = 0b00100000;
#elif defined(TARGET_HEXAGON)
- sign = 1;
- frac = ~0ULL;
+ /* Sign bit set, all frac bits set. */
+ dnan_pattern = 0b11111111;
#else
- /*
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
- * do not have floating-point.
- */
- if (snan_bit_is_one(status)) {
- /* set all bits other than msb */
- frac = (1ULL << (DECOMPOSED_BINARY_POINT - 1)) - 1;
- } else {
- /* set msb */
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
- }
+ /*
+ * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
+ * S390, SH4, TriCore, and Xtensa. Our other supported targets
+ * do not have floating-point.
+ */
+ if (snan_bit_is_one(status)) {
+ /* sign bit clear, set all frac bits other than msb */
+ dnan_pattern = 0b00111111;
+ } else {
+ /* sign bit clear, set frac msb */
+ dnan_pattern = 0b01000000;
+ }
#endif
+ }
+ assert(dnan_pattern != 0);
+
+ sign = dnan_pattern >> 7;
+ /*
+ * Place default_nan_pattern [6:0] into bits [62:56],
+ * and replecate bit [0] down into [55:0]
+ */
+ frac = deposit64(0, DECOMPOSED_BINARY_POINT - 7, 7, dnan_pattern);
+ frac = deposit64(frac, 0, DECOMPOSED_BINARY_POINT - 7, -(dnan_pattern & 1));
*p = (FloatParts64) {
.cls = float_class_qnan,
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 41/72] tests/fp: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (39 preceding siblings ...)
2024-12-11 16:19 ` [PULL 40/72] fpu: Allow runtime choice of default NaN value Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 42/72] target/microblaze: " Peter Maydell
` (31 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly for the tests/fp code.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-36-peter.maydell@linaro.org
---
tests/fp/fp-bench.c | 1 +
tests/fp/fp-test-log2.c | 1 +
tests/fp/fp-test.c | 1 +
3 files changed, 3 insertions(+)
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
index 39d80c9038f..eacb39b99cb 100644
--- a/tests/fp/fp-bench.c
+++ b/tests/fp/fp-bench.c
@@ -495,6 +495,7 @@ static void run_bench(void)
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
+ set_float_default_nan_pattern(0b01000000, &soft_status);
f = bench_funcs[operation][precision];
g_assert(f);
diff --git a/tests/fp/fp-test-log2.c b/tests/fp/fp-test-log2.c
index de702c4c80d..79f619cdea9 100644
--- a/tests/fp/fp-test-log2.c
+++ b/tests/fp/fp-test-log2.c
@@ -71,6 +71,7 @@ int main(int ac, char **av)
int i;
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
+ set_float_default_nan_pattern(0b01000000, &qsf);
set_float_rounding_mode(float_round_nearest_even, &qsf);
test.d = 0.0;
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
index f290d523ab1..c619e5dbf72 100644
--- a/tests/fp/fp-test.c
+++ b/tests/fp/fp-test.c
@@ -941,6 +941,7 @@ void run_test(void)
*/
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
+ set_float_default_nan_pattern(0b01000000, &qsf);
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
genCases_setLevel(test_level);
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 42/72] target/microblaze: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (40 preceding siblings ...)
2024-12-11 16:19 ` [PULL 41/72] tests/fp: Set default NaN pattern explicitly Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 43/72] target/i386: " Peter Maydell
` (30 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly, and remove the ifdef from
parts64_default_nan().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-37-peter.maydell@linaro.org
---
target/microblaze/cpu.c | 2 ++
fpu/softfloat-specialize.c.inc | 3 +--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 710eb1146c1..0e1e22d1e8e 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -207,6 +207,8 @@ static void mb_cpu_reset_hold(Object *obj, ResetType type)
* this architecture.
*/
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
+ /* Default NaN: sign bit set, most significant frac bit set */
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
#if defined(CONFIG_USER_ONLY)
/* start in user mode with interrupts enabled. */
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index b1ec534983c..d77404f0c47 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -139,8 +139,7 @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
/* Sign bit clear, all frac bits set */
dnan_pattern = 0b01111111;
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
- || defined(TARGET_MICROBLAZE)
+#elif defined(TARGET_I386) || defined(TARGET_X86_64)
/* Sign bit set, most significant frac bit set */
dnan_pattern = 0b11000000;
#elif defined(TARGET_HPPA)
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 43/72] target/i386: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (41 preceding siblings ...)
2024-12-11 16:19 ` [PULL 42/72] target/microblaze: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 44/72] target/hppa: " Peter Maydell
` (29 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly, and remove the ifdef from
parts64_default_nan().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-38-peter.maydell@linaro.org
---
target/i386/tcg/fpu_helper.c | 4 ++++
fpu/softfloat-specialize.c.inc | 3 ---
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index 4303b3356aa..d0a1e2f3c8a 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -181,6 +181,10 @@ void cpu_init_fp_statuses(CPUX86State *env)
*/
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
+ /* Default NaN: sign bit set, most significant frac bit set */
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
+ set_float_default_nan_pattern(0b11000000, &env->mmx_status);
+ set_float_default_nan_pattern(0b11000000, &env->sse_status);
}
static inline uint8_t save_exception_flags(CPUX86State *env)
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index d77404f0c47..452fe378cd2 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -139,9 +139,6 @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
/* Sign bit clear, all frac bits set */
dnan_pattern = 0b01111111;
-#elif defined(TARGET_I386) || defined(TARGET_X86_64)
- /* Sign bit set, most significant frac bit set */
- dnan_pattern = 0b11000000;
#elif defined(TARGET_HPPA)
/* Sign bit clear, msb-1 frac bit set */
dnan_pattern = 0b00100000;
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 44/72] target/hppa: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (42 preceding siblings ...)
2024-12-11 16:19 ` [PULL 43/72] target/i386: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 45/72] target/alpha: " Peter Maydell
` (28 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly, and remove the ifdef from
parts64_default_nan().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-39-peter.maydell@linaro.org
---
target/hppa/fpu_helper.c | 2 ++
fpu/softfloat-specialize.c.inc | 3 ---
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
index 69c4ce37835..239c027ec52 100644
--- a/target/hppa/fpu_helper.c
+++ b/target/hppa/fpu_helper.c
@@ -65,6 +65,8 @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
/* For inf * 0 + NaN, return the input NaN */
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
+ /* Default NaN: sign bit clear, msb-1 frac bit set */
+ set_float_default_nan_pattern(0b00100000, &env->fp_status);
}
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 452fe378cd2..b5ec1944d15 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -139,9 +139,6 @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
/* Sign bit clear, all frac bits set */
dnan_pattern = 0b01111111;
-#elif defined(TARGET_HPPA)
- /* Sign bit clear, msb-1 frac bit set */
- dnan_pattern = 0b00100000;
#elif defined(TARGET_HEXAGON)
/* Sign bit set, all frac bits set. */
dnan_pattern = 0b11111111;
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 45/72] target/alpha: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (43 preceding siblings ...)
2024-12-11 16:19 ` [PULL 44/72] target/hppa: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 46/72] target/arm: " Peter Maydell
` (27 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly for the alpha target.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-40-peter.maydell@linaro.org
---
target/alpha/cpu.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index 5d75c941f7a..70f67e6fd4e 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -199,6 +199,8 @@ static void alpha_cpu_initfn(Object *obj)
* operand in Fa. That is float_2nan_prop_ba.
*/
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
+ /* Default NaN: sign bit clear, msb frac bit set */
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
#if defined(CONFIG_USER_ONLY)
env->flags = ENV_FLAG_PS_USER | ENV_FLAG_FEN;
cpu_alpha_store_fpcr(env, (uint64_t)(FPCR_INVD | FPCR_DZED | FPCR_OVFD
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 46/72] target/arm: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (44 preceding siblings ...)
2024-12-11 16:19 ` [PULL 45/72] target/alpha: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 47/72] target/loongarch: " Peter Maydell
` (26 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly for the arm target.
This includes setting it for the old linux-user nwfpe emulation.
For nwfpe, our default doesn't match the real kernel, but we
avoid making a behaviour change in this commit.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-41-peter.maydell@linaro.org
---
linux-user/arm/nwfpe/fpa11.c | 5 +++++
target/arm/cpu.c | 2 ++
2 files changed, 7 insertions(+)
diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
index 8356beb52c6..0f1afbd91df 100644
--- a/linux-user/arm/nwfpe/fpa11.c
+++ b/linux-user/arm/nwfpe/fpa11.c
@@ -69,6 +69,11 @@ void resetFPA11(void)
* this late date.
*/
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &fpa11->fp_status);
+ /*
+ * Use the same default NaN value as Arm VFP. This doesn't match
+ * the Linux kernel's nwfpe emulation, which uses an all-1s value.
+ */
+ set_float_default_nan_pattern(0b01000000, &fpa11->fp_status);
}
void SetRoundingMode(const unsigned int opcode)
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index c81f6df3fca..4f7e18eb8e6 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -179,6 +179,7 @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
* the pseudocode function the arguments are in the order c, a, b.
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
* and the input NaN if it is signalling
+ * * Default NaN has sign bit clear, msb frac bit set
*/
static void arm_set_default_fp_behaviours(float_status *s)
{
@@ -186,6 +187,7 @@ static void arm_set_default_fp_behaviours(float_status *s)
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
+ set_float_default_nan_pattern(0b01000000, s);
}
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 47/72] target/loongarch: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (45 preceding siblings ...)
2024-12-11 16:19 ` [PULL 46/72] target/arm: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 48/72] target/m68k: " Peter Maydell
` (25 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly for loongarch.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-42-peter.maydell@linaro.org
---
target/loongarch/tcg/fpu_helper.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
index aea5e0fe5e6..a83acf64b08 100644
--- a/target/loongarch/tcg/fpu_helper.c
+++ b/target/loongarch/tcg/fpu_helper.c
@@ -38,6 +38,8 @@ void restore_fp_status(CPULoongArchState *env)
*/
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
+ /* Default NaN: sign bit clear, msb frac bit set */
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
}
int ieee_ex_to_loongarch(int xcpt)
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 48/72] target/m68k: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (46 preceding siblings ...)
2024-12-11 16:19 ` [PULL 47/72] target/loongarch: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 49/72] target/mips: " Peter Maydell
` (24 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly for m68k.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-43-peter.maydell@linaro.org
---
target/m68k/cpu.c | 2 ++
fpu/softfloat-specialize.c.inc | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 13b76e22488..9de8ce67078 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -105,6 +105,8 @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
* preceding paragraph for nonsignaling NaNs.
*/
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
+ /* Default NaN: sign bit clear, all frac bits set */
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
nan = floatx80_default_nan(&env->fp_status);
for (i = 0; i < 8; i++) {
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index b5ec1944d15..ecb7a52ae7c 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -136,7 +136,7 @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
uint8_t dnan_pattern = status->default_nan_pattern;
if (dnan_pattern == 0) {
-#if defined(TARGET_SPARC) || defined(TARGET_M68K)
+#if defined(TARGET_SPARC)
/* Sign bit clear, all frac bits set */
dnan_pattern = 0b01111111;
#elif defined(TARGET_HEXAGON)
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 49/72] target/mips: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (47 preceding siblings ...)
2024-12-11 16:19 ` [PULL 48/72] target/m68k: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 50/72] target/openrisc: " Peter Maydell
` (23 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly for MIPS. Note that this
is our only target which currently changes the default NaN
at runtime (which it was previously doing indirectly when it
changed the snan_bit_is_one setting).
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-44-peter.maydell@linaro.org
---
target/mips/fpu_helper.h | 7 +++++++
target/mips/msa.c | 3 +++
2 files changed, 10 insertions(+)
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
index 8ca0ca7ea39..6ad1e466cfd 100644
--- a/target/mips/fpu_helper.h
+++ b/target/mips/fpu_helper.h
@@ -47,6 +47,13 @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
+ /*
+ * With nan2008, the default NaN value has the sign bit clear and the
+ * frac msb set; with the older mode, the sign bit is clear, and all
+ * frac bits except the msb are set.
+ */
+ set_float_default_nan_pattern(nan2008 ? 0b01000000 : 0b00111111,
+ &env->active_fpu.fp_status);
}
diff --git a/target/mips/msa.c b/target/mips/msa.c
index 93a9a87d76d..fc77bfc7b9a 100644
--- a/target/mips/msa.c
+++ b/target/mips/msa.c
@@ -81,4 +81,7 @@ void msa_reset(CPUMIPSState *env)
/* Inf * 0 + NaN returns the input NaN */
set_float_infzeronan_rule(float_infzeronan_dnan_never,
&env->active_tc.msa_fp_status);
+ /* Default NaN: sign bit clear, frac msb set */
+ set_float_default_nan_pattern(0b01000000,
+ &env->active_tc.msa_fp_status);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 50/72] target/openrisc: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (48 preceding siblings ...)
2024-12-11 16:19 ` [PULL 49/72] target/mips: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 51/72] target/ppc: " Peter Maydell
` (22 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly for openrisc.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-45-peter.maydell@linaro.org
---
target/openrisc/cpu.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index b96561d1f26..3ccf85e95f0 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -111,6 +111,8 @@ static void openrisc_cpu_reset_hold(Object *obj, ResetType type)
*/
set_float_2nan_prop_rule(float_2nan_prop_x87, &cpu->env.fp_status);
+ /* Default NaN: sign bit clear, frac msb set */
+ set_float_default_nan_pattern(0b01000000, &cpu->env.fp_status);
#ifndef CONFIG_USER_ONLY
cpu->env.picmr = 0x00000000;
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 51/72] target/ppc: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (49 preceding siblings ...)
2024-12-11 16:19 ` [PULL 50/72] target/openrisc: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 52/72] target/sh4: " Peter Maydell
` (21 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly for ppc.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-46-peter.maydell@linaro.org
---
target/ppc/cpu_init.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index eb9d7b13701..1253dbf622c 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -7286,6 +7286,10 @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
+ /* Default NaN: sign bit clear, set frac msb */
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
+ set_float_default_nan_pattern(0b01000000, &env->vec_status);
+
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
ppc_spr_t *spr = &env->spr_cb[i];
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 52/72] target/sh4: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (50 preceding siblings ...)
2024-12-11 16:19 ` [PULL 51/72] target/ppc: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 53/72] target/rx: " Peter Maydell
` (20 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly for sh4. Note that sh4
is one of the only three targets (the others being HPPA and
sometimes MIPS) that has snan_bit_is_one set.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-47-peter.maydell@linaro.org
---
target/sh4/cpu.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index 8f07261dcfd..d5008859b8e 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -127,6 +127,8 @@ static void superh_cpu_reset_hold(Object *obj, ResetType type)
set_flush_to_zero(1, &env->fp_status);
#endif
set_default_nan_mode(1, &env->fp_status);
+ /* sign bit clear, set all frac bits other than msb */
+ set_float_default_nan_pattern(0b00111111, &env->fp_status);
}
static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 53/72] target/rx: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (51 preceding siblings ...)
2024-12-11 16:19 ` [PULL 52/72] target/sh4: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 54/72] target/s390x: " Peter Maydell
` (19 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly for rx.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-48-peter.maydell@linaro.org
---
target/rx/cpu.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index 65a74ce720f..69ec0bc7b3d 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -100,6 +100,8 @@ static void rx_cpu_reset_hold(Object *obj, ResetType type)
* then prefer dest over source", which is float_2nan_prop_s_ab.
*/
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
+ /* Default NaN value: sign bit clear, set frac msb */
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
}
static ObjectClass *rx_cpu_class_by_name(const char *cpu_model)
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 54/72] target/s390x: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (52 preceding siblings ...)
2024-12-11 16:19 ` [PULL 53/72] target/rx: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 55/72] target/sparc: " Peter Maydell
` (18 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly for s390x.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-49-peter.maydell@linaro.org
---
target/s390x/cpu.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index e74055bad79..adb27504ad5 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -209,6 +209,8 @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
set_float_infzeronan_rule(float_infzeronan_dnan_always,
&env->fpu_status);
+ /* Default NaN value: sign bit clear, frac msb set */
+ set_float_default_nan_pattern(0b01000000, &env->fpu_status);
/* fall through */
case RESET_TYPE_S390_CPU_NORMAL:
env->psw.mask &= ~PSW_MASK_RI;
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 55/72] target/sparc: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (53 preceding siblings ...)
2024-12-11 16:19 ` [PULL 54/72] target/s390x: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 56/72] target/xtensa: " Peter Maydell
` (17 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly for SPARC, and remove
the ifdef from parts64_default_nan.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-50-peter.maydell@linaro.org
---
target/sparc/cpu.c | 2 ++
fpu/softfloat-specialize.c.inc | 5 +----
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 0f2997a85e6..6b66ecb3f59 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -818,6 +818,8 @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
/* For inf * 0 + NaN, return the input NaN */
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
+ /* Default NaN value: sign bit clear, all frac bits set */
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
cpu_exec_realizefn(cs, &local_err);
if (local_err != NULL) {
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index ecb7a52ae7c..06185237d0f 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -136,10 +136,7 @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
uint8_t dnan_pattern = status->default_nan_pattern;
if (dnan_pattern == 0) {
-#if defined(TARGET_SPARC)
- /* Sign bit clear, all frac bits set */
- dnan_pattern = 0b01111111;
-#elif defined(TARGET_HEXAGON)
+#if defined(TARGET_HEXAGON)
/* Sign bit set, all frac bits set. */
dnan_pattern = 0b11111111;
#else
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 56/72] target/xtensa: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (54 preceding siblings ...)
2024-12-11 16:19 ` [PULL 55/72] target/sparc: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 57/72] target/hexagon: " Peter Maydell
` (16 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly for xtensa.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-51-peter.maydell@linaro.org
---
target/xtensa/cpu.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 3163b758235..0d4d79b58b4 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -136,6 +136,8 @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
/* For inf * 0 + NaN, return the input NaN */
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
set_no_signaling_nans(!dfpu, &env->fp_status);
+ /* Default NaN value: sign bit clear, set frac msb */
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
xtensa_use_first_nan(env, !dfpu);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 57/72] target/hexagon: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (55 preceding siblings ...)
2024-12-11 16:19 ` [PULL 56/72] target/xtensa: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 58/72] target/riscv: " Peter Maydell
` (15 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly for hexagon.
Remove the ifdef from parts64_default_nan(); the only
remaining unconverted targets all use the default case.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-52-peter.maydell@linaro.org
---
target/hexagon/cpu.c | 2 ++
fpu/softfloat-specialize.c.inc | 5 -----
2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 020038fc490..c9aa9408ec8 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -286,6 +286,8 @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
set_default_nan_mode(1, &env->fp_status);
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
+ /* Default NaN value: sign bit set, all frac bits set */
+ set_float_default_nan_pattern(0b11111111, &env->fp_status);
}
static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info)
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 06185237d0f..5954a6213b9 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -136,10 +136,6 @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
uint8_t dnan_pattern = status->default_nan_pattern;
if (dnan_pattern == 0) {
-#if defined(TARGET_HEXAGON)
- /* Sign bit set, all frac bits set. */
- dnan_pattern = 0b11111111;
-#else
/*
* This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
* S390, SH4, TriCore, and Xtensa. Our other supported targets
@@ -152,7 +148,6 @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
/* sign bit clear, set frac msb */
dnan_pattern = 0b01000000;
}
-#endif
}
assert(dnan_pattern != 0);
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 58/72] target/riscv: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (56 preceding siblings ...)
2024-12-11 16:19 ` [PULL 57/72] target/hexagon: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 59/72] target/tricore: " Peter Maydell
` (14 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly for riscv.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-53-peter.maydell@linaro.org
---
target/riscv/cpu.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index f219f0c3b52..80b09952e78 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1022,6 +1022,8 @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
cs->exception_index = RISCV_EXCP_NONE;
env->load_res = -1;
set_default_nan_mode(1, &env->fp_status);
+ /* Default NaN value: sign bit clear, frac msb set */
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
env->vill = true;
#ifndef CONFIG_USER_ONLY
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 59/72] target/tricore: Set default NaN pattern explicitly
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (57 preceding siblings ...)
2024-12-11 16:19 ` [PULL 58/72] target/riscv: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 60/72] fpu: Remove default handling for dnan_pattern Peter Maydell
` (13 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Set the default NaN pattern explicitly for tricore.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-54-peter.maydell@linaro.org
---
target/tricore/helper.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/target/tricore/helper.c b/target/tricore/helper.c
index 7014255f77c..e8b0ec51611 100644
--- a/target/tricore/helper.c
+++ b/target/tricore/helper.c
@@ -117,6 +117,8 @@ void fpu_set_state(CPUTriCoreState *env)
set_flush_to_zero(1, &env->fp_status);
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
set_default_nan_mode(1, &env->fp_status);
+ /* Default NaN pattern: sign bit clear, frac msb set */
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
}
uint32_t psw_read(CPUTriCoreState *env)
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 60/72] fpu: Remove default handling for dnan_pattern
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (58 preceding siblings ...)
2024-12-11 16:19 ` [PULL 59/72] target/tricore: " Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 61/72] softfloat: Inline pickNaNMulAdd Peter Maydell
` (12 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
Now that all our targets have bene converted to explicitly specify
their pattern for the default NaN value we can remove the remaining
fallback code in parts64_default_nan().
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241202131347.498124-55-peter.maydell@linaro.org
---
fpu/softfloat-specialize.c.inc | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 5954a6213b9..e075c47889a 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -135,20 +135,6 @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
uint64_t frac;
uint8_t dnan_pattern = status->default_nan_pattern;
- if (dnan_pattern == 0) {
- /*
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
- * do not have floating-point.
- */
- if (snan_bit_is_one(status)) {
- /* sign bit clear, set all frac bits other than msb */
- dnan_pattern = 0b00111111;
- } else {
- /* sign bit clear, set frac msb */
- dnan_pattern = 0b01000000;
- }
- }
assert(dnan_pattern != 0);
sign = dnan_pattern >> 7;
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 61/72] softfloat: Inline pickNaNMulAdd
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (59 preceding siblings ...)
2024-12-11 16:19 ` [PULL 60/72] fpu: Remove default handling for dnan_pattern Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 62/72] softfloat: Use goto for default nan case in pick_nan_muladd Peter Maydell
` (11 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
From: Richard Henderson <richard.henderson@linaro.org>
Inline pickNaNMulAdd into its only caller. This makes
one assert redundant with the immediately preceding IF.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20241203203949.483774-3-richard.henderson@linaro.org
[PMM: keep comment from old code in new location]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat-parts.c.inc | 41 +++++++++++++++++++++++++-
fpu/softfloat-specialize.c.inc | 54 ----------------------------------
2 files changed, 40 insertions(+), 55 deletions(-)
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 655b7d9da51..c1a97c35b20 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -79,9 +79,48 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
}
if (s->default_nan_mode) {
+ /*
+ * We guarantee not to require the target to tell us how to
+ * pick a NaN if we're always returning the default NaN.
+ * But if we're not in default-NaN mode then the target must
+ * specify.
+ */
which = 3;
+ } else if (infzero) {
+ /*
+ * Inf * 0 + NaN -- some implementations return the
+ * default NaN here, and some return the input NaN.
+ */
+ switch (s->float_infzeronan_rule) {
+ case float_infzeronan_dnan_never:
+ which = 2;
+ break;
+ case float_infzeronan_dnan_always:
+ which = 3;
+ break;
+ case float_infzeronan_dnan_if_qnan:
+ which = is_qnan(c->cls) ? 3 : 2;
+ break;
+ default:
+ g_assert_not_reached();
+ }
} else {
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, have_snan, s);
+ FloatClass cls[3] = { a->cls, b->cls, c->cls };
+ Float3NaNPropRule rule = s->float_3nan_prop_rule;
+
+ assert(rule != float_3nan_prop_none);
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
+ /* We have at least one SNaN input and should prefer it */
+ do {
+ which = rule & R_3NAN_1ST_MASK;
+ rule >>= R_3NAN_1ST_LENGTH;
+ } while (!is_snan(cls[which]));
+ } else {
+ do {
+ which = rule & R_3NAN_1ST_MASK;
+ rule >>= R_3NAN_1ST_LENGTH;
+ } while (!is_nan(cls[which]));
+ }
}
if (which == 3) {
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index e075c47889a..f26458eaa31 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -448,60 +448,6 @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
}
}
-/*----------------------------------------------------------------------------
-| Select which NaN to propagate for a three-input operation.
-| For the moment we assume that no CPU needs the 'larger significand'
-| information.
-| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
-*----------------------------------------------------------------------------*/
-static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
- bool infzero, bool have_snan, float_status *status)
-{
- FloatClass cls[3] = { a_cls, b_cls, c_cls };
- Float3NaNPropRule rule = status->float_3nan_prop_rule;
- int which;
-
- /*
- * We guarantee not to require the target to tell us how to
- * pick a NaN if we're always returning the default NaN.
- * But if we're not in default-NaN mode then the target must
- * specify.
- */
- assert(!status->default_nan_mode);
-
- if (infzero) {
- /*
- * Inf * 0 + NaN -- some implementations return the default NaN here,
- * and some return the input NaN.
- */
- switch (status->float_infzeronan_rule) {
- case float_infzeronan_dnan_never:
- return 2;
- case float_infzeronan_dnan_always:
- return 3;
- case float_infzeronan_dnan_if_qnan:
- return is_qnan(c_cls) ? 3 : 2;
- default:
- g_assert_not_reached();
- }
- }
-
- assert(rule != float_3nan_prop_none);
- if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
- /* We have at least one SNaN input and should prefer it */
- do {
- which = rule & R_3NAN_1ST_MASK;
- rule >>= R_3NAN_1ST_LENGTH;
- } while (!is_snan(cls[which]));
- } else {
- do {
- which = rule & R_3NAN_1ST_MASK;
- rule >>= R_3NAN_1ST_LENGTH;
- } while (!is_nan(cls[which]));
- }
- return which;
-}
-
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is a quiet
| NaN; otherwise returns 0.
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 62/72] softfloat: Use goto for default nan case in pick_nan_muladd
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (60 preceding siblings ...)
2024-12-11 16:19 ` [PULL 61/72] softfloat: Inline pickNaNMulAdd Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 63/72] softfloat: Remove which from parts_pick_nan_muladd Peter Maydell
` (10 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
From: Richard Henderson <richard.henderson@linaro.org>
Remove "3" as a special case for which and simply
branch to return the desired value.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20241203203949.483774-4-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat-parts.c.inc | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index c1a97c35b20..be7e93127d4 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -85,7 +85,7 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
* But if we're not in default-NaN mode then the target must
* specify.
*/
- which = 3;
+ goto default_nan;
} else if (infzero) {
/*
* Inf * 0 + NaN -- some implementations return the
@@ -93,17 +93,18 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
*/
switch (s->float_infzeronan_rule) {
case float_infzeronan_dnan_never:
- which = 2;
break;
case float_infzeronan_dnan_always:
- which = 3;
- break;
+ goto default_nan;
case float_infzeronan_dnan_if_qnan:
- which = is_qnan(c->cls) ? 3 : 2;
+ if (is_qnan(c->cls)) {
+ goto default_nan;
+ }
break;
default:
g_assert_not_reached();
}
+ which = 2;
} else {
FloatClass cls[3] = { a->cls, b->cls, c->cls };
Float3NaNPropRule rule = s->float_3nan_prop_rule;
@@ -123,11 +124,6 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
}
}
- if (which == 3) {
- parts_default_nan(a, s);
- return a;
- }
-
switch (which) {
case 0:
break;
@@ -144,6 +140,10 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
parts_silence_nan(a, s);
}
return a;
+
+ default_nan:
+ parts_default_nan(a, s);
+ return a;
}
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 63/72] softfloat: Remove which from parts_pick_nan_muladd
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (61 preceding siblings ...)
2024-12-11 16:19 ` [PULL 62/72] softfloat: Use goto for default nan case in pick_nan_muladd Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 64/72] softfloat: Pad array size in pick_nan_muladd Peter Maydell
` (9 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
From: Richard Henderson <richard.henderson@linaro.org>
Assign the pointer return value to 'a' directly,
rather than going through an intermediary index.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20241203203949.483774-5-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat-parts.c.inc | 32 ++++++++++----------------------
1 file changed, 10 insertions(+), 22 deletions(-)
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index be7e93127d4..525db617411 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -65,9 +65,9 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
FloatPartsN *c, float_status *s,
int ab_mask, int abc_mask)
{
- int which;
bool infzero = (ab_mask == float_cmask_infzero);
bool have_snan = (abc_mask & float_cmask_snan);
+ FloatPartsN *ret;
if (unlikely(have_snan)) {
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
@@ -104,42 +104,30 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
default:
g_assert_not_reached();
}
- which = 2;
+ ret = c;
} else {
- FloatClass cls[3] = { a->cls, b->cls, c->cls };
+ FloatPartsN *val[3] = { a, b, c };
Float3NaNPropRule rule = s->float_3nan_prop_rule;
assert(rule != float_3nan_prop_none);
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
/* We have at least one SNaN input and should prefer it */
do {
- which = rule & R_3NAN_1ST_MASK;
+ ret = val[rule & R_3NAN_1ST_MASK];
rule >>= R_3NAN_1ST_LENGTH;
- } while (!is_snan(cls[which]));
+ } while (!is_snan(ret->cls));
} else {
do {
- which = rule & R_3NAN_1ST_MASK;
+ ret = val[rule & R_3NAN_1ST_MASK];
rule >>= R_3NAN_1ST_LENGTH;
- } while (!is_nan(cls[which]));
+ } while (!is_nan(ret->cls));
}
}
- switch (which) {
- case 0:
- break;
- case 1:
- a = b;
- break;
- case 2:
- a = c;
- break;
- default:
- g_assert_not_reached();
+ if (is_snan(ret->cls)) {
+ parts_silence_nan(ret, s);
}
- if (is_snan(a->cls)) {
- parts_silence_nan(a, s);
- }
- return a;
+ return ret;
default_nan:
parts_default_nan(a, s);
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 64/72] softfloat: Pad array size in pick_nan_muladd
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (62 preceding siblings ...)
2024-12-11 16:19 ` [PULL 63/72] softfloat: Remove which from parts_pick_nan_muladd Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 65/72] softfloat: Move propagateFloatx80NaN to softfloat.c Peter Maydell
` (8 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
From: Richard Henderson <richard.henderson@linaro.org>
While all indices into val[] should be in [0-2], the mask
applied is two bits. To help static analysis see there is
no possibility of read beyond the end of the array, pad the
array to 4 entries, with the final being (implicitly) NULL.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20241203203949.483774-6-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat-parts.c.inc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 525db617411..5fcdbc87fd7 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -106,7 +106,7 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
}
ret = c;
} else {
- FloatPartsN *val[3] = { a, b, c };
+ FloatPartsN *val[R_3NAN_1ST_MASK + 1] = { a, b, c };
Float3NaNPropRule rule = s->float_3nan_prop_rule;
assert(rule != float_3nan_prop_none);
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 65/72] softfloat: Move propagateFloatx80NaN to softfloat.c
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (63 preceding siblings ...)
2024-12-11 16:19 ` [PULL 64/72] softfloat: Pad array size in pick_nan_muladd Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 66/72] softfloat: Use parts_pick_nan in propagateFloatx80NaN Peter Maydell
` (7 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
From: Richard Henderson <richard.henderson@linaro.org>
This function is part of the public interface and
is not "specialized" to any target in any way.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20241203203949.483774-7-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat.c | 52 ++++++++++++++++++++++++++++++++++
fpu/softfloat-specialize.c.inc | 52 ----------------------------------
2 files changed, 52 insertions(+), 52 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 027a8e576d3..6ba1cfd32a0 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -4920,6 +4920,58 @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
*zExpPtr = 1 - shiftCount;
}
+/*----------------------------------------------------------------------------
+| Takes two extended double-precision floating-point values `a' and `b', one
+| of which is a NaN, and returns the appropriate NaN result. If either `a' or
+| `b' is a signaling NaN, the invalid exception is raised.
+*----------------------------------------------------------------------------*/
+
+floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
+{
+ bool aIsLargerSignificand;
+ FloatClass a_cls, b_cls;
+
+ /* This is not complete, but is good enough for pickNaN. */
+ a_cls = (!floatx80_is_any_nan(a)
+ ? float_class_normal
+ : floatx80_is_signaling_nan(a, status)
+ ? float_class_snan
+ : float_class_qnan);
+ b_cls = (!floatx80_is_any_nan(b)
+ ? float_class_normal
+ : floatx80_is_signaling_nan(b, status)
+ ? float_class_snan
+ : float_class_qnan);
+
+ if (is_snan(a_cls) || is_snan(b_cls)) {
+ float_raise(float_flag_invalid, status);
+ }
+
+ if (status->default_nan_mode) {
+ return floatx80_default_nan(status);
+ }
+
+ if (a.low < b.low) {
+ aIsLargerSignificand = 0;
+ } else if (b.low < a.low) {
+ aIsLargerSignificand = 1;
+ } else {
+ aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
+ }
+
+ if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
+ if (is_snan(b_cls)) {
+ return floatx80_silence_nan(b, status);
+ }
+ return b;
+ } else {
+ if (is_snan(a_cls)) {
+ return floatx80_silence_nan(a, status);
+ }
+ return a;
+ }
+}
+
/*----------------------------------------------------------------------------
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
| and extended significand formed by the concatenation of `zSig0' and `zSig1',
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index f26458eaa31..f7a320f6ff9 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -551,58 +551,6 @@ floatx80 floatx80_silence_nan(floatx80 a, float_status *status)
return a;
}
-/*----------------------------------------------------------------------------
-| Takes two extended double-precision floating-point values `a' and `b', one
-| of which is a NaN, and returns the appropriate NaN result. If either `a' or
-| `b' is a signaling NaN, the invalid exception is raised.
-*----------------------------------------------------------------------------*/
-
-floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
-{
- bool aIsLargerSignificand;
- FloatClass a_cls, b_cls;
-
- /* This is not complete, but is good enough for pickNaN. */
- a_cls = (!floatx80_is_any_nan(a)
- ? float_class_normal
- : floatx80_is_signaling_nan(a, status)
- ? float_class_snan
- : float_class_qnan);
- b_cls = (!floatx80_is_any_nan(b)
- ? float_class_normal
- : floatx80_is_signaling_nan(b, status)
- ? float_class_snan
- : float_class_qnan);
-
- if (is_snan(a_cls) || is_snan(b_cls)) {
- float_raise(float_flag_invalid, status);
- }
-
- if (status->default_nan_mode) {
- return floatx80_default_nan(status);
- }
-
- if (a.low < b.low) {
- aIsLargerSignificand = 0;
- } else if (b.low < a.low) {
- aIsLargerSignificand = 1;
- } else {
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
- }
-
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
- if (is_snan(b_cls)) {
- return floatx80_silence_nan(b, status);
- }
- return b;
- } else {
- if (is_snan(a_cls)) {
- return floatx80_silence_nan(a, status);
- }
- return a;
- }
-}
-
/*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
| NaN; otherwise returns 0.
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 66/72] softfloat: Use parts_pick_nan in propagateFloatx80NaN
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (64 preceding siblings ...)
2024-12-11 16:19 ` [PULL 65/72] softfloat: Move propagateFloatx80NaN to softfloat.c Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:19 ` [PULL 67/72] softfloat: Inline pickNaN Peter Maydell
` (6 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
From: Richard Henderson <richard.henderson@linaro.org>
Unpacking and repacking the parts may be slightly more work
than we did before, but we get to reuse more code. For a
code path handling exceptional values, this is an improvement.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20241203203949.483774-8-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat.c | 43 +++++--------------------------------------
1 file changed, 5 insertions(+), 38 deletions(-)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 6ba1cfd32a0..8de8d5f3425 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -4928,48 +4928,15 @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
{
- bool aIsLargerSignificand;
- FloatClass a_cls, b_cls;
+ FloatParts128 pa, pb, *pr;
- /* This is not complete, but is good enough for pickNaN. */
- a_cls = (!floatx80_is_any_nan(a)
- ? float_class_normal
- : floatx80_is_signaling_nan(a, status)
- ? float_class_snan
- : float_class_qnan);
- b_cls = (!floatx80_is_any_nan(b)
- ? float_class_normal
- : floatx80_is_signaling_nan(b, status)
- ? float_class_snan
- : float_class_qnan);
-
- if (is_snan(a_cls) || is_snan(b_cls)) {
- float_raise(float_flag_invalid, status);
- }
-
- if (status->default_nan_mode) {
+ if (!floatx80_unpack_canonical(&pa, a, status) ||
+ !floatx80_unpack_canonical(&pb, b, status)) {
return floatx80_default_nan(status);
}
- if (a.low < b.low) {
- aIsLargerSignificand = 0;
- } else if (b.low < a.low) {
- aIsLargerSignificand = 1;
- } else {
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
- }
-
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
- if (is_snan(b_cls)) {
- return floatx80_silence_nan(b, status);
- }
- return b;
- } else {
- if (is_snan(a_cls)) {
- return floatx80_silence_nan(a, status);
- }
- return a;
- }
+ pr = parts_pick_nan(&pa, &pb, status);
+ return floatx80_round_pack_canonical(pr, status);
}
/*----------------------------------------------------------------------------
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 67/72] softfloat: Inline pickNaN
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (65 preceding siblings ...)
2024-12-11 16:19 ` [PULL 66/72] softfloat: Use parts_pick_nan in propagateFloatx80NaN Peter Maydell
@ 2024-12-11 16:19 ` Peter Maydell
2024-12-11 16:20 ` [PULL 68/72] softfloat: Share code between parts_pick_nan cases Peter Maydell
` (5 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:19 UTC (permalink / raw)
To: qemu-devel
From: Richard Henderson <richard.henderson@linaro.org>
Inline pickNaN into its only caller. This makes one assert
redundant with the immediately preceding IF.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20241203203949.483774-9-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat-parts.c.inc | 82 +++++++++++++++++++++++++----
fpu/softfloat-specialize.c.inc | 96 ----------------------------------
2 files changed, 73 insertions(+), 105 deletions(-)
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 5fcdbc87fd7..a1b148e90b9 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -39,24 +39,88 @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
float_status *s)
{
+ int cmp, which;
+
if (is_snan(a->cls) || is_snan(b->cls)) {
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
}
if (s->default_nan_mode) {
parts_default_nan(a, s);
- } else {
- int cmp = frac_cmp(a, b);
- if (cmp == 0) {
- cmp = a->sign < b->sign;
- }
+ return a;
+ }
- if (pickNaN(a->cls, b->cls, cmp > 0, s)) {
- a = b;
- }
+ cmp = frac_cmp(a, b);
+ if (cmp == 0) {
+ cmp = a->sign < b->sign;
+ }
+
+ switch (s->float_2nan_prop_rule) {
+ case float_2nan_prop_s_ab:
if (is_snan(a->cls)) {
- parts_silence_nan(a, s);
+ which = 0;
+ } else if (is_snan(b->cls)) {
+ which = 1;
+ } else if (is_qnan(a->cls)) {
+ which = 0;
+ } else {
+ which = 1;
}
+ break;
+ case float_2nan_prop_s_ba:
+ if (is_snan(b->cls)) {
+ which = 1;
+ } else if (is_snan(a->cls)) {
+ which = 0;
+ } else if (is_qnan(b->cls)) {
+ which = 1;
+ } else {
+ which = 0;
+ }
+ break;
+ case float_2nan_prop_ab:
+ which = is_nan(a->cls) ? 0 : 1;
+ break;
+ case float_2nan_prop_ba:
+ which = is_nan(b->cls) ? 1 : 0;
+ break;
+ case float_2nan_prop_x87:
+ /*
+ * This implements x87 NaN propagation rules:
+ * SNaN + QNaN => return the QNaN
+ * two SNaNs => return the one with the larger significand, silenced
+ * two QNaNs => return the one with the larger significand
+ * SNaN and a non-NaN => return the SNaN, silenced
+ * QNaN and a non-NaN => return the QNaN
+ *
+ * If we get down to comparing significands and they are the same,
+ * return the NaN with the positive sign bit (if any).
+ */
+ if (is_snan(a->cls)) {
+ if (is_snan(b->cls)) {
+ which = cmp > 0 ? 0 : 1;
+ } else {
+ which = is_qnan(b->cls) ? 1 : 0;
+ }
+ } else if (is_qnan(a->cls)) {
+ if (is_snan(b->cls) || !is_qnan(b->cls)) {
+ which = 0;
+ } else {
+ which = cmp > 0 ? 0 : 1;
+ }
+ } else {
+ which = 1;
+ }
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ if (which) {
+ a = b;
+ }
+ if (is_snan(a->cls)) {
+ parts_silence_nan(a, s);
}
return a;
}
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index f7a320f6ff9..cbbbab52ba3 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -352,102 +352,6 @@ bool float32_is_signaling_nan(float32 a_, float_status *status)
}
}
-/*----------------------------------------------------------------------------
-| Select which NaN to propagate for a two-input operation.
-| IEEE754 doesn't specify all the details of this, so the
-| algorithm is target-specific.
-| The routine is passed various bits of information about the
-| two NaNs and should return 0 to select NaN a and 1 for NaN b.
-| Note that signalling NaNs are always squashed to quiet NaNs
-| by the caller, by calling floatXX_silence_nan() before
-| returning them.
-|
-| aIsLargerSignificand is only valid if both a and b are NaNs
-| of some kind, and is true if a has the larger significand,
-| or if both a and b have the same significand but a is
-| positive but b is negative. It is only needed for the x87
-| tie-break rule.
-*----------------------------------------------------------------------------*/
-
-static int pickNaN(FloatClass a_cls, FloatClass b_cls,
- bool aIsLargerSignificand, float_status *status)
-{
- /*
- * We guarantee not to require the target to tell us how to
- * pick a NaN if we're always returning the default NaN.
- * But if we're not in default-NaN mode then the target must
- * specify via set_float_2nan_prop_rule().
- */
- assert(!status->default_nan_mode);
-
- switch (status->float_2nan_prop_rule) {
- case float_2nan_prop_s_ab:
- if (is_snan(a_cls)) {
- return 0;
- } else if (is_snan(b_cls)) {
- return 1;
- } else if (is_qnan(a_cls)) {
- return 0;
- } else {
- return 1;
- }
- break;
- case float_2nan_prop_s_ba:
- if (is_snan(b_cls)) {
- return 1;
- } else if (is_snan(a_cls)) {
- return 0;
- } else if (is_qnan(b_cls)) {
- return 1;
- } else {
- return 0;
- }
- break;
- case float_2nan_prop_ab:
- if (is_nan(a_cls)) {
- return 0;
- } else {
- return 1;
- }
- break;
- case float_2nan_prop_ba:
- if (is_nan(b_cls)) {
- return 1;
- } else {
- return 0;
- }
- break;
- case float_2nan_prop_x87:
- /*
- * This implements x87 NaN propagation rules:
- * SNaN + QNaN => return the QNaN
- * two SNaNs => return the one with the larger significand, silenced
- * two QNaNs => return the one with the larger significand
- * SNaN and a non-NaN => return the SNaN, silenced
- * QNaN and a non-NaN => return the QNaN
- *
- * If we get down to comparing significands and they are the same,
- * return the NaN with the positive sign bit (if any).
- */
- if (is_snan(a_cls)) {
- if (is_snan(b_cls)) {
- return aIsLargerSignificand ? 0 : 1;
- }
- return is_qnan(b_cls) ? 1 : 0;
- } else if (is_qnan(a_cls)) {
- if (is_snan(b_cls) || !is_qnan(b_cls)) {
- return 0;
- } else {
- return aIsLargerSignificand ? 0 : 1;
- }
- } else {
- return 1;
- }
- default:
- g_assert_not_reached();
- }
-}
-
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is a quiet
| NaN; otherwise returns 0.
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 68/72] softfloat: Share code between parts_pick_nan cases
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (66 preceding siblings ...)
2024-12-11 16:19 ` [PULL 67/72] softfloat: Inline pickNaN Peter Maydell
@ 2024-12-11 16:20 ` Peter Maydell
2024-12-11 16:20 ` [PULL 69/72] softfloat: Sink frac_cmp in parts_pick_nan until needed Peter Maydell
` (4 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:20 UTC (permalink / raw)
To: qemu-devel
From: Richard Henderson <richard.henderson@linaro.org>
Remember if there was an SNaN, and use that to simplify
float_2nan_prop_s_{ab,ba} to only the snan component.
Then, fall through to the corresponding
float_2nan_prop_{ab,ba} case to handle any remaining
nans, which must be quiet.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20241203203949.483774-10-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat-parts.c.inc | 32 ++++++++++++--------------------
1 file changed, 12 insertions(+), 20 deletions(-)
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index a1b148e90b9..3c77dcbb154 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -39,10 +39,12 @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
float_status *s)
{
+ bool have_snan = false;
int cmp, which;
if (is_snan(a->cls) || is_snan(b->cls)) {
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
+ have_snan = true;
}
if (s->default_nan_mode) {
@@ -57,30 +59,20 @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
switch (s->float_2nan_prop_rule) {
case float_2nan_prop_s_ab:
- if (is_snan(a->cls)) {
- which = 0;
- } else if (is_snan(b->cls)) {
- which = 1;
- } else if (is_qnan(a->cls)) {
- which = 0;
- } else {
- which = 1;
+ if (have_snan) {
+ which = is_snan(a->cls) ? 0 : 1;
+ break;
}
- break;
- case float_2nan_prop_s_ba:
- if (is_snan(b->cls)) {
- which = 1;
- } else if (is_snan(a->cls)) {
- which = 0;
- } else if (is_qnan(b->cls)) {
- which = 1;
- } else {
- which = 0;
- }
- break;
+ /* fall through */
case float_2nan_prop_ab:
which = is_nan(a->cls) ? 0 : 1;
break;
+ case float_2nan_prop_s_ba:
+ if (have_snan) {
+ which = is_snan(b->cls) ? 1 : 0;
+ break;
+ }
+ /* fall through */
case float_2nan_prop_ba:
which = is_nan(b->cls) ? 1 : 0;
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 69/72] softfloat: Sink frac_cmp in parts_pick_nan until needed
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (67 preceding siblings ...)
2024-12-11 16:20 ` [PULL 68/72] softfloat: Share code between parts_pick_nan cases Peter Maydell
@ 2024-12-11 16:20 ` Peter Maydell
2024-12-11 16:20 ` [PULL 70/72] softfloat: Replace WHICH with RET in parts_pick_nan Peter Maydell
` (3 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:20 UTC (permalink / raw)
To: qemu-devel
From: Richard Henderson <richard.henderson@linaro.org>
Move the fractional comparison to the end of the
float_2nan_prop_x87 case. This is not required for
any other 2nan propagation rule. Reorganize the
x87 case itself to break out of the switch when the
fractional comparison is not required.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20241203203949.483774-11-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat-parts.c.inc | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 3c77dcbb154..abe24aeaa00 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -52,11 +52,6 @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
return a;
}
- cmp = frac_cmp(a, b);
- if (cmp == 0) {
- cmp = a->sign < b->sign;
- }
-
switch (s->float_2nan_prop_rule) {
case float_2nan_prop_s_ab:
if (have_snan) {
@@ -89,20 +84,24 @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
* return the NaN with the positive sign bit (if any).
*/
if (is_snan(a->cls)) {
- if (is_snan(b->cls)) {
- which = cmp > 0 ? 0 : 1;
- } else {
+ if (!is_snan(b->cls)) {
which = is_qnan(b->cls) ? 1 : 0;
+ break;
}
} else if (is_qnan(a->cls)) {
if (is_snan(b->cls) || !is_qnan(b->cls)) {
which = 0;
- } else {
- which = cmp > 0 ? 0 : 1;
+ break;
}
} else {
which = 1;
+ break;
}
+ cmp = frac_cmp(a, b);
+ if (cmp == 0) {
+ cmp = a->sign < b->sign;
+ }
+ which = cmp > 0 ? 0 : 1;
break;
default:
g_assert_not_reached();
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 70/72] softfloat: Replace WHICH with RET in parts_pick_nan
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (68 preceding siblings ...)
2024-12-11 16:20 ` [PULL 69/72] softfloat: Sink frac_cmp in parts_pick_nan until needed Peter Maydell
@ 2024-12-11 16:20 ` Peter Maydell
2024-12-11 16:20 ` [PULL 71/72] MAINTAINERS: update email address for Leif Lindholm Peter Maydell
` (2 subsequent siblings)
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:20 UTC (permalink / raw)
To: qemu-devel
From: Richard Henderson <richard.henderson@linaro.org>
Replace the "index" selecting between A and B with a result variable
of the proper type. This improves clarity within the function.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20241203203949.483774-12-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
fpu/softfloat-parts.c.inc | 28 +++++++++++++---------------
1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index abe24aeaa00..ba8de7be76e 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -40,7 +40,8 @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
float_status *s)
{
bool have_snan = false;
- int cmp, which;
+ FloatPartsN *ret;
+ int cmp;
if (is_snan(a->cls) || is_snan(b->cls)) {
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
@@ -55,21 +56,21 @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
switch (s->float_2nan_prop_rule) {
case float_2nan_prop_s_ab:
if (have_snan) {
- which = is_snan(a->cls) ? 0 : 1;
+ ret = is_snan(a->cls) ? a : b;
break;
}
/* fall through */
case float_2nan_prop_ab:
- which = is_nan(a->cls) ? 0 : 1;
+ ret = is_nan(a->cls) ? a : b;
break;
case float_2nan_prop_s_ba:
if (have_snan) {
- which = is_snan(b->cls) ? 1 : 0;
+ ret = is_snan(b->cls) ? b : a;
break;
}
/* fall through */
case float_2nan_prop_ba:
- which = is_nan(b->cls) ? 1 : 0;
+ ret = is_nan(b->cls) ? b : a;
break;
case float_2nan_prop_x87:
/*
@@ -85,35 +86,32 @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
*/
if (is_snan(a->cls)) {
if (!is_snan(b->cls)) {
- which = is_qnan(b->cls) ? 1 : 0;
+ ret = is_qnan(b->cls) ? b : a;
break;
}
} else if (is_qnan(a->cls)) {
if (is_snan(b->cls) || !is_qnan(b->cls)) {
- which = 0;
+ ret = a;
break;
}
} else {
- which = 1;
+ ret = b;
break;
}
cmp = frac_cmp(a, b);
if (cmp == 0) {
cmp = a->sign < b->sign;
}
- which = cmp > 0 ? 0 : 1;
+ ret = cmp > 0 ? a : b;
break;
default:
g_assert_not_reached();
}
- if (which) {
- a = b;
+ if (is_snan(ret->cls)) {
+ parts_silence_nan(ret, s);
}
- if (is_snan(a->cls)) {
- parts_silence_nan(a, s);
- }
- return a;
+ return ret;
}
static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 71/72] MAINTAINERS: update email address for Leif Lindholm
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (69 preceding siblings ...)
2024-12-11 16:20 ` [PULL 70/72] softfloat: Replace WHICH with RET in parts_pick_nan Peter Maydell
@ 2024-12-11 16:20 ` Peter Maydell
2024-12-11 16:20 ` [PULL 72/72] MAINTAINERS: Add correct email address for Vikram Garhwal Peter Maydell
2024-12-13 1:20 ` [PULL 00/72] target-arm queue Stefan Hajnoczi
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:20 UTC (permalink / raw)
To: qemu-devel
From: Leif Lindholm <quic_llindhol@quicinc.com>
I'm migrating to Qualcomm's new open source email infrastructure, so
update my email address, and update the mailmap to match.
Signed-off-by: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20241205114047.1125842-1-leif.lindholm@oss.qualcomm.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
MAINTAINERS | 2 +-
.mailmap | 5 +++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index aaf0505a214..9ae6a78ae9c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -915,7 +915,7 @@ F: include/hw/ssi/imx_spi.h
SBSA-REF
M: Radoslaw Biernacki <rad@semihalf.com>
M: Peter Maydell <peter.maydell@linaro.org>
-R: Leif Lindholm <quic_llindhol@quicinc.com>
+R: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
L: qemu-arm@nongnu.org
S: Maintained
diff --git a/.mailmap b/.mailmap
index 727ce204b2d..5f6df414e1f 100644
--- a/.mailmap
+++ b/.mailmap
@@ -87,8 +87,9 @@ Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
Juan Quintela <quintela@trasno.org> <quintela@redhat.com>
-Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
-Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <quic_llindhol@quicinc.com>
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif.lindholm@linaro.org>
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif@nuviainc.com>
Luc Michel <luc@lmichel.fr> <luc.michel@git.antfield.fr>
Luc Michel <luc@lmichel.fr> <luc.michel@greensocs.com>
Luc Michel <luc@lmichel.fr> <lmichel@kalray.eu>
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* [PULL 72/72] MAINTAINERS: Add correct email address for Vikram Garhwal
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (70 preceding siblings ...)
2024-12-11 16:20 ` [PULL 71/72] MAINTAINERS: update email address for Leif Lindholm Peter Maydell
@ 2024-12-11 16:20 ` Peter Maydell
2024-12-13 1:20 ` [PULL 00/72] target-arm queue Stefan Hajnoczi
72 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-11 16:20 UTC (permalink / raw)
To: qemu-devel
From: Vikram Garhwal <vikram.garhwal@bytedance.com>
Previously, maintainer role was paused due to inactive email id. Commit id:
c009d715721861984c4987bcc78b7ee183e86d75.
Signed-off-by: Vikram Garhwal <vikram.garhwal@bytedance.com>
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
Message-id: 20241204184205.12952-1-vikram.garhwal@bytedance.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
MAINTAINERS | 2 ++
1 file changed, 2 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 9ae6a78ae9c..1d2003a9a1d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1914,6 +1914,7 @@ F: tests/qtest/fuzz-sb16-test.c
Xilinx CAN
M: Francisco Iglesias <francisco.iglesias@amd.com>
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
S: Maintained
F: hw/net/can/xlnx-*
F: include/hw/net/xlnx-*
@@ -2673,6 +2674,7 @@ F: include/hw/rx/
CAN bus subsystem and hardware
M: Pavel Pisa <pisa@cmp.felk.cvut.cz>
M: Francisco Iglesias <francisco.iglesias@amd.com>
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
S: Maintained
W: https://canbus.pages.fel.cvut.cz/
F: net/can/*
--
2.34.1
^ permalink raw reply related [flat|nested] 75+ messages in thread
* Re: [PULL 00/72] target-arm queue
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
` (71 preceding siblings ...)
2024-12-11 16:20 ` [PULL 72/72] MAINTAINERS: Add correct email address for Vikram Garhwal Peter Maydell
@ 2024-12-13 1:20 ` Stefan Hajnoczi
2024-12-13 10:44 ` Peter Maydell
72 siblings, 1 reply; 75+ messages in thread
From: Stefan Hajnoczi @ 2024-12-13 1:20 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 116 bytes --]
Applied, thanks.
Please update the changelog at https://wiki.qemu.org/ChangeLog/10.0 for any user-visible changes.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 75+ messages in thread
* Re: [PULL 00/72] target-arm queue
2024-12-13 1:20 ` [PULL 00/72] target-arm queue Stefan Hajnoczi
@ 2024-12-13 10:44 ` Peter Maydell
0 siblings, 0 replies; 75+ messages in thread
From: Peter Maydell @ 2024-12-13 10:44 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: qemu-devel
On Fri, 13 Dec 2024 at 01:25, Stefan Hajnoczi <stefanha@redhat.com> wrote:
>
> Applied, thanks.
This doesn't seem to have been applied -- did you forget
to push to upstream master?
thanks
-- PMM
^ permalink raw reply [flat|nested] 75+ messages in thread
end of thread, other threads:[~2024-12-13 10:45 UTC | newest]
Thread overview: 75+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-11 16:18 [PULL 00/72] target-arm queue Peter Maydell
2024-12-11 16:18 ` [PULL 01/72] hw/net/lan9118: Extract lan9118_phy Peter Maydell
2024-12-11 16:18 ` [PULL 02/72] hw/net/lan9118_phy: Reuse in imx_fec and consolidate implementations Peter Maydell
2024-12-11 16:18 ` [PULL 03/72] hw/net/lan9118_phy: Fix off-by-one error in MII_ANLPAR register Peter Maydell
2024-12-11 16:18 ` [PULL 04/72] hw/net/lan9118_phy: Reuse MII constants Peter Maydell
2024-12-11 16:18 ` [PULL 05/72] hw/net/lan9118_phy: Add missing 100 mbps full duplex advertisement Peter Maydell
2024-12-11 16:18 ` [PULL 06/72] fpu: handle raising Invalid for infzero in pick_nan_muladd Peter Maydell
2024-12-11 16:18 ` [PULL 07/72] fpu: Check for default_nan_mode before calling pickNaNMulAdd Peter Maydell
2024-12-11 16:19 ` [PULL 08/72] softfloat: Allow runtime choice of inf * 0 + NaN result Peter Maydell
2024-12-11 16:19 ` [PULL 09/72] tests/fp: Explicitly set inf-zero-nan rule Peter Maydell
2024-12-11 16:19 ` [PULL 10/72] target/arm: Set FloatInfZeroNaNRule explicitly Peter Maydell
2024-12-11 16:19 ` [PULL 11/72] target/s390: " Peter Maydell
2024-12-11 16:19 ` [PULL 12/72] target/ppc: " Peter Maydell
2024-12-11 16:19 ` [PULL 13/72] target/mips: " Peter Maydell
2024-12-11 16:19 ` [PULL 14/72] target/sparc: " Peter Maydell
2024-12-11 16:19 ` [PULL 15/72] target/xtensa: " Peter Maydell
2024-12-11 16:19 ` [PULL 16/72] target/x86: " Peter Maydell
2024-12-11 16:19 ` [PULL 17/72] target/loongarch: " Peter Maydell
2024-12-11 16:19 ` [PULL 18/72] target/hppa: " Peter Maydell
2024-12-11 16:19 ` [PULL 19/72] softfloat: Pass have_snan to pickNaNMulAdd Peter Maydell
2024-12-11 16:19 ` [PULL 20/72] softfloat: Allow runtime choice of NaN propagation for muladd Peter Maydell
2024-12-11 16:19 ` [PULL 21/72] tests/fp: Explicitly set 3-NaN propagation rule Peter Maydell
2024-12-11 16:19 ` [PULL 22/72] target/arm: Set Float3NaNPropRule explicitly Peter Maydell
2024-12-11 16:19 ` [PULL 23/72] target/loongarch: " Peter Maydell
2024-12-11 16:19 ` [PULL 24/72] target/ppc: " Peter Maydell
2024-12-11 16:19 ` [PULL 25/72] target/s390x: " Peter Maydell
2024-12-11 16:19 ` [PULL 26/72] target/sparc: " Peter Maydell
2024-12-11 16:19 ` [PULL 27/72] target/mips: " Peter Maydell
2024-12-11 16:19 ` [PULL 28/72] target/xtensa: " Peter Maydell
2024-12-11 16:19 ` [PULL 29/72] target/i386: " Peter Maydell
2024-12-11 16:19 ` [PULL 30/72] target/hppa: " Peter Maydell
2024-12-11 16:19 ` [PULL 31/72] fpu: Remove use_first_nan field from float_status Peter Maydell
2024-12-11 16:19 ` [PULL 32/72] target/m68k: Don't pass NULL float_status to floatx80_default_nan() Peter Maydell
2024-12-11 16:19 ` [PULL 33/72] softfloat: Create floatx80 default NaN from parts64_default_nan Peter Maydell
2024-12-11 16:19 ` [PULL 34/72] target/loongarch: Use normal float_status in fclass_s and fclass_d helpers Peter Maydell
2024-12-11 16:19 ` [PULL 35/72] target/m68k: In frem helper, initialize local float_status from env->fp_status Peter Maydell
2024-12-11 16:19 ` [PULL 36/72] target/m68k: Init local float_status from env fp_status in gdb get/set reg Peter Maydell
2024-12-11 16:19 ` [PULL 37/72] target/sparc: Initialize local scratch float_status from env->fp_status Peter Maydell
2024-12-11 16:19 ` [PULL 38/72] target/ppc: Use env->fp_status in helper_compute_fprf functions Peter Maydell
2024-12-11 16:19 ` [PULL 39/72] target/arm: Copy entire float_status in is_ebf Peter Maydell
2024-12-11 16:19 ` [PULL 40/72] fpu: Allow runtime choice of default NaN value Peter Maydell
2024-12-11 16:19 ` [PULL 41/72] tests/fp: Set default NaN pattern explicitly Peter Maydell
2024-12-11 16:19 ` [PULL 42/72] target/microblaze: " Peter Maydell
2024-12-11 16:19 ` [PULL 43/72] target/i386: " Peter Maydell
2024-12-11 16:19 ` [PULL 44/72] target/hppa: " Peter Maydell
2024-12-11 16:19 ` [PULL 45/72] target/alpha: " Peter Maydell
2024-12-11 16:19 ` [PULL 46/72] target/arm: " Peter Maydell
2024-12-11 16:19 ` [PULL 47/72] target/loongarch: " Peter Maydell
2024-12-11 16:19 ` [PULL 48/72] target/m68k: " Peter Maydell
2024-12-11 16:19 ` [PULL 49/72] target/mips: " Peter Maydell
2024-12-11 16:19 ` [PULL 50/72] target/openrisc: " Peter Maydell
2024-12-11 16:19 ` [PULL 51/72] target/ppc: " Peter Maydell
2024-12-11 16:19 ` [PULL 52/72] target/sh4: " Peter Maydell
2024-12-11 16:19 ` [PULL 53/72] target/rx: " Peter Maydell
2024-12-11 16:19 ` [PULL 54/72] target/s390x: " Peter Maydell
2024-12-11 16:19 ` [PULL 55/72] target/sparc: " Peter Maydell
2024-12-11 16:19 ` [PULL 56/72] target/xtensa: " Peter Maydell
2024-12-11 16:19 ` [PULL 57/72] target/hexagon: " Peter Maydell
2024-12-11 16:19 ` [PULL 58/72] target/riscv: " Peter Maydell
2024-12-11 16:19 ` [PULL 59/72] target/tricore: " Peter Maydell
2024-12-11 16:19 ` [PULL 60/72] fpu: Remove default handling for dnan_pattern Peter Maydell
2024-12-11 16:19 ` [PULL 61/72] softfloat: Inline pickNaNMulAdd Peter Maydell
2024-12-11 16:19 ` [PULL 62/72] softfloat: Use goto for default nan case in pick_nan_muladd Peter Maydell
2024-12-11 16:19 ` [PULL 63/72] softfloat: Remove which from parts_pick_nan_muladd Peter Maydell
2024-12-11 16:19 ` [PULL 64/72] softfloat: Pad array size in pick_nan_muladd Peter Maydell
2024-12-11 16:19 ` [PULL 65/72] softfloat: Move propagateFloatx80NaN to softfloat.c Peter Maydell
2024-12-11 16:19 ` [PULL 66/72] softfloat: Use parts_pick_nan in propagateFloatx80NaN Peter Maydell
2024-12-11 16:19 ` [PULL 67/72] softfloat: Inline pickNaN Peter Maydell
2024-12-11 16:20 ` [PULL 68/72] softfloat: Share code between parts_pick_nan cases Peter Maydell
2024-12-11 16:20 ` [PULL 69/72] softfloat: Sink frac_cmp in parts_pick_nan until needed Peter Maydell
2024-12-11 16:20 ` [PULL 70/72] softfloat: Replace WHICH with RET in parts_pick_nan Peter Maydell
2024-12-11 16:20 ` [PULL 71/72] MAINTAINERS: update email address for Leif Lindholm Peter Maydell
2024-12-11 16:20 ` [PULL 72/72] MAINTAINERS: Add correct email address for Vikram Garhwal Peter Maydell
2024-12-13 1:20 ` [PULL 00/72] target-arm queue Stefan Hajnoczi
2024-12-13 10:44 ` Peter Maydell
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.