mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 01:33:56 -06:00
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:
commit
fb49b69bf9
49 changed files with 452 additions and 337 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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) \
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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',
|
||||||
|
|
31
tests/functional/test_arm_microbit.py
Executable file
31
tests/functional/test_arm_microbit.py
Executable 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()
|
Loading…
Add table
Add a link
Reference in a new issue