Re: [PATCH 3/5] tests/acpi: allow changes for core_count2 test

2022-05-27 Thread Ani Sinha



On Fri, 27 May 2022, Julia Suvorova wrote:

> Signed-off-by: Julia Suvorova 

Acked-by: Ani Sinha 

> ---
>  tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
>  tests/data/acpi/q35/APIC.core-count2| 0
>  tests/data/acpi/q35/DSDT.core-count2| 0
>  tests/data/acpi/q35/FACP.core-count2| 0
>  4 files changed, 3 insertions(+)
>  create mode 100644 tests/data/acpi/q35/APIC.core-count2
>  create mode 100644 tests/data/acpi/q35/DSDT.core-count2
>  create mode 100644 tests/data/acpi/q35/FACP.core-count2
>
> diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
> b/tests/qtest/bios-tables-test-allowed-diff.h
> index dfb8523c8b..e81dc67a2e 100644
> --- a/tests/qtest/bios-tables-test-allowed-diff.h
> +++ b/tests/qtest/bios-tables-test-allowed-diff.h
> @@ -1 +1,4 @@
>  /* List of comma-separated changed AML files to ignore */
> +"tests/data/acpi/q35/APIC.core-count2",
> +"tests/data/acpi/q35/DSDT.core-count2",
> +"tests/data/acpi/q35/FACP.core-count2",
> diff --git a/tests/data/acpi/q35/APIC.core-count2 
> b/tests/data/acpi/q35/APIC.core-count2
> new file mode 100644
> index 00..e69de29bb2
> diff --git a/tests/data/acpi/q35/DSDT.core-count2 
> b/tests/data/acpi/q35/DSDT.core-count2
> new file mode 100644
> index 00..e69de29bb2
> diff --git a/tests/data/acpi/q35/FACP.core-count2 
> b/tests/data/acpi/q35/FACP.core-count2
> new file mode 100644
> index 00..e69de29bb2
> --
> 2.35.1
>
>



Re: [PATCH 4/5] bios-tables-test: add test for number of cores > 255

2022-05-27 Thread Ani Sinha



On Fri, 27 May 2022, Julia Suvorova wrote:

> The new test is run with a large number of cpus and checks if the
> core_count field in smbios_cpu_test (structure type 4) is correct.
>
> Choose q35 as it allows to run with -smp > 255.
>
> Signed-off-by: Julia Suvorova 
> ---
>  tests/qtest/bios-tables-test.c | 35 +-
>  1 file changed, 34 insertions(+), 1 deletion(-)
>
> diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
> index 0ba9d749a5..f2464adaa0 100644
> --- a/tests/qtest/bios-tables-test.c
> +++ b/tests/qtest/bios-tables-test.c
> @@ -100,6 +100,8 @@ typedef struct {
>  smbios_entry_point smbios_ep_table;
>  uint16_t smbios_cpu_max_speed;
>  uint16_t smbios_cpu_curr_speed;
> +uint8_t smbios_core_count;
> +uint16_t smbios_core_count2;
>  uint8_t *required_struct_types;
>  int required_struct_types_len;
>  QTestState *qts;
> @@ -640,8 +642,9 @@ static inline bool smbios_single_instance(uint8_t type)
>
>  static bool smbios_cpu_test(test_data *data, uint32_t addr)
>  {
> +uint8_t real_cc, expect_cc = data->smbios_core_count;
> +uint16_t real, real_cc2, expect_cc2 = data->smbios_core_count2;
>  uint16_t expect_speed[2];
> -uint16_t real;

while you are at it, I suggest renaming this to real_speed or some such so
that its better redeable.

>  int offset[2];
>  int i;
>
> @@ -660,6 +663,20 @@ static bool smbios_cpu_test(test_data *data, uint32_t 
> addr)
>  }
>  }
>
> +real_cc = qtest_readb(data->qts, addr + offsetof(struct smbios_type_4, 
> core_count));
> +real_cc2 = qtest_readw(data->qts, addr + offsetof(struct smbios_type_4, 
> core_count2));
> +
> +if (expect_cc && (real_cc != expect_cc)) {

I think better to say if ((expect_cc < 256) && (real_cc != expect_cc))

> +fprintf(stderr, "Unexpected SMBIOS CPU count: real %u expect %u\n",
> +real_cc, expect_cc);
> +return false;
> +}
> +if ((expect_cc == 0xFF) && (real_cc2 != expect_cc2)) {
> +fprintf(stderr, "Unexpected SMBIOS CPU count2: real %u expect %u\n",
> +real_cc2, expect_cc2);
> +return false;
> +}
> +
>  return true;
>  }
>
> @@ -905,6 +922,21 @@ static void test_acpi_q35_tcg(void)
>  free_test_data();
>  }
>
> +static void test_acpi_q35_tcg_core_count2(void)
> +{
> +test_data data = {
> +.machine = MACHINE_Q35,
> +.variant = ".core-count2",
> +.required_struct_types = base_required_struct_types,
> +.required_struct_types_len = ARRAY_SIZE(base_required_struct_types),
> +.smbios_core_count = 0xFF,
> +.smbios_core_count2 = 275,
> +};
> +
> +test_acpi_one("-machine smbios-entry-point-type=64 -smp 275", );
> +free_test_data();
> +}
> +
>  static void test_acpi_q35_tcg_bridge(void)
>  {
>  test_data data;
> @@ -1787,6 +1819,7 @@ int main(int argc, char *argv[])
>  qtest_add_func("acpi/piix4/pci-hotplug/off",
> test_acpi_piix4_no_acpi_pci_hotplug);
>  qtest_add_func("acpi/q35", test_acpi_q35_tcg);
> +qtest_add_func("acpi/q35/core-count2", 
> test_acpi_q35_tcg_core_count2);

How about checking thread count as well in the same test or in a
different test?

>  qtest_add_func("acpi/q35/bridge", test_acpi_q35_tcg_bridge);
>  qtest_add_func("acpi/q35/multif-bridge", 
> test_acpi_q35_multif_bridge);
>  qtest_add_func("acpi/q35/mmio64", test_acpi_q35_tcg_mmio64);
> --
> 2.35.1
>
>



Re: [PATCH 1/5] hw/smbios: add core_count2 to smbios table type 4

2022-05-27 Thread Ani Sinha



On Fri, 27 May 2022, Julia Suvorova wrote:

> In order to use the increased number of cpus, we need to bring smbios
> tables in line with the SMBIOS 3.0 specification. This allows us to
> introduce core_count2 which acts as a duplicate of core_count if we have
> fewer cores than 256, and contains the actual core number per socket if
> we have more.
>
> core_enabled2 and thread_count2 fields work the same way.
>
> Signed-off-by: Julia Suvorova 

Other than the comment below,
Reviewed-by: Ani Sinha 

> ---
>  include/hw/firmware/smbios.h |  3 +++
>  hw/smbios/smbios.c   | 11 +--
>  2 files changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
> index 4b7ad77a44..c427ae5558 100644
> --- a/include/hw/firmware/smbios.h
> +++ b/include/hw/firmware/smbios.h
> @@ -187,6 +187,9 @@ struct smbios_type_4 {
>  uint8_t thread_count;
>  uint16_t processor_characteristics;
>  uint16_t processor_family2;
> +uint16_t core_count2;
> +uint16_t core_enabled2;
> +uint16_t thread_count2;

I would add a comment along the lines of
/* section 7.5, table 21 smbios spec version 3.0.0 */

>  } QEMU_PACKED;
>
>  /* SMBIOS type 11 - OEM strings */
> diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> index 60349ee402..45d7be6b30 100644
> --- a/hw/smbios/smbios.c
> +++ b/hw/smbios/smbios.c
> @@ -709,8 +709,15 @@ static void smbios_build_type_4_table(MachineState *ms, 
> unsigned instance)
>  SMBIOS_TABLE_SET_STR(4, serial_number_str, type4.serial);
>  SMBIOS_TABLE_SET_STR(4, asset_tag_number_str, type4.asset);
>  SMBIOS_TABLE_SET_STR(4, part_number_str, type4.part);
> -t->core_count = t->core_enabled = ms->smp.cores;
> -t->thread_count = ms->smp.threads;
> +
> +t->core_count = (ms->smp.cores > 255) ? 0xFF : ms->smp.cores;
> +t->core_enabled = t->core_count;
> +
> +t->core_count2 = t->core_enabled2 = cpu_to_le16(ms->smp.cores);
> +
> +t->thread_count = (ms->smp.threads > 255) ? 0xFF : ms->smp.threads;
> +t->thread_count2 = cpu_to_le16(ms->smp.threads);
> +
>  t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */
>  t->processor_family2 = cpu_to_le16(0x01); /* Other */
>
> --
> 2.35.1
>
>



GSoC project: VIRTIO_F_IN_ORDER support for virtio devices

2022-05-27 Thread Guo Zhi
Hi everyone,
I'm Zhi Guo, a student from GSoC 2022.
My project is VIRTIO_F_IN_ORDER support for virtio devices. 

VIRTIO_F_IN_ORDER is a new feature presented in VIRTIO 1.1. As mentioned on the 
project description 
page(https://wiki.qemu.org/Google_Summer_of_Code_2022#VIRTIO_F_IN_ORDER_support_for_virtio_devices),
 VIRTIO_F_IN_ORDER is a feature that devices and drivers can negotiate when the 
device uses descriptors in the same order in which they were made available by 
the driver. This feature can help devices and drivers batch buffers and improve 
performance. Currently the devices and drivers available in Linux and QEMU do 
not support the VIRTIO_F_IN_ORDER feature. The only implementation is available 
in DPDK for the virtio-net driver. I will spend this summer to implement 
VIRTIO_F_IN_ORDER feature in both Linux and QEMU, and in both split and packed 
virtqueue layouts. Patches will be sent as soon as possible.

Best regards,

Zhi



Re: [PATCH v4 2/3] target/riscv: Add stimecmp support

2022-05-27 Thread Atish Kumar Patra
On Thu, May 26, 2022 at 7:07 PM Alistair Francis  wrote:
>
> On Thu, May 26, 2022 at 5:16 PM Atish Patra  wrote:
> >
> > On Wed, May 25, 2022 at 10:11 PM Alistair Francis  
> > wrote:
> > >
> > > On Sat, May 14, 2022 at 4:39 AM Atish Patra  wrote:
> > > >
> > > > stimecmp allows the supervisor mode to update stimecmp CSR directly
> > > > to program the next timer interrupt. This CSR is part of the Sstc
> > > > extension which was ratified recently.
> > > >
> > > > Signed-off-by: Atish Patra 
> > > > ---
> > > >  target/riscv/cpu.c |  8 
> > > >  target/riscv/cpu.h |  7 +++
> > > >  target/riscv/cpu_bits.h|  4 ++
> > > >  target/riscv/csr.c | 92 +++
> > > >  target/riscv/machine.c |  2 +
> > > >  target/riscv/meson.build   |  3 +-
> > > >  target/riscv/time_helper.c | 98 ++
> > > >  target/riscv/time_helper.h | 30 
> > > >  8 files changed, 243 insertions(+), 1 deletion(-)
> > > >  create mode 100644 target/riscv/time_helper.c
> > > >  create mode 100644 target/riscv/time_helper.h
> > > >
> > > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > > > index 19f4e8294042..d58dd2f857a7 100644
> > > > --- a/target/riscv/cpu.c
> > > > +++ b/target/riscv/cpu.c
> > > > @@ -23,6 +23,7 @@
> > > >  #include "qemu/log.h"
> > > >  #include "cpu.h"
> > > >  #include "internals.h"
> > > > +#include "time_helper.h"
> > > >  #include "exec/exec-all.h"
> > > >  #include "qapi/error.h"
> > > >  #include "qemu/error-report.h"
> > > > @@ -779,7 +780,12 @@ static void riscv_cpu_init(Object *obj)
> > > >  #ifndef CONFIG_USER_ONLY
> > > >  qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq,
> > > >IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
> > > > +
> > > > +if (cpu->cfg.ext_sstc) {
> > > > +riscv_timer_init(cpu);
> > > > +}
> > > >  #endif /* CONFIG_USER_ONLY */
> > > > +
> > > >  }
> > > >
> > > >  static Property riscv_cpu_properties[] = {
> > > > @@ -806,6 +812,7 @@ static Property riscv_cpu_properties[] = {
> > > >  DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
> > > >  DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
> > > >  DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
> > > > +DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true),
> > > >
> > > >  DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
> > > >  DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
> > > > @@ -965,6 +972,7 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, 
> > > > char **isa_str, int max_str_len)
> > > >  ISA_EDATA_ENTRY(zbs, ext_zbs),
> > > >  ISA_EDATA_ENTRY(zve32f, ext_zve32f),
> > > >  ISA_EDATA_ENTRY(zve64f, ext_zve64f),
> > > > +ISA_EDATA_ENTRY(sstc, ext_sstc),
> > > >  ISA_EDATA_ENTRY(svinval, ext_svinval),
> > > >  ISA_EDATA_ENTRY(svnapot, ext_svnapot),
> > > >  ISA_EDATA_ENTRY(svpbmt, ext_svpbmt),
> > > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > > > index 1119d5201066..9a01e6d0f587 100644
> > > > --- a/target/riscv/cpu.h
> > > > +++ b/target/riscv/cpu.h
> > > > @@ -276,6 +276,11 @@ struct CPUArchState {
> > > >  uint64_t mfromhost;
> > > >  uint64_t mtohost;
> > > >
> > > > +/* Sstc CSRs */
> > > > +uint64_t stimecmp;
> > > > +/* For RV32 only */
> > > > +uint8_t stimecmp_wr_done;
> > > > +
> > > >  /* physical memory protection */
> > > >  pmp_table_t pmp_state;
> > > >  target_ulong mseccfg;
> > > > @@ -329,6 +334,7 @@ struct CPUArchState {
> > > >  float_status fp_status;
> > > >
> > > >  /* Fields from here on are preserved across CPU reset. */
> > > > +QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
> > > >
> > > >  hwaddr kernel_addr;
> > > >  hwaddr fdt_addr;
> > > > @@ -379,6 +385,7 @@ struct RISCVCPUConfig {
> > > >  bool ext_counters;
> > > >  bool ext_ifencei;
> > > >  bool ext_icsr;
> > > > +bool ext_sstc;
> > > >  bool ext_svinval;
> > > >  bool ext_svnapot;
> > > >  bool ext_svpbmt;
> > > > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > > > index 4e5b630f5965..29d0e4a1be01 100644
> > > > --- a/target/riscv/cpu_bits.h
> > > > +++ b/target/riscv/cpu_bits.h
> > > > @@ -215,6 +215,10 @@
> > > >  #define CSR_STVAL   0x143
> > > >  #define CSR_SIP 0x144
> > > >
> > > > +/* Sstc supervisor CSRs */
> > > > +#define CSR_STIMECMP0x14D
> > > > +#define CSR_STIMECMPH   0x15D
> > > > +
> > > >  /* Supervisor Protection and Translation */
> > > >  #define CSR_SPTBR   0x180
> > > >  #define CSR_SATP0x180
> > > > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > > > index 245f007e66e1..8952d1308008 100644
> > > > --- a/target/riscv/csr.c
> > > > +++ b/target/riscv/csr.c
> > > > @@ -21,6 +21,7 @@
> > > >  #include "qemu/log.h"
> > > >  #include "qemu/timer.h"
> > > >  #include "cpu.h"
> > 

Re: [PATCH v2] linux-user: Adjust child_tidptr on set_tid_address() syscall

2022-05-27 Thread Richard Henderson

On 5/27/22 13:44, Helge Deller wrote:

I think the previous patch was wrong, since we just emulate writing to
child_tidptr. Below is updated RFC patch.

---
[PATCH] linux-user: Adjust child_tidptr on set_tid_address()

Keep track of the new child tidptr given by a set_tid_address() syscall.

Signed-off-by: Helge Deller


Reviewed-by: Richard Henderson 

r~



[RESEND PATCH 1/2] modules: introduces module_kconfig directive

2022-05-27 Thread Dario Faggioli
From: Jose R. Ziviani 

module_kconfig is a new directive that should be used with module_obj
whenever that module depends on the Kconfig to be enabled.

When the module is enabled in Kconfig we are sure that its dependencies
will be enabled as well, thus the module will be loaded without any
problem.

The correct way to use module_kconfig is by passing the Kconfig option
to module_kconfig (or the *config-devices.mak without CONFIG_).

Signed-off-by: Jose R. Ziviani 
Signed-off-by: Dario Faggioli 
---
Cc: Gerd Hoffmann 
Cc: John Snow 
Cc: Cleber Rosa 
Cc: Paolo Bonzini 
Cc: qemu-s3...@nongnu.org
---
 hw/display/qxl.c|1 +
 hw/display/vhost-user-gpu-pci.c |1 +
 hw/display/vhost-user-gpu.c |1 +
 hw/display/vhost-user-vga.c |1 +
 hw/display/virtio-gpu-base.c|1 +
 hw/display/virtio-gpu-gl.c  |1 +
 hw/display/virtio-gpu-pci-gl.c  |1 +
 hw/display/virtio-gpu-pci.c |1 +
 hw/display/virtio-gpu.c |1 +
 hw/display/virtio-vga-gl.c  |1 +
 hw/display/virtio-vga.c |1 +
 hw/s390x/virtio-ccw-gpu.c   |1 +
 hw/usb/ccid-card-emulated.c |1 +
 hw/usb/ccid-card-passthru.c |1 +
 hw/usb/host-libusb.c|1 +
 hw/usb/redirect.c   |1 +
 include/qemu/module.h   |   10 ++
 scripts/modinfo-generate.py |2 ++
 18 files changed, 28 insertions(+)

diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 2db34714fb..5b10f697f1 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -2515,6 +2515,7 @@ static const TypeInfo qxl_primary_info = {
 .class_init= qxl_primary_class_init,
 };
 module_obj("qxl-vga");
+module_kconfig(QXL);
 
 static void qxl_secondary_class_init(ObjectClass *klass, void *data)
 {
diff --git a/hw/display/vhost-user-gpu-pci.c b/hw/display/vhost-user-gpu-pci.c
index daefcf7101..d119bcae45 100644
--- a/hw/display/vhost-user-gpu-pci.c
+++ b/hw/display/vhost-user-gpu-pci.c
@@ -44,6 +44,7 @@ static const VirtioPCIDeviceTypeInfo vhost_user_gpu_pci_info 
= {
 .instance_init = vhost_user_gpu_pci_initfn,
 };
 module_obj(TYPE_VHOST_USER_GPU_PCI);
+module_kconfig(VHOST_USER_GPU);
 
 static void vhost_user_gpu_pci_register_types(void)
 {
diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c
index 96e56c4467..3340ef9e5f 100644
--- a/hw/display/vhost-user-gpu.c
+++ b/hw/display/vhost-user-gpu.c
@@ -606,6 +606,7 @@ static const TypeInfo vhost_user_gpu_info = {
 .class_init = vhost_user_gpu_class_init,
 };
 module_obj(TYPE_VHOST_USER_GPU);
+module_kconfig(VHOST_USER_GPU);
 
 static void vhost_user_gpu_register_types(void)
 {
diff --git a/hw/display/vhost-user-vga.c b/hw/display/vhost-user-vga.c
index 072c9c65bc..0c146080fd 100644
--- a/hw/display/vhost-user-vga.c
+++ b/hw/display/vhost-user-vga.c
@@ -45,6 +45,7 @@ static const VirtioPCIDeviceTypeInfo vhost_user_vga_info = {
 .instance_init = vhost_user_vga_inst_initfn,
 };
 module_obj(TYPE_VHOST_USER_VGA);
+module_kconfig(VHOST_USER_VGA);
 
 static void vhost_user_vga_register_types(void)
 {
diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c
index 8ba5da4312..790cec333c 100644
--- a/hw/display/virtio-gpu-base.c
+++ b/hw/display/virtio-gpu-base.c
@@ -260,6 +260,7 @@ static const TypeInfo virtio_gpu_base_info = {
 .abstract = true
 };
 module_obj(TYPE_VIRTIO_GPU_BASE);
+module_kconfig(VIRTIO_GPU);
 
 static void
 virtio_register_types(void)
diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c
index 0bca887703..e06be60dfb 100644
--- a/hw/display/virtio-gpu-gl.c
+++ b/hw/display/virtio-gpu-gl.c
@@ -160,6 +160,7 @@ static const TypeInfo virtio_gpu_gl_info = {
 .class_init = virtio_gpu_gl_class_init,
 };
 module_obj(TYPE_VIRTIO_GPU_GL);
+module_kconfig(VIRTIO_GPU);
 
 static void virtio_register_types(void)
 {
diff --git a/hw/display/virtio-gpu-pci-gl.c b/hw/display/virtio-gpu-pci-gl.c
index 99b14a0718..a2819e1ca9 100644
--- a/hw/display/virtio-gpu-pci-gl.c
+++ b/hw/display/virtio-gpu-pci-gl.c
@@ -47,6 +47,7 @@ static const VirtioPCIDeviceTypeInfo virtio_gpu_gl_pci_info = 
{
 .instance_init = virtio_gpu_gl_initfn,
 };
 module_obj(TYPE_VIRTIO_GPU_GL_PCI);
+module_kconfig(VIRTIO_PCI);
 
 static void virtio_gpu_gl_pci_register_types(void)
 {
diff --git a/hw/display/virtio-gpu-pci.c b/hw/display/virtio-gpu-pci.c
index e36eee0c40..93f214ff58 100644
--- a/hw/display/virtio-gpu-pci.c
+++ b/hw/display/virtio-gpu-pci.c
@@ -65,6 +65,7 @@ static const TypeInfo virtio_gpu_pci_base_info = {
 .abstract = true
 };
 module_obj(TYPE_VIRTIO_GPU_PCI_BASE);
+module_kconfig(VIRTIO_PCI);
 
 #define TYPE_VIRTIO_GPU_PCI "virtio-gpu-pci"
 typedef struct VirtIOGPUPCI VirtIOGPUPCI;
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 529b5246b2..cd4a56056f 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -1452,6 +1452,7 @@ static const TypeInfo virtio_gpu_info = {
 .class_init = virtio_gpu_class_init,
 };
 

[RESEND PATCH 2/2] modules: generates per-target modinfo

2022-05-27 Thread Dario Faggioli
From: Jose R. Ziviani 

This patch changes the way modinfo is generated and built. Instead of
one modinfo.c it generates one modinfo--softmmu.c per target. It
aims a fine-tune control of modules by configuring Kconfig.

Signed-off-by: Jose R. Ziviani 
Signed-off-by: Dario Faggioli 
---
Cc: Gerd Hoffmann 
Cc: John Snow 
Cc: Cleber Rosa 
Cc: Paolo Bonzini 
Cc: qemu-s3...@nongnu.org
---
 meson.build |   25 +
 scripts/modinfo-generate.py |   42 +-
 2 files changed, 42 insertions(+), 25 deletions(-)

diff --git a/meson.build b/meson.build
index df7c34b076..3744923aa7 100644
--- a/meson.build
+++ b/meson.build
@@ -3172,14 +3172,23 @@ foreach d, list : target_modules
 endforeach
 
 if enable_modules
-  modinfo_src = custom_target('modinfo.c',
-  output: 'modinfo.c',
-  input: modinfo_files,
-  command: [modinfo_generate, '@INPUT@'],
-  capture: true)
-  modinfo_lib = static_library('modinfo', modinfo_src)
-  modinfo_dep = declare_dependency(link_whole: modinfo_lib)
-  softmmu_ss.add(modinfo_dep)
+  foreach target : target_dirs
+if target.endswith('-softmmu')
+  config_target = config_target_mak[target]
+  config_devices_mak = target + '-config-devices.mak'
+  modinfo_src = custom_target('modinfo-' + target + '.c',
+  output: 'modinfo-' + target + '.c',
+  input: modinfo_files,
+  command: [modinfo_generate, '--devices', 
config_devices_mak, '@INPUT@'],
+  capture: true)
+
+  modinfo_lib = static_library('modinfo-' + target + '.c', modinfo_src)
+  modinfo_dep = declare_dependency(link_with: modinfo_lib)
+
+  arch = config_target['TARGET_NAME'] == 'sparc64' ? 'sparc64' : 
config_target['TARGET_BASE_ARCH']
+  hw_arch[arch].add(modinfo_dep)
+endif
+  endforeach
 endif
 
 nm = find_program('nm')
diff --git a/scripts/modinfo-generate.py b/scripts/modinfo-generate.py
index 689f33c0f2..a0c09edae1 100755
--- a/scripts/modinfo-generate.py
+++ b/scripts/modinfo-generate.py
@@ -32,7 +32,7 @@ def parse_line(line):
 continue
 return (kind, data)
 
-def generate(name, lines):
+def generate(name, lines, core_modules):
 arch = ""
 objs = []
 deps = []
@@ -49,7 +49,13 @@ def generate(name, lines):
 elif kind == 'arch':
 arch = data;
 elif kind == 'kconfig':
-pass # ignore
+# don't add a module which dependency is not enabled
+# in kconfig
+if data.strip() not in core_modules:
+print("/* module {} isn't enabled in Kconfig. */"
+  .format(data.strip()))
+print("/* },{ */")
+return []
 else:
 print("unknown:", kind)
 exit(1)
@@ -60,7 +66,7 @@ def generate(name, lines):
 print_array("objs", objs)
 print_array("deps", deps)
 print_array("opts", opts)
-print("},{");
+print("},{")
 return deps
 
 def print_pre():
@@ -74,26 +80,28 @@ def print_post():
 print("}};")
 
 def main(args):
+if len(args) < 3 or args[0] != '--devices':
+print('Expected: modinfo-generate.py --devices '
+  'config-device.mak [modinfo files]', file=sys.stderr)
+exit(1)
+
+# get all devices enabled in kconfig, from *-config-device.mak
+enabled_core_modules = set()
+with open(args[1]) as file:
+for line in file.readlines():
+config = line.split('=')
+if config[1].rstrip() == 'y':
+enabled_core_modules.add(config[0][7:]) # remove CONFIG_
+
 deps = {}
 print_pre()
-for modinfo in args:
+for modinfo in args[2:]:
 with open(modinfo) as f:
 lines = f.readlines()
 print("/* %s */" % modinfo)
-(basename, ext) = os.path.splitext(modinfo)
-deps[basename] = generate(basename, lines)
+(basename, _) = os.path.splitext(modinfo)
+deps[basename] = generate(basename, lines, enabled_core_modules)
 print_post()
 
-flattened_deps = {flat.strip('" ') for dep in deps.values() for flat in 
dep}
-error = False
-for dep in flattened_deps:
-if dep not in deps.keys():
-print("Dependency {} cannot be satisfied".format(dep),
-  file=sys.stderr)
-error = True
-
-if error:
-exit(1)
-
 if __name__ == "__main__":
 main(sys.argv[1:])





[RESEND PATCH 0/2] modules: Improve modinfo.c support

2022-05-27 Thread Dario Faggioli
Hello,

This is a RESEND of patch series "[PATCH v3 0/2] modules: Improve modinfo.c
support", from Sept 2021.

Message-ID: <20210928204628.20001-1-jzivi...@suse.de>
https://lore.kernel.org/qemu-devel/20210928204628.20001-1-jzivi...@suse.de/

Jose sent it because we were having issues building QEMU in the way we do that
for openSUSE and SUSE Linux Enterprise.

It was, back then, Acked by Gerd (see Message-ID:
20210929050908.3fqf3wwbk6vrt...@sirius.home.kraxel.org), but then never picked
up. Well, since we are still having those building problems without it, I've
rebased and I'm resending it, as agreed with Gerd himself.

"Rebase" was as easy as just reapplying the patches (no offsets, no fuzz). Yet,
I removed the ack, assuming that it needs being re-locked at.

`make check` is happy. The CI, well, it looks fine to me. There's some 'Build'
jobs that are taking too much to complete, and hence causing failures in the
'Test' ones, but that seems unrelated to the patches. I'll try to restart them
in these days, and see if they manage to finish.

 https://gitlab.com/dfaggioli/qemu/-/pipelines/549884208

FWIW, we've also started to use it, as downstream patches, in our packages,
on top of various versions of QEMU.

Let me know if there's anything more or different that I should do.

Thanks and Regards
---
Jose R. Ziviani (2):
  modules: introduces module_kconfig directive
  modules: generates per-target modinfo

 hw/display/qxl.c|  1 +
 hw/display/vhost-user-gpu-pci.c |  1 +
 hw/display/vhost-user-gpu.c |  1 +
 hw/display/vhost-user-vga.c |  1 +
 hw/display/virtio-gpu-base.c|  1 +
 hw/display/virtio-gpu-gl.c  |  1 +
 hw/display/virtio-gpu-pci-gl.c  |  1 +
 hw/display/virtio-gpu-pci.c |  1 +
 hw/display/virtio-gpu.c |  1 +
 hw/display/virtio-vga-gl.c  |  1 +
 hw/display/virtio-vga.c |  1 +
 hw/s390x/virtio-ccw-gpu.c   |  1 +
 hw/usb/ccid-card-emulated.c |  1 +
 hw/usb/ccid-card-passthru.c |  1 +
 hw/usb/host-libusb.c|  1 +
 hw/usb/redirect.c   |  1 +
 include/qemu/module.h   | 10 
 meson.build | 25 +---
 scripts/modinfo-generate.py | 42 -
 19 files changed, 69 insertions(+), 24 deletions(-)
--
Signature




Re: building e2k qemu errors

2022-05-27 Thread Joe Nosay
Will do, thanks

On Fri, May 27, 2022 at 1:42 PM Peter Maydell 
wrote:

> On Fri, 27 May 2022 at 16:16, Joe Nosay  wrote:
> >
> > Does the newest qemu source at github include the e2k cpu?
> > And, what is the exact address?
>
> Please keep emails on the mailing list, not on private email.
>
> thanks
> -- PMM
>


Re: [PATCH v2] linux-user: Adjust child_tidptr on set_tid_address() syscall

2022-05-27 Thread Helge Deller
I think the previous patch was wrong, since we just emulate writing to
child_tidptr. Below is updated RFC patch.

---
[PATCH] linux-user: Adjust child_tidptr on set_tid_address()

Keep track of the new child tidptr given by a set_tid_address() syscall.

Signed-off-by: Helge Deller 

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f65045efe6..9114c611a0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -320,9 +320,6 @@ _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
 #ifdef __NR_exit_group
 _syscall1(int,exit_group,int,error_code)
 #endif
-#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
-_syscall1(int,set_tid_address,int *,tidptr)
-#endif
 #if defined(__NR_futex)
 _syscall6(int,sys_futex,int *,uaddr,int,op,int,val,
   const struct timespec *,timeout,int *,uaddr2,int,val3)
@@ -12200,9 +12197,14 @@ static abi_long do_syscall1(void *cpu_env, int num, 
abi_long arg1,
 }
 #endif

-#if defined(TARGET_NR_set_tid_address) && defined(__NR_set_tid_address)
+#if defined(TARGET_NR_set_tid_address)
 case TARGET_NR_set_tid_address:
-return get_errno(set_tid_address((int *)g2h(cpu, arg1)));
+{
+TaskState *ts = cpu->opaque;
+ts->child_tidptr = arg1;
+/* do not call host set_tid_address() syscall, instead return tid() */
+return get_errno(sys_gettid());
+}
 #endif

 case TARGET_NR_tkill:



[PATCH] ebpf: replace deprecated bpf_program__set_socket_filter

2022-05-27 Thread Haochen Tong
bpf_program__set_ functions have been deprecated since libbpf 0.8.
Replace with the equivalent bpf_program__set_type call to avoid a
deprecation warning.

Signed-off-by: Haochen Tong 
---
 ebpf/ebpf_rss.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ebpf/ebpf_rss.c b/ebpf/ebpf_rss.c
index 118c68da83..cee658c158 100644
--- a/ebpf/ebpf_rss.c
+++ b/ebpf/ebpf_rss.c
@@ -49,7 +49,7 @@ bool ebpf_rss_load(struct EBPFRSSContext *ctx)
 goto error;
 }
 
-bpf_program__set_socket_filter(rss_bpf_ctx->progs.tun_rss_steering_prog);
+bpf_program__set_type(rss_bpf_ctx->progs.tun_rss_steering_prog, 
BPF_PROG_TYPE_SOCKET_FILTER);
 
 if (rss_bpf__load(rss_bpf_ctx)) {
 trace_ebpf_error("eBPF RSS", "can not load RSS program");
-- 
2.36.1




Re: [PATCH 0/2] backend/tpm: Resolve issue with TPM 2 DA lockout

2022-05-27 Thread Stefan Berger




On 5/27/22 15:24, Marc-André Lureau wrote:

Hi

On Fri, May 27, 2022 at 7:36 PM Stefan Berger  wrote:


This series of patches resolves an issue with a TPM 2's dictionary attack
lockout logic being triggered upon well-timed VM resets. Normally, the OS
TPM driver sends a TPM2_Shutdown to the TPM 2 upon reboot and before a VM
is reset. However, the OS driver cannot do this when the user resets a VM.
In this case QEMU must send the command because otherwise several well-
timed VM resets will trigger the TPM 2's dictionary attack (DA) logic and
it will then refuse to do certain key-related operations until the DA
logic has timed out.


How does real hardware deal with that situation? Shouldn't this
"shutdown"/reset logic be implemented on swtpm side instead, when
CMD_INIT is received? (when the VM is restarted)
I don't know what real hardware can actually do when the machine is 
reset, presumably via some reset line, or the power is removed. Probably 
it has no way to react to this.


Typically the OS driver has to send the command and since it cannot do 
this I would defer it to the TPM emulator reset handler code, so the 
next layer down.








Regards,
   Stefan

Stefan Berger (2):
   backends/tpm: Record the last command sent to the TPM
   backends/tpm: Send TPM2_Shutdown upon VM reset

  backends/tpm/tpm_emulator.c | 44 +
  backends/tpm/tpm_int.h  |  3 +++
  backends/tpm/tpm_util.c |  9 
  backends/tpm/trace-events   |  1 +
  include/sysemu/tpm_util.h   |  3 +++
  5 files changed, 60 insertions(+)

--
2.35.3







Re: [PATCH 0/2] backend/tpm: Resolve issue with TPM 2 DA lockout

2022-05-27 Thread Marc-André Lureau
Hi

On Fri, May 27, 2022 at 7:36 PM Stefan Berger  wrote:
>
> This series of patches resolves an issue with a TPM 2's dictionary attack
> lockout logic being triggered upon well-timed VM resets. Normally, the OS
> TPM driver sends a TPM2_Shutdown to the TPM 2 upon reboot and before a VM
> is reset. However, the OS driver cannot do this when the user resets a VM.
> In this case QEMU must send the command because otherwise several well-
> timed VM resets will trigger the TPM 2's dictionary attack (DA) logic and
> it will then refuse to do certain key-related operations until the DA
> logic has timed out.

How does real hardware deal with that situation? Shouldn't this
"shutdown"/reset logic be implemented on swtpm side instead, when
CMD_INIT is received? (when the VM is restarted)

>
> Regards,
>   Stefan
>
> Stefan Berger (2):
>   backends/tpm: Record the last command sent to the TPM
>   backends/tpm: Send TPM2_Shutdown upon VM reset
>
>  backends/tpm/tpm_emulator.c | 44 +
>  backends/tpm/tpm_int.h  |  3 +++
>  backends/tpm/tpm_util.c |  9 
>  backends/tpm/trace-events   |  1 +
>  include/sysemu/tpm_util.h   |  3 +++
>  5 files changed, 60 insertions(+)
>
> --
> 2.35.3
>




CTU CAN FD IP core SocketCAN driver - success with mainine Linux kernel and mainline QEMU builds

2022-05-27 Thread Pavel Pisa
Hello everybody,

I want to report successful build and test of the CTU CAN FD driver
from actual Linux kernel mainline GIT on actual QEMU build from
mainline git. Test on HW from net-next has been repeatedly
run by Matej Vasilevski during his timestamping patches work.

Thanks to all who helped, namely Ondrej Ille for his investment
in the project and rewrite of registers generator to provide
headers files acceptable for mainline, Marc Kleine-Budde
for review, integration and cleanup and together with
Pavel Machek to provide valuable feeback what is not acceptable.

I hope that we will be ready with with timestamping patches
cleanup for 5.20 merge windows as well as with support
for HDL sources parameterizable number of Tx buffres.

In the long term, I consider to use mechanism of software
virtual FIFO to implement multiqueue Tx support which
is in the fact needed in all serious CAN applications
to prevent bus level priority inversion.

We plan to visit and present on the Embedded World
in Nuremberg, so I would be happy to meet you there.
I hope that Carsten Emde and OSADL will pass over
information where we are available.

Program for Tuesday afternoon is given already
Talk QtRvSim – RISC-V Simulator for Computer Architectures
Classes, June 21, 2022 Session 10.3 – System-on-Chip (SoC)
Design RISC-V Development (16:00 - 16:30) at Embedded World
Conference. Our toy there https://github.com/cvut/qtrvsim

Best wishes,

Pavel Pisa
phone:  +420 603531357
e-mail: p...@cmp.felk.cvut.cz
Department of Control Engineering FEE CVUT
Karlovo namesti 13, 121 35, Prague 2
university: http://control.fel.cvut.cz/
personal:   http://cmp.felk.cvut.cz/~pisa
projects:   https://www.openhub.net/accounts/ppisa
CAN related:http://canbus.pages.fel.cvut.cz/
Open Technologies Research Education and Exchange Services
https://gitlab.fel.cvut.cz/otrees/org/-/wikis/home




[PATCH 104/114] target/arm: Use TRANS_FEAT for DO_FP_IMM

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 30 ++
 1 file changed, 14 insertions(+), 16 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index b47d5d7f21..e2ae387d62 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3924,22 +3924,20 @@ static bool do_fp_imm(DisasContext *s, arg_rpri_esz *a, 
uint64_t imm,
 return true;
 }
 
-#define DO_FP_IMM(NAME, name, const0, const1) \
-static bool trans_##NAME##_zpzi(DisasContext *s, arg_rpri_esz *a) \
-{ \
-static gen_helper_sve_fp2scalar * const fns[4] = {\
-NULL, gen_helper_sve_##name##_h,  \
-gen_helper_sve_##name##_s,\
-gen_helper_sve_##name##_d \
-};\
-static uint64_t const val[4][2] = {   \
-{ -1, -1 },   \
-{ float16_##const0, float16_##const1 },   \
-{ float32_##const0, float32_##const1 },   \
-{ float64_##const0, float64_##const1 },   \
-};\
-return do_fp_imm(s, a, val[a->esz][a->imm], fns[a->esz]); \
-}
+#define DO_FP_IMM(NAME, name, const0, const1)   \
+static gen_helper_sve_fp2scalar * const name##_fns[4] = {   \
+NULL, gen_helper_sve_##name##_h,\
+gen_helper_sve_##name##_s,  \
+gen_helper_sve_##name##_d   \
+};  \
+static uint64_t const name##_const[4][2] = {\
+{ -1, -1 }, \
+{ float16_##const0, float16_##const1 }, \
+{ float32_##const0, float32_##const1 }, \
+{ float64_##const0, float64_##const1 }, \
+};  \
+TRANS_FEAT(NAME##_zpzi, aa64_sve, do_fp_imm, a, \
+   name##_const[a->esz][a->imm], name##_fns[a->esz])
 
 DO_FP_IMM(FADD, fadds, half, one)
 DO_FP_IMM(FSUB, fsubs, half, one)
-- 
2.34.1




[PATCH 111/114] target/arm: Use TRANS_FEAT for do_FMLAL_zzzw

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 26 --
 1 file changed, 4 insertions(+), 22 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 44af7530b6..57bff0d345 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -7149,33 +7149,15 @@ TRANS_FEAT(FLOGB, aa64_sve2, gen_gvec_fpst_arg_zpz, 
flogb_fns[a->esz],
 
 static bool do_FMLAL_zzzw(DisasContext *s, arg__esz *a, bool sub, bool sel)
 {
-if (!dc_isar_feature(aa64_sve2, s)) {
-return false;
-}
 return gen_gvec_ptr_(s, gen_helper_sve2_fmlal_zzzw_s,
  a->rd, a->rn, a->rm, a->ra,
  (sel << 1) | sub, cpu_env);
 }
 
-static bool trans_FMLALB_zzzw(DisasContext *s, arg__esz *a)
-{
-return do_FMLAL_zzzw(s, a, false, false);
-}
-
-static bool trans_FMLALT_zzzw(DisasContext *s, arg__esz *a)
-{
-return do_FMLAL_zzzw(s, a, false, true);
-}
-
-static bool trans_FMLSLB_zzzw(DisasContext *s, arg__esz *a)
-{
-return do_FMLAL_zzzw(s, a, true, false);
-}
-
-static bool trans_FMLSLT_zzzw(DisasContext *s, arg__esz *a)
-{
-return do_FMLAL_zzzw(s, a, true, true);
-}
+TRANS_FEAT(FMLALB_zzzw, aa64_sve2, do_FMLAL_zzzw, a, false, false)
+TRANS_FEAT(FMLALT_zzzw, aa64_sve2, do_FMLAL_zzzw, a, false, true)
+TRANS_FEAT(FMLSLB_zzzw, aa64_sve2, do_FMLAL_zzzw, a, true, false)
+TRANS_FEAT(FMLSLT_zzzw, aa64_sve2, do_FMLAL_zzzw, a, true, true)
 
 static bool do_FMLAL_zzxw(DisasContext *s, arg_rrxr_esz *a, bool sub, bool sel)
 {
-- 
2.34.1




Re: [PATCH] ppc: fix boot with sam460ex

2022-05-27 Thread BALATON Zoltan

On Fri, 27 May 2022, Michael S. Tsirkin wrote:

On Fri, May 27, 2022 at 12:46:57PM +0200, BALATON Zoltan wrote:

Hello,

Some changes to commit message (patch is OK).


Want to write the commit message for me then?


How about:

Recent changes to pcie_host corrected size of its internal region to match 
what it expects: only the low 28 bits are ever decoded. Previous code just 
ignored bit 29 (if size was 1 << 29) in the address which does not make 
much sense.  We are now asserting on size > 1 << 28 instead, but PPC 4xx 
actually allows guest to configure different sizes, and some firmwares 
seem to set it to 1 << 29.


This caused e.g. qemu-system-ppc -M sam460ex to exit with an assert when 
the guest writes a value to CFGMSK register when trying to map config 
space. This is done in the board firmware in ppc4xx_init_pcie_port() in 
roms/u-boot-sam460ex/arch/powerpc/cpu/ppc4xx/4xx_pcie.c


It's not clear what the proper fix should be but for now let's force the 
size to 256MB, so anything outside the expected address range is ignored.



Fixes: commit 1f1a7b2269 ("include/hw/pci/pcie_host: Correct 
PCIE_MMCFG_SIZE_MAX")
Reviewed-by: BALATON Zoltan 
Tested-by: BALATON Zoltan 
Signed-off-by: Michael S. Tsirkin 
---

Affected system is orphan so I guess I will merge the patch unless
someone objects.

hw/ppc/ppc440_uc.c | 8 
1 file changed, 8 insertions(+)

diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c
index 993e3ba955..a1ecf6dd1c 100644
--- a/hw/ppc/ppc440_uc.c
+++ b/hw/ppc/ppc440_uc.c
@@ -1180,6 +1180,14 @@ static void dcr_write_pcie(void *opaque, int dcrn, 
uint32_t val)
case PEGPL_CFGMSK:
s->cfg_mask = val;
size = ~(val & 0xfffe) + 1;
+/*
+ * Firmware sets this register to E001. Why we are not sure,
+ * but the current guess is anything above PCIE_MMCFG_SIZE_MAX is
+ * ignored.
+ */
+if (size > PCIE_MMCFG_SIZE_MAX) {
+size = PCIE_MMCFG_SIZE_MAX;
+}
pcie_host_mmcfg_update(PCIE_HOST_BRIDGE(s), val & 1, s->cfg_base, size);
break;
case PEGPL_MSGBAH:








[PATCH 113/114] target/arm: Add sve feature check for remaining trans_* functions

2022-05-27 Thread Richard Henderson
For all remaining trans_* functions that do not already
have a check, add one now.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 177 ++---
 1 file changed, 163 insertions(+), 14 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 5fb66547ec..836511d719 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1311,6 +1311,9 @@ TRANS_FEAT(INDEX_rr, aa64_sve, do_index, a->esz, a->rd,
 
 static bool trans_ADDVL(DisasContext *s, arg_ADDVL *a)
 {
+if (!dc_isar_feature(aa64_sve, s)) {
+return false;
+}
 if (sve_access_check(s)) {
 TCGv_i64 rd = cpu_reg_sp(s, a->rd);
 TCGv_i64 rn = cpu_reg_sp(s, a->rn);
@@ -1321,6 +1324,9 @@ static bool trans_ADDVL(DisasContext *s, arg_ADDVL *a)
 
 static bool trans_ADDPL(DisasContext *s, arg_ADDPL *a)
 {
+if (!dc_isar_feature(aa64_sve, s)) {
+return false;
+}
 if (sve_access_check(s)) {
 TCGv_i64 rd = cpu_reg_sp(s, a->rd);
 TCGv_i64 rn = cpu_reg_sp(s, a->rn);
@@ -1331,6 +1337,9 @@ static bool trans_ADDPL(DisasContext *s, arg_ADDPL *a)
 
 static bool trans_RDVL(DisasContext *s, arg_RDVL *a)
 {
+if (!dc_isar_feature(aa64_sve, s)) {
+return false;
+}
 if (sve_access_check(s)) {
 TCGv_i64 reg = cpu_reg(s, a->rd);
 tcg_gen_movi_i64(reg, a->imm * vec_full_reg_size(s));
@@ -1451,6 +1460,9 @@ static bool trans_AND_(DisasContext *s, arg_rprr_s *a)
 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
 };
 
+if (!dc_isar_feature(aa64_sve, s)) {
+return false;
+}
 if (!a->s) {
 if (a->rn == a->rm) {
 if (a->pg == a->rn) {
@@ -1486,6 +1498,9 @@ static bool trans_BIC_(DisasContext *s, arg_rprr_s *a)
 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
 };
 
+if (!dc_isar_feature(aa64_sve, s)) {
+return false;
+}
 if (!a->s && a->pg == a->rn) {
 return gen_gvec_fn_ppp(s, tcg_gen_gvec_andc, a->rd, a->rn, a->rm);
 }
@@ -1514,6 +1529,9 @@ static bool trans_EOR_(DisasContext *s, arg_rprr_s *a)
 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
 };
 
+if (!dc_isar_feature(aa64_sve, s)) {
+return false;
+}
 /* Alias NOT (predicate) is EOR Pd.B, Pg/Z, Pn.B, Pg.B */
 if (!a->s && a->pg == a->rm) {
 return gen_gvec_fn_ppp(s, tcg_gen_gvec_andc, a->rd, a->pg, a->rn);
@@ -1523,7 +1541,7 @@ static bool trans_EOR_(DisasContext *s, arg_rprr_s *a)
 
 static bool trans_SEL_(DisasContext *s, arg_rprr_s *a)
 {
-if (a->s) {
+if (a->s || !dc_isar_feature(aa64_sve, s)) {
 return false;
 }
 if (sve_access_check(s)) {
@@ -1558,6 +1576,9 @@ static bool trans_ORR_(DisasContext *s, arg_rprr_s *a)
 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
 };
 
+if (!dc_isar_feature(aa64_sve, s)) {
+return false;
+}
 if (!a->s && a->pg == a->rn && a->rn == a->rm) {
 return do_mov_p(s, a->rd, a->rn);
 }
@@ -1585,6 +1606,10 @@ static bool trans_ORN_(DisasContext *s, arg_rprr_s 
*a)
 .fno = gen_helper_sve_orn_,
 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
 };
+
+if (!dc_isar_feature(aa64_sve, s)) {
+return false;
+}
 return do__flags(s, a, );
 }
 
@@ -1609,6 +1634,10 @@ static bool trans_NOR_(DisasContext *s, arg_rprr_s 
*a)
 .fno = gen_helper_sve_nor_,
 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
 };
+
+if (!dc_isar_feature(aa64_sve, s)) {
+return false;
+}
 return do__flags(s, a, );
 }
 
@@ -1633,6 +1662,10 @@ static bool trans_NAND_(DisasContext *s, arg_rprr_s 
*a)
 .fno = gen_helper_sve_nand_,
 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
 };
+
+if (!dc_isar_feature(aa64_sve, s)) {
+return false;
+}
 return do__flags(s, a, );
 }
 
@@ -1642,6 +1675,9 @@ static bool trans_NAND_(DisasContext *s, arg_rprr_s 
*a)
 
 static bool trans_PTEST(DisasContext *s, arg_PTEST *a)
 {
+if (!dc_isar_feature(aa64_sve, s)) {
+return false;
+}
 if (sve_access_check(s)) {
 int nofs = pred_full_reg_offset(s, a->rn);
 int gofs = pred_full_reg_offset(s, a->pg);
@@ -1998,6 +2034,9 @@ static void do_sat_addsub_vec(DisasContext *s, int esz, 
int rd, int rn,
 
 static bool trans_CNT_r(DisasContext *s, arg_CNT_r *a)
 {
+if (!dc_isar_feature(aa64_sve, s)) {
+return false;
+}
 if (sve_access_check(s)) {
 unsigned fullsz = vec_full_reg_size(s);
 unsigned numelem = decode_pred_count(fullsz, a->pat, a->esz);
@@ -2008,6 +2047,9 @@ static bool trans_CNT_r(DisasContext *s, arg_CNT_r *a)
 
 static bool trans_INCDEC_r(DisasContext *s, arg_incdec_cnt *a)
 {
+if (!dc_isar_feature(aa64_sve, s)) {
+return false;
+}
 if (sve_access_check(s)) {
 unsigned fullsz = vec_full_reg_size(s);
 unsigned numelem = 

[PATCH 102/114] target/arm: Use TRANS_FEAT for gen_gvec_fpst_zzzzp

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 42 +-
 1 file changed, 14 insertions(+), 28 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 8f50956d3b..75854a7c6c 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3998,22 +3998,14 @@ TRANS_FEAT(FCADD, aa64_sve, gen_gvec_fpst_zzzp, 
fcadd_fns[a->esz],
a->rd, a->rn, a->rm, a->pg, a->rot,
a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR)
 
-static bool do_fmla(DisasContext *s, arg_rprrr_esz *a,
-gen_helper_gvec_5_ptr *fn)
-{
-return gen_gvec_fpst_p(s, fn, a->rd, a->rn, a->rm, a->ra, a->pg, 0,
-   a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
-}
-
 #define DO_FMLA(NAME, name) \
-static bool trans_##NAME(DisasContext *s, arg_rprrr_esz *a)  \
-{\
-static gen_helper_gvec_5_ptr * const fns[4] = {  \
-NULL, gen_helper_sve_##name##_h, \
-gen_helper_sve_##name##_s, gen_helper_sve_##name##_d \
-};   \
-return do_fmla(s, a, fns[a->esz]);   \
-}
+static gen_helper_gvec_5_ptr * const name##_fns[4] = {  \
+NULL, gen_helper_sve_##name##_h,\
+gen_helper_sve_##name##_s, gen_helper_sve_##name##_d\
+};  \
+TRANS_FEAT(NAME, aa64_sve, gen_gvec_fpst_p, name##_fns[a->esz], \
+   a->rd, a->rn, a->rm, a->ra, a->pg, 0,\
+   a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR)
 
 DO_FMLA(FMLA_zpzzz, fmla_zpzzz)
 DO_FMLA(FMLS_zpzzz, fmls_zpzzz)
@@ -4022,19 +4014,13 @@ DO_FMLA(FNMLS_zpzzz, fnmls_zpzzz)
 
 #undef DO_FMLA
 
-static bool trans_FCMLA_zpzzz(DisasContext *s, arg_FCMLA_zpzzz *a)
-{
-static gen_helper_gvec_5_ptr * const fns[4] = {
-NULL,
-gen_helper_sve_fcmla_zpzzz_h,
-gen_helper_sve_fcmla_zpzzz_s,
-gen_helper_sve_fcmla_zpzzz_d,
-};
-
-return gen_gvec_fpst_p(s, fns[a->esz], a->rd, a->rn, a->rm,
-   a->ra, a->pg, a->rot,
-   a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
-}
+static gen_helper_gvec_5_ptr * const fcmla_fns[4] = {
+NULL, gen_helper_sve_fcmla_zpzzz_h,
+gen_helper_sve_fcmla_zpzzz_s, gen_helper_sve_fcmla_zpzzz_d,
+};
+TRANS_FEAT(FCMLA_zpzzz, aa64_sve, gen_gvec_fpst_p, fcmla_fns[a->esz],
+   a->rd, a->rn, a->rm, a->ra, a->pg, a->rot,
+   a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR)
 
 static bool trans_FCMLA_zzxz(DisasContext *s, arg_FCMLA_zzxz *a)
 {
-- 
2.34.1




[PATCH 110/114] target/arm: Use TRANS_FEAT for do_shr_narrow

2022-05-27 Thread Richard Henderson
Rename from do_sve2_shr_narrow and hoist the sve2
check into the TRANS_FEAT macro.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 470 +
 1 file changed, 211 insertions(+), 259 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 0fb118f6ef..44af7530b6 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -6552,10 +6552,10 @@ static const GVecGen2 sqxtunt_ops[3] = {
 };
 TRANS_FEAT(SQXTUNT, aa64_sve2, do_narrow_extract, a, sqxtunt_ops)
 
-static bool do_sve2_shr_narrow(DisasContext *s, arg_rri_esz *a,
-   const GVecGen2i ops[3])
+static bool do_shr_narrow(DisasContext *s, arg_rri_esz *a,
+  const GVecGen2i ops[3])
 {
-if (a->esz < 0 || a->esz > MO_32 || !dc_isar_feature(aa64_sve2, s)) {
+if (a->esz < 0 || a->esz > MO_32) {
 return false;
 }
 assert(a->imm > 0 && a->imm <= (8 << a->esz));
@@ -6604,28 +6604,25 @@ static void gen_shrnb_vec(unsigned vece, TCGv_vec d, 
TCGv_vec n, int64_t shr)
 tcg_temp_free_vec(t);
 }
 
-static bool trans_SHRNB(DisasContext *s, arg_rri_esz *a)
-{
-static const TCGOpcode vec_list[] = { INDEX_op_shri_vec, 0 };
-static const GVecGen2i ops[3] = {
-{ .fni8 = gen_shrnb16_i64,
-  .fniv = gen_shrnb_vec,
-  .opt_opc = vec_list,
-  .fno = gen_helper_sve2_shrnb_h,
-  .vece = MO_16 },
-{ .fni8 = gen_shrnb32_i64,
-  .fniv = gen_shrnb_vec,
-  .opt_opc = vec_list,
-  .fno = gen_helper_sve2_shrnb_s,
-  .vece = MO_32 },
-{ .fni8 = gen_shrnb64_i64,
-  .fniv = gen_shrnb_vec,
-  .opt_opc = vec_list,
-  .fno = gen_helper_sve2_shrnb_d,
-  .vece = MO_64 },
-};
-return do_sve2_shr_narrow(s, a, ops);
-}
+static const TCGOpcode shrnb_vec_list[] = { INDEX_op_shri_vec, 0 };
+static const GVecGen2i shrnb_ops[3] = {
+{ .fni8 = gen_shrnb16_i64,
+  .fniv = gen_shrnb_vec,
+  .opt_opc = shrnb_vec_list,
+  .fno = gen_helper_sve2_shrnb_h,
+  .vece = MO_16 },
+{ .fni8 = gen_shrnb32_i64,
+  .fniv = gen_shrnb_vec,
+  .opt_opc = shrnb_vec_list,
+  .fno = gen_helper_sve2_shrnb_s,
+  .vece = MO_32 },
+{ .fni8 = gen_shrnb64_i64,
+  .fniv = gen_shrnb_vec,
+  .opt_opc = shrnb_vec_list,
+  .fno = gen_helper_sve2_shrnb_d,
+  .vece = MO_64 },
+};
+TRANS_FEAT(SHRNB, aa64_sve2, do_shr_narrow, a, shrnb_ops)
 
 static void gen_shrnt_i64(unsigned vece, TCGv_i64 d, TCGv_i64 n, int shr)
 {
@@ -,51 +6663,42 @@ static void gen_shrnt_vec(unsigned vece, TCGv_vec d, 
TCGv_vec n, int64_t shr)
 tcg_temp_free_vec(t);
 }
 
-static bool trans_SHRNT(DisasContext *s, arg_rri_esz *a)
-{
-static const TCGOpcode vec_list[] = { INDEX_op_shli_vec, 0 };
-static const GVecGen2i ops[3] = {
-{ .fni8 = gen_shrnt16_i64,
-  .fniv = gen_shrnt_vec,
-  .opt_opc = vec_list,
-  .load_dest = true,
-  .fno = gen_helper_sve2_shrnt_h,
-  .vece = MO_16 },
-{ .fni8 = gen_shrnt32_i64,
-  .fniv = gen_shrnt_vec,
-  .opt_opc = vec_list,
-  .load_dest = true,
-  .fno = gen_helper_sve2_shrnt_s,
-  .vece = MO_32 },
-{ .fni8 = gen_shrnt64_i64,
-  .fniv = gen_shrnt_vec,
-  .opt_opc = vec_list,
-  .load_dest = true,
-  .fno = gen_helper_sve2_shrnt_d,
-  .vece = MO_64 },
-};
-return do_sve2_shr_narrow(s, a, ops);
-}
+static const TCGOpcode shrnt_vec_list[] = { INDEX_op_shli_vec, 0 };
+static const GVecGen2i shrnt_ops[3] = {
+{ .fni8 = gen_shrnt16_i64,
+  .fniv = gen_shrnt_vec,
+  .opt_opc = shrnt_vec_list,
+  .load_dest = true,
+  .fno = gen_helper_sve2_shrnt_h,
+  .vece = MO_16 },
+{ .fni8 = gen_shrnt32_i64,
+  .fniv = gen_shrnt_vec,
+  .opt_opc = shrnt_vec_list,
+  .load_dest = true,
+  .fno = gen_helper_sve2_shrnt_s,
+  .vece = MO_32 },
+{ .fni8 = gen_shrnt64_i64,
+  .fniv = gen_shrnt_vec,
+  .opt_opc = shrnt_vec_list,
+  .load_dest = true,
+  .fno = gen_helper_sve2_shrnt_d,
+  .vece = MO_64 },
+};
+TRANS_FEAT(SHRNT, aa64_sve2, do_shr_narrow, a, shrnt_ops)
 
-static bool trans_RSHRNB(DisasContext *s, arg_rri_esz *a)
-{
-static const GVecGen2i ops[3] = {
-{ .fno = gen_helper_sve2_rshrnb_h },
-{ .fno = gen_helper_sve2_rshrnb_s },
-{ .fno = gen_helper_sve2_rshrnb_d },
-};
-return do_sve2_shr_narrow(s, a, ops);
-}
+static const GVecGen2i rshrnb_ops[3] = {
+{ .fno = gen_helper_sve2_rshrnb_h },
+{ .fno = gen_helper_sve2_rshrnb_s },
+{ .fno = gen_helper_sve2_rshrnb_d },
+};
+TRANS_FEAT(RSHRNB, aa64_sve2, do_shr_narrow, a, rshrnb_ops)
 
-static bool trans_RSHRNT(DisasContext *s, arg_rri_esz *a)
-{
-static const GVecGen2i ops[3] = {
-{ .fno = gen_helper_sve2_rshrnt_h },
-{ .fno = 

[PATCH 112/114] target/arm: Use TRANS_FEAT for do_FMLAL_zzxw

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 26 --
 1 file changed, 4 insertions(+), 22 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 57bff0d345..5fb66547ec 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -7161,33 +7161,15 @@ TRANS_FEAT(FMLSLT_zzzw, aa64_sve2, do_FMLAL_zzzw, a, 
true, true)
 
 static bool do_FMLAL_zzxw(DisasContext *s, arg_rrxr_esz *a, bool sub, bool sel)
 {
-if (!dc_isar_feature(aa64_sve2, s)) {
-return false;
-}
 return gen_gvec_ptr_(s, gen_helper_sve2_fmlal_zzxw_s,
  a->rd, a->rn, a->rm, a->ra,
  (a->index << 2) | (sel << 1) | sub, cpu_env);
 }
 
-static bool trans_FMLALB_zzxw(DisasContext *s, arg_rrxr_esz *a)
-{
-return do_FMLAL_zzxw(s, a, false, false);
-}
-
-static bool trans_FMLALT_zzxw(DisasContext *s, arg_rrxr_esz *a)
-{
-return do_FMLAL_zzxw(s, a, false, true);
-}
-
-static bool trans_FMLSLB_zzxw(DisasContext *s, arg_rrxr_esz *a)
-{
-return do_FMLAL_zzxw(s, a, true, false);
-}
-
-static bool trans_FMLSLT_zzxw(DisasContext *s, arg_rrxr_esz *a)
-{
-return do_FMLAL_zzxw(s, a, true, true);
-}
+TRANS_FEAT(FMLALB_zzxw, aa64_sve2, do_FMLAL_zzxw, a, false, false)
+TRANS_FEAT(FMLALT_zzxw, aa64_sve2, do_FMLAL_zzxw, a, false, true)
+TRANS_FEAT(FMLSLB_zzxw, aa64_sve2, do_FMLAL_zzxw, a, true, false)
+TRANS_FEAT(FMLSLT_zzxw, aa64_sve2, do_FMLAL_zzxw, a, true, true)
 
 TRANS_FEAT(SMMLA, aa64_sve_i8mm, gen_gvec_ool_arg_,
gen_helper_gvec_smmla_b, a, 0)
-- 
2.34.1




[PATCH 100/114] target/arm: Use TRANS_FEAT for FCADD

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 30 +++---
 1 file changed, 7 insertions(+), 23 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 1108494919..e323b2d6d5 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3966,29 +3966,13 @@ DO_FPCMP(FACGT, facgt)
 
 #undef DO_FPCMP
 
-static bool trans_FCADD(DisasContext *s, arg_FCADD *a)
-{
-static gen_helper_gvec_4_ptr * const fns[3] = {
-gen_helper_sve_fcadd_h,
-gen_helper_sve_fcadd_s,
-gen_helper_sve_fcadd_d
-};
-
-if (a->esz == 0) {
-return false;
-}
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : 
FPST_FPCR);
-tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   pred_full_reg_offset(s, a->pg),
-   status, vsz, vsz, a->rot, fns[a->esz - 1]);
-tcg_temp_free_ptr(status);
-}
-return true;
-}
+static gen_helper_gvec_4_ptr * const fcadd_fns[] = {
+NULL,   gen_helper_sve_fcadd_h,
+gen_helper_sve_fcadd_s, gen_helper_sve_fcadd_d,
+};
+TRANS_FEAT(FCADD, aa64_sve, gen_gvec_fpst_zzzp, fcadd_fns[a->esz],
+   a->rd, a->rn, a->rm, a->pg, a->rot,
+   a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR)
 
 static bool do_fmla(DisasContext *s, arg_rprrr_esz *a,
 gen_helper_gvec_5_ptr *fn)
-- 
2.34.1




[PATCH 109/114] target/arm: Use TRANS_FEAT for do_shll_tb

2022-05-27 Thread Richard Henderson
Rename from do_sve2_shll_tb and hoist the sve2
check into the TRANS_FEAT macro.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 102 -
 1 file changed, 45 insertions(+), 57 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 8e7f8308c7..0fb118f6ef 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -6194,46 +6194,11 @@ static void gen_ushll_vec(unsigned vece, TCGv_vec d, 
TCGv_vec n, int64_t imm)
 }
 }
 
-static bool do_sve2_shll_tb(DisasContext *s, arg_rri_esz *a,
-bool sel, bool uns)
+static bool do_shll_tb(DisasContext *s, arg_rri_esz *a,
+   const GVecGen2i ops[3], bool sel)
 {
-static const TCGOpcode sshll_list[] = {
-INDEX_op_shli_vec, INDEX_op_sari_vec, 0
-};
-static const TCGOpcode ushll_list[] = {
-INDEX_op_shli_vec, INDEX_op_shri_vec, 0
-};
-static const GVecGen2i ops[2][3] = {
-{ { .fniv = gen_sshll_vec,
-.opt_opc = sshll_list,
-.fno = gen_helper_sve2_sshll_h,
-.vece = MO_16 },
-  { .fniv = gen_sshll_vec,
-.opt_opc = sshll_list,
-.fno = gen_helper_sve2_sshll_s,
-.vece = MO_32 },
-  { .fniv = gen_sshll_vec,
-.opt_opc = sshll_list,
-.fno = gen_helper_sve2_sshll_d,
-.vece = MO_64 } },
-{ { .fni8 = gen_ushll16_i64,
-.fniv = gen_ushll_vec,
-.opt_opc = ushll_list,
-.fno = gen_helper_sve2_ushll_h,
-.vece = MO_16 },
-  { .fni8 = gen_ushll32_i64,
-.fniv = gen_ushll_vec,
-.opt_opc = ushll_list,
-.fno = gen_helper_sve2_ushll_s,
-.vece = MO_32 },
-  { .fni8 = gen_ushll64_i64,
-.fniv = gen_ushll_vec,
-.opt_opc = ushll_list,
-.fno = gen_helper_sve2_ushll_d,
-.vece = MO_64 } },
-};
 
-if (a->esz < 0 || a->esz > 2 || !dc_isar_feature(aa64_sve2, s)) {
+if (a->esz < 0 || a->esz > 2) {
 return false;
 }
 if (sve_access_check(s)) {
@@ -6241,30 +6206,53 @@ static bool do_sve2_shll_tb(DisasContext *s, 
arg_rri_esz *a,
 tcg_gen_gvec_2i(vec_full_reg_offset(s, a->rd),
 vec_full_reg_offset(s, a->rn),
 vsz, vsz, (a->imm << 1) | sel,
-[uns][a->esz]);
+[a->esz]);
 }
 return true;
 }
 
-static bool trans_SSHLLB(DisasContext *s, arg_rri_esz *a)
-{
-return do_sve2_shll_tb(s, a, false, false);
-}
+static const TCGOpcode sshll_list[] = {
+INDEX_op_shli_vec, INDEX_op_sari_vec, 0
+};
+static const GVecGen2i sshll_ops[3] = {
+{ .fniv = gen_sshll_vec,
+  .opt_opc = sshll_list,
+  .fno = gen_helper_sve2_sshll_h,
+  .vece = MO_16 },
+{ .fniv = gen_sshll_vec,
+  .opt_opc = sshll_list,
+  .fno = gen_helper_sve2_sshll_s,
+  .vece = MO_32 },
+{ .fniv = gen_sshll_vec,
+  .opt_opc = sshll_list,
+  .fno = gen_helper_sve2_sshll_d,
+  .vece = MO_64 }
+};
+TRANS_FEAT(SSHLLB, aa64_sve2, do_shll_tb, a, sshll_ops, false)
+TRANS_FEAT(SSHLLT, aa64_sve2, do_shll_tb, a, sshll_ops, true)
 
-static bool trans_SSHLLT(DisasContext *s, arg_rri_esz *a)
-{
-return do_sve2_shll_tb(s, a, true, false);
-}
-
-static bool trans_USHLLB(DisasContext *s, arg_rri_esz *a)
-{
-return do_sve2_shll_tb(s, a, false, true);
-}
-
-static bool trans_USHLLT(DisasContext *s, arg_rri_esz *a)
-{
-return do_sve2_shll_tb(s, a, true, true);
-}
+static const TCGOpcode ushll_list[] = {
+INDEX_op_shli_vec, INDEX_op_shri_vec, 0
+};
+static const GVecGen2i ushll_ops[3] = {
+{ .fni8 = gen_ushll16_i64,
+  .fniv = gen_ushll_vec,
+  .opt_opc = ushll_list,
+  .fno = gen_helper_sve2_ushll_h,
+  .vece = MO_16 },
+{ .fni8 = gen_ushll32_i64,
+  .fniv = gen_ushll_vec,
+  .opt_opc = ushll_list,
+  .fno = gen_helper_sve2_ushll_s,
+  .vece = MO_32 },
+{ .fni8 = gen_ushll64_i64,
+  .fniv = gen_ushll_vec,
+  .opt_opc = ushll_list,
+  .fno = gen_helper_sve2_ushll_d,
+  .vece = MO_64 },
+};
+TRANS_FEAT(USHLLB, aa64_sve2, do_shll_tb, a, ushll_ops, false)
+TRANS_FEAT(USHLLT, aa64_sve2, do_shll_tb, a, ushll_ops, true)
 
 static gen_helper_gvec_3 * const bext_fns[4] = {
 gen_helper_sve2_bext_b, gen_helper_sve2_bext_h,
-- 
2.34.1




[PATCH 114/114] target/arm: Remove aa64_sve check from before disas_sve

2022-05-27 Thread Richard Henderson
We now have individual checks on all insns within disas_sve.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-a64.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index f502545307..935e1929bb 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -14772,7 +14772,7 @@ static void aarch64_tr_translate_insn(DisasContextBase 
*dcbase, CPUState *cpu)
 unallocated_encoding(s);
 break;
 case 0x2:
-if (!dc_isar_feature(aa64_sve, s) || !disas_sve(s, insn)) {
+if (!disas_sve(s, insn)) {
 unallocated_encoding(s);
 }
 break;
-- 
2.34.1




[PATCH 099/114] target/arm: Use TRANS_FEAT for gen_gvec_fpst_arg_zpzz

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 68 --
 1 file changed, 22 insertions(+), 46 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index f0f2db351e..1108494919 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3841,29 +3841,24 @@ DO_FP3(FRSQRTS, rsqrts)
  *** SVE Floating Point Arithmetic - Predicated Group
  */
 
-#define DO_FP3(NAME, name) \
-static bool trans_##NAME(DisasContext *s, arg_rprr_esz *a)  \
-{   \
-static gen_helper_gvec_4_ptr * const fns[4] = { \
-NULL, gen_helper_sve_##name##_h,\
-gen_helper_sve_##name##_s, gen_helper_sve_##name##_d\
-};  \
-return gen_gvec_fpst_arg_zpzz(s, fns[a->esz], a);   \
-}
+#define DO_ZPZZ_FP(NAME, FEAT, name) \
+static gen_helper_gvec_4_ptr * const name##_zpzz_fns[4] = { \
+NULL,  gen_helper_##name##_h,   \
+gen_helper_##name##_s, gen_helper_##name##_d\
+};  \
+TRANS_FEAT(NAME, FEAT, gen_gvec_fpst_arg_zpzz, name##_zpzz_fns[a->esz], a)
 
-DO_FP3(FADD_zpzz, fadd)
-DO_FP3(FSUB_zpzz, fsub)
-DO_FP3(FMUL_zpzz, fmul)
-DO_FP3(FMIN_zpzz, fmin)
-DO_FP3(FMAX_zpzz, fmax)
-DO_FP3(FMINNM_zpzz, fminnum)
-DO_FP3(FMAXNM_zpzz, fmaxnum)
-DO_FP3(FABD, fabd)
-DO_FP3(FSCALE, fscalbn)
-DO_FP3(FDIV, fdiv)
-DO_FP3(FMULX, fmulx)
-
-#undef DO_FP3
+DO_ZPZZ_FP(FADD_zpzz, aa64_sve, sve_fadd)
+DO_ZPZZ_FP(FSUB_zpzz, aa64_sve, sve_fsub)
+DO_ZPZZ_FP(FMUL_zpzz, aa64_sve, sve_fmul)
+DO_ZPZZ_FP(FMIN_zpzz, aa64_sve, sve_fmin)
+DO_ZPZZ_FP(FMAX_zpzz, aa64_sve, sve_fmax)
+DO_ZPZZ_FP(FMINNM_zpzz, aa64_sve, sve_fminnum)
+DO_ZPZZ_FP(FMAXNM_zpzz, aa64_sve, sve_fmaxnum)
+DO_ZPZZ_FP(FABD, aa64_sve, sve_fabd)
+DO_ZPZZ_FP(FSCALE, aa64_sve, sve_fscalbn)
+DO_ZPZZ_FP(FDIV, aa64_sve, sve_fdiv)
+DO_ZPZZ_FP(FMULX, aa64_sve, sve_fmulx)
 
 typedef void gen_helper_sve_fp2scalar(TCGv_ptr, TCGv_ptr, TCGv_ptr,
   TCGv_i64, TCGv_ptr, TCGv_i32);
@@ -7125,30 +7120,11 @@ TRANS_FEAT(HISTCNT, aa64_sve2, gen_gvec_ool_arg_zpzz,
 TRANS_FEAT(HISTSEG, aa64_sve2, gen_gvec_ool_arg_zzz,
a->esz == 0 ? gen_helper_sve2_histseg : NULL, a, 0)
 
-static bool do_sve2_zpzz_fp(DisasContext *s, arg_rprr_esz *a,
-gen_helper_gvec_4_ptr *fn)
-{
-if (!dc_isar_feature(aa64_sve2, s)) {
-return false;
-}
-return gen_gvec_fpst_arg_zpzz(s, fn, a);
-}
-
-#define DO_SVE2_ZPZZ_FP(NAME, name) \
-static bool trans_##NAME(DisasContext *s, arg_rprr_esz *a)  \
-{   \
-static gen_helper_gvec_4_ptr * const fns[4] = { \
-NULL,gen_helper_sve2_##name##_zpzz_h,   \
-gen_helper_sve2_##name##_zpzz_s, gen_helper_sve2_##name##_zpzz_d\
-};  \
-return do_sve2_zpzz_fp(s, a, fns[a->esz]);  \
-}
-
-DO_SVE2_ZPZZ_FP(FADDP, faddp)
-DO_SVE2_ZPZZ_FP(FMAXNMP, fmaxnmp)
-DO_SVE2_ZPZZ_FP(FMINNMP, fminnmp)
-DO_SVE2_ZPZZ_FP(FMAXP, fmaxp)
-DO_SVE2_ZPZZ_FP(FMINP, fminp)
+DO_ZPZZ_FP(FADDP, aa64_sve2, sve2_faddp_zpzz)
+DO_ZPZZ_FP(FMAXNMP, aa64_sve2, sve2_fmaxnmp_zpzz)
+DO_ZPZZ_FP(FMINNMP, aa64_sve2, sve2_fminnmp_zpzz)
+DO_ZPZZ_FP(FMAXP, aa64_sve2, sve2_fmaxp_zpzz)
+DO_ZPZZ_FP(FMINP, aa64_sve2, sve2_fminp_zpzz)
 
 /*
  * SVE Integer Multiply-Add (unpredicated)
-- 
2.34.1




[PATCH 106/114] target/arm: Remove assert in trans_FCMLA_zzxz

2022-05-27 Thread Richard Henderson
Since 636ddeb15c0, we do not require rd == ra.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 886cf539a5..436d09b928 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -4027,8 +4027,6 @@ static bool trans_FCMLA_zzxz(DisasContext *s, 
arg_FCMLA_zzxz *a)
 NULL,
 };
 
-tcg_debug_assert(a->rd == a->ra);
-
 return gen_gvec_fpst_(s, fns[a->esz], a->rd, a->rn, a->rm, a->ra,
   a->index * 4 + a->rot,
   a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
-- 
2.34.1




[PATCH 103/114] target/arm: Move null function and sve check into do_fp_imm

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 75854a7c6c..b47d5d7f21 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3911,33 +3911,34 @@ static void do_fp_scalar(DisasContext *s, int zd, int 
zn, int pg, bool is_fp16,
 tcg_temp_free_ptr(t_zd);
 }
 
-static void do_fp_imm(DisasContext *s, arg_rpri_esz *a, uint64_t imm,
+static bool do_fp_imm(DisasContext *s, arg_rpri_esz *a, uint64_t imm,
   gen_helper_sve_fp2scalar *fn)
 {
-do_fp_scalar(s, a->rd, a->rn, a->pg, a->esz == MO_16,
- tcg_constant_i64(imm), fn);
+if (fn == NULL) {
+return false;
+}
+if (sve_access_check(s)) {
+do_fp_scalar(s, a->rd, a->rn, a->pg, a->esz == MO_16,
+ tcg_constant_i64(imm), fn);
+}
+return true;
 }
 
 #define DO_FP_IMM(NAME, name, const0, const1) \
 static bool trans_##NAME##_zpzi(DisasContext *s, arg_rpri_esz *a) \
 { \
-static gen_helper_sve_fp2scalar * const fns[3] = {\
-gen_helper_sve_##name##_h,\
+static gen_helper_sve_fp2scalar * const fns[4] = {\
+NULL, gen_helper_sve_##name##_h,  \
 gen_helper_sve_##name##_s,\
 gen_helper_sve_##name##_d \
 };\
-static uint64_t const val[3][2] = {   \
+static uint64_t const val[4][2] = {   \
+{ -1, -1 },   \
 { float16_##const0, float16_##const1 },   \
 { float32_##const0, float32_##const1 },   \
 { float64_##const0, float64_##const1 },   \
 };\
-if (a->esz == 0) {\
-return false; \
-} \
-if (sve_access_check(s)) {\
-do_fp_imm(s, a, val[a->esz - 1][a->imm], fns[a->esz - 1]);\
-} \
-return true;  \
+return do_fp_imm(s, a, val[a->esz][a->imm], fns[a->esz]); \
 }
 
 DO_FP_IMM(FADD, fadds, half, one)
-- 
2.34.1




[PATCH 108/114] target/arm: Use TRANS_FEAT for do_narrow_extract

2022-05-27 Thread Richard Henderson
Rename from do_sve2_narrow_extract and hoist the sve2
check into the TRANS_FEAT macro.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 223 +
 1 file changed, 102 insertions(+), 121 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 70e8d90ae8..8e7f8308c7 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -6345,11 +6345,10 @@ TRANS_FEAT(SLI, aa64_sve2, gen_gvec_fn_arg_zzi, 
gen_gvec_sli, a)
 TRANS_FEAT(SABA, aa64_sve2, gen_gvec_fn_arg_zzz, gen_gvec_saba, a)
 TRANS_FEAT(UABA, aa64_sve2, gen_gvec_fn_arg_zzz, gen_gvec_uaba, a)
 
-static bool do_sve2_narrow_extract(DisasContext *s, arg_rri_esz *a,
-   const GVecGen2 ops[3])
+static bool do_narrow_extract(DisasContext *s, arg_rri_esz *a,
+  const GVecGen2 ops[3])
 {
-if (a->esz < 0 || a->esz > MO_32 || a->imm != 0 ||
-!dc_isar_feature(aa64_sve2, s)) {
+if (a->esz < 0 || a->esz > MO_32 || a->imm != 0) {
 return false;
 }
 if (sve_access_check(s)) {
@@ -6382,24 +6381,21 @@ static void gen_sqxtnb_vec(unsigned vece, TCGv_vec d, 
TCGv_vec n)
 tcg_temp_free_vec(t);
 }
 
-static bool trans_SQXTNB(DisasContext *s, arg_rri_esz *a)
-{
-static const GVecGen2 ops[3] = {
-{ .fniv = gen_sqxtnb_vec,
-  .opt_opc = sqxtn_list,
-  .fno = gen_helper_sve2_sqxtnb_h,
-  .vece = MO_16 },
-{ .fniv = gen_sqxtnb_vec,
-  .opt_opc = sqxtn_list,
-  .fno = gen_helper_sve2_sqxtnb_s,
-  .vece = MO_32 },
-{ .fniv = gen_sqxtnb_vec,
-  .opt_opc = sqxtn_list,
-  .fno = gen_helper_sve2_sqxtnb_d,
-  .vece = MO_64 },
-};
-return do_sve2_narrow_extract(s, a, ops);
-}
+static const GVecGen2 sqxtnb_ops[3] = {
+{ .fniv = gen_sqxtnb_vec,
+  .opt_opc = sqxtn_list,
+  .fno = gen_helper_sve2_sqxtnb_h,
+  .vece = MO_16 },
+{ .fniv = gen_sqxtnb_vec,
+  .opt_opc = sqxtn_list,
+  .fno = gen_helper_sve2_sqxtnb_s,
+  .vece = MO_32 },
+{ .fniv = gen_sqxtnb_vec,
+  .opt_opc = sqxtn_list,
+  .fno = gen_helper_sve2_sqxtnb_d,
+  .vece = MO_64 },
+};
+TRANS_FEAT(SQXTNB, aa64_sve2, do_narrow_extract, a, sqxtnb_ops)
 
 static void gen_sqxtnt_vec(unsigned vece, TCGv_vec d, TCGv_vec n)
 {
@@ -6419,27 +6415,24 @@ static void gen_sqxtnt_vec(unsigned vece, TCGv_vec d, 
TCGv_vec n)
 tcg_temp_free_vec(t);
 }
 
-static bool trans_SQXTNT(DisasContext *s, arg_rri_esz *a)
-{
-static const GVecGen2 ops[3] = {
-{ .fniv = gen_sqxtnt_vec,
-  .opt_opc = sqxtn_list,
-  .load_dest = true,
-  .fno = gen_helper_sve2_sqxtnt_h,
-  .vece = MO_16 },
-{ .fniv = gen_sqxtnt_vec,
-  .opt_opc = sqxtn_list,
-  .load_dest = true,
-  .fno = gen_helper_sve2_sqxtnt_s,
-  .vece = MO_32 },
-{ .fniv = gen_sqxtnt_vec,
-  .opt_opc = sqxtn_list,
-  .load_dest = true,
-  .fno = gen_helper_sve2_sqxtnt_d,
-  .vece = MO_64 },
-};
-return do_sve2_narrow_extract(s, a, ops);
-}
+static const GVecGen2 sqxtnt_ops[3] = {
+{ .fniv = gen_sqxtnt_vec,
+  .opt_opc = sqxtn_list,
+  .load_dest = true,
+  .fno = gen_helper_sve2_sqxtnt_h,
+  .vece = MO_16 },
+{ .fniv = gen_sqxtnt_vec,
+  .opt_opc = sqxtn_list,
+  .load_dest = true,
+  .fno = gen_helper_sve2_sqxtnt_s,
+  .vece = MO_32 },
+{ .fniv = gen_sqxtnt_vec,
+  .opt_opc = sqxtn_list,
+  .load_dest = true,
+  .fno = gen_helper_sve2_sqxtnt_d,
+  .vece = MO_64 },
+};
+TRANS_FEAT(SQXTNT, aa64_sve2, do_narrow_extract, a, sqxtnt_ops)
 
 static const TCGOpcode uqxtn_list[] = {
 INDEX_op_shli_vec, INDEX_op_umin_vec, 0
@@ -6456,24 +6449,21 @@ static void gen_uqxtnb_vec(unsigned vece, TCGv_vec d, 
TCGv_vec n)
 tcg_temp_free_vec(t);
 }
 
-static bool trans_UQXTNB(DisasContext *s, arg_rri_esz *a)
-{
-static const GVecGen2 ops[3] = {
-{ .fniv = gen_uqxtnb_vec,
-  .opt_opc = uqxtn_list,
-  .fno = gen_helper_sve2_uqxtnb_h,
-  .vece = MO_16 },
-{ .fniv = gen_uqxtnb_vec,
-  .opt_opc = uqxtn_list,
-  .fno = gen_helper_sve2_uqxtnb_s,
-  .vece = MO_32 },
-{ .fniv = gen_uqxtnb_vec,
-  .opt_opc = uqxtn_list,
-  .fno = gen_helper_sve2_uqxtnb_d,
-  .vece = MO_64 },
-};
-return do_sve2_narrow_extract(s, a, ops);
-}
+static const GVecGen2 uqxtnb_ops[3] = {
+{ .fniv = gen_uqxtnb_vec,
+  .opt_opc = uqxtn_list,
+  .fno = gen_helper_sve2_uqxtnb_h,
+  .vece = MO_16 },
+{ .fniv = gen_uqxtnb_vec,
+  .opt_opc = uqxtn_list,
+  .fno = gen_helper_sve2_uqxtnb_s,
+  .vece = MO_32 },
+{ .fniv = gen_uqxtnb_vec,
+  .opt_opc = uqxtn_list,
+  .fno = gen_helper_sve2_uqxtnb_d,
+  .vece = MO_64 },
+};
+TRANS_FEAT(UQXTNB, aa64_sve2, do_narrow_extract, 

[PATCH 097/114] target/arm: Use TRANS_FEAT for do_ppz_fp

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 41 ++
 1 file changed, 19 insertions(+), 22 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 2f96f52293..2ee48186ba 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3696,35 +3696,32 @@ TRANS_FEAT(FRSQRTE, aa64_sve, gen_gvec_fpst_arg_zz, 
frsqrte_fns[a->esz], a, 0)
  *** SVE Floating Point Compare with Zero Group
  */
 
-static void do_ppz_fp(DisasContext *s, arg_rpr_esz *a,
+static bool do_ppz_fp(DisasContext *s, arg_rpr_esz *a,
   gen_helper_gvec_3_ptr *fn)
 {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : 
FPST_FPCR);
+if (fn == NULL) {
+return false;
+}
+if (sve_access_check(s)) {
+unsigned vsz = vec_full_reg_size(s);
+TCGv_ptr status =
+fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
 
-tcg_gen_gvec_3_ptr(pred_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   pred_full_reg_offset(s, a->pg),
-   status, vsz, vsz, 0, fn);
-tcg_temp_free_ptr(status);
+tcg_gen_gvec_3_ptr(pred_full_reg_offset(s, a->rd),
+   vec_full_reg_offset(s, a->rn),
+   pred_full_reg_offset(s, a->pg),
+   status, vsz, vsz, 0, fn);
+tcg_temp_free_ptr(status);
+}
+return true;
 }
 
 #define DO_PPZ(NAME, name) \
-static bool trans_##NAME(DisasContext *s, arg_rpr_esz *a) \
-{ \
-static gen_helper_gvec_3_ptr * const fns[3] = {   \
-gen_helper_sve_##name##_h,\
-gen_helper_sve_##name##_s,\
-gen_helper_sve_##name##_d,\
+static gen_helper_gvec_3_ptr * const name##_fns[] = { \
+NULL,  gen_helper_sve_##name##_h, \
+gen_helper_sve_##name##_s, gen_helper_sve_##name##_d, \
 };\
-if (a->esz == 0) {\
-return false; \
-} \
-if (sve_access_check(s)) {\
-do_ppz_fp(s, a, fns[a->esz - 1]); \
-} \
-return true;  \
-}
+TRANS_FEAT(NAME, aa64_sve, do_ppz_fp, a, name##_fns[a->esz])
 
 DO_PPZ(FCMGE_ppz0, fcmge0)
 DO_PPZ(FCMGT_ppz0, fcmgt0)
-- 
2.34.1




[PATCH 092/114] target/arm: Expand frint_fns for MO_8

2022-05-27 Thread Richard Henderson
Simplify indexing of this array.  This will allow folding
of the illegal esz == 0 into the normal fn == NULL check.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 2f7651249a..99e5d89645 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -4167,7 +4167,8 @@ static bool trans_FCVTZU_dd(DisasContext *s, arg_rpr_esz 
*a)
 return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzu_dd);
 }
 
-static gen_helper_gvec_3_ptr * const frint_fns[3] = {
+static gen_helper_gvec_3_ptr * const frint_fns[] = {
+NULL,
 gen_helper_sve_frint_h,
 gen_helper_sve_frint_s,
 gen_helper_sve_frint_d
@@ -4179,7 +4180,7 @@ static bool trans_FRINTI(DisasContext *s, arg_rpr_esz *a)
 return false;
 }
 return do_zpz_ptr(s, a->rd, a->rn, a->pg, a->esz == MO_16,
-  frint_fns[a->esz - 1]);
+  frint_fns[a->esz]);
 }
 
 static bool trans_FRINTX(DisasContext *s, arg_rpr_esz *a)
@@ -4222,7 +4223,7 @@ static bool trans_FRINTN(DisasContext *s, arg_rpr_esz *a)
 if (a->esz == 0) {
 return false;
 }
-return do_frint_mode(s, a, float_round_nearest_even, frint_fns[a->esz - 
1]);
+return do_frint_mode(s, a, float_round_nearest_even, frint_fns[a->esz]);
 }
 
 static bool trans_FRINTP(DisasContext *s, arg_rpr_esz *a)
@@ -4230,7 +4231,7 @@ static bool trans_FRINTP(DisasContext *s, arg_rpr_esz *a)
 if (a->esz == 0) {
 return false;
 }
-return do_frint_mode(s, a, float_round_up, frint_fns[a->esz - 1]);
+return do_frint_mode(s, a, float_round_up, frint_fns[a->esz]);
 }
 
 static bool trans_FRINTM(DisasContext *s, arg_rpr_esz *a)
@@ -4238,7 +4239,7 @@ static bool trans_FRINTM(DisasContext *s, arg_rpr_esz *a)
 if (a->esz == 0) {
 return false;
 }
-return do_frint_mode(s, a, float_round_down, frint_fns[a->esz - 1]);
+return do_frint_mode(s, a, float_round_down, frint_fns[a->esz]);
 }
 
 static bool trans_FRINTZ(DisasContext *s, arg_rpr_esz *a)
@@ -4246,7 +4247,7 @@ static bool trans_FRINTZ(DisasContext *s, arg_rpr_esz *a)
 if (a->esz == 0) {
 return false;
 }
-return do_frint_mode(s, a, float_round_to_zero, frint_fns[a->esz - 1]);
+return do_frint_mode(s, a, float_round_to_zero, frint_fns[a->esz]);
 }
 
 static bool trans_FRINTA(DisasContext *s, arg_rpr_esz *a)
@@ -4254,7 +4255,7 @@ static bool trans_FRINTA(DisasContext *s, arg_rpr_esz *a)
 if (a->esz == 0) {
 return false;
 }
-return do_frint_mode(s, a, float_round_ties_away, frint_fns[a->esz - 1]);
+return do_frint_mode(s, a, float_round_ties_away, frint_fns[a->esz]);
 }
 
 static bool trans_FRECPX(DisasContext *s, arg_rpr_esz *a)
-- 
2.34.1




[PATCH 101/114] target/arm: Introduce gen_gvec_fpst_zzzzp

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 59 +++---
 1 file changed, 29 insertions(+), 30 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index e323b2d6d5..8f50956d3b 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -289,6 +289,30 @@ static bool gen_gvec_fpst_(DisasContext *s, 
gen_helper_gvec_4_ptr *fn,
 return ret;
 }
 
+/* Invoke an out-of-line helper on 4 Zregs, 1 Preg, plus fpst. */
+static bool gen_gvec_fpst_p(DisasContext *s, gen_helper_gvec_5_ptr *fn,
+int rd, int rn, int rm, int ra, int pg,
+int data, ARMFPStatusFlavour flavour)
+{
+if (fn == NULL) {
+return false;
+}
+if (sve_access_check(s)) {
+unsigned vsz = vec_full_reg_size(s);
+TCGv_ptr status = fpstatus_ptr(flavour);
+
+tcg_gen_gvec_5_ptr(vec_full_reg_offset(s, rd),
+   vec_full_reg_offset(s, rn),
+   vec_full_reg_offset(s, rm),
+   vec_full_reg_offset(s, ra),
+   pred_full_reg_offset(s, pg),
+   status, vsz, vsz, data, fn);
+
+tcg_temp_free_ptr(status);
+}
+return true;
+}
+
 /* Invoke an out-of-line helper on 2 Zregs and a predicate. */
 static bool gen_gvec_ool_zzp(DisasContext *s, gen_helper_gvec_3 *fn,
  int rd, int rn, int pg, int data)
@@ -3977,21 +4001,8 @@ TRANS_FEAT(FCADD, aa64_sve, gen_gvec_fpst_zzzp, 
fcadd_fns[a->esz],
 static bool do_fmla(DisasContext *s, arg_rprrr_esz *a,
 gen_helper_gvec_5_ptr *fn)
 {
-if (a->esz == 0) {
-return false;
-}
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : 
FPST_FPCR);
-tcg_gen_gvec_5_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   vec_full_reg_offset(s, a->ra),
-   pred_full_reg_offset(s, a->pg),
-   status, vsz, vsz, 0, fn);
-tcg_temp_free_ptr(status);
-}
-return true;
+return gen_gvec_fpst_p(s, fn, a->rd, a->rn, a->rm, a->ra, a->pg, 0,
+   a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
 }
 
 #define DO_FMLA(NAME, name) \
@@ -4020,21 +4031,9 @@ static bool trans_FCMLA_zpzzz(DisasContext *s, 
arg_FCMLA_zpzzz *a)
 gen_helper_sve_fcmla_zpzzz_d,
 };
 
-if (a->esz == 0) {
-return false;
-}
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : 
FPST_FPCR);
-tcg_gen_gvec_5_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   vec_full_reg_offset(s, a->ra),
-   pred_full_reg_offset(s, a->pg),
-   status, vsz, vsz, a->rot, fns[a->esz]);
-tcg_temp_free_ptr(status);
-}
-return true;
+return gen_gvec_fpst_p(s, fns[a->esz], a->rd, a->rn, a->rm,
+   a->ra, a->pg, a->rot,
+   a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
 }
 
 static bool trans_FCMLA_zzxz(DisasContext *s, arg_FCMLA_zzxz *a)
-- 
2.34.1




[PATCH 107/114] target/arm: Use TRANS_FEAT for FCMLA_zzxz

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 19 ++-
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 436d09b928..70e8d90ae8 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -4018,19 +4018,12 @@ TRANS_FEAT(FCMLA_zpzzz, aa64_sve, gen_gvec_fpst_p, 
fcmla_fns[a->esz],
a->rd, a->rn, a->rm, a->ra, a->pg, a->rot,
a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR)
 
-static bool trans_FCMLA_zzxz(DisasContext *s, arg_FCMLA_zzxz *a)
-{
-static gen_helper_gvec_4_ptr * const fns[4] = {
-NULL,
-gen_helper_gvec_fcmlah_idx,
-gen_helper_gvec_fcmlas_idx,
-NULL,
-};
-
-return gen_gvec_fpst_(s, fns[a->esz], a->rd, a->rn, a->rm, a->ra,
-  a->index * 4 + a->rot,
-  a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
-}
+static gen_helper_gvec_4_ptr * const fcmla_idx_fns[4] = {
+NULL, gen_helper_gvec_fcmlah_idx, gen_helper_gvec_fcmlas_idx, NULL
+};
+TRANS_FEAT(FCMLA_zzxz, aa64_sve, gen_gvec_fpst_, fcmla_idx_fns[a->esz],
+   a->rd, a->rn, a->rm, a->ra, a->index * 4 + a->rot,
+   a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR)
 
 /*
  *** SVE Floating Point Unary Operations Predicated Group
-- 
2.34.1




[PATCH 088/114] target/arm: Use TRANS_FEAT for FTMAD

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 29 +++--
 1 file changed, 7 insertions(+), 22 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 29fcc8b014..11e4b4e1e4 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3715,28 +3715,13 @@ DO_PPZ(FCMNE_ppz0, fcmne0)
  *** SVE floating-point trig multiply-add coefficient
  */
 
-static bool trans_FTMAD(DisasContext *s, arg_FTMAD *a)
-{
-static gen_helper_gvec_3_ptr * const fns[3] = {
-gen_helper_sve_ftmad_h,
-gen_helper_sve_ftmad_s,
-gen_helper_sve_ftmad_d,
-};
-
-if (a->esz == 0) {
-return false;
-}
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : 
FPST_FPCR);
-tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   status, vsz, vsz, a->imm, fns[a->esz - 1]);
-tcg_temp_free_ptr(status);
-}
-return true;
-}
+static gen_helper_gvec_3_ptr * const ftmad_fns[4] = {
+NULL,   gen_helper_sve_ftmad_h,
+gen_helper_sve_ftmad_s, gen_helper_sve_ftmad_d,
+};
+TRANS_FEAT(FTMAD, aa64_sve, gen_gvec_fpst_zzz,
+   ftmad_fns[a->esz], a->rd, a->rn, a->rm, a->imm,
+   a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR)
 
 /*
  *** SVE Floating Point Accumulating Reduction Group
-- 
2.34.1




[PATCH 091/114] target/arm: Use TRANS_FEAT for FRECPE, FRSQRTE

2022-05-27 Thread Richard Henderson
Rename do_zz_fp to gen_gvec_fpst_arg_zz, and move up.
Split out gen_gvec_fpst_zz as a helper while we're at it.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 77 ++
 1 file changed, 36 insertions(+), 41 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 4a9ecd5e72..2f7651249a 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -152,6 +152,32 @@ static bool gen_gvec_ool_zz(DisasContext *s, 
gen_helper_gvec_2 *fn,
 return true;
 }
 
+static bool gen_gvec_fpst_zz(DisasContext *s, gen_helper_gvec_2_ptr *fn,
+ int rd, int rn, int data,
+ ARMFPStatusFlavour flavour)
+{
+if (fn == NULL) {
+return false;
+}
+if (sve_access_check(s)) {
+unsigned vsz = vec_full_reg_size(s);
+TCGv_ptr status = fpstatus_ptr(flavour);
+
+tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, rd),
+   vec_full_reg_offset(s, rn),
+   status, vsz, vsz, data, fn);
+tcg_temp_free_ptr(status);
+}
+return true;
+}
+
+static bool gen_gvec_fpst_arg_zz(DisasContext *s, gen_helper_gvec_2_ptr *fn,
+ arg_rr_esz *a, int data)
+{
+return gen_gvec_fpst_zz(s, fn, a->rd, a->rn, data,
+a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
+}
+
 /* Invoke an out-of-line helper on 3 Zregs. */
 static bool gen_gvec_ool_zzz(DisasContext *s, gen_helper_gvec_3 *fn,
  int rd, int rn, int rm, int data)
@@ -3627,48 +3653,17 @@ DO_VPZ(FMAXV, fmaxv)
  *** SVE Floating Point Unary Operations - Unpredicated Group
  */
 
-static void do_zz_fp(DisasContext *s, arg_rr_esz *a, gen_helper_gvec_2_ptr *fn)
-{
-unsigned vsz = vec_full_reg_size(s);
-TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : 
FPST_FPCR);
+static gen_helper_gvec_2_ptr * const frecpe_fns[] = {
+NULL, gen_helper_gvec_frecpe_h,
+gen_helper_gvec_frecpe_s, gen_helper_gvec_frecpe_d,
+};
+TRANS_FEAT(FRECPE, aa64_sve, gen_gvec_fpst_arg_zz, frecpe_fns[a->esz], a, 0)
 
-tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   status, vsz, vsz, 0, fn);
-tcg_temp_free_ptr(status);
-}
-
-static bool trans_FRECPE(DisasContext *s, arg_rr_esz *a)
-{
-static gen_helper_gvec_2_ptr * const fns[3] = {
-gen_helper_gvec_frecpe_h,
-gen_helper_gvec_frecpe_s,
-gen_helper_gvec_frecpe_d,
-};
-if (a->esz == 0) {
-return false;
-}
-if (sve_access_check(s)) {
-do_zz_fp(s, a, fns[a->esz - 1]);
-}
-return true;
-}
-
-static bool trans_FRSQRTE(DisasContext *s, arg_rr_esz *a)
-{
-static gen_helper_gvec_2_ptr * const fns[3] = {
-gen_helper_gvec_frsqrte_h,
-gen_helper_gvec_frsqrte_s,
-gen_helper_gvec_frsqrte_d,
-};
-if (a->esz == 0) {
-return false;
-}
-if (sve_access_check(s)) {
-do_zz_fp(s, a, fns[a->esz - 1]);
-}
-return true;
-}
+static gen_helper_gvec_2_ptr * const frsqrte_fns[] = {
+NULL,  gen_helper_gvec_frsqrte_h,
+gen_helper_gvec_frsqrte_s, gen_helper_gvec_frsqrte_d,
+};
+TRANS_FEAT(FRSQRTE, aa64_sve, gen_gvec_fpst_arg_zz, frsqrte_fns[a->esz], a, 0)
 
 /*
  *** SVE Floating Point Compare with Zero Group
-- 
2.34.1




[PATCH 105/114] target/arm: Use TRANS_FEAT for DO_FPCMP

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index e2ae387d62..886cf539a5 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3970,14 +3970,11 @@ static bool do_fp_cmp(DisasContext *s, arg_rprr_esz *a,
 }
 
 #define DO_FPCMP(NAME, name) \
-static bool trans_##NAME##_ppzz(DisasContext *s, arg_rprr_esz *a) \
-{ \
-static gen_helper_gvec_4_ptr * const fns[4] = {   \
+static gen_helper_gvec_4_ptr * const name##_fns[4] = {\
 NULL, gen_helper_sve_##name##_h,  \
 gen_helper_sve_##name##_s, gen_helper_sve_##name##_d  \
 };\
-return do_fp_cmp(s, a, fns[a->esz]);  \
-}
+TRANS_FEAT(NAME##_ppzz, aa64_sve, do_fp_cmp, a, name##_fns[a->esz])
 
 DO_FPCMP(FCMGE, fcmge)
 DO_FPCMP(FCMGT, fcmgt)
-- 
2.34.1




[PATCH 094/114] target/arm: Move null function and sve check into do_frint_mode

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 52 +-
 1 file changed, 23 insertions(+), 29 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 2a5fbec2d6..43cfd2818e 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -4140,62 +4140,56 @@ TRANS_FEAT(FRINTX, aa64_sve, gen_gvec_fpst_arg_zpz, 
frintx_fns[a->esz],
 static bool do_frint_mode(DisasContext *s, arg_rpr_esz *a,
   int mode, gen_helper_gvec_3_ptr *fn)
 {
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_i32 tmode = tcg_const_i32(mode);
-TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : 
FPST_FPCR);
+unsigned vsz;
+TCGv_i32 tmode;
+TCGv_ptr status;
 
-gen_helper_set_rmode(tmode, tmode, status);
-
-tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   pred_full_reg_offset(s, a->pg),
-   status, vsz, vsz, 0, fn);
-
-gen_helper_set_rmode(tmode, tmode, status);
-tcg_temp_free_i32(tmode);
-tcg_temp_free_ptr(status);
+if (fn == NULL) {
+return false;
 }
+if (!sve_access_check(s)) {
+return true;
+}
+
+vsz = vec_full_reg_size(s);
+tmode = tcg_const_i32(mode);
+status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
+
+gen_helper_set_rmode(tmode, tmode, status);
+
+tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
+   vec_full_reg_offset(s, a->rn),
+   pred_full_reg_offset(s, a->pg),
+   status, vsz, vsz, 0, fn);
+
+gen_helper_set_rmode(tmode, tmode, status);
+tcg_temp_free_i32(tmode);
+tcg_temp_free_ptr(status);
 return true;
 }
 
 static bool trans_FRINTN(DisasContext *s, arg_rpr_esz *a)
 {
-if (a->esz == 0) {
-return false;
-}
 return do_frint_mode(s, a, float_round_nearest_even, frint_fns[a->esz]);
 }
 
 static bool trans_FRINTP(DisasContext *s, arg_rpr_esz *a)
 {
-if (a->esz == 0) {
-return false;
-}
 return do_frint_mode(s, a, float_round_up, frint_fns[a->esz]);
 }
 
 static bool trans_FRINTM(DisasContext *s, arg_rpr_esz *a)
 {
-if (a->esz == 0) {
-return false;
-}
 return do_frint_mode(s, a, float_round_down, frint_fns[a->esz]);
 }
 
 static bool trans_FRINTZ(DisasContext *s, arg_rpr_esz *a)
 {
-if (a->esz == 0) {
-return false;
-}
 return do_frint_mode(s, a, float_round_to_zero, frint_fns[a->esz]);
 }
 
 static bool trans_FRINTA(DisasContext *s, arg_rpr_esz *a)
 {
-if (a->esz == 0) {
-return false;
-}
 return do_frint_mode(s, a, float_round_ties_away, frint_fns[a->esz]);
 }
 
-- 
2.34.1




[PATCH 093/114] target/arm: Rename do_zpz_ptr to gen_gvec_ool_fpst_arg_zpz

2022-05-27 Thread Richard Henderson
Rename the function to match other expansion function and
move to be adjacent.  Split out gen_gvec_fpst_zzp as a
helper while we're at it.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 392 -
 1 file changed, 129 insertions(+), 263 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 99e5d89645..2a5fbec2d6 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -318,6 +318,33 @@ static bool gen_gvec_ool_arg_zpzi(DisasContext *s, 
gen_helper_gvec_3 *fn,
 return gen_gvec_ool_zzp(s, fn, a->rd, a->rn, a->pg, a->imm);
 }
 
+static bool gen_gvec_fpst_zzp(DisasContext *s, gen_helper_gvec_3_ptr *fn,
+  int rd, int rn, int pg, int data,
+  ARMFPStatusFlavour flavour)
+{
+if (fn == NULL) {
+return false;
+}
+if (sve_access_check(s)) {
+unsigned vsz = vec_full_reg_size(s);
+TCGv_ptr status = fpstatus_ptr(flavour);
+
+tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
+   vec_full_reg_offset(s, rn),
+   pred_full_reg_offset(s, pg),
+   status, vsz, vsz, data, fn);
+tcg_temp_free_ptr(status);
+}
+return true;
+}
+
+static bool gen_gvec_fpst_arg_zpz(DisasContext *s, gen_helper_gvec_3_ptr *fn,
+  arg_rpr_esz *a, int data,
+  ARMFPStatusFlavour flavour)
+{
+return gen_gvec_fpst_zzp(s, fn, a->rd, a->rn, a->pg, data, flavour);
+}
+
 /* Invoke an out-of-line helper on 3 Zregs and a predicate. */
 static bool gen_gvec_ool_zzzp(DisasContext *s, gen_helper_gvec_4 *fn,
   int rd, int rn, int rm, int pg, int data)
@@ -4044,128 +4071,53 @@ static bool trans_FCMLA_zzxz(DisasContext *s, 
arg_FCMLA_zzxz *a)
  *** SVE Floating Point Unary Operations Predicated Group
  */
 
-static bool do_zpz_ptr(DisasContext *s, int rd, int rn, int pg,
-   bool is_fp16, gen_helper_gvec_3_ptr *fn)
-{
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_ptr status = fpstatus_ptr(is_fp16 ? FPST_FPCR_F16 : FPST_FPCR);
-tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
-   vec_full_reg_offset(s, rn),
-   pred_full_reg_offset(s, pg),
-   status, vsz, vsz, 0, fn);
-tcg_temp_free_ptr(status);
-}
-return true;
-}
+TRANS_FEAT(FCVT_sh, aa64_sve, gen_gvec_fpst_arg_zpz,
+   gen_helper_sve_fcvt_sh, a, 0, FPST_FPCR)
+TRANS_FEAT(FCVT_hs, aa64_sve, gen_gvec_fpst_arg_zpz,
+   gen_helper_sve_fcvt_hs, a, 0, FPST_FPCR)
 
-static bool trans_FCVT_sh(DisasContext *s, arg_rpr_esz *a)
-{
-return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_sh);
-}
+TRANS_FEAT(BFCVT, aa64_sve_bf16, gen_gvec_fpst_arg_zpz,
+   gen_helper_sve_bfcvt, a, 0, FPST_FPCR)
 
-static bool trans_FCVT_hs(DisasContext *s, arg_rpr_esz *a)
-{
-return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_hs);
-}
+TRANS_FEAT(FCVT_dh, aa64_sve, gen_gvec_fpst_arg_zpz,
+   gen_helper_sve_fcvt_dh, a, 0, FPST_FPCR)
+TRANS_FEAT(FCVT_hd, aa64_sve, gen_gvec_fpst_arg_zpz,
+   gen_helper_sve_fcvt_hd, a, 0, FPST_FPCR)
+TRANS_FEAT(FCVT_ds, aa64_sve, gen_gvec_fpst_arg_zpz,
+   gen_helper_sve_fcvt_ds, a, 0, FPST_FPCR)
+TRANS_FEAT(FCVT_sd, aa64_sve, gen_gvec_fpst_arg_zpz,
+   gen_helper_sve_fcvt_sd, a, 0, FPST_FPCR)
 
-static bool trans_BFCVT(DisasContext *s, arg_rpr_esz *a)
-{
-if (!dc_isar_feature(aa64_sve_bf16, s)) {
-return false;
-}
-return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_bfcvt);
-}
+TRANS_FEAT(FCVTZS_hh, aa64_sve, gen_gvec_fpst_arg_zpz,
+   gen_helper_sve_fcvtzs_hh, a, 0, FPST_FPCR_F16)
+TRANS_FEAT(FCVTZU_hh, aa64_sve, gen_gvec_fpst_arg_zpz,
+   gen_helper_sve_fcvtzu_hh, a, 0, FPST_FPCR_F16)
+TRANS_FEAT(FCVTZS_hs, aa64_sve, gen_gvec_fpst_arg_zpz,
+   gen_helper_sve_fcvtzs_hs, a, 0, FPST_FPCR_F16)
+TRANS_FEAT(FCVTZU_hs, aa64_sve, gen_gvec_fpst_arg_zpz,
+   gen_helper_sve_fcvtzu_hs, a, 0, FPST_FPCR_F16)
+TRANS_FEAT(FCVTZS_hd, aa64_sve, gen_gvec_fpst_arg_zpz,
+   gen_helper_sve_fcvtzs_hd, a, 0, FPST_FPCR_F16)
+TRANS_FEAT(FCVTZU_hd, aa64_sve, gen_gvec_fpst_arg_zpz,
+   gen_helper_sve_fcvtzu_hd, a, 0, FPST_FPCR_F16)
 
-static bool trans_FCVT_dh(DisasContext *s, arg_rpr_esz *a)
-{
-return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_dh);
-}
+TRANS_FEAT(FCVTZS_ss, aa64_sve, gen_gvec_fpst_arg_zpz,
+   gen_helper_sve_fcvtzs_ss, a, 0, FPST_FPCR)
+TRANS_FEAT(FCVTZU_ss, aa64_sve, gen_gvec_fpst_arg_zpz,
+   gen_helper_sve_fcvtzu_ss, a, 0, FPST_FPCR)
+TRANS_FEAT(FCVTZS_sd, aa64_sve, gen_gvec_fpst_arg_zpz,
+   gen_helper_sve_fcvtzs_sd, a, 0, FPST_FPCR)

[PATCH 083/114] target/arm: Use TRANS_FEAT for FMLA

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 6e8d8d54bf..5aa3e477cf 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3521,15 +3521,8 @@ static bool do_FMLA_zzxz(DisasContext *s, arg_rrxr_esz 
*a, bool sub)
   a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
 }
 
-static bool trans_FMLA_zzxz(DisasContext *s, arg_FMLA_zzxz *a)
-{
-return do_FMLA_zzxz(s, a, false);
-}
-
-static bool trans_FMLS_zzxz(DisasContext *s, arg_FMLA_zzxz *a)
-{
-return do_FMLA_zzxz(s, a, true);
-}
+TRANS_FEAT(FMLA_zzxz, aa64_sve, do_FMLA_zzxz, a, false)
+TRANS_FEAT(FMLS_zzxz, aa64_sve, do_FMLA_zzxz, a, true)
 
 /*
  *** SVE Floating Point Multiply Indexed Group
-- 
2.34.1




[PATCH 070/114] target/arm: Use TRANS_FEAT for MUL_zzi

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index d44b24e988..c0781ecf60 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3315,15 +3315,7 @@ static bool trans_SUBR_zzi(DisasContext *s, arg_rri_esz 
*a)
 return true;
 }
 
-static bool trans_MUL_zzi(DisasContext *s, arg_rri_esz *a)
-{
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-tcg_gen_gvec_muli(a->esz, vec_full_reg_offset(s, a->rd),
-  vec_full_reg_offset(s, a->rn), a->imm, vsz, vsz);
-}
-return true;
-}
+TRANS_FEAT(MUL_zzi, aa64_sve, gen_gvec_fn_arg_zzi, tcg_gen_gvec_muli, a)
 
 static bool do_zzi_sat(DisasContext *s, arg_rri_esz *a, bool u, bool d)
 {
-- 
2.34.1




[PATCH 098/114] target/arm: Rename do_zpzz_ptr to gen_gvec_fpst_arg_zpzz

2022-05-27 Thread Richard Henderson
Rename the function to match other expansion functions and
move to be adjacent.  Split out gen_gvec_fpst_zzzp as a
helper while we're at it.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 52 +++---
 1 file changed, 31 insertions(+), 21 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 2ee48186ba..f0f2db351e 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -369,6 +369,35 @@ static bool gen_gvec_ool_arg_zpzz(DisasContext *s, 
gen_helper_gvec_4 *fn,
 return gen_gvec_ool_zzzp(s, fn, a->rd, a->rn, a->rm, a->pg, data);
 }
 
+/* Invoke an out-of-line helper on 3 Zregs and a predicate. */
+static bool gen_gvec_fpst_zzzp(DisasContext *s, gen_helper_gvec_4_ptr *fn,
+   int rd, int rn, int rm, int pg, int data,
+   ARMFPStatusFlavour flavour)
+{
+if (fn == NULL) {
+return false;
+}
+if (sve_access_check(s)) {
+unsigned vsz = vec_full_reg_size(s);
+TCGv_ptr status = fpstatus_ptr(flavour);
+
+tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, rd),
+   vec_full_reg_offset(s, rn),
+   vec_full_reg_offset(s, rm),
+   pred_full_reg_offset(s, pg),
+   status, vsz, vsz, data, fn);
+tcg_temp_free_ptr(status);
+}
+return true;
+}
+
+static bool gen_gvec_fpst_arg_zpzz(DisasContext *s, gen_helper_gvec_4_ptr *fn,
+   arg_rprr_esz *a)
+{
+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);
+}
+
 /* Invoke a vector expander on two Zregs and an immediate.  */
 static bool gen_gvec_fn_zzi(DisasContext *s, GVecGen2iFn *gvec_fn,
 int esz, int rd, int rn, uint64_t imm)
@@ -3812,25 +3841,6 @@ DO_FP3(FRSQRTS, rsqrts)
  *** SVE Floating Point Arithmetic - Predicated Group
  */
 
-static bool do_zpzz_fp(DisasContext *s, arg_rprr_esz *a,
-   gen_helper_gvec_4_ptr *fn)
-{
-if (fn == NULL) {
-return false;
-}
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : 
FPST_FPCR);
-tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   pred_full_reg_offset(s, a->pg),
-   status, vsz, vsz, 0, fn);
-tcg_temp_free_ptr(status);
-}
-return true;
-}
-
 #define DO_FP3(NAME, name) \
 static bool trans_##NAME(DisasContext *s, arg_rprr_esz *a)  \
 {   \
@@ -3838,7 +3848,7 @@ static bool trans_##NAME(DisasContext *s, arg_rprr_esz 
*a)  \
 NULL, gen_helper_sve_##name##_h,\
 gen_helper_sve_##name##_s, gen_helper_sve_##name##_d\
 };  \
-return do_zpzz_fp(s, a, fns[a->esz]);   \
+return gen_gvec_fpst_arg_zpzz(s, fns[a->esz], a);   \
 }
 
 DO_FP3(FADD_zpzz, fadd)
@@ -7121,7 +7131,7 @@ static bool do_sve2_zpzz_fp(DisasContext *s, arg_rprr_esz 
*a,
 if (!dc_isar_feature(aa64_sve2, s)) {
 return false;
 }
-return do_zpzz_fp(s, a, fn);
+return gen_gvec_fpst_arg_zpzz(s, fn, a);
 }
 
 #define DO_SVE2_ZPZZ_FP(NAME, name) \
-- 
2.34.1




[PATCH 082/114] target/arm: Use TRANS_FEAT for MOVPRFX

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 17 +++--
 1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index a040d694ea..6e8d8d54bf 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -6054,20 +6054,9 @@ static bool trans_PRF_rr(DisasContext *s, arg_PRF_rr *a)
  * In the meantime, just emit the moves.
  */
 
-static bool trans_MOVPRFX(DisasContext *s, arg_MOVPRFX *a)
-{
-return do_mov_z(s, a->rd, a->rn);
-}
-
-static bool trans_MOVPRFX_m(DisasContext *s, arg_rpr_esz *a)
-{
-return do_sel_z(s, a->rd, a->rn, a->rd, a->pg, a->esz);
-}
-
-static bool trans_MOVPRFX_z(DisasContext *s, arg_rpr_esz *a)
-{
-return do_movz_zpz(s, a->rd, a->rn, a->pg, a->esz, false);
-}
+TRANS_FEAT(MOVPRFX, aa64_sve, do_mov_z, a->rd, a->rn)
+TRANS_FEAT(MOVPRFX_m, aa64_sve, do_sel_z, a->rd, a->rn, a->rd, a->pg, a->esz)
+TRANS_FEAT(MOVPRFX_z, aa64_sve, do_movz_zpz, a->rd, a->rn, a->pg, a->esz, 
false)
 
 /*
  * SVE2 Integer Multiply - Unpredicated
-- 
2.34.1




[PATCH 090/114] target/arm: Use TRANS_FEAT for do_reduce

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 0d71072f83..4a9ecd5e72 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3609,15 +3609,11 @@ static bool do_reduce(DisasContext *s, arg_rpr_esz *a,
 }
 
 #define DO_VPZ(NAME, name) \
-static bool trans_##NAME(DisasContext *s, arg_rpr_esz *a)\
-{\
-static gen_helper_fp_reduce * const fns[4] = {   \
-NULL, gen_helper_sve_##name##_h, \
-gen_helper_sve_##name##_s,   \
-gen_helper_sve_##name##_d,   \
+static gen_helper_fp_reduce * const name##_fns[4] = {\
+NULL,  gen_helper_sve_##name##_h,\
+gen_helper_sve_##name##_s, gen_helper_sve_##name##_d,\
 };   \
-return do_reduce(s, a, fns[a->esz]); \
-}
+TRANS_FEAT(NAME, aa64_sve, do_reduce, a, name##_fns[a->esz])
 
 DO_VPZ(FADDV, faddv)
 DO_VPZ(FMINNMV, fminnmv)
@@ -3625,6 +3621,8 @@ DO_VPZ(FMAXNMV, fmaxnmv)
 DO_VPZ(FMINV, fminv)
 DO_VPZ(FMAXV, fmaxv)
 
+#undef DO_VPZ
+
 /*
  *** SVE Floating Point Unary Operations - Unpredicated Group
  */
-- 
2.34.1




[PATCH 066/114] target/arm: Use TRANS_FEAT for do_ppzz_flags

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 28 
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 8eb70fd56f..73b5b67c25 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2708,14 +2708,12 @@ static bool do_ppzz_flags(DisasContext *s, arg_rprr_esz 
*a,
 }
 
 #define DO_PPZZ(NAME, name) \
-static bool trans_##NAME##_ppzz(DisasContext *s, arg_rprr_esz *a) \
-{ \
-static gen_helper_gvec_flags_4 * const fns[4] = { \
-gen_helper_sve_##name##_ppzz_b, gen_helper_sve_##name##_ppzz_h,   \
-gen_helper_sve_##name##_ppzz_s, gen_helper_sve_##name##_ppzz_d,   \
-};\
-return do_ppzz_flags(s, a, fns[a->esz]);  \
-}
+static gen_helper_gvec_flags_4 * const name##_ppzz_fns[4] = {   \
+gen_helper_sve_##name##_ppzz_b, gen_helper_sve_##name##_ppzz_h, \
+gen_helper_sve_##name##_ppzz_s, gen_helper_sve_##name##_ppzz_d, \
+};  \
+TRANS_FEAT(NAME##_ppzz, aa64_sve, do_ppzz_flags,\
+   a, name##_ppzz_fns[a->esz])
 
 DO_PPZZ(CMPEQ, cmpeq)
 DO_PPZZ(CMPNE, cmpne)
@@ -2727,14 +2725,12 @@ DO_PPZZ(CMPHS, cmphs)
 #undef DO_PPZZ
 
 #define DO_PPZW(NAME, name) \
-static bool trans_##NAME##_ppzw(DisasContext *s, arg_rprr_esz *a) \
-{ \
-static gen_helper_gvec_flags_4 * const fns[4] = { \
-gen_helper_sve_##name##_ppzw_b, gen_helper_sve_##name##_ppzw_h,   \
-gen_helper_sve_##name##_ppzw_s, NULL  \
-};\
-return do_ppzz_flags(s, a, fns[a->esz]);  \
-}
+static gen_helper_gvec_flags_4 * const name##_ppzw_fns[4] = {   \
+gen_helper_sve_##name##_ppzw_b, gen_helper_sve_##name##_ppzw_h, \
+gen_helper_sve_##name##_ppzw_s, NULL\
+};  \
+TRANS_FEAT(NAME##_ppzw, aa64_sve, do_ppzz_flags,\
+   a, name##_ppzw_fns[a->esz])
 
 DO_PPZW(CMPEQ, cmpeq)
 DO_PPZW(CMPNE, cmpne)
-- 
2.34.1




[PATCH 089/114] target/arm: Move null function and sve check into do_reduce

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 30 +-
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 11e4b4e1e4..0d71072f83 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3572,15 +3572,24 @@ TRANS_FEAT(FMUL_zzx, aa64_sve, gen_gvec_fpst_zzz,
 typedef void gen_helper_fp_reduce(TCGv_i64, TCGv_ptr, TCGv_ptr,
   TCGv_ptr, TCGv_i32);
 
-static void do_reduce(DisasContext *s, arg_rpr_esz *a,
+static bool do_reduce(DisasContext *s, arg_rpr_esz *a,
   gen_helper_fp_reduce *fn)
 {
-unsigned vsz = vec_full_reg_size(s);
-unsigned p2vsz = pow2ceil(vsz);
-TCGv_i32 t_desc = tcg_constant_i32(simd_desc(vsz, vsz, p2vsz));
+unsigned vsz, p2vsz;
+TCGv_i32 t_desc;
 TCGv_ptr t_zn, t_pg, status;
 TCGv_i64 temp;
 
+if (fn == NULL) {
+return false;
+}
+if (!sve_access_check(s)) {
+return true;
+}
+
+vsz = vec_full_reg_size(s);
+p2vsz = pow2ceil(vsz);
+t_desc = tcg_constant_i32(simd_desc(vsz, vsz, p2vsz));
 temp = tcg_temp_new_i64();
 t_zn = tcg_temp_new_ptr();
 t_pg = tcg_temp_new_ptr();
@@ -3596,23 +3605,18 @@ static void do_reduce(DisasContext *s, arg_rpr_esz *a,
 
 write_fp_dreg(s, a->rd, temp);
 tcg_temp_free_i64(temp);
+return true;
 }
 
 #define DO_VPZ(NAME, name) \
 static bool trans_##NAME(DisasContext *s, arg_rpr_esz *a)\
 {\
-static gen_helper_fp_reduce * const fns[3] = {   \
-gen_helper_sve_##name##_h,   \
+static gen_helper_fp_reduce * const fns[4] = {   \
+NULL, gen_helper_sve_##name##_h, \
 gen_helper_sve_##name##_s,   \
 gen_helper_sve_##name##_d,   \
 };   \
-if (a->esz == 0) {   \
-return false;\
-}\
-if (sve_access_check(s)) {   \
-do_reduce(s, a, fns[a->esz - 1]);\
-}\
-return true; \
+return do_reduce(s, a, fns[a->esz]); \
 }
 
 DO_VPZ(FADDV, faddv)
-- 
2.34.1




[PATCH 084/114] target/arm: Use TRANS_FEAT for BFMLA

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 28 
 1 file changed, 4 insertions(+), 24 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 5aa3e477cf..f2939fbeb9 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -7568,39 +7568,19 @@ TRANS_FEAT(BFMMLA, aa64_sve_bf16, gen_gvec_ool_arg_,
 
 static bool do_BFMLAL_zzzw(DisasContext *s, arg__esz *a, bool sel)
 {
-if (!dc_isar_feature(aa64_sve_bf16, s)) {
-return false;
-}
 return gen_gvec_fpst_(s, gen_helper_gvec_bfmlal,
   a->rd, a->rn, a->rm, a->ra, sel, FPST_FPCR);
 }
 
-static bool trans_BFMLALB_zzzw(DisasContext *s, arg__esz *a)
-{
-return do_BFMLAL_zzzw(s, a, false);
-}
-
-static bool trans_BFMLALT_zzzw(DisasContext *s, arg__esz *a)
-{
-return do_BFMLAL_zzzw(s, a, true);
-}
+TRANS_FEAT(BFMLALB_zzzw, aa64_sve_bf16, do_BFMLAL_zzzw, a, false)
+TRANS_FEAT(BFMLALT_zzzw, aa64_sve_bf16, do_BFMLAL_zzzw, a, true)
 
 static bool do_BFMLAL_zzxw(DisasContext *s, arg_rrxr_esz *a, bool sel)
 {
-if (!dc_isar_feature(aa64_sve_bf16, s)) {
-return false;
-}
 return gen_gvec_fpst_(s, gen_helper_gvec_bfmlal_idx,
   a->rd, a->rn, a->rm, a->ra,
   (a->index << 1) | sel, FPST_FPCR);
 }
 
-static bool trans_BFMLALB_zzxw(DisasContext *s, arg_rrxr_esz *a)
-{
-return do_BFMLAL_zzxw(s, a, false);
-}
-
-static bool trans_BFMLALT_zzxw(DisasContext *s, arg_rrxr_esz *a)
-{
-return do_BFMLAL_zzxw(s, a, true);
-}
+TRANS_FEAT(BFMLALB_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, false)
+TRANS_FEAT(BFMLALT_zzxw, aa64_sve_bf16, do_BFMLAL_zzxw, a, true)
-- 
2.34.1




[PATCH 061/114] target/arm: Use TRANS_FEAT for do_clast_fp

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 5135866798..21c2bd099d 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2542,15 +2542,8 @@ static bool do_clast_fp(DisasContext *s, arg_rpr_esz *a, 
bool before)
 return true;
 }
 
-static bool trans_CLASTA_v(DisasContext *s, arg_rpr_esz *a)
-{
-return do_clast_fp(s, a, false);
-}
-
-static bool trans_CLASTB_v(DisasContext *s, arg_rpr_esz *a)
-{
-return do_clast_fp(s, a, true);
-}
+TRANS_FEAT(CLASTA_v, aa64_sve, do_clast_fp, a, false)
+TRANS_FEAT(CLASTB_v, aa64_sve, do_clast_fp, a, true)
 
 /* Compute CLAST for a Xreg.  */
 static bool do_clast_general(DisasContext *s, arg_rpr_esz *a, bool before)
-- 
2.34.1




[PATCH 096/114] target/arm: Use TRANS_FEAT for FLOGB

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 29 ++---
 1 file changed, 6 insertions(+), 23 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 552a551fef..2f96f52293 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -7280,29 +7280,12 @@ TRANS_FEAT(FCVTX_ds, aa64_sve2, do_frint_mode, a,
 TRANS_FEAT(FCVTXNT_ds, aa64_sve2, do_frint_mode, a,
float_round_to_odd, gen_helper_sve2_fcvtnt_ds)
 
-static bool trans_FLOGB(DisasContext *s, arg_rpr_esz *a)
-{
-static gen_helper_gvec_3_ptr * const fns[] = {
-NULL,   gen_helper_flogb_h,
-gen_helper_flogb_s, gen_helper_flogb_d
-};
-
-if (!dc_isar_feature(aa64_sve2, s) || fns[a->esz] == NULL) {
-return false;
-}
-if (sve_access_check(s)) {
-TCGv_ptr status =
-fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
-unsigned vsz = vec_full_reg_size(s);
-
-tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   pred_full_reg_offset(s, a->pg),
-   status, vsz, vsz, 0, fns[a->esz]);
-tcg_temp_free_ptr(status);
-}
-return true;
-}
+static gen_helper_gvec_3_ptr * const flogb_fns[] = {
+NULL,   gen_helper_flogb_h,
+gen_helper_flogb_s, gen_helper_flogb_d
+};
+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)
 
 static bool do_FMLAL_zzzw(DisasContext *s, arg__esz *a, bool sub, bool sel)
 {
-- 
2.34.1




[PATCH 077/114] target/arm: Introduce gen_gvec_{ptr,fpst}_zzzz

2022-05-27 Thread Richard Henderson
Use these for the several varieties of floating-point
multiply-add instructions.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 140 ++---
 1 file changed, 53 insertions(+), 87 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index b8bd1047b0..a799ce3110 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -205,6 +205,35 @@ static bool gen_gvec_ool_arg_zzxz(DisasContext *s, 
gen_helper_gvec_4 *fn,
 return gen_gvec_ool_(s, fn, a->rd, a->rn, a->rm, a->ra, a->index);
 }
 
+/* Invoke an out-of-line helper on 4 Zregs, plus a pointer. */
+static bool gen_gvec_ptr_(DisasContext *s, gen_helper_gvec_4_ptr *fn,
+  int rd, int rn, int rm, int ra,
+  int data, TCGv_ptr ptr)
+{
+if (fn == NULL) {
+return false;
+}
+if (sve_access_check(s)) {
+unsigned vsz = vec_full_reg_size(s);
+tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, rd),
+   vec_full_reg_offset(s, rn),
+   vec_full_reg_offset(s, rm),
+   vec_full_reg_offset(s, ra),
+   ptr, vsz, vsz, data, fn);
+}
+return true;
+}
+
+static bool gen_gvec_fpst_(DisasContext *s, gen_helper_gvec_4_ptr *fn,
+   int rd, int rn, int rm, int ra,
+   int data, ARMFPStatusFlavour flavour)
+{
+TCGv_ptr status = fpstatus_ptr(flavour);
+bool ret = gen_gvec_ptr_(s, fn, rd, rn, rm, ra, data, status);
+tcg_temp_free_ptr(status);
+return ret;
+}
+
 /* Invoke an out-of-line helper on 2 Zregs and a predicate. */
 static bool gen_gvec_ool_zzp(DisasContext *s, gen_helper_gvec_3 *fn,
  int rd, int rn, int pg, int data)
@@ -3485,24 +3514,15 @@ DO_SVE2_RRXR_ROT(CDOT_zzxw_d, 
gen_helper_sve2_cdot_idx_d)
 
 static bool do_FMLA_zzxz(DisasContext *s, arg_rrxr_esz *a, bool sub)
 {
-static gen_helper_gvec_4_ptr * const fns[3] = {
+static gen_helper_gvec_4_ptr * const fns[4] = {
+NULL,
 gen_helper_gvec_fmla_idx_h,
 gen_helper_gvec_fmla_idx_s,
 gen_helper_gvec_fmla_idx_d,
 };
-
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : 
FPST_FPCR);
-tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   vec_full_reg_offset(s, a->ra),
-   status, vsz, vsz, (a->index << 1) | sub,
-   fns[a->esz - 1]);
-tcg_temp_free_ptr(status);
-}
-return true;
+return gen_gvec_fpst_(s, fns[a->esz], a->rd, a->rn, a->rm, a->ra,
+  (a->index << 1) | sub,
+  a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
 }
 
 static bool trans_FMLA_zzxz(DisasContext *s, arg_FMLA_zzxz *a)
@@ -4040,26 +4060,18 @@ static bool trans_FCMLA_zpzzz(DisasContext *s, 
arg_FCMLA_zpzzz *a)
 
 static bool trans_FCMLA_zzxz(DisasContext *s, arg_FCMLA_zzxz *a)
 {
-static gen_helper_gvec_4_ptr * const fns[2] = {
+static gen_helper_gvec_4_ptr * const fns[4] = {
+NULL,
 gen_helper_gvec_fcmlah_idx,
 gen_helper_gvec_fcmlas_idx,
+NULL,
 };
 
-tcg_debug_assert(a->esz == 1 || a->esz == 2);
 tcg_debug_assert(a->rd == a->ra);
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : 
FPST_FPCR);
-tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   vec_full_reg_offset(s, a->ra),
-   status, vsz, vsz,
-   a->index * 4 + a->rot,
-   fns[a->esz - 1]);
-tcg_temp_free_ptr(status);
-}
-return true;
+
+return gen_gvec_fpst_(s, fns[a->esz], a->rd, a->rn, a->rm, a->ra,
+  a->index * 4 + a->rot,
+  a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
 }
 
 /*
@@ -7327,17 +7339,7 @@ static bool trans_FMMLA(DisasContext *s, arg__esz *a)
 return false;
 }
 
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_ptr status = fpstatus_ptr(FPST_FPCR);
-tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   vec_full_reg_offset(s, a->ra),
-   status, vsz, vsz, 0, fn);
-tcg_temp_free_ptr(status);
-}
- 

[PATCH 081/114] target/arm: Use TRANS_FEAT for SEL_zpzz

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index b6b5980e2d..a040d694ea 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -795,10 +795,7 @@ static gen_helper_gvec_4 * const udiv_fns[4] = {
 };
 TRANS_FEAT(UDIV_zpzz, aa64_sve, gen_gvec_ool_arg_zpzz, udiv_fns[a->esz], a, 0)
 
-static bool trans_SEL_zpzz(DisasContext *s, arg_rprr_esz *a)
-{
-return do_sel_z(s, a->rd, a->rn, a->rm, a->pg, a->esz);
-}
+TRANS_FEAT(SEL_zpzz, aa64_sve, do_sel_z, a->rd, a->rn, a->rm, a->pg, a->esz)
 
 /*
  *** SVE Integer Arithmetic - Unary Predicated Group
-- 
2.34.1




[PATCH 062/114] target/arm: Use TRANS_FEAT for do_clast_general

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 21c2bd099d..f5453e99e1 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2575,15 +2575,8 @@ static bool do_clast_general(DisasContext *s, 
arg_rpr_esz *a, bool before)
 return true;
 }
 
-static bool trans_CLASTA_r(DisasContext *s, arg_rpr_esz *a)
-{
-return do_clast_general(s, a, false);
-}
-
-static bool trans_CLASTB_r(DisasContext *s, arg_rpr_esz *a)
-{
-return do_clast_general(s, a, true);
-}
+TRANS_FEAT(CLASTA_r, aa64_sve, do_clast_general, a, false)
+TRANS_FEAT(CLASTB_r, aa64_sve, do_clast_general, a, true)
 
 /* Compute LAST for a scalar.  */
 static TCGv_i64 do_last_scalar(DisasContext *s, int esz,
-- 
2.34.1




[PATCH 095/114] target/arm: Use TRANS_FEAT for do_frint_mode

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 53 ++
 1 file changed, 14 insertions(+), 39 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 43cfd2818e..552a551fef 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -4168,30 +4168,16 @@ static bool do_frint_mode(DisasContext *s, arg_rpr_esz 
*a,
 return true;
 }
 
-static bool trans_FRINTN(DisasContext *s, arg_rpr_esz *a)
-{
-return do_frint_mode(s, a, float_round_nearest_even, frint_fns[a->esz]);
-}
-
-static bool trans_FRINTP(DisasContext *s, arg_rpr_esz *a)
-{
-return do_frint_mode(s, a, float_round_up, frint_fns[a->esz]);
-}
-
-static bool trans_FRINTM(DisasContext *s, arg_rpr_esz *a)
-{
-return do_frint_mode(s, a, float_round_down, frint_fns[a->esz]);
-}
-
-static bool trans_FRINTZ(DisasContext *s, arg_rpr_esz *a)
-{
-return do_frint_mode(s, a, float_round_to_zero, frint_fns[a->esz]);
-}
-
-static bool trans_FRINTA(DisasContext *s, arg_rpr_esz *a)
-{
-return do_frint_mode(s, a, float_round_ties_away, frint_fns[a->esz]);
-}
+TRANS_FEAT(FRINTN, aa64_sve, do_frint_mode, a,
+   float_round_nearest_even, frint_fns[a->esz])
+TRANS_FEAT(FRINTP, aa64_sve, do_frint_mode, a,
+   float_round_up, frint_fns[a->esz])
+TRANS_FEAT(FRINTM, aa64_sve, do_frint_mode, a,
+   float_round_down, frint_fns[a->esz])
+TRANS_FEAT(FRINTZ, aa64_sve, do_frint_mode, a,
+   float_round_to_zero, frint_fns[a->esz])
+TRANS_FEAT(FRINTA, aa64_sve, do_frint_mode, a,
+   float_round_ties_away, frint_fns[a->esz])
 
 static gen_helper_gvec_3_ptr * const frecpx_fns[] = {
 NULL,gen_helper_sve_frecpx_h,
@@ -7289,21 +7275,10 @@ TRANS_FEAT(FCVTLT_hs, 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)
 
-static bool trans_FCVTX_ds(DisasContext *s, arg_rpr_esz *a)
-{
-if (!dc_isar_feature(aa64_sve2, s)) {
-return false;
-}
-return do_frint_mode(s, a, float_round_to_odd, gen_helper_sve_fcvt_ds);
-}
-
-static bool trans_FCVTXNT_ds(DisasContext *s, arg_rpr_esz *a)
-{
-if (!dc_isar_feature(aa64_sve2, s)) {
-return false;
-}
-return do_frint_mode(s, a, float_round_to_odd, gen_helper_sve2_fcvtnt_ds);
-}
+TRANS_FEAT(FCVTX_ds, aa64_sve2, do_frint_mode, a,
+   float_round_to_odd, gen_helper_sve_fcvt_ds)
+TRANS_FEAT(FCVTXNT_ds, aa64_sve2, do_frint_mode, a,
+   float_round_to_odd, gen_helper_sve2_fcvtnt_ds)
 
 static bool trans_FLOGB(DisasContext *s, arg_rpr_esz *a)
 {
-- 
2.34.1




[PATCH 064/114] target/arm: Use TRANS_FEAT for do_last_general

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 841c1b5644..caa587506c 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2622,15 +2622,8 @@ static bool do_last_general(DisasContext *s, arg_rpr_esz 
*a, bool before)
 return true;
 }
 
-static bool trans_LASTA_r(DisasContext *s, arg_rpr_esz *a)
-{
-return do_last_general(s, a, false);
-}
-
-static bool trans_LASTB_r(DisasContext *s, arg_rpr_esz *a)
-{
-return do_last_general(s, a, true);
-}
+TRANS_FEAT(LASTA_r, aa64_sve, do_last_general, a, false)
+TRANS_FEAT(LASTB_r, aa64_sve, do_last_general, a, true)
 
 static bool trans_CPY_m_r(DisasContext *s, arg_rpr_esz *a)
 {
-- 
2.34.1




[PATCH 068/114] target/arm: Use TRANS_FEAT for do_ppzi_flags

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 22acd5ead0..03b2eddd8b 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2786,14 +2786,12 @@ static bool do_ppzi_flags(DisasContext *s, arg_rpri_esz 
*a,
 }
 
 #define DO_PPZI(NAME, name) \
-static bool trans_##NAME##_ppzi(DisasContext *s, arg_rpri_esz *a) \
-{ \
-static gen_helper_gvec_flags_3 * const fns[4] = { \
+static gen_helper_gvec_flags_3 * const name##_ppzi_fns[4] = { \
 gen_helper_sve_##name##_ppzi_b, gen_helper_sve_##name##_ppzi_h,   \
 gen_helper_sve_##name##_ppzi_s, gen_helper_sve_##name##_ppzi_d,   \
 };\
-return do_ppzi_flags(s, a, fns[a->esz]);  \
-}
+TRANS_FEAT(NAME##_ppzi, aa64_sve, do_ppzi_flags, a,   \
+   name##_ppzi_fns[a->esz])
 
 DO_PPZI(CMPEQ, cmpeq)
 DO_PPZI(CMPNE, cmpne)
-- 
2.34.1




[PATCH 075/114] target/arm: Use TRANS_FEAT for do_zzi_sat

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 23 ---
 1 file changed, 4 insertions(+), 19 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 6b2f235e4a..e6434589f4 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3313,25 +3313,10 @@ static bool do_zzi_sat(DisasContext *s, arg_rri_esz *a, 
bool u, bool d)
 return true;
 }
 
-static bool trans_SQADD_zzi(DisasContext *s, arg_rri_esz *a)
-{
-return do_zzi_sat(s, a, false, false);
-}
-
-static bool trans_UQADD_zzi(DisasContext *s, arg_rri_esz *a)
-{
-return do_zzi_sat(s, a, true, false);
-}
-
-static bool trans_SQSUB_zzi(DisasContext *s, arg_rri_esz *a)
-{
-return do_zzi_sat(s, a, false, true);
-}
-
-static bool trans_UQSUB_zzi(DisasContext *s, arg_rri_esz *a)
-{
-return do_zzi_sat(s, a, true, true);
-}
+TRANS_FEAT(SQADD_zzi, aa64_sve, do_zzi_sat, a, false, false)
+TRANS_FEAT(UQADD_zzi, aa64_sve, do_zzi_sat, a, true, false)
+TRANS_FEAT(SQSUB_zzi, aa64_sve, do_zzi_sat, a, false, true)
+TRANS_FEAT(UQSUB_zzi, aa64_sve, do_zzi_sat, a, true, true)
 
 static bool do_zzi_ool(DisasContext *s, arg_rri_esz *a, gen_helper_gvec_2i *fn)
 {
-- 
2.34.1




[PATCH 087/114] target/arm: Use TRANS_FEAT for FMUL_zzx

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 26 +++---
 1 file changed, 7 insertions(+), 19 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index d596e7a027..29fcc8b014 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3557,25 +3557,13 @@ TRANS_FEAT(FMLS_zzxz, aa64_sve, do_FMLA_zzxz, a, true)
  *** SVE Floating Point Multiply Indexed Group
  */
 
-static bool trans_FMUL_zzx(DisasContext *s, arg_FMUL_zzx *a)
-{
-static gen_helper_gvec_3_ptr * const fns[3] = {
-gen_helper_gvec_fmul_idx_h,
-gen_helper_gvec_fmul_idx_s,
-gen_helper_gvec_fmul_idx_d,
-};
-
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : 
FPST_FPCR);
-tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   status, vsz, vsz, a->index, fns[a->esz - 1]);
-tcg_temp_free_ptr(status);
-}
-return true;
-}
+static gen_helper_gvec_3_ptr * const fmul_idx_fns[4] = {
+NULL,   gen_helper_gvec_fmul_idx_h,
+gen_helper_gvec_fmul_idx_s, gen_helper_gvec_fmul_idx_d,
+};
+TRANS_FEAT(FMUL_zzx, aa64_sve, gen_gvec_fpst_zzz,
+   fmul_idx_fns[a->esz], a->rd, a->rn, a->rm, a->index,
+   a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR)
 
 /*
  *** SVE Floating Point Fast Reduction Group
-- 
2.34.1




[PATCH 072/114] target/arm: Reject add/sub w/ shifted byte early

2022-05-27 Thread Richard Henderson
Remove the unparsed extractions in trans_ADD_zzi, trans_SUBR_zzi,
and do_zzi_sat which are intended to reject an 8-bit shift of an
8-bit constant for 8-bit element.

Signed-off-by: Richard Henderson 
---
 target/arm/sve.decode  | 35 ---
 target/arm/translate-sve.c |  9 -
 2 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/target/arm/sve.decode b/target/arm/sve.decode
index c02da0a082..8cff63cf25 100644
--- a/target/arm/sve.decode
+++ b/target/arm/sve.decode
@@ -793,13 +793,34 @@ FDUP00100101 esz:2 111 00 1110 imm:8 rd:5
 }
 
 # SVE integer add/subtract immediate (unpredicated)
-ADD_zzi 00100101 .. 100 000 11 .  . @rdn_sh_i8u
-SUB_zzi 00100101 .. 100 001 11 .  . @rdn_sh_i8u
-SUBR_zzi00100101 .. 100 011 11 .  . @rdn_sh_i8u
-SQADD_zzi   00100101 .. 100 100 11 .  . @rdn_sh_i8u
-UQADD_zzi   00100101 .. 100 101 11 .  . @rdn_sh_i8u
-SQSUB_zzi   00100101 .. 100 110 11 .  . @rdn_sh_i8u
-UQSUB_zzi   00100101 .. 100 111 11 .  . @rdn_sh_i8u
+{
+  INVALID   00100101 00 100 000 11 1  -
+  ADD_zzi   00100101 .. 100 000 11 .  . @rdn_sh_i8u
+}
+{
+  INVALID   00100101 00 100 001 11 1  -
+  SUB_zzi   00100101 .. 100 001 11 .  . @rdn_sh_i8u
+}
+{
+  INVALID   00100101 00 100 011 11 1  -
+  SUBR_zzi  00100101 .. 100 011 11 .  . @rdn_sh_i8u
+}
+{
+  INVALID   00100101 00 100 100 11 1  -
+  SQADD_zzi 00100101 .. 100 100 11 .  . @rdn_sh_i8u
+}
+{
+  INVALID   00100101 00 100 101 11 1  -
+  UQADD_zzi 00100101 .. 100 101 11 .  . @rdn_sh_i8u
+}
+{
+  INVALID   00100101 00 100 110 11 1  -
+  SQSUB_zzi 00100101 .. 100 110 11 .  . @rdn_sh_i8u
+}
+{
+  INVALID   00100101 00 100 111 11 1  -
+  UQSUB_zzi 00100101 .. 100 111 11 .  . @rdn_sh_i8u
+}
 
 # SVE integer min/max immediate (unpredicated)
 SMAX_zzi00100101 .. 101 000 110  .  @rdn_i8s
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 14faef0564..bf988cab3e 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3262,9 +3262,6 @@ static bool trans_DUP_i(DisasContext *s, arg_DUP_i *a)
 
 static bool trans_ADD_zzi(DisasContext *s, arg_rri_esz *a)
 {
-if (a->esz == 0 && extract32(s->insn, 13, 1)) {
-return false;
-}
 return gen_gvec_fn_arg_zzi(s, tcg_gen_gvec_addi, a);
 }
 
@@ -3305,9 +3302,6 @@ static bool trans_SUBR_zzi(DisasContext *s, arg_rri_esz 
*a)
   .scalar_first = true }
 };
 
-if (a->esz == 0 && extract32(s->insn, 13, 1)) {
-return false;
-}
 if (sve_access_check(s)) {
 unsigned vsz = vec_full_reg_size(s);
 tcg_gen_gvec_2s(vec_full_reg_offset(s, a->rd),
@@ -3321,9 +3315,6 @@ TRANS_FEAT(MUL_zzi, aa64_sve, gen_gvec_fn_arg_zzi, 
tcg_gen_gvec_muli, a)
 
 static bool do_zzi_sat(DisasContext *s, arg_rri_esz *a, bool u, bool d)
 {
-if (a->esz == 0 && extract32(s->insn, 13, 1)) {
-return false;
-}
 if (sve_access_check(s)) {
 do_sat_addsub_vec(s, a->esz, a->rd, a->rn,
   tcg_constant_i64(a->imm), u, d);
-- 
2.34.1




[PATCH 043/114] target/arm: Use TRANS_FEAT for do_vpz_ool

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 20 +++-
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 911d2e28bf..6103bd7f1d 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -858,14 +858,11 @@ static bool do_vpz_ool(DisasContext *s, arg_rpr_esz *a,
 }
 
 #define DO_VPZ(NAME, name) \
-static bool trans_##NAME(DisasContext *s, arg_rpr_esz *a)\
-{\
-static gen_helper_gvec_reduc * const fns[4] = {  \
+static gen_helper_gvec_reduc * const name##_fns[4] = {   \
 gen_helper_sve_##name##_b, gen_helper_sve_##name##_h,\
 gen_helper_sve_##name##_s, gen_helper_sve_##name##_d,\
 };   \
-return do_vpz_ool(s, a, fns[a->esz]);\
-}
+TRANS_FEAT(NAME, aa64_sve, do_vpz_ool, a, name##_fns[a->esz])
 
 DO_VPZ(ORV, orv)
 DO_VPZ(ANDV, andv)
@@ -877,14 +874,11 @@ DO_VPZ(UMAXV, umaxv)
 DO_VPZ(SMINV, sminv)
 DO_VPZ(UMINV, uminv)
 
-static bool trans_SADDV(DisasContext *s, arg_rpr_esz *a)
-{
-static gen_helper_gvec_reduc * const fns[4] = {
-gen_helper_sve_saddv_b, gen_helper_sve_saddv_h,
-gen_helper_sve_saddv_s, NULL
-};
-return do_vpz_ool(s, a, fns[a->esz]);
-}
+static gen_helper_gvec_reduc * const saddv_fns[4] = {
+gen_helper_sve_saddv_b, gen_helper_sve_saddv_h,
+gen_helper_sve_saddv_s, NULL
+};
+TRANS_FEAT(SADDV, aa64_sve, do_vpz_ool, a, saddv_fns[a->esz])
 
 #undef DO_VPZ
 
-- 
2.34.1




[PATCH 086/114] target/arm: Use TRANS_FEAT for DO_FP3

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 61bf5f5757..d596e7a027 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3799,14 +3799,11 @@ static bool trans_FADDA(DisasContext *s, arg_rprr_esz 
*a)
  */
 
 #define DO_FP3(NAME, name) \
-static bool trans_##NAME(DisasContext *s, arg_rrr_esz *a)   \
-{   \
-static gen_helper_gvec_3_ptr * const fns[4] = { \
+static gen_helper_gvec_3_ptr * const name##_fns[4] = {  \
 NULL, gen_helper_gvec_##name##_h,   \
 gen_helper_gvec_##name##_s, gen_helper_gvec_##name##_d  \
 };  \
-return gen_gvec_fpst_arg_zzz(s, fns[a->esz], a, 0); \
-}
+TRANS_FEAT(NAME, aa64_sve, gen_gvec_fpst_arg_zzz, name##_fns[a->esz], a, 0)
 
 DO_FP3(FADD_zzz, fadd)
 DO_FP3(FSUB_zzz, fsub)
-- 
2.34.1




[PATCH 074/114] target/arm: Use TRANS_FEAT for ADD_zzi

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 83980f5ee6..6b2f235e4a 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3254,10 +3254,7 @@ static bool trans_DUP_i(DisasContext *s, arg_DUP_i *a)
 return true;
 }
 
-static bool trans_ADD_zzi(DisasContext *s, arg_rri_esz *a)
-{
-return gen_gvec_fn_arg_zzi(s, tcg_gen_gvec_addi, a);
-}
+TRANS_FEAT(ADD_zzi, aa64_sve, gen_gvec_fn_arg_zzi, tcg_gen_gvec_addi, a)
 
 static bool trans_SUB_zzi(DisasContext *s, arg_rri_esz *a)
 {
-- 
2.34.1




[PATCH 063/114] target/arm: Use TRANS_FEAT for do_last_fp

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index f5453e99e1..841c1b5644 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2608,15 +2608,8 @@ static bool do_last_fp(DisasContext *s, arg_rpr_esz *a, 
bool before)
 return true;
 }
 
-static bool trans_LASTA_v(DisasContext *s, arg_rpr_esz *a)
-{
-return do_last_fp(s, a, false);
-}
-
-static bool trans_LASTB_v(DisasContext *s, arg_rpr_esz *a)
-{
-return do_last_fp(s, a, true);
-}
+TRANS_FEAT(LASTA_v, aa64_sve, do_last_fp, a, false)
+TRANS_FEAT(LASTB_v, aa64_sve, do_last_fp, a, true)
 
 /* Compute LAST for a Xreg.  */
 static bool do_last_general(DisasContext *s, arg_rpr_esz *a, bool before)
-- 
2.34.1




[PATCH 069/114] target/arm: Use TRANS_FEAT for do_brk2, do_brk3

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 45 --
 1 file changed, 14 insertions(+), 31 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 03b2eddd8b..d44b24e988 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2879,40 +2879,23 @@ static bool do_brk2(DisasContext *s, arg_rpr_s *a,
 return true;
 }
 
-static bool trans_BRKPA(DisasContext *s, arg_rprr_s *a)
-{
-return do_brk3(s, a, gen_helper_sve_brkpa, gen_helper_sve_brkpas);
-}
+TRANS_FEAT(BRKPA, aa64_sve, do_brk3, a,
+   gen_helper_sve_brkpa, gen_helper_sve_brkpas)
+TRANS_FEAT(BRKPB, aa64_sve, do_brk3, a,
+   gen_helper_sve_brkpb, gen_helper_sve_brkpbs)
 
-static bool trans_BRKPB(DisasContext *s, arg_rprr_s *a)
-{
-return do_brk3(s, a, gen_helper_sve_brkpb, gen_helper_sve_brkpbs);
-}
+TRANS_FEAT(BRKA_m, aa64_sve, do_brk2, a,
+   gen_helper_sve_brka_m, gen_helper_sve_brkas_m)
+TRANS_FEAT(BRKB_m, aa64_sve, do_brk2, a,
+   gen_helper_sve_brkb_m, gen_helper_sve_brkbs_m)
 
-static bool trans_BRKA_m(DisasContext *s, arg_rpr_s *a)
-{
-return do_brk2(s, a, gen_helper_sve_brka_m, gen_helper_sve_brkas_m);
-}
+TRANS_FEAT(BRKA_z, aa64_sve, do_brk2, a,
+   gen_helper_sve_brka_z, gen_helper_sve_brkas_z)
+TRANS_FEAT(BRKB_z, aa64_sve, do_brk2, a,
+   gen_helper_sve_brkb_z, gen_helper_sve_brkbs_z)
 
-static bool trans_BRKB_m(DisasContext *s, arg_rpr_s *a)
-{
-return do_brk2(s, a, gen_helper_sve_brkb_m, gen_helper_sve_brkbs_m);
-}
-
-static bool trans_BRKA_z(DisasContext *s, arg_rpr_s *a)
-{
-return do_brk2(s, a, gen_helper_sve_brka_z, gen_helper_sve_brkas_z);
-}
-
-static bool trans_BRKB_z(DisasContext *s, arg_rpr_s *a)
-{
-return do_brk2(s, a, gen_helper_sve_brkb_z, gen_helper_sve_brkbs_z);
-}
-
-static bool trans_BRKN(DisasContext *s, arg_rpr_s *a)
-{
-return do_brk2(s, a, gen_helper_sve_brkn, gen_helper_sve_brkns);
-}
+TRANS_FEAT(BRKN, aa64_sve, do_brk2, a,
+   gen_helper_sve_brkn, gen_helper_sve_brkns)
 
 /*
  *** SVE Predicate Count Group
-- 
2.34.1




[PATCH 053/114] target/arm: Use TRANS_FEAT for do_pfirst_pnext

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 6fd9a42ef9..abb5433ee5 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1668,15 +1668,8 @@ static bool do_pfirst_pnext(DisasContext *s, arg_rr_esz 
*a,
 return true;
 }
 
-static bool trans_PFIRST(DisasContext *s, arg_rr_esz *a)
-{
-return do_pfirst_pnext(s, a, gen_helper_sve_pfirst);
-}
-
-static bool trans_PNEXT(DisasContext *s, arg_rr_esz *a)
-{
-return do_pfirst_pnext(s, a, gen_helper_sve_pnext);
-}
+TRANS_FEAT(PFIRST, aa64_sve, do_pfirst_pnext, a, gen_helper_sve_pfirst)
+TRANS_FEAT(PNEXT, aa64_sve, do_pfirst_pnext, a, gen_helper_sve_pnext)
 
 /*
  *** SVE Element Count Group
-- 
2.34.1




[PATCH 085/114] target/arm: Rename do_zzz_fp to gen_gvec_ool_fpst_arg_zzz

2022-05-27 Thread Richard Henderson
Rename the function to match gen_gvec_ool_arg_zzz,
and move to be adjacent.  Split out gen_gvec_fpst_zzz
as a helper while we're at it.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 50 +++---
 1 file changed, 30 insertions(+), 20 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index f2939fbeb9..61bf5f5757 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -175,6 +175,35 @@ static bool gen_gvec_ool_arg_zzz(DisasContext *s, 
gen_helper_gvec_3 *fn,
 return gen_gvec_ool_zzz(s, fn, a->rd, a->rn, a->rm, data);
 }
 
+/* Invoke an out-of-line helper on 3 Zregs, plus float_status. */
+static bool gen_gvec_fpst_zzz(DisasContext *s, gen_helper_gvec_3_ptr *fn,
+  int rd, int rn, int rm,
+  int data, ARMFPStatusFlavour flavour)
+{
+if (fn == NULL) {
+return false;
+}
+if (sve_access_check(s)) {
+unsigned vsz = vec_full_reg_size(s);
+TCGv_ptr status = fpstatus_ptr(flavour);
+
+tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
+   vec_full_reg_offset(s, rn),
+   vec_full_reg_offset(s, rm),
+   status, vsz, vsz, data, fn);
+
+tcg_temp_free_ptr(status);
+}
+return true;
+}
+
+static bool gen_gvec_fpst_arg_zzz(DisasContext *s, gen_helper_gvec_3_ptr *fn,
+  arg_rrr_esz *a, int data)
+{
+return gen_gvec_fpst_zzz(s, fn, a->rd, a->rn, a->rm, data,
+ a->esz == MO_16 ? FPST_FPCR_F16 : FPST_FPCR);
+}
+
 /* Invoke an out-of-line helper on 4 Zregs. */
 static bool gen_gvec_ool_(DisasContext *s, gen_helper_gvec_4 *fn,
   int rd, int rn, int rm, int ra, int data)
@@ -3769,25 +3798,6 @@ static bool trans_FADDA(DisasContext *s, arg_rprr_esz *a)
  *** SVE Floating Point Arithmetic - Unpredicated Group
  */
 
-static bool do_zzz_fp(DisasContext *s, arg_rrr_esz *a,
-  gen_helper_gvec_3_ptr *fn)
-{
-if (fn == NULL) {
-return false;
-}
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_ptr status = fpstatus_ptr(a->esz == MO_16 ? FPST_FPCR_F16 : 
FPST_FPCR);
-tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn),
-   vec_full_reg_offset(s, a->rm),
-   status, vsz, vsz, 0, fn);
-tcg_temp_free_ptr(status);
-}
-return true;
-}
-
-
 #define DO_FP3(NAME, name) \
 static bool trans_##NAME(DisasContext *s, arg_rrr_esz *a)   \
 {   \
@@ -3795,7 +3805,7 @@ static bool trans_##NAME(DisasContext *s, arg_rrr_esz *a) 
  \
 NULL, gen_helper_gvec_##name##_h,   \
 gen_helper_gvec_##name##_s, gen_helper_gvec_##name##_d  \
 };  \
-return do_zzz_fp(s, a, fns[a->esz]);\
+return gen_gvec_fpst_arg_zzz(s, fns[a->esz], a, 0); \
 }
 
 DO_FP3(FADD_zzz, fadd)
-- 
2.34.1




[PATCH 057/114] target/arm: Move sve zip high_ofs into simd_data

2022-05-27 Thread Richard Henderson
This is in line with how we treat uzp, and will
eliminate the special case code during translation.

Signed-off-by: Richard Henderson 
---
 target/arm/sve_helper.c|  6 --
 target/arm/translate-sve.c | 12 ++--
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index e0f9aa9983..3bdcd4ce9d 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -3382,6 +3382,7 @@ void HELPER(sve_punpk_p)(void *vd, void *vn, uint32_t 
pred_desc)
 void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t desc)   \
 {\
 intptr_t oprsz = simd_oprsz(desc);   \
+intptr_t odd_ofs = simd_data(desc);  \
 intptr_t i, oprsz_2 = oprsz / 2; \
 ARMVectorReg tmp_n, tmp_m;   \
 /* We produce output faster than we consume input.   \
@@ -3393,8 +3394,9 @@ void HELPER(NAME)(void *vd, void *vn, void *vm, uint32_t 
desc)   \
 vm = memcpy(_m, vm, oprsz_2);\
 }\
 for (i = 0; i < oprsz_2; i += sizeof(TYPE)) {\
-*(TYPE *)(vd + H(2 * i + 0)) = *(TYPE *)(vn + H(i)); \
-*(TYPE *)(vd + H(2 * i + sizeof(TYPE))) = *(TYPE *)(vm + H(i)); \
+*(TYPE *)(vd + H(2 * i + 0)) = *(TYPE *)(vn + odd_ofs + H(i)); \
+*(TYPE *)(vd + H(2 * i + sizeof(TYPE))) =\
+*(TYPE *)(vm + odd_ofs + H(i));  \
 }\
 if (sizeof(TYPE) == 16 && unlikely(oprsz & 16)) {\
 memset(vd + oprsz - 16, 0, 16);  \
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 1e6bcedb9d..c2ced3e2bb 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2298,9 +2298,9 @@ static bool do_zip(DisasContext *s, arg_rrr_esz *a, bool 
high)
 unsigned vsz = vec_full_reg_size(s);
 unsigned high_ofs = high ? vsz / 2 : 0;
 tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn) + high_ofs,
-   vec_full_reg_offset(s, a->rm) + high_ofs,
-   vsz, vsz, 0, fns[a->esz]);
+   vec_full_reg_offset(s, a->rn),
+   vec_full_reg_offset(s, a->rm),
+   vsz, vsz, high_ofs, fns[a->esz]);
 }
 return true;
 }
@@ -2324,9 +2324,9 @@ static bool do_zip_q(DisasContext *s, arg_rrr_esz *a, 
bool high)
 unsigned vsz = vec_full_reg_size(s);
 unsigned high_ofs = high ? QEMU_ALIGN_DOWN(vsz, 32) / 2 : 0;
 tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
-   vec_full_reg_offset(s, a->rn) + high_ofs,
-   vec_full_reg_offset(s, a->rm) + high_ofs,
-   vsz, vsz, 0, gen_helper_sve2_zip_q);
+   vec_full_reg_offset(s, a->rn),
+   vec_full_reg_offset(s, a->rm),
+   vsz, vsz, high_ofs, gen_helper_sve2_zip_q);
 }
 return true;
 }
-- 
2.34.1




[PATCH 055/114] target/arm: Use TRANS_FEAT for do_perm_pred3

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 35 ++-
 1 file changed, 6 insertions(+), 29 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 7139e6c0b0..413e89b19c 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2272,35 +2272,12 @@ static bool do_perm_pred2(DisasContext *s, arg_rr_esz 
*a, bool high_odd,
 return true;
 }
 
-static bool trans_ZIP1_p(DisasContext *s, arg_rrr_esz *a)
-{
-return do_perm_pred3(s, a, 0, gen_helper_sve_zip_p);
-}
-
-static bool trans_ZIP2_p(DisasContext *s, arg_rrr_esz *a)
-{
-return do_perm_pred3(s, a, 1, gen_helper_sve_zip_p);
-}
-
-static bool trans_UZP1_p(DisasContext *s, arg_rrr_esz *a)
-{
-return do_perm_pred3(s, a, 0, gen_helper_sve_uzp_p);
-}
-
-static bool trans_UZP2_p(DisasContext *s, arg_rrr_esz *a)
-{
-return do_perm_pred3(s, a, 1, gen_helper_sve_uzp_p);
-}
-
-static bool trans_TRN1_p(DisasContext *s, arg_rrr_esz *a)
-{
-return do_perm_pred3(s, a, 0, gen_helper_sve_trn_p);
-}
-
-static bool trans_TRN2_p(DisasContext *s, arg_rrr_esz *a)
-{
-return do_perm_pred3(s, a, 1, gen_helper_sve_trn_p);
-}
+TRANS_FEAT(ZIP1_p, aa64_sve, do_perm_pred3, a, 0, gen_helper_sve_zip_p)
+TRANS_FEAT(ZIP2_p, aa64_sve, do_perm_pred3, a, 1, gen_helper_sve_zip_p)
+TRANS_FEAT(UZP1_p, aa64_sve, do_perm_pred3, a, 0, gen_helper_sve_uzp_p)
+TRANS_FEAT(UZP2_p, aa64_sve, do_perm_pred3, a, 1, gen_helper_sve_uzp_p)
+TRANS_FEAT(TRN1_p, aa64_sve, do_perm_pred3, a, 0, gen_helper_sve_trn_p)
+TRANS_FEAT(TRN2_p, aa64_sve, do_perm_pred3, a, 1, gen_helper_sve_trn_p)
 
 static bool trans_REV_p(DisasContext *s, arg_rr_esz *a)
 {
-- 
2.34.1




[PATCH 080/114] target/arm: Implement NOT (prediates) alias

2022-05-27 Thread Richard Henderson
This alias is defined on EOR (prediates).  While the
same operation could be performed with NAND or NOR,
only bother with the official alias.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index f33bc9d480..b6b5980e2d 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1381,6 +1381,11 @@ static bool trans_EOR_(DisasContext *s, arg_rprr_s 
*a)
 .fno = gen_helper_sve_eor_,
 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
 };
+
+/* Alias NOT (predicate) is EOR Pd.B, Pg/Z, Pn.B, Pg.B */
+if (!a->s && a->pg == a->rm) {
+return gen_gvec_fn_ppp(s, tcg_gen_gvec_andc, a->rd, a->pg, a->rn);
+}
 return do__flags(s, a, );
 }
 
-- 
2.34.1




[PATCH 049/114] target/arm: Use TRANS_FEAT for do_index

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 35 ---
 1 file changed, 8 insertions(+), 27 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 44c2342923..dac29749ce 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1126,33 +1126,14 @@ static bool do_index(DisasContext *s, int esz, int rd,
 return true;
 }
 
-static bool trans_INDEX_ii(DisasContext *s, arg_INDEX_ii *a)
-{
-TCGv_i64 start = tcg_constant_i64(a->imm1);
-TCGv_i64 incr = tcg_constant_i64(a->imm2);
-return do_index(s, a->esz, a->rd, start, incr);
-}
-
-static bool trans_INDEX_ir(DisasContext *s, arg_INDEX_ir *a)
-{
-TCGv_i64 start = tcg_constant_i64(a->imm);
-TCGv_i64 incr = cpu_reg(s, a->rm);
-return do_index(s, a->esz, a->rd, start, incr);
-}
-
-static bool trans_INDEX_ri(DisasContext *s, arg_INDEX_ri *a)
-{
-TCGv_i64 start = cpu_reg(s, a->rn);
-TCGv_i64 incr = tcg_constant_i64(a->imm);
-return do_index(s, a->esz, a->rd, start, incr);
-}
-
-static bool trans_INDEX_rr(DisasContext *s, arg_INDEX_rr *a)
-{
-TCGv_i64 start = cpu_reg(s, a->rn);
-TCGv_i64 incr = cpu_reg(s, a->rm);
-return do_index(s, a->esz, a->rd, start, incr);
-}
+TRANS_FEAT(INDEX_ii, aa64_sve, do_index, a->esz, a->rd,
+   tcg_constant_i64(a->imm1), tcg_constant_i64(a->imm2))
+TRANS_FEAT(INDEX_ir, aa64_sve, do_index, a->esz, a->rd,
+   tcg_constant_i64(a->imm), cpu_reg(s, a->rm))
+TRANS_FEAT(INDEX_ri, aa64_sve, do_index, a->esz, a->rd,
+   cpu_reg(s, a->rn), tcg_constant_i64(a->imm))
+TRANS_FEAT(INDEX_rr, aa64_sve, do_index, a->esz, a->rd,
+   cpu_reg(s, a->rn), cpu_reg(s, a->rm))
 
 /*
  *** SVE Stack Allocation Group
-- 
2.34.1




[PATCH 060/114] target/arm: Use TRANS_FEAT for do_clast_vector

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 7c9deb267f..5135866798 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2492,15 +2492,8 @@ static bool do_clast_vector(DisasContext *s, 
arg_rprr_esz *a, bool before)
 return true;
 }
 
-static bool trans_CLASTA_z(DisasContext *s, arg_rprr_esz *a)
-{
-return do_clast_vector(s, a, false);
-}
-
-static bool trans_CLASTB_z(DisasContext *s, arg_rprr_esz *a)
-{
-return do_clast_vector(s, a, true);
-}
+TRANS_FEAT(CLASTA_z, aa64_sve, do_clast_vector, a, false)
+TRANS_FEAT(CLASTB_z, aa64_sve, do_clast_vector, a, true)
 
 /* Compute CLAST for a scalar.  */
 static void do_clast_scalar(DisasContext *s, int esz, int pg, int rm,
-- 
2.34.1




[PATCH 040/114] target/arm: Hoist sve access check through do_sel_z

2022-05-27 Thread Richard Henderson
The check is already done in gen_gvec_ool_zzzp,
which is called by do_sel_z; remove from callers.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 14 --
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 6fa721eca6..62bfc6fe7c 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -697,13 +697,13 @@ TRANS_FEAT(UQSUB_zzz, aa64_sve, gen_gvec_fn_arg_zzz, 
tcg_gen_gvec_ussub, a)
 /* Select active elememnts from Zn and inactive elements from Zm,
  * storing the result in Zd.
  */
-static void do_sel_z(DisasContext *s, int rd, int rn, int rm, int pg, int esz)
+static bool do_sel_z(DisasContext *s, int rd, int rn, int rm, int pg, int esz)
 {
 static gen_helper_gvec_4 * const fns[4] = {
 gen_helper_sve_sel_zpzz_b, gen_helper_sve_sel_zpzz_h,
 gen_helper_sve_sel_zpzz_s, gen_helper_sve_sel_zpzz_d
 };
-gen_gvec_ool_zzzp(s, fns[esz], rd, rn, rm, pg, 0);
+return gen_gvec_ool_zzzp(s, fns[esz], rd, rn, rm, pg, 0);
 }
 
 #define DO_ZPZZ(NAME, FEAT, name) \
@@ -749,10 +749,7 @@ TRANS_FEAT(UDIV_zpzz, aa64_sve, gen_gvec_ool_arg_zpzz, 
udiv_fns[a->esz], a, 0)
 
 static bool trans_SEL_zpzz(DisasContext *s, arg_rprr_esz *a)
 {
-if (sve_access_check(s)) {
-do_sel_z(s, a->rd, a->rn, a->rm, a->pg, a->esz);
-}
-return true;
+return do_sel_z(s, a->rd, a->rn, a->rm, a->pg, a->esz);
 }
 
 /*
@@ -6343,10 +6340,7 @@ static bool trans_MOVPRFX(DisasContext *s, arg_MOVPRFX 
*a)
 
 static bool trans_MOVPRFX_m(DisasContext *s, arg_rpr_esz *a)
 {
-if (sve_access_check(s)) {
-do_sel_z(s, a->rd, a->rn, a->rd, a->pg, a->esz);
-}
-return true;
+return do_sel_z(s, a->rd, a->rn, a->rd, a->pg, a->esz);
 }
 
 static bool trans_MOVPRFX_z(DisasContext *s, arg_rpr_esz *a)
-- 
2.34.1




[PATCH 041/114] target/arm: Introduce gen_gvec_fn_arg_zzi

2022-05-27 Thread Richard Henderson
We have two places that perform this particular operation.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 21 +
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 62bfc6fe7c..7a3b5f137a 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -273,6 +273,16 @@ static bool gen_gvec_fn_zzi(DisasContext *s, GVecGen2iFn 
*gvec_fn,
 return true;
 }
 
+static bool gen_gvec_fn_arg_zzi(DisasContext *s, GVecGen2iFn *gvec_fn,
+arg_rri_esz *a)
+{
+if (a->esz < 0) {
+/* Invalid tsz encoding -- see tszimm_esz. */
+return false;
+}
+return gen_gvec_fn_zzi(s, gvec_fn, a->esz, a->rd, a->rn, a->imm);
+}
+
 /* Invoke a vector expander on three Zregs.  */
 static bool gen_gvec_fn_zzz(DisasContext *s, GVecGen3Fn *gvec_fn,
 int esz, int rd, int rn, int rm)
@@ -3503,12 +3513,7 @@ static bool trans_ADD_zzi(DisasContext *s, arg_rri_esz 
*a)
 if (a->esz == 0 && extract32(s->insn, 13, 1)) {
 return false;
 }
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-tcg_gen_gvec_addi(a->esz, vec_full_reg_offset(s, a->rd),
-  vec_full_reg_offset(s, a->rn), a->imm, vsz, vsz);
-}
-return true;
+return gen_gvec_fn_arg_zzi(s, tcg_gen_gvec_addi, a);
 }
 
 static bool trans_SUB_zzi(DisasContext *s, arg_rri_esz *a)
@@ -6825,10 +6830,10 @@ TRANS_FEAT(ADCLT, aa64_sve2, do_adcl, a, true)
 
 static bool do_sve2_fn2i(DisasContext *s, arg_rri_esz *a, GVecGen2iFn *fn)
 {
-if (a->esz < 0 || !dc_isar_feature(aa64_sve2, s)) {
+if (!dc_isar_feature(aa64_sve2, s)) {
 return false;
 }
-return gen_gvec_fn_zzi(s, fn, a->esz, a->rd, a->rn, a->imm);
+return gen_gvec_fn_arg_zzi(s, fn, a);
 }
 
 static bool trans_SSRA(DisasContext *s, arg_rri_esz *a)
-- 
2.34.1




[PATCH 079/114] target/arm: Move sve check into gen_gvec_fn_ppp

2022-05-27 Thread Richard Henderson
Combined with the check already present in gen_mov_p,
we can simplify some special cases in trans_AND_
and trans_BIC_.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 30 --
 1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 364e419f3e..f33bc9d480 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -370,13 +370,16 @@ static void do_dupi_z(DisasContext *s, int rd, uint64_t 
word)
 }
 
 /* Invoke a vector expander on three Pregs.  */
-static void gen_gvec_fn_ppp(DisasContext *s, GVecGen3Fn *gvec_fn,
+static bool gen_gvec_fn_ppp(DisasContext *s, GVecGen3Fn *gvec_fn,
 int rd, int rn, int rm)
 {
-unsigned psz = pred_gvec_reg_size(s);
-gvec_fn(MO_64, pred_full_reg_offset(s, rd),
-pred_full_reg_offset(s, rn),
-pred_full_reg_offset(s, rm), psz, psz);
+if (sve_access_check(s)) {
+unsigned psz = pred_gvec_reg_size(s);
+gvec_fn(MO_64, pred_full_reg_offset(s, rd),
+pred_full_reg_offset(s, rn),
+pred_full_reg_offset(s, rm), psz, psz);
+}
+return true;
 }
 
 /* Invoke a vector move on two Pregs.  */
@@ -1317,19 +1320,13 @@ static bool trans_AND_(DisasContext *s, arg_rprr_s 
*a)
 };
 
 if (!a->s) {
-if (!sve_access_check(s)) {
-return true;
-}
 if (a->rn == a->rm) {
 if (a->pg == a->rn) {
-do_mov_p(s, a->rd, a->rn);
-} else {
-gen_gvec_fn_ppp(s, tcg_gen_gvec_and, a->rd, a->rn, a->pg);
+return do_mov_p(s, a->rd, a->rn);
 }
-return true;
+return gen_gvec_fn_ppp(s, tcg_gen_gvec_and, a->rd, a->rn, a->pg);
 } else if (a->pg == a->rn || a->pg == a->rm) {
-gen_gvec_fn_ppp(s, tcg_gen_gvec_and, a->rd, a->rn, a->rm);
-return true;
+return gen_gvec_fn_ppp(s, tcg_gen_gvec_and, a->rd, a->rn, a->rm);
 }
 }
 return do__flags(s, a, );
@@ -1358,10 +1355,7 @@ static bool trans_BIC_(DisasContext *s, arg_rprr_s 
*a)
 };
 
 if (!a->s && a->pg == a->rn) {
-if (sve_access_check(s)) {
-gen_gvec_fn_ppp(s, tcg_gen_gvec_andc, a->rd, a->rn, a->rm);
-}
-return true;
+return gen_gvec_fn_ppp(s, tcg_gen_gvec_andc, a->rd, a->rn, a->rm);
 }
 return do__flags(s, a, );
 }
-- 
2.34.1




[PATCH 059/114] target/arm: Use TRANS_FEAT for do_zip, do_zip_q

2022-05-27 Thread Richard Henderson
Convert SVE translation functions using do_zip*
to use TRANS_FEAT and gen_gvec_ool_arg_zzz.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 54 +-
 1 file changed, 13 insertions(+), 41 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 75c52d8ce1..7c9deb267f 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2287,48 +2287,20 @@ TRANS_FEAT(PUNPKHI, aa64_sve, do_perm_pred2, a, 1, 
gen_helper_sve_punpk_p)
  *** SVE Permute - Interleaving Group
  */
 
-static bool do_zip(DisasContext *s, arg_rrr_esz *a, bool high)
-{
-static gen_helper_gvec_3 * const fns[4] = {
-gen_helper_sve_zip_b, gen_helper_sve_zip_h,
-gen_helper_sve_zip_s, gen_helper_sve_zip_d,
-};
-unsigned vsz = vec_full_reg_size(s);
-unsigned high_ofs = high ? vsz / 2 : 0;
+static gen_helper_gvec_3 * const zip_fns[4] = {
+gen_helper_sve_zip_b, gen_helper_sve_zip_h,
+gen_helper_sve_zip_s, gen_helper_sve_zip_d,
+};
+TRANS_FEAT(ZIP1_z, aa64_sve, gen_gvec_ool_arg_zzz,
+   zip_fns[a->esz], a, 0)
+TRANS_FEAT(ZIP2_z, aa64_sve, gen_gvec_ool_arg_zzz,
+   zip_fns[a->esz], a, vec_full_reg_size(s) / 2)
 
-return gen_gvec_ool_arg_zzz(s, fns[a->esz], a, high_ofs);
-}
-
-static bool trans_ZIP1_z(DisasContext *s, arg_rrr_esz *a)
-{
-return do_zip(s, a, false);
-}
-
-static bool trans_ZIP2_z(DisasContext *s, arg_rrr_esz *a)
-{
-return do_zip(s, a, true);
-}
-
-static bool do_zip_q(DisasContext *s, arg_rrr_esz *a, bool high)
-{
-unsigned vsz = vec_full_reg_size(s);
-unsigned high_ofs = high ? QEMU_ALIGN_DOWN(vsz, 32) / 2 : 0;
-
-if (!dc_isar_feature(aa64_sve_f64mm, s)) {
-return false;
-}
-return gen_gvec_ool_arg_zzz(s, gen_helper_sve2_zip_q, a, high_ofs);
-}
-
-static bool trans_ZIP1_q(DisasContext *s, arg_rrr_esz *a)
-{
-return do_zip_q(s, a, false);
-}
-
-static bool trans_ZIP2_q(DisasContext *s, arg_rrr_esz *a)
-{
-return do_zip_q(s, a, true);
-}
+TRANS_FEAT(ZIP1_q, aa64_sve_f64mm, gen_gvec_ool_arg_zzz,
+   gen_helper_sve2_zip_q, a, 0)
+TRANS_FEAT(ZIP2_q, aa64_sve_f64mm, gen_gvec_ool_arg_zzz,
+   gen_helper_sve2_zip_q, a,
+   QEMU_ALIGN_DOWN(vec_full_reg_size(s), 32) / 2)
 
 static gen_helper_gvec_3 * const uzp_fns[4] = {
 gen_helper_sve_uzp_b, gen_helper_sve_uzp_h,
-- 
2.34.1




[PATCH 048/114] target/arm: Move sve check into do_index

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 53 ++
 1 file changed, 25 insertions(+), 28 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 52bbd1a4fa..44c2342923 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1087,12 +1087,20 @@ TRANS_FEAT(MLS, aa64_sve, do_zpzzz_ool, a, 
mls_fns[a->esz])
  *** SVE Index Generation Group
  */
 
-static void do_index(DisasContext *s, int esz, int rd,
+static bool do_index(DisasContext *s, int esz, int rd,
  TCGv_i64 start, TCGv_i64 incr)
 {
-unsigned vsz = vec_full_reg_size(s);
-TCGv_i32 desc = tcg_constant_i32(simd_desc(vsz, vsz, 0));
-TCGv_ptr t_zd = tcg_temp_new_ptr();
+unsigned vsz;
+TCGv_i32 desc;
+TCGv_ptr t_zd;
+
+if (!sve_access_check(s)) {
+return true;
+}
+
+vsz = vec_full_reg_size(s);
+desc = tcg_constant_i32(simd_desc(vsz, vsz, 0));
+t_zd = tcg_temp_new_ptr();
 
 tcg_gen_addi_ptr(t_zd, cpu_env, vec_full_reg_offset(s, rd));
 if (esz == 3) {
@@ -1115,46 +1123,35 @@ static void do_index(DisasContext *s, int esz, int rd,
 tcg_temp_free_i32(i32);
 }
 tcg_temp_free_ptr(t_zd);
+return true;
 }
 
 static bool trans_INDEX_ii(DisasContext *s, arg_INDEX_ii *a)
 {
-if (sve_access_check(s)) {
-TCGv_i64 start = tcg_constant_i64(a->imm1);
-TCGv_i64 incr = tcg_constant_i64(a->imm2);
-do_index(s, a->esz, a->rd, start, incr);
-}
-return true;
+TCGv_i64 start = tcg_constant_i64(a->imm1);
+TCGv_i64 incr = tcg_constant_i64(a->imm2);
+return do_index(s, a->esz, a->rd, start, incr);
 }
 
 static bool trans_INDEX_ir(DisasContext *s, arg_INDEX_ir *a)
 {
-if (sve_access_check(s)) {
-TCGv_i64 start = tcg_constant_i64(a->imm);
-TCGv_i64 incr = cpu_reg(s, a->rm);
-do_index(s, a->esz, a->rd, start, incr);
-}
-return true;
+TCGv_i64 start = tcg_constant_i64(a->imm);
+TCGv_i64 incr = cpu_reg(s, a->rm);
+return do_index(s, a->esz, a->rd, start, incr);
 }
 
 static bool trans_INDEX_ri(DisasContext *s, arg_INDEX_ri *a)
 {
-if (sve_access_check(s)) {
-TCGv_i64 start = cpu_reg(s, a->rn);
-TCGv_i64 incr = tcg_constant_i64(a->imm);
-do_index(s, a->esz, a->rd, start, incr);
-}
-return true;
+TCGv_i64 start = cpu_reg(s, a->rn);
+TCGv_i64 incr = tcg_constant_i64(a->imm);
+return do_index(s, a->esz, a->rd, start, incr);
 }
 
 static bool trans_INDEX_rr(DisasContext *s, arg_INDEX_rr *a)
 {
-if (sve_access_check(s)) {
-TCGv_i64 start = cpu_reg(s, a->rn);
-TCGv_i64 incr = cpu_reg(s, a->rm);
-do_index(s, a->esz, a->rd, start, incr);
-}
-return true;
+TCGv_i64 start = cpu_reg(s, a->rn);
+TCGv_i64 incr = cpu_reg(s, a->rm);
+return do_index(s, a->esz, a->rd, start, incr);
 }
 
 /*
-- 
2.34.1




[PATCH 078/114] target/arm: Use TRANS_FEAT for FMMLA

2022-05-27 Thread Richard Henderson
Being able to specify the feature predicate in TRANS_FEAT
makes it easier to split trans_FMMLA by element size,
which also happens to simplify the decode.

Signed-off-by: Richard Henderson 
---
 target/arm/sve.decode  |  7 +++
 target/arm/translate-sve.c | 27 ---
 2 files changed, 7 insertions(+), 27 deletions(-)

diff --git a/target/arm/sve.decode b/target/arm/sve.decode
index 7e79198f5b..a54feb2f61 100644
--- a/target/arm/sve.decode
+++ b/target/arm/sve.decode
@@ -1598,10 +1598,9 @@ SQRDCMLAH_  01000100 esz:2 0 rm:5 0011 rot:2 rn:5 
rd:5  ra=%reg_movprfx
 USDOT_  01000100 .. 0 . 011 110 . .  @rda_rn_rm
 
 ### SVE2 floating point matrix multiply accumulate
-{
-  BFMMLA01100100 01 1 . 111 001 . .  @rda_rn_rm_e0
-  FMMLA 01100100 .. 1 . 111 001 . .  @rda_rn_rm
-}
+BFMMLA  01100100 01 1 . 111 001 . .  @rda_rn_rm_e0
+FMMLA_s 01100100 10 1 . 111 001 . .  @rda_rn_rm_e0
+FMMLA_d 01100100 11 1 . 111 001 . .  @rda_rn_rm_e0
 
 ### SVE2 Memory Gather Load Group
 
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index a799ce3110..364e419f3e 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -7318,29 +7318,10 @@ DO_SVE2_ZPZZ_FP(FMINP, fminp)
  * SVE Integer Multiply-Add (unpredicated)
  */
 
-static bool trans_FMMLA(DisasContext *s, arg__esz *a)
-{
-gen_helper_gvec_4_ptr *fn;
-
-switch (a->esz) {
-case MO_32:
-if (!dc_isar_feature(aa64_sve_f32mm, s)) {
-return false;
-}
-fn = gen_helper_fmmla_s;
-break;
-case MO_64:
-if (!dc_isar_feature(aa64_sve_f64mm, s)) {
-return false;
-}
-fn = gen_helper_fmmla_d;
-break;
-default:
-return false;
-}
-
-return gen_gvec_fpst_(s, fn, a->rd, a->rn, a->rm, a->ra, 0, FPST_FPCR);
-}
+TRANS_FEAT(FMMLA_s, aa64_sve_f32mm, gen_gvec_fpst_, gen_helper_fmmla_s,
+   a->rd, a->rn, a->rm, a->ra, 0, FPST_FPCR)
+TRANS_FEAT(FMMLA_d, aa64_sve_f64mm, gen_gvec_fpst_, gen_helper_fmmla_d,
+   a->rd, a->rn, a->rm, a->ra, 0, FPST_FPCR)
 
 static gen_helper_gvec_4 * const sqdmlal_zzzw_fns[] = {
 NULL,   gen_helper_sve2_sqdmlal_zzzw_h,
-- 
2.34.1




[PATCH 045/114] target/arm: Introduce do_shift_zpzi

2022-05-27 Thread Richard Henderson
Share code between the various shifts using arg_rpri_esz.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 68 +-
 1 file changed, 30 insertions(+), 38 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index f15e9a30b3..c7c16863c0 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -900,20 +900,39 @@ static bool do_movz_zpz(DisasContext *s, int rd, int rn, 
int pg,
 return gen_gvec_ool_zzp(s, fns[esz], rd, rn, pg, invert);
 }
 
+static bool do_shift_zpzi(DisasContext *s, arg_rpri_esz *a, bool asr,
+  gen_helper_gvec_3 * const fns[4])
+{
+int max;
+
+if (a->esz < 0) {
+/* Invalid tsz encoding -- see tszimm_esz. */
+return false;
+}
+
+/*
+ * Shift by element size is architecturally valid.
+ * For arithmetic right-shift, it's the same as by one less.
+ * For logical shifts and ASRD, it is a zeroing operation.
+ */
+max = 8 << a->esz;
+if (a->imm >= max) {
+if (asr) {
+a->imm = max - 1;
+} else {
+return do_movz_zpz(s, a->rd, a->rd, a->pg, a->esz, true);
+}
+}
+return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
+}
+
 static bool trans_ASR_zpzi(DisasContext *s, arg_rpri_esz *a)
 {
 static gen_helper_gvec_3 * const fns[4] = {
 gen_helper_sve_asr_zpzi_b, gen_helper_sve_asr_zpzi_h,
 gen_helper_sve_asr_zpzi_s, gen_helper_sve_asr_zpzi_d,
 };
-if (a->esz < 0) {
-/* Invalid tsz encoding -- see tszimm_esz. */
-return false;
-}
-/* Shift by element size is architecturally valid.  For
-   arithmetic right-shift, it's the same as by one less. */
-a->imm = MIN(a->imm, (8 << a->esz) - 1);
-return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
+return do_shift_zpzi(s, a, true, fns);
 }
 
 static bool trans_LSR_zpzi(DisasContext *s, arg_rpri_esz *a)
@@ -922,16 +941,7 @@ static bool trans_LSR_zpzi(DisasContext *s, arg_rpri_esz 
*a)
 gen_helper_sve_lsr_zpzi_b, gen_helper_sve_lsr_zpzi_h,
 gen_helper_sve_lsr_zpzi_s, gen_helper_sve_lsr_zpzi_d,
 };
-if (a->esz < 0) {
-return false;
-}
-/* Shift by element size is architecturally valid.
-   For logical shifts, it is a zeroing operation.  */
-if (a->imm >= (8 << a->esz)) {
-return do_movz_zpz(s, a->rd, a->rd, a->pg, a->esz, true);
-} else {
-return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
-}
+return do_shift_zpzi(s, a, false, fns);
 }
 
 static bool trans_LSL_zpzi(DisasContext *s, arg_rpri_esz *a)
@@ -940,16 +950,7 @@ static bool trans_LSL_zpzi(DisasContext *s, arg_rpri_esz 
*a)
 gen_helper_sve_lsl_zpzi_b, gen_helper_sve_lsl_zpzi_h,
 gen_helper_sve_lsl_zpzi_s, gen_helper_sve_lsl_zpzi_d,
 };
-if (a->esz < 0) {
-return false;
-}
-/* Shift by element size is architecturally valid.
-   For logical shifts, it is a zeroing operation.  */
-if (a->imm >= (8 << a->esz)) {
-return do_movz_zpz(s, a->rd, a->rd, a->pg, a->esz, true);
-} else {
-return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
-}
+return do_shift_zpzi(s, a, false, fns);
 }
 
 static bool trans_ASRD(DisasContext *s, arg_rpri_esz *a)
@@ -958,16 +959,7 @@ static bool trans_ASRD(DisasContext *s, arg_rpri_esz *a)
 gen_helper_sve_asrd_b, gen_helper_sve_asrd_h,
 gen_helper_sve_asrd_s, gen_helper_sve_asrd_d,
 };
-if (a->esz < 0) {
-return false;
-}
-/* Shift by element size is architecturally valid.  For arithmetic
-   right shift for division, it is a zeroing operation.  */
-if (a->imm >= (8 << a->esz)) {
-return do_movz_zpz(s, a->rd, a->rd, a->pg, a->esz, true);
-} else {
-return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
-}
+return do_shift_zpzi(s, a, false, fns);
 }
 
 static gen_helper_gvec_3 * const sqshl_zpzi_fns[4] = {
-- 
2.34.1




[PATCH 039/114] target/arm: Use TRANS_FEAT for do_zz_dbm

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 17 +++--
 1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 7938c5393e..6fa721eca6 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2046,20 +2046,9 @@ static bool do_zz_dbm(DisasContext *s, arg_rr_dbm *a, 
GVecGen2iFn *gvec_fn)
 return gen_gvec_fn_zzi(s, gvec_fn, MO_64, a->rd, a->rn, imm);
 }
 
-static bool trans_AND_zzi(DisasContext *s, arg_rr_dbm *a)
-{
-return do_zz_dbm(s, a, tcg_gen_gvec_andi);
-}
-
-static bool trans_ORR_zzi(DisasContext *s, arg_rr_dbm *a)
-{
-return do_zz_dbm(s, a, tcg_gen_gvec_ori);
-}
-
-static bool trans_EOR_zzi(DisasContext *s, arg_rr_dbm *a)
-{
-return do_zz_dbm(s, a, tcg_gen_gvec_xori);
-}
+TRANS_FEAT(AND_zzi, aa64_sve, do_zz_dbm, a, tcg_gen_gvec_andi)
+TRANS_FEAT(ORR_zzi, aa64_sve, do_zz_dbm, a, tcg_gen_gvec_ori)
+TRANS_FEAT(EOR_zzi, aa64_sve, do_zz_dbm, a, tcg_gen_gvec_xori)
 
 static bool trans_DUPM(DisasContext *s, arg_DUPM *a)
 {
-- 
2.34.1




[PATCH 052/114] target/arm: Use TRANS_FEAT for RDFFR, WRFFR

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index ce6e000f6f..6fd9a42ef9 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1636,15 +1636,8 @@ static bool trans_RDFFR_p(DisasContext *s, arg_RDFFR_p 
*a)
 return trans_AND_(s, _a);
 }
 
-static bool trans_RDFFR(DisasContext *s, arg_RDFFR *a)
-{
-return do_mov_p(s, a->rd, FFR_PRED_NUM);
-}
-
-static bool trans_WRFFR(DisasContext *s, arg_WRFFR *a)
-{
-return do_mov_p(s, FFR_PRED_NUM, a->rn);
-}
+TRANS_FEAT(RDFFR, aa64_sve, do_mov_p, a->rd, FFR_PRED_NUM)
+TRANS_FEAT(WRFFR, aa64_sve, do_mov_p, FFR_PRED_NUM, a->rn)
 
 static bool do_pfirst_pnext(DisasContext *s, arg_rr_esz *a,
 void (*gen_fn)(TCGv_i32, TCGv_ptr,
-- 
2.34.1




[PATCH 071/114] target/arm: Reject dup_i w/ shifted byte early

2022-05-27 Thread Richard Henderson
Remove the unparsed extraction in trans_DUP_i,
which is intended to reject an 8-bit shift of
an 8-bit constant for 8-bit element.

Signed-off-by: Richard Henderson 
---
 target/arm/sve.decode  |  5 -
 target/arm/translate-sve.c | 10 ++
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/target/arm/sve.decode b/target/arm/sve.decode
index 0388cce3bd..c02da0a082 100644
--- a/target/arm/sve.decode
+++ b/target/arm/sve.decode
@@ -787,7 +787,10 @@ WHILE_ptr   00100101 esz:2 1 rm:5 001 100 rn:5 rw:1 
rd:4
 FDUP00100101 esz:2 111 00 1110 imm:8 rd:5
 
 # SVE broadcast integer immediate (unpredicated)
-DUP_i   00100101 esz:2 111 00 011 .  rd:5   imm=%sh8_i8s
+{
+  INVALID   00100101 00111 00 011 1  -
+  DUP_i 00100101 esz:2 111 00 011 .  rd:5   imm=%sh8_i8s
+}
 
 # SVE integer add/subtract immediate (unpredicated)
 ADD_zzi 00100101 .. 100 000 11 .  . @rdn_sh_i8u
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index c0781ecf60..14faef0564 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -403,6 +403,12 @@ const uint64_t pred_esz_masks[4] = {
 0xull, 0x0101010101010101ull
 };
 
+static bool trans_INVALID(DisasContext *s, arg_INVALID *a)
+{
+unallocated_encoding(s);
+return true;
+}
+
 /*
  *** SVE Logical - Unpredicated Group
  */
@@ -3246,13 +3252,9 @@ static bool trans_FDUP(DisasContext *s, arg_FDUP *a)
 
 static bool trans_DUP_i(DisasContext *s, arg_DUP_i *a)
 {
-if (a->esz == 0 && extract32(s->insn, 13, 1)) {
-return false;
-}
 if (sve_access_check(s)) {
 unsigned vsz = vec_full_reg_size(s);
 int dofs = vec_full_reg_offset(s, a->rd);
-
 tcg_gen_gvec_dup_imm(a->esz, dofs, vsz, vsz, a->imm);
 }
 return true;
-- 
2.34.1




[PATCH 037/114] target/arm: Use TRANS_FEAT for do_sve2_zzzz_fn

2022-05-27 Thread Richard Henderson
Convert SVE translation functions using do_sve2__fn
to use TRANS_FEAT and gen_gvec_fn_arg_.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 38 ++
 1 file changed, 6 insertions(+), 32 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index e0b083f861..f89c78a23e 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -491,14 +491,6 @@ static bool trans_XAR(DisasContext *s, arg_rrri_esz *a)
 return true;
 }
 
-static bool do_sve2__fn(DisasContext *s, arg__esz *a, GVecGen4Fn *fn)
-{
-if (!dc_isar_feature(aa64_sve2, s)) {
-return false;
-}
-return gen_gvec_fn_arg_(s, fn, a);
-}
-
 static void gen_eor3_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
 {
 tcg_gen_xor_i64(d, n, m);
@@ -525,10 +517,7 @@ static void gen_eor3(unsigned vece, uint32_t d, uint32_t 
n, uint32_t m,
 tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, );
 }
 
-static bool trans_EOR3(DisasContext *s, arg__esz *a)
-{
-return do_sve2__fn(s, a, gen_eor3);
-}
+TRANS_FEAT(EOR3, aa64_sve2, gen_gvec_fn_arg_, gen_eor3, a)
 
 static void gen_bcax_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
 {
@@ -556,10 +545,7 @@ static void gen_bcax(unsigned vece, uint32_t d, uint32_t 
n, uint32_t m,
 tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, );
 }
 
-static bool trans_BCAX(DisasContext *s, arg__esz *a)
-{
-return do_sve2__fn(s, a, gen_bcax);
-}
+TRANS_FEAT(BCAX, aa64_sve2, gen_gvec_fn_arg_, gen_bcax, a)
 
 static void gen_bsl(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
 uint32_t a, uint32_t oprsz, uint32_t maxsz)
@@ -568,10 +554,7 @@ static void gen_bsl(unsigned vece, uint32_t d, uint32_t n, 
uint32_t m,
 tcg_gen_gvec_bitsel(vece, d, a, n, m, oprsz, maxsz);
 }
 
-static bool trans_BSL(DisasContext *s, arg__esz *a)
-{
-return do_sve2__fn(s, a, gen_bsl);
-}
+TRANS_FEAT(BSL, aa64_sve2, gen_gvec_fn_arg_, gen_bsl, a)
 
 static void gen_bsl1n_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
 {
@@ -606,10 +589,7 @@ static void gen_bsl1n(unsigned vece, uint32_t d, uint32_t 
n, uint32_t m,
 tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, );
 }
 
-static bool trans_BSL1N(DisasContext *s, arg__esz *a)
-{
-return do_sve2__fn(s, a, gen_bsl1n);
-}
+TRANS_FEAT(BSL1N, aa64_sve2, gen_gvec_fn_arg_, gen_bsl1n, a)
 
 static void gen_bsl2n_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
 {
@@ -653,10 +633,7 @@ static void gen_bsl2n(unsigned vece, uint32_t d, uint32_t 
n, uint32_t m,
 tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, );
 }
 
-static bool trans_BSL2N(DisasContext *s, arg__esz *a)
-{
-return do_sve2__fn(s, a, gen_bsl2n);
-}
+TRANS_FEAT(BSL2N, aa64_sve2, gen_gvec_fn_arg_, gen_bsl2n, a)
 
 static void gen_nbsl_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_i64 k)
 {
@@ -685,10 +662,7 @@ static void gen_nbsl(unsigned vece, uint32_t d, uint32_t 
n, uint32_t m,
 tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, );
 }
 
-static bool trans_NBSL(DisasContext *s, arg__esz *a)
-{
-return do_sve2__fn(s, a, gen_nbsl);
-}
+TRANS_FEAT(NBSL, aa64_sve2, gen_gvec_fn_arg_, gen_nbsl, a)
 
 /*
  *** SVE Integer Arithmetic - Unpredicated Group
-- 
2.34.1




[PATCH 051/114] target/arm: Use TRANS_FEAT for do_predset

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 19 +--
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index c8eb2c684b..ce6e000f6f 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1616,22 +1616,13 @@ static bool do_predset(DisasContext *s, int esz, int 
rd, int pat, bool setflag)
 return true;
 }
 
-static bool trans_PTRUE(DisasContext *s, arg_PTRUE *a)
-{
-return do_predset(s, a->esz, a->rd, a->pat, a->s);
-}
+TRANS_FEAT(PTRUE, aa64_sve, do_predset, a->esz, a->rd, a->pat, a->s)
 
-static bool trans_SETFFR(DisasContext *s, arg_SETFFR *a)
-{
-/* Note pat == 31 is #all, to set all elements.  */
-return do_predset(s, 0, FFR_PRED_NUM, 31, false);
-}
+/* Note pat == 31 is #all, to set all elements.  */
+TRANS_FEAT(SETFFR, aa64_sve, do_predset, 0, FFR_PRED_NUM, 31, false)
 
-static bool trans_PFALSE(DisasContext *s, arg_PFALSE *a)
-{
-/* Note pat == 32 is #unimp, to set no elements.  */
-return do_predset(s, 0, a->rd, 32, false);
-}
+/* Note pat == 32 is #unimp, to set no elements.  */
+TRANS_FEAT(PFALSE, aa64_sve, do_predset, 0, a->rd, 32, false)
 
 static bool trans_RDFFR_p(DisasContext *s, arg_RDFFR_p *a)
 {
-- 
2.34.1




[PATCH 044/114] target/arm: Use TRANS_FEAT for do_shift_imm

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 17 +++--
 1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 6103bd7f1d..f15e9a30b3 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1054,20 +1054,9 @@ static bool do_shift_imm(DisasContext *s, arg_rri_esz 
*a, bool asr,
 return true;
 }
 
-static bool trans_ASR_zzi(DisasContext *s, arg_rri_esz *a)
-{
-return do_shift_imm(s, a, true, tcg_gen_gvec_sari);
-}
-
-static bool trans_LSR_zzi(DisasContext *s, arg_rri_esz *a)
-{
-return do_shift_imm(s, a, false, tcg_gen_gvec_shri);
-}
-
-static bool trans_LSL_zzi(DisasContext *s, arg_rri_esz *a)
-{
-return do_shift_imm(s, a, false, tcg_gen_gvec_shli);
-}
+TRANS_FEAT(ASR_zzi, aa64_sve, do_shift_imm, a, true, tcg_gen_gvec_sari)
+TRANS_FEAT(LSR_zzi, aa64_sve, do_shift_imm, a, false, tcg_gen_gvec_shri)
+TRANS_FEAT(LSL_zzi, aa64_sve, do_shift_imm, a, false, tcg_gen_gvec_shli)
 
 #define DO_ZZW(NAME, name) \
 static gen_helper_gvec_3 * const name##_zzw_fns[4] = {\
-- 
2.34.1




[PATCH 038/114] target/arm: Introduce gen_gvec_fn_zzi

2022-05-27 Thread Richard Henderson
We have two places that perform this particular operation.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 30 +-
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index f89c78a23e..7938c5393e 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -258,6 +258,21 @@ static bool gen_gvec_ool_arg_zpzz(DisasContext *s, 
gen_helper_gvec_4 *fn,
 return gen_gvec_ool_zzzp(s, fn, a->rd, a->rn, a->rm, a->pg, data);
 }
 
+/* Invoke a vector expander on two Zregs and an immediate.  */
+static bool gen_gvec_fn_zzi(DisasContext *s, GVecGen2iFn *gvec_fn,
+int esz, int rd, int rn, uint64_t imm)
+{
+if (gvec_fn == NULL) {
+return false;
+}
+if (sve_access_check(s)) {
+unsigned vsz = vec_full_reg_size(s);
+gvec_fn(esz, vec_full_reg_offset(s, rd),
+vec_full_reg_offset(s, rn), imm, vsz, vsz);
+}
+return true;
+}
+
 /* Invoke a vector expander on three Zregs.  */
 static bool gen_gvec_fn_zzz(DisasContext *s, GVecGen3Fn *gvec_fn,
 int esz, int rd, int rn, int rm)
@@ -2028,12 +2043,7 @@ static bool do_zz_dbm(DisasContext *s, arg_rr_dbm *a, 
GVecGen2iFn *gvec_fn)
 extract32(a->dbm, 6, 6))) {
 return false;
 }
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-gvec_fn(MO_64, vec_full_reg_offset(s, a->rd),
-vec_full_reg_offset(s, a->rn), imm, vsz, vsz);
-}
-return true;
+return gen_gvec_fn_zzi(s, gvec_fn, MO_64, a->rd, a->rn, imm);
 }
 
 static bool trans_AND_zzi(DisasContext *s, arg_rr_dbm *a)
@@ -6835,13 +6845,7 @@ static bool do_sve2_fn2i(DisasContext *s, arg_rri_esz 
*a, GVecGen2iFn *fn)
 if (a->esz < 0 || !dc_isar_feature(aa64_sve2, s)) {
 return false;
 }
-if (sve_access_check(s)) {
-unsigned vsz = vec_full_reg_size(s);
-unsigned rd_ofs = vec_full_reg_offset(s, a->rd);
-unsigned rn_ofs = vec_full_reg_offset(s, a->rn);
-fn(a->esz, rd_ofs, rn_ofs, a->imm, vsz, vsz);
-}
-return true;
+return gen_gvec_fn_zzi(s, fn, a->esz, a->rd, a->rn, a->imm);
 }
 
 static bool trans_SSRA(DisasContext *s, arg_rri_esz *a)
-- 
2.34.1




[PATCH 073/114] target/arm: Reject copy w/ shifted byte early

2022-05-27 Thread Richard Henderson
Remove the unparsed extractions in trans_CPY_{m,z}_i which are intended
to reject an 8-bit shift of an 8-bit constant for 8-bit element.

Signed-off-by: Richard Henderson 
---
 target/arm/sve.decode  | 10 --
 target/arm/translate-sve.c |  6 --
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/target/arm/sve.decode b/target/arm/sve.decode
index 8cff63cf25..7e79198f5b 100644
--- a/target/arm/sve.decode
+++ b/target/arm/sve.decode
@@ -528,8 +528,14 @@ DUPM0101 11  dbm:13 rd:5
 FCPY0101 .. 01  110 imm:8 . @rdn_pg4
 
 # SVE copy integer immediate (predicated)
-CPY_m_i 0101 .. 01  01 .  .   @rdn_pg4 imm=%sh8_i8s
-CPY_z_i 0101 .. 01  00 .  .   @rdn_pg4 imm=%sh8_i8s
+{
+  INVALID   0101 00 01  01 1  -
+  CPY_m_i   0101 .. 01  01 .  .   @rdn_pg4 imm=%sh8_i8s
+}
+{
+  INVALID   0101 00 01  00 1  -
+  CPY_z_i   0101 .. 01  00 .  .   @rdn_pg4 imm=%sh8_i8s
+}
 
 ### SVE Permute - Extract Group
 
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index bf988cab3e..83980f5ee6 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2024,9 +2024,6 @@ static bool trans_FCPY(DisasContext *s, arg_FCPY *a)
 
 static bool trans_CPY_m_i(DisasContext *s, arg_rpri_esz *a)
 {
-if (a->esz == 0 && extract32(s->insn, 13, 1)) {
-return false;
-}
 if (sve_access_check(s)) {
 do_cpy_m(s, a->esz, a->rd, a->rn, a->pg, tcg_constant_i64(a->imm));
 }
@@ -2040,9 +2037,6 @@ static bool trans_CPY_z_i(DisasContext *s, arg_CPY_z_i *a)
 gen_helper_sve_cpy_z_s, gen_helper_sve_cpy_z_d,
 };
 
-if (a->esz == 0 && extract32(s->insn, 13, 1)) {
-return false;
-}
 if (sve_access_check(s)) {
 unsigned vsz = vec_full_reg_size(s);
 tcg_gen_gvec_2i_ool(vec_full_reg_offset(s, a->rd),
-- 
2.34.1




[PATCH 042/114] target/arm: Use TRANS_FEAT for do_sve2_fn2i

2022-05-27 Thread Richard Henderson
Convert SVE translation functions using do_sve2_fn2i
to use TRANS_FEAT and gen_gvec_fn_arg_zzi.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 43 ++
 1 file changed, 6 insertions(+), 37 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 7a3b5f137a..911d2e28bf 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -6828,43 +6828,12 @@ static bool do_adcl(DisasContext *s, arg__esz *a, 
bool sel)
 TRANS_FEAT(ADCLB, aa64_sve2, do_adcl, a, false)
 TRANS_FEAT(ADCLT, aa64_sve2, do_adcl, a, true)
 
-static bool do_sve2_fn2i(DisasContext *s, arg_rri_esz *a, GVecGen2iFn *fn)
-{
-if (!dc_isar_feature(aa64_sve2, s)) {
-return false;
-}
-return gen_gvec_fn_arg_zzi(s, fn, a);
-}
-
-static bool trans_SSRA(DisasContext *s, arg_rri_esz *a)
-{
-return do_sve2_fn2i(s, a, gen_gvec_ssra);
-}
-
-static bool trans_USRA(DisasContext *s, arg_rri_esz *a)
-{
-return do_sve2_fn2i(s, a, gen_gvec_usra);
-}
-
-static bool trans_SRSRA(DisasContext *s, arg_rri_esz *a)
-{
-return do_sve2_fn2i(s, a, gen_gvec_srsra);
-}
-
-static bool trans_URSRA(DisasContext *s, arg_rri_esz *a)
-{
-return do_sve2_fn2i(s, a, gen_gvec_ursra);
-}
-
-static bool trans_SRI(DisasContext *s, arg_rri_esz *a)
-{
-return do_sve2_fn2i(s, a, gen_gvec_sri);
-}
-
-static bool trans_SLI(DisasContext *s, arg_rri_esz *a)
-{
-return do_sve2_fn2i(s, a, gen_gvec_sli);
-}
+TRANS_FEAT(SSRA, aa64_sve2, gen_gvec_fn_arg_zzi, gen_gvec_ssra, a)
+TRANS_FEAT(USRA, aa64_sve2, gen_gvec_fn_arg_zzi, gen_gvec_usra, a)
+TRANS_FEAT(SRSRA, aa64_sve2, gen_gvec_fn_arg_zzi, gen_gvec_srsra, a)
+TRANS_FEAT(URSRA, aa64_sve2, gen_gvec_fn_arg_zzi, gen_gvec_ursra, a)
+TRANS_FEAT(SRI, aa64_sve2, gen_gvec_fn_arg_zzi, gen_gvec_sri, a)
+TRANS_FEAT(SLI, aa64_sve2, gen_gvec_fn_arg_zzi, gen_gvec_sli, a)
 
 TRANS_FEAT(SABA, aa64_sve2, gen_gvec_fn_arg_zzz, gen_gvec_saba, a)
 TRANS_FEAT(UABA, aa64_sve2, gen_gvec_fn_arg_zzz, gen_gvec_uaba, a)
-- 
2.34.1




[PATCH 076/114] target/arm: Use TRANS_FEAT for do_zzi_ool

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index e6434589f4..b8bd1047b0 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -3330,14 +3330,11 @@ static bool do_zzi_ool(DisasContext *s, arg_rri_esz *a, 
gen_helper_gvec_2i *fn)
 }
 
 #define DO_ZZI(NAME, name) \
-static bool trans_##NAME##_zzi(DisasContext *s, arg_rri_esz *a) \
-{   \
-static gen_helper_gvec_2i * const fns[4] = {\
+static gen_helper_gvec_2i * const name##i_fns[4] = {\
 gen_helper_sve_##name##i_b, gen_helper_sve_##name##i_h, \
 gen_helper_sve_##name##i_s, gen_helper_sve_##name##i_d, \
 };  \
-return do_zzi_ool(s, a, fns[a->esz]);   \
-}
+TRANS_FEAT(NAME##_zzi, aa64_sve, do_zzi_ool, a, name##i_fns[a->esz])
 
 DO_ZZI(SMAX, smax)
 DO_ZZI(UMAX, umax)
-- 
2.34.1




[PATCH 047/114] target/arm: Use TRANS_FEAT for do_zpzzz_ool

2022-05-27 Thread Richard Henderson
Remove the DO_ZPZZZ macro, as it had just the two uses.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 23 ++-
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 98f9cfa86c..52bbd1a4fa 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1071,20 +1071,17 @@ static bool do_zpzzz_ool(DisasContext *s, arg_rprrr_esz 
*a,
 return true;
 }
 
-#define DO_ZPZZZ(NAME, name) \
-static bool trans_##NAME(DisasContext *s, arg_rprrr_esz *a)  \
-{\
-static gen_helper_gvec_5 * const fns[4] = {  \
-gen_helper_sve_##name##_b, gen_helper_sve_##name##_h,\
-gen_helper_sve_##name##_s, gen_helper_sve_##name##_d,\
-};   \
-return do_zpzzz_ool(s, a, fns[a->esz]);  \
-}
+static gen_helper_gvec_5 * const mla_fns[4] = {
+gen_helper_sve_mla_b, gen_helper_sve_mla_h,
+gen_helper_sve_mla_s, gen_helper_sve_mla_d,
+};
+TRANS_FEAT(MLA, aa64_sve, do_zpzzz_ool, a, mla_fns[a->esz])
 
-DO_ZPZZZ(MLA, mla)
-DO_ZPZZZ(MLS, mls)
-
-#undef DO_ZPZZZ
+static gen_helper_gvec_5 * const mls_fns[4] = {
+gen_helper_sve_mls_b, gen_helper_sve_mls_h,
+gen_helper_sve_mls_s, gen_helper_sve_mls_d,
+};
+TRANS_FEAT(MLS, aa64_sve, do_zpzzz_ool, a, mls_fns[a->esz])
 
 /*
  *** SVE Index Generation Group
-- 
2.34.1




[PATCH 034/114] target/arm: Use TRANS_FEAT for do_sve2_fn_zzz

2022-05-27 Thread Richard Henderson
Convert SVE translation functions using do_sve2_fn_zzz
to use TRANS_FEAT and gen_gvec_fn_arg_zzz.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 19 ++-
 1 file changed, 2 insertions(+), 17 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index ddb34cad8e..e92fef2304 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -6897,23 +6897,8 @@ static bool trans_SLI(DisasContext *s, arg_rri_esz *a)
 return do_sve2_fn2i(s, a, gen_gvec_sli);
 }
 
-static bool do_sve2_fn_zzz(DisasContext *s, arg_rrr_esz *a, GVecGen3Fn *fn)
-{
-if (!dc_isar_feature(aa64_sve2, s)) {
-return false;
-}
-return gen_gvec_fn_arg_zzz(s, fn, a);
-}
-
-static bool trans_SABA(DisasContext *s, arg_rrr_esz *a)
-{
-return do_sve2_fn_zzz(s, a, gen_gvec_saba);
-}
-
-static bool trans_UABA(DisasContext *s, arg_rrr_esz *a)
-{
-return do_sve2_fn_zzz(s, a, gen_gvec_uaba);
-}
+TRANS_FEAT(SABA, aa64_sve2, gen_gvec_fn_arg_zzz, gen_gvec_saba, a)
+TRANS_FEAT(UABA, aa64_sve2, gen_gvec_fn_arg_zzz, gen_gvec_uaba, a)
 
 static bool do_sve2_narrow_extract(DisasContext *s, arg_rri_esz *a,
const GVecGen2 ops[3])
-- 
2.34.1




[PATCH 032/114] target/arm: More use of gen_gvec_fn_arg_zzz

2022-05-27 Thread Richard Henderson
Two uses of gen_gvec_fn_zzz can pass on arg_rrr_esz instead.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 1b3afcc24c..2dbf296128 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -6425,7 +6425,7 @@ static bool trans_MUL_zzz(DisasContext *s, arg_rrr_esz *a)
 if (!dc_isar_feature(aa64_sve2, s)) {
 return false;
 }
-return gen_gvec_fn_zzz(s, tcg_gen_gvec_mul, a->esz, a->rd, a->rn, a->rm);
+return gen_gvec_fn_arg_zzz(s, tcg_gen_gvec_mul, a);
 }
 
 static gen_helper_gvec_3 * const smulh_zzz_fns[4] = {
@@ -6946,7 +6946,7 @@ static bool do_sve2_fn_zzz(DisasContext *s, arg_rrr_esz 
*a, GVecGen3Fn *fn)
 if (!dc_isar_feature(aa64_sve2, s)) {
 return false;
 }
-return gen_gvec_fn_zzz(s, fn, a->esz, a->rd, a->rn, a->rm);
+return gen_gvec_fn_arg_zzz(s, fn, a);
 }
 
 static bool trans_SABA(DisasContext *s, arg_rrr_esz *a)
-- 
2.34.1




[PATCH 046/114] target/arm: Use TRANS_FEAT for do_shift_zpzi

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 52 +++---
 1 file changed, 20 insertions(+), 32 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index c7c16863c0..98f9cfa86c 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -926,41 +926,29 @@ static bool do_shift_zpzi(DisasContext *s, arg_rpri_esz 
*a, bool asr,
 return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
 }
 
-static bool trans_ASR_zpzi(DisasContext *s, arg_rpri_esz *a)
-{
-static gen_helper_gvec_3 * const fns[4] = {
-gen_helper_sve_asr_zpzi_b, gen_helper_sve_asr_zpzi_h,
-gen_helper_sve_asr_zpzi_s, gen_helper_sve_asr_zpzi_d,
-};
-return do_shift_zpzi(s, a, true, fns);
-}
+static gen_helper_gvec_3 * const asr_zpzi_fns[4] = {
+gen_helper_sve_asr_zpzi_b, gen_helper_sve_asr_zpzi_h,
+gen_helper_sve_asr_zpzi_s, gen_helper_sve_asr_zpzi_d,
+};
+TRANS_FEAT(ASR_zpzi, aa64_sve, do_shift_zpzi, a, true, asr_zpzi_fns)
 
-static bool trans_LSR_zpzi(DisasContext *s, arg_rpri_esz *a)
-{
-static gen_helper_gvec_3 * const fns[4] = {
-gen_helper_sve_lsr_zpzi_b, gen_helper_sve_lsr_zpzi_h,
-gen_helper_sve_lsr_zpzi_s, gen_helper_sve_lsr_zpzi_d,
-};
-return do_shift_zpzi(s, a, false, fns);
-}
+static gen_helper_gvec_3 * const lsr_zpzi_fns[4] = {
+gen_helper_sve_lsr_zpzi_b, gen_helper_sve_lsr_zpzi_h,
+gen_helper_sve_lsr_zpzi_s, gen_helper_sve_lsr_zpzi_d,
+};
+TRANS_FEAT(LSR_zpzi, aa64_sve, do_shift_zpzi, a, false, lsr_zpzi_fns)
 
-static bool trans_LSL_zpzi(DisasContext *s, arg_rpri_esz *a)
-{
-static gen_helper_gvec_3 * const fns[4] = {
-gen_helper_sve_lsl_zpzi_b, gen_helper_sve_lsl_zpzi_h,
-gen_helper_sve_lsl_zpzi_s, gen_helper_sve_lsl_zpzi_d,
-};
-return do_shift_zpzi(s, a, false, fns);
-}
+static gen_helper_gvec_3 * const lsl_zpzi_fns[4] = {
+gen_helper_sve_lsl_zpzi_b, gen_helper_sve_lsl_zpzi_h,
+gen_helper_sve_lsl_zpzi_s, gen_helper_sve_lsl_zpzi_d,
+};
+TRANS_FEAT(LSL_zpzi, aa64_sve, do_shift_zpzi, a, false, lsl_zpzi_fns)
 
-static bool trans_ASRD(DisasContext *s, arg_rpri_esz *a)
-{
-static gen_helper_gvec_3 * const fns[4] = {
-gen_helper_sve_asrd_b, gen_helper_sve_asrd_h,
-gen_helper_sve_asrd_s, gen_helper_sve_asrd_d,
-};
-return do_shift_zpzi(s, a, false, fns);
-}
+static gen_helper_gvec_3 * const asrd_fns[4] = {
+gen_helper_sve_asrd_b, gen_helper_sve_asrd_h,
+gen_helper_sve_asrd_s, gen_helper_sve_asrd_d,
+};
+TRANS_FEAT(ASRD, aa64_sve, do_shift_zpzi, a, false, asrd_fns)
 
 static gen_helper_gvec_3 * const sqshl_zpzi_fns[4] = {
 gen_helper_sve2_sqshl_zpzi_b, gen_helper_sve2_sqshl_zpzi_h,
-- 
2.34.1




[PATCH 067/114] target/arm: Use TRANS_FEAT for do_sve2_ppzz_flags

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 28 
 1 file changed, 8 insertions(+), 20 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 73b5b67c25..22acd5ead0 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -7319,27 +7319,15 @@ DO_SVE2_ZZZ_NARROW(SUBHNT, subhnt)
 DO_SVE2_ZZZ_NARROW(RSUBHNB, rsubhnb)
 DO_SVE2_ZZZ_NARROW(RSUBHNT, rsubhnt)
 
-static bool do_sve2_ppzz_flags(DisasContext *s, arg_rprr_esz *a,
-   gen_helper_gvec_flags_4 *fn)
-{
-if (!dc_isar_feature(aa64_sve2, s)) {
-return false;
-}
-return do_ppzz_flags(s, a, fn);
-}
+static gen_helper_gvec_flags_4 * const match_fns[4] = {
+gen_helper_sve2_match_ppzz_b, gen_helper_sve2_match_ppzz_h, NULL, NULL
+};
+TRANS_FEAT(MATCH, aa64_sve2, do_ppzz_flags, a, match_fns[a->esz])
 
-#define DO_SVE2_PPZZ_MATCH(NAME, name)  \
-static bool trans_##NAME(DisasContext *s, arg_rprr_esz *a)  \
-{   \
-static gen_helper_gvec_flags_4 * const fns[4] = {   \
-gen_helper_sve2_##name##_ppzz_b, gen_helper_sve2_##name##_ppzz_h,   \
-NULL,NULL   \
-};  \
-return do_sve2_ppzz_flags(s, a, fns[a->esz]);   \
-}
-
-DO_SVE2_PPZZ_MATCH(MATCH, match)
-DO_SVE2_PPZZ_MATCH(NMATCH, nmatch)
+static gen_helper_gvec_flags_4 * const nmatch_fns[4] = {
+gen_helper_sve2_nmatch_ppzz_b, gen_helper_sve2_nmatch_ppzz_h, NULL, NULL
+};
+TRANS_FEAT(NMATCH, aa64_sve2, do_ppzz_flags, a, nmatch_fns[a->esz])
 
 static gen_helper_gvec_4 * const histcnt_fns[4] = {
 NULL, NULL, gen_helper_sve2_histcnt_s, gen_helper_sve2_histcnt_d
-- 
2.34.1




[PATCH 031/114] target/arm: Rename do_zzz_fn to gen_gvec_fn_arg_zzz

2022-05-27 Thread Richard Henderson
Rename the function to match gen_gvec_fn_zzz,
and move to be adjacent.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 31 ---
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 3af4626e58..1b3afcc24c 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -274,6 +274,12 @@ static bool gen_gvec_fn_zzz(DisasContext *s, GVecGen3Fn 
*gvec_fn,
 return true;
 }
 
+static bool gen_gvec_fn_arg_zzz(DisasContext *s, GVecGen3Fn *fn,
+arg_rrr_esz *a)
+{
+return gen_gvec_fn_zzz(s, fn, a->esz, a->rd, a->rn, a->rm);
+}
+
 /* Invoke a vector expander on four Zregs.  */
 static void gen_gvec_fn_(DisasContext *s, GVecGen4Fn *gvec_fn,
  int esz, int rd, int rn, int rm, int ra)
@@ -370,29 +376,24 @@ const uint64_t pred_esz_masks[4] = {
  *** SVE Logical - Unpredicated Group
  */
 
-static bool do_zzz_fn(DisasContext *s, arg_rrr_esz *a, GVecGen3Fn *gvec_fn)
-{
-return gen_gvec_fn_zzz(s, gvec_fn, a->esz, a->rd, a->rn, a->rm);
-}
-
 static bool trans_AND_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_zzz_fn(s, a, tcg_gen_gvec_and);
+return gen_gvec_fn_arg_zzz(s, tcg_gen_gvec_and, a);
 }
 
 static bool trans_ORR_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_zzz_fn(s, a, tcg_gen_gvec_or);
+return gen_gvec_fn_arg_zzz(s, tcg_gen_gvec_or, a);
 }
 
 static bool trans_EOR_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_zzz_fn(s, a, tcg_gen_gvec_xor);
+return gen_gvec_fn_arg_zzz(s, tcg_gen_gvec_xor, a);
 }
 
 static bool trans_BIC_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_zzz_fn(s, a, tcg_gen_gvec_andc);
+return gen_gvec_fn_arg_zzz(s, tcg_gen_gvec_andc, a);
 }
 
 static void gen_xar8_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, int64_t sh)
@@ -707,32 +708,32 @@ static bool trans_NBSL(DisasContext *s, arg__esz *a)
 
 static bool trans_ADD_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_zzz_fn(s, a, tcg_gen_gvec_add);
+return gen_gvec_fn_arg_zzz(s, tcg_gen_gvec_add, a);
 }
 
 static bool trans_SUB_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_zzz_fn(s, a, tcg_gen_gvec_sub);
+return gen_gvec_fn_arg_zzz(s, tcg_gen_gvec_sub, a);
 }
 
 static bool trans_SQADD_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_zzz_fn(s, a, tcg_gen_gvec_ssadd);
+return gen_gvec_fn_arg_zzz(s, tcg_gen_gvec_ssadd, a);
 }
 
 static bool trans_SQSUB_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_zzz_fn(s, a, tcg_gen_gvec_sssub);
+return gen_gvec_fn_arg_zzz(s, tcg_gen_gvec_sssub, a);
 }
 
 static bool trans_UQADD_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_zzz_fn(s, a, tcg_gen_gvec_usadd);
+return gen_gvec_fn_arg_zzz(s, tcg_gen_gvec_usadd, a);
 }
 
 static bool trans_UQSUB_zzz(DisasContext *s, arg_rrr_esz *a)
 {
-return do_zzz_fn(s, a, tcg_gen_gvec_ussub);
+return gen_gvec_fn_arg_zzz(s, tcg_gen_gvec_ussub, a);
 }
 
 /*
-- 
2.34.1




[PATCH 050/114] target/arm: Use TRANS_FEAT for do_adr

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 23 ---
 1 file changed, 4 insertions(+), 19 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index dac29749ce..c8eb2c684b 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1177,25 +1177,10 @@ static bool do_adr(DisasContext *s, arg_rrri *a, 
gen_helper_gvec_3 *fn)
 return gen_gvec_ool_zzz(s, fn, a->rd, a->rn, a->rm, a->imm);
 }
 
-static bool trans_ADR_p32(DisasContext *s, arg_rrri *a)
-{
-return do_adr(s, a, gen_helper_sve_adr_p32);
-}
-
-static bool trans_ADR_p64(DisasContext *s, arg_rrri *a)
-{
-return do_adr(s, a, gen_helper_sve_adr_p64);
-}
-
-static bool trans_ADR_s32(DisasContext *s, arg_rrri *a)
-{
-return do_adr(s, a, gen_helper_sve_adr_s32);
-}
-
-static bool trans_ADR_u32(DisasContext *s, arg_rrri *a)
-{
-return do_adr(s, a, gen_helper_sve_adr_u32);
-}
+TRANS_FEAT(ADR_p32, aa64_sve, do_adr, a, gen_helper_sve_adr_p32)
+TRANS_FEAT(ADR_p64, aa64_sve, do_adr, a, gen_helper_sve_adr_p64)
+TRANS_FEAT(ADR_s32, aa64_sve, do_adr, a, gen_helper_sve_adr_s32)
+TRANS_FEAT(ADR_u32, aa64_sve, do_adr, a, gen_helper_sve_adr_u32)
 
 /*
  *** SVE Integer Misc - Unpredicated Group
-- 
2.34.1




[PATCH 027/114] target/arm: Use TRANS_FEAT for gen_gvec_ool_arg_zpzz

2022-05-27 Thread Richard Henderson
Convert SVE translation functions directly using
gen_gvec_ool_arg_zpzz to TRANS_FEAT.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 85 --
 1 file changed, 36 insertions(+), 49 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index d63099c5b7..f8277eeb7c 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -755,54 +755,46 @@ static void do_sel_z(DisasContext *s, int rd, int rn, int 
rm, int pg, int esz)
 gen_gvec_ool_zzzp(s, fns[esz], rd, rn, rm, pg, 0);
 }
 
-#define DO_ZPZZ(NAME, name) \
-static bool trans_##NAME##_zpzz(DisasContext *s, arg_rprr_esz *a) \
-{ \
-static gen_helper_gvec_4 * const fns[4] = {   \
-gen_helper_sve_##name##_zpzz_b, gen_helper_sve_##name##_zpzz_h,   \
-gen_helper_sve_##name##_zpzz_s, gen_helper_sve_##name##_zpzz_d,   \
+#define DO_ZPZZ(NAME, FEAT, name) \
+static gen_helper_gvec_4 * const name##_zpzz_fns[4] = {   \
+gen_helper_##name##_zpzz_b, gen_helper_##name##_zpzz_h,   \
+gen_helper_##name##_zpzz_s, gen_helper_##name##_zpzz_d,   \
 };\
-return gen_gvec_ool_arg_zpzz(s, fns[a->esz], a, 0);   \
-}
+TRANS_FEAT(NAME, FEAT, gen_gvec_ool_arg_zpzz, \
+   name##_zpzz_fns[a->esz], a, 0)
 
-DO_ZPZZ(AND, and)
-DO_ZPZZ(EOR, eor)
-DO_ZPZZ(ORR, orr)
-DO_ZPZZ(BIC, bic)
+DO_ZPZZ(AND_zpzz, aa64_sve, sve_and)
+DO_ZPZZ(EOR_zpzz, aa64_sve, sve_eor)
+DO_ZPZZ(ORR_zpzz, aa64_sve, sve_orr)
+DO_ZPZZ(BIC_zpzz, aa64_sve, sve_bic)
 
-DO_ZPZZ(ADD, add)
-DO_ZPZZ(SUB, sub)
+DO_ZPZZ(ADD_zpzz, aa64_sve, sve_add)
+DO_ZPZZ(SUB_zpzz, aa64_sve, sve_sub)
 
-DO_ZPZZ(SMAX, smax)
-DO_ZPZZ(UMAX, umax)
-DO_ZPZZ(SMIN, smin)
-DO_ZPZZ(UMIN, umin)
-DO_ZPZZ(SABD, sabd)
-DO_ZPZZ(UABD, uabd)
+DO_ZPZZ(SMAX_zpzz, aa64_sve, sve_smax)
+DO_ZPZZ(UMAX_zpzz, aa64_sve, sve_umax)
+DO_ZPZZ(SMIN_zpzz, aa64_sve, sve_smin)
+DO_ZPZZ(UMIN_zpzz, aa64_sve, sve_umin)
+DO_ZPZZ(SABD_zpzz, aa64_sve, sve_sabd)
+DO_ZPZZ(UABD_zpzz, aa64_sve, sve_uabd)
 
-DO_ZPZZ(MUL, mul)
-DO_ZPZZ(SMULH, smulh)
-DO_ZPZZ(UMULH, umulh)
+DO_ZPZZ(MUL_zpzz, aa64_sve, sve_mul)
+DO_ZPZZ(SMULH_zpzz, aa64_sve, sve_smulh)
+DO_ZPZZ(UMULH_zpzz, aa64_sve, sve_umulh)
 
-DO_ZPZZ(ASR, asr)
-DO_ZPZZ(LSR, lsr)
-DO_ZPZZ(LSL, lsl)
+DO_ZPZZ(ASR_zpzz, aa64_sve, sve_asr)
+DO_ZPZZ(LSR_zpzz, aa64_sve, sve_lsr)
+DO_ZPZZ(LSL_zpzz, aa64_sve, sve_lsl)
 
-static bool trans_SDIV_zpzz(DisasContext *s, arg_rprr_esz *a)
-{
-static gen_helper_gvec_4 * const fns[4] = {
-NULL, NULL, gen_helper_sve_sdiv_zpzz_s, gen_helper_sve_sdiv_zpzz_d
-};
-return gen_gvec_ool_arg_zpzz(s, fns[a->esz], a, 0);
-}
+static gen_helper_gvec_4 * const sdiv_fns[4] = {
+NULL, NULL, gen_helper_sve_sdiv_zpzz_s, gen_helper_sve_sdiv_zpzz_d
+};
+TRANS_FEAT(SDIV_zpzz, aa64_sve, gen_gvec_ool_arg_zpzz, sdiv_fns[a->esz], a, 0)
 
-static bool trans_UDIV_zpzz(DisasContext *s, arg_rprr_esz *a)
-{
-static gen_helper_gvec_4 * const fns[4] = {
-NULL, NULL, gen_helper_sve_udiv_zpzz_s, gen_helper_sve_udiv_zpzz_d
-};
-return gen_gvec_ool_arg_zpzz(s, fns[a->esz], a, 0);
-}
+static gen_helper_gvec_4 * const udiv_fns[4] = {
+NULL, NULL, gen_helper_sve_udiv_zpzz_s, gen_helper_sve_udiv_zpzz_d
+};
+TRANS_FEAT(UDIV_zpzz, aa64_sve, gen_gvec_ool_arg_zpzz, udiv_fns[a->esz], a, 0)
 
 static bool trans_SEL_zpzz(DisasContext *s, arg_rprr_esz *a)
 {
@@ -1068,17 +1060,12 @@ TRANS_FEAT(SQSHLU, aa64_sve2, gen_gvec_ool_arg_zpzi,
  */
 
 #define DO_ZPZW(NAME, name) \
-static bool trans_##NAME##_zpzw(DisasContext *s, arg_rprr_esz *a) \
-{ \
-static gen_helper_gvec_4 * const fns[3] = {   \
+static gen_helper_gvec_4 * const name##_zpzw_fns[4] = {   \
 gen_helper_sve_##name##_zpzw_b, gen_helper_sve_##name##_zpzw_h,   \
-gen_helper_sve_##name##_zpzw_s,   \
+gen_helper_sve_##name##_zpzw_s, NULL  \
 };\
-if (a->esz < 0 || a->esz >= 3) {  \
-return false; \
-} \
-return gen_gvec_ool_arg_zpzz(s, fns[a->esz], a, 0);   \
-}
+TRANS_FEAT(NAME##_zpzw, aa64_sve, gen_gvec_ool_arg_zpzz,  \
+   a->esz < 0 ? NULL : name##_zpzw_fns[a->esz], a, 0)
 
 DO_ZPZW(ASR, asr)
 DO_ZPZW(LSR, lsr)
-- 
2.34.1




[PATCH 065/114] target/arm: Use TRANS_FEAT for SPLICE

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 17 -
 1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index caa587506c..8eb70fd56f 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2658,20 +2658,11 @@ TRANS_FEAT(REVH, aa64_sve, gen_gvec_ool_arg_zpz, 
revh_fns[a->esz], a, 0)
 TRANS_FEAT(REVW, aa64_sve, gen_gvec_ool_arg_zpz,
a->esz == 3 ? gen_helper_sve_revw_d : NULL, a, 0)
 
-static bool trans_SPLICE(DisasContext *s, arg_rprr_esz *a)
-{
-return gen_gvec_ool_zzzp(s, gen_helper_sve_splice,
- a->rd, a->rn, a->rm, a->pg, a->esz);
-}
+TRANS_FEAT(SPLICE, aa64_sve, gen_gvec_ool_arg_zpzz,
+   gen_helper_sve_splice, a, a->esz)
 
-static bool trans_SPLICE_sve2(DisasContext *s, arg_rpr_esz *a)
-{
-if (!dc_isar_feature(aa64_sve2, s)) {
-return false;
-}
-return gen_gvec_ool_zzzp(s, gen_helper_sve_splice,
- a->rd, a->rn, (a->rn + 1) % 32, a->pg, a->esz);
-}
+TRANS_FEAT(SPLICE_sve2, aa64_sve2, gen_gvec_ool_zzzp, gen_helper_sve_splice,
+   a->rd, a->rn, (a->rn + 1) % 32, a->pg, a->esz)
 
 /*
  *** SVE Integer Compare - Vectors Group
-- 
2.34.1




[PATCH 029/114] target/arm: Merge gen_gvec_fn_zz into do_mov_z

2022-05-27 Thread Richard Henderson
There is only one caller for gen_gvec_fn_zz; inline it.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 13 +++--
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 0a69a1ef65..5ab9de46a7 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -258,15 +258,6 @@ static bool gen_gvec_ool_arg_zpzz(DisasContext *s, 
gen_helper_gvec_4 *fn,
 return gen_gvec_ool_zzzp(s, fn, a->rd, a->rn, a->rm, a->pg, data);
 }
 
-/* Invoke a vector expander on two Zregs.  */
-static void gen_gvec_fn_zz(DisasContext *s, GVecGen2Fn *gvec_fn,
-   int esz, int rd, int rn)
-{
-unsigned vsz = vec_full_reg_size(s);
-gvec_fn(esz, vec_full_reg_offset(s, rd),
-vec_full_reg_offset(s, rn), vsz, vsz);
-}
-
 /* Invoke a vector expander on three Zregs.  */
 static void gen_gvec_fn_zzz(DisasContext *s, GVecGen3Fn *gvec_fn,
 int esz, int rd, int rn, int rm)
@@ -292,7 +283,9 @@ static void gen_gvec_fn_(DisasContext *s, GVecGen4Fn 
*gvec_fn,
 static bool do_mov_z(DisasContext *s, int rd, int rn)
 {
 if (sve_access_check(s)) {
-gen_gvec_fn_zz(s, tcg_gen_gvec_mov, MO_8, rd, rn);
+unsigned vsz = vec_full_reg_size(s);
+tcg_gen_gvec_mov(MO_8, vec_full_reg_offset(s, rd),
+ vec_full_reg_offset(s, rn), vsz, vsz);
 }
 return true;
 }
-- 
2.34.1




[PATCH 023/114] target/arm: Rename do_zpzi_ool to gen_gvec_ool_arg_zpzi

2022-05-27 Thread Richard Henderson
Rename the function to match gen_gvec_ool_arg_zpz,
and move to be adjacent.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 29 ++---
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index fe11cfed6b..86e87a2078 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -228,6 +228,11 @@ static bool gen_gvec_ool_arg_zpz(DisasContext *s, 
gen_helper_gvec_3 *fn,
 return gen_gvec_ool_zzp(s, fn, a->rd, a->rn, a->pg, data);
 }
 
+static bool gen_gvec_ool_arg_zpzi(DisasContext *s, gen_helper_gvec_3 *fn,
+  arg_rpri_esz *a)
+{
+return gen_gvec_ool_zzp(s, fn, a->rd, a->rn, a->pg, a->imm);
+}
 
 /* Invoke an out-of-line helper on 3 Zregs and a predicate. */
 static void gen_gvec_ool_zzzp(DisasContext *s, gen_helper_gvec_4 *fn,
@@ -952,12 +957,6 @@ static bool do_movz_zpz(DisasContext *s, int rd, int rn, 
int pg,
 return gen_gvec_ool_zzp(s, fns[esz], rd, rn, pg, invert);
 }
 
-static bool do_zpzi_ool(DisasContext *s, arg_rpri_esz *a,
-gen_helper_gvec_3 *fn)
-{
-return gen_gvec_ool_zzp(s, fn, a->rd, a->rn, a->pg, a->imm);
-}
-
 static bool trans_ASR_zpzi(DisasContext *s, arg_rpri_esz *a)
 {
 static gen_helper_gvec_3 * const fns[4] = {
@@ -971,7 +970,7 @@ static bool trans_ASR_zpzi(DisasContext *s, arg_rpri_esz *a)
 /* Shift by element size is architecturally valid.  For
arithmetic right-shift, it's the same as by one less. */
 a->imm = MIN(a->imm, (8 << a->esz) - 1);
-return do_zpzi_ool(s, a, fns[a->esz]);
+return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
 }
 
 static bool trans_LSR_zpzi(DisasContext *s, arg_rpri_esz *a)
@@ -988,7 +987,7 @@ static bool trans_LSR_zpzi(DisasContext *s, arg_rpri_esz *a)
 if (a->imm >= (8 << a->esz)) {
 return do_movz_zpz(s, a->rd, a->rd, a->pg, a->esz, true);
 } else {
-return do_zpzi_ool(s, a, fns[a->esz]);
+return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
 }
 }
 
@@ -1006,7 +1005,7 @@ static bool trans_LSL_zpzi(DisasContext *s, arg_rpri_esz 
*a)
 if (a->imm >= (8 << a->esz)) {
 return do_movz_zpz(s, a->rd, a->rd, a->pg, a->esz, true);
 } else {
-return do_zpzi_ool(s, a, fns[a->esz]);
+return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
 }
 }
 
@@ -1024,7 +1023,7 @@ static bool trans_ASRD(DisasContext *s, arg_rpri_esz *a)
 if (a->imm >= (8 << a->esz)) {
 return do_movz_zpz(s, a->rd, a->rd, a->pg, a->esz, true);
 } else {
-return do_zpzi_ool(s, a, fns[a->esz]);
+return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
 }
 }
 
@@ -1037,7 +1036,7 @@ static bool trans_SQSHL_zpzi(DisasContext *s, 
arg_rpri_esz *a)
 if (a->esz < 0 || !dc_isar_feature(aa64_sve2, s)) {
 return false;
 }
-return do_zpzi_ool(s, a, fns[a->esz]);
+return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
 }
 
 static bool trans_UQSHL_zpzi(DisasContext *s, arg_rpri_esz *a)
@@ -1049,7 +1048,7 @@ static bool trans_UQSHL_zpzi(DisasContext *s, 
arg_rpri_esz *a)
 if (a->esz < 0 || !dc_isar_feature(aa64_sve2, s)) {
 return false;
 }
-return do_zpzi_ool(s, a, fns[a->esz]);
+return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
 }
 
 static bool trans_SRSHR(DisasContext *s, arg_rpri_esz *a)
@@ -1061,7 +1060,7 @@ static bool trans_SRSHR(DisasContext *s, arg_rpri_esz *a)
 if (a->esz < 0 || !dc_isar_feature(aa64_sve2, s)) {
 return false;
 }
-return do_zpzi_ool(s, a, fns[a->esz]);
+return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
 }
 
 static bool trans_URSHR(DisasContext *s, arg_rpri_esz *a)
@@ -1073,7 +1072,7 @@ static bool trans_URSHR(DisasContext *s, arg_rpri_esz *a)
 if (a->esz < 0 || !dc_isar_feature(aa64_sve2, s)) {
 return false;
 }
-return do_zpzi_ool(s, a, fns[a->esz]);
+return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
 }
 
 static bool trans_SQSHLU(DisasContext *s, arg_rpri_esz *a)
@@ -1085,7 +1084,7 @@ static bool trans_SQSHLU(DisasContext *s, arg_rpri_esz *a)
 if (a->esz < 0 || !dc_isar_feature(aa64_sve2, s)) {
 return false;
 }
-return do_zpzi_ool(s, a, fns[a->esz]);
+return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
 }
 
 /*
-- 
2.34.1




[PATCH 030/114] target/arm: Move null function and sve check into gen_gvec_fn_zzz

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 36 +++-
 1 file changed, 15 insertions(+), 21 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 5ab9de46a7..3af4626e58 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -259,13 +259,19 @@ static bool gen_gvec_ool_arg_zpzz(DisasContext *s, 
gen_helper_gvec_4 *fn,
 }
 
 /* Invoke a vector expander on three Zregs.  */
-static void gen_gvec_fn_zzz(DisasContext *s, GVecGen3Fn *gvec_fn,
+static bool gen_gvec_fn_zzz(DisasContext *s, GVecGen3Fn *gvec_fn,
 int esz, int rd, int rn, int rm)
 {
-unsigned vsz = vec_full_reg_size(s);
-gvec_fn(esz, vec_full_reg_offset(s, rd),
-vec_full_reg_offset(s, rn),
-vec_full_reg_offset(s, rm), vsz, vsz);
+if (gvec_fn == NULL) {
+return false;
+}
+if (sve_access_check(s)) {
+unsigned vsz = vec_full_reg_size(s);
+gvec_fn(esz, vec_full_reg_offset(s, rd),
+vec_full_reg_offset(s, rn),
+vec_full_reg_offset(s, rm), vsz, vsz);
+}
+return true;
 }
 
 /* Invoke a vector expander on four Zregs.  */
@@ -366,10 +372,7 @@ const uint64_t pred_esz_masks[4] = {
 
 static bool do_zzz_fn(DisasContext *s, arg_rrr_esz *a, GVecGen3Fn *gvec_fn)
 {
-if (sve_access_check(s)) {
-gen_gvec_fn_zzz(s, gvec_fn, a->esz, a->rd, a->rn, a->rm);
-}
-return true;
+return gen_gvec_fn_zzz(s, gvec_fn, a->esz, a->rd, a->rn, a->rm);
 }
 
 static bool trans_AND_zzz(DisasContext *s, arg_rrr_esz *a)
@@ -6421,10 +6424,7 @@ static bool trans_MUL_zzz(DisasContext *s, arg_rrr_esz 
*a)
 if (!dc_isar_feature(aa64_sve2, s)) {
 return false;
 }
-if (sve_access_check(s)) {
-gen_gvec_fn_zzz(s, tcg_gen_gvec_mul, a->esz, a->rd, a->rn, a->rm);
-}
-return true;
+return gen_gvec_fn_zzz(s, tcg_gen_gvec_mul, a->esz, a->rd, a->rn, a->rm);
 }
 
 static gen_helper_gvec_3 * const smulh_zzz_fns[4] = {
@@ -6945,10 +6945,7 @@ static bool do_sve2_fn_zzz(DisasContext *s, arg_rrr_esz 
*a, GVecGen3Fn *fn)
 if (!dc_isar_feature(aa64_sve2, s)) {
 return false;
 }
-if (sve_access_check(s)) {
-gen_gvec_fn_zzz(s, fn, a->esz, a->rd, a->rn, a->rm);
-}
-return true;
+return gen_gvec_fn_zzz(s, fn, a->esz, a->rd, a->rn, a->rm);
 }
 
 static bool trans_SABA(DisasContext *s, arg_rrr_esz *a)
@@ -7880,10 +7877,7 @@ static bool trans_RAX1(DisasContext *s, arg_rrr_esz *a)
 if (!dc_isar_feature(aa64_sve2_sha3, s)) {
 return false;
 }
-if (sve_access_check(s)) {
-gen_gvec_fn_zzz(s, gen_gvec_rax1, MO_64, a->rd, a->rn, a->rm);
-}
-return true;
+return gen_gvec_fn_zzz(s, gen_gvec_rax1, MO_64, a->rd, a->rn, a->rm);
 }
 
 static bool trans_FCVTNT_sh(DisasContext *s, arg_rpr_esz *a)
-- 
2.34.1




[PATCH 024/114] target/arm: Use TRANS_FEAT for gen_gvec_ool_arg_zpzi

2022-05-27 Thread Richard Henderson
Convert some SVE translation functions using
gen_gvec_ool_arg_zpzi to TRANS_FEAT.

Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 85 ++
 1 file changed, 30 insertions(+), 55 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 86e87a2078..10614bf915 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1027,65 +1027,40 @@ static bool trans_ASRD(DisasContext *s, arg_rpri_esz *a)
 }
 }
 
-static bool trans_SQSHL_zpzi(DisasContext *s, arg_rpri_esz *a)
-{
-static gen_helper_gvec_3 * const fns[4] = {
-gen_helper_sve2_sqshl_zpzi_b, gen_helper_sve2_sqshl_zpzi_h,
-gen_helper_sve2_sqshl_zpzi_s, gen_helper_sve2_sqshl_zpzi_d,
-};
-if (a->esz < 0 || !dc_isar_feature(aa64_sve2, s)) {
-return false;
-}
-return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
-}
+static gen_helper_gvec_3 * const sqshl_zpzi_fns[4] = {
+gen_helper_sve2_sqshl_zpzi_b, gen_helper_sve2_sqshl_zpzi_h,
+gen_helper_sve2_sqshl_zpzi_s, gen_helper_sve2_sqshl_zpzi_d,
+};
+TRANS_FEAT(SQSHL_zpzi, aa64_sve2, gen_gvec_ool_arg_zpzi,
+   a->esz < 0 ? NULL : sqshl_zpzi_fns[a->esz], a)
 
-static bool trans_UQSHL_zpzi(DisasContext *s, arg_rpri_esz *a)
-{
-static gen_helper_gvec_3 * const fns[4] = {
-gen_helper_sve2_uqshl_zpzi_b, gen_helper_sve2_uqshl_zpzi_h,
-gen_helper_sve2_uqshl_zpzi_s, gen_helper_sve2_uqshl_zpzi_d,
-};
-if (a->esz < 0 || !dc_isar_feature(aa64_sve2, s)) {
-return false;
-}
-return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
-}
+static gen_helper_gvec_3 * const uqshl_zpzi_fns[4] = {
+gen_helper_sve2_uqshl_zpzi_b, gen_helper_sve2_uqshl_zpzi_h,
+gen_helper_sve2_uqshl_zpzi_s, gen_helper_sve2_uqshl_zpzi_d,
+};
+TRANS_FEAT(UQSHL_zpzi, aa64_sve2, gen_gvec_ool_arg_zpzi,
+   a->esz < 0 ? NULL : uqshl_zpzi_fns[a->esz], a)
 
-static bool trans_SRSHR(DisasContext *s, arg_rpri_esz *a)
-{
-static gen_helper_gvec_3 * const fns[4] = {
-gen_helper_sve2_srshr_b, gen_helper_sve2_srshr_h,
-gen_helper_sve2_srshr_s, gen_helper_sve2_srshr_d,
-};
-if (a->esz < 0 || !dc_isar_feature(aa64_sve2, s)) {
-return false;
-}
-return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
-}
+static gen_helper_gvec_3 * const srshr_fns[4] = {
+gen_helper_sve2_srshr_b, gen_helper_sve2_srshr_h,
+gen_helper_sve2_srshr_s, gen_helper_sve2_srshr_d,
+};
+TRANS_FEAT(SRSHR, aa64_sve2, gen_gvec_ool_arg_zpzi,
+   a->esz < 0 ? NULL : srshr_fns[a->esz], a)
 
-static bool trans_URSHR(DisasContext *s, arg_rpri_esz *a)
-{
-static gen_helper_gvec_3 * const fns[4] = {
-gen_helper_sve2_urshr_b, gen_helper_sve2_urshr_h,
-gen_helper_sve2_urshr_s, gen_helper_sve2_urshr_d,
-};
-if (a->esz < 0 || !dc_isar_feature(aa64_sve2, s)) {
-return false;
-}
-return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
-}
+static gen_helper_gvec_3 * const urshr_fns[4] = {
+gen_helper_sve2_urshr_b, gen_helper_sve2_urshr_h,
+gen_helper_sve2_urshr_s, gen_helper_sve2_urshr_d,
+};
+TRANS_FEAT(URSHR, aa64_sve2, gen_gvec_ool_arg_zpzi,
+   a->esz < 0 ? NULL : urshr_fns[a->esz], a)
 
-static bool trans_SQSHLU(DisasContext *s, arg_rpri_esz *a)
-{
-static gen_helper_gvec_3 * const fns[4] = {
-gen_helper_sve2_sqshlu_b, gen_helper_sve2_sqshlu_h,
-gen_helper_sve2_sqshlu_s, gen_helper_sve2_sqshlu_d,
-};
-if (a->esz < 0 || !dc_isar_feature(aa64_sve2, s)) {
-return false;
-}
-return gen_gvec_ool_arg_zpzi(s, fns[a->esz], a);
-}
+static gen_helper_gvec_3 * const sqshlu_fns[4] = {
+gen_helper_sve2_sqshlu_b, gen_helper_sve2_sqshlu_h,
+gen_helper_sve2_sqshlu_s, gen_helper_sve2_sqshlu_d,
+};
+TRANS_FEAT(SQSHLU, aa64_sve2, gen_gvec_ool_arg_zpzi,
+   a->esz < 0 ? NULL : sqshlu_fns[a->esz], a)
 
 /*
  *** SVE Bitwise Shift - Predicated Group
-- 
2.34.1




[PATCH 054/114] target/arm: Use TRANS_FEAT for do_EXT

2022-05-27 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/translate-sve.c | 14 ++
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index abb5433ee5..7139e6c0b0 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -2081,18 +2081,8 @@ static bool do_EXT(DisasContext *s, int rd, int rn, int 
rm, int imm)
 return true;
 }
 
-static bool trans_EXT(DisasContext *s, arg_EXT *a)
-{
-return do_EXT(s, a->rd, a->rn, a->rm, a->imm);
-}
-
-static bool trans_EXT_sve2(DisasContext *s, arg_rri *a)
-{
-if (!dc_isar_feature(aa64_sve2, s)) {
-return false;
-}
-return do_EXT(s, a->rd, a->rn, (a->rn + 1) % 32, a->imm);
-}
+TRANS_FEAT(EXT, aa64_sve, do_EXT, a->rd, a->rn, a->rm, a->imm)
+TRANS_FEAT(EXT_sve2, aa64_sve2, do_EXT, a->rd, a->rn, (a->rn + 1) % 32, a->imm)
 
 /*
  *** SVE Permute - Unpredicated Group
-- 
2.34.1




  1   2   3   4   >