RE: [PATCH v1 0/2] Upgrade ACPI SPCR table to support SPCR table version 4 format

2024-05-05 Thread JeeHeng Sia


> -Original Message-
> From: Peter Maydell 
> Sent: Thursday, May 2, 2024 5:19 PM
> To: JeeHeng Sia 
> Cc: qemu-...@nongnu.org; qemu-devel@nongnu.org; qemu-ri...@nongnu.org; 
> m...@redhat.com; imamm...@redhat.com;
> anisi...@redhat.com; shannon.zha...@gmail.com; suni...@ventanamicro.com; 
> pal...@dabbelt.com; alistair.fran...@wdc.com;
> bin.m...@windriver.com; liwei1...@gmail.com; dbarb...@ventanamicro.com; 
> zhiwei_...@linux.alibaba.com
> Subject: Re: [PATCH v1 0/2] Upgrade ACPI SPCR table to support SPCR table 
> version 4 format
> 
> On Thu, 2 May 2024 at 06:12, Sia Jee Heng  
> wrote:
> >
> > Update the SPCR table to accommodate the SPCR Table version 4 [1].
> > The SPCR table has been modified to adhere to the version 4 format [2].
> >
> > Meanwhile, the virt SPCR golden reference files have been updated to
> > accommodate the SPCR Table version 4.
> >
> > [1]: 
> > https://learn.microsoft.com/en-us/windows-hardware/drivers/serports/serial-port-console-redirection-table
> > [2]: https://github.com/acpica/acpica/pull/931
> >
> > Sia Jee Heng (2):
> >   tests/qtest/bios-tables-test: Update virt SPCR golden references
> >   hw/acpi: Upgrade ACPI SPCR table to support SPCR table version 4
> > format
> 
> This isn't the right way to make a change that requires
> updates to the bios-tables-test reference files, because
> "make check" will fail after patch 1 but before patch 2.
> 
> You need a three-patch approach. How to do that is documented
> in the comment at the top of bios-tables-test.c. The resulting
> three patches should look like:
>  * patch 1 updates bios-tables-test-allowed-diff.h to
>mark the affected test or tests as "OK to fail"
>  * patch 2 makes the changes to QEMU that alter the
>required table output
>  * patch 3 updates the reference files and removes the
>tests from the allowed-diff file
> 
> See for instance commits 6c1c2e912fcf9, 1ec896fe7ca938,
> ea2fde5bccc514 as an example.
Thank you for the guidance. I will improve the patch by referring to the 
example provided.
> 
> Side note: if riscv virt has APCI tables now, maybe we
> should add testing of them to the bios-tables-test ?
Sure. I will make modifications based on the RISC-V test.
> 
> thanks
> -- PMM


Re: More doc updates needed for new migrate argument @channels

2024-05-05 Thread Markus Armbruster
Peter Xu  writes:

[...]

> I also copied qemu-devel starting from now.

My bad, I messed that up!




Re: [PATCH 2/3] vfio/migration: Emit VFIO device migration state change QAPI event

2024-05-05 Thread Markus Armbruster
Peter, Fabiano, I'd like to hear your opinion on the issue discussed
below.

Avihai Horon  writes:

> On 02/05/2024 13:22, Joao Martins wrote:
>> External email: Use caution opening links or attachments
>>
>>
>> On 01/05/2024 13:28, Avihai Horon wrote:
>>> On 01/05/2024 14:50, Joao Martins wrote:
 External email: Use caution opening links or attachments


 On 30/04/2024 06:16, Avihai Horon wrote:
> Emit VFIO device migration state change QAPI event when a VFIO device
> changes its migration state. This can be used by management applications
> to get updates on the current state of the VFIO device for their own
> purposes.
>
> A new per VFIO device capability, "migration-events", is added so events
> can be enabled only for the required devices. It is disabled by default.
>
> Signed-off-by: Avihai Horon
> ---
>include/hw/vfio/vfio-common.h |  1 +
>hw/vfio/migration.c   | 44 +++
>hw/vfio/pci.c |  2 ++
>3 files changed, 47 insertions(+)
>
> diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
> index b9da6c08ef..3ec5f2425e 100644
> --- a/include/hw/vfio/vfio-common.h
> +++ b/include/hw/vfio/vfio-common.h
> @@ -115,6 +115,7 @@ typedef struct VFIODevice {
>bool no_mmap;
>bool ram_block_discard_allowed;
>OnOffAuto enable_migration;
> +bool migration_events;
>VFIODeviceOps *ops;
>unsigned int num_irqs;
>unsigned int num_regions;
> diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c
> index 06ae40969b..6bbccf6545 100644
> --- a/hw/vfio/migration.c
> +++ b/hw/vfio/migration.c
> @@ -24,6 +24,7 @@
>#include "migration/register.h"
>#include "migration/blocker.h"
>#include "qapi/error.h"
> +#include "qapi/qapi-events-vfio.h"
>#include "exec/ramlist.h"
>#include "exec/ram_addr.h"
>#include "pci.h"
> @@ -80,6 +81,46 @@ static const char *mig_state_to_str(enum
> vfio_device_mig_state state)
>}
>}
>
> +static VFIODeviceMigState
> +mig_state_to_qapi_state(enum vfio_device_mig_state state)
> +{
> +switch (state) {
> +case VFIO_DEVICE_STATE_STOP:
> +return QAPI_VFIO_DEVICE_MIG_STATE_STOP;
> +case VFIO_DEVICE_STATE_RUNNING:
> +return QAPI_VFIO_DEVICE_MIG_STATE_RUNNING;
> +case VFIO_DEVICE_STATE_STOP_COPY:
> +return QAPI_VFIO_DEVICE_MIG_STATE_STOP_COPY;
> +case VFIO_DEVICE_STATE_RESUMING:
> +return QAPI_VFIO_DEVICE_MIG_STATE_RESUMING;
> +case VFIO_DEVICE_STATE_RUNNING_P2P:
> +return QAPI_VFIO_DEVICE_MIG_STATE_RUNNING_P2P;
> +case VFIO_DEVICE_STATE_PRE_COPY:
> +return QAPI_VFIO_DEVICE_MIG_STATE_PRE_COPY;
> +case VFIO_DEVICE_STATE_PRE_COPY_P2P:
> +return QAPI_VFIO_DEVICE_MIG_STATE_PRE_COPY_P2P;
> +default:
> +g_assert_not_reached();
> +}
> +}
> +
> +static void vfio_migration_send_state_change_event(VFIODevice *vbasedev)
> +{
> +VFIOMigration *migration = vbasedev->migration;
> +const char *id;
> +Object *obj;
> +
> +if (!vbasedev->migration_events) {
> +return;
> +}
> +
 Shouldn't this leap frog migrate_events() capability instead of 
 introducing its
 vfio equivalent i.e.

   if (!migrate_events()) {
   return;
   }

 ?
>>>
>>> I used a per VFIO device cap so the events can be fine tuned for each device
>>> (maybe one device should send events while the other not).
>>> This gives the most flexibility and I don't think it complicates the
>>> configuration (one downside, though, is that it can't be enabled/disabled
>>> dynamically during runtime).
>>>
>> Right.
>>
>>> I don't think events add much overhead, so if you prefer a global cap, I can
>>> change it.
>>> However, I'm not sure overloading the existing migrate_events() is valid?
>>>
>> migration 'events' capability just means we will have some migration events
>> emited via QAPI monitor for: 1) general global status and 2) for each 
>> migration
>> pass (both with different event names=.
>
> Yes, it's already overloaded.
>
> In migration QAPI it says: "@events: generate events for each migration state 
> change (since 2.4)".
> This only refers to the MIGRATION event AFAIU.
>
> Later on (in QEMU 2.6), MIGRATION_PASS event was added and the events cap was 
> overloaded for the first time (without changing @events description).
>
> Now we want to add yet another use for events capability, the VFIO migration 
> state change events.
>
> I think what bothers me is the @events description, which is not accurate.
> Maybe it should be changed to "@events: generate migration related events 

Re: [PATCH 1/3] qapi/vfio: Add VFIO device migration state change QAPI event

2024-05-05 Thread Markus Armbruster
Avihai Horon  writes:

> On 01/05/2024 14:50, Joao Martins wrote:
>> External email: Use caution opening links or attachments
>>
>>
>> On 30/04/2024 06:16, Avihai Horon wrote:
>>> Add a new QAPI event for VFIO device migration state change. This event
>>> will be emitted when a VFIO device changes its migration state, for
>>> example, during migration or when stopping/starting the guest.
>>>
>>> This event can be used by management applications to get updates on the
>>> current state of the VFIO device for their own purposes.
>>>
>>> Signed-off-by: Avihai Horon 
>>> ---
>>>   MAINTAINERS   |  1 +
>>>   qapi/qapi-schema.json |  1 +
>>>   qapi/vfio.json| 61 +++
>>>   qapi/meson.build  |  1 +
>>>   4 files changed, 64 insertions(+)
>>>   create mode 100644 qapi/vfio.json
>>>
>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>> index 302b6fd00c..ef58a39d36 100644
>>> --- a/MAINTAINERS
>>> +++ b/MAINTAINERS
>>> @@ -2159,6 +2159,7 @@ F: hw/vfio/*
>>>  F: include/hw/vfio/
>>>  F: docs/igd-assign.txt
>>>  F: docs/devel/migration/vfio.rst
>>> +F: qapi/vfio.json
>>>
>>>   vfio-ccw
>>>   M: Eric Farman 
>>> diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json
>>> index 5e33da7228..b1581988e4 100644
>>> --- a/qapi/qapi-schema.json
>>> +++ b/qapi/qapi-schema.json
>>> @@ -78,5 +78,6 @@
>>>  { 'include': 'pci.json' }
>>>  { 'include': 'stats.json' }
>>>  { 'include': 'virtio.json' }
>>> +{ 'include': 'vfio.json' }
>>>  { 'include': 'cryptodev.json' }
>>>  { 'include': 'cxl.json' }
>>> diff --git a/qapi/vfio.json b/qapi/vfio.json
>>> new file mode 100644
>>> index 00..a38f26bccd
>>> --- /dev/null
>>> +++ b/qapi/vfio.json
>>> @@ -0,0 +1,61 @@
>>> +# -*- Mode: Python -*-
>>> +# vim: filetype=python
>>> +#
>>> +
>>> +##
>>> +# = VFIO devices
>>> +##
>>> +
>>> +##
>>> +# @VFIODeviceMigState:
>>> +#
>>> +# An enumeration of the VFIO device migration states.
>>> +#
>>> +# @stop: The device is stopped.
>>> +#
>>> +# @running: The device is running.
>>> +#
>>> +# @stop-copy: The device is stopped and its internal state is available
>>> +# for reading.
>>> +#
>>> +# @resuming: The device is stopped and its internal state is available
>>> +# for writing.
>>> +#
>>> +# @running-p2p: The device is running in the P2P quiescent state.
>>> +#
>>> +# @pre-copy: The device is running, tracking its internal state and its
>>> +# internal state is available for reading.
>>> +#
>>> +# @pre-copy-p2p: The device is running in the P2P quiescent state,
>>> +# tracking its internal state and its internal state is available
>>> +# for reading.
>>> +#
>>> +# Since: 9.1
>>> +##
>>> +{ 'enum': 'VFIODeviceMigState',
>>> +  'data': [ 'stop', 'running', 'stop-copy', 'resuming', 'running-p2p',
>>> +'pre-copy', 'pre-copy-p2p' ],
>>> +  'prefix': 'QAPI_VFIO_DEVICE_MIG_STATE' }

Without 'prefix', you get VFIO_DEVICE_MIG_STATE_STOP and so forth.  Why
do you need a QAPI_ prefix?

>>> +
>>
>> Considering MIG can also be interpreted as Multi Instance GPU elsewhere
>> unrelated to this shouldn't we be explicit here? i.e.
>>
>>  VFIO_DEVICE_MIGRATION_STATE
>>
>> ... to avoid ambiguiosity.
>
> I used mig to avoid long names, but I don't mind changing it to migration if 
> that's clearer.
>
> Thanks.

We generally avoid abbreviations in QAPI/QMP.

The event that reports general migration state change is called
MIGRATION, and its data type MigrationStatus.

We could call this one VFIO_MIGRATION, and its data type
VfioMigrationStatus.

>>> +##
>>> +# @VFIO_DEVICE_MIG_STATE_CHANGED:
>>> +#
>>> +# This event is emitted when a VFIO device migration state is changed.
>>> +#
>>> +# @device-id: The id of the VFIO device (final component of QOM path).
>>> +#
>>> +# @device-state: The new changed device migration state.
>>> +#
>>> +# Since: 9.1
>>> +#
>>> +# Example:
>>> +#
>>> +# <- {"timestamp": {"seconds": 1713771323, "microseconds": 212268},
>>> +# "event": "VFIO_DEVICE_MIG_STATE_CHANGED",
>>> +# "data": {"device-id": "vfio_dev1", "device-state": "stop"} }
>>> +##
>>> +{ 'event': 'VFIO_DEVICE_MIG_STATE_CHANGED',
>>> +  'data': {
>>> +  'device-id': 'str',
>>> +  'device-state': 'VFIODeviceMigState'
>>> +  } }
>>> diff --git a/qapi/meson.build b/qapi/meson.build
>>> index c92af6e063..e7bc54e5d0 100644
>>> --- a/qapi/meson.build
>>> +++ b/qapi/meson.build
>>> @@ -52,6 +52,7 @@ qapi_all_modules = [
>>>'stats',
>>>'trace',
>>>'transaction',
>>> +  'vfio',
>>>'virtio',
>>>'yank',
>>>  ]

The new code is in the intersection of VFIO and migration.  Putting it
into new vfio.json instead of existing migration.json lets you add it to
MAINTAINERS section VFIO instead of Migration.  Up to the maintainers
involved.




Re: [PATCH] Fixes: Indentation using TABs and improve formatting

2024-05-05 Thread Thomas Huth

On 04/05/2024 22.34, Michael Tokarev wrote:

04.05.2024 21:58, Tanmay wrote:

Hi,

I have attached a patch file that fixes indentation and formatting for 
some files as listed in https://gitlab.com/qemu-project/qemu/-/issues/373 
.


it is sort of good you posted this patch to stable@.  It has absolutely 
nothing to do
with stable, but it serves as a an example of things which should - in my 
opinion -

not be done at all.


I disagree. Yes, clean-up patches like this make it somewhat difficult to 
backport other patches to stable, but that should not be the reason to not 
do cleanups at all. If we keep badly formatted code in the repository, 
people will copy-n-paste it to other places, or if you have to do fixes in 
sources that have mixed TABs and spaces, you often get complaints from 
checkpatch.pl though it is not your fault. So we should get this straight at 
one point in time.


So, Tanmay, could you please resend your patch, this time to 
qemu-devel@nongnu.org instead of qemu-stable, and CC: qemu-...@nongnu.org 
and the corresponding ARM maintainers (you can use 
scripts/get_maintainers.pl to find out the correct maintainers that should 
be CC:-ed). And if possible, please send your patch inline and not as an 
attachment (so it's possible to comment on the patch via hitting the reply 
button), preferably with "git send-email" instead of using your e-mail program.


 Thanks!
  Thomas




Re: [PATCH v3 1/5] hw/loongarch: Rename LOONGARCH_MACHINE with VIRT_MACHINE

2024-05-05 Thread Thomas Huth

On 06/05/2024 05.02, Bibo Mao wrote:

On LoongArch system, there is only virt machine type now, name
LOONGARCH_MACHINE is confused, rename it with VIRT_MACHINE. Machine name
about Other real hw boards can be added in future.

Signed-off-by: Bibo Mao 
---

...

@@ -1245,7 +1244,7 @@ static void loongarch_class_init(ObjectClass *oc, void 
*data)
  
  static const TypeInfo loongarch_machine_types[] = {

  {
-.name   = TYPE_LOONGARCH_MACHINE,
+.name   = TYPE_VIRT_MACHINE,
  .parent = TYPE_MACHINE,
  .instance_size  = sizeof(LoongArchMachineState),
  .class_init = loongarch_class_init,
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 4e14bf6060..5ea2f0370d 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -73,8 +73,8 @@ struct LoongArchMachineState {
  struct loongarch_boot_info bootinfo;
  };
  
-#define TYPE_LOONGARCH_MACHINE  MACHINE_TYPE_NAME("virt")

-OBJECT_DECLARE_SIMPLE_TYPE(LoongArchMachineState, LOONGARCH_MACHINE)
+#define TYPE_VIRT_MACHINE  MACHINE_TYPE_NAME("virt")
+OBJECT_DECLARE_SIMPLE_TYPE(LoongArchMachineState, VIRT_MACHINE)
  bool loongarch_is_acpi_enabled(LoongArchMachineState *lams);
  void loongarch_acpi_setup(LoongArchMachineState *lams);
  #endif


 Hi,

there are currently some efforts going on to create the possibility to link 
a QEMU binary that contains all targets in one binary. Since we already have 
a TYPE_VIRT_MACHINE for other targets, I wonder whether it might be better 
to use LOONGARCH_VIRT_MACHINE than just VIRT_MACHINE here? Philippe, could 
you comment on this?


 Thomas




Re: [PATCH 1/3] qapi/vfio: Add VFIO device migration state change QAPI event

2024-05-05 Thread Markus Armbruster
Avihai Horon  writes:

> On 02/05/2024 14:19, Markus Armbruster wrote:
>> External email: Use caution opening links or attachments
>>
>>
>> Avihai Horon  writes:
>>
>>> Add a new QAPI event for VFIO device migration state change. This event
>>> will be emitted when a VFIO device changes its migration state, for
>>> example, during migration or when stopping/starting the guest.
>>>
>>> This event can be used by management applications to get updates on the
>>> current state of the VFIO device for their own purposes.
>>>
>>> Signed-off-by: Avihai Horon 
>>
>> Can you explain briefly why this event makes sense only for VFIO devices?
>
> VFIO devices have their own protocol for migration and a unique set of 
> migration states.
> This event holds info about these VFIO migration states, which I think cannot 
> be described in the same accuracy by other events such as run state or 
> migration states.

Would it make sense to work this into the commit message?

[...]




Re: [PATCH 4/4] tests/qtest: Check STM32L4x5 clock connections

2024-05-05 Thread Thomas Huth

On 05/05/2024 16.05, Inès Varhol wrote:

For USART, GPIO and SYSCFG devices, check that clock frequency before
and after enabling the peripheral clock in RCC is correct.

Signed-off-by: Inès Varhol 
---
Hello,

Should these tests be regrouped in stm32l4x5_rcc-test.c ?


 Hi,

sounds mostly like a matter of taste at a first glance. Or what would be the 
benefit of putting everything into the *rcc-test.c file? Could you maybe 
consolidate the get_clock_freq_hz() function that way? (maybe that 
get_clock_freq_hz() function could also be consolidated as a inline function 
in a shared header instead?)


 Thomas




Re: [PATCH v2 11/15] hw/riscv/riscv-iommu: add DBG support

2024-05-05 Thread Frank Chang
Hi Daniel,

Daniel Henrique Barboza  於 2024年3月8日 週五 上午12:05寫道:
>
> From: Tomasz Jeznach 
>
> DBG support adds three additional registers: tr_req_iova, tr_req_ctl and
> tr_response.
>
> The DBG cap is always enabled. No on/off toggle is provided for it.
>
> Signed-off-by: Tomasz Jeznach 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  hw/riscv/riscv-iommu-bits.h | 20 +
>  hw/riscv/riscv-iommu.c  | 57 -
>  2 files changed, 76 insertions(+), 1 deletion(-)
>
> diff --git a/hw/riscv/riscv-iommu-bits.h b/hw/riscv/riscv-iommu-bits.h
> index 0994f5ce48..b3f92411bb 100644
> --- a/hw/riscv/riscv-iommu-bits.h
> +++ b/hw/riscv/riscv-iommu-bits.h
> @@ -83,6 +83,7 @@ struct riscv_iommu_pq_record {
>  #define RISCV_IOMMU_CAP_MSI_MRIFBIT_ULL(23)
>  #define RISCV_IOMMU_CAP_ATS BIT_ULL(25)
>  #define RISCV_IOMMU_CAP_IGS GENMASK_ULL(29, 28)
> +#define RISCV_IOMMU_CAP_DBG BIT_ULL(31)
>  #define RISCV_IOMMU_CAP_PAS GENMASK_ULL(37, 32)
>  #define RISCV_IOMMU_CAP_PD8 BIT_ULL(38)
>
> @@ -177,6 +178,25 @@ enum {
>  RISCV_IOMMU_INTR_COUNT
>  };
>
> +#define RISCV_IOMMU_IPSR_CIPBIT(RISCV_IOMMU_INTR_CQ)
> +#define RISCV_IOMMU_IPSR_FIPBIT(RISCV_IOMMU_INTR_FQ)
> +#define RISCV_IOMMU_IPSR_PMIP   BIT(RISCV_IOMMU_INTR_PM)
> +#define RISCV_IOMMU_IPSR_PIPBIT(RISCV_IOMMU_INTR_PQ)

These are not related to the DBG.

> +
> +/* 5.24 Translation request IOVA (64bits) */
> +#define RISCV_IOMMU_REG_TR_REQ_IOVA 0x0258
> +
> +/* 5.25 Translation request control (64bits) */
> +#define RISCV_IOMMU_REG_TR_REQ_CTL  0x0260
> +#define RISCV_IOMMU_TR_REQ_CTL_GO_BUSY  BIT_ULL(0)
> +#define RISCV_IOMMU_TR_REQ_CTL_PID  GENMASK_ULL(31, 12)
> +#define RISCV_IOMMU_TR_REQ_CTL_DID  GENMASK_ULL(63, 40)
> +
> +/* 5.26 Translation request response (64bits) */
> +#define RISCV_IOMMU_REG_TR_RESPONSE 0x0268
> +#define RISCV_IOMMU_TR_RESPONSE_FAULT   BIT_ULL(0)
> +#define RISCV_IOMMU_TR_RESPONSE_PPN RISCV_IOMMU_PPN_FIELD
> +
>  /* 5.27 Interrupt cause to vector (64bits) */
>  #define RISCV_IOMMU_REG_IVEC0x02F8
>
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> index 7af5929b10..1fa1286d07 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -1457,6 +1457,46 @@ static void 
> riscv_iommu_process_pq_control(RISCVIOMMUState *s)
>  riscv_iommu_reg_mod32(s, RISCV_IOMMU_REG_PQCSR, ctrl_set, ctrl_clr);
>  }
>
> +static void riscv_iommu_process_dbg(RISCVIOMMUState *s)
> +{
> +uint64_t iova = riscv_iommu_reg_get64(s, RISCV_IOMMU_REG_TR_REQ_IOVA);
> +uint64_t ctrl = riscv_iommu_reg_get64(s, RISCV_IOMMU_REG_TR_REQ_CTL);
> +unsigned devid = get_field(ctrl, RISCV_IOMMU_TR_REQ_CTL_DID);
> +unsigned pid = get_field(ctrl, RISCV_IOMMU_TR_REQ_CTL_PID);
> +RISCVIOMMUContext *ctx;
> +void *ref;
> +
> +if (!(ctrl & RISCV_IOMMU_TR_REQ_CTL_GO_BUSY)) {
> +return;
> +}
> +
> +ctx = riscv_iommu_ctx(s, devid, pid, );
> +if (ctx == NULL) {
> +riscv_iommu_reg_set64(s, RISCV_IOMMU_REG_TR_RESPONSE,
> + RISCV_IOMMU_TR_RESPONSE_FAULT |
> + (RISCV_IOMMU_FQ_CAUSE_DMA_DISABLED << 10));
> +} else {
> +IOMMUTLBEntry iotlb = {
> +.iova = iova,
> +.perm = IOMMU_NONE,

.perm should honor tr_req_ctl.[Exe|Nw]

> +.addr_mask = ~0,
> +.target_as = NULL,
> +};
> +int fault = riscv_iommu_translate(s, ctx, , false);
> +if (fault) {
> +iova = RISCV_IOMMU_TR_RESPONSE_FAULT | (((uint64_t) fault) << 
> 10);
> +} else {
> +iova = ((iotlb.translated_addr & ~iotlb.addr_mask) >> 2) &

For 4-KB page, we should right-shift 12 bits.

> +RISCV_IOMMU_TR_RESPONSE_PPN;

It's possible that the translation is not 4-KB page (i.e. superpage),
which we should set tr_response.S
and encode translation range size in tr_response.PPN.

Regards,
Frank Chang

> +}
> +riscv_iommu_reg_set64(s, RISCV_IOMMU_REG_TR_RESPONSE, iova);
> +}
> +
> +riscv_iommu_reg_mod64(s, RISCV_IOMMU_REG_TR_REQ_CTL, 0,
> +RISCV_IOMMU_TR_REQ_CTL_GO_BUSY);
> +riscv_iommu_ctx_put(s, ref);
> +}
> +
>  /* Core IOMMU execution activation */
>  enum {
>  RISCV_IOMMU_EXEC_DDTP,
> @@ -1502,7 +1542,7 @@ static void *riscv_iommu_core_proc(void* arg)
>  /* NOP */
>  break;
>  case BIT(RISCV_IOMMU_EXEC_TR_REQUEST):
> -/* DBG support not implemented yet */
> +riscv_iommu_process_dbg(s);
>  break;
>  }
>  exec &= ~mask;
> @@ -1574,6 +1614,12 @@ static MemTxResult riscv_iommu_mmio_write(void 
> *opaque, hwaddr addr,
>  exec = BIT(RISCV_IOMMU_EXEC_PQCSR);
>  busy = RISCV_IOMMU_PQCSR_BUSY;
>  break;
> +
> +case RISCV_IOMMU_REG_TR_REQ_CTL:
> +  

Re: [PATCH 0/3] virtio-net: Convert feature properties to OnOffAuto

2024-05-05 Thread Jason Wang
On Wed, May 1, 2024 at 3:20 PM Akihiko Odaki  wrote:
>
> On 2024/04/29 16:05, Michael S. Tsirkin wrote:
> > On Sun, Apr 28, 2024 at 04:21:06PM +0900, Akihiko Odaki wrote:
> >> Based-on: <20240428-rss-v10-0-73cbaa91a...@daynix.com>
> >> ("[PATCH v10 00/18] virtio-net RSS/hash report fixes and improvements")
> >>
> >> Some features are not always available, and virtio-net used to disable
> >> them when not available even if the corresponding properties were
> >> explicitly set to "on".

I think we'd better fail the initialization in this case, otherwise it
might confuse libvirt.

Adding Jonathon for more comments.

> >>
> >> Convert feature properties to OnOffAuto so that the user can explicitly
> >> tell QEMU to automatically select the value by setting them "auto".
> >> QEMU will give an error if they are set "on".
> >>
> >> Signed-off-by: Akihiko Odaki 
> >
> > Should we maybe bite the bullet allow "auto" for all binary/boolean
> > properties? Just ignore "auto" if no one cares ATM.
>
> It is not always obvious whether "auto" should be considered as "on" or
> "off" for existing boolean properties. The properties this patch deals
> with are to enable features so "auto" should be considered as "on" if
> possible. However, other properties may mean to disable features, and in
> such a case, "auto" should be considered as "off".
>
> It may still make sense to accept "auto" for all virtio-net feature bits
> for consistency. In particular, I left guest_rsc_ext property boolean
> since nobody cares "auto" for that feature, but this can be converted to
> OnOffAuto.
>

Thanks




[PATCH v3 0/5] Add migration test for loongarch64

2024-05-05 Thread Bibo Mao
Migration test case is added for loongarch64 here. Since compat machine
type is required for migration test case, also compat machine qemu 9.0
is added for loongarch virt machine.

Migration test case passes to run in both tcg and kvm mode with the
patch, 54 migration subtests passes in 188 seconds.

---
v2 ... v3:
  1. Refresh the patch based on the latest qemu version, solve the
confliction issue.

v1 ... v2:
  1. Keep the default memory size unchanged with 1GB, only modify minimum
memory size with 256MB
  2. Remove tab char in file tests/migration/loongarch64/a-b-kernel.S
---
Bibo Mao (5):
  hw/loongarch: Rename LOONGARCH_MACHINE with VIRT_MACHINE
  hw/loongarch: Rename LoongArchMachineState with VirtMachineState
  hw/loongarch: Add compat machine for 9.0
  hw/loongarch: Set minimium memory size as 256M
  tests: Add migration test for loongarch64

 hw/loongarch/acpi-build.c|  80 ++---
 hw/loongarch/boot.c  |  10 +-
 hw/loongarch/fw_cfg.c|   2 +-
 hw/loongarch/fw_cfg.h|   2 +-
 hw/loongarch/virt.c  | 364 ---
 include/hw/loongarch/virt.h  |  10 +-
 tests/migration/Makefile |   2 +-
 tests/migration/loongarch64/Makefile |  18 ++
 tests/migration/loongarch64/a-b-kernel.S |  49 +++
 tests/migration/loongarch64/a-b-kernel.h |  16 +
 tests/migration/migration-test.h |   3 +
 tests/qtest/meson.build  |   4 +
 tests/qtest/migration-test.c |  10 +
 13 files changed, 351 insertions(+), 219 deletions(-)
 create mode 100644 tests/migration/loongarch64/Makefile
 create mode 100644 tests/migration/loongarch64/a-b-kernel.S
 create mode 100644 tests/migration/loongarch64/a-b-kernel.h


base-commit: 248f6f62df073a3b4158fd0093863ab885feabb5
-- 
2.39.3




[PATCH v3 1/5] hw/loongarch: Rename LOONGARCH_MACHINE with VIRT_MACHINE

2024-05-05 Thread Bibo Mao
On LoongArch system, there is only virt machine type now, name
LOONGARCH_MACHINE is confused, rename it with VIRT_MACHINE. Machine name
about Other real hw boards can be added in future.

Signed-off-by: Bibo Mao 
---
 hw/loongarch/acpi-build.c   |  8 
 hw/loongarch/boot.c |  2 +-
 hw/loongarch/virt.c | 19 +--
 include/hw/loongarch/virt.h |  4 ++--
 4 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
index e5ab1080af..72322cdb1e 100644
--- a/hw/loongarch/acpi-build.c
+++ b/hw/loongarch/acpi-build.c
@@ -167,7 +167,7 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
MachineState *machine)
 int i, arch_id, node_id;
 uint64_t mem_len, mem_base;
 int nb_numa_nodes = machine->numa_state->num_nodes;
-LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
+LoongArchMachineState *lams = VIRT_MACHINE(machine);
 MachineClass *mc = MACHINE_GET_CLASS(lams);
 const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine);
 AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lams->oem_id,
@@ -279,7 +279,7 @@ static void
 build_la_ged_aml(Aml *dsdt, MachineState *machine)
 {
 uint32_t event;
-LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
+LoongArchMachineState *lams = VIRT_MACHINE(machine);
 
 build_ged_aml(dsdt, "\\_SB."GED_DEVICE,
   HOTPLUG_HANDLER(lams->acpi_ged),
@@ -391,7 +391,7 @@ static void
 build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
 {
 Aml *dsdt, *scope, *pkg;
-LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
+LoongArchMachineState *lams = VIRT_MACHINE(machine);
 AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lams->oem_id,
 .oem_table_id = lams->oem_table_id };
 
@@ -421,7 +421,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
MachineState *machine)
 
 static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
 {
-LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
+LoongArchMachineState *lams = VIRT_MACHINE(machine);
 GArray *table_offsets;
 AcpiFadtData fadt_data;
 unsigned facs, rsdt, dsdt;
diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c
index 7d1630b2e7..e46c70b1b3 100644
--- a/hw/loongarch/boot.c
+++ b/hw/loongarch/boot.c
@@ -316,7 +316,7 @@ static void loongarch_direct_kernel_boot(struct 
loongarch_boot_info *info)
 
 void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info)
 {
-LoongArchMachineState *lams = LOONGARCH_MACHINE(ms);
+LoongArchMachineState *lams = VIRT_MACHINE(ms);
 int i;
 
 /* register reset function */
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index c0999878df..e343974b48 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -880,7 +880,7 @@ static void loongarch_init(MachineState *machine)
 ram_addr_t ram_size = machine->ram_size;
 uint64_t highram_size = 0, phyAddr = 0;
 MemoryRegion *address_space_mem = get_system_memory();
-LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
+LoongArchMachineState *lams = VIRT_MACHINE(machine);
 int nb_numa_nodes = machine->numa_state->num_nodes;
 NodeInfo *numa_info = machine->numa_state->nodes;
 int i;
@@ -1032,7 +1032,7 @@ bool loongarch_is_acpi_enabled(LoongArchMachineState 
*lams)
 static void loongarch_get_acpi(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
 {
-LoongArchMachineState *lams = LOONGARCH_MACHINE(obj);
+LoongArchMachineState *lams = VIRT_MACHINE(obj);
 OnOffAuto acpi = lams->acpi;
 
 visit_type_OnOffAuto(v, name, , errp);
@@ -1041,14 +1041,14 @@ static void loongarch_get_acpi(Object *obj, Visitor *v, 
const char *name,
 static void loongarch_set_acpi(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
 {
-LoongArchMachineState *lams = LOONGARCH_MACHINE(obj);
+LoongArchMachineState *lams = VIRT_MACHINE(obj);
 
 visit_type_OnOffAuto(v, name, >acpi, errp);
 }
 
 static void loongarch_machine_initfn(Object *obj)
 {
-LoongArchMachineState *lams = LOONGARCH_MACHINE(obj);
+LoongArchMachineState *lams = VIRT_MACHINE(obj);
 
 lams->acpi = ON_OFF_AUTO_AUTO;
 lams->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
@@ -1080,7 +1080,7 @@ static void virt_machine_device_pre_plug(HotplugHandler 
*hotplug_dev,
 static void virt_mem_unplug_request(HotplugHandler *hotplug_dev,
  DeviceState *dev, Error **errp)
 {
-LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev);
+LoongArchMachineState *lams = VIRT_MACHINE(hotplug_dev);
 
 /* the acpi ged is always exist */
 hotplug_handler_unplug_request(HOTPLUG_HANDLER(lams->acpi_ged), dev,
@@ -1098,7 +1098,7 @@ static void 
virt_machine_device_unplug_request(HotplugHandler 

[PATCH v3 4/5] hw/loongarch: Set minimium memory size as 256M

2024-05-05 Thread Bibo Mao
The minimum memory size for LoongArch UEFI bios is 256M, also some
test cases such as migration and qos use 256M memory by default.

Here set minimum memory size for Loongarch VirtMachine with 256M rather
than 1G, so that test cases with 256M memory can pass to run.

Signed-off-by: Bibo Mao 
---
 hw/loongarch/virt.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 8a6e2d6677..7d699c036b 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -919,8 +919,8 @@ static void virt_init(MachineState *machine)
 cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
 }
 
-if (ram_size < 1 * GiB) {
-error_report("ram_size must be greater than 1G.");
+if (ram_size < 256 * MiB) {
+error_report("ram_size must be greater than 256M.");
 exit(1);
 }
 create_fdt(vms);
-- 
2.39.3




[PATCH v3 2/5] hw/loongarch: Rename LoongArchMachineState with VirtMachineState

2024-05-05 Thread Bibo Mao
Rename LoongArchMachineState with VirtMachineState, and change variable
name LoongArchMachineState *lams with VirtMachineState *vms, and rename
function loongarch_xxx() with virt_xxx() also.

Signed-off-by: Bibo Mao 
---
 hw/loongarch/acpi-build.c   |  80 +-
 hw/loongarch/boot.c |  10 +-
 hw/loongarch/fw_cfg.c   |   2 +-
 hw/loongarch/fw_cfg.h   |   2 +-
 hw/loongarch/virt.c | 309 ++--
 include/hw/loongarch/virt.h |   8 +-
 6 files changed, 205 insertions(+), 206 deletions(-)

diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
index 72322cdb1e..b6741809ef 100644
--- a/hw/loongarch/acpi-build.c
+++ b/hw/loongarch/acpi-build.c
@@ -105,14 +105,14 @@ build_facs(GArray *table_data)
 
 /* build MADT */
 static void
-build_madt(GArray *table_data, BIOSLinker *linker, LoongArchMachineState *lams)
+build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
 {
-MachineState *ms = MACHINE(lams);
+MachineState *ms = MACHINE(vms);
 MachineClass *mc = MACHINE_GET_CLASS(ms);
 const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms);
 int i, arch_id;
-AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lams->oem_id,
-.oem_table_id = lams->oem_table_id };
+AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = vms->oem_id,
+.oem_table_id = vms->oem_table_id };
 
 acpi_table_begin(, table_data);
 
@@ -167,11 +167,11 @@ build_srat(GArray *table_data, BIOSLinker *linker, 
MachineState *machine)
 int i, arch_id, node_id;
 uint64_t mem_len, mem_base;
 int nb_numa_nodes = machine->numa_state->num_nodes;
-LoongArchMachineState *lams = VIRT_MACHINE(machine);
-MachineClass *mc = MACHINE_GET_CLASS(lams);
+VirtMachineState *vms = VIRT_MACHINE(machine);
+MachineClass *mc = MACHINE_GET_CLASS(vms);
 const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine);
-AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lams->oem_id,
-.oem_table_id = lams->oem_table_id };
+AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = vms->oem_id,
+.oem_table_id = vms->oem_table_id };
 
 acpi_table_begin(, table_data);
 build_append_int_noprefix(table_data, 1, 4); /* Reserved */
@@ -279,13 +279,13 @@ static void
 build_la_ged_aml(Aml *dsdt, MachineState *machine)
 {
 uint32_t event;
-LoongArchMachineState *lams = VIRT_MACHINE(machine);
+VirtMachineState *vms = VIRT_MACHINE(machine);
 
 build_ged_aml(dsdt, "\\_SB."GED_DEVICE,
-  HOTPLUG_HANDLER(lams->acpi_ged),
+  HOTPLUG_HANDLER(vms->acpi_ged),
   VIRT_SCI_IRQ, AML_SYSTEM_MEMORY,
   VIRT_GED_EVT_ADDR);
-event = object_property_get_uint(OBJECT(lams->acpi_ged),
+event = object_property_get_uint(OBJECT(vms->acpi_ged),
  "ged-event", _abort);
 if (event & ACPI_GED_MEM_HOTPLUG_EVT) {
 build_memory_hotplug_aml(dsdt, machine->ram_slots, "\\_SB", NULL,
@@ -295,7 +295,7 @@ build_la_ged_aml(Aml *dsdt, MachineState *machine)
 acpi_dsdt_add_power_button(dsdt);
 }
 
-static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams)
+static void build_pci_device_aml(Aml *scope, VirtMachineState *vms)
 {
 struct GPEXConfig cfg = {
 .mmio64.base = VIRT_PCI_MEM_BASE,
@@ -305,13 +305,13 @@ static void build_pci_device_aml(Aml *scope, 
LoongArchMachineState *lams)
 .ecam.base   = VIRT_PCI_CFG_BASE,
 .ecam.size   = VIRT_PCI_CFG_SIZE,
 .irq = VIRT_GSI_BASE + VIRT_DEVICE_IRQS,
-.bus = lams->pci_bus,
+.bus = vms->pci_bus,
 };
 
 acpi_dsdt_add_gpex(scope, );
 }
 
-static void build_flash_aml(Aml *scope, LoongArchMachineState *lams)
+static void build_flash_aml(Aml *scope, VirtMachineState *vms)
 {
 Aml *dev, *crs;
 MemoryRegion *flash_mem;
@@ -322,11 +322,11 @@ static void build_flash_aml(Aml *scope, 
LoongArchMachineState *lams)
 hwaddr flash1_base;
 hwaddr flash1_size;
 
-flash_mem = pflash_cfi01_get_memory(lams->flash[0]);
+flash_mem = pflash_cfi01_get_memory(vms->flash[0]);
 flash0_base = flash_mem->addr;
 flash0_size = memory_region_size(flash_mem);
 
-flash_mem = pflash_cfi01_get_memory(lams->flash[1]);
+flash_mem = pflash_cfi01_get_memory(vms->flash[1]);
 flash1_base = flash_mem->addr;
 flash1_size = memory_region_size(flash_mem);
 
@@ -352,7 +352,7 @@ static void build_flash_aml(Aml *scope, 
LoongArchMachineState *lams)
 }
 
 #ifdef CONFIG_TPM
-static void acpi_dsdt_add_tpm(Aml *scope, LoongArchMachineState *vms)
+static void acpi_dsdt_add_tpm(Aml *scope, VirtMachineState *vms)
 {
 PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
 hwaddr pbus_base = VIRT_PLATFORM_BUS_BASEADDRESS;
@@ -391,18 +391,18 @@ static void
 build_dsdt(GArray 

[PATCH v3 3/5] hw/loongarch: Add compat machine for 9.0

2024-05-05 Thread Bibo Mao
Since migration test case requires compat machine type support,
compat machine is added for qemu 9.0 here.

Signed-off-by: Bibo Mao 
---
 hw/loongarch/virt.c | 60 +++--
 1 file changed, 47 insertions(+), 13 deletions(-)

diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index c8d697f38f..8a6e2d6677 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -408,6 +408,32 @@ static void fdt_add_pcie_irq_map_node(const 
VirtMachineState *vms,
 }
 }
 
+#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
+static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
+void *data) \
+{ \
+MachineClass *mc = MACHINE_CLASS(oc); \
+virt_machine_##major##_##minor##_options(mc); \
+mc->desc = "QEMU " # major "." # minor " ARM Virtual Machine"; \
+if (latest) { \
+mc->alias = "virt"; \
+} \
+} \
+static const TypeInfo machvirt_##major##_##minor##_info = { \
+.name = MACHINE_TYPE_NAME("virt-" # major "." # minor), \
+.parent = TYPE_VIRT_MACHINE, \
+.class_init = virt_##major##_##minor##_class_init, \
+}; \
+static void machvirt_machine_##major##_##minor##_init(void) \
+{ \
+type_register_static(_##major##_##minor##_info); \
+} \
+type_init(machvirt_machine_##major##_##minor##_init);
+
+#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor) \
+DEFINE_VIRT_MACHINE_LATEST(major, minor, true)
+#define DEFINE_VIRT_MACHINE(major, minor) \
+DEFINE_VIRT_MACHINE_LATEST(major, minor, false)
 
 qemu_fdt_setprop(ms->fdt, nodename, "interrupt-map", full_irq_map,
  GPEX_NUM_IRQS * GPEX_NUM_IRQS *
@@ -1241,18 +1267,26 @@ static void virt_class_init(ObjectClass *oc, void *data)
 #endif
 }
 
-static const TypeInfo virt_machine_types[] = {
-{
-.name   = TYPE_VIRT_MACHINE,
-.parent = TYPE_MACHINE,
-.instance_size  = sizeof(VirtMachineState),
-.class_init = virt_class_init,
-.instance_init = virt_machine_initfn,
-.interfaces = (InterfaceInfo[]) {
- { TYPE_HOTPLUG_HANDLER },
- { }
-},
-}
+static const TypeInfo virt_machine_info = {
+.name   = TYPE_VIRT_MACHINE,
+.parent = TYPE_MACHINE,
+.abstract   = true,
+.instance_size  = sizeof(VirtMachineState),
+.class_init = virt_class_init,
+.instance_init = virt_machine_initfn,
+.interfaces = (InterfaceInfo[]) {
+{ TYPE_HOTPLUG_HANDLER },
+{ }
+},
 };
 
-DEFINE_TYPES(virt_machine_types)
+static void machvirt_machine_init(void)
+{
+type_register_static(_machine_info);
+}
+type_init(machvirt_machine_init);
+
+static void virt_machine_9_0_options(MachineClass *mc)
+{
+}
+DEFINE_VIRT_MACHINE_AS_LATEST(9, 0)
-- 
2.39.3




[PATCH v3 5/5] tests: Add migration test for loongarch64

2024-05-05 Thread Bibo Mao
This patch adds migration test support for loongarch64. The test code
comes from aarch64 mostly, only that it booted as bios in qemu since
kernel requires elf format and bios uses binary format.

In addition to providing the binary, this patch also includes the source
code and the build script in tests/migration/loongarch64. So users can
change the source and/or re-compile the binary as they wish.

Signed-off-by: Bibo Mao 
Acked-by: Thomas Huth 
Acked-by: Peter Xu 
Reviewed-by: Fabiano Rosas 
---
 tests/migration/Makefile |  2 +-
 tests/migration/loongarch64/Makefile | 18 +
 tests/migration/loongarch64/a-b-kernel.S | 49 
 tests/migration/loongarch64/a-b-kernel.h | 16 
 tests/migration/migration-test.h |  3 ++
 tests/qtest/meson.build  |  4 ++
 tests/qtest/migration-test.c | 10 +
 7 files changed, 101 insertions(+), 1 deletion(-)
 create mode 100644 tests/migration/loongarch64/Makefile
 create mode 100644 tests/migration/loongarch64/a-b-kernel.S
 create mode 100644 tests/migration/loongarch64/a-b-kernel.h

diff --git a/tests/migration/Makefile b/tests/migration/Makefile
index 13e99b1692..cfebfe23f8 100644
--- a/tests/migration/Makefile
+++ b/tests/migration/Makefile
@@ -5,7 +5,7 @@
 # See the COPYING file in the top-level directory.
 #
 
-TARGET_LIST = i386 aarch64 s390x
+TARGET_LIST = i386 aarch64 s390x loongarch64
 
 SRC_PATH = ../..
 
diff --git a/tests/migration/loongarch64/Makefile 
b/tests/migration/loongarch64/Makefile
new file mode 100644
index 00..5d8719205f
--- /dev/null
+++ b/tests/migration/loongarch64/Makefile
@@ -0,0 +1,18 @@
+# To specify cross compiler prefix, use CROSS_PREFIX=
+#   $ make CROSS_PREFIX=loongarch64-linux-gnu-
+
+.PHONY: all clean
+all: a-b-kernel.h
+
+a-b-kernel.h: loongarch64.kernel
+   echo "$$__note" > $@
+   xxd -i $< | sed -e 's/.*int.*//' >> $@
+
+loongarch64.kernel: loongarch64.elf
+   $(CROSS_PREFIX)objcopy -j .text -O binary $< $@
+
+loongarch64.elf: a-b-kernel.S
+   $(CROSS_PREFIX)gcc -o $@ -nostdlib -Wl,--build-id=none $<
+
+clean:
+   $(RM) *.kernel *.elf
diff --git a/tests/migration/loongarch64/a-b-kernel.S 
b/tests/migration/loongarch64/a-b-kernel.S
new file mode 100644
index 00..cd543345fe
--- /dev/null
+++ b/tests/migration/loongarch64/a-b-kernel.S
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2024 Loongson Technology Corporation Limited
+ */
+#include "../migration-test.h"
+
+#define LOONGARCH_CSR_CRMD  0
+#define LOONGARCH_VIRT_UART 0x1FE001E0
+.section .text
+
+.globl  _start
+_start:
+/* output char 'A' to UART16550 */
+li.d$t0, LOONGARCH_VIRT_UART
+li.w$t1, 'A'
+st.b$t1, $t0, 0
+
+/* traverse test memory region */
+li.d$t0, LOONGARCH_TEST_MEM_START
+li.d$t1, LOONGARCH_TEST_MEM_END
+li.d$t2, TEST_MEM_PAGE_SIZE
+li.d$t4, LOONGARCH_VIRT_UART
+li.w$t5, 'B'
+
+clean:
+st.b$zero, $t0, 0
+add.d   $t0,   $t0, $t2
+bne $t0,   $t1, clean
+/* keeps a counter so we can limit the output speed */
+addi.d  $t6,   $zero, 0
+
+mainloop:
+li.d$t0, LOONGARCH_TEST_MEM_START
+
+innerloop:
+ld.bu   $t3, $t0, 0
+addi.w  $t3, $t3, 1
+ext.w.b $t3, $t3
+st.b$t3, $t0, 0
+add.d   $t0, $t0, $t2
+bne $t0, $t1, innerloop
+
+addi.d  $t6, $t6, 1
+andi$t6, $t6, 31
+bnez$t6, mainloop
+
+st.b$t5, $t4, 0
+b   mainloop
+nop
diff --git a/tests/migration/loongarch64/a-b-kernel.h 
b/tests/migration/loongarch64/a-b-kernel.h
new file mode 100644
index 00..b3fe466754
--- /dev/null
+++ b/tests/migration/loongarch64/a-b-kernel.h
@@ -0,0 +1,16 @@
+/* This file is automatically generated from the assembly file in
+* tests/migration/loongarch64. Edit that file and then run "make all"
+* inside tests/migration to update, and then remember to send both
+* the header and the assembler differences in your patch submission.
+*/
+unsigned char loongarch64_kernel[] = {
+  0x0c, 0xc0, 0x3f, 0x14, 0x8c, 0x81, 0x87, 0x03, 0x0d, 0x04, 0x81, 0x03,
+  0x8d, 0x01, 0x00, 0x29, 0x0c, 0x00, 0x04, 0x14, 0x0d, 0x80, 0x0c, 0x14,
+  0x2e, 0x00, 0x00, 0x14, 0x10, 0xc0, 0x3f, 0x14, 0x10, 0x82, 0x87, 0x03,
+  0x11, 0x08, 0x81, 0x03, 0x80, 0x01, 0x00, 0x29, 0x8c, 0xb9, 0x10, 0x00,
+  0x8d, 0xf9, 0xff, 0x5f, 0x12, 0x00, 0xc0, 0x02, 0x0c, 0x00, 0x04, 0x14,
+  0x8f, 0x01, 0x00, 0x2a, 0xef, 0x05, 0x80, 0x02, 0xef, 0x5d, 0x00, 0x00,
+  0x8f, 0x01, 0x00, 0x29, 0x8c, 0xb9, 0x10, 0x00, 0x8d, 0xed, 0xff, 0x5f,
+  0x52, 0x06, 0xc0, 0x02, 0x52, 0x7e, 0x40, 0x03, 0x5f, 0xde, 0xff, 0x47,
+  0x11, 0x02, 0x00, 0x29, 0xff, 0xd7, 0xff, 0x53, 0x00, 0x00, 0x40, 0x03
+};
diff --git a/tests/migration/migration-test.h b/tests/migration/migration-test.h
index 68512c0b1b..f402e48349 100644
--- a/tests/migration/migration-test.h
+++ b/tests/migration/migration-test.h
@@ 

[PULL 10/15] Hexagon (target/hexagon) Mark has_pred_dest in trans functions

2024-05-05 Thread Brian Cain
From: Taylor Simpson 

Check that the value matches opcode_wregs

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20240307032327.4799-5-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/decode.c   | 3 +++
 target/hexagon/gen_trans_funcs.py | 5 +
 target/hexagon/insn.h | 1 +
 3 files changed, 9 insertions(+)

diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c
index a4d8500fea..84a3899556 100644
--- a/target/hexagon/decode.c
+++ b/target/hexagon/decode.c
@@ -366,6 +366,9 @@ static void decode_shuffle_for_execution(Packet *packet)
 for (flag = false, i = 0; i < last_insn + 1; i++) {
 int opcode = packet->insn[i].opcode;
 
+g_assert(packet->insn[i].has_pred_dest ==
+ (strstr(opcode_wregs[opcode], "Pd4") ||
+  strstr(opcode_wregs[opcode], "Pe4")));
 if ((strstr(opcode_wregs[opcode], "Pd4") ||
  strstr(opcode_wregs[opcode], "Pe4")) &&
 GET_ATTRIB(opcode, A_STORE) == 0) {
diff --git a/target/hexagon/gen_trans_funcs.py 
b/target/hexagon/gen_trans_funcs.py
index 1201172dda..9f86b4edbd 100755
--- a/target/hexagon/gen_trans_funcs.py
+++ b/target/hexagon/gen_trans_funcs.py
@@ -70,6 +70,7 @@ def mark_which_imm_extended(f, tag):
 ## insn->regno[2] = args->Rt;
 ## insn->new_read_idx = -1;
 ## insn->dest_idx = 0;
+## insn->has_pred_dest = false;
 ## return true;
 ## }
 ##
@@ -88,6 +89,7 @@ def gen_trans_funcs(f):
 
 new_read_idx = -1
 dest_idx = -1
+has_pred_dest = "false"
 for regno, (reg_type, reg_id, *_) in enumerate(regs):
 reg = hex_common.get_register(tag, reg_type, reg_id)
 f.write(code_fmt(f"""\
@@ -98,6 +100,8 @@ def gen_trans_funcs(f):
 # dest_idx should be the first destination, so check for -1
 if reg.is_written() and dest_idx == -1:
 dest_idx = regno
+if reg_type == "P" and reg.is_written() and not reg.is_read():
+has_pred_dest = "true"
 
 if len(imms) != 0:
 mark_which_imm_extended(f, tag)
@@ -121,6 +125,7 @@ def gen_trans_funcs(f):
 f.write(code_fmt(f"""\
 insn->new_read_idx = {new_read_idx};
 insn->dest_idx = {dest_idx};
+insn->has_pred_dest = {has_pred_dest};
 """))
 f.write(textwrap.dedent(f"""\
 return true;
diff --git a/target/hexagon/insn.h b/target/hexagon/insn.h
index a770379958..24dcf7fe9f 100644
--- a/target/hexagon/insn.h
+++ b/target/hexagon/insn.h
@@ -41,6 +41,7 @@ struct Instruction {
 uint32_t new_value_producer_slot:4;
 int32_t new_read_idx;
 int32_t dest_idx;
+bool has_pred_dest;
 
 bool part1;  /*
   * cmp-jumps are split into two insns.
-- 
2.25.1



[PULL 14/15] Hexagon (target/hexagon) Remove gen_shortcode.py

2024-05-05 Thread Brian Cain
From: Taylor Simpson 

This data structure is not used

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20240307032327.4799-9-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/README   |  1 -
 target/hexagon/gen_shortcode.py | 63 -
 target/hexagon/meson.build  | 10 --
 target/hexagon/opcodes.c|  7 
 4 files changed, 81 deletions(-)
 delete mode 100755 target/hexagon/gen_shortcode.py

diff --git a/target/hexagon/README b/target/hexagon/README
index 224a3f9206..7ffd517d70 100644
--- a/target/hexagon/README
+++ b/target/hexagon/README
@@ -46,7 +46,6 @@ header files in /target/hexagon
 gen_printinsn.py-> printinsn_generated.h.inc
 gen_op_attribs.py   -> op_attribs_generated.h.inc
 gen_helper_protos.py-> helper_protos_generated.h.inc
-gen_shortcode.py-> shortcode_generated.h.inc
 gen_tcg_funcs.py-> tcg_funcs_generated.c.inc
 gen_tcg_func_table.py   -> tcg_func_table_generated.c.inc
 gen_helper_funcs.py -> helper_funcs_generated.c.inc
diff --git a/target/hexagon/gen_shortcode.py b/target/hexagon/gen_shortcode.py
deleted file mode 100755
index deb94446c4..00
--- a/target/hexagon/gen_shortcode.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env python3
-
-##
-##  Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
-##
-##  This program is free software; you can redistribute it and/or modify
-##  it under the terms of the GNU General Public License as published by
-##  the Free Software Foundation; either version 2 of the License, or
-##  (at your option) any later version.
-##
-##  This program is distributed in the hope that it will be useful,
-##  but WITHOUT ANY WARRANTY; without even the implied warranty of
-##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-##  GNU General Public License for more details.
-##
-##  You should have received a copy of the GNU General Public License
-##  along with this program; if not, see .
-##
-
-import sys
-import re
-import string
-import hex_common
-
-
-def gen_shortcode(f, tag):
-f.write(f"DEF_SHORTCODE({tag}, {hex_common.semdict[tag]})\n")
-
-
-def main():
-hex_common.read_semantics_file(sys.argv[1])
-hex_common.read_attribs_file(sys.argv[2])
-hex_common.calculate_attribs()
-tagregs = hex_common.get_tagregs()
-tagimms = hex_common.get_tagimms()
-
-with open(sys.argv[3], "w") as f:
-f.write("#ifndef DEF_SHORTCODE\n")
-f.write("#define DEF_SHORTCODE(TAG,SHORTCODE)/* Nothing */\n")
-f.write("#endif\n")
-
-for tag in hex_common.tags:
-## Skip the priv instructions
-if "A_PRIV" in hex_common.attribdict[tag]:
-continue
-## Skip the guest instructions
-if "A_GUEST" in hex_common.attribdict[tag]:
-continue
-## Skip the diag instructions
-if tag == "Y6_diag":
-continue
-if tag == "Y6_diag0":
-continue
-if tag == "Y6_diag1":
-continue
-
-gen_shortcode(f, tag)
-
-f.write("#undef DEF_SHORTCODE\n")
-
-
-if __name__ == "__main__":
-main()
diff --git a/target/hexagon/meson.build b/target/hexagon/meson.build
index b3a0944d3b..988e7489ba 100644
--- a/target/hexagon/meson.build
+++ b/target/hexagon/meson.build
@@ -42,21 +42,11 @@ hexagon_ss.add(semantics_generated)
 #
 # Step 2
 # We use Python scripts to generate the following files
-# shortcode_generated.h.inc
 # tcg_func_table_generated.c.inc
 # printinsn_generated.h.inc
 # op_attribs_generated.h.inc
 # opcodes_def_generated.h.inc
 #
-shortcode_generated = custom_target(
-'shortcode_generated.h.inc',
-output: 'shortcode_generated.h.inc',
-depends: [semantics_generated],
-depend_files: [hex_common_py, attribs_def],
-command: [python, files('gen_shortcode.py'), semantics_generated, 
attribs_def, '@OUTPUT@'],
-)
-hexagon_ss.add(shortcode_generated)
-
 tcg_func_table_generated = custom_target(
 'tcg_func_table_generated.c.inc',
 output: 'tcg_func_table_generated.c.inc',
diff --git a/target/hexagon/opcodes.c b/target/hexagon/opcodes.c
index 02ae9cf787..c8bde2f9e9 100644
--- a/target/hexagon/opcodes.c
+++ b/target/hexagon/opcodes.c
@@ -37,13 +37,6 @@ const char * const opcode_names[] = {
 };
 
 
-const char * const opcode_short_semantics[] = {
-#define DEF_SHORTCODE(TAG, SHORTCODE)  [TAG] = #SHORTCODE,
-#include "shortcode_generated.h.inc"
-#undef DEF_SHORTCODE
-NULL
-};
-
 DECLARE_BITMAP(opcode_attribs[XX_LAST_OPCODE], A_ZZ_LASTATTRIB);
 
 static void init_attribs(int tag, ...)
-- 
2.25.1



[PULL 05/15] Hexagon (target/hexagon) Pass SP explicitly to helpers that need it

2024-05-05 Thread Brian Cain
From: Taylor Simpson 

Rather than reading SP from the env, pass it explicitly

Signed-off-by: Taylor Simpson 
Reviewed-by: Anton Johansson 
Tested-by: Anton Johansson 
Reviewed-by: Brian Cain 
Message-Id: <20240214042726.19290-3-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/attribs_def.h.inc |  3 ++-
 target/hexagon/hex_common.py | 11 +++
 target/hexagon/macros.h  |  2 +-
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/target/hexagon/attribs_def.h.inc b/target/hexagon/attribs_def.h.inc
index 87942d46f4..9e3a05f882 100644
--- a/target/hexagon/attribs_def.h.inc
+++ b/target/hexagon/attribs_def.h.inc
@@ -1,5 +1,5 @@
 /*
- *  Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+ *  Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -117,6 +117,7 @@ DEF_ATTRIB(IMPLICIT_READS_P1, "Reads the P1 register", "", 
"")
 DEF_ATTRIB(IMPLICIT_READS_P2, "Reads the P2 register", "", "")
 DEF_ATTRIB(IMPLICIT_READS_P3, "Reads the P3 register", "", "")
 DEF_ATTRIB(IMPLICIT_WRITES_USR, "May write USR", "", "")
+DEF_ATTRIB(IMPLICIT_READS_SP, "Reads the SP register", "", "")
 DEF_ATTRIB(COMMUTES, "The operation is communitive", "", "")
 DEF_ATTRIB(DEALLOCRET, "dealloc_return", "", "")
 DEF_ATTRIB(DEALLOCFRAME, "deallocframe", "", "")
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index 63d18f73ad..03c9ce1d8a 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -101,6 +101,7 @@ def calculate_attribs():
 add_qemu_macro_attrib('fLSBNEW1', 'A_IMPLICIT_READS_P1')
 add_qemu_macro_attrib('fLSBNEW1NOT', 'A_IMPLICIT_READS_P1')
 add_qemu_macro_attrib('fREAD_P3', 'A_IMPLICIT_READS_P3')
+add_qemu_macro_attrib('fREAD_SP', 'A_IMPLICIT_READS_SP')
 
 # Recurse down macros, find attributes from sub-macros
 macroValues = list(macros.values())
@@ -201,6 +202,10 @@ def need_p0(tag):
 return "A_IMPLICIT_READS_P0" in attribdict[tag]
 
 
+def need_sp(tag):
+return "A_IMPLICIT_READS_SP" in attribdict[tag]
+
+
 def need_slot(tag):
 if (
 "A_CVI_SCATTER" not in attribdict[tag]
@@ -1144,6 +1149,12 @@ def helper_args(tag, regs, imms):
 "hex_pred[0]",
 "uint32_t P0"
 ))
+if need_sp(tag):
+args.append(HelperArg(
+"i32",
+"hex_gpr[HEX_REG_SP]",
+"uint32_t SP"
+))
 if need_slot(tag):
 args.append(HelperArg(
 "i32",
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index aedc863fab..feb798c6c0 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -343,7 +343,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int 
shift)
 
 #define fREAD_LR() (env->gpr[HEX_REG_LR])
 
-#define fREAD_SP() (env->gpr[HEX_REG_SP])
+#define fREAD_SP() (SP)
 #define fREAD_LC0 (env->gpr[HEX_REG_LC0])
 #define fREAD_LC1 (env->gpr[HEX_REG_LC1])
 #define fREAD_SA0 (env->gpr[HEX_REG_SA0])
-- 
2.25.1



[PULL 15/15] Hexagon (target/hexagon) Remove hex_common.read_attribs_file

2024-05-05 Thread Brian Cain
From: Taylor Simpson 

The attribinfo data structure is not used
Adjust the command-line arguments to the python scripts
Add hex_common.read_common_files for TCG/helper generation scripts

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Reviewed-by: Philippe Mathieu-Daudé 
Message-Id: <20240307032327.4799-10-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/gen_analyze_funcs.py | 19 +-
 target/hexagon/gen_helper_funcs.py  | 21 ++-
 target/hexagon/gen_helper_protos.py | 19 +-
 target/hexagon/gen_idef_parser_funcs.py |  5 ++--
 target/hexagon/gen_op_attribs.py|  5 ++--
 target/hexagon/gen_opcodes_def.py   |  4 +--
 target/hexagon/gen_printinsn.py |  5 ++--
 target/hexagon/gen_tcg_func_table.py|  5 ++--
 target/hexagon/gen_tcg_funcs.py | 21 ++-
 target/hexagon/hex_common.py| 35 +++--
 target/hexagon/meson.build  | 31 +++---
 11 files changed, 52 insertions(+), 118 deletions(-)

diff --git a/target/hexagon/gen_analyze_funcs.py 
b/target/hexagon/gen_analyze_funcs.py
index 81e1d9cfa3..54bac19724 100755
--- a/target/hexagon/gen_analyze_funcs.py
+++ b/target/hexagon/gen_analyze_funcs.py
@@ -78,24 +78,7 @@ def gen_analyze_func(f, tag, regs, imms):
 
 
 def main():
-hex_common.read_semantics_file(sys.argv[1])
-hex_common.read_attribs_file(sys.argv[2])
-hex_common.read_overrides_file(sys.argv[3])
-hex_common.read_overrides_file(sys.argv[4])
-## Whether or not idef-parser is enabled is
-## determined by the number of arguments to
-## this script:
-##
-##   5 args. -> not enabled,
-##   6 args. -> idef-parser enabled.
-##
-## The 6:th arg. then holds a list of the successfully
-## parsed instructions.
-is_idef_parser_enabled = len(sys.argv) > 6
-if is_idef_parser_enabled:
-hex_common.read_idef_parser_enabled_file(sys.argv[5])
-hex_common.calculate_attribs()
-hex_common.init_registers()
+hex_common.read_common_files()
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
diff --git a/target/hexagon/gen_helper_funcs.py 
b/target/hexagon/gen_helper_funcs.py
index 9cc3d69c49..e9685bff2f 100755
--- a/target/hexagon/gen_helper_funcs.py
+++ b/target/hexagon/gen_helper_funcs.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 
 ##
-##  Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+##  Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
 ##
 ##  This program is free software; you can redistribute it and/or modify
 ##  it under the terms of the GNU General Public License as published by
@@ -102,24 +102,7 @@ def gen_helper_function(f, tag, tagregs, tagimms):
 
 
 def main():
-hex_common.read_semantics_file(sys.argv[1])
-hex_common.read_attribs_file(sys.argv[2])
-hex_common.read_overrides_file(sys.argv[3])
-hex_common.read_overrides_file(sys.argv[4])
-## Whether or not idef-parser is enabled is
-## determined by the number of arguments to
-## this script:
-##
-##   5 args. -> not enabled,
-##   6 args. -> idef-parser enabled.
-##
-## The 6:th arg. then holds a list of the successfully
-## parsed instructions.
-is_idef_parser_enabled = len(sys.argv) > 6
-if is_idef_parser_enabled:
-hex_common.read_idef_parser_enabled_file(sys.argv[5])
-hex_common.calculate_attribs()
-hex_common.init_registers()
+hex_common.read_common_files()
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
diff --git a/target/hexagon/gen_helper_protos.py 
b/target/hexagon/gen_helper_protos.py
index f8578d5033..fd2bfd0f36 100755
--- a/target/hexagon/gen_helper_protos.py
+++ b/target/hexagon/gen_helper_protos.py
@@ -52,24 +52,7 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
 
 
 def main():
-hex_common.read_semantics_file(sys.argv[1])
-hex_common.read_attribs_file(sys.argv[2])
-hex_common.read_overrides_file(sys.argv[3])
-hex_common.read_overrides_file(sys.argv[4])
-## Whether or not idef-parser is enabled is
-## determined by the number of arguments to
-## this script:
-##
-##   5 args. -> not enabled,
-##   6 args. -> idef-parser enabled.
-##
-## The 6:th arg. then holds a list of the successfully
-## parsed instructions.
-is_idef_parser_enabled = len(sys.argv) > 6
-if is_idef_parser_enabled:
-hex_common.read_idef_parser_enabled_file(sys.argv[5])
-hex_common.calculate_attribs()
-hex_common.init_registers()
+hex_common.read_common_files()
 tagregs = hex_common.get_tagregs()
 tagimms = hex_common.get_tagimms()
 
diff --git a/target/hexagon/gen_idef_parser_funcs.py 
b/target/hexagon/gen_idef_parser_funcs.py
index 550a48cb7b..eb494abba8 100644
--- a/target/hexagon/gen_idef_parser_funcs.py
+++ 

Re: [PATCH 6/6] target/i386/confidential-guest: Fix comment of x86_confidential_guest_kvm_type()

2024-05-05 Thread Zhao Liu
Hi Xiaoyao,

On Sat, Apr 27, 2024 at 07:05:41AM +0800, Xiaoyao Li wrote:
> Date: Sat, 27 Apr 2024 07:05:41 +0800
> From: Xiaoyao Li 
> Subject: Re: [PATCH 6/6] target/i386/confidential-guest: Fix comment of
>  x86_confidential_guest_kvm_type()
> 
> On 4/26/2024 6:07 PM, Zhao Liu wrote:
> > Update the comment to match the X86ConfidentialGuestClass
> > implementation.
> > 
> > Suggested-by: Xiaoyao Li 
> 
> I think it should be "Reported-by"
>

Right, let me fix and respin it.

Thanks,
Zhao




[PULL 06/15] Hexagon (target/hexagon) Only pass env to generated helper when needed

2024-05-05 Thread Brian Cain
From: Taylor Simpson 

Currently, we pass env to every generated helper.  When the semantics of
the instruction only depend on the arguments, this is unnecessary and
adds extra overhead to the helper call.

We add the TCG_CALL_NO_RWG_SE flag to any non-HVX helpers that don't get
the ptr to env.

The A2_nop and SA1_setin1 instructions end up with no arguments.  This
results in a "old-style function definition" error from the compiler, so
we write overrides for them.

With this change, the number of helpers with env argument is
idef-parser enabled:329 total, 23 with env
idef-parser disabled:   1543 total, 550 with env

Signed-off-by: Taylor Simpson 
Reviewed-by: Anton Johansson 
Tested-by: Anton Johansson 
Message-Id: <20240214042726.19290-4-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/gen_helper_protos.py | 12 ++--
 target/hexagon/gen_tcg.h|  5 -
 target/hexagon/hex_common.py| 23 ++-
 3 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/target/hexagon/gen_helper_protos.py 
b/target/hexagon/gen_helper_protos.py
index c82b0f54e4..f8578d5033 100755
--- a/target/hexagon/gen_helper_protos.py
+++ b/target/hexagon/gen_helper_protos.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 
 ##
-##  Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+##  Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
 ##
 ##  This program is free software; you can redistribute it and/or modify
 ##  it under the terms of the GNU General Public License as published by
@@ -40,7 +40,15 @@ def gen_helper_prototype(f, tag, tagregs, tagimms):
 declared.append(arg.proto_arg)
 
 arguments = ", ".join(declared)
-f.write(f"DEF_HELPER_{len(declared) - 1}({tag}, {arguments})\n")
+
+## Add the TCG_CALL_NO_RWG_SE flag to helpers that don't take the env
+## argument and aren't HVX instructions.  Since HVX instructions take
+## pointers to their arguments, they will have side effects.
+if hex_common.need_env(tag) or hex_common.is_hvx_insn(tag):
+f.write(f"DEF_HELPER_{len(declared) - 1}({tag}, {arguments})\n")
+else:
+f.write(f"DEF_HELPER_FLAGS_{len(declared) - 1}({tag}, "
+f"TCG_CALL_NO_RWG_SE, {arguments})\n")
 
 
 def main():
diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 1c4391b415..3fc1f4e281 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+ *  Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -1369,3 +1369,6 @@
 gen_helper_raise_exception(tcg_env, excp); \
 } while (0)
 #endif
+
+#define fGEN_TCG_A2_nop(SHORTCODE) do { } while (0)
+#define fGEN_TCG_SA1_setin1(SHORTCODE) tcg_gen_movi_tl(RdV, -1)
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index 03c9ce1d8a..c09b48bb36 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -206,6 +206,18 @@ def need_sp(tag):
 return "A_IMPLICIT_READS_SP" in attribdict[tag]
 
 
+def is_hvx_insn(tag):
+return "A_CVI" in attribdict[tag]
+
+
+def need_env(tag):
+return ("A_STORE" in attribdict[tag] or
+"A_LOAD" in attribdict[tag] or
+"A_CVI_GATHER" in attribdict[tag] or
+"A_CVI_SCATTER" in attribdict[tag] or
+"A_IMPLICIT_WRITES_USR" in attribdict[tag])
+
+
 def need_slot(tag):
 if (
 "A_CVI_SCATTER" not in attribdict[tag]
@@ -1085,11 +1097,12 @@ def helper_args(tag, regs, imms):
 args = []
 
 ## First argument is the CPU state
-args.append(HelperArg(
-"env",
-"tcg_env",
-"CPUHexagonState *env"
-))
+if need_env(tag):
+args.append(HelperArg(
+"env",
+"tcg_env",
+"CPUHexagonState *env"
+))
 
 ## For predicated instructions, we pass in the destination register
 if is_predicated(tag):
-- 
2.25.1



[PULL 11/15] Hexagon (tests/tcg/hexagon) Test HVX .new read from high half of pair

2024-05-05 Thread Brian Cain
From: Taylor Simpson 

Make sure the decoding of HVX .new is correctly handling this case

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20240307032327.4799-6-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 tests/tcg/hexagon/hvx_misc.c | 16 +++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/tests/tcg/hexagon/hvx_misc.c b/tests/tcg/hexagon/hvx_misc.c
index b45170acd1..1fe14b5158 100644
--- a/tests/tcg/hexagon/hvx_misc.c
+++ b/tests/tcg/hexagon/hvx_misc.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright(c) 2021-2023 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+ *  Copyright(c) 2021-2024 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -231,6 +231,7 @@ static void test_masked_store(bool invert)
 static void test_new_value_store(void)
 {
 void *p0 = buffer0;
+void *p1 = buffer1;
 void *pout = output;
 
 asm("{\n\t"
@@ -242,6 +243,19 @@ static void test_new_value_store(void)
 expect[0] = buffer0[0];
 
 check_output_w(__LINE__, 1);
+
+/* Test the .new read from the high half of a pair */
+asm("v7 = vmem(%0 + #0)\n\t"
+"v12 = vmem(%1 + #0)\n\t"
+"{\n\t"
+"v5:4 = vcombine(v12, v7)\n\t"
+"vmem(%2 + #0) = v5.new\n\t"
+"}\n\t"
+: : "r"(p0), "r"(p1), "r"(pout) : "v4", "v5", "v7", "v12", "memory");
+
+expect[0] = buffer1[0];
+
+check_output_w(__LINE__, 1);
 }
 
 static void test_max_temps()
-- 
2.25.1



[PULL 07/15] Hexagon (target/hexagon) Add is_old/is_new to Register class

2024-05-05 Thread Brian Cain
From: Taylor Simpson 

Signed-off-by: Taylor Simpson 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Brian Cain 
Message-Id: <20240307032327.4799-2-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/hex_common.py | 12 
 1 file changed, 12 insertions(+)

diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index c09b48bb36..f6f187968a 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -428,10 +428,18 @@ def is_readwrite(self):
 class OldSource(Source):
 def reg_tcg(self):
 return f"{self.regtype}{self.regid}V"
+def is_old(self):
+return True
+def is_new(self):
+return False
 
 class NewSource(Source):
 def reg_tcg(self):
 return f"{self.regtype}{self.regid}N"
+def is_old(self):
+return False
+def is_new(self):
+return True
 
 class ReadWrite:
 def reg_tcg(self):
@@ -444,6 +452,10 @@ def is_read(self):
 return True
 def is_readwrite(self):
 return True
+def is_old(self):
+return True
+def is_new(self):
+return False
 
 class GprDest(Register, Single, Dest):
 def decl_tcg(self, f, tag, regno):
-- 
2.25.1



[PULL 02/15] Hexagon (target/hexagon) Enable more short-circuit packets (scalar core)

2024-05-05 Thread Brian Cain
From: Taylor Simpson 

Look for read-after-write instead of overlap of reads and writes

Here is an example with overalp but no read-after-write:
0x000200fc:  0x38103876 {   R0 = add(R0,R1); R6 = add(R6,R7) }

BEFORE:
  000200fc
 mov_i32 loc2,$0x0
 mov_i32 loc2,r0
 add_i32 loc3,loc2,r1
 mov_i32 loc2,loc3
 mov_i32 loc4,$0x0
 mov_i32 loc4,r6
 add_i32 loc5,loc4,r7
 mov_i32 loc4,loc5
 mov_i32 r0,loc2
 mov_i32 r6,loc4

AFTER:
  000200fc
 add_i32 loc2,r0,r1
 mov_i32 r0,loc2
 add_i32 loc3,r6,r7
 mov_i32 r6,loc3

We can also short-circuit packets with .new values by reading from the
real destination instead of the temporary.
0x00020100:  0x78005ff3 {   R19 = #0xff
0x00020104:  0x2002e204 if (cmp.eq(N19.new,R2)) jump:t PC+8 }

BEFORE:
  00020100
 mov_i32 pc,$0x20108
 mov_i32 loc8,$0x0
 mov_i32 loc8,$0xff
 setcond_i32 loc10,loc8,r2,eq
 mov_i32 loc6,loc10
 mov_i32 r19,loc8
 add_i32 pkt_cnt,pkt_cnt,$0x2
 add_i32 insn_cnt,insn_cnt,$0x4
 brcond_i32 loc6,$0x0,eq,$L1
 goto_tb $0x0
 mov_i32 pc,$0x20108
 exit_tb $0x7fbb5440
 set_label $L1
 goto_tb $0x1
 exit_tb $0x7fbb5441
 set_label $L0
 exit_tb $0x7fbb5443

AFTER:
  00020100
 mov_i32 pc,$0x20108
 mov_i32 r19,$0xff
 setcond_i32 loc7,r19,r2,eq
 mov_i32 loc4,loc7
 add_i32 pkt_cnt,pkt_cnt,$0x2
 add_i32 insn_cnt,insn_cnt,$0x4
 brcond_i32 loc4,$0x0,eq,$L1
 goto_tb $0x0
 mov_i32 pc,$0x20108
 exit_tb $0x7f976440
 set_label $L1
 goto_tb $0x1
 exit_tb $0x7f976441
 set_label $L0
 exit_tb $0x7f976443

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20240201103340.119081-3-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/translate.c | 21 -
 target/hexagon/translate.h | 13 +++--
 2 files changed, 11 insertions(+), 23 deletions(-)

diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 47a870f42d..8d42ebd91c 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -1,5 +1,5 @@
 /*
- *  Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+ *  Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -396,20 +396,8 @@ static bool need_commit(DisasContext *ctx)
 }
 }
 
-/* Check for overlap between register reads and writes */
-for (int i = 0; i < ctx->reg_log_idx; i++) {
-int rnum = ctx->reg_log[i];
-if (test_bit(rnum, ctx->regs_read)) {
-return true;
-}
-}
-
-/* Check for overlap between predicate reads and writes */
-for (int i = 0; i < ctx->preg_log_idx; i++) {
-int pnum = ctx->preg_log[i];
-if (test_bit(pnum, ctx->pregs_read)) {
-return true;
-}
+if (ctx->read_after_write) {
+return true;
 }
 
 /* Check for overlap between HVX reads and writes */
@@ -468,6 +456,7 @@ static void analyze_packet(DisasContext *ctx)
 {
 Packet *pkt = ctx->pkt;
 ctx->has_hvx_helper = false;
+ctx->read_after_write = false;
 for (int i = 0; i < pkt->num_insns; i++) {
 Insn *insn = >insn[i];
 ctx->insn = insn;
@@ -492,11 +481,9 @@ static void gen_start_packet(DisasContext *ctx)
 ctx->next_PC = next_PC;
 ctx->reg_log_idx = 0;
 bitmap_zero(ctx->regs_written, TOTAL_PER_THREAD_REGS);
-bitmap_zero(ctx->regs_read, TOTAL_PER_THREAD_REGS);
 bitmap_zero(ctx->predicated_regs, TOTAL_PER_THREAD_REGS);
 ctx->preg_log_idx = 0;
 bitmap_zero(ctx->pregs_written, NUM_PREGS);
-bitmap_zero(ctx->pregs_read, NUM_PREGS);
 ctx->future_vregs_idx = 0;
 ctx->tmp_vregs_idx = 0;
 ctx->vreg_log_idx = 0;
diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index f06d71fc53..d5e7f49ad8 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -38,12 +38,10 @@ typedef struct DisasContext {
 int reg_log[REG_WRITES_MAX];
 int reg_log_idx;
 DECLARE_BITMAP(regs_written, TOTAL_PER_THREAD_REGS);
-DECLARE_BITMAP(regs_read, TOTAL_PER_THREAD_REGS);
 DECLARE_BITMAP(predicated_regs, TOTAL_PER_THREAD_REGS);
 int preg_log[PRED_WRITES_MAX];
 int preg_log_idx;
 DECLARE_BITMAP(pregs_written, NUM_PREGS);
-DECLARE_BITMAP(pregs_read, NUM_PREGS);
 uint8_t store_width[STORES_MAX];
 bool s1_store_processed;
 int future_vregs_idx;
@@ -68,6 +66,7 @@ typedef struct DisasContext {
 bool is_tight_loop;
 bool short_circuit;
 bool has_hvx_helper;
+bool read_after_write;
 TCGv new_value[TOTAL_PER_THREAD_REGS];
 TCGv new_pred_value[NUM_PREGS];
 TCGv pred_written;
@@ -88,13 +87,14 @@ static inline void ctx_log_pred_write(DisasContext *ctx, 
int pnum)
 
 static inline void ctx_log_pred_read(DisasContext *ctx, int pnum)
 {
-set_bit(pnum, ctx->pregs_read);
+if 

[PULL 13/15] Hexagon (target/hexagon) Remove gen_op_regs.py

2024-05-05 Thread Brian Cain
From: Taylor Simpson 

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20240307032327.4799-8-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/README |   1 -
 target/hexagon/gen_op_regs.py | 125 --
 target/hexagon/meson.build|  14 +---
 3 files changed, 2 insertions(+), 138 deletions(-)
 delete mode 100755 target/hexagon/gen_op_regs.py

diff --git a/target/hexagon/README b/target/hexagon/README
index c1d8c8d0ab..224a3f9206 100644
--- a/target/hexagon/README
+++ b/target/hexagon/README
@@ -43,7 +43,6 @@ target/hexagon/gen_semantics.c.  This step produces
 That file is consumed by the following python scripts to produce the indicated
 header files in /target/hexagon
 gen_opcodes_def.py  -> opcodes_def_generated.h.inc
-gen_op_regs.py  -> op_regs_generated.h.inc
 gen_printinsn.py-> printinsn_generated.h.inc
 gen_op_attribs.py   -> op_attribs_generated.h.inc
 gen_helper_protos.py-> helper_protos_generated.h.inc
diff --git a/target/hexagon/gen_op_regs.py b/target/hexagon/gen_op_regs.py
deleted file mode 100755
index 7b7b33895a..00
--- a/target/hexagon/gen_op_regs.py
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/usr/bin/env python3
-
-##
-##  Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
-##
-##  This program is free software; you can redistribute it and/or modify
-##  it under the terms of the GNU General Public License as published by
-##  the Free Software Foundation; either version 2 of the License, or
-##  (at your option) any later version.
-##
-##  This program is distributed in the hope that it will be useful,
-##  but WITHOUT ANY WARRANTY; without even the implied warranty of
-##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-##  GNU General Public License for more details.
-##
-##  You should have received a copy of the GNU General Public License
-##  along with this program; if not, see .
-##
-
-import sys
-import re
-import string
-import hex_common
-
-
-##
-## Generate the register and immediate operands for each instruction
-##
-def calculate_regid_reg(tag):
-def letter_inc(x):
-return chr(ord(x) + 1)
-
-ordered_implregs = ["SP", "FP", "LR"]
-srcdst_lett = "X"
-src_lett = "S"
-dst_lett = "D"
-retstr = ""
-mapdict = {}
-for reg in ordered_implregs:
-reg_rd = 0
-reg_wr = 0
-if ("A_IMPLICIT_WRITES_" + reg) in hex_common.attribdict[tag]:
-reg_wr = 1
-if reg_rd and reg_wr:
-retstr += srcdst_lett
-mapdict[srcdst_lett] = reg
-srcdst_lett = letter_inc(srcdst_lett)
-elif reg_rd:
-retstr += src_lett
-mapdict[src_lett] = reg
-src_lett = letter_inc(src_lett)
-elif reg_wr:
-retstr += dst_lett
-mapdict[dst_lett] = reg
-dst_lett = letter_inc(dst_lett)
-return retstr, mapdict
-
-
-def calculate_regid_letters(tag):
-retstr, mapdict = calculate_regid_reg(tag)
-return retstr
-
-
-def strip_reg_prefix(x):
-y = x.replace("UREG.", "")
-y = y.replace("MREG.", "")
-return y.replace("GREG.", "")
-
-
-def main():
-hex_common.read_semantics_file(sys.argv[1])
-hex_common.read_attribs_file(sys.argv[2])
-hex_common.init_registers()
-tagregs = hex_common.get_tagregs(full=True)
-tagimms = hex_common.get_tagimms()
-
-with open(sys.argv[3], "w") as f:
-for tag in hex_common.tags:
-regs = tagregs[tag]
-rregs = []
-wregs = []
-regids = ""
-for regtype, regid, _, numregs in regs:
-reg = hex_common.get_register(tag, regtype, regid)
-if reg.is_read():
-if regid[0] not in regids:
-regids += regid[0]
-rregs.append(regtype + regid + numregs)
-if reg.is_written():
-wregs.append(regtype + regid + numregs)
-if regid[0] not in regids:
-regids += regid[0]
-for attrib in hex_common.attribdict[tag]:
-if hex_common.attribinfo[attrib]["rreg"]:
-rregs.append(strip_reg_prefix(attribinfo[attrib]["rreg"]))
-if hex_common.attribinfo[attrib]["wreg"]:
-wregs.append(strip_reg_prefix(attribinfo[attrib]["wreg"]))
-regids += calculate_regid_letters(tag)
-f.write(
-f'REGINFO({tag},"{regids}",\t/*RD:*/\t"{",".join(rregs)}",'
-f'\t/*WR:*/\t"{",".join(wregs)}")\n'
-)
-
-for tag in hex_common.tags:
-imms = tagimms[tag]
-f.write(f"IMMINFO({tag}")
-if not imms:
-f.write(""",'u',0,0,'U',0,0""")
-  

[PULL 04/15] Hexagon (target/hexagon) Pass P0 explicitly to helpers that need it

2024-05-05 Thread Brian Cain
From: Taylor Simpson 

Rather than reading P0 from the env, pass it explicitly

Signed-off-by: Taylor Simpson 
Reviewed-by: Anton Johansson 
Tested-by: Anton Johansson 
Reviewed-by: Brian Cain 
Message-Id: <20240214042726.19290-2-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/hex_common.py | 10 ++
 target/hexagon/macros.h  |  4 ++--
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index 9e7f613e3c..63d18f73ad 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -197,6 +197,10 @@ def get_tagimms():
 return dict(zip(tags, list(map(compute_tag_immediates, tags
 
 
+def need_p0(tag):
+return "A_IMPLICIT_READS_P0" in attribdict[tag]
+
+
 def need_slot(tag):
 if (
 "A_CVI_SCATTER" not in attribdict[tag]
@@ -1134,6 +1138,12 @@ def helper_args(tag, regs, imms):
 "tcg_constant_tl(ctx->next_PC)",
 "target_ulong next_PC"
 ))
+if need_p0(tag):
+args.append(HelperArg(
+"i32",
+"hex_pred[0]",
+"uint32_t P0"
+))
 if need_slot(tag):
 args.append(HelperArg(
 "i32",
diff --git a/target/hexagon/macros.h b/target/hexagon/macros.h
index 1376d6ccc1..aedc863fab 100644
--- a/target/hexagon/macros.h
+++ b/target/hexagon/macros.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+ *  Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -358,7 +358,7 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int 
shift)
 #endif
 #define fREAD_PC() (PC)
 
-#define fREAD_P0() (env->pred[0])
+#define fREAD_P0() (P0)
 
 #define fCHECK_PCALIGN(A)
 
-- 
2.25.1



[PULL 12/15] Hexagon (target/hexagon) Remove uses of op_regs_generated.h.inc

2024-05-05 Thread Brian Cain
From: Taylor Simpson 

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20240307032327.4799-7-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/decode.c | 55 +++--
 target/hexagon/mmvec/decode_ext_mmvec.c | 34 ---
 target/hexagon/opcodes.c| 28 -
 target/hexagon/opcodes.h|  4 --
 4 files changed, 12 insertions(+), 109 deletions(-)

diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c
index 84a3899556..23deba2426 100644
--- a/target/hexagon/decode.c
+++ b/target/hexagon/decode.c
@@ -115,24 +115,13 @@ static void
 decode_fill_newvalue_regno(Packet *packet)
 {
 int i, use_regidx, offset, def_idx, dst_idx;
-uint16_t def_opcode, use_opcode;
-char *dststr;
 
 for (i = 1; i < packet->num_insns; i++) {
 if (GET_ATTRIB(packet->insn[i].opcode, A_DOTNEWVALUE) &&
 !GET_ATTRIB(packet->insn[i].opcode, A_EXTENSION)) {
-use_opcode = packet->insn[i].opcode;
 
-/* It's a store, so we're adjusting the Nt field */
-if (GET_ATTRIB(use_opcode, A_STORE)) {
-use_regidx = strchr(opcode_reginfo[use_opcode], 't') -
-opcode_reginfo[use_opcode];
-} else {/* It's a Jump, so we're adjusting the Ns field */
-use_regidx = strchr(opcode_reginfo[use_opcode], 's') -
-opcode_reginfo[use_opcode];
-}
-g_assert(packet->insn[i].new_read_idx != -1 &&
- packet->insn[i].new_read_idx == use_regidx);
+g_assert(packet->insn[i].new_read_idx != -1);
+use_regidx = packet->insn[i].new_read_idx;
 
 /*
  * What's encoded at the N-field is the offset to who's producing
@@ -153,39 +142,9 @@ decode_fill_newvalue_regno(Packet *packet)
  */
 g_assert(!((def_idx < 0) || (def_idx > (packet->num_insns - 1;
 
-/*
- * packet->insn[def_idx] is the producer
- * Figure out which type of destination it produces
- * and the corresponding index in the reginfo
- */
-def_opcode = packet->insn[def_idx].opcode;
-dststr = strstr(opcode_wregs[def_opcode], "Rd");
-if (dststr) {
-dststr = strchr(opcode_reginfo[def_opcode], 'd');
-} else {
-dststr = strstr(opcode_wregs[def_opcode], "Rx");
-if (dststr) {
-dststr = strchr(opcode_reginfo[def_opcode], 'x');
-} else {
-dststr = strstr(opcode_wregs[def_opcode], "Re");
-if (dststr) {
-dststr = strchr(opcode_reginfo[def_opcode], 'e');
-} else {
-dststr = strstr(opcode_wregs[def_opcode], "Ry");
-if (dststr) {
-dststr = strchr(opcode_reginfo[def_opcode], 'y');
-} else {
-g_assert_not_reached();
-}
-}
-}
-}
-g_assert(dststr != NULL);
-
 /* Now patch up the consumer with the register number */
-dst_idx = dststr - opcode_reginfo[def_opcode];
-g_assert(packet->insn[def_idx].dest_idx != -1 &&
- packet->insn[def_idx].dest_idx == dst_idx);
+g_assert(packet->insn[def_idx].dest_idx != -1);
+dst_idx = packet->insn[def_idx].dest_idx;
 packet->insn[i].regno[use_regidx] =
 packet->insn[def_idx].regno[dst_idx];
 /*
@@ -366,11 +325,7 @@ static void decode_shuffle_for_execution(Packet *packet)
 for (flag = false, i = 0; i < last_insn + 1; i++) {
 int opcode = packet->insn[i].opcode;
 
-g_assert(packet->insn[i].has_pred_dest ==
- (strstr(opcode_wregs[opcode], "Pd4") ||
-  strstr(opcode_wregs[opcode], "Pe4")));
-if ((strstr(opcode_wregs[opcode], "Pd4") ||
- strstr(opcode_wregs[opcode], "Pe4")) &&
+if (packet->insn[i].has_pred_dest &&
 GET_ATTRIB(opcode, A_STORE) == 0) {
 /* This should be a compare (not a store conditional) */
 if (flag) {
diff --git a/target/hexagon/mmvec/decode_ext_mmvec.c 
b/target/hexagon/mmvec/decode_ext_mmvec.c
index c1320406df..f850d0154d 100644
--- a/target/hexagon/mmvec/decode_ext_mmvec.c
+++ b/target/hexagon/mmvec/decode_ext_mmvec.c
@@ -28,21 +28,15 @@ check_new_value(Packet *pkt)
 {
 /* .new value for a MMVector store */
 int i, j;
-const char *reginfo;
-const char *destletters;
-const char *dststr = NULL;
 uint16_t def_opcode;
-char letter;
 
 for (i = 1; i < pkt->num_insns; i++) {
 uint16_t use_opcode = 

[PULL 08/15] Hexagon (target/hexagon) Mark new_read_idx in trans functions

2024-05-05 Thread Brian Cain
From: Taylor Simpson 

Check that the value matches opcode_reginfo

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20240307032327.4799-3-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/decode.c |  2 ++
 target/hexagon/gen_trans_funcs.py   | 15 ++-
 target/hexagon/insn.h   |  3 ++-
 target/hexagon/mmvec/decode_ext_mmvec.c |  2 ++
 4 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c
index a40210ca1e..4595e30384 100644
--- a/target/hexagon/decode.c
+++ b/target/hexagon/decode.c
@@ -131,6 +131,8 @@ decode_fill_newvalue_regno(Packet *packet)
 use_regidx = strchr(opcode_reginfo[use_opcode], 's') -
 opcode_reginfo[use_opcode];
 }
+g_assert(packet->insn[i].new_read_idx != -1 &&
+ packet->insn[i].new_read_idx == use_regidx);
 
 /*
  * What's encoded at the N-field is the offset to who's producing
diff --git a/target/hexagon/gen_trans_funcs.py 
b/target/hexagon/gen_trans_funcs.py
index 53e844a44b..8acecdb993 100755
--- a/target/hexagon/gen_trans_funcs.py
+++ b/target/hexagon/gen_trans_funcs.py
@@ -68,6 +68,7 @@ def mark_which_imm_extended(f, tag):
 ## insn->regno[0] = args->Rd;
 ## insn->regno[1] = args->Rs;
 ## insn->regno[2] = args->Rt;
+## insn->new_read_idx = -1;
 ## return true;
 ## }
 ##
@@ -84,14 +85,14 @@ def gen_trans_funcs(f):
 insn->opcode = {tag};
 """))
 
-regno = 0
-for reg in regs:
-reg_type = reg[0]
-reg_id = reg[1]
+new_read_idx = -1
+for regno, (reg_type, reg_id, *_) in enumerate(regs):
+reg = hex_common.get_register(tag, reg_type, reg_id)
 f.write(code_fmt(f"""\
 insn->regno[{regno}] = args->{reg_type}{reg_id};
 """))
-regno += 1
+if reg.is_read() and reg.is_new():
+new_read_idx = regno
 
 if len(imms) != 0:
 mark_which_imm_extended(f, tag)
@@ -112,6 +113,9 @@ def gen_trans_funcs(f):
 insn->immed[{immno}] = args->{imm_type}{imm_letter};
 """))
 
+f.write(code_fmt(f"""\
+insn->new_read_idx = {new_read_idx};
+"""))
 f.write(textwrap.dedent(f"""\
 return true;
 {close_curly}
@@ -120,5 +124,6 @@ def gen_trans_funcs(f):
 
 if __name__ == "__main__":
 hex_common.read_semantics_file(sys.argv[1])
+hex_common.init_registers()
 with open(sys.argv[2], "w") as f:
 gen_trans_funcs(f)
diff --git a/target/hexagon/insn.h b/target/hexagon/insn.h
index 3e7a22c91e..36502bf056 100644
--- a/target/hexagon/insn.h
+++ b/target/hexagon/insn.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+ *  Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -39,6 +39,7 @@ struct Instruction {
 uint32_t slot:3;
 uint32_t which_extended:1;/* If has an extender, which immediate */
 uint32_t new_value_producer_slot:4;
+int32_t new_read_idx;
 
 bool part1;  /*
   * cmp-jumps are split into two insns.
diff --git a/target/hexagon/mmvec/decode_ext_mmvec.c 
b/target/hexagon/mmvec/decode_ext_mmvec.c
index 202d84c7c0..e9007f5d71 100644
--- a/target/hexagon/mmvec/decode_ext_mmvec.c
+++ b/target/hexagon/mmvec/decode_ext_mmvec.c
@@ -41,6 +41,8 @@ check_new_value(Packet *pkt)
 GET_ATTRIB(use_opcode, A_STORE)) {
 int use_regidx = strchr(opcode_reginfo[use_opcode], 's') -
 opcode_reginfo[use_opcode];
+g_assert(pkt->insn[i].new_read_idx != -1 &&
+ pkt->insn[i].new_read_idx == use_regidx);
 /*
  * What's encoded at the N-field is the offset to who's producing
  * the value.
-- 
2.25.1



[PULL 00/15] Hexagon: simplify gen for packets w/o read-after-write

2024-05-05 Thread Brian Cain
The following changes since commit 248f6f62df073a3b4158fd0093863ab885feabb5:

  Merge tag 'pull-axp-20240504' of https://gitlab.com/rth7680/qemu into staging 
(2024-05-04 08:39:46 -0700)

are available in the Git repository at:

  https://github.com/quic/qemu tags/pull-hex-20240505

for you to fetch changes up to a4696661491cac8c1c08e7d482d751f808ce3143:

  Hexagon (target/hexagon) Remove hex_common.read_attribs_file (2024-05-05 
16:22:07 -0700)


Short-circuit for packets w/o read-after-write
Cleanup unused code in gen_*.py scripts


Taylor Simpson (15):
  Hexagon (target/hexagon) Analyze reads before writes
  Hexagon (target/hexagon) Enable more short-circuit packets (scalar core)
  Hexagon (target/hexagon) Enable more short-circuit packets (HVX)
  Hexagon (target/hexagon) Pass P0 explicitly to helpers that need it
  Hexagon (target/hexagon) Pass SP explicitly to helpers that need it
  Hexagon (target/hexagon) Only pass env to generated helper when needed
  Hexagon (target/hexagon) Add is_old/is_new to Register class
  Hexagon (target/hexagon) Mark new_read_idx in trans functions
  Hexagon (target/hexagon) Mark dest_idx in trans functions
  Hexagon (target/hexagon) Mark has_pred_dest in trans functions
  Hexagon (tests/tcg/hexagon) Test HVX .new read from high half of pair
  Hexagon (target/hexagon) Remove uses of op_regs_generated.h.inc
  Hexagon (target/hexagon) Remove gen_op_regs.py
  Hexagon (target/hexagon) Remove gen_shortcode.py
  Hexagon (target/hexagon) Remove hex_common.read_attribs_file

 target/hexagon/README   |  11 +-
 target/hexagon/attribs_def.h.inc|   3 +-
 target/hexagon/decode.c |  48 +---
 target/hexagon/gen_analyze_funcs.py |  70 ++--
 target/hexagon/gen_helper_funcs.py  |  21 +---
 target/hexagon/gen_helper_protos.py |  31 ++
 target/hexagon/gen_idef_parser_funcs.py |   5 +-
 target/hexagon/gen_op_attribs.py|   5 +-
 target/hexagon/gen_op_regs.py   | 125 -
 target/hexagon/gen_opcodes_def.py   |   4 +-
 target/hexagon/gen_printinsn.py |   5 +-
 target/hexagon/gen_shortcode.py |  63 ---
 target/hexagon/gen_tcg.h|   5 +-
 target/hexagon/gen_tcg_func_table.py|   5 +-
 target/hexagon/gen_tcg_funcs.py |  21 +---
 target/hexagon/gen_trans_funcs.py   |  26 -
 target/hexagon/hex_common.py| 189 ++--
 target/hexagon/insn.h   |   5 +-
 target/hexagon/macros.h |   6 +-
 target/hexagon/meson.build  |  55 +++---
 target/hexagon/mmvec/decode_ext_mmvec.c |  30 ++---
 target/hexagon/opcodes.c|  35 --
 target/hexagon/opcodes.h|   4 -
 target/hexagon/translate.c  |  77 ++---
 target/hexagon/translate.h  | 119 
 tests/tcg/hexagon/hvx_misc.c|  16 ++-
 26 files changed, 374 insertions(+), 610 deletions(-)
 delete mode 100755 target/hexagon/gen_op_regs.py
 delete mode 100755 target/hexagon/gen_shortcode.py


[PULL 09/15] Hexagon (target/hexagon) Mark dest_idx in trans functions

2024-05-05 Thread Brian Cain
From: Taylor Simpson 

Check that the value matches opcode_reginfo/opcode_wregs

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20240307032327.4799-4-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/decode.c | 2 ++
 target/hexagon/gen_trans_funcs.py   | 6 ++
 target/hexagon/insn.h   | 1 +
 target/hexagon/mmvec/decode_ext_mmvec.c | 2 ++
 4 files changed, 11 insertions(+)

diff --git a/target/hexagon/decode.c b/target/hexagon/decode.c
index 4595e30384..a4d8500fea 100644
--- a/target/hexagon/decode.c
+++ b/target/hexagon/decode.c
@@ -184,6 +184,8 @@ decode_fill_newvalue_regno(Packet *packet)
 
 /* Now patch up the consumer with the register number */
 dst_idx = dststr - opcode_reginfo[def_opcode];
+g_assert(packet->insn[def_idx].dest_idx != -1 &&
+ packet->insn[def_idx].dest_idx == dst_idx);
 packet->insn[i].regno[use_regidx] =
 packet->insn[def_idx].regno[dst_idx];
 /*
diff --git a/target/hexagon/gen_trans_funcs.py 
b/target/hexagon/gen_trans_funcs.py
index 8acecdb993..1201172dda 100755
--- a/target/hexagon/gen_trans_funcs.py
+++ b/target/hexagon/gen_trans_funcs.py
@@ -69,6 +69,7 @@ def mark_which_imm_extended(f, tag):
 ## insn->regno[1] = args->Rs;
 ## insn->regno[2] = args->Rt;
 ## insn->new_read_idx = -1;
+## insn->dest_idx = 0;
 ## return true;
 ## }
 ##
@@ -86,6 +87,7 @@ def gen_trans_funcs(f):
 """))
 
 new_read_idx = -1
+dest_idx = -1
 for regno, (reg_type, reg_id, *_) in enumerate(regs):
 reg = hex_common.get_register(tag, reg_type, reg_id)
 f.write(code_fmt(f"""\
@@ -93,6 +95,9 @@ def gen_trans_funcs(f):
 """))
 if reg.is_read() and reg.is_new():
 new_read_idx = regno
+# dest_idx should be the first destination, so check for -1
+if reg.is_written() and dest_idx == -1:
+dest_idx = regno
 
 if len(imms) != 0:
 mark_which_imm_extended(f, tag)
@@ -115,6 +120,7 @@ def gen_trans_funcs(f):
 
 f.write(code_fmt(f"""\
 insn->new_read_idx = {new_read_idx};
+insn->dest_idx = {dest_idx};
 """))
 f.write(textwrap.dedent(f"""\
 return true;
diff --git a/target/hexagon/insn.h b/target/hexagon/insn.h
index 36502bf056..a770379958 100644
--- a/target/hexagon/insn.h
+++ b/target/hexagon/insn.h
@@ -40,6 +40,7 @@ struct Instruction {
 uint32_t which_extended:1;/* If has an extender, which immediate */
 uint32_t new_value_producer_slot:4;
 int32_t new_read_idx;
+int32_t dest_idx;
 
 bool part1;  /*
   * cmp-jumps are split into two insns.
diff --git a/target/hexagon/mmvec/decode_ext_mmvec.c 
b/target/hexagon/mmvec/decode_ext_mmvec.c
index e9007f5d71..c1320406df 100644
--- a/target/hexagon/mmvec/decode_ext_mmvec.c
+++ b/target/hexagon/mmvec/decode_ext_mmvec.c
@@ -86,6 +86,8 @@ check_new_value(Packet *pkt)
 /* still not there, we have a bad packet */
 g_assert_not_reached();
 }
+g_assert(pkt->insn[def_idx].dest_idx != -1 &&
+ pkt->insn[def_idx].dest_idx == dststr - reginfo);
 int def_regnum = pkt->insn[def_idx].regno[dststr - reginfo];
 /* Now patch up the consumer with the register number */
 pkt->insn[i].regno[use_regidx] = def_regnum ^ def_oreg;
-- 
2.25.1



[PULL 03/15] Hexagon (target/hexagon) Enable more short-circuit packets (HVX)

2024-05-05 Thread Brian Cain
From: Taylor Simpson 

Look for read-after-write instead of overlap of reads and writes

HVX instructions with helpers have pass-by-reference semantics, so
we check for overlaps of reads and writes within the same instruction.

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20240201103340.119081-4-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/gen_analyze_funcs.py | 19 ---
 target/hexagon/hex_common.py| 45 ++-
 target/hexagon/translate.c  | 58 ++-
 target/hexagon/translate.h  | 88 +++--
 4 files changed, 115 insertions(+), 95 deletions(-)

diff --git a/target/hexagon/gen_analyze_funcs.py 
b/target/hexagon/gen_analyze_funcs.py
index 890e6a3a95..81e1d9cfa3 100755
--- a/target/hexagon/gen_analyze_funcs.py
+++ b/target/hexagon/gen_analyze_funcs.py
@@ -43,6 +43,16 @@ def gen_analyze_func(f, tag, regs, imms):
 f.write("{\n")
 
 f.write("Insn *insn G_GNUC_UNUSED = ctx->insn;\n")
+if (hex_common.is_hvx_insn(tag)):
+if hex_common.has_hvx_helper(tag):
+f.write(
+"const bool G_GNUC_UNUSED insn_has_hvx_helper = true;\n"
+)
+f.write("ctx_start_hvx_insn(ctx);\n")
+else:
+f.write(
+"const bool G_GNUC_UNUSED insn_has_hvx_helper = false;\n"
+)
 
 ## Declare all the registers
 for regno, register in enumerate(regs):
@@ -64,15 +74,6 @@ def gen_analyze_func(f, tag, regs, imms):
 if reg.is_written():
 reg.analyze_write(f, tag, regno)
 
-has_generated_helper = not hex_common.skip_qemu_helper(
-tag
-) and not hex_common.is_idef_parser_enabled(tag)
-
-## Mark HVX instructions with generated helpers
-if (has_generated_helper and
-"A_CVI" in hex_common.attribdict[tag]):
-f.write("ctx->has_hvx_helper = true;\n")
-
 f.write("}\n\n")
 
 
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index 33801e4bd7..9e7f613e3c 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -241,6 +241,16 @@ def is_idef_parser_enabled(tag):
 return tag in idef_parser_enabled
 
 
+def is_hvx_insn(tag):
+return "A_CVI" in attribdict[tag]
+
+
+def has_hvx_helper(tag):
+return (is_hvx_insn(tag) and
+not skip_qemu_helper(tag) and
+not is_idef_parser_enabled(tag))
+
+
 def imm_name(immlett):
 return f"{immlett}iV"
 
@@ -704,7 +714,8 @@ def analyze_write(self, f, tag, regno):
 newv = hvx_newv(tag)
 predicated = "true" if is_predicated(tag) else "false"
 f.write(code_fmt(f"""\
-ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated});
+ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated},
+   insn_has_hvx_helper);
 """))
 
 class VRegSource(Register, Hvx, OldSource):
@@ -724,7 +735,7 @@ def helper_hvx_desc(self, f):
 """))
 def analyze_read(self, f, regno):
 f.write(code_fmt(f"""\
-ctx_log_vreg_read(ctx, {self.reg_num});
+ctx_log_vreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
 """))
 
 class VRegNewSource(Register, Hvx, NewSource):
@@ -741,7 +752,7 @@ def helper_hvx_desc(self, f):
 """))
 def analyze_read(self, f, regno):
 f.write(code_fmt(f"""\
-ctx_log_vreg_read_new(ctx, {self.reg_num});
+ctx_log_vreg_read_new(ctx, {self.reg_num}, insn_has_hvx_helper);
 """))
 
 class VRegReadWrite(Register, Hvx, ReadWrite):
@@ -767,13 +778,14 @@ def helper_hvx_desc(self, f):
 """))
 def analyze_read(self, f, regno):
 f.write(code_fmt(f"""\
-ctx_log_vreg_read(ctx, {self.reg_num});
+ctx_log_vreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
 """))
 def analyze_write(self, f, tag, regno):
 newv = hvx_newv(tag)
 predicated = "true" if is_predicated(tag) else "false"
 f.write(code_fmt(f"""\
-ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated});
+ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated},
+   insn_has_hvx_helper);
 """))
 
 class VRegTmp(Register, Hvx, ReadWrite):
@@ -801,13 +813,14 @@ def helper_hvx_desc(self, f):
 """))
 def analyze_read(self, f, regno):
 f.write(code_fmt(f"""\
-ctx_log_vreg_read(ctx, {self.reg_num});
+ctx_log_vreg_read(ctx, {self.reg_num}, insn_has_hvx_helper);
 """))
 def analyze_write(self, f, tag, regno):
 newv = hvx_newv(tag)
 predicated = "true" if is_predicated(tag) else "false"
 f.write(code_fmt(f"""\
-ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated});
+ctx_log_vreg_write(ctx, {self.reg_num}, {newv}, {predicated},
+   

[PULL 01/15] Hexagon (target/hexagon) Analyze reads before writes

2024-05-05 Thread Brian Cain
From: Taylor Simpson 

We divide gen_analyze_funcs.py into 3 phases
Declare the operands
Analyze the register reads
Analyze the register writes

We also create special versions of ctx_log_*_read for new operands
Check that the operand is written before the read

This is a precursor to improving the analysis for short-circuiting
the packet semantics in a subsequent commit

Signed-off-by: Taylor Simpson 
Reviewed-by: Brian Cain 
Message-Id: <20240201103340.119081-2-ltaylorsimp...@gmail.com>
Signed-off-by: Brian Cain 
---
 target/hexagon/README   |  9 +++--
 target/hexagon/gen_analyze_funcs.py | 34 ++--
 target/hexagon/hex_common.py| 63 +++--
 target/hexagon/translate.h  | 26 +++-
 4 files changed, 83 insertions(+), 49 deletions(-)

diff --git a/target/hexagon/README b/target/hexagon/README
index 746ebec378..c1d8c8d0ab 100644
--- a/target/hexagon/README
+++ b/target/hexagon/README
@@ -183,10 +183,11 @@ when the override is present.
 }
 
 We also generate an analyze_ function for each instruction.  Currently,
-these functions record the writes to registers by calling ctx_log_*.  During
-gen_start_packet, we invoke the analyze_ function for each instruction in
-the packet, and we mark the implicit writes.  After the analysis is performed,
-we initialize the result register for each of the predicated assignments.
+these functions record the reads and writes to registers by calling ctx_log_*.
+During gen_start_packet, we invoke the analyze_ function for each 
instruction in
+the packet, and we mark the implicit writes.  The analysis determines if the 
packet
+semantics can be short-circuited.  If not, we initialize the result register 
for each
+of the predicated assignments.
 
 In addition to instruction semantics, we use a generator to create the decode
 tree.  This generation is a four step process.
diff --git a/target/hexagon/gen_analyze_funcs.py 
b/target/hexagon/gen_analyze_funcs.py
index a9af666cef..890e6a3a95 100755
--- a/target/hexagon/gen_analyze_funcs.py
+++ b/target/hexagon/gen_analyze_funcs.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 
 ##
-##  Copyright(c) 2022-2023 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+##  Copyright(c) 2022-2024 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
 ##
 ##  This program is free software; you can redistribute it and/or modify
 ##  it under the terms of the GNU General Public License as published by
@@ -44,15 +44,25 @@ def gen_analyze_func(f, tag, regs, imms):
 
 f.write("Insn *insn G_GNUC_UNUSED = ctx->insn;\n")
 
-i = 0
-## Analyze all the registers
-for regtype, regid in regs:
-reg = hex_common.get_register(tag, regtype, regid)
+## Declare all the registers
+for regno, register in enumerate(regs):
+reg_type, reg_id = register
+reg = hex_common.get_register(tag, reg_type, reg_id)
+reg.decl_reg_num(f, regno)
+
+## Analyze the register reads
+for regno, register in enumerate(regs):
+reg_type, reg_id = register
+reg = hex_common.get_register(tag, reg_type, reg_id)
+if reg.is_read():
+reg.analyze_read(f, regno)
+
+## Analyze the register writes
+for regno, register in enumerate(regs):
+reg_type, reg_id = register
+reg = hex_common.get_register(tag, reg_type, reg_id)
 if reg.is_written():
-reg.analyze_write(f, tag, i)
-else:
-reg.analyze_read(f, i)
-i += 1
+reg.analyze_write(f, tag, regno)
 
 has_generated_helper = not hex_common.skip_qemu_helper(
 tag
@@ -89,13 +99,13 @@ def main():
 tagimms = hex_common.get_tagimms()
 
 with open(sys.argv[-1], "w") as f:
-f.write("#ifndef HEXAGON_TCG_FUNCS_H\n")
-f.write("#define HEXAGON_TCG_FUNCS_H\n\n")
+f.write("#ifndef HEXAGON_ANALYZE_FUNCS_C_INC\n")
+f.write("#define HEXAGON_ANALYZE_FUNCS_C_INC\n\n")
 
 for tag in hex_common.tags:
 gen_analyze_func(f, tag, tagregs[tag], tagimms[tag])
 
-f.write("#endif/* HEXAGON_TCG_FUNCS_H */\n")
+f.write("#endif/* HEXAGON_ANALYZE_FUNCS_C_INC */\n")
 
 
 if __name__ == "__main__":
diff --git a/target/hexagon/hex_common.py b/target/hexagon/hex_common.py
index 195620c7ec..33801e4bd7 100755
--- a/target/hexagon/hex_common.py
+++ b/target/hexagon/hex_common.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 
 ##
-##  Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
+##  Copyright(c) 2019-2024 Qualcomm Innovation Center, Inc. All Rights 
Reserved.
 ##
 ##  This program is free software; you can redistribute it and/or modify
 ##  it under the terms of the GNU General Public License as published by
@@ -425,7 +425,6 @@ def log_write(self, f, tag):
 gen_log_reg_write(ctx, {self.reg_num}, {self.reg_tcg()});
 """))
 def analyze_write(self, f, tag, regno):
-

Re: [PATCH 1/6] target/i386/kvm: Add feature bit definitions for KVM CPUID

2024-05-05 Thread Zhao Liu
Hi Zide,

On Fri, Apr 26, 2024 at 10:23:27AM -0700, Chen, Zide wrote:
> Date: Fri, 26 Apr 2024 10:23:27 -0700
> From: "Chen, Zide" 
> Subject: Re: [PATCH 1/6] target/i386/kvm: Add feature bit definitions for
>  KVM CPUID
> 
> On 4/26/2024 3:07 AM, Zhao Liu wrote:
> > Add feature definiations for KVM_CPUID_FEATURES in CPUID (
> > CPUID[4000_0001].EAX and CPUID[4000_0001].EDX), to get rid of lots of
> > offset calculations.
> > 
> > Signed-off-by: Zhao Liu 
> > ---
> > v2: Changed the prefix from CPUID_FEAT_KVM_* to CPUID_KVM_*. (Xiaoyao)
> > ---
> >  hw/i386/kvm/clock.c   |  5 ++---
> >  target/i386/cpu.h | 23 +++
> >  target/i386/kvm/kvm.c | 28 ++--
> >  3 files changed, 39 insertions(+), 17 deletions(-)
> > 
> > diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
> > index 40aa9a32c32c..ce416c05a3d0 100644
> > --- a/hw/i386/kvm/clock.c
> > +++ b/hw/i386/kvm/clock.c
> > @@ -27,7 +27,6 @@
> >  #include "qapi/error.h"
> >  
> >  #include 
> > -#include "standard-headers/asm-x86/kvm_para.h"
> >  #include "qom/object.h"
> >  
> >  #define TYPE_KVM_CLOCK "kvmclock"
> > @@ -334,8 +333,8 @@ void kvmclock_create(bool create_always)
> >  
> >  assert(kvm_enabled());
> >  if (create_always ||
> > -cpu->env.features[FEAT_KVM] & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
> > -   (1ULL << 
> > KVM_FEATURE_CLOCKSOURCE2))) {
> > +cpu->env.features[FEAT_KVM] & (CPUID_KVM_CLOCK |
> > +   CPUID_KVM_CLOCK2)) {
> 
> To achieve this purpose, how about doing the alternative to define an
> API similar to KVM's guest_pv_has()?
>
> _has() is simpler and clearer than "features[] & CPUID_x",
> additionally, this helps to keep the definitions identical to KVM, more
> readable and easier for future maintenance.

Yes, it's a clearer way! I can explore the _has() pattern in another
series and try to expand it to more CPUID leaves.

Thanks,
Zhao





[PATCH v5] target/riscv: Implement dynamic establishment of custom decoder

2024-05-05 Thread Huang Tao
In this patch, we modify the decoder to be a freely composable data
structure instead of a hardcoded one. It can be dynamically builded up
according to the extensions.
This approach has several benefits:
1. Provides support for heterogeneous cpu architectures. As we add decoder in
   RISCVCPU, each cpu can have their own decoder, and the decoders can be
   different due to cpu's features.
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
   can be added to the dynamic_decoder when building up the decoder. Therefore,
   there is no need to run the guard_func when decoding each instruction. It can
   improve the decoding efficiency
3. For vendor or dynamic cpus, it allows them to customize their own decoder
   functions to improve decoding efficiency, especially when vendor-defined
   instruction sets increase. Because of dynamic building up, it can skip the 
other
   decoder guard functions when decoding.
4. Pre patch for allowing adding a vendor decoder before decode_insn32() with 
minimal
   overhead for users that don't need this particular vendor decoder.

Signed-off-by: Huang Tao 
Suggested-by: Christoph Muellner 
Co-authored-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
Changes in v5:
- rebase on https://github.com/alistair23/qemu/tree/riscv-to-apply.next

Changes in v4:
- fix typo
- rename function
- add 'if tcg_enable()'
- move function to tcg-cpu.c and declarations to tcg-cpu.h

Changes in v3:
- use GPtrArray to save decode function poionter list.
---
 target/riscv/cpu.c |  1 +
 target/riscv/cpu.h |  1 +
 target/riscv/tcg/tcg-cpu.c | 15 +++
 target/riscv/tcg/tcg-cpu.h | 15 +++
 target/riscv/translate.c   | 31 +++
 5 files changed, 47 insertions(+), 16 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a74f0eb29c..2cb145121d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1134,6 +1134,7 @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
 error_propagate(errp, local_err);
 return;
 }
+riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
 } else if (kvm_enabled()) {
 riscv_kvm_cpu_finalize_features(cpu, _err);
 if (local_err != NULL) {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index e0dd1828b5..2838d9640b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -455,6 +455,7 @@ struct ArchCPU {
 uint32_t pmu_avail_ctrs;
 /* Mapping of events to counters */
 GHashTable *pmu_event_ctr_map;
+const GPtrArray *decoders;
 };
 
 /**
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 4ebebebe09..3a4ec3662a 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -863,6 +863,21 @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
 }
 }
 
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
+{
+GPtrArray *dynamic_decoders;
+dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
+for (size_t i = 0; i < decoder_table_size; ++i) {
+if (decoder_table[i].guard_func &&
+decoder_table[i].guard_func(>cfg)) {
+g_ptr_array_add(dynamic_decoders,
+(gpointer)decoder_table[i].riscv_cpu_decode_fn);
+}
+}
+
+cpu->decoders = dynamic_decoders;
+}
+
 bool riscv_cpu_tcg_compatible(RISCVCPU *cpu)
 {
 return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL;
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
index f7b32417f8..ce94253fe4 100644
--- a/target/riscv/tcg/tcg-cpu.h
+++ b/target/riscv/tcg/tcg-cpu.h
@@ -26,4 +26,19 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error 
**errp);
 void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
 bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);
 
+struct DisasContext;
+struct RISCVCPUConfig;
+typedef struct RISCVDecoder {
+bool (*guard_func)(const struct RISCVCPUConfig *);
+bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
+} RISCVDecoder;
+
+typedef bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
+
+extern const size_t decoder_table_size;
+
+extern const RISCVDecoder decoder_table[];
+
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu);
+
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 9ff09ebdb6..15e7123a68 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -37,6 +37,8 @@
 #include "exec/helper-info.c.inc"
 #undef  HELPER_H
 
+#include "tcg/tcg-cpu.h"
+
 /* global register indices */
 static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
 static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
@@ -116,6 +118,7 @@ typedef struct DisasContext {
 /* FRM is known to contain a valid value. */
 bool frm_valid;
 bool insn_start_updated;
+const GPtrArray *decoders;
 } DisasContext;
 
 

RE: [PATCH v3 00/19] Add a host IOMMU device abstraction to check with vIOMMU

2024-05-05 Thread Duan, Zhenzhong
Hi Cédric,

>-Original Message-
>From: Cédric Le Goater 
>Sent: Friday, May 3, 2024 10:04 PM
>To: Duan, Zhenzhong ; qemu-
>de...@nongnu.org
>Cc: alex.william...@redhat.com; eric.au...@redhat.com; m...@redhat.com;
>pet...@redhat.com; jasow...@redhat.com; j...@nvidia.com;
>nicol...@nvidia.com; joao.m.mart...@oracle.com; Tian, Kevin
>; Liu, Yi L ; Peng, Chao P
>
>Subject: Re: [PATCH v3 00/19] Add a host IOMMU device abstraction to
>check with vIOMMU
>
>On 4/29/24 08:50, Zhenzhong Duan wrote:
>> Hi,
>>
>> The most important change in this version is instroducing a common
>> HostIOMMUDeviceCaps structure in HostIOMMUDevice and a new
>interface
>> between vIOMMU and HostIOMMUDevice.
>>
>> HostIOMMUDeviceClass::realize() is introduced to initialize
>> HostIOMMUDeviceCaps and other fields of HostIOMMUDevice variants.
>>
>> HostIOMMUDeviceClass::check_cap() is introduced to query host IOMMU
>> device capabilities.
>>
>> After the change, part2 is only 3 patches, so merge it with part1 to be
>> a single prerequisite series, same for changelog. If anyone doesn't like
>> that, I can split again.
>>
>> The class tree is as below:
>>
>>HostIOMMUDevice
>>   | .caps
>>   | .realize()
>>   | .check_cap()
>>   |
>>  .---.
>>  ||  |
>> HostIOMMUDeviceLegacyVFIO  {HostIOMMUDeviceLegacyVDPA}
>HostIOMMUDeviceIOMMUFD
>>  | .vdev  | {.vdev}  | .iommufd
>>  | .devid
>>  | [.ioas_id]
>>  | 
>> [.attach_hwpt()]
>>  | 
>> [.detach_hwpt()]
>>  |
>>.--.
>>|  |
>> HostIOMMUDeviceIOMMUFDVFIO
>{HostIOMMUDeviceIOMMUFDVDPA}
>>| .vdev| {.vdev}
>>
>> * The attributes in [] will be implemented in nesting series.
>> * The classes in {} will be implemented in future.
>> * .vdev in different class points to different agent device,
>> * i.e., for VFIO it points to VFIODevice.
>>
>> PATCH1-4: Introduce HostIOMMUDevice and its sub classes
>> PATCH5-11: Introduce HostIOMMUDeviceCaps, implement .realize()
>and .check_cap() handler
>> PATCH12-16: Create HostIOMMUDevice instance and pass to vIOMMU
>> PATCH17-19: Implement compatibility check between host IOMMU and
>vIOMMU(intel_iommu)
>>
>> Qemu code can be found at:
>>
>https://github.com/yiliu1765/qemu/tree/zhenzhong/iommufd_nesting_pre
>q_v3
>>
>> Besides the compatibility check in this series, in nesting series, this
>> host IOMMU device is extended for much wider usage. For anyone
>interested
>> on the nesting series, here is the link:
>>
>https://github.com/yiliu1765/qemu/tree/zhenzhong/iommufd_nesting_rfc
>v2
>
>
>v4 should be a good candidate, we will need feedback from the vIOMMU
>maintainers though.
>
>However, have you considered another/complementary approach which
>would be to create an host IOMMU (iommufd) backend object and a
>vIOMMU
>device object together for each vfio-pci device being plugged in the
>machine ?

I did consider about a single iommufd instance for qemu and finally chose
to support multiple iommufd instances, reason below:

I was taking iommufd as a backend of VFIO device not a backend of vIOMMU.
So there is an iommufd property linked to iommufd instances.
We do support multiple iommufd instances in nesting series just as
we do in cdev series, such as:

-device 
intel-iommu,caching-mode=on,dma-drain=on,device-iotlb=on,x-scalable-mode=modern
-object iommufd,id=iommufd0
-device vfio-pci,host=6f:01.0,id=vfio0,bus=root0,iommufd=iommufd0
-object iommufd,id=iommufd1
-device vfio-pci,host=6f:01.1,id=vfio1,bus=root1,iommufd=iommufd1
-device vfio-pci,host=6f:01.2,id=vfio2,bus=root2

Adding iommufd property to vIOMMU will limit the whole qemu to use only
one iommufd instance, it's also confusing if there is also vfio device with 
legacy
backend.

I'm not clear how useful multiple iommufd instances support are.
One possible benefit is for security? It may bring a slightly fine-grained
isolation in kernel.

We can discuss this further, if it's unnecessary to support multiple iommufd
instances in nesting series, I can change to single iommufd instance support
and add an iommufd property for vIOMMU just as you suggested.

Thanks
Zhenzhong

>
>Something like,
>
> -device pcie-root-port,port=23,chassis=8,id=pci.8,bus=pcie.0 \
> -object 

RE: [PATCH v3 11/19] backends/iommufd: Implement HostIOMMUDeviceClass::check_cap() handler

2024-05-05 Thread Duan, Zhenzhong
>-Original Message-
>From: Cédric Le Goater 
>Subject: Re: [PATCH v3 11/19] backends/iommufd: Implement
>HostIOMMUDeviceClass::check_cap() handler
>
>> +static int hiod_iommufd_check_cap(HostIOMMUDevice *hiod, int
>cap,
> Error **errp)
>> +{
>> +switch (cap) {
>> +case HOST_IOMMU_DEVICE_CAP_IOMMUFD:
>> +return 1;
>
> I don't understand this value.

 1 means this host iommu device is attached to IOMMUFD backend,
 or else 0 if attached to legacy backend.
>>>
>>> Hmm, this looks hacky to me and it is not used anywhere in the patchset.
>>> Let's reconsider when there is actually a use for it. Until then, please
>>> drop. My feeling is that a new HostIOMMUDeviceClass
>handler/attributed
>>> should be introduced instead.
>>
>> Got it, will drop it in this series.
>>
>> Is "return 1" directly the concern on your side?
>
>I don't know yet why the implementation would need to know if the host
>IOMMU device is of type IOMMUFD. If that's the case, there are alternative
>ways, like using OBJECT_CHECK( ..., TYPE_HOST_IOMMU_DEVICE_IOMMUFD)
>or
>a class attribute defined at build time but that's a bit the same. Let's
>see when the need arises.

Got it, let's revisit it in nesting series, will drop it for now.

Thanks
Zhenzhong


RE: [PATCH intel_iommu 0/7] FLTS for VT-d

2024-05-05 Thread Duan, Zhenzhong
Hi Clement,

Sorry for late response, just back from vacation.
I saw your rebased version and thanks for your work.
I'll schedule a timeslot to review them.

Thanks
Zhenzhong

>-Original Message-
>From: CLEMENT MATHIEU--DRIF 
>Subject: Re: [PATCH intel_iommu 0/7] FLTS for VT-d
>
>Hi Zhenzhong,
>
>I will rebase,
>
>thanks
>
>On 01/05/2024 14:40, Duan, Zhenzhong wrote:
>> Caution: External email. Do not open attachments or click links, unless this
>email comes from a known sender and you know the content is safe.
>>
>>
>> Ah, this is a duplicate effort on stage-1 translation.
>>
>> Hi Clement,
>>
>> We had ever sent a rfcv1 series "intel_iommu: Enable stage-1 translation"
>> for both emulated and passthrough device, link:
>> https://lists.gnu.org/archive/html/qemu-devel/2024-01/msg02740.html
>> which now evolves to rfcv2, link:
>>
>https://github.com/yiliu1765/qemu/commits/zhenzhong/iommufd_nesting
>_rfcv2/
>>
>> It had addressed recent community comments, also the comments in old
>history series:
>>
>https://patchwork.kernel.org/project/kvm/cover/20210302203827.437645
>-1-yi.l@intel.com/
>>
>> Would you mind rebasing your remaining part, i.e., ATS, PRI emulation, etc
>on to our rfcv2?
>>
>> Thanks
>> Zhenzhong
>>
>>> -Original Message-
>>> From: Cédric Le Goater 
>>> Subject: Re: [PATCH intel_iommu 0/7] FLTS for VT-d
>>>
>>> Hello,
>>>
>>> Adding a few people in Cc: who are familiar with the Intel IOMMU.
>>>
>>> Thanks,
>>>
>>> C.
>>>
>>>
>>>
>>>
>>> On 4/22/24 17:52, CLEMENT MATHIEU--DRIF wrote:
 This series is the first of a list that add support for SVM in the Intel
>IOMMU.

 Here, we implement support for first-stage translation in VT-d.
 The PASID-based IOTLB invalidation is also added in this series as it is a
 requirement of FLTS.

 The last patch introduces the 'flts' option to enable the feature from
 the command line.
 Once enabled, several drivers of the Linux kernel use this feature.

 This work is based on the VT-d specification version 4.1 (March 2023)

 Here is a link to a GitHub repository where you can find the following
>>> elements :
   - Qemu with all the patches for SVM
   - ATS
   - PRI
   - PASID based IOTLB invalidation
   - Device IOTLB invalidations
   - First-stage translations
   - Requests with already translated addresses
   - A demo device
   - A simple driver for the demo device
   - A userspace program (for testing and demonstration purposes)

 https://github.com/BullSequana/Qemu-in-guest-SVM-demo

 Clément Mathieu--Drif (7):
 intel_iommu: fix FRCD construction macro.
 intel_iommu: rename slpte to pte before adding FLTS
 intel_iommu: make types match
 intel_iommu: add support for first-stage translation
 intel_iommu: extract device IOTLB invalidation logic
 intel_iommu: add PASID-based IOTLB invalidation
 intel_iommu: add a CLI option to enable FLTS

hw/i386/intel_iommu.c  | 655 ++-
>-
>>> -
hw/i386/intel_iommu_internal.h | 114 --
include/hw/i386/intel_iommu.h  |   3 +-
3 files changed, 609 insertions(+), 163 deletions(-)



[PATCH v4] target/loongarch: Add TCG macro in structure CPUArchState

2024-05-05 Thread Bibo Mao
In structure CPUArchState some struct elements are only used in TCG
mode, and it is not used in KVM mode. Macro CONFIG_TCG is added to
make it simpiler in KVM mode, also there is the same modification
in c code when these structure elements are used.

When VM runs in KVM mode, TLB entries are not used and do not need
migrate. It is only useful when it runs in TCG mode.

Signed-off-by: Bibo Mao 
Reviewed-by: Richard Henderson 
---
v3 --> v4:
- Refresh the patch based on the latest mainline version.

v2 --> v3:
- Remove print info about fp_status in loongarch_cpu_dump_state() since
it is always zero.
- Return tcg_enabled() directly in tlb_needed()

v1 --> v2:
- Add field needed in structure vmstate_tlb, dynamically judge whether
tlb should be migrated, since mostly qemu-system-loongarch64 is compiled
with both kvm and tcg accl enabled.
---
 target/loongarch/cpu.c|  7 +--
 target/loongarch/cpu.h| 16 ++--
 target/loongarch/cpu_helper.c |  9 +
 target/loongarch/machine.c| 30 +-
 4 files changed, 49 insertions(+), 13 deletions(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 1ebba043f4..ab813a8f67 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -505,7 +505,9 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType 
type)
 lacc->parent_phases.hold(obj, type);
 }
 
+#ifdef CONFIG_TCG
 env->fcsr0_mask = FCSR0_M1 | FCSR0_M2 | FCSR0_M3;
+#endif
 env->fcsr0 = 0x0;
 
 int n;
@@ -550,7 +552,9 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType 
type)
 
 #ifndef CONFIG_USER_ONLY
 env->pc = 0x1c00;
+#ifdef CONFIG_TCG
 memset(env->tlb, 0, sizeof(env->tlb));
+#endif
 if (kvm_enabled()) {
 kvm_arch_reset_vcpu(env);
 }
@@ -686,8 +690,7 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int 
flags)
 int i;
 
 qemu_fprintf(f, " PC=%016" PRIx64 " ", env->pc);
-qemu_fprintf(f, " FCSR0 0x%08x  fp_status 0x%02x\n", env->fcsr0,
- get_float_exception_flags(>fp_status));
+qemu_fprintf(f, " FCSR0 0x%08x\n", env->fcsr0);
 
 /* gpr */
 for (i = 0; i < 32; i++) {
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index c5722670f5..41b8e6d96d 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -270,6 +270,7 @@ union fpr_t {
 VReg  vreg;
 };
 
+#ifdef CONFIG_TCG
 struct LoongArchTLB {
 uint64_t tlb_misc;
 /* Fields corresponding to CSR_TLBELO0/1 */
@@ -277,23 +278,18 @@ struct LoongArchTLB {
 uint64_t tlb_entry1;
 };
 typedef struct LoongArchTLB LoongArchTLB;
+#endif
 
 typedef struct CPUArchState {
 uint64_t gpr[32];
 uint64_t pc;
 
 fpr_t fpr[32];
-float_status fp_status;
 bool cf[8];
-
 uint32_t fcsr0;
-uint32_t fcsr0_mask;
 
 uint32_t cpucfg[21];
 
-uint64_t lladdr; /* LL virtual address compared against SC */
-uint64_t llval;
-
 /* LoongArch CSRs */
 uint64_t CSR_CRMD;
 uint64_t CSR_PRMD;
@@ -350,8 +346,16 @@ typedef struct CPUArchState {
 uint64_t CSR_DERA;
 uint64_t CSR_DSAVE;
 
+#ifdef CONFIG_TCG
+float_status fp_status;
+uint32_t fcsr0_mask;
+uint64_t lladdr; /* LL virtual address compared against SC */
+uint64_t llval;
+#endif
 #ifndef CONFIG_USER_ONLY
+#ifdef CONFIG_TCG
 LoongArchTLB  tlb[LOONGARCH_TLB_MAX];
+#endif
 
 AddressSpace *address_space_iocsr;
 bool load_elf;
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index 960eec9567..580362ac3e 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -11,6 +11,7 @@
 #include "internals.h"
 #include "cpu-csr.h"
 
+#ifdef CONFIG_TCG
 static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
int *prot, target_ulong address,
int access_type, int index, int mmu_idx)
@@ -154,6 +155,14 @@ static int loongarch_map_address(CPULoongArchState *env, 
hwaddr *physical,
 
 return TLBRET_NOMATCH;
 }
+#else
+static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
+ int *prot, target_ulong address,
+ MMUAccessType access_type, int mmu_idx)
+{
+return TLBRET_NOMATCH;
+}
+#endif
 
 static hwaddr dmw_va2pa(CPULoongArchState *env, target_ulong va,
 target_ulong dmw)
diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c
index c7029fb9b4..9cd9e848d6 100644
--- a/target/loongarch/machine.c
+++ b/target/loongarch/machine.c
@@ -8,6 +8,7 @@
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "migration/cpu.h"
+#include "sysemu/tcg.h"
 #include "vec.h"
 
 static const VMStateDescription vmstate_fpu_reg = {
@@ -109,9 +110,15 @@ static const VMStateDescription vmstate_lasx = {
 },
 };
 
+#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
+static bool tlb_needed(void *opaque)
+{
+   

[PATCH 02/57] target/arm: Split out gengvec64.c

2024-05-05 Thread Richard Henderson
Split some routines out of translate-a64.c and translate-sve.c
that are used by both.

Signed-off-by: Richard Henderson 
---
 target/arm/tcg/translate-a64.h |   4 +
 target/arm/tcg/gengvec64.c | 190 +
 target/arm/tcg/translate-a64.c |  26 -
 target/arm/tcg/translate-sve.c | 145 +
 target/arm/tcg/meson.build |   1 +
 5 files changed, 197 insertions(+), 169 deletions(-)
 create mode 100644 target/arm/tcg/gengvec64.c

diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
index 7b811b8ac5..91750f0ca9 100644
--- a/target/arm/tcg/translate-a64.h
+++ b/target/arm/tcg/translate-a64.h
@@ -193,6 +193,10 @@ void gen_gvec_rax1(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 void gen_gvec_xar(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
   uint32_t rm_ofs, int64_t shift,
   uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_eor3(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
+   uint32_t a, uint32_t oprsz, uint32_t maxsz);
+void gen_gvec_bcax(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
+   uint32_t a, uint32_t oprsz, uint32_t maxsz);
 
 void gen_sve_ldr(DisasContext *s, TCGv_ptr, int vofs, int len, int rn, int 
imm);
 void gen_sve_str(DisasContext *s, TCGv_ptr, int vofs, int len, int rn, int 
imm);
diff --git a/target/arm/tcg/gengvec64.c b/target/arm/tcg/gengvec64.c
new file mode 100644
index 00..093b498b13
--- /dev/null
+++ b/target/arm/tcg/gengvec64.c
@@ -0,0 +1,190 @@
+/*
+ *  AArch64 generic vector expansion
+ *
+ *  Copyright (c) 2013 Alexander Graf 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "translate.h"
+#include "translate-a64.h"
+
+
+static void gen_rax1_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m)
+{
+tcg_gen_rotli_i64(d, m, 1);
+tcg_gen_xor_i64(d, d, n);
+}
+
+static void gen_rax1_vec(unsigned vece, TCGv_vec d, TCGv_vec n, TCGv_vec m)
+{
+tcg_gen_rotli_vec(vece, d, m, 1);
+tcg_gen_xor_vec(vece, d, d, n);
+}
+
+void gen_gvec_rax1(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+   uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static const TCGOpcode vecop_list[] = { INDEX_op_rotli_vec, 0 };
+static const GVecGen3 op = {
+.fni8 = gen_rax1_i64,
+.fniv = gen_rax1_vec,
+.opt_opc = vecop_list,
+.fno = gen_helper_crypto_rax1,
+.vece = MO_64,
+};
+tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, );
+}
+
+static void gen_xar8_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, int64_t sh)
+{
+TCGv_i64 t = tcg_temp_new_i64();
+uint64_t mask = dup_const(MO_8, 0xff >> sh);
+
+tcg_gen_xor_i64(t, n, m);
+tcg_gen_shri_i64(d, t, sh);
+tcg_gen_shli_i64(t, t, 8 - sh);
+tcg_gen_andi_i64(d, d, mask);
+tcg_gen_andi_i64(t, t, ~mask);
+tcg_gen_or_i64(d, d, t);
+}
+
+static void gen_xar16_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, int64_t sh)
+{
+TCGv_i64 t = tcg_temp_new_i64();
+uint64_t mask = dup_const(MO_16, 0x >> sh);
+
+tcg_gen_xor_i64(t, n, m);
+tcg_gen_shri_i64(d, t, sh);
+tcg_gen_shli_i64(t, t, 16 - sh);
+tcg_gen_andi_i64(d, d, mask);
+tcg_gen_andi_i64(t, t, ~mask);
+tcg_gen_or_i64(d, d, t);
+}
+
+static void gen_xar_i32(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, int32_t sh)
+{
+tcg_gen_xor_i32(d, n, m);
+tcg_gen_rotri_i32(d, d, sh);
+}
+
+static void gen_xar_i64(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, int64_t sh)
+{
+tcg_gen_xor_i64(d, n, m);
+tcg_gen_rotri_i64(d, d, sh);
+}
+
+static void gen_xar_vec(unsigned vece, TCGv_vec d, TCGv_vec n,
+TCGv_vec m, int64_t sh)
+{
+tcg_gen_xor_vec(vece, d, n, m);
+tcg_gen_rotri_vec(vece, d, d, sh);
+}
+
+void gen_gvec_xar(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+  uint32_t rm_ofs, int64_t shift,
+  uint32_t opr_sz, uint32_t max_sz)
+{
+static const TCGOpcode vecop[] = { INDEX_op_rotli_vec, 0 };
+static const GVecGen3i ops[4] = {
+{ .fni8 = gen_xar8_i64,
+  .fniv = gen_xar_vec,
+  .fno = gen_helper_sve2_xar_b,
+  .opt_opc = vecop,
+  .vece = MO_8 },
+{ .fni8 = gen_xar16_i64,
+  .fniv = gen_xar_vec,
+  .fno = gen_helper_sve2_xar_h,
+  

[PATCH 30/57] target/arm: Improve vector UQADD, UQSUB, SQADD, SQSUB

2024-05-05 Thread Richard Henderson
No need for a full comparison; xor produces non-zero bits
for QC just fine.

Signed-off-by: Richard Henderson 
---
 target/arm/tcg/gengvec.c | 32 
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c
index 22c9d17dce..bfe6885a01 100644
--- a/target/arm/tcg/gengvec.c
+++ b/target/arm/tcg/gengvec.c
@@ -1217,21 +1217,21 @@ void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, [vece]);
 }
 
-static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
+static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec qc,
   TCGv_vec a, TCGv_vec b)
 {
 TCGv_vec x = tcg_temp_new_vec_matching(t);
 tcg_gen_add_vec(vece, x, a, b);
 tcg_gen_usadd_vec(vece, t, a, b);
-tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
-tcg_gen_or_vec(vece, sat, sat, x);
+tcg_gen_xor_vec(vece, x, x, t);
+tcg_gen_or_vec(vece, qc, qc, x);
 }
 
 void gen_gvec_uqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
 {
 static const TCGOpcode vecop_list[] = {
-INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
+INDEX_op_usadd_vec, INDEX_op_add_vec, 0
 };
 static const GVecGen4 ops[4] = {
 { .fniv = gen_uqadd_vec,
@@ -1259,21 +1259,21 @@ void gen_gvec_uqadd_qc(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
rn_ofs, rm_ofs, opr_sz, max_sz, [vece]);
 }
 
-static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
+static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec qc,
   TCGv_vec a, TCGv_vec b)
 {
 TCGv_vec x = tcg_temp_new_vec_matching(t);
 tcg_gen_add_vec(vece, x, a, b);
 tcg_gen_ssadd_vec(vece, t, a, b);
-tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
-tcg_gen_or_vec(vece, sat, sat, x);
+tcg_gen_xor_vec(vece, x, x, t);
+tcg_gen_or_vec(vece, qc, qc, x);
 }
 
 void gen_gvec_sqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
 {
 static const TCGOpcode vecop_list[] = {
-INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
+INDEX_op_ssadd_vec, INDEX_op_add_vec, 0
 };
 static const GVecGen4 ops[4] = {
 { .fniv = gen_sqadd_vec,
@@ -1301,21 +1301,21 @@ void gen_gvec_sqadd_qc(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
rn_ofs, rm_ofs, opr_sz, max_sz, [vece]);
 }
 
-static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
+static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec qc,
   TCGv_vec a, TCGv_vec b)
 {
 TCGv_vec x = tcg_temp_new_vec_matching(t);
 tcg_gen_sub_vec(vece, x, a, b);
 tcg_gen_ussub_vec(vece, t, a, b);
-tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
-tcg_gen_or_vec(vece, sat, sat, x);
+tcg_gen_xor_vec(vece, x, x, t);
+tcg_gen_or_vec(vece, qc, qc, x);
 }
 
 void gen_gvec_uqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
 {
 static const TCGOpcode vecop_list[] = {
-INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
+INDEX_op_ussub_vec, INDEX_op_sub_vec, 0
 };
 static const GVecGen4 ops[4] = {
 { .fniv = gen_uqsub_vec,
@@ -1343,21 +1343,21 @@ void gen_gvec_uqsub_qc(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
rn_ofs, rm_ofs, opr_sz, max_sz, [vece]);
 }
 
-static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
+static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec qc,
   TCGv_vec a, TCGv_vec b)
 {
 TCGv_vec x = tcg_temp_new_vec_matching(t);
 tcg_gen_sub_vec(vece, x, a, b);
 tcg_gen_sssub_vec(vece, t, a, b);
-tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
-tcg_gen_or_vec(vece, sat, sat, x);
+tcg_gen_xor_vec(vece, x, x, t);
+tcg_gen_or_vec(vece, qc, qc, x);
 }
 
 void gen_gvec_sqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
 {
 static const TCGOpcode vecop_list[] = {
-INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
+INDEX_op_sssub_vec, INDEX_op_sub_vec, 0
 };
 static const GVecGen4 ops[4] = {
 { .fniv = gen_sqsub_vec,
-- 
2.34.1




[PATCH 07/57] target/arm: Convert Cryptographic 2-register SHA512 to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  5 
 target/arm/tcg/translate-a64.c | 50 ++
 2 files changed, 8 insertions(+), 47 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index c342c27608..5a46205751 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -631,3 +631,8 @@ RAX11100 1110 011 . 100011 . .  
@rrr_q1e3
 SM3PARTW1   1100 1110 011 . 11 . .  @rrr_q1e0
 SM3PARTW2   1100 1110 011 . 110001 . .  @rrr_q1e0
 SM4EKEY 1100 1110 011 . 110010 . .  @rrr_q1e0
+
+### Cryptographic two-register SHA512
+
+SHA512SU0   1100 1110 110 0 10 . .  @rr_q1e0
+SM4E1100 1110 110 0 11 . .  @r2r_q1e0
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index d2d9198f22..1bfee2583a 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -4630,6 +4630,9 @@ TRANS_FEAT(SM3PARTW1, aa64_sm3, do_gvec_op3_ool, a, 0, 
gen_helper_crypto_sm3part
 TRANS_FEAT(SM3PARTW2, aa64_sm3, do_gvec_op3_ool, a, 0, 
gen_helper_crypto_sm3partw2)
 TRANS_FEAT(SM4EKEY, aa64_sm4, do_gvec_op3_ool, a, 0, gen_helper_crypto_sm4ekey)
 
+TRANS_FEAT(SHA512SU0, aa64_sha512, do_gvec_op2_ool, a, 0, 
gen_helper_crypto_sha512su0)
+TRANS_FEAT(SM4E, aa64_sm4, do_gvec_op3_ool, a, 0, gen_helper_crypto_sm4e)
+
 
 /* Shift a TCGv src by TCGv shift_amount, put result in dst.
  * Note that it is the caller's responsibility to ensure that the
@@ -13524,52 +13527,6 @@ static void disas_simd_indexed(DisasContext *s, 
uint32_t insn)
 }
 }
 
-/* Crypto two-reg SHA512
- *  31 12  11  10  95 40
- * +-++--+--+
- * | 1 1 0 0 1 1 1 0 1 1 0 0 0 0 0 0 1 0 0 0 | opcode |  Rn  |  Rd  |
- * +-++--+--+
- */
-static void disas_crypto_two_reg_sha512(DisasContext *s, uint32_t insn)
-{
-int opcode = extract32(insn, 10, 2);
-int rn = extract32(insn, 5, 5);
-int rd = extract32(insn, 0, 5);
-bool feature;
-
-switch (opcode) {
-case 0: /* SHA512SU0 */
-feature = dc_isar_feature(aa64_sha512, s);
-break;
-case 1: /* SM4E */
-feature = dc_isar_feature(aa64_sm4, s);
-break;
-default:
-unallocated_encoding(s);
-return;
-}
-
-if (!feature) {
-unallocated_encoding(s);
-return;
-}
-
-if (!fp_access_check(s)) {
-return;
-}
-
-switch (opcode) {
-case 0: /* SHA512SU0 */
-gen_gvec_op2_ool(s, true, rd, rn, 0, gen_helper_crypto_sha512su0);
-break;
-case 1: /* SM4E */
-gen_gvec_op3_ool(s, true, rd, rd, rn, 0, gen_helper_crypto_sm4e);
-break;
-default:
-g_assert_not_reached();
-}
-}
-
 /* Crypto four-register
  *  31   23 22 21 20  16 15  14  10 95 40
  * +---+-+--+---+--+--+--+
@@ -13744,7 +13701,6 @@ static const AArch64DecodeTable data_proc_simd[] = {
 { 0x5e000400, 0xdfe08400, disas_simd_scalar_copy },
 { 0x5f00, 0xdf000400, disas_simd_indexed }, /* scalar indexed */
 { 0x5f000400, 0xdf800400, disas_simd_scalar_shift_imm },
-{ 0xcec08000, 0xf000, disas_crypto_two_reg_sha512 },
 { 0xce00, 0xff808000, disas_crypto_four_reg },
 { 0xce80, 0xffe0, disas_crypto_xar },
 { 0xce408000, 0xffe0c000, disas_crypto_three_reg_imm2 },
-- 
2.34.1




[PATCH 32/57] target/arm: Inline scalar SUQADD and USQADD

2024-05-05 Thread Richard Henderson
This eliminates the last uses of these neon helpers.
Incorporate the MO_64 expanders as an option to the vector expander.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|   8 --
 target/arm/tcg/translate-a64.h |   8 ++
 target/arm/tcg/gengvec64.c |  71 ++
 target/arm/tcg/neon_helper.c   | 165 -
 target/arm/tcg/translate-a64.c |  73 +--
 5 files changed, 103 insertions(+), 222 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index de2c5c9aef..c76158d6d3 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -274,14 +274,6 @@ DEF_HELPER_FLAGS_3(neon_qadd_u16, TCG_CALL_NO_RWG, i32, 
env, i32, i32)
 DEF_HELPER_FLAGS_3(neon_qadd_s16, TCG_CALL_NO_RWG, i32, env, i32, i32)
 DEF_HELPER_FLAGS_3(neon_qadd_u32, TCG_CALL_NO_RWG, i32, env, i32, i32)
 DEF_HELPER_FLAGS_3(neon_qadd_s32, TCG_CALL_NO_RWG, i32, env, i32, i32)
-DEF_HELPER_FLAGS_3(neon_uqadd_s8, TCG_CALL_NO_RWG, i32, env, i32, i32)
-DEF_HELPER_FLAGS_3(neon_uqadd_s16, TCG_CALL_NO_RWG, i32, env, i32, i32)
-DEF_HELPER_FLAGS_3(neon_uqadd_s32, TCG_CALL_NO_RWG, i32, env, i32, i32)
-DEF_HELPER_FLAGS_3(neon_uqadd_s64, TCG_CALL_NO_RWG, i64, env, i64, i64)
-DEF_HELPER_FLAGS_3(neon_sqadd_u8, TCG_CALL_NO_RWG, i32, env, i32, i32)
-DEF_HELPER_FLAGS_3(neon_sqadd_u16, TCG_CALL_NO_RWG, i32, env, i32, i32)
-DEF_HELPER_FLAGS_3(neon_sqadd_u32, TCG_CALL_NO_RWG, i32, env, i32, i32)
-DEF_HELPER_FLAGS_3(neon_sqadd_u64, TCG_CALL_NO_RWG, i64, env, i64, i64)
 DEF_HELPER_3(neon_qsub_u8, i32, env, i32, i32)
 DEF_HELPER_3(neon_qsub_s8, i32, env, i32, i32)
 DEF_HELPER_3(neon_qsub_u16, i32, env, i32, i32)
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
index b5cb26f8a2..0fcf7cb63a 100644
--- a/target/arm/tcg/translate-a64.h
+++ b/target/arm/tcg/translate-a64.h
@@ -197,9 +197,17 @@ void gen_gvec_eor3(unsigned vece, uint32_t d, uint32_t n, 
uint32_t m,
uint32_t a, uint32_t oprsz, uint32_t maxsz);
 void gen_gvec_bcax(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
uint32_t a, uint32_t oprsz, uint32_t maxsz);
+
+void gen_suqadd_bhs(TCGv_i64 res, TCGv_i64 qc,
+TCGv_i64 a, TCGv_i64 b, MemOp esz);
+void gen_suqadd_d(TCGv_i64 res, TCGv_i64 qc, TCGv_i64 a, TCGv_i64 b);
 void gen_gvec_suqadd_qc(unsigned vece, uint32_t rd_ofs,
 uint32_t rn_ofs, uint32_t rm_ofs,
 uint32_t opr_sz, uint32_t max_sz);
+
+void gen_usqadd_bhs(TCGv_i64 res, TCGv_i64 qc,
+TCGv_i64 a, TCGv_i64 b, MemOp esz);
+void gen_usqadd_d(TCGv_i64 res, TCGv_i64 qc, TCGv_i64 a, TCGv_i64 b);
 void gen_gvec_usqadd_qc(unsigned vece, uint32_t rd_ofs,
 uint32_t rn_ofs, uint32_t rm_ofs,
 uint32_t opr_sz, uint32_t max_sz);
diff --git a/target/arm/tcg/gengvec64.c b/target/arm/tcg/gengvec64.c
index 201a719bc1..876abadd76 100644
--- a/target/arm/tcg/gengvec64.c
+++ b/target/arm/tcg/gengvec64.c
@@ -188,6 +188,38 @@ void gen_gvec_bcax(unsigned vece, uint32_t d, uint32_t n, 
uint32_t m,
 tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, );
 }
 
+/*
+ * Set @res to the correctly saturated result.
+ * Set @qc non-zero if saturation occured.
+ */
+void gen_suqadd_bhs(TCGv_i64 res, TCGv_i64 qc,
+TCGv_i64 a, TCGv_i64 b, MemOp esz)
+{
+TCGv_i64 max = tcg_constant_i64((1ull << ((8 << esz) - 1)) - 1);
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_add_i64(t, a, b);
+tcg_gen_smin_i64(res, t, max);
+tcg_gen_xor_i64(t, t, res);
+tcg_gen_or_i64(qc, qc, t);
+}
+
+void gen_suqadd_d(TCGv_i64 res, TCGv_i64 qc, TCGv_i64 a, TCGv_i64 b)
+{
+TCGv_i64 max = tcg_constant_i64(INT64_MAX);
+TCGv_i64 t = tcg_temp_new_i64();
+
+/* Maximum value that can be added to @a without overflow. */
+tcg_gen_sub_i64(t, max, a);
+
+/* Constrain addend so that the next addition never overflows. */
+tcg_gen_umin_i64(t, t, b);
+tcg_gen_add_i64(res, a, t);
+
+tcg_gen_xor_i64(t, t, b);
+tcg_gen_or_i64(qc, qc, t);
+}
+
 static void gen_suqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec qc,
TCGv_vec a, TCGv_vec b)
 {
@@ -231,6 +263,7 @@ void gen_gvec_suqadd_qc(unsigned vece, uint32_t rd_ofs,
   .write_aofs = true,
   .vece = MO_32 },
 { .fniv = gen_suqadd_vec,
+  .fni8 = gen_suqadd_d,
   .fno = gen_helper_gvec_suqadd_d,
   .opt_opc = vecop_list,
   .write_aofs = true,
@@ -240,6 +273,43 @@ void gen_gvec_suqadd_qc(unsigned vece, uint32_t rd_ofs,
rn_ofs, rm_ofs, opr_sz, max_sz, [vece]);
 }
 
+void gen_usqadd_bhs(TCGv_i64 res, TCGv_i64 qc,
+TCGv_i64 a, TCGv_i64 b, MemOp esz)
+{
+TCGv_i64 max = tcg_constant_i64(MAKE_64BIT_MASK(0, 8 << esz));
+TCGv_i64 zero = tcg_constant_i64(0);
+TCGv_i64 tmp = tcg_temp_new_i64();
+
+tcg_gen_add_i64(tmp, a, b);
+tcg_gen_smin_i64(res, tmp, max);
+

[PATCH 31/57] target/arm: Convert SUQADD and USQADD to gvec

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|  16 +
 target/arm/tcg/translate-a64.h |   6 ++
 target/arm/tcg/gengvec64.c | 106 +++
 target/arm/tcg/translate-a64.c | 113 ++---
 target/arm/tcg/vec_helper.c|  64 +++
 5 files changed, 241 insertions(+), 64 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index f830531dd3..de2c5c9aef 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -836,6 +836,22 @@ DEF_HELPER_FLAGS_5(gvec_sqsub_s, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(gvec_sqsub_d, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_usqadd_b, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_usqadd_h, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_usqadd_s, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_usqadd_d, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_suqadd_b, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_suqadd_h, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_suqadd_s, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_suqadd_d, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_5(gvec_fmlal_a32, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
index 91750f0ca9..b5cb26f8a2 100644
--- a/target/arm/tcg/translate-a64.h
+++ b/target/arm/tcg/translate-a64.h
@@ -197,6 +197,12 @@ void gen_gvec_eor3(unsigned vece, uint32_t d, uint32_t n, 
uint32_t m,
uint32_t a, uint32_t oprsz, uint32_t maxsz);
 void gen_gvec_bcax(unsigned vece, uint32_t d, uint32_t n, uint32_t m,
uint32_t a, uint32_t oprsz, uint32_t maxsz);
+void gen_gvec_suqadd_qc(unsigned vece, uint32_t rd_ofs,
+uint32_t rn_ofs, uint32_t rm_ofs,
+uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_usqadd_qc(unsigned vece, uint32_t rd_ofs,
+uint32_t rn_ofs, uint32_t rm_ofs,
+uint32_t opr_sz, uint32_t max_sz);
 
 void gen_sve_ldr(DisasContext *s, TCGv_ptr, int vofs, int len, int rn, int 
imm);
 void gen_sve_str(DisasContext *s, TCGv_ptr, int vofs, int len, int rn, int 
imm);
diff --git a/target/arm/tcg/gengvec64.c b/target/arm/tcg/gengvec64.c
index 093b498b13..201a719bc1 100644
--- a/target/arm/tcg/gengvec64.c
+++ b/target/arm/tcg/gengvec64.c
@@ -188,3 +188,109 @@ void gen_gvec_bcax(unsigned vece, uint32_t d, uint32_t n, 
uint32_t m,
 tcg_gen_gvec_4(d, n, m, a, oprsz, maxsz, );
 }
 
+static void gen_suqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec qc,
+   TCGv_vec a, TCGv_vec b)
+{
+TCGv_vec max =
+tcg_constant_vec_matching(t, vece, (1ull << ((8 << vece) - 1)) - 1);
+TCGv_vec u = tcg_temp_new_vec_matching(t);
+
+/* Maximum value that can be added to @a without overflow. */
+tcg_gen_sub_vec(vece, u, max, a);
+
+/* Constrain addend so that the next addition never overflows. */
+tcg_gen_umin_vec(vece, t, u, b);
+tcg_gen_add_vec(vece, t, t, a);
+
+/* Compute QC by comparing the adjusted @b. */
+tcg_gen_xor_vec(vece, u, u, b);
+tcg_gen_or_vec(vece, qc, qc, u);
+}
+
+void gen_gvec_suqadd_qc(unsigned vece, uint32_t rd_ofs,
+uint32_t rn_ofs, uint32_t rm_ofs,
+uint32_t opr_sz, uint32_t max_sz)
+{
+static const TCGOpcode vecop_list[] = {
+INDEX_op_add_vec, INDEX_op_sub_vec, INDEX_op_umin_vec, 0
+};
+static const GVecGen4 ops[4] = {
+{ .fniv = gen_suqadd_vec,
+  .fno = gen_helper_gvec_suqadd_b,
+  .opt_opc = vecop_list,
+  .write_aofs = true,
+  .vece = MO_8 },
+{ .fniv = gen_suqadd_vec,
+  .fno = gen_helper_gvec_suqadd_h,
+  .opt_opc = vecop_list,
+  .write_aofs = true,
+  .vece = MO_16 },
+{ .fniv = gen_suqadd_vec,
+  .fno = gen_helper_gvec_suqadd_s,
+  .opt_opc = vecop_list,
+  .write_aofs = true,
+  .vece = MO_32 },
+{ .fniv = gen_suqadd_vec,
+  .fno = gen_helper_gvec_suqadd_d,
+  .opt_opc = vecop_list,
+  .write_aofs = true,
+  .vece = MO_64 },
+};
+tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
+   rn_ofs, rm_ofs, opr_sz, max_sz, [vece]);
+}
+
+static void gen_usqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec qc,
+   TCGv_vec a, TCGv_vec b)
+{
+TCGv_vec u = tcg_temp_new_vec_matching(t);
+TCGv_vec z = 

[PATCH 57/57] target/arm: Convert SQDMULH, SQRDMULH to decodetree

2024-05-05 Thread Richard Henderson
These are the last instructions within disas_simd_three_reg_same
and disas_simd_scalar_three_reg_same, so remove them.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|  10 ++
 target/arm/tcg/a64.decode  |  18 +++
 target/arm/tcg/translate-a64.c | 276 ++---
 target/arm/tcg/vec_helper.c|  64 
 4 files changed, 172 insertions(+), 196 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 85f9302563..24feecee9b 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -968,6 +968,16 @@ DEF_HELPER_FLAGS_5(neon_sqrdmulh_h, TCG_CALL_NO_RWG,
 DEF_HELPER_FLAGS_5(neon_sqrdmulh_s, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
 
+DEF_HELPER_FLAGS_5(neon_sqdmulh_idx_h, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(neon_sqdmulh_idx_s, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_5(neon_sqrdmulh_idx_h, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(neon_sqrdmulh_idx_s, TCG_CALL_NO_RWG,
+   void, ptr, ptr, ptr, ptr, i32)
+
 DEF_HELPER_FLAGS_4(sve2_sqdmulh_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(sve2_sqdmulh_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(sve2_sqdmulh_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 8f7ae63e17..b9dc02c46f 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -774,6 +774,9 @@ CMHS_s  0111 1110 111 . 00111 1 . . 
@rrr_d
 CMTST_s 0101 1110 111 . 10001 1 . . @rrr_d
 CMEQ_s  0111 1110 111 . 10001 1 . . @rrr_d
 
+SQDMULH_s   0101 1110 ..1 . 10110 1 . . @rrr_e
+SQRDMULH_s  0111 1110 ..1 . 10110 1 . . @rrr_e
+
 ### Advanced SIMD scalar pairwise
 
 FADDP_s 0101 1110 0011  1101 10 . . @rr_h
@@ -931,6 +934,9 @@ PMUL_v  0.10 1110 001 . 10011 1 . . 
@qrrr_b
 MLA_v   0.00 1110 ..1 . 10010 1 . . @qrrr_e
 MLS_v   0.10 1110 ..1 . 10010 1 . . @qrrr_e
 
+SQDMULH_v   0.00 1110 ..1 . 10110 1 . . @qrrr_e
+SQRDMULH_v  0.10 1110 ..1 . 10110 1 . . @qrrr_e
+
 ### Advanced SIMD scalar x indexed element
 
 FMUL_si 0101  00 ..  1001 . 0 . .   @rrx_h
@@ -949,6 +955,12 @@ FMULX_si0111  00 ..  1001 . 0 . .  
 @rrx_h
 FMULX_si0111  10 . . 1001 . 0 . .   @rrx_s
 FMULX_si0111  11 0 . 1001 . 0 . .   @rrx_d
 
+SQDMULH_si  0101  01 ..  1100 . 0 . .   @rrx_h
+SQDMULH_si  0101  10 ..  1100 . 0 . .   @rrx_s
+
+SQRDMULH_si 0101  01 ..  1101 . 0 . .   @rrx_h
+SQRDMULH_si 0101  10 . . 1101 . 0 . .   @rrx_s
+
 ### Advanced SIMD vector x indexed element
 
 FMUL_vi 0.00  00 ..  1001 . 0 . .   @qrrx_h
@@ -980,3 +992,9 @@ MLA_vi  0.10  10 . .  . 0 . .   
@qrrx_s
 
 MLS_vi  0.10  01 ..  0100 . 0 . .   @qrrx_h
 MLS_vi  0.10  10 . . 0100 . 0 . .   @qrrx_s
+
+SQDMULH_vi  0.00  01 ..  1100 . 0 . .   @qrrx_h
+SQDMULH_vi  0.00  10 . . 1100 . 0 . .   @qrrx_s
+
+SQRDMULH_vi 0.00  01 ..  1101 . 0 . .   @qrrx_h
+SQRDMULH_vi 0.00  10 . . 1101 . 0 . .   @qrrx_s
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 0d8aba7a88..56f78b415f 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -1351,6 +1351,14 @@ static bool do_gvec_fn3_no64(DisasContext *s, arg_qrrr_e 
*a, GVecGen3Fn *fn)
 return true;
 }
 
+static bool do_gvec_fn3_no8_no64(DisasContext *s, arg_qrrr_e *a, GVecGen3Fn 
*fn)
+{
+if (a->esz == MO_8) {
+return false;
+}
+return do_gvec_fn3_no64(s, a, fn);
+}
+
 static bool do_gvec_fn4(DisasContext *s, arg_q_e *a, GVecGen4Fn *fn)
 {
 if (!a->q && a->esz == MO_64) {
@@ -5168,6 +5176,25 @@ static const ENVScalar2 f_scalar_uqrshl = {
 };
 TRANS(UQRSHL_s, do_env_scalar2, a, _scalar_uqrshl)
 
+static bool do_env_scalar2_hs(DisasContext *s, arg_rrr_e *a,
+  const ENVScalar2 *f)
+{
+if (a->esz == MO_16 || a->esz == MO_32) {
+return do_env_scalar2(s, a, f);
+}
+return false;
+}
+
+static const ENVScalar2 f_scalar_sqdmulh = {
+{ NULL, gen_helper_neon_qdmulh_s16, gen_helper_neon_qdmulh_s32 }
+};
+TRANS(SQDMULH_s, do_env_scalar2_hs, a, _scalar_sqdmulh)
+
+static const ENVScalar2 f_scalar_sqrdmulh = {
+{ NULL, gen_helper_neon_qrdmulh_s16, gen_helper_neon_qrdmulh_s32 }
+};
+TRANS(SQRDMULH_s, do_env_scalar2_hs, a, _scalar_sqrdmulh)
+
 static bool do_cmop_d(DisasContext *s, 

[PATCH 09/57] target/arm: Convert Cryptographic 3-register, imm2 to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  | 10 
 target/arm/tcg/translate-a64.c | 43 ++
 2 files changed, 22 insertions(+), 31 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index ef6902e86a..1292312a7f 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -644,3 +644,13 @@ SM4E1100 1110 110 0 11 . .  
@r2r_q1e0
 EOR31100 1110 000 . 0 . . . @_q1e3
 BCAX1100 1110 001 . 0 . . . @_q1e3
 SM3SS1  1100 1110 010 . 0 . . . @_q1e3
+
+### Cryptographic three-register, imm2
+
+   rd rn rm imm
+@crypto3i    ... rm:5 .. imm:2 .. rn:5 rd:5 
+
+SM3TT1A 11001110 010 . 10 .. 00 . . @crypto3i
+SM3TT1B 11001110 010 . 10 .. 01 . . @crypto3i
+SM3TT2A 11001110 010 . 10 .. 10 . . @crypto3i
+SM3TT2B 11001110 010 . 10 .. 11 . . @crypto3i
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index a20da75423..219a666cbb 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -4677,6 +4677,18 @@ static bool trans_SM3SS1(DisasContext *s, arg_SM3SS1 *a)
 return true;
 }
 
+static bool do_crypto3i(DisasContext *s, arg_crypto3i *a, gen_helper_gvec_3 
*fn)
+{
+if (fp_access_check(s)) {
+gen_gvec_op3_ool(s, true, a->rd, a->rn, a->rm, a->imm, fn);
+}
+return true;
+}
+TRANS_FEAT(SM3TT1A, aa64_sm3, do_crypto3i, a, gen_helper_crypto_sm3tt1a)
+TRANS_FEAT(SM3TT1B, aa64_sm3, do_crypto3i, a, gen_helper_crypto_sm3tt1b)
+TRANS_FEAT(SM3TT2A, aa64_sm3, do_crypto3i, a, gen_helper_crypto_sm3tt2a)
+TRANS_FEAT(SM3TT2B, aa64_sm3, do_crypto3i, a, gen_helper_crypto_sm3tt2b)
+
 /* Shift a TCGv src by TCGv shift_amount, put result in dst.
  * Note that it is the caller's responsibility to ensure that the
  * shift amount is in range (ie 0..31 or 0..63) and provide the ARM
@@ -13598,36 +13610,6 @@ static void disas_crypto_xar(DisasContext *s, uint32_t 
insn)
  vec_full_reg_size(s));
 }
 
-/* Crypto three-reg imm2
- *  31   21 20  16 15  14 13 12  11  10  95 40
- * +---+--+-+--++--+--+
- * | 1 1 0 0 1 1 1 0 0 1 0 |  Rm  | 1 0 | imm2 | opcode |  Rn  |  Rd  |
- * +---+--+-+--++--+--+
- */
-static void disas_crypto_three_reg_imm2(DisasContext *s, uint32_t insn)
-{
-static gen_helper_gvec_3 * const fns[4] = {
-gen_helper_crypto_sm3tt1a, gen_helper_crypto_sm3tt1b,
-gen_helper_crypto_sm3tt2a, gen_helper_crypto_sm3tt2b,
-};
-int opcode = extract32(insn, 10, 2);
-int imm2 = extract32(insn, 12, 2);
-int rm = extract32(insn, 16, 5);
-int rn = extract32(insn, 5, 5);
-int rd = extract32(insn, 0, 5);
-
-if (!dc_isar_feature(aa64_sm3, s)) {
-unallocated_encoding(s);
-return;
-}
-
-if (!fp_access_check(s)) {
-return;
-}
-
-gen_gvec_op3_ool(s, true, rd, rn, rm, imm2, fns[opcode]);
-}
-
 /* C3.6 Data processing - SIMD, inc Crypto
  *
  * As the decode gets a little complex we are using a table based
@@ -13657,7 +13639,6 @@ static const AArch64DecodeTable data_proc_simd[] = {
 { 0x5f00, 0xdf000400, disas_simd_indexed }, /* scalar indexed */
 { 0x5f000400, 0xdf800400, disas_simd_scalar_shift_imm },
 { 0xce80, 0xffe0, disas_crypto_xar },
-{ 0xce408000, 0xffe0c000, disas_crypto_three_reg_imm2 },
 { 0x0e400400, 0x9f60c400, disas_simd_three_reg_same_fp16 },
 { 0x0e780800, 0x8f7e0c00, disas_simd_two_reg_misc_fp16 },
 { 0x5e400400, 0xdf60c400, disas_simd_scalar_three_reg_same_fp16 },
-- 
2.34.1




[PATCH 54/57] target/arm: Convert MUL, PMUL to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  5 
 target/arm/tcg/translate-a64.c | 51 +-
 2 files changed, 25 insertions(+), 31 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index e1667775f6..dbeb5667fd 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -926,6 +926,8 @@ SABD_v  0.00 1110 ..1 . 01110 1 . . 
@qrrr_e
 UABD_v  0.10 1110 ..1 . 01110 1 . . @qrrr_e
 SABA_v  0.00 1110 ..1 . 0 1 . . @qrrr_e
 UABA_v  0.10 1110 ..1 . 0 1 . . @qrrr_e
+MUL_v   0.00 1110 ..1 . 10011 1 . . @qrrr_e
+PMUL_v  0.10 1110 001 . 10011 1 . . @qrrr_b
 
 ### Advanced SIMD scalar x indexed element
 
@@ -967,3 +969,6 @@ FMLAL_vi0.00  10 ..   . 0 . .   
@qrrx_h
 FMLSL_vi0.00  10 ..  0100 . 0 . .   @qrrx_h
 FMLAL2_vi   0.10  10 ..  1000 . 0 . .   @qrrx_h
 FMLSL2_vi   0.10  10 ..  1100 . 0 . .   @qrrx_h
+
+MUL_vi  0.00  01 ..  1000 . 0 . .   @qrrx_h
+MUL_vi  0.00  10 . . 1000 . 0 . .   @qrrx_s
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 2e746d2877..cd39fa1f20 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5469,6 +5469,8 @@ TRANS(SABA_v, do_gvec_fn3_no64, a, gen_gvec_saba)
 TRANS(UABA_v, do_gvec_fn3_no64, a, gen_gvec_uaba)
 TRANS(SABD_v, do_gvec_fn3_no64, a, gen_gvec_sabd)
 TRANS(UABD_v, do_gvec_fn3_no64, a, gen_gvec_uabd)
+TRANS(MUL_v, do_gvec_fn3_no64, a, tcg_gen_gvec_mul)
+TRANS(PMUL_v, do_gvec_op3_ool, a, 0, gen_helper_gvec_pmul_b)
 
 static bool do_cmop_v(DisasContext *s, arg_qrrr_e *a, TCGCond cond)
 {
@@ -5695,6 +5697,22 @@ TRANS_FEAT(FMLSL_vi, aa64_fhm, do_fmlal_idx, a, true, 
false)
 TRANS_FEAT(FMLAL2_vi, aa64_fhm, do_fmlal_idx, a, false, true)
 TRANS_FEAT(FMLSL2_vi, aa64_fhm, do_fmlal_idx, a, true, true)
 
+static bool do_int3_vector_idx(DisasContext *s, arg_qrrx_e *a,
+   gen_helper_gvec_3 * const fns[2])
+{
+assert(a->esz == MO_16 || a->esz == MO_32);
+if (fp_access_check(s)) {
+gen_gvec_op3_ool(s, a->q, a->rd, a->rn, a->rm, a->idx, fns[a->esz - 
1]);
+}
+return true;
+}
+
+static gen_helper_gvec_3 * const f_vector_idx_mul[2] = {
+gen_helper_gvec_mul_idx_h,
+gen_helper_gvec_mul_idx_s,
+};
+TRANS(MUL_vi, do_int3_vector_idx, a, f_vector_idx_mul)
+
 /*
  * Advanced SIMD scalar pairwise
  */
@@ -10921,12 +10939,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 int rd = extract32(insn, 0, 5);
 
 switch (opcode) {
-case 0x13: /* MUL, PMUL */
-if (u && size != 0) {
-unallocated_encoding(s);
-return;
-}
-/* fall through */
 case 0x12: /* MLA, MLS */
 if (size == 3) {
 unallocated_encoding(s);
@@ -10963,6 +10975,7 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 case 0x0f: /* SABA, UABA */
 case 0x10: /* ADD, SUB */
 case 0x11: /* CMTST, CMEQ */
+case 0x13: /* MUL, PMUL */
 unallocated_encoding(s);
 return;
 }
@@ -10972,13 +10985,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 }
 
 switch (opcode) {
-case 0x13: /* MUL, PMUL */
-if (!u) { /* MUL */
-gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_mul, size);
-} else {  /* PMUL */
-gen_gvec_op3_ool(s, is_q, rd, rn, rm, 0, gen_helper_gvec_pmul_b);
-}
-return;
 case 0x12: /* MLA, MLS */
 if (u) {
 gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_mls, size);
@@ -12192,7 +12198,6 @@ static void disas_simd_indexed(DisasContext *s, 
uint32_t insn)
 TCGv_ptr fpst;
 
 switch (16 * u + opcode) {
-case 0x08: /* MUL */
 case 0x10: /* MLA */
 case 0x14: /* MLS */
 if (is_scalar) {
@@ -12279,6 +12284,7 @@ static void disas_simd_indexed(DisasContext *s, 
uint32_t insn)
 case 0x01: /* FMLA */
 case 0x04: /* FMLSL */
 case 0x05: /* FMLS */
+case 0x08: /* MUL */
 case 0x09: /* FMUL */
 case 0x18: /* FMLAL2 */
 case 0x19: /* FMULX */
@@ -12401,22 +12407,6 @@ static void disas_simd_indexed(DisasContext *s, 
uint32_t insn)
 }
 return;
 
-case 0x08: /* MUL */
-if (!is_long && !is_scalar) {
-static gen_helper_gvec_3 * const fns[3] = {
-gen_helper_gvec_mul_idx_h,
-gen_helper_gvec_mul_idx_s,
-gen_helper_gvec_mul_idx_d,
-};
-tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
-   vec_full_reg_offset(s, rn),
-   vec_full_reg_offset(s, rm),
-   is_q ? 16 : 8, vec_full_reg_size(s),
- 

[PATCH 18/57] target/arm: Convert FCMEQ, FCMGE, FCMGT, FACGE, FACGT to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|   5 +
 target/arm/tcg/a64.decode  |  30 ++
 target/arm/tcg/translate-a64.c | 188 +++--
 target/arm/tcg/vec_helper.c|  30 ++
 4 files changed, 174 insertions(+), 79 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index e021c18517..8d076011c1 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -727,18 +727,23 @@ DEF_HELPER_FLAGS_5(gvec_fabd_s, TCG_CALL_NO_RWG, void, 
ptr, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_5(gvec_fceq_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(gvec_fceq_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_fceq_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_5(gvec_fcge_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(gvec_fcge_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_fcge_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_5(gvec_fcgt_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(gvec_fcgt_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_fcgt_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_5(gvec_facge_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 DEF_HELPER_FLAGS_5(gvec_facge_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_facge_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 
 DEF_HELPER_FLAGS_5(gvec_facgt_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 DEF_HELPER_FLAGS_5(gvec_facgt_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_facgt_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 
 DEF_HELPER_FLAGS_5(gvec_fmax_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(gvec_fmax_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index cb84a8685f..94d35733df 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -713,6 +713,21 @@ FMINNM_s0001 1110 ..1 . 0111 10 . . 
@rrr_hsd
 FMULX_s 0101 1110 010 . 00011 1 . . @rrr_h
 FMULX_s 0101 1110 0.1 . 11011 1 . . @rrr_sd
 
+FCMEQ_s 0101 1110 010 . 00100 1 . . @rrr_h
+FCMEQ_s 0101 1110 0.1 . 11100 1 . . @rrr_sd
+
+FCMGE_s 0111 1110 010 . 00100 1 . . @rrr_h
+FCMGE_s 0111 1110 0.1 . 11100 1 . . @rrr_sd
+
+FCMGT_s 0111 1110 110 . 00100 1 . . @rrr_h
+FCMGT_s 0111 1110 1.1 . 11100 1 . . @rrr_sd
+
+FACGE_s 0111 1110 010 . 00101 1 . . @rrr_h
+FACGE_s 0111 1110 0.1 . 11101 1 . . @rrr_sd
+
+FACGT_s 0111 1110 110 . 00101 1 . . @rrr_h
+FACGT_s 0111 1110 1.1 . 11101 1 . . @rrr_sd
+
 ### Advanced SIMD three same
 
 FADD_v  0.00 1110 010 . 00010 1 . . @qrrr_h
@@ -748,6 +763,21 @@ FMLA_v  0.00 1110 0.1 . 11001 1 . . 
@qrrr_sd
 FMLS_v  0.00 1110 110 . 1 1 . . @qrrr_h
 FMLS_v  0.00 1110 1.1 . 11001 1 . . @qrrr_sd
 
+FCMEQ_v 0.00 1110 010 . 00100 1 . . @qrrr_h
+FCMEQ_v 0.00 1110 0.1 . 11100 1 . . @qrrr_sd
+
+FCMGE_v 0.10 1110 010 . 00100 1 . . @qrrr_h
+FCMGE_v 0.10 1110 0.1 . 11100 1 . . @qrrr_sd
+
+FCMGT_v 0.10 1110 110 . 00100 1 . . @qrrr_h
+FCMGT_v 0.10 1110 1.1 . 11100 1 . . @qrrr_sd
+
+FACGE_v 0.10 1110 010 . 00101 1 . . @qrrr_h
+FACGE_v 0.10 1110 0.1 . 11101 1 . . @qrrr_sd
+
+FACGT_v 0.10 1110 110 . 00101 1 . . @qrrr_h
+FACGT_v 0.10 1110 1.1 . 11101 1 . . @qrrr_sd
+
 ### Advanced SIMD scalar x indexed element
 
 FMUL_si 0101  00 ..  1001 . 0 . .   @rrx_h
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 36aae079da..ce3f716798 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -4976,6 +4976,41 @@ static const FPScalar f_scalar_fnmul = {
 };
 TRANS(FNMUL_s, do_fp3_scalar, a, _scalar_fnmul)
 
+static const FPScalar f_scalar_fcmeq = {
+gen_helper_advsimd_ceq_f16,
+gen_helper_neon_ceq_f32,
+gen_helper_neon_ceq_f64,
+};
+TRANS(FCMEQ_s, do_fp3_scalar, a, _scalar_fcmeq)
+
+static const FPScalar f_scalar_fcmge = {
+gen_helper_advsimd_cge_f16,
+gen_helper_neon_cge_f32,
+gen_helper_neon_cge_f64,
+};
+TRANS(FCMGE_s, do_fp3_scalar, a, _scalar_fcmge)
+
+static const FPScalar f_scalar_fcmgt = {
+gen_helper_advsimd_cgt_f16,
+gen_helper_neon_cgt_f32,
+gen_helper_neon_cgt_f64,
+};
+TRANS(FCMGT_s, do_fp3_scalar, a, _scalar_fcmgt)
+
+static const FPScalar f_scalar_facge = {
+   

[PATCH 19/57] target/arm: Convert FABD to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|  1 +
 target/arm/tcg/a64.decode  |  6 
 target/arm/tcg/translate-a64.c | 60 ++
 target/arm/tcg/vec_helper.c|  6 
 4 files changed, 53 insertions(+), 20 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 8d076011c1..ff6e3094f4 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -724,6 +724,7 @@ DEF_HELPER_FLAGS_5(gvec_fmul_d, TCG_CALL_NO_RWG, void, ptr, 
ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_5(gvec_fabd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(gvec_fabd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_fabd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_5(gvec_fceq_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(gvec_fceq_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 94d35733df..6aa6643d19 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -728,6 +728,9 @@ FACGE_s 0111 1110 0.1 . 11101 1 . . 
@rrr_sd
 FACGT_s 0111 1110 110 . 00101 1 . . @rrr_h
 FACGT_s 0111 1110 1.1 . 11101 1 . . @rrr_sd
 
+FABD_s  0111 1110 110 . 00010 1 . . @rrr_h
+FABD_s  0111 1110 1.1 . 11010 1 . . @rrr_sd
+
 ### Advanced SIMD three same
 
 FADD_v  0.00 1110 010 . 00010 1 . . @qrrr_h
@@ -778,6 +781,9 @@ FACGE_v 0.10 1110 0.1 . 11101 1 . . 
@qrrr_sd
 FACGT_v 0.10 1110 110 . 00101 1 . . @qrrr_h
 FACGT_v 0.10 1110 1.1 . 11101 1 . . @qrrr_sd
 
+FABD_v  0.10 1110 110 . 00010 1 . . @qrrr_h
+FABD_v  0.10 1110 1.1 . 11010 1 . . @qrrr_sd
+
 ### Advanced SIMD scalar x indexed element
 
 FMUL_si 0101  00 ..  1001 . 0 . .   @rrx_h
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index ce3f716798..5f5f62c907 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5011,6 +5011,31 @@ static const FPScalar f_scalar_facgt = {
 };
 TRANS(FACGT_s, do_fp3_scalar, a, _scalar_facgt)
 
+static void gen_fabd_h(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, TCGv_ptr s)
+{
+gen_helper_vfp_subh(d, n, m, s);
+gen_vfp_absh(d, d);
+}
+
+static void gen_fabd_s(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, TCGv_ptr s)
+{
+gen_helper_vfp_subs(d, n, m, s);
+gen_vfp_abss(d, d);
+}
+
+static void gen_fabd_d(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_ptr s)
+{
+gen_helper_vfp_subd(d, n, m, s);
+gen_vfp_absd(d, d);
+}
+
+static const FPScalar f_scalar_fabd = {
+gen_fabd_h,
+gen_fabd_s,
+gen_fabd_d,
+};
+TRANS(FABD_s, do_fp3_scalar, a, _scalar_fabd)
+
 static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a,
   gen_helper_gvec_3_ptr * const fns[3])
 {
@@ -5151,6 +5176,13 @@ static gen_helper_gvec_3_ptr * const f_vector_facgt[3] = 
{
 };
 TRANS(FACGT_v, do_fp3_vector, a, f_vector_facgt)
 
+static gen_helper_gvec_3_ptr * const f_vector_fabd[3] = {
+gen_helper_gvec_fabd_h,
+gen_helper_gvec_fabd_s,
+gen_helper_gvec_fabd_d,
+};
+TRANS(FABD_v, do_fp3_vector, a, f_vector_fabd)
+
 /*
  * Advanced SIMD scalar/vector x indexed element
  */
@@ -9297,10 +9329,6 @@ static void handle_3same_float(DisasContext *s, int 
size, int elements,
 case 0x3f: /* FRSQRTS */
 gen_helper_rsqrtsf_f64(tcg_res, tcg_op1, tcg_op2, fpst);
 break;
-case 0x7a: /* FABD */
-gen_helper_vfp_subd(tcg_res, tcg_op1, tcg_op2, fpst);
-gen_vfp_absd(tcg_res, tcg_res);
-break;
 default:
 case 0x18: /* FMAXNM */
 case 0x19: /* FMLA */
@@ -9316,6 +9344,7 @@ static void handle_3same_float(DisasContext *s, int size, 
int elements,
 case 0x5c: /* FCMGE */
 case 0x5d: /* FACGE */
 case 0x5f: /* FDIV */
+case 0x7a: /* FABD */
 case 0x7c: /* FCMGT */
 case 0x7d: /* FACGT */
 g_assert_not_reached();
@@ -9338,10 +9367,6 @@ static void handle_3same_float(DisasContext *s, int 
size, int elements,
 case 0x3f: /* FRSQRTS */
 gen_helper_rsqrtsf_f32(tcg_res, tcg_op1, tcg_op2, fpst);
 break;
-case 0x7a: /* FABD */
-gen_helper_vfp_subs(tcg_res, tcg_op1, tcg_op2, fpst);
-gen_vfp_abss(tcg_res, tcg_res);
-break;
 default:
 case 0x18: /* FMAXNM */
 case 0x19: /* FMLA */
@@ -9357,6 +9382,7 @@ static void handle_3same_float(DisasContext *s, int size, 
int elements,
 case 0x5c: /* FCMGE */
 case 0x5d: /* FACGE */
 case 0x5f: /* FDIV */
+

[PATCH 35/57] target/arm: Convert SUQADD, USQADD to decodetree

2024-05-05 Thread Richard Henderson
These are faux 2-operand instructions, reading from rd.
Sort them next to the other three-operand same insns for clarity.

Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  8 +
 target/arm/tcg/translate-a64.c | 64 --
 2 files changed, 14 insertions(+), 58 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 5eced906a9..7cea0d2721 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -45,6 +45,7 @@
 @rrr_sd  ... rm:5 .. rn:5 rd:5  _e esz=%esz_sd
 @rrr_hsd ... rm:5 .. rn:5 rd:5  _e esz=%esz_hsd
 @rrr_e   esz:2 . rm:5 .. rn:5 rd:5  _e
+@r2r_e   esz:2 . . .. rm:5 rd:5 _e rn=%rd
 
 @rrx_h   .. .. rm:4  . . rn:5 rd:5  _e esz=1 idx=%hlm
 @rrx_s   .. . rm:5   . . rn:5 rd:5  _e esz=2 idx=%hl
@@ -60,6 +61,7 @@
 @qrrr_h . q:1 .. ... rm:5 .. rn:5 rd:5  _e esz=1
 @qrrr_sd. q:1 .. ... rm:5 .. rn:5 rd:5  _e esz=%esz_sd
 @qrrr_e . q:1 .. esz:2 . rm:5 .. rn:5 rd:5  _e
+@qr2r_e . q:1 .. esz:2 . . .. rm:5 rd:5 _e rn=%rd
 
 @qrrx_h . q:1 ..  .. .. rm:4  . . rn:5 rd:5 \
 _e esz=1 idx=%hlm
@@ -750,6 +752,9 @@ UQADD_s 0111 1110 ..1 . 1 1 . . 
@rrr_e
 SQSUB_s 0101 1110 ..1 . 00101 1 . . @rrr_e
 UQSUB_s 0111 1110 ..1 . 00101 1 . . @rrr_e
 
+SUQADD_s0101 1110 ..1 0 00111 0 . . @r2r_e
+USQADD_s0111 1110 ..1 0 00111 0 . . @r2r_e
+
 ### Advanced SIMD scalar pairwise
 
 FADDP_s 0101 1110 0011  1101 10 . . @rr_h
@@ -868,6 +873,9 @@ UQADD_v 0.10 1110 ..1 . 1 1 . . 
@qrrr_e
 SQSUB_v 0.00 1110 ..1 . 00101 1 . . @qrrr_e
 UQSUB_v 0.10 1110 ..1 . 00101 1 . . @qrrr_e
 
+SUQADD_v0.00 1110 ..1 0 00111 0 . . @qr2r_e
+USQADD_v0.10 1110 ..1 0 00111 0 . . @qr2r_e
+
 ### Advanced SIMD scalar x indexed element
 
 FMUL_si 0101  00 ..  1001 . 0 . .   @rrx_h
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 5d91263ebb..ccc30d61f3 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5097,6 +5097,8 @@ TRANS(SQADD_s, do_satacc_s, a, MO_SIGN, MO_SIGN, 
gen_sqadd_bhs, gen_sqadd_d)
 TRANS(SQSUB_s, do_satacc_s, a, MO_SIGN, MO_SIGN, gen_sqsub_bhs, gen_sqsub_d)
 TRANS(UQADD_s, do_satacc_s, a, 0, 0, gen_uqadd_bhs, gen_uqadd_d)
 TRANS(UQSUB_s, do_satacc_s, a, 0, 0, gen_uqsub_bhs, gen_uqsub_d)
+TRANS(SUQADD_s, do_satacc_s, a, MO_SIGN, 0, gen_suqadd_bhs, gen_suqadd_d)
+TRANS(USQADD_s, do_satacc_s, a, 0, MO_SIGN, gen_usqadd_bhs, gen_usqadd_d)
 
 static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a,
   gen_helper_gvec_3_ptr * const fns[3])
@@ -5340,6 +5342,8 @@ TRANS(SQADD_v, do_gvec_fn3, a, gen_gvec_sqadd_qc)
 TRANS(UQADD_v, do_gvec_fn3, a, gen_gvec_uqadd_qc)
 TRANS(SQSUB_v, do_gvec_fn3, a, gen_gvec_sqsub_qc)
 TRANS(UQSUB_v, do_gvec_fn3, a, gen_gvec_uqsub_qc)
+TRANS(SUQADD_v, do_gvec_fn3, a, gen_gvec_suqadd_qc)
+TRANS(USQADD_v, do_gvec_fn3, a, gen_gvec_usqadd_qc)
 
 /*
  * Advanced SIMD scalar/vector x indexed element
@@ -10003,48 +10007,6 @@ static void handle_2misc_narrow(DisasContext *s, bool 
scalar,
 clear_vec_high(s, is_q, rd);
 }
 
-/* Remaining saturating accumulating ops */
-static void handle_2misc_satacc(DisasContext *s, bool is_scalar, bool is_u,
-bool is_q, unsigned size, int rn, int rd)
-{
-TCGv_i64 res, qc, a, b;
-
-if (!is_scalar) {
-gen_gvec_fn3(s, is_q, rd, rd, rn,
- is_u ? gen_gvec_usqadd_qc : gen_gvec_suqadd_qc, size);
-return;
-}
-
-res = tcg_temp_new_i64();
-qc = tcg_temp_new_i64();
-a = tcg_temp_new_i64();
-b = tcg_temp_new_i64();
-
-/* Read and extend scalar inputs to 64-bits. */
-read_vec_element(s, a, rd, 0, size | (is_u ? 0 : MO_SIGN));
-read_vec_element(s, b, rn, 0, size | (is_u ? MO_SIGN : 0));
-tcg_gen_ld_i64(qc, tcg_env, offsetof(CPUARMState, vfp.qc));
-
-if (size == MO_64) {
-if (is_u) {
-gen_usqadd_d(res, qc, a, b);
-} else {
-gen_suqadd_d(res, qc, a, b);
-}
-} else {
-if (is_u) {
-gen_usqadd_bhs(res, qc, a, b, size);
-} else {
-gen_suqadd_bhs(res, qc, a, b, size);
-/* Truncate signed 64-bit result for writeback. */
-tcg_gen_ext_i64(res, res, size);
-}
-}
-
-write_fp_dreg(s, rd, res);
-tcg_gen_st_i64(qc, tcg_env, offsetof(CPUARMState, vfp.qc));
-}
-
 /* AdvSIMD scalar two reg misc
  *  31 30  29 28   24 23  22 21   17 1612 11 10 95 40
  * 

[PATCH 45/57] target/arm: Use TCG_COND_TSTNE in gen_cmtst_{i32,i64}

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/gengvec.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c
index 51e66ccf5f..1d6bc6021d 100644
--- a/target/arm/tcg/gengvec.c
+++ b/target/arm/tcg/gengvec.c
@@ -933,14 +933,12 @@ void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 /* CMTST : test is "if (X & Y != 0)". */
 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
 {
-tcg_gen_and_i32(d, a, b);
-tcg_gen_negsetcond_i32(TCG_COND_NE, d, d, tcg_constant_i32(0));
+tcg_gen_negsetcond_i32(TCG_COND_TSTNE, d, a, b);
 }
 
 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
 {
-tcg_gen_and_i64(d, a, b);
-tcg_gen_negsetcond_i64(TCG_COND_NE, d, d, tcg_constant_i64(0));
+tcg_gen_negsetcond_i64(TCG_COND_TSTNE, d, a, b);
 }
 
 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
-- 
2.34.1




[PATCH 46/57] target/arm: Convert SHADD, UHADD to gvec

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h |   6 --
 target/arm/tcg/translate.h  |   5 ++
 target/arm/tcg/gengvec.c| 144 
 target/arm/tcg/neon_helper.c|  27 --
 target/arm/tcg/translate-a64.c  |  17 ++--
 target/arm/tcg/translate-neon.c |   4 +-
 6 files changed, 158 insertions(+), 45 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 9a89c9cea7..b26bfcb079 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -268,12 +268,6 @@ DEF_HELPER_FLAGS_2(fjcvtzs, TCG_CALL_NO_RWG, i64, f64, ptr)
 DEF_HELPER_FLAGS_3(check_hcr_el2_trap, TCG_CALL_NO_WG, void, env, i32, i32)
 
 /* neon_helper.c */
-DEF_HELPER_2(neon_hadd_s8, i32, i32, i32)
-DEF_HELPER_2(neon_hadd_u8, i32, i32, i32)
-DEF_HELPER_2(neon_hadd_s16, i32, i32, i32)
-DEF_HELPER_2(neon_hadd_u16, i32, i32, i32)
-DEF_HELPER_2(neon_hadd_s32, s32, s32, s32)
-DEF_HELPER_2(neon_hadd_u32, i32, i32, i32)
 DEF_HELPER_2(neon_rhadd_s8, i32, i32, i32)
 DEF_HELPER_2(neon_rhadd_u8, i32, i32, i32)
 DEF_HELPER_2(neon_rhadd_s16, i32, i32, i32)
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index 048cb45ebe..dd99d76bf2 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -472,6 +472,11 @@ void gen_neon_sqrshl(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 void gen_neon_uqrshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
  uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
 
+void gen_gvec_shadd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_uhadd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+
 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
 void gen_ushl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
 void gen_sshl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c
index 1d6bc6021d..e59deec2d9 100644
--- a/target/arm/tcg/gengvec.c
+++ b/target/arm/tcg/gengvec.c
@@ -1854,3 +1854,147 @@ void gen_gvec_uminp(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 tcg_debug_assert(vece <= MO_32);
 tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, 0, fns[vece]);
 }
+
+static void gen_shadd8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_and_i64(t, a, b);
+tcg_gen_vec_sar8i_i64(a, a, 1);
+tcg_gen_vec_sar8i_i64(b, b, 1);
+tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
+tcg_gen_vec_add8_i64(d, a, b);
+tcg_gen_vec_add8_i64(d, d, t);
+}
+
+static void gen_shadd16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_and_i64(t, a, b);
+tcg_gen_vec_sar16i_i64(a, a, 1);
+tcg_gen_vec_sar16i_i64(b, b, 1);
+tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
+tcg_gen_vec_add16_i64(d, a, b);
+tcg_gen_vec_add16_i64(d, d, t);
+}
+
+static void gen_shadd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
+{
+TCGv_i32 t = tcg_temp_new_i32();
+
+tcg_gen_and_i32(t, a, b);
+tcg_gen_sari_i32(a, a, 1);
+tcg_gen_sari_i32(b, b, 1);
+tcg_gen_andi_i32(t, t, 1);
+tcg_gen_add_i32(d, a, b);
+tcg_gen_add_i32(d, d, t);
+}
+
+static void gen_shadd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
+{
+TCGv_vec t = tcg_temp_new_vec_matching(d);
+
+tcg_gen_and_vec(vece, t, a, b);
+tcg_gen_sari_vec(vece, a, a, 1);
+tcg_gen_sari_vec(vece, b, b, 1);
+tcg_gen_and_vec(vece, t, t, tcg_constant_vec_matching(d, vece, 1));
+tcg_gen_add_vec(vece, d, a, b);
+tcg_gen_add_vec(vece, d, d, t);
+}
+
+void gen_gvec_shadd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static const TCGOpcode vecop_list[] = {
+INDEX_op_sari_vec, INDEX_op_add_vec, 0
+};
+static const GVecGen3 g[] = {
+{ .fni8 = gen_shadd8_i64,
+  .fniv = gen_shadd_vec,
+  .opt_opc = vecop_list,
+  .vece = MO_8 },
+{ .fni8 = gen_shadd16_i64,
+  .fniv = gen_shadd_vec,
+  .opt_opc = vecop_list,
+  .vece = MO_16 },
+{ .fni4 = gen_shadd_i32,
+  .fniv = gen_shadd_vec,
+  .opt_opc = vecop_list,
+  .vece = MO_32 },
+};
+tcg_debug_assert(vece <= MO_32);
+tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, [vece]);
+}
+
+static void gen_uhadd8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_and_i64(t, a, b);
+tcg_gen_vec_shr8i_i64(a, a, 1);
+tcg_gen_vec_shr8i_i64(b, b, 1);
+tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
+tcg_gen_vec_add8_i64(d, a, b);
+tcg_gen_vec_add8_i64(d, d, t);
+}
+
+static void gen_uhadd16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_and_i64(t, a, b);
+

[PATCH 56/57] target/arm: Tidy SQDMULH, SQRDMULH (vector)

2024-05-05 Thread Richard Henderson
We already have a gvec helper for the operations, but we aren't
using it on the aa32 neon side.  Create a unified expander for
use by both aa32 and aa64 translators.

Signed-off-by: Richard Henderson 
---
 target/arm/tcg/translate.h  |  4 
 target/arm/tcg/gengvec.c| 20 
 target/arm/tcg/translate-a64.c  | 23 ---
 target/arm/tcg/translate-neon.c | 23 +++
 4 files changed, 31 insertions(+), 39 deletions(-)

diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index 3b1e68b779..aba21f730f 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -539,6 +539,10 @@ void gen_gvec_sri(unsigned vece, uint32_t rd_ofs, uint32_t 
rm_ofs,
 void gen_gvec_sli(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
   int64_t shift, uint32_t opr_sz, uint32_t max_sz);
 
+void gen_gvec_sqdmulh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_sqrdmulh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+  uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
 void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
   uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
 void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c
index a4133bf5f8..beedf46184 100644
--- a/target/arm/tcg/gengvec.c
+++ b/target/arm/tcg/gengvec.c
@@ -34,6 +34,26 @@ static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t 
rn_ofs, uint32_t rm_ofs,
opr_sz, max_sz, 0, fn);
 }
 
+void gen_gvec_sqdmulh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static gen_helper_gvec_3_ptr * const fns[2] = {
+gen_helper_neon_sqdmulh_h, gen_helper_neon_sqdmulh_s
+};
+tcg_debug_assert(vece >= 1 && vece <= 2);
+gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
+}
+
+void gen_gvec_sqrdmulh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static gen_helper_gvec_3_ptr * const fns[2] = {
+gen_helper_neon_sqrdmulh_h, gen_helper_neon_sqrdmulh_s
+};
+tcg_debug_assert(vece >= 1 && vece <= 2);
+gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
+}
+
 void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
   uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
 {
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index c217522b2b..0d8aba7a88 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -725,19 +725,6 @@ static void gen_gvec_op3_fpst(DisasContext *s, bool is_q, 
int rd, int rn,
is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
 }
 
-/* Expand a 3-operand + qc + operation using an out-of-line helper.  */
-static void gen_gvec_op3_qc(DisasContext *s, bool is_q, int rd, int rn,
-int rm, gen_helper_gvec_3_ptr *fn)
-{
-TCGv_ptr qc_ptr = tcg_temp_new_ptr();
-
-tcg_gen_addi_ptr(qc_ptr, tcg_env, offsetof(CPUARMState, vfp.qc));
-tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
-   vec_full_reg_offset(s, rn),
-   vec_full_reg_offset(s, rm), qc_ptr,
-   is_q ? 16 : 8, vec_full_reg_size(s), 0, fn);
-}
-
 /* Expand a 4-operand operation using an out-of-line helper.  */
 static void gen_gvec_op4_ool(DisasContext *s, bool is_q, int rd, int rn,
  int rm, int ra, int data, gen_helper_gvec_4 *fn)
@@ -11001,12 +10988,10 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 
 switch (opcode) {
 case 0x16: /* SQDMULH, SQRDMULH */
-{
-static gen_helper_gvec_3_ptr * const fns[2][2] = {
-{ gen_helper_neon_sqdmulh_h, gen_helper_neon_sqrdmulh_h },
-{ gen_helper_neon_sqdmulh_s, gen_helper_neon_sqrdmulh_s },
-};
-gen_gvec_op3_qc(s, is_q, rd, rn, rm, fns[size - 1][u]);
+if (u) {
+gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqrdmulh_qc, size);
+} else {
+gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sqdmulh_qc, size);
 }
 return;
 }
diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c
index f9a8753906..915c9e56db 100644
--- a/target/arm/tcg/translate-neon.c
+++ b/target/arm/tcg/translate-neon.c
@@ -937,28 +937,11 @@ DO_SHA2(SHA256SU1, gen_helper_crypto_sha256su1)
 }
 
 #define DO_3SAME_VQDMULH(INSN, FUNC)\
-WRAP_ENV_FN(gen_##INSN##_tramp16, gen_helper_neon_##FUNC##_s16);\
-

[PATCH 55/57] target/arm: Convert MLA, MLS to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  8 
 target/arm/tcg/translate-a64.c | 77 ++
 2 files changed, 31 insertions(+), 54 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index dbeb5667fd..8f7ae63e17 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -928,6 +928,8 @@ SABA_v  0.00 1110 ..1 . 0 1 . . 
@qrrr_e
 UABA_v  0.10 1110 ..1 . 0 1 . . @qrrr_e
 MUL_v   0.00 1110 ..1 . 10011 1 . . @qrrr_e
 PMUL_v  0.10 1110 001 . 10011 1 . . @qrrr_b
+MLA_v   0.00 1110 ..1 . 10010 1 . . @qrrr_e
+MLS_v   0.10 1110 ..1 . 10010 1 . . @qrrr_e
 
 ### Advanced SIMD scalar x indexed element
 
@@ -972,3 +974,9 @@ FMLSL2_vi   0.10  10 ..  1100 . 0 . .   
@qrrx_h
 
 MUL_vi  0.00  01 ..  1000 . 0 . .   @qrrx_h
 MUL_vi  0.00  10 . . 1000 . 0 . .   @qrrx_s
+
+MLA_vi  0.10  01 ..   . 0 . .   @qrrx_h
+MLA_vi  0.10  10 . .  . 0 . .   @qrrx_s
+
+MLS_vi  0.10  01 ..  0100 . 0 . .   @qrrx_h
+MLS_vi  0.10  10 . . 0100 . 0 . .   @qrrx_s
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index cd39fa1f20..c217522b2b 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5471,6 +5471,8 @@ TRANS(SABD_v, do_gvec_fn3_no64, a, gen_gvec_sabd)
 TRANS(UABD_v, do_gvec_fn3_no64, a, gen_gvec_uabd)
 TRANS(MUL_v, do_gvec_fn3_no64, a, tcg_gen_gvec_mul)
 TRANS(PMUL_v, do_gvec_op3_ool, a, 0, gen_helper_gvec_pmul_b)
+TRANS(MLA_v, do_gvec_fn3_no64, a, gen_gvec_mla)
+TRANS(MLS_v, do_gvec_fn3_no64, a, gen_gvec_mls)
 
 static bool do_cmop_v(DisasContext *s, arg_qrrr_e *a, TCGCond cond)
 {
@@ -5713,6 +5715,24 @@ static gen_helper_gvec_3 * const f_vector_idx_mul[2] = {
 };
 TRANS(MUL_vi, do_int3_vector_idx, a, f_vector_idx_mul)
 
+static bool do_mla_vector_idx(DisasContext *s, arg_qrrx_e *a, bool sub)
+{
+static gen_helper_gvec_4 * const fns[2][2] = {
+{ gen_helper_gvec_mla_idx_h, gen_helper_gvec_mls_idx_h },
+{ gen_helper_gvec_mla_idx_s, gen_helper_gvec_mls_idx_s },
+};
+
+assert(a->esz == MO_16 || a->esz == MO_32);
+if (fp_access_check(s)) {
+gen_gvec_op4_ool(s, a->q, a->rd, a->rn, a->rm, a->rd,
+ a->idx, fns[a->esz - 1][sub]);
+}
+return true;
+}
+
+TRANS(MLA_vi, do_mla_vector_idx, a, false)
+TRANS(MLS_vi, do_mla_vector_idx, a, true)
+
 /*
  * Advanced SIMD scalar pairwise
  */
@@ -10939,12 +10959,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 int rd = extract32(insn, 0, 5);
 
 switch (opcode) {
-case 0x12: /* MLA, MLS */
-if (size == 3) {
-unallocated_encoding(s);
-return;
-}
-break;
 case 0x16: /* SQDMULH, SQRDMULH */
 if (size == 0 || size == 3) {
 unallocated_encoding(s);
@@ -10975,6 +10989,7 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 case 0x0f: /* SABA, UABA */
 case 0x10: /* ADD, SUB */
 case 0x11: /* CMTST, CMEQ */
+case 0x12: /* MLA, MLS */
 case 0x13: /* MUL, PMUL */
 unallocated_encoding(s);
 return;
@@ -10985,13 +11000,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 }
 
 switch (opcode) {
-case 0x12: /* MLA, MLS */
-if (u) {
-gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_mls, size);
-} else {
-gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_mla, size);
-}
-return;
 case 0x16: /* SQDMULH, SQRDMULH */
 {
 static gen_helper_gvec_3_ptr * const fns[2][2] = {
@@ -12198,13 +12206,6 @@ static void disas_simd_indexed(DisasContext *s, 
uint32_t insn)
 TCGv_ptr fpst;
 
 switch (16 * u + opcode) {
-case 0x10: /* MLA */
-case 0x14: /* MLS */
-if (is_scalar) {
-unallocated_encoding(s);
-return;
-}
-break;
 case 0x02: /* SMLAL, SMLAL2 */
 case 0x12: /* UMLAL, UMLAL2 */
 case 0x06: /* SMLSL, SMLSL2 */
@@ -12286,6 +12287,8 @@ static void disas_simd_indexed(DisasContext *s, 
uint32_t insn)
 case 0x05: /* FMLS */
 case 0x08: /* MUL */
 case 0x09: /* FMUL */
+case 0x10: /* MLA */
+case 0x14: /* MLS */
 case 0x18: /* FMLAL2 */
 case 0x19: /* FMULX */
 case 0x1c: /* FMLSL2 */
@@ -12406,40 +12409,6 @@ static void disas_simd_indexed(DisasContext *s, 
uint32_t insn)
: gen_helper_gvec_fcmlah_idx);
 }
 return;
-
-case 0x10: /* MLA */
-if (!is_long && !is_scalar) {
-static gen_helper_gvec_4 * const fns[3] = {
-gen_helper_gvec_mla_idx_h,
-

[PATCH 49/57] target/arm: Convert SHSUB, UHSUB to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  2 ++
 target/arm/tcg/translate-a64.c | 11 +++
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 0881f00ecf..80c4c650c9 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -914,6 +914,8 @@ CMTST_v 0.00 1110 ..1 . 10001 1 . . 
@qrrr_e
 CMEQ_v  0.10 1110 ..1 . 10001 1 . . @qrrr_e
 SHADD_v 0.00 1110 ..1 . 0 1 . . @qrrr_e
 UHADD_v 0.10 1110 ..1 . 0 1 . . @qrrr_e
+SHSUB_v 0.00 1110 ..1 . 00100 1 . . @qrrr_e
+UHSUB_v 0.10 1110 ..1 . 00100 1 . . @qrrr_e
 
 ### Advanced SIMD scalar x indexed element
 
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 0e28a5abbd..83e2c363e7 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5457,6 +5457,8 @@ TRANS(ADD_v, do_gvec_fn3, a, tcg_gen_gvec_add)
 TRANS(SUB_v, do_gvec_fn3, a, tcg_gen_gvec_sub)
 TRANS(SHADD_v, do_gvec_fn3_no64, a, gen_gvec_shadd)
 TRANS(UHADD_v, do_gvec_fn3_no64, a, gen_gvec_uhadd)
+TRANS(SHSUB_v, do_gvec_fn3_no64, a, gen_gvec_shsub)
+TRANS(UHSUB_v, do_gvec_fn3_no64, a, gen_gvec_uhsub)
 
 static bool do_cmop_v(DisasContext *s, arg_qrrr_e *a, TCGCond cond)
 {
@@ -10917,7 +10919,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 }
 /* fall through */
 case 0x2: /* SRHADD, URHADD */
-case 0x4: /* SHSUB, UHSUB */
 case 0xc: /* SMAX, UMAX */
 case 0xd: /* SMIN, UMIN */
 case 0xe: /* SABD, UABD */
@@ -10943,6 +10944,7 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 
 case 0x0: /* SHADD, UHADD */
 case 0x01: /* SQADD, UQADD */
+case 0x04: /* SHSUB, UHSUB */
 case 0x05: /* SQSUB, UQSUB */
 case 0x06: /* CMGT, CMHI */
 case 0x07: /* CMGE, CMHS */
@@ -10961,13 +10963,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 }
 
 switch (opcode) {
-case 0x04: /* SHSUB, UHSUB */
-if (u) {
-gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uhsub, size);
-} else {
-gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_shsub, size);
-}
-return;
 case 0x0c: /* SMAX, UMAX */
 if (u) {
 gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umax, size);
-- 
2.34.1




[PATCH 04/57] target/arm: Convert Cryptographic 3-register SHA to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  | 11 +
 target/arm/tcg/translate-a64.c | 78 +-
 2 files changed, 21 insertions(+), 68 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 1de09903dc..7590659ee6 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -30,6 +30,7 @@
 
 @rr_q1e0  .. rn:5 rd:5  _e q=1 esz=0
 @r2r_q1e0     .. rm:5 rd:5  _e rn=%rd q=1 
esz=0
+@rrr_q1e0    ... rm:5 .. rn:5 rd:5  _e q=1 esz=0
 
 ### Data Processing - Immediate
 
@@ -603,3 +604,13 @@ AESE01001110 00 10100 00100 10 . .  
@r2r_q1e0
 AESD01001110 00 10100 00101 10 . .  @r2r_q1e0
 AESMC   01001110 00 10100 00110 10 . .  @rr_q1e0
 AESIMC  01001110 00 10100 00111 10 . .  @rr_q1e0
+
+### Cryptographic three-register SHA
+
+SHA1C   0101 1110 000 . 00 . .  @rrr_q1e0
+SHA1P   0101 1110 000 . 000100 . .  @rrr_q1e0
+SHA1M   0101 1110 000 . 001000 . .  @rrr_q1e0
+SHA1SU0 0101 1110 000 . 001100 . .  @rrr_q1e0
+SHA256H 0101 1110 000 . 01 . .  @rrr_q1e0
+SHA256H20101 1110 000 . 010100 . .  @rrr_q1e0
+SHA256SU1   0101 1110 000 . 011000 . .  @rrr_q1e0
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 1ba6a30176..b31e70b5d3 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -4590,7 +4590,7 @@ static bool trans_EXTR(DisasContext *s, arg_extract *a)
 }
 
 /*
- * Cryptographic AES
+ * Cryptographic AES, SHA
  */
 
 TRANS_FEAT(AESE, aa64_aes, do_gvec_op3_ool, a, 0, gen_helper_crypto_aese)
@@ -4598,6 +4598,15 @@ TRANS_FEAT(AESD, aa64_aes, do_gvec_op3_ool, a, 0, 
gen_helper_crypto_aesd)
 TRANS_FEAT(AESMC, aa64_aes, do_gvec_op2_ool, a, 0, gen_helper_crypto_aesmc)
 TRANS_FEAT(AESIMC, aa64_aes, do_gvec_op2_ool, a, 0, gen_helper_crypto_aesimc)
 
+TRANS_FEAT(SHA1C, aa64_sha1, do_gvec_op3_ool, a, 0, gen_helper_crypto_sha1c)
+TRANS_FEAT(SHA1P, aa64_sha1, do_gvec_op3_ool, a, 0, gen_helper_crypto_sha1p)
+TRANS_FEAT(SHA1M, aa64_sha1, do_gvec_op3_ool, a, 0, gen_helper_crypto_sha1m)
+TRANS_FEAT(SHA1SU0, aa64_sha1, do_gvec_op3_ool, a, 0, 
gen_helper_crypto_sha1su0)
+
+TRANS_FEAT(SHA256H, aa64_sha256, do_gvec_op3_ool, a, 0, 
gen_helper_crypto_sha256h)
+TRANS_FEAT(SHA256H2, aa64_sha256, do_gvec_op3_ool, a, 0, 
gen_helper_crypto_sha256h2)
+TRANS_FEAT(SHA256SU1, aa64_sha256, do_gvec_op3_ool, a, 0, 
gen_helper_crypto_sha256su1)
+
 /* Shift a TCGv src by TCGv shift_amount, put result in dst.
  * Note that it is the caller's responsibility to ensure that the
  * shift amount is in range (ie 0..31 or 0..63) and provide the ARM
@@ -13491,72 +13500,6 @@ static void disas_simd_indexed(DisasContext *s, 
uint32_t insn)
 }
 }
 
-/* Crypto three-reg SHA
- *  31 24 23  22  21 20  16  15 1412 11 10 95 40
- * +-+--+---+--+---++-+--+--+
- * | 0 1 0 1 1 1 1 0 | size | 0 |  Rm  | 0 | opcode | 0 0 |  Rn  |  Rd  |
- * +-+--+---+--+---++-+--+--+
- */
-static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
-{
-int size = extract32(insn, 22, 2);
-int opcode = extract32(insn, 12, 3);
-int rm = extract32(insn, 16, 5);
-int rn = extract32(insn, 5, 5);
-int rd = extract32(insn, 0, 5);
-gen_helper_gvec_3 *genfn;
-bool feature;
-
-if (size != 0) {
-unallocated_encoding(s);
-return;
-}
-
-switch (opcode) {
-case 0: /* SHA1C */
-genfn = gen_helper_crypto_sha1c;
-feature = dc_isar_feature(aa64_sha1, s);
-break;
-case 1: /* SHA1P */
-genfn = gen_helper_crypto_sha1p;
-feature = dc_isar_feature(aa64_sha1, s);
-break;
-case 2: /* SHA1M */
-genfn = gen_helper_crypto_sha1m;
-feature = dc_isar_feature(aa64_sha1, s);
-break;
-case 3: /* SHA1SU0 */
-genfn = gen_helper_crypto_sha1su0;
-feature = dc_isar_feature(aa64_sha1, s);
-break;
-case 4: /* SHA256H */
-genfn = gen_helper_crypto_sha256h;
-feature = dc_isar_feature(aa64_sha256, s);
-break;
-case 5: /* SHA256H2 */
-genfn = gen_helper_crypto_sha256h2;
-feature = dc_isar_feature(aa64_sha256, s);
-break;
-case 6: /* SHA256SU1 */
-genfn = gen_helper_crypto_sha256su1;
-feature = dc_isar_feature(aa64_sha256, s);
-break;
-default:
-unallocated_encoding(s);
-return;
-}
-
-if (!feature) {
-unallocated_encoding(s);
-return;
-}
-
-if (!fp_access_check(s)) {
-return;
-}
-gen_gvec_op3_ool(s, true, rd, rn, rm, 0, genfn);
-}
-
 /* Crypto two-reg SHA
  * 

[PATCH 23/57] target/arm: Use gvec for neon faddp, fmaxp, fminp

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h |  7 -
 target/arm/tcg/translate-neon.c | 55 ++---
 target/arm/tcg/vec_helper.c | 45 ---
 3 files changed, 3 insertions(+), 104 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 3268477329..065460ea80 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -650,13 +650,6 @@ DEF_HELPER_FLAGS_6(gvec_fcmlas_idx, TCG_CALL_NO_RWG,
 DEF_HELPER_FLAGS_6(gvec_fcmlad, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, ptr, i32)
 
-DEF_HELPER_FLAGS_5(neon_paddh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_5(neon_pmaxh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_5(neon_pminh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_5(neon_padds, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_5(neon_pmaxs, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
-DEF_HELPER_FLAGS_5(neon_pmins, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
-
 DEF_HELPER_FLAGS_4(gvec_sstoh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_sitos, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_ustoh, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c
index 144f18ba22..2326a05a0a 100644
--- a/target/arm/tcg/translate-neon.c
+++ b/target/arm/tcg/translate-neon.c
@@ -1144,6 +1144,9 @@ DO_3S_FP_GVEC(VFMA, gen_helper_gvec_vfma_s, 
gen_helper_gvec_vfma_h)
 DO_3S_FP_GVEC(VFMS, gen_helper_gvec_vfms_s, gen_helper_gvec_vfms_h)
 DO_3S_FP_GVEC(VRECPS, gen_helper_gvec_recps_nf_s, gen_helper_gvec_recps_nf_h)
 DO_3S_FP_GVEC(VRSQRTS, gen_helper_gvec_rsqrts_nf_s, 
gen_helper_gvec_rsqrts_nf_h)
+DO_3S_FP_GVEC(VPADD, gen_helper_gvec_faddp_s, gen_helper_gvec_faddp_h)
+DO_3S_FP_GVEC(VPMAX, gen_helper_gvec_fmaxp_s, gen_helper_gvec_fmaxp_h)
+DO_3S_FP_GVEC(VPMIN, gen_helper_gvec_fminp_s, gen_helper_gvec_fminp_h)
 
 WRAP_FP_GVEC(gen_VMAXNM_fp32_3s, FPST_STD, gen_helper_gvec_fmaxnum_s)
 WRAP_FP_GVEC(gen_VMAXNM_fp16_3s, FPST_STD_F16, gen_helper_gvec_fmaxnum_h)
@@ -1180,58 +1183,6 @@ static bool trans_VMINNM_fp_3s(DisasContext *s, 
arg_3same *a)
 return do_3same(s, a, gen_VMINNM_fp32_3s);
 }
 
-static bool do_3same_fp_pair(DisasContext *s, arg_3same *a,
- gen_helper_gvec_3_ptr *fn)
-{
-/* FP pairwise operations */
-TCGv_ptr fpstatus;
-
-if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
-return false;
-}
-
-/* UNDEF accesses to D16-D31 if they don't exist. */
-if (!dc_isar_feature(aa32_simd_r32, s) &&
-((a->vd | a->vn | a->vm) & 0x10)) {
-return false;
-}
-
-if (!vfp_access_check(s)) {
-return true;
-}
-
-assert(a->q == 0); /* enforced by decode patterns */
-
-
-fpstatus = fpstatus_ptr(a->size == MO_16 ? FPST_STD_F16 : FPST_STD);
-tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
-   vfp_reg_offset(1, a->vn),
-   vfp_reg_offset(1, a->vm),
-   fpstatus, 8, 8, 0, fn);
-
-return true;
-}
-
-/*
- * For all the functions using this macro, size == 1 means fp16,
- * which is an architecture extension we don't implement yet.
- */
-#define DO_3S_FP_PAIR(INSN,FUNC)\
-static bool trans_##INSN##_fp_3s(DisasContext *s, arg_3same *a) \
-{   \
-if (a->size == MO_16) { \
-if (!dc_isar_feature(aa32_fp16_arith, s)) { \
-return false;   \
-}   \
-return do_3same_fp_pair(s, a, FUNC##h); \
-}   \
-return do_3same_fp_pair(s, a, FUNC##s); \
-}
-
-DO_3S_FP_PAIR(VPADD, gen_helper_neon_padd)
-DO_3S_FP_PAIR(VPMAX, gen_helper_neon_pmax)
-DO_3S_FP_PAIR(VPMIN, gen_helper_neon_pmin)
-
 static bool do_vector_2sh(DisasContext *s, arg_2reg_shift *a, GVecGen2iFn *fn)
 {
 /* Handle a 2-reg-shift insn which can be vectorized. */
diff --git a/target/arm/tcg/vec_helper.c b/target/arm/tcg/vec_helper.c
index 79e1fdcaa9..26a9ca9c14 100644
--- a/target/arm/tcg/vec_helper.c
+++ b/target/arm/tcg/vec_helper.c
@@ -2192,51 +2192,6 @@ DO_ABA(gvec_uaba_d, uint64_t)
 
 #undef DO_ABA
 
-#define DO_NEON_PAIRWISE(NAME, OP)  \
-void HELPER(NAME##s)(void *vd, void *vn, void *vm,  \
- void *stat, uint32_t oprsz)\
-{   \
-float_status *fpst = stat;  \
-float32 *d = vd;

[PATCH 34/57] target/arm: Convert SQADD, SQSUB, UQADD, UQSUB to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  11 
 target/arm/tcg/translate-a64.c | 100 +++--
 2 files changed, 68 insertions(+), 43 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index d0618ca794..5eced906a9 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -44,6 +44,7 @@
 @rrr_h   ... rm:5 .. rn:5 rd:5  _e esz=1
 @rrr_sd  ... rm:5 .. rn:5 rd:5  _e esz=%esz_sd
 @rrr_hsd ... rm:5 .. rn:5 rd:5  _e esz=%esz_hsd
+@rrr_e   esz:2 . rm:5 .. rn:5 rd:5  _e
 
 @rrx_h   .. .. rm:4  . . rn:5 rd:5  _e esz=1 idx=%hlm
 @rrx_s   .. . rm:5   . . rn:5 rd:5  _e esz=2 idx=%hl
@@ -744,6 +745,11 @@ FRECPS_s0101 1110 0.1 . 1 1 . . 
@rrr_sd
 FRSQRTS_s   0101 1110 110 . 00111 1 . . @rrr_h
 FRSQRTS_s   0101 1110 1.1 . 1 1 . . @rrr_sd
 
+SQADD_s 0101 1110 ..1 . 1 1 . . @rrr_e
+UQADD_s 0111 1110 ..1 . 1 1 . . @rrr_e
+SQSUB_s 0101 1110 ..1 . 00101 1 . . @rrr_e
+UQSUB_s 0111 1110 ..1 . 00101 1 . . @rrr_e
+
 ### Advanced SIMD scalar pairwise
 
 FADDP_s 0101 1110 0011  1101 10 . . @rr_h
@@ -857,6 +863,11 @@ BSL_v   0.10 1110 011 . 00011 1 . . 
@qrrr_b
 BIT_v   0.10 1110 101 . 00011 1 . . @qrrr_b
 BIF_v   0.10 1110 111 . 00011 1 . . @qrrr_b
 
+SQADD_v 0.00 1110 ..1 . 1 1 . . @qrrr_e
+UQADD_v 0.10 1110 ..1 . 1 1 . . @qrrr_e
+SQSUB_v 0.00 1110 ..1 . 00101 1 . . @qrrr_e
+UQSUB_v 0.10 1110 ..1 . 00101 1 . . @qrrr_e
+
 ### Advanced SIMD scalar x indexed element
 
 FMUL_si 0101  00 ..  1001 . 0 . .   @rrx_h
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 12235e06d8..5d91263ebb 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5061,6 +5061,43 @@ static const FPScalar f_scalar_frsqrts = {
 };
 TRANS(FRSQRTS_s, do_fp3_scalar, a, _scalar_frsqrts)
 
+static bool do_satacc_s(DisasContext *s, arg_rrr_e *a,
+MemOp sgn_n, MemOp sgn_m,
+void (*gen_bhs)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64, MemOp),
+void (*gen_d)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
+{
+TCGv_i64 t0, t1, t2, qc;
+MemOp esz = a->esz;
+
+if (!fp_access_check(s)) {
+return true;
+}
+
+t0 = tcg_temp_new_i64();
+t1 = tcg_temp_new_i64();
+t2 = tcg_temp_new_i64();
+qc = tcg_temp_new_i64();
+read_vec_element(s, t1, a->rn, 0, esz | sgn_n);
+read_vec_element(s, t2, a->rm, 0, esz | sgn_m);
+tcg_gen_ld_i64(qc, tcg_env, offsetof(CPUARMState, vfp.qc));
+
+if (esz == MO_64) {
+gen_d(t0, qc, t1, t2);
+} else {
+gen_bhs(t0, qc, t1, t2, esz);
+tcg_gen_ext_i64(t0, t0, esz);
+}
+
+write_fp_dreg(s, a->rd, t0);
+tcg_gen_st_i64(qc, tcg_env, offsetof(CPUARMState, vfp.qc));
+return true;
+}
+
+TRANS(SQADD_s, do_satacc_s, a, MO_SIGN, MO_SIGN, gen_sqadd_bhs, gen_sqadd_d)
+TRANS(SQSUB_s, do_satacc_s, a, MO_SIGN, MO_SIGN, gen_sqsub_bhs, gen_sqsub_d)
+TRANS(UQADD_s, do_satacc_s, a, 0, 0, gen_uqadd_bhs, gen_uqadd_d)
+TRANS(UQSUB_s, do_satacc_s, a, 0, 0, gen_uqsub_bhs, gen_uqsub_d)
+
 static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a,
   gen_helper_gvec_3_ptr * const fns[3])
 {
@@ -5299,6 +5336,11 @@ TRANS(BSL_v, do_bitsel, a->q, a->rd, a->rd, a->rn, a->rm)
 TRANS(BIT_v, do_bitsel, a->q, a->rd, a->rm, a->rn, a->rd)
 TRANS(BIF_v, do_bitsel, a->q, a->rd, a->rm, a->rd, a->rn)
 
+TRANS(SQADD_v, do_gvec_fn3, a, gen_gvec_sqadd_qc)
+TRANS(UQADD_v, do_gvec_fn3, a, gen_gvec_uqadd_qc)
+TRANS(SQSUB_v, do_gvec_fn3, a, gen_gvec_sqsub_qc)
+TRANS(UQSUB_v, do_gvec_fn3, a, gen_gvec_uqsub_qc)
+
 /*
  * Advanced SIMD scalar/vector x indexed element
  */
@@ -9285,29 +9327,8 @@ static void handle_3same_64(DisasContext *s, int opcode, 
bool u,
  * or scalar-three-reg-same groups.
  */
 TCGCond cond;
-TCGv_i64 qc;
 
 switch (opcode) {
-case 0x1: /* SQADD */
-qc = tcg_temp_new_i64();
-tcg_gen_ld_i64(qc, tcg_env, offsetof(CPUARMState, vfp.qc));
-if (u) {
-gen_uqadd_d(tcg_rd, qc, tcg_rn, tcg_rm);
-} else {
-gen_sqadd_d(tcg_rd, qc, tcg_rn, tcg_rm);
-}
-tcg_gen_st_i64(qc, tcg_env, offsetof(CPUARMState, vfp.qc));
-break;
-case 0x5: /* SQSUB */
-qc = tcg_temp_new_i64();
-tcg_gen_ld_i64(qc, tcg_env, offsetof(CPUARMState, vfp.qc));
-if (u) {
-gen_uqsub_d(tcg_rd, qc, tcg_rn, tcg_rm);
-} else {
-gen_sqsub_d(tcg_rd, qc, tcg_rn, tcg_rm);
-}
-

[PATCH 51/57] target/arm: Convert SRHADD, URHADD to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  2 ++
 target/arm/tcg/translate-a64.c | 11 +++
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 80c4c650c9..fc8a5ca14f 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -916,6 +916,8 @@ SHADD_v 0.00 1110 ..1 . 0 1 . . 
@qrrr_e
 UHADD_v 0.10 1110 ..1 . 0 1 . . @qrrr_e
 SHSUB_v 0.00 1110 ..1 . 00100 1 . . @qrrr_e
 UHSUB_v 0.10 1110 ..1 . 00100 1 . . @qrrr_e
+SRHADD_v0.00 1110 ..1 . 00010 1 . . @qrrr_e
+URHADD_v0.10 1110 ..1 . 00010 1 . . @qrrr_e
 
 ### Advanced SIMD scalar x indexed element
 
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 87b86b7c54..b707c6ae4d 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5459,6 +5459,8 @@ TRANS(SHADD_v, do_gvec_fn3_no64, a, gen_gvec_shadd)
 TRANS(UHADD_v, do_gvec_fn3_no64, a, gen_gvec_uhadd)
 TRANS(SHSUB_v, do_gvec_fn3_no64, a, gen_gvec_shsub)
 TRANS(UHSUB_v, do_gvec_fn3_no64, a, gen_gvec_uhsub)
+TRANS(SRHADD_v, do_gvec_fn3_no64, a, gen_gvec_srhadd)
+TRANS(URHADD_v, do_gvec_fn3_no64, a, gen_gvec_urhadd)
 
 static bool do_cmop_v(DisasContext *s, arg_qrrr_e *a, TCGCond cond)
 {
@@ -10917,7 +10919,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 return;
 }
 /* fall through */
-case 0x2: /* SRHADD, URHADD */
 case 0xc: /* SMAX, UMAX */
 case 0xd: /* SMIN, UMIN */
 case 0xe: /* SABD, UABD */
@@ -10943,6 +10944,7 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 
 case 0x0: /* SHADD, UHADD */
 case 0x01: /* SQADD, UQADD */
+case 0x02: /* SRHADD, URHADD */
 case 0x04: /* SHSUB, UHSUB */
 case 0x05: /* SQSUB, UQSUB */
 case 0x06: /* CMGT, CMHI */
@@ -10962,13 +10964,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 }
 
 switch (opcode) {
-case 0x02: /* SRHADD, URHADD */
-if (u) {
-gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_urhadd, size);
-} else {
-gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_srhadd, size);
-}
-return;
 case 0x0c: /* SMAX, UMAX */
 if (u) {
 gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umax, size);
-- 
2.34.1




[PATCH 33/57] target/arm: Inline scalar SQADD, UQADD, SQSUB, UQSUB

2024-05-05 Thread Richard Henderson
This eliminates the last uses of these neon helpers.
Incorporate the MO_64 expanders as an option to the vector expander.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|  17 
 target/arm/tcg/translate.h |  15 +++
 target/arm/tcg/gengvec.c   | 116 +++
 target/arm/tcg/neon_helper.c   | 162 -
 target/arm/tcg/translate-a64.c |  67 --
 5 files changed, 169 insertions(+), 208 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index c76158d6d3..a14c040451 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -268,23 +268,6 @@ DEF_HELPER_FLAGS_2(fjcvtzs, TCG_CALL_NO_RWG, i64, f64, ptr)
 DEF_HELPER_FLAGS_3(check_hcr_el2_trap, TCG_CALL_NO_WG, void, env, i32, i32)
 
 /* neon_helper.c */
-DEF_HELPER_FLAGS_3(neon_qadd_u8, TCG_CALL_NO_RWG, i32, env, i32, i32)
-DEF_HELPER_FLAGS_3(neon_qadd_s8, TCG_CALL_NO_RWG, i32, env, i32, i32)
-DEF_HELPER_FLAGS_3(neon_qadd_u16, TCG_CALL_NO_RWG, i32, env, i32, i32)
-DEF_HELPER_FLAGS_3(neon_qadd_s16, TCG_CALL_NO_RWG, i32, env, i32, i32)
-DEF_HELPER_FLAGS_3(neon_qadd_u32, TCG_CALL_NO_RWG, i32, env, i32, i32)
-DEF_HELPER_FLAGS_3(neon_qadd_s32, TCG_CALL_NO_RWG, i32, env, i32, i32)
-DEF_HELPER_3(neon_qsub_u8, i32, env, i32, i32)
-DEF_HELPER_3(neon_qsub_s8, i32, env, i32, i32)
-DEF_HELPER_3(neon_qsub_u16, i32, env, i32, i32)
-DEF_HELPER_3(neon_qsub_s16, i32, env, i32, i32)
-DEF_HELPER_3(neon_qsub_u32, i32, env, i32, i32)
-DEF_HELPER_3(neon_qsub_s32, i32, env, i32, i32)
-DEF_HELPER_3(neon_qadd_u64, i64, env, i64, i64)
-DEF_HELPER_3(neon_qadd_s64, i64, env, i64, i64)
-DEF_HELPER_3(neon_qsub_u64, i64, env, i64, i64)
-DEF_HELPER_3(neon_qsub_s64, i64, env, i64, i64)
-
 DEF_HELPER_2(neon_hadd_s8, i32, i32, i32)
 DEF_HELPER_2(neon_hadd_u8, i32, i32, i32)
 DEF_HELPER_2(neon_hadd_s16, i32, i32, i32)
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index 3abdbedfe5..87439dcc61 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -466,12 +466,27 @@ void gen_sshl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
 void gen_ushl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
 void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
 
+void gen_uqadd_bhs(TCGv_i64 res, TCGv_i64 qc,
+   TCGv_i64 a, TCGv_i64 b, MemOp esz);
+void gen_uqadd_d(TCGv_i64 d, TCGv_i64 q, TCGv_i64 a, TCGv_i64 b);
 void gen_gvec_uqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+
+void gen_sqadd_bhs(TCGv_i64 res, TCGv_i64 qc,
+   TCGv_i64 a, TCGv_i64 b, MemOp esz);
+void gen_sqadd_d(TCGv_i64 d, TCGv_i64 q, TCGv_i64 a, TCGv_i64 b);
 void gen_gvec_sqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+
+void gen_uqsub_bhs(TCGv_i64 res, TCGv_i64 qc,
+   TCGv_i64 a, TCGv_i64 b, MemOp esz);
+void gen_uqsub_d(TCGv_i64 d, TCGv_i64 q, TCGv_i64 a, TCGv_i64 b);
 void gen_gvec_uqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+
+void gen_sqsub_bhs(TCGv_i64 res, TCGv_i64 qc,
+   TCGv_i64 a, TCGv_i64 b, MemOp esz);
+void gen_sqsub_d(TCGv_i64 d, TCGv_i64 q, TCGv_i64 a, TCGv_i64 b);
 void gen_gvec_sqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
 
diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c
index bfe6885a01..66a514ba86 100644
--- a/target/arm/tcg/gengvec.c
+++ b/target/arm/tcg/gengvec.c
@@ -1217,6 +1217,28 @@ void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, [vece]);
 }
 
+void gen_uqadd_bhs(TCGv_i64 res, TCGv_i64 qc, TCGv_i64 a, TCGv_i64 b, MemOp 
esz)
+{
+uint64_t max = MAKE_64BIT_MASK(0, 8 << esz);
+TCGv_i64 tmp = tcg_temp_new_i64();
+
+tcg_gen_add_i64(tmp, a, b);
+tcg_gen_umin_i64(res, tmp, tcg_constant_i64(max));
+tcg_gen_xor_i64(tmp, tmp, res);
+tcg_gen_or_i64(qc, qc, tmp);
+}
+
+void gen_uqadd_d(TCGv_i64 res, TCGv_i64 qc, TCGv_i64 a, TCGv_i64 b)
+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_add_i64(t, a, b);
+tcg_gen_movcond_i64(TCG_COND_LTU, res, t, a,
+tcg_constant_i64(UINT64_MAX), t);
+tcg_gen_xor_i64(t, t, res);
+tcg_gen_or_i64(qc, qc, t);
+}
+
 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec qc,
   TCGv_vec a, TCGv_vec b)
 {
@@ -1250,6 +1272,7 @@ void gen_gvec_uqadd_qc(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
   .opt_opc = vecop_list,
   .vece = MO_32 },
 { .fniv = gen_uqadd_vec,
+  .fni8 = gen_uqadd_d,
   .fno = gen_helper_gvec_uqadd_d,
   .write_aofs = true,
   .opt_opc = vecop_list,
@@ -1259,6 +1282,41 @@ void 

[PATCH 43/57] target/arm: Convert ADD, SUB (vector) to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  6 ++
 target/arm/tcg/translate-a64.c | 34 +++---
 2 files changed, 17 insertions(+), 23 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 86279edc98..97fe1ef927 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -765,6 +765,9 @@ UQSHL_s 0111 1110 ..1 . 01001 1 . . 
@rrr_e
 SQRSHL_s0101 1110 ..1 . 01011 1 . . @rrr_e
 UQRSHL_s0111 1110 ..1 . 01011 1 . . @rrr_e
 
+ADD_s   0101 1110 111 . 1 1 . . @rrr_d
+SUB_s   0111 1110 111 . 1 1 . . @rrr_d
+
 ### Advanced SIMD scalar pairwise
 
 FADDP_s 0101 1110 0011  1101 10 . . @rr_h
@@ -895,6 +898,9 @@ UQSHL_v 0.10 1110 ..1 . 01001 1 . . 
@qrrr_e
 SQRSHL_v0.00 1110 ..1 . 01011 1 . . @qrrr_e
 UQRSHL_v0.10 1110 ..1 . 01011 1 . . @qrrr_e
 
+ADD_v   0.00 1110 ..1 . 1 1 . . @qrrr_e
+SUB_v   0.10 1110 ..1 . 1 1 . . @qrrr_e
+
 ### Advanced SIMD scalar x indexed element
 
 FMUL_si 0101  00 ..  1001 . 0 . .   @rrx_h
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index db3ba77760..9daa8fe5b0 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5119,6 +5119,8 @@ TRANS(SSHL_s, do_int3_scalar_d, a, gen_sshl_i64)
 TRANS(USHL_s, do_int3_scalar_d, a, gen_ushl_i64)
 TRANS(SRSHL_s, do_int3_scalar_d, a, gen_helper_neon_rshl_s64)
 TRANS(URSHL_s, do_int3_scalar_d, a, gen_helper_neon_rshl_u64)
+TRANS(ADD_s, do_int3_scalar_d, a, tcg_gen_add_i64)
+TRANS(SUB_s, do_int3_scalar_d, a, tcg_gen_sub_i64)
 
 typedef struct ENVScalar2 {
 NeonGenTwoOpEnvFn *gen_bhs[3];
@@ -5433,6 +5435,8 @@ TRANS(UQSHL_v, do_gvec_fn3, a, gen_neon_uqshl)
 TRANS(SQRSHL_v, do_gvec_fn3, a, gen_neon_sqrshl)
 TRANS(UQRSHL_v, do_gvec_fn3, a, gen_neon_uqrshl)
 
+TRANS(ADD_v, do_gvec_fn3, a, tcg_gen_gvec_add)
+TRANS(SUB_v, do_gvec_fn3, a, tcg_gen_gvec_sub)
 
 /*
  * Advanced SIMD scalar/vector x indexed element
@@ -9438,13 +9442,6 @@ static void handle_3same_64(DisasContext *s, int opcode, 
bool u,
 }
 gen_cmtst_i64(tcg_rd, tcg_rn, tcg_rm);
 break;
-case 0x10: /* ADD, SUB */
-if (u) {
-tcg_gen_sub_i64(tcg_rd, tcg_rn, tcg_rm);
-} else {
-tcg_gen_add_i64(tcg_rd, tcg_rn, tcg_rm);
-}
-break;
 default:
 case 0x1: /* SQADD / UQADD */
 case 0x5: /* SQSUB / UQSUB */
@@ -9452,6 +9449,7 @@ static void handle_3same_64(DisasContext *s, int opcode, 
bool u,
 case 0x9: /* SQSHL, UQSHL */
 case 0xa: /* SRSHL, URSHL */
 case 0xb: /* SQRSHL, UQRSHL */
+case 0x10: /* ADD, SUB */
 g_assert_not_reached();
 }
 }
@@ -9476,7 +9474,6 @@ static void disas_simd_scalar_three_reg_same(DisasContext 
*s, uint32_t insn)
 case 0x6: /* CMGT, CMHI */
 case 0x7: /* CMGE, CMHS */
 case 0x11: /* CMTST, CMEQ */
-case 0x10: /* ADD, SUB (vector) */
 if (size != 3) {
 unallocated_encoding(s);
 return;
@@ -9495,6 +9492,7 @@ static void disas_simd_scalar_three_reg_same(DisasContext 
*s, uint32_t insn)
 case 0x9: /* SQSHL, UQSHL */
 case 0xa: /* SRSHL, URSHL */
 case 0xb: /* SQRSHL, UQRSHL */
+case 0x10: /* ADD, SUB (vector) */
 unallocated_encoding(s);
 return;
 }
@@ -10952,6 +10950,11 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 
 case 0x01: /* SQADD, UQADD */
 case 0x05: /* SQSUB, UQSUB */
+case 0x08: /* SSHL, USHL */
+case 0x09: /* SQSHL, UQSHL */
+case 0x0a: /* SRSHL, URSHL */
+case 0x0b: /* SQRSHL, UQRSHL */
+case 0x10: /* ADD, SUB */
 unallocated_encoding(s);
 return;
 }
@@ -10989,13 +10992,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_saba, size);
 }
 return;
-case 0x10: /* ADD, SUB */
-if (u) {
-gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_sub, size);
-} else {
-gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_add, size);
-}
-return;
 case 0x13: /* MUL, PMUL */
 if (!u) { /* MUL */
 gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_mul, size);
@@ -11038,14 +11034,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
  vec_full_reg_offset(s, rm),
  is_q ? 16 : 8, vec_full_reg_size(s));
 return;
-
-case 0x01: /* SQADD, UQADD */
-case 0x05: /* SQSUB, UQSUB */
-case 0x08: /* SSHL, USHL */
-case 0x09: /* SQSHL, UQSHL */
-case 0x0a: /* SRSHL, URSHL */
-case 0x0b: /* SQRSHL, UQRSHL */
-g_assert_not_reached();
 }
 
 if (size == 

[PATCH 12/57] target/arm: Convert FMULX to decodetree

2024-05-05 Thread Richard Henderson
Convert all forms (scalar, vector, scalar indexed, vector indexed),
which allows us to remove switch table entries elsewhere.

Signed-off-by: Richard Henderson 
---
 target/arm/tcg/helper-a64.h|   8 ++
 target/arm/tcg/a64.decode  |  45 +++
 target/arm/tcg/translate-a64.c | 221 +++--
 target/arm/tcg/vec_helper.c|  39 +++---
 4 files changed, 259 insertions(+), 54 deletions(-)

diff --git a/target/arm/tcg/helper-a64.h b/target/arm/tcg/helper-a64.h
index 0518165399..b79751a717 100644
--- a/target/arm/tcg/helper-a64.h
+++ b/target/arm/tcg/helper-a64.h
@@ -132,3 +132,11 @@ DEF_HELPER_4(cpye, void, env, i32, i32, i32)
 DEF_HELPER_4(cpyfp, void, env, i32, i32, i32)
 DEF_HELPER_4(cpyfm, void, env, i32, i32, i32)
 DEF_HELPER_4(cpyfe, void, env, i32, i32, i32)
+
+DEF_HELPER_FLAGS_5(gvec_fmulx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_fmulx_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_fmulx_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+
+DEF_HELPER_FLAGS_5(gvec_fmulx_idx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, 
ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_fmulx_idx_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, 
ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_fmulx_idx_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, 
ptr, i32)
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index d5bfeae7a8..e28f58bd9a 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -20,21 +20,44 @@
 #
 
 %rd 0:5
+%esz_sd 22:1 !function=plus_2
+%hl 11:1 21:1
+%hlm11:1 20:2
 
   rn
  rd imm
 _sf rd rn imm sf
   imm
+_e  rd rn rm esz
+_e  rd rn rm idx esz
 _e  q rd rn esz
 _e q rd rn rm esz
+_e q rd rn rm idx esz
 _eq rd rn rm ra esz
 
+@rrr_h   ... rm:5 .. rn:5 rd:5  _e esz=1
+@rrr_sd  ... rm:5 .. rn:5 rd:5  _e esz=%esz_sd
+
+@rrx_h   .. .. rm:4  . . rn:5 rd:5  _e esz=1 idx=%hlm
+@rrx_s   .. . rm:5   . . rn:5 rd:5  _e esz=2 idx=%hl
+@rrx_d   .. . rm:5   idx:1 . rn:5 rd:5  _e esz=3
+
 @rr_q1e0  .. rn:5 rd:5  _e q=1 esz=0
 @r2r_q1e0     .. rm:5 rd:5  _e rn=%rd q=1 
esz=0
 @rrr_q1e0    ... rm:5 .. rn:5 rd:5  _e q=1 esz=0
 @rrr_q1e3    ... rm:5 .. rn:5 rd:5  _e q=1 esz=3
 @_q1e3   ... rm:5 . ra:5 rn:5 rd:5  _e q=1 esz=3
 
+@qrrr_h . q:1 .. ... rm:5 .. rn:5 rd:5  _e esz=1
+@qrrr_sd. q:1 .. ... rm:5 .. rn:5 rd:5  _e esz=%esz_sd
+
+@qrrx_h . q:1 ..  .. .. rm:4  . . rn:5 rd:5 \
+_e esz=1 idx=%hlm
+@qrrx_s . q:1 ..  .. . rm:5   . . rn:5 rd:5 \
+_e esz=2 idx=%hl
+@qrrx_d . q:1 ..  .. . rm:5   idx:1 . rn:5 rd:5 \
+_e esz=3
+
 ### Data Processing - Immediate
 
 # PC-rel addressing
@@ -671,3 +694,25 @@ INS_general 0 1   00 1110 000 imm:5 0 0011 1 rn:5 rd:5
 SMOV0 q:1 00 1110 000 imm:5 0 0101 1 rn:5 rd:5
 UMOV0 q:1 00 1110 000 imm:5 0 0111 1 rn:5 rd:5
 INS_element 0 1   10 1110 000 di:5  0 si:4 1 rn:5 rd:5
+
+### Advanced SIMD scalar three same
+
+FMULX_s 0101 1110 010 . 00011 1 . . @rrr_h
+FMULX_s 0101 1110 0.1 . 11011 1 . . @rrr_sd
+
+### Advanced SIMD three same
+
+FMULX_v 0.00 0111 010 . 00011 1 . . @qrrr_h
+FMULX_v 0.00 1110 0.1 . 11011 1 . . @qrrr_sd
+
+### Advanced SIMD scalar x indexed element
+
+FMULX_si0111  00 ..  1001 . 0 . .   @rrx_h
+FMULX_si0111  10 . . 1001 . 0 . .   @rrx_s
+FMULX_si0111  11 0 . 1001 . 0 . .   @rrx_d
+
+### Advanced SIMD vector x indexed element
+
+FMULX_vi0.10  00 ..  1001 . 0 . .   @qrrx_h
+FMULX_vi0.10  10 . . 1001 . 0 . .   @qrrx_s
+FMULX_vi0.10  11 0 . 1001 . 0 . .   @qrrx_d
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 4860b59d18..33da0c5f0f 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -4842,6 +4842,178 @@ static bool trans_INS_element(DisasContext *s, 
arg_INS_element *a)
 return true;
 }
 
+/*
+ * Advanced SIMD three same
+ */
+
+typedef struct FPScalar {
+void (*gen_h)(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
+void (*gen_s)(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
+void (*gen_d)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
+} FPScalar;
+
+static bool do_fp3_scalar(DisasContext *s, arg_rrr_e *a, const FPScalar *f)
+{
+switch (a->esz) {
+case MO_64:
+if (fp_access_check(s)) {
+TCGv_i64 t0 = read_fp_dreg(s, a->rn);
+TCGv_i64 t1 = 

[PATCH 01/57] target/arm: Split out gengvec.c

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/translate.h |5 +
 target/arm/tcg/gengvec.c   | 1612 
 target/arm/tcg/translate.c | 1588 ---
 target/arm/tcg/meson.build |1 +
 4 files changed, 1618 insertions(+), 1588 deletions(-)
 create mode 100644 target/arm/tcg/gengvec.c

diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index dc66ff2190..80e85096a8 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -445,6 +445,11 @@ void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, 
uint32_t rm_ofs,
 void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
int64_t shift, uint32_t opr_sz, uint32_t max_sz);
 
+void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh);
+void gen_srshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh);
+void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh);
+void gen_urshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh);
+
 void gen_gvec_srshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
 int64_t shift, uint32_t opr_sz, uint32_t max_sz);
 void gen_gvec_urshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c
new file mode 100644
index 00..7a1856253f
--- /dev/null
+++ b/target/arm/tcg/gengvec.c
@@ -0,0 +1,1612 @@
+/*
+ *  ARM generic vector expansion
+ *
+ *  Copyright (c) 2003 Fabrice Bellard
+ *  Copyright (c) 2005-2007 CodeSourcery
+ *  Copyright (c) 2007 OpenedHand, Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "translate.h"
+
+
+static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs,
+uint32_t opr_sz, uint32_t max_sz,
+gen_helper_gvec_3_ptr *fn)
+{
+TCGv_ptr qc_ptr = tcg_temp_new_ptr();
+
+tcg_gen_addi_ptr(qc_ptr, tcg_env, offsetof(CPUARMState, vfp.qc));
+tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, qc_ptr,
+   opr_sz, max_sz, 0, fn);
+}
+
+void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+  uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static gen_helper_gvec_3_ptr * const fns[2] = {
+gen_helper_gvec_qrdmlah_s16, gen_helper_gvec_qrdmlah_s32
+};
+tcg_debug_assert(vece >= 1 && vece <= 2);
+gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
+}
+
+void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+  uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static gen_helper_gvec_3_ptr * const fns[2] = {
+gen_helper_gvec_qrdmlsh_s16, gen_helper_gvec_qrdmlsh_s32
+};
+tcg_debug_assert(vece >= 1 && vece <= 2);
+gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
+}
+
+#define GEN_CMP0(NAME, COND)  \
+void NAME(unsigned vece, uint32_t d, uint32_t m,  \
+  uint32_t opr_sz, uint32_t max_sz)   \
+{ tcg_gen_gvec_cmpi(COND, vece, d, m, 0, opr_sz, max_sz); }
+
+GEN_CMP0(gen_gvec_ceq0, TCG_COND_EQ)
+GEN_CMP0(gen_gvec_cle0, TCG_COND_LE)
+GEN_CMP0(gen_gvec_cge0, TCG_COND_GE)
+GEN_CMP0(gen_gvec_clt0, TCG_COND_LT)
+GEN_CMP0(gen_gvec_cgt0, TCG_COND_GT)
+
+#undef GEN_CMP0
+
+static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+tcg_gen_vec_sar8i_i64(a, a, shift);
+tcg_gen_vec_add8_i64(d, d, a);
+}
+
+static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+tcg_gen_vec_sar16i_i64(a, a, shift);
+tcg_gen_vec_add16_i64(d, d, a);
+}
+
+static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
+{
+tcg_gen_sari_i32(a, a, shift);
+tcg_gen_add_i32(d, d, a);
+}
+
+static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
+{
+tcg_gen_sari_i64(a, a, shift);
+tcg_gen_add_i64(d, d, a);
+}
+
+static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
+{
+tcg_gen_sari_vec(vece, a, a, sh);
+tcg_gen_add_vec(vece, d, d, a);
+}
+
+void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
+   int64_t shift, uint32_t opr_sz, uint32_t max_sz)
+{
+static const TCGOpcode vecop_list[] = {
+INDEX_op_sari_vec, INDEX_op_add_vec, 0
+

[PATCH 50/57] target/arm: Convert SRHADD, URHADD to gvec

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h |   7 --
 target/arm/tcg/translate.h  |   4 +
 target/arm/tcg/gengvec.c| 144 
 target/arm/tcg/neon_helper.c|  27 --
 target/arm/tcg/translate-a64.c  |  48 ++-
 target/arm/tcg/translate-neon.c |  26 +-
 6 files changed, 158 insertions(+), 98 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index b95f24ed0a..85f9302563 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -268,13 +268,6 @@ DEF_HELPER_FLAGS_2(fjcvtzs, TCG_CALL_NO_RWG, i64, f64, ptr)
 DEF_HELPER_FLAGS_3(check_hcr_el2_trap, TCG_CALL_NO_WG, void, env, i32, i32)
 
 /* neon_helper.c */
-DEF_HELPER_2(neon_rhadd_s8, i32, i32, i32)
-DEF_HELPER_2(neon_rhadd_u8, i32, i32, i32)
-DEF_HELPER_2(neon_rhadd_s16, i32, i32, i32)
-DEF_HELPER_2(neon_rhadd_u16, i32, i32, i32)
-DEF_HELPER_2(neon_rhadd_s32, s32, s32, s32)
-DEF_HELPER_2(neon_rhadd_u32, i32, i32, i32)
-
 DEF_HELPER_2(neon_pmin_u8, i32, i32, i32)
 DEF_HELPER_2(neon_pmin_s8, i32, i32, i32)
 DEF_HELPER_2(neon_pmin_u16, i32, i32, i32)
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index 315e0afd04..3b1e68b779 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -480,6 +480,10 @@ void gen_gvec_shsub(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
 void gen_gvec_uhsub(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_srhadd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_urhadd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
 
 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
 void gen_ushl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c
index b82de576d2..a4133bf5f8 100644
--- a/target/arm/tcg/gengvec.c
+++ b/target/arm/tcg/gengvec.c
@@ -2142,3 +2142,147 @@ void gen_gvec_uhsub(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 assert(vece <= MO_32);
 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, [vece]);
 }
+
+static void gen_srhadd8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_or_i64(t, a, b);
+tcg_gen_vec_sar8i_i64(a, a, 1);
+tcg_gen_vec_sar8i_i64(b, b, 1);
+tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
+tcg_gen_vec_add8_i64(d, a, b);
+tcg_gen_vec_add8_i64(d, d, t);
+}
+
+static void gen_srhadd16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_or_i64(t, a, b);
+tcg_gen_vec_sar16i_i64(a, a, 1);
+tcg_gen_vec_sar16i_i64(b, b, 1);
+tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
+tcg_gen_vec_add16_i64(d, a, b);
+tcg_gen_vec_add16_i64(d, d, t);
+}
+
+static void gen_srhadd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
+{
+TCGv_i32 t = tcg_temp_new_i32();
+
+tcg_gen_or_i32(t, a, b);
+tcg_gen_sari_i32(a, a, 1);
+tcg_gen_sari_i32(b, b, 1);
+tcg_gen_andi_i32(t, t, 1);
+tcg_gen_add_i32(d, a, b);
+tcg_gen_add_i32(d, d, t);
+}
+
+static void gen_srhadd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
+{
+TCGv_vec t = tcg_temp_new_vec_matching(d);
+
+tcg_gen_or_vec(vece, t, a, b);
+tcg_gen_sari_vec(vece, a, a, 1);
+tcg_gen_sari_vec(vece, b, b, 1);
+tcg_gen_and_vec(vece, t, t, tcg_constant_vec_matching(d, vece, 1));
+tcg_gen_add_vec(vece, d, a, b);
+tcg_gen_add_vec(vece, d, d, t);
+}
+
+void gen_gvec_srhadd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static const TCGOpcode vecop_list[] = {
+INDEX_op_sari_vec, INDEX_op_add_vec, 0
+};
+static const GVecGen3 g[] = {
+{ .fni8 = gen_srhadd8_i64,
+  .fniv = gen_srhadd_vec,
+  .opt_opc = vecop_list,
+  .vece = MO_8 },
+{ .fni8 = gen_srhadd16_i64,
+  .fniv = gen_srhadd_vec,
+  .opt_opc = vecop_list,
+  .vece = MO_16 },
+{ .fni4 = gen_srhadd_i32,
+  .fniv = gen_srhadd_vec,
+  .opt_opc = vecop_list,
+  .vece = MO_32 },
+};
+assert(vece <= MO_32);
+tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, [vece]);
+}
+
+static void gen_urhadd8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_or_i64(t, a, b);
+tcg_gen_vec_shr8i_i64(a, a, 1);
+tcg_gen_vec_shr8i_i64(b, b, 1);
+tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
+tcg_gen_vec_add8_i64(d, a, b);
+tcg_gen_vec_add8_i64(d, d, t);
+}
+
+static void gen_urhadd16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_or_i64(t, a, 

[PATCH 41/57] target/arm: Convert SQRSHL and UQRSHL (register) to gvec

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h |  8 ++
 target/arm/tcg/translate.h  |  4 +++
 target/arm/tcg/neon-dp.decode   | 17 ++--
 target/arm/tcg/gengvec.c| 24 
 target/arm/tcg/neon_helper.c| 24 
 target/arm/tcg/translate-a64.c  | 17 +---
 target/arm/tcg/translate-neon.c | 49 ++---
 7 files changed, 71 insertions(+), 72 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index f345087ddb..9a89c9cea7 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -334,6 +334,14 @@ DEF_HELPER_FLAGS_5(neon_uqshl_b, TCG_CALL_NO_RWG, void, 
ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(neon_uqshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 DEF_HELPER_FLAGS_5(neon_uqshl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 DEF_HELPER_FLAGS_5(neon_uqshl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(neon_sqrshl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(neon_sqrshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(neon_sqrshl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(neon_sqrshl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(neon_uqrshl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(neon_uqrshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(neon_uqrshl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(neon_uqrshl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 
 DEF_HELPER_FLAGS_4(gvec_srshl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_srshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index 6c6d4d49e7..048cb45ebe 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -467,6 +467,10 @@ void gen_neon_sqshl(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
 void gen_neon_uqshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_neon_sqrshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_neon_uqrshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
 
 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
 void gen_ushl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
diff --git a/target/arm/tcg/neon-dp.decode b/target/arm/tcg/neon-dp.decode
index 6d4996b8d8..788578c8fa 100644
--- a/target/arm/tcg/neon-dp.decode
+++ b/target/arm/tcg/neon-dp.decode
@@ -102,25 +102,12 @@ VCGE_U_3s 001 1 0 . ..   0011 . . . 1 
 @3same
 
 VSHL_S_3s 001 0 0 . ..   0100 . . . 0  @3same_rev
 VSHL_U_3s 001 1 0 . ..   0100 . . . 0  @3same_rev
-
-# Insns operating on 64-bit elements (size!=0b11 handled elsewhere)
-# The _rev suffix indicates that Vn and Vm are reversed (as explained
-# by the comment for the @3same_rev format).
-@3same_64_rev ... . . . 11    . q:1 . .  \
- &3same vm=%vn_dp vn=%vm_dp vd=%vd_dp size=3
-
 VQSHL_S_3s    001 0 0 . ..   0100 . . . 1  @3same_rev
 VQSHL_U_3s    001 1 0 . ..   0100 . . . 1  @3same_rev
 VRSHL_S_3s    001 0 0 . ..   0101 . . . 0  @3same_rev
 VRSHL_U_3s    001 1 0 . ..   0101 . . . 0  @3same_rev
-{
-  VQRSHL_S64_3s   001 0 0 . ..   0101 . . . 1  @3same_64_rev
-  VQRSHL_S_3s 001 0 0 . ..   0101 . . . 1  @3same_rev
-}
-{
-  VQRSHL_U64_3s   001 1 0 . ..   0101 . . . 1  @3same_64_rev
-  VQRSHL_U_3s 001 1 0 . ..   0101 . . . 1  @3same_rev
-}
+VQRSHL_S_3s   001 0 0 . ..   0101 . . . 1  @3same_rev
+VQRSHL_U_3s   001 1 0 . ..   0101 . . . 1  @3same_rev
 
 VMAX_S_3s 001 0 0 . ..   0110 . . . 0  @3same
 VMAX_U_3s 001 1 0 . ..   0110 . . . 0  @3same
diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c
index 773dbf41d3..51e66ccf5f 100644
--- a/target/arm/tcg/gengvec.c
+++ b/target/arm/tcg/gengvec.c
@@ -1263,6 +1263,30 @@ void gen_neon_uqshl(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
opr_sz, max_sz, 0, fns[vece]);
 }
 
+void gen_neon_sqrshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+ uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static gen_helper_gvec_3_ptr * const fns[] = {
+gen_helper_neon_sqrshl_b, gen_helper_neon_sqrshl_h,
+gen_helper_neon_sqrshl_s, gen_helper_neon_sqrshl_d,
+};
+

[PATCH 42/57] target/arm: Convert SQRSHL, UQRSHL to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  4 +++
 target/arm/tcg/translate-a64.c | 48 --
 2 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 9f5ea9223d..86279edc98 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -762,6 +762,8 @@ SRSHL_s 0101 1110 111 . 01010 1 . . 
@rrr_d
 URSHL_s 0111 1110 111 . 01010 1 . . @rrr_d
 SQSHL_s 0101 1110 ..1 . 01001 1 . . @rrr_e
 UQSHL_s 0111 1110 ..1 . 01001 1 . . @rrr_e
+SQRSHL_s0101 1110 ..1 . 01011 1 . . @rrr_e
+UQRSHL_s0111 1110 ..1 . 01011 1 . . @rrr_e
 
 ### Advanced SIMD scalar pairwise
 
@@ -890,6 +892,8 @@ SRSHL_v 0.00 1110 ..1 . 01010 1 . . 
@qrrr_e
 URSHL_v 0.10 1110 ..1 . 01010 1 . . @qrrr_e
 SQSHL_v 0.00 1110 ..1 . 01001 1 . . @qrrr_e
 UQSHL_v 0.10 1110 ..1 . 01001 1 . . @qrrr_e
+SQRSHL_v0.00 1110 ..1 . 01011 1 . . @qrrr_e
+UQRSHL_v0.10 1110 ..1 . 01011 1 . . @qrrr_e
 
 ### Advanced SIMD scalar x indexed element
 
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 8f5d8564eb..db3ba77760 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5163,6 +5163,22 @@ static const ENVScalar2 f_scalar_uqshl = {
 };
 TRANS(UQSHL_s, do_env_scalar2, a, _scalar_uqshl)
 
+static const ENVScalar2 f_scalar_sqrshl = {
+{ gen_helper_neon_qrshl_s8,
+  gen_helper_neon_qrshl_s16,
+  gen_helper_neon_qrshl_s32 },
+gen_helper_neon_qrshl_s64,
+};
+TRANS(SQRSHL_s, do_env_scalar2, a, _scalar_sqrshl)
+
+static const ENVScalar2 f_scalar_uqrshl = {
+{ gen_helper_neon_qrshl_u8,
+  gen_helper_neon_qrshl_u16,
+  gen_helper_neon_qrshl_u32 },
+gen_helper_neon_qrshl_u64,
+};
+TRANS(UQRSHL_s, do_env_scalar2, a, _scalar_uqrshl)
+
 static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a,
   gen_helper_gvec_3_ptr * const fns[3])
 {
@@ -5414,6 +5430,8 @@ TRANS(SRSHL_v, do_gvec_fn3, a, gen_gvec_srshl)
 TRANS(URSHL_v, do_gvec_fn3, a, gen_gvec_urshl)
 TRANS(SQSHL_v, do_gvec_fn3, a, gen_neon_sqshl)
 TRANS(UQSHL_v, do_gvec_fn3, a, gen_neon_uqshl)
+TRANS(SQRSHL_v, do_gvec_fn3, a, gen_neon_sqrshl)
+TRANS(UQRSHL_v, do_gvec_fn3, a, gen_neon_uqrshl)
 
 
 /*
@@ -9420,13 +9438,6 @@ static void handle_3same_64(DisasContext *s, int opcode, 
bool u,
 }
 gen_cmtst_i64(tcg_rd, tcg_rn, tcg_rm);
 break;
-case 0xb: /* SQRSHL, UQRSHL */
-if (u) {
-gen_helper_neon_qrshl_u64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
-} else {
-gen_helper_neon_qrshl_s64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
-}
-break;
 case 0x10: /* ADD, SUB */
 if (u) {
 tcg_gen_sub_i64(tcg_rd, tcg_rn, tcg_rm);
@@ -9440,6 +9451,7 @@ static void handle_3same_64(DisasContext *s, int opcode, 
bool u,
 case 0x8: /* SSHL, USHL */
 case 0x9: /* SQSHL, UQSHL */
 case 0xa: /* SRSHL, URSHL */
+case 0xb: /* SQRSHL, UQRSHL */
 g_assert_not_reached();
 }
 }
@@ -9461,8 +9473,6 @@ static void disas_simd_scalar_three_reg_same(DisasContext 
*s, uint32_t insn)
 TCGv_i64 tcg_rd;
 
 switch (opcode) {
-case 0xb: /* SQRSHL, UQRSHL */
-break;
 case 0x6: /* CMGT, CMHI */
 case 0x7: /* CMGE, CMHS */
 case 0x11: /* CMTST, CMEQ */
@@ -9484,6 +9494,7 @@ static void disas_simd_scalar_three_reg_same(DisasContext 
*s, uint32_t insn)
 case 0x8: /* SSHL, USHL */
 case 0x9: /* SQSHL, UQSHL */
 case 0xa: /* SRSHL, URSHL */
+case 0xb: /* SQRSHL, UQRSHL */
 unallocated_encoding(s);
 return;
 }
@@ -9510,16 +9521,6 @@ static void 
disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn)
 void (*genfn)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64, MemOp) = NULL;
 
 switch (opcode) {
-case 0xb: /* SQRSHL, UQRSHL */
-{
-static NeonGenTwoOpEnvFn * const fns[3][2] = {
-{ gen_helper_neon_qrshl_s8, gen_helper_neon_qrshl_u8 },
-{ gen_helper_neon_qrshl_s16, gen_helper_neon_qrshl_u16 },
-{ gen_helper_neon_qrshl_s32, gen_helper_neon_qrshl_u32 },
-};
-genenvfn = fns[size][u];
-break;
-}
 case 0x16: /* SQDMULH, SQRDMULH */
 {
 static NeonGenTwoOpEnvFn * const fns[2][2] = {
@@ -9534,6 +9535,7 @@ static void disas_simd_scalar_three_reg_same(DisasContext 
*s, uint32_t insn)
 case 0x1: /* SQADD, UQADD */
 case 0x5: /* SQSUB, UQSUB */
 case 0x9: /* SQSHL, UQSHL */
+case 0xb: /* SQRSHL, UQRSHL */
 g_assert_not_reached();
 }
 
@@ -10959,13 +10961,6 @@ static void disas_simd_3same_int(DisasContext *s, 

[PATCH 53/57] target/arm: Convert SABA, SABD, UABA, UABD to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  4 
 target/arm/tcg/translate-a64.c | 22 ++
 2 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 9b68444595..e1667775f6 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -922,6 +922,10 @@ SMAX_v  0.00 1110 ..1 . 01100 1 . . 
@qrrr_e
 UMAX_v  0.10 1110 ..1 . 01100 1 . . @qrrr_e
 SMIN_v  0.00 1110 ..1 . 01101 1 . . @qrrr_e
 UMIN_v  0.10 1110 ..1 . 01101 1 . . @qrrr_e
+SABD_v  0.00 1110 ..1 . 01110 1 . . @qrrr_e
+UABD_v  0.10 1110 ..1 . 01110 1 . . @qrrr_e
+SABA_v  0.00 1110 ..1 . 0 1 . . @qrrr_e
+UABA_v  0.10 1110 ..1 . 0 1 . . @qrrr_e
 
 ### Advanced SIMD scalar x indexed element
 
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 9ab73fc330..2e746d2877 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5465,6 +5465,10 @@ TRANS(SMAX_v, do_gvec_fn3_no64, a, tcg_gen_gvec_smax)
 TRANS(UMAX_v, do_gvec_fn3_no64, a, tcg_gen_gvec_umax)
 TRANS(SMIN_v, do_gvec_fn3_no64, a, tcg_gen_gvec_smin)
 TRANS(UMIN_v, do_gvec_fn3_no64, a, tcg_gen_gvec_umin)
+TRANS(SABA_v, do_gvec_fn3_no64, a, gen_gvec_saba)
+TRANS(UABA_v, do_gvec_fn3_no64, a, gen_gvec_uaba)
+TRANS(SABD_v, do_gvec_fn3_no64, a, gen_gvec_sabd)
+TRANS(UABD_v, do_gvec_fn3_no64, a, gen_gvec_uabd)
 
 static bool do_cmop_v(DisasContext *s, arg_qrrr_e *a, TCGCond cond)
 {
@@ -10923,8 +10927,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 return;
 }
 /* fall through */
-case 0xe: /* SABD, UABD */
-case 0xf: /* SABA, UABA */
 case 0x12: /* MLA, MLS */
 if (size == 3) {
 unallocated_encoding(s);
@@ -10957,6 +10959,8 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 case 0x0b: /* SQRSHL, UQRSHL */
 case 0x0c: /* SMAX, UMAX */
 case 0x0d: /* SMIN, UMIN */
+case 0x0e: /* SABD, UABD */
+case 0x0f: /* SABA, UABA */
 case 0x10: /* ADD, SUB */
 case 0x11: /* CMTST, CMEQ */
 unallocated_encoding(s);
@@ -10968,20 +10972,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 }
 
 switch (opcode) {
-case 0xe: /* SABD, UABD */
-if (u) {
-gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uabd, size);
-} else {
-gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sabd, size);
-}
-return;
-case 0xf: /* SABA, UABA */
-if (u) {
-gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uaba, size);
-} else {
-gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_saba, size);
-}
-return;
 case 0x13: /* MUL, PMUL */
 if (!u) { /* MUL */
 gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_mul, size);
-- 
2.34.1




[PATCH 08/57] target/arm: Convert Cryptographic 4-register to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |   8 ++
 target/arm/tcg/translate-a64.c | 132 +++--
 2 files changed, 51 insertions(+), 89 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 5a46205751..ef6902e86a 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -27,11 +27,13 @@
   imm
 _e  q rd rn esz
 _e q rd rn rm esz
+_eq rd rn rm ra esz
 
 @rr_q1e0  .. rn:5 rd:5  _e q=1 esz=0
 @r2r_q1e0     .. rm:5 rd:5  _e rn=%rd q=1 
esz=0
 @rrr_q1e0    ... rm:5 .. rn:5 rd:5  _e q=1 esz=0
 @rrr_q1e3    ... rm:5 .. rn:5 rd:5  _e q=1 esz=3
+@_q1e3   ... rm:5 . ra:5 rn:5 rd:5  _e q=1 esz=3
 
 ### Data Processing - Immediate
 
@@ -636,3 +638,9 @@ SM4EKEY 1100 1110 011 . 110010 . .  
@rrr_q1e0
 
 SHA512SU0   1100 1110 110 0 10 . .  @rr_q1e0
 SM4E1100 1110 110 0 11 . .  @r2r_q1e0
+
+### Cryptographic four-register
+
+EOR31100 1110 000 . 0 . . . @_q1e3
+BCAX1100 1110 001 . 0 . . . @_q1e3
+SM3SS1  1100 1110 010 . 0 . . . @_q1e3
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 1bfee2583a..a20da75423 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -1353,6 +1353,17 @@ static bool do_gvec_fn3(DisasContext *s, arg_qrrr_e *a, 
GVecGen3Fn *fn)
 return true;
 }
 
+static bool do_gvec_fn4(DisasContext *s, arg_q_e *a, GVecGen4Fn *fn)
+{
+if (!a->q && a->esz == MO_64) {
+return false;
+}
+if (fp_access_check(s)) {
+gen_gvec_fn4(s, a->q, a->rd, a->rn, a->rm, a->ra, fn, a->esz);
+}
+return true;
+}
+
 /*
  * This utility function is for doing register extension with an
  * optional shift. You will likely want to pass a temporary for the
@@ -4633,6 +4644,38 @@ TRANS_FEAT(SM4EKEY, aa64_sm4, do_gvec_op3_ool, a, 0, 
gen_helper_crypto_sm4ekey)
 TRANS_FEAT(SHA512SU0, aa64_sha512, do_gvec_op2_ool, a, 0, 
gen_helper_crypto_sha512su0)
 TRANS_FEAT(SM4E, aa64_sm4, do_gvec_op3_ool, a, 0, gen_helper_crypto_sm4e)
 
+TRANS_FEAT(EOR3, aa64_sha3, do_gvec_fn4, a, gen_gvec_eor3)
+TRANS_FEAT(BCAX, aa64_sha3, do_gvec_fn4, a, gen_gvec_bcax)
+
+static bool trans_SM3SS1(DisasContext *s, arg_SM3SS1 *a)
+{
+if (!dc_isar_feature(aa64_sm3, s)) {
+return false;
+}
+if (fp_access_check(s)) {
+TCGv_i32 tcg_op1 = tcg_temp_new_i32();
+TCGv_i32 tcg_op2 = tcg_temp_new_i32();
+TCGv_i32 tcg_op3 = tcg_temp_new_i32();
+TCGv_i32 tcg_res = tcg_temp_new_i32();
+unsigned vsz, dofs;
+
+read_vec_element_i32(s, tcg_op1, a->rn, 3, MO_32);
+read_vec_element_i32(s, tcg_op2, a->rm, 3, MO_32);
+read_vec_element_i32(s, tcg_op3, a->ra, 3, MO_32);
+
+tcg_gen_rotri_i32(tcg_res, tcg_op1, 20);
+tcg_gen_add_i32(tcg_res, tcg_res, tcg_op2);
+tcg_gen_add_i32(tcg_res, tcg_res, tcg_op3);
+tcg_gen_rotri_i32(tcg_res, tcg_res, 25);
+
+/* Clear the whole register first, then store bits [127:96]. */
+vsz = vec_full_reg_size(s);
+dofs = vec_full_reg_offset(s, a->rd);
+tcg_gen_gvec_dup_imm(MO_64, dofs, vsz, vsz, 0);
+write_vec_element_i32(s, tcg_res, a->rd, 3, MO_32);
+}
+return true;
+}
 
 /* Shift a TCGv src by TCGv shift_amount, put result in dst.
  * Note that it is the caller's responsibility to ensure that the
@@ -13527,94 +13570,6 @@ static void disas_simd_indexed(DisasContext *s, 
uint32_t insn)
 }
 }
 
-/* Crypto four-register
- *  31   23 22 21 20  16 15  14  10 95 40
- * +---+-+--+---+--+--+--+
- * | 1 1 0 0 1 1 1 0 0 | Op0 |  Rm  | 0 |  Ra  |  Rn  |  Rd  |
- * +---+-+--+---+--+--+--+
- */
-static void disas_crypto_four_reg(DisasContext *s, uint32_t insn)
-{
-int op0 = extract32(insn, 21, 2);
-int rm = extract32(insn, 16, 5);
-int ra = extract32(insn, 10, 5);
-int rn = extract32(insn, 5, 5);
-int rd = extract32(insn, 0, 5);
-bool feature;
-
-switch (op0) {
-case 0: /* EOR3 */
-case 1: /* BCAX */
-feature = dc_isar_feature(aa64_sha3, s);
-break;
-case 2: /* SM3SS1 */
-feature = dc_isar_feature(aa64_sm3, s);
-break;
-default:
-unallocated_encoding(s);
-return;
-}
-
-if (!feature) {
-unallocated_encoding(s);
-return;
-}
-
-if (!fp_access_check(s)) {
-return;
-}
-
-if (op0 < 2) {
-TCGv_i64 tcg_op1, tcg_op2, tcg_op3, tcg_res[2];
-int pass;
-
-tcg_op1 = tcg_temp_new_i64();
-tcg_op2 = tcg_temp_new_i64();
-tcg_op3 = tcg_temp_new_i64();
-   

[PATCH 40/57] target/arm: Convert SQSHL, UQSHL to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  4 ++
 target/arm/tcg/translate-a64.c | 74 ++
 2 files changed, 53 insertions(+), 25 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 6f55e0e300..9f5ea9223d 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -760,6 +760,8 @@ SSHL_s  0101 1110 111 . 01000 1 . . 
@rrr_d
 USHL_s  0111 1110 111 . 01000 1 . . @rrr_d
 SRSHL_s 0101 1110 111 . 01010 1 . . @rrr_d
 URSHL_s 0111 1110 111 . 01010 1 . . @rrr_d
+SQSHL_s 0101 1110 ..1 . 01001 1 . . @rrr_e
+UQSHL_s 0111 1110 ..1 . 01001 1 . . @rrr_e
 
 ### Advanced SIMD scalar pairwise
 
@@ -886,6 +888,8 @@ SSHL_v  0.00 1110 ..1 . 01000 1 . . 
@qrrr_e
 USHL_v  0.10 1110 ..1 . 01000 1 . . @qrrr_e
 SRSHL_v 0.00 1110 ..1 . 01010 1 . . @qrrr_e
 URSHL_v 0.10 1110 ..1 . 01010 1 . . @qrrr_e
+SQSHL_v 0.00 1110 ..1 . 01001 1 . . @qrrr_e
+UQSHL_v 0.10 1110 ..1 . 01001 1 . . @qrrr_e
 
 ### Advanced SIMD scalar x indexed element
 
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index fc0f371211..c1c513fd12 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5120,6 +5120,49 @@ TRANS(USHL_s, do_int3_scalar_d, a, gen_ushl_i64)
 TRANS(SRSHL_s, do_int3_scalar_d, a, gen_helper_neon_rshl_s64)
 TRANS(URSHL_s, do_int3_scalar_d, a, gen_helper_neon_rshl_u64)
 
+typedef struct ENVScalar2 {
+NeonGenTwoOpEnvFn *gen_bhs[3];
+NeonGenTwo64OpEnvFn *gen_d;
+} ENVScalar2;
+
+static bool do_env_scalar2(DisasContext *s, arg_rrr_e *a, const ENVScalar2 *f)
+{
+if (!fp_access_check(s)) {
+return true;
+}
+if (a->esz == MO_64) {
+TCGv_i64 t0 = read_fp_dreg(s, a->rn);
+TCGv_i64 t1 = read_fp_dreg(s, a->rm);
+f->gen_d(t0, tcg_env, t0, t1);
+write_fp_dreg(s, a->rd, t0);
+} else {
+TCGv_i32 t0 = tcg_temp_new_i32();
+TCGv_i32 t1 = tcg_temp_new_i32();
+
+read_vec_element_i32(s, t0, a->rn, 0, a->esz);
+read_vec_element_i32(s, t1, a->rm, 0, a->esz);
+f->gen_bhs[a->esz](t0, tcg_env, t0, t1);
+write_fp_sreg(s, a->rd, t0);
+}
+return true;
+}
+
+static const ENVScalar2 f_scalar_sqshl = {
+{ gen_helper_neon_qshl_s8,
+  gen_helper_neon_qshl_s16,
+  gen_helper_neon_qshl_s32 },
+gen_helper_neon_qshl_s64,
+};
+TRANS(SQSHL_s, do_env_scalar2, a, _scalar_sqshl)
+
+static const ENVScalar2 f_scalar_uqshl = {
+{ gen_helper_neon_qshl_u8,
+  gen_helper_neon_qshl_u16,
+  gen_helper_neon_qshl_u32 },
+gen_helper_neon_qshl_u64,
+};
+TRANS(UQSHL_s, do_env_scalar2, a, _scalar_uqshl)
+
 static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a,
   gen_helper_gvec_3_ptr * const fns[3])
 {
@@ -5369,6 +5412,8 @@ TRANS(SSHL_v, do_gvec_fn3, a, gen_gvec_sshl)
 TRANS(USHL_v, do_gvec_fn3, a, gen_gvec_ushl)
 TRANS(SRSHL_v, do_gvec_fn3, a, gen_gvec_srshl)
 TRANS(URSHL_v, do_gvec_fn3, a, gen_gvec_urshl)
+TRANS(SQSHL_v, do_gvec_fn3, a, gen_neon_sqshl)
+TRANS(UQSHL_v, do_gvec_fn3, a, gen_neon_uqshl)
 
 
 /*
@@ -9375,13 +9420,6 @@ static void handle_3same_64(DisasContext *s, int opcode, 
bool u,
 }
 gen_cmtst_i64(tcg_rd, tcg_rn, tcg_rm);
 break;
-case 0x9: /* SQSHL, UQSHL */
-if (u) {
-gen_helper_neon_qshl_u64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
-} else {
-gen_helper_neon_qshl_s64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
-}
-break;
 case 0xb: /* SQRSHL, UQRSHL */
 if (u) {
 gen_helper_neon_qrshl_u64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
@@ -9400,6 +9438,7 @@ static void handle_3same_64(DisasContext *s, int opcode, 
bool u,
 case 0x1: /* SQADD / UQADD */
 case 0x5: /* SQSUB / UQSUB */
 case 0x8: /* SSHL, USHL */
+case 0x9: /* SQSHL, UQSHL */
 case 0xa: /* SRSHL, URSHL */
 g_assert_not_reached();
 }
@@ -9422,7 +9461,6 @@ static void disas_simd_scalar_three_reg_same(DisasContext 
*s, uint32_t insn)
 TCGv_i64 tcg_rd;
 
 switch (opcode) {
-case 0x9: /* SQSHL, UQSHL */
 case 0xb: /* SQRSHL, UQRSHL */
 break;
 case 0x6: /* CMGT, CMHI */
@@ -9444,6 +9482,7 @@ static void disas_simd_scalar_three_reg_same(DisasContext 
*s, uint32_t insn)
 case 0x1: /* SQADD, UQADD */
 case 0x5: /* SQSUB, UQSUB */
 case 0x8: /* SSHL, USHL */
+case 0x9: /* SQSHL, UQSHL */
 case 0xa: /* SRSHL, URSHL */
 unallocated_encoding(s);
 return;
@@ -9471,16 +9510,6 @@ static void 
disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn)
 void (*genfn)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64, MemOp) = NULL;
 
 switch (opcode) {
-case 0x9: /* 

[PATCH 47/57] target/arm: Convert SHADD, UHADD to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  2 ++
 target/arm/tcg/translate-a64.c | 11 +++
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index d97390cacb..0881f00ecf 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -912,6 +912,8 @@ CMGE_v  0.00 1110 ..1 . 00111 1 . . 
@qrrr_e
 CMHS_v  0.10 1110 ..1 . 00111 1 . . @qrrr_e
 CMTST_v 0.00 1110 ..1 . 10001 1 . . @qrrr_e
 CMEQ_v  0.10 1110 ..1 . 10001 1 . . @qrrr_e
+SHADD_v 0.00 1110 ..1 . 0 1 . . @qrrr_e
+UHADD_v 0.10 1110 ..1 . 0 1 . . @qrrr_e
 
 ### Advanced SIMD scalar x indexed element
 
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 4f7d03b5f2..c70c3cec2a 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5455,6 +5455,8 @@ TRANS(UQRSHL_v, do_gvec_fn3, a, gen_neon_uqrshl)
 
 TRANS(ADD_v, do_gvec_fn3, a, tcg_gen_gvec_add)
 TRANS(SUB_v, do_gvec_fn3, a, tcg_gen_gvec_sub)
+TRANS(SHADD_v, do_gvec_fn3_no64, a, gen_gvec_shadd)
+TRANS(UHADD_v, do_gvec_fn3_no64, a, gen_gvec_uhadd)
 
 static bool do_cmop_v(DisasContext *s, arg_qrrr_e *a, TCGCond cond)
 {
@@ -10914,7 +10916,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 return;
 }
 /* fall through */
-case 0x0: /* SHADD, UHADD */
 case 0x2: /* SRHADD, URHADD */
 case 0x4: /* SHSUB, UHSUB */
 case 0xc: /* SMAX, UMAX */
@@ -10940,6 +10941,7 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 }
 break;
 
+case 0x0: /* SHADD, UHADD */
 case 0x01: /* SQADD, UQADD */
 case 0x05: /* SQSUB, UQSUB */
 case 0x06: /* CMGT, CMHI */
@@ -10959,13 +10961,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 }
 
 switch (opcode) {
-case 0x00: /* SHADD, UHADD */
-if (u) {
-gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uhadd, size);
-} else {
-gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_shadd, size);
-}
-return;
 case 0x0c: /* SMAX, UMAX */
 if (u) {
 gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umax, size);
-- 
2.34.1




[PATCH 52/57] target/arm: Convert SMAX, SMIN, UMAX, UMIN to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  4 
 target/arm/tcg/translate-a64.c | 22 ++
 2 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index fc8a5ca14f..9b68444595 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -918,6 +918,10 @@ SHSUB_v 0.00 1110 ..1 . 00100 1 . . 
@qrrr_e
 UHSUB_v 0.10 1110 ..1 . 00100 1 . . @qrrr_e
 SRHADD_v0.00 1110 ..1 . 00010 1 . . @qrrr_e
 URHADD_v0.10 1110 ..1 . 00010 1 . . @qrrr_e
+SMAX_v  0.00 1110 ..1 . 01100 1 . . @qrrr_e
+UMAX_v  0.10 1110 ..1 . 01100 1 . . @qrrr_e
+SMIN_v  0.00 1110 ..1 . 01101 1 . . @qrrr_e
+UMIN_v  0.10 1110 ..1 . 01101 1 . . @qrrr_e
 
 ### Advanced SIMD scalar x indexed element
 
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index b707c6ae4d..9ab73fc330 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5461,6 +5461,10 @@ TRANS(SHSUB_v, do_gvec_fn3_no64, a, gen_gvec_shsub)
 TRANS(UHSUB_v, do_gvec_fn3_no64, a, gen_gvec_uhsub)
 TRANS(SRHADD_v, do_gvec_fn3_no64, a, gen_gvec_srhadd)
 TRANS(URHADD_v, do_gvec_fn3_no64, a, gen_gvec_urhadd)
+TRANS(SMAX_v, do_gvec_fn3_no64, a, tcg_gen_gvec_smax)
+TRANS(UMAX_v, do_gvec_fn3_no64, a, tcg_gen_gvec_umax)
+TRANS(SMIN_v, do_gvec_fn3_no64, a, tcg_gen_gvec_smin)
+TRANS(UMIN_v, do_gvec_fn3_no64, a, tcg_gen_gvec_umin)
 
 static bool do_cmop_v(DisasContext *s, arg_qrrr_e *a, TCGCond cond)
 {
@@ -10919,8 +10923,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 return;
 }
 /* fall through */
-case 0xc: /* SMAX, UMAX */
-case 0xd: /* SMIN, UMIN */
 case 0xe: /* SABD, UABD */
 case 0xf: /* SABA, UABA */
 case 0x12: /* MLA, MLS */
@@ -10953,6 +10955,8 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 case 0x09: /* SQSHL, UQSHL */
 case 0x0a: /* SRSHL, URSHL */
 case 0x0b: /* SQRSHL, UQRSHL */
+case 0x0c: /* SMAX, UMAX */
+case 0x0d: /* SMIN, UMIN */
 case 0x10: /* ADD, SUB */
 case 0x11: /* CMTST, CMEQ */
 unallocated_encoding(s);
@@ -10964,20 +10968,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 }
 
 switch (opcode) {
-case 0x0c: /* SMAX, UMAX */
-if (u) {
-gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umax, size);
-} else {
-gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_smax, size);
-}
-return;
-case 0x0d: /* SMIN, UMIN */
-if (u) {
-gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umin, size);
-} else {
-gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_smin, size);
-}
-return;
 case 0xe: /* SABD, UABD */
 if (u) {
 gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_uabd, size);
-- 
2.34.1




[PATCH 28/57] target/arm: Convert FMLAL, FMLSL to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  10 +++
 target/arm/tcg/translate-a64.c | 144 ++---
 2 files changed, 51 insertions(+), 103 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 16e9675335..9aa4fb9bd0 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -797,6 +797,11 @@ FMLA_v  0.00 1110 0.1 . 11001 1 . . 
@qrrr_sd
 FMLS_v  0.00 1110 110 . 1 1 . . @qrrr_h
 FMLS_v  0.00 1110 1.1 . 11001 1 . . @qrrr_sd
 
+FMLAL_v 0.00 1110 001 . 11101 1 . . @qrrr_h
+FMLSL_v 0.00 1110 101 . 11101 1 . . @qrrr_h
+FMLAL2_v0.10 1110 001 . 11001 1 . . @qrrr_h
+FMLSL2_v0.10 1110 101 . 11001 1 . . @qrrr_h
+
 FCMEQ_v 0.00 1110 010 . 00100 1 . . @qrrr_h
 FCMEQ_v 0.00 1110 0.1 . 11100 1 . . @qrrr_sd
 
@@ -877,3 +882,8 @@ FMLS_vi 0.00  11 0 . 0101 . 0 . .   
@qrrx_d
 FMULX_vi0.10  00 ..  1001 . 0 . .   @qrrx_h
 FMULX_vi0.10  10 . . 1001 . 0 . .   @qrrx_s
 FMULX_vi0.10  11 0 . 1001 . 0 . .   @qrrx_d
+
+FMLAL_vi0.00  10 ..   . 0 . .   @qrrx_h
+FMLSL_vi0.00  10 ..  0100 . 0 . .   @qrrx_h
+FMLAL2_vi   0.10  10 ..  1000 . 0 . .   @qrrx_h
+FMLSL2_vi   0.10  10 ..  1100 . 0 . .   @qrrx_h
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index be63f46247..a082ce8441 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5257,6 +5257,24 @@ static gen_helper_gvec_3_ptr * const f_vector_fminnmp[3] 
= {
 };
 TRANS(FMINNMP_v, do_fp3_vector, a, f_vector_fminnmp)
 
+static bool do_fmlal(DisasContext *s, arg_qrrr_e *a, bool is_s, bool is_2)
+{
+if (fp_access_check(s)) {
+int data = (is_2 << 1) | is_s;
+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), tcg_env,
+   a->q ? 16 : 8, vec_full_reg_size(s),
+   data, gen_helper_gvec_fmlal_a64);
+}
+return true;
+}
+
+TRANS_FEAT(FMLAL_v, aa64_fhm, do_fmlal, a, false, false)
+TRANS_FEAT(FMLSL_v, aa64_fhm, do_fmlal, a, true, false)
+TRANS_FEAT(FMLAL2_v, aa64_fhm, do_fmlal, a, false, true)
+TRANS_FEAT(FMLSL2_v, aa64_fhm, do_fmlal, a, true, true)
+
 TRANS(ADDP_v, do_gvec_fn3, a, gen_gvec_addp)
 TRANS(SMAXP_v, do_gvec_fn3_no64, a, gen_gvec_smaxp)
 TRANS(SMINP_v, do_gvec_fn3_no64, a, gen_gvec_sminp)
@@ -5448,6 +5466,24 @@ static bool do_fmla_vector_idx(DisasContext *s, 
arg_qrrx_e *a, bool neg)
 TRANS(FMLA_vi, do_fmla_vector_idx, a, false)
 TRANS(FMLS_vi, do_fmla_vector_idx, a, true)
 
+static bool do_fmlal_idx(DisasContext *s, arg_qrrx_e *a, bool is_s, bool is_2)
+{
+if (fp_access_check(s)) {
+int data = (a->idx << 2) | (is_2 << 1) | is_s;
+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), tcg_env,
+   a->q ? 16 : 8, vec_full_reg_size(s),
+   data, gen_helper_gvec_fmlal_idx_a64);
+}
+return true;
+}
+
+TRANS_FEAT(FMLAL_vi, aa64_fhm, do_fmlal_idx, a, false, false)
+TRANS_FEAT(FMLSL_vi, aa64_fhm, do_fmlal_idx, a, true, false)
+TRANS_FEAT(FMLAL2_vi, aa64_fhm, do_fmlal_idx, a, false, true)
+TRANS_FEAT(FMLSL2_vi, aa64_fhm, do_fmlal_idx, a, true, true)
+
 /*
  * Advanced SIMD scalar pairwise
  */
@@ -10905,78 +10941,6 @@ static void disas_simd_3same_logic(DisasContext *s, 
uint32_t insn)
 }
 }
 
-/* Floating point op subgroup of C3.6.16. */
-static void disas_simd_3same_float(DisasContext *s, uint32_t insn)
-{
-/* For floating point ops, the U, size[1] and opcode bits
- * together indicate the operation. size[0] indicates single
- * or double.
- */
-int fpopcode = extract32(insn, 11, 5)
-| (extract32(insn, 23, 1) << 5)
-| (extract32(insn, 29, 1) << 6);
-int is_q = extract32(insn, 30, 1);
-int size = extract32(insn, 22, 1);
-int rm = extract32(insn, 16, 5);
-int rn = extract32(insn, 5, 5);
-int rd = extract32(insn, 0, 5);
-
-if (size == 1 && !is_q) {
-unallocated_encoding(s);
-return;
-}
-
-switch (fpopcode) {
-case 0x1d: /* FMLAL  */
-case 0x3d: /* FMLSL  */
-case 0x59: /* FMLAL2 */
-case 0x79: /* FMLSL2 */
-if (size & 1 || !dc_isar_feature(aa64_fhm, s)) {
-unallocated_encoding(s);
-return;
-}
-if (fp_access_check(s)) {
-int is_s = extract32(insn, 23, 1);
-int is_2 = extract32(insn, 29, 1);
-int data = (is_2 << 1) 

[PATCH 03/57] target/arm: Convert Cryptographic AES to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  | 21 +++--
 target/arm/tcg/translate-a64.c | 86 +++---
 2 files changed, 54 insertions(+), 53 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 0e7656fd15..1de09903dc 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -19,11 +19,17 @@
 # This file is processed by scripts/decodetree.py
 #
 
-   rn
-  rd imm
-_sf  rd rn imm sf
-   imm
+%rd 0:5
 
+  rn
+ rd imm
+_sf rd rn imm sf
+  imm
+_e  q rd rn esz
+_e q rd rn rm esz
+
+@rr_q1e0  .. rn:5 rd:5  _e q=1 esz=0
+@r2r_q1e0     .. rm:5 rd:5  _e rn=%rd q=1 
esz=0
 
 ### Data Processing - Immediate
 
@@ -590,3 +596,10 @@ CPYFE   00 011 0 01100 .  01 . . 
@cpy
 CPYP00 011 1 01000 .  01 . . @cpy
 CPYM00 011 1 01010 .  01 . . @cpy
 CPYE00 011 1 01100 .  01 . . @cpy
+
+### Cryptographic AES
+
+AESE01001110 00 10100 00100 10 . .  @r2r_q1e0
+AESD01001110 00 10100 00101 10 . .  @r2r_q1e0
+AESMC   01001110 00 10100 00110 10 . .  @rr_q1e0
+AESIMC  01001110 00 10100 00111 10 . .  @rr_q1e0
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 283078d385..1ba6a30176 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -1314,6 +1314,34 @@ bool sme_enabled_check_with_svcr(DisasContext *s, 
unsigned req)
 return true;
 }
 
+/*
+ * Expanders for AdvSIMD translation functions.
+ */
+
+static bool do_gvec_op2_ool(DisasContext *s, arg_qrr_e *a, int data,
+gen_helper_gvec_2 *fn)
+{
+if (!a->q && a->esz == MO_64) {
+return false;
+}
+if (fp_access_check(s)) {
+gen_gvec_op2_ool(s, a->q, a->rd, a->rn, data, fn);
+}
+return true;
+}
+
+static bool do_gvec_op3_ool(DisasContext *s, arg_qrrr_e *a, int data,
+gen_helper_gvec_3 *fn)
+{
+if (!a->q && a->esz == MO_64) {
+return false;
+}
+if (fp_access_check(s)) {
+gen_gvec_op3_ool(s, a->q, a->rd, a->rn, a->rm, data, fn);
+}
+return true;
+}
+
 /*
  * This utility function is for doing register extension with an
  * optional shift. You will likely want to pass a temporary for the
@@ -4561,6 +4589,15 @@ static bool trans_EXTR(DisasContext *s, arg_extract *a)
 return true;
 }
 
+/*
+ * Cryptographic AES
+ */
+
+TRANS_FEAT(AESE, aa64_aes, do_gvec_op3_ool, a, 0, gen_helper_crypto_aese)
+TRANS_FEAT(AESD, aa64_aes, do_gvec_op3_ool, a, 0, gen_helper_crypto_aesd)
+TRANS_FEAT(AESMC, aa64_aes, do_gvec_op2_ool, a, 0, gen_helper_crypto_aesmc)
+TRANS_FEAT(AESIMC, aa64_aes, do_gvec_op2_ool, a, 0, gen_helper_crypto_aesimc)
+
 /* Shift a TCGv src by TCGv shift_amount, put result in dst.
  * Note that it is the caller's responsibility to ensure that the
  * shift amount is in range (ie 0..31 or 0..63) and provide the ARM
@@ -13454,54 +13491,6 @@ static void disas_simd_indexed(DisasContext *s, 
uint32_t insn)
 }
 }
 
-/* Crypto AES
- *  31 24 23  22 21   17 1612 11 10 95 40
- * +-+--+---++-+--+--+
- * | 0 1 0 0 1 1 1 0 | size | 1 0 1 0 0 | opcode | 1 0 |  Rn  |  Rd  |
- * +-+--+---++-+--+--+
- */
-static void disas_crypto_aes(DisasContext *s, uint32_t insn)
-{
-int size = extract32(insn, 22, 2);
-int opcode = extract32(insn, 12, 5);
-int rn = extract32(insn, 5, 5);
-int rd = extract32(insn, 0, 5);
-gen_helper_gvec_2 *genfn2 = NULL;
-gen_helper_gvec_3 *genfn3 = NULL;
-
-if (!dc_isar_feature(aa64_aes, s) || size != 0) {
-unallocated_encoding(s);
-return;
-}
-
-switch (opcode) {
-case 0x4: /* AESE */
-genfn3 = gen_helper_crypto_aese;
-break;
-case 0x6: /* AESMC */
-genfn2 = gen_helper_crypto_aesmc;
-break;
-case 0x5: /* AESD */
-genfn3 = gen_helper_crypto_aesd;
-break;
-case 0x7: /* AESIMC */
-genfn2 = gen_helper_crypto_aesimc;
-break;
-default:
-unallocated_encoding(s);
-return;
-}
-
-if (!fp_access_check(s)) {
-return;
-}
-if (genfn2) {
-gen_gvec_op2_ool(s, true, rd, rn, 0, genfn2);
-} else {
-gen_gvec_op3_ool(s, true, rd, rd, rn, 0, genfn3);
-}
-}
-
 /* Crypto three-reg SHA
  *  31 24 23  22  21 20  16  15 1412 11 10 95 40
  * +-+--+---+--+---++-+--+--+
@@ -13911,7 +13900,6 @@ static const AArch64DecodeTable data_proc_simd[] = {
 { 0x5e000400, 0xdfe08400, 

[PATCH 21/57] target/arm: Convert FADDP to decodetree

2024-05-05 Thread Richard Henderson
This fixes a bug in which scalar half-precision did not
diagnose sz == 1 as UNDEFINED.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|  4 ++
 target/arm/tcg/a64.decode  | 12 +
 target/arm/tcg/translate-a64.c | 87 ++
 target/arm/tcg/vec_helper.c| 23 +
 4 files changed, 105 insertions(+), 21 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index ff6e3094f4..8441b49d1f 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -1048,6 +1048,10 @@ DEF_HELPER_FLAGS_5(gvec_uclamp_s, TCG_CALL_NO_RWG,
 DEF_HELPER_FLAGS_5(gvec_uclamp_d, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
 
+DEF_HELPER_FLAGS_5(gvec_faddp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_faddp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_faddp_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+
 #ifdef TARGET_AARCH64
 #include "tcg/helper-a64.h"
 #include "tcg/helper-sve.h"
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 8d0a6a147e..9d28cb5894 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -29,6 +29,7 @@
  rd imm
 _sf rd rn imm sf
   imm
+_e   rd rn esz
 _e  rd rn rm esz
 _e  rd rn rm idx esz
 _e  q rd rn esz
@@ -36,6 +37,9 @@
 _e q rd rn rm idx esz
 _eq rd rn rm ra esz
 
+@rr_h    ... . .. rn:5 rd:5 _e esz=1
+@rr_sd   ... . .. rn:5 rd:5 _e esz=%esz_sd
+
 @rrr_h   ... rm:5 .. rn:5 rd:5  _e esz=1
 @rrr_sd  ... rm:5 .. rn:5 rd:5  _e esz=%esz_sd
 @rrr_hsd ... rm:5 .. rn:5 rd:5  _e esz=%esz_hsd
@@ -737,6 +741,11 @@ FRECPS_s0101 1110 0.1 . 1 1 . . 
@rrr_sd
 FRSQRTS_s   0101 1110 110 . 00111 1 . . @rrr_h
 FRSQRTS_s   0101 1110 1.1 . 1 1 . . @rrr_sd
 
+### Advanced SIMD scalar pairwise
+
+FADDP_s 0101 1110 0011  1101 10 . . @rr_h
+FADDP_s 0111 1110 0.11  1101 10 . . @rr_sd
+
 ### Advanced SIMD three same
 
 FADD_v  0.00 1110 010 . 00010 1 . . @qrrr_h
@@ -796,6 +805,9 @@ FRECPS_v0.00 1110 0.1 . 1 1 . . 
@qrrr_sd
 FRSQRTS_v   0.00 1110 110 . 00111 1 . . @qrrr_h
 FRSQRTS_v   0.00 1110 1.1 . 1 1 . . @qrrr_sd
 
+FADDP_v 0.10 1110 010 . 00010 1 . . @qrrr_h
+FADDP_v 0.10 1110 0.1 . 11010 1 . . @qrrr_sd
+
 ### Advanced SIMD scalar x indexed element
 
 FMUL_si 0101  00 ..  1001 . 0 . .   @rrx_h
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index d5828ba8df..f5ee6145b1 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5211,6 +5211,13 @@ static gen_helper_gvec_3_ptr * const f_vector_frsqrts[3] 
= {
 };
 TRANS(FRSQRTS_v, do_fp3_vector, a, f_vector_frsqrts)
 
+static gen_helper_gvec_3_ptr * const f_vector_faddp[3] = {
+gen_helper_gvec_faddp_h,
+gen_helper_gvec_faddp_s,
+gen_helper_gvec_faddp_d,
+};
+TRANS(FADDP_v, do_fp3_vector, a, f_vector_faddp)
+
 /*
  * Advanced SIMD scalar/vector x indexed element
  */
@@ -5396,6 +5403,56 @@ static bool do_fmla_vector_idx(DisasContext *s, 
arg_qrrx_e *a, bool neg)
 TRANS(FMLA_vi, do_fmla_vector_idx, a, false)
 TRANS(FMLS_vi, do_fmla_vector_idx, a, true)
 
+/*
+ * Advanced SIMD scalar pairwise
+ */
+
+static bool do_fp3_scalar_pair(DisasContext *s, arg_rr_e *a, const FPScalar *f)
+{
+switch (a->esz) {
+case MO_64:
+if (fp_access_check(s)) {
+TCGv_i64 t0 = tcg_temp_new_i64();
+TCGv_i64 t1 = tcg_temp_new_i64();
+
+read_vec_element(s, t0, a->rn, 0, MO_64);
+read_vec_element(s, t1, a->rn, 1, MO_64);
+f->gen_d(t0, t0, t1, fpstatus_ptr(FPST_FPCR));
+write_fp_dreg(s, a->rd, t0);
+}
+break;
+case MO_32:
+if (fp_access_check(s)) {
+TCGv_i32 t0 = tcg_temp_new_i32();
+TCGv_i32 t1 = tcg_temp_new_i32();
+
+read_vec_element_i32(s, t0, a->rn, 0, MO_32);
+read_vec_element_i32(s, t1, a->rn, 1, MO_32);
+f->gen_s(t0, t0, t1, fpstatus_ptr(FPST_FPCR));
+write_fp_sreg(s, a->rd, t0);
+}
+break;
+case MO_16:
+if (!dc_isar_feature(aa64_fp16, s)) {
+return false;
+}
+if (fp_access_check(s)) {
+TCGv_i32 t0 = tcg_temp_new_i32();
+TCGv_i32 t1 = tcg_temp_new_i32();
+
+read_vec_element_i32(s, t0, a->rn, 0, MO_16);
+read_vec_element_i32(s, t1, a->rn, 1, MO_16);
+f->gen_h(t0, t0, t1, fpstatus_ptr(FPST_FPCR_F16));
+write_fp_sreg(s, a->rd, t0);
+}
+break;
+default:
+

[PATCH 27/57] target/arm: Use gvec for neon pmax, pmin

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/translate-neon.c | 78 ++---
 1 file changed, 4 insertions(+), 74 deletions(-)

diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c
index 6c5a7a98e1..18b048611b 100644
--- a/target/arm/tcg/translate-neon.c
+++ b/target/arm/tcg/translate-neon.c
@@ -831,6 +831,10 @@ DO_3SAME_NO_SZ_3(VABA_S, gen_gvec_saba)
 DO_3SAME_NO_SZ_3(VABD_U, gen_gvec_uabd)
 DO_3SAME_NO_SZ_3(VABA_U, gen_gvec_uaba)
 DO_3SAME_NO_SZ_3(VPADD, gen_gvec_addp)
+DO_3SAME_NO_SZ_3(VPMAX_S, gen_gvec_smaxp)
+DO_3SAME_NO_SZ_3(VPMIN_S, gen_gvec_sminp)
+DO_3SAME_NO_SZ_3(VPMAX_U, gen_gvec_umaxp)
+DO_3SAME_NO_SZ_3(VPMIN_U, gen_gvec_uminp)
 
 #define DO_3SAME_CMP(INSN, COND)\
 static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
@@ -1003,80 +1007,6 @@ DO_3SAME_32_ENV(VQSHL_U, qshl_u)
 DO_3SAME_32_ENV(VQRSHL_S, qrshl_s)
 DO_3SAME_32_ENV(VQRSHL_U, qrshl_u)
 
-static bool do_3same_pair(DisasContext *s, arg_3same *a, NeonGenTwoOpFn *fn)
-{
-/* Operations handled pairwise 32 bits at a time */
-TCGv_i32 tmp, tmp2, tmp3;
-
-if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
-return false;
-}
-
-/* UNDEF accesses to D16-D31 if they don't exist. */
-if (!dc_isar_feature(aa32_simd_r32, s) &&
-((a->vd | a->vn | a->vm) & 0x10)) {
-return false;
-}
-
-if (a->size == 3) {
-return false;
-}
-
-if (!vfp_access_check(s)) {
-return true;
-}
-
-assert(a->q == 0); /* enforced by decode patterns */
-
-/*
- * Note that we have to be careful not to clobber the source operands
- * in the "vm == vd" case by storing the result of the first pass too
- * early. Since Q is 0 there are always just two passes, so instead
- * of a complicated loop over each pass we just unroll.
- */
-tmp = tcg_temp_new_i32();
-tmp2 = tcg_temp_new_i32();
-tmp3 = tcg_temp_new_i32();
-
-read_neon_element32(tmp, a->vn, 0, MO_32);
-read_neon_element32(tmp2, a->vn, 1, MO_32);
-fn(tmp, tmp, tmp2);
-
-read_neon_element32(tmp3, a->vm, 0, MO_32);
-read_neon_element32(tmp2, a->vm, 1, MO_32);
-fn(tmp3, tmp3, tmp2);
-
-write_neon_element32(tmp, a->vd, 0, MO_32);
-write_neon_element32(tmp3, a->vd, 1, MO_32);
-
-return true;
-}
-
-#define DO_3SAME_PAIR(INSN, func)   \
-static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a)\
-{   \
-static NeonGenTwoOpFn * const fns[] = { \
-gen_helper_neon_##func##8,  \
-gen_helper_neon_##func##16, \
-gen_helper_neon_##func##32, \
-};  \
-if (a->size > 2) {  \
-return false;   \
-}   \
-return do_3same_pair(s, a, fns[a->size]);   \
-}
-
-/* 32-bit pairwise ops end up the same as the elementwise versions.  */
-#define gen_helper_neon_pmax_s32  tcg_gen_smax_i32
-#define gen_helper_neon_pmax_u32  tcg_gen_umax_i32
-#define gen_helper_neon_pmin_s32  tcg_gen_smin_i32
-#define gen_helper_neon_pmin_u32  tcg_gen_umin_i32
-
-DO_3SAME_PAIR(VPMAX_S, pmax_s)
-DO_3SAME_PAIR(VPMIN_S, pmin_s)
-DO_3SAME_PAIR(VPMAX_U, pmax_u)
-DO_3SAME_PAIR(VPMIN_U, pmin_u)
-
 #define DO_3SAME_VQDMULH(INSN, FUNC)\
 WRAP_ENV_FN(gen_##INSN##_tramp16, gen_helper_neon_##FUNC##_s16);\
 WRAP_ENV_FN(gen_##INSN##_tramp32, gen_helper_neon_##FUNC##_s32);\
-- 
2.34.1




[PATCH 44/57] target/arm: Convert CMGT, CMHI, CMGE, CMHS, CMTST, CMEQ to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  12 +++
 target/arm/tcg/translate-a64.c | 132 -
 2 files changed, 60 insertions(+), 84 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 97fe1ef927..d97390cacb 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -767,6 +767,12 @@ UQRSHL_s0111 1110 ..1 . 01011 1 . . 
@rrr_e
 
 ADD_s   0101 1110 111 . 1 1 . . @rrr_d
 SUB_s   0111 1110 111 . 1 1 . . @rrr_d
+CMGT_s  0101 1110 111 . 00110 1 . . @rrr_d
+CMHI_s  0111 1110 111 . 00110 1 . . @rrr_d
+CMGE_s  0101 1110 111 . 00111 1 . . @rrr_d
+CMHS_s  0111 1110 111 . 00111 1 . . @rrr_d
+CMTST_s 0101 1110 111 . 10001 1 . . @rrr_d
+CMEQ_s  0111 1110 111 . 10001 1 . . @rrr_d
 
 ### Advanced SIMD scalar pairwise
 
@@ -900,6 +906,12 @@ UQRSHL_v0.10 1110 ..1 . 01011 1 . . 
@qrrr_e
 
 ADD_v   0.00 1110 ..1 . 1 1 . . @qrrr_e
 SUB_v   0.10 1110 ..1 . 1 1 . . @qrrr_e
+CMGT_v  0.00 1110 ..1 . 00110 1 . . @qrrr_e
+CMHI_v  0.10 1110 ..1 . 00110 1 . . @qrrr_e
+CMGE_v  0.00 1110 ..1 . 00111 1 . . @qrrr_e
+CMHS_v  0.10 1110 ..1 . 00111 1 . . @qrrr_e
+CMTST_v 0.00 1110 ..1 . 10001 1 . . @qrrr_e
+CMEQ_v  0.10 1110 ..1 . 10001 1 . . @qrrr_e
 
 ### Advanced SIMD scalar x indexed element
 
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 9daa8fe5b0..d338cec77d 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5181,6 +5181,24 @@ static const ENVScalar2 f_scalar_uqrshl = {
 };
 TRANS(UQRSHL_s, do_env_scalar2, a, _scalar_uqrshl)
 
+static bool do_cmop_d(DisasContext *s, arg_rrr_e *a, TCGCond cond)
+{
+if (fp_access_check(s)) {
+TCGv_i64 t0 = read_fp_dreg(s, a->rn);
+TCGv_i64 t1 = read_fp_dreg(s, a->rm);
+tcg_gen_negsetcond_i64(cond, t0, t0, t1);
+write_fp_dreg(s, a->rd, t0);
+}
+return true;
+}
+
+TRANS(CMGT_s, do_cmop_d, a, TCG_COND_GT)
+TRANS(CMHI_s, do_cmop_d, a, TCG_COND_GTU)
+TRANS(CMGE_s, do_cmop_d, a, TCG_COND_GE)
+TRANS(CMHS_s, do_cmop_d, a, TCG_COND_GEU)
+TRANS(CMEQ_s, do_cmop_d, a, TCG_COND_EQ)
+TRANS(CMTST_s, do_cmop_d, a, TCG_COND_TSTNE)
+
 static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a,
   gen_helper_gvec_3_ptr * const fns[3])
 {
@@ -5438,6 +5456,28 @@ TRANS(UQRSHL_v, do_gvec_fn3, a, gen_neon_uqrshl)
 TRANS(ADD_v, do_gvec_fn3, a, tcg_gen_gvec_add)
 TRANS(SUB_v, do_gvec_fn3, a, tcg_gen_gvec_sub)
 
+static bool do_cmop_v(DisasContext *s, arg_qrrr_e *a, TCGCond cond)
+{
+if (a->esz == MO_64 && !a->q) {
+return false;
+}
+if (fp_access_check(s)) {
+tcg_gen_gvec_cmp(cond, a->esz,
+ vec_full_reg_offset(s, a->rd),
+ vec_full_reg_offset(s, a->rn),
+ vec_full_reg_offset(s, a->rm),
+ a->q ? 16 : 8, vec_full_reg_size(s));
+}
+return true;
+}
+
+TRANS(CMGT_v, do_cmop_v, a, TCG_COND_GT)
+TRANS(CMHI_v, do_cmop_v, a, TCG_COND_GTU)
+TRANS(CMGE_v, do_cmop_v, a, TCG_COND_GE)
+TRANS(CMHS_v, do_cmop_v, a, TCG_COND_GEU)
+TRANS(CMEQ_v, do_cmop_v, a, TCG_COND_EQ)
+TRANS(CMTST_v, do_gvec_fn3, a, gen_gvec_cmtst)
+
 /*
  * Advanced SIMD scalar/vector x indexed element
  */
@@ -9415,45 +9455,6 @@ static void 
disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
 }
 }
 
-static void handle_3same_64(DisasContext *s, int opcode, bool u,
-TCGv_i64 tcg_rd, TCGv_i64 tcg_rn, TCGv_i64 tcg_rm)
-{
-/* Handle 64x64->64 opcodes which are shared between the scalar
- * and vector 3-same groups. We cover every opcode where size == 3
- * is valid in either the three-reg-same (integer, not pairwise)
- * or scalar-three-reg-same groups.
- */
-TCGCond cond;
-
-switch (opcode) {
-case 0x6: /* CMGT, CMHI */
-cond = u ? TCG_COND_GTU : TCG_COND_GT;
-do_cmop:
-/* 64 bit integer comparison, result = test ? -1 : 0. */
-tcg_gen_negsetcond_i64(cond, tcg_rd, tcg_rn, tcg_rm);
-break;
-case 0x7: /* CMGE, CMHS */
-cond = u ? TCG_COND_GEU : TCG_COND_GE;
-goto do_cmop;
-case 0x11: /* CMTST, CMEQ */
-if (u) {
-cond = TCG_COND_EQ;
-goto do_cmop;
-}
-gen_cmtst_i64(tcg_rd, tcg_rn, tcg_rm);
-break;
-default:
-case 0x1: /* SQADD / UQADD */
-case 0x5: /* SQSUB / UQSUB */
-case 0x8: /* SSHL, USHL */
-case 0x9: /* SQSHL, UQSHL */
-case 0xa: /* SRSHL, URSHL */
-case 0xb: /* SQRSHL, UQRSHL */
-case 0x10: /* ADD, SUB */
- 

[PATCH 48/57] target/arm: Convert SHSUB, UHSUB to gvec

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h |   6 --
 target/arm/tcg/translate.h  |   4 +
 target/arm/tcg/gengvec.c| 144 
 target/arm/tcg/neon_helper.c|  27 --
 target/arm/tcg/translate-a64.c  |  17 ++--
 target/arm/tcg/translate-neon.c |   4 +-
 6 files changed, 157 insertions(+), 45 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index b26bfcb079..b95f24ed0a 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -274,12 +274,6 @@ DEF_HELPER_2(neon_rhadd_s16, i32, i32, i32)
 DEF_HELPER_2(neon_rhadd_u16, i32, i32, i32)
 DEF_HELPER_2(neon_rhadd_s32, s32, s32, s32)
 DEF_HELPER_2(neon_rhadd_u32, i32, i32, i32)
-DEF_HELPER_2(neon_hsub_s8, i32, i32, i32)
-DEF_HELPER_2(neon_hsub_u8, i32, i32, i32)
-DEF_HELPER_2(neon_hsub_s16, i32, i32, i32)
-DEF_HELPER_2(neon_hsub_u16, i32, i32, i32)
-DEF_HELPER_2(neon_hsub_s32, s32, s32, s32)
-DEF_HELPER_2(neon_hsub_u32, i32, i32, i32)
 
 DEF_HELPER_2(neon_pmin_u8, i32, i32, i32)
 DEF_HELPER_2(neon_pmin_s8, i32, i32, i32)
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index dd99d76bf2..315e0afd04 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -476,6 +476,10 @@ void gen_gvec_shadd(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
 void gen_gvec_uhadd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_shsub(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_uhsub(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
 
 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
 void gen_ushl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c
index e59deec2d9..b82de576d2 100644
--- a/target/arm/tcg/gengvec.c
+++ b/target/arm/tcg/gengvec.c
@@ -1998,3 +1998,147 @@ void gen_gvec_uhadd(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 tcg_debug_assert(vece <= MO_32);
 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, [vece]);
 }
+
+static void gen_shsub8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_andc_i64(t, b, a);
+tcg_gen_vec_sar8i_i64(a, a, 1);
+tcg_gen_vec_sar8i_i64(b, b, 1);
+tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
+tcg_gen_vec_sub8_i64(d, a, b);
+tcg_gen_vec_sub8_i64(d, d, t);
+}
+
+static void gen_shsub16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_andc_i64(t, b, a);
+tcg_gen_vec_sar16i_i64(a, a, 1);
+tcg_gen_vec_sar16i_i64(b, b, 1);
+tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
+tcg_gen_vec_sub16_i64(d, a, b);
+tcg_gen_vec_sub16_i64(d, d, t);
+}
+
+static void gen_shsub_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
+{
+TCGv_i32 t = tcg_temp_new_i32();
+
+tcg_gen_andc_i32(t, b, a);
+tcg_gen_sari_i32(a, a, 1);
+tcg_gen_sari_i32(b, b, 1);
+tcg_gen_andi_i32(t, t, 1);
+tcg_gen_sub_i32(d, a, b);
+tcg_gen_sub_i32(d, d, t);
+}
+
+static void gen_shsub_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
+{
+TCGv_vec t = tcg_temp_new_vec_matching(d);
+
+tcg_gen_andc_vec(vece, t, b, a);
+tcg_gen_sari_vec(vece, a, a, 1);
+tcg_gen_sari_vec(vece, b, b, 1);
+tcg_gen_and_vec(vece, t, t, tcg_constant_vec_matching(d, vece, 1));
+tcg_gen_sub_vec(vece, d, a, b);
+tcg_gen_sub_vec(vece, d, d, t);
+}
+
+void gen_gvec_shsub(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static const TCGOpcode vecop_list[] = {
+INDEX_op_sari_vec, INDEX_op_sub_vec, 0
+};
+static const GVecGen3 g[4] = {
+{ .fni8 = gen_shsub8_i64,
+  .fniv = gen_shsub_vec,
+  .opt_opc = vecop_list,
+  .vece = MO_8 },
+{ .fni8 = gen_shsub16_i64,
+  .fniv = gen_shsub_vec,
+  .opt_opc = vecop_list,
+  .vece = MO_16 },
+{ .fni4 = gen_shsub_i32,
+  .fniv = gen_shsub_vec,
+  .opt_opc = vecop_list,
+  .vece = MO_32 },
+};
+assert(vece <= MO_32);
+tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, [vece]);
+}
+
+static void gen_uhsub8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_andc_i64(t, b, a);
+tcg_gen_vec_shr8i_i64(a, a, 1);
+tcg_gen_vec_shr8i_i64(b, b, 1);
+tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
+tcg_gen_vec_sub8_i64(d, a, b);
+tcg_gen_vec_sub8_i64(d, d, t);
+}
+
+static void gen_uhsub16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
+{
+TCGv_i64 t = tcg_temp_new_i64();
+
+tcg_gen_andc_i64(t, b, a);
+tcg_gen_vec_shr16i_i64(a, a, 

[PATCH 22/57] target/arm: Convert FMAXP, FMINP, FMAXNMP, FMINNMP to decodetree

2024-05-05 Thread Richard Henderson
These are the last instructions within disas_simd_three_reg_same_fp16,
so remove it.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|  16 ++
 target/arm/tcg/a64.decode  |  24 +++
 target/arm/tcg/translate-a64.c | 296 ++---
 target/arm/tcg/vec_helper.c|  16 ++
 4 files changed, 107 insertions(+), 245 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 8441b49d1f..3268477329 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -1052,6 +1052,22 @@ DEF_HELPER_FLAGS_5(gvec_faddp_h, TCG_CALL_NO_RWG, void, 
ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(gvec_faddp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 DEF_HELPER_FLAGS_5(gvec_faddp_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 
+DEF_HELPER_FLAGS_5(gvec_fmaxp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_fmaxp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_fmaxp_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+
+DEF_HELPER_FLAGS_5(gvec_fminp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_fminp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_fminp_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+
+DEF_HELPER_FLAGS_5(gvec_fmaxnump_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_fmaxnump_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_fmaxnump_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+
+DEF_HELPER_FLAGS_5(gvec_fminnump_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_fminnump_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_fminnump_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+
 #ifdef TARGET_AARCH64
 #include "tcg/helper-a64.h"
 #include "tcg/helper-sve.h"
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 9d28cb5894..e6bd84c433 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -746,6 +746,18 @@ FRSQRTS_s   0101 1110 1.1 . 1 1 . . 
@rrr_sd
 FADDP_s 0101 1110 0011  1101 10 . . @rr_h
 FADDP_s 0111 1110 0.11  1101 10 . . @rr_sd
 
+FMAXP_s 0101 1110 0011   10 . . @rr_h
+FMAXP_s 0111 1110 0.11   10 . . @rr_sd
+
+FMINP_s 0101 1110 1011   10 . . @rr_h
+FMINP_s 0111 1110 1.11   10 . . @rr_sd
+
+FMAXNMP_s   0101 1110 0011  1100 10 . . @rr_h
+FMAXNMP_s   0111 1110 0.11  1100 10 . . @rr_sd
+
+FMINNMP_s   0101 1110 1011  1100 10 . . @rr_h
+FMINNMP_s   0111 1110 1.11  1100 10 . . @rr_sd
+
 ### Advanced SIMD three same
 
 FADD_v  0.00 1110 010 . 00010 1 . . @qrrr_h
@@ -808,6 +820,18 @@ FRSQRTS_v   0.00 1110 1.1 . 1 1 . . 
@qrrr_sd
 FADDP_v 0.10 1110 010 . 00010 1 . . @qrrr_h
 FADDP_v 0.10 1110 0.1 . 11010 1 . . @qrrr_sd
 
+FMAXP_v 0.10 1110 010 . 00110 1 . . @qrrr_h
+FMAXP_v 0.10 1110 0.1 . 0 1 . . @qrrr_sd
+
+FMINP_v 0.10 1110 110 . 00110 1 . . @qrrr_h
+FMINP_v 0.10 1110 1.1 . 0 1 . . @qrrr_sd
+
+FMAXNMP_v   0.10 1110 010 . 0 1 . . @qrrr_h
+FMAXNMP_v   0.10 1110 0.1 . 11000 1 . . @qrrr_sd
+
+FMINNMP_v   0.10 1110 110 . 0 1 . . @qrrr_h
+FMINNMP_v   0.10 1110 1.1 . 11000 1 . . @qrrr_sd
+
 ### Advanced SIMD scalar x indexed element
 
 FMUL_si 0101  00 ..  1001 . 0 . .   @rrx_h
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index f5ee6145b1..e7d562627d 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5218,6 +5218,34 @@ static gen_helper_gvec_3_ptr * const f_vector_faddp[3] = 
{
 };
 TRANS(FADDP_v, do_fp3_vector, a, f_vector_faddp)
 
+static gen_helper_gvec_3_ptr * const f_vector_fmaxp[3] = {
+gen_helper_gvec_fmaxp_h,
+gen_helper_gvec_fmaxp_s,
+gen_helper_gvec_fmaxp_d,
+};
+TRANS(FMAXP_v, do_fp3_vector, a, f_vector_fmaxp)
+
+static gen_helper_gvec_3_ptr * const f_vector_fminp[3] = {
+gen_helper_gvec_fminp_h,
+gen_helper_gvec_fminp_s,
+gen_helper_gvec_fminp_d,
+};
+TRANS(FMINP_v, do_fp3_vector, a, f_vector_fminp)
+
+static gen_helper_gvec_3_ptr * const f_vector_fmaxnmp[3] = {
+gen_helper_gvec_fmaxnump_h,
+gen_helper_gvec_fmaxnump_s,
+gen_helper_gvec_fmaxnump_d,
+};
+TRANS(FMAXNMP_v, do_fp3_vector, a, f_vector_fmaxnmp)
+
+static gen_helper_gvec_3_ptr * const f_vector_fminnmp[3] = {
+gen_helper_gvec_fminnump_h,
+gen_helper_gvec_fminnump_s,
+gen_helper_gvec_fminnump_d,
+};
+TRANS(FMINNMP_v, do_fp3_vector, a, f_vector_fminnmp)
+
 /*
  * Advanced SIMD scalar/vector x indexed element
  */
@@ 

[PATCH 25/57] target/arm: Use gvec for neon padd

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h | 2 --
 target/arm/tcg/neon_helper.c| 5 -
 target/arm/tcg/translate-neon.c | 3 +--
 3 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index d3579a101f..51ed49aa50 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -354,8 +354,6 @@ DEF_HELPER_3(neon_qrshl_s64, i64, env, i64, i64)
 
 DEF_HELPER_2(neon_add_u8, i32, i32, i32)
 DEF_HELPER_2(neon_add_u16, i32, i32, i32)
-DEF_HELPER_2(neon_padd_u8, i32, i32, i32)
-DEF_HELPER_2(neon_padd_u16, i32, i32, i32)
 DEF_HELPER_2(neon_sub_u8, i32, i32, i32)
 DEF_HELPER_2(neon_sub_u16, i32, i32, i32)
 DEF_HELPER_2(neon_mul_u8, i32, i32, i32)
diff --git a/target/arm/tcg/neon_helper.c b/target/arm/tcg/neon_helper.c
index bc6c4a54e9..a0b51c8809 100644
--- a/target/arm/tcg/neon_helper.c
+++ b/target/arm/tcg/neon_helper.c
@@ -745,11 +745,6 @@ uint32_t HELPER(neon_add_u16)(uint32_t a, uint32_t b)
 return (a + b) ^ mask;
 }
 
-#define NEON_FN(dest, src1, src2) dest = src1 + src2
-NEON_POP(padd_u8, neon_u8, 4)
-NEON_POP(padd_u16, neon_u16, 2)
-#undef NEON_FN
-
 #define NEON_FN(dest, src1, src2) dest = src1 - src2
 NEON_VOP(sub_u8, neon_u8, 4)
 NEON_VOP(sub_u16, neon_u16, 2)
diff --git a/target/arm/tcg/translate-neon.c b/target/arm/tcg/translate-neon.c
index 2326a05a0a..6c5a7a98e1 100644
--- a/target/arm/tcg/translate-neon.c
+++ b/target/arm/tcg/translate-neon.c
@@ -830,6 +830,7 @@ DO_3SAME_NO_SZ_3(VABD_S, gen_gvec_sabd)
 DO_3SAME_NO_SZ_3(VABA_S, gen_gvec_saba)
 DO_3SAME_NO_SZ_3(VABD_U, gen_gvec_uabd)
 DO_3SAME_NO_SZ_3(VABA_U, gen_gvec_uaba)
+DO_3SAME_NO_SZ_3(VPADD, gen_gvec_addp)
 
 #define DO_3SAME_CMP(INSN, COND)\
 static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
@@ -1070,13 +1071,11 @@ static bool do_3same_pair(DisasContext *s, arg_3same 
*a, NeonGenTwoOpFn *fn)
 #define gen_helper_neon_pmax_u32  tcg_gen_umax_i32
 #define gen_helper_neon_pmin_s32  tcg_gen_smin_i32
 #define gen_helper_neon_pmin_u32  tcg_gen_umin_i32
-#define gen_helper_neon_padd_u32  tcg_gen_add_i32
 
 DO_3SAME_PAIR(VPMAX_S, pmax_s)
 DO_3SAME_PAIR(VPMIN_S, pmin_s)
 DO_3SAME_PAIR(VPMAX_U, pmax_u)
 DO_3SAME_PAIR(VPMIN_U, pmin_u)
-DO_3SAME_PAIR(VPADD, padd_u)
 
 #define DO_3SAME_VQDMULH(INSN, FUNC)\
 WRAP_ENV_FN(gen_##INSN##_tramp16, gen_helper_neon_##FUNC##_s16);\
-- 
2.34.1




[PATCH 13/57] target/arm: Convert FADD, FSUB, FDIV, FMUL to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/helper-a64.h|   4 +
 target/arm/tcg/translate.h |   5 +
 target/arm/tcg/a64.decode  |  27 +
 target/arm/tcg/translate-a64.c | 205 +
 target/arm/tcg/vec_helper.c|   4 +
 5 files changed, 143 insertions(+), 102 deletions(-)

diff --git a/target/arm/tcg/helper-a64.h b/target/arm/tcg/helper-a64.h
index b79751a717..371388f61b 100644
--- a/target/arm/tcg/helper-a64.h
+++ b/target/arm/tcg/helper-a64.h
@@ -133,6 +133,10 @@ DEF_HELPER_4(cpyfp, void, env, i32, i32, i32)
 DEF_HELPER_4(cpyfm, void, env, i32, i32, i32)
 DEF_HELPER_4(cpyfe, void, env, i32, i32, i32)
 
+DEF_HELPER_FLAGS_5(gvec_fdiv_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_fdiv_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_fdiv_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
+
 DEF_HELPER_FLAGS_5(gvec_fmulx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 DEF_HELPER_FLAGS_5(gvec_fmulx_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 DEF_HELPER_FLAGS_5(gvec_fmulx_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index 80e85096a8..ecfa242eef 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -252,6 +252,11 @@ static inline int shl_12(DisasContext *s, int x)
 return x << 12;
 }
 
+static inline int xor_2(DisasContext *s, int x)
+{
+return x ^ 2;
+}
+
 static inline int neon_3same_fp_size(DisasContext *s, int x)
 {
 /* Convert 0==fp32, 1==fp16 into a MO_* value */
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index e28f58bd9a..828ea2d62a 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -21,6 +21,7 @@
 
 %rd 0:5
 %esz_sd 22:1 !function=plus_2
+%esz_hsd22:2 !function=xor_2
 %hl 11:1 21:1
 %hlm11:1 20:2
 
@@ -37,6 +38,7 @@
 
 @rrr_h   ... rm:5 .. rn:5 rd:5  _e esz=1
 @rrr_sd  ... rm:5 .. rn:5 rd:5  _e esz=%esz_sd
+@rrr_hsd ... rm:5 .. rn:5 rd:5  _e esz=%esz_hsd
 
 @rrx_h   .. .. rm:4  . . rn:5 rd:5  _e esz=1 idx=%hlm
 @rrx_s   .. . rm:5   . . rn:5 rd:5  _e esz=2 idx=%hl
@@ -697,22 +699,47 @@ INS_element 0 1   10 1110 000 di:5  0 si:4 1 rn:5 rd:5
 
 ### Advanced SIMD scalar three same
 
+FADD_s  0001 1110 ..1 . 0010 10 . . @rrr_hsd
+FSUB_s  0001 1110 ..1 . 0011 10 . . @rrr_hsd
+FDIV_s  0001 1110 ..1 . 0001 10 . . @rrr_hsd
+FMUL_s  0001 1110 ..1 .  10 . . @rrr_hsd
+
 FMULX_s 0101 1110 010 . 00011 1 . . @rrr_h
 FMULX_s 0101 1110 0.1 . 11011 1 . . @rrr_sd
 
 ### Advanced SIMD three same
 
+FADD_v  0.00 1110 010 . 00010 1 . . @qrrr_h
+FADD_v  0.00 1110 0.1 . 11010 1 . . @qrrr_sd
+
+FSUB_v  0.00 1110 110 . 00010 1 . . @qrrr_h
+FSUB_v  0.00 1110 1.1 . 11010 1 . . @qrrr_sd
+
+FDIV_v  0.10 1110 010 . 00111 1 . . @qrrr_h
+FDIV_v  0.10 1110 0.1 . 1 1 . . @qrrr_sd
+
+FMUL_v  0.10 1110 010 . 00011 1 . . @qrrr_h
+FMUL_v  0.10 1110 0.1 . 11011 1 . . @qrrr_sd
+
 FMULX_v 0.00 0111 010 . 00011 1 . . @qrrr_h
 FMULX_v 0.00 1110 0.1 . 11011 1 . . @qrrr_sd
 
 ### Advanced SIMD scalar x indexed element
 
+FMUL_si 0101  00 ..  1001 . 0 . .   @rrx_h
+FMUL_si 0101  10 . . 1001 . 0 . .   @rrx_s
+FMUL_si 0101  11 0 . 1001 . 0 . .   @rrx_d
+
 FMULX_si0111  00 ..  1001 . 0 . .   @rrx_h
 FMULX_si0111  10 . . 1001 . 0 . .   @rrx_s
 FMULX_si0111  11 0 . 1001 . 0 . .   @rrx_d
 
 ### Advanced SIMD vector x indexed element
 
+FMUL_vi 0.00  00 ..  1001 . 0 . .   @qrrx_h
+FMUL_vi 0.00  10 . . 1001 . 0 . .   @qrrx_s
+FMUL_vi 0.00  11 0 . 1001 . 0 . .   @qrrx_d
+
 FMULX_vi0.10  00 ..  1001 . 0 . .   @qrrx_h
 FMULX_vi0.10  10 . . 1001 . 0 . .   @qrrx_s
 FMULX_vi0.10  11 0 . 1001 . 0 . .   @qrrx_d
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 33da0c5f0f..f3b037a7c6 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -4888,6 +4888,34 @@ static bool do_fp3_scalar(DisasContext *s, arg_rrr_e *a, 
const FPScalar *f)
 return true;
 }
 
+static const FPScalar f_scalar_fadd = {
+gen_helper_vfp_addh,
+gen_helper_vfp_adds,
+gen_helper_vfp_addd,
+};
+TRANS(FADD_s, do_fp3_scalar, a, _scalar_fadd)
+
+static const FPScalar 

[PATCH 37/57] target/arm: Convert SRSHL and URSHL (register) to gvec

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h | 10 +
 target/arm/tcg/translate.h  |  4 
 target/arm/tcg/neon-dp.decode   | 10 ++---
 target/arm/tcg/gengvec.c| 22 +++
 target/arm/tcg/neon_helper.c| 38 -
 target/arm/tcg/translate-a64.c  | 17 ++-
 target/arm/tcg/translate-neon.c |  6 ++
 7 files changed, 84 insertions(+), 23 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index a14c040451..25eb7bf5df 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -327,6 +327,16 @@ DEF_HELPER_3(neon_qrshl_s32, i32, env, i32, i32)
 DEF_HELPER_3(neon_qrshl_u64, i64, env, i64, i64)
 DEF_HELPER_3(neon_qrshl_s64, i64, env, i64, i64)
 
+DEF_HELPER_FLAGS_4(gvec_srshl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_srshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_srshl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_srshl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(gvec_urshl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_urshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_urshl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_urshl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
 DEF_HELPER_2(neon_add_u8, i32, i32, i32)
 DEF_HELPER_2(neon_add_u16, i32, i32, i32)
 DEF_HELPER_2(neon_sub_u8, i32, i32, i32)
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index 87439dcc61..ea63ffc47b 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -459,6 +459,10 @@ void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
 void gen_gvec_ushl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_srshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_urshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
 
 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
 void gen_ushl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
diff --git a/target/arm/tcg/neon-dp.decode b/target/arm/tcg/neon-dp.decode
index fd3a01bfa0..8525c65c0d 100644
--- a/target/arm/tcg/neon-dp.decode
+++ b/target/arm/tcg/neon-dp.decode
@@ -117,14 +117,8 @@ VSHL_U_3s 001 1 0 . ..   0100 . . . 0 
 @3same_rev
   VQSHL_U64_3s    001 1 0 . ..   0100 . . . 1  @3same_64_rev
   VQSHL_U_3s  001 1 0 . ..   0100 . . . 1  @3same_rev
 }
-{
-  VRSHL_S64_3s    001 0 0 . ..   0101 . . . 0  @3same_64_rev
-  VRSHL_S_3s  001 0 0 . ..   0101 . . . 0  @3same_rev
-}
-{
-  VRSHL_U64_3s    001 1 0 . ..   0101 . . . 0  @3same_64_rev
-  VRSHL_U_3s  001 1 0 . ..   0101 . . . 0  @3same_rev
-}
+VRSHL_S_3s    001 0 0 . ..   0101 . . . 0  @3same_rev
+VRSHL_U_3s    001 1 0 . ..   0101 . . . 0  @3same_rev
 {
   VQRSHL_S64_3s   001 0 0 . ..   0101 . . . 1  @3same_64_rev
   VQRSHL_S_3s 001 0 0 . ..   0101 . . . 1  @3same_rev
diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c
index 66a514ba86..d9a9132722 100644
--- a/target/arm/tcg/gengvec.c
+++ b/target/arm/tcg/gengvec.c
@@ -1217,6 +1217,28 @@ void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, [vece]);
 }
 
+void gen_gvec_srshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static gen_helper_gvec_3 * const fns[] = {
+gen_helper_gvec_srshl_b, gen_helper_gvec_srshl_h,
+gen_helper_gvec_srshl_s, gen_helper_gvec_srshl_d,
+};
+tcg_debug_assert(vece <= MO_64);
+tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, 0, fns[vece]);
+}
+
+void gen_gvec_urshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static gen_helper_gvec_3 * const fns[] = {
+gen_helper_gvec_urshl_b, gen_helper_gvec_urshl_h,
+gen_helper_gvec_urshl_s, gen_helper_gvec_urshl_d,
+};
+tcg_debug_assert(vece <= MO_64);
+tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, 0, fns[vece]);
+}
+
 void gen_uqadd_bhs(TCGv_i64 res, TCGv_i64 qc, TCGv_i64 a, TCGv_i64 b, MemOp 
esz)
 {
 uint64_t max = MAKE_64BIT_MASK(0, 8 << esz);
diff --git a/target/arm/tcg/neon_helper.c b/target/arm/tcg/neon_helper.c
index 0af15e9f6e..516ecc1dcb 100644
--- a/target/arm/tcg/neon_helper.c
+++ b/target/arm/tcg/neon_helper.c
@@ -6,10 +6,11 @@

[PATCH 14/57] target/arm: Convert FMAX, FMIN, FMAXNM, FMINNM to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|   4 +
 target/arm/tcg/a64.decode  |  17 
 target/arm/tcg/translate-a64.c | 168 +
 target/arm/tcg/vec_helper.c|   4 +
 4 files changed, 113 insertions(+), 80 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 2b02733305..7ee15b9651 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -748,15 +748,19 @@ DEF_HELPER_FLAGS_5(gvec_facgt_s, TCG_CALL_NO_RWG, void, 
ptr, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_5(gvec_fmax_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(gvec_fmax_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_fmax_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_5(gvec_fmin_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(gvec_fmin_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_fmin_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_5(gvec_fmaxnum_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 DEF_HELPER_FLAGS_5(gvec_fmaxnum_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_fmaxnum_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 
 DEF_HELPER_FLAGS_5(gvec_fminnum_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 DEF_HELPER_FLAGS_5(gvec_fminnum_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(gvec_fminnum_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 
 DEF_HELPER_FLAGS_5(gvec_recps_nf_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 DEF_HELPER_FLAGS_5(gvec_recps_nf_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 828ea2d62a..4d72fafae7 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -704,6 +704,11 @@ FSUB_s  0001 1110 ..1 . 0011 10 . . 
@rrr_hsd
 FDIV_s  0001 1110 ..1 . 0001 10 . . @rrr_hsd
 FMUL_s  0001 1110 ..1 .  10 . . @rrr_hsd
 
+FMAX_s  0001 1110 ..1 . 0100 10 . . @rrr_hsd
+FMIN_s  0001 1110 ..1 . 0101 10 . . @rrr_hsd
+FMAXNM_s0001 1110 ..1 . 0110 10 . . @rrr_hsd
+FMINNM_s0001 1110 ..1 . 0111 10 . . @rrr_hsd
+
 FMULX_s 0101 1110 010 . 00011 1 . . @rrr_h
 FMULX_s 0101 1110 0.1 . 11011 1 . . @rrr_sd
 
@@ -721,6 +726,18 @@ FDIV_v  0.10 1110 0.1 . 1 1 . . 
@qrrr_sd
 FMUL_v  0.10 1110 010 . 00011 1 . . @qrrr_h
 FMUL_v  0.10 1110 0.1 . 11011 1 . . @qrrr_sd
 
+FMAX_v  0.00 1110 010 . 00110 1 . . @qrrr_h
+FMAX_v  0.00 1110 0.1 . 0 1 . . @qrrr_sd
+
+FMIN_v  0.00 1110 110 . 00110 1 . . @qrrr_h
+FMIN_v  0.00 1110 1.1 . 0 1 . . @qrrr_sd
+
+FMAXNM_v0.00 1110 010 . 0 1 . . @qrrr_h
+FMAXNM_v0.00 1110 0.1 . 11000 1 . . @qrrr_sd
+
+FMINNM_v0.00 1110 110 . 0 1 . . @qrrr_h
+FMINNM_v0.00 1110 1.1 . 11000 1 . . @qrrr_sd
+
 FMULX_v 0.00 0111 010 . 00011 1 . . @qrrr_h
 FMULX_v 0.00 1110 0.1 . 11011 1 . . @qrrr_sd
 
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index f3b037a7c6..c7b379385f 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -4916,6 +4916,34 @@ static const FPScalar f_scalar_fmul = {
 };
 TRANS(FMUL_s, do_fp3_scalar, a, _scalar_fmul)
 
+static const FPScalar f_scalar_fmax = {
+gen_helper_advsimd_maxh,
+gen_helper_vfp_maxs,
+gen_helper_vfp_maxd,
+};
+TRANS(FMAX_s, do_fp3_scalar, a, _scalar_fmax)
+
+static const FPScalar f_scalar_fmin = {
+gen_helper_advsimd_minh,
+gen_helper_vfp_mins,
+gen_helper_vfp_mind,
+};
+TRANS(FMIN_s, do_fp3_scalar, a, _scalar_fmin)
+
+static const FPScalar f_scalar_fmaxnm = {
+gen_helper_advsimd_maxnumh,
+gen_helper_vfp_maxnums,
+gen_helper_vfp_maxnumd,
+};
+TRANS(FMAXNM_s, do_fp3_scalar, a, _scalar_fmaxnm)
+
+static const FPScalar f_scalar_fminnm = {
+gen_helper_advsimd_minnumh,
+gen_helper_vfp_minnums,
+gen_helper_vfp_minnumd,
+};
+TRANS(FMINNM_s, do_fp3_scalar, a, _scalar_fminnm)
+
 static const FPScalar f_scalar_fmulx = {
 gen_helper_advsimd_mulxh,
 gen_helper_vfp_mulxs,
@@ -4979,6 +5007,34 @@ static gen_helper_gvec_3_ptr * const f_vector_fmul[3] = {
 };
 TRANS(FMUL_v, do_fp3_vector, a, f_vector_fmul)
 
+static gen_helper_gvec_3_ptr * const f_vector_fmax[3] = {
+gen_helper_gvec_fmax_h,
+gen_helper_gvec_fmax_s,
+gen_helper_gvec_fmax_d,
+};
+TRANS(FMAX_v, do_fp3_vector, a, f_vector_fmax)
+
+static gen_helper_gvec_3_ptr * const f_vector_fmin[3] = {
+gen_helper_gvec_fmin_h,
+gen_helper_gvec_fmin_s,
+

[PATCH 26/57] target/arm: Convert SMAXP, SMINP, UMAXP, UMINP to decodetree

2024-05-05 Thread Richard Henderson
These are the last instructions within handle_simd_3same_pair
so remove it.

Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|  16 +
 target/arm/tcg/translate.h |   8 +++
 target/arm/tcg/a64.decode  |   4 ++
 target/arm/tcg/gengvec.c   |  48 +
 target/arm/tcg/translate-a64.c | 119 +
 target/arm/tcg/vec_helper.c|  16 +
 6 files changed, 109 insertions(+), 102 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 51ed49aa50..f830531dd3 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -1064,6 +1064,22 @@ DEF_HELPER_FLAGS_4(gvec_addp_h, TCG_CALL_NO_RWG, void, 
ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_addp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_addp_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 
+DEF_HELPER_FLAGS_4(gvec_smaxp_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_smaxp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_smaxp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(gvec_sminp_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_sminp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_sminp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(gvec_umaxp_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_umaxp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_umaxp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(gvec_uminp_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_uminp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_uminp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
 #ifdef TARGET_AARCH64
 #include "tcg/helper-a64.h"
 #include "tcg/helper-sve.h"
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index 04771f483b..3abdbedfe5 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -516,6 +516,14 @@ void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 
 void gen_gvec_addp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_smaxp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_sminp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_umaxp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_gvec_uminp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
 
 /*
  * Forward to the isar_feature_* tests given a DisasContext pointer.
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index ed3603b92f..16e9675335 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -837,6 +837,10 @@ FMINNMP_v   0.10 1110 110 . 0 1 . . 
@qrrr_h
 FMINNMP_v   0.10 1110 1.1 . 11000 1 . . @qrrr_sd
 
 ADDP_v  0.00 1110 ..1 . 10111 1 . . @qrrr_e
+SMAXP_v 0.00 1110 ..1 . 10100 1 . . @qrrr_e
+SMINP_v 0.00 1110 ..1 . 10101 1 . . @qrrr_e
+UMAXP_v 0.10 1110 ..1 . 10100 1 . . @qrrr_e
+UMINP_v 0.10 1110 ..1 . 10101 1 . . @qrrr_e
 
 ### Advanced SIMD scalar x indexed element
 
diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c
index f010dd5a0e..22c9d17dce 100644
--- a/target/arm/tcg/gengvec.c
+++ b/target/arm/tcg/gengvec.c
@@ -1622,3 +1622,51 @@ void gen_gvec_addp(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 };
 tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, 0, fns[vece]);
 }
+
+void gen_gvec_smaxp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static gen_helper_gvec_3 * const fns[4] = {
+gen_helper_gvec_smaxp_b,
+gen_helper_gvec_smaxp_h,
+gen_helper_gvec_smaxp_s,
+};
+tcg_debug_assert(vece <= MO_32);
+tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, 0, fns[vece]);
+}
+
+void gen_gvec_sminp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static gen_helper_gvec_3 * const fns[4] = {
+gen_helper_gvec_sminp_b,
+gen_helper_gvec_sminp_h,
+gen_helper_gvec_sminp_s,
+};
+tcg_debug_assert(vece <= MO_32);
+tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, 0, fns[vece]);
+}
+
+void gen_gvec_umaxp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static gen_helper_gvec_3 * 

[PATCH 11/57] target/arm: Convert Advanced SIMD copy to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  13 +
 target/arm/tcg/translate-a64.c | 426 +++--
 2 files changed, 152 insertions(+), 287 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 7f354af25d..d5bfeae7a8 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -658,3 +658,16 @@ SM3TT2B 11001110 010 . 10 .. 11 . . 
@crypto3i
 ### Cryptographic XAR
 
 XAR 1100 1110 100 rm:5 imm:6 rn:5 rd:5
+
+### Advanced SIMD scalar copy
+
+DUP_element_s   0101 1110 000 imm:5 0  1 rn:5 rd:5
+
+### Advanced SIMD copy
+
+DUP_element_v   0 q:1 00 1110 000 imm:5 0  1 rn:5 rd:5
+DUP_general 0 q:1 00 1110 000 imm:5 0 0001 1 rn:5 rd:5
+INS_general 0 1   00 1110 000 imm:5 0 0011 1 rn:5 rd:5
+SMOV0 q:1 00 1110 000 imm:5 0 0101 1 rn:5 rd:5
+UMOV0 q:1 00 1110 000 imm:5 0 0111 1 rn:5 rd:5
+INS_element 0 1   10 1110 000 di:5  0 si:4 1 rn:5 rd:5
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 5e99b6494e..4860b59d18 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -4703,6 +4703,145 @@ static bool trans_XAR(DisasContext *s, arg_XAR *a)
 return true;
 }
 
+/*
+ * Advanced SIMD copy
+ */
+
+static bool decode_esz_idx(int imm, MemOp *pesz, unsigned *pidx)
+{
+unsigned esz = ctz32(imm);
+if (esz <= MO_64) {
+*pesz = esz;
+*pidx = imm >> (esz + 1);
+return true;
+}
+return false;
+}
+
+static bool trans_DUP_element_s(DisasContext *s, arg_DUP_element_s *a)
+{
+MemOp esz;
+unsigned idx;
+
+if (!decode_esz_idx(a->imm, , )) {
+return false;
+}
+if (fp_access_check(s)) {
+/*
+ * This instruction just extracts the specified element and
+ * zero-extends it into the bottom of the destination register.
+ */
+TCGv_i64 tmp = tcg_temp_new_i64();
+read_vec_element(s, tmp, a->rn, idx, esz);
+write_fp_dreg(s, a->rd, tmp);
+}
+return true;
+}
+
+static bool trans_DUP_element_v(DisasContext *s, arg_DUP_element_v *a)
+{
+MemOp esz;
+unsigned idx;
+
+if (!decode_esz_idx(a->imm, , )) {
+return false;
+}
+if (esz == MO_64 && !a->q) {
+return false;
+}
+if (fp_access_check(s)) {
+tcg_gen_gvec_dup_mem(esz, vec_full_reg_offset(s, a->rd),
+ vec_reg_offset(s, a->rn, idx, esz),
+ a->q ? 16 : 8, vec_full_reg_size(s));
+}
+return true;
+}
+
+static bool trans_DUP_general(DisasContext *s, arg_DUP_general *a)
+{
+MemOp esz;
+unsigned idx;
+
+if (!decode_esz_idx(a->imm, , )) {
+return false;
+}
+if (esz == MO_64 && !a->q) {
+return false;
+}
+if (fp_access_check(s)) {
+tcg_gen_gvec_dup_i64(esz, vec_full_reg_offset(s, a->rd),
+ a->q ? 16 : 8, vec_full_reg_size(s),
+ cpu_reg(s, a->rn));
+}
+return true;
+}
+
+static bool do_smov_umov(DisasContext *s, arg_SMOV *a, MemOp is_signed)
+{
+MemOp esz;
+unsigned idx;
+
+if (!decode_esz_idx(a->imm, , )) {
+return false;
+}
+if (is_signed) {
+if (esz == MO_64 || (esz == MO_32 && !a->q)) {
+return false;
+}
+} else {
+if (esz == MO_64 ? !a->q : a->q) {
+return false;
+}
+}
+if (fp_access_check(s)) {
+TCGv_i64 tcg_rd = cpu_reg(s, a->rd);
+read_vec_element(s, tcg_rd, a->rn, idx, esz | is_signed);
+if (is_signed && !a->q) {
+tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
+}
+}
+return true;
+}
+
+TRANS(SMOV, do_smov_umov, a, MO_SIGN)
+TRANS(UMOV, do_smov_umov, a, 0)
+
+static bool trans_INS_general(DisasContext *s, arg_INS_general *a)
+{
+MemOp esz;
+unsigned idx;
+
+if (!decode_esz_idx(a->imm, , )) {
+return false;
+}
+if (fp_access_check(s)) {
+write_vec_element(s, cpu_reg(s, a->rn), a->rd, idx, esz);
+clear_vec_high(s, true, a->rd);
+}
+return true;
+}
+
+static bool trans_INS_element(DisasContext *s, arg_INS_element *a)
+{
+MemOp esz;
+unsigned didx, sidx;
+
+if (!decode_esz_idx(a->di, , )) {
+return false;
+}
+sidx = a->si >> esz;
+if (fp_access_check(s)) {
+TCGv_i64 tmp = tcg_temp_new_i64();
+
+read_vec_element(s, tmp, a->rn, sidx, esz);
+write_vec_element(s, tmp, a->rd, didx, esz);
+
+/* INS is considered a 128-bit write for SVE. */
+clear_vec_high(s, true, a->rd);
+}
+return true;
+}
+
 /* Shift a TCGv src by TCGv shift_amount, put result in dst.
  * Note that it is the caller's responsibility to ensure that the
  * shift amount is in range (ie 0..31 or 0..63) and provide the ARM
@@ -7761,268 +7900,6 @@ static void disas_simd_across_lanes(DisasContext 

[PATCH 20/57] target/arm: Convert FRECPS, FRSQRTS to decodetree

2024-05-05 Thread Richard Henderson
These are the last instructions within handle_3same_float
and disas_simd_scalar_three_reg_same_fp16 so remove them.

Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  12 ++
 target/arm/tcg/translate-a64.c | 293 -
 2 files changed, 46 insertions(+), 259 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 6aa6643d19..8d0a6a147e 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -731,6 +731,12 @@ FACGT_s 0111 1110 1.1 . 11101 1 . . 
@rrr_sd
 FABD_s  0111 1110 110 . 00010 1 . . @rrr_h
 FABD_s  0111 1110 1.1 . 11010 1 . . @rrr_sd
 
+FRECPS_s0101 1110 010 . 00111 1 . . @rrr_h
+FRECPS_s0101 1110 0.1 . 1 1 . . @rrr_sd
+
+FRSQRTS_s   0101 1110 110 . 00111 1 . . @rrr_h
+FRSQRTS_s   0101 1110 1.1 . 1 1 . . @rrr_sd
+
 ### Advanced SIMD three same
 
 FADD_v  0.00 1110 010 . 00010 1 . . @qrrr_h
@@ -784,6 +790,12 @@ FACGT_v 0.10 1110 1.1 . 11101 1 . . 
@qrrr_sd
 FABD_v  0.10 1110 110 . 00010 1 . . @qrrr_h
 FABD_v  0.10 1110 1.1 . 11010 1 . . @qrrr_sd
 
+FRECPS_v0.00 1110 010 . 00111 1 . . @qrrr_h
+FRECPS_v0.00 1110 0.1 . 1 1 . . @qrrr_sd
+
+FRSQRTS_v   0.00 1110 110 . 00111 1 . . @qrrr_h
+FRSQRTS_v   0.00 1110 1.1 . 1 1 . . @qrrr_sd
+
 ### Advanced SIMD scalar x indexed element
 
 FMUL_si 0101  00 ..  1001 . 0 . .   @rrx_h
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 5f5f62c907..d5828ba8df 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5036,6 +5036,20 @@ static const FPScalar f_scalar_fabd = {
 };
 TRANS(FABD_s, do_fp3_scalar, a, _scalar_fabd)
 
+static const FPScalar f_scalar_frecps = {
+gen_helper_recpsf_f16,
+gen_helper_recpsf_f32,
+gen_helper_recpsf_f64,
+};
+TRANS(FRECPS_s, do_fp3_scalar, a, _scalar_frecps)
+
+static const FPScalar f_scalar_frsqrts = {
+gen_helper_rsqrtsf_f16,
+gen_helper_rsqrtsf_f32,
+gen_helper_rsqrtsf_f64,
+};
+TRANS(FRSQRTS_s, do_fp3_scalar, a, _scalar_frsqrts)
+
 static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a,
   gen_helper_gvec_3_ptr * const fns[3])
 {
@@ -5183,6 +5197,20 @@ static gen_helper_gvec_3_ptr * const f_vector_fabd[3] = {
 };
 TRANS(FABD_v, do_fp3_vector, a, f_vector_fabd)
 
+static gen_helper_gvec_3_ptr * const f_vector_frecps[3] = {
+gen_helper_gvec_recps_h,
+gen_helper_gvec_recps_s,
+gen_helper_gvec_recps_d,
+};
+TRANS(FRECPS_v, do_fp3_vector, a, f_vector_frecps)
+
+static gen_helper_gvec_3_ptr * const f_vector_frsqrts[3] = {
+gen_helper_gvec_rsqrts_h,
+gen_helper_gvec_rsqrts_s,
+gen_helper_gvec_rsqrts_d,
+};
+TRANS(FRSQRTS_v, do_fp3_vector, a, f_vector_frsqrts)
+
 /*
  * Advanced SIMD scalar/vector x indexed element
  */
@@ -9302,107 +9330,6 @@ static void handle_3same_64(DisasContext *s, int 
opcode, bool u,
 }
 }
 
-/* Handle the 3-same-operands float operations; shared by the scalar
- * and vector encodings. The caller must filter out any encodings
- * not allocated for the encoding it is dealing with.
- */
-static void handle_3same_float(DisasContext *s, int size, int elements,
-   int fpopcode, int rd, int rn, int rm)
-{
-int pass;
-TCGv_ptr fpst = fpstatus_ptr(FPST_FPCR);
-
-for (pass = 0; pass < elements; pass++) {
-if (size) {
-/* Double */
-TCGv_i64 tcg_op1 = tcg_temp_new_i64();
-TCGv_i64 tcg_op2 = tcg_temp_new_i64();
-TCGv_i64 tcg_res = tcg_temp_new_i64();
-
-read_vec_element(s, tcg_op1, rn, pass, MO_64);
-read_vec_element(s, tcg_op2, rm, pass, MO_64);
-
-switch (fpopcode) {
-case 0x1f: /* FRECPS */
-gen_helper_recpsf_f64(tcg_res, tcg_op1, tcg_op2, fpst);
-break;
-case 0x3f: /* FRSQRTS */
-gen_helper_rsqrtsf_f64(tcg_res, tcg_op1, tcg_op2, fpst);
-break;
-default:
-case 0x18: /* FMAXNM */
-case 0x19: /* FMLA */
-case 0x1a: /* FADD */
-case 0x1b: /* FMULX */
-case 0x1c: /* FCMEQ */
-case 0x1e: /* FMAX */
-case 0x38: /* FMINNM */
-case 0x39: /* FMLS */
-case 0x3a: /* FSUB */
-case 0x3e: /* FMIN */
-case 0x5b: /* FMUL */
-case 0x5c: /* FCMGE */
-case 0x5d: /* FACGE */
-case 0x5f: /* FDIV */
-case 0x7a: /* FABD */
-case 0x7c: /* FCMGT */
-case 0x7d: /* FACGT */
-g_assert_not_reached();
-}
-
-write_vec_element(s, 

[PATCH 05/57] target/arm: Convert Cryptographic 2-register SHA to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  6 
 target/arm/tcg/translate-a64.c | 54 +++---
 2 files changed, 10 insertions(+), 50 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 7590659ee6..350afabc77 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -614,3 +614,9 @@ SHA1SU0 0101 1110 000 . 001100 . .  
@rrr_q1e0
 SHA256H 0101 1110 000 . 01 . .  @rrr_q1e0
 SHA256H20101 1110 000 . 010100 . .  @rrr_q1e0
 SHA256SU1   0101 1110 000 . 011000 . .  @rrr_q1e0
+
+### Cryptographic two-register SHA
+
+SHA1H   0101 1110 0010 1000  10 . . @rr_q1e0
+SHA1SU1 0101 1110 0010 1000 0001 10 . . @rr_q1e0
+SHA256SU0   0101 1110 0010 1000 0010 10 . . @rr_q1e0
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index b31e70b5d3..89f733ef12 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -4607,6 +4607,10 @@ TRANS_FEAT(SHA256H, aa64_sha256, do_gvec_op3_ool, a, 0, 
gen_helper_crypto_sha256
 TRANS_FEAT(SHA256H2, aa64_sha256, do_gvec_op3_ool, a, 0, 
gen_helper_crypto_sha256h2)
 TRANS_FEAT(SHA256SU1, aa64_sha256, do_gvec_op3_ool, a, 0, 
gen_helper_crypto_sha256su1)
 
+TRANS_FEAT(SHA1H, aa64_sha1, do_gvec_op2_ool, a, 0, gen_helper_crypto_sha1h)
+TRANS_FEAT(SHA1SU1, aa64_sha1, do_gvec_op2_ool, a, 0, 
gen_helper_crypto_sha1su1)
+TRANS_FEAT(SHA256SU0, aa64_sha256, do_gvec_op2_ool, a, 0, 
gen_helper_crypto_sha256su0)
+
 /* Shift a TCGv src by TCGv shift_amount, put result in dst.
  * Note that it is the caller's responsibility to ensure that the
  * shift amount is in range (ie 0..31 or 0..63) and provide the ARM
@@ -13500,55 +13504,6 @@ static void disas_simd_indexed(DisasContext *s, 
uint32_t insn)
 }
 }
 
-/* Crypto two-reg SHA
- *  31 24 23  22 21   17 1612 11 10 95 40
- * +-+--+---++-+--+--+
- * | 0 1 0 1 1 1 1 0 | size | 1 0 1 0 0 | opcode | 1 0 |  Rn  |  Rd  |
- * +-+--+---++-+--+--+
- */
-static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
-{
-int size = extract32(insn, 22, 2);
-int opcode = extract32(insn, 12, 5);
-int rn = extract32(insn, 5, 5);
-int rd = extract32(insn, 0, 5);
-gen_helper_gvec_2 *genfn;
-bool feature;
-
-if (size != 0) {
-unallocated_encoding(s);
-return;
-}
-
-switch (opcode) {
-case 0: /* SHA1H */
-feature = dc_isar_feature(aa64_sha1, s);
-genfn = gen_helper_crypto_sha1h;
-break;
-case 1: /* SHA1SU1 */
-feature = dc_isar_feature(aa64_sha1, s);
-genfn = gen_helper_crypto_sha1su1;
-break;
-case 2: /* SHA256SU0 */
-feature = dc_isar_feature(aa64_sha256, s);
-genfn = gen_helper_crypto_sha256su0;
-break;
-default:
-unallocated_encoding(s);
-return;
-}
-
-if (!feature) {
-unallocated_encoding(s);
-return;
-}
-
-if (!fp_access_check(s)) {
-return;
-}
-gen_gvec_op2_ool(s, true, rd, rn, 0, genfn);
-}
-
 /* Crypto three-reg SHA512
  *  31   21 20  16 15  14  13 12  11  10  95 40
  * +---+--+---+---+-++--+--+
@@ -13843,7 +13798,6 @@ static const AArch64DecodeTable data_proc_simd[] = {
 { 0x5e000400, 0xdfe08400, disas_simd_scalar_copy },
 { 0x5f00, 0xdf000400, disas_simd_indexed }, /* scalar indexed */
 { 0x5f000400, 0xdf800400, disas_simd_scalar_shift_imm },
-{ 0x5e280800, 0xff3e0c00, disas_crypto_two_reg_sha },
 { 0xce608000, 0xffe0b000, disas_crypto_three_reg_sha512 },
 { 0xcec08000, 0xf000, disas_crypto_two_reg_sha512 },
 { 0xce00, 0xff808000, disas_crypto_four_reg },
-- 
2.34.1




[PATCH 39/57] target/arm: Convert SQSHL and UQSHL (register) to gvec

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h |  8 
 target/arm/tcg/translate.h  |  4 
 target/arm/tcg/neon-dp.decode   | 10 ++---
 target/arm/tcg/gengvec.c| 24 ++
 target/arm/tcg/neon_helper.c| 36 +
 target/arm/tcg/translate-a64.c  | 17 +++-
 target/arm/tcg/translate-neon.c |  6 ++
 7 files changed, 83 insertions(+), 22 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 25eb7bf5df..f345087ddb 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -326,6 +326,14 @@ DEF_HELPER_3(neon_qrshl_u32, i32, env, i32, i32)
 DEF_HELPER_3(neon_qrshl_s32, i32, env, i32, i32)
 DEF_HELPER_3(neon_qrshl_u64, i64, env, i64, i64)
 DEF_HELPER_3(neon_qrshl_s64, i64, env, i64, i64)
+DEF_HELPER_FLAGS_5(neon_sqshl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(neon_sqshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(neon_sqshl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(neon_sqshl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(neon_uqshl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(neon_uqshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(neon_uqshl_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
+DEF_HELPER_FLAGS_5(neon_uqshl_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 
 DEF_HELPER_FLAGS_4(gvec_srshl_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(gvec_srshl_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index ea63ffc47b..6c6d4d49e7 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -463,6 +463,10 @@ void gen_gvec_srshl(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
 void gen_gvec_urshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_neon_sqshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+void gen_neon_uqshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
 
 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
 void gen_ushl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
diff --git a/target/arm/tcg/neon-dp.decode b/target/arm/tcg/neon-dp.decode
index 8525c65c0d..6d4996b8d8 100644
--- a/target/arm/tcg/neon-dp.decode
+++ b/target/arm/tcg/neon-dp.decode
@@ -109,14 +109,8 @@ VSHL_U_3s 001 1 0 . ..   0100 . . . 0 
 @3same_rev
 @3same_64_rev ... . . . 11    . q:1 . .  \
  &3same vm=%vn_dp vn=%vm_dp vd=%vd_dp size=3
 
-{
-  VQSHL_S64_3s    001 0 0 . ..   0100 . . . 1  @3same_64_rev
-  VQSHL_S_3s  001 0 0 . ..   0100 . . . 1  @3same_rev
-}
-{
-  VQSHL_U64_3s    001 1 0 . ..   0100 . . . 1  @3same_64_rev
-  VQSHL_U_3s  001 1 0 . ..   0100 . . . 1  @3same_rev
-}
+VQSHL_S_3s    001 0 0 . ..   0100 . . . 1  @3same_rev
+VQSHL_U_3s    001 1 0 . ..   0100 . . . 1  @3same_rev
 VRSHL_S_3s    001 0 0 . ..   0101 . . . 0  @3same_rev
 VRSHL_U_3s    001 1 0 . ..   0101 . . . 0  @3same_rev
 {
diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c
index d9a9132722..773dbf41d3 100644
--- a/target/arm/tcg/gengvec.c
+++ b/target/arm/tcg/gengvec.c
@@ -1239,6 +1239,30 @@ void gen_gvec_urshl(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, 0, fns[vece]);
 }
 
+void gen_neon_sqshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static gen_helper_gvec_3_ptr * const fns[] = {
+gen_helper_neon_sqshl_b, gen_helper_neon_sqshl_h,
+gen_helper_neon_sqshl_s, gen_helper_neon_sqshl_d,
+};
+tcg_debug_assert(vece <= MO_64);
+tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, tcg_env,
+   opr_sz, max_sz, 0, fns[vece]);
+}
+
+void gen_neon_uqshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static gen_helper_gvec_3_ptr * const fns[] = {
+gen_helper_neon_uqshl_b, gen_helper_neon_uqshl_h,
+gen_helper_neon_uqshl_s, gen_helper_neon_uqshl_d,
+};
+tcg_debug_assert(vece <= MO_64);
+tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, tcg_env,
+   opr_sz, max_sz, 0, fns[vece]);
+}
+
 void gen_uqadd_bhs(TCGv_i64 res, TCGv_i64 qc, TCGv_i64 a, TCGv_i64 b, MemOp 
esz)
 {
 uint64_t max = MAKE_64BIT_MASK(0, 8 << esz);
diff --git 

[PATCH 38/57] target/arm: Convert SRSHL, URSHL to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  4 
 target/arm/tcg/translate-a64.c | 22 +++---
 2 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index b98e0a5c5d..6f55e0e300 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -758,6 +758,8 @@ USQADD_s0111 1110 ..1 0 00111 0 . . 
@r2r_e
 
 SSHL_s  0101 1110 111 . 01000 1 . . @rrr_d
 USHL_s  0111 1110 111 . 01000 1 . . @rrr_d
+SRSHL_s 0101 1110 111 . 01010 1 . . @rrr_d
+URSHL_s 0111 1110 111 . 01010 1 . . @rrr_d
 
 ### Advanced SIMD scalar pairwise
 
@@ -882,6 +884,8 @@ USQADD_v0.10 1110 ..1 0 00111 0 . . 
@qr2r_e
 
 SSHL_v  0.00 1110 ..1 . 01000 1 . . @qrrr_e
 USHL_v  0.10 1110 ..1 . 01000 1 . . @qrrr_e
+SRSHL_v 0.00 1110 ..1 . 01010 1 . . @qrrr_e
+URSHL_v 0.10 1110 ..1 . 01010 1 . . @qrrr_e
 
 ### Advanced SIMD scalar x indexed element
 
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index eab28c04b9..8aa691aa30 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5117,6 +5117,8 @@ static bool do_int3_scalar_d(DisasContext *s, arg_rrr_e 
*a,
 
 TRANS(SSHL_s, do_int3_scalar_d, a, gen_sshl_i64)
 TRANS(USHL_s, do_int3_scalar_d, a, gen_ushl_i64)
+TRANS(SRSHL_s, do_int3_scalar_d, a, gen_helper_neon_rshl_s64)
+TRANS(URSHL_s, do_int3_scalar_d, a, gen_helper_neon_rshl_u64)
 
 static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a,
   gen_helper_gvec_3_ptr * const fns[3])
@@ -5365,6 +5367,8 @@ TRANS(USQADD_v, do_gvec_fn3, a, gen_gvec_usqadd_qc)
 
 TRANS(SSHL_v, do_gvec_fn3, a, gen_gvec_sshl)
 TRANS(USHL_v, do_gvec_fn3, a, gen_gvec_ushl)
+TRANS(SRSHL_v, do_gvec_fn3, a, gen_gvec_srshl)
+TRANS(URSHL_v, do_gvec_fn3, a, gen_gvec_urshl)
 
 
 /*
@@ -9378,13 +9382,6 @@ static void handle_3same_64(DisasContext *s, int opcode, 
bool u,
 gen_helper_neon_qshl_s64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
 }
 break;
-case 0xa: /* SRSHL, URSHL */
-if (u) {
-gen_helper_neon_rshl_u64(tcg_rd, tcg_rn, tcg_rm);
-} else {
-gen_helper_neon_rshl_s64(tcg_rd, tcg_rn, tcg_rm);
-}
-break;
 case 0xb: /* SQRSHL, UQRSHL */
 if (u) {
 gen_helper_neon_qrshl_u64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
@@ -9403,6 +9400,7 @@ static void handle_3same_64(DisasContext *s, int opcode, 
bool u,
 case 0x1: /* SQADD / UQADD */
 case 0x5: /* SQSUB / UQSUB */
 case 0x8: /* SSHL, USHL */
+case 0xa: /* SRSHL, URSHL */
 g_assert_not_reached();
 }
 }
@@ -9427,7 +9425,6 @@ static void disas_simd_scalar_three_reg_same(DisasContext 
*s, uint32_t insn)
 case 0x9: /* SQSHL, UQSHL */
 case 0xb: /* SQRSHL, UQRSHL */
 break;
-case 0xa: /* SRSHL, URSHL */
 case 0x6: /* CMGT, CMHI */
 case 0x7: /* CMGE, CMHS */
 case 0x11: /* CMTST, CMEQ */
@@ -9447,6 +9444,7 @@ static void disas_simd_scalar_three_reg_same(DisasContext 
*s, uint32_t insn)
 case 0x1: /* SQADD, UQADD */
 case 0x5: /* SQSUB, UQSUB */
 case 0x8: /* SSHL, USHL */
+case 0xa: /* SRSHL, URSHL */
 unallocated_encoding(s);
 return;
 }
@@ -10931,13 +10929,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 }
 
 switch (opcode) {
-case 0x0a: /* SRSHL, URSHL */
-if (u) {
-gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_urshl, size);
-} else {
-gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_srshl, size);
-}
-return;
 case 0x0c: /* SMAX, UMAX */
 if (u) {
 gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umax, size);
@@ -11019,6 +11010,7 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 case 0x01: /* SQADD, UQADD */
 case 0x05: /* SQSUB, UQSUB */
 case 0x08: /* SSHL, USHL */
+case 0x0a: /* SRSHL, URSHL */
 g_assert_not_reached();
 }
 
-- 
2.34.1




[PATCH 06/57] target/arm: Convert Cryptographic 3-register SHA512 to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  | 11 
 target/arm/tcg/translate-a64.c | 97 --
 2 files changed, 32 insertions(+), 76 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 350afabc77..c342c27608 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -31,6 +31,7 @@
 @rr_q1e0  .. rn:5 rd:5  _e q=1 esz=0
 @r2r_q1e0     .. rm:5 rd:5  _e rn=%rd q=1 
esz=0
 @rrr_q1e0    ... rm:5 .. rn:5 rd:5  _e q=1 esz=0
+@rrr_q1e3    ... rm:5 .. rn:5 rd:5  _e q=1 esz=3
 
 ### Data Processing - Immediate
 
@@ -620,3 +621,13 @@ SHA256SU1   0101 1110 000 . 011000 . .  
@rrr_q1e0
 SHA1H   0101 1110 0010 1000  10 . . @rr_q1e0
 SHA1SU1 0101 1110 0010 1000 0001 10 . . @rr_q1e0
 SHA256SU0   0101 1110 0010 1000 0010 10 . . @rr_q1e0
+
+### Cryptographic three-register SHA512
+
+SHA512H 1100 1110 011 . 10 . .  @rrr_q1e0
+SHA512H21100 1110 011 . 11 . .  @rrr_q1e0
+SHA512SU1   1100 1110 011 . 100010 . .  @rrr_q1e0
+RAX11100 1110 011 . 100011 . .  @rrr_q1e3
+SM3PARTW1   1100 1110 011 . 11 . .  @rrr_q1e0
+SM3PARTW2   1100 1110 011 . 110001 . .  @rrr_q1e0
+SM4EKEY 1100 1110 011 . 110010 . .  @rrr_q1e0
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 89f733ef12..d2d9198f22 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -1342,6 +1342,17 @@ static bool do_gvec_op3_ool(DisasContext *s, arg_qrrr_e 
*a, int data,
 return true;
 }
 
+static bool do_gvec_fn3(DisasContext *s, arg_qrrr_e *a, GVecGen3Fn *fn)
+{
+if (!a->q && a->esz == MO_64) {
+return false;
+}
+if (fp_access_check(s)) {
+gen_gvec_fn3(s, a->q, a->rd, a->rn, a->rm, fn, a->esz);
+}
+return true;
+}
+
 /*
  * This utility function is for doing register extension with an
  * optional shift. You will likely want to pass a temporary for the
@@ -4590,7 +4601,7 @@ static bool trans_EXTR(DisasContext *s, arg_extract *a)
 }
 
 /*
- * Cryptographic AES, SHA
+ * Cryptographic AES, SHA, SHA512
  */
 
 TRANS_FEAT(AESE, aa64_aes, do_gvec_op3_ool, a, 0, gen_helper_crypto_aese)
@@ -4611,6 +4622,15 @@ TRANS_FEAT(SHA1H, aa64_sha1, do_gvec_op2_ool, a, 0, 
gen_helper_crypto_sha1h)
 TRANS_FEAT(SHA1SU1, aa64_sha1, do_gvec_op2_ool, a, 0, 
gen_helper_crypto_sha1su1)
 TRANS_FEAT(SHA256SU0, aa64_sha256, do_gvec_op2_ool, a, 0, 
gen_helper_crypto_sha256su0)
 
+TRANS_FEAT(SHA512H, aa64_sha512, do_gvec_op3_ool, a, 0, 
gen_helper_crypto_sha512h)
+TRANS_FEAT(SHA512H2, aa64_sha512, do_gvec_op3_ool, a, 0, 
gen_helper_crypto_sha512h2)
+TRANS_FEAT(SHA512SU1, aa64_sha512, do_gvec_op3_ool, a, 0, 
gen_helper_crypto_sha512su1)
+TRANS_FEAT(RAX1, aa64_sha3, do_gvec_fn3, a, gen_gvec_rax1)
+TRANS_FEAT(SM3PARTW1, aa64_sm3, do_gvec_op3_ool, a, 0, 
gen_helper_crypto_sm3partw1)
+TRANS_FEAT(SM3PARTW2, aa64_sm3, do_gvec_op3_ool, a, 0, 
gen_helper_crypto_sm3partw2)
+TRANS_FEAT(SM4EKEY, aa64_sm4, do_gvec_op3_ool, a, 0, gen_helper_crypto_sm4ekey)
+
+
 /* Shift a TCGv src by TCGv shift_amount, put result in dst.
  * Note that it is the caller's responsibility to ensure that the
  * shift amount is in range (ie 0..31 or 0..63) and provide the ARM
@@ -13504,80 +13524,6 @@ static void disas_simd_indexed(DisasContext *s, 
uint32_t insn)
 }
 }
 
-/* Crypto three-reg SHA512
- *  31   21 20  16 15  14  13 12  11  10  95 40
- * +---+--+---+---+-++--+--+
- * | 1 1 0 0 1 1 1 0 0 1 1 |  Rm  | 1 | O | 0 0 | opcode |  Rn  |  Rd  |
- * +---+--+---+---+-++--+--+
- */
-static void disas_crypto_three_reg_sha512(DisasContext *s, uint32_t insn)
-{
-int opcode = extract32(insn, 10, 2);
-int o =  extract32(insn, 14, 1);
-int rm = extract32(insn, 16, 5);
-int rn = extract32(insn, 5, 5);
-int rd = extract32(insn, 0, 5);
-bool feature;
-gen_helper_gvec_3 *oolfn = NULL;
-GVecGen3Fn *gvecfn = NULL;
-
-if (o == 0) {
-switch (opcode) {
-case 0: /* SHA512H */
-feature = dc_isar_feature(aa64_sha512, s);
-oolfn = gen_helper_crypto_sha512h;
-break;
-case 1: /* SHA512H2 */
-feature = dc_isar_feature(aa64_sha512, s);
-oolfn = gen_helper_crypto_sha512h2;
-break;
-case 2: /* SHA512SU1 */
-feature = dc_isar_feature(aa64_sha512, s);
-oolfn = gen_helper_crypto_sha512su1;
-break;
-case 3: /* RAX1 */
-feature = dc_isar_feature(aa64_sha3, s);
-gvecfn = gen_gvec_rax1;
-break;
-default:
-

[PATCH 24/57] target/arm: Convert ADDP to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|   5 ++
 target/arm/tcg/translate.h |   3 +
 target/arm/tcg/a64.decode  |   6 ++
 target/arm/tcg/gengvec.c   |  12 
 target/arm/tcg/translate-a64.c | 128 ++---
 target/arm/tcg/vec_helper.c|  30 
 6 files changed, 77 insertions(+), 107 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 065460ea80..d3579a101f 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -1061,6 +1061,11 @@ DEF_HELPER_FLAGS_5(gvec_fminnump_h, TCG_CALL_NO_RWG, 
void, ptr, ptr, ptr, ptr, i
 DEF_HELPER_FLAGS_5(gvec_fminnump_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 DEF_HELPER_FLAGS_5(gvec_fminnump_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, 
i32)
 
+DEF_HELPER_FLAGS_4(gvec_addp_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_addp_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_addp_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(gvec_addp_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
 #ifdef TARGET_AARCH64
 #include "tcg/helper-a64.h"
 #include "tcg/helper-sve.h"
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index b05a9eb668..04771f483b 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -514,6 +514,9 @@ void gen_gvec_saba(unsigned vece, uint32_t rd_ofs, uint32_t 
rn_ofs,
 void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
 
+void gen_gvec_addp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+   uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
+
 /*
  * Forward to the isar_feature_* tests given a DisasContext pointer.
  */
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index e6bd84c433..ed3603b92f 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -38,6 +38,7 @@
 _eq rd rn rm ra esz
 
 @rr_h    ... . .. rn:5 rd:5 _e esz=1
+@rr_d    ... . .. rn:5 rd:5 _e esz=3
 @rr_sd   ... . .. rn:5 rd:5 _e esz=%esz_sd
 
 @rrr_h   ... rm:5 .. rn:5 rd:5  _e esz=1
@@ -56,6 +57,7 @@
 
 @qrrr_h . q:1 .. ... rm:5 .. rn:5 rd:5  _e esz=1
 @qrrr_sd. q:1 .. ... rm:5 .. rn:5 rd:5  _e esz=%esz_sd
+@qrrr_e . q:1 .. esz:2 . rm:5 .. rn:5 rd:5  _e
 
 @qrrx_h . q:1 ..  .. .. rm:4  . . rn:5 rd:5 \
 _e esz=1 idx=%hlm
@@ -758,6 +760,8 @@ FMAXNMP_s   0111 1110 0.11  1100 10 . . 
@rr_sd
 FMINNMP_s   0101 1110 1011  1100 10 . . @rr_h
 FMINNMP_s   0111 1110 1.11  1100 10 . . @rr_sd
 
+ADDP_s  0101 1110  0001 1011 10 . . @rr_d
+
 ### Advanced SIMD three same
 
 FADD_v  0.00 1110 010 . 00010 1 . . @qrrr_h
@@ -832,6 +836,8 @@ FMAXNMP_v   0.10 1110 0.1 . 11000 1 . . 
@qrrr_sd
 FMINNMP_v   0.10 1110 110 . 0 1 . . @qrrr_h
 FMINNMP_v   0.10 1110 1.1 . 11000 1 . . @qrrr_sd
 
+ADDP_v  0.00 1110 ..1 . 10111 1 . . @qrrr_e
+
 ### Advanced SIMD scalar x indexed element
 
 FMUL_si 0101  00 ..  1001 . 0 . .   @rrx_h
diff --git a/target/arm/tcg/gengvec.c b/target/arm/tcg/gengvec.c
index 7a1856253f..f010dd5a0e 100644
--- a/target/arm/tcg/gengvec.c
+++ b/target/arm/tcg/gengvec.c
@@ -1610,3 +1610,15 @@ void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, 
uint32_t rn_ofs,
 };
 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, [vece]);
 }
+
+void gen_gvec_addp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
+   uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
+{
+static gen_helper_gvec_3 * const fns[4] = {
+gen_helper_gvec_addp_b,
+gen_helper_gvec_addp_h,
+gen_helper_gvec_addp_s,
+gen_helper_gvec_addp_d,
+};
+tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, 0, fns[vece]);
+}
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index e7d562627d..2ba211f4a5 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5246,6 +5246,8 @@ static gen_helper_gvec_3_ptr * const f_vector_fminnmp[3] 
= {
 };
 TRANS(FMINNMP_v, do_fp3_vector, a, f_vector_fminnmp)
 
+TRANS(ADDP_v, do_gvec_fn3, a, gen_gvec_addp)
+
 /*
  * Advanced SIMD scalar/vector x indexed element
  */
@@ -5486,6 +5488,20 @@ TRANS(FMINP_s, do_fp3_scalar_pair, a, _scalar_fmin)
 TRANS(FMAXNMP_s, do_fp3_scalar_pair, a, _scalar_fmaxnm)
 TRANS(FMINNMP_s, do_fp3_scalar_pair, a, _scalar_fminnm)
 
+static bool trans_ADDP_s(DisasContext *s, arg_rr_e *a)
+{
+if (fp_access_check(s)) {
+TCGv_i64 t0 = tcg_temp_new_i64();
+TCGv_i64 t1 = tcg_temp_new_i64();
+
+read_vec_element(s, t0, a->rn, 0, 

[PATCH 15/57] target/arm: Expand vfp neg and abs inline

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|  6 
 target/arm/tcg/translate.h | 30 +++
 target/arm/tcg/translate-a64.c | 44 +--
 target/arm/tcg/translate-vfp.c | 54 +-
 target/arm/vfp_helper.c| 30 ---
 5 files changed, 79 insertions(+), 85 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 7ee15b9651..0fd01c9c52 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -132,12 +132,6 @@ DEF_HELPER_3(vfp_maxnumd, f64, f64, f64, ptr)
 DEF_HELPER_3(vfp_minnumh, f16, f16, f16, ptr)
 DEF_HELPER_3(vfp_minnums, f32, f32, f32, ptr)
 DEF_HELPER_3(vfp_minnumd, f64, f64, f64, ptr)
-DEF_HELPER_1(vfp_negh, f16, f16)
-DEF_HELPER_1(vfp_negs, f32, f32)
-DEF_HELPER_1(vfp_negd, f64, f64)
-DEF_HELPER_1(vfp_absh, f16, f16)
-DEF_HELPER_1(vfp_abss, f32, f32)
-DEF_HELPER_1(vfp_absd, f64, f64)
 DEF_HELPER_2(vfp_sqrth, f16, f16, env)
 DEF_HELPER_2(vfp_sqrts, f32, f32, env)
 DEF_HELPER_2(vfp_sqrtd, f64, f64, env)
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
index ecfa242eef..b05a9eb668 100644
--- a/target/arm/tcg/translate.h
+++ b/target/arm/tcg/translate.h
@@ -406,6 +406,36 @@ static inline void gen_swstep_exception(DisasContext *s, 
int isv, int ex)
  */
 uint64_t vfp_expand_imm(int size, uint8_t imm8);
 
+static inline void gen_vfp_absh(TCGv_i32 d, TCGv_i32 s)
+{
+tcg_gen_andi_i32(d, s, INT16_MAX);
+}
+
+static inline void gen_vfp_abss(TCGv_i32 d, TCGv_i32 s)
+{
+tcg_gen_andi_i32(d, s, INT32_MAX);
+}
+
+static inline void gen_vfp_absd(TCGv_i64 d, TCGv_i64 s)
+{
+tcg_gen_andi_i64(d, s, INT64_MAX);
+}
+
+static inline void gen_vfp_negh(TCGv_i32 d, TCGv_i32 s)
+{
+tcg_gen_xori_i32(d, s, 1u << 15);
+}
+
+static inline void gen_vfp_negs(TCGv_i32 d, TCGv_i32 s)
+{
+tcg_gen_xori_i32(d, s, 1u << 31);
+}
+
+static inline void gen_vfp_negd(TCGv_i64 d, TCGv_i64 s)
+{
+tcg_gen_xori_i64(d, s, 1ull << 63);
+}
+
 /* Vector operations shared between ARM and AArch64.  */
 void gen_gvec_ceq0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
uint32_t opr_sz, uint32_t max_sz);
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index c7b379385f..e6c3da5b2a 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -6592,10 +6592,10 @@ static void handle_fp_1src_half(DisasContext *s, int 
opcode, int rd, int rn)
 tcg_gen_mov_i32(tcg_res, tcg_op);
 break;
 case 0x1: /* FABS */
-tcg_gen_andi_i32(tcg_res, tcg_op, 0x7fff);
+gen_vfp_absh(tcg_res, tcg_op);
 break;
 case 0x2: /* FNEG */
-tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
+gen_vfp_negh(tcg_res, tcg_op);
 break;
 case 0x3: /* FSQRT */
 fpst = fpstatus_ptr(FPST_FPCR_F16);
@@ -6646,10 +6646,10 @@ static void handle_fp_1src_single(DisasContext *s, int 
opcode, int rd, int rn)
 tcg_gen_mov_i32(tcg_res, tcg_op);
 goto done;
 case 0x1: /* FABS */
-gen_helper_vfp_abss(tcg_res, tcg_op);
+gen_vfp_abss(tcg_res, tcg_op);
 goto done;
 case 0x2: /* FNEG */
-gen_helper_vfp_negs(tcg_res, tcg_op);
+gen_vfp_negs(tcg_res, tcg_op);
 goto done;
 case 0x3: /* FSQRT */
 gen_helper_vfp_sqrts(tcg_res, tcg_op, tcg_env);
@@ -6721,10 +6721,10 @@ static void handle_fp_1src_double(DisasContext *s, int 
opcode, int rd, int rn)
 
 switch (opcode) {
 case 0x1: /* FABS */
-gen_helper_vfp_absd(tcg_res, tcg_op);
+gen_vfp_absd(tcg_res, tcg_op);
 goto done;
 case 0x2: /* FNEG */
-gen_helper_vfp_negd(tcg_res, tcg_op);
+gen_vfp_negd(tcg_res, tcg_op);
 goto done;
 case 0x3: /* FSQRT */
 gen_helper_vfp_sqrtd(tcg_res, tcg_op, tcg_env);
@@ -6950,7 +6950,7 @@ static void handle_fp_2src_single(DisasContext *s, int 
opcode,
 switch (opcode) {
 case 0x8: /* FNMUL */
 gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst);
-gen_helper_vfp_negs(tcg_res, tcg_res);
+gen_vfp_negs(tcg_res, tcg_res);
 break;
 default:
 case 0x0: /* FMUL */
@@ -6984,7 +6984,7 @@ static void handle_fp_2src_double(DisasContext *s, int 
opcode,
 switch (opcode) {
 case 0x8: /* FNMUL */
 gen_helper_vfp_muld(tcg_res, tcg_op1, tcg_op2, fpst);
-gen_helper_vfp_negd(tcg_res, tcg_res);
+gen_vfp_negd(tcg_res, tcg_res);
 break;
 default:
 case 0x0: /* FMUL */
@@ -7018,7 +7018,7 @@ static void handle_fp_2src_half(DisasContext *s, int 
opcode,
 switch (opcode) {
 case 0x8: /* FNMUL */
 gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
-tcg_gen_xori_i32(tcg_res, tcg_res, 0x8000);
+gen_vfp_negh(tcg_res, tcg_res);
 break;
 default:
 case 0x0: /* FMUL */
@@ -7103,11 +7103,11 @@ static void handle_fp_3src_single(DisasContext *s, bool 

[PATCH 36/57] target/arm: Convert SSHL, USHL to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  7 ++
 target/arm/tcg/translate-a64.c | 40 +-
 2 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 7cea0d2721..b98e0a5c5d 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -42,6 +42,7 @@
 @rr_sd   ... . .. rn:5 rd:5 _e esz=%esz_sd
 
 @rrr_h   ... rm:5 .. rn:5 rd:5  _e esz=1
+@rrr_d   ... rm:5 .. rn:5 rd:5  _e esz=3
 @rrr_sd  ... rm:5 .. rn:5 rd:5  _e esz=%esz_sd
 @rrr_hsd ... rm:5 .. rn:5 rd:5  _e esz=%esz_hsd
 @rrr_e   esz:2 . rm:5 .. rn:5 rd:5  _e
@@ -755,6 +756,9 @@ UQSUB_s 0111 1110 ..1 . 00101 1 . . 
@rrr_e
 SUQADD_s0101 1110 ..1 0 00111 0 . . @r2r_e
 USQADD_s0111 1110 ..1 0 00111 0 . . @r2r_e
 
+SSHL_s  0101 1110 111 . 01000 1 . . @rrr_d
+USHL_s  0111 1110 111 . 01000 1 . . @rrr_d
+
 ### Advanced SIMD scalar pairwise
 
 FADDP_s 0101 1110 0011  1101 10 . . @rr_h
@@ -876,6 +880,9 @@ UQSUB_v 0.10 1110 ..1 . 00101 1 . . 
@qrrr_e
 SUQADD_v0.00 1110 ..1 0 00111 0 . . @qr2r_e
 USQADD_v0.10 1110 ..1 0 00111 0 . . @qr2r_e
 
+SSHL_v  0.00 1110 ..1 . 01000 1 . . @qrrr_e
+USHL_v  0.10 1110 ..1 . 01000 1 . . @qrrr_e
+
 ### Advanced SIMD scalar x indexed element
 
 FMUL_si 0101  00 ..  1001 . 0 . .   @rrx_h
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index ccc30d61f3..fd36137e10 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5100,6 +5100,24 @@ TRANS(UQSUB_s, do_satacc_s, a, 0, 0, gen_uqsub_bhs, 
gen_uqsub_d)
 TRANS(SUQADD_s, do_satacc_s, a, MO_SIGN, 0, gen_suqadd_bhs, gen_suqadd_d)
 TRANS(USQADD_s, do_satacc_s, a, 0, MO_SIGN, gen_usqadd_bhs, gen_usqadd_d)
 
+static bool do_int3_scalar_d(DisasContext *s, arg_rrr_e *a,
+ void (*fn)(TCGv_i64, TCGv_i64, TCGv_i64))
+{
+if (fp_access_check(s)) {
+TCGv_i64 t0 = tcg_temp_new_i64();
+TCGv_i64 t1 = tcg_temp_new_i64();
+
+read_vec_element(s, t0, a->rn, 0, MO_64);
+read_vec_element(s, t1, a->rm, 0, MO_64);
+fn(t0, t0, t1);
+write_fp_dreg(s, a->rd, t0);
+}
+return true;
+}
+
+TRANS(SSHL_s, do_int3_scalar_d, a, gen_sshl_i64)
+TRANS(USHL_s, do_int3_scalar_d, a, gen_ushl_i64)
+
 static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a,
   gen_helper_gvec_3_ptr * const fns[3])
 {
@@ -5345,6 +5363,10 @@ TRANS(UQSUB_v, do_gvec_fn3, a, gen_gvec_uqsub_qc)
 TRANS(SUQADD_v, do_gvec_fn3, a, gen_gvec_suqadd_qc)
 TRANS(USQADD_v, do_gvec_fn3, a, gen_gvec_usqadd_qc)
 
+TRANS(SSHL_v, do_gvec_fn3, a, gen_gvec_sshl)
+TRANS(USHL_v, do_gvec_fn3, a, gen_gvec_ushl)
+
+
 /*
  * Advanced SIMD scalar/vector x indexed element
  */
@@ -9349,13 +9371,6 @@ static void handle_3same_64(DisasContext *s, int opcode, 
bool u,
 }
 gen_cmtst_i64(tcg_rd, tcg_rn, tcg_rm);
 break;
-case 0x8: /* SSHL, USHL */
-if (u) {
-gen_ushl_i64(tcg_rd, tcg_rn, tcg_rm);
-} else {
-gen_sshl_i64(tcg_rd, tcg_rn, tcg_rm);
-}
-break;
 case 0x9: /* SQSHL, UQSHL */
 if (u) {
 gen_helper_neon_qshl_u64(tcg_rd, tcg_env, tcg_rn, tcg_rm);
@@ -9387,6 +9402,7 @@ static void handle_3same_64(DisasContext *s, int opcode, 
bool u,
 default:
 case 0x1: /* SQADD / UQADD */
 case 0x5: /* SQSUB / UQSUB */
+case 0x8: /* SSHL, USHL */
 g_assert_not_reached();
 }
 }
@@ -9411,7 +9427,6 @@ static void disas_simd_scalar_three_reg_same(DisasContext 
*s, uint32_t insn)
 case 0x9: /* SQSHL, UQSHL */
 case 0xb: /* SQRSHL, UQRSHL */
 break;
-case 0x8: /* SSHL, USHL */
 case 0xa: /* SRSHL, URSHL */
 case 0x6: /* CMGT, CMHI */
 case 0x7: /* CMGE, CMHS */
@@ -9431,6 +9446,7 @@ static void disas_simd_scalar_three_reg_same(DisasContext 
*s, uint32_t insn)
 default:
 case 0x1: /* SQADD, UQADD */
 case 0x5: /* SQSUB, UQSUB */
+case 0x8: /* SSHL, USHL */
 unallocated_encoding(s);
 return;
 }
@@ -10915,13 +10931,6 @@ static void disas_simd_3same_int(DisasContext *s, 
uint32_t insn)
 }
 
 switch (opcode) {
-case 0x08: /* SSHL, USHL */
-if (u) {
-gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_ushl, size);
-} else {
-gen_gvec_fn3(s, is_q, rd, rn, rm, gen_gvec_sshl, size);
-}
-return;
 case 0x0c: /* SMAX, UMAX */
 if (u) {
 gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_umax, size);
@@ -11002,6 +11011,7 @@ static void 

[PATCH 29/57] target/arm: Convert disas_simd_3same_logic to decodetree

2024-05-05 Thread Richard Henderson
This includes AND, ORR, EOR, BIC, ORN, BSF, BIT, BIF.

Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  | 10 +
 target/arm/tcg/translate-a64.c | 68 ++
 2 files changed, 29 insertions(+), 49 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 9aa4fb9bd0..d0618ca794 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -55,6 +55,7 @@
 @rrr_q1e3    ... rm:5 .. rn:5 rd:5  _e q=1 esz=3
 @_q1e3   ... rm:5 . ra:5 rn:5 rd:5  _e q=1 esz=3
 
+@qrrr_b . q:1 .. ... rm:5 .. rn:5 rd:5  _e esz=0
 @qrrr_h . q:1 .. ... rm:5 .. rn:5 rd:5  _e esz=1
 @qrrr_sd. q:1 .. ... rm:5 .. rn:5 rd:5  _e esz=%esz_sd
 @qrrr_e . q:1 .. esz:2 . rm:5 .. rn:5 rd:5  _e
@@ -847,6 +848,15 @@ SMINP_v 0.00 1110 ..1 . 10101 1 . . 
@qrrr_e
 UMAXP_v 0.10 1110 ..1 . 10100 1 . . @qrrr_e
 UMINP_v 0.10 1110 ..1 . 10101 1 . . @qrrr_e
 
+AND_v   0.00 1110 001 . 00011 1 . . @qrrr_b
+BIC_v   0.00 1110 011 . 00011 1 . . @qrrr_b
+ORR_v   0.00 1110 101 . 00011 1 . . @qrrr_b
+ORN_v   0.00 1110 111 . 00011 1 . . @qrrr_b
+EOR_v   0.10 1110 001 . 00011 1 . . @qrrr_b
+BSL_v   0.10 1110 011 . 00011 1 . . @qrrr_b
+BIT_v   0.10 1110 101 . 00011 1 . . @qrrr_b
+BIF_v   0.10 1110 111 . 00011 1 . . @qrrr_b
+
 ### Advanced SIMD scalar x indexed element
 
 FMUL_si 0101  00 ..  1001 . 0 . .   @rrx_h
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index a082ce8441..cbb63c9d30 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5281,6 +5281,24 @@ TRANS(SMINP_v, do_gvec_fn3_no64, a, gen_gvec_sminp)
 TRANS(UMAXP_v, do_gvec_fn3_no64, a, gen_gvec_umaxp)
 TRANS(UMINP_v, do_gvec_fn3_no64, a, gen_gvec_uminp)
 
+TRANS(AND_v, do_gvec_fn3, a, tcg_gen_gvec_and)
+TRANS(BIC_v, do_gvec_fn3, a, tcg_gen_gvec_andc)
+TRANS(ORR_v, do_gvec_fn3, a, tcg_gen_gvec_or)
+TRANS(ORN_v, do_gvec_fn3, a, tcg_gen_gvec_orc)
+TRANS(EOR_v, do_gvec_fn3, a, tcg_gen_gvec_xor)
+
+static bool do_bitsel(DisasContext *s, bool is_q, int d, int a, int b, int c)
+{
+if (fp_access_check(s)) {
+gen_gvec_fn4(s, is_q, d, a, b, c, tcg_gen_gvec_bitsel, 0);
+}
+return true;
+}
+
+TRANS(BSL_v, do_bitsel, a->q, a->rd, a->rd, a->rn, a->rm)
+TRANS(BIT_v, do_bitsel, a->q, a->rd, a->rm, a->rn, a->rd)
+TRANS(BIF_v, do_bitsel, a->q, a->rd, a->rm, a->rd, a->rn)
+
 /*
  * Advanced SIMD scalar/vector x indexed element
  */
@@ -10895,52 +10913,6 @@ static void disas_simd_three_reg_diff(DisasContext *s, 
uint32_t insn)
 }
 }
 
-/* Logic op (opcode == 3) subgroup of C3.6.16. */
-static void disas_simd_3same_logic(DisasContext *s, uint32_t insn)
-{
-int rd = extract32(insn, 0, 5);
-int rn = extract32(insn, 5, 5);
-int rm = extract32(insn, 16, 5);
-int size = extract32(insn, 22, 2);
-bool is_u = extract32(insn, 29, 1);
-bool is_q = extract32(insn, 30, 1);
-
-if (!fp_access_check(s)) {
-return;
-}
-
-switch (size + 4 * is_u) {
-case 0: /* AND */
-gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_and, 0);
-return;
-case 1: /* BIC */
-gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_andc, 0);
-return;
-case 2: /* ORR */
-gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_or, 0);
-return;
-case 3: /* ORN */
-gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_orc, 0);
-return;
-case 4: /* EOR */
-gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_xor, 0);
-return;
-
-case 5: /* BSL bitwise select */
-gen_gvec_fn4(s, is_q, rd, rd, rn, rm, tcg_gen_gvec_bitsel, 0);
-return;
-case 6: /* BIT, bitwise insert if true */
-gen_gvec_fn4(s, is_q, rd, rm, rn, rd, tcg_gen_gvec_bitsel, 0);
-return;
-case 7: /* BIF, bitwise insert if false */
-gen_gvec_fn4(s, is_q, rd, rm, rd, rn, tcg_gen_gvec_bitsel, 0);
-return;
-
-default:
-g_assert_not_reached();
-}
-}
-
 /* Integer op subgroup of C3.6.16. */
 static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
 {
@@ -11206,12 +11178,10 @@ static void disas_simd_three_reg_same(DisasContext 
*s, uint32_t insn)
 int opcode = extract32(insn, 11, 5);
 
 switch (opcode) {
-case 0x3: /* logic ops */
-disas_simd_3same_logic(s, insn);
-break;
 default:
 disas_simd_3same_int(s, insn);
 break;
+case 0x3: /* logic ops */
 case 0x14: /* SMAXP, UMAXP */
 case 0x15: /* SMINP, UMINP */
 case 0x17: /* ADDP */
-- 
2.34.1




[PATCH 16/57] target/arm: Convert FNMUL to decodetree

2024-05-05 Thread Richard Henderson
This is the last instruction within disas_fp_2src,
so remove that and its subroutines.

Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |   1 +
 target/arm/tcg/translate-a64.c | 177 +
 2 files changed, 27 insertions(+), 151 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 4d72fafae7..dbfdfd80f9 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -703,6 +703,7 @@ FADD_s  0001 1110 ..1 . 0010 10 . . 
@rrr_hsd
 FSUB_s  0001 1110 ..1 . 0011 10 . . @rrr_hsd
 FDIV_s  0001 1110 ..1 . 0001 10 . . @rrr_hsd
 FMUL_s  0001 1110 ..1 .  10 . . @rrr_hsd
+FNMUL_s 0001 1110 ..1 . 1000 10 . . @rrr_hsd
 
 FMAX_s  0001 1110 ..1 . 0100 10 . . @rrr_hsd
 FMIN_s  0001 1110 ..1 . 0101 10 . . @rrr_hsd
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index e6c3da5b2a..caf4d8154d 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -4951,6 +4951,31 @@ static const FPScalar f_scalar_fmulx = {
 };
 TRANS(FMULX_s, do_fp3_scalar, a, _scalar_fmulx)
 
+static void gen_fnmul_h(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, TCGv_ptr s)
+{
+gen_helper_vfp_mulh(d, n, m, s);
+gen_vfp_negh(d, d);
+}
+
+static void gen_fnmul_s(TCGv_i32 d, TCGv_i32 n, TCGv_i32 m, TCGv_ptr s)
+{
+gen_helper_vfp_muls(d, n, m, s);
+gen_vfp_negs(d, d);
+}
+
+static void gen_fnmul_d(TCGv_i64 d, TCGv_i64 n, TCGv_i64 m, TCGv_ptr s)
+{
+gen_helper_vfp_muld(d, n, m, s);
+gen_vfp_negd(d, d);
+}
+
+static const FPScalar f_scalar_fnmul = {
+gen_fnmul_h,
+gen_fnmul_s,
+gen_fnmul_d,
+};
+TRANS(FNMUL_s, do_fp3_scalar, a, _scalar_fnmul)
+
 static bool do_fp3_vector(DisasContext *s, arg_qrrr_e *a,
   gen_helper_gvec_3_ptr * const fns[3])
 {
@@ -6933,156 +6958,6 @@ static void disas_fp_1src(DisasContext *s, uint32_t 
insn)
 }
 }
 
-/* Floating-point data-processing (2 source) - single precision */
-static void handle_fp_2src_single(DisasContext *s, int opcode,
-  int rd, int rn, int rm)
-{
-TCGv_i32 tcg_op1;
-TCGv_i32 tcg_op2;
-TCGv_i32 tcg_res;
-TCGv_ptr fpst;
-
-tcg_res = tcg_temp_new_i32();
-fpst = fpstatus_ptr(FPST_FPCR);
-tcg_op1 = read_fp_sreg(s, rn);
-tcg_op2 = read_fp_sreg(s, rm);
-
-switch (opcode) {
-case 0x8: /* FNMUL */
-gen_helper_vfp_muls(tcg_res, tcg_op1, tcg_op2, fpst);
-gen_vfp_negs(tcg_res, tcg_res);
-break;
-default:
-case 0x0: /* FMUL */
-case 0x1: /* FDIV */
-case 0x2: /* FADD */
-case 0x3: /* FSUB */
-case 0x4: /* FMAX */
-case 0x5: /* FMIN */
-case 0x6: /* FMAXNM */
-case 0x7: /* FMINNM */
-g_assert_not_reached();
-}
-
-write_fp_sreg(s, rd, tcg_res);
-}
-
-/* Floating-point data-processing (2 source) - double precision */
-static void handle_fp_2src_double(DisasContext *s, int opcode,
-  int rd, int rn, int rm)
-{
-TCGv_i64 tcg_op1;
-TCGv_i64 tcg_op2;
-TCGv_i64 tcg_res;
-TCGv_ptr fpst;
-
-tcg_res = tcg_temp_new_i64();
-fpst = fpstatus_ptr(FPST_FPCR);
-tcg_op1 = read_fp_dreg(s, rn);
-tcg_op2 = read_fp_dreg(s, rm);
-
-switch (opcode) {
-case 0x8: /* FNMUL */
-gen_helper_vfp_muld(tcg_res, tcg_op1, tcg_op2, fpst);
-gen_vfp_negd(tcg_res, tcg_res);
-break;
-default:
-case 0x0: /* FMUL */
-case 0x1: /* FDIV */
-case 0x2: /* FADD */
-case 0x3: /* FSUB */
-case 0x4: /* FMAX */
-case 0x5: /* FMIN */
-case 0x6: /* FMAXNM */
-case 0x7: /* FMINNM */
-g_assert_not_reached();
-}
-
-write_fp_dreg(s, rd, tcg_res);
-}
-
-/* Floating-point data-processing (2 source) - half precision */
-static void handle_fp_2src_half(DisasContext *s, int opcode,
-int rd, int rn, int rm)
-{
-TCGv_i32 tcg_op1;
-TCGv_i32 tcg_op2;
-TCGv_i32 tcg_res;
-TCGv_ptr fpst;
-
-tcg_res = tcg_temp_new_i32();
-fpst = fpstatus_ptr(FPST_FPCR_F16);
-tcg_op1 = read_fp_hreg(s, rn);
-tcg_op2 = read_fp_hreg(s, rm);
-
-switch (opcode) {
-case 0x8: /* FNMUL */
-gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
-gen_vfp_negh(tcg_res, tcg_res);
-break;
-default:
-case 0x0: /* FMUL */
-case 0x1: /* FDIV */
-case 0x2: /* FADD */
-case 0x3: /* FSUB */
-case 0x4: /* FMAX */
-case 0x5: /* FMIN */
-case 0x6: /* FMAXNM */
-case 0x7: /* FMINNM */
-g_assert_not_reached();
-}
-
-write_fp_sreg(s, rd, tcg_res);
-}
-
-/* Floating point data-processing (2 source)
- *   31  30  29 28   24 23  22  21 20  16 1512 11 10 95 40
- * +---+---+---+---+--+---+--++-+--+--+
- * | M | 0 | 

[PATCH 10/57] target/arm: Convert XAR to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  4 
 target/arm/tcg/translate-a64.c | 43 +++---
 2 files changed, 18 insertions(+), 29 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 1292312a7f..7f354af25d 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -654,3 +654,7 @@ SM3TT1A 11001110 010 . 10 .. 00 . . 
@crypto3i
 SM3TT1B 11001110 010 . 10 .. 01 . . @crypto3i
 SM3TT2A 11001110 010 . 10 .. 10 . . @crypto3i
 SM3TT2B 11001110 010 . 10 .. 11 . . @crypto3i
+
+### Cryptographic XAR
+
+XAR 1100 1110 100 rm:5 imm:6 rn:5 rd:5
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 219a666cbb..5e99b6494e 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -4689,6 +4689,20 @@ TRANS_FEAT(SM3TT1B, aa64_sm3, do_crypto3i, a, 
gen_helper_crypto_sm3tt1b)
 TRANS_FEAT(SM3TT2A, aa64_sm3, do_crypto3i, a, gen_helper_crypto_sm3tt2a)
 TRANS_FEAT(SM3TT2B, aa64_sm3, do_crypto3i, a, gen_helper_crypto_sm3tt2b)
 
+static bool trans_XAR(DisasContext *s, arg_XAR *a)
+{
+if (!dc_isar_feature(aa64_sha3, s)) {
+return false;
+}
+if (fp_access_check(s)) {
+gen_gvec_xar(MO_64, vec_full_reg_offset(s, a->rd),
+ vec_full_reg_offset(s, a->rn),
+ vec_full_reg_offset(s, a->rm), a->imm, 16,
+ vec_full_reg_size(s));
+}
+return true;
+}
+
 /* Shift a TCGv src by TCGv shift_amount, put result in dst.
  * Note that it is the caller's responsibility to ensure that the
  * shift amount is in range (ie 0..31 or 0..63) and provide the ARM
@@ -13582,34 +13596,6 @@ static void disas_simd_indexed(DisasContext *s, 
uint32_t insn)
 }
 }
 
-/* Crypto XAR
- *  31   21 20  16 1510 95 40
- * +---+--++--+--+
- * | 1 1 0 0 1 1 1 0 1 0 0 |  Rm  |  imm6  |  Rn  |  Rd  |
- * +---+--++--+--+
- */
-static void disas_crypto_xar(DisasContext *s, uint32_t insn)
-{
-int rm = extract32(insn, 16, 5);
-int imm6 = extract32(insn, 10, 6);
-int rn = extract32(insn, 5, 5);
-int rd = extract32(insn, 0, 5);
-
-if (!dc_isar_feature(aa64_sha3, s)) {
-unallocated_encoding(s);
-return;
-}
-
-if (!fp_access_check(s)) {
-return;
-}
-
-gen_gvec_xar(MO_64, vec_full_reg_offset(s, rd),
- vec_full_reg_offset(s, rn),
- vec_full_reg_offset(s, rm), imm6, 16,
- vec_full_reg_size(s));
-}
-
 /* C3.6 Data processing - SIMD, inc Crypto
  *
  * As the decode gets a little complex we are using a table based
@@ -13638,7 +13624,6 @@ static const AArch64DecodeTable data_proc_simd[] = {
 { 0x5e000400, 0xdfe08400, disas_simd_scalar_copy },
 { 0x5f00, 0xdf000400, disas_simd_indexed }, /* scalar indexed */
 { 0x5f000400, 0xdf800400, disas_simd_scalar_shift_imm },
-{ 0xce80, 0xffe0, disas_crypto_xar },
 { 0x0e400400, 0x9f60c400, disas_simd_three_reg_same_fp16 },
 { 0x0e780800, 0x8f7e0c00, disas_simd_two_reg_misc_fp16 },
 { 0x5e400400, 0xdf60c400, disas_simd_scalar_three_reg_same_fp16 },
-- 
2.34.1




[PATCH 17/57] target/arm: Convert FMLA, FMLS to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/helper.h|   2 +
 target/arm/tcg/a64.decode  |  22 +++
 target/arm/tcg/translate-a64.c | 241 +
 target/arm/tcg/vec_helper.c|  14 ++
 4 files changed, 163 insertions(+), 116 deletions(-)

diff --git a/target/arm/helper.h b/target/arm/helper.h
index 0fd01c9c52..e021c18517 100644
--- a/target/arm/helper.h
+++ b/target/arm/helper.h
@@ -770,9 +770,11 @@ DEF_HELPER_FLAGS_5(gvec_fmls_s, TCG_CALL_NO_RWG, void, 
ptr, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_5(gvec_vfma_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(gvec_vfma_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_vfma_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_5(gvec_vfms_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_5(gvec_vfms_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(gvec_vfms_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
 
 DEF_HELPER_FLAGS_5(gvec_ftsmul_h, TCG_CALL_NO_RWG,
void, ptr, ptr, ptr, ptr, i32)
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index dbfdfd80f9..cb84a8685f 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -742,12 +742,26 @@ FMINNM_v0.00 1110 1.1 . 11000 1 . . 
@qrrr_sd
 FMULX_v 0.00 0111 010 . 00011 1 . . @qrrr_h
 FMULX_v 0.00 1110 0.1 . 11011 1 . . @qrrr_sd
 
+FMLA_v  0.00 1110 010 . 1 1 . . @qrrr_h
+FMLA_v  0.00 1110 0.1 . 11001 1 . . @qrrr_sd
+
+FMLS_v  0.00 1110 110 . 1 1 . . @qrrr_h
+FMLS_v  0.00 1110 1.1 . 11001 1 . . @qrrr_sd
+
 ### Advanced SIMD scalar x indexed element
 
 FMUL_si 0101  00 ..  1001 . 0 . .   @rrx_h
 FMUL_si 0101  10 . . 1001 . 0 . .   @rrx_s
 FMUL_si 0101  11 0 . 1001 . 0 . .   @rrx_d
 
+FMLA_si 0101  00 ..  0001 . 0 . .   @rrx_h
+FMLA_si 0101  10 ..  0001 . 0 . .   @rrx_s
+FMLA_si 0101  11 0.  0001 . 0 . .   @rrx_d
+
+FMLS_si 0101  00 ..  0101 . 0 . .   @rrx_h
+FMLS_si 0101  10 ..  0101 . 0 . .   @rrx_s
+FMLS_si 0101  11 0.  0101 . 0 . .   @rrx_d
+
 FMULX_si0111  00 ..  1001 . 0 . .   @rrx_h
 FMULX_si0111  10 . . 1001 . 0 . .   @rrx_s
 FMULX_si0111  11 0 . 1001 . 0 . .   @rrx_d
@@ -758,6 +772,14 @@ FMUL_vi 0.00  00 ..  1001 . 0 . .  
 @qrrx_h
 FMUL_vi 0.00  10 . . 1001 . 0 . .   @qrrx_s
 FMUL_vi 0.00  11 0 . 1001 . 0 . .   @qrrx_d
 
+FMLA_vi 0.00  00 ..  0001 . 0 . .   @qrrx_h
+FMLA_vi 0.00  10 . . 0001 . 0 . .   @qrrx_s
+FMLA_vi 0.00  11 0 . 0001 . 0 . .   @qrrx_d
+
+FMLS_vi 0.00  00 ..  0101 . 0 . .   @qrrx_h
+FMLS_vi 0.00  10 . . 0101 . 0 . .   @qrrx_s
+FMLS_vi 0.00  11 0 . 0101 . 0 . .   @qrrx_d
+
 FMULX_vi0.10  00 ..  1001 . 0 . .   @qrrx_h
 FMULX_vi0.10  10 . . 1001 . 0 . .   @qrrx_s
 FMULX_vi0.10  11 0 . 1001 . 0 . .   @qrrx_d
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index caf4d8154d..36aae079da 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -5067,6 +5067,20 @@ static gen_helper_gvec_3_ptr * const f_vector_fmulx[3] = 
{
 };
 TRANS(FMULX_v, do_fp3_vector, a, f_vector_fmulx)
 
+static gen_helper_gvec_3_ptr * const f_vector_fmla[3] = {
+gen_helper_gvec_vfma_h,
+gen_helper_gvec_vfma_s,
+gen_helper_gvec_vfma_d,
+};
+TRANS(FMLA_v, do_fp3_vector, a, f_vector_fmla)
+
+static gen_helper_gvec_3_ptr * const f_vector_fmls[3] = {
+gen_helper_gvec_vfms_h,
+gen_helper_gvec_vfms_s,
+gen_helper_gvec_vfms_d,
+};
+TRANS(FMLS_v, do_fp3_vector, a, f_vector_fmls)
+
 /*
  * Advanced SIMD scalar/vector x indexed element
  */
@@ -5116,6 +5130,64 @@ static bool do_fp3_scalar_idx(DisasContext *s, arg_rrx_e 
*a, const FPScalar *f)
 TRANS(FMUL_si, do_fp3_scalar_idx, a, _scalar_fmul)
 TRANS(FMULX_si, do_fp3_scalar_idx, a, _scalar_fmulx)
 
+static bool do_fmla_scalar_idx(DisasContext *s, arg_rrx_e *a, bool neg)
+{
+switch (a->esz) {
+case MO_64:
+if (fp_access_check(s)) {
+TCGv_i64 t0 = read_fp_dreg(s, a->rd);
+TCGv_i64 t1 = read_fp_dreg(s, a->rn);
+TCGv_i64 t2 = tcg_temp_new_i64();
+
+read_vec_element(s, t2, a->rm, a->idx, MO_64);
+if (neg) {
+gen_vfp_negd(t1, t1);
+}
+gen_helper_vfp_muladdd(t0, t1, t2, t0, 

[PATCH 00/57] target/arm: Convert a64 advsimd to decodetree (part 1)

2024-05-05 Thread Richard Henderson
Based-on: 20240424170908.759043-1-richard.hender...@linaro.org
("[PATCH 0/5] tcg: Misc improvements")

In the process, convert more code to gvec as well -- I will need
the gvec code for implementing SME2.  I guess this is about 1/3
of the job done, but there's no reason to wait until the patch
set is completely unwieldy.


r~


Richard Henderson (57):
  target/arm: Split out gengvec.c
  target/arm: Split out gengvec64.c
  target/arm: Convert Cryptographic AES to decodetree
  target/arm: Convert Cryptographic 3-register SHA to decodetree
  target/arm: Convert Cryptographic 2-register SHA to decodetree
  target/arm: Convert Cryptographic 3-register SHA512 to decodetree
  target/arm: Convert Cryptographic 2-register SHA512 to decodetree
  target/arm: Convert Cryptographic 4-register to decodetree
  target/arm: Convert Cryptographic 3-register, imm2 to decodetree
  target/arm: Convert XAR to decodetree
  target/arm: Convert Advanced SIMD copy to decodetree
  target/arm: Convert FMULX to decodetree
  target/arm: Convert FADD, FSUB, FDIV, FMUL to decodetree
  target/arm: Convert FMAX, FMIN, FMAXNM, FMINNM to decodetree
  target/arm: Expand vfp neg and abs inline
  target/arm: Convert FNMUL to decodetree
  target/arm: Convert FMLA, FMLS to decodetree
  target/arm: Convert FCMEQ, FCMGE, FCMGT, FACGE, FACGT to decodetree
  target/arm: Convert FABD to decodetree
  target/arm: Convert FRECPS, FRSQRTS to decodetree
  target/arm: Convert FADDP to decodetree
  target/arm: Convert FMAXP, FMINP, FMAXNMP, FMINNMP to decodetree
  target/arm: Use gvec for neon faddp, fmaxp, fminp
  target/arm: Convert ADDP to decodetree
  target/arm: Use gvec for neon padd
  target/arm: Convert SMAXP, SMINP, UMAXP, UMINP to decodetree
  target/arm: Use gvec for neon pmax, pmin
  target/arm: Convert FMLAL, FMLSL to decodetree
  target/arm: Convert disas_simd_3same_logic to decodetree
  target/arm: Improve vector UQADD, UQSUB, SQADD, SQSUB
  target/arm: Convert SUQADD and USQADD to gvec
  target/arm: Inline scalar SUQADD and USQADD
  target/arm: Inline scalar SQADD, UQADD, SQSUB, UQSUB
  target/arm: Convert SQADD, SQSUB, UQADD, UQSUB to decodetree
  target/arm: Convert SUQADD, USQADD to decodetree
  target/arm: Convert SSHL, USHL to decodetree
  target/arm: Convert SRSHL and URSHL (register) to gvec
  target/arm: Convert SRSHL, URSHL to decodetree
  target/arm: Convert SQSHL and UQSHL (register) to gvec
  target/arm: Convert SQSHL, UQSHL to decodetree
  target/arm: Convert SQRSHL and UQRSHL (register) to gvec
  target/arm: Convert SQRSHL, UQRSHL to decodetree
  target/arm: Convert ADD, SUB (vector) to decodetree
  target/arm: Convert CMGT, CMHI, CMGE, CMHS, CMTST, CMEQ to decodetree
  target/arm: Use TCG_COND_TSTNE in gen_cmtst_{i32,i64}
  target/arm: Convert SHADD, UHADD to gvec
  target/arm: Convert SHADD, UHADD to decodetree
  target/arm: Convert SHSUB, UHSUB to gvec
  target/arm: Convert SHSUB, UHSUB to decodetree
  target/arm: Convert SRHADD, URHADD to gvec
  target/arm: Convert SRHADD, URHADD to decodetree
  target/arm: Convert SMAX, SMIN, UMAX, UMIN to decodetree
  target/arm: Convert SABA, SABD, UABA, UABD to decodetree
  target/arm: Convert MUL, PMUL to decodetree
  target/arm: Convert MLA, MLS to decodetree
  target/arm: Tidy SQDMULH, SQRDMULH (vector)
  target/arm: Convert SQDMULH, SQRDMULH to decodetree

 target/arm/helper.h |  164 +-
 target/arm/tcg/helper-a64.h |   12 +
 target/arm/tcg/translate-a64.h  |   18 +
 target/arm/tcg/translate.h  |   95 +
 target/arm/tcg/a64.decode   |  416 +++-
 target/arm/tcg/neon-dp.decode   |   37 +-
 target/arm/tcg/gengvec.c| 2308 +
 target/arm/tcg/gengvec64.c  |  367 +++
 target/arm/tcg/neon_helper.c|  511 +---
 target/arm/tcg/translate-a64.c  | 4080 ++-
 target/arm/tcg/translate-neon.c |  254 +-
 target/arm/tcg/translate-sve.c  |  145 +-
 target/arm/tcg/translate-vfp.c  |   54 +-
 target/arm/tcg/translate.c  | 1588 
 target/arm/tcg/vec_helper.c |  349 ++-
 target/arm/vfp_helper.c |   30 -
 target/arm/tcg/meson.build  |2 +
 17 files changed, 5121 insertions(+), 5309 deletions(-)
 create mode 100644 target/arm/tcg/gengvec.c
 create mode 100644 target/arm/tcg/gengvec64.c

-- 
2.34.1




Re: [PATCH v3 0/3] Fix MSI-X handling for Xen HVM

2024-05-05 Thread Marek Marczykowski-Górecki
On Mon, May 06, 2024 at 02:33:19AM +0200, Marek Marczykowski-Górecki wrote:
> This series fixes handling MSI-X when device model is running in a stubdomain.
> The main part is to avoid accessing /dev/mem, which also fixes running dom0
> with lockdown enabled.
> 
> It depends on a behavior change of Xen that was just comitted, and signaled
> with a feature flag. If Xen is too old (and XENFEAT_dm_msix_all_writes flag is
> not set), fallback to the old behavior.
> 
> The other part is a fix to enforce read-only registers in the config space.
> This fixes MSI-X setup for iwlwifi Linux driver, as it happen to write to 
> MSI-X
> capability id reg (as a workaround for some older device which has another
> register there). It should be no-op, but due to a bug in xen_pt code,
> it broke MSI-X detection.
> 
> All those patches have been shipped in Qubes OS 4.2 already, and prove to fix
> the issue.
> 
> See individual commit messages for details.

Initially I sent the series with the old Anthony's address, but just in
case I forwarded it to his new address too.

> Marek Marczykowski-Górecki (3):
>   hw/xen/xen_pt: Save back data only for declared registers
>   Update Xen's features.h header
>   Do not access /dev/mem in MSI-X PCI passthrough on Xen
> 
>  hw/xen/xen_pt.c |  7 +-
>  hw/xen/xen_pt_msi.c | 94 ++
>  include/hw/xen/interface/features.h | 17 +-
>  3 files changed, 82 insertions(+), 36 deletions(-)
> 
> base-commit: 2358f1b60f73287fe606c7ff48043b4f9e1c2d0f
> -- 
> git-series 0.9.1

-- 
Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab


signature.asc
Description: PGP signature


[PATCH v3 2/3] Update Xen's features.h header

2024-05-05 Thread Marek Marczykowski-Górecki
Update it to get XENFEAT_dm_msix_all_writes for the next patch.

Signed-off-by: Marek Marczykowski-Górecki 
---
 include/hw/xen/interface/features.h | 17 +
 1 file changed, 17 insertions(+)

diff --git a/include/hw/xen/interface/features.h 
b/include/hw/xen/interface/features.h
index d2a9175..8801930 100644
--- a/include/hw/xen/interface/features.h
+++ b/include/hw/xen/interface/features.h
@@ -111,6 +111,23 @@
 #define XENFEAT_not_direct_mapped 16
 #define XENFEAT_direct_mapped 17
 
+/*
+ * Signal whether the domain is able to use the following hypercalls:
+ *
+ * VCPUOP_register_runstate_phys_area
+ * VCPUOP_register_vcpu_time_phys_area
+ */
+#define XENFEAT_runstate_phys_area18
+#define XENFEAT_vcpu_time_phys_area   19
+
+/*
+ * If set, Xen will passthrough all MSI-X vector ctrl writes to device model,
+ * not only those unmasking an entry. This allows device model to properly keep
+ * track of the MSI-X table without having to read it from the device behind
+ * Xen's backs. This information is relevant only for device models.
+ */
+#define XENFEAT_dm_msix_all_writes20
+
 #define XENFEAT_NR_SUBMAPS 1
 
 #endif /* __XEN_PUBLIC_FEATURES_H__ */
-- 
git-series 0.9.1



[PATCH v3 1/3] hw/xen/xen_pt: Save back data only for declared registers

2024-05-05 Thread Marek Marczykowski-Górecki
Call pci_default_write_config() only after resolving any handlers from
XenPTRegInfo structures, and only with a value updated with those
handlers. This is important for two reasons:
1. XenPTRegInfo has ro_mask which needs to be enforced - Xen-specific
   hooks do that on their own (especially xen_pt_*_reg_write()).
2. Not setting value early allows hooks to see the old value too.

If it would be only about the first point, setting PCIDevice.wmask would
probably be sufficient, but given the second point, change those
writes.

Relevant handlers already save data back to the emulated registers
space, call the pci_default_write_config() only for its side effects.

Signed-off-by: Marek Marczykowski-Górecki 
---
v3:
 - use emulated register value for pci_default_write_config() call, not
   the one for writting back to the hardware
 - greatly simplify the patch by calling pci_default_write_config() on
   the whole value
v2:
 - rewrite commit message, previous one was very misleading
 - fix loop saving register values
 - fix int overflow when calculating write mask
---
 hw/xen/xen_pt.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c
index 3635d1b..5f12d3c 100644
--- a/hw/xen/xen_pt.c
+++ b/hw/xen/xen_pt.c
@@ -311,7 +311,6 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t 
addr,
 }
 
 memory_region_transaction_begin();
-pci_default_write_config(d, addr, val, len);
 
 /* adjust the read and write value to appropriate CFC-CFF window */
 read_val <<= (addr & 3) << 3;
@@ -397,6 +396,12 @@ static void xen_pt_pci_write_config(PCIDevice *d, uint32_t 
addr,
 /* need to shift back before passing them to xen_host_pci_set_block. */
 val >>= (addr & 3) << 3;
 
+/* Call default handler for its side effects only, with value already
+ * written by specific handlers. */
+pci_default_write_config(d, addr,
+ pci_default_read_config(d, addr, len),
+ len);
+
 memory_region_transaction_commit();
 
 out:
-- 
git-series 0.9.1



  1   2   >