1
The following changes since commit a97978bcc2d1f650c7d411428806e5b03082b8c7:
1
First arm pullreq of the cycle; this is mostly my softfloat NaN
2
handling series. (Lots more in my to-review queue, but I don't
3
like pullreqs growing too close to a hundred patches at a time :-))
2
4
3
Merge remote-tracking branch 'remotes/dg-gitlab/tags/ppc-for-6.1-20210603' into staging (2021-06-03 10:00:35 +0100)
5
thanks
6
-- PMM
7
8
The following changes since commit 97f2796a3736ed37a1b85dc1c76a6c45b829dd17:
9
10
Open 10.0 development tree (2024-12-10 17:41:17 +0000)
4
11
5
are available in the Git repository at:
12
are available in the Git repository at:
6
13
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210603
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20241211
8
15
9
for you to fetch changes up to 1c861885894d840235954060050d240259f5340b:
16
for you to fetch changes up to 1abe28d519239eea5cf9620bb13149423e5665f8:
10
17
11
tests/unit/test-vmstate: Assert that dup() and mkstemp() succeed (2021-06-03 16:43:27 +0100)
18
MAINTAINERS: Add correct email address for Vikram Garhwal (2024-12-11 15:31:09 +0000)
12
19
13
----------------------------------------------------------------
20
----------------------------------------------------------------
14
target-arm queue:
21
target-arm queue:
15
* Some not-yet-enabled preliminaries for M-profile MVE support
22
* hw/net/lan9118: Extract PHY model, reuse with imx_fec, fix bugs
16
* Consistently use "Cortex-Axx", not "Cortex Axx" in docs, comments
23
* fpu: Make muladd NaN handling runtime-selected, not compile-time
17
* docs: Fix installation of man pages with Sphinx 4.x
24
* fpu: Make default NaN pattern runtime-selected, not compile-time
18
* Mark LDS{MIN,MAX} as signed operations
25
* fpu: Minor NaN-related cleanups
19
* Fix missing syndrome value for DAIF and PAC check exceptions
26
* MAINTAINERS: email address updates
20
* Implement BFloat16 extensions
21
* Refactoring of hvf accelerator code in preparation for aarch64 support
22
* Fix some coverity nits in test code
23
27
24
----------------------------------------------------------------
28
----------------------------------------------------------------
25
Alexander Graf (12):
29
Bernhard Beschow (5):
26
hvf: Move assert_hvf_ok() into common directory
30
hw/net/lan9118: Extract lan9118_phy
27
hvf: Move vcpu thread functions into common directory
31
hw/net/lan9118_phy: Reuse in imx_fec and consolidate implementations
28
hvf: Move cpu functions into common directory
32
hw/net/lan9118_phy: Fix off-by-one error in MII_ANLPAR register
29
hvf: Move hvf internal definitions into common header
33
hw/net/lan9118_phy: Reuse MII constants
30
hvf: Make hvf_set_phys_mem() static
34
hw/net/lan9118_phy: Add missing 100 mbps full duplex advertisement
31
hvf: Remove use of hv_uvaddr_t and hv_gpaddr_t
32
hvf: Split out common code on vcpu init and destroy
33
hvf: Use cpu_synchronize_state()
34
hvf: Make synchronize functions static
35
hvf: Remove hvf-accel-ops.h
36
hvf: Introduce hvf vcpu struct
37
hvf: Simplify post reset/init/loadvm hooks
38
35
39
Damien Goutte-Gattat (1):
36
Leif Lindholm (1):
40
docs: Fix installation of man pages with Sphinx 4.x
37
MAINTAINERS: update email address for Leif Lindholm
41
38
42
Jamie Iles (4):
39
Peter Maydell (54):
43
target/arm: fix missing exception class
40
fpu: handle raising Invalid for infzero in pick_nan_muladd
44
target/arm: fold do_raise_exception into raise_exception
41
fpu: Check for default_nan_mode before calling pickNaNMulAdd
45
target/arm: use raise_exception_ra for MTE check failure
42
softfloat: Allow runtime choice of inf * 0 + NaN result
46
target/arm: use raise_exception_ra for stack limit exception
43
tests/fp: Explicitly set inf-zero-nan rule
44
target/arm: Set FloatInfZeroNaNRule explicitly
45
target/s390: Set FloatInfZeroNaNRule explicitly
46
target/ppc: Set FloatInfZeroNaNRule explicitly
47
target/mips: Set FloatInfZeroNaNRule explicitly
48
target/sparc: Set FloatInfZeroNaNRule explicitly
49
target/xtensa: Set FloatInfZeroNaNRule explicitly
50
target/x86: Set FloatInfZeroNaNRule explicitly
51
target/loongarch: Set FloatInfZeroNaNRule explicitly
52
target/hppa: Set FloatInfZeroNaNRule explicitly
53
softfloat: Pass have_snan to pickNaNMulAdd
54
softfloat: Allow runtime choice of NaN propagation for muladd
55
tests/fp: Explicitly set 3-NaN propagation rule
56
target/arm: Set Float3NaNPropRule explicitly
57
target/loongarch: Set Float3NaNPropRule explicitly
58
target/ppc: Set Float3NaNPropRule explicitly
59
target/s390x: Set Float3NaNPropRule explicitly
60
target/sparc: Set Float3NaNPropRule explicitly
61
target/mips: Set Float3NaNPropRule explicitly
62
target/xtensa: Set Float3NaNPropRule explicitly
63
target/i386: Set Float3NaNPropRule explicitly
64
target/hppa: Set Float3NaNPropRule explicitly
65
fpu: Remove use_first_nan field from float_status
66
target/m68k: Don't pass NULL float_status to floatx80_default_nan()
67
softfloat: Create floatx80 default NaN from parts64_default_nan
68
target/loongarch: Use normal float_status in fclass_s and fclass_d helpers
69
target/m68k: In frem helper, initialize local float_status from env->fp_status
70
target/m68k: Init local float_status from env fp_status in gdb get/set reg
71
target/sparc: Initialize local scratch float_status from env->fp_status
72
target/ppc: Use env->fp_status in helper_compute_fprf functions
73
fpu: Allow runtime choice of default NaN value
74
tests/fp: Set default NaN pattern explicitly
75
target/microblaze: Set default NaN pattern explicitly
76
target/i386: Set default NaN pattern explicitly
77
target/hppa: Set default NaN pattern explicitly
78
target/alpha: Set default NaN pattern explicitly
79
target/arm: Set default NaN pattern explicitly
80
target/loongarch: Set default NaN pattern explicitly
81
target/m68k: Set default NaN pattern explicitly
82
target/mips: Set default NaN pattern explicitly
83
target/openrisc: Set default NaN pattern explicitly
84
target/ppc: Set default NaN pattern explicitly
85
target/sh4: Set default NaN pattern explicitly
86
target/rx: Set default NaN pattern explicitly
87
target/s390x: Set default NaN pattern explicitly
88
target/sparc: Set default NaN pattern explicitly
89
target/xtensa: Set default NaN pattern explicitly
90
target/hexagon: Set default NaN pattern explicitly
91
target/riscv: Set default NaN pattern explicitly
92
target/tricore: Set default NaN pattern explicitly
93
fpu: Remove default handling for dnan_pattern
47
94
48
Peter Maydell (15):
95
Richard Henderson (11):
49
target/arm: Add isar feature check functions for MVE
96
target/arm: Copy entire float_status in is_ebf
50
target/arm: Update feature checks for insns which are "MVE or FP"
97
softfloat: Inline pickNaNMulAdd
51
target/arm: Move fpsp/fpdp isar check into callers of do_vfp_2op_sp/dp
98
softfloat: Use goto for default nan case in pick_nan_muladd
52
target/arm: Add MVE check to VMOV_reg_sp and VMOV_reg_dp
99
softfloat: Remove which from parts_pick_nan_muladd
53
target/arm: Fix return values in fp_sysreg_checks()
100
softfloat: Pad array size in pick_nan_muladd
54
target/arm: Implement M-profile VPR register
101
softfloat: Move propagateFloatx80NaN to softfloat.c
55
target/arm: Make FPSCR.LTPSIZE writable for MVE
102
softfloat: Use parts_pick_nan in propagateFloatx80NaN
56
target/arm: Allow board models to specify initial NS VTOR
103
softfloat: Inline pickNaN
57
arm: Consistently use "Cortex-Axx", not "Cortex Axx"
104
softfloat: Share code between parts_pick_nan cases
58
tests/qtest/bios-tables-test: Check for dup2() failure
105
softfloat: Sink frac_cmp in parts_pick_nan until needed
59
tests/qtest/e1000e-test: Check qemu_recv() succeeded
106
softfloat: Replace WHICH with RET in parts_pick_nan
60
tests/qtest/hd-geo-test: Fix checks on mkstemp() return value
61
tests/qtest/pflash-cfi02-test: Avoid potential integer overflow
62
tests/qtest/tpm-tests: Remove unnecessary NULL checks
63
tests/unit/test-vmstate: Assert that dup() and mkstemp() succeed
64
107
65
Richard Henderson (13):
108
Vikram Garhwal (1):
66
target/arm: Mark LDS{MIN,MAX} as signed operations
109
MAINTAINERS: Add correct email address for Vikram Garhwal
67
target/arm: Add isar_feature_{aa32, aa64, aa64_sve}_bf16
68
target/arm: Unify unallocated path in disas_fp_1src
69
target/arm: Implement scalar float32 to bfloat16 conversion
70
target/arm: Implement vector float32 to bfloat16 conversion
71
softfpu: Add float_round_to_odd_inf
72
target/arm: Implement bfloat16 dot product (vector)
73
target/arm: Implement bfloat16 dot product (indexed)
74
target/arm: Implement bfloat16 matrix multiply accumulate
75
target/arm: Implement bfloat widening fma (vector)
76
target/arm: Implement bfloat widening fma (indexed)
77
linux-user/aarch64: Enable hwcap bits for bfloat16
78
target/arm: Enable BFloat16 extensions
79
110
80
docs/conf.py | 1 +
111
MAINTAINERS | 4 +-
81
docs/system/arm/aspeed.rst | 4 +-
112
include/fpu/softfloat-helpers.h | 38 +++-
82
docs/system/arm/nuvoton.rst | 6 +-
113
include/fpu/softfloat-types.h | 89 +++++++-
83
docs/system/arm/sabrelite.rst | 2 +-
114
include/hw/net/imx_fec.h | 9 +-
84
include/fpu/softfloat-types.h | 4 +-
115
include/hw/net/lan9118_phy.h | 37 ++++
85
include/hw/arm/allwinner-h3.h | 2 +-
116
include/hw/net/mii.h | 6 +
86
include/hw/arm/armv7m.h | 2 +
117
target/mips/fpu_helper.h | 20 ++
87
include/hw/core/cpu.h | 3 +-
118
target/sparc/helper.h | 4 +-
88
include/sysemu/hvf_int.h | 58 +++++
119
fpu/softfloat.c | 19 ++
89
target/arm/cpu.h | 48 +++-
120
hw/net/imx_fec.c | 146 ++------------
90
target/arm/helper-sve.h | 4 +
121
hw/net/lan9118.c | 137 ++-----------
91
target/arm/helper.h | 15 ++
122
hw/net/lan9118_phy.c | 222 ++++++++++++++++++++
92
target/i386/hvf/hvf-accel-ops.h | 23 --
123
linux-user/arm/nwfpe/fpa11.c | 5 +
93
target/i386/hvf/hvf-i386.h | 33 +--
124
target/alpha/cpu.c | 2 +
94
target/i386/hvf/vmx.h | 24 +-
125
target/arm/cpu.c | 10 +
95
target/i386/hvf/x86hvf.h | 2 -
126
target/arm/tcg/vec_helper.c | 20 +-
96
target/arm/neon-dp.decode | 1 +
127
target/hexagon/cpu.c | 2 +
97
target/arm/neon-shared.decode | 11 +
128
target/hppa/fpu_helper.c | 12 ++
98
target/arm/sve.decode | 19 +-
129
target/i386/tcg/fpu_helper.c | 12 ++
99
target/arm/vfp.decode | 2 +
130
target/loongarch/tcg/fpu_helper.c | 14 +-
100
accel/hvf/hvf-accel-ops.c | 471 ++++++++++++++++++++++++++++++++++++++++
131
target/m68k/cpu.c | 14 +-
101
accel/hvf/hvf-all.c | 47 ++++
132
target/m68k/fpu_helper.c | 6 +-
102
hw/arm/armv7m.c | 7 +
133
target/m68k/helper.c | 6 +-
103
hw/arm/aspeed.c | 6 +-
134
target/microblaze/cpu.c | 2 +
104
hw/arm/mcimx6ul-evk.c | 2 +-
135
target/mips/msa.c | 10 +
105
hw/arm/mcimx7d-sabre.c | 2 +-
136
target/openrisc/cpu.c | 2 +
106
hw/arm/npcm7xx_boards.c | 4 +-
137
target/ppc/cpu_init.c | 19 ++
107
hw/arm/sabrelite.c | 2 +-
138
target/ppc/fpu_helper.c | 3 +-
108
hw/misc/npcm7xx_clk.c | 2 +-
139
target/riscv/cpu.c | 2 +
109
linux-user/elfload.c | 2 +
140
target/rx/cpu.c | 2 +
110
target/arm/cpu.c | 13 ++
141
target/s390x/cpu.c | 5 +
111
target/arm/cpu64.c | 3 +
142
target/sh4/cpu.c | 2 +
112
target/arm/cpu_tcg.c | 1 +
143
target/sparc/cpu.c | 6 +
113
target/arm/m_helper.c | 5 +-
144
target/sparc/fop_helper.c | 8 +-
114
target/arm/machine.c | 20 ++
145
target/sparc/translate.c | 4 +-
115
target/arm/mte_helper.c | 12 +-
146
target/tricore/helper.c | 2 +
116
target/arm/op_helper.c | 32 ++-
147
target/xtensa/cpu.c | 4 +
117
target/arm/sve_helper.c | 2 +
148
target/xtensa/fpu_helper.c | 3 +-
118
target/arm/translate-a64.c | 155 +++++++++++--
149
tests/fp/fp-bench.c | 7 +
119
target/arm/translate-neon.c | 91 ++++++++
150
tests/fp/fp-test-log2.c | 1 +
120
target/arm/translate-sve.c | 112 ++++++++++
151
tests/fp/fp-test.c | 7 +
121
target/arm/translate-vfp.c | 164 ++++++++++----
152
fpu/softfloat-parts.c.inc | 152 +++++++++++---
122
target/arm/vec_helper.c | 140 +++++++++++-
153
fpu/softfloat-specialize.c.inc | 412 ++------------------------------------
123
target/arm/vfp_helper.c | 21 +-
154
.mailmap | 5 +-
124
target/i386/hvf/hvf-accel-ops.c | 146 -------------
155
hw/net/Kconfig | 5 +
125
target/i386/hvf/hvf.c | 464 +++++----------------------------------
156
hw/net/meson.build | 1 +
126
target/i386/hvf/x86.c | 28 +--
157
hw/net/trace-events | 10 +-
127
target/i386/hvf/x86_descr.c | 26 +--
158
47 files changed, 778 insertions(+), 730 deletions(-)
128
target/i386/hvf/x86_emu.c | 62 +++---
159
create mode 100644 include/hw/net/lan9118_phy.h
129
target/i386/hvf/x86_mmu.c | 4 +-
160
create mode 100644 hw/net/lan9118_phy.c
130
target/i386/hvf/x86_task.c | 12 +-
131
target/i386/hvf/x86hvf.c | 222 +++++++++----------
132
tests/qtest/bios-tables-test.c | 8 +-
133
tests/qtest/e1000e-test.c | 3 +-
134
tests/qtest/hd-geo-test.c | 4 +-
135
tests/qtest/pflash-cfi02-test.c | 2 +-
136
tests/qtest/tpm-tests.c | 12 +-
137
tests/unit/test-vmstate.c | 5 +-
138
fpu/softfloat-parts.c.inc | 6 +-
139
MAINTAINERS | 8 +
140
accel/hvf/meson.build | 7 +
141
accel/meson.build | 1 +
142
target/i386/hvf/meson.build | 1 -
143
63 files changed, 1666 insertions(+), 935 deletions(-)
144
create mode 100644 include/sysemu/hvf_int.h
145
delete mode 100644 target/i386/hvf/hvf-accel-ops.h
146
create mode 100644 accel/hvf/hvf-accel-ops.c
147
create mode 100644 accel/hvf/hvf-all.c
148
delete mode 100644 target/i386/hvf/hvf-accel-ops.c
149
create mode 100644 accel/hvf/meson.build
150
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Until now, Hypervisor.framework has only been available on x86_64 systems.
3
A very similar implementation of the same device exists in imx_fec. Prepare for
4
With Apple Silicon shipping now, it extends its reach to aarch64. To
4
a common implementation by extracting a device model into its own files.
5
prepare for support for multiple architectures, let's start moving common
6
code out into its own accel directory.
7
5
8
This patch moves assert_hvf_ok() and introduces generic build infrastructure.
6
Some migration state has been moved into the new device model which breaks
7
migration compatibility for the following machines:
8
* smdkc210
9
* realview-*
10
* vexpress-*
11
* kzm
12
* mps2-*
9
13
10
Signed-off-by: Alexander Graf <agraf@csgraf.de>
14
While breaking migration ABI, fix the size of the MII registers to be 16 bit,
11
Reviewed-by: Sergio Lopez <slp@redhat.com>
15
as defined by IEEE 802.3u.
12
Message-id: 20210519202253.76782-2-agraf@csgraf.de
16
17
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
18
Tested-by: Guenter Roeck <linux@roeck-us.net>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Message-id: 20241102125724.532843-2-shentey@gmail.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
22
---
16
include/sysemu/hvf_int.h | 18 +++++++++++++++
23
include/hw/net/lan9118_phy.h | 37 ++++++++
17
accel/hvf/hvf-all.c | 47 ++++++++++++++++++++++++++++++++++++++++
24
hw/net/lan9118.c | 137 +++++-----------------------
18
target/i386/hvf/hvf.c | 33 +---------------------------
25
hw/net/lan9118_phy.c | 169 +++++++++++++++++++++++++++++++++++
19
MAINTAINERS | 8 +++++++
26
hw/net/Kconfig | 4 +
20
accel/hvf/meson.build | 6 +++++
27
hw/net/meson.build | 1 +
21
accel/meson.build | 1 +
28
5 files changed, 233 insertions(+), 115 deletions(-)
22
6 files changed, 81 insertions(+), 32 deletions(-)
29
create mode 100644 include/hw/net/lan9118_phy.h
23
create mode 100644 include/sysemu/hvf_int.h
30
create mode 100644 hw/net/lan9118_phy.c
24
create mode 100644 accel/hvf/hvf-all.c
25
create mode 100644 accel/hvf/meson.build
26
31
27
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
32
diff --git a/include/hw/net/lan9118_phy.h b/include/hw/net/lan9118_phy.h
28
new file mode 100644
33
new file mode 100644
29
index XXXXXXX..XXXXXXX
34
index XXXXXXX..XXXXXXX
30
--- /dev/null
35
--- /dev/null
31
+++ b/include/sysemu/hvf_int.h
36
+++ b/include/hw/net/lan9118_phy.h
32
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@
33
+/*
38
+/*
34
+ * QEMU Hypervisor.framework (HVF) support
39
+ * SMSC LAN9118 PHY emulation
40
+ *
41
+ * Copyright (c) 2009 CodeSourcery, LLC.
42
+ * Written by Paul Brook
35
+ *
43
+ *
36
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
37
+ * See the COPYING file in the top-level directory.
45
+ * See the COPYING file in the top-level directory.
38
+ *
39
+ */
46
+ */
40
+
47
+
41
+/* header to be included in HVF-specific code */
48
+#ifndef HW_NET_LAN9118_PHY_H
42
+
49
+#define HW_NET_LAN9118_PHY_H
43
+#ifndef HVF_INT_H
50
+
44
+#define HVF_INT_H
51
+#include "qom/object.h"
45
+
52
+#include "hw/sysbus.h"
46
+#include <Hypervisor/hv.h>
53
+
47
+
54
+#define TYPE_LAN9118_PHY "lan9118-phy"
48
+void assert_hvf_ok(hv_return_t ret);
55
+OBJECT_DECLARE_SIMPLE_TYPE(Lan9118PhyState, LAN9118_PHY)
56
+
57
+typedef struct Lan9118PhyState {
58
+ SysBusDevice parent_obj;
59
+
60
+ uint16_t status;
61
+ uint16_t control;
62
+ uint16_t advertise;
63
+ uint16_t ints;
64
+ uint16_t int_mask;
65
+ qemu_irq irq;
66
+ bool link_down;
67
+} Lan9118PhyState;
68
+
69
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down);
70
+void lan9118_phy_reset(Lan9118PhyState *s);
71
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg);
72
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val);
49
+
73
+
50
+#endif
74
+#endif
51
diff --git a/accel/hvf/hvf-all.c b/accel/hvf/hvf-all.c
75
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/net/lan9118.c
78
+++ b/hw/net/lan9118.c
79
@@ -XXX,XX +XXX,XX @@
80
#include "net/net.h"
81
#include "net/eth.h"
82
#include "hw/irq.h"
83
+#include "hw/net/lan9118_phy.h"
84
#include "hw/net/lan9118.h"
85
#include "hw/ptimer.h"
86
#include "hw/qdev-properties.h"
87
@@ -XXX,XX +XXX,XX @@ do { printf("lan9118: " fmt , ## __VA_ARGS__); } while (0)
88
#define MAC_CR_RXEN 0x00000004
89
#define MAC_CR_RESERVED 0x7f404213
90
91
-#define PHY_INT_ENERGYON 0x80
92
-#define PHY_INT_AUTONEG_COMPLETE 0x40
93
-#define PHY_INT_FAULT 0x20
94
-#define PHY_INT_DOWN 0x10
95
-#define PHY_INT_AUTONEG_LP 0x08
96
-#define PHY_INT_PARFAULT 0x04
97
-#define PHY_INT_AUTONEG_PAGE 0x02
98
-
99
#define GPT_TIMER_EN 0x20000000
100
101
/*
102
@@ -XXX,XX +XXX,XX @@ struct lan9118_state {
103
uint32_t mac_mii_data;
104
uint32_t mac_flow;
105
106
- uint32_t phy_status;
107
- uint32_t phy_control;
108
- uint32_t phy_advertise;
109
- uint32_t phy_int;
110
- uint32_t phy_int_mask;
111
+ Lan9118PhyState mii;
112
+ IRQState mii_irq;
113
114
int32_t eeprom_writable;
115
uint8_t eeprom[128];
116
@@ -XXX,XX +XXX,XX @@ struct lan9118_state {
117
118
static const VMStateDescription vmstate_lan9118 = {
119
.name = "lan9118",
120
- .version_id = 2,
121
- .minimum_version_id = 1,
122
+ .version_id = 3,
123
+ .minimum_version_id = 3,
124
.fields = (const VMStateField[]) {
125
VMSTATE_PTIMER(timer, lan9118_state),
126
VMSTATE_UINT32(irq_cfg, lan9118_state),
127
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118 = {
128
VMSTATE_UINT32(mac_mii_acc, lan9118_state),
129
VMSTATE_UINT32(mac_mii_data, lan9118_state),
130
VMSTATE_UINT32(mac_flow, lan9118_state),
131
- VMSTATE_UINT32(phy_status, lan9118_state),
132
- VMSTATE_UINT32(phy_control, lan9118_state),
133
- VMSTATE_UINT32(phy_advertise, lan9118_state),
134
- VMSTATE_UINT32(phy_int, lan9118_state),
135
- VMSTATE_UINT32(phy_int_mask, lan9118_state),
136
VMSTATE_INT32(eeprom_writable, lan9118_state),
137
VMSTATE_UINT8_ARRAY(eeprom, lan9118_state, 128),
138
VMSTATE_INT32(tx_fifo_size, lan9118_state),
139
@@ -XXX,XX +XXX,XX @@ static void lan9118_reload_eeprom(lan9118_state *s)
140
lan9118_mac_changed(s);
141
}
142
143
-static void phy_update_irq(lan9118_state *s)
144
+static void lan9118_update_irq(void *opaque, int n, int level)
145
{
146
- if (s->phy_int & s->phy_int_mask) {
147
+ lan9118_state *s = opaque;
148
+
149
+ if (level) {
150
s->int_sts |= PHY_INT;
151
} else {
152
s->int_sts &= ~PHY_INT;
153
@@ -XXX,XX +XXX,XX @@ static void phy_update_irq(lan9118_state *s)
154
lan9118_update(s);
155
}
156
157
-static void phy_update_link(lan9118_state *s)
158
-{
159
- /* Autonegotiation status mirrors link status. */
160
- if (qemu_get_queue(s->nic)->link_down) {
161
- s->phy_status &= ~0x0024;
162
- s->phy_int |= PHY_INT_DOWN;
163
- } else {
164
- s->phy_status |= 0x0024;
165
- s->phy_int |= PHY_INT_ENERGYON;
166
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
167
- }
168
- phy_update_irq(s);
169
-}
170
-
171
static void lan9118_set_link(NetClientState *nc)
172
{
173
- phy_update_link(qemu_get_nic_opaque(nc));
174
-}
175
-
176
-static void phy_reset(lan9118_state *s)
177
-{
178
- s->phy_status = 0x7809;
179
- s->phy_control = 0x3000;
180
- s->phy_advertise = 0x01e1;
181
- s->phy_int_mask = 0;
182
- s->phy_int = 0;
183
- phy_update_link(s);
184
+ lan9118_phy_update_link(&LAN9118(qemu_get_nic_opaque(nc))->mii,
185
+ nc->link_down);
186
}
187
188
static void lan9118_reset(DeviceState *d)
189
@@ -XXX,XX +XXX,XX @@ static void lan9118_reset(DeviceState *d)
190
s->read_word_n = 0;
191
s->write_word_n = 0;
192
193
- phy_reset(s);
194
-
195
s->eeprom_writable = 0;
196
lan9118_reload_eeprom(s);
197
}
198
@@ -XXX,XX +XXX,XX @@ static void do_tx_packet(lan9118_state *s)
199
uint32_t status;
200
201
/* FIXME: Honor TX disable, and allow queueing of packets. */
202
- if (s->phy_control & 0x4000) {
203
+ if (s->mii.control & 0x4000) {
204
/* This assumes the receive routine doesn't touch the VLANClient. */
205
qemu_receive_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len);
206
} else {
207
@@ -XXX,XX +XXX,XX @@ static void tx_fifo_push(lan9118_state *s, uint32_t val)
208
}
209
}
210
211
-static uint32_t do_phy_read(lan9118_state *s, int reg)
212
-{
213
- uint32_t val;
214
-
215
- switch (reg) {
216
- case 0: /* Basic Control */
217
- return s->phy_control;
218
- case 1: /* Basic Status */
219
- return s->phy_status;
220
- case 2: /* ID1 */
221
- return 0x0007;
222
- case 3: /* ID2 */
223
- return 0xc0d1;
224
- case 4: /* Auto-neg advertisement */
225
- return s->phy_advertise;
226
- case 5: /* Auto-neg Link Partner Ability */
227
- return 0x0f71;
228
- case 6: /* Auto-neg Expansion */
229
- return 1;
230
- /* TODO 17, 18, 27, 29, 30, 31 */
231
- case 29: /* Interrupt source. */
232
- val = s->phy_int;
233
- s->phy_int = 0;
234
- phy_update_irq(s);
235
- return val;
236
- case 30: /* Interrupt mask */
237
- return s->phy_int_mask;
238
- default:
239
- qemu_log_mask(LOG_GUEST_ERROR,
240
- "do_phy_read: PHY read reg %d\n", reg);
241
- return 0;
242
- }
243
-}
244
-
245
-static void do_phy_write(lan9118_state *s, int reg, uint32_t val)
246
-{
247
- switch (reg) {
248
- case 0: /* Basic Control */
249
- if (val & 0x8000) {
250
- phy_reset(s);
251
- break;
252
- }
253
- s->phy_control = val & 0x7980;
254
- /* Complete autonegotiation immediately. */
255
- if (val & 0x1000) {
256
- s->phy_status |= 0x0020;
257
- }
258
- break;
259
- case 4: /* Auto-neg advertisement */
260
- s->phy_advertise = (val & 0x2d7f) | 0x80;
261
- break;
262
- /* TODO 17, 18, 27, 31 */
263
- case 30: /* Interrupt mask */
264
- s->phy_int_mask = val & 0xff;
265
- phy_update_irq(s);
266
- break;
267
- default:
268
- qemu_log_mask(LOG_GUEST_ERROR,
269
- "do_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
270
- }
271
-}
272
-
273
static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
274
{
275
switch (reg) {
276
@@ -XXX,XX +XXX,XX @@ static void do_mac_write(lan9118_state *s, int reg, uint32_t val)
277
if (val & 2) {
278
DPRINTF("PHY write %d = 0x%04x\n",
279
(val >> 6) & 0x1f, s->mac_mii_data);
280
- do_phy_write(s, (val >> 6) & 0x1f, s->mac_mii_data);
281
+ lan9118_phy_write(&s->mii, (val >> 6) & 0x1f, s->mac_mii_data);
282
} else {
283
- s->mac_mii_data = do_phy_read(s, (val >> 6) & 0x1f);
284
+ s->mac_mii_data = lan9118_phy_read(&s->mii, (val >> 6) & 0x1f);
285
DPRINTF("PHY read %d = 0x%04x\n",
286
(val >> 6) & 0x1f, s->mac_mii_data);
287
}
288
@@ -XXX,XX +XXX,XX @@ static void lan9118_writel(void *opaque, hwaddr offset,
289
break;
290
case CSR_PMT_CTRL:
291
if (val & 0x400) {
292
- phy_reset(s);
293
+ lan9118_phy_reset(&s->mii);
294
}
295
s->pmt_ctrl &= ~0x34e;
296
s->pmt_ctrl |= (val & 0x34e);
297
@@ -XXX,XX +XXX,XX @@ static void lan9118_realize(DeviceState *dev, Error **errp)
298
const MemoryRegionOps *mem_ops =
299
s->mode_16bit ? &lan9118_16bit_mem_ops : &lan9118_mem_ops;
300
301
+ qemu_init_irq(&s->mii_irq, lan9118_update_irq, s, 0);
302
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
303
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
304
+ return;
305
+ }
306
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
307
+
308
memory_region_init_io(&s->mmio, OBJECT(dev), mem_ops, s,
309
"lan9118-mmio", 0x100);
310
sysbus_init_mmio(sbd, &s->mmio);
311
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
52
new file mode 100644
312
new file mode 100644
53
index XXXXXXX..XXXXXXX
313
index XXXXXXX..XXXXXXX
54
--- /dev/null
314
--- /dev/null
55
+++ b/accel/hvf/hvf-all.c
315
+++ b/hw/net/lan9118_phy.c
56
@@ -XXX,XX +XXX,XX @@
316
@@ -XXX,XX +XXX,XX @@
57
+/*
317
+/*
58
+ * QEMU Hypervisor.framework support
318
+ * SMSC LAN9118 PHY emulation
59
+ *
319
+ *
60
+ * This work is licensed under the terms of the GNU GPL, version 2. See
320
+ * Copyright (c) 2009 CodeSourcery, LLC.
61
+ * the COPYING file in the top-level directory.
321
+ * Written by Paul Brook
322
+ *
323
+ * This code is licensed under the GNU GPL v2
62
+ *
324
+ *
63
+ * Contributions after 2012-01-13 are licensed under the terms of the
325
+ * Contributions after 2012-01-13 are licensed under the terms of the
64
+ * GNU GPL, version 2 or (at your option) any later version.
326
+ * GNU GPL, version 2 or (at your option) any later version.
65
+ */
327
+ */
66
+
328
+
67
+#include "qemu/osdep.h"
329
+#include "qemu/osdep.h"
68
+#include "qemu-common.h"
330
+#include "hw/net/lan9118_phy.h"
69
+#include "qemu/error-report.h"
331
+#include "hw/irq.h"
70
+#include "sysemu/hvf.h"
332
+#include "hw/resettable.h"
71
+#include "sysemu/hvf_int.h"
333
+#include "migration/vmstate.h"
72
+
334
+#include "qemu/log.h"
73
+void assert_hvf_ok(hv_return_t ret)
335
+
74
+{
336
+#define PHY_INT_ENERGYON (1 << 7)
75
+ if (ret == HV_SUCCESS) {
337
+#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
76
+ return;
338
+#define PHY_INT_FAULT (1 << 5)
339
+#define PHY_INT_DOWN (1 << 4)
340
+#define PHY_INT_AUTONEG_LP (1 << 3)
341
+#define PHY_INT_PARFAULT (1 << 2)
342
+#define PHY_INT_AUTONEG_PAGE (1 << 1)
343
+
344
+static void lan9118_phy_update_irq(Lan9118PhyState *s)
345
+{
346
+ qemu_set_irq(s->irq, !!(s->ints & s->int_mask));
347
+}
348
+
349
+uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
350
+{
351
+ uint16_t val;
352
+
353
+ switch (reg) {
354
+ case 0: /* Basic Control */
355
+ return s->control;
356
+ case 1: /* Basic Status */
357
+ return s->status;
358
+ case 2: /* ID1 */
359
+ return 0x0007;
360
+ case 3: /* ID2 */
361
+ return 0xc0d1;
362
+ case 4: /* Auto-neg advertisement */
363
+ return s->advertise;
364
+ case 5: /* Auto-neg Link Partner Ability */
365
+ return 0x0f71;
366
+ case 6: /* Auto-neg Expansion */
367
+ return 1;
368
+ /* TODO 17, 18, 27, 29, 30, 31 */
369
+ case 29: /* Interrupt source. */
370
+ val = s->ints;
371
+ s->ints = 0;
372
+ lan9118_phy_update_irq(s);
373
+ return val;
374
+ case 30: /* Interrupt mask */
375
+ return s->int_mask;
376
+ default:
377
+ qemu_log_mask(LOG_GUEST_ERROR,
378
+ "lan9118_phy_read: PHY read reg %d\n", reg);
379
+ return 0;
77
+ }
380
+ }
78
+
381
+}
79
+ switch (ret) {
382
+
80
+ case HV_ERROR:
383
+void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
81
+ error_report("Error: HV_ERROR");
384
+{
385
+ switch (reg) {
386
+ case 0: /* Basic Control */
387
+ if (val & 0x8000) {
388
+ lan9118_phy_reset(s);
389
+ break;
390
+ }
391
+ s->control = val & 0x7980;
392
+ /* Complete autonegotiation immediately. */
393
+ if (val & 0x1000) {
394
+ s->status |= 0x0020;
395
+ }
82
+ break;
396
+ break;
83
+ case HV_BUSY:
397
+ case 4: /* Auto-neg advertisement */
84
+ error_report("Error: HV_BUSY");
398
+ s->advertise = (val & 0x2d7f) | 0x80;
85
+ break;
399
+ break;
86
+ case HV_BAD_ARGUMENT:
400
+ /* TODO 17, 18, 27, 31 */
87
+ error_report("Error: HV_BAD_ARGUMENT");
401
+ case 30: /* Interrupt mask */
88
+ break;
402
+ s->int_mask = val & 0xff;
89
+ case HV_NO_RESOURCES:
403
+ lan9118_phy_update_irq(s);
90
+ error_report("Error: HV_NO_RESOURCES");
91
+ break;
92
+ case HV_NO_DEVICE:
93
+ error_report("Error: HV_NO_DEVICE");
94
+ break;
95
+ case HV_UNSUPPORTED:
96
+ error_report("Error: HV_UNSUPPORTED");
97
+ break;
404
+ break;
98
+ default:
405
+ default:
99
+ error_report("Unknown Error");
406
+ qemu_log_mask(LOG_GUEST_ERROR,
407
+ "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
100
+ }
408
+ }
101
+
409
+}
102
+ abort();
410
+
103
+}
411
+void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
104
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
412
+{
413
+ s->link_down = link_down;
414
+
415
+ /* Autonegotiation status mirrors link status. */
416
+ if (link_down) {
417
+ s->status &= ~0x0024;
418
+ s->ints |= PHY_INT_DOWN;
419
+ } else {
420
+ s->status |= 0x0024;
421
+ s->ints |= PHY_INT_ENERGYON;
422
+ s->ints |= PHY_INT_AUTONEG_COMPLETE;
423
+ }
424
+ lan9118_phy_update_irq(s);
425
+}
426
+
427
+void lan9118_phy_reset(Lan9118PhyState *s)
428
+{
429
+ s->control = 0x3000;
430
+ s->status = 0x7809;
431
+ s->advertise = 0x01e1;
432
+ s->int_mask = 0;
433
+ s->ints = 0;
434
+ lan9118_phy_update_link(s, s->link_down);
435
+}
436
+
437
+static void lan9118_phy_reset_hold(Object *obj, ResetType type)
438
+{
439
+ Lan9118PhyState *s = LAN9118_PHY(obj);
440
+
441
+ lan9118_phy_reset(s);
442
+}
443
+
444
+static void lan9118_phy_init(Object *obj)
445
+{
446
+ Lan9118PhyState *s = LAN9118_PHY(obj);
447
+
448
+ qdev_init_gpio_out(DEVICE(s), &s->irq, 1);
449
+}
450
+
451
+static const VMStateDescription vmstate_lan9118_phy = {
452
+ .name = "lan9118-phy",
453
+ .version_id = 1,
454
+ .minimum_version_id = 1,
455
+ .fields = (const VMStateField[]) {
456
+ VMSTATE_UINT16(control, Lan9118PhyState),
457
+ VMSTATE_UINT16(status, Lan9118PhyState),
458
+ VMSTATE_UINT16(advertise, Lan9118PhyState),
459
+ VMSTATE_UINT16(ints, Lan9118PhyState),
460
+ VMSTATE_UINT16(int_mask, Lan9118PhyState),
461
+ VMSTATE_BOOL(link_down, Lan9118PhyState),
462
+ VMSTATE_END_OF_LIST()
463
+ }
464
+};
465
+
466
+static void lan9118_phy_class_init(ObjectClass *klass, void *data)
467
+{
468
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
469
+ DeviceClass *dc = DEVICE_CLASS(klass);
470
+
471
+ rc->phases.hold = lan9118_phy_reset_hold;
472
+ dc->vmsd = &vmstate_lan9118_phy;
473
+}
474
+
475
+static const TypeInfo types[] = {
476
+ {
477
+ .name = TYPE_LAN9118_PHY,
478
+ .parent = TYPE_SYS_BUS_DEVICE,
479
+ .instance_size = sizeof(Lan9118PhyState),
480
+ .instance_init = lan9118_phy_init,
481
+ .class_init = lan9118_phy_class_init,
482
+ }
483
+};
484
+
485
+DEFINE_TYPES(types)
486
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
105
index XXXXXXX..XXXXXXX 100644
487
index XXXXXXX..XXXXXXX 100644
106
--- a/target/i386/hvf/hvf.c
488
--- a/hw/net/Kconfig
107
+++ b/target/i386/hvf/hvf.c
489
+++ b/hw/net/Kconfig
108
@@ -XXX,XX +XXX,XX @@
490
@@ -XXX,XX +XXX,XX @@ config VMXNET3_PCI
109
#include "qemu/error-report.h"
491
config SMC91C111
110
492
bool
111
#include "sysemu/hvf.h"
493
112
+#include "sysemu/hvf_int.h"
494
+config LAN9118_PHY
113
#include "sysemu/runstate.h"
495
+ bool
114
#include "hvf-i386.h"
496
+
115
#include "vmcs.h"
497
config LAN9118
116
@@ -XXX,XX +XXX,XX @@
498
bool
117
499
+ select LAN9118_PHY
118
HVFState *hvf_state;
500
select PTIMER
119
501
120
-static void assert_hvf_ok(hv_return_t ret)
502
config NE2000_ISA
121
-{
503
diff --git a/hw/net/meson.build b/hw/net/meson.build
122
- if (ret == HV_SUCCESS) {
123
- return;
124
- }
125
-
126
- switch (ret) {
127
- case HV_ERROR:
128
- error_report("Error: HV_ERROR");
129
- break;
130
- case HV_BUSY:
131
- error_report("Error: HV_BUSY");
132
- break;
133
- case HV_BAD_ARGUMENT:
134
- error_report("Error: HV_BAD_ARGUMENT");
135
- break;
136
- case HV_NO_RESOURCES:
137
- error_report("Error: HV_NO_RESOURCES");
138
- break;
139
- case HV_NO_DEVICE:
140
- error_report("Error: HV_NO_DEVICE");
141
- break;
142
- case HV_UNSUPPORTED:
143
- error_report("Error: HV_UNSUPPORTED");
144
- break;
145
- default:
146
- error_report("Unknown Error");
147
- }
148
-
149
- abort();
150
-}
151
-
152
/* Memory slots */
153
hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
154
{
155
diff --git a/MAINTAINERS b/MAINTAINERS
156
index XXXXXXX..XXXXXXX 100644
504
index XXXXXXX..XXXXXXX 100644
157
--- a/MAINTAINERS
505
--- a/hw/net/meson.build
158
+++ b/MAINTAINERS
506
+++ b/hw/net/meson.build
159
@@ -XXX,XX +XXX,XX @@ M: Roman Bolshakov <r.bolshakov@yadro.com>
507
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_VMXNET3_PCI', if_true: files('vmxnet3.c'))
160
W: https://wiki.qemu.org/Features/HVF
508
161
S: Maintained
509
system_ss.add(when: 'CONFIG_SMC91C111', if_true: files('smc91c111.c'))
162
F: target/i386/hvf/
510
system_ss.add(when: 'CONFIG_LAN9118', if_true: files('lan9118.c'))
163
+
511
+system_ss.add(when: 'CONFIG_LAN9118_PHY', if_true: files('lan9118_phy.c'))
164
+HVF
512
system_ss.add(when: 'CONFIG_NE2000_ISA', if_true: files('ne2000-isa.c'))
165
+M: Cameron Esfahani <dirty@apple.com>
513
system_ss.add(when: 'CONFIG_OPENCORES_ETH', if_true: files('opencores_eth.c'))
166
+M: Roman Bolshakov <r.bolshakov@yadro.com>
514
system_ss.add(when: 'CONFIG_XGMAC', if_true: files('xgmac.c'))
167
+W: https://wiki.qemu.org/Features/HVF
168
+S: Maintained
169
+F: accel/hvf/
170
F: include/sysemu/hvf.h
171
+F: include/sysemu/hvf_int.h
172
173
WHPX CPUs
174
M: Sunil Muthuswamy <sunilmut@microsoft.com>
175
diff --git a/accel/hvf/meson.build b/accel/hvf/meson.build
176
new file mode 100644
177
index XXXXXXX..XXXXXXX
178
--- /dev/null
179
+++ b/accel/hvf/meson.build
180
@@ -XXX,XX +XXX,XX @@
181
+hvf_ss = ss.source_set()
182
+hvf_ss.add(files(
183
+ 'hvf-all.c',
184
+))
185
+
186
+specific_ss.add_all(when: 'CONFIG_HVF', if_true: hvf_ss)
187
diff --git a/accel/meson.build b/accel/meson.build
188
index XXXXXXX..XXXXXXX 100644
189
--- a/accel/meson.build
190
+++ b/accel/meson.build
191
@@ -XXX,XX +XXX,XX @@ specific_ss.add(files('accel-common.c'))
192
softmmu_ss.add(files('accel-softmmu.c'))
193
user_ss.add(files('accel-user.c'))
194
195
+subdir('hvf')
196
subdir('qtest')
197
subdir('kvm')
198
subdir('tcg')
199
--
515
--
200
2.20.1
516
2.34.1
201
202
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
The ARM version of Hypervisor.framework no longer defines these two
3
imx_fec models the same PHY as lan9118_phy. The code is almost the same with
4
types, so let's just revert to standard ones.
4
imx_fec having more logging and tracing. Merge these improvements into
5
lan9118_phy and reuse in imx_fec to fix the code duplication.
5
6
6
Signed-off-by: Alexander Graf <agraf@csgraf.de>
7
Some migration state how resides in the new device model which breaks migration
7
Reviewed-by: Sergio Lopez <slp@redhat.com>
8
compatibility for the following machines:
8
Message-id: 20210519202253.76782-7-agraf@csgraf.de
9
* imx25-pdk
10
* sabrelite
11
* mcimx7d-sabre
12
* mcimx6ul-evk
13
14
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
15
Tested-by: Guenter Roeck <linux@roeck-us.net>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20241102125724.532843-3-shentey@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
19
---
12
accel/hvf/hvf-accel-ops.c | 6 +++---
20
include/hw/net/imx_fec.h | 9 ++-
13
1 file changed, 3 insertions(+), 3 deletions(-)
21
hw/net/imx_fec.c | 146 ++++-----------------------------------
22
hw/net/lan9118_phy.c | 82 ++++++++++++++++------
23
hw/net/Kconfig | 1 +
24
hw/net/trace-events | 10 +--
25
5 files changed, 85 insertions(+), 163 deletions(-)
14
26
15
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
27
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
16
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
17
--- a/accel/hvf/hvf-accel-ops.c
29
--- a/include/hw/net/imx_fec.h
18
+++ b/accel/hvf/hvf-accel-ops.c
30
+++ b/include/hw/net/imx_fec.h
19
@@ -XXX,XX +XXX,XX @@ static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
31
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(IMXFECState, IMX_FEC)
20
macslot->present = 1;
32
#define TYPE_IMX_ENET "imx.enet"
21
macslot->gpa_start = slot->start;
33
22
macslot->size = slot->size;
34
#include "hw/sysbus.h"
23
- ret = hv_vm_map((hv_uvaddr_t)slot->mem, slot->start, slot->size, flags);
35
+#include "hw/net/lan9118_phy.h"
24
+ ret = hv_vm_map(slot->mem, slot->start, slot->size, flags);
36
+#include "hw/irq.h"
25
assert_hvf_ok(ret);
37
#include "net/net.h"
26
return 0;
38
27
}
39
#define ENET_EIR 1
28
@@ -XXX,XX +XXX,XX @@ static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)
40
@@ -XXX,XX +XXX,XX @@ struct IMXFECState {
29
/* protect region against writes; begin tracking it */
41
uint32_t tx_descriptor[ENET_TX_RING_NUM];
30
if (on) {
42
uint32_t tx_ring_num;
31
slot->flags |= HVF_SLOT_LOG;
43
32
- hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
44
- uint32_t phy_status;
33
+ hv_vm_protect((uintptr_t)slot->start, (size_t)slot->size,
45
- uint32_t phy_control;
34
HV_MEMORY_READ);
46
- uint32_t phy_advertise;
35
/* stop tracking region*/
47
- uint32_t phy_int;
48
- uint32_t phy_int_mask;
49
+ Lan9118PhyState mii;
50
+ IRQState mii_irq;
51
uint32_t phy_num;
52
bool phy_connected;
53
struct IMXFECState *phy_consumer;
54
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/net/imx_fec.c
57
+++ b/hw/net/imx_fec.c
58
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth_txdescs = {
59
60
static const VMStateDescription vmstate_imx_eth = {
61
.name = TYPE_IMX_FEC,
62
- .version_id = 2,
63
- .minimum_version_id = 2,
64
+ .version_id = 3,
65
+ .minimum_version_id = 3,
66
.fields = (const VMStateField[]) {
67
VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
68
VMSTATE_UINT32(rx_descriptor, IMXFECState),
69
VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
70
- VMSTATE_UINT32(phy_status, IMXFECState),
71
- VMSTATE_UINT32(phy_control, IMXFECState),
72
- VMSTATE_UINT32(phy_advertise, IMXFECState),
73
- VMSTATE_UINT32(phy_int, IMXFECState),
74
- VMSTATE_UINT32(phy_int_mask, IMXFECState),
75
VMSTATE_END_OF_LIST()
76
},
77
.subsections = (const VMStateDescription * const []) {
78
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth = {
79
},
80
};
81
82
-#define PHY_INT_ENERGYON (1 << 7)
83
-#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
84
-#define PHY_INT_FAULT (1 << 5)
85
-#define PHY_INT_DOWN (1 << 4)
86
-#define PHY_INT_AUTONEG_LP (1 << 3)
87
-#define PHY_INT_PARFAULT (1 << 2)
88
-#define PHY_INT_AUTONEG_PAGE (1 << 1)
89
-
90
static void imx_eth_update(IMXFECState *s);
91
92
/*
93
@@ -XXX,XX +XXX,XX @@ static void imx_eth_update(IMXFECState *s);
94
* For now we don't handle any GPIO/interrupt line, so the OS will
95
* have to poll for the PHY status.
96
*/
97
-static void imx_phy_update_irq(IMXFECState *s)
98
+static void imx_phy_update_irq(void *opaque, int n, int level)
99
{
100
- imx_eth_update(s);
101
-}
102
-
103
-static void imx_phy_update_link(IMXFECState *s)
104
-{
105
- /* Autonegotiation status mirrors link status. */
106
- if (qemu_get_queue(s->nic)->link_down) {
107
- trace_imx_phy_update_link("down");
108
- s->phy_status &= ~0x0024;
109
- s->phy_int |= PHY_INT_DOWN;
110
- } else {
111
- trace_imx_phy_update_link("up");
112
- s->phy_status |= 0x0024;
113
- s->phy_int |= PHY_INT_ENERGYON;
114
- s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
115
- }
116
- imx_phy_update_irq(s);
117
+ imx_eth_update(opaque);
118
}
119
120
static void imx_eth_set_link(NetClientState *nc)
121
{
122
- imx_phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
123
-}
124
-
125
-static void imx_phy_reset(IMXFECState *s)
126
-{
127
- trace_imx_phy_reset();
128
-
129
- s->phy_status = 0x7809;
130
- s->phy_control = 0x3000;
131
- s->phy_advertise = 0x01e1;
132
- s->phy_int_mask = 0;
133
- s->phy_int = 0;
134
- imx_phy_update_link(s);
135
+ lan9118_phy_update_link(&IMX_FEC(qemu_get_nic_opaque(nc))->mii,
136
+ nc->link_down);
137
}
138
139
static uint32_t imx_phy_read(IMXFECState *s, int reg)
140
{
141
- uint32_t val;
142
uint32_t phy = reg / 32;
143
144
if (!s->phy_connected) {
145
@@ -XXX,XX +XXX,XX @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
146
147
reg %= 32;
148
149
- switch (reg) {
150
- case 0: /* Basic Control */
151
- val = s->phy_control;
152
- break;
153
- case 1: /* Basic Status */
154
- val = s->phy_status;
155
- break;
156
- case 2: /* ID1 */
157
- val = 0x0007;
158
- break;
159
- case 3: /* ID2 */
160
- val = 0xc0d1;
161
- break;
162
- case 4: /* Auto-neg advertisement */
163
- val = s->phy_advertise;
164
- break;
165
- case 5: /* Auto-neg Link Partner Ability */
166
- val = 0x0f71;
167
- break;
168
- case 6: /* Auto-neg Expansion */
169
- val = 1;
170
- break;
171
- case 29: /* Interrupt source. */
172
- val = s->phy_int;
173
- s->phy_int = 0;
174
- imx_phy_update_irq(s);
175
- break;
176
- case 30: /* Interrupt mask */
177
- val = s->phy_int_mask;
178
- break;
179
- case 17:
180
- case 18:
181
- case 27:
182
- case 31:
183
- qemu_log_mask(LOG_UNIMP, "[%s.phy]%s: reg %d not implemented\n",
184
- TYPE_IMX_FEC, __func__, reg);
185
- val = 0;
186
- break;
187
- default:
188
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
189
- TYPE_IMX_FEC, __func__, reg);
190
- val = 0;
191
- break;
192
- }
193
-
194
- trace_imx_phy_read(val, phy, reg);
195
-
196
- return val;
197
+ return lan9118_phy_read(&s->mii, reg);
198
}
199
200
static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
201
@@ -XXX,XX +XXX,XX @@ static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
202
203
reg %= 32;
204
205
- trace_imx_phy_write(val, phy, reg);
206
-
207
- switch (reg) {
208
- case 0: /* Basic Control */
209
- if (val & 0x8000) {
210
- imx_phy_reset(s);
211
- } else {
212
- s->phy_control = val & 0x7980;
213
- /* Complete autonegotiation immediately. */
214
- if (val & 0x1000) {
215
- s->phy_status |= 0x0020;
216
- }
217
- }
218
- break;
219
- case 4: /* Auto-neg advertisement */
220
- s->phy_advertise = (val & 0x2d7f) | 0x80;
221
- break;
222
- case 30: /* Interrupt mask */
223
- s->phy_int_mask = val & 0xff;
224
- imx_phy_update_irq(s);
225
- break;
226
- case 17:
227
- case 18:
228
- case 27:
229
- case 31:
230
- qemu_log_mask(LOG_UNIMP, "[%s.phy)%s: reg %d not implemented\n",
231
- TYPE_IMX_FEC, __func__, reg);
232
- break;
233
- default:
234
- qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
235
- TYPE_IMX_FEC, __func__, reg);
236
- break;
237
- }
238
+ lan9118_phy_write(&s->mii, reg, val);
239
}
240
241
static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr)
242
@@ -XXX,XX +XXX,XX @@ static void imx_eth_reset(DeviceState *d)
243
244
s->rx_descriptor = 0;
245
memset(s->tx_descriptor, 0, sizeof(s->tx_descriptor));
246
-
247
- /* We also reset the PHY */
248
- imx_phy_reset(s);
249
}
250
251
static uint32_t imx_default_read(IMXFECState *s, uint32_t index)
252
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
253
sysbus_init_irq(sbd, &s->irq[0]);
254
sysbus_init_irq(sbd, &s->irq[1]);
255
256
+ qemu_init_irq(&s->mii_irq, imx_phy_update_irq, s, 0);
257
+ object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
258
+ if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
259
+ return;
260
+ }
261
+ qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
262
+
263
qemu_macaddr_default_if_unset(&s->conf.macaddr);
264
265
s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
266
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
267
index XXXXXXX..XXXXXXX 100644
268
--- a/hw/net/lan9118_phy.c
269
+++ b/hw/net/lan9118_phy.c
270
@@ -XXX,XX +XXX,XX @@
271
* Copyright (c) 2009 CodeSourcery, LLC.
272
* Written by Paul Brook
273
*
274
+ * Copyright (c) 2013 Jean-Christophe Dubois. <jcd@tribudubois.net>
275
+ *
276
* This code is licensed under the GNU GPL v2
277
*
278
* Contributions after 2012-01-13 are licensed under the terms of the
279
@@ -XXX,XX +XXX,XX @@
280
#include "hw/resettable.h"
281
#include "migration/vmstate.h"
282
#include "qemu/log.h"
283
+#include "trace.h"
284
285
#define PHY_INT_ENERGYON (1 << 7)
286
#define PHY_INT_AUTONEG_COMPLETE (1 << 6)
287
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
288
289
switch (reg) {
290
case 0: /* Basic Control */
291
- return s->control;
292
+ val = s->control;
293
+ break;
294
case 1: /* Basic Status */
295
- return s->status;
296
+ val = s->status;
297
+ break;
298
case 2: /* ID1 */
299
- return 0x0007;
300
+ val = 0x0007;
301
+ break;
302
case 3: /* ID2 */
303
- return 0xc0d1;
304
+ val = 0xc0d1;
305
+ break;
306
case 4: /* Auto-neg advertisement */
307
- return s->advertise;
308
+ val = s->advertise;
309
+ break;
310
case 5: /* Auto-neg Link Partner Ability */
311
- return 0x0f71;
312
+ val = 0x0f71;
313
+ break;
314
case 6: /* Auto-neg Expansion */
315
- return 1;
316
- /* TODO 17, 18, 27, 29, 30, 31 */
317
+ val = 1;
318
+ break;
319
case 29: /* Interrupt source. */
320
val = s->ints;
321
s->ints = 0;
322
lan9118_phy_update_irq(s);
323
- return val;
324
+ break;
325
case 30: /* Interrupt mask */
326
- return s->int_mask;
327
+ val = s->int_mask;
328
+ break;
329
+ case 17:
330
+ case 18:
331
+ case 27:
332
+ case 31:
333
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
334
+ __func__, reg);
335
+ val = 0;
336
+ break;
337
default:
338
- qemu_log_mask(LOG_GUEST_ERROR,
339
- "lan9118_phy_read: PHY read reg %d\n", reg);
340
- return 0;
341
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
342
+ __func__, reg);
343
+ val = 0;
344
+ break;
345
}
346
+
347
+ trace_lan9118_phy_read(val, reg);
348
+
349
+ return val;
350
}
351
352
void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
353
{
354
+ trace_lan9118_phy_write(val, reg);
355
+
356
switch (reg) {
357
case 0: /* Basic Control */
358
if (val & 0x8000) {
359
lan9118_phy_reset(s);
360
- break;
361
- }
362
- s->control = val & 0x7980;
363
- /* Complete autonegotiation immediately. */
364
- if (val & 0x1000) {
365
- s->status |= 0x0020;
366
+ } else {
367
+ s->control = val & 0x7980;
368
+ /* Complete autonegotiation immediately. */
369
+ if (val & 0x1000) {
370
+ s->status |= 0x0020;
371
+ }
372
}
373
break;
374
case 4: /* Auto-neg advertisement */
375
s->advertise = (val & 0x2d7f) | 0x80;
376
break;
377
- /* TODO 17, 18, 27, 31 */
378
case 30: /* Interrupt mask */
379
s->int_mask = val & 0xff;
380
lan9118_phy_update_irq(s);
381
break;
382
+ case 17:
383
+ case 18:
384
+ case 27:
385
+ case 31:
386
+ qemu_log_mask(LOG_UNIMP, "%s: reg %d not implemented\n",
387
+ __func__, reg);
388
+ break;
389
default:
390
- qemu_log_mask(LOG_GUEST_ERROR,
391
- "lan9118_phy_write: PHY write reg %d = 0x%04x\n", reg, val);
392
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad address at offset %d\n",
393
+ __func__, reg);
394
+ break;
395
}
396
}
397
398
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
399
400
/* Autonegotiation status mirrors link status. */
401
if (link_down) {
402
+ trace_lan9118_phy_update_link("down");
403
s->status &= ~0x0024;
404
s->ints |= PHY_INT_DOWN;
36
} else {
405
} else {
37
slot->flags &= ~HVF_SLOT_LOG;
406
+ trace_lan9118_phy_update_link("up");
38
- hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
407
s->status |= 0x0024;
39
+ hv_vm_protect((uintptr_t)slot->start, (size_t)slot->size,
408
s->ints |= PHY_INT_ENERGYON;
40
HV_MEMORY_READ | HV_MEMORY_WRITE);
409
s->ints |= PHY_INT_AUTONEG_COMPLETE;
41
}
410
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
42
}
411
412
void lan9118_phy_reset(Lan9118PhyState *s)
413
{
414
+ trace_lan9118_phy_reset();
415
+
416
s->control = 0x3000;
417
s->status = 0x7809;
418
s->advertise = 0x01e1;
419
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_phy = {
420
.version_id = 1,
421
.minimum_version_id = 1,
422
.fields = (const VMStateField[]) {
423
- VMSTATE_UINT16(control, Lan9118PhyState),
424
VMSTATE_UINT16(status, Lan9118PhyState),
425
+ VMSTATE_UINT16(control, Lan9118PhyState),
426
VMSTATE_UINT16(advertise, Lan9118PhyState),
427
VMSTATE_UINT16(ints, Lan9118PhyState),
428
VMSTATE_UINT16(int_mask, Lan9118PhyState),
429
diff --git a/hw/net/Kconfig b/hw/net/Kconfig
430
index XXXXXXX..XXXXXXX 100644
431
--- a/hw/net/Kconfig
432
+++ b/hw/net/Kconfig
433
@@ -XXX,XX +XXX,XX @@ config ALLWINNER_SUN8I_EMAC
434
435
config IMX_FEC
436
bool
437
+ select LAN9118_PHY
438
439
config CADENCE
440
bool
441
diff --git a/hw/net/trace-events b/hw/net/trace-events
442
index XXXXXXX..XXXXXXX 100644
443
--- a/hw/net/trace-events
444
+++ b/hw/net/trace-events
445
@@ -XXX,XX +XXX,XX @@ allwinner_sun8i_emac_set_link(bool active) "Set link: active=%u"
446
allwinner_sun8i_emac_read(uint64_t offset, uint64_t val) "MMIO read: offset=0x%" PRIx64 " value=0x%" PRIx64
447
allwinner_sun8i_emac_write(uint64_t offset, uint64_t val) "MMIO write: offset=0x%" PRIx64 " value=0x%" PRIx64
448
449
+# lan9118_phy.c
450
+lan9118_phy_read(uint16_t val, int reg) "[0x%02x] -> 0x%04" PRIx16
451
+lan9118_phy_write(uint16_t val, int reg) "[0x%02x] <- 0x%04" PRIx16
452
+lan9118_phy_update_link(const char *s) "%s"
453
+lan9118_phy_reset(void) ""
454
+
455
# lance.c
456
lance_mem_readw(uint64_t addr, uint32_t ret) "addr=0x%"PRIx64"val=0x%04x"
457
lance_mem_writew(uint64_t addr, uint32_t val) "addr=0x%"PRIx64"val=0x%04x"
458
@@ -XXX,XX +XXX,XX @@ i82596_set_multicast(uint16_t count) "Added %d multicast entries"
459
i82596_channel_attention(void *s) "%p: Received CHANNEL ATTENTION"
460
461
# imx_fec.c
462
-imx_phy_read(uint32_t val, int phy, int reg) "0x%04"PRIx32" <= phy[%d].reg[%d]"
463
imx_phy_read_num(int phy, int configured) "read request from unconfigured phy %d (configured %d)"
464
-imx_phy_write(uint32_t val, int phy, int reg) "0x%04"PRIx32" => phy[%d].reg[%d]"
465
imx_phy_write_num(int phy, int configured) "write request to unconfigured phy %d (configured %d)"
466
-imx_phy_update_link(const char *s) "%s"
467
-imx_phy_reset(void) ""
468
imx_fec_read_bd(uint64_t addr, int flags, int len, int data) "tx_bd 0x%"PRIx64" flags 0x%04x len %d data 0x%08x"
469
imx_enet_read_bd(uint64_t addr, int flags, int len, int data, int options, int status) "tx_bd 0x%"PRIx64" flags 0x%04x len %d data 0x%08x option 0x%04x status 0x%04x"
470
imx_eth_tx_bd_busy(void) "tx_bd ran out of descriptors to transmit"
43
--
471
--
44
2.20.1
472
2.34.1
45
46
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
We can move the definition of hvf_vcpu_exec() into our internal
3
Turns 0x70 into 0xe0 (== 0x70 << 1) which adds the missing MII_ANLPAR_TX and
4
hvf header, obsoleting the need for hvf-accel-ops.h.
4
fixes the MSB of selector field to be zero, as specified in the datasheet.
5
5
6
Signed-off-by: Alexander Graf <agraf@csgraf.de>
6
Fixes: 2a424990170b "LAN9118 emulation"
7
Reviewed-by: Sergio Lopez <slp@redhat.com>
7
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
8
Message-id: 20210519202253.76782-11-agraf@csgraf.de
8
Tested-by: Guenter Roeck <linux@roeck-us.net>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20241102125724.532843-4-shentey@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
accel/hvf/hvf-accel-ops.h | 17 -----------------
13
hw/net/lan9118_phy.c | 2 +-
13
include/sysemu/hvf_int.h | 1 +
14
1 file changed, 1 insertion(+), 1 deletion(-)
14
accel/hvf/hvf-accel-ops.c | 2 --
15
target/i386/hvf/hvf.c | 2 --
16
4 files changed, 1 insertion(+), 21 deletions(-)
17
delete mode 100644 accel/hvf/hvf-accel-ops.h
18
15
19
diff --git a/accel/hvf/hvf-accel-ops.h b/accel/hvf/hvf-accel-ops.h
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
20
deleted file mode 100644
21
index XXXXXXX..XXXXXXX
22
--- a/accel/hvf/hvf-accel-ops.h
23
+++ /dev/null
24
@@ -XXX,XX +XXX,XX @@
25
-/*
26
- * Accelerator CPUS Interface
27
- *
28
- * Copyright 2020 SUSE LLC
29
- *
30
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
31
- * See the COPYING file in the top-level directory.
32
- */
33
-
34
-#ifndef HVF_CPUS_H
35
-#define HVF_CPUS_H
36
-
37
-#include "sysemu/cpus.h"
38
-
39
-int hvf_vcpu_exec(CPUState *);
40
-
41
-#endif /* HVF_CPUS_H */
42
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
43
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
44
--- a/include/sysemu/hvf_int.h
18
--- a/hw/net/lan9118_phy.c
45
+++ b/include/sysemu/hvf_int.h
19
+++ b/hw/net/lan9118_phy.c
46
@@ -XXX,XX +XXX,XX @@ extern HVFState *hvf_state;
20
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
47
void assert_hvf_ok(hv_return_t ret);
21
val = s->advertise;
48
int hvf_arch_init_vcpu(CPUState *cpu);
22
break;
49
void hvf_arch_vcpu_destroy(CPUState *cpu);
23
case 5: /* Auto-neg Link Partner Ability */
50
+int hvf_vcpu_exec(CPUState *);
24
- val = 0x0f71;
51
hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
25
+ val = 0x0fe1;
52
int hvf_put_registers(CPUState *);
26
break;
53
int hvf_get_registers(CPUState *);
27
case 6: /* Auto-neg Expansion */
54
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
28
val = 1;
55
index XXXXXXX..XXXXXXX 100644
56
--- a/accel/hvf/hvf-accel-ops.c
57
+++ b/accel/hvf/hvf-accel-ops.c
58
@@ -XXX,XX +XXX,XX @@
59
#include "sysemu/runstate.h"
60
#include "qemu/guest-random.h"
61
62
-#include "hvf-accel-ops.h"
63
-
64
HVFState *hvf_state;
65
66
/* Memory slots */
67
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/i386/hvf/hvf.c
70
+++ b/target/i386/hvf/hvf.c
71
@@ -XXX,XX +XXX,XX @@
72
#include "qemu/accel.h"
73
#include "target/i386/cpu.h"
74
75
-#include "hvf-accel-ops.h"
76
-
77
void vmx_update_tpr(CPUState *cpu)
78
{
79
/* TODO: need integrate APIC handling */
80
--
29
--
81
2.20.1
30
2.34.1
82
83
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Until now, Hypervisor.framework has only been available on x86_64 systems.
3
Prefer named constants over magic values for better readability.
4
With Apple Silicon shipping now, it extends its reach to aarch64. To
5
prepare for support for multiple architectures, let's start moving common
6
code out into its own accel directory.
7
4
8
This patch moves a few internal struct and constant defines over.
9
10
Signed-off-by: Alexander Graf <agraf@csgraf.de>
11
Reviewed-by: Sergio Lopez <slp@redhat.com>
12
Message-id: 20210519202253.76782-5-agraf@csgraf.de
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
7
Tested-by: Guenter Roeck <linux@roeck-us.net>
8
Message-id: 20241102125724.532843-5-shentey@gmail.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
include/sysemu/hvf_int.h | 30 ++++++++++++++++++++++++++++++
11
include/hw/net/mii.h | 6 +++++
17
target/i386/hvf/hvf-i386.h | 31 +------------------------------
12
hw/net/lan9118_phy.c | 63 ++++++++++++++++++++++++++++----------------
18
2 files changed, 31 insertions(+), 30 deletions(-)
13
2 files changed, 46 insertions(+), 23 deletions(-)
19
14
20
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
15
diff --git a/include/hw/net/mii.h b/include/hw/net/mii.h
21
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
22
--- a/include/sysemu/hvf_int.h
17
--- a/include/hw/net/mii.h
23
+++ b/include/sysemu/hvf_int.h
18
+++ b/include/hw/net/mii.h
24
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
25
20
#define MII_BMSR_JABBER (1 << 1) /* Jabber detected */
26
#include <Hypervisor/hv.h>
21
#define MII_BMSR_EXTCAP (1 << 0) /* Ext-reg capability */
27
22
28
+/* hvf_slot flags */
23
+#define MII_ANAR_RFAULT (1 << 13) /* Say we can detect faults */
29
+#define HVF_SLOT_LOG (1 << 0)
24
#define MII_ANAR_PAUSE_ASYM (1 << 11) /* Try for asymmetric pause */
25
#define MII_ANAR_PAUSE (1 << 10) /* Try for pause */
26
#define MII_ANAR_TXFD (1 << 8)
27
@@ -XXX,XX +XXX,XX @@
28
#define MII_ANAR_10FD (1 << 6)
29
#define MII_ANAR_10 (1 << 5)
30
#define MII_ANAR_CSMACD (1 << 0)
31
+#define MII_ANAR_SELECT (0x001f) /* Selector bits */
32
33
#define MII_ANLPAR_ACK (1 << 14)
34
#define MII_ANLPAR_PAUSEASY (1 << 11) /* can pause asymmetrically */
35
@@ -XXX,XX +XXX,XX @@
36
#define RTL8201CP_PHYID1 0x0000
37
#define RTL8201CP_PHYID2 0x8201
38
39
+/* SMSC LAN9118 */
40
+#define SMSCLAN9118_PHYID1 0x0007
41
+#define SMSCLAN9118_PHYID2 0xc0d1
30
+
42
+
31
+typedef struct hvf_slot {
43
/* RealTek 8211E */
32
+ uint64_t start;
44
#define RTL8211E_PHYID1 0x001c
33
+ uint64_t size;
45
#define RTL8211E_PHYID2 0xc915
34
+ uint8_t *mem;
46
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
35
+ int slot_id;
36
+ uint32_t flags;
37
+ MemoryRegion *region;
38
+} hvf_slot;
39
+
40
+typedef struct hvf_vcpu_caps {
41
+ uint64_t vmx_cap_pinbased;
42
+ uint64_t vmx_cap_procbased;
43
+ uint64_t vmx_cap_procbased2;
44
+ uint64_t vmx_cap_entry;
45
+ uint64_t vmx_cap_exit;
46
+ uint64_t vmx_cap_preemption_timer;
47
+} hvf_vcpu_caps;
48
+
49
+struct HVFState {
50
+ AccelState parent;
51
+ hvf_slot slots[32];
52
+ int num_slots;
53
+
54
+ hvf_vcpu_caps *hvf_caps;
55
+};
56
+extern HVFState *hvf_state;
57
+
58
void hvf_set_phys_mem(MemoryRegionSection *, bool);
59
void assert_hvf_ok(hv_return_t ret);
60
hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
61
diff --git a/target/i386/hvf/hvf-i386.h b/target/i386/hvf/hvf-i386.h
62
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
63
--- a/target/i386/hvf/hvf-i386.h
48
--- a/hw/net/lan9118_phy.c
64
+++ b/target/i386/hvf/hvf-i386.h
49
+++ b/hw/net/lan9118_phy.c
65
@@ -XXX,XX +XXX,XX @@
50
@@ -XXX,XX +XXX,XX @@
66
51
67
#include "qemu/accel.h"
52
#include "qemu/osdep.h"
68
#include "sysemu/hvf.h"
53
#include "hw/net/lan9118_phy.h"
69
+#include "sysemu/hvf_int.h"
54
+#include "hw/net/mii.h"
70
#include "cpu.h"
55
#include "hw/irq.h"
71
#include "x86.h"
56
#include "hw/resettable.h"
72
57
#include "migration/vmstate.h"
73
-/* hvf_slot flags */
58
@@ -XXX,XX +XXX,XX @@ uint16_t lan9118_phy_read(Lan9118PhyState *s, int reg)
74
-#define HVF_SLOT_LOG (1 << 0)
59
uint16_t val;
75
-
60
76
-typedef struct hvf_slot {
61
switch (reg) {
77
- uint64_t start;
62
- case 0: /* Basic Control */
78
- uint64_t size;
63
+ case MII_BMCR:
79
- uint8_t *mem;
64
val = s->control;
80
- int slot_id;
65
break;
81
- uint32_t flags;
66
- case 1: /* Basic Status */
82
- MemoryRegion *region;
67
+ case MII_BMSR:
83
-} hvf_slot;
68
val = s->status;
84
-
69
break;
85
-typedef struct hvf_vcpu_caps {
70
- case 2: /* ID1 */
86
- uint64_t vmx_cap_pinbased;
71
- val = 0x0007;
87
- uint64_t vmx_cap_procbased;
72
+ case MII_PHYID1:
88
- uint64_t vmx_cap_procbased2;
73
+ val = SMSCLAN9118_PHYID1;
89
- uint64_t vmx_cap_entry;
74
break;
90
- uint64_t vmx_cap_exit;
75
- case 3: /* ID2 */
91
- uint64_t vmx_cap_preemption_timer;
76
- val = 0xc0d1;
92
-} hvf_vcpu_caps;
77
+ case MII_PHYID2:
93
-
78
+ val = SMSCLAN9118_PHYID2;
94
-struct HVFState {
79
break;
95
- AccelState parent;
80
- case 4: /* Auto-neg advertisement */
96
- hvf_slot slots[32];
81
+ case MII_ANAR:
97
- int num_slots;
82
val = s->advertise;
98
-
83
break;
99
- hvf_vcpu_caps *hvf_caps;
84
- case 5: /* Auto-neg Link Partner Ability */
100
-};
85
- val = 0x0fe1;
101
-extern HVFState *hvf_state;
86
+ case MII_ANLPAR:
102
-
87
+ val = MII_ANLPAR_PAUSEASY | MII_ANLPAR_PAUSE | MII_ANLPAR_T4 |
103
void hvf_handle_io(CPUArchState *, uint16_t, void *, int, int, int);
88
+ MII_ANLPAR_TXFD | MII_ANLPAR_TX | MII_ANLPAR_10FD |
104
89
+ MII_ANLPAR_10 | MII_ANLPAR_CSMACD;
105
#ifdef NEED_CPU_H
90
break;
91
- case 6: /* Auto-neg Expansion */
92
- val = 1;
93
+ case MII_ANER:
94
+ val = MII_ANER_NWAY;
95
break;
96
case 29: /* Interrupt source. */
97
val = s->ints;
98
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
99
trace_lan9118_phy_write(val, reg);
100
101
switch (reg) {
102
- case 0: /* Basic Control */
103
- if (val & 0x8000) {
104
+ case MII_BMCR:
105
+ if (val & MII_BMCR_RESET) {
106
lan9118_phy_reset(s);
107
} else {
108
- s->control = val & 0x7980;
109
+ s->control = val & (MII_BMCR_LOOPBACK | MII_BMCR_SPEED100 |
110
+ MII_BMCR_AUTOEN | MII_BMCR_PDOWN | MII_BMCR_FD |
111
+ MII_BMCR_CTST);
112
/* Complete autonegotiation immediately. */
113
- if (val & 0x1000) {
114
- s->status |= 0x0020;
115
+ if (val & MII_BMCR_AUTOEN) {
116
+ s->status |= MII_BMSR_AN_COMP;
117
}
118
}
119
break;
120
- case 4: /* Auto-neg advertisement */
121
- s->advertise = (val & 0x2d7f) | 0x80;
122
+ case MII_ANAR:
123
+ s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
124
+ MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
125
+ MII_ANAR_SELECT))
126
+ | MII_ANAR_TX;
127
break;
128
case 30: /* Interrupt mask */
129
s->int_mask = val & 0xff;
130
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_update_link(Lan9118PhyState *s, bool link_down)
131
/* Autonegotiation status mirrors link status. */
132
if (link_down) {
133
trace_lan9118_phy_update_link("down");
134
- s->status &= ~0x0024;
135
+ s->status &= ~(MII_BMSR_AN_COMP | MII_BMSR_LINK_ST);
136
s->ints |= PHY_INT_DOWN;
137
} else {
138
trace_lan9118_phy_update_link("up");
139
- s->status |= 0x0024;
140
+ s->status |= MII_BMSR_AN_COMP | MII_BMSR_LINK_ST;
141
s->ints |= PHY_INT_ENERGYON;
142
s->ints |= PHY_INT_AUTONEG_COMPLETE;
143
}
144
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_reset(Lan9118PhyState *s)
145
{
146
trace_lan9118_phy_reset();
147
148
- s->control = 0x3000;
149
- s->status = 0x7809;
150
- s->advertise = 0x01e1;
151
+ s->control = MII_BMCR_AUTOEN | MII_BMCR_SPEED100;
152
+ s->status = MII_BMSR_100TX_FD
153
+ | MII_BMSR_100TX_HD
154
+ | MII_BMSR_10T_FD
155
+ | MII_BMSR_10T_HD
156
+ | MII_BMSR_AUTONEG
157
+ | MII_BMSR_EXTCAP;
158
+ s->advertise = MII_ANAR_TXFD
159
+ | MII_ANAR_TX
160
+ | MII_ANAR_10FD
161
+ | MII_ANAR_10
162
+ | MII_ANAR_CSMACD;
163
s->int_mask = 0;
164
s->ints = 0;
165
lan9118_phy_update_link(s, s->link_down);
106
--
166
--
107
2.20.1
167
2.34.1
108
109
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
This is BFMLAL{B,T} for both AArch64 AdvSIMD and SVE,
3
The real device advertises this mode and the device model already advertises
4
and VFMA{B,T}.BF16 for AArch32 NEON.
4
100 mbps half duplex and 10 mbps full+half duplex. So advertise this mode to
5
make the model more realistic.
5
6
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
8
Message-id: 20210525225817.400336-11-richard.henderson@linaro.org
9
Tested-by: Guenter Roeck <linux@roeck-us.net>
10
Message-id: 20241102125724.532843-6-shentey@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/helper.h | 2 ++
13
hw/net/lan9118_phy.c | 4 ++--
12
target/arm/neon-shared.decode | 2 ++
14
1 file changed, 2 insertions(+), 2 deletions(-)
13
target/arm/sve.decode | 2 ++
14
target/arm/translate-a64.c | 15 ++++++++++++++-
15
target/arm/translate-neon.c | 10 ++++++++++
16
target/arm/translate-sve.c | 30 ++++++++++++++++++++++++++++++
17
target/arm/vec_helper.c | 22 ++++++++++++++++++++++
18
7 files changed, 82 insertions(+), 1 deletion(-)
19
15
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.h
18
--- a/hw/net/lan9118_phy.c
23
+++ b/target/arm/helper.h
19
+++ b/hw/net/lan9118_phy.c
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_bfmmla, TCG_CALL_NO_RWG,
20
@@ -XXX,XX +XXX,XX @@ void lan9118_phy_write(Lan9118PhyState *s, int reg, uint16_t val)
25
26
DEF_HELPER_FLAGS_6(gvec_bfmlal, TCG_CALL_NO_RWG,
27
void, ptr, ptr, ptr, ptr, ptr, i32)
28
+DEF_HELPER_FLAGS_6(gvec_bfmlal_idx, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, ptr, i32)
30
31
#ifdef TARGET_AARCH64
32
#include "helper-a64.h"
33
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/neon-shared.decode
36
+++ b/target/arm/neon-shared.decode
37
@@ -XXX,XX +XXX,XX @@ VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 0 . 1 index:1 ... \
38
rm=%vfml_scalar_q0_rm vn=%vn_sp vd=%vd_dp q=0
39
VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 1 . 1 . rm:3 \
40
index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp q=1
41
+VFMA_b16_scal 1111 1110 0.11 .... .... 1000 . q:1 . 1 . vm:3 \
42
+ index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp
43
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/sve.decode
46
+++ b/target/arm/sve.decode
47
@@ -XXX,XX +XXX,XX @@ FMLALB_zzxw 01100100 10 1 ..... 0100.0 ..... ..... @rrxr_3a esz=2
48
FMLALT_zzxw 01100100 10 1 ..... 0100.1 ..... ..... @rrxr_3a esz=2
49
FMLSLB_zzxw 01100100 10 1 ..... 0110.0 ..... ..... @rrxr_3a esz=2
50
FMLSLT_zzxw 01100100 10 1 ..... 0110.1 ..... ..... @rrxr_3a esz=2
51
+BFMLALB_zzxw 01100100 11 1 ..... 0100.0 ..... ..... @rrxr_3a esz=2
52
+BFMLALT_zzxw 01100100 11 1 ..... 0100.1 ..... ..... @rrxr_3a esz=2
53
54
### SVE2 floating-point bfloat16 dot-product (indexed)
55
BFDOT_zzxz 01100100 01 1 ..... 010000 ..... ..... @rrxr_2 esz=2
56
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate-a64.c
59
+++ b/target/arm/translate-a64.c
60
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
61
unallocated_encoding(s);
62
return;
63
}
64
+ size = MO_32;
65
break;
66
case 1: /* BFDOT */
67
if (is_scalar || !dc_isar_feature(aa64_bf16, s)) {
68
unallocated_encoding(s);
69
return;
70
}
71
+ size = MO_32;
72
+ break;
73
+ case 3: /* BFMLAL{B,T} */
74
+ if (is_scalar || !dc_isar_feature(aa64_bf16, s)) {
75
+ unallocated_encoding(s);
76
+ return;
77
+ }
78
+ /* can't set is_fp without other incorrect size checks */
79
+ size = MO_16;
80
break;
81
default:
82
unallocated_encoding(s);
83
return;
84
}
85
- size = MO_32;
86
break;
21
break;
87
case 0x11: /* FCMLA #0 */
22
case MII_ANAR:
88
case 0x13: /* FCMLA #90 */
23
s->advertise = (val & (MII_ANAR_RFAULT | MII_ANAR_PAUSE_ASYM |
89
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
24
- MII_ANAR_PAUSE | MII_ANAR_10FD | MII_ANAR_10 |
90
gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
25
- MII_ANAR_SELECT))
91
gen_helper_gvec_usdot_idx_b);
26
+ MII_ANAR_PAUSE | MII_ANAR_TXFD | MII_ANAR_10FD |
92
return;
27
+ MII_ANAR_10 | MII_ANAR_SELECT))
93
+ case 3: /* BFMLAL{B,T} */
28
| MII_ANAR_TX;
94
+ gen_gvec_op4_fpst(s, 1, rd, rn, rm, rd, 0, (index << 1) | is_q,
29
break;
95
+ gen_helper_gvec_bfmlal_idx);
30
case 30: /* Interrupt mask */
96
+ return;
97
}
98
g_assert_not_reached();
99
case 0x11: /* FCMLA #0 */
100
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/target/arm/translate-neon.c
103
+++ b/target/arm/translate-neon.c
104
@@ -XXX,XX +XXX,XX @@ static bool trans_VFMA_b16(DisasContext *s, arg_VFMA_b16 *a)
105
return do_neon_ddda_fpst(s, 7, a->vd, a->vn, a->vm, a->q, FPST_STD,
106
gen_helper_gvec_bfmlal);
107
}
108
+
109
+static bool trans_VFMA_b16_scal(DisasContext *s, arg_VFMA_b16_scal *a)
110
+{
111
+ if (!dc_isar_feature(aa32_bf16, s)) {
112
+ return false;
113
+ }
114
+ return do_neon_ddda_fpst(s, 6, a->vd, a->vn, a->vm,
115
+ (a->index << 1) | a->q, FPST_STD,
116
+ gen_helper_gvec_bfmlal_idx);
117
+}
118
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
119
index XXXXXXX..XXXXXXX 100644
120
--- a/target/arm/translate-sve.c
121
+++ b/target/arm/translate-sve.c
122
@@ -XXX,XX +XXX,XX @@ static bool trans_BFMLALT_zzzw(DisasContext *s, arg_rrrr_esz *a)
123
{
124
return do_BFMLAL_zzzw(s, a, true);
125
}
126
+
127
+static bool do_BFMLAL_zzxw(DisasContext *s, arg_rrxr_esz *a, bool sel)
128
+{
129
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
130
+ return false;
131
+ }
132
+ if (sve_access_check(s)) {
133
+ TCGv_ptr status = fpstatus_ptr(FPST_FPCR);
134
+ unsigned vsz = vec_full_reg_size(s);
135
+
136
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
137
+ vec_full_reg_offset(s, a->rn),
138
+ vec_full_reg_offset(s, a->rm),
139
+ vec_full_reg_offset(s, a->ra),
140
+ status, vsz, vsz, (a->index << 1) | sel,
141
+ gen_helper_gvec_bfmlal_idx);
142
+ tcg_temp_free_ptr(status);
143
+ }
144
+ return true;
145
+}
146
+
147
+static bool trans_BFMLALB_zzxw(DisasContext *s, arg_rrxr_esz *a)
148
+{
149
+ return do_BFMLAL_zzxw(s, a, false);
150
+}
151
+
152
+static bool trans_BFMLALT_zzxw(DisasContext *s, arg_rrxr_esz *a)
153
+{
154
+ return do_BFMLAL_zzxw(s, a, true);
155
+}
156
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
157
index XXXXXXX..XXXXXXX 100644
158
--- a/target/arm/vec_helper.c
159
+++ b/target/arm/vec_helper.c
160
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_bfmlal)(void *vd, void *vn, void *vm, void *va,
161
}
162
clear_tail(d, opr_sz, simd_maxsz(desc));
163
}
164
+
165
+void HELPER(gvec_bfmlal_idx)(void *vd, void *vn, void *vm,
166
+ void *va, void *stat, uint32_t desc)
167
+{
168
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
169
+ intptr_t sel = extract32(desc, SIMD_DATA_SHIFT, 1);
170
+ intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 1, 3);
171
+ intptr_t elements = opr_sz / 4;
172
+ intptr_t eltspersegment = MIN(16 / 4, elements);
173
+ float32 *d = vd, *a = va;
174
+ bfloat16 *n = vn, *m = vm;
175
+
176
+ for (i = 0; i < elements; i += eltspersegment) {
177
+ float32 m_idx = m[H2(2 * i + index)] << 16;
178
+
179
+ for (j = i; j < i + eltspersegment; j++) {
180
+ float32 n_j = n[H2(2 * j + sel)] << 16;
181
+ d[H4(j)] = float32_muladd(n_j, m_idx, a[H4(j)], 0, stat);
182
+ }
183
+ }
184
+ clear_tail(d, opr_sz, simd_maxsz(desc));
185
+}
186
--
31
--
187
2.20.1
32
2.34.1
188
189
diff view generated by jsdifflib
1
Some v8M instructions are present if either the floating point
1
For IEEE fused multiply-add, the (0 * inf) + NaN case should raise
2
extension or MVE is implemented. Update our implementation of them
2
Invalid for the multiplication of 0 by infinity. Currently we handle
3
to check for MVE as well as for FP.
3
this in the per-architecture ifdef ladder in pickNaNMulAdd().
4
However, since this isn't really architecture specific we can hoist
5
it up to the generic code.
4
6
5
This is all the insns which use CheckDecodeFaults(ExtType_MveOrFp) or
7
For the cases where the infzero test in pickNaNMulAdd was
6
CheckDecodeFaults(ExtType_MveOrDpFp) in their pseudocode, which are
8
returning 2, we can delete the check entirely and allow the
7
essentially the loads and stores, moves and sysreg accesses, except
9
code to fall into the normal pick-a-NaN handling, because this
8
for VMOV_reg_sp and VMOV_reg_dp, which we handle in subsequent
10
will return 2 anyway (input 'c' being the only NaN in this case).
9
patches because they need a refactor to provide a place to put the
11
For the cases where infzero was returning 3 to indicate "return
10
new MVE check.
12
the default NaN", we must retain that "return 3".
13
14
For Arm, this looks like it might be a behaviour change because we
15
used to set float_flag_invalid | float_flag_invalid_imz only if C is
16
a quiet NaN. However, it is not, because Arm target code never looks
17
at float_flag_invalid_imz, and for the (0 * inf) + SNaN case we
18
already raised float_flag_invalid via the "abc_mask &
19
float_cmask_snan" check in pick_nan_muladd.
20
21
For any target architecture using the "default implementation" at the
22
bottom of the ifdef, this is a behaviour change but will be fixing a
23
bug (where we failed to raise the Invalid exception for (0 * inf +
24
QNaN). The architectures using the default case are:
25
* hppa
26
* i386
27
* sh4
28
* tricore
29
30
The x86, Tricore and SH4 CPU architecture manuals are clear that this
31
should have raised Invalid; HPPA is a bit vaguer but still seems
32
clear enough.
11
33
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
35
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210520152840.24453-3-peter.maydell@linaro.org
36
Message-id: 20241202131347.498124-2-peter.maydell@linaro.org
15
---
37
---
16
target/arm/translate-vfp.c | 48 +++++++++++++++++++++++---------------
38
fpu/softfloat-parts.c.inc | 13 +++++++------
17
1 file changed, 29 insertions(+), 19 deletions(-)
39
fpu/softfloat-specialize.c.inc | 29 +----------------------------
40
2 files changed, 8 insertions(+), 34 deletions(-)
18
41
19
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
42
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
20
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate-vfp.c
44
--- a/fpu/softfloat-parts.c.inc
22
+++ b/target/arm/translate-vfp.c
45
+++ b/fpu/softfloat-parts.c.inc
23
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_to_gp(DisasContext *s, arg_VMOV_to_gp *a)
46
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
24
/* VMOV scalar to general purpose register */
47
int ab_mask, int abc_mask)
25
TCGv_i32 tmp;
48
{
26
49
int which;
27
- /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
50
+ bool infzero = (ab_mask == float_cmask_infzero);
28
- if (a->size == MO_32
51
29
- ? !dc_isar_feature(aa32_fpsp_v2, s)
52
if (unlikely(abc_mask & float_cmask_snan)) {
30
- : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
53
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
31
- return false;
32
+ /*
33
+ * SIZE == MO_32 is a VFP instruction; otherwise NEON. MVE has
34
+ * all sizes, whether the CPU has fp or not.
35
+ */
36
+ if (!dc_isar_feature(aa32_mve, s)) {
37
+ if (a->size == MO_32
38
+ ? !dc_isar_feature(aa32_fpsp_v2, s)
39
+ : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
40
+ return false;
41
+ }
42
}
54
}
43
55
44
/* UNDEF accesses to D16-D31 if they don't exist */
56
- which = pickNaNMulAdd(a->cls, b->cls, c->cls,
45
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_from_gp(DisasContext *s, arg_VMOV_from_gp *a)
57
- ab_mask == float_cmask_infzero, s);
46
/* VMOV general purpose register to scalar */
58
+ if (infzero) {
47
TCGv_i32 tmp;
59
+ /* This is (0 * inf) + NaN or (inf * 0) + NaN */
48
60
+ float_raise(float_flag_invalid | float_flag_invalid_imz, s);
49
- /* SIZE == MO_32 is a VFP instruction; otherwise NEON. */
61
+ }
50
- if (a->size == MO_32
62
+
51
- ? !dc_isar_feature(aa32_fpsp_v2, s)
63
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
52
- : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
64
53
- return false;
65
if (s->default_nan_mode || which == 3) {
54
+ /*
66
- /*
55
+ * SIZE == MO_32 is a VFP instruction; otherwise NEON. MVE has
67
- * Note that this check is after pickNaNMulAdd so that function
56
+ * all sizes, whether the CPU has fp or not.
68
- * has an opportunity to set the Invalid flag for infzero.
57
+ */
69
- */
58
+ if (!dc_isar_feature(aa32_mve, s)) {
70
parts_default_nan(a, s);
59
+ if (a->size == MO_32
71
return a;
60
+ ? !dc_isar_feature(aa32_fpsp_v2, s)
61
+ : !arm_dc_feature(s, ARM_FEATURE_NEON)) {
62
+ return false;
63
+ }
64
}
72
}
65
73
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
66
/* UNDEF accesses to D16-D31 if they don't exist */
74
index XXXXXXX..XXXXXXX 100644
67
@@ -XXX,XX +XXX,XX @@ typedef enum FPSysRegCheckResult {
75
--- a/fpu/softfloat-specialize.c.inc
68
76
+++ b/fpu/softfloat-specialize.c.inc
69
static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
77
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
70
{
78
* the default NaN
71
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
79
*/
72
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
80
if (infzero && is_qnan(c_cls)) {
73
return FPSysRegCheckFailed;
81
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
82
return 3;
74
}
83
}
75
84
76
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_single(DisasContext *s, arg_VMOV_single *a)
85
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
77
{
86
* case sets InvalidOp and returns the default NaN
78
TCGv_i32 tmp;
87
*/
79
88
if (infzero) {
80
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
89
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
81
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
90
return 3;
82
return false;
91
}
92
/* Prefer sNaN over qNaN, in the a, b, c order. */
93
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
94
* For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
95
* case sets InvalidOp and returns the input value 'c'
96
*/
97
- if (infzero) {
98
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
99
- return 2;
100
- }
101
/* Prefer sNaN over qNaN, in the c, a, b order. */
102
if (is_snan(c_cls)) {
103
return 2;
104
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
105
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
106
* case sets InvalidOp and returns the input value 'c'
107
*/
108
- if (infzero) {
109
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
110
- return 2;
111
- }
112
+
113
/* Prefer sNaN over qNaN, in the c, a, b order. */
114
if (is_snan(c_cls)) {
115
return 2;
116
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
117
* to return an input NaN if we have one (ie c) rather than generating
118
* a default NaN
119
*/
120
- if (infzero) {
121
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
122
- return 2;
123
- }
124
125
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
126
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
127
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
128
return 1;
83
}
129
}
84
130
#elif defined(TARGET_RISCV)
85
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
131
- /* For RISC-V, InvalidOp is set when multiplicands are Inf and zero */
86
{
132
- if (infzero) {
87
TCGv_i32 tmp;
133
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
88
134
- }
89
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
135
return 3; /* default NaN */
90
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
136
#elif defined(TARGET_S390X)
91
return false;
137
if (infzero) {
138
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
139
return 3;
92
}
140
}
93
141
94
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_dp(DisasContext *s, arg_VMOV_64_dp *a)
142
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
95
* floating point register. Note that this does not require support
143
return 2;
96
* for double precision arithmetic.
144
}
145
#elif defined(TARGET_SPARC)
146
- /* For (inf,0,nan) return c. */
147
- if (infzero) {
148
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
149
- return 2;
150
- }
151
/* Prefer SNaN over QNaN, order C, B, A. */
152
if (is_snan(c_cls)) {
153
return 2;
154
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
155
* For Xtensa, the (inf,zero,nan) case sets InvalidOp and returns
156
* an input NaN if we have one (ie c).
97
*/
157
*/
98
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
158
- if (infzero) {
99
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
159
- float_raise(float_flag_invalid | float_flag_invalid_imz, status);
100
return false;
160
- return 2;
101
}
161
- }
102
162
if (status->use_first_nan) {
103
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_hp(DisasContext *s, arg_VLDR_VSTR_sp *a)
163
if (is_nan(a_cls)) {
104
uint32_t offset;
164
return 0;
105
TCGv_i32 addr, tmp;
106
107
- if (!dc_isar_feature(aa32_fp16_arith, s)) {
108
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
109
return false;
110
}
111
112
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
113
uint32_t offset;
114
TCGv_i32 addr, tmp;
115
116
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
117
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
118
return false;
119
}
120
121
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
122
TCGv_i64 tmp;
123
124
/* Note that this does not require support for double arithmetic. */
125
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
126
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
127
return false;
128
}
129
130
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
131
TCGv_i32 addr, tmp;
132
int i, n;
133
134
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
135
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
136
return false;
137
}
138
139
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
140
int i, n;
141
142
/* Note that this does not require support for double arithmetic. */
143
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
144
+ if (!dc_isar_feature(aa32_fpsp_v2, s) && !dc_isar_feature(aa32_mve, s)) {
145
return false;
146
}
147
148
--
165
--
149
2.20.1
166
2.34.1
150
151
diff view generated by jsdifflib
New patch
1
If the target sets default_nan_mode then we're always going to return
2
the default NaN, and pickNaNMulAdd() no longer has any side effects.
3
For consistency with pickNaN(), check for default_nan_mode before
4
calling pickNaNMulAdd().
1
5
6
When we convert pickNaNMulAdd() to allow runtime selection of the NaN
7
propagation rule, this means we won't have to make the targets which
8
use default_nan_mode also set a propagation rule.
9
10
Since RiscV always uses default_nan_mode, this allows us to remove
11
its ifdef case from pickNaNMulAdd().
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20241202131347.498124-3-peter.maydell@linaro.org
16
---
17
fpu/softfloat-parts.c.inc | 8 ++++++--
18
fpu/softfloat-specialize.c.inc | 9 +++++++--
19
2 files changed, 13 insertions(+), 4 deletions(-)
20
21
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
22
index XXXXXXX..XXXXXXX 100644
23
--- a/fpu/softfloat-parts.c.inc
24
+++ b/fpu/softfloat-parts.c.inc
25
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
26
float_raise(float_flag_invalid | float_flag_invalid_imz, s);
27
}
28
29
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
30
+ if (s->default_nan_mode) {
31
+ which = 3;
32
+ } else {
33
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
34
+ }
35
36
- if (s->default_nan_mode || which == 3) {
37
+ if (which == 3) {
38
parts_default_nan(a, s);
39
return a;
40
}
41
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
42
index XXXXXXX..XXXXXXX 100644
43
--- a/fpu/softfloat-specialize.c.inc
44
+++ b/fpu/softfloat-specialize.c.inc
45
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
46
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
47
bool infzero, float_status *status)
48
{
49
+ /*
50
+ * We guarantee not to require the target to tell us how to
51
+ * pick a NaN if we're always returning the default NaN.
52
+ * But if we're not in default-NaN mode then the target must
53
+ * specify.
54
+ */
55
+ assert(!status->default_nan_mode);
56
#if defined(TARGET_ARM)
57
/* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
58
* the default NaN
59
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
60
} else {
61
return 1;
62
}
63
-#elif defined(TARGET_RISCV)
64
- return 3; /* default NaN */
65
#elif defined(TARGET_S390X)
66
if (infzero) {
67
return 3;
68
--
69
2.34.1
diff view generated by jsdifflib
1
Add the isar feature check functions we will need for v8.1M MVE:
1
IEEE 758 does not define a fixed rule for what NaN to return in
2
* a check for MVE present: this corresponds to the pseudocode's
2
the case of a fused multiply-add of inf * 0 + NaN. Different
3
CheckDecodeFaults(ExtType_Mve)
3
architectures thus do different things:
4
* a check for the optional floating-point part of MVE: this
4
* some return the default NaN
5
corresponds to CheckDecodeFaults(ExtType_MveFp)
5
* some return the input NaN
6
* Arm returns the default NaN if the input NaN is quiet,
7
and the input NaN if it is signalling
8
9
We want to make this logic be runtime selected rather than
10
hardcoded into the binary, because:
11
* this will let us have multiple targets in one QEMU binary
12
* the Arm FEAT_AFP architectural feature includes letting
13
the guest select a NaN propagation rule at runtime
14
15
In this commit we add an enum for the propagation rule, the field in
16
float_status, and the corresponding getters and setters. We change
17
pickNaNMulAdd to honour this, but because all targets still leave
18
this field at its default 0 value, the fallback logic will pick the
19
rule type with the old ifdef ladder.
20
21
Note that four architectures both use the muladd softfloat functions
22
and did not have a branch of the ifdef ladder to specify their
23
behaviour (and so were ending up with the "default" case, probably
24
wrongly): i386, HPPA, SH4 and Tricore. SH4 and Tricore both set
25
default_nan_mode, and so will never get into pickNaNMulAdd(). For
26
HPPA and i386 we retain the same behaviour as the old default-case,
27
which is to not ever return the default NaN. This might not be
28
correct but it is not a behaviour change.
6
29
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210520152840.24453-2-peter.maydell@linaro.org
32
Message-id: 20241202131347.498124-4-peter.maydell@linaro.org
10
---
33
---
11
target/arm/cpu.h | 22 ++++++++++++++++++++++
34
include/fpu/softfloat-helpers.h | 11 ++++
12
1 file changed, 22 insertions(+)
35
include/fpu/softfloat-types.h | 23 +++++++++
13
36
fpu/softfloat-specialize.c.inc | 91 ++++++++++++++++++++++-----------
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
37
3 files changed, 95 insertions(+), 30 deletions(-)
38
39
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
15
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
41
--- a/include/fpu/softfloat-helpers.h
17
+++ b/target/arm/cpu.h
42
+++ b/include/fpu/softfloat-helpers.h
18
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
43
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
19
}
44
status->float_2nan_prop_rule = rule;
20
}
45
}
21
46
22
+static inline bool isar_feature_aa32_mve(const ARMISARegisters *id)
47
+static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
48
+ float_status *status)
23
+{
49
+{
24
+ /*
50
+ status->float_infzeronan_rule = rule;
25
+ * Return true if MVE is supported (either integer or floating point).
26
+ * We must check for M-profile as the MVFR1 field means something
27
+ * else for A-profile.
28
+ */
29
+ return isar_feature_aa32_mprofile(id) &&
30
+ FIELD_EX32(id->mvfr1, MVFR1, MVE) > 0;
31
+}
51
+}
32
+
52
+
33
+static inline bool isar_feature_aa32_mve_fp(const ARMISARegisters *id)
53
static inline void set_flush_to_zero(bool val, float_status *status)
54
{
55
status->flush_to_zero = val;
56
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
57
return status->float_2nan_prop_rule;
58
}
59
60
+static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
34
+{
61
+{
35
+ /*
62
+ return status->float_infzeronan_rule;
36
+ * Return true if MVE is supported (either integer or floating point).
37
+ * We must check for M-profile as the MVFR1 field means something
38
+ * else for A-profile.
39
+ */
40
+ return isar_feature_aa32_mprofile(id) &&
41
+ FIELD_EX32(id->mvfr1, MVFR1, MVE) >= 2;
42
+}
63
+}
43
+
64
+
44
static inline bool isar_feature_aa32_vfp_simd(const ARMISARegisters *id)
65
static inline bool get_flush_to_zero(float_status *status)
45
{
66
{
67
return status->flush_to_zero;
68
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
69
index XXXXXXX..XXXXXXX 100644
70
--- a/include/fpu/softfloat-types.h
71
+++ b/include/fpu/softfloat-types.h
72
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
73
float_2nan_prop_x87,
74
} Float2NaNPropRule;
75
76
+/*
77
+ * Rule for result of fused multiply-add 0 * Inf + NaN.
78
+ * This must be a NaN, but implementations differ on whether this
79
+ * is the input NaN or the default NaN.
80
+ *
81
+ * You don't need to set this if default_nan_mode is enabled.
82
+ * When not in default-NaN mode, it is an error for the target
83
+ * not to set the rule in float_status if it uses muladd, and we
84
+ * will assert if we need to handle an input NaN and no rule was
85
+ * selected.
86
+ */
87
+typedef enum __attribute__((__packed__)) {
88
+ /* No propagation rule specified */
89
+ float_infzeronan_none = 0,
90
+ /* Result is never the default NaN (so always the input NaN) */
91
+ float_infzeronan_dnan_never,
92
+ /* Result is always the default NaN */
93
+ float_infzeronan_dnan_always,
94
+ /* Result is the default NaN if the input NaN is quiet */
95
+ float_infzeronan_dnan_if_qnan,
96
+} FloatInfZeroNaNRule;
97
+
98
/*
99
* Floating Point Status. Individual architectures may maintain
100
* several versions of float_status for different functions. The
101
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
102
FloatRoundMode float_rounding_mode;
103
FloatX80RoundPrec floatx80_rounding_precision;
104
Float2NaNPropRule float_2nan_prop_rule;
105
+ FloatInfZeroNaNRule float_infzeronan_rule;
106
bool tininess_before_rounding;
107
/* should denormalised results go to zero and set the inexact flag? */
108
bool flush_to_zero;
109
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
110
index XXXXXXX..XXXXXXX 100644
111
--- a/fpu/softfloat-specialize.c.inc
112
+++ b/fpu/softfloat-specialize.c.inc
113
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
114
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
115
bool infzero, float_status *status)
116
{
117
+ FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
118
+
46
/*
119
/*
120
* We guarantee not to require the target to tell us how to
121
* pick a NaN if we're always returning the default NaN.
122
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
123
* specify.
124
*/
125
assert(!status->default_nan_mode);
126
+
127
+ if (rule == float_infzeronan_none) {
128
+ /*
129
+ * Temporarily fall back to ifdef ladder
130
+ */
131
#if defined(TARGET_ARM)
132
- /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
133
- * the default NaN
134
- */
135
- if (infzero && is_qnan(c_cls)) {
136
- return 3;
137
+ /*
138
+ * For ARM, the (inf,zero,qnan) case returns the default NaN,
139
+ * but (inf,zero,snan) returns the input NaN.
140
+ */
141
+ rule = float_infzeronan_dnan_if_qnan;
142
+#elif defined(TARGET_MIPS)
143
+ if (snan_bit_is_one(status)) {
144
+ /*
145
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
146
+ * case sets InvalidOp and returns the default NaN
147
+ */
148
+ rule = float_infzeronan_dnan_always;
149
+ } else {
150
+ /*
151
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
152
+ * case sets InvalidOp and returns the input value 'c'
153
+ */
154
+ rule = float_infzeronan_dnan_never;
155
+ }
156
+#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
157
+ defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
158
+ defined(TARGET_I386) || defined(TARGET_LOONGARCH)
159
+ /*
160
+ * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
161
+ * case sets InvalidOp and returns the input value 'c'
162
+ */
163
+ /*
164
+ * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
165
+ * to return an input NaN if we have one (ie c) rather than generating
166
+ * a default NaN
167
+ */
168
+ rule = float_infzeronan_dnan_never;
169
+#elif defined(TARGET_S390X)
170
+ rule = float_infzeronan_dnan_always;
171
+#endif
172
}
173
174
+ if (infzero) {
175
+ /*
176
+ * Inf * 0 + NaN -- some implementations return the default NaN here,
177
+ * and some return the input NaN.
178
+ */
179
+ switch (rule) {
180
+ case float_infzeronan_dnan_never:
181
+ return 2;
182
+ case float_infzeronan_dnan_always:
183
+ return 3;
184
+ case float_infzeronan_dnan_if_qnan:
185
+ return is_qnan(c_cls) ? 3 : 2;
186
+ default:
187
+ g_assert_not_reached();
188
+ }
189
+ }
190
+
191
+#if defined(TARGET_ARM)
192
+
193
/* This looks different from the ARM ARM pseudocode, because the ARM ARM
194
* puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
195
*/
196
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
197
}
198
#elif defined(TARGET_MIPS)
199
if (snan_bit_is_one(status)) {
200
- /*
201
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
202
- * case sets InvalidOp and returns the default NaN
203
- */
204
- if (infzero) {
205
- return 3;
206
- }
207
/* Prefer sNaN over qNaN, in the a, b, c order. */
208
if (is_snan(a_cls)) {
209
return 0;
210
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
211
return 2;
212
}
213
} else {
214
- /*
215
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
216
- * case sets InvalidOp and returns the input value 'c'
217
- */
218
/* Prefer sNaN over qNaN, in the c, a, b order. */
219
if (is_snan(c_cls)) {
220
return 2;
221
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
222
}
223
}
224
#elif defined(TARGET_LOONGARCH64)
225
- /*
226
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
227
- * case sets InvalidOp and returns the input value 'c'
228
- */
229
-
230
/* Prefer sNaN over qNaN, in the c, a, b order. */
231
if (is_snan(c_cls)) {
232
return 2;
233
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
234
return 1;
235
}
236
#elif defined(TARGET_PPC)
237
- /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
238
- * to return an input NaN if we have one (ie c) rather than generating
239
- * a default NaN
240
- */
241
-
242
/* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
243
* otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
244
*/
245
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
246
return 1;
247
}
248
#elif defined(TARGET_S390X)
249
- if (infzero) {
250
- return 3;
251
- }
252
-
253
if (is_snan(a_cls)) {
254
return 0;
255
} else if (is_snan(b_cls)) {
47
--
256
--
48
2.20.1
257
2.34.1
49
50
diff view generated by jsdifflib
New patch
1
Explicitly set a rule in the softfloat tests for the inf-zero-nan
2
muladd special case. In meson.build we put -DTARGET_ARM in fpcflags,
3
and so we should select here the Arm rule of
4
float_infzeronan_dnan_if_qnan.
1
5
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20241202131347.498124-5-peter.maydell@linaro.org
9
---
10
tests/fp/fp-bench.c | 5 +++++
11
tests/fp/fp-test.c | 5 +++++
12
2 files changed, 10 insertions(+)
13
14
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/fp/fp-bench.c
17
+++ b/tests/fp/fp-bench.c
18
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
19
{
20
bench_func_t f;
21
22
+ /*
23
+ * These implementation-defined choices for various things IEEE
24
+ * doesn't specify match those used by the Arm architecture.
25
+ */
26
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
27
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
28
29
f = bench_funcs[operation][precision];
30
g_assert(f);
31
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/tests/fp/fp-test.c
34
+++ b/tests/fp/fp-test.c
35
@@ -XXX,XX +XXX,XX @@ void run_test(void)
36
{
37
unsigned int i;
38
39
+ /*
40
+ * These implementation-defined choices for various things IEEE
41
+ * doesn't specify match those used by the Arm architecture.
42
+ */
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
44
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
45
46
genCases_setLevel(test_level);
47
verCases_maxErrorCount = n_max_errors;
48
--
49
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Set the FloatInfZeroNaNRule explicitly for the Arm target,
2
so we can remove the ifdef from pickNaNMulAdd().
2
3
3
Disable BF16 again for !have_neon and !have_vfp during realize.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210525225817.400336-13-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-6-peter.maydell@linaro.org
9
---
7
---
10
target/arm/cpu.c | 3 +++
8
target/arm/cpu.c | 3 +++
11
target/arm/cpu64.c | 3 +++
9
fpu/softfloat-specialize.c.inc | 8 +-------
12
target/arm/cpu_tcg.c | 1 +
10
2 files changed, 4 insertions(+), 7 deletions(-)
13
3 files changed, 7 insertions(+)
14
11
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.c
14
--- a/target/arm/cpu.c
18
+++ b/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
16
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
20
17
* * tininess-before-rounding
21
u = cpu->isar.id_isar6;
18
* * 2-input NaN propagation prefers SNaN over QNaN, and then
22
u = FIELD_DP32(u, ID_ISAR6, JSCVT, 0);
19
* operand A over operand B (see FPProcessNaNs() pseudocode)
23
+ u = FIELD_DP32(u, ID_ISAR6, BF16, 0);
20
+ * * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
24
cpu->isar.id_isar6 = u;
21
+ * and the input NaN if it is signalling
25
22
*/
26
u = cpu->isar.mvfr0;
23
static void arm_set_default_fp_behaviours(float_status *s)
27
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
24
{
28
25
set_float_detect_tininess(float_tininess_before_rounding, s);
29
t = cpu->isar.id_aa64isar1;
26
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
30
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 0);
27
+ set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
31
+ t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 0);
28
}
32
t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 0);
29
33
cpu->isar.id_aa64isar1 = t;
30
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
34
31
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
35
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
36
u = cpu->isar.id_isar6;
37
u = FIELD_DP32(u, ID_ISAR6, DP, 0);
38
u = FIELD_DP32(u, ID_ISAR6, FHM, 0);
39
+ u = FIELD_DP32(u, ID_ISAR6, BF16, 0);
40
u = FIELD_DP32(u, ID_ISAR6, I8MM, 0);
41
cpu->isar.id_isar6 = u;
42
43
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
44
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/cpu64.c
33
--- a/fpu/softfloat-specialize.c.inc
46
+++ b/target/arm/cpu64.c
34
+++ b/fpu/softfloat-specialize.c.inc
47
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
35
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
48
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
36
/*
49
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
37
* Temporarily fall back to ifdef ladder
50
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
38
*/
51
+ t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1);
39
-#if defined(TARGET_ARM)
52
t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
40
- /*
53
t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2); /* ARMv8.4-RCPC */
41
- * For ARM, the (inf,zero,qnan) case returns the default NaN,
54
t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1);
42
- * but (inf,zero,snan) returns the input NaN.
55
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
43
- */
56
t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1);
44
- rule = float_infzeronan_dnan_if_qnan;
57
t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2); /* PMULL */
45
-#elif defined(TARGET_MIPS)
58
t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1);
46
+#if defined(TARGET_MIPS)
59
+ t = FIELD_DP64(t, ID_AA64ZFR0, BFLOAT16, 1);
47
if (snan_bit_is_one(status)) {
60
t = FIELD_DP64(t, ID_AA64ZFR0, SHA3, 1);
48
/*
61
t = FIELD_DP64(t, ID_AA64ZFR0, SM4, 1);
49
* For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
62
t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1);
63
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
64
u = FIELD_DP32(u, ID_ISAR6, FHM, 1);
65
u = FIELD_DP32(u, ID_ISAR6, SB, 1);
66
u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
67
+ u = FIELD_DP32(u, ID_ISAR6, BF16, 1);
68
u = FIELD_DP32(u, ID_ISAR6, I8MM, 1);
69
cpu->isar.id_isar6 = u;
70
71
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/cpu_tcg.c
74
+++ b/target/arm/cpu_tcg.c
75
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
76
t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
77
t = FIELD_DP32(t, ID_ISAR6, SB, 1);
78
t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
79
+ t = FIELD_DP32(t, ID_ISAR6, BF16, 1);
80
t = FIELD_DP32(t, ID_ISAR6, I8MM, 1);
81
cpu->isar.id_isar6 = t;
82
83
--
50
--
84
2.20.1
51
2.34.1
85
86
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for s390, so we
2
can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-7-peter.maydell@linaro.org
7
---
8
target/s390x/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/s390x/cpu.c
15
+++ b/target/s390x/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
17
set_float_detect_tininess(float_tininess_before_rounding,
18
&env->fpu_status);
19
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fpu_status);
20
+ set_float_infzeronan_rule(float_infzeronan_dnan_always,
21
+ &env->fpu_status);
22
/* fall through */
23
case RESET_TYPE_S390_CPU_NORMAL:
24
env->psw.mask &= ~PSW_MASK_RI;
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
* a default NaN
31
*/
32
rule = float_infzeronan_dnan_never;
33
-#elif defined(TARGET_S390X)
34
- rule = float_infzeronan_dnan_always;
35
#endif
36
}
37
38
--
39
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the PPC target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-8-peter.maydell@linaro.org
7
---
8
target/ppc/cpu_init.c | 7 +++++++
9
fpu/softfloat-specialize.c.inc | 7 +------
10
2 files changed, 8 insertions(+), 6 deletions(-)
11
12
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/ppc/cpu_init.c
15
+++ b/target/ppc/cpu_init.c
16
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->vec_status);
20
+ /*
21
+ * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
22
+ * to return an input NaN if we have one (ie c) rather than generating
23
+ * a default NaN
24
+ */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
26
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
27
28
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
29
ppc_spr_t *spr = &env->spr_cb[i];
30
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
31
index XXXXXXX..XXXXXXX 100644
32
--- a/fpu/softfloat-specialize.c.inc
33
+++ b/fpu/softfloat-specialize.c.inc
34
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
35
*/
36
rule = float_infzeronan_dnan_never;
37
}
38
-#elif defined(TARGET_PPC) || defined(TARGET_SPARC) || \
39
+#elif defined(TARGET_SPARC) || \
40
defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
41
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
42
/*
43
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
44
* case sets InvalidOp and returns the input value 'c'
45
*/
46
- /*
47
- * For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
48
- * to return an input NaN if we have one (ie c) rather than generating
49
- * a default NaN
50
- */
51
rule = float_infzeronan_dnan_never;
52
#endif
53
}
54
--
55
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the MIPS target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-9-peter.maydell@linaro.org
7
---
8
target/mips/fpu_helper.h | 9 +++++++++
9
target/mips/msa.c | 4 ++++
10
fpu/softfloat-specialize.c.inc | 16 +---------------
11
3 files changed, 14 insertions(+), 15 deletions(-)
12
13
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/mips/fpu_helper.h
16
+++ b/target/mips/fpu_helper.h
17
@@ -XXX,XX +XXX,XX @@ static inline void restore_flush_mode(CPUMIPSState *env)
18
static inline void restore_snan_bit_mode(CPUMIPSState *env)
19
{
20
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
21
+ FloatInfZeroNaNRule izn_rule;
22
23
/*
24
* With nan2008, SNaNs are silenced in the usual way.
25
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
26
*/
27
set_snan_bit_is_one(!nan2008, &env->active_fpu.fp_status);
28
set_default_nan_mode(!nan2008, &env->active_fpu.fp_status);
29
+ /*
30
+ * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
31
+ * case sets InvalidOp and returns the default NaN.
32
+ * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
33
+ * case sets InvalidOp and returns the input value 'c'.
34
+ */
35
+ izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
36
+ set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
37
}
38
39
static inline void restore_fp_status(CPUMIPSState *env)
40
diff --git a/target/mips/msa.c b/target/mips/msa.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/mips/msa.c
43
+++ b/target/mips/msa.c
44
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
45
46
/* set proper signanling bit meaning ("1" means "quiet") */
47
set_snan_bit_is_one(0, &env->active_tc.msa_fp_status);
48
+
49
+ /* Inf * 0 + NaN returns the input NaN */
50
+ set_float_infzeronan_rule(float_infzeronan_dnan_never,
51
+ &env->active_tc.msa_fp_status);
52
}
53
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
54
index XXXXXXX..XXXXXXX 100644
55
--- a/fpu/softfloat-specialize.c.inc
56
+++ b/fpu/softfloat-specialize.c.inc
57
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
58
/*
59
* Temporarily fall back to ifdef ladder
60
*/
61
-#if defined(TARGET_MIPS)
62
- if (snan_bit_is_one(status)) {
63
- /*
64
- * For MIPS systems that conform to IEEE754-1985, the (inf,zero,nan)
65
- * case sets InvalidOp and returns the default NaN
66
- */
67
- rule = float_infzeronan_dnan_always;
68
- } else {
69
- /*
70
- * For MIPS systems that conform to IEEE754-2008, the (inf,zero,nan)
71
- * case sets InvalidOp and returns the input value 'c'
72
- */
73
- rule = float_infzeronan_dnan_never;
74
- }
75
-#elif defined(TARGET_SPARC) || \
76
+#if defined(TARGET_SPARC) || \
77
defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
78
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
79
/*
80
--
81
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the SPARC target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-10-peter.maydell@linaro.org
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 +--
10
2 files changed, 3 insertions(+), 2 deletions(-)
11
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sparc/cpu.c
15
+++ b/target/sparc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
17
* the CPU state struct so it won't get zeroed on reset.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &env->fp_status);
20
+ /* For inf * 0 + NaN, return the input NaN */
21
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
23
cpu_exec_realizefn(cs, &local_err);
24
if (local_err != NULL) {
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
/*
31
* Temporarily fall back to ifdef ladder
32
*/
33
-#if defined(TARGET_SPARC) || \
34
- defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
35
+#if defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
36
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
37
/*
38
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the xtensa target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-11-peter.maydell@linaro.org
7
---
8
target/xtensa/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 +-
10
2 files changed, 3 insertions(+), 1 deletion(-)
11
12
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/xtensa/cpu.c
15
+++ b/target/xtensa/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
17
reset_mmu(env);
18
cs->halted = env->runstall;
19
#endif
20
+ /* For inf * 0 + NaN, return the input NaN */
21
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
set_no_signaling_nans(!dfpu, &env->fp_status);
23
xtensa_use_first_nan(env, !dfpu);
24
}
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
/*
31
* Temporarily fall back to ifdef ladder
32
*/
33
-#if defined(TARGET_XTENSA) || defined(TARGET_HPPA) || \
34
+#if defined(TARGET_HPPA) || \
35
defined(TARGET_I386) || defined(TARGET_LOONGARCH)
36
/*
37
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
38
--
39
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the x86 target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-12-peter.maydell@linaro.org
6
---
7
target/i386/tcg/fpu_helper.c | 7 +++++++
8
fpu/softfloat-specialize.c.inc | 2 +-
9
2 files changed, 8 insertions(+), 1 deletion(-)
10
11
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/i386/tcg/fpu_helper.c
14
+++ b/target/i386/tcg/fpu_helper.c
15
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
16
*/
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->mmx_status);
18
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->sse_status);
19
+ /*
20
+ * Only SSE has multiply-add instructions. In the SDM Section 14.5.2
21
+ * "Fused-Multiply-ADD (FMA) Numeric Behavior" the NaN handling is
22
+ * specified -- for 0 * inf + NaN the input NaN is selected, and if
23
+ * there are multiple input NaNs they are selected in the order a, b, c.
24
+ */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
26
}
27
28
static inline uint8_t save_exception_flags(CPUX86State *env)
29
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
30
index XXXXXXX..XXXXXXX 100644
31
--- a/fpu/softfloat-specialize.c.inc
32
+++ b/fpu/softfloat-specialize.c.inc
33
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
34
* Temporarily fall back to ifdef ladder
35
*/
36
#if defined(TARGET_HPPA) || \
37
- defined(TARGET_I386) || defined(TARGET_LOONGARCH)
38
+ defined(TARGET_LOONGARCH)
39
/*
40
* For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
41
* case sets InvalidOp and returns the input value 'c'
42
--
43
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the loongarch target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-13-peter.maydell@linaro.org
6
---
7
target/loongarch/tcg/fpu_helper.c | 5 +++++
8
fpu/softfloat-specialize.c.inc | 7 +------
9
2 files changed, 6 insertions(+), 6 deletions(-)
10
11
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/loongarch/tcg/fpu_helper.c
14
+++ b/target/loongarch/tcg/fpu_helper.c
15
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
16
&env->fp_status);
17
set_flush_to_zero(0, &env->fp_status);
18
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
19
+ /*
20
+ * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
21
+ * case sets InvalidOp and returns the input value 'c'
22
+ */
23
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
}
25
26
int ieee_ex_to_loongarch(int xcpt)
27
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
28
index XXXXXXX..XXXXXXX 100644
29
--- a/fpu/softfloat-specialize.c.inc
30
+++ b/fpu/softfloat-specialize.c.inc
31
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
32
/*
33
* Temporarily fall back to ifdef ladder
34
*/
35
-#if defined(TARGET_HPPA) || \
36
- defined(TARGET_LOONGARCH)
37
- /*
38
- * For LoongArch systems that conform to IEEE754-2008, the (inf,zero,nan)
39
- * case sets InvalidOp and returns the input value 'c'
40
- */
41
+#if defined(TARGET_HPPA)
42
rule = float_infzeronan_dnan_never;
43
#endif
44
}
45
--
46
2.34.1
diff view generated by jsdifflib
New patch
1
Set the FloatInfZeroNaNRule explicitly for the HPPA target,
2
so we can remove the ifdef from pickNaNMulAdd().
1
3
4
As this is the last target to be converted to explicitly setting
5
the rule, we can remove the fallback code in pickNaNMulAdd()
6
entirely.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20241202131347.498124-14-peter.maydell@linaro.org
11
---
12
target/hppa/fpu_helper.c | 2 ++
13
fpu/softfloat-specialize.c.inc | 13 +------------
14
2 files changed, 3 insertions(+), 12 deletions(-)
15
16
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/hppa/fpu_helper.c
19
+++ b/target/hppa/fpu_helper.c
20
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
21
* HPPA does note implement a CPU reset method at all...
22
*/
23
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
24
+ /* For inf * 0 + NaN, return the input NaN */
25
+ set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
26
}
27
28
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
29
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
30
index XXXXXXX..XXXXXXX 100644
31
--- a/fpu/softfloat-specialize.c.inc
32
+++ b/fpu/softfloat-specialize.c.inc
33
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
34
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
35
bool infzero, float_status *status)
36
{
37
- FloatInfZeroNaNRule rule = status->float_infzeronan_rule;
38
-
39
/*
40
* We guarantee not to require the target to tell us how to
41
* pick a NaN if we're always returning the default NaN.
42
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
43
*/
44
assert(!status->default_nan_mode);
45
46
- if (rule == float_infzeronan_none) {
47
- /*
48
- * Temporarily fall back to ifdef ladder
49
- */
50
-#if defined(TARGET_HPPA)
51
- rule = float_infzeronan_dnan_never;
52
-#endif
53
- }
54
-
55
if (infzero) {
56
/*
57
* Inf * 0 + NaN -- some implementations return the default NaN here,
58
* and some return the input NaN.
59
*/
60
- switch (rule) {
61
+ switch (status->float_infzeronan_rule) {
62
case float_infzeronan_dnan_never:
63
return 2;
64
case float_infzeronan_dnan_always:
65
--
66
2.34.1
diff view generated by jsdifflib
1
Coverity notices that the checks against mkstemp() failing in
1
The new implementation of pickNaNMulAdd() will find it convenient
2
create_qcow2_with_mbr() are wrong: mkstemp returns -1 on failure but
2
to know whether at least one of the three arguments to the muladd
3
the check is just "g_assert(fd)". Fix to use "g_assert(fd >= 0)",
3
was a signaling NaN. We already calculate that in the caller,
4
matching the correct check in create_test_img().
4
so pass it in as a new bool have_snan.
5
5
6
Fixes: Coverity CID 1432274
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
8
Message-id: 20241202131347.498124-15-peter.maydell@linaro.org
10
Message-id: 20210525134458.6675-4-peter.maydell@linaro.org
11
---
9
---
12
tests/qtest/hd-geo-test.c | 4 ++--
10
fpu/softfloat-parts.c.inc | 5 +++--
13
1 file changed, 2 insertions(+), 2 deletions(-)
11
fpu/softfloat-specialize.c.inc | 2 +-
12
2 files changed, 4 insertions(+), 3 deletions(-)
14
13
15
diff --git a/tests/qtest/hd-geo-test.c b/tests/qtest/hd-geo-test.c
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/tests/qtest/hd-geo-test.c
16
--- a/fpu/softfloat-parts.c.inc
18
+++ b/tests/qtest/hd-geo-test.c
17
+++ b/fpu/softfloat-parts.c.inc
19
@@ -XXX,XX +XXX,XX @@ static char *create_qcow2_with_mbr(MBRpartitions mbr, uint64_t sectors)
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
19
{
20
int which;
21
bool infzero = (ab_mask == float_cmask_infzero);
22
+ bool have_snan = (abc_mask & float_cmask_snan);
23
24
- if (unlikely(abc_mask & float_cmask_snan)) {
25
+ if (unlikely(have_snan)) {
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
20
}
27
}
21
28
22
fd = mkstemp(raw_path);
29
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
23
- g_assert(fd);
30
if (s->default_nan_mode) {
24
+ g_assert(fd >= 0);
31
which = 3;
25
close(fd);
32
} else {
26
33
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, s);
27
fd = open(raw_path, O_WRONLY);
34
+ which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, have_snan, s);
28
@@ -XXX,XX +XXX,XX @@ static char *create_qcow2_with_mbr(MBRpartitions mbr, uint64_t sectors)
35
}
29
close(fd);
36
30
37
if (which == 3) {
31
fd = mkstemp(qcow2_path);
38
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
32
- g_assert(fd);
39
index XXXXXXX..XXXXXXX 100644
33
+ g_assert(fd >= 0);
40
--- a/fpu/softfloat-specialize.c.inc
34
close(fd);
41
+++ b/fpu/softfloat-specialize.c.inc
35
42
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
36
qemu_img_path = getenv("QTEST_QEMU_IMG");
43
| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
44
*----------------------------------------------------------------------------*/
45
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
46
- bool infzero, float_status *status)
47
+ bool infzero, bool have_snan, float_status *status)
48
{
49
/*
50
* We guarantee not to require the target to tell us how to
37
--
51
--
38
2.20.1
52
2.34.1
39
40
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
IEEE 758 does not define a fixed rule for which NaN to pick as the
2
2
result if both operands of a 3-operand fused multiply-add operation
3
Note that the SVE BFLOAT16 support does not require SVE2,
3
are NaNs. As a result different architectures have ended up with
4
it is an independent extension.
4
different rules for propagating NaNs.
5
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
QEMU currently hardcodes the NaN propagation logic into the binary
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
because pickNaNMulAdd() has an ifdef ladder for different targets.
8
Message-id: 20210525225817.400336-2-richard.henderson@linaro.org
8
We want to make the propagation rule instead be selectable at
9
runtime, because:
10
* this will let us have multiple targets in one QEMU binary
11
* the Arm FEAT_AFP architectural feature includes letting
12
the guest select a NaN propagation rule at runtime
13
14
In this commit we add an enum for the propagation rule, the field in
15
float_status, and the corresponding getters and setters. We change
16
pickNaNMulAdd to honour this, but because all targets still leave
17
this field at its default 0 value, the fallback logic will pick the
18
rule type with the old ifdef ladder.
19
20
It's valid not to set a propagation rule if default_nan_mode is
21
enabled, because in that case there's no need to pick a NaN; all the
22
callers of pickNaNMulAdd() catch this case and skip calling it.
23
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-id: 20241202131347.498124-16-peter.maydell@linaro.org
10
---
27
---
11
target/arm/cpu.h | 15 +++++++++++++++
28
include/fpu/softfloat-helpers.h | 11 +++
12
1 file changed, 15 insertions(+)
29
include/fpu/softfloat-types.h | 55 +++++++++++
13
30
fpu/softfloat-specialize.c.inc | 167 ++++++++------------------------
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
31
3 files changed, 107 insertions(+), 126 deletions(-)
32
33
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
15
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
35
--- a/include/fpu/softfloat-helpers.h
17
+++ b/target/arm/cpu.h
36
+++ b/include/fpu/softfloat-helpers.h
18
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id)
37
@@ -XXX,XX +XXX,XX @@ static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
19
return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0;
38
status->float_2nan_prop_rule = rule;
20
}
39
}
21
40
22
+static inline bool isar_feature_aa32_bf16(const ARMISARegisters *id)
41
+static inline void set_float_3nan_prop_rule(Float3NaNPropRule rule,
42
+ float_status *status)
23
+{
43
+{
24
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, BF16) != 0;
44
+ status->float_3nan_prop_rule = rule;
25
+}
45
+}
26
+
46
+
27
static inline bool isar_feature_aa32_i8mm(const ARMISARegisters *id)
47
static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
48
float_status *status)
28
{
49
{
29
return FIELD_EX32(id->id_isar6, ID_ISAR6, I8MM) != 0;
50
@@ -XXX,XX +XXX,XX @@ static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
30
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
51
return status->float_2nan_prop_rule;
31
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
32
}
52
}
33
53
34
+static inline bool isar_feature_aa64_bf16(const ARMISARegisters *id)
54
+static inline Float3NaNPropRule get_float_3nan_prop_rule(float_status *status)
35
+{
55
+{
36
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, BF16) != 0;
56
+ return status->float_3nan_prop_rule;
37
+}
57
+}
38
+
58
+
39
static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id)
59
static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status)
40
{
60
{
41
/* We always set the AdvSIMD and FP fields identically. */
61
return status->float_infzeronan_rule;
42
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sve2_bitperm(const ARMISARegisters *id)
62
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
43
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BITPERM) != 0;
63
index XXXXXXX..XXXXXXX 100644
64
--- a/include/fpu/softfloat-types.h
65
+++ b/include/fpu/softfloat-types.h
66
@@ -XXX,XX +XXX,XX @@ this code that are retained.
67
#ifndef SOFTFLOAT_TYPES_H
68
#define SOFTFLOAT_TYPES_H
69
70
+#include "hw/registerfields.h"
71
+
72
/*
73
* Software IEC/IEEE floating-point types.
74
*/
75
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
76
float_2nan_prop_x87,
77
} Float2NaNPropRule;
78
79
+/*
80
+ * 3-input NaN propagation rule, for fused multiply-add. Individual
81
+ * architectures have different rules for which input NaN is
82
+ * propagated to the output when there is more than one NaN on the
83
+ * input.
84
+ *
85
+ * If default_nan_mode is enabled then it is valid not to set a NaN
86
+ * propagation rule, because the softfloat code guarantees not to try
87
+ * to pick a NaN to propagate in default NaN mode. When not in
88
+ * default-NaN mode, it is an error for the target not to set the rule
89
+ * in float_status if it uses a muladd, and we will assert if we need
90
+ * to handle an input NaN and no rule was selected.
91
+ *
92
+ * The naming scheme for Float3NaNPropRule values is:
93
+ * float_3nan_prop_s_abc:
94
+ * = "Prefer SNaN over QNaN, then operand A over B over C"
95
+ * float_3nan_prop_abc:
96
+ * = "Prefer A over B over C regardless of SNaN vs QNAN"
97
+ *
98
+ * For QEMU, the multiply-add operation is A * B + C.
99
+ */
100
+
101
+/*
102
+ * We set the Float3NaNPropRule enum values up so we can select the
103
+ * right value in pickNaNMulAdd in a data driven way.
104
+ */
105
+FIELD(3NAN, 1ST, 0, 2) /* which operand is most preferred ? */
106
+FIELD(3NAN, 2ND, 2, 2) /* which operand is next most preferred ? */
107
+FIELD(3NAN, 3RD, 4, 2) /* which operand is least preferred ? */
108
+FIELD(3NAN, SNAN, 6, 1) /* do we prefer SNaN over QNaN ? */
109
+
110
+#define PROPRULE(X, Y, Z) \
111
+ ((X << R_3NAN_1ST_SHIFT) | (Y << R_3NAN_2ND_SHIFT) | (Z << R_3NAN_3RD_SHIFT))
112
+
113
+typedef enum __attribute__((__packed__)) {
114
+ float_3nan_prop_none = 0, /* No propagation rule specified */
115
+ float_3nan_prop_abc = PROPRULE(0, 1, 2),
116
+ float_3nan_prop_acb = PROPRULE(0, 2, 1),
117
+ float_3nan_prop_bac = PROPRULE(1, 0, 2),
118
+ float_3nan_prop_bca = PROPRULE(1, 2, 0),
119
+ float_3nan_prop_cab = PROPRULE(2, 0, 1),
120
+ float_3nan_prop_cba = PROPRULE(2, 1, 0),
121
+ float_3nan_prop_s_abc = float_3nan_prop_abc | R_3NAN_SNAN_MASK,
122
+ float_3nan_prop_s_acb = float_3nan_prop_acb | R_3NAN_SNAN_MASK,
123
+ float_3nan_prop_s_bac = float_3nan_prop_bac | R_3NAN_SNAN_MASK,
124
+ float_3nan_prop_s_bca = float_3nan_prop_bca | R_3NAN_SNAN_MASK,
125
+ float_3nan_prop_s_cab = float_3nan_prop_cab | R_3NAN_SNAN_MASK,
126
+ float_3nan_prop_s_cba = float_3nan_prop_cba | R_3NAN_SNAN_MASK,
127
+} Float3NaNPropRule;
128
+
129
+#undef PROPRULE
130
+
131
/*
132
* Rule for result of fused multiply-add 0 * Inf + NaN.
133
* This must be a NaN, but implementations differ on whether this
134
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
135
FloatRoundMode float_rounding_mode;
136
FloatX80RoundPrec floatx80_rounding_precision;
137
Float2NaNPropRule float_2nan_prop_rule;
138
+ Float3NaNPropRule float_3nan_prop_rule;
139
FloatInfZeroNaNRule float_infzeronan_rule;
140
bool tininess_before_rounding;
141
/* should denormalised results go to zero and set the inexact flag? */
142
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
143
index XXXXXXX..XXXXXXX 100644
144
--- a/fpu/softfloat-specialize.c.inc
145
+++ b/fpu/softfloat-specialize.c.inc
146
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
147
static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
148
bool infzero, bool have_snan, float_status *status)
149
{
150
+ FloatClass cls[3] = { a_cls, b_cls, c_cls };
151
+ Float3NaNPropRule rule = status->float_3nan_prop_rule;
152
+ int which;
153
+
154
/*
155
* We guarantee not to require the target to tell us how to
156
* pick a NaN if we're always returning the default NaN.
157
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
158
}
159
}
160
161
+ if (rule == float_3nan_prop_none) {
162
#if defined(TARGET_ARM)
163
-
164
- /* This looks different from the ARM ARM pseudocode, because the ARM ARM
165
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
166
- */
167
- if (is_snan(c_cls)) {
168
- return 2;
169
- } else if (is_snan(a_cls)) {
170
- return 0;
171
- } else if (is_snan(b_cls)) {
172
- return 1;
173
- } else if (is_qnan(c_cls)) {
174
- return 2;
175
- } else if (is_qnan(a_cls)) {
176
- return 0;
177
- } else {
178
- return 1;
179
- }
180
+ /*
181
+ * This looks different from the ARM ARM pseudocode, because the ARM ARM
182
+ * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
183
+ */
184
+ rule = float_3nan_prop_s_cab;
185
#elif defined(TARGET_MIPS)
186
- if (snan_bit_is_one(status)) {
187
- /* Prefer sNaN over qNaN, in the a, b, c order. */
188
- if (is_snan(a_cls)) {
189
- return 0;
190
- } else if (is_snan(b_cls)) {
191
- return 1;
192
- } else if (is_snan(c_cls)) {
193
- return 2;
194
- } else if (is_qnan(a_cls)) {
195
- return 0;
196
- } else if (is_qnan(b_cls)) {
197
- return 1;
198
+ if (snan_bit_is_one(status)) {
199
+ rule = float_3nan_prop_s_abc;
200
} else {
201
- return 2;
202
+ rule = float_3nan_prop_s_cab;
203
}
204
- } else {
205
- /* Prefer sNaN over qNaN, in the c, a, b order. */
206
- if (is_snan(c_cls)) {
207
- return 2;
208
- } else if (is_snan(a_cls)) {
209
- return 0;
210
- } else if (is_snan(b_cls)) {
211
- return 1;
212
- } else if (is_qnan(c_cls)) {
213
- return 2;
214
- } else if (is_qnan(a_cls)) {
215
- return 0;
216
- } else {
217
- return 1;
218
- }
219
- }
220
#elif defined(TARGET_LOONGARCH64)
221
- /* Prefer sNaN over qNaN, in the c, a, b order. */
222
- if (is_snan(c_cls)) {
223
- return 2;
224
- } else if (is_snan(a_cls)) {
225
- return 0;
226
- } else if (is_snan(b_cls)) {
227
- return 1;
228
- } else if (is_qnan(c_cls)) {
229
- return 2;
230
- } else if (is_qnan(a_cls)) {
231
- return 0;
232
- } else {
233
- return 1;
234
- }
235
+ rule = float_3nan_prop_s_cab;
236
#elif defined(TARGET_PPC)
237
- /* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
238
- * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
239
- */
240
- if (is_nan(a_cls)) {
241
- return 0;
242
- } else if (is_nan(c_cls)) {
243
- return 2;
244
- } else {
245
- return 1;
246
- }
247
+ /*
248
+ * If fRA is a NaN return it; otherwise if fRB is a NaN return it;
249
+ * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
250
+ */
251
+ rule = float_3nan_prop_acb;
252
#elif defined(TARGET_S390X)
253
- if (is_snan(a_cls)) {
254
- return 0;
255
- } else if (is_snan(b_cls)) {
256
- return 1;
257
- } else if (is_snan(c_cls)) {
258
- return 2;
259
- } else if (is_qnan(a_cls)) {
260
- return 0;
261
- } else if (is_qnan(b_cls)) {
262
- return 1;
263
- } else {
264
- return 2;
265
- }
266
+ rule = float_3nan_prop_s_abc;
267
#elif defined(TARGET_SPARC)
268
- /* Prefer SNaN over QNaN, order C, B, A. */
269
- if (is_snan(c_cls)) {
270
- return 2;
271
- } else if (is_snan(b_cls)) {
272
- return 1;
273
- } else if (is_snan(a_cls)) {
274
- return 0;
275
- } else if (is_qnan(c_cls)) {
276
- return 2;
277
- } else if (is_qnan(b_cls)) {
278
- return 1;
279
- } else {
280
- return 0;
281
- }
282
+ rule = float_3nan_prop_s_cba;
283
#elif defined(TARGET_XTENSA)
284
- /*
285
- * For Xtensa, the (inf,zero,nan) case sets InvalidOp and returns
286
- * an input NaN if we have one (ie c).
287
- */
288
- if (status->use_first_nan) {
289
- if (is_nan(a_cls)) {
290
- return 0;
291
- } else if (is_nan(b_cls)) {
292
- return 1;
293
+ if (status->use_first_nan) {
294
+ rule = float_3nan_prop_abc;
295
} else {
296
- return 2;
297
+ rule = float_3nan_prop_cba;
298
}
299
- } else {
300
- if (is_nan(c_cls)) {
301
- return 2;
302
- } else if (is_nan(b_cls)) {
303
- return 1;
304
- } else {
305
- return 0;
306
- }
307
- }
308
#else
309
- /* A default implementation: prefer a to b to c.
310
- * This is unlikely to actually match any real implementation.
311
- */
312
- if (is_nan(a_cls)) {
313
- return 0;
314
- } else if (is_nan(b_cls)) {
315
- return 1;
316
- } else {
317
- return 2;
318
- }
319
+ rule = float_3nan_prop_abc;
320
#endif
321
+ }
322
+
323
+ assert(rule != float_3nan_prop_none);
324
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
325
+ /* We have at least one SNaN input and should prefer it */
326
+ do {
327
+ which = rule & R_3NAN_1ST_MASK;
328
+ rule >>= R_3NAN_1ST_LENGTH;
329
+ } while (!is_snan(cls[which]));
330
+ } else {
331
+ do {
332
+ which = rule & R_3NAN_1ST_MASK;
333
+ rule >>= R_3NAN_1ST_LENGTH;
334
+ } while (!is_nan(cls[which]));
335
+ }
336
+ return which;
44
}
337
}
45
338
46
+static inline bool isar_feature_aa64_sve_bf16(const ARMISARegisters *id)
339
/*----------------------------------------------------------------------------
47
+{
48
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BFLOAT16) != 0;
49
+}
50
+
51
static inline bool isar_feature_aa64_sve2_sha3(const ARMISARegisters *id)
52
{
53
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SHA3) != 0;
54
--
340
--
55
2.20.1
341
2.34.1
56
57
diff view generated by jsdifflib
New patch
1
Explicitly set a rule in the softfloat tests for propagating NaNs in
2
the muladd case. In meson.build we put -DTARGET_ARM in fpcflags, and
3
so we should select here the Arm rule of float_3nan_prop_s_cab.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20241202131347.498124-17-peter.maydell@linaro.org
8
---
9
tests/fp/fp-bench.c | 1 +
10
tests/fp/fp-test.c | 1 +
11
2 files changed, 2 insertions(+)
12
13
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/fp/fp-bench.c
16
+++ b/tests/fp/fp-bench.c
17
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
18
* doesn't specify match those used by the Arm architecture.
19
*/
20
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
21
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
22
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
23
24
f = bench_funcs[operation][precision];
25
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/fp/fp-test.c
28
+++ b/tests/fp/fp-test.c
29
@@ -XXX,XX +XXX,XX @@ void run_test(void)
30
* doesn't specify match those used by the Arm architecture.
31
*/
32
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
33
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
34
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
35
36
genCases_setLevel(test_level);
37
--
38
2.34.1
diff view generated by jsdifflib
1
Currently we allow board models to specify the initial value of the
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
Secure VTOR register, using an init-svtor property on the TYPE_ARMV7M
2
ifdef from pickNaNMulAdd().
3
object which is plumbed through to the CPU. Allow board models to
4
also specify the initial value of the Non-secure VTOR via a similar
5
init-nsvtor property.
6
3
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210520152840.24453-10-peter.maydell@linaro.org
6
Message-id: 20241202131347.498124-18-peter.maydell@linaro.org
10
---
7
---
11
include/hw/arm/armv7m.h | 2 ++
8
target/arm/cpu.c | 5 +++++
12
target/arm/cpu.h | 2 ++
9
fpu/softfloat-specialize.c.inc | 8 +-------
13
hw/arm/armv7m.c | 7 +++++++
10
2 files changed, 6 insertions(+), 7 deletions(-)
14
target/arm/cpu.c | 10 ++++++++++
15
4 files changed, 21 insertions(+)
16
11
17
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/armv7m.h
20
+++ b/include/hw/arm/armv7m.h
21
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(ARMv7MState, ARMV7M)
22
* devices will be automatically layered on top of this view.)
23
* + Property "idau": IDAU interface (forwarded to CPU object)
24
* + Property "init-svtor": secure VTOR reset value (forwarded to CPU object)
25
+ * + Property "init-nsvtor": non-secure VTOR reset value (forwarded to CPU object)
26
* + Property "vfp": enable VFP (forwarded to CPU object)
27
* + Property "dsp": enable DSP (forwarded to CPU object)
28
* + Property "enable-bitband": expose bitbanded IO
29
@@ -XXX,XX +XXX,XX @@ struct ARMv7MState {
30
MemoryRegion *board_memory;
31
Object *idau;
32
uint32_t init_svtor;
33
+ uint32_t init_nsvtor;
34
bool enable_bitband;
35
bool start_powered_off;
36
bool vfp;
37
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/cpu.h
40
+++ b/target/arm/cpu.h
41
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
42
43
/* For v8M, initial value of the Secure VTOR */
44
uint32_t init_svtor;
45
+ /* For v8M, initial value of the Non-secure VTOR */
46
+ uint32_t init_nsvtor;
47
48
/* [QEMU_]KVM_ARM_TARGET_* constant for this CPU, or
49
* QEMU_KVM_ARM_TARGET_NONE if the kernel doesn't support this CPU type.
50
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/arm/armv7m.c
53
+++ b/hw/arm/armv7m.c
54
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
55
return;
56
}
57
}
58
+ if (object_property_find(OBJECT(s->cpu), "init-nsvtor")) {
59
+ if (!object_property_set_uint(OBJECT(s->cpu), "init-nsvtor",
60
+ s->init_nsvtor, errp)) {
61
+ return;
62
+ }
63
+ }
64
if (object_property_find(OBJECT(s->cpu), "start-powered-off")) {
65
if (!object_property_set_bool(OBJECT(s->cpu), "start-powered-off",
66
s->start_powered_off, errp)) {
67
@@ -XXX,XX +XXX,XX @@ static Property armv7m_properties[] = {
68
MemoryRegion *),
69
DEFINE_PROP_LINK("idau", ARMv7MState, idau, TYPE_IDAU_INTERFACE, Object *),
70
DEFINE_PROP_UINT32("init-svtor", ARMv7MState, init_svtor, 0),
71
+ DEFINE_PROP_UINT32("init-nsvtor", ARMv7MState, init_nsvtor, 0),
72
DEFINE_PROP_BOOL("enable-bitband", ARMv7MState, enable_bitband, false),
73
DEFINE_PROP_BOOL("start-powered-off", ARMv7MState, start_powered_off,
74
false),
75
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
12
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
76
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/cpu.c
14
--- a/target/arm/cpu.c
78
+++ b/target/arm/cpu.c
15
+++ b/target/arm/cpu.c
79
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
16
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
80
env->regs[14] = 0xffffffff;
17
* * tininess-before-rounding
81
18
* * 2-input NaN propagation prefers SNaN over QNaN, and then
82
env->v7m.vecbase[M_REG_S] = cpu->init_svtor & 0xffffff80;
19
* operand A over operand B (see FPProcessNaNs() pseudocode)
83
+ env->v7m.vecbase[M_REG_NS] = cpu->init_nsvtor & 0xffffff80;
20
+ * * 3-input NaN propagation prefers SNaN over QNaN, and then
84
21
+ * operand C over A over B (see FPProcessNaNs3() pseudocode,
85
/* Load the initial SP and PC from offset 0 and 4 in the vector table */
22
+ * but note that for QEMU muladd is a * b + c, whereas for
86
vecbase = env->v7m.vecbase[env->v7m.secure];
23
+ * the pseudocode function the arguments are in the order c, a, b.
87
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
24
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
88
&cpu->init_svtor,
25
* and the input NaN if it is signalling
89
OBJ_PROP_FLAG_READWRITE);
26
*/
27
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
28
{
29
set_float_detect_tininess(float_tininess_before_rounding, s);
30
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
31
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
32
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
33
}
34
35
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
36
index XXXXXXX..XXXXXXX 100644
37
--- a/fpu/softfloat-specialize.c.inc
38
+++ b/fpu/softfloat-specialize.c.inc
39
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
90
}
40
}
91
+ if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
41
92
+ /*
42
if (rule == float_3nan_prop_none) {
93
+ * Initial value of the NS VTOR (for cores without the Security
43
-#if defined(TARGET_ARM)
94
+ * extension, this is the only VTOR)
44
- /*
95
+ */
45
- * This looks different from the ARM ARM pseudocode, because the ARM ARM
96
+ object_property_add_uint32_ptr(obj, "init-nsvtor",
46
- * puts the operands to a fused mac operation (a*b)+c in the order c,a,b
97
+ &cpu->init_nsvtor,
47
- */
98
+ OBJ_PROP_FLAG_READWRITE);
48
- rule = float_3nan_prop_s_cab;
99
+ }
49
-#elif defined(TARGET_MIPS)
100
50
+#if defined(TARGET_MIPS)
101
qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property);
51
if (snan_bit_is_one(status)) {
102
52
rule = float_3nan_prop_s_abc;
53
} else {
103
--
54
--
104
2.20.1
55
2.34.1
105
106
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for loongarch, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-19-peter.maydell@linaro.org
7
---
8
target/loongarch/tcg/fpu_helper.c | 1 +
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 1 insertion(+), 2 deletions(-)
11
12
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/loongarch/tcg/fpu_helper.c
15
+++ b/target/loongarch/tcg/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
17
* case sets InvalidOp and returns the input value 'c'
18
*/
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
21
}
22
23
int ieee_ex_to_loongarch(int xcpt)
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
29
} else {
30
rule = float_3nan_prop_s_cab;
31
}
32
-#elif defined(TARGET_LOONGARCH64)
33
- rule = float_3nan_prop_s_cab;
34
#elif defined(TARGET_PPC)
35
/*
36
* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for PPC, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-20-peter.maydell@linaro.org
7
---
8
target/ppc/cpu_init.c | 8 ++++++++
9
fpu/softfloat-specialize.c.inc | 6 ------
10
2 files changed, 8 insertions(+), 6 deletions(-)
11
12
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/ppc/cpu_init.c
15
+++ b/target/ppc/cpu_init.c
16
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->vec_status);
20
+ /*
21
+ * NaN propagation for fused multiply-add:
22
+ * if fRA is a NaN return it; otherwise if fRB is a NaN return it;
23
+ * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
24
+ * whereas QEMU labels the operands as (a * b) + c.
25
+ */
26
+ set_float_3nan_prop_rule(float_3nan_prop_acb, &env->fp_status);
27
+ set_float_3nan_prop_rule(float_3nan_prop_acb, &env->vec_status);
28
/*
29
* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
30
* to return an input NaN if we have one (ie c) rather than generating
31
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
32
index XXXXXXX..XXXXXXX 100644
33
--- a/fpu/softfloat-specialize.c.inc
34
+++ b/fpu/softfloat-specialize.c.inc
35
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
36
} else {
37
rule = float_3nan_prop_s_cab;
38
}
39
-#elif defined(TARGET_PPC)
40
- /*
41
- * If fRA is a NaN return it; otherwise if fRB is a NaN return it;
42
- * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
43
- */
44
- rule = float_3nan_prop_acb;
45
#elif defined(TARGET_S390X)
46
rule = float_3nan_prop_s_abc;
47
#elif defined(TARGET_SPARC)
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for s390x, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-21-peter.maydell@linaro.org
7
---
8
target/s390x/cpu.c | 1 +
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 1 insertion(+), 2 deletions(-)
11
12
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/s390x/cpu.c
15
+++ b/target/s390x/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
17
set_float_detect_tininess(float_tininess_before_rounding,
18
&env->fpu_status);
19
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fpu_status);
20
+ set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
21
set_float_infzeronan_rule(float_infzeronan_dnan_always,
22
&env->fpu_status);
23
/* fall through */
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
29
} else {
30
rule = float_3nan_prop_s_cab;
31
}
32
-#elif defined(TARGET_S390X)
33
- rule = float_3nan_prop_s_abc;
34
#elif defined(TARGET_SPARC)
35
rule = float_3nan_prop_s_cba;
36
#elif defined(TARGET_XTENSA)
37
--
38
2.34.1
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for SPARC, and remove the
2
ifdef from pickNaNMulAdd().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-22-peter.maydell@linaro.org
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 2 --
10
2 files changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/sparc/cpu.c
15
+++ b/target/sparc/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
17
* the CPU state struct so it won't get zeroed on reset.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &env->fp_status);
20
+ /* For fused-multiply add, prefer SNaN over QNaN, then C->B->A */
21
+ set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
22
/* For inf * 0 + NaN, return the input NaN */
23
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
24
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
30
} else {
31
rule = float_3nan_prop_s_cab;
32
}
33
-#elif defined(TARGET_SPARC)
34
- rule = float_3nan_prop_s_cba;
35
#elif defined(TARGET_XTENSA)
36
if (status->use_first_nan) {
37
rule = float_3nan_prop_abc;
38
--
39
2.34.1
diff view generated by jsdifflib
1
Split out the handling of VMOV_reg_sp and VMOV_reg_dp so that we can
1
Set the Float3NaNPropRule explicitly for Arm, and remove the
2
permit the insns if either FP or MVE are present.
2
ifdef from pickNaNMulAdd().
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210520152840.24453-5-peter.maydell@linaro.org
6
Message-id: 20241202131347.498124-23-peter.maydell@linaro.org
7
---
7
---
8
target/arm/translate-vfp.c | 15 +++++++++++++--
8
target/mips/fpu_helper.h | 4 ++++
9
1 file changed, 13 insertions(+), 2 deletions(-)
9
target/mips/msa.c | 3 +++
10
fpu/softfloat-specialize.c.inc | 8 +-------
11
3 files changed, 8 insertions(+), 7 deletions(-)
10
12
11
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
13
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-vfp.c
15
--- a/target/mips/fpu_helper.h
14
+++ b/target/arm/translate-vfp.c
16
+++ b/target/mips/fpu_helper.h
15
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
17
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
16
return do_vfp_2op_##PREC(s, FN, a->vd, a->vm); \
18
{
19
bool nan2008 = env->active_fpu.fcr31 & (1 << FCR31_NAN2008);
20
FloatInfZeroNaNRule izn_rule;
21
+ Float3NaNPropRule nan3_rule;
22
23
/*
24
* With nan2008, SNaNs are silenced in the usual way.
25
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
26
*/
27
izn_rule = nan2008 ? float_infzeronan_dnan_never : float_infzeronan_dnan_always;
28
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
29
+ nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
30
+ set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
31
+
32
}
33
34
static inline void restore_fp_status(CPUMIPSState *env)
35
diff --git a/target/mips/msa.c b/target/mips/msa.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/mips/msa.c
38
+++ b/target/mips/msa.c
39
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
40
set_float_2nan_prop_rule(float_2nan_prop_s_ab,
41
&env->active_tc.msa_fp_status);
42
43
+ set_float_3nan_prop_rule(float_3nan_prop_s_cab,
44
+ &env->active_tc.msa_fp_status);
45
+
46
/* clear float_status exception flags */
47
set_float_exception_flags(0, &env->active_tc.msa_fp_status);
48
49
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
50
index XXXXXXX..XXXXXXX 100644
51
--- a/fpu/softfloat-specialize.c.inc
52
+++ b/fpu/softfloat-specialize.c.inc
53
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
17
}
54
}
18
55
19
-DO_VFP_2OP(VMOV_reg, sp, tcg_gen_mov_i32, aa32_fpsp_v2)
56
if (rule == float_3nan_prop_none) {
20
-DO_VFP_2OP(VMOV_reg, dp, tcg_gen_mov_i64, aa32_fpdp_v2)
57
-#if defined(TARGET_MIPS)
21
+#define DO_VFP_VMOV(INSN, PREC, FN) \
58
- if (snan_bit_is_one(status)) {
22
+ static bool trans_##INSN##_##PREC(DisasContext *s, \
59
- rule = float_3nan_prop_s_abc;
23
+ arg_##INSN##_##PREC *a) \
60
- } else {
24
+ { \
61
- rule = float_3nan_prop_s_cab;
25
+ if (!dc_isar_feature(aa32_fp##PREC##_v2, s) && \
62
- }
26
+ !dc_isar_feature(aa32_mve, s)) { \
63
-#elif defined(TARGET_XTENSA)
27
+ return false; \
64
+#if defined(TARGET_XTENSA)
28
+ } \
65
if (status->use_first_nan) {
29
+ return do_vfp_2op_##PREC(s, FN, a->vd, a->vm); \
66
rule = float_3nan_prop_abc;
30
+ }
67
} else {
31
+
32
+DO_VFP_VMOV(VMOV_reg, sp, tcg_gen_mov_i32)
33
+DO_VFP_VMOV(VMOV_reg, dp, tcg_gen_mov_i64)
34
35
DO_VFP_2OP(VABS, hp, gen_helper_vfp_absh, aa32_fp16_arith)
36
DO_VFP_2OP(VABS, sp, gen_helper_vfp_abss, aa32_fpsp_v2)
37
--
68
--
38
2.20.1
69
2.34.1
39
40
diff view generated by jsdifflib
1
The M-profile FPSCR has an LTPSIZE field, but if MVE is not
1
Set the Float3NaNPropRule explicitly for xtensa, and remove the
2
implemented it is read-only and always reads as 4; this is how QEMU
2
ifdef from pickNaNMulAdd().
3
currently handles it.
4
5
Make the field writable when MVE is implemented.
6
7
We can safely add the field to the MVE migration struct because
8
currently no CPUs enable MVE and so the migration struct is never
9
used.
10
3
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20210520152840.24453-8-peter.maydell@linaro.org
6
Message-id: 20241202131347.498124-24-peter.maydell@linaro.org
14
---
7
---
15
target/arm/cpu.h | 3 ++-
8
target/xtensa/fpu_helper.c | 2 ++
16
target/arm/machine.c | 1 +
9
fpu/softfloat-specialize.c.inc | 8 --------
17
target/arm/vfp_helper.c | 9 ++++++---
10
2 files changed, 2 insertions(+), 8 deletions(-)
18
3 files changed, 9 insertions(+), 4 deletions(-)
19
11
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
14
--- a/target/xtensa/fpu_helper.c
23
+++ b/target/arm/cpu.h
15
+++ b/target/xtensa/fpu_helper.c
24
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
16
@@ -XXX,XX +XXX,XX @@ void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
25
uint32_t fpdscr[M_REG_NUM_BANKS];
17
set_use_first_nan(use_first, &env->fp_status);
26
uint32_t cpacr[M_REG_NUM_BANKS];
18
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
27
uint32_t nsacr;
19
&env->fp_status);
28
- int ltpsize;
20
+ set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
29
+ uint32_t ltpsize;
21
+ &env->fp_status);
30
uint32_t vpr;
22
}
31
} v7m;
23
32
24
void HELPER(wur_fpu2k_fcr)(CPUXtensaState *env, uint32_t v)
33
@@ -XXX,XX +XXX,XX @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
34
35
#define FPCR_LTPSIZE_SHIFT 16 /* LTPSIZE, M-profile only */
36
#define FPCR_LTPSIZE_MASK (7 << FPCR_LTPSIZE_SHIFT)
37
+#define FPCR_LTPSIZE_LENGTH 3
38
39
#define FPCR_NZCV_MASK (FPCR_N | FPCR_Z | FPCR_C | FPCR_V)
40
#define FPCR_NZCVQC_MASK (FPCR_NZCV_MASK | FPCR_QC)
41
diff --git a/target/arm/machine.c b/target/arm/machine.c
42
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/machine.c
27
--- a/fpu/softfloat-specialize.c.inc
44
+++ b/target/arm/machine.c
28
+++ b/fpu/softfloat-specialize.c.inc
45
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_mve = {
29
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
46
.needed = mve_needed,
47
.fields = (VMStateField[]) {
48
VMSTATE_UINT32(env.v7m.vpr, ARMCPU),
49
+ VMSTATE_UINT32(env.v7m.ltpsize, ARMCPU),
50
VMSTATE_END_OF_LIST()
51
},
52
};
53
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/vfp_helper.c
56
+++ b/target/arm/vfp_helper.c
57
@@ -XXX,XX +XXX,XX @@ uint32_t vfp_get_fpscr(CPUARMState *env)
58
59
void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
60
{
61
+ ARMCPU *cpu = env_archcpu(env);
62
+
63
/* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
64
- if (!cpu_isar_feature(any_fp16, env_archcpu(env))) {
65
+ if (!cpu_isar_feature(any_fp16, cpu)) {
66
val &= ~FPCR_FZ16;
67
}
30
}
68
31
69
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
32
if (rule == float_3nan_prop_none) {
70
* because in v7A no-short-vector-support cores still had to
33
-#if defined(TARGET_XTENSA)
71
* allow Stride/Len to be written with the only effect that
34
- if (status->use_first_nan) {
72
* some insns are required to UNDEF if the guest sets them.
35
- rule = float_3nan_prop_abc;
73
- *
36
- } else {
74
- * TODO: if M-profile MVE implemented, set LTPSIZE.
37
- rule = float_3nan_prop_cba;
75
*/
38
- }
76
env->vfp.vec_len = extract32(val, 16, 3);
39
-#else
77
env->vfp.vec_stride = extract32(val, 20, 2);
40
rule = float_3nan_prop_abc;
78
+ } else if (cpu_isar_feature(aa32_mve, cpu)) {
41
-#endif
79
+ env->v7m.ltpsize = extract32(val, FPCR_LTPSIZE_SHIFT,
80
+ FPCR_LTPSIZE_LENGTH);
81
}
42
}
82
43
83
if (arm_feature(env, ARM_FEATURE_NEON)) {
44
assert(rule != float_3nan_prop_none);
84
--
45
--
85
2.20.1
46
2.34.1
86
87
diff view generated by jsdifflib
New patch
1
Set the Float3NaNPropRule explicitly for i386. We had no
2
i386-specific behaviour in the old ifdef ladder, so we were using the
3
default "prefer a then b then c" fallback; this is actually the
4
correct per-the-spec handling for i386.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241202131347.498124-25-peter.maydell@linaro.org
9
---
10
target/i386/tcg/fpu_helper.c | 1 +
11
1 file changed, 1 insertion(+)
12
13
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/i386/tcg/fpu_helper.c
16
+++ b/target/i386/tcg/fpu_helper.c
17
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
18
* there are multiple input NaNs they are selected in the order a, b, c.
19
*/
20
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
21
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
22
}
23
24
static inline uint8_t save_exception_flags(CPUX86State *env)
25
--
26
2.34.1
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
Set the Float3NaNPropRule explicitly for HPPA, and remove the
2
ifdef from pickNaNMulAdd().
2
3
3
Until now, Hypervisor.framework has only been available on x86_64 systems.
4
HPPA is the only target that was using the default branch of the
4
With Apple Silicon shipping now, it extends its reach to aarch64. To
5
ifdef ladder (other targets either do not use muladd or set
5
prepare for support for multiple architectures, let's start moving common
6
default_nan_mode), so we can remove the ifdef fallback entirely now
6
code out into its own accel directory.
7
(allowing the "rule not set" case to fall into the default of the
8
switch statement and assert).
7
9
8
This patch splits the vcpu init and destroy functions into a generic and
10
We add a TODO note that the HPPA rule is probably wrong; this is
9
an architecture specific portion. This also allows us to move the generic
11
not a behavioural change for this refactoring.
10
functions into the generic hvf code, removing exported functions.
11
12
12
Signed-off-by: Alexander Graf <agraf@csgraf.de>
13
Reviewed-by: Sergio Lopez <slp@redhat.com>
14
Message-id: 20210519202253.76782-8-agraf@csgraf.de
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20241202131347.498124-26-peter.maydell@linaro.org
17
---
16
---
18
accel/hvf/hvf-accel-ops.h | 2 --
17
target/hppa/fpu_helper.c | 8 ++++++++
19
include/sysemu/hvf_int.h | 2 ++
18
fpu/softfloat-specialize.c.inc | 4 ----
20
accel/hvf/hvf-accel-ops.c | 30 ++++++++++++++++++++++++++++++
19
2 files changed, 8 insertions(+), 4 deletions(-)
21
target/i386/hvf/hvf.c | 23 ++---------------------
22
4 files changed, 34 insertions(+), 23 deletions(-)
23
20
24
diff --git a/accel/hvf/hvf-accel-ops.h b/accel/hvf/hvf-accel-ops.h
21
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
25
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
26
--- a/accel/hvf/hvf-accel-ops.h
23
--- a/target/hppa/fpu_helper.c
27
+++ b/accel/hvf/hvf-accel-ops.h
24
+++ b/target/hppa/fpu_helper.c
28
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
29
26
* HPPA does note implement a CPU reset method at all...
30
#include "sysemu/cpus.h"
27
*/
31
28
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status);
32
-int hvf_init_vcpu(CPUState *);
29
+ /*
33
int hvf_vcpu_exec(CPUState *);
30
+ * TODO: The HPPA architecture reference only documents its NaN
34
void hvf_cpu_synchronize_state(CPUState *);
31
+ * propagation rule for 2-operand operations. Testing on real hardware
35
void hvf_cpu_synchronize_post_reset(CPUState *);
32
+ * might be necessary to confirm whether this order for muladd is correct.
36
void hvf_cpu_synchronize_post_init(CPUState *);
33
+ * Not preferring the SNaN is almost certainly incorrect as it diverges
37
void hvf_cpu_synchronize_pre_loadvm(CPUState *);
34
+ * from the documented rules for 2-operand operations.
38
-void hvf_vcpu_destroy(CPUState *);
35
+ */
39
36
+ set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
40
#endif /* HVF_CPUS_H */
37
/* For inf * 0 + NaN, return the input NaN */
41
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
38
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
39
}
40
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
42
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
43
--- a/include/sysemu/hvf_int.h
42
--- a/fpu/softfloat-specialize.c.inc
44
+++ b/include/sysemu/hvf_int.h
43
+++ b/fpu/softfloat-specialize.c.inc
45
@@ -XXX,XX +XXX,XX @@ struct HVFState {
44
@@ -XXX,XX +XXX,XX @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
46
extern HVFState *hvf_state;
47
48
void assert_hvf_ok(hv_return_t ret);
49
+int hvf_arch_init_vcpu(CPUState *cpu);
50
+void hvf_arch_vcpu_destroy(CPUState *cpu);
51
hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
52
int hvf_put_registers(CPUState *);
53
int hvf_get_registers(CPUState *);
54
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/accel/hvf/hvf-accel-ops.c
57
+++ b/accel/hvf/hvf-accel-ops.c
58
@@ -XXX,XX +XXX,XX @@ static void hvf_type_init(void)
59
60
type_init(hvf_type_init);
61
62
+static void hvf_vcpu_destroy(CPUState *cpu)
63
+{
64
+ hv_return_t ret = hv_vcpu_destroy(cpu->hvf_fd);
65
+ assert_hvf_ok(ret);
66
+
67
+ hvf_arch_vcpu_destroy(cpu);
68
+}
69
+
70
+static int hvf_init_vcpu(CPUState *cpu)
71
+{
72
+ int r;
73
+
74
+ /* init cpu signals */
75
+ sigset_t set;
76
+ struct sigaction sigact;
77
+
78
+ memset(&sigact, 0, sizeof(sigact));
79
+ sigact.sa_handler = dummy_signal;
80
+ sigaction(SIG_IPI, &sigact, NULL);
81
+
82
+ pthread_sigmask(SIG_BLOCK, NULL, &set);
83
+ sigdelset(&set, SIG_IPI);
84
+
85
+ r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf_fd, HV_VCPU_DEFAULT);
86
+ cpu->vcpu_dirty = 1;
87
+ assert_hvf_ok(r);
88
+
89
+ return hvf_arch_init_vcpu(cpu);
90
+}
91
+
92
/*
93
* The HVF-specific vCPU thread function. This one should only run when the host
94
* CPU supports the VMX "unrestricted guest" feature.
95
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
96
index XXXXXXX..XXXXXXX 100644
97
--- a/target/i386/hvf/hvf.c
98
+++ b/target/i386/hvf/hvf.c
99
@@ -XXX,XX +XXX,XX @@ static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
100
return false;
101
}
102
103
-void hvf_vcpu_destroy(CPUState *cpu)
104
+void hvf_arch_vcpu_destroy(CPUState *cpu)
105
{
106
X86CPU *x86_cpu = X86_CPU(cpu);
107
CPUX86State *env = &x86_cpu->env;
108
109
- hv_return_t ret = hv_vcpu_destroy((hv_vcpuid_t)cpu->hvf_fd);
110
g_free(env->hvf_mmio_buf);
111
- assert_hvf_ok(ret);
112
}
113
114
static void init_tsc_freq(CPUX86State *env)
115
@@ -XXX,XX +XXX,XX @@ static inline bool apic_bus_freq_is_known(CPUX86State *env)
116
return env->apic_bus_freq != 0;
117
}
118
119
-int hvf_init_vcpu(CPUState *cpu)
120
+int hvf_arch_init_vcpu(CPUState *cpu)
121
{
122
-
123
X86CPU *x86cpu = X86_CPU(cpu);
124
CPUX86State *env = &x86cpu->env;
125
- int r;
126
-
127
- /* init cpu signals */
128
- sigset_t set;
129
- struct sigaction sigact;
130
-
131
- memset(&sigact, 0, sizeof(sigact));
132
- sigact.sa_handler = dummy_signal;
133
- sigaction(SIG_IPI, &sigact, NULL);
134
-
135
- pthread_sigmask(SIG_BLOCK, NULL, &set);
136
- sigdelset(&set, SIG_IPI);
137
138
init_emu();
139
init_decoder();
140
@@ -XXX,XX +XXX,XX @@ int hvf_init_vcpu(CPUState *cpu)
141
}
45
}
142
}
46
}
143
47
144
- r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf_fd, HV_VCPU_DEFAULT);
48
- if (rule == float_3nan_prop_none) {
145
- cpu->vcpu_dirty = 1;
49
- rule = float_3nan_prop_abc;
146
- assert_hvf_ok(r);
50
- }
147
-
51
-
148
if (hv_vmx_read_capability(HV_VMX_CAP_PINBASED,
52
assert(rule != float_3nan_prop_none);
149
&hvf_state->hvf_caps->vmx_cap_pinbased)) {
53
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
150
abort();
54
/* We have at least one SNaN input and should prefer it */
151
--
55
--
152
2.20.1
56
2.34.1
153
154
diff view generated by jsdifflib
New patch
1
The use_first_nan field in float_status was an xtensa-specific way to
2
select at runtime from two different NaN propagation rules. Now that
3
xtensa is using the target-agnostic NaN propagation rule selection
4
that we've just added, we can remove use_first_nan, because there is
5
no longer any code that reads it.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20241202131347.498124-27-peter.maydell@linaro.org
10
---
11
include/fpu/softfloat-helpers.h | 5 -----
12
include/fpu/softfloat-types.h | 1 -
13
target/xtensa/fpu_helper.c | 1 -
14
3 files changed, 7 deletions(-)
15
16
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/fpu/softfloat-helpers.h
19
+++ b/include/fpu/softfloat-helpers.h
20
@@ -XXX,XX +XXX,XX @@ static inline void set_snan_bit_is_one(bool val, float_status *status)
21
status->snan_bit_is_one = val;
22
}
23
24
-static inline void set_use_first_nan(bool val, float_status *status)
25
-{
26
- status->use_first_nan = val;
27
-}
28
-
29
static inline void set_no_signaling_nans(bool val, float_status *status)
30
{
31
status->no_signaling_nans = val;
32
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/include/fpu/softfloat-types.h
35
+++ b/include/fpu/softfloat-types.h
36
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
37
* softfloat-specialize.inc.c)
38
*/
39
bool snan_bit_is_one;
40
- bool use_first_nan;
41
bool no_signaling_nans;
42
/* should overflowed results subtract re_bias to its exponent? */
43
bool rebias_overflow;
44
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/xtensa/fpu_helper.c
47
+++ b/target/xtensa/fpu_helper.c
48
@@ -XXX,XX +XXX,XX @@ static const struct {
49
50
void xtensa_use_first_nan(CPUXtensaState *env, bool use_first)
51
{
52
- set_use_first_nan(use_first, &env->fp_status);
53
set_float_2nan_prop_rule(use_first ? float_2nan_prop_ab : float_2nan_prop_ba,
54
&env->fp_status);
55
set_float_3nan_prop_rule(use_first ? float_3nan_prop_abc : float_3nan_prop_cba,
56
--
57
2.34.1
diff view generated by jsdifflib
New patch
1
Currently m68k_cpu_reset_hold() calls floatx80_default_nan(NULL)
2
to get the NaN bit pattern to reset the FPU registers. This
3
works because it happens that our implementation of
4
floatx80_default_nan() doesn't actually look at the float_status
5
pointer except for TARGET_MIPS. However, this isn't guaranteed,
6
and to be able to remove the ifdef in floatx80_default_nan()
7
we're going to need a real float_status here.
1
8
9
Rearrange m68k_cpu_reset_hold() so that we initialize env->fp_status
10
earlier, and thus can pass it to floatx80_default_nan().
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20241202131347.498124-28-peter.maydell@linaro.org
15
---
16
target/m68k/cpu.c | 12 +++++++-----
17
1 file changed, 7 insertions(+), 5 deletions(-)
18
19
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/m68k/cpu.c
22
+++ b/target/m68k/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
24
CPUState *cs = CPU(obj);
25
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(obj);
26
CPUM68KState *env = cpu_env(cs);
27
- floatx80 nan = floatx80_default_nan(NULL);
28
+ floatx80 nan;
29
int i;
30
31
if (mcc->parent_phases.hold) {
32
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
33
#else
34
cpu_m68k_set_sr(env, SR_S | SR_I);
35
#endif
36
- for (i = 0; i < 8; i++) {
37
- env->fregs[i].d = nan;
38
- }
39
- cpu_m68k_set_fpcr(env, 0);
40
/*
41
* M68000 FAMILY PROGRAMMER'S REFERENCE MANUAL
42
* 3.4 FLOATING-POINT INSTRUCTION DETAILS
43
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
44
* preceding paragraph for nonsignaling NaNs.
45
*/
46
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
47
+
48
+ nan = floatx80_default_nan(&env->fp_status);
49
+ for (i = 0; i < 8; i++) {
50
+ env->fregs[i].d = nan;
51
+ }
52
+ cpu_m68k_set_fpcr(env, 0);
53
env->fpsr = 0;
54
55
/* TODO: We should set PC from the interrupt vector. */
56
--
57
2.34.1
diff view generated by jsdifflib
1
From: Jamie Iles <jamie@nuviainc.com>
1
We create our 128-bit default NaN by calling parts64_default_nan()
2
and then adjusting the result. We can do the same trick for creating
3
the floatx80 default NaN, which lets us drop a target ifdef.
2
4
3
The sequence cpu_restore_state() + raise_exception() is equivalent to
5
floatx80 is used only by:
4
raise_exception_ra(), so use that instead. (In this case we never
6
i386
5
cared about the syndrome value, because M-profile doesn't use the
7
m68k
6
syndrome; the old code was just written unnecessarily awkwardly.)
8
arm nwfpe old floating-point emulation emulation support
9
(which is essentially dead, especially the parts involving floatx80)
10
PPC (only in the xsrqpxp instruction, which just rounds an input
11
value by converting to floatx80 and back, so will never generate
12
the default NaN)
7
13
8
Cc: Richard Henderson <richard.henderson@linaro.org>
14
The floatx80 default NaN as currently implemented is:
9
Cc: Peter Maydell <peter.maydell@linaro.org>
15
m68k: sign = 0, exp = 1...1, int = 1, frac = 1....1
10
Signed-off-by: Jamie Iles <jamie@nuviainc.com>
16
i386: sign = 1, exp = 1...1, int = 1, frac = 10...0
11
[PMM: Retain edited version of comment; rewrite commit message]
17
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
These are the same as the parts64_default_nan for these architectures.
19
20
This is technically a possible behaviour change for arm linux-user
21
nwfpe emulation emulation, because the default NaN will now have the
22
sign bit clear. But we were already generating a different floatx80
23
default NaN from the real kernel emulation we are supposedly
24
following, which appears to use an all-bits-1 value:
25
https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L267
26
27
This won't affect the only "real" use of the nwfpe emulation, which
28
is ancient binaries that used it as part of the old floating point
29
calling convention; that only uses loads and stores of 32 and 64 bit
30
floats, not any of the floatx80 behaviour the original hardware had.
31
We also get the nwfpe float64 default NaN value wrong:
32
https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L166
33
so if we ever cared about this obscure corner the right fix would be
34
to correct that so nwfpe used its own default-NaN setting rather
35
than the Arm VFP one.
36
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
37
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
38
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
39
Message-id: 20241202131347.498124-29-peter.maydell@linaro.org
14
---
40
---
15
target/arm/m_helper.c | 5 +----
41
fpu/softfloat-specialize.c.inc | 20 ++++++++++----------
16
target/arm/op_helper.c | 9 +++------
42
1 file changed, 10 insertions(+), 10 deletions(-)
17
2 files changed, 4 insertions(+), 10 deletions(-)
18
43
19
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
44
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
20
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/m_helper.c
46
--- a/fpu/softfloat-specialize.c.inc
22
+++ b/target/arm/m_helper.c
47
+++ b/fpu/softfloat-specialize.c.inc
23
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
48
@@ -XXX,XX +XXX,XX @@ static void parts128_silence_nan(FloatParts128 *p, float_status *status)
24
limit = is_psp ? env->v7m.psplim[false] : env->v7m.msplim[false];
49
floatx80 floatx80_default_nan(float_status *status)
25
50
{
26
if (val < limit) {
51
floatx80 r;
27
- CPUState *cs = env_cpu(env);
52
+ /*
28
-
53
+ * Extrapolate from the choices made by parts64_default_nan to fill
29
- cpu_restore_state(cs, GETPC(), true);
54
+ * in the floatx80 format. We assume that floatx80's explicit
30
- raise_exception(env, EXCP_STKOF, 0, 1);
55
+ * integer bit is always set (this is true for i386 and m68k,
31
+ raise_exception_ra(env, EXCP_STKOF, 0, 1, GETPC());
56
+ * which are the only real users of this format).
32
}
57
+ */
33
58
+ FloatParts64 p64;
34
if (is_psp) {
59
+ parts64_default_nan(&p64, status);
35
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
60
36
index XXXXXXX..XXXXXXX 100644
61
- /* None of the targets that have snan_bit_is_one use floatx80. */
37
--- a/target/arm/op_helper.c
62
- assert(!snan_bit_is_one(status));
38
+++ b/target/arm/op_helper.c
63
-#if defined(TARGET_M68K)
39
@@ -XXX,XX +XXX,XX @@ void HELPER(v8m_stackcheck)(CPUARMState *env, uint32_t newvalue)
64
- r.low = UINT64_C(0xFFFFFFFFFFFFFFFF);
40
* raising an exception if the limit is breached.
65
- r.high = 0x7FFF;
41
*/
66
-#else
42
if (newvalue < v7m_sp_limit(env)) {
67
- /* X86 */
43
- CPUState *cs = env_cpu(env);
68
- r.low = UINT64_C(0xC000000000000000);
44
-
69
- r.high = 0xFFFF;
45
/*
70
-#endif
46
* Stack limit exceptions are a rare case, so rather than syncing
71
+ r.high = 0x7FFF | (p64.sign << 15);
47
- * PC/condbits before the call, we use cpu_restore_state() to
72
+ r.low = (1ULL << DECOMPOSED_BINARY_POINT) | p64.frac;
48
- * get them right before raising the exception.
73
return r;
49
+ * PC/condbits before the call, we use raise_exception_ra() so
50
+ * that cpu_restore_state() will sort them out.
51
*/
52
- cpu_restore_state(cs, GETPC(), true);
53
- raise_exception(env, EXCP_STKOF, 0, 1);
54
+ raise_exception_ra(env, EXCP_STKOF, 0, 1, GETPC());
55
}
56
}
74
}
57
75
58
--
76
--
59
2.20.1
77
2.34.1
60
61
diff view generated by jsdifflib
1
Coverity points out that we calculate a 64-bit value using 32-bit
1
In target/loongarch's helper_fclass_s() and helper_fclass_d() we pass
2
arithmetic; add the cast to force the multiply to be done as 64-bits.
2
a zero-initialized float_status struct to float32_is_quiet_nan() and
3
(The overflow will never happen with the current test data.)
3
float64_is_quiet_nan(), with the cryptic comment "for
4
snan_bit_is_one".
4
5
5
Fixes: Coverity CID 1432320
6
This pattern appears to have been copied from target/riscv, where it
7
is used because the functions there do not have ready access to the
8
CPU state struct. The comment presumably refers to the fact that the
9
main reason the is_quiet_nan() functions want the float_state is
10
because they want to know about the snan_bit_is_one config.
11
12
In the loongarch helpers, though, we have the CPU state struct
13
to hand. Use the usual env->fp_status here. This avoids our needing
14
to track that we need to update the initializer of the local
15
float_status structs when the core softfloat code adds new
16
options for targets to configure their behaviour.
17
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
20
Message-id: 20241202131347.498124-30-peter.maydell@linaro.org
9
Message-id: 20210525134458.6675-5-peter.maydell@linaro.org
10
---
21
---
11
tests/qtest/pflash-cfi02-test.c | 2 +-
22
target/loongarch/tcg/fpu_helper.c | 6 ++----
12
1 file changed, 1 insertion(+), 1 deletion(-)
23
1 file changed, 2 insertions(+), 4 deletions(-)
13
24
14
diff --git a/tests/qtest/pflash-cfi02-test.c b/tests/qtest/pflash-cfi02-test.c
25
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
15
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/qtest/pflash-cfi02-test.c
27
--- a/target/loongarch/tcg/fpu_helper.c
17
+++ b/tests/qtest/pflash-cfi02-test.c
28
+++ b/target/loongarch/tcg/fpu_helper.c
18
@@ -XXX,XX +XXX,XX @@ static void test_geometry(const void *opaque)
29
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fclass_s(CPULoongArchState *env, uint64_t fj)
19
30
} else if (float32_is_zero_or_denormal(f)) {
20
for (int region = 0; region < nb_erase_regions; ++region) {
31
return sign ? 1 << 4 : 1 << 8;
21
for (uint32_t i = 0; i < c->nb_blocs[region]; ++i) {
32
} else if (float32_is_any_nan(f)) {
22
- uint64_t byte_addr = i * c->sector_len[region];
33
- float_status s = { }; /* for snan_bit_is_one */
23
+ uint64_t byte_addr = (uint64_t)i * c->sector_len[region];
34
- return float32_is_quiet_nan(f, &s) ? 1 << 1 : 1 << 0;
24
g_assert_cmphex(flash_read(c, byte_addr), ==, bank_mask(c));
35
+ return float32_is_quiet_nan(f, &env->fp_status) ? 1 << 1 : 1 << 0;
25
}
36
} else {
37
return sign ? 1 << 3 : 1 << 7;
38
}
39
@@ -XXX,XX +XXX,XX @@ uint64_t helper_fclass_d(CPULoongArchState *env, uint64_t fj)
40
} else if (float64_is_zero_or_denormal(f)) {
41
return sign ? 1 << 4 : 1 << 8;
42
} else if (float64_is_any_nan(f)) {
43
- float_status s = { }; /* for snan_bit_is_one */
44
- return float64_is_quiet_nan(f, &s) ? 1 << 1 : 1 << 0;
45
+ return float64_is_quiet_nan(f, &env->fp_status) ? 1 << 1 : 1 << 0;
46
} else {
47
return sign ? 1 << 3 : 1 << 7;
26
}
48
}
27
--
49
--
28
2.20.1
50
2.34.1
29
30
diff view generated by jsdifflib
New patch
1
In the frem helper, we have a local float_status because we want to
2
execute the floatx80_div() with a custom rounding mode. Instead of
3
zero-initializing the local float_status and then having to set it up
4
with the m68k standard behaviour (including the NaN propagation rule
5
and copying the rounding precision from env->fp_status), initialize
6
it as a complete copy of env->fp_status. This will avoid our having
7
to add new code in this function for every new config knob we add
8
to fp_status.
1
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20241202131347.498124-31-peter.maydell@linaro.org
13
---
14
target/m68k/fpu_helper.c | 6 ++----
15
1 file changed, 2 insertions(+), 4 deletions(-)
16
17
diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/m68k/fpu_helper.c
20
+++ b/target/m68k/fpu_helper.c
21
@@ -XXX,XX +XXX,XX @@ void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
22
23
fp_rem = floatx80_rem(val1->d, val0->d, &env->fp_status);
24
if (!floatx80_is_any_nan(fp_rem)) {
25
- float_status fp_status = { };
26
+ /* Use local temporary fp_status to set different rounding mode */
27
+ float_status fp_status = env->fp_status;
28
uint32_t quotient;
29
int sign;
30
31
/* Calculate quotient directly using round to nearest mode */
32
- set_float_2nan_prop_rule(float_2nan_prop_ab, &fp_status);
33
set_float_rounding_mode(float_round_nearest_even, &fp_status);
34
- set_floatx80_rounding_precision(
35
- get_floatx80_rounding_precision(&env->fp_status), &fp_status);
36
fp_quot.d = floatx80_div(val1->d, val0->d, &fp_status);
37
38
sign = extractFloatx80Sign(fp_quot.d);
39
--
40
2.34.1
diff view generated by jsdifflib
1
If MVE is implemented for an M-profile CPU then it has a VPR
1
In cf_fpu_gdb_get_reg() and cf_fpu_gdb_set_reg() we do the conversion
2
register, which tracks predication information.
2
from float64 to floatx80 using a scratch float_status, because we
3
3
don't want the conversion to affect the CPU's floating point exception
4
Implement the read and write handling of this register, and
4
status. Currently we use a zero-initialized float_status. This will
5
the migration of its state.
5
get steadily more awkward as we add config knobs to float_status
6
that the target must initialize. Avoid having to add any of that
7
configuration here by instead initializing our local float_status
8
from the env->fp_status.
6
9
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210520152840.24453-7-peter.maydell@linaro.org
12
Message-id: 20241202131347.498124-32-peter.maydell@linaro.org
10
---
13
---
11
target/arm/cpu.h | 6 ++++++
14
target/m68k/helper.c | 6 ++++--
12
target/arm/machine.c | 19 +++++++++++++++++++
15
1 file changed, 4 insertions(+), 2 deletions(-)
13
target/arm/translate-vfp.c | 38 ++++++++++++++++++++++++++++++++++++++
14
3 files changed, 63 insertions(+)
15
16
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
--- a/target/m68k/helper.c
19
+++ b/target/arm/cpu.h
20
+++ b/target/m68k/helper.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
21
@@ -XXX,XX +XXX,XX @@ static int cf_fpu_gdb_get_reg(CPUState *cs, GByteArray *mem_buf, int n)
21
uint32_t cpacr[M_REG_NUM_BANKS];
22
CPUM68KState *env = &cpu->env;
22
uint32_t nsacr;
23
23
int ltpsize;
24
if (n < 8) {
24
+ uint32_t vpr;
25
- float_status s = {};
25
} v7m;
26
+ /* Use scratch float_status so any exceptions don't change CPU state */
26
27
+ float_status s = env->fp_status;
27
/* Information associated with an exception about to be taken:
28
return gdb_get_reg64(mem_buf, floatx80_to_float64(env->fregs[n].d, &s));
28
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_FPCCR, ASPEN, 31, 1)
29
R_V7M_FPCCR_UFRDY_MASK | \
30
R_V7M_FPCCR_ASPEN_MASK)
31
32
+/* v7M VPR bits */
33
+FIELD(V7M_VPR, P0, 0, 16)
34
+FIELD(V7M_VPR, MASK01, 16, 4)
35
+FIELD(V7M_VPR, MASK23, 20, 4)
36
+
37
/*
38
* System register ID fields.
39
*/
40
diff --git a/target/arm/machine.c b/target/arm/machine.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/machine.c
43
+++ b/target/arm/machine.c
44
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_fp = {
45
}
29
}
46
};
30
switch (n) {
47
31
@@ -XXX,XX +XXX,XX @@ static int cf_fpu_gdb_set_reg(CPUState *cs, uint8_t *mem_buf, int n)
48
+static bool mve_needed(void *opaque)
32
CPUM68KState *env = &cpu->env;
49
+{
33
50
+ ARMCPU *cpu = opaque;
34
if (n < 8) {
51
+
35
- float_status s = {};
52
+ return cpu_isar_feature(aa32_mve, cpu);
36
+ /* Use scratch float_status so any exceptions don't change CPU state */
53
+}
37
+ float_status s = env->fp_status;
54
+
38
env->fregs[n].d = float64_to_floatx80(ldq_be_p(mem_buf), &s);
55
+static const VMStateDescription vmstate_m_mve = {
39
return 8;
56
+ .name = "cpu/m/mve",
57
+ .version_id = 1,
58
+ .minimum_version_id = 1,
59
+ .needed = mve_needed,
60
+ .fields = (VMStateField[]) {
61
+ VMSTATE_UINT32(env.v7m.vpr, ARMCPU),
62
+ VMSTATE_END_OF_LIST()
63
+ },
64
+};
65
+
66
static const VMStateDescription vmstate_m = {
67
.name = "cpu/m",
68
.version_id = 4,
69
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
70
&vmstate_m_other_sp,
71
&vmstate_m_v8m,
72
&vmstate_m_fp,
73
+ &vmstate_m_mve,
74
NULL
75
}
76
};
77
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/translate-vfp.c
80
+++ b/target/arm/translate-vfp.c
81
@@ -XXX,XX +XXX,XX @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
82
return FPSysRegCheckFailed;
83
}
84
break;
85
+ case ARM_VFP_VPR:
86
+ case ARM_VFP_P0:
87
+ if (!dc_isar_feature(aa32_mve, s)) {
88
+ return FPSysRegCheckFailed;
89
+ }
90
+ break;
91
default:
92
return FPSysRegCheckFailed;
93
}
94
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
95
tcg_temp_free_i32(sfpa);
96
break;
97
}
98
+ case ARM_VFP_VPR:
99
+ /* Behaves as NOP if not privileged */
100
+ if (IS_USER(s)) {
101
+ break;
102
+ }
103
+ tmp = loadfn(s, opaque);
104
+ store_cpu_field(tmp, v7m.vpr);
105
+ break;
106
+ case ARM_VFP_P0:
107
+ {
108
+ TCGv_i32 vpr;
109
+ tmp = loadfn(s, opaque);
110
+ vpr = load_cpu_field(v7m.vpr);
111
+ tcg_gen_deposit_i32(vpr, vpr, tmp,
112
+ R_V7M_VPR_P0_SHIFT, R_V7M_VPR_P0_LENGTH);
113
+ store_cpu_field(vpr, v7m.vpr);
114
+ tcg_temp_free_i32(tmp);
115
+ break;
116
+ }
117
default:
118
g_assert_not_reached();
119
}
120
@@ -XXX,XX +XXX,XX @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
121
tcg_temp_free_i32(fpscr);
122
break;
123
}
124
+ case ARM_VFP_VPR:
125
+ /* Behaves as NOP if not privileged */
126
+ if (IS_USER(s)) {
127
+ break;
128
+ }
129
+ tmp = load_cpu_field(v7m.vpr);
130
+ storefn(s, opaque, tmp);
131
+ break;
132
+ case ARM_VFP_P0:
133
+ tmp = load_cpu_field(v7m.vpr);
134
+ tcg_gen_extract_i32(tmp, tmp, R_V7M_VPR_P0_SHIFT, R_V7M_VPR_P0_LENGTH);
135
+ storefn(s, opaque, tmp);
136
+ break;
137
default:
138
g_assert_not_reached();
139
}
40
}
140
--
41
--
141
2.20.1
42
2.34.1
142
143
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
In the helper functions flcmps and flcmpd we use a scratch float_status
2
so that we don't change the CPU state if the comparison raises any
3
floating point exception flags. Instead of zero-initializing this
4
scratch float_status, initialize it as a copy of env->fp_status. This
5
avoids the need to explicitly initialize settings like the NaN
6
propagation rule or others we might add to softfloat in future.
2
7
3
The hooks we have that call us after reset, init and loadvm really all
8
To do this we need to pass the CPU env pointer in to the helper.
4
just want to say "The reference of all register state is in the QEMU
5
vcpu struct, please push it".
6
9
7
We already have a working pushing mechanism though called cpu->vcpu_dirty,
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
so we can just reuse that for all of the above, syncing state properly the
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
next time we actually execute a vCPU.
12
Message-id: 20241202131347.498124-33-peter.maydell@linaro.org
13
---
14
target/sparc/helper.h | 4 ++--
15
target/sparc/fop_helper.c | 8 ++++----
16
target/sparc/translate.c | 4 ++--
17
3 files changed, 8 insertions(+), 8 deletions(-)
10
18
11
This fixes PSCI resets on ARM, as they modify CPU state even after the
19
diff --git a/target/sparc/helper.h b/target/sparc/helper.h
12
post init call has completed, but before we execute the vCPU again.
13
14
To also make the scheme work for x86, we have to make sure we don't
15
move stale eflags into our env when the vcpu state is dirty.
16
17
Signed-off-by: Alexander Graf <agraf@csgraf.de>
18
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
19
Tested-by: Roman Bolshakov <r.bolshakov@yadro.com>
20
Reviewed-by: Sergio Lopez <slp@redhat.com>
21
Message-id: 20210519202253.76782-13-agraf@csgraf.de
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
---
24
accel/hvf/hvf-accel-ops.c | 27 +++++++--------------------
25
target/i386/hvf/x86hvf.c | 5 ++++-
26
2 files changed, 11 insertions(+), 21 deletions(-)
27
28
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
29
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
30
--- a/accel/hvf/hvf-accel-ops.c
21
--- a/target/sparc/helper.h
31
+++ b/accel/hvf/hvf-accel-ops.c
22
+++ b/target/sparc/helper.h
32
@@ -XXX,XX +XXX,XX @@ static void hvf_cpu_synchronize_state(CPUState *cpu)
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(fcmpd, TCG_CALL_NO_WG, i32, env, f64, f64)
33
}
24
DEF_HELPER_FLAGS_3(fcmped, TCG_CALL_NO_WG, i32, env, f64, f64)
25
DEF_HELPER_FLAGS_3(fcmpq, TCG_CALL_NO_WG, i32, env, i128, i128)
26
DEF_HELPER_FLAGS_3(fcmpeq, TCG_CALL_NO_WG, i32, env, i128, i128)
27
-DEF_HELPER_FLAGS_2(flcmps, TCG_CALL_NO_RWG_SE, i32, f32, f32)
28
-DEF_HELPER_FLAGS_2(flcmpd, TCG_CALL_NO_RWG_SE, i32, f64, f64)
29
+DEF_HELPER_FLAGS_3(flcmps, TCG_CALL_NO_RWG_SE, i32, env, f32, f32)
30
+DEF_HELPER_FLAGS_3(flcmpd, TCG_CALL_NO_RWG_SE, i32, env, f64, f64)
31
DEF_HELPER_2(raise_exception, noreturn, env, int)
32
33
DEF_HELPER_FLAGS_3(faddd, TCG_CALL_NO_WG, f64, env, f64, f64)
34
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/sparc/fop_helper.c
37
+++ b/target/sparc/fop_helper.c
38
@@ -XXX,XX +XXX,XX @@ uint32_t helper_fcmpeq(CPUSPARCState *env, Int128 src1, Int128 src2)
39
return finish_fcmp(env, r, GETPC());
34
}
40
}
35
41
36
-static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu,
42
-uint32_t helper_flcmps(float32 src1, float32 src2)
37
- run_on_cpu_data arg)
43
+uint32_t helper_flcmps(CPUSPARCState *env, float32 src1, float32 src2)
38
+static void do_hvf_cpu_synchronize_set_dirty(CPUState *cpu,
39
+ run_on_cpu_data arg)
40
{
44
{
41
- hvf_put_registers(cpu);
45
/*
42
- cpu->vcpu_dirty = false;
46
* FLCMP never raises an exception nor modifies any FSR fields.
43
+ /* QEMU state is the reference, push it to HVF now and on next entry */
47
* Perform the comparison with a dummy fp environment.
44
+ cpu->vcpu_dirty = true;
48
*/
49
- float_status discard = { };
50
+ float_status discard = env->fp_status;
51
FloatRelation r;
52
53
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
54
@@ -XXX,XX +XXX,XX @@ uint32_t helper_flcmps(float32 src1, float32 src2)
55
g_assert_not_reached();
45
}
56
}
46
57
47
static void hvf_cpu_synchronize_post_reset(CPUState *cpu)
58
-uint32_t helper_flcmpd(float64 src1, float64 src2)
59
+uint32_t helper_flcmpd(CPUSPARCState *env, float64 src1, float64 src2)
48
{
60
{
49
- run_on_cpu(cpu, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
61
- float_status discard = { };
50
-}
62
+ float_status discard = env->fp_status;
51
-
63
FloatRelation r;
52
-static void do_hvf_cpu_synchronize_post_init(CPUState *cpu,
64
53
- run_on_cpu_data arg)
65
set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
54
-{
66
diff --git a/target/sparc/translate.c b/target/sparc/translate.c
55
- hvf_put_registers(cpu);
67
index XXXXXXX..XXXXXXX 100644
56
- cpu->vcpu_dirty = false;
68
--- a/target/sparc/translate.c
57
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_set_dirty, RUN_ON_CPU_NULL);
69
+++ b/target/sparc/translate.c
70
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPs(DisasContext *dc, arg_FLCMPs *a)
71
72
src1 = gen_load_fpr_F(dc, a->rs1);
73
src2 = gen_load_fpr_F(dc, a->rs2);
74
- gen_helper_flcmps(cpu_fcc[a->cc], src1, src2);
75
+ gen_helper_flcmps(cpu_fcc[a->cc], tcg_env, src1, src2);
76
return advance_pc(dc);
58
}
77
}
59
78
60
static void hvf_cpu_synchronize_post_init(CPUState *cpu)
79
@@ -XXX,XX +XXX,XX @@ static bool trans_FLCMPd(DisasContext *dc, arg_FLCMPd *a)
61
{
80
62
- run_on_cpu(cpu, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
81
src1 = gen_load_fpr_D(dc, a->rs1);
63
-}
82
src2 = gen_load_fpr_D(dc, a->rs2);
64
-
83
- gen_helper_flcmpd(cpu_fcc[a->cc], src1, src2);
65
-static void do_hvf_cpu_synchronize_pre_loadvm(CPUState *cpu,
84
+ gen_helper_flcmpd(cpu_fcc[a->cc], tcg_env, src1, src2);
66
- run_on_cpu_data arg)
85
return advance_pc(dc);
67
-{
68
- cpu->vcpu_dirty = true;
69
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_set_dirty, RUN_ON_CPU_NULL);
70
}
86
}
71
87
72
static void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)
73
{
74
- run_on_cpu(cpu, do_hvf_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);
75
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_set_dirty, RUN_ON_CPU_NULL);
76
}
77
78
static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)
79
diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/i386/hvf/x86hvf.c
82
+++ b/target/i386/hvf/x86hvf.c
83
@@ -XXX,XX +XXX,XX @@ int hvf_process_events(CPUState *cpu_state)
84
X86CPU *cpu = X86_CPU(cpu_state);
85
CPUX86State *env = &cpu->env;
86
87
- env->eflags = rreg(cpu_state->hvf->fd, HV_X86_RFLAGS);
88
+ if (!cpu_state->vcpu_dirty) {
89
+ /* light weight sync for CPU_INTERRUPT_HARD and IF_MASK */
90
+ env->eflags = rreg(cpu_state->hvf->fd, HV_X86_RFLAGS);
91
+ }
92
93
if (cpu_state->interrupt_request & CPU_INTERRUPT_INIT) {
94
cpu_synchronize_state(cpu_state);
95
--
88
--
96
2.20.1
89
2.34.1
97
98
diff view generated by jsdifflib
New patch
1
In the helper_compute_fprf functions, we pass a dummy float_status
2
in to the is_signaling_nan() function. This is unnecessary, because
3
we have convenient access to the CPU env pointer here and that
4
is already set up with the correct values for the snan_bit_is_one
5
and no_signaling_nans config settings. is_signaling_nan() doesn't
6
ever update the fp_status with any exception flags, so there is
7
no reason not to use env->fp_status here.
1
8
9
Use env->fp_status instead of the dummy fp_status.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20241202131347.498124-34-peter.maydell@linaro.org
14
---
15
target/ppc/fpu_helper.c | 3 +--
16
1 file changed, 1 insertion(+), 2 deletions(-)
17
18
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/ppc/fpu_helper.c
21
+++ b/target/ppc/fpu_helper.c
22
@@ -XXX,XX +XXX,XX @@ void helper_compute_fprf_##tp(CPUPPCState *env, tp arg) \
23
} else if (tp##_is_infinity(arg)) { \
24
fprf = neg ? 0x09 << FPSCR_FPRF : 0x05 << FPSCR_FPRF; \
25
} else { \
26
- float_status dummy = { }; /* snan_bit_is_one = 0 */ \
27
- if (tp##_is_signaling_nan(arg, &dummy)) { \
28
+ if (tp##_is_signaling_nan(arg, &env->fp_status)) { \
29
fprf = 0x00 << FPSCR_FPRF; \
30
} else { \
31
fprf = 0x11 << FPSCR_FPRF; \
32
--
33
2.34.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is BFDOT for both AArch64 AdvSIMD and SVE,
3
Now that float_status has a bunch of fp parameters,
4
and VDOT.BF16 for AArch32 NEON.
4
it is easier to copy an existing structure than create
5
one from scratch. Begin by copying the structure that
6
corresponds to the FPSR and make only the adjustments
7
required for BFloat16 semantics.
5
8
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210525225817.400336-8-richard.henderson@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20241203203949.483774-2-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
14
---
11
target/arm/helper.h | 2 ++
15
target/arm/tcg/vec_helper.c | 20 +++++++-------------
12
target/arm/neon-shared.decode | 2 ++
16
1 file changed, 7 insertions(+), 13 deletions(-)
13
target/arm/sve.decode | 3 +++
14
target/arm/translate-a64.c | 41 +++++++++++++++++++++++++++--------
15
target/arm/translate-neon.c | 9 ++++++++
16
target/arm/translate-sve.c | 12 ++++++++++
17
target/arm/vec_helper.c | 20 +++++++++++++++++
18
7 files changed, 80 insertions(+), 9 deletions(-)
19
17
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
18
diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.h
20
--- a/target/arm/tcg/vec_helper.c
23
+++ b/target/arm/helper.h
21
+++ b/target/arm/tcg/vec_helper.c
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_usmmla_b, TCG_CALL_NO_RWG,
22
@@ -XXX,XX +XXX,XX @@ bool is_ebf(CPUARMState *env, float_status *statusp, float_status *oddstatusp)
25
23
* no effect on AArch32 instructions.
26
DEF_HELPER_FLAGS_5(gvec_bfdot, TCG_CALL_NO_RWG,
24
*/
27
void, ptr, ptr, ptr, ptr, i32)
25
bool ebf = is_a64(env) && env->vfp.fpcr & FPCR_EBF;
28
+DEF_HELPER_FLAGS_5(gvec_bfdot_idx, TCG_CALL_NO_RWG,
26
- *statusp = (float_status){
29
+ void, ptr, ptr, ptr, ptr, i32)
27
- .tininess_before_rounding = float_tininess_before_rounding,
30
28
- .float_rounding_mode = float_round_to_odd_inf,
31
#ifdef TARGET_AARCH64
29
- .flush_to_zero = true,
32
#include "helper-a64.h"
30
- .flush_inputs_to_zero = true,
33
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
31
- .default_nan_mode = true,
34
index XXXXXXX..XXXXXXX 100644
32
- };
35
--- a/target/arm/neon-shared.decode
36
+++ b/target/arm/neon-shared.decode
37
@@ -XXX,XX +XXX,XX @@ VUSDOT_scalar 1111 1110 1 . 00 .... .... 1101 . q:1 index:1 0 vm:4 \
38
vn=%vn_dp vd=%vd_dp
39
VSUDOT_scalar 1111 1110 1 . 00 .... .... 1101 . q:1 index:1 1 vm:4 \
40
vn=%vn_dp vd=%vd_dp
41
+VDOT_b16_scal 1111 1110 0 . 00 .... .... 1101 . q:1 index:1 0 vm:4 \
42
+ vn=%vn_dp vd=%vd_dp
43
44
%vfml_scalar_q0_rm 0:3 5:1
45
%vfml_scalar_q1_index 5:1 3:1
46
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/sve.decode
49
+++ b/target/arm/sve.decode
50
@@ -XXX,XX +XXX,XX @@ FMLALB_zzxw 01100100 10 1 ..... 0100.0 ..... ..... @rrxr_3a esz=2
51
FMLALT_zzxw 01100100 10 1 ..... 0100.1 ..... ..... @rrxr_3a esz=2
52
FMLSLB_zzxw 01100100 10 1 ..... 0110.0 ..... ..... @rrxr_3a esz=2
53
FMLSLT_zzxw 01100100 10 1 ..... 0110.1 ..... ..... @rrxr_3a esz=2
54
+
33
+
55
+### SVE2 floating-point bfloat16 dot-product (indexed)
34
+ *statusp = env->vfp.fp_status;
56
+BFDOT_zzxz 01100100 01 1 ..... 010000 ..... ..... @rrxr_2 esz=2
35
+ set_default_nan_mode(true, statusp);
57
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
36
58
index XXXXXXX..XXXXXXX 100644
37
if (ebf) {
59
--- a/target/arm/translate-a64.c
38
- float_status *fpst = &env->vfp.fp_status;
60
+++ b/target/arm/translate-a64.c
39
- set_flush_to_zero(get_flush_to_zero(fpst), statusp);
61
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
40
- set_flush_inputs_to_zero(get_flush_inputs_to_zero(fpst), statusp);
62
return;
41
- set_float_rounding_mode(get_float_rounding_mode(fpst), statusp);
63
}
64
break;
65
- case 0x0f: /* SUDOT, USDOT */
66
- if (is_scalar || (size & 1) || !dc_isar_feature(aa64_i8mm, s)) {
67
+ case 0x0f:
68
+ switch (size) {
69
+ case 0: /* SUDOT */
70
+ case 2: /* USDOT */
71
+ if (is_scalar || !dc_isar_feature(aa64_i8mm, s)) {
72
+ unallocated_encoding(s);
73
+ return;
74
+ }
75
+ break;
76
+ case 1: /* BFDOT */
77
+ if (is_scalar || !dc_isar_feature(aa64_bf16, s)) {
78
+ unallocated_encoding(s);
79
+ return;
80
+ }
81
+ break;
82
+ default:
83
unallocated_encoding(s);
84
return;
85
}
86
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
87
u ? gen_helper_gvec_udot_idx_b
88
: gen_helper_gvec_sdot_idx_b);
89
return;
90
- case 0x0f: /* SUDOT, USDOT */
91
- gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
92
- extract32(insn, 23, 1)
93
- ? gen_helper_gvec_usdot_idx_b
94
- : gen_helper_gvec_sudot_idx_b);
95
- return;
96
-
42
-
97
+ case 0x0f:
43
/* EBF=1 needs to do a step with round-to-odd semantics */
98
+ switch (extract32(insn, 22, 2)) {
44
*oddstatusp = *statusp;
99
+ case 0: /* SUDOT */
45
set_float_rounding_mode(float_round_to_odd, oddstatusp);
100
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
46
+ } else {
101
+ gen_helper_gvec_sudot_idx_b);
47
+ set_flush_to_zero(true, statusp);
102
+ return;
48
+ set_flush_inputs_to_zero(true, statusp);
103
+ case 1: /* BFDOT */
49
+ set_float_rounding_mode(float_round_to_odd_inf, statusp);
104
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
50
}
105
+ gen_helper_gvec_bfdot_idx);
51
-
106
+ return;
52
return ebf;
107
+ case 2: /* USDOT */
108
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, index,
109
+ gen_helper_gvec_usdot_idx_b);
110
+ return;
111
+ }
112
+ g_assert_not_reached();
113
case 0x11: /* FCMLA #0 */
114
case 0x13: /* FCMLA #90 */
115
case 0x15: /* FCMLA #180 */
116
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/arm/translate-neon.c
119
+++ b/target/arm/translate-neon.c
120
@@ -XXX,XX +XXX,XX @@ static bool trans_VSUDOT_scalar(DisasContext *s, arg_VSUDOT_scalar *a)
121
gen_helper_gvec_sudot_idx_b);
122
}
53
}
123
54
124
+static bool trans_VDOT_b16_scal(DisasContext *s, arg_VDOT_b16_scal *a)
125
+{
126
+ if (!dc_isar_feature(aa32_bf16, s)) {
127
+ return false;
128
+ }
129
+ return do_neon_ddda(s, a->q * 6, a->vd, a->vn, a->vm, a->index,
130
+ gen_helper_gvec_bfdot_idx);
131
+}
132
+
133
static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
134
{
135
int opr_sz;
136
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
137
index XXXXXXX..XXXXXXX 100644
138
--- a/target/arm/translate-sve.c
139
+++ b/target/arm/translate-sve.c
140
@@ -XXX,XX +XXX,XX @@ static bool trans_BFDOT_zzzz(DisasContext *s, arg_rrrr_esz *a)
141
}
142
return true;
143
}
144
+
145
+static bool trans_BFDOT_zzxz(DisasContext *s, arg_rrxr_esz *a)
146
+{
147
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
148
+ return false;
149
+ }
150
+ if (sve_access_check(s)) {
151
+ gen_gvec_ool_zzzz(s, gen_helper_gvec_bfdot_idx,
152
+ a->rd, a->rn, a->rm, a->ra, a->index);
153
+ }
154
+ return true;
155
+}
156
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
157
index XXXXXXX..XXXXXXX 100644
158
--- a/target/arm/vec_helper.c
159
+++ b/target/arm/vec_helper.c
160
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_bfdot)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
161
}
162
clear_tail(d, opr_sz, simd_maxsz(desc));
163
}
164
+
165
+void HELPER(gvec_bfdot_idx)(void *vd, void *vn, void *vm,
166
+ void *va, uint32_t desc)
167
+{
168
+ intptr_t i, j, opr_sz = simd_oprsz(desc);
169
+ intptr_t index = simd_data(desc);
170
+ intptr_t elements = opr_sz / 4;
171
+ intptr_t eltspersegment = MIN(16 / 4, elements);
172
+ float32 *d = vd, *a = va;
173
+ uint32_t *n = vn, *m = vm;
174
+
175
+ for (i = 0; i < elements; i += eltspersegment) {
176
+ uint32_t m_idx = m[i + H4(index)];
177
+
178
+ for (j = i; j < i + eltspersegment; j++) {
179
+ d[j] = bfdotadd(a[j], n[j], m_idx);
180
+ }
181
+ }
182
+ clear_tail(d, opr_sz, simd_maxsz(desc));
183
+}
184
--
55
--
185
2.20.1
56
2.34.1
186
57
187
58
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Currently we hardcode the default NaN value in parts64_default_nan()
2
using a compile-time ifdef ladder. This is awkward for two cases:
3
* for single-QEMU-binary we can't hard-code target-specifics like this
4
* for Arm FEAT_AFP the default NaN value depends on FPCR.AH
5
(specifically the sign bit is different)
2
6
3
This is BFCVT{N,T} for both AArch64 AdvSIMD and SVE,
7
Add a field to float_status to specify the default NaN value; fall
4
and VCVT.BF16.F32 for AArch32 NEON.
8
back to the old ifdef behaviour if these are not set.
5
9
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
The default NaN value is specified by setting a uint8_t to a
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
pattern corresponding to the sign and upper fraction parts of
8
Message-id: 20210525225817.400336-5-richard.henderson@linaro.org
12
the NaN; the lower bits of the fraction are set from bit 0 of
13
the pattern.
14
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20241202131347.498124-35-peter.maydell@linaro.org
10
---
18
---
11
target/arm/helper-sve.h | 4 ++++
19
include/fpu/softfloat-helpers.h | 11 +++++++
12
target/arm/helper.h | 1 +
20
include/fpu/softfloat-types.h | 10 ++++++
13
target/arm/neon-dp.decode | 1 +
21
fpu/softfloat-specialize.c.inc | 55 ++++++++++++++++++++-------------
14
target/arm/sve.decode | 2 ++
22
3 files changed, 54 insertions(+), 22 deletions(-)
15
target/arm/sve_helper.c | 2 ++
16
target/arm/translate-a64.c | 17 ++++++++++++++
17
target/arm/translate-neon.c | 45 +++++++++++++++++++++++++++++++++++++
18
target/arm/translate-sve.c | 16 +++++++++++++
19
target/arm/vfp_helper.c | 7 ++++++
20
9 files changed, 95 insertions(+)
21
23
22
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
24
diff --git a/include/fpu/softfloat-helpers.h b/include/fpu/softfloat-helpers.h
23
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper-sve.h
26
--- a/include/fpu/softfloat-helpers.h
25
+++ b/target/arm/helper-sve.h
27
+++ b/include/fpu/softfloat-helpers.h
26
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_fcvt_hd, TCG_CALL_NO_RWG,
28
@@ -XXX,XX +XXX,XX @@ static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
27
void, ptr, ptr, ptr, ptr, i32)
29
status->float_infzeronan_rule = rule;
28
DEF_HELPER_FLAGS_5(sve_fcvt_sd, TCG_CALL_NO_RWG,
29
void, ptr, ptr, ptr, ptr, i32)
30
+DEF_HELPER_FLAGS_5(sve_bfcvt, TCG_CALL_NO_RWG,
31
+ void, ptr, ptr, ptr, ptr, i32)
32
33
DEF_HELPER_FLAGS_5(sve_fcvtzs_hh, TCG_CALL_NO_RWG,
34
void, ptr, ptr, ptr, ptr, i32)
35
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve2_fcvtnt_sh, TCG_CALL_NO_RWG,
36
void, ptr, ptr, ptr, ptr, i32)
37
DEF_HELPER_FLAGS_5(sve2_fcvtnt_ds, TCG_CALL_NO_RWG,
38
void, ptr, ptr, ptr, ptr, i32)
39
+DEF_HELPER_FLAGS_5(sve_bfcvtnt, TCG_CALL_NO_RWG,
40
+ void, ptr, ptr, ptr, ptr, i32)
41
42
DEF_HELPER_FLAGS_5(sve2_fcvtlt_hs, TCG_CALL_NO_RWG,
43
void, ptr, ptr, ptr, ptr, i32)
44
diff --git a/target/arm/helper.h b/target/arm/helper.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/helper.h
47
+++ b/target/arm/helper.h
48
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_cmped, void, f64, f64, env)
49
DEF_HELPER_2(vfp_fcvtds, f64, f32, env)
50
DEF_HELPER_2(vfp_fcvtsd, f32, f64, env)
51
DEF_HELPER_FLAGS_2(bfcvt, TCG_CALL_NO_RWG, i32, f32, ptr)
52
+DEF_HELPER_FLAGS_2(bfcvt_pair, TCG_CALL_NO_RWG, i32, i64, ptr)
53
54
DEF_HELPER_2(vfp_uitoh, f16, i32, ptr)
55
DEF_HELPER_2(vfp_uitos, f32, i32, ptr)
56
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/neon-dp.decode
59
+++ b/target/arm/neon-dp.decode
60
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
61
VRINTZ 1111 001 11 . 11 .. 10 .... 0 1011 . . 0 .... @2misc
62
63
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
64
+ VCVT_B16_F32 1111 001 11 . 11 .. 10 .... 0 1100 1 . 0 .... @2misc_q0
65
66
VRINTM 1111 001 11 . 11 .. 10 .... 0 1101 . . 0 .... @2misc
67
68
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/sve.decode
71
+++ b/target/arm/sve.decode
72
@@ -XXX,XX +XXX,XX @@ FNMLS_zpzzz 01100101 .. 1 ..... 111 ... ..... ..... @rdn_pg_rm_ra
73
# SVE floating-point convert precision
74
FCVT_sh 01100101 10 0010 00 101 ... ..... ..... @rd_pg_rn_e0
75
FCVT_hs 01100101 10 0010 01 101 ... ..... ..... @rd_pg_rn_e0
76
+BFCVT 01100101 10 0010 10 101 ... ..... ..... @rd_pg_rn_e0
77
FCVT_dh 01100101 11 0010 00 101 ... ..... ..... @rd_pg_rn_e0
78
FCVT_hd 01100101 11 0010 01 101 ... ..... ..... @rd_pg_rn_e0
79
FCVT_ds 01100101 11 0010 10 101 ... ..... ..... @rd_pg_rn_e0
80
@@ -XXX,XX +XXX,XX @@ RAX1 01000101 00 1 ..... 11110 1 ..... ..... @rd_rn_rm_e0
81
FCVTXNT_ds 01100100 00 0010 10 101 ... ..... ..... @rd_pg_rn_e0
82
FCVTX_ds 01100101 00 0010 10 101 ... ..... ..... @rd_pg_rn_e0
83
FCVTNT_sh 01100100 10 0010 00 101 ... ..... ..... @rd_pg_rn_e0
84
+BFCVTNT 01100100 10 0010 10 101 ... ..... ..... @rd_pg_rn_e0
85
FCVTLT_hs 01100100 10 0010 01 101 ... ..... ..... @rd_pg_rn_e0
86
FCVTNT_ds 01100100 11 0010 10 101 ... ..... ..... @rd_pg_rn_e0
87
FCVTLT_sd 01100100 11 0010 11 101 ... ..... ..... @rd_pg_rn_e0
88
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/sve_helper.c
91
+++ b/target/arm/sve_helper.c
92
@@ -XXX,XX +XXX,XX @@ static inline uint64_t vfp_float64_to_uint64_rtz(float64 f, float_status *s)
93
94
DO_ZPZ_FP(sve_fcvt_sh, uint32_t, H1_4, sve_f32_to_f16)
95
DO_ZPZ_FP(sve_fcvt_hs, uint32_t, H1_4, sve_f16_to_f32)
96
+DO_ZPZ_FP(sve_bfcvt, uint32_t, H1_4, float32_to_bfloat16)
97
DO_ZPZ_FP(sve_fcvt_dh, uint64_t, , sve_f64_to_f16)
98
DO_ZPZ_FP(sve_fcvt_hd, uint64_t, , sve_f16_to_f64)
99
DO_ZPZ_FP(sve_fcvt_ds, uint64_t, , float64_to_float32)
100
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vg, void *status, uint32_t desc) \
101
} while (i != 0); \
102
}
30
}
103
31
104
+DO_FCVTNT(sve_bfcvtnt, uint32_t, uint16_t, H1_4, H1_2, float32_to_bfloat16)
32
+static inline void set_float_default_nan_pattern(uint8_t dnan_pattern,
105
DO_FCVTNT(sve2_fcvtnt_sh, uint32_t, uint16_t, H1_4, H1_2, sve_f32_to_f16)
33
+ float_status *status)
106
DO_FCVTNT(sve2_fcvtnt_ds, uint64_t, uint32_t, , H1_4, float64_to_float32)
107
108
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/target/arm/translate-a64.c
111
+++ b/target/arm/translate-a64.c
112
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_narrow(DisasContext *s, bool scalar,
113
tcg_temp_free_i32(ahp);
114
}
115
break;
116
+ case 0x36: /* BFCVTN, BFCVTN2 */
117
+ {
118
+ TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);
119
+ gen_helper_bfcvt_pair(tcg_res[pass], tcg_op, fpst);
120
+ tcg_temp_free_ptr(fpst);
121
+ }
122
+ break;
123
case 0x56: /* FCVTXN, FCVTXN2 */
124
/* 64 bit to 32 bit float conversion
125
* with von Neumann rounding (round to odd)
126
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
127
}
128
handle_2misc_narrow(s, false, opcode, 0, is_q, size - 1, rn, rd);
129
return;
130
+ case 0x36: /* BFCVTN, BFCVTN2 */
131
+ if (!dc_isar_feature(aa64_bf16, s) || size != 2) {
132
+ unallocated_encoding(s);
133
+ return;
134
+ }
135
+ if (!fp_access_check(s)) {
136
+ return;
137
+ }
138
+ handle_2misc_narrow(s, false, opcode, 0, is_q, size - 1, rn, rd);
139
+ return;
140
case 0x17: /* FCVTL, FCVTL2 */
141
if (!fp_access_check(s)) {
142
return;
143
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
144
index XXXXXXX..XXXXXXX 100644
145
--- a/target/arm/translate-neon.c
146
+++ b/target/arm/translate-neon.c
147
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
148
return true;
149
}
150
151
+static bool trans_VCVT_B16_F32(DisasContext *s, arg_2misc *a)
152
+{
34
+{
153
+ TCGv_ptr fpst;
35
+ status->default_nan_pattern = dnan_pattern;
154
+ TCGv_i64 tmp;
155
+ TCGv_i32 dst0, dst1;
156
+
157
+ if (!dc_isar_feature(aa32_bf16, s)) {
158
+ return false;
159
+ }
160
+
161
+ /* UNDEF accesses to D16-D31 if they don't exist. */
162
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
163
+ ((a->vd | a->vm) & 0x10)) {
164
+ return false;
165
+ }
166
+
167
+ if ((a->vm & 1) || (a->size != 1)) {
168
+ return false;
169
+ }
170
+
171
+ if (!vfp_access_check(s)) {
172
+ return true;
173
+ }
174
+
175
+ fpst = fpstatus_ptr(FPST_STD);
176
+ tmp = tcg_temp_new_i64();
177
+ dst0 = tcg_temp_new_i32();
178
+ dst1 = tcg_temp_new_i32();
179
+
180
+ read_neon_element64(tmp, a->vm, 0, MO_64);
181
+ gen_helper_bfcvt_pair(dst0, tmp, fpst);
182
+
183
+ read_neon_element64(tmp, a->vm, 1, MO_64);
184
+ gen_helper_bfcvt_pair(dst1, tmp, fpst);
185
+
186
+ write_neon_element32(dst0, a->vd, 0, MO_32);
187
+ write_neon_element32(dst1, a->vd, 1, MO_32);
188
+
189
+ tcg_temp_free_i64(tmp);
190
+ tcg_temp_free_i32(dst0);
191
+ tcg_temp_free_i32(dst1);
192
+ tcg_temp_free_ptr(fpst);
193
+ return true;
194
+}
36
+}
195
+
37
+
196
static bool trans_VCVT_F16_F32(DisasContext *s, arg_2misc *a)
38
static inline void set_flush_to_zero(bool val, float_status *status)
197
{
39
{
198
TCGv_ptr fpst;
40
status->flush_to_zero = val;
199
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
41
@@ -XXX,XX +XXX,XX @@ static inline FloatInfZeroNaNRule get_float_infzeronan_rule(float_status *status
200
index XXXXXXX..XXXXXXX 100644
42
return status->float_infzeronan_rule;
201
--- a/target/arm/translate-sve.c
202
+++ b/target/arm/translate-sve.c
203
@@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_hs(DisasContext *s, arg_rpr_esz *a)
204
return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_hs);
205
}
43
}
206
44
207
+static bool trans_BFCVT(DisasContext *s, arg_rpr_esz *a)
45
+static inline uint8_t get_float_default_nan_pattern(float_status *status)
208
+{
46
+{
209
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
47
+ return status->default_nan_pattern;
210
+ return false;
211
+ }
212
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_bfcvt);
213
+}
48
+}
214
+
49
+
215
static bool trans_FCVT_dh(DisasContext *s, arg_rpr_esz *a)
50
static inline bool get_flush_to_zero(float_status *status)
216
{
51
{
217
return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_dh);
52
return status->flush_to_zero;
218
@@ -XXX,XX +XXX,XX @@ static bool trans_FCVTNT_sh(DisasContext *s, arg_rpr_esz *a)
53
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
219
return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve2_fcvtnt_sh);
54
index XXXXXXX..XXXXXXX 100644
220
}
55
--- a/include/fpu/softfloat-types.h
221
56
+++ b/include/fpu/softfloat-types.h
222
+static bool trans_BFCVTNT(DisasContext *s, arg_rpr_esz *a)
57
@@ -XXX,XX +XXX,XX @@ typedef struct float_status {
223
+{
58
/* should denormalised inputs go to zero and set the input_denormal flag? */
224
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
59
bool flush_inputs_to_zero;
225
+ return false;
60
bool default_nan_mode;
61
+ /*
62
+ * The pattern to use for the default NaN. Here the high bit specifies
63
+ * the default NaN's sign bit, and bits 6..0 specify the high bits of the
64
+ * fractional part. The low bits of the fractional part are copies of bit 0.
65
+ * The exponent of the default NaN is (as for any NaN) always all 1s.
66
+ * Note that a value of 0 here is not a valid NaN. The target must set
67
+ * this to the correct non-zero value, or we will assert when trying to
68
+ * create a default NaN.
69
+ */
70
+ uint8_t default_nan_pattern;
71
/*
72
* The flags below are not used on all specializations and may
73
* constant fold away (see snan_bit_is_one()/no_signalling_nans() in
74
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
75
index XXXXXXX..XXXXXXX 100644
76
--- a/fpu/softfloat-specialize.c.inc
77
+++ b/fpu/softfloat-specialize.c.inc
78
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
79
{
80
bool sign = 0;
81
uint64_t frac;
82
+ uint8_t dnan_pattern = status->default_nan_pattern;
83
84
+ if (dnan_pattern == 0) {
85
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
86
- /* !snan_bit_is_one, set all bits */
87
- frac = (1ULL << DECOMPOSED_BINARY_POINT) - 1;
88
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
89
+ /* Sign bit clear, all frac bits set */
90
+ dnan_pattern = 0b01111111;
91
+#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
92
|| defined(TARGET_MICROBLAZE)
93
- /* !snan_bit_is_one, set sign and msb */
94
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
95
- sign = 1;
96
+ /* Sign bit set, most significant frac bit set */
97
+ dnan_pattern = 0b11000000;
98
#elif defined(TARGET_HPPA)
99
- /* snan_bit_is_one, set msb-1. */
100
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 2);
101
+ /* Sign bit clear, msb-1 frac bit set */
102
+ dnan_pattern = 0b00100000;
103
#elif defined(TARGET_HEXAGON)
104
- sign = 1;
105
- frac = ~0ULL;
106
+ /* Sign bit set, all frac bits set. */
107
+ dnan_pattern = 0b11111111;
108
#else
109
- /*
110
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
111
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
112
- * do not have floating-point.
113
- */
114
- if (snan_bit_is_one(status)) {
115
- /* set all bits other than msb */
116
- frac = (1ULL << (DECOMPOSED_BINARY_POINT - 1)) - 1;
117
- } else {
118
- /* set msb */
119
- frac = 1ULL << (DECOMPOSED_BINARY_POINT - 1);
120
- }
121
+ /*
122
+ * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
123
+ * S390, SH4, TriCore, and Xtensa. Our other supported targets
124
+ * do not have floating-point.
125
+ */
126
+ if (snan_bit_is_one(status)) {
127
+ /* sign bit clear, set all frac bits other than msb */
128
+ dnan_pattern = 0b00111111;
129
+ } else {
130
+ /* sign bit clear, set frac msb */
131
+ dnan_pattern = 0b01000000;
132
+ }
133
#endif
226
+ }
134
+ }
227
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_bfcvtnt);
135
+ assert(dnan_pattern != 0);
228
+}
229
+
136
+
230
static bool trans_FCVTNT_ds(DisasContext *s, arg_rpr_esz *a)
137
+ sign = dnan_pattern >> 7;
231
{
138
+ /*
232
if (!dc_isar_feature(aa64_sve2, s)) {
139
+ * Place default_nan_pattern [6:0] into bits [62:56],
233
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
140
+ * and replecate bit [0] down into [55:0]
234
index XXXXXXX..XXXXXXX 100644
141
+ */
235
--- a/target/arm/vfp_helper.c
142
+ frac = deposit64(0, DECOMPOSED_BINARY_POINT - 7, 7, dnan_pattern);
236
+++ b/target/arm/vfp_helper.c
143
+ frac = deposit64(frac, 0, DECOMPOSED_BINARY_POINT - 7, -(dnan_pattern & 1));
237
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(bfcvt)(float32 x, void *status)
144
238
return float32_to_bfloat16(x, status);
145
*p = (FloatParts64) {
239
}
146
.cls = float_class_qnan,
240
241
+uint32_t HELPER(bfcvt_pair)(uint64_t pair, void *status)
242
+{
243
+ bfloat16 lo = float32_to_bfloat16(extract64(pair, 0, 32), status);
244
+ bfloat16 hi = float32_to_bfloat16(extract64(pair, 32, 32), status);
245
+ return deposit32(lo, 16, 16, hi);
246
+}
247
+
248
/*
249
* VFP3 fixed point conversion. The AArch32 versions of fix-to-float
250
* must always round-to-nearest; the AArch64 ones honour the FPSCR
251
--
147
--
252
2.20.1
148
2.34.1
253
254
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for the tests/fp code.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-36-peter.maydell@linaro.org
6
---
7
tests/fp/fp-bench.c | 1 +
8
tests/fp/fp-test-log2.c | 1 +
9
tests/fp/fp-test.c | 1 +
10
3 files changed, 3 insertions(+)
11
12
diff --git a/tests/fp/fp-bench.c b/tests/fp/fp-bench.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/fp/fp-bench.c
15
+++ b/tests/fp/fp-bench.c
16
@@ -XXX,XX +XXX,XX @@ static void run_bench(void)
17
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &soft_status);
18
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &soft_status);
19
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &soft_status);
20
+ set_float_default_nan_pattern(0b01000000, &soft_status);
21
22
f = bench_funcs[operation][precision];
23
g_assert(f);
24
diff --git a/tests/fp/fp-test-log2.c b/tests/fp/fp-test-log2.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/tests/fp/fp-test-log2.c
27
+++ b/tests/fp/fp-test-log2.c
28
@@ -XXX,XX +XXX,XX @@ int main(int ac, char **av)
29
int i;
30
31
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
32
+ set_float_default_nan_pattern(0b01000000, &qsf);
33
set_float_rounding_mode(float_round_nearest_even, &qsf);
34
35
test.d = 0.0;
36
diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/tests/fp/fp-test.c
39
+++ b/tests/fp/fp-test.c
40
@@ -XXX,XX +XXX,XX @@ void run_test(void)
41
*/
42
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &qsf);
43
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &qsf);
44
+ set_float_default_nan_pattern(0b01000000, &qsf);
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, &qsf);
46
47
genCases_setLevel(test_level);
48
--
49
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-37-peter.maydell@linaro.org
7
---
8
target/microblaze/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 +--
10
2 files changed, 3 insertions(+), 2 deletions(-)
11
12
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/microblaze/cpu.c
15
+++ b/target/microblaze/cpu.c
16
@@ -XXX,XX +XXX,XX @@ static void mb_cpu_reset_hold(Object *obj, ResetType type)
17
* this architecture.
18
*/
19
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
20
+ /* Default NaN: sign bit set, most significant frac bit set */
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
22
23
#if defined(CONFIG_USER_ONLY)
24
/* start in user mode with interrupts enabled. */
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
31
/* Sign bit clear, all frac bits set */
32
dnan_pattern = 0b01111111;
33
-#elif defined(TARGET_I386) || defined(TARGET_X86_64) \
34
- || defined(TARGET_MICROBLAZE)
35
+#elif defined(TARGET_I386) || defined(TARGET_X86_64)
36
/* Sign bit set, most significant frac bit set */
37
dnan_pattern = 0b11000000;
38
#elif defined(TARGET_HPPA)
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-38-peter.maydell@linaro.org
7
---
8
target/i386/tcg/fpu_helper.c | 4 ++++
9
fpu/softfloat-specialize.c.inc | 3 ---
10
2 files changed, 4 insertions(+), 3 deletions(-)
11
12
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/i386/tcg/fpu_helper.c
15
+++ b/target/i386/tcg/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void cpu_init_fp_statuses(CPUX86State *env)
17
*/
18
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->sse_status);
19
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->sse_status);
20
+ /* Default NaN: sign bit set, most significant frac bit set */
21
+ set_float_default_nan_pattern(0b11000000, &env->fp_status);
22
+ set_float_default_nan_pattern(0b11000000, &env->mmx_status);
23
+ set_float_default_nan_pattern(0b11000000, &env->sse_status);
24
}
25
26
static inline uint8_t save_exception_flags(CPUX86State *env)
27
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
28
index XXXXXXX..XXXXXXX 100644
29
--- a/fpu/softfloat-specialize.c.inc
30
+++ b/fpu/softfloat-specialize.c.inc
31
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
32
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
33
/* Sign bit clear, all frac bits set */
34
dnan_pattern = 0b01111111;
35
-#elif defined(TARGET_I386) || defined(TARGET_X86_64)
36
- /* Sign bit set, most significant frac bit set */
37
- dnan_pattern = 0b11000000;
38
#elif defined(TARGET_HPPA)
39
/* Sign bit clear, msb-1 frac bit set */
40
dnan_pattern = 0b00100000;
41
--
42
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly, and remove the ifdef from
2
parts64_default_nan().
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20241202131347.498124-39-peter.maydell@linaro.org
7
---
8
target/hppa/fpu_helper.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 3 ---
10
2 files changed, 2 insertions(+), 3 deletions(-)
11
12
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/hppa/fpu_helper.c
15
+++ b/target/hppa/fpu_helper.c
16
@@ -XXX,XX +XXX,XX @@ void HELPER(loaded_fr0)(CPUHPPAState *env)
17
set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status);
18
/* For inf * 0 + NaN, return the input NaN */
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
20
+ /* Default NaN: sign bit clear, msb-1 frac bit set */
21
+ set_float_default_nan_pattern(0b00100000, &env->fp_status);
22
}
23
24
void cpu_hppa_loaded_fr0(CPUHPPAState *env)
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
26
index XXXXXXX..XXXXXXX 100644
27
--- a/fpu/softfloat-specialize.c.inc
28
+++ b/fpu/softfloat-specialize.c.inc
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
30
#if defined(TARGET_SPARC) || defined(TARGET_M68K)
31
/* Sign bit clear, all frac bits set */
32
dnan_pattern = 0b01111111;
33
-#elif defined(TARGET_HPPA)
34
- /* Sign bit clear, msb-1 frac bit set */
35
- dnan_pattern = 0b00100000;
36
#elif defined(TARGET_HEXAGON)
37
/* Sign bit set, all frac bits set. */
38
dnan_pattern = 0b11111111;
39
--
40
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for the alpha target.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-40-peter.maydell@linaro.org
6
---
7
target/alpha/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/alpha/cpu.c
13
+++ b/target/alpha/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void alpha_cpu_initfn(Object *obj)
15
* operand in Fa. That is float_2nan_prop_ba.
16
*/
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
18
+ /* Default NaN: sign bit clear, msb frac bit set */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
#if defined(CONFIG_USER_ONLY)
21
env->flags = ENV_FLAG_PS_USER | ENV_FLAG_FEN;
22
cpu_alpha_store_fpcr(env, (uint64_t)(FPCR_INVD | FPCR_DZED | FPCR_OVFD
23
--
24
2.34.1
diff view generated by jsdifflib
1
The do_vfp_2op_sp() and do_vfp_2op_dp() functions currently check
1
Set the default NaN pattern explicitly for the arm target.
2
whether floating point is supported via the aa32_fpdp_v2 and
2
This includes setting it for the old linux-user nwfpe emulation.
3
aa32_fpsp_v2 isar checks. For v8.1M MVE support, the VMOV_reg trans
3
For nwfpe, our default doesn't match the real kernel, but we
4
functions (but not any of the others) need to update this to also
4
avoid making a behaviour change in this commit.
5
allow the insn if MVE is implemented. Move the check out of the do_
6
function and into its callsites (which are all implemented via the
7
DO_VFP_2OP macro), so we have a place to change the check for the
8
VMOV insns.
9
5
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210520152840.24453-4-peter.maydell@linaro.org
8
Message-id: 20241202131347.498124-41-peter.maydell@linaro.org
13
---
9
---
14
target/arm/translate-vfp.c | 37 +++++++++++++++++++------------------
10
linux-user/arm/nwfpe/fpa11.c | 5 +++++
15
1 file changed, 19 insertions(+), 18 deletions(-)
11
target/arm/cpu.c | 2 ++
12
2 files changed, 7 insertions(+)
16
13
17
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
14
diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate-vfp.c
16
--- a/linux-user/arm/nwfpe/fpa11.c
20
+++ b/target/arm/translate-vfp.c
17
+++ b/linux-user/arm/nwfpe/fpa11.c
21
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_sp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
18
@@ -XXX,XX +XXX,XX @@ void resetFPA11(void)
22
int veclen = s->vec_len;
19
* this late date.
23
TCGv_i32 f0, fd;
20
*/
24
21
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &fpa11->fp_status);
25
- if (!dc_isar_feature(aa32_fpsp_v2, s)) {
22
+ /*
26
- return false;
23
+ * Use the same default NaN value as Arm VFP. This doesn't match
27
- }
24
+ * the Linux kernel's nwfpe emulation, which uses an all-1s value.
28
+ /* Note that the caller must check the aa32_fpsp_v2 feature. */
25
+ */
29
26
+ set_float_default_nan_pattern(0b01000000, &fpa11->fp_status);
30
if (!dc_isar_feature(aa32_fpshvec, s) &&
31
(veclen != 0 || s->vec_stride != 0)) {
32
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_hp(DisasContext *s, VFPGen2OpSPFn *fn, int vd, int vm)
33
*/
34
TCGv_i32 f0;
35
36
+ /* Note that the caller must check the aa32_fp16_arith feature */
37
+
38
if (!dc_isar_feature(aa32_fp16_arith, s)) {
39
return false;
40
}
41
@@ -XXX,XX +XXX,XX @@ static bool do_vfp_2op_dp(DisasContext *s, VFPGen2OpDPFn *fn, int vd, int vm)
42
int veclen = s->vec_len;
43
TCGv_i64 f0, fd;
44
45
- if (!dc_isar_feature(aa32_fpdp_v2, s)) {
46
- return false;
47
- }
48
+ /* Note that the caller must check the aa32_fpdp_v2 feature. */
49
50
/* UNDEF accesses to D16-D31 if they don't exist */
51
if (!dc_isar_feature(aa32_simd_r32, s) && ((vd | vm) & 0x10)) {
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_imm_dp(DisasContext *s, arg_VMOV_imm_dp *a)
53
return true;
54
}
27
}
55
28
56
-#define DO_VFP_2OP(INSN, PREC, FN) \
29
void SetRoundingMode(const unsigned int opcode)
57
+#define DO_VFP_2OP(INSN, PREC, FN, CHECK) \
30
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
58
static bool trans_##INSN##_##PREC(DisasContext *s, \
31
index XXXXXXX..XXXXXXX 100644
59
arg_##INSN##_##PREC *a) \
32
--- a/target/arm/cpu.c
60
{ \
33
+++ b/target/arm/cpu.c
61
+ if (!dc_isar_feature(CHECK, s)) { \
34
@@ -XXX,XX +XXX,XX @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
62
+ return false; \
35
* the pseudocode function the arguments are in the order c, a, b.
63
+ } \
36
* * 0 * Inf + NaN returns the default NaN if the input NaN is quiet,
64
return do_vfp_2op_##PREC(s, FN, a->vd, a->vm); \
37
* and the input NaN if it is signalling
65
}
38
+ * * Default NaN has sign bit clear, msb frac bit set
66
39
*/
67
-DO_VFP_2OP(VMOV_reg, sp, tcg_gen_mov_i32)
40
static void arm_set_default_fp_behaviours(float_status *s)
68
-DO_VFP_2OP(VMOV_reg, dp, tcg_gen_mov_i64)
69
+DO_VFP_2OP(VMOV_reg, sp, tcg_gen_mov_i32, aa32_fpsp_v2)
70
+DO_VFP_2OP(VMOV_reg, dp, tcg_gen_mov_i64, aa32_fpdp_v2)
71
72
-DO_VFP_2OP(VABS, hp, gen_helper_vfp_absh)
73
-DO_VFP_2OP(VABS, sp, gen_helper_vfp_abss)
74
-DO_VFP_2OP(VABS, dp, gen_helper_vfp_absd)
75
+DO_VFP_2OP(VABS, hp, gen_helper_vfp_absh, aa32_fp16_arith)
76
+DO_VFP_2OP(VABS, sp, gen_helper_vfp_abss, aa32_fpsp_v2)
77
+DO_VFP_2OP(VABS, dp, gen_helper_vfp_absd, aa32_fpdp_v2)
78
79
-DO_VFP_2OP(VNEG, hp, gen_helper_vfp_negh)
80
-DO_VFP_2OP(VNEG, sp, gen_helper_vfp_negs)
81
-DO_VFP_2OP(VNEG, dp, gen_helper_vfp_negd)
82
+DO_VFP_2OP(VNEG, hp, gen_helper_vfp_negh, aa32_fp16_arith)
83
+DO_VFP_2OP(VNEG, sp, gen_helper_vfp_negs, aa32_fpsp_v2)
84
+DO_VFP_2OP(VNEG, dp, gen_helper_vfp_negd, aa32_fpdp_v2)
85
86
static void gen_VSQRT_hp(TCGv_i32 vd, TCGv_i32 vm)
87
{
41
{
88
@@ -XXX,XX +XXX,XX @@ static void gen_VSQRT_dp(TCGv_i64 vd, TCGv_i64 vm)
42
@@ -XXX,XX +XXX,XX @@ static void arm_set_default_fp_behaviours(float_status *s)
89
gen_helper_vfp_sqrtd(vd, vm, cpu_env);
43
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
44
set_float_3nan_prop_rule(float_3nan_prop_s_cab, s);
45
set_float_infzeronan_rule(float_infzeronan_dnan_if_qnan, s);
46
+ set_float_default_nan_pattern(0b01000000, s);
90
}
47
}
91
48
92
-DO_VFP_2OP(VSQRT, hp, gen_VSQRT_hp)
49
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
93
-DO_VFP_2OP(VSQRT, sp, gen_VSQRT_sp)
94
-DO_VFP_2OP(VSQRT, dp, gen_VSQRT_dp)
95
+DO_VFP_2OP(VSQRT, hp, gen_VSQRT_hp, aa32_fp16_arith)
96
+DO_VFP_2OP(VSQRT, sp, gen_VSQRT_sp, aa32_fpsp_v2)
97
+DO_VFP_2OP(VSQRT, dp, gen_VSQRT_dp, aa32_fpdp_v2)
98
99
static bool trans_VCMP_hp(DisasContext *s, arg_VCMP_sp *a)
100
{
101
--
50
--
102
2.20.1
51
2.34.1
103
104
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for loongarch.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-42-peter.maydell@linaro.org
6
---
7
target/loongarch/tcg/fpu_helper.c | 2 ++
8
1 file changed, 2 insertions(+)
9
10
diff --git a/target/loongarch/tcg/fpu_helper.c b/target/loongarch/tcg/fpu_helper.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/loongarch/tcg/fpu_helper.c
13
+++ b/target/loongarch/tcg/fpu_helper.c
14
@@ -XXX,XX +XXX,XX @@ void restore_fp_status(CPULoongArchState *env)
15
*/
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
17
set_float_3nan_prop_rule(float_3nan_prop_s_cab, &env->fp_status);
18
+ /* Default NaN: sign bit clear, msb frac bit set */
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
20
}
21
22
int ieee_ex_to_loongarch(int xcpt)
23
--
24
2.34.1
diff view generated by jsdifflib
New patch
1
Set the default NaN pattern explicitly for m68k.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-43-peter.maydell@linaro.org
6
---
7
target/m68k/cpu.c | 2 ++
8
fpu/softfloat-specialize.c.inc | 2 +-
9
2 files changed, 3 insertions(+), 1 deletion(-)
10
11
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/m68k/cpu.c
14
+++ b/target/m68k/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
16
* preceding paragraph for nonsignaling NaNs.
17
*/
18
set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
19
+ /* Default NaN: sign bit clear, all frac bits set */
20
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
21
22
nan = floatx80_default_nan(&env->fp_status);
23
for (i = 0; i < 8; i++) {
24
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat-specialize.c.inc
27
+++ b/fpu/softfloat-specialize.c.inc
28
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
29
uint8_t dnan_pattern = status->default_nan_pattern;
30
31
if (dnan_pattern == 0) {
32
-#if defined(TARGET_SPARC) || defined(TARGET_M68K)
33
+#if defined(TARGET_SPARC)
34
/* Sign bit clear, all frac bits set */
35
dnan_pattern = 0b01111111;
36
#elif defined(TARGET_HEXAGON)
37
--
38
2.34.1
diff view generated by jsdifflib
1
Coverity points out that in tpm_test_swtpm_migration_test() we
1
Set the default NaN pattern explicitly for MIPS. Note that this
2
assume that src_tpm_addr and dst_tpm_addr are non-NULL (we
2
is our only target which currently changes the default NaN
3
pass them to tpm_util_migration_start_qemu() which will
3
at runtime (which it was previously doing indirectly when it
4
unconditionally dereference them) but then later explicitly
4
changed the snan_bit_is_one setting).
5
check them for NULL. Remove the pointless checks.
6
7
Fixes: Coverity CID 1432367, 1432359
8
5
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
8
Message-id: 20241202131347.498124-44-peter.maydell@linaro.org
12
Message-id: 20210525134458.6675-6-peter.maydell@linaro.org
13
---
9
---
14
tests/qtest/tpm-tests.c | 12 ++++--------
10
target/mips/fpu_helper.h | 7 +++++++
15
1 file changed, 4 insertions(+), 8 deletions(-)
11
target/mips/msa.c | 3 +++
12
2 files changed, 10 insertions(+)
16
13
17
diff --git a/tests/qtest/tpm-tests.c b/tests/qtest/tpm-tests.c
14
diff --git a/target/mips/fpu_helper.h b/target/mips/fpu_helper.h
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qtest/tpm-tests.c
16
--- a/target/mips/fpu_helper.h
20
+++ b/tests/qtest/tpm-tests.c
17
+++ b/target/mips/fpu_helper.h
21
@@ -XXX,XX +XXX,XX @@ void tpm_test_swtpm_migration_test(const char *src_tpm_path,
18
@@ -XXX,XX +XXX,XX @@ static inline void restore_snan_bit_mode(CPUMIPSState *env)
22
qtest_quit(src_qemu);
19
set_float_infzeronan_rule(izn_rule, &env->active_fpu.fp_status);
23
20
nan3_rule = nan2008 ? float_3nan_prop_s_cab : float_3nan_prop_s_abc;
24
tpm_util_swtpm_kill(dst_tpm_pid);
21
set_float_3nan_prop_rule(nan3_rule, &env->active_fpu.fp_status);
25
- if (dst_tpm_addr) {
22
+ /*
26
- g_unlink(dst_tpm_addr->u.q_unix.path);
23
+ * With nan2008, the default NaN value has the sign bit clear and the
27
- qapi_free_SocketAddress(dst_tpm_addr);
24
+ * frac msb set; with the older mode, the sign bit is clear, and all
28
- }
25
+ * frac bits except the msb are set.
29
+ g_unlink(dst_tpm_addr->u.q_unix.path);
26
+ */
30
+ qapi_free_SocketAddress(dst_tpm_addr);
27
+ set_float_default_nan_pattern(nan2008 ? 0b01000000 : 0b00111111,
31
28
+ &env->active_fpu.fp_status);
32
tpm_util_swtpm_kill(src_tpm_pid);
29
33
- if (src_tpm_addr) {
30
}
34
- g_unlink(src_tpm_addr->u.q_unix.path);
31
35
- qapi_free_SocketAddress(src_tpm_addr);
32
diff --git a/target/mips/msa.c b/target/mips/msa.c
36
- }
33
index XXXXXXX..XXXXXXX 100644
37
+ g_unlink(src_tpm_addr->u.q_unix.path);
34
--- a/target/mips/msa.c
38
+ qapi_free_SocketAddress(src_tpm_addr);
35
+++ b/target/mips/msa.c
36
@@ -XXX,XX +XXX,XX @@ void msa_reset(CPUMIPSState *env)
37
/* Inf * 0 + NaN returns the input NaN */
38
set_float_infzeronan_rule(float_infzeronan_dnan_never,
39
&env->active_tc.msa_fp_status);
40
+ /* Default NaN: sign bit clear, frac msb set */
41
+ set_float_default_nan_pattern(0b01000000,
42
+ &env->active_tc.msa_fp_status);
39
}
43
}
40
--
44
--
41
2.20.1
45
2.34.1
42
43
diff view generated by jsdifflib
1
The e1000e_send_verify() test calls qemu_recv() but doesn't
1
Set the default NaN pattern explicitly for openrisc.
2
check that the call succeeded, which annoys Coverity. Add
3
an explicit test check for the length of the data.
4
2
5
(This is a test check, not a "we assume this syscall always
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
succeeds", so we use g_assert_cmpint() rather than g_assert().)
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-45-peter.maydell@linaro.org
6
---
7
target/openrisc/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
7
9
8
Fixes: Coverity CID 1432324
10
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
11
Message-id: 20210525134458.6675-3-peter.maydell@linaro.org
12
---
13
tests/qtest/e1000e-test.c | 3 ++-
14
1 file changed, 2 insertions(+), 1 deletion(-)
15
16
diff --git a/tests/qtest/e1000e-test.c b/tests/qtest/e1000e-test.c
17
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
18
--- a/tests/qtest/e1000e-test.c
12
--- a/target/openrisc/cpu.c
19
+++ b/tests/qtest/e1000e-test.c
13
+++ b/target/openrisc/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *a
14
@@ -XXX,XX +XXX,XX @@ static void openrisc_cpu_reset_hold(Object *obj, ResetType type)
21
/* Check data sent to the backend */
15
*/
22
ret = qemu_recv(test_sockets[0], &recv_len, sizeof(recv_len), 0);
16
set_float_2nan_prop_rule(float_2nan_prop_x87, &cpu->env.fp_status);
23
g_assert_cmpint(ret, == , sizeof(recv_len));
17
24
- qemu_recv(test_sockets[0], buffer, 64, 0);
18
+ /* Default NaN: sign bit clear, frac msb set */
25
+ ret = qemu_recv(test_sockets[0], buffer, 64, 0);
19
+ set_float_default_nan_pattern(0b01000000, &cpu->env.fp_status);
26
+ g_assert_cmpint(ret, >=, 5);
20
27
g_assert_cmpstr(buffer, == , "TEST");
21
#ifndef CONFIG_USER_ONLY
28
22
cpu->env.picmr = 0x00000000;
29
/* Free test data buffer */
30
--
23
--
31
2.20.1
24
2.34.1
32
33
diff view generated by jsdifflib
1
Coverity complains that we don't check for failures from dup()
1
Set the default NaN pattern explicitly for ppc.
2
and mkstemp(); add asserts that these syscalls succeeded.
3
2
4
Fixes: Coverity CID 1432516, 1432574
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20241202131347.498124-46-peter.maydell@linaro.org
8
Message-id: 20210525134458.6675-7-peter.maydell@linaro.org
9
---
6
---
10
tests/unit/test-vmstate.c | 5 ++++-
7
target/ppc/cpu_init.c | 4 ++++
11
1 file changed, 4 insertions(+), 1 deletion(-)
8
1 file changed, 4 insertions(+)
12
9
13
diff --git a/tests/unit/test-vmstate.c b/tests/unit/test-vmstate.c
10
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/unit/test-vmstate.c
12
--- a/target/ppc/cpu_init.c
16
+++ b/tests/unit/test-vmstate.c
13
+++ b/target/ppc/cpu_init.c
17
@@ -XXX,XX +XXX,XX @@ static int temp_fd;
14
@@ -XXX,XX +XXX,XX @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
18
/* Duplicate temp_fd and seek to the beginning of the file */
15
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
19
static QEMUFile *open_test_file(bool write)
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->vec_status);
20
{
17
21
- int fd = dup(temp_fd);
18
+ /* Default NaN: sign bit clear, set frac msb */
22
+ int fd;
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
23
QIOChannel *ioc;
20
+ set_float_default_nan_pattern(0b01000000, &env->vec_status);
24
QEMUFile *f;
21
+
25
22
for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
26
+ fd = dup(temp_fd);
23
ppc_spr_t *spr = &env->spr_cb[i];
27
+ g_assert(fd >= 0);
28
lseek(fd, 0, SEEK_SET);
29
if (write) {
30
g_assert_cmpint(ftruncate(fd, 0), ==, 0);
31
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
32
g_autofree char *temp_file = g_strdup_printf("%s/vmst.test.XXXXXX",
33
g_get_tmp_dir());
34
temp_fd = mkstemp(temp_file);
35
+ g_assert(temp_fd >= 0);
36
37
module_call_init(MODULE_INIT_QOM);
38
24
39
--
25
--
40
2.20.1
26
2.34.1
41
42
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
Set the default NaN pattern explicitly for sh4. Note that sh4
2
is one of the only three targets (the others being HPPA and
3
sometimes MIPS) that has snan_bit_is_one set.
2
4
3
The hvf accel synchronize functions are only used as input for local
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
callback functions, so we can make them static.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20241202131347.498124-47-peter.maydell@linaro.org
8
---
9
target/sh4/cpu.c | 2 ++
10
1 file changed, 2 insertions(+)
5
11
6
Signed-off-by: Alexander Graf <agraf@csgraf.de>
12
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
7
Reviewed-by: Sergio Lopez <slp@redhat.com>
8
Message-id: 20210519202253.76782-10-agraf@csgraf.de
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
accel/hvf/hvf-accel-ops.h | 3 ---
13
accel/hvf/hvf-accel-ops.c | 6 +++---
14
2 files changed, 3 insertions(+), 6 deletions(-)
15
16
diff --git a/accel/hvf/hvf-accel-ops.h b/accel/hvf/hvf-accel-ops.h
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/accel/hvf/hvf-accel-ops.h
14
--- a/target/sh4/cpu.c
19
+++ b/accel/hvf/hvf-accel-ops.h
15
+++ b/target/sh4/cpu.c
20
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static void superh_cpu_reset_hold(Object *obj, ResetType type)
21
#include "sysemu/cpus.h"
17
set_flush_to_zero(1, &env->fp_status);
22
18
#endif
23
int hvf_vcpu_exec(CPUState *);
19
set_default_nan_mode(1, &env->fp_status);
24
-void hvf_cpu_synchronize_post_reset(CPUState *);
20
+ /* sign bit clear, set all frac bits other than msb */
25
-void hvf_cpu_synchronize_post_init(CPUState *);
21
+ set_float_default_nan_pattern(0b00111111, &env->fp_status);
26
-void hvf_cpu_synchronize_pre_loadvm(CPUState *);
27
28
#endif /* HVF_CPUS_H */
29
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/accel/hvf/hvf-accel-ops.c
32
+++ b/accel/hvf/hvf-accel-ops.c
33
@@ -XXX,XX +XXX,XX @@ static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu,
34
cpu->vcpu_dirty = false;
35
}
22
}
36
23
37
-void hvf_cpu_synchronize_post_reset(CPUState *cpu)
24
static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
38
+static void hvf_cpu_synchronize_post_reset(CPUState *cpu)
39
{
40
run_on_cpu(cpu, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
41
}
42
@@ -XXX,XX +XXX,XX @@ static void do_hvf_cpu_synchronize_post_init(CPUState *cpu,
43
cpu->vcpu_dirty = false;
44
}
45
46
-void hvf_cpu_synchronize_post_init(CPUState *cpu)
47
+static void hvf_cpu_synchronize_post_init(CPUState *cpu)
48
{
49
run_on_cpu(cpu, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
50
}
51
@@ -XXX,XX +XXX,XX @@ static void do_hvf_cpu_synchronize_pre_loadvm(CPUState *cpu,
52
cpu->vcpu_dirty = true;
53
}
54
55
-void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)
56
+static void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)
57
{
58
run_on_cpu(cpu, do_hvf_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);
59
}
60
--
25
--
61
2.20.1
26
2.34.1
62
63
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
Set the default NaN pattern explicitly for rx.
2
2
3
The hvf_set_phys_mem() function is only called within the same file.
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Make it static.
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-48-peter.maydell@linaro.org
6
---
7
target/rx/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
5
9
6
Signed-off-by: Alexander Graf <agraf@csgraf.de>
10
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
7
Reviewed-by: Sergio Lopez <slp@redhat.com>
8
Message-id: 20210519202253.76782-6-agraf@csgraf.de
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/sysemu/hvf_int.h | 1 -
13
accel/hvf/hvf-accel-ops.c | 2 +-
14
2 files changed, 1 insertion(+), 2 deletions(-)
15
16
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
17
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
18
--- a/include/sysemu/hvf_int.h
12
--- a/target/rx/cpu.c
19
+++ b/include/sysemu/hvf_int.h
13
+++ b/target/rx/cpu.c
20
@@ -XXX,XX +XXX,XX @@ struct HVFState {
14
@@ -XXX,XX +XXX,XX @@ static void rx_cpu_reset_hold(Object *obj, ResetType type)
21
};
15
* then prefer dest over source", which is float_2nan_prop_s_ab.
22
extern HVFState *hvf_state;
16
*/
23
17
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
24
-void hvf_set_phys_mem(MemoryRegionSection *, bool);
18
+ /* Default NaN value: sign bit clear, set frac msb */
25
void assert_hvf_ok(hv_return_t ret);
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
26
hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
27
int hvf_put_registers(CPUState *);
28
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/accel/hvf/hvf-accel-ops.c
31
+++ b/accel/hvf/hvf-accel-ops.c
32
@@ -XXX,XX +XXX,XX @@ static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
33
return 0;
34
}
20
}
35
21
36
-void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
22
static ObjectClass *rx_cpu_class_by_name(const char *cpu_model)
37
+static void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
38
{
39
hvf_slot *mem;
40
MemoryRegion *area = section->mr;
41
--
23
--
42
2.20.1
24
2.34.1
43
44
diff view generated by jsdifflib
1
Coverity notes that we don't check for dup2() failing. Add some
1
Set the default NaN pattern explicitly for s390x.
2
assertions so that if it does ever happen we get some indication.
3
(This is similar to how we handle other "don't expect this syscall to
4
fail" checks in this test code.)
5
2
6
Fixes: Coverity CID 1432346
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210525134458.6675-2-peter.maydell@linaro.org
5
Message-id: 20241202131347.498124-49-peter.maydell@linaro.org
10
---
6
---
11
tests/qtest/bios-tables-test.c | 8 ++++++--
7
target/s390x/cpu.c | 2 ++
12
1 file changed, 6 insertions(+), 2 deletions(-)
8
1 file changed, 2 insertions(+)
13
9
14
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
10
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
15
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/qtest/bios-tables-test.c
12
--- a/target/s390x/cpu.c
17
+++ b/tests/qtest/bios-tables-test.c
13
+++ b/target/s390x/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void test_acpi_asl(test_data *data)
14
@@ -XXX,XX +XXX,XX @@ static void s390_cpu_reset_hold(Object *obj, ResetType type)
19
exp_sdt->asl_file, sdt->asl_file);
15
set_float_3nan_prop_rule(float_3nan_prop_s_abc, &env->fpu_status);
20
int out = dup(STDOUT_FILENO);
16
set_float_infzeronan_rule(float_infzeronan_dnan_always,
21
int ret G_GNUC_UNUSED;
17
&env->fpu_status);
22
+ int dupret;
18
+ /* Default NaN value: sign bit clear, frac msb set */
23
19
+ set_float_default_nan_pattern(0b01000000, &env->fpu_status);
24
- dup2(STDERR_FILENO, STDOUT_FILENO);
20
/* fall through */
25
+ g_assert(out >= 0);
21
case RESET_TYPE_S390_CPU_NORMAL:
26
+ dupret = dup2(STDERR_FILENO, STDOUT_FILENO);
22
env->psw.mask &= ~PSW_MASK_RI;
27
+ g_assert(dupret >= 0);
28
ret = system(diff) ;
29
- dup2(out, STDOUT_FILENO);
30
+ dupret = dup2(out, STDOUT_FILENO);
31
+ g_assert(dupret >= 0);
32
close(out);
33
g_free(diff);
34
}
35
--
23
--
36
2.20.1
24
2.34.1
37
38
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
Set the default NaN pattern explicitly for SPARC, and remove
2
the ifdef from parts64_default_nan.
2
3
3
Until now, Hypervisor.framework has only been available on x86_64 systems.
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
With Apple Silicon shipping now, it extends its reach to aarch64. To
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
prepare for support for multiple architectures, let's start moving common
6
Message-id: 20241202131347.498124-50-peter.maydell@linaro.org
6
code out into its own accel directory.
7
---
8
target/sparc/cpu.c | 2 ++
9
fpu/softfloat-specialize.c.inc | 5 +----
10
2 files changed, 3 insertions(+), 4 deletions(-)
7
11
8
This patch moves the vCPU thread loop over.
12
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
9
10
Signed-off-by: Alexander Graf <agraf@csgraf.de>
11
Reviewed-by: Sergio Lopez <slp@redhat.com>
12
Message-id: 20210519202253.76782-3-agraf@csgraf.de
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
{target/i386 => accel}/hvf/hvf-accel-ops.h | 0
17
{target/i386 => accel}/hvf/hvf-accel-ops.c | 0
18
target/i386/hvf/x86hvf.c | 2 +-
19
accel/hvf/meson.build | 1 +
20
target/i386/hvf/meson.build | 1 -
21
5 files changed, 2 insertions(+), 2 deletions(-)
22
rename {target/i386 => accel}/hvf/hvf-accel-ops.h (100%)
23
rename {target/i386 => accel}/hvf/hvf-accel-ops.c (100%)
24
25
diff --git a/target/i386/hvf/hvf-accel-ops.h b/accel/hvf/hvf-accel-ops.h
26
similarity index 100%
27
rename from target/i386/hvf/hvf-accel-ops.h
28
rename to accel/hvf/hvf-accel-ops.h
29
diff --git a/target/i386/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
30
similarity index 100%
31
rename from target/i386/hvf/hvf-accel-ops.c
32
rename to accel/hvf/hvf-accel-ops.c
33
diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c
34
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
35
--- a/target/i386/hvf/x86hvf.c
14
--- a/target/sparc/cpu.c
36
+++ b/target/i386/hvf/x86hvf.c
15
+++ b/target/sparc/cpu.c
37
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
38
#include <Hypervisor/hv.h>
17
set_float_3nan_prop_rule(float_3nan_prop_s_cba, &env->fp_status);
39
#include <Hypervisor/hv_vmx.h>
18
/* For inf * 0 + NaN, return the input NaN */
40
19
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
41
-#include "hvf-accel-ops.h"
20
+ /* Default NaN value: sign bit clear, all frac bits set */
42
+#include "accel/hvf/hvf-accel-ops.h"
21
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
43
22
44
void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg,
23
cpu_exec_realizefn(cs, &local_err);
45
SegmentCache *qseg, bool is_tr)
24
if (local_err != NULL) {
46
diff --git a/accel/hvf/meson.build b/accel/hvf/meson.build
25
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
47
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
48
--- a/accel/hvf/meson.build
27
--- a/fpu/softfloat-specialize.c.inc
49
+++ b/accel/hvf/meson.build
28
+++ b/fpu/softfloat-specialize.c.inc
50
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
51
hvf_ss = ss.source_set()
30
uint8_t dnan_pattern = status->default_nan_pattern;
52
hvf_ss.add(files(
31
53
'hvf-all.c',
32
if (dnan_pattern == 0) {
54
+ 'hvf-accel-ops.c',
33
-#if defined(TARGET_SPARC)
55
))
34
- /* Sign bit clear, all frac bits set */
56
35
- dnan_pattern = 0b01111111;
57
specific_ss.add_all(when: 'CONFIG_HVF', if_true: hvf_ss)
36
-#elif defined(TARGET_HEXAGON)
58
diff --git a/target/i386/hvf/meson.build b/target/i386/hvf/meson.build
37
+#if defined(TARGET_HEXAGON)
59
index XXXXXXX..XXXXXXX 100644
38
/* Sign bit set, all frac bits set. */
60
--- a/target/i386/hvf/meson.build
39
dnan_pattern = 0b11111111;
61
+++ b/target/i386/hvf/meson.build
40
#else
62
@@ -XXX,XX +XXX,XX @@
63
i386_softmmu_ss.add(when: [hvf, 'CONFIG_HVF'], if_true: files(
64
'hvf.c',
65
- 'hvf-accel-ops.c',
66
'x86.c',
67
'x86_cpuid.c',
68
'x86_decode.c',
69
--
41
--
70
2.20.1
42
2.34.1
71
72
diff view generated by jsdifflib
1
From: Jamie Iles <jamie@nuviainc.com>
1
Set the default NaN pattern explicitly for xtensa.
2
2
3
Now that there are no other users of do_raise_exception, fold it into
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
raise_exception.
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20241202131347.498124-51-peter.maydell@linaro.org
6
---
7
target/xtensa/cpu.c | 2 ++
8
1 file changed, 2 insertions(+)
5
9
6
Cc: Richard Henderson <richard.henderson@linaro.org>
10
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
7
Cc: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Jamie Iles <jamie@nuviainc.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/op_helper.c | 12 ++----------
13
1 file changed, 2 insertions(+), 10 deletions(-)
14
15
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/op_helper.c
12
--- a/target/xtensa/cpu.c
18
+++ b/target/arm/op_helper.c
13
+++ b/target/xtensa/cpu.c
19
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@ static void xtensa_cpu_reset_hold(Object *obj, ResetType type)
20
#define SIGNBIT (uint32_t)0x80000000
15
/* For inf * 0 + NaN, return the input NaN */
21
#define SIGNBIT64 ((uint64_t)1 << 63)
16
set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status);
22
17
set_no_signaling_nans(!dfpu, &env->fp_status);
23
-static CPUState *do_raise_exception(CPUARMState *env, uint32_t excp,
18
+ /* Default NaN value: sign bit clear, set frac msb */
24
- uint32_t syndrome, uint32_t target_el)
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
25
+void raise_exception(CPUARMState *env, uint32_t excp,
20
xtensa_use_first_nan(env, !dfpu);
26
+ uint32_t syndrome, uint32_t target_el)
27
{
28
CPUState *cs = env_cpu(env);
29
30
@@ -XXX,XX +XXX,XX @@ static CPUState *do_raise_exception(CPUARMState *env, uint32_t excp,
31
cs->exception_index = excp;
32
env->exception.syndrome = syndrome;
33
env->exception.target_el = target_el;
34
-
35
- return cs;
36
-}
37
-
38
-void raise_exception(CPUARMState *env, uint32_t excp,
39
- uint32_t syndrome, uint32_t target_el)
40
-{
41
- CPUState *cs = do_raise_exception(env, excp, syndrome, target_el);
42
cpu_loop_exit(cs);
43
}
21
}
44
22
45
--
23
--
46
2.20.1
24
2.34.1
47
48
diff view generated by jsdifflib
1
From: Damien Goutte-Gattat <dgouttegattat@incenp.org>
1
Set the default NaN pattern explicitly for hexagon.
2
Remove the ifdef from parts64_default_nan(); the only
3
remaining unconverted targets all use the default case.
2
4
3
The 4.x branch of Sphinx introduces a breaking change, as generated man
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
pages are now written to subdirectories corresponding to the manual
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
section they belong to. This results in `make install` erroring out when
7
Message-id: 20241202131347.498124-52-peter.maydell@linaro.org
6
attempting to install the man pages, because they are not where it
8
---
7
expects to find them.
9
target/hexagon/cpu.c | 2 ++
10
fpu/softfloat-specialize.c.inc | 5 -----
11
2 files changed, 2 insertions(+), 5 deletions(-)
8
12
9
This patch restores the behavior of Sphinx 3.x regarding man pages.
13
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
10
11
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/256
12
Signed-off-by: Damien Goutte-Gattat <dgouttegattat@incenp.org>
13
Message-id: 20210503161422.15028-1-dgouttegattat@incenp.org
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
docs/conf.py | 1 +
18
1 file changed, 1 insertion(+)
19
20
diff --git a/docs/conf.py b/docs/conf.py
21
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
22
--- a/docs/conf.py
15
--- a/target/hexagon/cpu.c
23
+++ b/docs/conf.py
16
+++ b/target/hexagon/cpu.c
24
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
25
['Stefan Hajnoczi <stefanha@redhat.com>',
18
26
'Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>'], 1),
19
set_default_nan_mode(1, &env->fp_status);
27
]
20
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
28
+man_make_section_directory = False
21
+ /* Default NaN value: sign bit set, all frac bits set */
29
22
+ set_float_default_nan_pattern(0b11111111, &env->fp_status);
30
# -- Options for Texinfo output -------------------------------------------
23
}
24
25
static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info)
26
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
27
index XXXXXXX..XXXXXXX 100644
28
--- a/fpu/softfloat-specialize.c.inc
29
+++ b/fpu/softfloat-specialize.c.inc
30
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
31
uint8_t dnan_pattern = status->default_nan_pattern;
32
33
if (dnan_pattern == 0) {
34
-#if defined(TARGET_HEXAGON)
35
- /* Sign bit set, all frac bits set. */
36
- dnan_pattern = 0b11111111;
37
-#else
38
/*
39
* This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
40
* S390, SH4, TriCore, and Xtensa. Our other supported targets
41
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
42
/* sign bit clear, set frac msb */
43
dnan_pattern = 0b01000000;
44
}
45
-#endif
46
}
47
assert(dnan_pattern != 0);
31
48
32
--
49
--
33
2.20.1
50
2.34.1
34
35
diff view generated by jsdifflib
1
The official punctuation for Arm CPU names uses a hyphen, like
1
Set the default NaN pattern explicitly for riscv.
2
"Cortex-A9". We mostly follow this, but in a few places usage
3
without the hyphen has crept in. Fix those so we consistently
4
use the same way of writing the CPU name.
5
6
This commit was created with:
7
git grep -z -l 'Cortex ' | xargs -0 sed -i 's/Cortex /Cortex-/'
8
2
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Message-id: 20241202131347.498124-53-peter.maydell@linaro.org
13
Message-id: 20210527095152.10968-1-peter.maydell@linaro.org
14
---
6
---
15
docs/system/arm/aspeed.rst | 4 ++--
7
target/riscv/cpu.c | 2 ++
16
docs/system/arm/nuvoton.rst | 6 +++---
8
1 file changed, 2 insertions(+)
17
docs/system/arm/sabrelite.rst | 2 +-
18
include/hw/arm/allwinner-h3.h | 2 +-
19
hw/arm/aspeed.c | 6 +++---
20
hw/arm/mcimx6ul-evk.c | 2 +-
21
hw/arm/mcimx7d-sabre.c | 2 +-
22
hw/arm/npcm7xx_boards.c | 4 ++--
23
hw/arm/sabrelite.c | 2 +-
24
hw/misc/npcm7xx_clk.c | 2 +-
25
10 files changed, 16 insertions(+), 16 deletions(-)
26
9
27
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
10
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
28
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
29
--- a/docs/system/arm/aspeed.rst
12
--- a/target/riscv/cpu.c
30
+++ b/docs/system/arm/aspeed.rst
13
+++ b/target/riscv/cpu.c
31
@@ -XXX,XX +XXX,XX @@ The QEMU Aspeed machines model BMCs of various OpenPOWER systems and
14
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
32
Aspeed evaluation boards. They are based on different releases of the
15
cs->exception_index = RISCV_EXCP_NONE;
33
Aspeed SoC : the AST2400 integrating an ARM926EJ-S CPU (400MHz), the
16
env->load_res = -1;
34
AST2500 with an ARM1176JZS CPU (800MHz) and more recently the AST2600
17
set_default_nan_mode(1, &env->fp_status);
35
-with dual cores ARM Cortex A7 CPUs (1.2GHz).
18
+ /* Default NaN value: sign bit clear, frac msb set */
36
+with dual cores ARM Cortex-A7 CPUs (1.2GHz).
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
37
20
env->vill = true;
38
The SoC comes with RAM, Gigabit ethernet, USB, SD/MMC, USB, SPI, I2C,
21
39
etc.
22
#ifndef CONFIG_USER_ONLY
40
@@ -XXX,XX +XXX,XX @@ AST2500 SoC based machines :
41
42
AST2600 SoC based machines :
43
44
-- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex A7)
45
+- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex-A7)
46
- ``tacoma-bmc`` OpenPOWER Witherspoon POWER9 AST2600 BMC
47
48
Supported devices
49
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
50
index XXXXXXX..XXXXXXX 100644
51
--- a/docs/system/arm/nuvoton.rst
52
+++ b/docs/system/arm/nuvoton.rst
53
@@ -XXX,XX +XXX,XX @@ Nuvoton iBMC boards (``npcm750-evb``, ``quanta-gsj``)
54
55
The `Nuvoton iBMC`_ chips (NPCM7xx) are a family of ARM-based SoCs that are
56
designed to be used as Baseboard Management Controllers (BMCs) in various
57
-servers. They all feature one or two ARM Cortex A9 CPU cores, as well as an
58
+servers. They all feature one or two ARM Cortex-A9 CPU cores, as well as an
59
assortment of peripherals targeted for either Enterprise or Data Center /
60
Hyperscale applications. The former is a superset of the latter, so NPCM750 has
61
all the peripherals of NPCM730 and more.
62
63
.. _Nuvoton iBMC: https://www.nuvoton.com/products/cloud-computing/ibmc/
64
65
-The NPCM750 SoC has two Cortex A9 cores and is targeted for the Enterprise
66
+The NPCM750 SoC has two Cortex-A9 cores and is targeted for the Enterprise
67
segment. The following machines are based on this chip :
68
69
- ``npcm750-evb`` Nuvoton NPCM750 Evaluation board
70
71
-The NPCM730 SoC has two Cortex A9 cores and is targeted for Data Center and
72
+The NPCM730 SoC has two Cortex-A9 cores and is targeted for Data Center and
73
Hyperscale applications. The following machines are based on this chip :
74
75
- ``quanta-gsj`` Quanta GSJ server BMC
76
diff --git a/docs/system/arm/sabrelite.rst b/docs/system/arm/sabrelite.rst
77
index XXXXXXX..XXXXXXX 100644
78
--- a/docs/system/arm/sabrelite.rst
79
+++ b/docs/system/arm/sabrelite.rst
80
@@ -XXX,XX +XXX,XX @@ Supported devices
81
82
The SABRE Lite machine supports the following devices:
83
84
- * Up to 4 Cortex A9 cores
85
+ * Up to 4 Cortex-A9 cores
86
* Generic Interrupt Controller
87
* 1 Clock Controller Module
88
* 1 System Reset Controller
89
diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
90
index XXXXXXX..XXXXXXX 100644
91
--- a/include/hw/arm/allwinner-h3.h
92
+++ b/include/hw/arm/allwinner-h3.h
93
@@ -XXX,XX +XXX,XX @@
94
*/
95
96
/*
97
- * The Allwinner H3 is a System on Chip containing four ARM Cortex A7
98
+ * The Allwinner H3 is a System on Chip containing four ARM Cortex-A7
99
* processor cores. Features and specifications include DDR2/DDR3 memory,
100
* SD/MMC storage cards, 10/100/1000Mbit Ethernet, USB 2.0, HDMI and
101
* various I/O modules.
102
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/hw/arm/aspeed.c
105
+++ b/hw/arm/aspeed.c
106
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
107
MachineClass *mc = MACHINE_CLASS(oc);
108
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
109
110
- mc->desc = "Aspeed AST2600 EVB (Cortex A7)";
111
+ mc->desc = "Aspeed AST2600 EVB (Cortex-A7)";
112
amc->soc_name = "ast2600-a1";
113
amc->hw_strap1 = AST2600_EVB_HW_STRAP1;
114
amc->hw_strap2 = AST2600_EVB_HW_STRAP2;
115
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_tacoma_class_init(ObjectClass *oc, void *data)
116
MachineClass *mc = MACHINE_CLASS(oc);
117
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
118
119
- mc->desc = "OpenPOWER Tacoma BMC (Cortex A7)";
120
+ mc->desc = "OpenPOWER Tacoma BMC (Cortex-A7)";
121
amc->soc_name = "ast2600-a1";
122
amc->hw_strap1 = TACOMA_BMC_HW_STRAP1;
123
amc->hw_strap2 = TACOMA_BMC_HW_STRAP2;
124
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_rainier_class_init(ObjectClass *oc, void *data)
125
MachineClass *mc = MACHINE_CLASS(oc);
126
AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
127
128
- mc->desc = "IBM Rainier BMC (Cortex A7)";
129
+ mc->desc = "IBM Rainier BMC (Cortex-A7)";
130
amc->soc_name = "ast2600-a1";
131
amc->hw_strap1 = RAINIER_BMC_HW_STRAP1;
132
amc->hw_strap2 = RAINIER_BMC_HW_STRAP2;
133
diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/arm/mcimx6ul-evk.c
136
+++ b/hw/arm/mcimx6ul-evk.c
137
@@ -XXX,XX +XXX,XX @@ static void mcimx6ul_evk_init(MachineState *machine)
138
139
static void mcimx6ul_evk_machine_init(MachineClass *mc)
140
{
141
- mc->desc = "Freescale i.MX6UL Evaluation Kit (Cortex A7)";
142
+ mc->desc = "Freescale i.MX6UL Evaluation Kit (Cortex-A7)";
143
mc->init = mcimx6ul_evk_init;
144
mc->max_cpus = FSL_IMX6UL_NUM_CPUS;
145
mc->default_ram_id = "mcimx6ul-evk.ram";
146
diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/hw/arm/mcimx7d-sabre.c
149
+++ b/hw/arm/mcimx7d-sabre.c
150
@@ -XXX,XX +XXX,XX @@ static void mcimx7d_sabre_init(MachineState *machine)
151
152
static void mcimx7d_sabre_machine_init(MachineClass *mc)
153
{
154
- mc->desc = "Freescale i.MX7 DUAL SABRE (Cortex A7)";
155
+ mc->desc = "Freescale i.MX7 DUAL SABRE (Cortex-A7)";
156
mc->init = mcimx7d_sabre_init;
157
mc->max_cpus = FSL_IMX7_NUM_CPUS;
158
mc->default_ram_id = "mcimx7d-sabre.ram";
159
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/hw/arm/npcm7xx_boards.c
162
+++ b/hw/arm/npcm7xx_boards.c
163
@@ -XXX,XX +XXX,XX @@ static void npcm750_evb_machine_class_init(ObjectClass *oc, void *data)
164
165
npcm7xx_set_soc_type(nmc, TYPE_NPCM750);
166
167
- mc->desc = "Nuvoton NPCM750 Evaluation Board (Cortex A9)";
168
+ mc->desc = "Nuvoton NPCM750 Evaluation Board (Cortex-A9)";
169
mc->init = npcm750_evb_init;
170
mc->default_ram_size = 512 * MiB;
171
};
172
@@ -XXX,XX +XXX,XX @@ static void gsj_machine_class_init(ObjectClass *oc, void *data)
173
174
npcm7xx_set_soc_type(nmc, TYPE_NPCM730);
175
176
- mc->desc = "Quanta GSJ (Cortex A9)";
177
+ mc->desc = "Quanta GSJ (Cortex-A9)";
178
mc->init = quanta_gsj_init;
179
mc->default_ram_size = 512 * MiB;
180
};
181
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/hw/arm/sabrelite.c
184
+++ b/hw/arm/sabrelite.c
185
@@ -XXX,XX +XXX,XX @@ static void sabrelite_init(MachineState *machine)
186
187
static void sabrelite_machine_init(MachineClass *mc)
188
{
189
- mc->desc = "Freescale i.MX6 Quad SABRE Lite Board (Cortex A9)";
190
+ mc->desc = "Freescale i.MX6 Quad SABRE Lite Board (Cortex-A9)";
191
mc->init = sabrelite_init;
192
mc->max_cpus = FSL_IMX6_NUM_CPUS;
193
mc->ignore_memory_transaction_failures = true;
194
diff --git a/hw/misc/npcm7xx_clk.c b/hw/misc/npcm7xx_clk.c
195
index XXXXXXX..XXXXXXX 100644
196
--- a/hw/misc/npcm7xx_clk.c
197
+++ b/hw/misc/npcm7xx_clk.c
198
@@ -XXX,XX +XXX,XX @@
199
#define NPCM7XX_CLOCK_REF_HZ (25000000)
200
201
/* Register Field Definitions */
202
-#define NPCM7XX_CLK_WDRCR_CA9C BIT(0) /* Cortex A9 Cores */
203
+#define NPCM7XX_CLK_WDRCR_CA9C BIT(0) /* Cortex-A9 Cores */
204
205
#define PLLCON_LOKI BIT(31)
206
#define PLLCON_LOKS BIT(30)
207
--
23
--
208
2.20.1
24
2.34.1
209
210
diff view generated by jsdifflib
1
From: Jamie Iles <jamie@nuviainc.com>
1
Set the default NaN pattern explicitly for tricore.
2
2
3
The DAIF and PAC checks used raise_exception_ra to raise an exception
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
and unwind CPU state but raise_exception_ra is currently designed for
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
handling data aborts as the syndrome is partially precomputed and
5
Message-id: 20241202131347.498124-54-peter.maydell@linaro.org
6
encoded in the TB and then merged in merge_syn_data_abort when handling
6
---
7
the data abort. Using raise_exception_ra for DAIF and PAC checks
7
target/tricore/helper.c | 2 ++
8
results in an empty syndrome being retrieved from data[2] in
8
1 file changed, 2 insertions(+)
9
restore_state_to_opc and setting ESR to 0. This manifested as:
10
9
11
kvm [571]: Unknown exception class: esr: 0x000000 –
10
diff --git a/target/tricore/helper.c b/target/tricore/helper.c
12
Unknown/Uncategorized
13
14
when launching a KVM guest when the host qemu used a CPU supporting
15
EL2+pointer authentication and enabling pointer authentication in the
16
guest.
17
18
Rework raise_exception_ra such that the state is restored before raising
19
the exception so that the exception is not clobbered by
20
restore_state_to_opc.
21
22
Fixes: 0d43e1a2d29a ("target/arm: Add PAuth helpers")
23
Cc: Richard Henderson <richard.henderson@linaro.org>
24
Cc: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Jamie Iles <jamie@nuviainc.com>
26
[PMM: added comment]
27
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
---
30
target/arm/op_helper.c | 11 +++++++++--
31
1 file changed, 9 insertions(+), 2 deletions(-)
32
33
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
34
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/op_helper.c
12
--- a/target/tricore/helper.c
36
+++ b/target/arm/op_helper.c
13
+++ b/target/tricore/helper.c
37
@@ -XXX,XX +XXX,XX @@ void raise_exception(CPUARMState *env, uint32_t excp,
14
@@ -XXX,XX +XXX,XX @@ void fpu_set_state(CPUTriCoreState *env)
38
void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
15
set_flush_to_zero(1, &env->fp_status);
39
uint32_t target_el, uintptr_t ra)
16
set_float_detect_tininess(float_tininess_before_rounding, &env->fp_status);
40
{
17
set_default_nan_mode(1, &env->fp_status);
41
- CPUState *cs = do_raise_exception(env, excp, syndrome, target_el);
18
+ /* Default NaN pattern: sign bit clear, frac msb set */
42
- cpu_loop_exit_restore(cs, ra);
19
+ set_float_default_nan_pattern(0b01000000, &env->fp_status);
43
+ CPUState *cs = env_cpu(env);
44
+
45
+ /*
46
+ * restore_state_to_opc() will set env->exception.syndrome, so
47
+ * we must restore CPU state here before setting the syndrome
48
+ * the caller passed us, and cannot use cpu_loop_exit_restore().
49
+ */
50
+ cpu_restore_state(cs, ra, true);
51
+ raise_exception(env, excp, syndrome, target_el);
52
}
20
}
53
21
54
uint64_t HELPER(neon_tbl)(CPUARMState *env, uint32_t desc,
22
uint32_t psw_read(CPUTriCoreState *env)
55
--
23
--
56
2.20.1
24
2.34.1
57
58
diff view generated by jsdifflib
1
The fp_sysreg_checks() function is supposed to be returning an
1
Now that all our targets have bene converted to explicitly specify
2
FPSysRegCheckResult, which is an enum with three possible values.
2
their pattern for the default NaN value we can remove the remaining
3
However, three places in the function "return false" (a hangover from
3
fallback code in parts64_default_nan().
4
a previous iteration of the design where the function just returned a
5
bool). Make these return FPSysRegCheckFailed instead (for no
6
functional change, since both false and FPSysRegCheckFailed are
7
zero).
8
4
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210520152840.24453-6-peter.maydell@linaro.org
7
Message-id: 20241202131347.498124-55-peter.maydell@linaro.org
12
---
8
---
13
target/arm/translate-vfp.c | 6 +++---
9
fpu/softfloat-specialize.c.inc | 14 --------------
14
1 file changed, 3 insertions(+), 3 deletions(-)
10
1 file changed, 14 deletions(-)
15
11
16
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
12
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-vfp.c
14
--- a/fpu/softfloat-specialize.c.inc
19
+++ b/target/arm/translate-vfp.c
15
+++ b/fpu/softfloat-specialize.c.inc
20
@@ -XXX,XX +XXX,XX @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
16
@@ -XXX,XX +XXX,XX @@ static void parts64_default_nan(FloatParts64 *p, float_status *status)
21
break;
17
uint64_t frac;
22
case ARM_VFP_FPSCR_NZCVQC:
18
uint8_t dnan_pattern = status->default_nan_pattern;
23
if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
19
24
- return false;
20
- if (dnan_pattern == 0) {
25
+ return FPSysRegCheckFailed;
21
- /*
26
}
22
- * This case is true for Alpha, ARM, MIPS, OpenRISC, PPC, RISC-V,
27
break;
23
- * S390, SH4, TriCore, and Xtensa. Our other supported targets
28
case ARM_VFP_FPCXT_S:
24
- * do not have floating-point.
29
case ARM_VFP_FPCXT_NS:
25
- */
30
if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
26
- if (snan_bit_is_one(status)) {
31
- return false;
27
- /* sign bit clear, set all frac bits other than msb */
32
+ return FPSysRegCheckFailed;
28
- dnan_pattern = 0b00111111;
33
}
29
- } else {
34
if (!s->v8m_secure) {
30
- /* sign bit clear, set frac msb */
35
- return false;
31
- dnan_pattern = 0b01000000;
36
+ return FPSysRegCheckFailed;
32
- }
37
}
33
- }
38
break;
34
assert(dnan_pattern != 0);
39
default:
35
36
sign = dnan_pattern >> 7;
40
--
37
--
41
2.20.1
38
2.34.1
42
43
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is BFDOT for both AArch64 AdvSIMD and SVE,
3
Inline pickNaNMulAdd into its only caller. This makes
4
and VDOT.BF16 for AArch32 NEON.
4
one assert redundant with the immediately preceding IF.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210525225817.400336-7-richard.henderson@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20241203203949.483774-3-richard.henderson@linaro.org
9
[PMM: keep comment from old code in new location]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/helper.h | 3 +++
12
fpu/softfloat-parts.c.inc | 41 +++++++++++++++++++++++++-
12
target/arm/neon-shared.decode | 2 ++
13
fpu/softfloat-specialize.c.inc | 54 ----------------------------------
13
target/arm/sve.decode | 3 +++
14
2 files changed, 40 insertions(+), 55 deletions(-)
14
target/arm/translate-a64.c | 20 ++++++++++++++++++
15
target/arm/translate-neon.c | 9 ++++++++
16
target/arm/translate-sve.c | 12 +++++++++++
17
target/arm/vec_helper.c | 40 +++++++++++++++++++++++++++++++++++
18
7 files changed, 89 insertions(+)
19
15
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.h
18
--- a/fpu/softfloat-parts.c.inc
23
+++ b/target/arm/helper.h
19
+++ b/fpu/softfloat-parts.c.inc
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_ummla_b, TCG_CALL_NO_RWG,
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
25
DEF_HELPER_FLAGS_5(gvec_usmmla_b, TCG_CALL_NO_RWG,
21
}
26
void, ptr, ptr, ptr, ptr, i32)
22
27
23
if (s->default_nan_mode) {
28
+DEF_HELPER_FLAGS_5(gvec_bfdot, TCG_CALL_NO_RWG,
24
+ /*
29
+ void, ptr, ptr, ptr, ptr, i32)
25
+ * We guarantee not to require the target to tell us how to
30
+
26
+ * pick a NaN if we're always returning the default NaN.
31
#ifdef TARGET_AARCH64
27
+ * But if we're not in default-NaN mode then the target must
32
#include "helper-a64.h"
28
+ * specify.
33
#include "helper-sve.h"
29
+ */
34
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
30
which = 3;
35
index XXXXXXX..XXXXXXX 100644
31
+ } else if (infzero) {
36
--- a/target/arm/neon-shared.decode
32
+ /*
37
+++ b/target/arm/neon-shared.decode
33
+ * Inf * 0 + NaN -- some implementations return the
38
@@ -XXX,XX +XXX,XX @@ VUDOT 1111 110 00 . 10 .... .... 1101 . q:1 . 1 .... \
34
+ * default NaN here, and some return the input NaN.
39
vm=%vm_dp vn=%vn_dp vd=%vd_dp
35
+ */
40
VUSDOT 1111 110 01 . 10 .... .... 1101 . q:1 . 0 .... \
36
+ switch (s->float_infzeronan_rule) {
41
vm=%vm_dp vn=%vn_dp vd=%vd_dp
37
+ case float_infzeronan_dnan_never:
42
+VDOT_b16 1111 110 00 . 00 .... .... 1101 . q:1 . 0 .... \
38
+ which = 2;
43
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
44
45
# VFM[AS]L
46
VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
47
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/sve.decode
50
+++ b/target/arm/sve.decode
51
@@ -XXX,XX +XXX,XX @@ FMLALT_zzzw 01100100 10 1 ..... 10 0 00 1 ..... ..... @rda_rn_rm_e0
52
FMLSLB_zzzw 01100100 10 1 ..... 10 1 00 0 ..... ..... @rda_rn_rm_e0
53
FMLSLT_zzzw 01100100 10 1 ..... 10 1 00 1 ..... ..... @rda_rn_rm_e0
54
55
+### SVE2 floating-point bfloat16 dot-product
56
+BFDOT_zzzz 01100100 01 1 ..... 10 0 00 0 ..... ..... @rda_rn_rm_e0
57
+
58
### SVE2 floating-point multiply-add long (indexed)
59
FMLALB_zzxw 01100100 10 1 ..... 0100.0 ..... ..... @rrxr_3a esz=2
60
FMLALT_zzxw 01100100 10 1 ..... 0100.1 ..... ..... @rrxr_3a esz=2
61
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/translate-a64.c
64
+++ b/target/arm/translate-a64.c
65
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
66
}
67
feature = dc_isar_feature(aa64_fcma, s);
68
break;
69
+ case 0x1f: /* BFDOT */
70
+ switch (size) {
71
+ case 1:
72
+ feature = dc_isar_feature(aa64_bf16, s);
73
+ break;
39
+ break;
74
+ default:
40
+ case float_infzeronan_dnan_always:
75
+ unallocated_encoding(s);
41
+ which = 3;
76
+ return;
42
+ break;
77
+ }
43
+ case float_infzeronan_dnan_if_qnan:
78
+ break;
44
+ which = is_qnan(c->cls) ? 3 : 2;
79
default:
80
unallocated_encoding(s);
81
return;
82
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
83
}
84
return;
85
86
+ case 0xf: /* BFDOT */
87
+ switch (size) {
88
+ case 1:
89
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfdot);
90
+ break;
45
+ break;
91
+ default:
46
+ default:
92
+ g_assert_not_reached();
47
+ g_assert_not_reached();
93
+ }
48
+ }
94
+ return;
49
} else {
50
- which = pickNaNMulAdd(a->cls, b->cls, c->cls, infzero, have_snan, s);
51
+ FloatClass cls[3] = { a->cls, b->cls, c->cls };
52
+ Float3NaNPropRule rule = s->float_3nan_prop_rule;
95
+
53
+
96
default:
54
+ assert(rule != float_3nan_prop_none);
97
g_assert_not_reached();
55
+ if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
56
+ /* We have at least one SNaN input and should prefer it */
57
+ do {
58
+ which = rule & R_3NAN_1ST_MASK;
59
+ rule >>= R_3NAN_1ST_LENGTH;
60
+ } while (!is_snan(cls[which]));
61
+ } else {
62
+ do {
63
+ which = rule & R_3NAN_1ST_MASK;
64
+ rule >>= R_3NAN_1ST_LENGTH;
65
+ } while (!is_nan(cls[which]));
66
+ }
98
}
67
}
99
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
68
69
if (which == 3) {
70
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
100
index XXXXXXX..XXXXXXX 100644
71
index XXXXXXX..XXXXXXX 100644
101
--- a/target/arm/translate-neon.c
72
--- a/fpu/softfloat-specialize.c.inc
102
+++ b/target/arm/translate-neon.c
73
+++ b/fpu/softfloat-specialize.c.inc
103
@@ -XXX,XX +XXX,XX @@ static bool trans_VUSDOT(DisasContext *s, arg_VUSDOT *a)
74
@@ -XXX,XX +XXX,XX @@ static int pickNaN(FloatClass a_cls, FloatClass b_cls,
104
gen_helper_gvec_usdot_b);
75
}
105
}
76
}
106
77
107
+static bool trans_VDOT_b16(DisasContext *s, arg_VDOT_b16 *a)
78
-/*----------------------------------------------------------------------------
108
+{
79
-| Select which NaN to propagate for a three-input operation.
109
+ if (!dc_isar_feature(aa32_bf16, s)) {
80
-| For the moment we assume that no CPU needs the 'larger significand'
110
+ return false;
81
-| information.
111
+ }
82
-| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
112
+ return do_neon_ddda(s, a->q * 7, a->vd, a->vn, a->vm, 0,
83
-*----------------------------------------------------------------------------*/
113
+ gen_helper_gvec_bfdot);
84
-static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
114
+}
85
- bool infzero, bool have_snan, float_status *status)
115
+
86
-{
116
static bool trans_VFML(DisasContext *s, arg_VFML *a)
87
- FloatClass cls[3] = { a_cls, b_cls, c_cls };
117
{
88
- Float3NaNPropRule rule = status->float_3nan_prop_rule;
118
int opr_sz;
89
- int which;
119
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
90
-
120
index XXXXXXX..XXXXXXX 100644
91
- /*
121
--- a/target/arm/translate-sve.c
92
- * We guarantee not to require the target to tell us how to
122
+++ b/target/arm/translate-sve.c
93
- * pick a NaN if we're always returning the default NaN.
123
@@ -XXX,XX +XXX,XX @@ static bool trans_UMMLA(DisasContext *s, arg_rrrr_esz *a)
94
- * But if we're not in default-NaN mode then the target must
124
{
95
- * specify.
125
return do_i8mm_zzzz_ool(s, a, gen_helper_gvec_ummla_b, 0);
96
- */
126
}
97
- assert(!status->default_nan_mode);
127
+
98
-
128
+static bool trans_BFDOT_zzzz(DisasContext *s, arg_rrrr_esz *a)
99
- if (infzero) {
129
+{
100
- /*
130
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
101
- * Inf * 0 + NaN -- some implementations return the default NaN here,
131
+ return false;
102
- * and some return the input NaN.
132
+ }
103
- */
133
+ if (sve_access_check(s)) {
104
- switch (status->float_infzeronan_rule) {
134
+ gen_gvec_ool_zzzz(s, gen_helper_gvec_bfdot,
105
- case float_infzeronan_dnan_never:
135
+ a->rd, a->rn, a->rm, a->ra, 0);
106
- return 2;
136
+ }
107
- case float_infzeronan_dnan_always:
137
+ return true;
108
- return 3;
138
+}
109
- case float_infzeronan_dnan_if_qnan:
139
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
110
- return is_qnan(c_cls) ? 3 : 2;
140
index XXXXXXX..XXXXXXX 100644
111
- default:
141
--- a/target/arm/vec_helper.c
112
- g_assert_not_reached();
142
+++ b/target/arm/vec_helper.c
113
- }
143
@@ -XXX,XX +XXX,XX @@ static void do_mmla_b(void *vd, void *vn, void *vm, void *va, uint32_t desc,
114
- }
144
DO_MMLA_B(gvec_smmla_b, do_smmla_b)
115
-
145
DO_MMLA_B(gvec_ummla_b, do_ummla_b)
116
- assert(rule != float_3nan_prop_none);
146
DO_MMLA_B(gvec_usmmla_b, do_usmmla_b)
117
- if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
147
+
118
- /* We have at least one SNaN input and should prefer it */
148
+/*
119
- do {
149
+ * BFloat16 Dot Product
120
- which = rule & R_3NAN_1ST_MASK;
150
+ */
121
- rule >>= R_3NAN_1ST_LENGTH;
151
+
122
- } while (!is_snan(cls[which]));
152
+static float32 bfdotadd(float32 sum, uint32_t e1, uint32_t e2)
123
- } else {
153
+{
124
- do {
154
+ /* FPCR is ignored for BFDOT and BFMMLA. */
125
- which = rule & R_3NAN_1ST_MASK;
155
+ float_status bf_status = {
126
- rule >>= R_3NAN_1ST_LENGTH;
156
+ .tininess_before_rounding = float_tininess_before_rounding,
127
- } while (!is_nan(cls[which]));
157
+ .float_rounding_mode = float_round_to_odd_inf,
128
- }
158
+ .flush_to_zero = true,
129
- return which;
159
+ .flush_inputs_to_zero = true,
130
-}
160
+ .default_nan_mode = true,
131
-
161
+ };
132
/*----------------------------------------------------------------------------
162
+ float32 t1, t2;
133
| Returns 1 if the double-precision floating-point value `a' is a quiet
163
+
134
| NaN; otherwise returns 0.
164
+ /*
165
+ * Extract each BFloat16 from the element pair, and shift
166
+ * them such that they become float32.
167
+ */
168
+ t1 = float32_mul(e1 << 16, e2 << 16, &bf_status);
169
+ t2 = float32_mul(e1 & 0xffff0000u, e2 & 0xffff0000u, &bf_status);
170
+ t1 = float32_add(t1, t2, &bf_status);
171
+ t1 = float32_add(sum, t1, &bf_status);
172
+
173
+ return t1;
174
+}
175
+
176
+void HELPER(gvec_bfdot)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
177
+{
178
+ intptr_t i, opr_sz = simd_oprsz(desc);
179
+ float32 *d = vd, *a = va;
180
+ uint32_t *n = vn, *m = vm;
181
+
182
+ for (i = 0; i < opr_sz / 4; ++i) {
183
+ d[i] = bfdotadd(a[i], n[i], m[i]);
184
+ }
185
+ clear_tail(d, opr_sz, simd_maxsz(desc));
186
+}
187
--
135
--
188
2.20.1
136
2.34.1
189
137
190
138
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The operands to tcg_gen_atomic_fetch_s{min,max}_i64 must
3
Remove "3" as a special case for which and simply
4
be signed, so that the inputs are properly extended.
4
branch to return the desired value.
5
Zero extend the result afterward, as needed.
6
5
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/364
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20210602020720.47679-1-richard.henderson@linaro.org
8
Message-id: 20241203203949.483774-4-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
target/arm/translate-a64.c | 13 ++++++++++---
11
fpu/softfloat-parts.c.inc | 20 ++++++++++----------
14
1 file changed, 10 insertions(+), 3 deletions(-)
12
1 file changed, 10 insertions(+), 10 deletions(-)
15
13
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.c
16
--- a/fpu/softfloat-parts.c.inc
19
+++ b/target/arm/translate-a64.c
17
+++ b/fpu/softfloat-parts.c.inc
20
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
21
int o3_opc = extract32(insn, 12, 4);
19
* But if we're not in default-NaN mode then the target must
22
bool r = extract32(insn, 22, 1);
20
* specify.
23
bool a = extract32(insn, 23, 1);
21
*/
24
- TCGv_i64 tcg_rs, clean_addr;
22
- which = 3;
25
+ TCGv_i64 tcg_rs, tcg_rt, clean_addr;
23
+ goto default_nan;
26
AtomicThreeOpFn *fn = NULL;
24
} else if (infzero) {
27
+ MemOp mop = s->be_data | size | MO_ALIGN;
25
/*
28
26
* Inf * 0 + NaN -- some implementations return the
29
if (is_vector || !dc_isar_feature(aa64_atomics, s)) {
27
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
30
unallocated_encoding(s);
28
*/
31
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
29
switch (s->float_infzeronan_rule) {
30
case float_infzeronan_dnan_never:
31
- which = 2;
32
break;
33
case float_infzeronan_dnan_always:
34
- which = 3;
35
- break;
36
+ goto default_nan;
37
case float_infzeronan_dnan_if_qnan:
38
- which = is_qnan(c->cls) ? 3 : 2;
39
+ if (is_qnan(c->cls)) {
40
+ goto default_nan;
41
+ }
42
break;
43
default:
44
g_assert_not_reached();
45
}
46
+ which = 2;
47
} else {
48
FloatClass cls[3] = { a->cls, b->cls, c->cls };
49
Float3NaNPropRule rule = s->float_3nan_prop_rule;
50
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
51
}
52
}
53
54
- if (which == 3) {
55
- parts_default_nan(a, s);
56
- return a;
57
- }
58
-
59
switch (which) {
60
case 0:
32
break;
61
break;
33
case 004: /* LDSMAX */
62
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
34
fn = tcg_gen_atomic_fetch_smax_i64;
63
parts_silence_nan(a, s);
35
+ mop |= MO_SIGN;
36
break;
37
case 005: /* LDSMIN */
38
fn = tcg_gen_atomic_fetch_smin_i64;
39
+ mop |= MO_SIGN;
40
break;
41
case 006: /* LDUMAX */
42
fn = tcg_gen_atomic_fetch_umax_i64;
43
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
44
}
64
}
45
65
return a;
46
tcg_rs = read_cpu_reg(s, rs, true);
47
+ tcg_rt = cpu_reg(s, rt);
48
49
if (o3_opc == 1) { /* LDCLR */
50
tcg_gen_not_i64(tcg_rs, tcg_rs);
51
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
52
/* The tcg atomic primitives are all full barriers. Therefore we
53
* can ignore the Acquire and Release bits of this instruction.
54
*/
55
- fn(cpu_reg(s, rt), clean_addr, tcg_rs, get_mem_index(s),
56
- s->be_data | size | MO_ALIGN);
57
+ fn(tcg_rt, clean_addr, tcg_rs, get_mem_index(s), mop);
58
+
66
+
59
+ if ((mop & MO_SIGN) && size != MO_64) {
67
+ default_nan:
60
+ tcg_gen_ext32u_i64(tcg_rt, tcg_rt);
68
+ parts_default_nan(a, s);
61
+ }
69
+ return a;
62
}
70
}
63
71
64
/*
72
/*
65
--
73
--
66
2.20.1
74
2.34.1
67
75
68
76
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is BFMLAL{B,T} for both AArch64 AdvSIMD and SVE,
3
Assign the pointer return value to 'a' directly,
4
and VFMA{B,T}.BF16 for AArch32 NEON.
4
rather than going through an intermediary index.
5
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210525225817.400336-10-richard.henderson@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20241203203949.483774-5-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/helper.h | 3 +++
11
fpu/softfloat-parts.c.inc | 32 ++++++++++----------------------
12
target/arm/neon-shared.decode | 3 +++
12
1 file changed, 10 insertions(+), 22 deletions(-)
13
target/arm/sve.decode | 3 +++
14
target/arm/translate-a64.c | 13 +++++++++----
15
target/arm/translate-neon.c | 9 +++++++++
16
target/arm/translate-sve.c | 30 ++++++++++++++++++++++++++++++
17
target/arm/vec_helper.c | 16 ++++++++++++++++
18
7 files changed, 73 insertions(+), 4 deletions(-)
19
13
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.h
16
--- a/fpu/softfloat-parts.c.inc
23
+++ b/target/arm/helper.h
17
+++ b/fpu/softfloat-parts.c.inc
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_bfdot_idx, TCG_CALL_NO_RWG,
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
25
DEF_HELPER_FLAGS_5(gvec_bfmmla, TCG_CALL_NO_RWG,
19
FloatPartsN *c, float_status *s,
26
void, ptr, ptr, ptr, ptr, i32)
20
int ab_mask, int abc_mask)
27
21
{
28
+DEF_HELPER_FLAGS_6(gvec_bfmlal, TCG_CALL_NO_RWG,
22
- int which;
29
+ void, ptr, ptr, ptr, ptr, ptr, i32)
23
bool infzero = (ab_mask == float_cmask_infzero);
30
+
24
bool have_snan = (abc_mask & float_cmask_snan);
31
#ifdef TARGET_AARCH64
25
+ FloatPartsN *ret;
32
#include "helper-a64.h"
26
33
#include "helper-sve.h"
27
if (unlikely(have_snan)) {
34
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
28
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
35
index XXXXXXX..XXXXXXX 100644
29
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
36
--- a/target/arm/neon-shared.decode
37
+++ b/target/arm/neon-shared.decode
38
@@ -XXX,XX +XXX,XX @@ VUSMMLA 1111 1100 1.10 .... .... 1100 .1.0 .... \
39
VMMLA_b16 1111 1100 0.00 .... .... 1100 .1.0 .... \
40
vm=%vm_dp vn=%vn_dp vd=%vd_dp
41
42
+VFMA_b16 1111 110 0 0.11 .... .... 1000 . q:1 . 1 .... \
43
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
44
+
45
VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
46
vn=%vn_dp vd=%vd_dp size=1
47
VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
48
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/sve.decode
51
+++ b/target/arm/sve.decode
52
@@ -XXX,XX +XXX,XX @@ FMLALT_zzzw 01100100 10 1 ..... 10 0 00 1 ..... ..... @rda_rn_rm_e0
53
FMLSLB_zzzw 01100100 10 1 ..... 10 1 00 0 ..... ..... @rda_rn_rm_e0
54
FMLSLT_zzzw 01100100 10 1 ..... 10 1 00 1 ..... ..... @rda_rn_rm_e0
55
56
+BFMLALB_zzzw 01100100 11 1 ..... 10 0 00 0 ..... ..... @rda_rn_rm_e0
57
+BFMLALT_zzzw 01100100 11 1 ..... 10 0 00 1 ..... ..... @rda_rn_rm_e0
58
+
59
### SVE2 floating-point bfloat16 dot-product
60
BFDOT_zzzz 01100100 01 1 ..... 10 0 00 0 ..... ..... @rda_rn_rm_e0
61
62
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/target/arm/translate-a64.c
65
+++ b/target/arm/translate-a64.c
66
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
67
}
68
feature = dc_isar_feature(aa64_bf16, s);
69
break;
70
- case 0x1f: /* BFDOT */
71
+ case 0x1f:
72
switch (size) {
73
- case 1:
74
+ case 1: /* BFDOT */
75
+ case 3: /* BFMLAL{B,T} */
76
feature = dc_isar_feature(aa64_bf16, s);
77
break;
78
default:
79
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
80
case 0xd: /* BFMMLA */
81
gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfmmla);
82
return;
83
- case 0xf: /* BFDOT */
84
+ case 0xf:
85
switch (size) {
86
- case 1:
87
+ case 1: /* BFDOT */
88
gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfdot);
89
break;
90
+ case 3: /* BFMLAL{B,T} */
91
+ gen_gvec_op4_fpst(s, 1, rd, rn, rm, rd, false, is_q,
92
+ gen_helper_gvec_bfmlal);
93
+ break;
94
default:
30
default:
95
g_assert_not_reached();
31
g_assert_not_reached();
96
}
32
}
97
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
33
- which = 2;
98
index XXXXXXX..XXXXXXX 100644
34
+ ret = c;
99
--- a/target/arm/translate-neon.c
35
} else {
100
+++ b/target/arm/translate-neon.c
36
- FloatClass cls[3] = { a->cls, b->cls, c->cls };
101
@@ -XXX,XX +XXX,XX @@ static bool trans_VMMLA_b16(DisasContext *s, arg_VMMLA_b16 *a)
37
+ FloatPartsN *val[3] = { a, b, c };
102
return do_neon_ddda(s, 7, a->vd, a->vn, a->vm, 0,
38
Float3NaNPropRule rule = s->float_3nan_prop_rule;
103
gen_helper_gvec_bfmmla);
39
104
}
40
assert(rule != float_3nan_prop_none);
105
+
41
if (have_snan && (rule & R_3NAN_SNAN_MASK)) {
106
+static bool trans_VFMA_b16(DisasContext *s, arg_VFMA_b16 *a)
42
/* We have at least one SNaN input and should prefer it */
107
+{
43
do {
108
+ if (!dc_isar_feature(aa32_bf16, s)) {
44
- which = rule & R_3NAN_1ST_MASK;
109
+ return false;
45
+ ret = val[rule & R_3NAN_1ST_MASK];
110
+ }
46
rule >>= R_3NAN_1ST_LENGTH;
111
+ return do_neon_ddda_fpst(s, 7, a->vd, a->vn, a->vm, a->q, FPST_STD,
47
- } while (!is_snan(cls[which]));
112
+ gen_helper_gvec_bfmlal);
48
+ } while (!is_snan(ret->cls));
113
+}
49
} else {
114
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
50
do {
115
index XXXXXXX..XXXXXXX 100644
51
- which = rule & R_3NAN_1ST_MASK;
116
--- a/target/arm/translate-sve.c
52
+ ret = val[rule & R_3NAN_1ST_MASK];
117
+++ b/target/arm/translate-sve.c
53
rule >>= R_3NAN_1ST_LENGTH;
118
@@ -XXX,XX +XXX,XX @@ static bool trans_BFMMLA(DisasContext *s, arg_rrrr_esz *a)
54
- } while (!is_nan(cls[which]));
55
+ } while (!is_nan(ret->cls));
56
}
119
}
57
}
120
return true;
58
121
}
59
- switch (which) {
122
+
60
- case 0:
123
+static bool do_BFMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel)
61
- break;
124
+{
62
- case 1:
125
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
63
- a = b;
126
+ return false;
64
- break;
127
+ }
65
- case 2:
128
+ if (sve_access_check(s)) {
66
- a = c;
129
+ TCGv_ptr status = fpstatus_ptr(FPST_FPCR);
67
- break;
130
+ unsigned vsz = vec_full_reg_size(s);
68
- default:
131
+
69
- g_assert_not_reached();
132
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
70
+ if (is_snan(ret->cls)) {
133
+ vec_full_reg_offset(s, a->rn),
71
+ parts_silence_nan(ret, s);
134
+ vec_full_reg_offset(s, a->rm),
135
+ vec_full_reg_offset(s, a->ra),
136
+ status, vsz, vsz, sel,
137
+ gen_helper_gvec_bfmlal);
138
+ tcg_temp_free_ptr(status);
139
+ }
140
+ return true;
141
+}
142
+
143
+static bool trans_BFMLALB_zzzw(DisasContext *s, arg_rrrr_esz *a)
144
+{
145
+ return do_BFMLAL_zzzw(s, a, false);
146
+}
147
+
148
+static bool trans_BFMLALT_zzzw(DisasContext *s, arg_rrrr_esz *a)
149
+{
150
+ return do_BFMLAL_zzzw(s, a, true);
151
+}
152
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/target/arm/vec_helper.c
155
+++ b/target/arm/vec_helper.c
156
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_bfmmla)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
157
}
72
}
158
clear_tail(d, opr_sz, simd_maxsz(desc));
73
- if (is_snan(a->cls)) {
159
}
74
- parts_silence_nan(a, s);
160
+
75
- }
161
+void HELPER(gvec_bfmlal)(void *vd, void *vn, void *vm, void *va,
76
- return a;
162
+ void *stat, uint32_t desc)
77
+ return ret;
163
+{
78
164
+ intptr_t i, opr_sz = simd_oprsz(desc);
79
default_nan:
165
+ intptr_t sel = simd_data(desc);
80
parts_default_nan(a, s);
166
+ float32 *d = vd, *a = va;
167
+ bfloat16 *n = vn, *m = vm;
168
+
169
+ for (i = 0; i < opr_sz / 4; ++i) {
170
+ float32 nn = n[H2(i * 2 + sel)] << 16;
171
+ float32 mm = m[H2(i * 2 + sel)] << 16;
172
+ d[H4(i)] = float32_muladd(nn, mm, a[H4(i)], 0, stat);
173
+ }
174
+ clear_tail(d, opr_sz, simd_maxsz(desc));
175
+}
176
--
81
--
177
2.20.1
82
2.34.1
178
83
179
84
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is BFMMLA for both AArch64 AdvSIMD and SVE,
3
While all indices into val[] should be in [0-2], the mask
4
and VMMLA.BF16 for AArch32 NEON.
4
applied is two bits. To help static analysis see there is
5
no possibility of read beyond the end of the array, pad the
6
array to 4 entries, with the final being (implicitly) NULL.
5
7
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210525225817.400336-9-richard.henderson@linaro.org
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20241203203949.483774-6-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/helper.h | 3 +++
13
fpu/softfloat-parts.c.inc | 2 +-
12
target/arm/neon-shared.decode | 2 ++
14
1 file changed, 1 insertion(+), 1 deletion(-)
13
target/arm/sve.decode | 6 +++--
14
target/arm/translate-a64.c | 10 +++++++++
15
target/arm/translate-neon.c | 9 ++++++++
16
target/arm/translate-sve.c | 12 ++++++++++
17
target/arm/vec_helper.c | 42 ++++++++++++++++++++++++++++++++++-
18
7 files changed, 81 insertions(+), 3 deletions(-)
19
15
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.h
18
--- a/fpu/softfloat-parts.c.inc
23
+++ b/target/arm/helper.h
19
+++ b/fpu/softfloat-parts.c.inc
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_bfdot, TCG_CALL_NO_RWG,
20
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
25
DEF_HELPER_FLAGS_5(gvec_bfdot_idx, TCG_CALL_NO_RWG,
26
void, ptr, ptr, ptr, ptr, i32)
27
28
+DEF_HELPER_FLAGS_5(gvec_bfmmla, TCG_CALL_NO_RWG,
29
+ void, ptr, ptr, ptr, ptr, i32)
30
+
31
#ifdef TARGET_AARCH64
32
#include "helper-a64.h"
33
#include "helper-sve.h"
34
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/neon-shared.decode
37
+++ b/target/arm/neon-shared.decode
38
@@ -XXX,XX +XXX,XX @@ VUMMLA 1111 1100 0.10 .... .... 1100 .1.1 .... \
39
vm=%vm_dp vn=%vn_dp vd=%vd_dp
40
VUSMMLA 1111 1100 1.10 .... .... 1100 .1.0 .... \
41
vm=%vm_dp vn=%vn_dp vd=%vd_dp
42
+VMMLA_b16 1111 1100 0.00 .... .... 1100 .1.0 .... \
43
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
44
45
VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
46
vn=%vn_dp vd=%vd_dp size=1
47
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/sve.decode
50
+++ b/target/arm/sve.decode
51
@@ -XXX,XX +XXX,XX @@ SQRDCMLAH_zzzz 01000100 esz:2 0 rm:5 0011 rot:2 rn:5 rd:5 ra=%reg_movprfx
52
USDOT_zzzz 01000100 .. 0 ..... 011 110 ..... ..... @rda_rn_rm
53
54
### SVE2 floating point matrix multiply accumulate
55
-
56
-FMMLA 01100100 .. 1 ..... 111001 ..... ..... @rda_rn_rm
57
+{
58
+ BFMMLA 01100100 01 1 ..... 111 001 ..... ..... @rda_rn_rm_e0
59
+ FMMLA 01100100 .. 1 ..... 111 001 ..... ..... @rda_rn_rm
60
+}
61
62
### SVE2 Memory Gather Load Group
63
64
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate-a64.c
67
+++ b/target/arm/translate-a64.c
68
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
69
}
21
}
70
feature = dc_isar_feature(aa64_fcma, s);
22
ret = c;
71
break;
23
} else {
72
+ case 0x1d: /* BFMMLA */
24
- FloatPartsN *val[3] = { a, b, c };
73
+ if (size != MO_16 || !is_q) {
25
+ FloatPartsN *val[R_3NAN_1ST_MASK + 1] = { a, b, c };
74
+ unallocated_encoding(s);
26
Float3NaNPropRule rule = s->float_3nan_prop_rule;
75
+ return;
27
76
+ }
28
assert(rule != float_3nan_prop_none);
77
+ feature = dc_isar_feature(aa64_bf16, s);
78
+ break;
79
case 0x1f: /* BFDOT */
80
switch (size) {
81
case 1:
82
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
83
}
84
return;
85
86
+ case 0xd: /* BFMMLA */
87
+ gen_gvec_op4_ool(s, is_q, rd, rn, rm, rd, 0, gen_helper_gvec_bfmmla);
88
+ return;
89
case 0xf: /* BFDOT */
90
switch (size) {
91
case 1:
92
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/target/arm/translate-neon.c
95
+++ b/target/arm/translate-neon.c
96
@@ -XXX,XX +XXX,XX @@ static bool trans_VUSMMLA(DisasContext *s, arg_VUSMMLA *a)
97
return do_neon_ddda(s, 7, a->vd, a->vn, a->vm, 0,
98
gen_helper_gvec_usmmla_b);
99
}
100
+
101
+static bool trans_VMMLA_b16(DisasContext *s, arg_VMMLA_b16 *a)
102
+{
103
+ if (!dc_isar_feature(aa32_bf16, s)) {
104
+ return false;
105
+ }
106
+ return do_neon_ddda(s, 7, a->vd, a->vn, a->vm, 0,
107
+ gen_helper_gvec_bfmmla);
108
+}
109
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/translate-sve.c
112
+++ b/target/arm/translate-sve.c
113
@@ -XXX,XX +XXX,XX @@ static bool trans_BFDOT_zzxz(DisasContext *s, arg_rrxr_esz *a)
114
}
115
return true;
116
}
117
+
118
+static bool trans_BFMMLA(DisasContext *s, arg_rrrr_esz *a)
119
+{
120
+ if (!dc_isar_feature(aa64_sve_bf16, s)) {
121
+ return false;
122
+ }
123
+ if (sve_access_check(s)) {
124
+ gen_gvec_ool_zzzz(s, gen_helper_gvec_bfmmla,
125
+ a->rd, a->rn, a->rm, a->ra, 0);
126
+ }
127
+ return true;
128
+}
129
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
130
index XXXXXXX..XXXXXXX 100644
131
--- a/target/arm/vec_helper.c
132
+++ b/target/arm/vec_helper.c
133
@@ -XXX,XX +XXX,XX @@ static void do_mmla_b(void *vd, void *vn, void *vm, void *va, uint32_t desc,
134
* Process the entire segment at once, writing back the
135
* results only after we've consumed all of the inputs.
136
*
137
- * Key to indicies by column:
138
+ * Key to indices by column:
139
* i j i j
140
*/
141
sum0 = a[H4(0 + 0)];
142
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_bfdot_idx)(void *vd, void *vn, void *vm,
143
}
144
clear_tail(d, opr_sz, simd_maxsz(desc));
145
}
146
+
147
+void HELPER(gvec_bfmmla)(void *vd, void *vn, void *vm, void *va, uint32_t desc)
148
+{
149
+ intptr_t s, opr_sz = simd_oprsz(desc);
150
+ float32 *d = vd, *a = va;
151
+ uint32_t *n = vn, *m = vm;
152
+
153
+ for (s = 0; s < opr_sz / 4; s += 4) {
154
+ float32 sum00, sum01, sum10, sum11;
155
+
156
+ /*
157
+ * Process the entire segment at once, writing back the
158
+ * results only after we've consumed all of the inputs.
159
+ *
160
+ * Key to indicies by column:
161
+ * i j i k j k
162
+ */
163
+ sum00 = a[s + H4(0 + 0)];
164
+ sum00 = bfdotadd(sum00, n[s + H4(0 + 0)], m[s + H4(0 + 0)]);
165
+ sum00 = bfdotadd(sum00, n[s + H4(0 + 1)], m[s + H4(0 + 1)]);
166
+
167
+ sum01 = a[s + H4(0 + 1)];
168
+ sum01 = bfdotadd(sum01, n[s + H4(0 + 0)], m[s + H4(2 + 0)]);
169
+ sum01 = bfdotadd(sum01, n[s + H4(0 + 1)], m[s + H4(2 + 1)]);
170
+
171
+ sum10 = a[s + H4(2 + 0)];
172
+ sum10 = bfdotadd(sum10, n[s + H4(2 + 0)], m[s + H4(0 + 0)]);
173
+ sum10 = bfdotadd(sum10, n[s + H4(2 + 1)], m[s + H4(0 + 1)]);
174
+
175
+ sum11 = a[s + H4(2 + 1)];
176
+ sum11 = bfdotadd(sum11, n[s + H4(2 + 0)], m[s + H4(2 + 0)]);
177
+ sum11 = bfdotadd(sum11, n[s + H4(2 + 1)], m[s + H4(2 + 1)]);
178
+
179
+ d[s + H4(0 + 0)] = sum00;
180
+ d[s + H4(0 + 1)] = sum01;
181
+ d[s + H4(2 + 0)] = sum10;
182
+ d[s + H4(2 + 1)] = sum11;
183
+ }
184
+ clear_tail(d, opr_sz, simd_maxsz(desc));
185
+}
186
--
29
--
187
2.20.1
30
2.34.1
188
31
189
32
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Until now, Hypervisor.framework has only been available on x86_64 systems.
3
This function is part of the public interface and
4
With Apple Silicon shipping now, it extends its reach to aarch64. To
4
is not "specialized" to any target in any way.
5
prepare for support for multiple architectures, let's start moving common
6
code out into its own accel directory.
7
5
8
This patch moves CPU and memory operations over. While at it, make sure
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
the code is consumable on non-i386 systems.
10
11
Signed-off-by: Alexander Graf <agraf@csgraf.de>
12
Reviewed-by: Sergio Lopez <slp@redhat.com>
13
Message-id: 20210519202253.76782-4-agraf@csgraf.de
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20241203203949.483774-7-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
10
---
17
include/sysemu/hvf_int.h | 4 +
11
fpu/softfloat.c | 52 ++++++++++++++++++++++++++++++++++
18
target/i386/hvf/hvf-i386.h | 2 -
12
fpu/softfloat-specialize.c.inc | 52 ----------------------------------
19
target/i386/hvf/x86hvf.h | 2 -
13
2 files changed, 52 insertions(+), 52 deletions(-)
20
accel/hvf/hvf-accel-ops.c | 308 ++++++++++++++++++++++++++++++++++++-
21
target/i386/hvf/hvf.c | 302 ------------------------------------
22
5 files changed, 311 insertions(+), 307 deletions(-)
23
14
24
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
25
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
26
--- a/include/sysemu/hvf_int.h
17
--- a/fpu/softfloat.c
27
+++ b/include/sysemu/hvf_int.h
18
+++ b/fpu/softfloat.c
28
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
29
20
*zExpPtr = 1 - shiftCount;
30
#include <Hypervisor/hv.h>
21
}
31
22
32
+void hvf_set_phys_mem(MemoryRegionSection *, bool);
23
+/*----------------------------------------------------------------------------
33
void assert_hvf_ok(hv_return_t ret);
24
+| Takes two extended double-precision floating-point values `a' and `b', one
34
+hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
25
+| of which is a NaN, and returns the appropriate NaN result. If either `a' or
35
+int hvf_put_registers(CPUState *);
26
+| `b' is a signaling NaN, the invalid exception is raised.
36
+int hvf_get_registers(CPUState *);
27
+*----------------------------------------------------------------------------*/
37
38
#endif
39
diff --git a/target/i386/hvf/hvf-i386.h b/target/i386/hvf/hvf-i386.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/i386/hvf/hvf-i386.h
42
+++ b/target/i386/hvf/hvf-i386.h
43
@@ -XXX,XX +XXX,XX @@ struct HVFState {
44
};
45
extern HVFState *hvf_state;
46
47
-void hvf_set_phys_mem(MemoryRegionSection *, bool);
48
void hvf_handle_io(CPUArchState *, uint16_t, void *, int, int, int);
49
-hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
50
51
#ifdef NEED_CPU_H
52
/* Functions exported to host specific mode */
53
diff --git a/target/i386/hvf/x86hvf.h b/target/i386/hvf/x86hvf.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/i386/hvf/x86hvf.h
56
+++ b/target/i386/hvf/x86hvf.h
57
@@ -XXX,XX +XXX,XX @@
58
#include "x86_descr.h"
59
60
int hvf_process_events(CPUState *);
61
-int hvf_put_registers(CPUState *);
62
-int hvf_get_registers(CPUState *);
63
bool hvf_inject_interrupts(CPUState *);
64
void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg,
65
SegmentCache *qseg, bool is_tr);
66
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/accel/hvf/hvf-accel-ops.c
69
+++ b/accel/hvf/hvf-accel-ops.c
70
@@ -XXX,XX +XXX,XX @@
71
#include "qemu/osdep.h"
72
#include "qemu/error-report.h"
73
#include "qemu/main-loop.h"
74
+#include "exec/address-spaces.h"
75
+#include "exec/exec-all.h"
76
+#include "sysemu/cpus.h"
77
#include "sysemu/hvf.h"
78
+#include "sysemu/hvf_int.h"
79
#include "sysemu/runstate.h"
80
-#include "target/i386/cpu.h"
81
#include "qemu/guest-random.h"
82
83
#include "hvf-accel-ops.h"
84
85
+HVFState *hvf_state;
86
+
28
+
87
+/* Memory slots */
29
+floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
30
+{
31
+ bool aIsLargerSignificand;
32
+ FloatClass a_cls, b_cls;
88
+
33
+
89
+hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
34
+ /* This is not complete, but is good enough for pickNaN. */
90
+{
35
+ a_cls = (!floatx80_is_any_nan(a)
91
+ hvf_slot *slot;
36
+ ? float_class_normal
92
+ int x;
37
+ : floatx80_is_signaling_nan(a, status)
93
+ for (x = 0; x < hvf_state->num_slots; ++x) {
38
+ ? float_class_snan
94
+ slot = &hvf_state->slots[x];
39
+ : float_class_qnan);
95
+ if (slot->size && start < (slot->start + slot->size) &&
40
+ b_cls = (!floatx80_is_any_nan(b)
96
+ (start + size) > slot->start) {
41
+ ? float_class_normal
97
+ return slot;
42
+ : floatx80_is_signaling_nan(b, status)
98
+ }
43
+ ? float_class_snan
99
+ }
44
+ : float_class_qnan);
100
+ return NULL;
101
+}
102
+
45
+
103
+struct mac_slot {
46
+ if (is_snan(a_cls) || is_snan(b_cls)) {
104
+ int present;
47
+ float_raise(float_flag_invalid, status);
105
+ uint64_t size;
106
+ uint64_t gpa_start;
107
+ uint64_t gva;
108
+};
109
+
110
+struct mac_slot mac_slots[32];
111
+
112
+static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
113
+{
114
+ struct mac_slot *macslot;
115
+ hv_return_t ret;
116
+
117
+ macslot = &mac_slots[slot->slot_id];
118
+
119
+ if (macslot->present) {
120
+ if (macslot->size != slot->size) {
121
+ macslot->present = 0;
122
+ ret = hv_vm_unmap(macslot->gpa_start, macslot->size);
123
+ assert_hvf_ok(ret);
124
+ }
125
+ }
48
+ }
126
+
49
+
127
+ if (!slot->size) {
50
+ if (status->default_nan_mode) {
128
+ return 0;
51
+ return floatx80_default_nan(status);
129
+ }
52
+ }
130
+
53
+
131
+ macslot->present = 1;
54
+ if (a.low < b.low) {
132
+ macslot->gpa_start = slot->start;
55
+ aIsLargerSignificand = 0;
133
+ macslot->size = slot->size;
56
+ } else if (b.low < a.low) {
134
+ ret = hv_vm_map((hv_uvaddr_t)slot->mem, slot->start, slot->size, flags);
57
+ aIsLargerSignificand = 1;
135
+ assert_hvf_ok(ret);
58
+ } else {
136
+ return 0;
59
+ aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
137
+}
138
+
139
+void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
140
+{
141
+ hvf_slot *mem;
142
+ MemoryRegion *area = section->mr;
143
+ bool writeable = !area->readonly && !area->rom_device;
144
+ hv_memory_flags_t flags;
145
+
146
+ if (!memory_region_is_ram(area)) {
147
+ if (writeable) {
148
+ return;
149
+ } else if (!memory_region_is_romd(area)) {
150
+ /*
151
+ * If the memory device is not in romd_mode, then we actually want
152
+ * to remove the hvf memory slot so all accesses will trap.
153
+ */
154
+ add = false;
155
+ }
156
+ }
60
+ }
157
+
61
+
158
+ mem = hvf_find_overlap_slot(
62
+ if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
159
+ section->offset_within_address_space,
63
+ if (is_snan(b_cls)) {
160
+ int128_get64(section->size));
64
+ return floatx80_silence_nan(b, status);
161
+
162
+ if (mem && add) {
163
+ if (mem->size == int128_get64(section->size) &&
164
+ mem->start == section->offset_within_address_space &&
165
+ mem->mem == (memory_region_get_ram_ptr(area) +
166
+ section->offset_within_region)) {
167
+ return; /* Same region was attempted to register, go away. */
168
+ }
65
+ }
169
+ }
66
+ return b;
170
+
67
+ } else {
171
+ /* Region needs to be reset. set the size to 0 and remap it. */
68
+ if (is_snan(a_cls)) {
172
+ if (mem) {
69
+ return floatx80_silence_nan(a, status);
173
+ mem->size = 0;
174
+ if (do_hvf_set_memory(mem, 0)) {
175
+ error_report("Failed to reset overlapping slot");
176
+ abort();
177
+ }
70
+ }
178
+ }
71
+ return a;
179
+
180
+ if (!add) {
181
+ return;
182
+ }
183
+
184
+ if (area->readonly ||
185
+ (!memory_region_is_ram(area) && memory_region_is_romd(area))) {
186
+ flags = HV_MEMORY_READ | HV_MEMORY_EXEC;
187
+ } else {
188
+ flags = HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC;
189
+ }
190
+
191
+ /* Now make a new slot. */
192
+ int x;
193
+
194
+ for (x = 0; x < hvf_state->num_slots; ++x) {
195
+ mem = &hvf_state->slots[x];
196
+ if (!mem->size) {
197
+ break;
198
+ }
199
+ }
200
+
201
+ if (x == hvf_state->num_slots) {
202
+ error_report("No free slots");
203
+ abort();
204
+ }
205
+
206
+ mem->size = int128_get64(section->size);
207
+ mem->mem = memory_region_get_ram_ptr(area) + section->offset_within_region;
208
+ mem->start = section->offset_within_address_space;
209
+ mem->region = area;
210
+
211
+ if (do_hvf_set_memory(mem, flags)) {
212
+ error_report("Error registering new memory slot");
213
+ abort();
214
+ }
72
+ }
215
+}
73
+}
216
+
74
+
217
+static void do_hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
75
/*----------------------------------------------------------------------------
218
+{
76
| Takes an abstract floating-point value having sign `zSign', exponent `zExp',
219
+ if (!cpu->vcpu_dirty) {
77
| and extended significand formed by the concatenation of `zSig0' and `zSig1',
220
+ hvf_get_registers(cpu);
78
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
221
+ cpu->vcpu_dirty = true;
222
+ }
223
+}
224
+
225
+void hvf_cpu_synchronize_state(CPUState *cpu)
226
+{
227
+ if (!cpu->vcpu_dirty) {
228
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);
229
+ }
230
+}
231
+
232
+static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu,
233
+ run_on_cpu_data arg)
234
+{
235
+ hvf_put_registers(cpu);
236
+ cpu->vcpu_dirty = false;
237
+}
238
+
239
+void hvf_cpu_synchronize_post_reset(CPUState *cpu)
240
+{
241
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
242
+}
243
+
244
+static void do_hvf_cpu_synchronize_post_init(CPUState *cpu,
245
+ run_on_cpu_data arg)
246
+{
247
+ hvf_put_registers(cpu);
248
+ cpu->vcpu_dirty = false;
249
+}
250
+
251
+void hvf_cpu_synchronize_post_init(CPUState *cpu)
252
+{
253
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
254
+}
255
+
256
+static void do_hvf_cpu_synchronize_pre_loadvm(CPUState *cpu,
257
+ run_on_cpu_data arg)
258
+{
259
+ cpu->vcpu_dirty = true;
260
+}
261
+
262
+void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)
263
+{
264
+ run_on_cpu(cpu, do_hvf_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);
265
+}
266
+
267
+static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)
268
+{
269
+ hvf_slot *slot;
270
+
271
+ slot = hvf_find_overlap_slot(
272
+ section->offset_within_address_space,
273
+ int128_get64(section->size));
274
+
275
+ /* protect region against writes; begin tracking it */
276
+ if (on) {
277
+ slot->flags |= HVF_SLOT_LOG;
278
+ hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
279
+ HV_MEMORY_READ);
280
+ /* stop tracking region*/
281
+ } else {
282
+ slot->flags &= ~HVF_SLOT_LOG;
283
+ hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
284
+ HV_MEMORY_READ | HV_MEMORY_WRITE);
285
+ }
286
+}
287
+
288
+static void hvf_log_start(MemoryListener *listener,
289
+ MemoryRegionSection *section, int old, int new)
290
+{
291
+ if (old != 0) {
292
+ return;
293
+ }
294
+
295
+ hvf_set_dirty_tracking(section, 1);
296
+}
297
+
298
+static void hvf_log_stop(MemoryListener *listener,
299
+ MemoryRegionSection *section, int old, int new)
300
+{
301
+ if (new != 0) {
302
+ return;
303
+ }
304
+
305
+ hvf_set_dirty_tracking(section, 0);
306
+}
307
+
308
+static void hvf_log_sync(MemoryListener *listener,
309
+ MemoryRegionSection *section)
310
+{
311
+ /*
312
+ * sync of dirty pages is handled elsewhere; just make sure we keep
313
+ * tracking the region.
314
+ */
315
+ hvf_set_dirty_tracking(section, 1);
316
+}
317
+
318
+static void hvf_region_add(MemoryListener *listener,
319
+ MemoryRegionSection *section)
320
+{
321
+ hvf_set_phys_mem(section, true);
322
+}
323
+
324
+static void hvf_region_del(MemoryListener *listener,
325
+ MemoryRegionSection *section)
326
+{
327
+ hvf_set_phys_mem(section, false);
328
+}
329
+
330
+static MemoryListener hvf_memory_listener = {
331
+ .priority = 10,
332
+ .region_add = hvf_region_add,
333
+ .region_del = hvf_region_del,
334
+ .log_start = hvf_log_start,
335
+ .log_stop = hvf_log_stop,
336
+ .log_sync = hvf_log_sync,
337
+};
338
+
339
+static void dummy_signal(int sig)
340
+{
341
+}
342
+
343
+bool hvf_allowed;
344
+
345
+static int hvf_accel_init(MachineState *ms)
346
+{
347
+ int x;
348
+ hv_return_t ret;
349
+ HVFState *s;
350
+
351
+ ret = hv_vm_create(HV_VM_DEFAULT);
352
+ assert_hvf_ok(ret);
353
+
354
+ s = g_new0(HVFState, 1);
355
+
356
+ s->num_slots = 32;
357
+ for (x = 0; x < s->num_slots; ++x) {
358
+ s->slots[x].size = 0;
359
+ s->slots[x].slot_id = x;
360
+ }
361
+
362
+ hvf_state = s;
363
+ memory_listener_register(&hvf_memory_listener, &address_space_memory);
364
+ return 0;
365
+}
366
+
367
+static void hvf_accel_class_init(ObjectClass *oc, void *data)
368
+{
369
+ AccelClass *ac = ACCEL_CLASS(oc);
370
+ ac->name = "HVF";
371
+ ac->init_machine = hvf_accel_init;
372
+ ac->allowed = &hvf_allowed;
373
+}
374
+
375
+static const TypeInfo hvf_accel_type = {
376
+ .name = TYPE_HVF_ACCEL,
377
+ .parent = TYPE_ACCEL,
378
+ .class_init = hvf_accel_class_init,
379
+};
380
+
381
+static void hvf_type_init(void)
382
+{
383
+ type_register_static(&hvf_accel_type);
384
+}
385
+
386
+type_init(hvf_type_init);
387
+
388
/*
389
* The HVF-specific vCPU thread function. This one should only run when the host
390
* CPU supports the VMX "unrestricted guest" feature.
391
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
392
index XXXXXXX..XXXXXXX 100644
79
index XXXXXXX..XXXXXXX 100644
393
--- a/target/i386/hvf/hvf.c
80
--- a/fpu/softfloat-specialize.c.inc
394
+++ b/target/i386/hvf/hvf.c
81
+++ b/fpu/softfloat-specialize.c.inc
395
@@ -XXX,XX +XXX,XX @@
82
@@ -XXX,XX +XXX,XX @@ floatx80 floatx80_silence_nan(floatx80 a, float_status *status)
396
83
return a;
397
#include "hvf-accel-ops.h"
84
}
398
85
399
-HVFState *hvf_state;
86
-/*----------------------------------------------------------------------------
87
-| Takes two extended double-precision floating-point values `a' and `b', one
88
-| of which is a NaN, and returns the appropriate NaN result. If either `a' or
89
-| `b' is a signaling NaN, the invalid exception is raised.
90
-*----------------------------------------------------------------------------*/
400
-
91
-
401
-/* Memory slots */
92
-floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
402
-hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
403
-{
93
-{
404
- hvf_slot *slot;
94
- bool aIsLargerSignificand;
405
- int x;
95
- FloatClass a_cls, b_cls;
406
- for (x = 0; x < hvf_state->num_slots; ++x) {
407
- slot = &hvf_state->slots[x];
408
- if (slot->size && start < (slot->start + slot->size) &&
409
- (start + size) > slot->start) {
410
- return slot;
411
- }
412
- }
413
- return NULL;
414
-}
415
-
96
-
416
-struct mac_slot {
97
- /* This is not complete, but is good enough for pickNaN. */
417
- int present;
98
- a_cls = (!floatx80_is_any_nan(a)
418
- uint64_t size;
99
- ? float_class_normal
419
- uint64_t gpa_start;
100
- : floatx80_is_signaling_nan(a, status)
420
- uint64_t gva;
101
- ? float_class_snan
421
-};
102
- : float_class_qnan);
103
- b_cls = (!floatx80_is_any_nan(b)
104
- ? float_class_normal
105
- : floatx80_is_signaling_nan(b, status)
106
- ? float_class_snan
107
- : float_class_qnan);
422
-
108
-
423
-struct mac_slot mac_slots[32];
109
- if (is_snan(a_cls) || is_snan(b_cls)) {
424
-
110
- float_raise(float_flag_invalid, status);
425
-static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
426
-{
427
- struct mac_slot *macslot;
428
- hv_return_t ret;
429
-
430
- macslot = &mac_slots[slot->slot_id];
431
-
432
- if (macslot->present) {
433
- if (macslot->size != slot->size) {
434
- macslot->present = 0;
435
- ret = hv_vm_unmap(macslot->gpa_start, macslot->size);
436
- assert_hvf_ok(ret);
437
- }
438
- }
111
- }
439
-
112
-
440
- if (!slot->size) {
113
- if (status->default_nan_mode) {
441
- return 0;
114
- return floatx80_default_nan(status);
442
- }
115
- }
443
-
116
-
444
- macslot->present = 1;
117
- if (a.low < b.low) {
445
- macslot->gpa_start = slot->start;
118
- aIsLargerSignificand = 0;
446
- macslot->size = slot->size;
119
- } else if (b.low < a.low) {
447
- ret = hv_vm_map((hv_uvaddr_t)slot->mem, slot->start, slot->size, flags);
120
- aIsLargerSignificand = 1;
448
- assert_hvf_ok(ret);
121
- } else {
449
- return 0;
122
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
450
-}
451
-
452
-void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
453
-{
454
- hvf_slot *mem;
455
- MemoryRegion *area = section->mr;
456
- bool writeable = !area->readonly && !area->rom_device;
457
- hv_memory_flags_t flags;
458
-
459
- if (!memory_region_is_ram(area)) {
460
- if (writeable) {
461
- return;
462
- } else if (!memory_region_is_romd(area)) {
463
- /*
464
- * If the memory device is not in romd_mode, then we actually want
465
- * to remove the hvf memory slot so all accesses will trap.
466
- */
467
- add = false;
468
- }
469
- }
123
- }
470
-
124
-
471
- mem = hvf_find_overlap_slot(
125
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
472
- section->offset_within_address_space,
126
- if (is_snan(b_cls)) {
473
- int128_get64(section->size));
127
- return floatx80_silence_nan(b, status);
474
-
475
- if (mem && add) {
476
- if (mem->size == int128_get64(section->size) &&
477
- mem->start == section->offset_within_address_space &&
478
- mem->mem == (memory_region_get_ram_ptr(area) +
479
- section->offset_within_region)) {
480
- return; /* Same region was attempted to register, go away. */
481
- }
128
- }
482
- }
129
- return b;
483
-
130
- } else {
484
- /* Region needs to be reset. set the size to 0 and remap it. */
131
- if (is_snan(a_cls)) {
485
- if (mem) {
132
- return floatx80_silence_nan(a, status);
486
- mem->size = 0;
487
- if (do_hvf_set_memory(mem, 0)) {
488
- error_report("Failed to reset overlapping slot");
489
- abort();
490
- }
133
- }
491
- }
134
- return a;
492
-
493
- if (!add) {
494
- return;
495
- }
496
-
497
- if (area->readonly ||
498
- (!memory_region_is_ram(area) && memory_region_is_romd(area))) {
499
- flags = HV_MEMORY_READ | HV_MEMORY_EXEC;
500
- } else {
501
- flags = HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC;
502
- }
503
-
504
- /* Now make a new slot. */
505
- int x;
506
-
507
- for (x = 0; x < hvf_state->num_slots; ++x) {
508
- mem = &hvf_state->slots[x];
509
- if (!mem->size) {
510
- break;
511
- }
512
- }
513
-
514
- if (x == hvf_state->num_slots) {
515
- error_report("No free slots");
516
- abort();
517
- }
518
-
519
- mem->size = int128_get64(section->size);
520
- mem->mem = memory_region_get_ram_ptr(area) + section->offset_within_region;
521
- mem->start = section->offset_within_address_space;
522
- mem->region = area;
523
-
524
- if (do_hvf_set_memory(mem, flags)) {
525
- error_report("Error registering new memory slot");
526
- abort();
527
- }
135
- }
528
-}
136
-}
529
-
137
-
530
void vmx_update_tpr(CPUState *cpu)
138
/*----------------------------------------------------------------------------
531
{
139
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
532
/* TODO: need integrate APIC handling */
140
| NaN; otherwise returns 0.
533
@@ -XXX,XX +XXX,XX @@ void hvf_handle_io(CPUArchState *env, uint16_t port, void *buffer,
534
}
535
}
536
537
-static void do_hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
538
-{
539
- if (!cpu->vcpu_dirty) {
540
- hvf_get_registers(cpu);
541
- cpu->vcpu_dirty = true;
542
- }
543
-}
544
-
545
-void hvf_cpu_synchronize_state(CPUState *cpu)
546
-{
547
- if (!cpu->vcpu_dirty) {
548
- run_on_cpu(cpu, do_hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);
549
- }
550
-}
551
-
552
-static void do_hvf_cpu_synchronize_post_reset(CPUState *cpu,
553
- run_on_cpu_data arg)
554
-{
555
- hvf_put_registers(cpu);
556
- cpu->vcpu_dirty = false;
557
-}
558
-
559
-void hvf_cpu_synchronize_post_reset(CPUState *cpu)
560
-{
561
- run_on_cpu(cpu, do_hvf_cpu_synchronize_post_reset, RUN_ON_CPU_NULL);
562
-}
563
-
564
-static void do_hvf_cpu_synchronize_post_init(CPUState *cpu,
565
- run_on_cpu_data arg)
566
-{
567
- hvf_put_registers(cpu);
568
- cpu->vcpu_dirty = false;
569
-}
570
-
571
-void hvf_cpu_synchronize_post_init(CPUState *cpu)
572
-{
573
- run_on_cpu(cpu, do_hvf_cpu_synchronize_post_init, RUN_ON_CPU_NULL);
574
-}
575
-
576
-static void do_hvf_cpu_synchronize_pre_loadvm(CPUState *cpu,
577
- run_on_cpu_data arg)
578
-{
579
- cpu->vcpu_dirty = true;
580
-}
581
-
582
-void hvf_cpu_synchronize_pre_loadvm(CPUState *cpu)
583
-{
584
- run_on_cpu(cpu, do_hvf_cpu_synchronize_pre_loadvm, RUN_ON_CPU_NULL);
585
-}
586
-
587
static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
588
{
589
int read, write;
590
@@ -XXX,XX +XXX,XX @@ static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
591
return false;
592
}
593
594
-static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)
595
-{
596
- hvf_slot *slot;
597
-
598
- slot = hvf_find_overlap_slot(
599
- section->offset_within_address_space,
600
- int128_get64(section->size));
601
-
602
- /* protect region against writes; begin tracking it */
603
- if (on) {
604
- slot->flags |= HVF_SLOT_LOG;
605
- hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
606
- HV_MEMORY_READ);
607
- /* stop tracking region*/
608
- } else {
609
- slot->flags &= ~HVF_SLOT_LOG;
610
- hv_vm_protect((hv_gpaddr_t)slot->start, (size_t)slot->size,
611
- HV_MEMORY_READ | HV_MEMORY_WRITE);
612
- }
613
-}
614
-
615
-static void hvf_log_start(MemoryListener *listener,
616
- MemoryRegionSection *section, int old, int new)
617
-{
618
- if (old != 0) {
619
- return;
620
- }
621
-
622
- hvf_set_dirty_tracking(section, 1);
623
-}
624
-
625
-static void hvf_log_stop(MemoryListener *listener,
626
- MemoryRegionSection *section, int old, int new)
627
-{
628
- if (new != 0) {
629
- return;
630
- }
631
-
632
- hvf_set_dirty_tracking(section, 0);
633
-}
634
-
635
-static void hvf_log_sync(MemoryListener *listener,
636
- MemoryRegionSection *section)
637
-{
638
- /*
639
- * sync of dirty pages is handled elsewhere; just make sure we keep
640
- * tracking the region.
641
- */
642
- hvf_set_dirty_tracking(section, 1);
643
-}
644
-
645
-static void hvf_region_add(MemoryListener *listener,
646
- MemoryRegionSection *section)
647
-{
648
- hvf_set_phys_mem(section, true);
649
-}
650
-
651
-static void hvf_region_del(MemoryListener *listener,
652
- MemoryRegionSection *section)
653
-{
654
- hvf_set_phys_mem(section, false);
655
-}
656
-
657
-static MemoryListener hvf_memory_listener = {
658
- .priority = 10,
659
- .region_add = hvf_region_add,
660
- .region_del = hvf_region_del,
661
- .log_start = hvf_log_start,
662
- .log_stop = hvf_log_stop,
663
- .log_sync = hvf_log_sync,
664
-};
665
-
666
void hvf_vcpu_destroy(CPUState *cpu)
667
{
668
X86CPU *x86_cpu = X86_CPU(cpu);
669
@@ -XXX,XX +XXX,XX @@ void hvf_vcpu_destroy(CPUState *cpu)
670
assert_hvf_ok(ret);
671
}
672
673
-static void dummy_signal(int sig)
674
-{
675
-}
676
-
677
static void init_tsc_freq(CPUX86State *env)
678
{
679
size_t length;
680
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
681
682
return ret;
683
}
684
-
685
-bool hvf_allowed;
686
-
687
-static int hvf_accel_init(MachineState *ms)
688
-{
689
- int x;
690
- hv_return_t ret;
691
- HVFState *s;
692
-
693
- ret = hv_vm_create(HV_VM_DEFAULT);
694
- assert_hvf_ok(ret);
695
-
696
- s = g_new0(HVFState, 1);
697
-
698
- s->num_slots = 32;
699
- for (x = 0; x < s->num_slots; ++x) {
700
- s->slots[x].size = 0;
701
- s->slots[x].slot_id = x;
702
- }
703
-
704
- hvf_state = s;
705
- memory_listener_register(&hvf_memory_listener, &address_space_memory);
706
- return 0;
707
-}
708
-
709
-static void hvf_accel_class_init(ObjectClass *oc, void *data)
710
-{
711
- AccelClass *ac = ACCEL_CLASS(oc);
712
- ac->name = "HVF";
713
- ac->init_machine = hvf_accel_init;
714
- ac->allowed = &hvf_allowed;
715
-}
716
-
717
-static const TypeInfo hvf_accel_type = {
718
- .name = TYPE_HVF_ACCEL,
719
- .parent = TYPE_ACCEL,
720
- .class_init = hvf_accel_class_init,
721
-};
722
-
723
-static void hvf_type_init(void)
724
-{
725
- type_register_static(&hvf_accel_type);
726
-}
727
-
728
-type_init(hvf_type_init);
729
--
141
--
730
2.20.1
142
2.34.1
731
732
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is the 64-bit BFCVT and the 32-bit VCVT{B,T}.BF16.F32.
3
Unpacking and repacking the parts may be slightly more work
4
than we did before, but we get to reuse more code. For a
5
code path handling exceptional values, this is an improvement.
4
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20241203203949.483774-8-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210525225817.400336-4-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
target/arm/helper.h | 1 +
12
fpu/softfloat.c | 43 +++++--------------------------------------
11
target/arm/vfp.decode | 2 ++
13
1 file changed, 5 insertions(+), 38 deletions(-)
12
target/arm/translate-a64.c | 19 +++++++++++++++++++
13
target/arm/translate-vfp.c | 24 ++++++++++++++++++++++++
14
target/arm/vfp_helper.c | 5 +++++
15
5 files changed, 51 insertions(+)
16
14
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
15
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.h
17
--- a/fpu/softfloat.c
20
+++ b/target/arm/helper.h
18
+++ b/fpu/softfloat.c
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_cmped, void, f64, f64, env)
19
@@ -XXX,XX +XXX,XX @@ void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr,
22
20
23
DEF_HELPER_2(vfp_fcvtds, f64, f32, env)
21
floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status)
24
DEF_HELPER_2(vfp_fcvtsd, f32, f64, env)
22
{
25
+DEF_HELPER_FLAGS_2(bfcvt, TCG_CALL_NO_RWG, i32, f32, ptr)
23
- bool aIsLargerSignificand;
26
24
- FloatClass a_cls, b_cls;
27
DEF_HELPER_2(vfp_uitoh, f16, i32, ptr)
25
+ FloatParts128 pa, pb, *pr;
28
DEF_HELPER_2(vfp_uitos, f32, i32, ptr)
26
29
diff --git a/target/arm/vfp.decode b/target/arm/vfp.decode
27
- /* This is not complete, but is good enough for pickNaN. */
30
index XXXXXXX..XXXXXXX 100644
28
- a_cls = (!floatx80_is_any_nan(a)
31
--- a/target/arm/vfp.decode
29
- ? float_class_normal
32
+++ b/target/arm/vfp.decode
30
- : floatx80_is_signaling_nan(a, status)
33
@@ -XXX,XX +XXX,XX @@ VCVT_f64_f16 ---- 1110 1.11 0010 .... 1011 t:1 1.0 .... \
31
- ? float_class_snan
34
32
- : float_class_qnan);
35
# VCVTB and VCVTT to f16: Vd format is always vd_sp;
33
- b_cls = (!floatx80_is_any_nan(b)
36
# Vm format depends on size bit
34
- ? float_class_normal
37
+VCVT_b16_f32 ---- 1110 1.11 0011 .... 1001 t:1 1.0 .... \
35
- : floatx80_is_signaling_nan(b, status)
38
+ vd=%vd_sp vm=%vm_sp
36
- ? float_class_snan
39
VCVT_f16_f32 ---- 1110 1.11 0011 .... 1010 t:1 1.0 .... \
37
- : float_class_qnan);
40
vd=%vd_sp vm=%vm_sp
38
-
41
VCVT_f16_f64 ---- 1110 1.11 0011 .... 1011 t:1 1.0 .... \
39
- if (is_snan(a_cls) || is_snan(b_cls)) {
42
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
40
- float_raise(float_flag_invalid, status);
43
index XXXXXXX..XXXXXXX 100644
41
- }
44
--- a/target/arm/translate-a64.c
42
-
45
+++ b/target/arm/translate-a64.c
43
- if (status->default_nan_mode) {
46
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
44
+ if (!floatx80_unpack_canonical(&pa, a, status) ||
47
case 0x3: /* FSQRT */
45
+ !floatx80_unpack_canonical(&pb, b, status)) {
48
gen_helper_vfp_sqrts(tcg_res, tcg_op, cpu_env);
46
return floatx80_default_nan(status);
49
goto done;
47
}
50
+ case 0x6: /* BFCVT */
48
51
+ gen_fpst = gen_helper_bfcvt;
49
- if (a.low < b.low) {
52
+ break;
50
- aIsLargerSignificand = 0;
53
case 0x8: /* FRINTN */
51
- } else if (b.low < a.low) {
54
case 0x9: /* FRINTP */
52
- aIsLargerSignificand = 1;
55
case 0xa: /* FRINTM */
53
- } else {
56
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
54
- aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
57
}
55
- }
58
break;
56
-
59
57
- if (pickNaN(a_cls, b_cls, aIsLargerSignificand, status)) {
60
+ case 0x6:
58
- if (is_snan(b_cls)) {
61
+ switch (type) {
59
- return floatx80_silence_nan(b, status);
62
+ case 1: /* BFCVT */
60
- }
63
+ if (!dc_isar_feature(aa64_bf16, s)) {
61
- return b;
64
+ goto do_unallocated;
62
- } else {
65
+ }
63
- if (is_snan(a_cls)) {
66
+ if (!fp_access_check(s)) {
64
- return floatx80_silence_nan(a, status);
67
+ return;
65
- }
68
+ }
66
- return a;
69
+ handle_fp_1src_single(s, opcode, rd, rn);
67
- }
70
+ break;
68
+ pr = parts_pick_nan(&pa, &pb, status);
71
+ default:
69
+ return floatx80_round_pack_canonical(pr, status);
72
+ goto do_unallocated;
73
+ }
74
+ break;
75
+
76
default:
77
do_unallocated:
78
unallocated_encoding(s);
79
diff --git a/target/arm/translate-vfp.c b/target/arm/translate-vfp.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/arm/translate-vfp.c
82
+++ b/target/arm/translate-vfp.c
83
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
84
return true;
85
}
70
}
86
71
87
+static bool trans_VCVT_b16_f32(DisasContext *s, arg_VCVT_b16_f32 *a)
72
/*----------------------------------------------------------------------------
88
+{
89
+ TCGv_ptr fpst;
90
+ TCGv_i32 tmp;
91
+
92
+ if (!dc_isar_feature(aa32_bf16, s)) {
93
+ return false;
94
+ }
95
+
96
+ if (!vfp_access_check(s)) {
97
+ return true;
98
+ }
99
+
100
+ fpst = fpstatus_ptr(FPST_FPCR);
101
+ tmp = tcg_temp_new_i32();
102
+
103
+ vfp_load_reg32(tmp, a->vm);
104
+ gen_helper_bfcvt(tmp, tmp, fpst);
105
+ tcg_gen_st16_i32(tmp, cpu_env, vfp_f16_offset(a->vd, a->t));
106
+ tcg_temp_free_ptr(fpst);
107
+ tcg_temp_free_i32(tmp);
108
+ return true;
109
+}
110
+
111
static bool trans_VCVT_f16_f32(DisasContext *s, arg_VCVT_f16_f32 *a)
112
{
113
TCGv_ptr fpst;
114
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/vfp_helper.c
117
+++ b/target/arm/vfp_helper.c
118
@@ -XXX,XX +XXX,XX @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUARMState *env)
119
return float64_to_float32(x, &env->vfp.fp_status);
120
}
121
122
+uint32_t HELPER(bfcvt)(float32 x, void *status)
123
+{
124
+ return float32_to_bfloat16(x, status);
125
+}
126
+
127
/*
128
* VFP3 fixed point conversion. The AArch32 versions of fix-to-float
129
* must always round-to-nearest; the AArch64 ones honour the FPSCR
130
--
73
--
131
2.20.1
74
2.34.1
132
133
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
There is no reason to call the hvf specific hvf_cpu_synchronize_state()
3
Inline pickNaN into its only caller. This makes one assert
4
when we can just use the generic cpu_synchronize_state() instead. This
4
redundant with the immediately preceding IF.
5
allows us to have less dependency on internal function definitions and
5
6
allows us to make hvf_cpu_synchronize_state() static.
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Alexander Graf <agraf@csgraf.de>
8
Message-id: 20241203203949.483774-9-richard.henderson@linaro.org
9
Reviewed-by: Sergio Lopez <slp@redhat.com>
10
Message-id: 20210519202253.76782-9-agraf@csgraf.de
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
accel/hvf/hvf-accel-ops.h | 1 -
11
fpu/softfloat-parts.c.inc | 82 +++++++++++++++++++++++++----
15
accel/hvf/hvf-accel-ops.c | 2 +-
12
fpu/softfloat-specialize.c.inc | 96 ----------------------------------
16
target/i386/hvf/x86hvf.c | 9 ++++-----
13
2 files changed, 73 insertions(+), 105 deletions(-)
17
3 files changed, 5 insertions(+), 7 deletions(-)
14
18
15
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
19
diff --git a/accel/hvf/hvf-accel-ops.h b/accel/hvf/hvf-accel-ops.h
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/accel/hvf/hvf-accel-ops.h
17
--- a/fpu/softfloat-parts.c.inc
22
+++ b/accel/hvf/hvf-accel-ops.h
18
+++ b/fpu/softfloat-parts.c.inc
23
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
24
#include "sysemu/cpus.h"
20
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
25
21
float_status *s)
26
int hvf_vcpu_exec(CPUState *);
22
{
27
-void hvf_cpu_synchronize_state(CPUState *);
23
+ int cmp, which;
28
void hvf_cpu_synchronize_post_reset(CPUState *);
24
+
29
void hvf_cpu_synchronize_post_init(CPUState *);
25
if (is_snan(a->cls) || is_snan(b->cls)) {
30
void hvf_cpu_synchronize_pre_loadvm(CPUState *);
26
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
31
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
27
}
28
29
if (s->default_nan_mode) {
30
parts_default_nan(a, s);
31
- } else {
32
- int cmp = frac_cmp(a, b);
33
- if (cmp == 0) {
34
- cmp = a->sign < b->sign;
35
- }
36
+ return a;
37
+ }
38
39
- if (pickNaN(a->cls, b->cls, cmp > 0, s)) {
40
- a = b;
41
- }
42
+ cmp = frac_cmp(a, b);
43
+ if (cmp == 0) {
44
+ cmp = a->sign < b->sign;
45
+ }
46
+
47
+ switch (s->float_2nan_prop_rule) {
48
+ case float_2nan_prop_s_ab:
49
if (is_snan(a->cls)) {
50
- parts_silence_nan(a, s);
51
+ which = 0;
52
+ } else if (is_snan(b->cls)) {
53
+ which = 1;
54
+ } else if (is_qnan(a->cls)) {
55
+ which = 0;
56
+ } else {
57
+ which = 1;
58
}
59
+ break;
60
+ case float_2nan_prop_s_ba:
61
+ if (is_snan(b->cls)) {
62
+ which = 1;
63
+ } else if (is_snan(a->cls)) {
64
+ which = 0;
65
+ } else if (is_qnan(b->cls)) {
66
+ which = 1;
67
+ } else {
68
+ which = 0;
69
+ }
70
+ break;
71
+ case float_2nan_prop_ab:
72
+ which = is_nan(a->cls) ? 0 : 1;
73
+ break;
74
+ case float_2nan_prop_ba:
75
+ which = is_nan(b->cls) ? 1 : 0;
76
+ break;
77
+ case float_2nan_prop_x87:
78
+ /*
79
+ * This implements x87 NaN propagation rules:
80
+ * SNaN + QNaN => return the QNaN
81
+ * two SNaNs => return the one with the larger significand, silenced
82
+ * two QNaNs => return the one with the larger significand
83
+ * SNaN and a non-NaN => return the SNaN, silenced
84
+ * QNaN and a non-NaN => return the QNaN
85
+ *
86
+ * If we get down to comparing significands and they are the same,
87
+ * return the NaN with the positive sign bit (if any).
88
+ */
89
+ if (is_snan(a->cls)) {
90
+ if (is_snan(b->cls)) {
91
+ which = cmp > 0 ? 0 : 1;
92
+ } else {
93
+ which = is_qnan(b->cls) ? 1 : 0;
94
+ }
95
+ } else if (is_qnan(a->cls)) {
96
+ if (is_snan(b->cls) || !is_qnan(b->cls)) {
97
+ which = 0;
98
+ } else {
99
+ which = cmp > 0 ? 0 : 1;
100
+ }
101
+ } else {
102
+ which = 1;
103
+ }
104
+ break;
105
+ default:
106
+ g_assert_not_reached();
107
+ }
108
+
109
+ if (which) {
110
+ a = b;
111
+ }
112
+ if (is_snan(a->cls)) {
113
+ parts_silence_nan(a, s);
114
}
115
return a;
116
}
117
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
32
index XXXXXXX..XXXXXXX 100644
118
index XXXXXXX..XXXXXXX 100644
33
--- a/accel/hvf/hvf-accel-ops.c
119
--- a/fpu/softfloat-specialize.c.inc
34
+++ b/accel/hvf/hvf-accel-ops.c
120
+++ b/fpu/softfloat-specialize.c.inc
35
@@ -XXX,XX +XXX,XX @@ static void do_hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
121
@@ -XXX,XX +XXX,XX @@ bool float32_is_signaling_nan(float32 a_, float_status *status)
36
}
122
}
37
}
123
}
38
124
39
-void hvf_cpu_synchronize_state(CPUState *cpu)
125
-/*----------------------------------------------------------------------------
40
+static void hvf_cpu_synchronize_state(CPUState *cpu)
126
-| Select which NaN to propagate for a two-input operation.
41
{
127
-| IEEE754 doesn't specify all the details of this, so the
42
if (!cpu->vcpu_dirty) {
128
-| algorithm is target-specific.
43
run_on_cpu(cpu, do_hvf_cpu_synchronize_state, RUN_ON_CPU_NULL);
129
-| The routine is passed various bits of information about the
44
diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c
130
-| two NaNs and should return 0 to select NaN a and 1 for NaN b.
45
index XXXXXXX..XXXXXXX 100644
131
-| Note that signalling NaNs are always squashed to quiet NaNs
46
--- a/target/i386/hvf/x86hvf.c
132
-| by the caller, by calling floatXX_silence_nan() before
47
+++ b/target/i386/hvf/x86hvf.c
133
-| returning them.
48
@@ -XXX,XX +XXX,XX @@
134
-|
49
#include "cpu.h"
135
-| aIsLargerSignificand is only valid if both a and b are NaNs
50
#include "x86_descr.h"
136
-| of some kind, and is true if a has the larger significand,
51
#include "x86_decode.h"
137
-| or if both a and b have the same significand but a is
52
+#include "sysemu/hw_accel.h"
138
-| positive but b is negative. It is only needed for the x87
53
139
-| tie-break rule.
54
#include "hw/i386/apic_internal.h"
140
-*----------------------------------------------------------------------------*/
55
56
#include <Hypervisor/hv.h>
57
#include <Hypervisor/hv_vmx.h>
58
59
-#include "accel/hvf/hvf-accel-ops.h"
60
-
141
-
61
void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg,
142
-static int pickNaN(FloatClass a_cls, FloatClass b_cls,
62
SegmentCache *qseg, bool is_tr)
143
- bool aIsLargerSignificand, float_status *status)
63
{
144
-{
64
@@ -XXX,XX +XXX,XX @@ int hvf_process_events(CPUState *cpu_state)
145
- /*
65
env->eflags = rreg(cpu_state->hvf_fd, HV_X86_RFLAGS);
146
- * We guarantee not to require the target to tell us how to
66
147
- * pick a NaN if we're always returning the default NaN.
67
if (cpu_state->interrupt_request & CPU_INTERRUPT_INIT) {
148
- * But if we're not in default-NaN mode then the target must
68
- hvf_cpu_synchronize_state(cpu_state);
149
- * specify via set_float_2nan_prop_rule().
69
+ cpu_synchronize_state(cpu_state);
150
- */
70
do_cpu_init(cpu);
151
- assert(!status->default_nan_mode);
71
}
152
-
72
153
- switch (status->float_2nan_prop_rule) {
73
@@ -XXX,XX +XXX,XX @@ int hvf_process_events(CPUState *cpu_state)
154
- case float_2nan_prop_s_ab:
74
cpu_state->halted = 0;
155
- if (is_snan(a_cls)) {
75
}
156
- return 0;
76
if (cpu_state->interrupt_request & CPU_INTERRUPT_SIPI) {
157
- } else if (is_snan(b_cls)) {
77
- hvf_cpu_synchronize_state(cpu_state);
158
- return 1;
78
+ cpu_synchronize_state(cpu_state);
159
- } else if (is_qnan(a_cls)) {
79
do_cpu_sipi(cpu);
160
- return 0;
80
}
161
- } else {
81
if (cpu_state->interrupt_request & CPU_INTERRUPT_TPR) {
162
- return 1;
82
cpu_state->interrupt_request &= ~CPU_INTERRUPT_TPR;
163
- }
83
- hvf_cpu_synchronize_state(cpu_state);
164
- break;
84
+ cpu_synchronize_state(cpu_state);
165
- case float_2nan_prop_s_ba:
85
apic_handle_tpr_access_report(cpu->apic_state, env->eip,
166
- if (is_snan(b_cls)) {
86
env->tpr_access_type);
167
- return 1;
87
}
168
- } else if (is_snan(a_cls)) {
169
- return 0;
170
- } else if (is_qnan(b_cls)) {
171
- return 1;
172
- } else {
173
- return 0;
174
- }
175
- break;
176
- case float_2nan_prop_ab:
177
- if (is_nan(a_cls)) {
178
- return 0;
179
- } else {
180
- return 1;
181
- }
182
- break;
183
- case float_2nan_prop_ba:
184
- if (is_nan(b_cls)) {
185
- return 1;
186
- } else {
187
- return 0;
188
- }
189
- break;
190
- case float_2nan_prop_x87:
191
- /*
192
- * This implements x87 NaN propagation rules:
193
- * SNaN + QNaN => return the QNaN
194
- * two SNaNs => return the one with the larger significand, silenced
195
- * two QNaNs => return the one with the larger significand
196
- * SNaN and a non-NaN => return the SNaN, silenced
197
- * QNaN and a non-NaN => return the QNaN
198
- *
199
- * If we get down to comparing significands and they are the same,
200
- * return the NaN with the positive sign bit (if any).
201
- */
202
- if (is_snan(a_cls)) {
203
- if (is_snan(b_cls)) {
204
- return aIsLargerSignificand ? 0 : 1;
205
- }
206
- return is_qnan(b_cls) ? 1 : 0;
207
- } else if (is_qnan(a_cls)) {
208
- if (is_snan(b_cls) || !is_qnan(b_cls)) {
209
- return 0;
210
- } else {
211
- return aIsLargerSignificand ? 0 : 1;
212
- }
213
- } else {
214
- return 1;
215
- }
216
- default:
217
- g_assert_not_reached();
218
- }
219
-}
220
-
221
/*----------------------------------------------------------------------------
222
| Returns 1 if the double-precision floating-point value `a' is a quiet
223
| NaN; otherwise returns 0.
88
--
224
--
89
2.20.1
225
2.34.1
90
226
91
227
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Remember if there was an SNaN, and use that to simplify
4
float_2nan_prop_s_{ab,ba} to only the snan component.
5
Then, fall through to the corresponding
6
float_2nan_prop_{ab,ba} case to handle any remaining
7
nans, which must be quiet.
8
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20241203203949.483774-10-richard.henderson@linaro.org
5
Message-id: 20210525225817.400336-3-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
13
---
8
target/arm/translate-a64.c | 15 ++++++---------
14
fpu/softfloat-parts.c.inc | 32 ++++++++++++--------------------
9
1 file changed, 6 insertions(+), 9 deletions(-)
15
1 file changed, 12 insertions(+), 20 deletions(-)
10
16
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
19
--- a/fpu/softfloat-parts.c.inc
14
+++ b/target/arm/translate-a64.c
20
+++ b/fpu/softfloat-parts.c.inc
15
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
21
@@ -XXX,XX +XXX,XX @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
16
int rd = extract32(insn, 0, 5);
22
static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
17
23
float_status *s)
18
if (mos) {
24
{
19
- unallocated_encoding(s);
25
+ bool have_snan = false;
20
- return;
26
int cmp, which;
21
+ goto do_unallocated;
27
28
if (is_snan(a->cls) || is_snan(b->cls)) {
29
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
30
+ have_snan = true;
22
}
31
}
23
32
24
switch (opcode) {
33
if (s->default_nan_mode) {
25
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
34
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
26
/* FCVT between half, single and double precision */
35
27
int dtype = extract32(opcode, 0, 2);
36
switch (s->float_2nan_prop_rule) {
28
if (type == 2 || dtype == type) {
37
case float_2nan_prop_s_ab:
29
- unallocated_encoding(s);
38
- if (is_snan(a->cls)) {
30
- return;
39
- which = 0;
31
+ goto do_unallocated;
40
- } else if (is_snan(b->cls)) {
41
- which = 1;
42
- } else if (is_qnan(a->cls)) {
43
- which = 0;
44
- } else {
45
- which = 1;
46
+ if (have_snan) {
47
+ which = is_snan(a->cls) ? 0 : 1;
48
+ break;
32
}
49
}
33
if (!fp_access_check(s)) {
50
- break;
34
return;
51
- case float_2nan_prop_s_ba:
35
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
52
- if (is_snan(b->cls)) {
36
53
- which = 1;
37
case 0x10 ... 0x13: /* FRINT{32,64}{X,Z} */
54
- } else if (is_snan(a->cls)) {
38
if (type > 1 || !dc_isar_feature(aa64_frint, s)) {
55
- which = 0;
39
- unallocated_encoding(s);
56
- } else if (is_qnan(b->cls)) {
40
- return;
57
- which = 1;
41
+ goto do_unallocated;
58
- } else {
42
}
59
- which = 0;
43
/* fall through */
60
- }
44
case 0x0 ... 0x3:
61
- break;
45
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
62
+ /* fall through */
46
break;
63
case float_2nan_prop_ab:
47
case 3:
64
which = is_nan(a->cls) ? 0 : 1;
48
if (!dc_isar_feature(aa64_fp16, s)) {
49
- unallocated_encoding(s);
50
- return;
51
+ goto do_unallocated;
52
}
53
54
if (!fp_access_check(s)) {
55
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
56
handle_fp_1src_half(s, opcode, rd, rn);
57
break;
58
default:
59
- unallocated_encoding(s);
60
+ goto do_unallocated;
61
}
62
break;
65
break;
63
66
+ case float_2nan_prop_s_ba:
64
default:
67
+ if (have_snan) {
65
+ do_unallocated:
68
+ which = is_snan(b->cls) ? 1 : 0;
66
unallocated_encoding(s);
69
+ break;
70
+ }
71
+ /* fall through */
72
case float_2nan_prop_ba:
73
which = is_nan(b->cls) ? 1 : 0;
67
break;
74
break;
68
}
69
--
75
--
70
2.20.1
76
2.34.1
71
72
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
For Arm BFDOT and BFMMLA, we need a version of round-to-odd
3
Move the fractional comparison to the end of the
4
that overflows to infinity, instead of the max normal number.
4
float_2nan_prop_x87 case. This is not required for
5
any other 2nan propagation rule. Reorganize the
6
x87 case itself to break out of the switch when the
7
fractional comparison is not required.
5
8
6
Cc: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210525225817.400336-6-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20241203203949.483774-11-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
include/fpu/softfloat-types.h | 4 +++-
14
fpu/softfloat-parts.c.inc | 19 +++++++++----------
13
fpu/softfloat-parts.c.inc | 6 ++++--
15
1 file changed, 9 insertions(+), 10 deletions(-)
14
2 files changed, 7 insertions(+), 3 deletions(-)
15
16
16
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/fpu/softfloat-types.h
19
+++ b/include/fpu/softfloat-types.h
20
@@ -XXX,XX +XXX,XX @@ typedef enum __attribute__((__packed__)) {
21
float_round_up = 2,
22
float_round_to_zero = 3,
23
float_round_ties_away = 4,
24
- /* Not an IEEE rounding mode: round to the closest odd mantissa value */
25
+ /* Not an IEEE rounding mode: round to closest odd, overflow to max */
26
float_round_to_odd = 5,
27
+ /* Not an IEEE rounding mode: round to closest odd, overflow to inf */
28
+ float_round_to_odd_inf = 6,
29
} FloatRoundMode;
30
31
/*
32
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
17
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
33
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
34
--- a/fpu/softfloat-parts.c.inc
19
--- a/fpu/softfloat-parts.c.inc
35
+++ b/fpu/softfloat-parts.c.inc
20
+++ b/fpu/softfloat-parts.c.inc
36
@@ -XXX,XX +XXX,XX @@ static void partsN(uncanon)(FloatPartsN *p, float_status *s,
21
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
37
g_assert_not_reached();
22
return a;
38
}
23
}
39
24
40
+ overflow_norm = false;
25
- cmp = frac_cmp(a, b);
41
switch (s->float_rounding_mode) {
26
- if (cmp == 0) {
42
case float_round_nearest_even:
27
- cmp = a->sign < b->sign;
43
- overflow_norm = false;
28
- }
44
inc = ((p->frac_lo & roundeven_mask) != frac_lsbm1 ? frac_lsbm1 : 0);
29
-
45
break;
30
switch (s->float_2nan_prop_rule) {
46
case float_round_ties_away:
31
case float_2nan_prop_s_ab:
47
- overflow_norm = false;
32
if (have_snan) {
48
inc = frac_lsbm1;
33
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
49
break;
34
* return the NaN with the positive sign bit (if any).
50
case float_round_to_zero:
35
*/
51
@@ -XXX,XX +XXX,XX @@ static void partsN(uncanon)(FloatPartsN *p, float_status *s,
36
if (is_snan(a->cls)) {
52
break;
37
- if (is_snan(b->cls)) {
53
case float_round_to_odd:
38
- which = cmp > 0 ? 0 : 1;
54
overflow_norm = true;
39
- } else {
55
+ /* fall through */
40
+ if (!is_snan(b->cls)) {
56
+ case float_round_to_odd_inf:
41
which = is_qnan(b->cls) ? 1 : 0;
57
inc = p->frac_lo & frac_lsb ? 0 : round_mask;
42
+ break;
43
}
44
} else if (is_qnan(a->cls)) {
45
if (is_snan(b->cls) || !is_qnan(b->cls)) {
46
which = 0;
47
- } else {
48
- which = cmp > 0 ? 0 : 1;
49
+ break;
50
}
51
} else {
52
which = 1;
53
+ break;
54
}
55
+ cmp = frac_cmp(a, b);
56
+ if (cmp == 0) {
57
+ cmp = a->sign < b->sign;
58
+ }
59
+ which = cmp > 0 ? 0 : 1;
58
break;
60
break;
59
default:
61
default:
60
@@ -XXX,XX +XXX,XX @@ static void partsN(uncanon)(FloatPartsN *p, float_status *s,
62
g_assert_not_reached();
61
? frac_lsbm1 : 0);
62
break;
63
case float_round_to_odd:
64
+ case float_round_to_odd_inf:
65
inc = p->frac_lo & frac_lsb ? 0 : round_mask;
66
break;
67
default:
68
--
63
--
69
2.20.1
64
2.34.1
70
71
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@csgraf.de>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We will need more than a single field for hvf going forward. To keep
3
Replace the "index" selecting between A and B with a result variable
4
the global vcpu struct uncluttered, let's allocate a special hvf vcpu
4
of the proper type. This improves clarity within the function.
5
struct, similar to how hax does it.
6
5
7
Signed-off-by: Alexander Graf <agraf@csgraf.de>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Tested-by: Roman Bolshakov <r.bolshakov@yadro.com>
8
Message-id: 20241203203949.483774-12-richard.henderson@linaro.org
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Sergio Lopez <slp@redhat.com>
12
Message-id: 20210519202253.76782-12-agraf@csgraf.de
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
include/hw/core/cpu.h | 3 +-
11
fpu/softfloat-parts.c.inc | 28 +++++++++++++---------------
17
include/sysemu/hvf_int.h | 4 +
12
1 file changed, 13 insertions(+), 15 deletions(-)
18
target/i386/hvf/vmx.h | 24 +++--
19
accel/hvf/hvf-accel-ops.c | 8 +-
20
target/i386/hvf/hvf.c | 104 +++++++++---------
21
target/i386/hvf/x86.c | 28 ++---
22
target/i386/hvf/x86_descr.c | 26 ++---
23
target/i386/hvf/x86_emu.c | 62 +++++------
24
target/i386/hvf/x86_mmu.c | 4 +-
25
target/i386/hvf/x86_task.c | 12 +--
26
target/i386/hvf/x86hvf.c | 210 ++++++++++++++++++------------------
27
11 files changed, 248 insertions(+), 237 deletions(-)
28
13
29
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
14
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
30
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/core/cpu.h
16
--- a/fpu/softfloat-parts.c.inc
32
+++ b/include/hw/core/cpu.h
17
+++ b/fpu/softfloat-parts.c.inc
33
@@ -XXX,XX +XXX,XX @@ struct KVMState;
18
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
34
struct kvm_run;
19
float_status *s)
35
36
struct hax_vcpu_state;
37
+struct hvf_vcpu_state;
38
39
#define TB_JMP_CACHE_BITS 12
40
#define TB_JMP_CACHE_SIZE (1 << TB_JMP_CACHE_BITS)
41
@@ -XXX,XX +XXX,XX @@ struct CPUState {
42
43
struct hax_vcpu_state *hax_vcpu;
44
45
- int hvf_fd;
46
+ struct hvf_vcpu_state *hvf;
47
48
/* track IOMMUs whose translations we've cached in the TCG TLB */
49
GArray *iommu_notifiers;
50
diff --git a/include/sysemu/hvf_int.h b/include/sysemu/hvf_int.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/include/sysemu/hvf_int.h
53
+++ b/include/sysemu/hvf_int.h
54
@@ -XXX,XX +XXX,XX @@ struct HVFState {
55
};
56
extern HVFState *hvf_state;
57
58
+struct hvf_vcpu_state {
59
+ int fd;
60
+};
61
+
62
void assert_hvf_ok(hv_return_t ret);
63
int hvf_arch_init_vcpu(CPUState *cpu);
64
void hvf_arch_vcpu_destroy(CPUState *cpu);
65
diff --git a/target/i386/hvf/vmx.h b/target/i386/hvf/vmx.h
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/i386/hvf/vmx.h
68
+++ b/target/i386/hvf/vmx.h
69
@@ -XXX,XX +XXX,XX @@
70
#include "vmcs.h"
71
#include "cpu.h"
72
#include "x86.h"
73
+#include "sysemu/hvf.h"
74
+#include "sysemu/hvf_int.h"
75
76
#include "exec/address-spaces.h"
77
78
@@ -XXX,XX +XXX,XX @@ static inline void macvm_set_rip(CPUState *cpu, uint64_t rip)
79
uint64_t val;
80
81
/* BUG, should take considering overlap.. */
82
- wreg(cpu->hvf_fd, HV_X86_RIP, rip);
83
+ wreg(cpu->hvf->fd, HV_X86_RIP, rip);
84
env->eip = rip;
85
86
/* after moving forward in rip, we need to clean INTERRUPTABILITY */
87
- val = rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY);
88
+ val = rvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY);
89
if (val & (VMCS_INTERRUPTIBILITY_STI_BLOCKING |
90
VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING)) {
91
env->hflags &= ~HF_INHIBIT_IRQ_MASK;
92
- wvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY,
93
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY,
94
val & ~(VMCS_INTERRUPTIBILITY_STI_BLOCKING |
95
VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING));
96
}
97
@@ -XXX,XX +XXX,XX @@ static inline void vmx_clear_nmi_blocking(CPUState *cpu)
98
CPUX86State *env = &x86_cpu->env;
99
100
env->hflags2 &= ~HF2_NMI_MASK;
101
- uint32_t gi = (uint32_t) rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY);
102
+ uint32_t gi = (uint32_t) rvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY);
103
gi &= ~VMCS_INTERRUPTIBILITY_NMI_BLOCKING;
104
- wvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY, gi);
105
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY, gi);
106
}
107
108
static inline void vmx_set_nmi_blocking(CPUState *cpu)
109
@@ -XXX,XX +XXX,XX @@ static inline void vmx_set_nmi_blocking(CPUState *cpu)
110
CPUX86State *env = &x86_cpu->env;
111
112
env->hflags2 |= HF2_NMI_MASK;
113
- uint32_t gi = (uint32_t)rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY);
114
+ uint32_t gi = (uint32_t)rvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY);
115
gi |= VMCS_INTERRUPTIBILITY_NMI_BLOCKING;
116
- wvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY, gi);
117
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY, gi);
118
}
119
120
static inline void vmx_set_nmi_window_exiting(CPUState *cpu)
121
{
20
{
122
uint64_t val;
21
bool have_snan = false;
123
- val = rvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS);
22
- int cmp, which;
124
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val |
23
+ FloatPartsN *ret;
125
+ val = rvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS);
24
+ int cmp;
126
+ wvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS, val |
25
127
VMCS_PRI_PROC_BASED_CTLS_NMI_WINDOW_EXITING);
26
if (is_snan(a->cls) || is_snan(b->cls)) {
128
27
float_raise(float_flag_invalid | float_flag_invalid_snan, s);
129
}
28
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
130
@@ -XXX,XX +XXX,XX @@ static inline void vmx_clear_nmi_window_exiting(CPUState *cpu)
29
switch (s->float_2nan_prop_rule) {
131
{
30
case float_2nan_prop_s_ab:
132
31
if (have_snan) {
133
uint64_t val;
32
- which = is_snan(a->cls) ? 0 : 1;
134
- val = rvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS);
33
+ ret = is_snan(a->cls) ? a : b;
135
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val &
136
+ val = rvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS);
137
+ wvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS, val &
138
~VMCS_PRI_PROC_BASED_CTLS_NMI_WINDOW_EXITING);
139
}
140
141
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
142
index XXXXXXX..XXXXXXX 100644
143
--- a/accel/hvf/hvf-accel-ops.c
144
+++ b/accel/hvf/hvf-accel-ops.c
145
@@ -XXX,XX +XXX,XX @@ type_init(hvf_type_init);
146
147
static void hvf_vcpu_destroy(CPUState *cpu)
148
{
149
- hv_return_t ret = hv_vcpu_destroy(cpu->hvf_fd);
150
+ hv_return_t ret = hv_vcpu_destroy(cpu->hvf->fd);
151
assert_hvf_ok(ret);
152
153
hvf_arch_vcpu_destroy(cpu);
154
+ g_free(cpu->hvf);
155
+ cpu->hvf = NULL;
156
}
157
158
static int hvf_init_vcpu(CPUState *cpu)
159
{
160
int r;
161
162
+ cpu->hvf = g_malloc0(sizeof(*cpu->hvf));
163
+
164
/* init cpu signals */
165
sigset_t set;
166
struct sigaction sigact;
167
@@ -XXX,XX +XXX,XX @@ static int hvf_init_vcpu(CPUState *cpu)
168
pthread_sigmask(SIG_BLOCK, NULL, &set);
169
sigdelset(&set, SIG_IPI);
170
171
- r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf_fd, HV_VCPU_DEFAULT);
172
+ r = hv_vcpu_create((hv_vcpuid_t *)&cpu->hvf->fd, HV_VCPU_DEFAULT);
173
cpu->vcpu_dirty = 1;
174
assert_hvf_ok(r);
175
176
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
177
index XXXXXXX..XXXXXXX 100644
178
--- a/target/i386/hvf/hvf.c
179
+++ b/target/i386/hvf/hvf.c
180
@@ -XXX,XX +XXX,XX @@ void vmx_update_tpr(CPUState *cpu)
181
int tpr = cpu_get_apic_tpr(x86_cpu->apic_state) << 4;
182
int irr = apic_get_highest_priority_irr(x86_cpu->apic_state);
183
184
- wreg(cpu->hvf_fd, HV_X86_TPR, tpr);
185
+ wreg(cpu->hvf->fd, HV_X86_TPR, tpr);
186
if (irr == -1) {
187
- wvmcs(cpu->hvf_fd, VMCS_TPR_THRESHOLD, 0);
188
+ wvmcs(cpu->hvf->fd, VMCS_TPR_THRESHOLD, 0);
189
} else {
190
- wvmcs(cpu->hvf_fd, VMCS_TPR_THRESHOLD, (irr > tpr) ? tpr >> 4 :
191
+ wvmcs(cpu->hvf->fd, VMCS_TPR_THRESHOLD, (irr > tpr) ? tpr >> 4 :
192
irr >> 4);
193
}
194
}
195
@@ -XXX,XX +XXX,XX @@ void vmx_update_tpr(CPUState *cpu)
196
static void update_apic_tpr(CPUState *cpu)
197
{
198
X86CPU *x86_cpu = X86_CPU(cpu);
199
- int tpr = rreg(cpu->hvf_fd, HV_X86_TPR) >> 4;
200
+ int tpr = rreg(cpu->hvf->fd, HV_X86_TPR) >> 4;
201
cpu_set_apic_tpr(x86_cpu->apic_state, tpr);
202
}
203
204
@@ -XXX,XX +XXX,XX @@ int hvf_arch_init_vcpu(CPUState *cpu)
205
}
206
207
/* set VMCS control fields */
208
- wvmcs(cpu->hvf_fd, VMCS_PIN_BASED_CTLS,
209
+ wvmcs(cpu->hvf->fd, VMCS_PIN_BASED_CTLS,
210
cap2ctrl(hvf_state->hvf_caps->vmx_cap_pinbased,
211
VMCS_PIN_BASED_CTLS_EXTINT |
212
VMCS_PIN_BASED_CTLS_NMI |
213
VMCS_PIN_BASED_CTLS_VNMI));
214
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS,
215
+ wvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS,
216
cap2ctrl(hvf_state->hvf_caps->vmx_cap_procbased,
217
VMCS_PRI_PROC_BASED_CTLS_HLT |
218
VMCS_PRI_PROC_BASED_CTLS_MWAIT |
219
VMCS_PRI_PROC_BASED_CTLS_TSC_OFFSET |
220
VMCS_PRI_PROC_BASED_CTLS_TPR_SHADOW) |
221
VMCS_PRI_PROC_BASED_CTLS_SEC_CONTROL);
222
- wvmcs(cpu->hvf_fd, VMCS_SEC_PROC_BASED_CTLS,
223
+ wvmcs(cpu->hvf->fd, VMCS_SEC_PROC_BASED_CTLS,
224
cap2ctrl(hvf_state->hvf_caps->vmx_cap_procbased2,
225
VMCS_PRI_PROC_BASED2_CTLS_APIC_ACCESSES));
226
227
- wvmcs(cpu->hvf_fd, VMCS_ENTRY_CTLS, cap2ctrl(hvf_state->hvf_caps->vmx_cap_entry,
228
+ wvmcs(cpu->hvf->fd, VMCS_ENTRY_CTLS, cap2ctrl(hvf_state->hvf_caps->vmx_cap_entry,
229
0));
230
- wvmcs(cpu->hvf_fd, VMCS_EXCEPTION_BITMAP, 0); /* Double fault */
231
+ wvmcs(cpu->hvf->fd, VMCS_EXCEPTION_BITMAP, 0); /* Double fault */
232
233
- wvmcs(cpu->hvf_fd, VMCS_TPR_THRESHOLD, 0);
234
+ wvmcs(cpu->hvf->fd, VMCS_TPR_THRESHOLD, 0);
235
236
x86cpu = X86_CPU(cpu);
237
x86cpu->env.xsave_buf = qemu_memalign(4096, 4096);
238
239
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_STAR, 1);
240
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_LSTAR, 1);
241
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_CSTAR, 1);
242
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_FMASK, 1);
243
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_FSBASE, 1);
244
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_GSBASE, 1);
245
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_KERNELGSBASE, 1);
246
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_TSC_AUX, 1);
247
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_TSC, 1);
248
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_SYSENTER_CS, 1);
249
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_SYSENTER_EIP, 1);
250
- hv_vcpu_enable_native_msr(cpu->hvf_fd, MSR_IA32_SYSENTER_ESP, 1);
251
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_STAR, 1);
252
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_LSTAR, 1);
253
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_CSTAR, 1);
254
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_FMASK, 1);
255
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_FSBASE, 1);
256
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_GSBASE, 1);
257
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_KERNELGSBASE, 1);
258
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_TSC_AUX, 1);
259
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_IA32_TSC, 1);
260
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_IA32_SYSENTER_CS, 1);
261
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_IA32_SYSENTER_EIP, 1);
262
+ hv_vcpu_enable_native_msr(cpu->hvf->fd, MSR_IA32_SYSENTER_ESP, 1);
263
264
return 0;
265
}
266
@@ -XXX,XX +XXX,XX @@ static void hvf_store_events(CPUState *cpu, uint32_t ins_len, uint64_t idtvec_in
267
}
268
if (idtvec_info & VMCS_IDT_VEC_ERRCODE_VALID) {
269
env->has_error_code = true;
270
- env->error_code = rvmcs(cpu->hvf_fd, VMCS_IDT_VECTORING_ERROR);
271
+ env->error_code = rvmcs(cpu->hvf->fd, VMCS_IDT_VECTORING_ERROR);
272
}
273
}
274
- if ((rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY) &
275
+ if ((rvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY) &
276
VMCS_INTERRUPTIBILITY_NMI_BLOCKING)) {
277
env->hflags2 |= HF2_NMI_MASK;
278
} else {
279
env->hflags2 &= ~HF2_NMI_MASK;
280
}
281
- if (rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY) &
282
+ if (rvmcs(cpu->hvf->fd, VMCS_GUEST_INTERRUPTIBILITY) &
283
(VMCS_INTERRUPTIBILITY_STI_BLOCKING |
284
VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING)) {
285
env->hflags |= HF_INHIBIT_IRQ_MASK;
286
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
287
return EXCP_HLT;
288
}
289
290
- hv_return_t r = hv_vcpu_run(cpu->hvf_fd);
291
+ hv_return_t r = hv_vcpu_run(cpu->hvf->fd);
292
assert_hvf_ok(r);
293
294
/* handle VMEXIT */
295
- uint64_t exit_reason = rvmcs(cpu->hvf_fd, VMCS_EXIT_REASON);
296
- uint64_t exit_qual = rvmcs(cpu->hvf_fd, VMCS_EXIT_QUALIFICATION);
297
- uint32_t ins_len = (uint32_t)rvmcs(cpu->hvf_fd,
298
+ uint64_t exit_reason = rvmcs(cpu->hvf->fd, VMCS_EXIT_REASON);
299
+ uint64_t exit_qual = rvmcs(cpu->hvf->fd, VMCS_EXIT_QUALIFICATION);
300
+ uint32_t ins_len = (uint32_t)rvmcs(cpu->hvf->fd,
301
VMCS_EXIT_INSTRUCTION_LENGTH);
302
303
- uint64_t idtvec_info = rvmcs(cpu->hvf_fd, VMCS_IDT_VECTORING_INFO);
304
+ uint64_t idtvec_info = rvmcs(cpu->hvf->fd, VMCS_IDT_VECTORING_INFO);
305
306
hvf_store_events(cpu, ins_len, idtvec_info);
307
- rip = rreg(cpu->hvf_fd, HV_X86_RIP);
308
- env->eflags = rreg(cpu->hvf_fd, HV_X86_RFLAGS);
309
+ rip = rreg(cpu->hvf->fd, HV_X86_RIP);
310
+ env->eflags = rreg(cpu->hvf->fd, HV_X86_RFLAGS);
311
312
qemu_mutex_lock_iothread();
313
314
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
315
case EXIT_REASON_EPT_FAULT:
316
{
317
hvf_slot *slot;
318
- uint64_t gpa = rvmcs(cpu->hvf_fd, VMCS_GUEST_PHYSICAL_ADDRESS);
319
+ uint64_t gpa = rvmcs(cpu->hvf->fd, VMCS_GUEST_PHYSICAL_ADDRESS);
320
321
if (((idtvec_info & VMCS_IDT_VEC_VALID) == 0) &&
322
((exit_qual & EXIT_QUAL_NMIUDTI) != 0)) {
323
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
324
store_regs(cpu);
325
break;
326
} else if (!string && !in) {
327
- RAX(env) = rreg(cpu->hvf_fd, HV_X86_RAX);
328
+ RAX(env) = rreg(cpu->hvf->fd, HV_X86_RAX);
329
hvf_handle_io(env, port, &RAX(env), 1, size, 1);
330
macvm_set_rip(cpu, rip + ins_len);
331
break;
332
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
333
break;
34
break;
334
}
35
}
335
case EXIT_REASON_CPUID: {
36
/* fall through */
336
- uint32_t rax = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RAX);
37
case float_2nan_prop_ab:
337
- uint32_t rbx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RBX);
38
- which = is_nan(a->cls) ? 0 : 1;
338
- uint32_t rcx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RCX);
39
+ ret = is_nan(a->cls) ? a : b;
339
- uint32_t rdx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RDX);
40
break;
340
+ uint32_t rax = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RAX);
41
case float_2nan_prop_s_ba:
341
+ uint32_t rbx = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RBX);
42
if (have_snan) {
342
+ uint32_t rcx = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RCX);
43
- which = is_snan(b->cls) ? 1 : 0;
343
+ uint32_t rdx = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RDX);
44
+ ret = is_snan(b->cls) ? b : a;
344
345
if (rax == 1) {
346
/* CPUID1.ecx.OSXSAVE needs to know CR4 */
347
- env->cr[4] = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR4);
348
+ env->cr[4] = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR4);
349
}
350
hvf_cpu_x86_cpuid(env, rax, rcx, &rax, &rbx, &rcx, &rdx);
351
352
- wreg(cpu->hvf_fd, HV_X86_RAX, rax);
353
- wreg(cpu->hvf_fd, HV_X86_RBX, rbx);
354
- wreg(cpu->hvf_fd, HV_X86_RCX, rcx);
355
- wreg(cpu->hvf_fd, HV_X86_RDX, rdx);
356
+ wreg(cpu->hvf->fd, HV_X86_RAX, rax);
357
+ wreg(cpu->hvf->fd, HV_X86_RBX, rbx);
358
+ wreg(cpu->hvf->fd, HV_X86_RCX, rcx);
359
+ wreg(cpu->hvf->fd, HV_X86_RDX, rdx);
360
361
macvm_set_rip(cpu, rip + ins_len);
362
break;
45
break;
363
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
46
}
364
case EXIT_REASON_XSETBV: {
47
/* fall through */
365
X86CPU *x86_cpu = X86_CPU(cpu);
48
case float_2nan_prop_ba:
366
CPUX86State *env = &x86_cpu->env;
49
- which = is_nan(b->cls) ? 1 : 0;
367
- uint32_t eax = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RAX);
50
+ ret = is_nan(b->cls) ? b : a;
368
- uint32_t ecx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RCX);
51
break;
369
- uint32_t edx = (uint32_t)rreg(cpu->hvf_fd, HV_X86_RDX);
52
case float_2nan_prop_x87:
370
+ uint32_t eax = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RAX);
53
/*
371
+ uint32_t ecx = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RCX);
54
@@ -XXX,XX +XXX,XX @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
372
+ uint32_t edx = (uint32_t)rreg(cpu->hvf->fd, HV_X86_RDX);
55
*/
373
56
if (is_snan(a->cls)) {
374
if (ecx) {
57
if (!is_snan(b->cls)) {
375
macvm_set_rip(cpu, rip + ins_len);
58
- which = is_qnan(b->cls) ? 1 : 0;
59
+ ret = is_qnan(b->cls) ? b : a;
376
break;
60
break;
377
}
61
}
378
env->xcr0 = ((uint64_t)edx << 32) | eax;
62
} else if (is_qnan(a->cls)) {
379
- wreg(cpu->hvf_fd, HV_X86_XCR0, env->xcr0 | 1);
63
if (is_snan(b->cls) || !is_qnan(b->cls)) {
380
+ wreg(cpu->hvf->fd, HV_X86_XCR0, env->xcr0 | 1);
64
- which = 0;
381
macvm_set_rip(cpu, rip + ins_len);
65
+ ret = a;
66
break;
67
}
68
} else {
69
- which = 1;
70
+ ret = b;
382
break;
71
break;
383
}
72
}
384
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
73
cmp = frac_cmp(a, b);
385
74
if (cmp == 0) {
386
switch (cr) {
75
cmp = a->sign < b->sign;
387
case 0x0: {
388
- macvm_set_cr0(cpu->hvf_fd, RRX(env, reg));
389
+ macvm_set_cr0(cpu->hvf->fd, RRX(env, reg));
390
break;
391
}
392
case 4: {
393
- macvm_set_cr4(cpu->hvf_fd, RRX(env, reg));
394
+ macvm_set_cr4(cpu->hvf->fd, RRX(env, reg));
395
break;
396
}
397
case 8: {
398
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
399
break;
400
}
76
}
401
case EXIT_REASON_TASK_SWITCH: {
77
- which = cmp > 0 ? 0 : 1;
402
- uint64_t vinfo = rvmcs(cpu->hvf_fd, VMCS_IDT_VECTORING_INFO);
78
+ ret = cmp > 0 ? a : b;
403
+ uint64_t vinfo = rvmcs(cpu->hvf->fd, VMCS_IDT_VECTORING_INFO);
79
break;
404
x68_segment_selector sel = {.sel = exit_qual & 0xffff};
80
default:
405
vmx_handle_task_switch(cpu, sel, (exit_qual >> 30) & 0x3,
81
g_assert_not_reached();
406
vinfo & VMCS_INTR_VALID, vinfo & VECTORING_INFO_VECTOR_MASK, vinfo
407
@@ -XXX,XX +XXX,XX @@ int hvf_vcpu_exec(CPUState *cpu)
408
break;
409
}
410
case EXIT_REASON_RDPMC:
411
- wreg(cpu->hvf_fd, HV_X86_RAX, 0);
412
- wreg(cpu->hvf_fd, HV_X86_RDX, 0);
413
+ wreg(cpu->hvf->fd, HV_X86_RAX, 0);
414
+ wreg(cpu->hvf->fd, HV_X86_RDX, 0);
415
macvm_set_rip(cpu, rip + ins_len);
416
break;
417
case VMX_REASON_VMCALL:
418
diff --git a/target/i386/hvf/x86.c b/target/i386/hvf/x86.c
419
index XXXXXXX..XXXXXXX 100644
420
--- a/target/i386/hvf/x86.c
421
+++ b/target/i386/hvf/x86.c
422
@@ -XXX,XX +XXX,XX @@ bool x86_read_segment_descriptor(struct CPUState *cpu,
423
}
82
}
424
83
425
if (GDT_SEL == sel.ti) {
84
- if (which) {
426
- base = rvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_BASE);
85
- a = b;
427
- limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_LIMIT);
86
+ if (is_snan(ret->cls)) {
428
+ base = rvmcs(cpu->hvf->fd, VMCS_GUEST_GDTR_BASE);
87
+ parts_silence_nan(ret, s);
429
+ limit = rvmcs(cpu->hvf->fd, VMCS_GUEST_GDTR_LIMIT);
430
} else {
431
- base = rvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_BASE);
432
- limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_LIMIT);
433
+ base = rvmcs(cpu->hvf->fd, VMCS_GUEST_LDTR_BASE);
434
+ limit = rvmcs(cpu->hvf->fd, VMCS_GUEST_LDTR_LIMIT);
435
}
88
}
436
89
- if (is_snan(a->cls)) {
437
if (sel.index * 8 >= limit) {
90
- parts_silence_nan(a, s);
438
@@ -XXX,XX +XXX,XX @@ bool x86_write_segment_descriptor(struct CPUState *cpu,
91
- }
439
uint32_t limit;
92
- return a;
440
93
+ return ret;
441
if (GDT_SEL == sel.ti) {
442
- base = rvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_BASE);
443
- limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_GDTR_LIMIT);
444
+ base = rvmcs(cpu->hvf->fd, VMCS_GUEST_GDTR_BASE);
445
+ limit = rvmcs(cpu->hvf->fd, VMCS_GUEST_GDTR_LIMIT);
446
} else {
447
- base = rvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_BASE);
448
- limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_LDTR_LIMIT);
449
+ base = rvmcs(cpu->hvf->fd, VMCS_GUEST_LDTR_BASE);
450
+ limit = rvmcs(cpu->hvf->fd, VMCS_GUEST_LDTR_LIMIT);
451
}
452
453
if (sel.index * 8 >= limit) {
454
@@ -XXX,XX +XXX,XX @@ bool x86_write_segment_descriptor(struct CPUState *cpu,
455
bool x86_read_call_gate(struct CPUState *cpu, struct x86_call_gate *idt_desc,
456
int gate)
457
{
458
- target_ulong base = rvmcs(cpu->hvf_fd, VMCS_GUEST_IDTR_BASE);
459
- uint32_t limit = rvmcs(cpu->hvf_fd, VMCS_GUEST_IDTR_LIMIT);
460
+ target_ulong base = rvmcs(cpu->hvf->fd, VMCS_GUEST_IDTR_BASE);
461
+ uint32_t limit = rvmcs(cpu->hvf->fd, VMCS_GUEST_IDTR_LIMIT);
462
463
memset(idt_desc, 0, sizeof(*idt_desc));
464
if (gate * 8 >= limit) {
465
@@ -XXX,XX +XXX,XX @@ bool x86_read_call_gate(struct CPUState *cpu, struct x86_call_gate *idt_desc,
466
467
bool x86_is_protected(struct CPUState *cpu)
468
{
469
- uint64_t cr0 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0);
470
+ uint64_t cr0 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0);
471
return cr0 & CR0_PE;
472
}
94
}
473
95
474
@@ -XXX,XX +XXX,XX @@ bool x86_is_v8086(struct CPUState *cpu)
96
static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
475
476
bool x86_is_long_mode(struct CPUState *cpu)
477
{
478
- return rvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER) & MSR_EFER_LMA;
479
+ return rvmcs(cpu->hvf->fd, VMCS_GUEST_IA32_EFER) & MSR_EFER_LMA;
480
}
481
482
bool x86_is_long64_mode(struct CPUState *cpu)
483
@@ -XXX,XX +XXX,XX @@ bool x86_is_long64_mode(struct CPUState *cpu)
484
485
bool x86_is_paging_mode(struct CPUState *cpu)
486
{
487
- uint64_t cr0 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0);
488
+ uint64_t cr0 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0);
489
return cr0 & CR0_PG;
490
}
491
492
bool x86_is_pae_enabled(struct CPUState *cpu)
493
{
494
- uint64_t cr4 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR4);
495
+ uint64_t cr4 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR4);
496
return cr4 & CR4_PAE;
497
}
498
499
diff --git a/target/i386/hvf/x86_descr.c b/target/i386/hvf/x86_descr.c
500
index XXXXXXX..XXXXXXX 100644
501
--- a/target/i386/hvf/x86_descr.c
502
+++ b/target/i386/hvf/x86_descr.c
503
@@ -XXX,XX +XXX,XX @@ static const struct vmx_segment_field {
504
505
uint32_t vmx_read_segment_limit(CPUState *cpu, X86Seg seg)
506
{
507
- return (uint32_t)rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].limit);
508
+ return (uint32_t)rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].limit);
509
}
510
511
uint32_t vmx_read_segment_ar(CPUState *cpu, X86Seg seg)
512
{
513
- return (uint32_t)rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].ar_bytes);
514
+ return (uint32_t)rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].ar_bytes);
515
}
516
517
uint64_t vmx_read_segment_base(CPUState *cpu, X86Seg seg)
518
{
519
- return rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].base);
520
+ return rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].base);
521
}
522
523
x68_segment_selector vmx_read_segment_selector(CPUState *cpu, X86Seg seg)
524
{
525
x68_segment_selector sel;
526
- sel.sel = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].selector);
527
+ sel.sel = rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].selector);
528
return sel;
529
}
530
531
void vmx_write_segment_selector(struct CPUState *cpu, x68_segment_selector selector, X86Seg seg)
532
{
533
- wvmcs(cpu->hvf_fd, vmx_segment_fields[seg].selector, selector.sel);
534
+ wvmcs(cpu->hvf->fd, vmx_segment_fields[seg].selector, selector.sel);
535
}
536
537
void vmx_read_segment_descriptor(struct CPUState *cpu, struct vmx_segment *desc, X86Seg seg)
538
{
539
- desc->sel = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].selector);
540
- desc->base = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].base);
541
- desc->limit = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].limit);
542
- desc->ar = rvmcs(cpu->hvf_fd, vmx_segment_fields[seg].ar_bytes);
543
+ desc->sel = rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].selector);
544
+ desc->base = rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].base);
545
+ desc->limit = rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].limit);
546
+ desc->ar = rvmcs(cpu->hvf->fd, vmx_segment_fields[seg].ar_bytes);
547
}
548
549
void vmx_write_segment_descriptor(CPUState *cpu, struct vmx_segment *desc, X86Seg seg)
550
{
551
const struct vmx_segment_field *sf = &vmx_segment_fields[seg];
552
553
- wvmcs(cpu->hvf_fd, sf->base, desc->base);
554
- wvmcs(cpu->hvf_fd, sf->limit, desc->limit);
555
- wvmcs(cpu->hvf_fd, sf->selector, desc->sel);
556
- wvmcs(cpu->hvf_fd, sf->ar_bytes, desc->ar);
557
+ wvmcs(cpu->hvf->fd, sf->base, desc->base);
558
+ wvmcs(cpu->hvf->fd, sf->limit, desc->limit);
559
+ wvmcs(cpu->hvf->fd, sf->selector, desc->sel);
560
+ wvmcs(cpu->hvf->fd, sf->ar_bytes, desc->ar);
561
}
562
563
void x86_segment_descriptor_to_vmx(struct CPUState *cpu, x68_segment_selector selector, struct x86_segment_descriptor *desc, struct vmx_segment *vmx_desc)
564
diff --git a/target/i386/hvf/x86_emu.c b/target/i386/hvf/x86_emu.c
565
index XXXXXXX..XXXXXXX 100644
566
--- a/target/i386/hvf/x86_emu.c
567
+++ b/target/i386/hvf/x86_emu.c
568
@@ -XXX,XX +XXX,XX @@ void simulate_rdmsr(struct CPUState *cpu)
569
570
switch (msr) {
571
case MSR_IA32_TSC:
572
- val = rdtscp() + rvmcs(cpu->hvf_fd, VMCS_TSC_OFFSET);
573
+ val = rdtscp() + rvmcs(cpu->hvf->fd, VMCS_TSC_OFFSET);
574
break;
575
case MSR_IA32_APICBASE:
576
val = cpu_get_apic_base(X86_CPU(cpu)->apic_state);
577
@@ -XXX,XX +XXX,XX @@ void simulate_rdmsr(struct CPUState *cpu)
578
val = x86_cpu->ucode_rev;
579
break;
580
case MSR_EFER:
581
- val = rvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER);
582
+ val = rvmcs(cpu->hvf->fd, VMCS_GUEST_IA32_EFER);
583
break;
584
case MSR_FSBASE:
585
- val = rvmcs(cpu->hvf_fd, VMCS_GUEST_FS_BASE);
586
+ val = rvmcs(cpu->hvf->fd, VMCS_GUEST_FS_BASE);
587
break;
588
case MSR_GSBASE:
589
- val = rvmcs(cpu->hvf_fd, VMCS_GUEST_GS_BASE);
590
+ val = rvmcs(cpu->hvf->fd, VMCS_GUEST_GS_BASE);
591
break;
592
case MSR_KERNELGSBASE:
593
- val = rvmcs(cpu->hvf_fd, VMCS_HOST_FS_BASE);
594
+ val = rvmcs(cpu->hvf->fd, VMCS_HOST_FS_BASE);
595
break;
596
case MSR_STAR:
597
abort();
598
@@ -XXX,XX +XXX,XX @@ void simulate_wrmsr(struct CPUState *cpu)
599
cpu_set_apic_base(X86_CPU(cpu)->apic_state, data);
600
break;
601
case MSR_FSBASE:
602
- wvmcs(cpu->hvf_fd, VMCS_GUEST_FS_BASE, data);
603
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_FS_BASE, data);
604
break;
605
case MSR_GSBASE:
606
- wvmcs(cpu->hvf_fd, VMCS_GUEST_GS_BASE, data);
607
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_GS_BASE, data);
608
break;
609
case MSR_KERNELGSBASE:
610
- wvmcs(cpu->hvf_fd, VMCS_HOST_FS_BASE, data);
611
+ wvmcs(cpu->hvf->fd, VMCS_HOST_FS_BASE, data);
612
break;
613
case MSR_STAR:
614
abort();
615
@@ -XXX,XX +XXX,XX @@ void simulate_wrmsr(struct CPUState *cpu)
616
break;
617
case MSR_EFER:
618
/*printf("new efer %llx\n", EFER(cpu));*/
619
- wvmcs(cpu->hvf_fd, VMCS_GUEST_IA32_EFER, data);
620
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_IA32_EFER, data);
621
if (data & MSR_EFER_NXE) {
622
- hv_vcpu_invalidate_tlb(cpu->hvf_fd);
623
+ hv_vcpu_invalidate_tlb(cpu->hvf->fd);
624
}
625
break;
626
case MSR_MTRRphysBase(0):
627
@@ -XXX,XX +XXX,XX @@ void load_regs(struct CPUState *cpu)
628
CPUX86State *env = &x86_cpu->env;
629
630
int i = 0;
631
- RRX(env, R_EAX) = rreg(cpu->hvf_fd, HV_X86_RAX);
632
- RRX(env, R_EBX) = rreg(cpu->hvf_fd, HV_X86_RBX);
633
- RRX(env, R_ECX) = rreg(cpu->hvf_fd, HV_X86_RCX);
634
- RRX(env, R_EDX) = rreg(cpu->hvf_fd, HV_X86_RDX);
635
- RRX(env, R_ESI) = rreg(cpu->hvf_fd, HV_X86_RSI);
636
- RRX(env, R_EDI) = rreg(cpu->hvf_fd, HV_X86_RDI);
637
- RRX(env, R_ESP) = rreg(cpu->hvf_fd, HV_X86_RSP);
638
- RRX(env, R_EBP) = rreg(cpu->hvf_fd, HV_X86_RBP);
639
+ RRX(env, R_EAX) = rreg(cpu->hvf->fd, HV_X86_RAX);
640
+ RRX(env, R_EBX) = rreg(cpu->hvf->fd, HV_X86_RBX);
641
+ RRX(env, R_ECX) = rreg(cpu->hvf->fd, HV_X86_RCX);
642
+ RRX(env, R_EDX) = rreg(cpu->hvf->fd, HV_X86_RDX);
643
+ RRX(env, R_ESI) = rreg(cpu->hvf->fd, HV_X86_RSI);
644
+ RRX(env, R_EDI) = rreg(cpu->hvf->fd, HV_X86_RDI);
645
+ RRX(env, R_ESP) = rreg(cpu->hvf->fd, HV_X86_RSP);
646
+ RRX(env, R_EBP) = rreg(cpu->hvf->fd, HV_X86_RBP);
647
for (i = 8; i < 16; i++) {
648
- RRX(env, i) = rreg(cpu->hvf_fd, HV_X86_RAX + i);
649
+ RRX(env, i) = rreg(cpu->hvf->fd, HV_X86_RAX + i);
650
}
651
652
- env->eflags = rreg(cpu->hvf_fd, HV_X86_RFLAGS);
653
+ env->eflags = rreg(cpu->hvf->fd, HV_X86_RFLAGS);
654
rflags_to_lflags(env);
655
- env->eip = rreg(cpu->hvf_fd, HV_X86_RIP);
656
+ env->eip = rreg(cpu->hvf->fd, HV_X86_RIP);
657
}
658
659
void store_regs(struct CPUState *cpu)
660
@@ -XXX,XX +XXX,XX @@ void store_regs(struct CPUState *cpu)
661
CPUX86State *env = &x86_cpu->env;
662
663
int i = 0;
664
- wreg(cpu->hvf_fd, HV_X86_RAX, RAX(env));
665
- wreg(cpu->hvf_fd, HV_X86_RBX, RBX(env));
666
- wreg(cpu->hvf_fd, HV_X86_RCX, RCX(env));
667
- wreg(cpu->hvf_fd, HV_X86_RDX, RDX(env));
668
- wreg(cpu->hvf_fd, HV_X86_RSI, RSI(env));
669
- wreg(cpu->hvf_fd, HV_X86_RDI, RDI(env));
670
- wreg(cpu->hvf_fd, HV_X86_RBP, RBP(env));
671
- wreg(cpu->hvf_fd, HV_X86_RSP, RSP(env));
672
+ wreg(cpu->hvf->fd, HV_X86_RAX, RAX(env));
673
+ wreg(cpu->hvf->fd, HV_X86_RBX, RBX(env));
674
+ wreg(cpu->hvf->fd, HV_X86_RCX, RCX(env));
675
+ wreg(cpu->hvf->fd, HV_X86_RDX, RDX(env));
676
+ wreg(cpu->hvf->fd, HV_X86_RSI, RSI(env));
677
+ wreg(cpu->hvf->fd, HV_X86_RDI, RDI(env));
678
+ wreg(cpu->hvf->fd, HV_X86_RBP, RBP(env));
679
+ wreg(cpu->hvf->fd, HV_X86_RSP, RSP(env));
680
for (i = 8; i < 16; i++) {
681
- wreg(cpu->hvf_fd, HV_X86_RAX + i, RRX(env, i));
682
+ wreg(cpu->hvf->fd, HV_X86_RAX + i, RRX(env, i));
683
}
684
685
lflags_to_rflags(env);
686
- wreg(cpu->hvf_fd, HV_X86_RFLAGS, env->eflags);
687
+ wreg(cpu->hvf->fd, HV_X86_RFLAGS, env->eflags);
688
macvm_set_rip(cpu, env->eip);
689
}
690
691
diff --git a/target/i386/hvf/x86_mmu.c b/target/i386/hvf/x86_mmu.c
692
index XXXXXXX..XXXXXXX 100644
693
--- a/target/i386/hvf/x86_mmu.c
694
+++ b/target/i386/hvf/x86_mmu.c
695
@@ -XXX,XX +XXX,XX @@ static bool test_pt_entry(struct CPUState *cpu, struct gpt_translation *pt,
696
pt->err_code |= MMU_PAGE_PT;
697
}
698
699
- uint32_t cr0 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0);
700
+ uint32_t cr0 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0);
701
/* check protection */
702
if (cr0 & CR0_WP) {
703
if (pt->write_access && !pte_write_access(pte)) {
704
@@ -XXX,XX +XXX,XX @@ static bool walk_gpt(struct CPUState *cpu, target_ulong addr, int err_code,
705
{
706
int top_level, level;
707
bool is_large = false;
708
- target_ulong cr3 = rvmcs(cpu->hvf_fd, VMCS_GUEST_CR3);
709
+ target_ulong cr3 = rvmcs(cpu->hvf->fd, VMCS_GUEST_CR3);
710
uint64_t page_mask = pae ? PAE_PTE_PAGE_MASK : LEGACY_PTE_PAGE_MASK;
711
712
memset(pt, 0, sizeof(*pt));
713
diff --git a/target/i386/hvf/x86_task.c b/target/i386/hvf/x86_task.c
714
index XXXXXXX..XXXXXXX 100644
715
--- a/target/i386/hvf/x86_task.c
716
+++ b/target/i386/hvf/x86_task.c
717
@@ -XXX,XX +XXX,XX @@ static void load_state_from_tss32(CPUState *cpu, struct x86_tss_segment32 *tss)
718
X86CPU *x86_cpu = X86_CPU(cpu);
719
CPUX86State *env = &x86_cpu->env;
720
721
- wvmcs(cpu->hvf_fd, VMCS_GUEST_CR3, tss->cr3);
722
+ wvmcs(cpu->hvf->fd, VMCS_GUEST_CR3, tss->cr3);
723
724
env->eip = tss->eip;
725
env->eflags = tss->eflags | 2;
726
@@ -XXX,XX +XXX,XX @@ static int task_switch_32(CPUState *cpu, x68_segment_selector tss_sel, x68_segme
727
728
void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel, int reason, bool gate_valid, uint8_t gate, uint64_t gate_type)
729
{
730
- uint64_t rip = rreg(cpu->hvf_fd, HV_X86_RIP);
731
+ uint64_t rip = rreg(cpu->hvf->fd, HV_X86_RIP);
732
if (!gate_valid || (gate_type != VMCS_INTR_T_HWEXCEPTION &&
733
gate_type != VMCS_INTR_T_HWINTR &&
734
gate_type != VMCS_INTR_T_NMI)) {
735
- int ins_len = rvmcs(cpu->hvf_fd, VMCS_EXIT_INSTRUCTION_LENGTH);
736
+ int ins_len = rvmcs(cpu->hvf->fd, VMCS_EXIT_INSTRUCTION_LENGTH);
737
macvm_set_rip(cpu, rip + ins_len);
738
return;
739
}
740
@@ -XXX,XX +XXX,XX @@ void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel, int rea
741
//ret = task_switch_16(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc);
742
VM_PANIC("task_switch_16");
743
744
- macvm_set_cr0(cpu->hvf_fd, rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0) | CR0_TS);
745
+ macvm_set_cr0(cpu->hvf->fd, rvmcs(cpu->hvf->fd, VMCS_GUEST_CR0) | CR0_TS);
746
x86_segment_descriptor_to_vmx(cpu, tss_sel, &next_tss_desc, &vmx_seg);
747
vmx_write_segment_descriptor(cpu, &vmx_seg, R_TR);
748
749
store_regs(cpu);
750
751
- hv_vcpu_invalidate_tlb(cpu->hvf_fd);
752
- hv_vcpu_flush(cpu->hvf_fd);
753
+ hv_vcpu_invalidate_tlb(cpu->hvf->fd);
754
+ hv_vcpu_flush(cpu->hvf->fd);
755
}
756
diff --git a/target/i386/hvf/x86hvf.c b/target/i386/hvf/x86hvf.c
757
index XXXXXXX..XXXXXXX 100644
758
--- a/target/i386/hvf/x86hvf.c
759
+++ b/target/i386/hvf/x86hvf.c
760
@@ -XXX,XX +XXX,XX @@ void hvf_put_xsave(CPUState *cpu_state)
761
762
x86_cpu_xsave_all_areas(X86_CPU(cpu_state), xsave);
763
764
- if (hv_vcpu_write_fpstate(cpu_state->hvf_fd, (void*)xsave, 4096)) {
765
+ if (hv_vcpu_write_fpstate(cpu_state->hvf->fd, (void*)xsave, 4096)) {
766
abort();
767
}
768
}
769
@@ -XXX,XX +XXX,XX @@ void hvf_put_segments(CPUState *cpu_state)
770
CPUX86State *env = &X86_CPU(cpu_state)->env;
771
struct vmx_segment seg;
772
773
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_IDTR_LIMIT, env->idt.limit);
774
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_IDTR_BASE, env->idt.base);
775
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_IDTR_LIMIT, env->idt.limit);
776
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_IDTR_BASE, env->idt.base);
777
778
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_GDTR_LIMIT, env->gdt.limit);
779
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_GDTR_BASE, env->gdt.base);
780
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_GDTR_LIMIT, env->gdt.limit);
781
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_GDTR_BASE, env->gdt.base);
782
783
- /* wvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR2, env->cr[2]); */
784
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR3, env->cr[3]);
785
+ /* wvmcs(cpu_state->hvf->fd, VMCS_GUEST_CR2, env->cr[2]); */
786
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_CR3, env->cr[3]);
787
vmx_update_tpr(cpu_state);
788
- wvmcs(cpu_state->hvf_fd, VMCS_GUEST_IA32_EFER, env->efer);
789
+ wvmcs(cpu_state->hvf->fd, VMCS_GUEST_IA32_EFER, env->efer);
790
791
- macvm_set_cr4(cpu_state->hvf_fd, env->cr[4]);
792
- macvm_set_cr0(cpu_state->hvf_fd, env->cr[0]);
793
+ macvm_set_cr4(cpu_state->hvf->fd, env->cr[4]);
794
+ macvm_set_cr0(cpu_state->hvf->fd, env->cr[0]);
795
796
hvf_set_segment(cpu_state, &seg, &env->segs[R_CS], false);
797
vmx_write_segment_descriptor(cpu_state, &seg, R_CS);
798
@@ -XXX,XX +XXX,XX @@ void hvf_put_segments(CPUState *cpu_state)
799
hvf_set_segment(cpu_state, &seg, &env->ldt, false);
800
vmx_write_segment_descriptor(cpu_state, &seg, R_LDTR);
801
802
- hv_vcpu_flush(cpu_state->hvf_fd);
803
+ hv_vcpu_flush(cpu_state->hvf->fd);
804
}
805
806
void hvf_put_msrs(CPUState *cpu_state)
807
{
808
CPUX86State *env = &X86_CPU(cpu_state)->env;
809
810
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_CS,
811
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_CS,
812
env->sysenter_cs);
813
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_ESP,
814
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_ESP,
815
env->sysenter_esp);
816
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_EIP,
817
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_EIP,
818
env->sysenter_eip);
819
820
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_STAR, env->star);
821
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_STAR, env->star);
822
823
#ifdef TARGET_X86_64
824
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_CSTAR, env->cstar);
825
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_KERNELGSBASE, env->kernelgsbase);
826
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_FMASK, env->fmask);
827
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_LSTAR, env->lstar);
828
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_CSTAR, env->cstar);
829
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_KERNELGSBASE, env->kernelgsbase);
830
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_FMASK, env->fmask);
831
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_LSTAR, env->lstar);
832
#endif
833
834
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_GSBASE, env->segs[R_GS].base);
835
- hv_vcpu_write_msr(cpu_state->hvf_fd, MSR_FSBASE, env->segs[R_FS].base);
836
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_GSBASE, env->segs[R_GS].base);
837
+ hv_vcpu_write_msr(cpu_state->hvf->fd, MSR_FSBASE, env->segs[R_FS].base);
838
}
839
840
841
@@ -XXX,XX +XXX,XX @@ void hvf_get_xsave(CPUState *cpu_state)
842
843
xsave = X86_CPU(cpu_state)->env.xsave_buf;
844
845
- if (hv_vcpu_read_fpstate(cpu_state->hvf_fd, (void*)xsave, 4096)) {
846
+ if (hv_vcpu_read_fpstate(cpu_state->hvf->fd, (void*)xsave, 4096)) {
847
abort();
848
}
849
850
@@ -XXX,XX +XXX,XX @@ void hvf_get_segments(CPUState *cpu_state)
851
vmx_read_segment_descriptor(cpu_state, &seg, R_LDTR);
852
hvf_get_segment(&env->ldt, &seg);
853
854
- env->idt.limit = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_IDTR_LIMIT);
855
- env->idt.base = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_IDTR_BASE);
856
- env->gdt.limit = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_GDTR_LIMIT);
857
- env->gdt.base = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_GDTR_BASE);
858
+ env->idt.limit = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_IDTR_LIMIT);
859
+ env->idt.base = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_IDTR_BASE);
860
+ env->gdt.limit = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_GDTR_LIMIT);
861
+ env->gdt.base = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_GDTR_BASE);
862
863
- env->cr[0] = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR0);
864
+ env->cr[0] = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_CR0);
865
env->cr[2] = 0;
866
- env->cr[3] = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR3);
867
- env->cr[4] = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_CR4);
868
+ env->cr[3] = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_CR3);
869
+ env->cr[4] = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_CR4);
870
871
- env->efer = rvmcs(cpu_state->hvf_fd, VMCS_GUEST_IA32_EFER);
872
+ env->efer = rvmcs(cpu_state->hvf->fd, VMCS_GUEST_IA32_EFER);
873
}
874
875
void hvf_get_msrs(CPUState *cpu_state)
876
@@ -XXX,XX +XXX,XX @@ void hvf_get_msrs(CPUState *cpu_state)
877
CPUX86State *env = &X86_CPU(cpu_state)->env;
878
uint64_t tmp;
879
880
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_CS, &tmp);
881
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_CS, &tmp);
882
env->sysenter_cs = tmp;
883
884
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_ESP, &tmp);
885
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_ESP, &tmp);
886
env->sysenter_esp = tmp;
887
888
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_IA32_SYSENTER_EIP, &tmp);
889
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_IA32_SYSENTER_EIP, &tmp);
890
env->sysenter_eip = tmp;
891
892
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_STAR, &env->star);
893
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_STAR, &env->star);
894
895
#ifdef TARGET_X86_64
896
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_CSTAR, &env->cstar);
897
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_KERNELGSBASE, &env->kernelgsbase);
898
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_FMASK, &env->fmask);
899
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_LSTAR, &env->lstar);
900
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_CSTAR, &env->cstar);
901
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_KERNELGSBASE, &env->kernelgsbase);
902
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_FMASK, &env->fmask);
903
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_LSTAR, &env->lstar);
904
#endif
905
906
- hv_vcpu_read_msr(cpu_state->hvf_fd, MSR_IA32_APICBASE, &tmp);
907
+ hv_vcpu_read_msr(cpu_state->hvf->fd, MSR_IA32_APICBASE, &tmp);
908
909
- env->tsc = rdtscp() + rvmcs(cpu_state->hvf_fd, VMCS_TSC_OFFSET);
910
+ env->tsc = rdtscp() + rvmcs(cpu_state->hvf->fd, VMCS_TSC_OFFSET);
911
}
912
913
int hvf_put_registers(CPUState *cpu_state)
914
@@ -XXX,XX +XXX,XX @@ int hvf_put_registers(CPUState *cpu_state)
915
X86CPU *x86cpu = X86_CPU(cpu_state);
916
CPUX86State *env = &x86cpu->env;
917
918
- wreg(cpu_state->hvf_fd, HV_X86_RAX, env->regs[R_EAX]);
919
- wreg(cpu_state->hvf_fd, HV_X86_RBX, env->regs[R_EBX]);
920
- wreg(cpu_state->hvf_fd, HV_X86_RCX, env->regs[R_ECX]);
921
- wreg(cpu_state->hvf_fd, HV_X86_RDX, env->regs[R_EDX]);
922
- wreg(cpu_state->hvf_fd, HV_X86_RBP, env->regs[R_EBP]);
923
- wreg(cpu_state->hvf_fd, HV_X86_RSP, env->regs[R_ESP]);
924
- wreg(cpu_state->hvf_fd, HV_X86_RSI, env->regs[R_ESI]);
925
- wreg(cpu_state->hvf_fd, HV_X86_RDI, env->regs[R_EDI]);
926
- wreg(cpu_state->hvf_fd, HV_X86_R8, env->regs[8]);
927
- wreg(cpu_state->hvf_fd, HV_X86_R9, env->regs[9]);
928
- wreg(cpu_state->hvf_fd, HV_X86_R10, env->regs[10]);
929
- wreg(cpu_state->hvf_fd, HV_X86_R11, env->regs[11]);
930
- wreg(cpu_state->hvf_fd, HV_X86_R12, env->regs[12]);
931
- wreg(cpu_state->hvf_fd, HV_X86_R13, env->regs[13]);
932
- wreg(cpu_state->hvf_fd, HV_X86_R14, env->regs[14]);
933
- wreg(cpu_state->hvf_fd, HV_X86_R15, env->regs[15]);
934
- wreg(cpu_state->hvf_fd, HV_X86_RFLAGS, env->eflags);
935
- wreg(cpu_state->hvf_fd, HV_X86_RIP, env->eip);
936
+ wreg(cpu_state->hvf->fd, HV_X86_RAX, env->regs[R_EAX]);
937
+ wreg(cpu_state->hvf->fd, HV_X86_RBX, env->regs[R_EBX]);
938
+ wreg(cpu_state->hvf->fd, HV_X86_RCX, env->regs[R_ECX]);
939
+ wreg(cpu_state->hvf->fd, HV_X86_RDX, env->regs[R_EDX]);
940
+ wreg(cpu_state->hvf->fd, HV_X86_RBP, env->regs[R_EBP]);
941
+ wreg(cpu_state->hvf->fd, HV_X86_RSP, env->regs[R_ESP]);
942
+ wreg(cpu_state->hvf->fd, HV_X86_RSI, env->regs[R_ESI]);
943
+ wreg(cpu_state->hvf->fd, HV_X86_RDI, env->regs[R_EDI]);
944
+ wreg(cpu_state->hvf->fd, HV_X86_R8, env->regs[8]);
945
+ wreg(cpu_state->hvf->fd, HV_X86_R9, env->regs[9]);
946
+ wreg(cpu_state->hvf->fd, HV_X86_R10, env->regs[10]);
947
+ wreg(cpu_state->hvf->fd, HV_X86_R11, env->regs[11]);
948
+ wreg(cpu_state->hvf->fd, HV_X86_R12, env->regs[12]);
949
+ wreg(cpu_state->hvf->fd, HV_X86_R13, env->regs[13]);
950
+ wreg(cpu_state->hvf->fd, HV_X86_R14, env->regs[14]);
951
+ wreg(cpu_state->hvf->fd, HV_X86_R15, env->regs[15]);
952
+ wreg(cpu_state->hvf->fd, HV_X86_RFLAGS, env->eflags);
953
+ wreg(cpu_state->hvf->fd, HV_X86_RIP, env->eip);
954
955
- wreg(cpu_state->hvf_fd, HV_X86_XCR0, env->xcr0);
956
+ wreg(cpu_state->hvf->fd, HV_X86_XCR0, env->xcr0);
957
958
hvf_put_xsave(cpu_state);
959
960
@@ -XXX,XX +XXX,XX @@ int hvf_put_registers(CPUState *cpu_state)
961
962
hvf_put_msrs(cpu_state);
963
964
- wreg(cpu_state->hvf_fd, HV_X86_DR0, env->dr[0]);
965
- wreg(cpu_state->hvf_fd, HV_X86_DR1, env->dr[1]);
966
- wreg(cpu_state->hvf_fd, HV_X86_DR2, env->dr[2]);
967
- wreg(cpu_state->hvf_fd, HV_X86_DR3, env->dr[3]);
968
- wreg(cpu_state->hvf_fd, HV_X86_DR4, env->dr[4]);
969
- wreg(cpu_state->hvf_fd, HV_X86_DR5, env->dr[5]);
970
- wreg(cpu_state->hvf_fd, HV_X86_DR6, env->dr[6]);
971
- wreg(cpu_state->hvf_fd, HV_X86_DR7, env->dr[7]);
972
+ wreg(cpu_state->hvf->fd, HV_X86_DR0, env->dr[0]);
973
+ wreg(cpu_state->hvf->fd, HV_X86_DR1, env->dr[1]);
974
+ wreg(cpu_state->hvf->fd, HV_X86_DR2, env->dr[2]);
975
+ wreg(cpu_state->hvf->fd, HV_X86_DR3, env->dr[3]);
976
+ wreg(cpu_state->hvf->fd, HV_X86_DR4, env->dr[4]);
977
+ wreg(cpu_state->hvf->fd, HV_X86_DR5, env->dr[5]);
978
+ wreg(cpu_state->hvf->fd, HV_X86_DR6, env->dr[6]);
979
+ wreg(cpu_state->hvf->fd, HV_X86_DR7, env->dr[7]);
980
981
return 0;
982
}
983
@@ -XXX,XX +XXX,XX @@ int hvf_get_registers(CPUState *cpu_state)
984
X86CPU *x86cpu = X86_CPU(cpu_state);
985
CPUX86State *env = &x86cpu->env;
986
987
- env->regs[R_EAX] = rreg(cpu_state->hvf_fd, HV_X86_RAX);
988
- env->regs[R_EBX] = rreg(cpu_state->hvf_fd, HV_X86_RBX);
989
- env->regs[R_ECX] = rreg(cpu_state->hvf_fd, HV_X86_RCX);
990
- env->regs[R_EDX] = rreg(cpu_state->hvf_fd, HV_X86_RDX);
991
- env->regs[R_EBP] = rreg(cpu_state->hvf_fd, HV_X86_RBP);
992
- env->regs[R_ESP] = rreg(cpu_state->hvf_fd, HV_X86_RSP);
993
- env->regs[R_ESI] = rreg(cpu_state->hvf_fd, HV_X86_RSI);
994
- env->regs[R_EDI] = rreg(cpu_state->hvf_fd, HV_X86_RDI);
995
- env->regs[8] = rreg(cpu_state->hvf_fd, HV_X86_R8);
996
- env->regs[9] = rreg(cpu_state->hvf_fd, HV_X86_R9);
997
- env->regs[10] = rreg(cpu_state->hvf_fd, HV_X86_R10);
998
- env->regs[11] = rreg(cpu_state->hvf_fd, HV_X86_R11);
999
- env->regs[12] = rreg(cpu_state->hvf_fd, HV_X86_R12);
1000
- env->regs[13] = rreg(cpu_state->hvf_fd, HV_X86_R13);
1001
- env->regs[14] = rreg(cpu_state->hvf_fd, HV_X86_R14);
1002
- env->regs[15] = rreg(cpu_state->hvf_fd, HV_X86_R15);
1003
+ env->regs[R_EAX] = rreg(cpu_state->hvf->fd, HV_X86_RAX);
1004
+ env->regs[R_EBX] = rreg(cpu_state->hvf->fd, HV_X86_RBX);
1005
+ env->regs[R_ECX] = rreg(cpu_state->hvf->fd, HV_X86_RCX);
1006
+ env->regs[R_EDX] = rreg(cpu_state->hvf->fd, HV_X86_RDX);
1007
+ env->regs[R_EBP] = rreg(cpu_state->hvf->fd, HV_X86_RBP);
1008
+ env->regs[R_ESP] = rreg(cpu_state->hvf->fd, HV_X86_RSP);
1009
+ env->regs[R_ESI] = rreg(cpu_state->hvf->fd, HV_X86_RSI);
1010
+ env->regs[R_EDI] = rreg(cpu_state->hvf->fd, HV_X86_RDI);
1011
+ env->regs[8] = rreg(cpu_state->hvf->fd, HV_X86_R8);
1012
+ env->regs[9] = rreg(cpu_state->hvf->fd, HV_X86_R9);
1013
+ env->regs[10] = rreg(cpu_state->hvf->fd, HV_X86_R10);
1014
+ env->regs[11] = rreg(cpu_state->hvf->fd, HV_X86_R11);
1015
+ env->regs[12] = rreg(cpu_state->hvf->fd, HV_X86_R12);
1016
+ env->regs[13] = rreg(cpu_state->hvf->fd, HV_X86_R13);
1017
+ env->regs[14] = rreg(cpu_state->hvf->fd, HV_X86_R14);
1018
+ env->regs[15] = rreg(cpu_state->hvf->fd, HV_X86_R15);
1019
1020
- env->eflags = rreg(cpu_state->hvf_fd, HV_X86_RFLAGS);
1021
- env->eip = rreg(cpu_state->hvf_fd, HV_X86_RIP);
1022
+ env->eflags = rreg(cpu_state->hvf->fd, HV_X86_RFLAGS);
1023
+ env->eip = rreg(cpu_state->hvf->fd, HV_X86_RIP);
1024
1025
hvf_get_xsave(cpu_state);
1026
- env->xcr0 = rreg(cpu_state->hvf_fd, HV_X86_XCR0);
1027
+ env->xcr0 = rreg(cpu_state->hvf->fd, HV_X86_XCR0);
1028
1029
hvf_get_segments(cpu_state);
1030
hvf_get_msrs(cpu_state);
1031
1032
- env->dr[0] = rreg(cpu_state->hvf_fd, HV_X86_DR0);
1033
- env->dr[1] = rreg(cpu_state->hvf_fd, HV_X86_DR1);
1034
- env->dr[2] = rreg(cpu_state->hvf_fd, HV_X86_DR2);
1035
- env->dr[3] = rreg(cpu_state->hvf_fd, HV_X86_DR3);
1036
- env->dr[4] = rreg(cpu_state->hvf_fd, HV_X86_DR4);
1037
- env->dr[5] = rreg(cpu_state->hvf_fd, HV_X86_DR5);
1038
- env->dr[6] = rreg(cpu_state->hvf_fd, HV_X86_DR6);
1039
- env->dr[7] = rreg(cpu_state->hvf_fd, HV_X86_DR7);
1040
+ env->dr[0] = rreg(cpu_state->hvf->fd, HV_X86_DR0);
1041
+ env->dr[1] = rreg(cpu_state->hvf->fd, HV_X86_DR1);
1042
+ env->dr[2] = rreg(cpu_state->hvf->fd, HV_X86_DR2);
1043
+ env->dr[3] = rreg(cpu_state->hvf->fd, HV_X86_DR3);
1044
+ env->dr[4] = rreg(cpu_state->hvf->fd, HV_X86_DR4);
1045
+ env->dr[5] = rreg(cpu_state->hvf->fd, HV_X86_DR5);
1046
+ env->dr[6] = rreg(cpu_state->hvf->fd, HV_X86_DR6);
1047
+ env->dr[7] = rreg(cpu_state->hvf->fd, HV_X86_DR7);
1048
1049
x86_update_hflags(env);
1050
return 0;
1051
@@ -XXX,XX +XXX,XX @@ int hvf_get_registers(CPUState *cpu_state)
1052
static void vmx_set_int_window_exiting(CPUState *cpu)
1053
{
1054
uint64_t val;
1055
- val = rvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS);
1056
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val |
1057
+ val = rvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS);
1058
+ wvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS, val |
1059
VMCS_PRI_PROC_BASED_CTLS_INT_WINDOW_EXITING);
1060
}
1061
1062
void vmx_clear_int_window_exiting(CPUState *cpu)
1063
{
1064
uint64_t val;
1065
- val = rvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS);
1066
- wvmcs(cpu->hvf_fd, VMCS_PRI_PROC_BASED_CTLS, val &
1067
+ val = rvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS);
1068
+ wvmcs(cpu->hvf->fd, VMCS_PRI_PROC_BASED_CTLS, val &
1069
~VMCS_PRI_PROC_BASED_CTLS_INT_WINDOW_EXITING);
1070
}
1071
1072
@@ -XXX,XX +XXX,XX @@ bool hvf_inject_interrupts(CPUState *cpu_state)
1073
uint64_t info = 0;
1074
if (have_event) {
1075
info = vector | intr_type | VMCS_INTR_VALID;
1076
- uint64_t reason = rvmcs(cpu_state->hvf_fd, VMCS_EXIT_REASON);
1077
+ uint64_t reason = rvmcs(cpu_state->hvf->fd, VMCS_EXIT_REASON);
1078
if (env->nmi_injected && reason != EXIT_REASON_TASK_SWITCH) {
1079
vmx_clear_nmi_blocking(cpu_state);
1080
}
1081
@@ -XXX,XX +XXX,XX @@ bool hvf_inject_interrupts(CPUState *cpu_state)
1082
info &= ~(1 << 12); /* clear undefined bit */
1083
if (intr_type == VMCS_INTR_T_SWINTR ||
1084
intr_type == VMCS_INTR_T_SWEXCEPTION) {
1085
- wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INST_LENGTH, env->ins_len);
1086
+ wvmcs(cpu_state->hvf->fd, VMCS_ENTRY_INST_LENGTH, env->ins_len);
1087
}
1088
1089
if (env->has_error_code) {
1090
- wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_EXCEPTION_ERROR,
1091
+ wvmcs(cpu_state->hvf->fd, VMCS_ENTRY_EXCEPTION_ERROR,
1092
env->error_code);
1093
/* Indicate that VMCS_ENTRY_EXCEPTION_ERROR is valid */
1094
info |= VMCS_INTR_DEL_ERRCODE;
1095
}
1096
/*printf("reinject %lx err %d\n", info, err);*/
1097
- wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INTR_INFO, info);
1098
+ wvmcs(cpu_state->hvf->fd, VMCS_ENTRY_INTR_INFO, info);
1099
};
1100
}
1101
1102
@@ -XXX,XX +XXX,XX @@ bool hvf_inject_interrupts(CPUState *cpu_state)
1103
if (!(env->hflags2 & HF2_NMI_MASK) && !(info & VMCS_INTR_VALID)) {
1104
cpu_state->interrupt_request &= ~CPU_INTERRUPT_NMI;
1105
info = VMCS_INTR_VALID | VMCS_INTR_T_NMI | EXCP02_NMI;
1106
- wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INTR_INFO, info);
1107
+ wvmcs(cpu_state->hvf->fd, VMCS_ENTRY_INTR_INFO, info);
1108
} else {
1109
vmx_set_nmi_window_exiting(cpu_state);
1110
}
1111
@@ -XXX,XX +XXX,XX @@ bool hvf_inject_interrupts(CPUState *cpu_state)
1112
int line = cpu_get_pic_interrupt(&x86cpu->env);
1113
cpu_state->interrupt_request &= ~CPU_INTERRUPT_HARD;
1114
if (line >= 0) {
1115
- wvmcs(cpu_state->hvf_fd, VMCS_ENTRY_INTR_INFO, line |
1116
+ wvmcs(cpu_state->hvf->fd, VMCS_ENTRY_INTR_INFO, line |
1117
VMCS_INTR_VALID | VMCS_INTR_T_HWINTR);
1118
}
1119
}
1120
@@ -XXX,XX +XXX,XX @@ int hvf_process_events(CPUState *cpu_state)
1121
X86CPU *cpu = X86_CPU(cpu_state);
1122
CPUX86State *env = &cpu->env;
1123
1124
- env->eflags = rreg(cpu_state->hvf_fd, HV_X86_RFLAGS);
1125
+ env->eflags = rreg(cpu_state->hvf->fd, HV_X86_RFLAGS);
1126
1127
if (cpu_state->interrupt_request & CPU_INTERRUPT_INIT) {
1128
cpu_synchronize_state(cpu_state);
1129
--
97
--
1130
2.20.1
98
2.34.1
1131
99
1132
100
diff view generated by jsdifflib
1
From: Jamie Iles <jamie@nuviainc.com>
1
From: Leif Lindholm <quic_llindhol@quicinc.com>
2
2
3
Now that raise_exception_ra restores the state before raising the
3
I'm migrating to Qualcomm's new open source email infrastructure, so
4
exception we can use restore_exception_ra to perform the state restore +
4
update my email address, and update the mailmap to match.
5
exception raising without clobbering the syndrome.
6
5
7
Cc: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
8
Cc: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
9
Signed-off-by: Jamie Iles <jamie@nuviainc.com>
8
Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
10
[PMM: Keep the one line of the comment that is still relevant]
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20241205114047.1125842-1-leif.lindholm@oss.qualcomm.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
target/arm/mte_helper.c | 12 +++---------
14
MAINTAINERS | 2 +-
15
1 file changed, 3 insertions(+), 9 deletions(-)
15
.mailmap | 5 +++--
16
2 files changed, 4 insertions(+), 3 deletions(-)
16
17
17
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
18
diff --git a/MAINTAINERS b/MAINTAINERS
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/mte_helper.c
20
--- a/MAINTAINERS
20
+++ b/target/arm/mte_helper.c
21
+++ b/MAINTAINERS
21
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
22
@@ -XXX,XX +XXX,XX @@ F: include/hw/ssi/imx_spi.h
22
23
SBSA-REF
23
switch (tcf) {
24
M: Radoslaw Biernacki <rad@semihalf.com>
24
case 1:
25
M: Peter Maydell <peter.maydell@linaro.org>
25
- /*
26
-R: Leif Lindholm <quic_llindhol@quicinc.com>
26
- * Tag check fail causes a synchronous exception.
27
+R: Leif Lindholm <leif.lindholm@oss.qualcomm.com>
27
- *
28
R: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
28
- * In restore_state_to_opc, we set the exception syndrome
29
L: qemu-arm@nongnu.org
29
- * for the load or store operation. Unwind first so we
30
S: Maintained
30
- * may overwrite that with the syndrome for the tag check.
31
diff --git a/.mailmap b/.mailmap
31
- */
32
index XXXXXXX..XXXXXXX 100644
32
- cpu_restore_state(env_cpu(env), ra, true);
33
--- a/.mailmap
33
+ /* Tag check fail causes a synchronous exception. */
34
+++ b/.mailmap
34
env->exception.vaddress = dirty_ptr;
35
@@ -XXX,XX +XXX,XX @@ Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
35
36
Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
36
is_write = FIELD_EX32(desc, MTEDESC, WRITE);
37
James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
37
syn = syn_data_abort_no_iss(arm_current_el(env) != 0, 0, 0, 0, 0,
38
Juan Quintela <quintela@trasno.org> <quintela@redhat.com>
38
is_write, 0x11);
39
-Leif Lindholm <quic_llindhol@quicinc.com> <leif.lindholm@linaro.org>
39
- raise_exception(env, EXCP_DATA_ABORT, syn, exception_target_el(env));
40
-Leif Lindholm <quic_llindhol@quicinc.com> <leif@nuviainc.com>
40
+ raise_exception_ra(env, EXCP_DATA_ABORT, syn,
41
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <quic_llindhol@quicinc.com>
41
+ exception_target_el(env), ra);
42
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif.lindholm@linaro.org>
42
/* noreturn, but fall through to the assert anyway */
43
+Leif Lindholm <leif.lindholm@oss.qualcomm.com> <leif@nuviainc.com>
43
44
Luc Michel <luc@lmichel.fr> <luc.michel@git.antfield.fr>
44
case 0:
45
Luc Michel <luc@lmichel.fr> <luc.michel@greensocs.com>
46
Luc Michel <luc@lmichel.fr> <lmichel@kalray.eu>
45
--
47
--
46
2.20.1
48
2.34.1
47
49
48
50
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Vikram Garhwal <vikram.garhwal@bytedance.com>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Previously, maintainer role was paused due to inactive email id. Commit id:
4
Message-id: 20210525225817.400336-12-richard.henderson@linaro.org
4
c009d715721861984c4987bcc78b7ee183e86d75.
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
6
Signed-off-by: Vikram Garhwal <vikram.garhwal@bytedance.com>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Message-id: 20241204184205.12952-1-vikram.garhwal@bytedance.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
linux-user/elfload.c | 2 ++
11
MAINTAINERS | 2 ++
9
1 file changed, 2 insertions(+)
12
1 file changed, 2 insertions(+)
10
13
11
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
14
diff --git a/MAINTAINERS b/MAINTAINERS
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/linux-user/elfload.c
16
--- a/MAINTAINERS
14
+++ b/linux-user/elfload.c
17
+++ b/MAINTAINERS
15
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
18
@@ -XXX,XX +XXX,XX @@ F: tests/qtest/fuzz-sb16-test.c
16
GET_FEATURE_ID(aa64_sve_i8mm, ARM_HWCAP2_A64_SVEI8MM);
19
17
GET_FEATURE_ID(aa64_sve_f32mm, ARM_HWCAP2_A64_SVEF32MM);
20
Xilinx CAN
18
GET_FEATURE_ID(aa64_sve_f64mm, ARM_HWCAP2_A64_SVEF64MM);
21
M: Francisco Iglesias <francisco.iglesias@amd.com>
19
+ GET_FEATURE_ID(aa64_sve_bf16, ARM_HWCAP2_A64_SVEBF16);
22
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
20
GET_FEATURE_ID(aa64_i8mm, ARM_HWCAP2_A64_I8MM);
23
S: Maintained
21
+ GET_FEATURE_ID(aa64_bf16, ARM_HWCAP2_A64_BF16);
24
F: hw/net/can/xlnx-*
22
GET_FEATURE_ID(aa64_rndr, ARM_HWCAP2_A64_RNG);
25
F: include/hw/net/xlnx-*
23
GET_FEATURE_ID(aa64_bti, ARM_HWCAP2_A64_BTI);
26
@@ -XXX,XX +XXX,XX @@ F: include/hw/rx/
24
GET_FEATURE_ID(aa64_mte, ARM_HWCAP2_A64_MTE);
27
CAN bus subsystem and hardware
28
M: Pavel Pisa <pisa@cmp.felk.cvut.cz>
29
M: Francisco Iglesias <francisco.iglesias@amd.com>
30
+M: Vikram Garhwal <vikram.garhwal@bytedance.com>
31
S: Maintained
32
W: https://canbus.pages.fel.cvut.cz/
33
F: net/can/*
25
--
34
--
26
2.20.1
35
2.34.1
27
28
diff view generated by jsdifflib