mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge tag 'pull-target-arm-20241105' of https://git.linaro.org/people/pmaydell/qemu-arm into staging
target-arm queue: * Fix MMU indexes for AArch32 Secure PL1&0 in a less complex and buggy way * Fix SVE SDOT/UDOT/USDOT (4-way, indexed) * softfloat: set 2-operand NaN propagation rule at runtime * disas: Fix build against Capstone v6 (again) * hw/rtc/ds1338: Trace send and receive operations * hw/timer/imx_gpt: Convert DPRINTF to trace events * hw/watchdog/wdt_imx2: Remove redundant assignment * hw/sensor/tmp105: Convert printf() to trace event, add tracing for read/write access * hw/net/npcm_gmac: Change error log to trace event * target/arm: Enable FEAT_CMOW for -cpu max # -----BEGIN PGP SIGNATURE----- # # iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmcp/yoZHHBldGVyLm1h # eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3ucMD/9pWk2ETLjdviPxlacs5IoM # HvGn8Ll2BSMbeb4YdJc7oZ4YJchGpgHhocEwZuaU9HheWjSg+ZEbyhZgN4DdkT8J # pYr+Rl0MgDNN219kYnO/yqnqlgHbtUpE7y57Li3ApoGNbWAVxsH0xoT45Lpi7DOd # uvJfIy/xdaT3zu/4uBjj7c2VrD8wntEayLM8hpqlgeQZKRG3Wtlk/xrQFKOHPDPO # MDbsGoc2FyogRQoo6WH+J6gkkR9PhqXe6Hbf6WIr1/uffZUZU4M8leSw2DgxrYHo # Zf36AzttwO4GHyML/5SR7uvzfXl7OkGyjedLGCUa7INc3br2+GvLMltdLGGPM9cc # ckMHOWd9ZQuSxcpbtPkSYRG0McRE1GLT+KV3BNOLnN9AJl3qv5Qa55iPrtpB08vX # 3jN6H964w99+NoSB2tTHszpep+M7SRuw5QLsuk3tC/qnBMpzKRwZjGVUegNUtfi/ # Lg5ExF8B62K+xb5j5FmODbbXZmb5AD0rV2MGRIVHjiHdnf7J2FmWUJCe2sYFRnRm # nzszhdOKw4PBhC2fb6Vb/DwCqdQy9vcITWpWBtcjkV5mAPhcBo/VNKNeKoc/tPNS # H8FIFIJbtv5aIixqtKcUBUmrBCYy4EoiRMLkqfC09VW60wtWswAP4KBQxi1ogehV # jJw8AgSLCl2MsVmyzgleZQ== # =Woag # -----END PGP SIGNATURE----- # gpg: Signature made Tue 05 Nov 2024 11:19:06 GMT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate] # gpg: aka "Peter Maydell <peter@archaic.org.uk>" [ultimate] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * tag 'pull-target-arm-20241105' of https://git.linaro.org/people/pmaydell/qemu-arm: (31 commits) target/arm: Enable FEAT_CMOW for -cpu max hw/net/npcm_gmac: Change error log to trace event hw/sensor/tmp105: Convert printf() to trace event, add tracing for read/write access hw/watchdog/wdt_imx2: Remove redundant assignment hw/timer/imx_gpt: Convert DPRINTF to trace events hw/rtc/ds1338: Trace send and receive operations disas: Fix build against Capstone v6 (again) target/arm: Fix SVE SDOT/UDOT/USDOT (4-way, indexed) target/arm: Add new MMU indexes for AArch32 Secure PL1&0 Revert "target/arm: Fix usage of MMU indexes when EL3 is AArch32" softfloat: Remove fallback rule from pickNaN() target/rx: Explicitly set 2-NaN propagation rule target/openrisc: Explicitly set 2-NaN propagation rule target/microblaze: Explicitly set 2-NaN propagation rule target/microblaze: Move setting of float rounding mode to reset target/alpha: Explicitly set 2-NaN propagation rule target/i386: Set 2-NaN propagation rule explicitly target/xtensa: Explicitly set 2-NaN propagation rule target/xtensa: Factor out calls to set_use_first_nan() target/sparc: Explicitly set 2-NaN propagation rule ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -26,6 +26,7 @@ the following architecture extensions:
|
||||
- FEAT_BF16 (AArch64 BFloat16 instructions)
|
||||
- FEAT_BTI (Branch Target Identification)
|
||||
- FEAT_CCIDX (Extended cache index)
|
||||
- FEAT_CMOW (Control for cache maintenance permission)
|
||||
- FEAT_CRC32 (CRC32 instructions)
|
||||
- FEAT_Crypto (Cryptographic Extension)
|
||||
- FEAT_CSV2 (Cache speculation variant 2)
|
||||
|
||||
@@ -390,118 +390,80 @@ bool float32_is_signaling_nan(float32 a_, float_status *status)
|
||||
static int pickNaN(FloatClass a_cls, FloatClass b_cls,
|
||||
bool aIsLargerSignificand, float_status *status)
|
||||
{
|
||||
#if defined(TARGET_ARM) || defined(TARGET_MIPS) || defined(TARGET_HPPA) || \
|
||||
defined(TARGET_LOONGARCH64) || defined(TARGET_S390X)
|
||||
/* ARM mandated NaN propagation rules (see FPProcessNaNs()), take
|
||||
* the first of:
|
||||
* 1. A if it is signaling
|
||||
* 2. B if it is signaling
|
||||
* 3. A (quiet)
|
||||
* 4. B (quiet)
|
||||
* A signaling NaN is always quietened before returning it.
|
||||
*/
|
||||
/* According to MIPS specifications, if one of the two operands is
|
||||
* a sNaN, a new qNaN has to be generated. This is done in
|
||||
* floatXX_silence_nan(). For qNaN inputs the specifications
|
||||
* says: "When possible, this QNaN result is one of the operand QNaN
|
||||
* values." In practice it seems that most implementations choose
|
||||
* the first operand if both operands are qNaN. In short this gives
|
||||
* the following rules:
|
||||
* 1. A if it is signaling
|
||||
* 2. B if it is signaling
|
||||
* 3. A (quiet)
|
||||
* 4. B (quiet)
|
||||
* A signaling NaN is always silenced before returning it.
|
||||
*/
|
||||
if (is_snan(a_cls)) {
|
||||
return 0;
|
||||
} else if (is_snan(b_cls)) {
|
||||
return 1;
|
||||
} else if (is_qnan(a_cls)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
#elif defined(TARGET_PPC) || defined(TARGET_M68K)
|
||||
/* PowerPC propagation rules:
|
||||
* 1. A if it sNaN or qNaN
|
||||
* 2. B if it sNaN or qNaN
|
||||
* A signaling NaN is always silenced before returning it.
|
||||
*/
|
||||
/* M68000 FAMILY PROGRAMMER'S REFERENCE MANUAL
|
||||
* 3.4 FLOATING-POINT INSTRUCTION DETAILS
|
||||
* If either operand, but not both operands, of an operation is a
|
||||
* nonsignaling NaN, then that NaN is returned as the result. If both
|
||||
* operands are nonsignaling NaNs, then the destination operand
|
||||
* nonsignaling NaN is returned as the result.
|
||||
* If either operand to an operation is a signaling NaN (SNaN), then the
|
||||
* SNaN bit is set in the FPSR EXC byte. If the SNaN exception enable bit
|
||||
* is set in the FPCR ENABLE byte, then the exception is taken and the
|
||||
* destination is not modified. If the SNaN exception enable bit is not
|
||||
* set, setting the SNaN bit in the operand to a one converts the SNaN to
|
||||
* a nonsignaling NaN. The operation then continues as described in the
|
||||
* preceding paragraph for nonsignaling NaNs.
|
||||
*/
|
||||
if (is_nan(a_cls)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
#elif defined(TARGET_SPARC)
|
||||
/* Prefer SNaN over QNaN, order B then A. */
|
||||
if (is_snan(b_cls)) {
|
||||
return 1;
|
||||
} else if (is_snan(a_cls)) {
|
||||
return 0;
|
||||
} else if (is_qnan(b_cls)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
#elif defined(TARGET_XTENSA)
|
||||
/*
|
||||
* Xtensa has two NaN propagation modes.
|
||||
* Which one is active is controlled by float_status::use_first_nan.
|
||||
* We guarantee not to require the target to tell us how to
|
||||
* pick a NaN if we're always returning the default NaN.
|
||||
* But if we're not in default-NaN mode then the target must
|
||||
* specify via set_float_2nan_prop_rule().
|
||||
*/
|
||||
if (status->use_first_nan) {
|
||||
assert(!status->default_nan_mode);
|
||||
|
||||
switch (status->float_2nan_prop_rule) {
|
||||
case float_2nan_prop_s_ab:
|
||||
if (is_snan(a_cls)) {
|
||||
return 0;
|
||||
} else if (is_snan(b_cls)) {
|
||||
return 1;
|
||||
} else if (is_qnan(a_cls)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case float_2nan_prop_s_ba:
|
||||
if (is_snan(b_cls)) {
|
||||
return 1;
|
||||
} else if (is_snan(a_cls)) {
|
||||
return 0;
|
||||
} else if (is_qnan(b_cls)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case float_2nan_prop_ab:
|
||||
if (is_nan(a_cls)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
case float_2nan_prop_ba:
|
||||
if (is_nan(b_cls)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* This implements x87 NaN propagation rules:
|
||||
* SNaN + QNaN => return the QNaN
|
||||
* two SNaNs => return the one with the larger significand, silenced
|
||||
* two QNaNs => return the one with the larger significand
|
||||
* SNaN and a non-NaN => return the SNaN, silenced
|
||||
* QNaN and a non-NaN => return the QNaN
|
||||
*
|
||||
* If we get down to comparing significands and they are the same,
|
||||
* return the NaN with the positive sign bit (if any).
|
||||
*/
|
||||
if (is_snan(a_cls)) {
|
||||
if (is_snan(b_cls)) {
|
||||
return aIsLargerSignificand ? 0 : 1;
|
||||
}
|
||||
return is_qnan(b_cls) ? 1 : 0;
|
||||
} else if (is_qnan(a_cls)) {
|
||||
if (is_snan(b_cls) || !is_qnan(b_cls)) {
|
||||
return 0;
|
||||
break;
|
||||
case float_2nan_prop_x87:
|
||||
/*
|
||||
* This implements x87 NaN propagation rules:
|
||||
* SNaN + QNaN => return the QNaN
|
||||
* two SNaNs => return the one with the larger significand, silenced
|
||||
* two QNaNs => return the one with the larger significand
|
||||
* SNaN and a non-NaN => return the SNaN, silenced
|
||||
* QNaN and a non-NaN => return the QNaN
|
||||
*
|
||||
* If we get down to comparing significands and they are the same,
|
||||
* return the NaN with the positive sign bit (if any).
|
||||
*/
|
||||
if (is_snan(a_cls)) {
|
||||
if (is_snan(b_cls)) {
|
||||
return aIsLargerSignificand ? 0 : 1;
|
||||
}
|
||||
return is_qnan(b_cls) ? 1 : 0;
|
||||
} else if (is_qnan(a_cls)) {
|
||||
if (is_snan(b_cls) || !is_qnan(b_cls)) {
|
||||
return 0;
|
||||
} else {
|
||||
return aIsLargerSignificand ? 0 : 1;
|
||||
}
|
||||
} else {
|
||||
return aIsLargerSignificand ? 0 : 1;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
|
||||
+2
-3
@@ -546,9 +546,8 @@ static void gmac_try_send_next_packet(NPCMGMACState *gmac)
|
||||
|
||||
/* 1 = DMA Owned, 0 = Software Owned */
|
||||
if (!(tx_desc.tdes0 & TX_DESC_TDES0_OWN)) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"TX Descriptor @ 0x%x is owned by software\n",
|
||||
desc_addr);
|
||||
trace_npcm_gmac_tx_desc_owner(DEVICE(gmac)->canonical_path,
|
||||
desc_addr);
|
||||
gmac->regs[R_NPCM_DMA_STATUS] |= NPCM_DMA_STATUS_TU;
|
||||
gmac_dma_set_state(gmac, NPCM_DMA_STATUS_TX_PROCESS_STATE_SHIFT,
|
||||
NPCM_DMA_STATUS_TX_SUSPENDED_STATE);
|
||||
|
||||
@@ -478,6 +478,7 @@ npcm_gmac_packet_received(const char* name, uint32_t len) "%s: Reception finishe
|
||||
npcm_gmac_packet_sent(const char* name, uint16_t len) "%s: TX packet sent!, length: 0x%04" PRIX16
|
||||
npcm_gmac_debug_desc_data(const char* name, void* addr, uint32_t des0, uint32_t des1, uint32_t des2, uint32_t des3)"%s: Address: %p Descriptor 0: 0x%04" PRIX32 " Descriptor 1: 0x%04" PRIX32 "Descriptor 2: 0x%04" PRIX32 " Descriptor 3: 0x%04" PRIX32
|
||||
npcm_gmac_packet_tx_desc_data(const char* name, uint32_t tdes0, uint32_t tdes1) "%s: Tdes0: 0x%04" PRIX32 " Tdes1: 0x%04" PRIX32
|
||||
npcm_gmac_tx_desc_owner(const char* name, uint32_t desc_addr) "%s: TX Descriptor @0x%04" PRIX32 " is owned by software"
|
||||
|
||||
# npcm_pcs.c
|
||||
npcm_pcs_reg_read(const char *name, uint16_t indirect_access_baes, uint64_t offset, uint16_t value) "%s: IND: 0x%02" PRIx16 " offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "qemu/module.h"
|
||||
#include "qom/object.h"
|
||||
#include "sysemu/rtc.h"
|
||||
#include "trace.h"
|
||||
|
||||
/* Size of NVRAM including both the user-accessible area and the
|
||||
* secondary register area.
|
||||
@@ -126,6 +127,9 @@ static uint8_t ds1338_recv(I2CSlave *i2c)
|
||||
uint8_t res;
|
||||
|
||||
res = s->nvram[s->ptr];
|
||||
|
||||
trace_ds1338_recv(s->ptr, res);
|
||||
|
||||
inc_regptr(s);
|
||||
return res;
|
||||
}
|
||||
@@ -134,6 +138,8 @@ static int ds1338_send(I2CSlave *i2c, uint8_t data)
|
||||
{
|
||||
DS1338State *s = DS1338(i2c);
|
||||
|
||||
trace_ds1338_send(s->ptr, data);
|
||||
|
||||
if (s->addr_byte) {
|
||||
s->ptr = data & (NVRAM_SIZE - 1);
|
||||
s->addr_byte = false;
|
||||
|
||||
@@ -22,6 +22,10 @@ pl031_set_alarm(uint32_t ticks) "alarm set for %u ticks"
|
||||
aspeed_rtc_read(uint64_t addr, uint64_t value) "addr 0x%02" PRIx64 " value 0x%08" PRIx64
|
||||
aspeed_rtc_write(uint64_t addr, uint64_t value) "addr 0x%02" PRIx64 " value 0x%08" PRIx64
|
||||
|
||||
# ds1338.c
|
||||
ds1338_recv(uint32_t addr, uint8_t value) "[0x%" PRIx32 "] -> 0x%02" PRIx8
|
||||
ds1338_send(uint32_t addr, uint8_t value) "[0x%" PRIx32 "] <- 0x%02" PRIx8
|
||||
|
||||
# m48t59.c
|
||||
m48txx_nvram_io_read(uint64_t addr, uint64_t value) "io read addr:0x%04" PRIx64 " value:0x%02" PRIx64
|
||||
m48txx_nvram_io_write(uint64_t addr, uint64_t value) "io write addr:0x%04" PRIx64 " value:0x%02" PRIx64
|
||||
|
||||
+6
-1
@@ -27,6 +27,7 @@
|
||||
#include "qapi/visitor.h"
|
||||
#include "qemu/module.h"
|
||||
#include "hw/registerfields.h"
|
||||
#include "trace.h"
|
||||
|
||||
FIELD(CONFIG, SHUTDOWN_MODE, 0, 1)
|
||||
FIELD(CONFIG, THERMOSTAT_MODE, 1, 1)
|
||||
@@ -150,17 +151,21 @@ static void tmp105_read(TMP105State *s)
|
||||
s->buf[s->len++] = ((uint16_t) s->limit[1]) >> 0;
|
||||
break;
|
||||
}
|
||||
|
||||
trace_tmp105_read(s->i2c.address, s->pointer);
|
||||
}
|
||||
|
||||
static void tmp105_write(TMP105State *s)
|
||||
{
|
||||
trace_tmp105_write(s->i2c.address, s->pointer);
|
||||
|
||||
switch (s->pointer & 3) {
|
||||
case TMP105_REG_TEMPERATURE:
|
||||
break;
|
||||
|
||||
case TMP105_REG_CONFIG:
|
||||
if (FIELD_EX8(s->buf[0] & ~s->config, CONFIG, SHUTDOWN_MODE)) {
|
||||
printf("%s: TMP105 shutdown\n", __func__);
|
||||
trace_tmp105_write_shutdown(s->i2c.address);
|
||||
}
|
||||
s->config = FIELD_DP8(s->buf[0], CONFIG, ONE_SHOT, 0);
|
||||
s->faults = tmp105_faultq[FIELD_EX8(s->config, CONFIG, FAULT_QUEUE)];
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# See docs/devel/tracing.rst for syntax documentation.
|
||||
|
||||
# tmp105.c
|
||||
tmp105_read(uint8_t dev, uint8_t addr) "device: 0x%02x, addr: 0x%02x"
|
||||
tmp105_write(uint8_t dev, uint8_t addr) "device: 0x%02x, addr 0x%02x"
|
||||
tmp105_write_shutdown(uint8_t dev) "device: 0x%02x"
|
||||
@@ -0,0 +1 @@
|
||||
#include "trace/trace-hw_sensor.h"
|
||||
+5
-13
@@ -18,19 +18,12 @@
|
||||
#include "migration/vmstate.h"
|
||||
#include "qemu/module.h"
|
||||
#include "qemu/log.h"
|
||||
#include "trace.h"
|
||||
|
||||
#ifndef DEBUG_IMX_GPT
|
||||
#define DEBUG_IMX_GPT 0
|
||||
#endif
|
||||
|
||||
#define DPRINTF(fmt, args...) \
|
||||
do { \
|
||||
if (DEBUG_IMX_GPT) { \
|
||||
fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_GPT, \
|
||||
__func__, ##args); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static const char *imx_gpt_reg_name(uint32_t reg)
|
||||
{
|
||||
switch (reg) {
|
||||
@@ -145,7 +138,7 @@ static void imx_gpt_set_freq(IMXGPTState *s)
|
||||
s->freq = imx_ccm_get_clock_frequency(s->ccm,
|
||||
s->clocks[clksrc]) / (1 + s->pr);
|
||||
|
||||
DPRINTF("Setting clksrc %d to frequency %d\n", clksrc, s->freq);
|
||||
trace_imx_gpt_set_freq(clksrc, s->freq);
|
||||
|
||||
if (s->freq) {
|
||||
ptimer_set_freq(s->timer, s->freq);
|
||||
@@ -317,7 +310,7 @@ static uint64_t imx_gpt_read(void *opaque, hwaddr offset, unsigned size)
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINTF("(%s) = 0x%08x\n", imx_gpt_reg_name(offset >> 2), reg_value);
|
||||
trace_imx_gpt_read(imx_gpt_reg_name(offset >> 2), reg_value);
|
||||
|
||||
return reg_value;
|
||||
}
|
||||
@@ -384,8 +377,7 @@ static void imx_gpt_write(void *opaque, hwaddr offset, uint64_t value,
|
||||
IMXGPTState *s = IMX_GPT(opaque);
|
||||
uint32_t oldreg;
|
||||
|
||||
DPRINTF("(%s, value = 0x%08x)\n", imx_gpt_reg_name(offset >> 2),
|
||||
(uint32_t)value);
|
||||
trace_imx_gpt_write(imx_gpt_reg_name(offset >> 2), (uint32_t)value);
|
||||
|
||||
switch (offset >> 2) {
|
||||
case 0:
|
||||
@@ -485,7 +477,7 @@ static void imx_gpt_timeout(void *opaque)
|
||||
{
|
||||
IMXGPTState *s = IMX_GPT(opaque);
|
||||
|
||||
DPRINTF("\n");
|
||||
trace_imx_gpt_timeout();
|
||||
|
||||
s->sr |= s->next_int;
|
||||
s->next_int = 0;
|
||||
|
||||
@@ -49,6 +49,12 @@ cmsdk_apb_dualtimer_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK A
|
||||
cmsdk_apb_dualtimer_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB dualtimer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
|
||||
cmsdk_apb_dualtimer_reset(void) "CMSDK APB dualtimer: reset"
|
||||
|
||||
# imx_gpt.c
|
||||
imx_gpt_set_freq(uint32_t clksrc, uint32_t freq) "Setting clksrc %u to %u Hz"
|
||||
imx_gpt_read(const char *name, uint64_t value) "%s -> 0x%08" PRIx64
|
||||
imx_gpt_write(const char *name, uint64_t value) "%s <- 0x%08" PRIx64
|
||||
imx_gpt_timeout(void) ""
|
||||
|
||||
# npcm7xx_timer.c
|
||||
npcm7xx_timer_read(const char *id, uint64_t offset, uint64_t value) " %s offset: 0x%04" PRIx64 " value 0x%08" PRIx64
|
||||
npcm7xx_timer_write(const char *id, uint64_t offset, uint64_t value) "%s offset: 0x%04" PRIx64 " value 0x%08" PRIx64
|
||||
|
||||
@@ -39,7 +39,6 @@ static void imx2_wdt_expired(void *opaque)
|
||||
|
||||
/* Perform watchdog action if watchdog is enabled */
|
||||
if (s->wcr & IMX2_WDT_WCR_WDE) {
|
||||
s->wrsr = IMX2_WDT_WRSR_TOUT;
|
||||
watchdog_perform_action();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#ifdef CONFIG_CAPSTONE
|
||||
|
||||
#define CAPSTONE_AARCH64_COMPAT_HEADER
|
||||
#define CAPSTONE_SYSTEMZ_COMPAT_HEADER
|
||||
#include <capstone.h>
|
||||
|
||||
#else
|
||||
|
||||
@@ -75,6 +75,12 @@ static inline void set_floatx80_rounding_precision(FloatX80RoundPrec val,
|
||||
status->floatx80_rounding_precision = val;
|
||||
}
|
||||
|
||||
static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
|
||||
float_status *status)
|
||||
{
|
||||
status->float_2nan_prop_rule = rule;
|
||||
}
|
||||
|
||||
static inline void set_flush_to_zero(bool val, float_status *status)
|
||||
{
|
||||
status->flush_to_zero = val;
|
||||
@@ -126,6 +132,11 @@ get_floatx80_rounding_precision(float_status *status)
|
||||
return status->floatx80_rounding_precision;
|
||||
}
|
||||
|
||||
static inline Float2NaNPropRule get_float_2nan_prop_rule(float_status *status)
|
||||
{
|
||||
return status->float_2nan_prop_rule;
|
||||
}
|
||||
|
||||
static inline bool get_flush_to_zero(float_status *status)
|
||||
{
|
||||
return status->flush_to_zero;
|
||||
|
||||
@@ -170,6 +170,43 @@ typedef enum __attribute__((__packed__)) {
|
||||
floatx80_precision_s,
|
||||
} FloatX80RoundPrec;
|
||||
|
||||
/*
|
||||
* 2-input NaN propagation rule. Individual architectures have
|
||||
* different rules for which input NaN is propagated to the output
|
||||
* when there is more than one NaN on the input.
|
||||
*
|
||||
* If default_nan_mode is enabled then it is valid not to set a
|
||||
* NaN propagation rule, because the softfloat code guarantees
|
||||
* not to try to pick a NaN to propagate in default NaN mode.
|
||||
* When not in default-NaN mode, it is an error for the target
|
||||
* not to set the rule in float_status, and we will assert if
|
||||
* we need to handle an input NaN and no rule was selected.
|
||||
*/
|
||||
typedef enum __attribute__((__packed__)) {
|
||||
/* No propagation rule specified */
|
||||
float_2nan_prop_none = 0,
|
||||
/* Prefer SNaN over QNaN, then operand A over B */
|
||||
float_2nan_prop_s_ab,
|
||||
/* Prefer SNaN over QNaN, then operand B over A */
|
||||
float_2nan_prop_s_ba,
|
||||
/* Prefer A over B regardless of SNaN vs QNaN */
|
||||
float_2nan_prop_ab,
|
||||
/* Prefer B over A regardless of SNaN vs QNaN */
|
||||
float_2nan_prop_ba,
|
||||
/*
|
||||
* This implements x87 NaN propagation rules:
|
||||
* SNaN + QNaN => return the QNaN
|
||||
* two SNaNs => return the one with the larger significand, silenced
|
||||
* two QNaNs => return the one with the larger significand
|
||||
* SNaN and a non-NaN => return the SNaN, silenced
|
||||
* QNaN and a non-NaN => return the QNaN
|
||||
*
|
||||
* If we get down to comparing significands and they are the same,
|
||||
* return the NaN with the positive sign bit (if any).
|
||||
*/
|
||||
float_2nan_prop_x87,
|
||||
} Float2NaNPropRule;
|
||||
|
||||
/*
|
||||
* Floating Point Status. Individual architectures may maintain
|
||||
* several versions of float_status for different functions. The
|
||||
@@ -181,6 +218,7 @@ typedef struct float_status {
|
||||
uint16_t float_exception_flags;
|
||||
FloatRoundMode float_rounding_mode;
|
||||
FloatX80RoundPrec floatx80_rounding_precision;
|
||||
Float2NaNPropRule float_2nan_prop_rule;
|
||||
bool tininess_before_rounding;
|
||||
/* should denormalised results go to zero and set the inexact flag? */
|
||||
bool flush_to_zero;
|
||||
|
||||
@@ -51,6 +51,24 @@ void resetFPA11(void)
|
||||
#ifdef MAINTAIN_FPCR
|
||||
fpa11->fpcr = MASK_RESET;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Real FPA11 hardware does not handle NaNs, but always takes an
|
||||
* exception for them to be software-emulated (ARM7500FE datasheet
|
||||
* section 10.4). There is no documented architectural requirement
|
||||
* for NaN propagation rules and it will depend on how the OS
|
||||
* level software emulation opted to do it. We here use prop_s_ab
|
||||
* which matches the later VFP hardware choice and how QEMU's
|
||||
* fpa11 emulation has worked in the past. The real Linux kernel
|
||||
* does something slightly different: arch/arm/nwfpe/softfloat-specialize
|
||||
* propagateFloat64NaN() has the curious behaviour that it prefers
|
||||
* the QNaN over the SNaN, but if both are QNaN it picks A and
|
||||
* if both are SNaN it picks B. In theory we could add this as
|
||||
* a NaN propagation rule, but in practice FPA11 emulation is so
|
||||
* close to totally dead that it's not worth trying to match it at
|
||||
* this late date.
|
||||
*/
|
||||
set_float_2nan_prop_rule(float_2nan_prop_s_ab, &fpa11->fp_status);
|
||||
}
|
||||
|
||||
void SetRoundingMode(const unsigned int opcode)
|
||||
|
||||
@@ -3484,6 +3484,7 @@ if have_system
|
||||
'hw/s390x',
|
||||
'hw/scsi',
|
||||
'hw/sd',
|
||||
'hw/sensor',
|
||||
'hw/sh4',
|
||||
'hw/sparc',
|
||||
'hw/sparc64',
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "qemu/qemu-print.h"
|
||||
#include "cpu.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "fpu/softfloat.h"
|
||||
|
||||
|
||||
static void alpha_cpu_set_pc(CPUState *cs, vaddr value)
|
||||
@@ -187,7 +188,17 @@ static void alpha_cpu_initfn(Object *obj)
|
||||
{
|
||||
CPUAlphaState *env = cpu_env(CPU(obj));
|
||||
|
||||
/* TODO all this should be done in reset, not init */
|
||||
|
||||
env->lock_addr = -1;
|
||||
|
||||
/*
|
||||
* TODO: this is incorrect. The Alpha Architecture Handbook version 4
|
||||
* describes NaN propagation in section 4.7.10.4. We should prefer
|
||||
* the operand in Fb (whether it is a QNaN or an SNaN), then the
|
||||
* operand in Fa. That is float_2nan_prop_ba.
|
||||
*/
|
||||
set_float_2nan_prop_rule(float_2nan_prop_x87, &env->fp_status);
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
env->flags = ENV_FLAG_PS_USER | ENV_FLAG_FEN;
|
||||
cpu_alpha_store_fpcr(env, (uint64_t)(FPCR_INVD | FPCR_DZED | FPCR_OVFD
|
||||
|
||||
@@ -802,6 +802,11 @@ static inline bool isar_feature_aa64_tidcp1(const ARMISARegisters *id)
|
||||
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, TIDCP1) != 0;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_cmow(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, CMOW) != 0;
|
||||
}
|
||||
|
||||
static inline bool isar_feature_aa64_hafs(const ARMISARegisters *id)
|
||||
{
|
||||
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) != 0;
|
||||
|
||||
+17
-8
@@ -168,6 +168,18 @@ void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
|
||||
QLIST_INSERT_HEAD(&cpu->el_change_hooks, entry, node);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the float_status behaviour to match the Arm defaults:
|
||||
* * tininess-before-rounding
|
||||
* * 2-input NaN propagation prefers SNaN over QNaN, and then
|
||||
* operand A over operand B (see FPProcessNaNs() pseudocode)
|
||||
*/
|
||||
static void arm_set_default_fp_behaviours(float_status *s)
|
||||
{
|
||||
set_float_detect_tininess(float_tininess_before_rounding, s);
|
||||
set_float_2nan_prop_rule(float_2nan_prop_s_ab, s);
|
||||
}
|
||||
|
||||
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
|
||||
{
|
||||
/* Reset a single ARMCPRegInfo register */
|
||||
@@ -549,14 +561,11 @@ static void arm_cpu_reset_hold(Object *obj, ResetType type)
|
||||
set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status);
|
||||
set_default_nan_mode(1, &env->vfp.standard_fp_status);
|
||||
set_default_nan_mode(1, &env->vfp.standard_fp_status_f16);
|
||||
set_float_detect_tininess(float_tininess_before_rounding,
|
||||
&env->vfp.fp_status);
|
||||
set_float_detect_tininess(float_tininess_before_rounding,
|
||||
&env->vfp.standard_fp_status);
|
||||
set_float_detect_tininess(float_tininess_before_rounding,
|
||||
&env->vfp.fp_status_f16);
|
||||
set_float_detect_tininess(float_tininess_before_rounding,
|
||||
&env->vfp.standard_fp_status_f16);
|
||||
arm_set_default_fp_behaviours(&env->vfp.fp_status);
|
||||
arm_set_default_fp_behaviours(&env->vfp.standard_fp_status);
|
||||
arm_set_default_fp_behaviours(&env->vfp.fp_status_f16);
|
||||
arm_set_default_fp_behaviours(&env->vfp.standard_fp_status_f16);
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
if (kvm_enabled()) {
|
||||
kvm_arm_reset_vcpu(cpu);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user