target-arm queue:

* hw/arm: Remove various uses of first_cpu global
  * hw/char/imx_serial: Fix reset value of UFCR register
  * hw/char/imx_serial: Update all state before restarting ageing timer
  * hw/pci-host/designware: Expose MSI IRQ
  * hw/arm/stellaris: refactoring, cleanup
  * hw/arm/stellaris: map both I2C controllers
  * tests/functional: Add a test for the arm microbit machine
  * target/arm: arm_reset_sve_state() should set FPSR, not FPCR
  * target/arm: refactorings preparatory to FEAT_AFP implementation
  * fpu: Rename float_flag_input_denormal to float_flag_input_denormal_flushed
  * fpu: Rename float_flag_output_denormal to float_flag_output_denormal_flushed
  * hw/usb/canokey: Fix buffer overflow for OUT packet
 -----BEGIN PGP SIGNATURE-----
 
 iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmeZOi0ZHHBldGVyLm1h
 eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3sUeEACwDhM4ldn/gVZgVN7nf42a
 /CLD/qJx1vqi5bAB5zkY1bSCR9hS2IkhTBoQQH9Ng6ztG1IRpT/tKXDJAemWty70
 XgExdl4yjdwXMQK4JKU9qSfaBTuX7Z8Hz+nA1AnblO/4H+XpVNVJzp8Ee/uWTyEd
 BKPBpwqbIXNwUWEqkzDok074Q05rHlhsJD2DsoJTcmtpROhLHLATwQDZGGFuf56H
 LVcdx6GRP+/mWEGWLtj19mvaR/2cn4rQf+I1MACZ81nRjQCHbCohNAMr2wFsKg1+
 2jYk9uHdFoambJ5+mFuC55Efk+QJaP4vDR0Gf3jLloFr+rS/5h3HiUuD8dUWOwFd
 mPWXsjwYzqBW2knt1nfq1ByzYWZ8rVQEn5G53dX/eoNXuDGsonZxPnevgmv5kIUc
 /W618Jez1nu9RDtNKccobHEtTGlGInJxJ7YzkU7Q6FO80IAqSdV7t9v7uPLJwcnz
 nQz+wVzb4oOmwMzn3BpKY7N/S7IZOSy3ASNHj8o4yCHMJT8Ki0/N4bl0k0DLxJ0T
 RiNCsV9c7MJfo9a+pbOnu0Lc3SjjropdvHYU+bB7R0mgd8ysN+Tou0dpa+i7tUTu
 DHWqs2/+UApHKBiC+DSynPjjRR2aT/5lYFncGaiEVoEQttPLka3SAzgHPVQZs1zD
 bxZkEAFktAFGIjU70fYNkg==
 =H4p7
 -----END PGP SIGNATURE-----

Merge tag 'pull-target-arm-20250128-1' of https://git.linaro.org/people/pmaydell/qemu-arm into staging

target-arm queue:
 * hw/arm: Remove various uses of first_cpu global
 * hw/char/imx_serial: Fix reset value of UFCR register
 * hw/char/imx_serial: Update all state before restarting ageing timer
 * hw/pci-host/designware: Expose MSI IRQ
 * hw/arm/stellaris: refactoring, cleanup
 * hw/arm/stellaris: map both I2C controllers
 * tests/functional: Add a test for the arm microbit machine
 * target/arm: arm_reset_sve_state() should set FPSR, not FPCR
 * target/arm: refactorings preparatory to FEAT_AFP implementation
 * fpu: Rename float_flag_input_denormal to float_flag_input_denormal_flushed
 * fpu: Rename float_flag_output_denormal to float_flag_output_denormal_flushed
 * hw/usb/canokey: Fix buffer overflow for OUT packet

# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmeZOi0ZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3sUeEACwDhM4ldn/gVZgVN7nf42a
# /CLD/qJx1vqi5bAB5zkY1bSCR9hS2IkhTBoQQH9Ng6ztG1IRpT/tKXDJAemWty70
# XgExdl4yjdwXMQK4JKU9qSfaBTuX7Z8Hz+nA1AnblO/4H+XpVNVJzp8Ee/uWTyEd
# BKPBpwqbIXNwUWEqkzDok074Q05rHlhsJD2DsoJTcmtpROhLHLATwQDZGGFuf56H
# LVcdx6GRP+/mWEGWLtj19mvaR/2cn4rQf+I1MACZ81nRjQCHbCohNAMr2wFsKg1+
# 2jYk9uHdFoambJ5+mFuC55Efk+QJaP4vDR0Gf3jLloFr+rS/5h3HiUuD8dUWOwFd
# mPWXsjwYzqBW2knt1nfq1ByzYWZ8rVQEn5G53dX/eoNXuDGsonZxPnevgmv5kIUc
# /W618Jez1nu9RDtNKccobHEtTGlGInJxJ7YzkU7Q6FO80IAqSdV7t9v7uPLJwcnz
# nQz+wVzb4oOmwMzn3BpKY7N/S7IZOSy3ASNHj8o4yCHMJT8Ki0/N4bl0k0DLxJ0T
# RiNCsV9c7MJfo9a+pbOnu0Lc3SjjropdvHYU+bB7R0mgd8ysN+Tou0dpa+i7tUTu
# DHWqs2/+UApHKBiC+DSynPjjRR2aT/5lYFncGaiEVoEQttPLka3SAzgHPVQZs1zD
# bxZkEAFktAFGIjU70fYNkg==
# =H4p7
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 28 Jan 2025 15:12:29 EST
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full]
# gpg:                 aka "Peter Maydell <peter@archaic.org.uk>" [unknown]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* tag 'pull-target-arm-20250128-1' of https://git.linaro.org/people/pmaydell/qemu-arm: (36 commits)
  hw/usb/canokey: Fix buffer overflow for OUT packet
  target/arm: Use FPST_A64_F16 for halfprec-to-other conversions
  target/arm: Remove redundant advsimd float16 helpers
  fpu: Fix a comment in softfloat-types.h
  fpu: Rename float_flag_output_denormal to float_flag_output_denormal_flushed
  fpu: Rename float_flag_input_denormal to float_flag_input_denormal_flushed
  target/arm: Remove now-unused vfp.fp_status_f16 and FPST_FPCR_F16
  target/arm: Use FPST_A64_F16 in A64 decoder
  target/arm: Use FPST_A32_F16 in A32 decoder
  target/arm: Use fp_status_f16_a64 in AArch64-only helpers
  target/arm: Use fp_status_f16_a32 in AArch32-only helpers
  target/arm: Define new fp_status_f16_a32 and fp_status_f16_a64
  target/arm: Remove now-unused vfp.fp_status and FPST_FPCR
  target/arm: Use FPST_A64 in A64 decoder
  target/arm: Use FPST_A32 in A32 decoder
  target/arm: Use fp_status_a32 in vfp_cmp helpers
  target/arm: Use fp_status_a32 in vjvct helper
  target/arm: Use fp_status_a64 or fp_status_a32 in is_ebf()
  target/arm: Use vfp.fp_status_a64 in A64-only helper functions
  target/arm: Define new fp_status_a32 and fp_status_a64
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2025-01-29 09:50:39 -05:00
commit fb49b69bf9
49 changed files with 452 additions and 337 deletions

View file

@ -1157,6 +1157,7 @@ F: hw/*/microbit*.c
F: include/hw/*/nrf51*.h F: include/hw/*/nrf51*.h
F: include/hw/*/microbit*.h F: include/hw/*/microbit*.h
F: tests/qtest/microbit-test.c F: tests/qtest/microbit-test.c
F: tests/functional/test_arm_microbit.py
F: docs/system/arm/nrf.rst F: docs/system/arm/nrf.rst
ARM PL011 Rust device ARM PL011 Rust device

View file

@ -198,7 +198,7 @@ static void partsN(canonicalize)(FloatPartsN *p, float_status *status,
if (likely(frac_eqz(p))) { if (likely(frac_eqz(p))) {
p->cls = float_class_zero; p->cls = float_class_zero;
} else if (status->flush_inputs_to_zero) { } else if (status->flush_inputs_to_zero) {
float_raise(float_flag_input_denormal, status); float_raise(float_flag_input_denormal_flushed, status);
p->cls = float_class_zero; p->cls = float_class_zero;
frac_clear(p); frac_clear(p);
} else { } else {
@ -334,7 +334,7 @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s,
} }
frac_shr(p, frac_shift); frac_shr(p, frac_shift);
} else if (s->flush_to_zero) { } else if (s->flush_to_zero) {
flags |= float_flag_output_denormal; flags |= float_flag_output_denormal_flushed;
p->cls = float_class_zero; p->cls = float_class_zero;
exp = 0; exp = 0;
frac_clear(p); frac_clear(p);

View file

@ -132,7 +132,7 @@ this code that are retained.
if (unlikely(soft_t ## _is_denormal(*a))) { \ if (unlikely(soft_t ## _is_denormal(*a))) { \
*a = soft_t ## _set_sign(soft_t ## _zero, \ *a = soft_t ## _set_sign(soft_t ## _zero, \
soft_t ## _is_neg(*a)); \ soft_t ## _is_neg(*a)); \
float_raise(float_flag_input_denormal, s); \ float_raise(float_flag_input_denormal_flushed, s); \
} \ } \
} }
@ -4848,7 +4848,7 @@ float128 float128_silence_nan(float128 a, float_status *status)
static bool parts_squash_denormal(FloatParts64 p, float_status *status) static bool parts_squash_denormal(FloatParts64 p, float_status *status)
{ {
if (p.exp == 0 && p.frac != 0) { if (p.exp == 0 && p.frac != 0) {
float_raise(float_flag_input_denormal, status); float_raise(float_flag_input_denormal_flushed, status);
return true; return true;
} }
@ -5017,7 +5017,7 @@ floatx80 roundAndPackFloatx80(FloatX80RoundPrec roundingPrecision, bool zSign,
} }
if ( zExp <= 0 ) { if ( zExp <= 0 ) {
if (status->flush_to_zero) { if (status->flush_to_zero) {
float_raise(float_flag_output_denormal, status); float_raise(float_flag_output_denormal_flushed, status);
return packFloatx80(zSign, 0, 0); return packFloatx80(zSign, 0, 0);
} }
isTiny = status->tininess_before_rounding isTiny = status->tininess_before_rounding

View file

@ -516,6 +516,7 @@ config FSL_IMX6
select PL310 # cache controller select PL310 # cache controller
select PCI_EXPRESS_DESIGNWARE select PCI_EXPRESS_DESIGNWARE
select SDHCI select SDHCI
select OR_IRQ
config ASPEED_SOC config ASPEED_SOC
bool bool
@ -573,6 +574,7 @@ config FSL_IMX7
select WDT_IMX2 select WDT_IMX2
select PCI_EXPRESS_DESIGNWARE select PCI_EXPRESS_DESIGNWARE
select SDHCI select SDHCI
select OR_IRQ
select UNIMP select UNIMP
config ARM_SMMUV3 config ARM_SMMUV3

View file

@ -82,7 +82,7 @@ static void bl475e_init(MachineState *machine)
sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_fatal); sysbus_realize(SYS_BUS_DEVICE(&s->soc), &error_fatal);
sc = STM32L4X5_SOC_GET_CLASS(&s->soc); sc = STM32L4X5_SOC_GET_CLASS(&s->soc);
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0, armv7m_load_kernel(s->soc.armv7m.cpu, machine->kernel_filename, 0,
sc->flash_size); sc->flash_size);
if (object_class_by_name(TYPE_DM163)) { if (object_class_by_name(TYPE_DM163)) {

View file

@ -106,6 +106,8 @@ static void fsl_imx6_init(Object *obj)
object_initialize_child(obj, "eth", &s->eth, TYPE_IMX_ENET); object_initialize_child(obj, "eth", &s->eth, TYPE_IMX_ENET);
object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST); object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
object_initialize_child(obj, "pcie4-msi-irq", &s->pcie4_msi_irq,
TYPE_OR_IRQ);
} }
static void fsl_imx6_realize(DeviceState *dev, Error **errp) static void fsl_imx6_realize(DeviceState *dev, Error **errp)
@ -435,14 +437,23 @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
sysbus_realize(SYS_BUS_DEVICE(&s->pcie), &error_abort); sysbus_realize(SYS_BUS_DEVICE(&s->pcie), &error_abort);
sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX6_PCIe_REG_ADDR); sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX6_PCIe_REG_ADDR);
object_property_set_int(OBJECT(&s->pcie4_msi_irq), "num-lines", 2,
&error_abort);
qdev_realize(DEVICE(&s->pcie4_msi_irq), NULL, &error_abort);
irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE4_MSI_IRQ);
qdev_connect_gpio_out(DEVICE(&s->pcie4_msi_irq), 0, irq);
irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE1_IRQ); irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE1_IRQ);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq);
irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE2_IRQ); irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE2_IRQ);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq);
irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE3_IRQ); irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE3_IRQ);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq);
irq = qdev_get_gpio_in(DEVICE(&s->a9mpcore), FSL_IMX6_PCIE4_IRQ); irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 0);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq);
irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 1);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 4, irq);
/* /*
* PCIe PHY * PCIe PHY

View file

@ -150,6 +150,8 @@ static void fsl_imx7_init(Object *obj)
* PCIE * PCIE
*/ */
object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST); object_initialize_child(obj, "pcie", &s->pcie, TYPE_DESIGNWARE_PCIE_HOST);
object_initialize_child(obj, "pcie4-msi-irq", &s->pcie4_msi_irq,
TYPE_OR_IRQ);
/* /*
* USBs * USBs
@ -597,14 +599,23 @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
sysbus_realize(SYS_BUS_DEVICE(&s->pcie), &error_abort); sysbus_realize(SYS_BUS_DEVICE(&s->pcie), &error_abort);
sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX7_PCIE_REG_ADDR); sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcie), 0, FSL_IMX7_PCIE_REG_ADDR);
object_property_set_int(OBJECT(&s->pcie4_msi_irq), "num-lines", 2,
&error_abort);
qdev_realize(DEVICE(&s->pcie4_msi_irq), NULL, &error_abort);
irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTD_MSI_IRQ);
qdev_connect_gpio_out(DEVICE(&s->pcie4_msi_irq), 0, irq);
irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTA_IRQ); irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTA_IRQ);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 0, irq);
irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTB_IRQ); irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTB_IRQ);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 1, irq);
irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTC_IRQ); irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTC_IRQ);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 2, irq);
irq = qdev_get_gpio_in(DEVICE(&s->a7mpcore), FSL_IMX7_PCI_INTD_IRQ); irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 0);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq); sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 3, irq);
irq = qdev_get_gpio_in(DEVICE(&s->pcie4_msi_irq), 1);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->pcie), 4, irq);
/* /*
* USBs * USBs

View file

@ -56,7 +56,7 @@ static void microbit_init(MachineState *machine)
memory_region_add_subregion_overlap(&s->nrf51.container, NRF51_TWI_BASE, memory_region_add_subregion_overlap(&s->nrf51.container, NRF51_TWI_BASE,
mr, -1); mr, -1);
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, armv7m_load_kernel(s->nrf51.armv7m.cpu, machine->kernel_filename,
0, s->nrf51.flash_size); 0, s->nrf51.flash_size);
} }

View file

@ -1211,7 +1211,7 @@ static void mps2tz_common_init(MachineState *machine)
mms->remap_irq); mms->remap_irq);
} }
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, armv7m_load_kernel(mms->iotkit.armv7m[0].cpu, machine->kernel_filename,
0, boot_ram_size(mms)); 0, boot_ram_size(mms));
} }

View file

@ -460,7 +460,7 @@ static void mps2_common_init(MachineState *machine)
qdev_get_gpio_in(armv7m, qdev_get_gpio_in(armv7m,
mmc->fpga_type == FPGA_AN511 ? 47 : 13)); mmc->fpga_type == FPGA_AN511 ? 47 : 13));
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, armv7m_load_kernel(mms->armv7m.cpu, machine->kernel_filename,
0, 0x400000); 0, 0x400000);
} }

View file

@ -92,7 +92,7 @@ static void emcraft_sf2_s2s010_init(MachineState *machine)
cs_line = qdev_get_gpio_in_named(spi_flash, SSI_GPIO_CS, 0); cs_line = qdev_get_gpio_in_named(spi_flash, SSI_GPIO_CS, 0);
sysbus_connect_irq(SYS_BUS_DEVICE(&soc->spi[0]), 1, cs_line); sysbus_connect_irq(SYS_BUS_DEVICE(&soc->spi[0]), 1, cs_line);
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, armv7m_load_kernel(soc->armv7m.cpu, machine->kernel_filename,
0, soc->envm_size); 0, soc->envm_size);
} }

View file

@ -590,7 +590,7 @@ static void musca_init(MachineState *machine)
"cfg_sec_resp", 0)); "cfg_sec_resp", 0));
} }
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, armv7m_load_kernel(mms->sse.armv7m[0].cpu, machine->kernel_filename,
0, 0x2000000); 0, 0x2000000);
} }

View file

@ -48,7 +48,7 @@ static void netduino2_init(MachineState *machine)
qdev_connect_clock_in(dev, "sysclk", sysclk); qdev_connect_clock_in(dev, "sysclk", sysclk);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, armv7m_load_kernel(STM32F205_SOC(dev)->armv7m.cpu, machine->kernel_filename,
0, FLASH_SIZE); 0, FLASH_SIZE);
} }

View file

@ -48,7 +48,7 @@ static void netduinoplus2_init(MachineState *machine)
qdev_connect_clock_in(dev, "sysclk", sysclk); qdev_connect_clock_in(dev, "sysclk", sysclk);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
armv7m_load_kernel(ARM_CPU(first_cpu), armv7m_load_kernel(STM32F405_SOC(dev)->armv7m.cpu,
machine->kernel_filename, machine->kernel_filename,
0, FLASH_SIZE); 0, FLASH_SIZE);
} }

View file

@ -76,16 +76,16 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
} }
/* This clock doesn't need migration because it is fixed-frequency */ /* This clock doesn't need migration because it is fixed-frequency */
clock_set_hz(s->sysclk, HCLK_FRQ); clock_set_hz(s->sysclk, HCLK_FRQ);
qdev_connect_clock_in(DEVICE(&s->cpu), "cpuclk", s->sysclk); qdev_connect_clock_in(DEVICE(&s->armv7m), "cpuclk", s->sysclk);
/* /*
* This SoC has no systick device, so don't connect refclk. * This SoC has no systick device, so don't connect refclk.
* TODO: model the lack of systick (currently the armv7m object * TODO: model the lack of systick (currently the armv7m object
* will always provide one). * will always provide one).
*/ */
object_property_set_link(OBJECT(&s->cpu), "memory", OBJECT(&s->container), object_property_set_link(OBJECT(&s->armv7m), "memory", OBJECT(&s->container),
&error_abort); &error_abort);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpu), errp)) { if (!sysbus_realize(SYS_BUS_DEVICE(&s->armv7m), errp)) {
return; return;
} }
@ -104,7 +104,7 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->uart), 0); mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->uart), 0);
memory_region_add_subregion_overlap(&s->container, NRF51_UART_BASE, mr, 0); memory_region_add_subregion_overlap(&s->container, NRF51_UART_BASE, mr, 0);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart), 0, sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart), 0,
qdev_get_gpio_in(DEVICE(&s->cpu), qdev_get_gpio_in(DEVICE(&s->armv7m),
BASE_TO_IRQ(NRF51_UART_BASE))); BASE_TO_IRQ(NRF51_UART_BASE)));
/* RNG */ /* RNG */
@ -115,7 +115,7 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->rng), 0); mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->rng), 0);
memory_region_add_subregion_overlap(&s->container, NRF51_RNG_BASE, mr, 0); memory_region_add_subregion_overlap(&s->container, NRF51_RNG_BASE, mr, 0);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->rng), 0, sysbus_connect_irq(SYS_BUS_DEVICE(&s->rng), 0,
qdev_get_gpio_in(DEVICE(&s->cpu), qdev_get_gpio_in(DEVICE(&s->armv7m),
BASE_TO_IRQ(NRF51_RNG_BASE))); BASE_TO_IRQ(NRF51_RNG_BASE)));
/* UICR, FICR, NVMC, FLASH */ /* UICR, FICR, NVMC, FLASH */
@ -161,7 +161,7 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
sysbus_mmio_map(SYS_BUS_DEVICE(&s->timer[i]), 0, base_addr); sysbus_mmio_map(SYS_BUS_DEVICE(&s->timer[i]), 0, base_addr);
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer[i]), 0, sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer[i]), 0,
qdev_get_gpio_in(DEVICE(&s->cpu), qdev_get_gpio_in(DEVICE(&s->armv7m),
BASE_TO_IRQ(base_addr))); BASE_TO_IRQ(base_addr)));
} }
@ -185,10 +185,10 @@ static void nrf51_soc_init(Object *obj)
memory_region_init(&s->container, obj, "nrf51-container", UINT64_MAX); memory_region_init(&s->container, obj, "nrf51-container", UINT64_MAX);
object_initialize_child(OBJECT(s), "armv6m", &s->cpu, TYPE_ARMV7M); object_initialize_child(OBJECT(s), "armv6m", &s->armv7m, TYPE_ARMV7M);
qdev_prop_set_string(DEVICE(&s->cpu), "cpu-type", qdev_prop_set_string(DEVICE(&s->armv7m), "cpu-type",
ARM_CPU_TYPE_NAME("cortex-m0")); ARM_CPU_TYPE_NAME("cortex-m0"));
qdev_prop_set_uint32(DEVICE(&s->cpu), "num-irq", 32); qdev_prop_set_uint32(DEVICE(&s->armv7m), "num-irq", 32);
object_initialize_child(obj, "uart", &s->uart, TYPE_NRF51_UART); object_initialize_child(obj, "uart", &s->uart, TYPE_NRF51_UART);
object_property_add_alias(obj, "serial0", OBJECT(&s->uart), "chardev"); object_property_add_alias(obj, "serial0", OBJECT(&s->uart), "chardev");

View file

@ -51,7 +51,7 @@ static void olimex_stm32_h405_init(MachineState *machine)
qdev_connect_clock_in(dev, "sysclk", sysclk); qdev_connect_clock_in(dev, "sysclk", sysclk);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
armv7m_load_kernel(ARM_CPU(first_cpu), armv7m_load_kernel(STM32F405_SOC(dev)->armv7m.cpu,
machine->kernel_filename, machine->kernel_filename,
0, FLASH_SIZE); 0, FLASH_SIZE);
} }

View file

@ -8,6 +8,7 @@
*/ */
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qemu/bitops.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "hw/core/split-irq.h" #include "hw/core/split-irq.h"
#include "hw/sysbus.h" #include "hw/sysbus.h"
@ -49,6 +50,31 @@
#define NUM_IRQ_LINES 64 #define NUM_IRQ_LINES 64
#define NUM_PRIO_BITS 3 #define NUM_PRIO_BITS 3
#define NUM_GPIO 7
#define NUM_UART 4
#define NUM_GPTM 4
#define NUM_I2C 2
/*
* See Stellaris Data Sheet chapter 5.2.5 "System Control",
* Register 13 .. 17: Device Capabilities 0 .. 4 (DC0 .. DC4).
*/
#define DC1_WDT 3
#define DC1_HIB 6
#define DC1_MPU 7
#define DC1_ADC 16
#define DC1_PWM 20
#define DC2_UART(n) (n)
#define DC2_SSI 4
#define DC2_QEI(n) (8 + n)
#define DC2_I2C(n) (12 + 2 * n)
#define DC2_GPTM(n) (16 + n)
#define DC2_COMP(n) (24 + n)
#define DC4_GPIO(n) (n)
#define DC4_EMAC 28
#define DEV_CAP(_dc, _cap) extract32(board->dc##_dc, DC##_dc##_##_cap, 1)
typedef const struct { typedef const struct {
const char *name; const char *name;
uint32_t did0; uint32_t did0;
@ -101,7 +127,7 @@ static void ssys_update(ssys_state *s)
qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0); qemu_set_irq(s->irq, (s->int_status & s->int_mask) != 0);
} }
static uint32_t pllcfg_sandstorm[16] = { static const uint32_t pllcfg_sandstorm[16] = {
0x31c0, /* 1 Mhz */ 0x31c0, /* 1 Mhz */
0x1ae0, /* 1.8432 Mhz */ 0x1ae0, /* 1.8432 Mhz */
0x18c0, /* 2 Mhz */ 0x18c0, /* 2 Mhz */
@ -120,7 +146,7 @@ static uint32_t pllcfg_sandstorm[16] = {
0x585b /* 8.192 Mhz */ 0x585b /* 8.192 Mhz */
}; };
static uint32_t pllcfg_fury[16] = { static const uint32_t pllcfg_fury[16] = {
0x3200, /* 1 Mhz */ 0x3200, /* 1 Mhz */
0x1b20, /* 1.8432 Mhz */ 0x1b20, /* 1.8432 Mhz */
0x1900, /* 2 Mhz */ 0x1900, /* 2 Mhz */
@ -964,7 +990,7 @@ static void stellaris_adc_init(Object *obj)
} }
/* Board init. */ /* Board init. */
static stellaris_board_info stellaris_boards[] = { static const stellaris_board_info stellaris_boards[] = {
{ "LM3S811EVB", { "LM3S811EVB",
0, 0,
0x0032000e, 0x0032000e,
@ -989,19 +1015,20 @@ static stellaris_board_info stellaris_boards[] = {
static void stellaris_init(MachineState *ms, stellaris_board_info *board) static void stellaris_init(MachineState *ms, stellaris_board_info *board)
{ {
static const int uart_irq[] = {5, 6, 33, 34}; static const int uart_irq[NUM_UART] = {5, 6, 33, 34};
static const int timer_irq[] = {19, 21, 23, 35}; static const int timer_irq[NUM_GPTM] = {19, 21, 23, 35};
static const uint32_t gpio_addr[7] = static const uint32_t gpio_addr[NUM_GPIO] =
{ 0x40004000, 0x40005000, 0x40006000, 0x40007000, { 0x40004000, 0x40005000, 0x40006000, 0x40007000,
0x40024000, 0x40025000, 0x40026000}; 0x40024000, 0x40025000, 0x40026000};
static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31}; static const int gpio_irq[NUM_GPIO] = {0, 1, 2, 3, 4, 30, 31};
static const uint32_t i2c_addr[NUM_I2C] = {0x40020000, 0x40021000};
static const int i2c_irq[NUM_I2C] = {8, 37};
/* Memory map of SoC devices, from /* Memory map of SoC devices, from
* Stellaris LM3S6965 Microcontroller Data Sheet (rev I) * Stellaris LM3S6965 Microcontroller Data Sheet (rev I)
* http://www.ti.com/lit/ds/symlink/lm3s6965.pdf * http://www.ti.com/lit/ds/symlink/lm3s6965.pdf
* *
* 40000000 wdtimer * 40000000 wdtimer
* 40002000 i2c (unimplemented)
* 40004000 GPIO * 40004000 GPIO
* 40005000 GPIO * 40005000 GPIO
* 40006000 GPIO * 40006000 GPIO
@ -1031,13 +1058,13 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
*/ */
Object *soc_container; Object *soc_container;
DeviceState *gpio_dev[7], *nvic; DeviceState *gpio_dev[NUM_GPIO], *armv7m, *nvic;
qemu_irq gpio_in[7][8]; qemu_irq gpio_in[NUM_GPIO][8];
qemu_irq gpio_out[7][8]; qemu_irq gpio_out[NUM_GPIO][8];
qemu_irq adc; qemu_irq adc;
int sram_size; int sram_size;
int flash_size; int flash_size;
I2CBus *i2c; DeviceState *i2c_dev[NUM_I2C] = { };
DeviceState *dev; DeviceState *dev;
DeviceState *ssys_dev; DeviceState *ssys_dev;
int i; int i;
@ -1095,25 +1122,26 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
qdev_prop_set_uint32(ssys_dev, "dc4", board->dc4); qdev_prop_set_uint32(ssys_dev, "dc4", board->dc4);
sysbus_realize_and_unref(SYS_BUS_DEVICE(ssys_dev), &error_fatal); sysbus_realize_and_unref(SYS_BUS_DEVICE(ssys_dev), &error_fatal);
nvic = qdev_new(TYPE_ARMV7M); armv7m = qdev_new(TYPE_ARMV7M);
object_property_add_child(soc_container, "v7m", OBJECT(nvic)); object_property_add_child(soc_container, "v7m", OBJECT(armv7m));
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES); qdev_prop_set_uint32(armv7m, "num-irq", NUM_IRQ_LINES);
qdev_prop_set_uint8(nvic, "num-prio-bits", NUM_PRIO_BITS); qdev_prop_set_uint8(armv7m, "num-prio-bits", NUM_PRIO_BITS);
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type); qdev_prop_set_string(armv7m, "cpu-type", ms->cpu_type);
qdev_prop_set_bit(nvic, "enable-bitband", true); qdev_prop_set_bit(armv7m, "enable-bitband", true);
qdev_connect_clock_in(nvic, "cpuclk", qdev_connect_clock_in(armv7m, "cpuclk",
qdev_get_clock_out(ssys_dev, "SYSCLK")); qdev_get_clock_out(ssys_dev, "SYSCLK"));
/* This SoC does not connect the systick reference clock */ /* This SoC does not connect the systick reference clock */
object_property_set_link(OBJECT(nvic), "memory", object_property_set_link(OBJECT(armv7m), "memory",
OBJECT(get_system_memory()), &error_abort); OBJECT(get_system_memory()), &error_abort);
/* This will exit with an error if the user passed us a bad cpu_type */ /* This will exit with an error if the user passed us a bad cpu_type */
sysbus_realize_and_unref(SYS_BUS_DEVICE(nvic), &error_fatal); sysbus_realize_and_unref(SYS_BUS_DEVICE(armv7m), &error_fatal);
nvic = armv7m;
/* Now we can wire up the IRQ and MMIO of the system registers */ /* Now we can wire up the IRQ and MMIO of the system registers */
sysbus_mmio_map(SYS_BUS_DEVICE(ssys_dev), 0, 0x400fe000); sysbus_mmio_map(SYS_BUS_DEVICE(ssys_dev), 0, 0x400fe000);
sysbus_connect_irq(SYS_BUS_DEVICE(ssys_dev), 0, qdev_get_gpio_in(nvic, 28)); sysbus_connect_irq(SYS_BUS_DEVICE(ssys_dev), 0, qdev_get_gpio_in(nvic, 28));
if (board->dc1 & (1 << 16)) { if (DEV_CAP(1, ADC)) {
dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000, dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000,
qdev_get_gpio_in(nvic, 14), qdev_get_gpio_in(nvic, 14),
qdev_get_gpio_in(nvic, 15), qdev_get_gpio_in(nvic, 15),
@ -1124,8 +1152,8 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
} else { } else {
adc = NULL; adc = NULL;
} }
for (i = 0; i < 4; i++) { for (i = 0; i < NUM_GPTM; i++) {
if (board->dc2 & (0x10000 << i)) { if (DEV_CAP(2, GPTM(i))) {
SysBusDevice *sbd; SysBusDevice *sbd;
dev = qdev_new(TYPE_STELLARIS_GPTM); dev = qdev_new(TYPE_STELLARIS_GPTM);
@ -1142,7 +1170,7 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
} }
} }
if (board->dc1 & (1 << 3)) { /* watchdog present */ if (DEV_CAP(1, WDT)) {
dev = qdev_new(TYPE_LUMINARY_WATCHDOG); dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
object_property_add_child(soc_container, "wdg", OBJECT(dev)); object_property_add_child(soc_container, "wdg", OBJECT(dev));
qdev_connect_clock_in(dev, "WDOGCLK", qdev_connect_clock_in(dev, "WDOGCLK",
@ -1158,8 +1186,8 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
} }
for (i = 0; i < 7; i++) { for (i = 0; i < NUM_GPIO; i++) {
if (board->dc4 & (1 << i)) { if (DEV_CAP(4, GPIO(i))) {
gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i], gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i],
qdev_get_gpio_in(nvic, qdev_get_gpio_in(nvic,
gpio_irq[i])); gpio_irq[i]));
@ -1170,17 +1198,21 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
} }
} }
if (board->dc2 & (1 << 12)) { for (i = 0; i < NUM_I2C; i++) {
dev = sysbus_create_simple(TYPE_STELLARIS_I2C, 0x40020000, if (DEV_CAP(2, I2C(i))) {
qdev_get_gpio_in(nvic, 8)); i2c_dev[i] = sysbus_create_simple(TYPE_STELLARIS_I2C, i2c_addr[i],
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c"); qdev_get_gpio_in(nvic,
if (board->peripherals & BP_OLED_I2C) { i2c_irq[i]));
i2c_slave_create_simple(i2c, "ssd0303", 0x3d);
} }
} }
if (board->peripherals & BP_OLED_I2C) {
I2CBus *bus = (I2CBus *)qdev_get_child_bus(i2c_dev[0], "i2c");
for (i = 0; i < 4; i++) { i2c_slave_create_simple(bus, "ssd0303", 0x3d);
if (board->dc2 & (1 << i)) { }
for (i = 0; i < NUM_UART; i++) {
if (DEV_CAP(2, UART(i))) {
SysBusDevice *sbd; SysBusDevice *sbd;
dev = qdev_new("pl011_luminary"); dev = qdev_new("pl011_luminary");
@ -1192,7 +1224,7 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(nvic, uart_irq[i])); sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(nvic, uart_irq[i]));
} }
} }
if (board->dc2 & (1 << 4)) { if (DEV_CAP(2, SSI)) {
dev = sysbus_create_simple("pl022", 0x40008000, dev = sysbus_create_simple("pl022", 0x40008000,
qdev_get_gpio_in(nvic, 7)); qdev_get_gpio_in(nvic, 7));
if (board->peripherals & BP_OLED_SSI) { if (board->peripherals & BP_OLED_SSI) {
@ -1301,7 +1333,7 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
qemu_irq_raise(gpio_out[GPIO_D][0]); qemu_irq_raise(gpio_out[GPIO_D][0]);
} }
} }
if (board->dc4 & (1 << 28)) { if (DEV_CAP(4, EMAC)) {
DeviceState *enet; DeviceState *enet;
enet = qdev_new("stellaris_enet"); enet = qdev_new("stellaris_enet");
@ -1356,8 +1388,6 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
/* Add dummy regions for the devices we don't implement yet, /* Add dummy regions for the devices we don't implement yet,
* so guest accesses don't cause unlogged crashes. * so guest accesses don't cause unlogged crashes.
*/ */
create_unimplemented_device("i2c-0", 0x40002000, 0x1000);
create_unimplemented_device("i2c-2", 0x40021000, 0x1000);
create_unimplemented_device("PWM", 0x40028000, 0x1000); create_unimplemented_device("PWM", 0x40028000, 0x1000);
create_unimplemented_device("QEI-0", 0x4002c000, 0x1000); create_unimplemented_device("QEI-0", 0x4002c000, 0x1000);
create_unimplemented_device("QEI-1", 0x4002d000, 0x1000); create_unimplemented_device("QEI-1", 0x4002d000, 0x1000);
@ -1365,7 +1395,7 @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
create_unimplemented_device("hibernation", 0x400fc000, 0x1000); create_unimplemented_device("hibernation", 0x400fc000, 0x1000);
create_unimplemented_device("flash-control", 0x400fd000, 0x1000); create_unimplemented_device("flash-control", 0x400fd000, 0x1000);
armv7m_load_kernel(ARM_CPU(first_cpu), ms->kernel_filename, 0, flash_size); armv7m_load_kernel(ARMV7M(armv7m)->cpu, ms->kernel_filename, 0, flash_size);
} }
/* FIXME: Figure out how to generate these from stellaris_boards. */ /* FIXME: Figure out how to generate these from stellaris_boards. */
@ -1379,6 +1409,10 @@ static void lm3s6965evb_init(MachineState *machine)
stellaris_init(machine, &stellaris_boards[1]); stellaris_init(machine, &stellaris_boards[1]);
} }
/*
* Stellaris LM3S811 Evaluation Board Schematics:
* https://www.ti.com/lit/ug/symlink/spmu030.pdf
*/
static void lm3s811evb_class_init(ObjectClass *oc, void *data) static void lm3s811evb_class_init(ObjectClass *oc, void *data)
{ {
MachineClass *mc = MACHINE_CLASS(oc); MachineClass *mc = MACHINE_CLASS(oc);
@ -1395,6 +1429,10 @@ static const TypeInfo lm3s811evb_type = {
.class_init = lm3s811evb_class_init, .class_init = lm3s811evb_class_init,
}; };
/*
* Stellaris: LM3S6965 Evaluation Board Schematics:
* https://www.ti.com/lit/ug/symlink/spmu029.pdf
*/
static void lm3s6965evb_class_init(ObjectClass *oc, void *data) static void lm3s6965evb_class_init(ObjectClass *oc, void *data)
{ {
MachineClass *mc = MACHINE_CLASS(oc); MachineClass *mc = MACHINE_CLASS(oc);

View file

@ -51,7 +51,7 @@ static void stm32vldiscovery_init(MachineState *machine)
qdev_connect_clock_in(dev, "sysclk", sysclk); qdev_connect_clock_in(dev, "sysclk", sysclk);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
armv7m_load_kernel(ARM_CPU(first_cpu), armv7m_load_kernel(STM32F100_SOC(dev)->armv7m.cpu,
machine->kernel_filename, machine->kernel_filename,
0, FLASH_SIZE); 0, FLASH_SIZE);
} }

View file

@ -160,6 +160,7 @@ static void imx_serial_reset(IMXSerialState *s)
s->ucr3 = 0x700; s->ucr3 = 0x700;
s->ubmr = 0; s->ubmr = 0;
s->ubrc = 4; s->ubrc = 4;
s->ufcr = BIT(11) | BIT(0);
fifo32_reset(&s->rx_fifo); fifo32_reset(&s->rx_fifo);
timer_del(&s->ageing_timer); timer_del(&s->ageing_timer);
@ -400,14 +401,14 @@ static void imx_put_data(void *opaque, uint32_t value)
if (fifo32_num_used(&s->rx_fifo) >= rxtl) { if (fifo32_num_used(&s->rx_fifo) >= rxtl) {
s->usr1 |= USR1_RRDY; s->usr1 |= USR1_RRDY;
} }
imx_serial_rx_fifo_ageing_timer_restart(s);
s->usr2 |= USR2_RDR; s->usr2 |= USR2_RDR;
s->uts1 &= ~UTS1_RXEMPTY; s->uts1 &= ~UTS1_RXEMPTY;
if (value & URXD_BRK) { if (value & URXD_BRK) {
s->usr2 |= USR2_BRCD; s->usr2 |= USR2_BRCD;
} }
imx_serial_rx_fifo_ageing_timer_restart(s);
imx_update(s); imx_update(s);
} }

View file

@ -55,8 +55,6 @@
#define DESIGNWARE_PCIE_ATU_DEVFN(x) (((x) >> 16) & 0xff) #define DESIGNWARE_PCIE_ATU_DEVFN(x) (((x) >> 16) & 0xff)
#define DESIGNWARE_PCIE_ATU_UPPER_TARGET 0x91C #define DESIGNWARE_PCIE_ATU_UPPER_TARGET 0x91C
#define DESIGNWARE_PCIE_IRQ_MSI 3
static DesignwarePCIEHost * static DesignwarePCIEHost *
designware_pcie_root_to_host(DesignwarePCIERoot *root) designware_pcie_root_to_host(DesignwarePCIERoot *root)
{ {
@ -90,7 +88,7 @@ static void designware_pcie_root_msi_write(void *opaque, hwaddr addr,
root->msi.intr[0].status |= BIT(val) & root->msi.intr[0].enable; root->msi.intr[0].status |= BIT(val) & root->msi.intr[0].enable;
if (root->msi.intr[0].status & ~root->msi.intr[0].mask) { if (root->msi.intr[0].status & ~root->msi.intr[0].mask) {
qemu_set_irq(host->pci.irqs[DESIGNWARE_PCIE_IRQ_MSI], 1); qemu_set_irq(host->pci.msi, 1);
} }
} }
@ -335,7 +333,7 @@ static void designware_pcie_root_config_write(PCIDevice *d, uint32_t address,
case DESIGNWARE_PCIE_MSI_INTR0_STATUS: case DESIGNWARE_PCIE_MSI_INTR0_STATUS:
root->msi.intr[0].status ^= val; root->msi.intr[0].status ^= val;
if (!root->msi.intr[0].status) { if (!root->msi.intr[0].status) {
qemu_set_irq(host->pci.irqs[DESIGNWARE_PCIE_IRQ_MSI], 0); qemu_set_irq(host->pci.msi, 0);
} }
break; break;
@ -680,6 +678,7 @@ static void designware_pcie_host_realize(DeviceState *dev, Error **errp)
for (i = 0; i < ARRAY_SIZE(s->pci.irqs); i++) { for (i = 0; i < ARRAY_SIZE(s->pci.irqs); i++) {
sysbus_init_irq(sbd, &s->pci.irqs[i]); sysbus_init_irq(sbd, &s->pci.irqs[i]);
} }
sysbus_init_irq(sbd, &s->pci.msi);
memory_region_init_io(&s->mmio, memory_region_init_io(&s->mmio,
OBJECT(s), OBJECT(s),

View file

@ -197,8 +197,8 @@ static void canokey_handle_data(USBDevice *dev, USBPacket *p)
switch (p->pid) { switch (p->pid) {
case USB_TOKEN_OUT: case USB_TOKEN_OUT:
trace_canokey_handle_data_out(ep_out, p->iov.size); trace_canokey_handle_data_out(ep_out, p->iov.size);
usb_packet_copy(p, key->ep_out_buffer[ep_out], p->iov.size);
out_pos = 0; out_pos = 0;
/* segment packet into (possibly multiple) ep_out */
while (out_pos != p->iov.size) { while (out_pos != p->iov.size) {
/* /*
* key->ep_out[ep_out] set by prepare_receive * key->ep_out[ep_out] set by prepare_receive
@ -207,8 +207,8 @@ static void canokey_handle_data(USBDevice *dev, USBPacket *p)
* to be the buffer length * to be the buffer length
*/ */
out_len = MIN(p->iov.size - out_pos, key->ep_out_size[ep_out]); out_len = MIN(p->iov.size - out_pos, key->ep_out_size[ep_out]);
memcpy(key->ep_out[ep_out], /* usb_packet_copy would update the pos offset internally */
key->ep_out_buffer[ep_out] + out_pos, out_len); usb_packet_copy(p, key->ep_out[ep_out], out_len);
out_pos += out_len; out_pos += out_len;
/* update ep_out_size to actual len */ /* update ep_out_size to actual len */
key->ep_out_size[ep_out] = out_len; key->ep_out_size[ep_out] = out_len;

View file

@ -24,8 +24,6 @@
#define CANOKEY_EP_NUM 3 #define CANOKEY_EP_NUM 3
/* BULK/INTR IN can be up to 1352 bytes, e.g. get key info */ /* BULK/INTR IN can be up to 1352 bytes, e.g. get key info */
#define CANOKEY_EP_IN_BUFFER_SIZE 2048 #define CANOKEY_EP_IN_BUFFER_SIZE 2048
/* BULK OUT can be up to 270 bytes, e.g. PIV import cert */
#define CANOKEY_EP_OUT_BUFFER_SIZE 512
typedef enum { typedef enum {
CANOKEY_EP_IN_WAIT, CANOKEY_EP_IN_WAIT,
@ -59,8 +57,6 @@ typedef struct CanoKeyState {
/* OUT pointer to canokey recv buffer */ /* OUT pointer to canokey recv buffer */
uint8_t *ep_out[CANOKEY_EP_NUM]; uint8_t *ep_out[CANOKEY_EP_NUM];
uint32_t ep_out_size[CANOKEY_EP_NUM]; uint32_t ep_out_size[CANOKEY_EP_NUM];
/* For large BULK OUT, multiple write to ep_out is needed */
uint8_t ep_out_buffer[CANOKEY_EP_NUM][CANOKEY_EP_OUT_BUFFER_SIZE];
/* Properties */ /* Properties */
char *file; /* canokey-file */ char *file; /* canokey-file */

View file

@ -154,8 +154,10 @@ enum {
float_flag_overflow = 0x0004, float_flag_overflow = 0x0004,
float_flag_underflow = 0x0008, float_flag_underflow = 0x0008,
float_flag_inexact = 0x0010, float_flag_inexact = 0x0010,
float_flag_input_denormal = 0x0020, /* We flushed an input denormal to 0 (because of flush_inputs_to_zero) */
float_flag_output_denormal = 0x0040, float_flag_input_denormal_flushed = 0x0020,
/* We flushed an output denormal to 0 (because of flush_to_zero) */
float_flag_output_denormal_flushed = 0x0040,
float_flag_invalid_isi = 0x0080, /* inf - inf */ float_flag_invalid_isi = 0x0080, /* inf - inf */
float_flag_invalid_imz = 0x0100, /* inf * 0 */ float_flag_invalid_imz = 0x0100, /* inf * 0 */
float_flag_invalid_idi = 0x0200, /* inf / inf */ float_flag_invalid_idi = 0x0200, /* inf / inf */
@ -300,9 +302,9 @@ typedef struct float_status {
Float3NaNPropRule float_3nan_prop_rule; Float3NaNPropRule float_3nan_prop_rule;
FloatInfZeroNaNRule float_infzeronan_rule; FloatInfZeroNaNRule float_infzeronan_rule;
bool tininess_before_rounding; bool tininess_before_rounding;
/* should denormalised results go to zero and set the inexact flag? */ /* should denormalised results go to zero and set output_denormal_flushed? */
bool flush_to_zero; bool flush_to_zero;
/* should denormalised inputs go to zero and set the input_denormal flag? */ /* should denormalised inputs go to zero and set input_denormal_flushed? */
bool flush_inputs_to_zero; bool flush_inputs_to_zero;
bool default_nan_mode; bool default_nan_mode;
/* /*

View file

@ -33,6 +33,7 @@
#include "hw/usb/chipidea.h" #include "hw/usb/chipidea.h"
#include "hw/usb/imx-usb-phy.h" #include "hw/usb/imx-usb-phy.h"
#include "hw/pci-host/designware.h" #include "hw/pci-host/designware.h"
#include "hw/or-irq.h"
#include "exec/memory.h" #include "exec/memory.h"
#include "cpu.h" #include "cpu.h"
#include "qom/object.h" #include "qom/object.h"
@ -73,6 +74,7 @@ struct FslIMX6State {
ChipideaState usb[FSL_IMX6_NUM_USBS]; ChipideaState usb[FSL_IMX6_NUM_USBS];
IMXFECState eth; IMXFECState eth;
DesignwarePCIEHost pcie; DesignwarePCIEHost pcie;
OrIRQState pcie4_msi_irq;
MemoryRegion rom; MemoryRegion rom;
MemoryRegion caam; MemoryRegion caam;
MemoryRegion ocram; MemoryRegion ocram;
@ -457,7 +459,7 @@ struct FslIMX6State {
#define FSL_IMX6_PCIE1_IRQ 120 #define FSL_IMX6_PCIE1_IRQ 120
#define FSL_IMX6_PCIE2_IRQ 121 #define FSL_IMX6_PCIE2_IRQ 121
#define FSL_IMX6_PCIE3_IRQ 122 #define FSL_IMX6_PCIE3_IRQ 122
#define FSL_IMX6_PCIE4_IRQ 123 #define FSL_IMX6_PCIE4_MSI_IRQ 123
#define FSL_IMX6_DCIC1_IRQ 124 #define FSL_IMX6_DCIC1_IRQ 124
#define FSL_IMX6_DCIC2_IRQ 125 #define FSL_IMX6_DCIC2_IRQ 125
#define FSL_IMX6_MLB150_HIGH_IRQ 126 #define FSL_IMX6_MLB150_HIGH_IRQ 126

View file

@ -36,6 +36,7 @@
#include "hw/net/imx_fec.h" #include "hw/net/imx_fec.h"
#include "hw/pci-host/designware.h" #include "hw/pci-host/designware.h"
#include "hw/usb/chipidea.h" #include "hw/usb/chipidea.h"
#include "hw/or-irq.h"
#include "cpu.h" #include "cpu.h"
#include "qom/object.h" #include "qom/object.h"
#include "qemu/units.h" #include "qemu/units.h"
@ -85,6 +86,7 @@ struct FslIMX7State {
IMX7GPRState gpr; IMX7GPRState gpr;
ChipideaState usb[FSL_IMX7_NUM_USBS]; ChipideaState usb[FSL_IMX7_NUM_USBS];
DesignwarePCIEHost pcie; DesignwarePCIEHost pcie;
OrIRQState pcie4_msi_irq;
MemoryRegion rom; MemoryRegion rom;
MemoryRegion caam; MemoryRegion caam;
MemoryRegion ocram; MemoryRegion ocram;
@ -428,7 +430,7 @@ enum FslIMX7IRQs {
FSL_IMX7_PCI_INTA_IRQ = 125, FSL_IMX7_PCI_INTA_IRQ = 125,
FSL_IMX7_PCI_INTB_IRQ = 124, FSL_IMX7_PCI_INTB_IRQ = 124,
FSL_IMX7_PCI_INTC_IRQ = 123, FSL_IMX7_PCI_INTC_IRQ = 123,
FSL_IMX7_PCI_INTD_IRQ = 122, FSL_IMX7_PCI_INTD_MSI_IRQ = 122,
FSL_IMX7_UART7_IRQ = 126, FSL_IMX7_UART7_IRQ = 126,

View file

@ -30,7 +30,7 @@ struct NRF51State {
SysBusDevice parent_obj; SysBusDevice parent_obj;
/*< public >*/ /*< public >*/
ARMv7MState cpu; ARMv7MState armv7m;
NRF51UARTState uart; NRF51UARTState uart;
NRF51RNGState rng; NRF51RNGState rng;

View file

@ -109,13 +109,13 @@ struct IMXSerialState {
uint32_t ucr1; uint32_t ucr1;
uint32_t ucr2; uint32_t ucr2;
uint32_t uts1; uint32_t uts1;
uint32_t ufcr;
/* /*
* The registers below are implemented just so that the * The registers below are implemented just so that the
* guest OS sees what it has written * guest OS sees what it has written
*/ */
uint32_t onems; uint32_t onems;
uint32_t ufcr;
uint32_t ubmr; uint32_t ubmr;
uint32_t ubrc; uint32_t ubrc;
uint32_t ucr3; uint32_t ucr3;

View file

@ -86,6 +86,7 @@ struct DesignwarePCIEHost {
MemoryRegion io; MemoryRegion io;
qemu_irq irqs[4]; qemu_irq irqs[4];
qemu_irq msi;
} pci; } pci;
MemoryRegion mmio; MemoryRegion mmio;

View file

@ -572,9 +572,11 @@ static void arm_cpu_reset_hold(Object *obj, ResetType type)
set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); 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);
set_default_nan_mode(1, &env->vfp.standard_fp_status_f16); set_default_nan_mode(1, &env->vfp.standard_fp_status_f16);
arm_set_default_fp_behaviours(&env->vfp.fp_status); arm_set_default_fp_behaviours(&env->vfp.fp_status_a32);
arm_set_default_fp_behaviours(&env->vfp.fp_status_a64);
arm_set_default_fp_behaviours(&env->vfp.standard_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.fp_status_f16_a32);
arm_set_default_fp_behaviours(&env->vfp.fp_status_f16_a64);
arm_set_default_fp_behaviours(&env->vfp.standard_fp_status_f16); arm_set_default_fp_behaviours(&env->vfp.standard_fp_status_f16);
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY

View file

@ -633,8 +633,10 @@ typedef struct CPUArchState {
/* There are a number of distinct float control structures: /* There are a number of distinct float control structures:
* *
* fp_status: is the "normal" fp status. * fp_status_a32: is the "normal" fp status for AArch32 insns
* fp_status_fp16: used for half-precision calculations * fp_status_a64: is the "normal" fp status for AArch64 insns
* fp_status_fp16_a32: used for AArch32 half-precision calculations
* fp_status_fp16_a64: used for AArch64 half-precision calculations
* standard_fp_status : the ARM "Standard FPSCR Value" * standard_fp_status : the ARM "Standard FPSCR Value"
* standard_fp_status_fp16 : used for half-precision * standard_fp_status_fp16 : used for half-precision
* calculations with the ARM "Standard FPSCR Value" * calculations with the ARM "Standard FPSCR Value"
@ -658,8 +660,10 @@ typedef struct CPUArchState {
* only thing which needs to read the exception flags being * only thing which needs to read the exception flags being
* an explicit FPSCR read. * an explicit FPSCR read.
*/ */
float_status fp_status; float_status fp_status_a32;
float_status fp_status_f16; float_status fp_status_a64;
float_status fp_status_f16_a32;
float_status fp_status_f16_a64;
float_status standard_fp_status; float_status standard_fp_status;
float_status standard_fp_status_f16; float_status standard_fp_status_f16;

View file

@ -6413,7 +6413,7 @@ static void arm_reset_sve_state(CPUARMState *env)
memset(env->vfp.zregs, 0, sizeof(env->vfp.zregs)); memset(env->vfp.zregs, 0, sizeof(env->vfp.zregs));
/* Recall that FFR is stored as pregs[16]. */ /* Recall that FFR is stored as pregs[16]. */
memset(env->vfp.pregs, 0, sizeof(env->vfp.pregs)); memset(env->vfp.pregs, 0, sizeof(env->vfp.pregs));
vfp_set_fpcr(env, 0x0800009f); vfp_set_fpsr(env, 0x0800009f);
} }
void aarch64_set_svcr(CPUARMState *env, uint64_t new, uint64_t mask) void aarch64_set_svcr(CPUARMState *env, uint64_t new, uint64_t mask)

View file

@ -439,15 +439,6 @@ uint32_t ADVSIMD_HELPER(name, h)(uint32_t a, uint32_t b, float_status *fpst) \
return float16_ ## name(a, b, fpst); \ return float16_ ## name(a, b, fpst); \
} }
ADVSIMD_HALFOP(add)
ADVSIMD_HALFOP(sub)
ADVSIMD_HALFOP(mul)
ADVSIMD_HALFOP(div)
ADVSIMD_HALFOP(min)
ADVSIMD_HALFOP(max)
ADVSIMD_HALFOP(minnum)
ADVSIMD_HALFOP(maxnum)
#define ADVSIMD_TWOHALFOP(name) \ #define ADVSIMD_TWOHALFOP(name) \
uint32_t ADVSIMD_HELPER(name, 2h)(uint32_t two_a, uint32_t two_b, \ uint32_t ADVSIMD_HELPER(name, 2h)(uint32_t two_a, uint32_t two_b, \
float_status *fpst) \ float_status *fpst) \

View file

@ -47,14 +47,6 @@ DEF_HELPER_FLAGS_2(frecpx_f16, TCG_CALL_NO_RWG, f16, f16, fpst)
DEF_HELPER_FLAGS_2(fcvtx_f64_to_f32, TCG_CALL_NO_RWG, f32, f64, fpst) DEF_HELPER_FLAGS_2(fcvtx_f64_to_f32, TCG_CALL_NO_RWG, f32, f64, fpst)
DEF_HELPER_FLAGS_3(crc32_64, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32) DEF_HELPER_FLAGS_3(crc32_64, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32)
DEF_HELPER_FLAGS_3(crc32c_64, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32) DEF_HELPER_FLAGS_3(crc32c_64, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32)
DEF_HELPER_FLAGS_3(advsimd_maxh, TCG_CALL_NO_RWG, f16, f16, f16, fpst)
DEF_HELPER_FLAGS_3(advsimd_minh, TCG_CALL_NO_RWG, f16, f16, f16, fpst)
DEF_HELPER_FLAGS_3(advsimd_maxnumh, TCG_CALL_NO_RWG, f16, f16, f16, fpst)
DEF_HELPER_FLAGS_3(advsimd_minnumh, TCG_CALL_NO_RWG, f16, f16, f16, fpst)
DEF_HELPER_3(advsimd_addh, f16, f16, f16, fpst)
DEF_HELPER_3(advsimd_subh, f16, f16, f16, fpst)
DEF_HELPER_3(advsimd_mulh, f16, f16, f16, fpst)
DEF_HELPER_3(advsimd_divh, f16, f16, f16, fpst)
DEF_HELPER_3(advsimd_ceq_f16, i32, f16, f16, fpst) DEF_HELPER_3(advsimd_ceq_f16, i32, f16, f16, fpst)
DEF_HELPER_3(advsimd_cge_f16, i32, f16, f16, fpst) DEF_HELPER_3(advsimd_cge_f16, i32, f16, f16, fpst)
DEF_HELPER_3(advsimd_cgt_f16, i32, f16, f16, fpst) DEF_HELPER_3(advsimd_cgt_f16, i32, f16, f16, fpst)

View file

@ -1038,13 +1038,13 @@ void HELPER(sme_fmopa_h)(void *vza, void *vzn, void *vzm, void *vpn,
float_status fpst_odd, fpst_std, fpst_f16; float_status fpst_odd, fpst_std, fpst_f16;
/* /*
* Make copies of fp_status and fp_status_f16, because this operation * Make copies of the fp status fields we use, because this operation
* does not update the cumulative fp exception status. It also * does not update the cumulative fp exception status. It also
* produces default NaNs. We also need a second copy of fp_status with * produces default NaNs. We also need a second copy of fp_status with
* round-to-odd -- see above. * round-to-odd -- see above.
*/ */
fpst_f16 = env->vfp.fp_status_f16; fpst_f16 = env->vfp.fp_status_f16_a64;
fpst_std = env->vfp.fp_status; fpst_std = env->vfp.fp_status_a64;
set_default_nan_mode(true, &fpst_std); set_default_nan_mode(true, &fpst_std);
set_default_nan_mode(true, &fpst_f16); set_default_nan_mode(true, &fpst_f16);
fpst_odd = fpst_std; fpst_odd = fpst_std;

View file

@ -4658,7 +4658,7 @@ static int16_t do_float16_logb_as_int(float16 a, float_status *s)
return -15 - clz32(frac); return -15 - clz32(frac);
} }
/* flush to zero */ /* flush to zero */
float_raise(float_flag_input_denormal, s); float_raise(float_flag_input_denormal_flushed, s);
} }
} else if (unlikely(exp == 0x1f)) { } else if (unlikely(exp == 0x1f)) {
if (frac == 0) { if (frac == 0) {
@ -4686,7 +4686,7 @@ static int32_t do_float32_logb_as_int(float32 a, float_status *s)
return -127 - clz32(frac); return -127 - clz32(frac);
} }
/* flush to zero */ /* flush to zero */
float_raise(float_flag_input_denormal, s); float_raise(float_flag_input_denormal_flushed, s);
} }
} else if (unlikely(exp == 0xff)) { } else if (unlikely(exp == 0xff)) {
if (frac == 0) { if (frac == 0) {
@ -4714,7 +4714,7 @@ static int64_t do_float64_logb_as_int(float64 a, float_status *s)
return -1023 - clz64(frac); return -1023 - clz64(frac);
} }
/* flush to zero */ /* flush to zero */
float_raise(float_flag_input_denormal, s); float_raise(float_flag_input_denormal_flushed, s);
} }
} else if (unlikely(exp == 0x7ff)) { } else if (unlikely(exp == 0x7ff)) {
if (frac == 0) { if (frac == 0) {

View file

@ -726,7 +726,7 @@ static void gen_gvec_op3_fpst(DisasContext *s, bool is_q, int rd, int rn,
int rm, bool is_fp16, int data, int rm, bool is_fp16, int data,
gen_helper_gvec_3_ptr *fn) gen_helper_gvec_3_ptr *fn)
{ {
TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR); TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_A64_F16 : FPST_A64);
tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd), tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
vec_full_reg_offset(s, rn), vec_full_reg_offset(s, rn),
vec_full_reg_offset(s, rm), fpst, vec_full_reg_offset(s, rm), fpst,
@ -768,7 +768,7 @@ static void gen_gvec_op4_fpst(DisasContext *s, bool is_q, int rd, int rn,
int rm, int ra, bool is_fp16, int data, int rm, int ra, bool is_fp16, int data,
gen_helper_gvec_4_ptr *fn) gen_helper_gvec_4_ptr *fn)
{ {
TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR); TCGv_ptr fpst = fpstatus_ptr(is_fp16 ? FPST_A64_F16 : FPST_A64);
tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, rd), tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, rd),
vec_full_reg_offset(s, rn), vec_full_reg_offset(s, rn),
vec_full_reg_offset(s, rm), vec_full_reg_offset(s, rm),
@ -5043,7 +5043,7 @@ static bool do_fp3_scalar(DisasContext *s, arg_rrr_e *a, const FPScalar *f)
if (fp_access_check(s)) { if (fp_access_check(s)) {
TCGv_i64 t0 = read_fp_dreg(s, a->rn); TCGv_i64 t0 = read_fp_dreg(s, a->rn);
TCGv_i64 t1 = read_fp_dreg(s, a->rm); TCGv_i64 t1 = read_fp_dreg(s, a->rm);
f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_A64));
write_fp_dreg(s, a->rd, t0); write_fp_dreg(s, a->rd, t0);
} }
break; break;
@ -5051,7 +5051,7 @@ static bool do_fp3_scalar(DisasContext *s, arg_rrr_e *a, const FPScalar *f)
if (fp_access_check(s)) { if (fp_access_check(s)) {
TCGv_i32 t0 = read_fp_sreg(s, a->rn); TCGv_i32 t0 = read_fp_sreg(s, a->rn);
TCGv_i32 t1 = read_fp_sreg(s, a->rm); TCGv_i32 t1 = read_fp_sreg(s, a->rm);
f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_A64));
write_fp_sreg(s, a->rd, t0); write_fp_sreg(s, a->rd, t0);
} }
break; break;
@ -5062,7 +5062,7 @@ static bool do_fp3_scalar(DisasContext *s, arg_rrr_e *a, const FPScalar *f)
if (fp_access_check(s)) { if (fp_access_check(s)) {
TCGv_i32 t0 = read_fp_hreg(s, a->rn); TCGv_i32 t0 = read_fp_hreg(s, a->rn);
TCGv_i32 t1 = read_fp_hreg(s, a->rm); TCGv_i32 t1 = read_fp_hreg(s, a->rm);
f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_FPCR_F16)); f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_A64_F16));
write_fp_sreg(s, a->rd, t0); write_fp_sreg(s, a->rd, t0);
} }
break; break;
@ -5101,28 +5101,28 @@ static const FPScalar f_scalar_fmul = {
TRANS(FMUL_s, do_fp3_scalar, a, &f_scalar_fmul) TRANS(FMUL_s, do_fp3_scalar, a, &f_scalar_fmul)
static const FPScalar f_scalar_fmax = { static const FPScalar f_scalar_fmax = {
gen_helper_advsimd_maxh, gen_helper_vfp_maxh,
gen_helper_vfp_maxs, gen_helper_vfp_maxs,
gen_helper_vfp_maxd, gen_helper_vfp_maxd,
}; };
TRANS(FMAX_s, do_fp3_scalar, a, &f_scalar_fmax) TRANS(FMAX_s, do_fp3_scalar, a, &f_scalar_fmax)
static const FPScalar f_scalar_fmin = { static const FPScalar f_scalar_fmin = {
gen_helper_advsimd_minh, gen_helper_vfp_minh,
gen_helper_vfp_mins, gen_helper_vfp_mins,
gen_helper_vfp_mind, gen_helper_vfp_mind,
}; };
TRANS(FMIN_s, do_fp3_scalar, a, &f_scalar_fmin) TRANS(FMIN_s, do_fp3_scalar, a, &f_scalar_fmin)
static const FPScalar f_scalar_fmaxnm = { static const FPScalar f_scalar_fmaxnm = {
gen_helper_advsimd_maxnumh, gen_helper_vfp_maxnumh,
gen_helper_vfp_maxnums, gen_helper_vfp_maxnums,
gen_helper_vfp_maxnumd, gen_helper_vfp_maxnumd,
}; };
TRANS(FMAXNM_s, do_fp3_scalar, a, &f_scalar_fmaxnm) TRANS(FMAXNM_s, do_fp3_scalar, a, &f_scalar_fmaxnm)
static const FPScalar f_scalar_fminnm = { static const FPScalar f_scalar_fminnm = {
gen_helper_advsimd_minnumh, gen_helper_vfp_minnumh,
gen_helper_vfp_minnums, gen_helper_vfp_minnums,
gen_helper_vfp_minnumd, gen_helper_vfp_minnumd,
}; };
@ -5243,9 +5243,9 @@ static bool do_fcmp0_s(DisasContext *s, arg_rr_e *a,
TCGv_i64 t0 = read_fp_dreg(s, a->rn); TCGv_i64 t0 = read_fp_dreg(s, a->rn);
TCGv_i64 t1 = tcg_constant_i64(0); TCGv_i64 t1 = tcg_constant_i64(0);
if (swap) { if (swap) {
f->gen_d(t0, t1, t0, fpstatus_ptr(FPST_FPCR)); f->gen_d(t0, t1, t0, fpstatus_ptr(FPST_A64));
} else { } else {
f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_A64));
} }
write_fp_dreg(s, a->rd, t0); write_fp_dreg(s, a->rd, t0);
} }
@ -5255,9 +5255,9 @@ static bool do_fcmp0_s(DisasContext *s, arg_rr_e *a,
TCGv_i32 t0 = read_fp_sreg(s, a->rn); TCGv_i32 t0 = read_fp_sreg(s, a->rn);
TCGv_i32 t1 = tcg_constant_i32(0); TCGv_i32 t1 = tcg_constant_i32(0);
if (swap) { if (swap) {
f->gen_s(t0, t1, t0, fpstatus_ptr(FPST_FPCR)); f->gen_s(t0, t1, t0, fpstatus_ptr(FPST_A64));
} else { } else {
f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_A64));
} }
write_fp_sreg(s, a->rd, t0); write_fp_sreg(s, a->rd, t0);
} }
@ -5270,9 +5270,9 @@ static bool do_fcmp0_s(DisasContext *s, arg_rr_e *a,
TCGv_i32 t0 = read_fp_hreg(s, a->rn); TCGv_i32 t0 = read_fp_hreg(s, a->rn);
TCGv_i32 t1 = tcg_constant_i32(0); TCGv_i32 t1 = tcg_constant_i32(0);
if (swap) { if (swap) {
f->gen_h(t0, t1, t0, fpstatus_ptr(FPST_FPCR_F16)); f->gen_h(t0, t1, t0, fpstatus_ptr(FPST_A64_F16));
} else { } else {
f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_FPCR_F16)); f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_A64_F16));
} }
write_fp_sreg(s, a->rd, t0); write_fp_sreg(s, a->rd, t0);
} }
@ -6207,7 +6207,7 @@ static bool do_fp3_scalar_idx(DisasContext *s, arg_rrx_e *a, const FPScalar *f)
TCGv_i64 t1 = tcg_temp_new_i64(); TCGv_i64 t1 = tcg_temp_new_i64();
read_vec_element(s, t1, a->rm, a->idx, MO_64); read_vec_element(s, t1, a->rm, a->idx, MO_64);
f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_A64));
write_fp_dreg(s, a->rd, t0); write_fp_dreg(s, a->rd, t0);
} }
break; break;
@ -6217,7 +6217,7 @@ static bool do_fp3_scalar_idx(DisasContext *s, arg_rrx_e *a, const FPScalar *f)
TCGv_i32 t1 = tcg_temp_new_i32(); TCGv_i32 t1 = tcg_temp_new_i32();
read_vec_element_i32(s, t1, a->rm, a->idx, MO_32); read_vec_element_i32(s, t1, a->rm, a->idx, MO_32);
f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_A64));
write_fp_sreg(s, a->rd, t0); write_fp_sreg(s, a->rd, t0);
} }
break; break;
@ -6230,7 +6230,7 @@ static bool do_fp3_scalar_idx(DisasContext *s, arg_rrx_e *a, const FPScalar *f)
TCGv_i32 t1 = tcg_temp_new_i32(); TCGv_i32 t1 = tcg_temp_new_i32();
read_vec_element_i32(s, t1, a->rm, a->idx, MO_16); read_vec_element_i32(s, t1, a->rm, a->idx, MO_16);
f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_FPCR_F16)); f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_A64_F16));
write_fp_sreg(s, a->rd, t0); write_fp_sreg(s, a->rd, t0);
} }
break; break;
@ -6256,7 +6256,7 @@ static bool do_fmla_scalar_idx(DisasContext *s, arg_rrx_e *a, bool neg)
if (neg) { if (neg) {
gen_vfp_negd(t1, t1); gen_vfp_negd(t1, t1);
} }
gen_helper_vfp_muladdd(t0, t1, t2, t0, fpstatus_ptr(FPST_FPCR)); gen_helper_vfp_muladdd(t0, t1, t2, t0, fpstatus_ptr(FPST_A64));
write_fp_dreg(s, a->rd, t0); write_fp_dreg(s, a->rd, t0);
} }
break; break;
@ -6270,7 +6270,7 @@ static bool do_fmla_scalar_idx(DisasContext *s, arg_rrx_e *a, bool neg)
if (neg) { if (neg) {
gen_vfp_negs(t1, t1); gen_vfp_negs(t1, t1);
} }
gen_helper_vfp_muladds(t0, t1, t2, t0, fpstatus_ptr(FPST_FPCR)); gen_helper_vfp_muladds(t0, t1, t2, t0, fpstatus_ptr(FPST_A64));
write_fp_sreg(s, a->rd, t0); write_fp_sreg(s, a->rd, t0);
} }
break; break;
@ -6288,7 +6288,7 @@ static bool do_fmla_scalar_idx(DisasContext *s, arg_rrx_e *a, bool neg)
gen_vfp_negh(t1, t1); gen_vfp_negh(t1, t1);
} }
gen_helper_advsimd_muladdh(t0, t1, t2, t0, gen_helper_advsimd_muladdh(t0, t1, t2, t0,
fpstatus_ptr(FPST_FPCR_F16)); fpstatus_ptr(FPST_A64_F16));
write_fp_sreg(s, a->rd, t0); write_fp_sreg(s, a->rd, t0);
} }
break; break;
@ -6601,7 +6601,7 @@ static bool do_fp3_scalar_pair(DisasContext *s, arg_rr_e *a, const FPScalar *f)
read_vec_element(s, t0, a->rn, 0, MO_64); read_vec_element(s, t0, a->rn, 0, MO_64);
read_vec_element(s, t1, a->rn, 1, MO_64); read_vec_element(s, t1, a->rn, 1, MO_64);
f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_A64));
write_fp_dreg(s, a->rd, t0); write_fp_dreg(s, a->rd, t0);
} }
break; break;
@ -6612,7 +6612,7 @@ static bool do_fp3_scalar_pair(DisasContext *s, arg_rr_e *a, const FPScalar *f)
read_vec_element_i32(s, t0, a->rn, 0, MO_32); read_vec_element_i32(s, t0, a->rn, 0, MO_32);
read_vec_element_i32(s, t1, a->rn, 1, MO_32); read_vec_element_i32(s, t1, a->rn, 1, MO_32);
f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_FPCR)); f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_A64));
write_fp_sreg(s, a->rd, t0); write_fp_sreg(s, a->rd, t0);
} }
break; break;
@ -6626,7 +6626,7 @@ static bool do_fp3_scalar_pair(DisasContext *s, arg_rr_e *a, const FPScalar *f)
read_vec_element_i32(s, t0, a->rn, 0, MO_16); read_vec_element_i32(s, t0, a->rn, 0, MO_16);
read_vec_element_i32(s, t1, a->rn, 1, MO_16); read_vec_element_i32(s, t1, a->rn, 1, MO_16);
f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_FPCR_F16)); f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_A64_F16));
write_fp_sreg(s, a->rd, t0); write_fp_sreg(s, a->rd, t0);
} }
break; break;
@ -6762,7 +6762,7 @@ static bool do_fmadd(DisasContext *s, arg_rrrr_e *a, bool neg_a, bool neg_n)
if (neg_n) { if (neg_n) {
gen_vfp_negd(tn, tn); gen_vfp_negd(tn, tn);
} }
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A64);
gen_helper_vfp_muladdd(ta, tn, tm, ta, fpst); gen_helper_vfp_muladdd(ta, tn, tm, ta, fpst);
write_fp_dreg(s, a->rd, ta); write_fp_dreg(s, a->rd, ta);
} }
@ -6780,7 +6780,7 @@ static bool do_fmadd(DisasContext *s, arg_rrrr_e *a, bool neg_a, bool neg_n)
if (neg_n) { if (neg_n) {
gen_vfp_negs(tn, tn); gen_vfp_negs(tn, tn);
} }
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A64);
gen_helper_vfp_muladds(ta, tn, tm, ta, fpst); gen_helper_vfp_muladds(ta, tn, tm, ta, fpst);
write_fp_sreg(s, a->rd, ta); write_fp_sreg(s, a->rd, ta);
} }
@ -6801,7 +6801,7 @@ static bool do_fmadd(DisasContext *s, arg_rrrr_e *a, bool neg_a, bool neg_n)
if (neg_n) { if (neg_n) {
gen_vfp_negh(tn, tn); gen_vfp_negh(tn, tn);
} }
fpst = fpstatus_ptr(FPST_FPCR_F16); fpst = fpstatus_ptr(FPST_A64_F16);
gen_helper_advsimd_muladdh(ta, tn, tm, ta, fpst); gen_helper_advsimd_muladdh(ta, tn, tm, ta, fpst);
write_fp_sreg(s, a->rd, ta); write_fp_sreg(s, a->rd, ta);
} }
@ -6895,17 +6895,17 @@ static bool do_fp_reduction(DisasContext *s, arg_qrr_e *a,
if (fp_access_check(s)) { if (fp_access_check(s)) {
MemOp esz = a->esz; MemOp esz = a->esz;
int elts = (a->q ? 16 : 8) >> esz; int elts = (a->q ? 16 : 8) >> esz;
TCGv_ptr fpst = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); TCGv_ptr fpst = fpstatus_ptr(esz == MO_16 ? FPST_A64_F16 : FPST_A64);
TCGv_i32 res = do_reduction_op(s, a->rn, esz, 0, elts, fpst, fn); TCGv_i32 res = do_reduction_op(s, a->rn, esz, 0, elts, fpst, fn);
write_fp_sreg(s, a->rd, res); write_fp_sreg(s, a->rd, res);
} }
return true; return true;
} }
TRANS_FEAT(FMAXNMV_h, aa64_fp16, do_fp_reduction, a, gen_helper_advsimd_maxnumh) TRANS_FEAT(FMAXNMV_h, aa64_fp16, do_fp_reduction, a, gen_helper_vfp_maxnumh)
TRANS_FEAT(FMINNMV_h, aa64_fp16, do_fp_reduction, a, gen_helper_advsimd_minnumh) TRANS_FEAT(FMINNMV_h, aa64_fp16, do_fp_reduction, a, gen_helper_vfp_minnumh)
TRANS_FEAT(FMAXV_h, aa64_fp16, do_fp_reduction, a, gen_helper_advsimd_maxh) TRANS_FEAT(FMAXV_h, aa64_fp16, do_fp_reduction, a, gen_helper_vfp_maxh)
TRANS_FEAT(FMINV_h, aa64_fp16, do_fp_reduction, a, gen_helper_advsimd_minh) TRANS_FEAT(FMINV_h, aa64_fp16, do_fp_reduction, a, gen_helper_vfp_minh)
TRANS(FMAXNMV_s, do_fp_reduction, a, gen_helper_vfp_maxnums) TRANS(FMAXNMV_s, do_fp_reduction, a, gen_helper_vfp_maxnums)
TRANS(FMINNMV_s, do_fp_reduction, a, gen_helper_vfp_minnums) TRANS(FMINNMV_s, do_fp_reduction, a, gen_helper_vfp_minnums)
@ -6939,7 +6939,7 @@ static void handle_fp_compare(DisasContext *s, int size,
bool cmp_with_zero, bool signal_all_nans) bool cmp_with_zero, bool signal_all_nans)
{ {
TCGv_i64 tcg_flags = tcg_temp_new_i64(); TCGv_i64 tcg_flags = tcg_temp_new_i64();
TCGv_ptr fpst = fpstatus_ptr(size == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); TCGv_ptr fpst = fpstatus_ptr(size == MO_16 ? FPST_A64_F16 : FPST_A64);
if (size == MO_64) { if (size == MO_64) {
TCGv_i64 tcg_vn, tcg_vm; TCGv_i64 tcg_vn, tcg_vm;
@ -8407,7 +8407,7 @@ static bool do_fp1_scalar(DisasContext *s, arg_rr_e *a,
return check == 0; return check == 0;
} }
fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_A64_F16 : FPST_A64);
if (rmode >= 0) { if (rmode >= 0) {
tcg_rmode = gen_set_rmode(rmode, fpst); tcg_rmode = gen_set_rmode(rmode, fpst);
} }
@ -8513,7 +8513,7 @@ static bool trans_FCVT_s_ds(DisasContext *s, arg_rr *a)
if (fp_access_check(s)) { if (fp_access_check(s)) {
TCGv_i32 tcg_rn = read_fp_sreg(s, a->rn); TCGv_i32 tcg_rn = read_fp_sreg(s, a->rn);
TCGv_i64 tcg_rd = tcg_temp_new_i64(); TCGv_i64 tcg_rd = tcg_temp_new_i64();
TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); TCGv_ptr fpst = fpstatus_ptr(FPST_A64);
gen_helper_vfp_fcvtds(tcg_rd, tcg_rn, fpst); gen_helper_vfp_fcvtds(tcg_rd, tcg_rn, fpst);
write_fp_dreg(s, a->rd, tcg_rd); write_fp_dreg(s, a->rd, tcg_rd);
@ -8526,7 +8526,7 @@ static bool trans_FCVT_s_hs(DisasContext *s, arg_rr *a)
if (fp_access_check(s)) { if (fp_access_check(s)) {
TCGv_i32 tmp = read_fp_sreg(s, a->rn); TCGv_i32 tmp = read_fp_sreg(s, a->rn);
TCGv_i32 ahp = get_ahp_flag(); TCGv_i32 ahp = get_ahp_flag();
TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); TCGv_ptr fpst = fpstatus_ptr(FPST_A64);
gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp); gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
/* write_fp_sreg is OK here because top half of result is zero */ /* write_fp_sreg is OK here because top half of result is zero */
@ -8540,7 +8540,7 @@ static bool trans_FCVT_s_sd(DisasContext *s, arg_rr *a)
if (fp_access_check(s)) { if (fp_access_check(s)) {
TCGv_i64 tcg_rn = read_fp_dreg(s, a->rn); TCGv_i64 tcg_rn = read_fp_dreg(s, a->rn);
TCGv_i32 tcg_rd = tcg_temp_new_i32(); TCGv_i32 tcg_rd = tcg_temp_new_i32();
TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); TCGv_ptr fpst = fpstatus_ptr(FPST_A64);
gen_helper_vfp_fcvtsd(tcg_rd, tcg_rn, fpst); gen_helper_vfp_fcvtsd(tcg_rd, tcg_rn, fpst);
write_fp_sreg(s, a->rd, tcg_rd); write_fp_sreg(s, a->rd, tcg_rd);
@ -8554,7 +8554,7 @@ static bool trans_FCVT_s_hd(DisasContext *s, arg_rr *a)
TCGv_i64 tcg_rn = read_fp_dreg(s, a->rn); TCGv_i64 tcg_rn = read_fp_dreg(s, a->rn);
TCGv_i32 tcg_rd = tcg_temp_new_i32(); TCGv_i32 tcg_rd = tcg_temp_new_i32();
TCGv_i32 ahp = get_ahp_flag(); TCGv_i32 ahp = get_ahp_flag();
TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); TCGv_ptr fpst = fpstatus_ptr(FPST_A64);
gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, fpst, ahp); gen_helper_vfp_fcvt_f64_to_f16(tcg_rd, tcg_rn, fpst, ahp);
/* write_fp_sreg is OK here because top half of tcg_rd is zero */ /* write_fp_sreg is OK here because top half of tcg_rd is zero */
@ -8568,7 +8568,7 @@ static bool trans_FCVT_s_sh(DisasContext *s, arg_rr *a)
if (fp_access_check(s)) { if (fp_access_check(s)) {
TCGv_i32 tcg_rn = read_fp_hreg(s, a->rn); TCGv_i32 tcg_rn = read_fp_hreg(s, a->rn);
TCGv_i32 tcg_rd = tcg_temp_new_i32(); TCGv_i32 tcg_rd = tcg_temp_new_i32();
TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_FPCR); TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_A64_F16);
TCGv_i32 tcg_ahp = get_ahp_flag(); TCGv_i32 tcg_ahp = get_ahp_flag();
gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp); gen_helper_vfp_fcvt_f16_to_f32(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp);
@ -8582,7 +8582,7 @@ static bool trans_FCVT_s_dh(DisasContext *s, arg_rr *a)
if (fp_access_check(s)) { if (fp_access_check(s)) {
TCGv_i32 tcg_rn = read_fp_hreg(s, a->rn); TCGv_i32 tcg_rn = read_fp_hreg(s, a->rn);
TCGv_i64 tcg_rd = tcg_temp_new_i64(); TCGv_i64 tcg_rd = tcg_temp_new_i64();
TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_FPCR); TCGv_ptr tcg_fpst = fpstatus_ptr(FPST_A64_F16);
TCGv_i32 tcg_ahp = get_ahp_flag(); TCGv_i32 tcg_ahp = get_ahp_flag();
gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp); gen_helper_vfp_fcvt_f16_to_f64(tcg_rd, tcg_rn, tcg_fpst, tcg_ahp);
@ -8598,7 +8598,7 @@ static bool do_cvtf_scalar(DisasContext *s, MemOp esz, int rd, int shift,
TCGv_i32 tcg_shift, tcg_single; TCGv_i32 tcg_shift, tcg_single;
TCGv_i64 tcg_double; TCGv_i64 tcg_double;
tcg_fpstatus = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); tcg_fpstatus = fpstatus_ptr(esz == MO_16 ? FPST_A64_F16 : FPST_A64);
tcg_shift = tcg_constant_i32(shift); tcg_shift = tcg_constant_i32(shift);
switch (esz) { switch (esz) {
@ -8693,7 +8693,7 @@ static void do_fcvt_scalar(DisasContext *s, MemOp out, MemOp esz,
TCGv_ptr tcg_fpstatus; TCGv_ptr tcg_fpstatus;
TCGv_i32 tcg_shift, tcg_rmode, tcg_single; TCGv_i32 tcg_shift, tcg_rmode, tcg_single;
tcg_fpstatus = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); tcg_fpstatus = fpstatus_ptr(esz == MO_16 ? FPST_A64_F16 : FPST_A64);
tcg_shift = tcg_constant_i32(shift); tcg_shift = tcg_constant_i32(shift);
tcg_rmode = gen_set_rmode(rmode, tcg_fpstatus); tcg_rmode = gen_set_rmode(rmode, tcg_fpstatus);
@ -8857,7 +8857,7 @@ static bool trans_FJCVTZS(DisasContext *s, arg_FJCVTZS *a)
} }
if (fp_access_check(s)) { if (fp_access_check(s)) {
TCGv_i64 t = read_fp_dreg(s, a->rn); TCGv_i64 t = read_fp_dreg(s, a->rn);
TCGv_ptr fpstatus = fpstatus_ptr(FPST_FPCR); TCGv_ptr fpstatus = fpstatus_ptr(FPST_A64);
gen_helper_fjcvtzs(t, t, fpstatus); gen_helper_fjcvtzs(t, t, fpstatus);
@ -9115,7 +9115,7 @@ static void gen_fcvtxn_sd(TCGv_i64 d, TCGv_i64 n)
* with von Neumann rounding (round to odd) * with von Neumann rounding (round to odd)
*/ */
TCGv_i32 tmp = tcg_temp_new_i32(); TCGv_i32 tmp = tcg_temp_new_i32();
gen_helper_fcvtx_f64_to_f32(tmp, n, fpstatus_ptr(FPST_FPCR)); gen_helper_fcvtx_f64_to_f32(tmp, n, fpstatus_ptr(FPST_A64));
tcg_gen_extu_i32_i64(d, tmp); tcg_gen_extu_i32_i64(d, tmp);
} }
@ -9208,7 +9208,7 @@ static void gen_fcvtn_hs(TCGv_i64 d, TCGv_i64 n)
{ {
TCGv_i32 tcg_lo = tcg_temp_new_i32(); TCGv_i32 tcg_lo = tcg_temp_new_i32();
TCGv_i32 tcg_hi = tcg_temp_new_i32(); TCGv_i32 tcg_hi = tcg_temp_new_i32();
TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); TCGv_ptr fpst = fpstatus_ptr(FPST_A64);
TCGv_i32 ahp = get_ahp_flag(); TCGv_i32 ahp = get_ahp_flag();
tcg_gen_extr_i64_i32(tcg_lo, tcg_hi, n); tcg_gen_extr_i64_i32(tcg_lo, tcg_hi, n);
@ -9221,7 +9221,7 @@ static void gen_fcvtn_hs(TCGv_i64 d, TCGv_i64 n)
static void gen_fcvtn_sd(TCGv_i64 d, TCGv_i64 n) static void gen_fcvtn_sd(TCGv_i64 d, TCGv_i64 n)
{ {
TCGv_i32 tmp = tcg_temp_new_i32(); TCGv_i32 tmp = tcg_temp_new_i32();
TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); TCGv_ptr fpst = fpstatus_ptr(FPST_A64);
gen_helper_vfp_fcvtsd(tmp, n, fpst); gen_helper_vfp_fcvtsd(tmp, n, fpst);
tcg_gen_extu_i32_i64(d, tmp); tcg_gen_extu_i32_i64(d, tmp);
@ -9237,7 +9237,7 @@ TRANS(FCVTXN_v, do_2misc_narrow_vector, a, f_scalar_fcvtxn)
static void gen_bfcvtn_hs(TCGv_i64 d, TCGv_i64 n) static void gen_bfcvtn_hs(TCGv_i64 d, TCGv_i64 n)
{ {
TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR); TCGv_ptr fpst = fpstatus_ptr(FPST_A64);
TCGv_i32 tmp = tcg_temp_new_i32(); TCGv_i32 tmp = tcg_temp_new_i32();
gen_helper_bfcvt_pair(tmp, n, fpst); gen_helper_bfcvt_pair(tmp, n, fpst);
tcg_gen_extu_i32_i64(d, tmp); tcg_gen_extu_i32_i64(d, tmp);
@ -9312,7 +9312,7 @@ static bool do_fp1_vector(DisasContext *s, arg_qrr_e *a,
return check == 0; return check == 0;
} }
fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_A64_F16 : FPST_A64);
if (rmode >= 0) { if (rmode >= 0) {
tcg_rmode = gen_set_rmode(rmode, fpst); tcg_rmode = gen_set_rmode(rmode, fpst);
} }
@ -9372,7 +9372,7 @@ static bool do_gvec_op2_fpst(DisasContext *s, MemOp esz, bool is_q,
return check == 0; return check == 0;
} }
fpst = fpstatus_ptr(esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); fpst = fpstatus_ptr(esz == MO_16 ? FPST_A64_F16 : FPST_A64);
tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, rd), tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, rd),
vec_full_reg_offset(s, rn), fpst, vec_full_reg_offset(s, rn), fpst,
is_q ? 16 : 8, vec_full_reg_size(s), is_q ? 16 : 8, vec_full_reg_size(s),
@ -9511,13 +9511,14 @@ static bool trans_FCVTL_v(DisasContext *s, arg_qrr_e *a)
return true; return true;
} }
fpst = fpstatus_ptr(FPST_FPCR);
if (a->esz == MO_64) { if (a->esz == MO_64) {
/* 32 -> 64 bit fp conversion */ /* 32 -> 64 bit fp conversion */
TCGv_i64 tcg_res[2]; TCGv_i64 tcg_res[2];
TCGv_i32 tcg_op = tcg_temp_new_i32(); TCGv_i32 tcg_op = tcg_temp_new_i32();
int srcelt = a->q ? 2 : 0; int srcelt = a->q ? 2 : 0;
fpst = fpstatus_ptr(FPST_A64);
for (pass = 0; pass < 2; pass++) { for (pass = 0; pass < 2; pass++) {
tcg_res[pass] = tcg_temp_new_i64(); tcg_res[pass] = tcg_temp_new_i64();
read_vec_element_i32(s, tcg_op, a->rn, srcelt + pass, MO_32); read_vec_element_i32(s, tcg_op, a->rn, srcelt + pass, MO_32);
@ -9532,6 +9533,8 @@ static bool trans_FCVTL_v(DisasContext *s, arg_qrr_e *a)
TCGv_i32 tcg_res[4]; TCGv_i32 tcg_res[4];
TCGv_i32 ahp = get_ahp_flag(); TCGv_i32 ahp = get_ahp_flag();
fpst = fpstatus_ptr(FPST_A64_F16);
for (pass = 0; pass < 4; pass++) { for (pass = 0; pass < 4; pass++) {
tcg_res[pass] = tcg_temp_new_i32(); tcg_res[pass] = tcg_temp_new_i32();
read_vec_element_i32(s, tcg_res[pass], a->rn, srcelt + pass, MO_16); read_vec_element_i32(s, tcg_res[pass], a->rn, srcelt + pass, MO_16);

View file

@ -358,9 +358,9 @@ static bool do_outprod_env(DisasContext *s, arg_op *a, MemOp esz,
TRANS_FEAT(FMOPA_h, aa64_sme, do_outprod_env, a, TRANS_FEAT(FMOPA_h, aa64_sme, do_outprod_env, a,
MO_32, gen_helper_sme_fmopa_h) MO_32, gen_helper_sme_fmopa_h)
TRANS_FEAT(FMOPA_s, aa64_sme, do_outprod_fpst, a, TRANS_FEAT(FMOPA_s, aa64_sme, do_outprod_fpst, a,
MO_32, FPST_FPCR, gen_helper_sme_fmopa_s) MO_32, FPST_A64, gen_helper_sme_fmopa_s)
TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst, a, TRANS_FEAT(FMOPA_d, aa64_sme_f64f64, do_outprod_fpst, a,
MO_64, FPST_FPCR, gen_helper_sme_fmopa_d) MO_64, FPST_A64, gen_helper_sme_fmopa_d)
TRANS_FEAT(BFMOPA, aa64_sme, do_outprod_env, a, MO_32, gen_helper_sme_bfmopa) TRANS_FEAT(BFMOPA, aa64_sme, do_outprod_env, a, MO_32, gen_helper_sme_bfmopa)

View file

@ -141,7 +141,7 @@ static bool gen_gvec_fpst_arg_zz(DisasContext *s, gen_helper_gvec_2_ptr *fn,
arg_rr_esz *a, int data) arg_rr_esz *a, int data)
{ {
return gen_gvec_fpst_zz(s, fn, a->rd, a->rn, data, return gen_gvec_fpst_zz(s, fn, a->rd, a->rn, data,
a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); a->esz == MO_16 ? FPST_A64_F16 : FPST_A64);
} }
/* Invoke an out-of-line helper on 3 Zregs. */ /* Invoke an out-of-line helper on 3 Zregs. */
@ -191,7 +191,7 @@ static bool gen_gvec_fpst_arg_zzz(DisasContext *s, gen_helper_gvec_3_ptr *fn,
arg_rrr_esz *a, int data) arg_rrr_esz *a, int data)
{ {
return gen_gvec_fpst_zzz(s, fn, a->rd, a->rn, a->rm, data, return gen_gvec_fpst_zzz(s, fn, a->rd, a->rn, a->rm, data,
a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); a->esz == MO_16 ? FPST_A64_F16 : FPST_A64);
} }
/* Invoke an out-of-line helper on 4 Zregs. */ /* Invoke an out-of-line helper on 4 Zregs. */
@ -397,7 +397,7 @@ static bool gen_gvec_fpst_arg_zpzz(DisasContext *s, gen_helper_gvec_4_ptr *fn,
arg_rprr_esz *a) arg_rprr_esz *a)
{ {
return gen_gvec_fpst_zzzp(s, fn, a->rd, a->rn, a->rm, a->pg, 0, return gen_gvec_fpst_zzzp(s, fn, a->rd, a->rn, a->rm, a->pg, 0,
a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); a->esz == MO_16 ? FPST_A64_F16 : FPST_A64);
} }
/* Invoke a vector expander on two Zregs and an immediate. */ /* Invoke a vector expander on two Zregs and an immediate. */
@ -3517,7 +3517,7 @@ static bool do_FMLA_zzxz(DisasContext *s, arg_rrxr_esz *a, bool sub)
}; };
return gen_gvec_fpst_zzzz(s, fns[a->esz], a->rd, a->rn, a->rm, a->ra, return gen_gvec_fpst_zzzz(s, fns[a->esz], a->rd, a->rn, a->rm, a->ra,
(a->index << 1) | sub, (a->index << 1) | sub,
a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); a->esz == MO_16 ? FPST_A64_F16 : FPST_A64);
} }
TRANS_FEAT(FMLA_zzxz, aa64_sve, do_FMLA_zzxz, a, false) TRANS_FEAT(FMLA_zzxz, aa64_sve, do_FMLA_zzxz, a, false)
@ -3533,7 +3533,7 @@ static gen_helper_gvec_3_ptr * const fmul_idx_fns[4] = {
}; };
TRANS_FEAT(FMUL_zzx, aa64_sve, gen_gvec_fpst_zzz, TRANS_FEAT(FMUL_zzx, aa64_sve, gen_gvec_fpst_zzz,
fmul_idx_fns[a->esz], a->rd, a->rn, a->rm, a->index, fmul_idx_fns[a->esz], a->rd, a->rn, a->rm, a->index,
a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) a->esz == MO_16 ? FPST_A64_F16 : FPST_A64)
/* /*
*** SVE Floating Point Fast Reduction Group *** SVE Floating Point Fast Reduction Group
@ -3566,7 +3566,7 @@ static bool do_reduce(DisasContext *s, arg_rpr_esz *a,
tcg_gen_addi_ptr(t_zn, tcg_env, vec_full_reg_offset(s, a->rn)); tcg_gen_addi_ptr(t_zn, tcg_env, vec_full_reg_offset(s, a->rn));
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, a->pg)); tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, a->pg));
status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); status = fpstatus_ptr(a->esz == MO_16 ? FPST_A64_F16 : FPST_A64);
fn(temp, t_zn, t_pg, status, t_desc); fn(temp, t_zn, t_pg, status, t_desc);
@ -3618,7 +3618,7 @@ static bool do_ppz_fp(DisasContext *s, arg_rpr_esz *a,
if (sve_access_check(s)) { if (sve_access_check(s)) {
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_ptr status = TCGv_ptr status =
fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); fpstatus_ptr(a->esz == MO_16 ? FPST_A64_F16 : FPST_A64);
tcg_gen_gvec_3_ptr(pred_full_reg_offset(s, a->rd), tcg_gen_gvec_3_ptr(pred_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn), vec_full_reg_offset(s, a->rn),
@ -3654,7 +3654,7 @@ static gen_helper_gvec_3_ptr * const ftmad_fns[4] = {
}; };
TRANS_FEAT_NONSTREAMING(FTMAD, aa64_sve, gen_gvec_fpst_zzz, TRANS_FEAT_NONSTREAMING(FTMAD, aa64_sve, gen_gvec_fpst_zzz,
ftmad_fns[a->esz], a->rd, a->rn, a->rm, a->imm, ftmad_fns[a->esz], a->rd, a->rn, a->rm, a->imm,
a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) a->esz == MO_16 ? FPST_A64_F16 : FPST_A64)
/* /*
*** SVE Floating Point Accumulating Reduction Group *** SVE Floating Point Accumulating Reduction Group
@ -3687,7 +3687,7 @@ static bool trans_FADDA(DisasContext *s, arg_rprr_esz *a)
t_pg = tcg_temp_new_ptr(); t_pg = tcg_temp_new_ptr();
tcg_gen_addi_ptr(t_rm, tcg_env, vec_full_reg_offset(s, a->rm)); tcg_gen_addi_ptr(t_rm, tcg_env, vec_full_reg_offset(s, a->rm));
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, a->pg)); tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, a->pg));
t_fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); t_fpst = fpstatus_ptr(a->esz == MO_16 ? FPST_A64_F16 : FPST_A64);
t_desc = tcg_constant_i32(simd_desc(vsz, vsz, 0)); t_desc = tcg_constant_i32(simd_desc(vsz, vsz, 0));
fns[a->esz - 1](t_val, t_val, t_rm, t_pg, t_fpst, t_desc); fns[a->esz - 1](t_val, t_val, t_rm, t_pg, t_fpst, t_desc);
@ -3762,7 +3762,7 @@ static void do_fp_scalar(DisasContext *s, int zd, int zn, int pg, bool is_fp16,
tcg_gen_addi_ptr(t_zn, tcg_env, vec_full_reg_offset(s, zn)); tcg_gen_addi_ptr(t_zn, tcg_env, vec_full_reg_offset(s, zn));
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg)); tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
status = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR); status = fpstatus_ptr(is_fp16 ? FPST_A64_F16 : FPST_A64);
desc = tcg_constant_i32(simd_desc(vsz, vsz, 0)); desc = tcg_constant_i32(simd_desc(vsz, vsz, 0));
fn(t_zd, t_zn, t_pg, scalar, status, desc); fn(t_zd, t_zn, t_pg, scalar, status, desc);
} }
@ -3814,7 +3814,7 @@ static bool do_fp_cmp(DisasContext *s, arg_rprr_esz *a,
} }
if (sve_access_check(s)) { if (sve_access_check(s)) {
unsigned vsz = vec_full_reg_size(s); unsigned vsz = vec_full_reg_size(s);
TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_A64_F16 : FPST_A64);
tcg_gen_gvec_4_ptr(pred_full_reg_offset(s, a->rd), tcg_gen_gvec_4_ptr(pred_full_reg_offset(s, a->rd),
vec_full_reg_offset(s, a->rn), vec_full_reg_offset(s, a->rn),
vec_full_reg_offset(s, a->rm), vec_full_reg_offset(s, a->rm),
@ -3847,7 +3847,7 @@ static gen_helper_gvec_4_ptr * const fcadd_fns[] = {
}; };
TRANS_FEAT(FCADD, aa64_sve, gen_gvec_fpst_zzzp, fcadd_fns[a->esz], TRANS_FEAT(FCADD, aa64_sve, gen_gvec_fpst_zzzp, fcadd_fns[a->esz],
a->rd, a->rn, a->rm, a->pg, a->rot, a->rd, a->rn, a->rm, a->pg, a->rot,
a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) a->esz == MO_16 ? FPST_A64_F16 : FPST_A64)
#define DO_FMLA(NAME, name) \ #define DO_FMLA(NAME, name) \
static gen_helper_gvec_5_ptr * const name##_fns[4] = { \ static gen_helper_gvec_5_ptr * const name##_fns[4] = { \
@ -3856,7 +3856,7 @@ TRANS_FEAT(FCADD, aa64_sve, gen_gvec_fpst_zzzp, fcadd_fns[a->esz],
}; \ }; \
TRANS_FEAT(NAME, aa64_sve, gen_gvec_fpst_zzzzp, name##_fns[a->esz], \ TRANS_FEAT(NAME, aa64_sve, gen_gvec_fpst_zzzzp, name##_fns[a->esz], \
a->rd, a->rn, a->rm, a->ra, a->pg, 0, \ a->rd, a->rn, a->rm, a->ra, a->pg, 0, \
a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) a->esz == MO_16 ? FPST_A64_F16 : FPST_A64)
DO_FMLA(FMLA_zpzzz, fmla_zpzzz) DO_FMLA(FMLA_zpzzz, fmla_zpzzz)
DO_FMLA(FMLS_zpzzz, fmls_zpzzz) DO_FMLA(FMLS_zpzzz, fmls_zpzzz)
@ -3871,66 +3871,66 @@ static gen_helper_gvec_5_ptr * const fcmla_fns[4] = {
}; };
TRANS_FEAT(FCMLA_zpzzz, aa64_sve, gen_gvec_fpst_zzzzp, fcmla_fns[a->esz], TRANS_FEAT(FCMLA_zpzzz, aa64_sve, gen_gvec_fpst_zzzzp, fcmla_fns[a->esz],
a->rd, a->rn, a->rm, a->ra, a->pg, a->rot, a->rd, a->rn, a->rm, a->ra, a->pg, a->rot,
a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) a->esz == MO_16 ? FPST_A64_F16 : FPST_A64)
static gen_helper_gvec_4_ptr * const fcmla_idx_fns[4] = { static gen_helper_gvec_4_ptr * const fcmla_idx_fns[4] = {
NULL, gen_helper_gvec_fcmlah_idx, gen_helper_gvec_fcmlas_idx, NULL NULL, gen_helper_gvec_fcmlah_idx, gen_helper_gvec_fcmlas_idx, NULL
}; };
TRANS_FEAT(FCMLA_zzxz, aa64_sve, gen_gvec_fpst_zzzz, fcmla_idx_fns[a->esz], TRANS_FEAT(FCMLA_zzxz, aa64_sve, gen_gvec_fpst_zzzz, fcmla_idx_fns[a->esz],
a->rd, a->rn, a->rm, a->ra, a->index * 4 + a->rot, a->rd, a->rn, a->rm, a->ra, a->index * 4 + a->rot,
a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) a->esz == MO_16 ? FPST_A64_F16 : FPST_A64)
/* /*
*** SVE Floating Point Unary Operations Predicated Group *** SVE Floating Point Unary Operations Predicated Group
*/ */
TRANS_FEAT(FCVT_sh, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVT_sh, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvt_sh, a, 0, FPST_FPCR) gen_helper_sve_fcvt_sh, a, 0, FPST_A64)
TRANS_FEAT(FCVT_hs, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVT_hs, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvt_hs, a, 0, FPST_FPCR) gen_helper_sve_fcvt_hs, a, 0, FPST_A64_F16)
TRANS_FEAT(BFCVT, aa64_sve_bf16, gen_gvec_fpst_arg_zpz, TRANS_FEAT(BFCVT, aa64_sve_bf16, gen_gvec_fpst_arg_zpz,
gen_helper_sve_bfcvt, a, 0, FPST_FPCR) gen_helper_sve_bfcvt, a, 0, FPST_A64)
TRANS_FEAT(FCVT_dh, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVT_dh, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvt_dh, a, 0, FPST_FPCR) gen_helper_sve_fcvt_dh, a, 0, FPST_A64)
TRANS_FEAT(FCVT_hd, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVT_hd, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvt_hd, a, 0, FPST_FPCR) gen_helper_sve_fcvt_hd, a, 0, FPST_A64_F16)
TRANS_FEAT(FCVT_ds, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVT_ds, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvt_ds, a, 0, FPST_FPCR) gen_helper_sve_fcvt_ds, a, 0, FPST_A64)
TRANS_FEAT(FCVT_sd, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVT_sd, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvt_sd, a, 0, FPST_FPCR) gen_helper_sve_fcvt_sd, a, 0, FPST_A64)
TRANS_FEAT(FCVTZS_hh, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTZS_hh, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvtzs_hh, a, 0, FPST_FPCR_F16) gen_helper_sve_fcvtzs_hh, a, 0, FPST_A64_F16)
TRANS_FEAT(FCVTZU_hh, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTZU_hh, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvtzu_hh, a, 0, FPST_FPCR_F16) gen_helper_sve_fcvtzu_hh, a, 0, FPST_A64_F16)
TRANS_FEAT(FCVTZS_hs, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTZS_hs, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvtzs_hs, a, 0, FPST_FPCR_F16) gen_helper_sve_fcvtzs_hs, a, 0, FPST_A64_F16)
TRANS_FEAT(FCVTZU_hs, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTZU_hs, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvtzu_hs, a, 0, FPST_FPCR_F16) gen_helper_sve_fcvtzu_hs, a, 0, FPST_A64_F16)
TRANS_FEAT(FCVTZS_hd, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTZS_hd, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvtzs_hd, a, 0, FPST_FPCR_F16) gen_helper_sve_fcvtzs_hd, a, 0, FPST_A64_F16)
TRANS_FEAT(FCVTZU_hd, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTZU_hd, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvtzu_hd, a, 0, FPST_FPCR_F16) gen_helper_sve_fcvtzu_hd, a, 0, FPST_A64_F16)
TRANS_FEAT(FCVTZS_ss, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTZS_ss, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvtzs_ss, a, 0, FPST_FPCR) gen_helper_sve_fcvtzs_ss, a, 0, FPST_A64)
TRANS_FEAT(FCVTZU_ss, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTZU_ss, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvtzu_ss, a, 0, FPST_FPCR) gen_helper_sve_fcvtzu_ss, a, 0, FPST_A64)
TRANS_FEAT(FCVTZS_sd, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTZS_sd, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvtzs_sd, a, 0, FPST_FPCR) gen_helper_sve_fcvtzs_sd, a, 0, FPST_A64)
TRANS_FEAT(FCVTZU_sd, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTZU_sd, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvtzu_sd, a, 0, FPST_FPCR) gen_helper_sve_fcvtzu_sd, a, 0, FPST_A64)
TRANS_FEAT(FCVTZS_ds, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTZS_ds, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvtzs_ds, a, 0, FPST_FPCR) gen_helper_sve_fcvtzs_ds, a, 0, FPST_A64)
TRANS_FEAT(FCVTZU_ds, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTZU_ds, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvtzu_ds, a, 0, FPST_FPCR) gen_helper_sve_fcvtzu_ds, a, 0, FPST_A64)
TRANS_FEAT(FCVTZS_dd, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTZS_dd, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvtzs_dd, a, 0, FPST_FPCR) gen_helper_sve_fcvtzs_dd, a, 0, FPST_A64)
TRANS_FEAT(FCVTZU_dd, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTZU_dd, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_fcvtzu_dd, a, 0, FPST_FPCR) gen_helper_sve_fcvtzu_dd, a, 0, FPST_A64)
static gen_helper_gvec_3_ptr * const frint_fns[] = { static gen_helper_gvec_3_ptr * const frint_fns[] = {
NULL, NULL,
@ -3939,7 +3939,7 @@ static gen_helper_gvec_3_ptr * const frint_fns[] = {
gen_helper_sve_frint_d gen_helper_sve_frint_d
}; };
TRANS_FEAT(FRINTI, aa64_sve, gen_gvec_fpst_arg_zpz, frint_fns[a->esz], TRANS_FEAT(FRINTI, aa64_sve, gen_gvec_fpst_arg_zpz, frint_fns[a->esz],
a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) a, 0, a->esz == MO_16 ? FPST_A64_F16 : FPST_A64)
static gen_helper_gvec_3_ptr * const frintx_fns[] = { static gen_helper_gvec_3_ptr * const frintx_fns[] = {
NULL, NULL,
@ -3948,7 +3948,7 @@ static gen_helper_gvec_3_ptr * const frintx_fns[] = {
gen_helper_sve_frintx_d gen_helper_sve_frintx_d
}; };
TRANS_FEAT(FRINTX, aa64_sve, gen_gvec_fpst_arg_zpz, frintx_fns[a->esz], TRANS_FEAT(FRINTX, aa64_sve, gen_gvec_fpst_arg_zpz, frintx_fns[a->esz],
a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); a, 0, a->esz == MO_16 ? FPST_A64_F16 : FPST_A64);
static bool do_frint_mode(DisasContext *s, arg_rpr_esz *a, static bool do_frint_mode(DisasContext *s, arg_rpr_esz *a,
ARMFPRounding mode, gen_helper_gvec_3_ptr *fn) ARMFPRounding mode, gen_helper_gvec_3_ptr *fn)
@ -3965,7 +3965,7 @@ static bool do_frint_mode(DisasContext *s, arg_rpr_esz *a,
} }
vsz = vec_full_reg_size(s); vsz = vec_full_reg_size(s);
status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR); status = fpstatus_ptr(a->esz == MO_16 ? FPST_A64_F16 : FPST_A64);
tmode = gen_set_rmode(mode, status); tmode = gen_set_rmode(mode, status);
tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd), tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
@ -3993,48 +3993,48 @@ static gen_helper_gvec_3_ptr * const frecpx_fns[] = {
gen_helper_sve_frecpx_s, gen_helper_sve_frecpx_d, gen_helper_sve_frecpx_s, gen_helper_sve_frecpx_d,
}; };
TRANS_FEAT(FRECPX, aa64_sve, gen_gvec_fpst_arg_zpz, frecpx_fns[a->esz], TRANS_FEAT(FRECPX, aa64_sve, gen_gvec_fpst_arg_zpz, frecpx_fns[a->esz],
a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) a, 0, a->esz == MO_16 ? FPST_A64_F16 : FPST_A64)
static gen_helper_gvec_3_ptr * const fsqrt_fns[] = { static gen_helper_gvec_3_ptr * const fsqrt_fns[] = {
NULL, gen_helper_sve_fsqrt_h, NULL, gen_helper_sve_fsqrt_h,
gen_helper_sve_fsqrt_s, gen_helper_sve_fsqrt_d, gen_helper_sve_fsqrt_s, gen_helper_sve_fsqrt_d,
}; };
TRANS_FEAT(FSQRT, aa64_sve, gen_gvec_fpst_arg_zpz, fsqrt_fns[a->esz], TRANS_FEAT(FSQRT, aa64_sve, gen_gvec_fpst_arg_zpz, fsqrt_fns[a->esz],
a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) a, 0, a->esz == MO_16 ? FPST_A64_F16 : FPST_A64)
TRANS_FEAT(SCVTF_hh, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(SCVTF_hh, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_scvt_hh, a, 0, FPST_FPCR_F16) gen_helper_sve_scvt_hh, a, 0, FPST_A64_F16)
TRANS_FEAT(SCVTF_sh, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(SCVTF_sh, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_scvt_sh, a, 0, FPST_FPCR_F16) gen_helper_sve_scvt_sh, a, 0, FPST_A64_F16)
TRANS_FEAT(SCVTF_dh, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(SCVTF_dh, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_scvt_dh, a, 0, FPST_FPCR_F16) gen_helper_sve_scvt_dh, a, 0, FPST_A64_F16)
TRANS_FEAT(SCVTF_ss, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(SCVTF_ss, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_scvt_ss, a, 0, FPST_FPCR) gen_helper_sve_scvt_ss, a, 0, FPST_A64)
TRANS_FEAT(SCVTF_ds, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(SCVTF_ds, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_scvt_ds, a, 0, FPST_FPCR) gen_helper_sve_scvt_ds, a, 0, FPST_A64)
TRANS_FEAT(SCVTF_sd, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(SCVTF_sd, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_scvt_sd, a, 0, FPST_FPCR) gen_helper_sve_scvt_sd, a, 0, FPST_A64)
TRANS_FEAT(SCVTF_dd, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(SCVTF_dd, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_scvt_dd, a, 0, FPST_FPCR) gen_helper_sve_scvt_dd, a, 0, FPST_A64)
TRANS_FEAT(UCVTF_hh, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(UCVTF_hh, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_ucvt_hh, a, 0, FPST_FPCR_F16) gen_helper_sve_ucvt_hh, a, 0, FPST_A64_F16)
TRANS_FEAT(UCVTF_sh, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(UCVTF_sh, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_ucvt_sh, a, 0, FPST_FPCR_F16) gen_helper_sve_ucvt_sh, a, 0, FPST_A64_F16)
TRANS_FEAT(UCVTF_dh, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(UCVTF_dh, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_ucvt_dh, a, 0, FPST_FPCR_F16) gen_helper_sve_ucvt_dh, a, 0, FPST_A64_F16)
TRANS_FEAT(UCVTF_ss, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(UCVTF_ss, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_ucvt_ss, a, 0, FPST_FPCR) gen_helper_sve_ucvt_ss, a, 0, FPST_A64)
TRANS_FEAT(UCVTF_ds, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(UCVTF_ds, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_ucvt_ds, a, 0, FPST_FPCR) gen_helper_sve_ucvt_ds, a, 0, FPST_A64)
TRANS_FEAT(UCVTF_sd, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(UCVTF_sd, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_ucvt_sd, a, 0, FPST_FPCR) gen_helper_sve_ucvt_sd, a, 0, FPST_A64)
TRANS_FEAT(UCVTF_dd, aa64_sve, gen_gvec_fpst_arg_zpz, TRANS_FEAT(UCVTF_dd, aa64_sve, gen_gvec_fpst_arg_zpz,
gen_helper_sve_ucvt_dd, a, 0, FPST_FPCR) gen_helper_sve_ucvt_dd, a, 0, FPST_A64)
/* /*
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group *** SVE Memory - 32-bit Gather and Unsized Contiguous Group
@ -6916,10 +6916,10 @@ DO_ZPZZ_FP(FMINP, aa64_sve2, sve2_fminp_zpzz)
TRANS_FEAT_NONSTREAMING(FMMLA_s, aa64_sve_f32mm, gen_gvec_fpst_zzzz, TRANS_FEAT_NONSTREAMING(FMMLA_s, aa64_sve_f32mm, gen_gvec_fpst_zzzz,
gen_helper_fmmla_s, a->rd, a->rn, a->rm, a->ra, gen_helper_fmmla_s, a->rd, a->rn, a->rm, a->ra,
0, FPST_FPCR) 0, FPST_A64)
TRANS_FEAT_NONSTREAMING(FMMLA_d, aa64_sve_f64mm, gen_gvec_fpst_zzzz, TRANS_FEAT_NONSTREAMING(FMMLA_d, aa64_sve_f64mm, gen_gvec_fpst_zzzz,
gen_helper_fmmla_d, a->rd, a->rn, a->rm, a->ra, gen_helper_fmmla_d, a->rd, a->rn, a->rm, a->ra,
0, FPST_FPCR) 0, FPST_A64)
static gen_helper_gvec_4 * const sqdmlal_zzzw_fns[] = { static gen_helper_gvec_4 * const sqdmlal_zzzw_fns[] = {
NULL, gen_helper_sve2_sqdmlal_zzzw_h, NULL, gen_helper_sve2_sqdmlal_zzzw_h,
@ -7035,17 +7035,17 @@ TRANS_FEAT_NONSTREAMING(RAX1, aa64_sve2_sha3, gen_gvec_fn_arg_zzz,
gen_gvec_rax1, a) gen_gvec_rax1, a)
TRANS_FEAT(FCVTNT_sh, aa64_sve2, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTNT_sh, aa64_sve2, gen_gvec_fpst_arg_zpz,
gen_helper_sve2_fcvtnt_sh, a, 0, FPST_FPCR) gen_helper_sve2_fcvtnt_sh, a, 0, FPST_A64)
TRANS_FEAT(FCVTNT_ds, aa64_sve2, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTNT_ds, aa64_sve2, gen_gvec_fpst_arg_zpz,
gen_helper_sve2_fcvtnt_ds, a, 0, FPST_FPCR) gen_helper_sve2_fcvtnt_ds, a, 0, FPST_A64)
TRANS_FEAT(BFCVTNT, aa64_sve_bf16, gen_gvec_fpst_arg_zpz, TRANS_FEAT(BFCVTNT, aa64_sve_bf16, gen_gvec_fpst_arg_zpz,
gen_helper_sve_bfcvtnt, a, 0, FPST_FPCR) gen_helper_sve_bfcvtnt, a, 0, FPST_A64)
TRANS_FEAT(FCVTLT_hs, aa64_sve2, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTLT_hs, aa64_sve2, gen_gvec_fpst_arg_zpz,
gen_helper_sve2_fcvtlt_hs, a, 0, FPST_FPCR) gen_helper_sve2_fcvtlt_hs, a, 0, FPST_A64)
TRANS_FEAT(FCVTLT_sd, aa64_sve2, gen_gvec_fpst_arg_zpz, TRANS_FEAT(FCVTLT_sd, aa64_sve2, gen_gvec_fpst_arg_zpz,
gen_helper_sve2_fcvtlt_sd, a, 0, FPST_FPCR) gen_helper_sve2_fcvtlt_sd, a, 0, FPST_A64)
TRANS_FEAT(FCVTX_ds, aa64_sve2, do_frint_mode, a, TRANS_FEAT(FCVTX_ds, aa64_sve2, do_frint_mode, a,
FPROUNDING_ODD, gen_helper_sve_fcvt_ds) FPROUNDING_ODD, gen_helper_sve_fcvt_ds)
@ -7057,7 +7057,7 @@ static gen_helper_gvec_3_ptr * const flogb_fns[] = {
gen_helper_flogb_s, gen_helper_flogb_d gen_helper_flogb_s, gen_helper_flogb_d
}; };
TRANS_FEAT(FLOGB, aa64_sve2, gen_gvec_fpst_arg_zpz, flogb_fns[a->esz], TRANS_FEAT(FLOGB, aa64_sve2, gen_gvec_fpst_arg_zpz, flogb_fns[a->esz],
a, 0, a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR) a, 0, a->esz == MO_16 ? FPST_A64_F16 : FPST_A64)
static bool do_FMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sub, bool sel) static bool do_FMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sub, bool sel)
{ {
@ -7101,7 +7101,7 @@ TRANS_FEAT_NONSTREAMING(BFMMLA, aa64_sve_bf16, gen_gvec_env_arg_zzzz,
static bool do_BFMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel) static bool do_BFMLAL_zzzw(DisasContext *s, arg_rrrr_esz *a, bool sel)
{ {
return gen_gvec_fpst_zzzz(s, gen_helper_gvec_bfmlal, return gen_gvec_fpst_zzzz(s, gen_helper_gvec_bfmlal,
a->rd, a->rn, a->rm, a->ra, sel, FPST_FPCR); a->rd, a->rn, a->rm, a->ra, sel, FPST_A64);
} }
TRANS_FEAT(BFMLALB_zzzw, aa64_sve_bf16, do_BFMLAL_zzzw, a, false) TRANS_FEAT(BFMLALB_zzzw, aa64_sve_bf16, do_BFMLAL_zzzw, a, false)
@ -7111,7 +7111,7 @@ static bool do_BFMLAL_zzxw(DisasContext *s, arg_rrxr_esz *a, bool sel)
{ {
return gen_gvec_fpst_zzzz(s, gen_helper_gvec_bfmlal_idx, return gen_gvec_fpst_zzzz(s, gen_helper_gvec_bfmlal_idx,
a->rd, a->rn, a->rm, a->ra, a->rd, a->rn, a->rm, a->ra,
(a->index << 1) | sel, FPST_FPCR); (a->index << 1) | sel, FPST_A64);
} }
TRANS_FEAT(BFMLALB_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, false) TRANS_FEAT(BFMLALB_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, false)

View file

@ -460,9 +460,9 @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
} }
if (sz == 1) { if (sz == 1) {
fpst = fpstatus_ptr(FPST_FPCR_F16); fpst = fpstatus_ptr(FPST_A32_F16);
} else { } else {
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
} }
tcg_rmode = gen_set_rmode(rounding, fpst); tcg_rmode = gen_set_rmode(rounding, fpst);
@ -527,9 +527,9 @@ static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
} }
if (sz == 1) { if (sz == 1) {
fpst = fpstatus_ptr(FPST_FPCR_F16); fpst = fpstatus_ptr(FPST_A32_F16);
} else { } else {
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
} }
tcg_shift = tcg_constant_i32(0); tcg_shift = tcg_constant_i32(0);
@ -1398,7 +1398,7 @@ static bool do_vfp_3op_sp(DisasContext *s, VFPGen3OpSPFn *fn,
f0 = tcg_temp_new_i32(); f0 = tcg_temp_new_i32();
f1 = tcg_temp_new_i32(); f1 = tcg_temp_new_i32();
fd = tcg_temp_new_i32(); fd = tcg_temp_new_i32();
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
vfp_load_reg32(f0, vn); vfp_load_reg32(f0, vn);
vfp_load_reg32(f1, vm); vfp_load_reg32(f1, vm);
@ -1433,7 +1433,7 @@ static bool do_vfp_3op_hp(DisasContext *s, VFPGen3OpSPFn *fn,
/* /*
* Do a half-precision operation. Functionally this is * Do a half-precision operation. Functionally this is
* the same as do_vfp_3op_sp(), except: * the same as do_vfp_3op_sp(), except:
* - it uses the FPST_FPCR_F16 * - it uses the FPST_A32_F16
* - it doesn't need the VFP vector handling (fp16 is a * - it doesn't need the VFP vector handling (fp16 is a
* v8 feature, and in v8 VFP vectors don't exist) * v8 feature, and in v8 VFP vectors don't exist)
* - it does the aa32_fp16_arith feature test * - it does the aa32_fp16_arith feature test
@ -1456,7 +1456,7 @@ static bool do_vfp_3op_hp(DisasContext *s, VFPGen3OpSPFn *fn,
f0 = tcg_temp_new_i32(); f0 = tcg_temp_new_i32();
f1 = tcg_temp_new_i32(); f1 = tcg_temp_new_i32();
fd = tcg_temp_new_i32(); fd = tcg_temp_new_i32();
fpst = fpstatus_ptr(FPST_FPCR_F16); fpst = fpstatus_ptr(FPST_A32_F16);
vfp_load_reg16(f0, vn); vfp_load_reg16(f0, vn);
vfp_load_reg16(f1, vm); vfp_load_reg16(f1, vm);
@ -1517,7 +1517,7 @@ static bool do_vfp_3op_dp(DisasContext *s, VFPGen3OpDPFn *fn,
f0 = tcg_temp_new_i64(); f0 = tcg_temp_new_i64();
f1 = tcg_temp_new_i64(); f1 = tcg_temp_new_i64();
fd = tcg_temp_new_i64(); fd = tcg_temp_new_i64();
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
vfp_load_reg64(f0, vn); vfp_load_reg64(f0, vn);
vfp_load_reg64(f1, vm); vfp_load_reg64(f1, vm);
@ -2122,7 +2122,7 @@ static bool do_vfm_hp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
/* VFNMA, VFNMS */ /* VFNMA, VFNMS */
gen_vfp_negh(vd, vd); gen_vfp_negh(vd, vd);
} }
fpst = fpstatus_ptr(FPST_FPCR_F16); fpst = fpstatus_ptr(FPST_A32_F16);
gen_helper_vfp_muladdh(vd, vn, vm, vd, fpst); gen_helper_vfp_muladdh(vd, vn, vm, vd, fpst);
vfp_store_reg32(vd, a->vd); vfp_store_reg32(vd, a->vd);
return true; return true;
@ -2181,7 +2181,7 @@ static bool do_vfm_sp(DisasContext *s, arg_VFMA_sp *a, bool neg_n, bool neg_d)
/* VFNMA, VFNMS */ /* VFNMA, VFNMS */
gen_vfp_negs(vd, vd); gen_vfp_negs(vd, vd);
} }
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
gen_helper_vfp_muladds(vd, vn, vm, vd, fpst); gen_helper_vfp_muladds(vd, vn, vm, vd, fpst);
vfp_store_reg32(vd, a->vd); vfp_store_reg32(vd, a->vd);
return true; return true;
@ -2246,7 +2246,7 @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
/* VFNMA, VFNMS */ /* VFNMA, VFNMS */
gen_vfp_negd(vd, vd); gen_vfp_negd(vd, vd);
} }
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
gen_helper_vfp_muladdd(vd, vn, vm, vd, fpst); gen_helper_vfp_muladdd(vd, vn, vm, vd, fpst);
vfp_store_reg64(vd, a->vd); vfp_store_reg64(vd, a->vd);
return true; return true;
@ -2424,17 +2424,17 @@ DO_VFP_2OP(VNEG, dp, gen_vfp_negd, aa32_fpdp_v2)
static void gen_VSQRT_hp(TCGv_i32 vd, TCGv_i32 vm) static void gen_VSQRT_hp(TCGv_i32 vd, TCGv_i32 vm)
{ {
gen_helper_vfp_sqrth(vd, vm, fpstatus_ptr(FPST_FPCR_F16)); gen_helper_vfp_sqrth(vd, vm, fpstatus_ptr(FPST_A32_F16));
} }
static void gen_VSQRT_sp(TCGv_i32 vd, TCGv_i32 vm) static void gen_VSQRT_sp(TCGv_i32 vd, TCGv_i32 vm)
{ {
gen_helper_vfp_sqrts(vd, vm, fpstatus_ptr(FPST_FPCR)); gen_helper_vfp_sqrts(vd, vm, fpstatus_ptr(FPST_A32));
} }
static void gen_VSQRT_dp(TCGv_i64 vd, TCGv_i64 vm) static void gen_VSQRT_dp(TCGv_i64 vd, TCGv_i64 vm)
{ {
gen_helper_vfp_sqrtd(vd, vm, fpstatus_ptr(FPST_FPCR)); gen_helper_vfp_sqrtd(vd, vm, fpstatus_ptr(FPST_A32));
} }
DO_VFP_2OP(VSQRT, hp, gen_VSQRT_hp, aa32_fp16_arith) DO_VFP_2OP(VSQRT, hp, gen_VSQRT_hp, aa32_fp16_arith)
@ -2565,7 +2565,7 @@ static bool trans_VCVT_f32_f16(DisasContext *s, arg_VCVT_f32_f16 *a)
return true; return true;
} }
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
ahp_mode = get_ahp_flag(); ahp_mode = get_ahp_flag();
tmp = tcg_temp_new_i32(); tmp = tcg_temp_new_i32();
/* The T bit tells us if we want the low or high 16 bits of Vm */ /* The T bit tells us if we want the low or high 16 bits of Vm */
@ -2599,7 +2599,7 @@ static bool trans_VCVT_f64_f16(DisasContext *s, arg_VCVT_f64_f16 *a)
return true; return true;
} }
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
ahp_mode = get_ahp_flag(); ahp_mode = get_ahp_flag();
tmp = tcg_temp_new_i32(); tmp = tcg_temp_new_i32();
/* The T bit tells us if we want the low or high 16 bits of Vm */ /* The T bit tells us if we want the low or high 16 bits of Vm */
@ -2623,7 +2623,7 @@ static bool trans_VCVT_b16_f32(DisasContext *s, arg_VCVT_b16_f32 *a)
return true; return true;
} }
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
tmp = tcg_temp_new_i32(); tmp = tcg_temp_new_i32();
vfp_load_reg32(tmp, a->vm); vfp_load_reg32(tmp, a->vm);
@ -2646,7 +2646,7 @@ static bool trans_VCVT_f16_f32(DisasContext *s, arg_VCVT_f16_f32 *a)
return true; return true;
} }
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
ahp_mode = get_ahp_flag(); ahp_mode = get_ahp_flag();
tmp = tcg_temp_new_i32(); tmp = tcg_temp_new_i32();
@ -2680,7 +2680,7 @@ static bool trans_VCVT_f16_f64(DisasContext *s, arg_VCVT_f16_f64 *a)
return true; return true;
} }
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
ahp_mode = get_ahp_flag(); ahp_mode = get_ahp_flag();
tmp = tcg_temp_new_i32(); tmp = tcg_temp_new_i32();
vm = tcg_temp_new_i64(); vm = tcg_temp_new_i64();
@ -2706,7 +2706,7 @@ static bool trans_VRINTR_hp(DisasContext *s, arg_VRINTR_sp *a)
tmp = tcg_temp_new_i32(); tmp = tcg_temp_new_i32();
vfp_load_reg16(tmp, a->vm); vfp_load_reg16(tmp, a->vm);
fpst = fpstatus_ptr(FPST_FPCR_F16); fpst = fpstatus_ptr(FPST_A32_F16);
gen_helper_rinth(tmp, tmp, fpst); gen_helper_rinth(tmp, tmp, fpst);
vfp_store_reg32(tmp, a->vd); vfp_store_reg32(tmp, a->vd);
return true; return true;
@ -2727,7 +2727,7 @@ static bool trans_VRINTR_sp(DisasContext *s, arg_VRINTR_sp *a)
tmp = tcg_temp_new_i32(); tmp = tcg_temp_new_i32();
vfp_load_reg32(tmp, a->vm); vfp_load_reg32(tmp, a->vm);
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
gen_helper_rints(tmp, tmp, fpst); gen_helper_rints(tmp, tmp, fpst);
vfp_store_reg32(tmp, a->vd); vfp_store_reg32(tmp, a->vd);
return true; return true;
@ -2757,7 +2757,7 @@ static bool trans_VRINTR_dp(DisasContext *s, arg_VRINTR_dp *a)
tmp = tcg_temp_new_i64(); tmp = tcg_temp_new_i64();
vfp_load_reg64(tmp, a->vm); vfp_load_reg64(tmp, a->vm);
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
gen_helper_rintd(tmp, tmp, fpst); gen_helper_rintd(tmp, tmp, fpst);
vfp_store_reg64(tmp, a->vd); vfp_store_reg64(tmp, a->vd);
return true; return true;
@ -2779,7 +2779,7 @@ static bool trans_VRINTZ_hp(DisasContext *s, arg_VRINTZ_sp *a)
tmp = tcg_temp_new_i32(); tmp = tcg_temp_new_i32();
vfp_load_reg16(tmp, a->vm); vfp_load_reg16(tmp, a->vm);
fpst = fpstatus_ptr(FPST_FPCR_F16); fpst = fpstatus_ptr(FPST_A32_F16);
tcg_rmode = gen_set_rmode(FPROUNDING_ZERO, fpst); tcg_rmode = gen_set_rmode(FPROUNDING_ZERO, fpst);
gen_helper_rinth(tmp, tmp, fpst); gen_helper_rinth(tmp, tmp, fpst);
gen_restore_rmode(tcg_rmode, fpst); gen_restore_rmode(tcg_rmode, fpst);
@ -2803,7 +2803,7 @@ static bool trans_VRINTZ_sp(DisasContext *s, arg_VRINTZ_sp *a)
tmp = tcg_temp_new_i32(); tmp = tcg_temp_new_i32();
vfp_load_reg32(tmp, a->vm); vfp_load_reg32(tmp, a->vm);
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
tcg_rmode = gen_set_rmode(FPROUNDING_ZERO, fpst); tcg_rmode = gen_set_rmode(FPROUNDING_ZERO, fpst);
gen_helper_rints(tmp, tmp, fpst); gen_helper_rints(tmp, tmp, fpst);
gen_restore_rmode(tcg_rmode, fpst); gen_restore_rmode(tcg_rmode, fpst);
@ -2836,7 +2836,7 @@ static bool trans_VRINTZ_dp(DisasContext *s, arg_VRINTZ_dp *a)
tmp = tcg_temp_new_i64(); tmp = tcg_temp_new_i64();
vfp_load_reg64(tmp, a->vm); vfp_load_reg64(tmp, a->vm);
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
tcg_rmode = gen_set_rmode(FPROUNDING_ZERO, fpst); tcg_rmode = gen_set_rmode(FPROUNDING_ZERO, fpst);
gen_helper_rintd(tmp, tmp, fpst); gen_helper_rintd(tmp, tmp, fpst);
gen_restore_rmode(tcg_rmode, fpst); gen_restore_rmode(tcg_rmode, fpst);
@ -2859,7 +2859,7 @@ static bool trans_VRINTX_hp(DisasContext *s, arg_VRINTX_sp *a)
tmp = tcg_temp_new_i32(); tmp = tcg_temp_new_i32();
vfp_load_reg16(tmp, a->vm); vfp_load_reg16(tmp, a->vm);
fpst = fpstatus_ptr(FPST_FPCR_F16); fpst = fpstatus_ptr(FPST_A32_F16);
gen_helper_rinth_exact(tmp, tmp, fpst); gen_helper_rinth_exact(tmp, tmp, fpst);
vfp_store_reg32(tmp, a->vd); vfp_store_reg32(tmp, a->vd);
return true; return true;
@ -2880,7 +2880,7 @@ static bool trans_VRINTX_sp(DisasContext *s, arg_VRINTX_sp *a)
tmp = tcg_temp_new_i32(); tmp = tcg_temp_new_i32();
vfp_load_reg32(tmp, a->vm); vfp_load_reg32(tmp, a->vm);
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
gen_helper_rints_exact(tmp, tmp, fpst); gen_helper_rints_exact(tmp, tmp, fpst);
vfp_store_reg32(tmp, a->vd); vfp_store_reg32(tmp, a->vd);
return true; return true;
@ -2910,7 +2910,7 @@ static bool trans_VRINTX_dp(DisasContext *s, arg_VRINTX_dp *a)
tmp = tcg_temp_new_i64(); tmp = tcg_temp_new_i64();
vfp_load_reg64(tmp, a->vm); vfp_load_reg64(tmp, a->vm);
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
gen_helper_rintd_exact(tmp, tmp, fpst); gen_helper_rintd_exact(tmp, tmp, fpst);
vfp_store_reg64(tmp, a->vd); vfp_store_reg64(tmp, a->vd);
return true; return true;
@ -2937,7 +2937,7 @@ static bool trans_VCVT_sp(DisasContext *s, arg_VCVT_sp *a)
vm = tcg_temp_new_i32(); vm = tcg_temp_new_i32();
vd = tcg_temp_new_i64(); vd = tcg_temp_new_i64();
vfp_load_reg32(vm, a->vm); vfp_load_reg32(vm, a->vm);
gen_helper_vfp_fcvtds(vd, vm, fpstatus_ptr(FPST_FPCR)); gen_helper_vfp_fcvtds(vd, vm, fpstatus_ptr(FPST_A32));
vfp_store_reg64(vd, a->vd); vfp_store_reg64(vd, a->vd);
return true; return true;
} }
@ -2963,7 +2963,7 @@ static bool trans_VCVT_dp(DisasContext *s, arg_VCVT_dp *a)
vd = tcg_temp_new_i32(); vd = tcg_temp_new_i32();
vm = tcg_temp_new_i64(); vm = tcg_temp_new_i64();
vfp_load_reg64(vm, a->vm); vfp_load_reg64(vm, a->vm);
gen_helper_vfp_fcvtsd(vd, vm, fpstatus_ptr(FPST_FPCR)); gen_helper_vfp_fcvtsd(vd, vm, fpstatus_ptr(FPST_A32));
vfp_store_reg32(vd, a->vd); vfp_store_reg32(vd, a->vd);
return true; return true;
} }
@ -2983,7 +2983,7 @@ static bool trans_VCVT_int_hp(DisasContext *s, arg_VCVT_int_sp *a)
vm = tcg_temp_new_i32(); vm = tcg_temp_new_i32();
vfp_load_reg32(vm, a->vm); vfp_load_reg32(vm, a->vm);
fpst = fpstatus_ptr(FPST_FPCR_F16); fpst = fpstatus_ptr(FPST_A32_F16);
if (a->s) { if (a->s) {
/* i32 -> f16 */ /* i32 -> f16 */
gen_helper_vfp_sitoh(vm, vm, fpst); gen_helper_vfp_sitoh(vm, vm, fpst);
@ -3010,7 +3010,7 @@ static bool trans_VCVT_int_sp(DisasContext *s, arg_VCVT_int_sp *a)
vm = tcg_temp_new_i32(); vm = tcg_temp_new_i32();
vfp_load_reg32(vm, a->vm); vfp_load_reg32(vm, a->vm);
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
if (a->s) { if (a->s) {
/* i32 -> f32 */ /* i32 -> f32 */
gen_helper_vfp_sitos(vm, vm, fpst); gen_helper_vfp_sitos(vm, vm, fpst);
@ -3044,7 +3044,7 @@ static bool trans_VCVT_int_dp(DisasContext *s, arg_VCVT_int_dp *a)
vm = tcg_temp_new_i32(); vm = tcg_temp_new_i32();
vd = tcg_temp_new_i64(); vd = tcg_temp_new_i64();
vfp_load_reg32(vm, a->vm); vfp_load_reg32(vm, a->vm);
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
if (a->s) { if (a->s) {
/* i32 -> f64 */ /* i32 -> f64 */
gen_helper_vfp_sitod(vd, vm, fpst); gen_helper_vfp_sitod(vd, vm, fpst);
@ -3105,7 +3105,7 @@ static bool trans_VCVT_fix_hp(DisasContext *s, arg_VCVT_fix_sp *a)
vd = tcg_temp_new_i32(); vd = tcg_temp_new_i32();
vfp_load_reg32(vd, a->vd); vfp_load_reg32(vd, a->vd);
fpst = fpstatus_ptr(FPST_FPCR_F16); fpst = fpstatus_ptr(FPST_A32_F16);
shift = tcg_constant_i32(frac_bits); shift = tcg_constant_i32(frac_bits);
/* Switch on op:U:sx bits */ /* Switch on op:U:sx bits */
@ -3161,7 +3161,7 @@ static bool trans_VCVT_fix_sp(DisasContext *s, arg_VCVT_fix_sp *a)
vd = tcg_temp_new_i32(); vd = tcg_temp_new_i32();
vfp_load_reg32(vd, a->vd); vfp_load_reg32(vd, a->vd);
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
shift = tcg_constant_i32(frac_bits); shift = tcg_constant_i32(frac_bits);
/* Switch on op:U:sx bits */ /* Switch on op:U:sx bits */
@ -3223,7 +3223,7 @@ static bool trans_VCVT_fix_dp(DisasContext *s, arg_VCVT_fix_dp *a)
vd = tcg_temp_new_i64(); vd = tcg_temp_new_i64();
vfp_load_reg64(vd, a->vd); vfp_load_reg64(vd, a->vd);
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
shift = tcg_constant_i32(frac_bits); shift = tcg_constant_i32(frac_bits);
/* Switch on op:U:sx bits */ /* Switch on op:U:sx bits */
@ -3273,7 +3273,7 @@ static bool trans_VCVT_hp_int(DisasContext *s, arg_VCVT_sp_int *a)
return true; return true;
} }
fpst = fpstatus_ptr(FPST_FPCR_F16); fpst = fpstatus_ptr(FPST_A32_F16);
vm = tcg_temp_new_i32(); vm = tcg_temp_new_i32();
vfp_load_reg16(vm, a->vm); vfp_load_reg16(vm, a->vm);
@ -3307,7 +3307,7 @@ static bool trans_VCVT_sp_int(DisasContext *s, arg_VCVT_sp_int *a)
return true; return true;
} }
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
vm = tcg_temp_new_i32(); vm = tcg_temp_new_i32();
vfp_load_reg32(vm, a->vm); vfp_load_reg32(vm, a->vm);
@ -3347,7 +3347,7 @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
return true; return true;
} }
fpst = fpstatus_ptr(FPST_FPCR); fpst = fpstatus_ptr(FPST_A32);
vm = tcg_temp_new_i64(); vm = tcg_temp_new_i64();
vd = tcg_temp_new_i32(); vd = tcg_temp_new_i32();
vfp_load_reg64(vm, a->vm); vfp_load_reg64(vm, a->vm);

View file

@ -670,8 +670,10 @@ static inline CPUARMTBFlags arm_tbflags_from_tb(const TranslationBlock *tb)
* Enum for argument to fpstatus_ptr(). * Enum for argument to fpstatus_ptr().
*/ */
typedef enum ARMFPStatusFlavour { typedef enum ARMFPStatusFlavour {
FPST_FPCR, FPST_A32,
FPST_FPCR_F16, FPST_A64,
FPST_A32_F16,
FPST_A64_F16,
FPST_STD, FPST_STD,
FPST_STD_F16, FPST_STD_F16,
} ARMFPStatusFlavour; } ARMFPStatusFlavour;
@ -684,10 +686,14 @@ typedef enum ARMFPStatusFlavour {
* been set up to point to the requested field in the CPU state struct. * been set up to point to the requested field in the CPU state struct.
* The options are: * The options are:
* *
* FPST_FPCR * FPST_A32
* for non-FP16 operations controlled by the FPCR * for AArch32 non-FP16 operations controlled by the FPCR
* FPST_FPCR_F16 * FPST_A64
* for operations controlled by the FPCR where FPCR.FZ16 is to be used * for AArch64 non-FP16 operations controlled by the FPCR
* FPST_A32_F16
* for AArch32 operations controlled by the FPCR where FPCR.FZ16 is to be used
* FPST_A64_F16
* for AArch64 operations controlled by the FPCR where FPCR.FZ16 is to be used
* FPST_STD * FPST_STD
* for A32/T32 Neon operations using the "standard FPSCR value" * for A32/T32 Neon operations using the "standard FPSCR value"
* FPST_STD_F16 * FPST_STD_F16
@ -699,11 +705,17 @@ static inline TCGv_ptr fpstatus_ptr(ARMFPStatusFlavour flavour)
int offset; int offset;
switch (flavour) { switch (flavour) {
case FPST_FPCR: case FPST_A32:
offset = offsetof(CPUARMState, vfp.fp_status); offset = offsetof(CPUARMState, vfp.fp_status_a32);
break; break;
case FPST_FPCR_F16: case FPST_A64:
offset = offsetof(CPUARMState, vfp.fp_status_f16); offset = offsetof(CPUARMState, vfp.fp_status_a64);
break;
case FPST_A32_F16:
offset = offsetof(CPUARMState, vfp.fp_status_f16_a32);
break;
case FPST_A64_F16:
offset = offsetof(CPUARMState, vfp.fp_status_f16_a64);
break; break;
case FPST_STD: case FPST_STD:
offset = offsetof(CPUARMState, vfp.standard_fp_status); offset = offsetof(CPUARMState, vfp.standard_fp_status);

View file

@ -2060,14 +2060,14 @@ void HELPER(gvec_fmlal_a32)(void *vd, void *vn, void *vm,
CPUARMState *env, uint32_t desc) CPUARMState *env, uint32_t desc)
{ {
do_fmlal(vd, vn, vm, &env->vfp.standard_fp_status, desc, do_fmlal(vd, vn, vm, &env->vfp.standard_fp_status, desc,
get_flush_inputs_to_zero(&env->vfp.fp_status_f16)); get_flush_inputs_to_zero(&env->vfp.fp_status_f16_a32));
} }
void HELPER(gvec_fmlal_a64)(void *vd, void *vn, void *vm, void HELPER(gvec_fmlal_a64)(void *vd, void *vn, void *vm,
CPUARMState *env, uint32_t desc) CPUARMState *env, uint32_t desc)
{ {
do_fmlal(vd, vn, vm, &env->vfp.fp_status, desc, do_fmlal(vd, vn, vm, &env->vfp.fp_status_a64, desc,
get_flush_inputs_to_zero(&env->vfp.fp_status_f16)); get_flush_inputs_to_zero(&env->vfp.fp_status_f16_a64));
} }
void HELPER(sve2_fmlal_zzzw_s)(void *vd, void *vn, void *vm, void *va, void HELPER(sve2_fmlal_zzzw_s)(void *vd, void *vn, void *vm, void *va,
@ -2076,8 +2076,8 @@ void HELPER(sve2_fmlal_zzzw_s)(void *vd, void *vn, void *vm, void *va,
intptr_t i, oprsz = simd_oprsz(desc); intptr_t i, oprsz = simd_oprsz(desc);
uint16_t negn = extract32(desc, SIMD_DATA_SHIFT, 1) << 15; uint16_t negn = extract32(desc, SIMD_DATA_SHIFT, 1) << 15;
intptr_t sel = extract32(desc, SIMD_DATA_SHIFT + 1, 1) * sizeof(float16); intptr_t sel = extract32(desc, SIMD_DATA_SHIFT + 1, 1) * sizeof(float16);
float_status *status = &env->vfp.fp_status; float_status *status = &env->vfp.fp_status_a64;
bool fz16 = get_flush_inputs_to_zero(&env->vfp.fp_status_f16); bool fz16 = get_flush_inputs_to_zero(&env->vfp.fp_status_f16_a64);
for (i = 0; i < oprsz; i += sizeof(float32)) { for (i = 0; i < oprsz; i += sizeof(float32)) {
float16 nn_16 = *(float16 *)(vn + H1_2(i + sel)) ^ negn; float16 nn_16 = *(float16 *)(vn + H1_2(i + sel)) ^ negn;
@ -2122,14 +2122,14 @@ void HELPER(gvec_fmlal_idx_a32)(void *vd, void *vn, void *vm,
CPUARMState *env, uint32_t desc) CPUARMState *env, uint32_t desc)
{ {
do_fmlal_idx(vd, vn, vm, &env->vfp.standard_fp_status, desc, do_fmlal_idx(vd, vn, vm, &env->vfp.standard_fp_status, desc,
get_flush_inputs_to_zero(&env->vfp.fp_status_f16)); get_flush_inputs_to_zero(&env->vfp.fp_status_f16_a32));
} }
void HELPER(gvec_fmlal_idx_a64)(void *vd, void *vn, void *vm, void HELPER(gvec_fmlal_idx_a64)(void *vd, void *vn, void *vm,
CPUARMState *env, uint32_t desc) CPUARMState *env, uint32_t desc)
{ {
do_fmlal_idx(vd, vn, vm, &env->vfp.fp_status, desc, do_fmlal_idx(vd, vn, vm, &env->vfp.fp_status_a64, desc,
get_flush_inputs_to_zero(&env->vfp.fp_status_f16)); get_flush_inputs_to_zero(&env->vfp.fp_status_f16_a64));
} }
void HELPER(sve2_fmlal_zzxw_s)(void *vd, void *vn, void *vm, void *va, void HELPER(sve2_fmlal_zzxw_s)(void *vd, void *vn, void *vm, void *va,
@ -2139,8 +2139,8 @@ void HELPER(sve2_fmlal_zzxw_s)(void *vd, void *vn, void *vm, void *va,
uint16_t negn = extract32(desc, SIMD_DATA_SHIFT, 1) << 15; uint16_t negn = extract32(desc, SIMD_DATA_SHIFT, 1) << 15;
intptr_t sel = extract32(desc, SIMD_DATA_SHIFT + 1, 1) * sizeof(float16); intptr_t sel = extract32(desc, SIMD_DATA_SHIFT + 1, 1) * sizeof(float16);
intptr_t idx = extract32(desc, SIMD_DATA_SHIFT + 2, 3) * sizeof(float16); intptr_t idx = extract32(desc, SIMD_DATA_SHIFT + 2, 3) * sizeof(float16);
float_status *status = &env->vfp.fp_status; float_status *status = &env->vfp.fp_status_a64;
bool fz16 = get_flush_inputs_to_zero(&env->vfp.fp_status_f16); bool fz16 = get_flush_inputs_to_zero(&env->vfp.fp_status_f16_a64);
for (i = 0; i < oprsz; i += 16) { for (i = 0; i < oprsz; i += 16) {
float16 mm_16 = *(float16 *)(vm + i + idx); float16 mm_16 = *(float16 *)(vm + i + idx);
@ -2808,7 +2808,7 @@ bool is_ebf(CPUARMState *env, float_status *statusp, float_status *oddstatusp)
*/ */
bool ebf = is_a64(env) && env->vfp.fpcr & FPCR_EBF; bool ebf = is_a64(env) && env->vfp.fpcr & FPCR_EBF;
*statusp = env->vfp.fp_status; *statusp = is_a64(env) ? env->vfp.fp_status_a64 : env->vfp.fp_status_a32;
set_default_nan_mode(true, statusp); set_default_nan_mode(true, statusp);
if (ebf) { if (ebf) {

View file

@ -34,42 +34,45 @@
#ifdef CONFIG_TCG #ifdef CONFIG_TCG
/* Convert host exception flags to vfp form. */ /* Convert host exception flags to vfp form. */
static inline int vfp_exceptbits_from_host(int host_bits) static inline uint32_t vfp_exceptbits_from_host(int host_bits)
{ {
int target_bits = 0; uint32_t target_bits = 0;
if (host_bits & float_flag_invalid) { if (host_bits & float_flag_invalid) {
target_bits |= 1; target_bits |= FPSR_IOC;
} }
if (host_bits & float_flag_divbyzero) { if (host_bits & float_flag_divbyzero) {
target_bits |= 2; target_bits |= FPSR_DZC;
} }
if (host_bits & float_flag_overflow) { if (host_bits & float_flag_overflow) {
target_bits |= 4; target_bits |= FPSR_OFC;
} }
if (host_bits & (float_flag_underflow | float_flag_output_denormal)) { if (host_bits & (float_flag_underflow | float_flag_output_denormal_flushed)) {
target_bits |= 8; target_bits |= FPSR_UFC;
} }
if (host_bits & float_flag_inexact) { if (host_bits & float_flag_inexact) {
target_bits |= 0x10; target_bits |= FPSR_IXC;
} }
if (host_bits & float_flag_input_denormal) { if (host_bits & float_flag_input_denormal_flushed) {
target_bits |= 0x80; target_bits |= FPSR_IDC;
} }
return target_bits; return target_bits;
} }
static uint32_t vfp_get_fpsr_from_host(CPUARMState *env) static uint32_t vfp_get_fpsr_from_host(CPUARMState *env)
{ {
uint32_t i; uint32_t i = 0;
i = get_float_exception_flags(&env->vfp.fp_status); i |= get_float_exception_flags(&env->vfp.fp_status_a32);
i |= get_float_exception_flags(&env->vfp.fp_status_a64);
i |= get_float_exception_flags(&env->vfp.standard_fp_status); i |= get_float_exception_flags(&env->vfp.standard_fp_status);
/* FZ16 does not generate an input denormal exception. */ /* FZ16 does not generate an input denormal exception. */
i |= (get_float_exception_flags(&env->vfp.fp_status_f16) i |= (get_float_exception_flags(&env->vfp.fp_status_f16_a32)
& ~float_flag_input_denormal); & ~float_flag_input_denormal_flushed);
i |= (get_float_exception_flags(&env->vfp.fp_status_f16_a64)
& ~float_flag_input_denormal_flushed);
i |= (get_float_exception_flags(&env->vfp.standard_fp_status_f16) i |= (get_float_exception_flags(&env->vfp.standard_fp_status_f16)
& ~float_flag_input_denormal); & ~float_flag_input_denormal_flushed);
return vfp_exceptbits_from_host(i); return vfp_exceptbits_from_host(i);
} }
@ -80,8 +83,10 @@ static void vfp_clear_float_status_exc_flags(CPUARMState *env)
* values. The caller should have arranged for env->vfp.fpsr to * values. The caller should have arranged for env->vfp.fpsr to
* be the architecturally up-to-date exception flag information first. * be the architecturally up-to-date exception flag information first.
*/ */
set_float_exception_flags(0, &env->vfp.fp_status); set_float_exception_flags(0, &env->vfp.fp_status_a32);
set_float_exception_flags(0, &env->vfp.fp_status_f16); set_float_exception_flags(0, &env->vfp.fp_status_a64);
set_float_exception_flags(0, &env->vfp.fp_status_f16_a32);
set_float_exception_flags(0, &env->vfp.fp_status_f16_a64);
set_float_exception_flags(0, &env->vfp.standard_fp_status); set_float_exception_flags(0, &env->vfp.standard_fp_status);
set_float_exception_flags(0, &env->vfp.standard_fp_status_f16); set_float_exception_flags(0, &env->vfp.standard_fp_status_f16);
} }
@ -108,25 +113,33 @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask)
i = float_round_to_zero; i = float_round_to_zero;
break; break;
} }
set_float_rounding_mode(i, &env->vfp.fp_status); set_float_rounding_mode(i, &env->vfp.fp_status_a32);
set_float_rounding_mode(i, &env->vfp.fp_status_f16); set_float_rounding_mode(i, &env->vfp.fp_status_a64);
set_float_rounding_mode(i, &env->vfp.fp_status_f16_a32);
set_float_rounding_mode(i, &env->vfp.fp_status_f16_a64);
} }
if (changed & FPCR_FZ16) { if (changed & FPCR_FZ16) {
bool ftz_enabled = val & FPCR_FZ16; bool ftz_enabled = val & FPCR_FZ16;
set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16); set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a32);
set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a64);
set_flush_to_zero(ftz_enabled, &env->vfp.standard_fp_status_f16); set_flush_to_zero(ftz_enabled, &env->vfp.standard_fp_status_f16);
set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16); set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a32);
set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16_a64);
set_flush_inputs_to_zero(ftz_enabled, &env->vfp.standard_fp_status_f16); set_flush_inputs_to_zero(ftz_enabled, &env->vfp.standard_fp_status_f16);
} }
if (changed & FPCR_FZ) { if (changed & FPCR_FZ) {
bool ftz_enabled = val & FPCR_FZ; bool ftz_enabled = val & FPCR_FZ;
set_flush_to_zero(ftz_enabled, &env->vfp.fp_status); set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_a32);
set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status); set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_a32);
set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_a64);
set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_a64);
} }
if (changed & FPCR_DN) { if (changed & FPCR_DN) {
bool dnan_enabled = val & FPCR_DN; bool dnan_enabled = val & FPCR_DN;
set_default_nan_mode(dnan_enabled, &env->vfp.fp_status); set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_a32);
set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16); set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_a64);
set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16_a32);
set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16_a64);
} }
} }
@ -360,9 +373,9 @@ void VFP_HELPER(cmpe, P)(ARGTYPE a, ARGTYPE b, CPUARMState *env) \
softfloat_to_vfp_compare(env, \ softfloat_to_vfp_compare(env, \
FLOATTYPE ## _compare(a, b, &env->vfp.FPST)); \ FLOATTYPE ## _compare(a, b, &env->vfp.FPST)); \
} }
DO_VFP_cmp(h, float16, dh_ctype_f16, fp_status_f16) DO_VFP_cmp(h, float16, dh_ctype_f16, fp_status_f16_a32)
DO_VFP_cmp(s, float32, float32, fp_status) DO_VFP_cmp(s, float32, float32, fp_status_a32)
DO_VFP_cmp(d, float64, float64, fp_status) DO_VFP_cmp(d, float64, float64, fp_status_a32)
#undef DO_VFP_cmp #undef DO_VFP_cmp
/* Integer to float and float to integer conversions */ /* Integer to float and float to integer conversions */
@ -1120,7 +1133,7 @@ uint64_t HELPER(fjcvtzs)(float64 value, float_status *status)
/* Normal inexact, denormal with flush-to-zero, or overflow or NaN */ /* Normal inexact, denormal with flush-to-zero, or overflow or NaN */
inexact = e_new & (float_flag_inexact | inexact = e_new & (float_flag_inexact |
float_flag_input_denormal | float_flag_input_denormal_flushed |
float_flag_invalid); float_flag_invalid);
/* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */ /* While not inexact for IEEE FP, -0.0 is inexact for JavaScript. */
@ -1132,7 +1145,7 @@ uint64_t HELPER(fjcvtzs)(float64 value, float_status *status)
uint32_t HELPER(vjcvt)(float64 value, CPUARMState *env) uint32_t HELPER(vjcvt)(float64 value, CPUARMState *env)
{ {
uint64_t pair = HELPER(fjcvtzs)(value, &env->vfp.fp_status); uint64_t pair = HELPER(fjcvtzs)(value, &env->vfp.fp_status_a32);
uint32_t result = pair; uint32_t result = pair;
uint32_t z = (pair >> 32) == 0; uint32_t z = (pair >> 32) == 0;

View file

@ -204,7 +204,7 @@ static void merge_exception_flags(CPUX86State *env, uint8_t old_flags)
(new_flags & float_flag_overflow ? FPUS_OE : 0) | (new_flags & float_flag_overflow ? FPUS_OE : 0) |
(new_flags & float_flag_underflow ? FPUS_UE : 0) | (new_flags & float_flag_underflow ? FPUS_UE : 0) |
(new_flags & float_flag_inexact ? FPUS_PE : 0) | (new_flags & float_flag_inexact ? FPUS_PE : 0) |
(new_flags & float_flag_input_denormal ? FPUS_DE : 0))); (new_flags & float_flag_input_denormal_flushed ? FPUS_DE : 0)));
} }
static inline floatx80 helper_fdiv(CPUX86State *env, floatx80 a, floatx80 b) static inline floatx80 helper_fdiv(CPUX86State *env, floatx80 a, floatx80 b)
@ -1829,7 +1829,7 @@ void helper_fxtract(CPUX86State *env)
int shift = clz64(temp.l.lower); int shift = clz64(temp.l.lower);
temp.l.lower <<= shift; temp.l.lower <<= shift;
expdif = 1 - EXPBIAS - shift; expdif = 1 - EXPBIAS - shift;
float_raise(float_flag_input_denormal, &env->fp_status); float_raise(float_flag_input_denormal_flushed, &env->fp_status);
} else { } else {
expdif = EXPD(temp) - EXPBIAS; expdif = EXPD(temp) - EXPBIAS;
} }
@ -3258,7 +3258,7 @@ void update_mxcsr_from_sse_status(CPUX86State *env)
uint8_t flags = get_float_exception_flags(&env->sse_status); uint8_t flags = get_float_exception_flags(&env->sse_status);
/* /*
* The MXCSR denormal flag has opposite semantics to * The MXCSR denormal flag has opposite semantics to
* float_flag_input_denormal (the softfloat code sets that flag * float_flag_input_denormal_flushed (the softfloat code sets that flag
* only when flushing input denormals to zero, but SSE sets it * only when flushing input denormals to zero, but SSE sets it
* only when not flushing them to zero), so is not converted * only when not flushing them to zero), so is not converted
* here. * here.
@ -3268,7 +3268,7 @@ void update_mxcsr_from_sse_status(CPUX86State *env)
(flags & float_flag_overflow ? FPUS_OE : 0) | (flags & float_flag_overflow ? FPUS_OE : 0) |
(flags & float_flag_underflow ? FPUS_UE : 0) | (flags & float_flag_underflow ? FPUS_UE : 0) |
(flags & float_flag_inexact ? FPUS_PE : 0) | (flags & float_flag_inexact ? FPUS_PE : 0) |
(flags & float_flag_output_denormal ? FPUS_UE | FPUS_PE : (flags & float_flag_output_denormal_flushed ? FPUS_UE | FPUS_PE :
0)); 0));
} }

View file

@ -175,7 +175,7 @@ static int cpu_m68k_exceptbits_from_host(int host_bits)
if (host_bits & float_flag_overflow) { if (host_bits & float_flag_overflow) {
target_bits |= 0x40; target_bits |= 0x40;
} }
if (host_bits & (float_flag_underflow | float_flag_output_denormal)) { if (host_bits & (float_flag_underflow | float_flag_output_denormal_flushed)) {
target_bits |= 0x20; target_bits |= 0x20;
} }
if (host_bits & float_flag_divbyzero) { if (host_bits & float_flag_divbyzero) {

View file

@ -6231,7 +6231,7 @@ static inline int update_msacsr(CPUMIPSState *env, int action, int denormal)
enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED; enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED;
/* Set Inexact (I) when flushing inputs to zero */ /* Set Inexact (I) when flushing inputs to zero */
if ((ieee_exception_flags & float_flag_input_denormal) && if ((ieee_exception_flags & float_flag_input_denormal_flushed) &&
(env->active_tc.msacsr & MSACSR_FS_MASK) != 0) { (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
if (action & CLEAR_IS_INEXACT) { if (action & CLEAR_IS_INEXACT) {
mips_exception_flags &= ~FP_INEXACT; mips_exception_flags &= ~FP_INEXACT;
@ -6241,7 +6241,7 @@ static inline int update_msacsr(CPUMIPSState *env, int action, int denormal)
} }
/* Set Inexact (I) and Underflow (U) when flushing outputs to zero */ /* Set Inexact (I) and Underflow (U) when flushing outputs to zero */
if ((ieee_exception_flags & float_flag_output_denormal) && if ((ieee_exception_flags & float_flag_output_denormal_flushed) &&
(env->active_tc.msacsr & MSACSR_FS_MASK) != 0) { (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
mips_exception_flags |= FP_INEXACT; mips_exception_flags |= FP_INEXACT;
if (action & CLEAR_FS_UNDERFLOW) { if (action & CLEAR_FS_UNDERFLOW) {

View file

@ -99,8 +99,8 @@ static void update_fpsw(CPURXState *env, float32 ret, uintptr_t retaddr)
if (xcpt & float_flag_inexact) { if (xcpt & float_flag_inexact) {
SET_FPSW(X); SET_FPSW(X);
} }
if ((xcpt & (float_flag_input_denormal if ((xcpt & (float_flag_input_denormal_flushed
| float_flag_output_denormal)) | float_flag_output_denormal_flushed))
&& !FIELD_EX32(env->fpsw, FPSW, DN)) { && !FIELD_EX32(env->fpsw, FPSW, DN)) {
env->fpsw = FIELD_DP32(env->fpsw, FPSW, CE, 1); env->fpsw = FIELD_DP32(env->fpsw, FPSW, CE, 1);
} }

View file

@ -43,7 +43,7 @@ static inline uint8_t f_get_excp_flags(CPUTriCoreState *env)
& (float_flag_invalid & (float_flag_invalid
| float_flag_overflow | float_flag_overflow
| float_flag_underflow | float_flag_underflow
| float_flag_output_denormal | float_flag_output_denormal_flushed
| float_flag_divbyzero | float_flag_divbyzero
| float_flag_inexact); | float_flag_inexact);
} }
@ -99,7 +99,7 @@ static void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags)
some_excp = 1; some_excp = 1;
} }
if (flags & float_flag_underflow || flags & float_flag_output_denormal) { if (flags & float_flag_underflow || flags & float_flag_output_denormal_flushed) {
env->FPU_FU = 1 << 31; env->FPU_FU = 1 << 31;
some_excp = 1; some_excp = 1;
} }
@ -109,7 +109,7 @@ static void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags)
some_excp = 1; some_excp = 1;
} }
if (flags & float_flag_inexact || flags & float_flag_output_denormal) { if (flags & float_flag_inexact || flags & float_flag_output_denormal_flushed) {
env->PSW |= 1 << 26; env->PSW |= 1 << 26;
some_excp = 1; some_excp = 1;
} }

View file

@ -91,6 +91,7 @@ tests_arm_system_thorough = [
'arm_cubieboard', 'arm_cubieboard',
'arm_emcraft_sf2', 'arm_emcraft_sf2',
'arm_integratorcp', 'arm_integratorcp',
'arm_microbit',
'arm_orangepi', 'arm_orangepi',
'arm_quanta_gsj', 'arm_quanta_gsj',
'arm_raspi2', 'arm_raspi2',

View file

@ -0,0 +1,31 @@
#!/usr/bin/env python3
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright 2025, The QEMU Project Developers.
#
# A functional test that runs MicroPython on the arm microbit machine.
from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern
from qemu_test import wait_for_console_pattern
class MicrobitMachine(QemuSystemTest):
ASSET_MICRO = Asset('https://ozlabs.org/~joel/microbit-micropython.hex',
'021641f93dfb11767d4978dbb3ca7f475d1b13c69e7f4aec3382f212636bffd6')
def test_arm_microbit(self):
self.set_machine('microbit')
micropython = self.ASSET_MICRO.fetch()
self.vm.set_console()
self.vm.add_args('-device', f'loader,file={micropython}')
self.vm.launch()
wait_for_console_pattern(self, 'Type "help()" for more information.')
exec_command_and_wait_for_pattern(self, 'import machine as mch', '>>>')
exec_command_and_wait_for_pattern(self, 'mch.reset()', 'MicroPython')
wait_for_console_pattern(self, '>>>')
if __name__ == '__main__':
QemuSystemTest.main()