[PATCH] target/riscv: Add missing include guard in pmu.h

2024-02-20 Thread frank . chang
From: Frank Chang 

Add missing include guard in pmu.h to avoid the problem of double
inclusion.

Signed-off-by: Frank Chang 
---
 target/riscv/pmu.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h
index 505fc850d3..7c0ad661e0 100644
--- a/target/riscv/pmu.h
+++ b/target/riscv/pmu.h
@@ -16,6 +16,9 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#ifndef RISCV_PMU_H
+#define RISCV_PMU_H
+
 #include "cpu.h"
 #include "qapi/error.h"
 
@@ -31,3 +34,5 @@ int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum 
riscv_pmu_event_idx event_idx);
 void riscv_pmu_generate_fdt_node(void *fdt, uint32_t cmask, char *pmu_name);
 int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value,
   uint32_t ctr_idx);
+
+#endif /* RISCV_PMU_H */
-- 
2.43.0




Re: [PATCH] target/riscv: Update $pc after linking to $ra in trans_cm_jalt()

2024-02-06 Thread Frank Chang
Reviewed-by: Frank Chang 

On Tue, Feb 6, 2024 at 9:19 PM Jason Chien  wrote:

> The original implementation sets $pc to the address read from the jump
> vector table first and links $ra with the address of the next instruction
> after the updated $pc. After jumping to the updated $pc and executing the
> next ret instruction, the program jumps to $ra, which is in the same
> function currently executing, which results in an infinite loop.
> This commit reverses the two action. Firstly, $ra is updated with the
> address of the next instruction after $pc, and sets $pc to the address
> read from the jump vector table.
>
> Signed-off-by: Jason Chien 
> ---
>  target/riscv/insn_trans/trans_rvzce.c.inc | 14 +++---
>  1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvzce.c.inc
> b/target/riscv/insn_trans/trans_rvzce.c.inc
> index 8d8a64f493..a185e2315f 100644
> --- a/target/riscv/insn_trans/trans_rvzce.c.inc
> +++ b/target/riscv/insn_trans/trans_rvzce.c.inc
> @@ -293,13 +293,6 @@ static bool trans_cm_jalt(DisasContext *ctx,
> arg_cm_jalt *a)
>  {
>  REQUIRE_ZCMT(ctx);
>
> -/*
> - * Update pc to current for the non-unwinding exception
> - * that might come from cpu_ld*_code() in the helper.
> - */
> -gen_update_pc(ctx, 0);
> -gen_helper_cm_jalt(cpu_pc, cpu_env, tcg_constant_i32(a->index));
> -
>  /* c.jt vs c.jalt depends on the index. */
>  if (a->index >= 32) {
>  TCGv succ_pc = dest_gpr(ctx, xRA);
> @@ -307,6 +300,13 @@ static bool trans_cm_jalt(DisasContext *ctx,
> arg_cm_jalt *a)
>  gen_set_gpr(ctx, xRA, succ_pc);
>  }
>
> +/*
> + * Update pc to current for the non-unwinding exception
> + * that might come from cpu_ld*_code() in the helper.
> + */
> +gen_update_pc(ctx, 0);
> +gen_helper_cm_jalt(cpu_pc, cpu_env, tcg_constant_i32(a->index));
> +
>  tcg_gen_lookup_and_goto_ptr();
>  ctx->base.is_jmp = DISAS_NORETURN;
>  return true;
> --
> 2.43.0
>
>
>


[PATCH] hw/intc: Update APLIC IDC after claiming iforce register

2024-03-21 Thread frank . chang
From: Frank Chang 

Currently, QEMU only sets the iforce register to 0 and returns early
when claiming the iforce register. However, this may leave mip.meip
remains at 1 if a spurious external interrupt triggered by iforce
register is the only pending interrupt to be claimed, and the interrupt
cannot be lowered as expected.

This commit fixes this issue by calling riscv_aplic_idc_update() to
update the IDC status after the iforce register is claimed.

Signed-off-by: Frank Chang 
Reviewed-by: Jim Shu 
---
 hw/intc/riscv_aplic.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
index 6a7fbfa861..fc5df0d598 100644
--- a/hw/intc/riscv_aplic.c
+++ b/hw/intc/riscv_aplic.c
@@ -488,6 +488,7 @@ static uint32_t riscv_aplic_idc_claimi(RISCVAPLICState 
*aplic, uint32_t idc)
 
 if (!topi) {
 aplic->iforce[idc] = 0;
+riscv_aplic_idc_update(aplic, idc);
 return 0;
 }
 
-- 
2.43.2




Re: [PATCH v2 01/15] exec/memtxattr: add process identifier to the transaction attributes

2024-04-23 Thread Frank Chang
Reviewed-by: Frank Chang 

Daniel Henrique Barboza  於 2024年3月8日 週五 上午12:04寫道:
>
> From: Tomasz Jeznach 
>
> Extend memory transaction attributes with process identifier to allow
> per-request address translation logic to use requester_id / process_id
> to identify memory mapping (e.g. enabling IOMMU w/ PASID translations).
>
> Signed-off-by: Tomasz Jeznach 
> ---
>  include/exec/memattrs.h | 5 +
>  1 file changed, 5 insertions(+)
>
> diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
> index 14cdd8d582..46d0725416 100644
> --- a/include/exec/memattrs.h
> +++ b/include/exec/memattrs.h
> @@ -52,6 +52,11 @@ typedef struct MemTxAttrs {
>  unsigned int memory:1;
>  /* Requester ID (for MSI for example) */
>  unsigned int requester_id:16;
> +
> +/*
> + * PCI PASID support: Limited to 8 bits process identifier.
> + */
> +unsigned int pasid:8;
>  } MemTxAttrs;
>
>  /* Bus masters which don't specify any attributes will get this,
> --
> 2.43.2
>
>



Re: [PATCH v2 04/15] hw/riscv: add riscv-iommu-pci device

2024-04-29 Thread Frank Chang
Daniel Henrique Barboza  於 2024年3月8日 週五
上午12:04寫道:
>
> From: Tomasz Jeznach 
>
> The RISC-V IOMMU can be modelled as a PCIe device following the
> guidelines of the RISC-V IOMMU spec, chapter 7.1, "Integrating an IOMMU
> as a PCIe device".
>
> Signed-off-by: Tomasz Jeznach 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  hw/riscv/meson.build   |   2 +-
>  hw/riscv/riscv-iommu-pci.c | 173 +
>  2 files changed, 174 insertions(+), 1 deletion(-)
>  create mode 100644 hw/riscv/riscv-iommu-pci.c
>
> diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
> index ba9eebd605..4674cec6c4 100644
> --- a/hw/riscv/meson.build
> +++ b/hw/riscv/meson.build
> @@ -10,6 +10,6 @@ riscv_ss.add(when: 'CONFIG_SIFIVE_U', if_true:
files('sifive_u.c'))
>  riscv_ss.add(when: 'CONFIG_SPIKE', if_true: files('spike.c'))
>  riscv_ss.add(when: 'CONFIG_MICROCHIP_PFSOC', if_true:
files('microchip_pfsoc.c'))
>  riscv_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c'))
> -riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files('riscv-iommu.c'))
> +riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files('riscv-iommu.c',
'riscv-iommu-pci.c'))
>
>  hw_arch += {'riscv': riscv_ss}
> diff --git a/hw/riscv/riscv-iommu-pci.c b/hw/riscv/riscv-iommu-pci.c
> new file mode 100644
> index 00..4eb1057210
> --- /dev/null
> +++ b/hw/riscv/riscv-iommu-pci.c
> @@ -0,0 +1,173 @@
> +/*
> + * QEMU emulation of an RISC-V IOMMU (Ziommu)
> + *
> + * Copyright (C) 2022-2023 Rivos Inc.
> + *
> + * 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.
> + *
> + * 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 .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/pci/msi.h"
> +#include "hw/pci/msix.h"
> +#include "hw/pci/pci_bus.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/riscv/riscv_hart.h"
> +#include "migration/vmstate.h"
> +#include "qapi/error.h"
> +#include "qemu/error-report.h"
> +#include "qemu/host-utils.h"
> +#include "qom/object.h"
> +
> +#include "cpu_bits.h"
> +#include "riscv-iommu.h"
> +#include "riscv-iommu-bits.h"
> +
> +#ifndef PCI_VENDOR_ID_RIVOS
> +#define PCI_VENDOR_ID_RIVOS   0x1efd
> +#endif
> +
> +#ifndef PCI_DEVICE_ID_RIVOS_IOMMU
> +#define PCI_DEVICE_ID_RIVOS_IOMMU 0xedf1
> +#endif
> +
> +/* RISC-V IOMMU PCI Device Emulation */
> +
> +typedef struct RISCVIOMMUStatePci {
> +PCIDevicepci; /* Parent PCIe device state */
> +MemoryRegion bar0;/* PCI BAR (including MSI-x config) */
> +RISCVIOMMUState  iommu;   /* common IOMMU state */
> +} RISCVIOMMUStatePci;
> +
> +/* interrupt delivery callback */
> +static void riscv_iommu_pci_notify(RISCVIOMMUState *iommu, unsigned
vector)
> +{
> +RISCVIOMMUStatePci *s = container_of(iommu, RISCVIOMMUStatePci,
iommu);
> +
> +if (msix_enabled(&(s->pci))) {
> +msix_notify(&(s->pci), vector);
> +}
> +}
> +
> +static void riscv_iommu_pci_realize(PCIDevice *dev, Error **errp)
> +{
> +RISCVIOMMUStatePci *s = DO_UPCAST(RISCVIOMMUStatePci, pci, dev);
> +RISCVIOMMUState *iommu = &s->iommu;
> +Error *err = NULL;
> +
> +/* Set device id for trace / debug */
> +DEVICE(iommu)->id = g_strdup_printf("%02x:%02x.%01x",
> +pci_dev_bus_num(dev), PCI_SLOT(dev->devfn),
PCI_FUNC(dev->devfn));

pci_dev_bus_num() calls pci_bus_num(),
and pci_bus_num() is assigned to pcibus_num(),
which returns bus->parent_dev->config[PCI_SECONDARY_BUS]
However, PCI bus number is not initialized by SW when IOMMU is initialized.
So pci_bus_num() will always return 0, IIRC.
Same issue as pci_bus_num() above.

> +qdev_realize(DEVICE(iommu), NULL, errp);
> +
> +memory_region_init(&s->bar0, OBJECT(s), "riscv-iommu-bar0",
> +QEMU_ALIGN_UP(memory_region_size(&iommu->regs_mr),
TARGET_PAGE_SIZE));
> +memory_region_add_subregion(&s->bar0, 0, &iommu->regs_mr);
> +
> +pcie_endpoint_cap_init(dev, 0);
> +
> +pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
> + PCI_BASE_ADDRESS_MEM_TYPE_64, &s->bar0);
> +
> +int ret = msix_init(dev, RISCV_IOMMU_INTR_COUNT,
> +&s->bar0, 0, RISCV_IOMMU_REG_MSI_CONFIG,
> +&s->bar0, 0, RISCV_IOMMU_REG_MSI_CONFIG + 256,
0, &err);
> +
> +if (ret == -ENOTSUP) {
> +/*
> + * MSI-x is not supported by the platform.
> + * Driver should use timer/polling based notification handlers.
> + */
> +warn_report_err(err);
> +} e

Re: [PATCH v2 05/15] hw/riscv: add riscv-iommu-sys platform device

2024-04-29 Thread Frank Chang
Reviewed-by: Frank Chang 

Daniel Henrique Barboza  於 2024年3月8日 週五 上午12:05寫道:
>
> From: Tomasz Jeznach 
>
> This device models the RISC-V IOMMU as a sysbus device.
>
> Signed-off-by: Tomasz Jeznach 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  hw/riscv/meson.build   |  2 +-
>  hw/riscv/riscv-iommu-sys.c | 93 ++
>  include/hw/riscv/iommu.h   |  4 ++
>  3 files changed, 98 insertions(+), 1 deletion(-)
>  create mode 100644 hw/riscv/riscv-iommu-sys.c
>
> diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
> index 4674cec6c4..e37c5d78e2 100644
> --- a/hw/riscv/meson.build
> +++ b/hw/riscv/meson.build
> @@ -10,6 +10,6 @@ riscv_ss.add(when: 'CONFIG_SIFIVE_U', if_true: 
> files('sifive_u.c'))
>  riscv_ss.add(when: 'CONFIG_SPIKE', if_true: files('spike.c'))
>  riscv_ss.add(when: 'CONFIG_MICROCHIP_PFSOC', if_true: 
> files('microchip_pfsoc.c'))
>  riscv_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c'))
> -riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files('riscv-iommu.c', 
> 'riscv-iommu-pci.c'))
> +riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files('riscv-iommu.c', 
> 'riscv-iommu-pci.c', 'riscv-iommu-sys.c'))
>
>  hw_arch += {'riscv': riscv_ss}
> diff --git a/hw/riscv/riscv-iommu-sys.c b/hw/riscv/riscv-iommu-sys.c
> new file mode 100644
> index 00..4305cf8d79
> --- /dev/null
> +++ b/hw/riscv/riscv-iommu-sys.c
> @@ -0,0 +1,93 @@
> +/*
> + * QEMU emulation of an RISC-V IOMMU (Ziommu) - Platform Device
> + *
> + * Copyright (C) 2022-2023 Rivos Inc.
> + *
> + * 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.
> + *
> + * 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 <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "hw/pci/pci_bus.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/sysbus.h"
> +#include "qapi/error.h"
> +#include "qapi/error.h"
> +#include "qemu/error-report.h"
> +#include "qemu/host-utils.h"
> +#include "qemu/module.h"
> +#include "qemu/osdep.h"
> +#include "qom/object.h"
> +
> +#include "riscv-iommu.h"
> +
> +/* RISC-V IOMMU System Platform Device Emulation */
> +
> +struct RISCVIOMMUStateSys {
> +SysBusDevice parent;
> +uint64_t addr;
> +RISCVIOMMUState  iommu;
> +};
> +
> +static void riscv_iommu_sys_realize(DeviceState *dev, Error **errp)
> +{
> +RISCVIOMMUStateSys *s = RISCV_IOMMU_SYS(dev);
> +PCIBus *pci_bus;
> +
> +qdev_realize(DEVICE(&s->iommu), NULL, errp);
> +sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iommu.regs_mr);
> +if (s->addr) {
> +sysbus_mmio_map(SYS_BUS_DEVICE(s), 0, s->addr);
> +}
> +
> +pci_bus = (PCIBus *) object_resolve_path_type("", TYPE_PCI_BUS, NULL);
> +if (pci_bus) {
> +riscv_iommu_pci_setup_iommu(&s->iommu, pci_bus, errp);
> +}
> +}
> +
> +static void riscv_iommu_sys_init(Object *obj)
> +{
> +RISCVIOMMUStateSys *s = RISCV_IOMMU_SYS(obj);
> +RISCVIOMMUState *iommu = &s->iommu;
> +
> +object_initialize_child(obj, "iommu", iommu, TYPE_RISCV_IOMMU);
> +qdev_alias_all_properties(DEVICE(iommu), obj);
> +}
> +
> +static Property riscv_iommu_sys_properties[] = {
> +DEFINE_PROP_UINT64("addr", RISCVIOMMUStateSys, addr, 0),
> +DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void riscv_iommu_sys_class_init(ObjectClass *klass, void *data)
> +{
> +DeviceClass *dc = DEVICE_CLASS(klass);
> +dc->realize = riscv_iommu_sys_realize;
> +set_bit(DEVICE_CATEGORY_MISC, dc->categories);
> +device_class_set_props(dc, riscv_iommu_sys_properties);
> +}
> +
> +static const TypeInfo riscv_iommu_sys = {
> +.name  = TYPE_RISCV_IOMMU_SYS,
> +.parent= TYPE_SYS_BUS_DEVICE,
> +.class_init= riscv_iommu_sys_class_init,
> +.instance_init = riscv_iommu_sys_

Re: [PATCH v2 06/15] hw/riscv/virt.c: support for RISC-V IOMMU PCIDevice hotplug

2024-04-29 Thread Frank Chang
Reviewed-by: Frank Chang 

Daniel Henrique Barboza  於 2024年3月8日 週五 上午12:06寫道:
>
> From: Tomasz Jeznach 
>
> Generate device tree entry for riscv-iommu PCI device, along with
> mapping all PCI device identifiers to the single IOMMU device instance.
>
> Signed-off-by: Tomasz Jeznach 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  hw/riscv/virt.c | 33 -
>  1 file changed, 32 insertions(+), 1 deletion(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index a094af97c3..67a8267747 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -32,6 +32,7 @@
>  #include "hw/core/sysbus-fdt.h"
>  #include "target/riscv/pmu.h"
>  #include "hw/riscv/riscv_hart.h"
> +#include "hw/riscv/iommu.h"
>  #include "hw/riscv/virt.h"
>  #include "hw/riscv/boot.h"
>  #include "hw/riscv/numa.h"
> @@ -1004,6 +1005,30 @@ static void create_fdt_virtio_iommu(RISCVVirtState *s, 
> uint16_t bdf)
> bdf + 1, iommu_phandle, bdf + 1, 0x - bdf);
>  }
>
> +static void create_fdt_iommu(RISCVVirtState *s, uint16_t bdf)
> +{
> +const char comp[] = "riscv,pci-iommu";
> +void *fdt = MACHINE(s)->fdt;
> +uint32_t iommu_phandle;
> +g_autofree char *iommu_node = NULL;
> +g_autofree char *pci_node = NULL;
> +
> +pci_node = g_strdup_printf("/soc/pci@%lx",
> +   (long) virt_memmap[VIRT_PCIE_ECAM].base);
> +iommu_node = g_strdup_printf("%s/iommu@%x", pci_node, bdf);
> +iommu_phandle = qemu_fdt_alloc_phandle(fdt);
> +qemu_fdt_add_subnode(fdt, iommu_node);
> +
> +qemu_fdt_setprop(fdt, iommu_node, "compatible", comp, sizeof(comp));
> +qemu_fdt_setprop_cell(fdt, iommu_node, "#iommu-cells", 1);
> +qemu_fdt_setprop_cell(fdt, iommu_node, "phandle", iommu_phandle);
> +qemu_fdt_setprop_cells(fdt, iommu_node, "reg",
> +   bdf << 8, 0, 0, 0, 0);
> +qemu_fdt_setprop_cells(fdt, pci_node, "iommu-map",
> +   0, iommu_phandle, 0, bdf,
> +   bdf + 1, iommu_phandle, bdf + 1, 0x - bdf);
> +}
> +
>  static void finalize_fdt(RISCVVirtState *s)
>  {
>  uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1;
> @@ -1712,9 +1737,11 @@ static HotplugHandler 
> *virt_machine_get_hotplug_handler(MachineState *machine,
>  MachineClass *mc = MACHINE_GET_CLASS(machine);
>
>  if (device_is_dynamic_sysbus(mc, dev) ||
> -object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
> +object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) ||
> +object_dynamic_cast(OBJECT(dev), TYPE_RISCV_IOMMU_PCI)) {
>  return HOTPLUG_HANDLER(machine);
>  }
> +
>  return NULL;
>  }
>
> @@ -1735,6 +1762,10 @@ static void virt_machine_device_plug_cb(HotplugHandler 
> *hotplug_dev,
>  if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
>  create_fdt_virtio_iommu(s, pci_get_bdf(PCI_DEVICE(dev)));
>  }
> +
> +if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_IOMMU_PCI)) {
> +create_fdt_iommu(s, pci_get_bdf(PCI_DEVICE(dev)));
> +}
>  }
>
>  static void virt_machine_class_init(ObjectClass *oc, void *data)
> --
> 2.43.2
>
>



Re: [PATCH v2 07/15] test/qtest: add riscv-iommu-pci tests

2024-04-29 Thread Frank Chang
Reviewed-by: Frank Chang 

Daniel Henrique Barboza  於 2024年3月8日 週五 上午12:05寫道:
>
> To test the RISC-V IOMMU emulation we'll use its PCI representation.
> Create a new 'riscv-iommu-pci' libqos device that will be present with
> CONFIG_RISCV_IOMMU.  This config is only available for RISC-V, so this
> device will only be consumed by the RISC-V libqos machine.
>
> Start with basic tests: a PCI sanity check and a reset state register
> test. The reset test was taken from the RISC-V IOMMU spec chapter 5.2,
> "Reset behavior".
>
> More tests will be added later.
>
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  tests/qtest/libqos/meson.build   |  4 ++
>  tests/qtest/libqos/riscv-iommu.c | 79 +++
>  tests/qtest/libqos/riscv-iommu.h | 67 +++
>  tests/qtest/meson.build  |  1 +
>  tests/qtest/riscv-iommu-test.c   | 93 
>  5 files changed, 244 insertions(+)
>  create mode 100644 tests/qtest/libqos/riscv-iommu.c
>  create mode 100644 tests/qtest/libqos/riscv-iommu.h
>  create mode 100644 tests/qtest/riscv-iommu-test.c
>
> diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
> index 3aed6efcb8..07fe20eacb 100644
> --- a/tests/qtest/libqos/meson.build
> +++ b/tests/qtest/libqos/meson.build
> @@ -67,6 +67,10 @@ if have_virtfs
>libqos_srcs += files('virtio-9p.c', 'virtio-9p-client.c')
>  endif
>
> +if config_all_devices.has_key('CONFIG_RISCV_IOMMU')
> +  libqos_srcs += files('riscv-iommu.c')
> +endif
> +
>  libqos = static_library('qos', libqos_srcs + genh,
>  name_suffix: 'fa',
>  build_by_default: false)
> diff --git a/tests/qtest/libqos/riscv-iommu.c 
> b/tests/qtest/libqos/riscv-iommu.c
> new file mode 100644
> index 00..8ae7d4888c
> --- /dev/null
> +++ b/tests/qtest/libqos/riscv-iommu.c
> @@ -0,0 +1,79 @@
> +/*
> + * libqos driver riscv-iommu-pci framework
> + *
> + * Copyright (c) 2024 Ventana Micro Systems Inc.
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or (at 
> your
> + * option) any later version.  See the COPYING file in the top-level 
> directory.
> + *
> + */
> +
> +#include "qemu/osdep.h"
> +#include "../libqtest.h"
> +#include "qemu/module.h"
> +#include "qgraph.h"
> +#include "pci.h"
> +#include "riscv-iommu.h"
> +
> +#define PCI_VENDOR_ID_RIVOS   0x1efd
> +#define PCI_DEVICE_ID_RIVOS_IOMMU 0xedf1
> +
> +static void *riscv_iommu_pci_get_driver(void *obj, const char *interface)
> +{
> +QRISCVIOMMU *r_iommu_pci = obj;
> +
> +if (!g_strcmp0(interface, "pci-device")) {
> +return &r_iommu_pci->dev;
> +}
> +
> +fprintf(stderr, "%s not present in riscv_iommu_pci\n", interface);
> +g_assert_not_reached();
> +}
> +
> +static void riscv_iommu_pci_start_hw(QOSGraphObject *obj)
> +{
> +QRISCVIOMMU *pci = (QRISCVIOMMU *)obj;
> +qpci_device_enable(&pci->dev);
> +}
> +
> +static void riscv_iommu_pci_destructor(QOSGraphObject *obj)
> +{
> +QRISCVIOMMU *pci = (QRISCVIOMMU *)obj;
> +qpci_iounmap(&pci->dev, pci->reg_bar);
> +}
> +
> +static void *riscv_iommu_pci_create(void *pci_bus, QGuestAllocator *alloc,
> +void *addr)
> +{
> +QRISCVIOMMU *r_iommu_pci = g_new0(QRISCVIOMMU, 1);
> +QPCIBus *bus = pci_bus;
> +
> +qpci_device_init(&r_iommu_pci->dev, bus, addr);
> +r_iommu_pci->reg_bar = qpci_iomap(&r_iommu_pci->dev, 0, NULL);
> +
> +r_iommu_pci->obj.get_driver = riscv_iommu_pci_get_driver;
> +r_iommu_pci->obj.start_hw = riscv_iommu_pci_start_hw;
> +r_iommu_pci->obj.destructor = riscv_iommu_pci_destructor;
> +return &r_iommu_pci->obj;
> +}
> +
> +static void riscv_iommu_pci_register_nodes(void)
> +{
> +QPCIAddress addr = {
> +.vendor_id = PCI_VENDOR_ID_RIVOS,
> +.device_id = PCI_DEVICE_ID_RIVOS_IOMMU,
> +.devfn = QPCI_DEVFN(1, 0),
> +};
> +
> +QOSGraphEdgeOptions opts = {
> +.extra_device_opts = "addr=01.0",
> +};
> +
> +add_qpci_address(&opts, &addr);
> +
> +qos_node_create_driver("riscv-iommu-pci", riscv_iommu_pci_create);
> +qos_node_produces("riscv-iommu-pci", "pci-device");
> +qos_node_consumes("riscv-iommu-pci", "pci-bus", &opts);
> +}
> +
> +libqos_init(riscv_iommu_pci_re

Re: [PATCH v2 03/15] hw/riscv: add RISC-V IOMMU base emulation

2024-05-02 Thread Frank Chang
Hi Daniel,

Daniel Henrique Barboza  於 2024年3月8日 週五 上午12:04寫道:
>
> From: Tomasz Jeznach 
>
> The RISC-V IOMMU specification is now ratified as-per the RISC-V
> international process. The latest frozen specifcation can be found
> at:
>
> https://github.com/riscv-non-isa/riscv-iommu/releases/download/v1.0/riscv-iommu.pdf
>
> Add the foundation of the device emulation for RISC-V IOMMU, which
> includes an IOMMU that has no capabilities but MSI interrupt support and
> fault queue interfaces. We'll add add more features incrementally in the
> next patches.
>
> Co-developed-by: Sebastien Boeuf 
> Signed-off-by: Sebastien Boeuf 
> Signed-off-by: Tomasz Jeznach 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  hw/riscv/Kconfig |4 +
>  hw/riscv/meson.build |1 +
>  hw/riscv/riscv-iommu.c   | 1492 ++
>  hw/riscv/riscv-iommu.h   |  141 
>  hw/riscv/trace-events|   11 +
>  hw/riscv/trace.h |2 +
>  include/hw/riscv/iommu.h |   36 +
>  meson.build  |1 +
>  8 files changed, 1688 insertions(+)
>  create mode 100644 hw/riscv/riscv-iommu.c
>  create mode 100644 hw/riscv/riscv-iommu.h
>  create mode 100644 hw/riscv/trace-events
>  create mode 100644 hw/riscv/trace.h
>  create mode 100644 include/hw/riscv/iommu.h
>
> diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
> index 5d644eb7b1..faf6a10029 100644
> --- a/hw/riscv/Kconfig
> +++ b/hw/riscv/Kconfig
> @@ -1,3 +1,6 @@
> +config RISCV_IOMMU
> +bool
> +
>  config RISCV_NUMA
>  bool
>
> @@ -38,6 +41,7 @@ config RISCV_VIRT
>  select SERIAL
>  select RISCV_ACLINT
>  select RISCV_APLIC
> +select RISCV_IOMMU
>  select RISCV_IMSIC
>  select SIFIVE_PLIC
>  select SIFIVE_TEST
> diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
> index 2f7ee81be3..ba9eebd605 100644
> --- a/hw/riscv/meson.build
> +++ b/hw/riscv/meson.build
> @@ -10,5 +10,6 @@ riscv_ss.add(when: 'CONFIG_SIFIVE_U', if_true: 
> files('sifive_u.c'))
>  riscv_ss.add(when: 'CONFIG_SPIKE', if_true: files('spike.c'))
>  riscv_ss.add(when: 'CONFIG_MICROCHIP_PFSOC', if_true: 
> files('microchip_pfsoc.c'))
>  riscv_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c'))
> +riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files('riscv-iommu.c'))
>
>  hw_arch += {'riscv': riscv_ss}
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> new file mode 100644
> index 00..df534b99b0
> --- /dev/null
> +++ b/hw/riscv/riscv-iommu.c
> @@ -0,0 +1,1492 @@
> +/*
> + * QEMU emulation of an RISC-V IOMMU (Ziommu)
> + *
> + * Copyright (C) 2021-2023, Rivos Inc.
> + *
> + * 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.
> + *
> + * 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 .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qom/object.h"
> +#include "hw/pci/pci_bus.h"
> +#include "hw/pci/pci_device.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/riscv/riscv_hart.h"
> +#include "migration/vmstate.h"
> +#include "qapi/error.h"
> +#include "qemu/timer.h"
> +
> +#include "cpu_bits.h"
> +#include "riscv-iommu.h"
> +#include "riscv-iommu-bits.h"
> +#include "trace.h"
> +
> +#define LIMIT_CACHE_CTX   (1U << 7)
> +#define LIMIT_CACHE_IOT   (1U << 20)
> +
> +/* Physical page number coversions */
> +#define PPN_PHYS(ppn) ((ppn) << TARGET_PAGE_BITS)
> +#define PPN_DOWN(phy) ((phy) >> TARGET_PAGE_BITS)
> +
> +typedef struct RISCVIOMMUContext RISCVIOMMUContext;
> +typedef struct RISCVIOMMUEntry RISCVIOMMUEntry;
> +
> +/* Device assigned I/O address space */
> +struct RISCVIOMMUSpace {
> +IOMMUMemoryRegion iova_mr;  /* IOVA memory region for attached device */
> +AddressSpace iova_as;   /* IOVA address space for attached device */
> +RISCVIOMMUState *iommu; /* Managing IOMMU device state */
> +uint32_t devid; /* Requester identifier, AKA device_id */
> +bool notifier;  /* IOMMU unmap notifier enabled */
> +QLIST_ENTRY(RISCVIOMMUSpace) list;
> +};
> +
> +/* Device translation context state. */
> +struct RISCVIOMMUContext {
> +uint64_t devid:24;  /* Requester Id, AKA device_id */
> +uint64_t pasid:20;  /* Process Address Space ID */
> +uint64_t __rfu:20;  /* reserved */
> +uint64_t tc;/* Translation Control */
> +uint64_t ta;/* Translation Attributes */
> +uint64_t msi_addr_mask; /* MSI 

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, &ref);
> +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, &iotlb, 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 suppo

Re: [PATCH v2 12/15] hw/riscv/riscv-iommu: Add another irq for mrif notifications

2024-05-05 Thread Frank Chang
Reviewed-by: Frank Chang 

Daniel Henrique Barboza  於 2024年3月8日 週五 上午12:06寫道:
>
> From: Andrew Jones 
>
> And add mrif notification trace.
>
> Signed-off-by: Andrew Jones 
> Reviewed-by: Daniel Henrique Barboza 
> ---
>  hw/riscv/riscv-iommu-pci.c | 2 +-
>  hw/riscv/riscv-iommu.c | 1 +
>  hw/riscv/trace-events  | 1 +
>  3 files changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/hw/riscv/riscv-iommu-pci.c b/hw/riscv/riscv-iommu-pci.c
> index 4eb1057210..8a7b71166c 100644
> --- a/hw/riscv/riscv-iommu-pci.c
> +++ b/hw/riscv/riscv-iommu-pci.c
> @@ -78,7 +78,7 @@ static void riscv_iommu_pci_realize(PCIDevice *dev, Error 
> **errp)
>  pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
>   PCI_BASE_ADDRESS_MEM_TYPE_64, &s->bar0);
>
> -int ret = msix_init(dev, RISCV_IOMMU_INTR_COUNT,
> +int ret = msix_init(dev, RISCV_IOMMU_INTR_COUNT + 1,
>  &s->bar0, 0, RISCV_IOMMU_REG_MSI_CONFIG,
>  &s->bar0, 0, RISCV_IOMMU_REG_MSI_CONFIG + 256, 0, 
> &err);
>
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> index 1fa1286d07..954a6892c2 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -543,6 +543,7 @@ static MemTxResult riscv_iommu_msi_write(RISCVIOMMUState 
> *s,
>  if (res != MEMTX_OK) {
>  return res;
>  }
> +trace_riscv_iommu_mrif_notification(s->parent_obj.id, n190, addr);
>
>  return MEMTX_OK;
>  }
> diff --git a/hw/riscv/trace-events b/hw/riscv/trace-events
> index 4b486b6420..d69719a27a 100644
> --- a/hw/riscv/trace-events
> +++ b/hw/riscv/trace-events
> @@ -6,6 +6,7 @@ riscv_iommu_flt(const char *id, unsigned b, unsigned d, 
> unsigned f, uint64_t rea
>  riscv_iommu_pri(const char *id, unsigned b, unsigned d, unsigned f, uint64_t 
> iova) "%s: page request %04x:%02x.%u iova: 0x%"PRIx64
>  riscv_iommu_dma(const char *id, unsigned b, unsigned d, unsigned f, unsigned 
> pasid, const char *dir, uint64_t iova, uint64_t phys) "%s: translate 
> %04x:%02x.%u #%u %s 0x%"PRIx64" -> 0x%"PRIx64
>  riscv_iommu_msi(const char *id, unsigned b, unsigned d, unsigned f, uint64_t 
> iova, uint64_t phys) "%s: translate %04x:%02x.%u MSI 0x%"PRIx64" -> 0x%"PRIx64
> +riscv_iommu_mrif_notification(const char *id, uint32_t nid, uint64_t phys) 
> "%s: sent MRIF notification 0x%x to 0x%"PRIx64
>  riscv_iommu_cmd(const char *id, uint64_t l, uint64_t u) "%s: command 
> 0x%"PRIx64" 0x%"PRIx64
>  riscv_iommu_notifier_add(const char *id) "%s: dev-iotlb notifier added"
>  riscv_iommu_notifier_del(const char *id) "%s: dev-iotlb notifier removed"
> --
> 2.43.2
>
>



Re: [PATCH v2 13/15] qtest/riscv-iommu-test: add init queues test

2024-05-07 Thread Frank Chang
Reviewed-by: Frank Chang 

Daniel Henrique Barboza  於 2024年3月8日 週五 上午12:06寫道:
>
> Add an additional test to further exercise the IOMMU where we attempt to
> initialize the command, fault and page-request queues.
>
> These steps are taken from chapter 6.2 of the RISC-V IOMMU spec,
> "Guidelines for initialization". It emulates what we expect from the
> software/OS when initializing the IOMMU.
>
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  tests/qtest/libqos/riscv-iommu.h |  29 +++
>  tests/qtest/riscv-iommu-test.c   | 141 +++
>  2 files changed, 170 insertions(+)
>
> diff --git a/tests/qtest/libqos/riscv-iommu.h 
> b/tests/qtest/libqos/riscv-iommu.h
> index 8c056caa7b..aeaa5fb8b8 100644
> --- a/tests/qtest/libqos/riscv-iommu.h
> +++ b/tests/qtest/libqos/riscv-iommu.h
> @@ -58,6 +58,35 @@
>
>  #define RISCV_IOMMU_REG_IPSR0x0054
>
> +#define RISCV_IOMMU_REG_IVEC0x02F8
> +#define RISCV_IOMMU_REG_IVEC_CIVGENMASK_ULL(3, 0)
> +#define RISCV_IOMMU_REG_IVEC_FIVGENMASK_ULL(7, 4)
> +#define RISCV_IOMMU_REG_IVEC_PIVGENMASK_ULL(15, 12)
> +
> +#define RISCV_IOMMU_REG_CQB 0x0018
> +#define RISCV_IOMMU_CQB_PPN_START   10
> +#define RISCV_IOMMU_CQB_PPN_LEN 44
> +#define RISCV_IOMMU_CQB_LOG2SZ_START0
> +#define RISCV_IOMMU_CQB_LOG2SZ_LEN  5
> +
> +#define RISCV_IOMMU_REG_CQT 0x0024
> +
> +#define RISCV_IOMMU_REG_FQB 0x0028
> +#define RISCV_IOMMU_FQB_PPN_START   10
> +#define RISCV_IOMMU_FQB_PPN_LEN 44
> +#define RISCV_IOMMU_FQB_LOG2SZ_START0
> +#define RISCV_IOMMU_FQB_LOG2SZ_LEN  5
> +
> +#define RISCV_IOMMU_REG_FQT 0x0034
> +
> +#define RISCV_IOMMU_REG_PQB 0x0038
> +#define RISCV_IOMMU_PQB_PPN_START   10
> +#define RISCV_IOMMU_PQB_PPN_LEN 44
> +#define RISCV_IOMMU_PQB_LOG2SZ_START0
> +#define RISCV_IOMMU_PQB_LOG2SZ_LEN  5
> +
> +#define RISCV_IOMMU_REG_PQT 0x0044
> +
>  typedef struct QRISCVIOMMU {
>  QOSGraphObject obj;
>  QPCIDevice dev;
> diff --git a/tests/qtest/riscv-iommu-test.c b/tests/qtest/riscv-iommu-test.c
> index 13b887d15e..64f3f092f2 100644
> --- a/tests/qtest/riscv-iommu-test.c
> +++ b/tests/qtest/riscv-iommu-test.c
> @@ -33,6 +33,20 @@ static uint64_t riscv_iommu_read_reg64(QRISCVIOMMU 
> *r_iommu, int reg_offset)
>  return reg;
>  }
>
> +static void riscv_iommu_write_reg32(QRISCVIOMMU *r_iommu, int reg_offset,
> +uint32_t val)
> +{
> +qpci_memwrite(&r_iommu->dev, r_iommu->reg_bar, reg_offset,
> +  &val, sizeof(val));
> +}
> +
> +static void riscv_iommu_write_reg64(QRISCVIOMMU *r_iommu, int reg_offset,
> +uint64_t val)
> +{
> +qpci_memwrite(&r_iommu->dev, r_iommu->reg_bar, reg_offset,
> +  &val, sizeof(val));
> +}
> +
>  static void test_pci_config(void *obj, void *data, QGuestAllocator *t_alloc)
>  {
>  QRISCVIOMMU *r_iommu = obj;
> @@ -84,10 +98,137 @@ static void test_reg_reset(void *obj, void *data, 
> QGuestAllocator *t_alloc)
>  g_assert_cmpuint(reg, ==, 0);
>  }
>
> +/*
> + * Common timeout-based poll for CQCSR, FQCSR and PQCSR. All
> + * their ON bits are mapped as RISCV_IOMMU_QUEUE_ACTIVE (16),
> + */
> +static void qtest_wait_for_queue_active(QRISCVIOMMU *r_iommu,
> +uint32_t queue_csr)
> +{
> +QTestState *qts = global_qtest;
> +guint64 timeout_us = 2 * 1000 * 1000;
> +gint64 start_time = g_get_monotonic_time();
> +uint32_t reg;
> +
> +for (;;) {
> +qtest_clock_step(qts, 100);
> +
> +reg = riscv_iommu_read_reg32(r_iommu, queue_csr);
> +if (reg & RISCV_IOMMU_QUEUE_ACTIVE) {
> +break;
> +}
> +g_assert(g_get_monotonic_time() - start_time <= timeout_us);
> +}
> +}
> +
> +/*
> + * Goes through the queue activation procedures of chapter 6.2,
> + * "Guidelines for initialization", of the RISCV-IOMMU spec.
> + */
> +static void test_iommu_init_queues(void *obj, void *data,
> +   QGuestAllocator *t_alloc)
> +{
> +QRISCVIOMMU *r_iommu = obj;
> +uint64_t reg64, q_addr;
> +uint32_t reg;
> +int k;
> +
> +reg64 = riscv_iommu_read_reg64(r_iommu, RISCV_IOMMU_REG_CAP);
> +g_assert_cmpuint(reg64 & RISCV_IOMMU_CAP_VERSION, ==, 0x10);
> +
> +/*
> + * Program the command queue. Write 0xF to civ, assert that
> + * we have 4 writable bits (k = 4). The amount of e

Re: [PATCH v2 14/15] hw/misc: EDU: added PASID support

2024-05-07 Thread Frank Chang
uld use the defines declared in
include/standard-headers/linux/pci_regs.h for readability.

> +}
> +
>  if (msi_init(pdev, 0, 1, true, false, errp)) {
>  return;
>  }
> @@ -404,20 +428,27 @@ static void pci_edu_uninit(PCIDevice *pdev)
>  msi_uninit(pdev);
>  }
>
> +

This new line is unnecessary.

>  static void edu_instance_init(Object *obj)
>  {
>  EduState *edu = EDU(obj);
>
> -edu->dma_mask = (1UL << 28) - 1;
> +edu->dma_mask = ~0ULL;

docs/specs/edu.txt says:
"For educational purposes, the device supports only 28 bits (256 MiB)
by default. Students shall set dma_mask for the device in the OS driver
properly."

We should either update the EDU spec or revert the change here.

>  object_property_add_uint64_ptr(obj, "dma_mask",
> &edu->dma_mask, OBJ_PROP_FLAG_READWRITE);
>  }
>
> +static Property edu_properties[] = {
> +DEFINE_PROP_BOOL("pasid", EduState, enable_pasid, TRUE),
> +DEFINE_PROP_END_OF_LIST(),
> +};
> +
>  static void edu_class_init(ObjectClass *class, void *data)
>  {
>  DeviceClass *dc = DEVICE_CLASS(class);
>  PCIDeviceClass *k = PCI_DEVICE_CLASS(class);
>
> +device_class_set_props(dc, edu_properties);
>  k->realize = pci_edu_realize;
>  k->exit = pci_edu_uninit;
>  k->vendor_id = PCI_VENDOR_ID_QEMU;
> @@ -430,7 +461,7 @@ static void edu_class_init(ObjectClass *class, void *data)
>  static void pci_edu_register_types(void)
>  {
>  static InterfaceInfo interfaces[] = {
> -{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
> +{ INTERFACE_PCIE_DEVICE },
>  { },
>  };
>  static const TypeInfo edu_info = {
> --
> 2.43.2
>
>

This commit introduces a new command for PASID (PV, bitwise OR of:
0x08; PASID, cmds[27:8]).
We should also update the EDU spec: docs/specs/edu.rst to address the changes.


Regards,
Frank Chang



Re: [PATCH v2 15/15] hw/misc: EDU: add ATS/PRI capability

2024-05-07 Thread Frank Chang
; +}
> +
> +iommu_mr = IOMMU_MEMORY_REGION(section->mr);
> +
> +/* Register ATS.INVAL notifier */
> +iommu = g_malloc0(sizeof(*iommu));
> +iommu->iommu_mr = iommu_mr;
> +iommu->iommu_offset = section->offset_within_address_space -
> +  section->offset_within_region;
> +iommu->edu = edu;
> +end = int128_add(int128_make64(section->offset_within_region),
> + section->size);
> +end = int128_sub(end, int128_one());
> +iommu_idx = memory_region_iommu_attrs_to_index(iommu_mr,
> +   MEMTXATTRS_UNSPECIFIED);
> +iommu_notifier_init(&iommu->n, edu_iommu_ats_inval_notify,
> +IOMMU_NOTIFIER_DEVIOTLB_UNMAP,
> +section->offset_within_region,
> +int128_get64(end),
> +iommu_idx);
> +memory_region_register_iommu_notifier(section->mr, &iommu->n, NULL);
> +QLIST_INSERT_HEAD(&edu->iommu_list, iommu, iommu_next);
> +
> +/* Register ATS.PRGR notifier */
> +iommu = g_memdup2(iommu, sizeof(*iommu));
> +iommu_notifier_init(&iommu->n, edu_iommu_ats_prgr_notify,
> +IOMMU_NOTIFIER_MAP,
> +section->offset_within_region,
> +int128_get64(end),
> +iommu_idx);
> +memory_region_register_iommu_notifier(section->mr, &iommu->n, NULL);
> +QLIST_INSERT_HEAD(&edu->iommu_list, iommu, iommu_next);
> +}
> +
> +static void edu_iommu_region_del(MemoryListener *listener,
> +   MemoryRegionSection *section)
> +{
> +EduState *edu = container_of(listener, EduState, iommu_listener);
> +struct edu_iommu *iommu;
> +
> +if (!memory_region_is_iommu(section->mr)) {
> +return;
> +}
> +
> +QLIST_FOREACH(iommu, &edu->iommu_list, iommu_next) {
> +if (MEMORY_REGION(iommu->iommu_mr) == section->mr &&
> +iommu->n.start == section->offset_within_region) {
> +memory_region_unregister_iommu_notifier(section->mr,
> +&iommu->n);
> +QLIST_REMOVE(iommu, iommu_next);
> +g_free(iommu);
> +break;
> +}
> +}
> +}
> +
>  static void pci_edu_realize(PCIDevice *pdev, Error **errp)
>  {
>  EduState *edu = EDU(pdev);
> +AddressSpace *dma_as = NULL;
>  uint8_t *pci_conf = pdev->config;
>  int pos;
>
> @@ -390,9 +603,28 @@ static void pci_edu_realize(PCIDevice *pdev, Error 
> **errp)
>  pos = PCI_CONFIG_SPACE_SIZE;
>  if (edu->enable_pasid) {
>  /* PCIe Spec 7.8.9 PASID Extended Capability Structure */
> -pcie_add_capability(pdev, 0x1b, 1, pos, 8);
> +pcie_add_capability(pdev, PCI_EXT_CAP_ID_PASID, 1, pos, 8);

This should be included in the 14th commit.

>  pci_set_long(pdev->config + pos + 4, 0x1400);
>  pci_set_long(pdev->wmask + pos + 4,  0xfff0);
> +pos += 8;
> +
> +/* ATS Capability */
> +pcie_ats_init(pdev, pos, true);
> +pos += PCI_EXT_CAP_ATS_SIZEOF;
> +
> +/* PRI Capability */
> +pcie_add_capability(pdev, PCI_EXT_CAP_ID_PRI, 1, pos, 16);
> +/* PRI STOPPED */
> +pci_set_long(pdev->config + pos +  4, 0x0100);
> +/* PRI ENABLE bit writable */
> +pci_set_long(pdev->wmask  + pos +  4, 0x0001);
> +/* PRI Capacity Supported */
> +pci_set_long(pdev->config + pos +  8, 0x0080);
> +/* PRI Allocations Allowed, 32 */
> +pci_set_long(pdev->config + pos + 12, 0x0040);
> +pci_set_long(pdev->wmask  + pos + 12, 0x007f);

We should use the defines declared in
include/standard-headers/linux/pci_regs.h for readability,
though some of the bitfields are not defined in the header file.

Regards,
Frank Chang

> +
> +pos += 8;
>  }
>
>  if (msi_init(pdev, 0, 1, true, false, errp)) {
> @@ -409,12 +641,24 @@ static void pci_edu_realize(PCIDevice *pdev, Error 
> **errp)
>  memory_region_init_io(&edu->mmio, OBJECT(edu), &edu_mmio_ops, edu,
>  "edu-mmio", 1 * MiB);
>  pci_register_bar(pdev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &edu->mmio);
> +
> +/* Register IOMMU listener */
> +edu->iommu_listener = (MemoryListener) {
> +.name = "edu-iommu",
> +.region_add = edu_iommu_region_add,
> +.region_del = edu_iommu_region_del,
> +};
> +
> +dma_as = pci_device_iommu_address_space(pdev);
> +memory_listener_register(&edu->iommu_listener, dma_as);
>  }
>
>  static void pci_edu_uninit(PCIDevice *pdev)
>  {
>  EduState *edu = EDU(pdev);
>
> +memory_listener_unregister(&edu->iommu_listener);
> +
>  qemu_mutex_lock(&edu->thr_mutex);
>  edu->stopping = true;
>  qemu_mutex_unlock(&edu->thr_mutex);
> --
> 2.43.2
>
>



Re: [RFC PATCH 1/1] pci-ids.rst: add Red Hat pci-id for generic IOMMU device

2024-05-07 Thread Frank Chang
Hi Daniel,

It's glad to see that we have the dedicate PCIe device ID for RISC-V IOMMU.

Reviewed-by: Frank Chang 

Daniel Henrique Barboza  於 2024年5月3日 週五 下午8:44寫道:

>
> Reserve an id to be used by the RISC-V IOMMU PCI device.
>
> Cc: Gerd Hoffmann 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  docs/specs/pci-ids.rst | 2 ++
>  include/hw/pci/pci.h   | 1 +
>  2 files changed, 3 insertions(+)
>
> diff --git a/docs/specs/pci-ids.rst b/docs/specs/pci-ids.rst
> index c0a3dec2e7..a89a9d0939 100644
> --- a/docs/specs/pci-ids.rst
> +++ b/docs/specs/pci-ids.rst
> @@ -94,6 +94,8 @@ PCI devices (other than virtio):
>PCI ACPI ERST device (``-device acpi-erst``)
>  1b36:0013
>PCI UFS device (``-device ufs``)
> +1b36:0014
> +  PCI RISC-V IOMMU device
>
>  All these devices are documented in :doc:`index`.
>
> diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
> index eaa3fc99d8..462aed1503 100644
> --- a/include/hw/pci/pci.h
> +++ b/include/hw/pci/pci.h
> @@ -115,6 +115,7 @@ extern bool pci_available;
>  #define PCI_DEVICE_ID_REDHAT_PVPANIC 0x0011
>  #define PCI_DEVICE_ID_REDHAT_ACPI_ERST   0x0012
>  #define PCI_DEVICE_ID_REDHAT_UFS 0x0013
> +#define PCI_DEVICE_ID_REDHAT_RISCV_IOMMU 0x0014
>  #define PCI_DEVICE_ID_REDHAT_QXL 0x0100
>
>  #define FMT_PCIBUS  PRIx64
> --
> 2.44.0
>
>



Re: [RFC PATCH 0/1] pci: allocate a PCI ID for RISC-V IOMMU

2024-05-07 Thread Frank Chang
Hi Daniel,

Daniel Henrique Barboza  於 2024年5月3日 週五 下午8:43寫道:
>
> Hi,
>
> In this RFC I want to check with Gerd and others if it's ok to add a PCI
> id for the RISC-V IOMMU device. It's currently under review in [1]. The

Is the link [1] missing?

Regards,
Frank Chang

> idea is to fold this patch into the RISC-V IOMMU series if we're all ok
> with this change.
>
> Gerd, we picked the ID right after the PCI UFS device. Let me know if
> you want another ID instead.
>
>
> Daniel Henrique Barboza (1):
>   pci-ids.rst: add Red Hat pci-id for generic IOMMU device
>
>  docs/specs/pci-ids.rst | 2 ++
>  include/hw/pci/pci.h   | 1 +
>  2 files changed, 3 insertions(+)
>
> --
> 2.44.0
>
>



Re: [PATCH v2 10/15] hw/riscv/riscv-iommu: add ATS support

2024-05-07 Thread Frank Chang
t;  enable_pri = (iotlb->perm == IOMMU_NONE) && (ctx->tc & BIT_ULL(32));
>  enable_pasid = (ctx->tc & RISCV_IOMMU_DC_TC_PDTV);
>
> +/* Check for ATS request. */
> +if (iotlb->perm == IOMMU_NONE) {
> +/* Check if ATS is disabled. */
> +if (!(ctx->tc & RISCV_IOMMU_DC_TC_EN_ATS)) {
> +enable_pri = false;
> +fault = RISCV_IOMMU_FQ_CAUSE_TTYPE_BLOCKED;
> +goto done;
> +}
> +trace_riscv_iommu_ats(s->parent_obj.id, PCI_BUS_NUM(ctx->devid),
> +PCI_SLOT(ctx->devid), PCI_FUNC(ctx->devid), iotlb->iova);

It's possible that iotlb->perm == IOMMU_NONE,
but the translation request comes from riscv_iommu_process_dbg().

> +}
> +
>  iot = riscv_iommu_iot_lookup(ctx, iot_cache, iotlb->iova);
>  perm = iot ? iot->perm : IOMMU_NONE;
>  if (perm != IOMMU_NONE) {
> @@ -1067,13 +1079,10 @@ done:
>
>  if (enable_faults && fault) {
>  struct riscv_iommu_fq_record ev;
> -unsigned ttype;
> -
> -if (iotlb->perm & IOMMU_RW) {
> -ttype = RISCV_IOMMU_FQ_TTYPE_UADDR_WR;
> -} else {
> -ttype = RISCV_IOMMU_FQ_TTYPE_UADDR_RD;
> -}
> +const unsigned ttype =
> +(iotlb->perm & IOMMU_RW) ? RISCV_IOMMU_FQ_TTYPE_UADDR_WR :
> +((iotlb->perm & IOMMU_RO) ? RISCV_IOMMU_FQ_TTYPE_UADDR_RD :
> +RISCV_IOMMU_FQ_TTYPE_PCIE_ATS_REQ);
>  ev.hdr = set_field(0, RISCV_IOMMU_FQ_HDR_CAUSE, fault);
>  ev.hdr = set_field(ev.hdr, RISCV_IOMMU_FQ_HDR_TTYPE, ttype);
>  ev.hdr = set_field(ev.hdr, RISCV_IOMMU_FQ_HDR_PV, enable_pasid);
> @@ -1105,6 +1114,73 @@ static MemTxResult riscv_iommu_iofence(RISCVIOMMUState 
> *s, bool notify,
>  MEMTXATTRS_UNSPECIFIED);
>  }
>
> +static void riscv_iommu_ats(RISCVIOMMUState *s,
> +struct riscv_iommu_command *cmd, IOMMUNotifierFlag flag,
> +IOMMUAccessFlags perm,
> +void (*trace_fn)(const char *id))
> +{
> +RISCVIOMMUSpace *as = NULL;
> +IOMMUNotifier *n;
> +IOMMUTLBEvent event;
> +uint32_t pasid;
> +uint32_t devid;
> +const bool pv = cmd->dword0 & RISCV_IOMMU_CMD_ATS_PV;
> +
> +if (cmd->dword0 & RISCV_IOMMU_CMD_ATS_DSV) {
> +/* Use device segment and requester id */
> +devid = get_field(cmd->dword0,
> +RISCV_IOMMU_CMD_ATS_DSEG | RISCV_IOMMU_CMD_ATS_RID);
> +} else {
> +devid = get_field(cmd->dword0, RISCV_IOMMU_CMD_ATS_RID);
> +}
> +
> +pasid = get_field(cmd->dword0, RISCV_IOMMU_CMD_ATS_PID);
> +
> +qemu_mutex_lock(&s->core_lock);
> +QLIST_FOREACH(as, &s->spaces, list) {
> +if (as->devid == devid) {
> +break;
> +}
> +}
> +qemu_mutex_unlock(&s->core_lock);
> +
> +if (!as || !as->notifier) {
> +return;
> +}
> +
> +event.type = flag;
> +event.entry.perm = perm;
> +event.entry.target_as = s->target_as;
> +
> +IOMMU_NOTIFIER_FOREACH(n, &as->iova_mr) {
> +if (!pv || n->iommu_idx == pasid) {
> +event.entry.iova = n->start;
> +event.entry.addr_mask = n->end - n->start;
> +trace_fn(as->iova_mr.parent_obj.name);
> +memory_region_notify_iommu_one(n, &event);
> +}
> +}
> +}
> +
> +static void riscv_iommu_ats_inval(RISCVIOMMUState *s,
> +struct riscv_iommu_command *cmd)
> +{
> +return riscv_iommu_ats(s, cmd, IOMMU_NOTIFIER_DEVIOTLB_UNMAP, IOMMU_NONE,
> +   trace_riscv_iommu_ats_inval);
> +}
> +
> +static void riscv_iommu_ats_prgr(RISCVIOMMUState *s,
> +struct riscv_iommu_command *cmd)
> +{
> +unsigned resp_code = get_field(cmd->dword1,
> +   RISCV_IOMMU_CMD_ATS_PRGR_RESP_CODE);
> +
> +/* Using the access flag to carry response code information */
> +IOMMUAccessFlags perm = resp_code ? IOMMU_NONE : IOMMU_RW;
> +return riscv_iommu_ats(s, cmd, IOMMU_NOTIFIER_MAP, perm,
> +   trace_riscv_iommu_ats_prgr);
> +}
> +
>  static void riscv_iommu_process_ddtp(RISCVIOMMUState *s)
>  {
>  uint64_t old_ddtp = s->ddtp;
> @@ -1260,6 +1336,17 @@ static void 
> riscv_iommu_process_cq_tail(RISCVIOMMUState *s)
>  get_field(cmd.dword0, RISCV_IOMMU_CMD_IODIR_PID));
>  break;
>
> +/* ATS commands */
> +case RISCV_IOMMU_CMD(RISCV_IOMMU_CMD_ATS_FUNC_INVAL,
> + RISCV_IOMMU_CMD_ATS_OPCODE):
> +

Re: [PATCH v2 08/15] hw/riscv/riscv-iommu: add Address Translation Cache (IOATC)

2024-05-08 Thread Frank Chang
Hi Daniel,

Daniel Henrique Barboza  於 2024年3月8日 週五 上午12:05寫道:
>
> From: Tomasz Jeznach 
>
> The RISC-V IOMMU spec predicts that the IOMMU can use translation caches
> to hold entries from the DDT. This includes implementation for all cache
> commands that are marked as 'not implemented'.
>
> There are some artifacts included in the cache that predicts s-stage and
> g-stage elements, although we don't support it yet. We'll introduce them
> next.
>
> Signed-off-by: Tomasz Jeznach 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  hw/riscv/riscv-iommu.c | 190 -
>  hw/riscv/riscv-iommu.h |   2 +
>  2 files changed, 188 insertions(+), 4 deletions(-)
>
> diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> index df534b99b0..0b93146327 100644
> --- a/hw/riscv/riscv-iommu.c
> +++ b/hw/riscv/riscv-iommu.c
> @@ -63,6 +63,16 @@ struct RISCVIOMMUContext {
>  uint64_t msiptp;/* MSI redirection page table pointer */
>  };
>
> +/* Address translation cache entry */
> +struct RISCVIOMMUEntry {
> +uint64_t iova:44;   /* IOVA Page Number */
> +uint64_t pscid:20;  /* Process Soft-Context identifier */
> +uint64_t phys:44;   /* Physical Page Number */
> +uint64_t gscid:16;  /* Guest Soft-Context identifier */
> +uint64_t perm:2;/* IOMMU_RW flags */
> +uint64_t __rfu:2;
> +};
> +
>  /* IOMMU index for transactions without PASID specified. */
>  #define RISCV_IOMMU_NOPASID 0
>
> @@ -629,14 +639,127 @@ static AddressSpace *riscv_iommu_space(RISCVIOMMUState 
> *s, uint32_t devid)
>  return &as->iova_as;
>  }
>
> +/* Translation Object cache support */
> +static gboolean __iot_equal(gconstpointer v1, gconstpointer v2)
> +{
> +RISCVIOMMUEntry *t1 = (RISCVIOMMUEntry *) v1;
> +RISCVIOMMUEntry *t2 = (RISCVIOMMUEntry *) v2;
> +return t1->gscid == t2->gscid && t1->pscid == t2->pscid &&
> +   t1->iova == t2->iova;
> +}
> +
> +static guint __iot_hash(gconstpointer v)
> +{
> +RISCVIOMMUEntry *t = (RISCVIOMMUEntry *) v;
> +return (guint)t->iova;
> +}
> +
> +/* GV: 1 PSCV: 1 AV: 1 */
> +static void __iot_inval_pscid_iova(gpointer key, gpointer value, gpointer 
> data)
> +{
> +RISCVIOMMUEntry *iot = (RISCVIOMMUEntry *) value;
> +    RISCVIOMMUEntry *arg = (RISCVIOMMUEntry *) data;
> +if (iot->gscid == arg->gscid &&
> +iot->pscid == arg->pscid &&
> +iot->iova == arg->iova) {
> +iot->perm = 0;

Maybe using IOMMU_NONE would be clearer?

Otherwise,
Reviewed-by: Frank Chang 

> +}
> +}
> +
> +/* GV: 1 PSCV: 1 AV: 0 */
> +static void __iot_inval_pscid(gpointer key, gpointer value, gpointer data)
> +{
> +RISCVIOMMUEntry *iot = (RISCVIOMMUEntry *) value;
> +RISCVIOMMUEntry *arg = (RISCVIOMMUEntry *) data;
> +if (iot->gscid == arg->gscid &&
> +iot->pscid == arg->pscid) {
> +iot->perm = 0;
> +}
> +}
> +
> +/* GV: 1 GVMA: 1 */
> +static void __iot_inval_gscid_gpa(gpointer key, gpointer value, gpointer 
> data)
> +{
> +RISCVIOMMUEntry *iot = (RISCVIOMMUEntry *) value;
> +RISCVIOMMUEntry *arg = (RISCVIOMMUEntry *) data;
> +if (iot->gscid == arg->gscid) {
> +/* simplified cache, no GPA matching */
> +iot->perm = 0;
> +}
> +}
> +
> +/* GV: 1 GVMA: 0 */
> +static void __iot_inval_gscid(gpointer key, gpointer value, gpointer data)
> +{
> +RISCVIOMMUEntry *iot = (RISCVIOMMUEntry *) value;
> +RISCVIOMMUEntry *arg = (RISCVIOMMUEntry *) data;
> +if (iot->gscid == arg->gscid) {
> +iot->perm = 0;
> +}
> +}
> +
> +/* GV: 0 */
> +static void __iot_inval_all(gpointer key, gpointer value, gpointer data)
> +{
> +RISCVIOMMUEntry *iot = (RISCVIOMMUEntry *) value;
> +iot->perm = 0;
> +}
> +
> +/* caller should keep ref-count for iot_cache object */
> +static RISCVIOMMUEntry *riscv_iommu_iot_lookup(RISCVIOMMUContext *ctx,
> +GHashTable *iot_cache, hwaddr iova)
> +{
> +RISCVIOMMUEntry key = {
> +.pscid = get_field(ctx->ta, RISCV_IOMMU_DC_TA_PSCID),
> +.iova  = PPN_DOWN(iova),
> +};
> +return g_hash_table_lookup(iot_cache, &key);
> +}
> +
> +/* caller should keep ref-count for iot_cache object */
> +static void riscv_iommu_iot_update(RISCVIOMMUState *s,
> +GHashTable *iot_cache, RISCVIOMMUEntry *iot)
> +{
> +if (!s->iot_limit) {
> +return;
> +}
> +
> +if (g_hash_table_size(s->iot_ca

Re: [PATCH v2 09/15] hw/riscv/riscv-iommu: add s-stage and g-stage support

2024-05-10 Thread Frank Chang
gt;perm & IOMMU_WO) &&
> +riscv_iommu_msi_check(s, ctx, base)) {
> +/* Trap MSI writes and return GPA address. */
> +iotlb->target_as = &s->trap_as;
> +iotlb->addr_mask = ~TARGET_PAGE_MASK;
> +return 0;
> +}
> +
> +/* Continue with G-Stage translation? */
> +if (!pass && en_g) {
> +pass = G_STAGE;
> +addr = base;
> +base = gatp;
> +sc[pass].step = 0;
> +continue;
> +}
> +
> +return 0;
> +}
> +
> +if (sc[pass].step == sc[pass].levels) {
> +break; /* Can't find leaf PTE */
> +}
> +
> +/* Continue with G-Stage translation? */
> +if (!pass && en_g) {
> +pass = G_STAGE;
> +addr = base;
> +base = gatp;
> +sc[pass].step = 0;
> +}

Will this if condition ever be executed?

For S-stage -> G-stage (i.e. Nested translation),
G-stage translation should be continued by
the S-stage Leaf PTE's if condition above?

> +} while (1);
> +
> +return (iotlb->perm & IOMMU_WO) ?
> +(pass ? RISCV_IOMMU_FQ_CAUSE_WR_FAULT_VS :
> +RISCV_IOMMU_FQ_CAUSE_WR_FAULT_S) :
> +(pass ? RISCV_IOMMU_FQ_CAUSE_RD_FAULT_VS :
> +RISCV_IOMMU_FQ_CAUSE_RD_FAULT_S);
>  }
>
>  /* Redirect MSI write for given GPA. */
> @@ -351,6 +572,10 @@ static int riscv_iommu_ctx_fetch(RISCVIOMMUState *s, 
> RISCVIOMMUContext *ctx)
>
>  case RISCV_IOMMU_DDTP_MODE_BARE:
>  /* mock up pass-through translation context */
> +ctx->gatp = set_field(0, RISCV_IOMMU_ATP_MODE_FIELD,
> +RISCV_IOMMU_DC_IOHGATP_MODE_BARE);
> +ctx->satp = set_field(0, RISCV_IOMMU_ATP_MODE_FIELD,
> +RISCV_IOMMU_DC_FSC_MODE_BARE);
>  ctx->tc = RISCV_IOMMU_DC_TC_V;
>  ctx->ta = 0;
>  ctx->msiptp = 0;
> @@ -424,6 +649,8 @@ static int riscv_iommu_ctx_fetch(RISCVIOMMUState *s, 
> RISCVIOMMUContext *ctx)
>
>  /* Set translation context. */
>  ctx->tc = le64_to_cpu(dc.tc);
> +ctx->gatp = le64_to_cpu(dc.iohgatp);
> +ctx->satp = le64_to_cpu(dc.fsc);
>  ctx->ta = le64_to_cpu(dc.ta);
>  ctx->msiptp = le64_to_cpu(dc.msiptp);
>  ctx->msi_addr_mask = le64_to_cpu(dc.msi_addr_mask);
> @@ -433,14 +660,38 @@ static int riscv_iommu_ctx_fetch(RISCVIOMMUState *s, 
> RISCVIOMMUContext *ctx)
>  return RISCV_IOMMU_FQ_CAUSE_DDT_INVALID;
>  }
>
> +/* FSC field checks */
> +mode = get_field(ctx->satp, RISCV_IOMMU_DC_FSC_MODE);
> +addr = PPN_PHYS(get_field(ctx->satp, RISCV_IOMMU_DC_FSC_PPN));
> +
> +if (mode == RISCV_IOMMU_DC_FSC_MODE_BARE) {
> +/* No S-Stage translation, done. */
> +return 0;
> +}
> +
>  if (!(ctx->tc & RISCV_IOMMU_DC_TC_PDTV)) {
>  if (ctx->pasid != RISCV_IOMMU_NOPASID) {
>  /* PASID is disabled */
>  return RISCV_IOMMU_FQ_CAUSE_TTYPE_BLOCKED;
>  }
> +if (mode > RISCV_IOMMU_DC_FSC_IOSATP_MODE_SV57) {
> +/* Invalid translation mode */
> +return RISCV_IOMMU_FQ_CAUSE_DDT_INVALID;
> +}
>  return 0;
>  }
>
> +if (ctx->pasid == RISCV_IOMMU_NOPASID) {
> +if (!(ctx->tc & RISCV_IOMMU_DC_TC_DPE)) {
> +/* No default PASID enabled, set BARE mode */
> +ctx->satp = 0ULL;
> +return 0;
> +} else {
> +/* Use default PASID #0 */
> +ctx->pasid = 0;

How do we differentiate between the default PASID: 0
and RISCV_IOMMU_NOPASID?

Regards,
Frank Chang

> +}
> +}
> +
>  /* FSC.TC.PDTV enabled */
>  if (mode > RISCV_IOMMU_DC_FSC_PDTP_MODE_PD20) {
>  /* Invalid PDTP.MODE */
> @@ -474,6 +725,7 @@ static int riscv_iommu_ctx_fetch(RISCVIOMMUState *s, 
> RISCVIOMMUContext *ctx)
>
>  /* Use FSC and TA from process directory entry. */
>  ctx->ta = le64_to_cpu(dc.ta);
> +ctx->satp = le64_to_cpu(dc.fsc);
>
>  return 0;
>  }
> @@ -710,6 +962,7 @@ static RISCVIOMMUEntry 
> *riscv_iommu_iot_lookup(RISCVIOMMUContext *ctx,
>  GHashTable *iot_cache, hwaddr iova)
>  {
>  RISCVIOMMUEntry key = {
> +.gscid = get_field(ctx->gatp, RISCV_IOMMU_DC_IOHGATP_GSCID),
>  .pscid = get_field(ctx->ta, RISCV_IOMMU_DC_TA_PSCID),
>  .iova  = PPN_DOWN(iova),
>  };
> @@ -779,7 +10

Re: [RFC PATCH 0/1] pci: allocate a PCI ID for RISC-V IOMMU

2024-05-10 Thread Frank Chang
Hi Daniel,

Daniel Henrique Barboza  於 2024年5月8日 週三 下午8:42寫道:
>
>
>
> On 5/7/24 12:44, Peter Maydell wrote:
> > On Fri, 3 May 2024 at 13:43, Daniel Henrique Barboza
> >  wrote:
> >>
> >> Hi,
> >>
> >> In this RFC I want to check with Gerd and others if it's ok to add a PCI
> >> id for the RISC-V IOMMU device. It's currently under review in [1]. The
> >> idea is to fold this patch into the RISC-V IOMMU series if we're all ok
> >> with this change.
> >
> > My question here would be "why is this risc-v specific?" (and more
> > generally "what is this for?" -- the cover letter and patch and
> > documentation page provide almost no information about what this
> > device is and why it needs to exist rather than using either
> > virtio-iommu or else a model of a real hardware IOMMU.)
>
> The RISC-V IOMMU device emulation under review ([1]) is a reference 
> implementation of
> the riscv-iommu spec [2]. AFAIK it is similar to what we already have with 
> aarch64 'smmuv3'
> 'virt' bus, i.e. an impl of ARM's SMMUv3 that isn't tied to a specific vendor.
>
> The difference here is that the riscv-iommu spec, ratified by RISC-V 
> International (RVI),
> predicts that the device could be implemented as a PCIe device. But RVI 
> didn't bother
> assigning a PCI ID for their reference IOMMU. The existing implementation in 
> [1] is using
> a Rivos PCI ID that we're treating as a placeholder only. We need an ID that 
> reflects that
> this is a device that adheres to the riscv-iommu spec, not to an IOMMU of any 
> particular
> vendor.
>
> Since RVI doesn't provide a PCI ID for it we went to Red Hat, and they were 
> kind enough
> to give us a PCI ID for the RISC-V IOMMU reference device.

That's great. Thanks to Red Hat.
I'm wondering do we have the plan to document the new PCI ID to the IOMMU spec
or somewhere else that's publicly accessible?

Regards,
Frank Chang

>
> I'll do a proper job this time and add all this context in the commit msg. 
> Including a
> proper shout-out to Gerd and Red Hat.
>
>
>
> Thanks,
>
>
> Daniel
>
>
> [1] 
> https://lore.kernel.org/qemu-riscv/20240307160319.675044-1-dbarb...@ventanamicro.com/
> [2] https://github.com/riscv-non-isa/riscv-iommu/releases/tag/v1.0.0
>
> >
> > thanks
> > -- PMM
>



Re: [PATCH v2 03/15] hw/riscv: add RISC-V IOMMU base emulation

2024-05-10 Thread Frank Chang
Hi Daniel,

Daniel Henrique Barboza  於 2024年5月8日 週三 下午7:16寫道:
>
> Hi Frank,
>
> I'll reply with that I've done so far. Still missing some stuff:
>
> On 5/2/24 08:37, Frank Chang wrote:
> > Hi Daniel,
> >
> > Daniel Henrique Barboza  於 2024年3月8日 週五 
> > 上午12:04寫道:
> >>
> >> From: Tomasz Jeznach 
> >>
> >> The RISC-V IOMMU specification is now ratified as-per the RISC-V
> >> international process. The latest frozen specifcation can be found
> >> at:
> >>
> >> https://github.com/riscv-non-isa/riscv-iommu/releases/download/v1.0/riscv-iommu.pdf
> >>
> >> Add the foundation of the device emulation for RISC-V IOMMU, which
> >> includes an IOMMU that has no capabilities but MSI interrupt support and
> >> fault queue interfaces. We'll add add more features incrementally in the
> >> next patches.
> >>
> >> Co-developed-by: Sebastien Boeuf 
> >> Signed-off-by: Sebastien Boeuf 
> >> Signed-off-by: Tomasz Jeznach 
> >> Signed-off-by: Daniel Henrique Barboza 
> >> ---
> >>   hw/riscv/Kconfig |4 +
> >>   hw/riscv/meson.build |1 +
> >>   hw/riscv/riscv-iommu.c   | 1492 ++
> >>   hw/riscv/riscv-iommu.h   |  141 
> >>   hw/riscv/trace-events|   11 +
> >>   hw/riscv/trace.h |2 +
> >>   include/hw/riscv/iommu.h |   36 +
> >>   meson.build  |1 +
> >>   8 files changed, 1688 insertions(+)
> >>   create mode 100644 hw/riscv/riscv-iommu.c
> >>   create mode 100644 hw/riscv/riscv-iommu.h
> >>   create mode 100644 hw/riscv/trace-events
> >>   create mode 100644 hw/riscv/trace.h
> >>   create mode 100644 include/hw/riscv/iommu.h
> >>
>
> (...)
>
> +{
> >> +const uint32_t ipsr =
> >> +riscv_iommu_reg_mod32(s, RISCV_IOMMU_REG_IPSR, (1 << vec), 0);
> >> +const uint32_t ivec = riscv_iommu_reg_get32(s, RISCV_IOMMU_REG_IVEC);
> >> +if (s->notify && !(ipsr & (1 << vec))) {
> >> +s->notify(s, (ivec >> (vec * 4)) & 0x0F);
> >> +}
> >
> > s->notify is assigned to riscv_iommu_pci_notify() only.
> > There's no way to assert the wire-signaled interrupt.
> >
> > We should also check fctl.WSI before asserting the interrupt.
> >
>
> This implementation does not support wire-signalled interrupts. It supports 
> only
> MSI, i.e. capabililities.IGS is always MSI (0). For this reason the code is 
> also
> not checking for fctl.WSI.
>
>
>
> >> +}
>   (...)
>
> >> +g_hash_table_unref(ctx_cache);
> >> +*ref = NULL;
> >> +
> >> +if (!(ctx->tc & RISCV_IOMMU_DC_TC_DTF)) {
> >
> > riscv_iommu_ctx_fetch() may return:
> > RISCV_IOMMU_FQ_CAUSE_DMA_DISABLED (256)
> > RISCV_IOMMU_FQ_CAUSE_DDT_LOAD_FAULT (257)
> > RISCV_IOMMU_FQ_CAUSE_DDT_INVALID (258)
> > RISCV_IOMMU_FQ_CAUSE_DDT_MISCONFIGURED (259)
> >
> > These faults are reported even when DTF is set to 1.
> > We should report these faults regardless of DTF setting.
>
>
> I created a "riscv_iommu_report_fault()" helper to centralize all the report 
> fault
> logic. This helper will check for DTF and, if set, we'll check the 'cause' to 
> see if
> we still want the fault to be reported or not. This helper is then used in 
> these 2
> instances where we're creating a fault by hand. It's also used extensively in
> riscv_iommu_msi_write() to handle all the cases you mentioned above where we
> weren't issuing faults.
>
>
> >
> >> +struct riscv_iommu_fq_record ev = { 0 };
> >> +ev.hdr = set_field(ev.hdr, RISCV_IOMMU_FQ_HDR_CAUSE, fault);
> >> +ev.hdr = set_field(ev.hdr, RISCV_IOMMU_FQ_HDR_TTYPE,
> >> +RISCV_IOMMU_FQ_TTYPE_UADDR_RD);
> >> +ev.hdr = set_field(ev.hdr, RISCV_IOMMU_FQ_HDR_DID, devid);
> >> +ev.hdr = set_field(ev.hdr, RISCV_IOMMU_FQ_HDR_PID, pasid);
> >> +ev.hdr = set_field(ev.hdr, RISCV_IOMMU_FQ_HDR_PV, !!pasid);
> >> +riscv_iommu_fault(s, &ev);
> >> +}
> >> +
> >> +g_free(ctx);
> >> +return NULL;
> >> +}
> >> +
> >> +static void riscv_iommu_ctx_put(RISCVIOMMUState *s, void *ref)
> >> +{
> >> +if (ref) {
> >> +g_hash_table_unref((GHashTable *)ref);
> >> +}
> >> +}
>

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

2024-05-10 Thread Frank Chang
Hi Daniel,

Daniel Henrique Barboza  於 2024年5月6日 週一 下午9:06寫道:
>
> Hi Frank,
>
> On 5/6/24 01:09, Frank Chang wrote:
> > 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, &ref);
> >> +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, &iotlb, false);
> >> +if (fault) {
> >> +  

Re: [PATCH v2 02/15] hw/riscv: add riscv-iommu-bits.h

2024-05-10 Thread Frank Chang
Reviewed-by: Frank Chang 

Daniel Henrique Barboza  於 2024年3月8日 週五 上午12:07寫道:
>
> From: Tomasz Jeznach 
>
> This header will be used by the RISC-V IOMMU emulation to be added
> in the next patch. Due to its size it's being sent in separate for
> an easier review.
>
> One thing to notice is that this header can be replaced by the future
> Linux RISC-V IOMMU driver header, which would become a linux-header we
> would import instead of keeping our own. The Linux implementation isn't
> upstream yet so for now we'll have to manage riscv-iommu-bits.h.
>
> Signed-off-by: Tomasz Jeznach 
> Signed-off-by: Daniel Henrique Barboza 
> ---
>  hw/riscv/riscv-iommu-bits.h | 335 
>  1 file changed, 335 insertions(+)
>  create mode 100644 hw/riscv/riscv-iommu-bits.h
>
> diff --git a/hw/riscv/riscv-iommu-bits.h b/hw/riscv/riscv-iommu-bits.h
> new file mode 100644
> index 00..8e80b1e52a
> --- /dev/null
> +++ b/hw/riscv/riscv-iommu-bits.h
> @@ -0,0 +1,335 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright © 2022-2023 Rivos Inc.
> + * Copyright © 2023 FORTH-ICS/CARV
> + * Copyright © 2023 RISC-V IOMMU Task Group
> + *
> + * RISC-V Ziommu - Register Layout and Data Structures.
> + *
> + * Based on the IOMMU spec version 1.0, 3/2023
> + * https://github.com/riscv-non-isa/riscv-iommu
> + */
> +
> +#ifndef HW_RISCV_IOMMU_BITS_H
> +#define HW_RISCV_IOMMU_BITS_H
> +
> +#include "qemu/osdep.h"
> +
> +#define RISCV_IOMMU_SPEC_DOT_VER 0x010
> +
> +#ifndef GENMASK_ULL
> +#define GENMASK_ULL(h, l) (((~0ULL) >> (63 - (h) + (l))) << (l))
> +#endif
> +
> +/*
> + * struct riscv_iommu_fq_record - Fault/Event Queue Record
> + * See section 3.2 for more info.
> + */
> +struct riscv_iommu_fq_record {
> +uint64_t hdr;
> +uint64_t _reserved;
> +uint64_t iotval;
> +uint64_t iotval2;
> +};
> +/* Header fields */
> +#define RISCV_IOMMU_FQ_HDR_CAUSEGENMASK_ULL(11, 0)
> +#define RISCV_IOMMU_FQ_HDR_PID  GENMASK_ULL(31, 12)
> +#define RISCV_IOMMU_FQ_HDR_PV   BIT_ULL(32)
> +#define RISCV_IOMMU_FQ_HDR_TTYPEGENMASK_ULL(39, 34)
> +#define RISCV_IOMMU_FQ_HDR_DID  GENMASK_ULL(63, 40)
> +
> +/*
> + * struct riscv_iommu_pq_record - PCIe Page Request record
> + * For more infos on the PCIe Page Request queue see chapter 3.3.
> + */
> +struct riscv_iommu_pq_record {
> +  uint64_t hdr;
> +  uint64_t payload;
> +};
> +/* Header fields */
> +#define RISCV_IOMMU_PREQ_HDR_PIDGENMASK_ULL(31, 12)
> +#define RISCV_IOMMU_PREQ_HDR_PV BIT_ULL(32)
> +#define RISCV_IOMMU_PREQ_HDR_PRIV   BIT_ULL(33)
> +#define RISCV_IOMMU_PREQ_HDR_EXEC   BIT_ULL(34)
> +#define RISCV_IOMMU_PREQ_HDR_DIDGENMASK_ULL(63, 40)
> +/* Payload fields */
> +#define RISCV_IOMMU_PREQ_PAYLOAD_M  GENMASK_ULL(2, 0)
> +
> +/* Common field positions */
> +#define RISCV_IOMMU_PPN_FIELD   GENMASK_ULL(53, 10)
> +#define RISCV_IOMMU_QUEUE_LOGSZ_FIELD   GENMASK_ULL(4, 0)
> +#define RISCV_IOMMU_QUEUE_INDEX_FIELD   GENMASK_ULL(31, 0)
> +#define RISCV_IOMMU_QUEUE_ENABLEBIT(0)
> +#define RISCV_IOMMU_QUEUE_INTR_ENABLE   BIT(1)
> +#define RISCV_IOMMU_QUEUE_MEM_FAULT BIT(8)
> +#define RISCV_IOMMU_QUEUE_OVERFLOW  BIT(9)
> +#define RISCV_IOMMU_QUEUE_ACTIVEBIT(16)
> +#define RISCV_IOMMU_QUEUE_BUSY  BIT(17)
> +#define RISCV_IOMMU_ATP_PPN_FIELD   GENMASK_ULL(43, 0)
> +#define RISCV_IOMMU_ATP_MODE_FIELD  GENMASK_ULL(63, 60)
> +
> +/* 5.3 IOMMU Capabilities (64bits) */
> +#define RISCV_IOMMU_REG_CAP 0x
> +#define RISCV_IOMMU_CAP_VERSION GENMASK_ULL(7, 0)
> +#define RISCV_IOMMU_CAP_MSI_FLATBIT_ULL(22)
> +#define RISCV_IOMMU_CAP_MSI_MRIFBIT_ULL(23)
> +#define RISCV_IOMMU_CAP_IGS GENMASK_ULL(29, 28)
> +#define RISCV_IOMMU_CAP_PAS GENMASK_ULL(37, 32)
> +#define RISCV_IOMMU_CAP_PD8 BIT_ULL(38)
> +
> +/* 5.4 Features control register (32bits) */
> +#define RISCV_IOMMU_REG_FCTL0x0008
> +
> +/* 5.5 Device-directory-table pointer (64bits) */
> +#define RISCV_IOMMU_REG_DDTP0x0010
> +#define RISCV_IOMMU_DDTP_MODE   GENMASK_ULL(3, 0)
> +#define RISCV_IOMMU_DDTP_BUSY   BIT_ULL(4)
> +#define RISCV_IOMMU_DDTP_PPNRISCV_IOMMU_PPN_FIELD
> +
> +enum riscv_iommu_ddtp_modes {
> +RISCV_IOMMU_DDTP_MODE_OFF = 0,
> +RISCV_IOMMU_DDTP_MODE_BARE = 1,
> +RISCV_IOMMU_DDTP_MODE_1LVL = 2,
> +RISCV_IOMMU_DDTP_MODE_2LVL = 3,
> +RISCV_IOMMU_DDTP_MODE_3LVL = 4,
> +RISCV_IOMMU_DDTP_MODE_MAX = 4
> +};
>

Re: [PATCH v2 00/15] riscv: QEMU RISC-V IOMMU Support

2024-05-10 Thread Frank Chang
Hi Daniel,

Thanks for the upstream work.
Sorry that it took a while for me to review the patchset.

Please let me know if you need any help from us to update the IOMMU model.
We would like to see it merged for QEMU 9.1.0.

Regards,
Frank Chang

Daniel Henrique Barboza  於 2024年3月8日 週五 上午12:04寫道:
>
> Hi,
>
> This is the second version of the work Tomasz sent in July 2023 [1].
> I'll be helping Tomasz upstreaming it.
>
> The core emulation code is left unchanged but a few tweaks were made in
> v2:
>
> - The most notable difference in this version is that the code was split
>   in smaller chunks. Patch 03 is still a 1700 lines patch, which is an
>   improvement from the 3800 lines patch from v1, but we can only go so
>   far when splitting the core components of the emulation. The reality
>   is that the IOMMU emulation is a rather complex piece of software and
>   there's not much we can do to alleviate it;
>
> - I'm not contributing the HPM support that was present in v1. It shaved
>   off 600 lines of code from the series, which is already large enough
>   as is. We'll introduce HPM in later versions or as a follow-up;
>
> - The riscv-iommu-header.h header was also trimmed. I shaved it of 300
>   or so from it, all of them from definitions that the emulation isn't
>   using it. The header will be eventually be imported from the Linux
>   driver (not upstream yet), so for now we can live with a trimmed
>   header for the emulation usage alone;
>
> - I added libqos tests for the riscv-iommu-pci device. The idea of these
>   tests is to give us more confidence in the emulation code;
>
> - 'edu' device support. The support was retrieved from Tomasz EDU branch
>   [2]. This device can then be used to test PCI passthrough to exercise
>   the IOMMU.
>
>
> Patches based on alistair/riscv-to-apply.next.
>
> v1 link: 
> https://lore.kernel.org/qemu-riscv/cover.1689819031.git.tjezn...@rivosinc.com/
>
> [1] 
> https://lore.kernel.org/qemu-riscv/cover.1689819031.git.tjezn...@rivosinc.com/
> [2] https://github.com/tjeznach/qemu.git, branch 'riscv_iommu_edu_impl'
>
> Andrew Jones (1):
>   hw/riscv/riscv-iommu: Add another irq for mrif notifications
>
> Daniel Henrique Barboza (2):
>   test/qtest: add riscv-iommu-pci tests
>   qtest/riscv-iommu-test: add init queues test
>
> Tomasz Jeznach (12):
>   exec/memtxattr: add process identifier to the transaction attributes
>   hw/riscv: add riscv-iommu-bits.h
>   hw/riscv: add RISC-V IOMMU base emulation
>   hw/riscv: add riscv-iommu-pci device
>   hw/riscv: add riscv-iommu-sys platform device
>   hw/riscv/virt.c: support for RISC-V IOMMU PCIDevice hotplug
>   hw/riscv/riscv-iommu: add Address Translation Cache (IOATC)
>   hw/riscv/riscv-iommu: add s-stage and g-stage support
>   hw/riscv/riscv-iommu: add ATS support
>   hw/riscv/riscv-iommu: add DBG support
>   hw/misc: EDU: added PASID support
>   hw/misc: EDU: add ATS/PRI capability
>
>  hw/misc/edu.c|  297 -
>  hw/riscv/Kconfig |4 +
>  hw/riscv/meson.build |1 +
>  hw/riscv/riscv-iommu-bits.h  |  407 ++
>  hw/riscv/riscv-iommu-pci.c   |  173 +++
>  hw/riscv/riscv-iommu-sys.c   |   93 ++
>  hw/riscv/riscv-iommu.c   | 2085 ++
>  hw/riscv/riscv-iommu.h   |  146 +++
>  hw/riscv/trace-events|   15 +
>  hw/riscv/trace.h |2 +
>  hw/riscv/virt.c  |   33 +-
>  include/exec/memattrs.h  |5 +
>  include/hw/riscv/iommu.h |   40 +
>  meson.build  |1 +
>  tests/qtest/libqos/meson.build   |4 +
>  tests/qtest/libqos/riscv-iommu.c |   79 ++
>  tests/qtest/libqos/riscv-iommu.h |   96 ++
>  tests/qtest/meson.build  |1 +
>  tests/qtest/riscv-iommu-test.c   |  234 
>  19 files changed, 3704 insertions(+), 12 deletions(-)
>  create mode 100644 hw/riscv/riscv-iommu-bits.h
>  create mode 100644 hw/riscv/riscv-iommu-pci.c
>  create mode 100644 hw/riscv/riscv-iommu-sys.c
>  create mode 100644 hw/riscv/riscv-iommu.c
>  create mode 100644 hw/riscv/riscv-iommu.h
>  create mode 100644 hw/riscv/trace-events
>  create mode 100644 hw/riscv/trace.h
>  create mode 100644 include/hw/riscv/iommu.h
>  create mode 100644 tests/qtest/libqos/riscv-iommu.c
>  create mode 100644 tests/qtest/libqos/riscv-iommu.h
>  create mode 100644 tests/qtest/riscv-iommu-test.c
>
> --
> 2.43.2
>
>



Re: [PATCH v5 1/2] riscv: Pass Object to register_cpu_props instead of DeviceState

2023-01-16 Thread Frank Chang
Reviewed-by: Frank Chang 

On Fri, Jan 13, 2023 at 6:35 PM Alexandre Ghiti 
wrote:

> One can extract the DeviceState pointer from the Object pointer, so pass
> the Object for future commits to access other fields of Object.
>
> No functional changes intended.
>
> Signed-off-by: Alexandre Ghiti 
> ---
>  target/riscv/cpu.c | 15 ---
>  1 file changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index cc75ca7667..7181b34f86 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -200,7 +200,7 @@ static const char * const riscv_intr_names[] = {
>  "reserved"
>  };
>
> -static void register_cpu_props(DeviceState *dev);
> +static void register_cpu_props(Object *obj);
>
>  const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
>  {
> @@ -238,7 +238,7 @@ static void riscv_any_cpu_init(Object *obj)
>  set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
>  #endif
>  set_priv_version(env, PRIV_VERSION_1_12_0);
> -register_cpu_props(DEVICE(obj));
> +register_cpu_props(obj);
>  }
>
>  #if defined(TARGET_RISCV64)
> @@ -247,7 +247,7 @@ static void rv64_base_cpu_init(Object *obj)
>  CPURISCVState *env = &RISCV_CPU(obj)->env;
>  /* We set this in the realise function */
>  set_misa(env, MXL_RV64, 0);
> -register_cpu_props(DEVICE(obj));
> +register_cpu_props(obj);
>  /* Set latest version of privileged specification */
>  set_priv_version(env, PRIV_VERSION_1_12_0);
>  }
> @@ -280,7 +280,7 @@ static void rv128_base_cpu_init(Object *obj)
>  CPURISCVState *env = &RISCV_CPU(obj)->env;
>  /* We set this in the realise function */
>  set_misa(env, MXL_RV128, 0);
> -register_cpu_props(DEVICE(obj));
> +register_cpu_props(obj);
>  /* Set latest version of privileged specification */
>  set_priv_version(env, PRIV_VERSION_1_12_0);
>  }
> @@ -290,7 +290,7 @@ static void rv32_base_cpu_init(Object *obj)
>  CPURISCVState *env = &RISCV_CPU(obj)->env;
>  /* We set this in the realise function */
>  set_misa(env, MXL_RV32, 0);
> -register_cpu_props(DEVICE(obj));
> +register_cpu_props(obj);
>  /* Set latest version of privileged specification */
>  set_priv_version(env, PRIV_VERSION_1_12_0);
>  }
> @@ -343,7 +343,7 @@ static void riscv_host_cpu_init(Object *obj)
>  #elif defined(TARGET_RISCV64)
>  set_misa(env, MXL_RV64, 0);
>  #endif
> -register_cpu_props(DEVICE(obj));
> +register_cpu_props(obj);
>  }
>  #endif
>
> @@ -1083,9 +1083,10 @@ static Property riscv_cpu_extensions[] = {
>  DEFINE_PROP_END_OF_LIST(),
>  };
>
> -static void register_cpu_props(DeviceState *dev)
> +static void register_cpu_props(Object *obj)
>  {
>  Property *prop;
> +DeviceState *dev = DEVICE(obj);
>
>  for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
>  qdev_property_add_static(dev, prop);
> --
> 2.37.2
>
>


Re: [PATCH v9 2/5] riscv: Change type of valid_vm_1_10_[32|64] to bool

2023-02-01 Thread Frank Chang
Reviewed-by: Frank Chang 

On Tue, Jan 31, 2023 at 10:29 PM Alexandre Ghiti 
wrote:

> This array is actually used as a boolean so swap its current char type
> to a boolean and at the same time, change the type of validate_vm to
> bool since it returns valid_vm_1_10_[32|64].
>
> Suggested-by: Andrew Jones 
> Signed-off-by: Alexandre Ghiti 
> Reviewed-by: Andrew Jones 
> Reviewed-by: Alistair Francis 
> Reviewed-by: Bin Meng 
> ---
>  target/riscv/csr.c | 21 +++--
>  1 file changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 0db2c233e5..6b157806a5 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -1117,16 +1117,16 @@ static const target_ulong hip_writable_mask =
> MIP_VSSIP;
>  static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP |
> MIP_VSEIP;
>  static const target_ulong vsip_writable_mask = MIP_VSSIP;
>
> -static const char valid_vm_1_10_32[16] = {
> -[VM_1_10_MBARE] = 1,
> -[VM_1_10_SV32] = 1
> +static const bool valid_vm_1_10_32[16] = {
> +[VM_1_10_MBARE] = true,
> +[VM_1_10_SV32] = true
>  };
>
> -static const char valid_vm_1_10_64[16] = {
> -[VM_1_10_MBARE] = 1,
> -[VM_1_10_SV39] = 1,
> -[VM_1_10_SV48] = 1,
> -[VM_1_10_SV57] = 1
> +static const bool valid_vm_1_10_64[16] = {
> +[VM_1_10_MBARE] = true,
> +[VM_1_10_SV39] = true,
> +[VM_1_10_SV48] = true,
> +[VM_1_10_SV57] = true
>  };
>
>  /* Machine Information Registers */
> @@ -1209,7 +1209,7 @@ static RISCVException read_mstatus(CPURISCVState
> *env, int csrno,
>  return RISCV_EXCP_NONE;
>  }
>
> -static int validate_vm(CPURISCVState *env, target_ulong vm)
> +static bool validate_vm(CPURISCVState *env, target_ulong vm)
>  {
>  if (riscv_cpu_mxl(env) == MXL_RV32) {
>  return valid_vm_1_10_32[vm & 0xf];
> @@ -2648,7 +2648,8 @@ static RISCVException read_satp(CPURISCVState *env,
> int csrno,
>  static RISCVException write_satp(CPURISCVState *env, int csrno,
>   target_ulong val)
>  {
> -target_ulong vm, mask;
> +target_ulong mask;
> +bool vm;
>
>  if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
>  return RISCV_EXCP_NONE;
> --
> 2.37.2
>
>
>


Re: [PATCH v9 5/5] riscv: Correctly set the device-tree entry 'mmu-type'

2023-02-01 Thread Frank Chang
Reviewed-by: Frank Chang 

On Tue, Jan 31, 2023 at 10:36 PM Alexandre Ghiti 
wrote:

> The 'mmu-type' should reflect what the hardware is capable of so use the
> new satp_mode field in RISCVCPUConfig to do that.
>
> Signed-off-by: Alexandre Ghiti 
> Reviewed-by: Andrew Jones 
> Reviewed-by: Alistair Francis 
> Reviewed-by: Bin Meng 
> ---
>  hw/riscv/virt.c | 19 ++-
>  1 file changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 94ff2a1584..48d034a5f7 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -228,7 +228,8 @@ static void create_fdt_socket_cpus(RISCVVirtState *s,
> int socket,
>  int cpu;
>  uint32_t cpu_phandle;
>  MachineState *mc = MACHINE(s);
> -char *name, *cpu_name, *core_name, *intc_name;
> +uint8_t satp_mode_max;
> +char *name, *cpu_name, *core_name, *intc_name, *sv_name;
>
>  for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) {
>  cpu_phandle = (*phandle)++;
> @@ -236,14 +237,14 @@ static void create_fdt_socket_cpus(RISCVVirtState
> *s, int socket,
>  cpu_name = g_strdup_printf("/cpus/cpu@%d",
>  s->soc[socket].hartid_base + cpu);
>  qemu_fdt_add_subnode(mc->fdt, cpu_name);
> -if (riscv_feature(&s->soc[socket].harts[cpu].env,
> -  RISCV_FEATURE_MMU)) {
> -qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type",
> -(is_32_bit) ? "riscv,sv32" :
> "riscv,sv48");
> -} else {
> -qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type",
> -"riscv,none");
> -}
> +
> +satp_mode_max = satp_mode_max_from_map(
> +s->soc[socket].harts[cpu].cfg.satp_mode.map);
> +sv_name = g_strdup_printf("riscv,%s",
> +  satp_mode_str(satp_mode_max,
> is_32_bit));
> +qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type", sv_name);
> +g_free(sv_name);
> +
>  name = riscv_isa_string(&s->soc[socket].harts[cpu]);
>  qemu_fdt_setprop_string(mc->fdt, cpu_name, "riscv,isa", name);
>  g_free(name);
> --
> 2.37.2
>
>
>


Re: [PATCH v9 4/5] riscv: Introduce satp mode hw capabilities

2023-02-01 Thread Frank Chang
On Tue, Jan 31, 2023 at 10:36 PM Alexandre Ghiti 
wrote:

> Currently, the max satp mode is set with the only constraint that it must
> be
> implemented in QEMU, i.e. set in valid_vm_1_10_[32|64].
>
> But we actually need to add another level of constraint: what the hw is
> actually capable of, because currently, a linux booting on a sifive-u54
> boots in sv57 mode which is incompatible with the cpu's sv39 max
> capability.
>
> So add a new bitmap to RISCVSATPMap which contains this capability and
> initialize it in every XXX_cpu_init.
>
> Finally:
> - valid_vm_1_10_[32|64] constrains which satp mode the CPU can use
> - the CPU hw capabilities constrains what the user may select
> - the user's selection then constrains what's available to the guest
>   OS.
>
> Signed-off-by: Alexandre Ghiti 
> Reviewed-by: Andrew Jones 
> ---
>  target/riscv/cpu.c | 79 +++---
>  target/riscv/cpu.h |  8 +++--
>  2 files changed, 60 insertions(+), 27 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 3a7a1746aa..6dd76355ec 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -292,26 +292,36 @@ const char *satp_mode_str(uint8_t satp_mode, bool
> is_32_bit)
>  g_assert_not_reached();
>  }
>
> -/* Sets the satp mode to the max supported */
> -static void set_satp_mode_default_map(RISCVCPU *cpu)
> +static void set_satp_mode_max_supported(RISCVCPU *cpu,
> +uint8_t satp_mode)
>  {
>  bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32;
> +const bool *valid_vm = rv32 ? valid_vm_1_10_32 : valid_vm_1_10_64;
>

This will break user-mode QEMU.
valid_vm_1_10_32 and valid_vm_1_10_64 are defined in !CONFIG_USER_ONLY
section.
This issue also exists in patch 3.
You have to move valid_vm_1_10_32 and valid_vm_1_10_64 out from
!CONFIG_USER_ONLY.

Regards,
Frank Chang


> -if (riscv_feature(&cpu->env, RISCV_FEATURE_MMU)) {
> -cpu->cfg.satp_mode.map |=
> -(1 << satp_mode_from_str(rv32 ? "sv32" : "sv57"));
> -} else {
> -cpu->cfg.satp_mode.map |= (1 << satp_mode_from_str("mbare"));
> +for (int i = 0; i <= satp_mode; ++i) {
> +if (valid_vm[i]) {
> +cpu->cfg.satp_mode.supported |= (1 << i);
> +}
>  }
>  }
>
> +/* Set the satp mode to the max supported */
> +static void set_satp_mode_default_map(RISCVCPU *cpu)
> +{
> +cpu->cfg.satp_mode.map = cpu->cfg.satp_mode.supported;
> +}
> +
>  static void riscv_any_cpu_init(Object *obj)
>  {
>  CPURISCVState *env = &RISCV_CPU(obj)->env;
> +RISCVCPU *cpu = RISCV_CPU(obj);
> +
>  #if defined(TARGET_RISCV32)
>  set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
> +set_satp_mode_max_supported(cpu, VM_1_10_SV32);
>  #elif defined(TARGET_RISCV64)
>  set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
> +set_satp_mode_max_supported(cpu, VM_1_10_SV57);
>  #endif
>  set_priv_version(env, PRIV_VERSION_1_12_0);
>  register_cpu_props(obj);
> @@ -321,18 +331,24 @@ static void riscv_any_cpu_init(Object *obj)
>  static void rv64_base_cpu_init(Object *obj)
>  {
>  CPURISCVState *env = &RISCV_CPU(obj)->env;
> +RISCVCPU *cpu = RISCV_CPU(obj);
> +
>  /* We set this in the realise function */
>  set_misa(env, MXL_RV64, 0);
>  register_cpu_props(obj);
>  /* Set latest version of privileged specification */
>  set_priv_version(env, PRIV_VERSION_1_12_0);
> +set_satp_mode_max_supported(cpu, VM_1_10_SV57);
>  }
>
>  static void rv64_sifive_u_cpu_init(Object *obj)
>  {
>  CPURISCVState *env = &RISCV_CPU(obj)->env;
> +RISCVCPU *cpu = RISCV_CPU(obj);
> +
>  set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS |
> RVU);
>  set_priv_version(env, PRIV_VERSION_1_10_0);
> +set_satp_mode_max_supported(cpu, VM_1_10_SV39);
>  }
>
>  static void rv64_sifive_e_cpu_init(Object *obj)
> @@ -343,6 +359,7 @@ static void rv64_sifive_e_cpu_init(Object *obj)
>  set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
>  set_priv_version(env, PRIV_VERSION_1_10_0);
>  cpu->cfg.mmu = false;
> +set_satp_mode_max_supported(cpu, VM_1_10_MBARE);
>  }
>
>  static void rv128_base_cpu_init(Object *obj)
> @@ -354,28 +371,36 @@ static void rv128_base_cpu_init(Object *obj)
>  exit(EXIT_FAILURE);
>  }
>  CPURISCVState *env = &RISCV_CPU(obj)->env;
> +RISCVCPU *cpu = RISCV_CPU(obj);
>  /* We set this in the realise function */
>  

[PATCH v10 00/77] support vector extension v1.0

2021-11-28 Thread frank . chang
From: Frank Chang 

This patchset implements the vector extension v1.0 for RISC-V on QEMU.

RVV v1.0 spec is now fronzen for public review:
https://github.com/riscv/riscv-v-spec/releases/tag/v1.0

The port is available here:
https://github.com/sifive/qemu/tree/rvv-1.0-upstream-v10

RVV v1.0 can be enabled with -cpu option: v=true and specify vext_spec
option to v1.0 (i.e. vext_spec=v1.0)

Note: This patchset depends on other patchsets listed in Based-on
  section below so it is not able to be built unless those patchsets
  are applied.

Changelog:

v10
  * Add ELEN checks for widening and narrowing instructions.

v9
  * Remove explicitly set mstatus.SD patches as mstatus.SD is now
set in add_status_sd().
  * Rebase on riscv-to-apply.next branch.

v8
  * Use {get,dest}_gpr APIs.
  * remove vector AMO instructions.
  * rename vpopc.m to vcpop.m.
  * rename vle1.v and vse1.v to vlm.v and vsm.v.
  * rename vmandnot.mm and vmornot.mm to vmandn.mm and vmorn.mm.

v7
  * remove hardcoded GDB vector registers list.
  * add vsetivli instruction.
  * add vle1.v and vse1.v instructions.

v6
  * add vector floating-point reciprocal estimate instruction.
  * add vector floating-point reciprocal square-root estimate instruction.
  * update check rules for segment register groups, each segment register
group has to follow overlap rules.
  * update viota.m instruction check rules.

v5
  * refactor RVV v1.0 check functions.
(Thanks to Richard Henderson's bitwise tricks.)
  * relax RV_VLEN_MAX to 1024-bits.
  * implement vstart CSR's behaviors.
  * trigger illegal instruction exception if frm is not valid for
vector floating-point instructions.
  * rebase on riscv-to-apply.next.

v4
  * remove explicit float flmul variable in DisasContext.
  * replace floating-point calculations with shift operations to
improve performance.
  * relax RV_VLEN_MAX to 512-bits.

v3
  * apply nan-box helpers from Richard Henderson.
  * remove fp16 api changes as they are sent independently in another
pathcset by Chih-Min Chao.
  * remove all tail elements clear functions as tail elements can
retain unchanged for either VTA set to undisturbed or agnostic.
  * add fp16 nan-box check generator function.
  * add floating-point rounding mode enum.
  * replace flmul arithmetic with shifts to avoid floating-point
conversions.
  * add Zvqmac extension.
  * replace gdbstub vector register xml files with dynamic generator.
  * bumped to RVV v1.0.
  * RVV v1.0 related changes:
* add vlre.v and vsr.v vector whole register
  load/store instructions
* add vrgatherei16 instruction.
* rearranged bits in vtype to make vlmul bits into a contiguous
  field.

v2
  * drop v0.7.1 support.
  * replace invisible return check macros with functions.
  * move mark_vs_dirty() to translators.
  * add SSTATUS_VS flag for s-mode.
  * nan-box scalar fp register for floating-point operations.
  * add gdbstub files for vector registers to allow system-mode
debugging with GDB.

Based-on: <20211021160847.2748577-1-frank.ch...@sifive.com>
Based-on: <20211021162956.2772656-1-frank.ch...@sifive.com>

Frank Chang (72):
  target/riscv: drop vector 0.7.1 and add 1.0 support
  target/riscv: Use FIELD_EX32() to extract wd field
  target/riscv: rvv-1.0: set mstatus.SD bit if mstatus.VS is dirty
  target/riscv: rvv-1.0: introduce writable misa.v field
  target/riscv: rvv-1.0: add translation-time vector context status
  target/riscv: rvv-1.0: remove rvv related codes from fcsr registers
  target/riscv: rvv-1.0: check MSTATUS_VS when accessing vector csr
registers
  target/riscv: rvv-1.0: remove MLEN calculations
  target/riscv: rvv-1.0: add fractional LMUL
  target/riscv: rvv-1.0: add VMA and VTA
  target/riscv: rvv-1.0: update check functions
  target/riscv: introduce more imm value modes in translator functions
  target/riscv: rvv:1.0: add translation-time nan-box helper function
  target/riscv: rvv-1.0: remove amo operations instructions
  target/riscv: rvv-1.0: configure instructions
  target/riscv: rvv-1.0: stride load and store instructions
  target/riscv: rvv-1.0: index load and store instructions
  target/riscv: rvv-1.0: fix address index overflow bug of indexed
load/store insns
  target/riscv: rvv-1.0: fault-only-first unit stride load
  target/riscv: rvv-1.0: load/store whole register instructions
  target/riscv: rvv-1.0: update vext_max_elems() for load/store insns
  target/riscv: rvv-1.0: take fractional LMUL into vector max elements
calculation
  target/riscv: rvv-1.0: floating-point square-root instruction
  target/riscv: rvv-1.0: floating-point classify instructions
  target/riscv: rvv-1.0: count population in mask instruction
  target/riscv: rvv-1.0: find-first-set mask bit instruction
  target/riscv: rvv-1.0: set-X-first mask bit instructions
  target/riscv: rvv-1.0: iota instruction
  target/riscv: rvv-1.0: element index instruction
  target/riscv: rvv-1.0: allow load elem

[PATCH v10 03/77] target/riscv: rvv-1.0: add mstatus VS field

2021-11-28 Thread frank . chang
From: LIU Zhiwei 

Signed-off-by: LIU Zhiwei 
Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h|  2 ++
 target/riscv/cpu_bits.h   |  1 +
 target/riscv/cpu_helper.c | 20 +++-
 target/riscv/csr.c| 12 +++-
 4 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5ea2004ae02..48b8f612109 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -352,6 +352,7 @@ int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, 
CPUState *cs,
 int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 bool riscv_cpu_fp_enabled(CPURISCVState *env);
+bool riscv_cpu_vector_enabled(CPURISCVState *env);
 bool riscv_cpu_virt_enabled(CPURISCVState *env);
 void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
 bool riscv_cpu_two_stage_lookup(int mmu_idx);
@@ -395,6 +396,7 @@ void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
 #define TB_FLAGS_PRIV_MMU_MASK3
 #define TB_FLAGS_PRIV_HYP_ACCESS_MASK   (1 << 2)
 #define TB_FLAGS_MSTATUS_FS MSTATUS_FS
+#define TB_FLAGS_MSTATUS_VS MSTATUS_VS
 
 typedef CPURISCVState CPUArchState;
 typedef RISCVCPU ArchCPU;
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 9913fa9f778..72a716c9990 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -375,6 +375,7 @@
 #define MSTATUS_UBE 0x0040
 #define MSTATUS_MPIE0x0080
 #define MSTATUS_SPP 0x0100
+#define MSTATUS_VS  0x0600
 #define MSTATUS_MPP 0x1800
 #define MSTATUS_FS  0x6000
 #define MSTATUS_XS  0x00018000
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index f30ff672f8c..5789c2e9690 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -90,12 +90,17 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 
 #ifdef CONFIG_USER_ONLY
 flags |= TB_FLAGS_MSTATUS_FS;
+flags |= TB_FLAGS_MSTATUS_VS;
 #else
 flags |= cpu_mmu_index(env, 0);
 if (riscv_cpu_fp_enabled(env)) {
 flags |= env->mstatus & MSTATUS_FS;
 }
 
+if (riscv_cpu_vector_enabled(env)) {
+flags |= env->mstatus & MSTATUS_VS;
+}
+
 if (riscv_has_ext(env, RVH)) {
 if (env->priv == PRV_M ||
 (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
@@ -189,11 +194,24 @@ bool riscv_cpu_fp_enabled(CPURISCVState *env)
 return false;
 }
 
+/* Return true is vector support is currently enabled */
+bool riscv_cpu_vector_enabled(CPURISCVState *env)
+{
+if (env->mstatus & MSTATUS_VS) {
+if (riscv_cpu_virt_enabled(env) && !(env->mstatus_hs & MSTATUS_VS)) {
+return false;
+}
+return true;
+}
+
+return false;
+}
+
 void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
 {
 uint64_t mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
 MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE |
-MSTATUS64_UXL;
+MSTATUS64_UXL | MSTATUS_VS;
 bool current_virt = riscv_cpu_virt_enabled(env);
 
 g_assert(riscv_has_ext(env, RVH));
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 9f41954894d..9b5bd5d7b49 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -273,6 +273,7 @@ static RISCVException write_fcsr(CPURISCVState *env, int 
csrno,
 {
 #if !defined(CONFIG_USER_ONLY)
 env->mstatus |= MSTATUS_FS;
+env->mstatus |= MSTATUS_VS;
 #endif
 env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
 if (vs(env, csrno) >= 0) {
@@ -307,6 +308,9 @@ static RISCVException read_vxrm(CPURISCVState *env, int 
csrno,
 static RISCVException write_vxrm(CPURISCVState *env, int csrno,
  target_ulong val)
 {
+#if !defined(CONFIG_USER_ONLY)
+env->mstatus |= MSTATUS_VS;
+#endif
 env->vxrm = val;
 return RISCV_EXCP_NONE;
 }
@@ -321,6 +325,9 @@ static RISCVException read_vxsat(CPURISCVState *env, int 
csrno,
 static RISCVException write_vxsat(CPURISCVState *env, int csrno,
   target_ulong val)
 {
+#if !defined(CONFIG_USER_ONLY)
+env->mstatus |= MSTATUS_VS;
+#endif
 env->vxsat = val;
 return RISCV_EXCP_NONE;
 }
@@ -335,6 +342,9 @@ static RISCVException read_vstart(CPURISCVState *env, int 
csrno,
 static RISCVException write_vstart(CPURISCVState *env, int csrno,
target_ulong val)
 {
+#if !defined(CONFIG_USER_ONLY)
+env->mstatus |= MSTATUS_VS;
+#endif
 env->vstart = val;
 return RISCV_EXCP_NONE;
 }
@@ -535,7 +545,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int 
csrno,
 mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTA

[PATCH v10 07/77] target/riscv: rvv-1.0: add translation-time vector context status

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: LIU Zhiwei 
Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h  |  5 +-
 target/riscv/cpu_helper.c   |  3 +
 target/riscv/insn_trans/trans_rvv.c.inc | 75 +
 target/riscv/translate.c| 40 +
 4 files changed, 109 insertions(+), 14 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 48b8f612109..eee2a2b19ed 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -410,10 +410,11 @@ FIELD(TB_FLAGS, VILL, 9, 1)
 /* Is a Hypervisor instruction load/store allowed? */
 FIELD(TB_FLAGS, HLSX, 10, 1)
 FIELD(TB_FLAGS, MSTATUS_HS_FS, 11, 2)
+FIELD(TB_FLAGS, MSTATUS_HS_VS, 13, 2)
 /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
-FIELD(TB_FLAGS, XL, 13, 2)
+FIELD(TB_FLAGS, XL, 15, 2)
 /* If PointerMasking should be applied */
-FIELD(TB_FLAGS, PM_ENABLED, 15, 1)
+FIELD(TB_FLAGS, PM_ENABLED, 17, 1)
 
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 5789c2e9690..7149657edf9 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -111,6 +111,9 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 
 flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_FS,
get_field(env->mstatus_hs, MSTATUS_FS));
+
+flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
+   get_field(env->mstatus_hs, MSTATUS_VS));
 }
 if (riscv_has_ext(env, RVJ)) {
 int priv = flags & TB_FLAGS_PRIV_MMU_MASK;
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 17ee3babefd..bc1d4a5f235 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -39,6 +39,7 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
 }
 gen_helper_vsetvl(dst, cpu_env, s1, s2);
 gen_set_gpr(ctx, a->rd, dst);
+mark_vs_dirty(ctx);
 
 tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
 tcg_gen_lookup_and_goto_ptr();
@@ -66,6 +67,7 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
 }
 gen_helper_vsetvl(dst, cpu_env, s1, s2);
 gen_set_gpr(ctx, a->rd, dst);
+mark_vs_dirty(ctx);
 
 gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
 ctx->base.is_jmp = DISAS_NORETURN;
@@ -154,7 +156,8 @@ typedef void gen_helper_ldst_us(TCGv_ptr, TCGv_ptr, TCGv,
 TCGv_env, TCGv_i32);
 
 static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
-  gen_helper_ldst_us *fn, DisasContext *s)
+  gen_helper_ldst_us *fn, DisasContext *s,
+  bool is_store)
 {
 TCGv_ptr dest, mask;
 TCGv base;
@@ -183,6 +186,11 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, 
uint32_t data,
 
 tcg_temp_free_ptr(dest);
 tcg_temp_free_ptr(mask);
+
+if (!is_store) {
+mark_vs_dirty(s);
+}
+
 gen_set_label(over);
 return true;
 }
@@ -233,7 +241,7 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, 
uint8_t seq)
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
-return ldst_us_trans(a->rd, a->rs1, data, fn, s);
+return ldst_us_trans(a->rd, a->rs1, data, fn, s, false);
 }
 
 static bool ld_us_check(DisasContext *s, arg_r2nfvm* a)
@@ -286,7 +294,7 @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, 
uint8_t seq)
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
-return ldst_us_trans(a->rd, a->rs1, data, fn, s);
+return ldst_us_trans(a->rd, a->rs1, data, fn, s, true);
 }
 
 static bool st_us_check(DisasContext *s, arg_r2nfvm* a)
@@ -309,7 +317,7 @@ typedef void gen_helper_ldst_stride(TCGv_ptr, TCGv_ptr, 
TCGv,
 
 static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
   uint32_t data, gen_helper_ldst_stride *fn,
-  DisasContext *s)
+  DisasContext *s, bool is_store)
 {
 TCGv_ptr dest, mask;
 TCGv base, stride;
@@ -331,6 +339,11 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, 
uint32_t rs2,
 
 tcg_temp_free_ptr(dest);
 tcg_temp_free_ptr(mask);
+
+if (!is_store) {
+mark_vs_dirty(s);
+}
+
 gen_set_label(over);
 return true;
 }
@@ -365,7 +378,7 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, 
uint8_t seq)
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
- 

[PATCH v10 04/77] target/riscv: rvv-1.0: set mstatus.SD bit if mstatus.VS is dirty

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/csr.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 9b5bd5d7b49..bb500afdeb5 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -502,6 +502,7 @@ static RISCVException read_mhartid(CPURISCVState *env, int 
csrno,
 static uint64_t add_status_sd(RISCVMXL xl, uint64_t status)
 {
 if ((status & MSTATUS_FS) == MSTATUS_FS ||
+(status & MSTATUS_VS) == MSTATUS_VS ||
 (status & MSTATUS_XS) == MSTATUS_XS) {
 switch (xl) {
 case MXL_RV32:
-- 
2.25.1




[PATCH v10 05/77] target/riscv: rvv-1.0: add sstatus VS field

2021-11-28 Thread frank . chang
From: LIU Zhiwei 

Signed-off-by: LIU Zhiwei 
Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu_bits.h | 1 +
 target/riscv/csr.c  | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 72a716c9990..bb62da7549d 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -409,6 +409,7 @@ typedef enum {
 #define SSTATUS_UPIE0x0010
 #define SSTATUS_SPIE0x0020
 #define SSTATUS_SPP 0x0100
+#define SSTATUS_VS  0x0600
 #define SSTATUS_FS  0x6000
 #define SSTATUS_XS  0x00018000
 #define SSTATUS_SUM 0x0004 /* since: priv-1.10 */
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index bb500afdeb5..83f4dbd8241 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -463,7 +463,7 @@ static const target_ulong vs_delegable_excps = 
DELEGABLE_EXCPS &
   (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)));
 static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
 SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
-SSTATUS_SUM | SSTATUS_MXR;
+SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS;
 static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
 static const target_ulong hip_writable_mask = MIP_VSSIP;
 static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | 
MIP_VSEIP;
-- 
2.25.1




[PATCH v10 10/77] target/riscv: rvv-1.0: add vlenb register

2021-11-28 Thread frank . chang
From: Greentime Hu 

Signed-off-by: Greentime Hu 
Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu_bits.h | 1 +
 target/riscv/csr.c  | 7 +++
 2 files changed, 8 insertions(+)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 8dc6aa62c64..1e31f4d35f5 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -63,6 +63,7 @@
 #define CSR_VCSR0x00f
 #define CSR_VL  0xc20
 #define CSR_VTYPE   0xc21
+#define CSR_VLENB   0xc22
 
 /* VCSR fields */
 #define VCSR_VXSAT_SHIFT0
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 832ccdcf331..5d1eec1ea05 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -285,6 +285,12 @@ static RISCVException read_vl(CPURISCVState *env, int 
csrno,
 return RISCV_EXCP_NONE;
 }
 
+static int read_vlenb(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env_archcpu(env)->cfg.vlen >> 3;
+return RISCV_EXCP_NONE;
+}
+
 static RISCVException read_vxrm(CPURISCVState *env, int csrno,
 target_ulong *val)
 {
@@ -1835,6 +1841,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_VCSR] = { "vcsr", vs, read_vcsr,write_vcsr   },
 [CSR_VL]   = { "vl",   vs, read_vl},
 [CSR_VTYPE]= { "vtype",vs, read_vtype },
+[CSR_VLENB]= { "vlenb",vs, read_vlenb },
 /* User Timers and Counters */
 [CSR_CYCLE]= { "cycle",ctr,read_instret  },
 [CSR_INSTRET]  = { "instret",  ctr,read_instret  },
-- 
2.25.1




[PATCH v10 06/77] target/riscv: rvv-1.0: introduce writable misa.v field

2021-11-28 Thread frank . chang
From: Frank Chang 

Implementations may have a writable misa.v field. Analogous to the way
in which the floating-point unit is handled, the mstatus.vs field may
exist even if misa.v is clear.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/csr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 83f4dbd8241..bc149add6ce 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -643,7 +643,7 @@ static RISCVException write_misa(CPURISCVState *env, int 
csrno,
 val &= env->misa_ext_mask;
 
 /* Mask extensions that are not supported by QEMU */
-val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU | RVV);
 
 /* 'D' depends on 'F', so clear 'D' if 'F' is not present */
 if ((val & RVD) && !(val & RVF)) {
-- 
2.25.1




[PATCH v10 16/77] target/riscv: introduce more imm value modes in translator functions

2021-11-28 Thread frank . chang
From: Frank Chang 

Immediate value in translator function is extended not only
zero-extended and sign-extended but with more modes to be applicable
with multiple formats of vector instructions.

* IMM_ZX: Zero-extended
* IMM_SX: Sign-extended
* IMM_TRUNC_SEW:  Truncate to log(SEW) bit
* IMM_TRUNC_2SEW: Truncate to log(2*SEW) bit

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 115 ++--
 1 file changed, 66 insertions(+), 49 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index bef37dd888e..66273afb537 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1313,8 +1313,32 @@ static void tcg_gen_gvec_rsubs(unsigned vece, uint32_t 
dofs, uint32_t aofs,
 
 GEN_OPIVX_GVEC_TRANS(vrsub_vx, rsubs)
 
+typedef enum {
+IMM_ZX, /* Zero-extended */
+IMM_SX, /* Sign-extended */
+IMM_TRUNC_SEW,  /* Truncate to log(SEW) bits */
+IMM_TRUNC_2SEW, /* Truncate to log(2*SEW) bits */
+} imm_mode_t;
+
+static int64_t extract_imm(DisasContext *s, uint32_t imm, imm_mode_t imm_mode)
+{
+switch (imm_mode) {
+case IMM_ZX:
+return extract64(imm, 0, 5);
+case IMM_SX:
+return sextract64(imm, 0, 5);
+case IMM_TRUNC_SEW:
+return extract64(imm, 0, s->sew + 3);
+case IMM_TRUNC_2SEW:
+return extract64(imm, 0, s->sew + 4);
+default:
+g_assert_not_reached();
+}
+}
+
 static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
-gen_helper_opivx *fn, DisasContext *s, int zx)
+gen_helper_opivx *fn, DisasContext *s,
+imm_mode_t imm_mode)
 {
 TCGv_ptr dest, src2, mask;
 TCGv src1;
@@ -1327,11 +1351,8 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, 
uint32_t vs2, uint32_t vm,
 dest = tcg_temp_new_ptr();
 mask = tcg_temp_new_ptr();
 src2 = tcg_temp_new_ptr();
-if (zx) {
-src1 = tcg_constant_tl(imm);
-} else {
-src1 = tcg_constant_tl(sextract64(imm, 0, 5));
-}
+src1 = tcg_constant_tl(extract_imm(s, imm, imm_mode));
+
 data = FIELD_DP32(data, VDATA, VM, vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
@@ -1355,28 +1376,23 @@ typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, 
int64_t,
 
 static inline bool
 do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn,
-  gen_helper_opivx *fn, int zx)
+  gen_helper_opivx *fn, imm_mode_t imm_mode)
 {
 if (!opivx_check(s, a)) {
 return false;
 }
 
 if (a->vm && s->vl_eq_vlmax) {
-if (zx) {
-gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
-extract64(a->rs1, 0, 5), MAXSZ(s), MAXSZ(s));
-} else {
-gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
-sextract64(a->rs1, 0, 5), MAXSZ(s), MAXSZ(s));
-}
+gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
+extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s));
 mark_vs_dirty(s);
 return true;
 }
-return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s, zx);
+return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s, imm_mode);
 }
 
 /* OPIVI with GVEC IR */
-#define GEN_OPIVI_GVEC_TRANS(NAME, ZX, OPIVX, SUF) \
+#define GEN_OPIVI_GVEC_TRANS(NAME, IMM_MODE, OPIVX, SUF) \
 static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
 {  \
 static gen_helper_opivx * const fns[4] = { \
@@ -1384,10 +1400,10 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)  
   \
 gen_helper_##OPIVX##_w, gen_helper_##OPIVX##_d,\
 }; \
 return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, \
- fns[s->sew], ZX); \
+ fns[s->sew], IMM_MODE);   \
 }
 
-GEN_OPIVI_GVEC_TRANS(vadd_vi, 0, vadd_vx, addi)
+GEN_OPIVI_GVEC_TRANS(vadd_vi, IMM_SX, vadd_vx, addi)
 
 static void tcg_gen_gvec_rsubi(unsigned vece, uint32_t dofs, uint32_t aofs,
int64_t c, uint32_t oprsz, uint32_t maxsz)
@@ -1396,7 +1412,7 @@ static void tcg_gen_gvec_rsubi(unsigned vece, uint32_t 
dofs, uint32_t aofs,
 tcg_gen_gvec_rsubs(vece, dofs, aofs, tmp, oprsz, maxsz);
 }
 
-GEN_OPIVI_GVEC_TRANS(vrsub_vi, 0, vrsub_vx, rsubi)
+GEN_OPIVI_GVEC_TRANS(vrsub_vi, IMM_SX, vrsub_vx, rsubi)
 
 /* Vector Widening Integer Add/Subtract */
 
@@ -1652,7 +1668,7

[PATCH v10 11/77] target/riscv: rvv-1.0: check MSTATUS_VS when accessing vector csr registers

2021-11-28 Thread frank . chang
From: Frank Chang 

If VS field is off, accessing vector csr registers should raise an
illegal-instruction exception.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/csr.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 5d1eec1ea05..3dfbc177381 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -48,6 +48,11 @@ static RISCVException fs(CPURISCVState *env, int csrno)
 static RISCVException vs(CPURISCVState *env, int csrno)
 {
 if (env->misa_ext & RVV) {
+#if !defined(CONFIG_USER_ONLY)
+if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+#endif
 return RISCV_EXCP_NONE;
 }
 return RISCV_EXCP_ILLEGAL_INST;
-- 
2.25.1




[PATCH v10 19/77] target/riscv: rvv-1.0: configure instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 62 +++--
 target/riscv/vector_helper.c| 14 +-
 2 files changed, 40 insertions(+), 36 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index afec187..049688d83a8 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -120,59 +120,51 @@ static bool require_noover(const int8_t dst, const int8_t 
dst_lmul,
 return !is_overlapped(dst, dst_size, src, src_size);
 }
 
-static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
+static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
 {
-TCGv s1, s2, dst;
+TCGv s1, dst;
 
-if (!require_rvv(ctx) || !has_ext(ctx, RVV)) {
+if (!require_rvv(s) || !has_ext(s, RVV)) {
 return false;
 }
 
-s2 = get_gpr(ctx, a->rs2, EXT_ZERO);
-dst = dest_gpr(ctx, a->rd);
+dst = dest_gpr(s, rd);
 
-/* Using x0 as the rs1 register specifier, encodes an infinite AVL */
-if (a->rs1 == 0) {
+if (rd == 0 && rs1 == 0) {
+s1 = tcg_temp_new();
+tcg_gen_mov_tl(s1, cpu_vl);
+} else if (rs1 == 0) {
 /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
 s1 = tcg_constant_tl(RV_VLEN_MAX);
 } else {
-s1 = get_gpr(ctx, a->rs1, EXT_ZERO);
+s1 = get_gpr(s, rs1, EXT_ZERO);
 }
+
 gen_helper_vsetvl(dst, cpu_env, s1, s2);
-gen_set_gpr(ctx, a->rd, dst);
-mark_vs_dirty(ctx);
+gen_set_gpr(s, rd, dst);
+mark_vs_dirty(s);
 
-tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn);
 tcg_gen_lookup_and_goto_ptr();
-ctx->base.is_jmp = DISAS_NORETURN;
-return true;
-}
+s->base.is_jmp = DISAS_NORETURN;
 
-static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
-{
-TCGv s1, s2, dst;
-
-if (!require_rvv(ctx) || !has_ext(ctx, RVV)) {
-return false;
+if (rd == 0 && rs1 == 0) {
+tcg_temp_free(s1);
 }
 
-s2 = tcg_constant_tl(a->zimm);
-dst = dest_gpr(ctx, a->rd);
+return true;
+}
 
-/* Using x0 as the rs1 register specifier, encodes an infinite AVL */
-if (a->rs1 == 0) {
-/* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
-s1 = tcg_constant_tl(RV_VLEN_MAX);
-} else {
-s1 = get_gpr(ctx, a->rs1, EXT_ZERO);
-}
-gen_helper_vsetvl(dst, cpu_env, s1, s2);
-gen_set_gpr(ctx, a->rd, dst);
-mark_vs_dirty(ctx);
+static bool trans_vsetvl(DisasContext *s, arg_vsetvl *a)
+{
+TCGv s2 = get_gpr(s, a->rs2, EXT_ZERO);
+return do_vsetvl(s, a->rd, a->rs1, s2);
+}
 
-gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
-ctx->base.is_jmp = DISAS_NORETURN;
-return true;
+static bool trans_vsetvli(DisasContext *s, arg_vsetvli *a)
+{
+TCGv s2 = tcg_constant_tl(a->zimm);
+return do_vsetvl(s, a->rd, a->rs1, s2);
 }
 
 /* vector register offset from env */
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index bf976d364f1..78fae782840 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -31,12 +31,24 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, 
target_ulong s1,
 {
 int vlmax, vl;
 RISCVCPU *cpu = env_archcpu(env);
+uint64_t lmul = FIELD_EX64(s2, VTYPE, VLMUL);
 uint16_t sew = 8 << FIELD_EX64(s2, VTYPE, VSEW);
 uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
 bool vill = FIELD_EX64(s2, VTYPE, VILL);
 target_ulong reserved = FIELD_EX64(s2, VTYPE, RESERVED);
 
-if ((sew > cpu->cfg.elen) || vill || (ediv != 0) || (reserved != 0)) {
+if (lmul & 4) {
+/* Fractional LMUL. */
+if (lmul == 4 ||
+cpu->cfg.elen >> (8 - lmul) < sew) {
+vill = true;
+}
+}
+
+if ((sew > cpu->cfg.elen)
+|| vill
+|| (ediv != 0)
+|| (reserved != 0)) {
 /* only set vill bit. */
 env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
 env->vl = 0;
-- 
2.25.1




[PATCH v10 09/77] target/riscv: rvv-1.0: add vcsr register

2021-11-28 Thread frank . chang
From: LIU Zhiwei 

Signed-off-by: LIU Zhiwei 
Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu_bits.h |  7 +++
 target/riscv/csr.c  | 17 +
 2 files changed, 24 insertions(+)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index bb62da7549d..8dc6aa62c64 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -60,9 +60,16 @@
 #define CSR_VSTART  0x008
 #define CSR_VXSAT   0x009
 #define CSR_VXRM0x00a
+#define CSR_VCSR0x00f
 #define CSR_VL  0xc20
 #define CSR_VTYPE   0xc21
 
+/* VCSR fields */
+#define VCSR_VXSAT_SHIFT0
+#define VCSR_VXSAT  (0x1 << VCSR_VXSAT_SHIFT)
+#define VCSR_VXRM_SHIFT 1
+#define VCSR_VXRM   (0x3 << VCSR_VXRM_SHIFT)
+
 /* User Timers and Counters */
 #define CSR_CYCLE   0xc00
 #define CSR_TIME0xc01
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index c522260986c..832ccdcf331 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -336,6 +336,22 @@ static RISCVException write_vstart(CPURISCVState *env, int 
csrno,
 return RISCV_EXCP_NONE;
 }
 
+static int read_vcsr(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = (env->vxrm << VCSR_VXRM_SHIFT) | (env->vxsat << VCSR_VXSAT_SHIFT);
+return RISCV_EXCP_NONE;
+}
+
+static int write_vcsr(CPURISCVState *env, int csrno, target_ulong val)
+{
+#if !defined(CONFIG_USER_ONLY)
+env->mstatus |= MSTATUS_VS;
+#endif
+env->vxrm = (val & VCSR_VXRM) >> VCSR_VXRM_SHIFT;
+env->vxsat = (val & VCSR_VXSAT) >> VCSR_VXSAT_SHIFT;
+return RISCV_EXCP_NONE;
+}
+
 /* User Timers and Counters */
 static RISCVException read_instret(CPURISCVState *env, int csrno,
target_ulong *val)
@@ -1816,6 +1832,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_VSTART]   = { "vstart",   vs, read_vstart,  write_vstart },
 [CSR_VXSAT]= { "vxsat",vs, read_vxsat,   write_vxsat  },
 [CSR_VXRM] = { "vxrm", vs, read_vxrm,write_vxrm   },
+[CSR_VCSR] = { "vcsr", vs, read_vcsr,write_vcsr   },
 [CSR_VL]   = { "vl",   vs, read_vl},
 [CSR_VTYPE]= { "vtype",vs, read_vtype },
 /* User Timers and Counters */
-- 
2.25.1




[PATCH v10 17/77] target/riscv: rvv:1.0: add translation-time nan-box helper function

2021-11-28 Thread frank . chang
From: Frank Chang 

* Add fp16 nan-box check generator function, if a 16-bit input is not
  properly nanboxed, then the input is replaced with the default qnan.
* Add do_nanbox() helper function to utilize gen_check_nanbox_X() to
  generate the NaN-boxed floating-point values based on SEW setting.
* Apply nanbox helper in opfvf_trans().

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 35 -
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 66273afb537..f9ace6ae412 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2098,6 +2098,33 @@ GEN_OPIVI_NARROW_TRANS(vnclip_vi, IMM_ZX, vnclip_vx)
 /*
  *** Vector Float Point Arithmetic Instructions
  */
+
+/*
+ * As RVF-only cpus always have values NaN-boxed to 64-bits,
+ * RVF and RVD can be treated equally.
+ * We don't have to deal with the cases of: SEW > FLEN.
+ *
+ * If SEW < FLEN, check whether input fp register is a valid
+ * NaN-boxed value, in which case the least-significant SEW bits
+ * of the f regsiter are used, else the canonical NaN value is used.
+ */
+static void do_nanbox(DisasContext *s, TCGv_i64 out, TCGv_i64 in)
+{
+switch (s->sew) {
+case 1:
+gen_check_nanbox_h(out, in);
+break;
+case 2:
+gen_check_nanbox_s(out, in);
+break;
+case 3:
+tcg_gen_mov_i64(out, in);
+break;
+default:
+g_assert_not_reached();
+}
+}
+
 /* Vector Single-Width Floating-Point Add/Subtract Instructions */
 
 /*
@@ -2151,6 +2178,7 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, 
uint32_t vs2,
 {
 TCGv_ptr dest, src2, mask;
 TCGv_i32 desc;
+TCGv_i64 t1;
 
 TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
@@ -2164,11 +2192,16 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, 
uint32_t vs2,
 tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
 tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
-fn(dest, mask, cpu_fpr[rs1], src2, cpu_env, desc);
+/* NaN-box f[rs1] */
+t1 = tcg_temp_new_i64();
+do_nanbox(s, t1, cpu_fpr[rs1]);
+
+fn(dest, mask, t1, src2, cpu_env, desc);
 
 tcg_temp_free_ptr(dest);
 tcg_temp_free_ptr(mask);
 tcg_temp_free_ptr(src2);
+tcg_temp_free_i64(t1);
 mark_vs_dirty(s);
 gen_set_label(over);
 return true;
-- 
2.25.1




[PATCH v10 22/77] target/riscv: rvv-1.0: fix address index overflow bug of indexed load/store insns

2021-11-28 Thread frank . chang
From: Frank Chang 

Replace ETYPE from signed int to unsigned int to prevent index overflow
issue, which would lead to wrong index address.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index df45c1620c1..3da4f3b1e62 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -374,10 +374,10 @@ static target_ulong NAME(target_ulong base,\
 return (base + *((ETYPE *)vs2 + H(idx)));  \
 }
 
-GEN_VEXT_GET_INDEX_ADDR(idx_b, int8_t,  H1)
-GEN_VEXT_GET_INDEX_ADDR(idx_h, int16_t, H2)
-GEN_VEXT_GET_INDEX_ADDR(idx_w, int32_t, H4)
-GEN_VEXT_GET_INDEX_ADDR(idx_d, int64_t, H8)
+GEN_VEXT_GET_INDEX_ADDR(idx_b, uint8_t,  H1)
+GEN_VEXT_GET_INDEX_ADDR(idx_h, uint16_t, H2)
+GEN_VEXT_GET_INDEX_ADDR(idx_w, uint32_t, H4)
+GEN_VEXT_GET_INDEX_ADDR(idx_d, uint64_t, H8)
 
 static inline void
 vext_ldst_index(void *vd, void *v0, target_ulong base,
-- 
2.25.1




[PATCH v10 20/77] target/riscv: rvv-1.0: stride load and store instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   | 129 ++--
 target/riscv/insn32.decode  |  43 ++-
 target/riscv/insn_trans/trans_rvv.c.inc | 376 
 target/riscv/vector_helper.c| 199 +
 4 files changed, 300 insertions(+), 447 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index ecb6af6cd99..5a760fa4a32 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -112,111 +112,30 @@ DEF_HELPER_2(hyp_hlvx_wu, tl, env, tl)
 
 /* Vector functions */
 DEF_HELPER_3(vsetvl, tl, env, tl, tl)
-DEF_HELPER_5(vlb_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_b_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlw_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlw_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlw_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlw_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_b_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_b_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwu_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwu_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwu_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwu_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_b_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsw_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsw_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsw_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsw_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_b_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_6(vlsb_v_b, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsb_v_h, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsb_v_w, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsb_v_d, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsh_v_h, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsh_v_w, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsh_v_d, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsw_v_w, void

[PATCH v10 08/77] target/riscv: rvv-1.0: remove rvv related codes from fcsr registers

2021-11-28 Thread frank . chang
From: Frank Chang 

* Remove VXRM and VXSAT fields from FCSR register as they are only
  presented in VCSR register.
* Remove RVV loose check in fs() predicate function.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/csr.c | 13 -
 1 file changed, 13 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index bc149add6ce..c522260986c 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -38,10 +38,6 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
 static RISCVException fs(CPURISCVState *env, int csrno)
 {
 #if !defined(CONFIG_USER_ONLY)
-/* loose check condition for fcsr in vector extension */
-if ((csrno == CSR_FCSR) && (env->misa_ext & RVV)) {
-return RISCV_EXCP_NONE;
-}
 if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
@@ -261,10 +257,6 @@ static RISCVException read_fcsr(CPURISCVState *env, int 
csrno,
 {
 *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
 | (env->frm << FSR_RD_SHIFT);
-if (vs(env, csrno) >= 0) {
-*val |= (env->vxrm << FSR_VXRM_SHIFT)
-| (env->vxsat << FSR_VXSAT_SHIFT);
-}
 return RISCV_EXCP_NONE;
 }
 
@@ -273,13 +265,8 @@ static RISCVException write_fcsr(CPURISCVState *env, int 
csrno,
 {
 #if !defined(CONFIG_USER_ONLY)
 env->mstatus |= MSTATUS_FS;
-env->mstatus |= MSTATUS_VS;
 #endif
 env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
-if (vs(env, csrno) >= 0) {
-env->vxrm = (val & FSR_VXRM) >> FSR_VXRM_SHIFT;
-env->vxsat = (val & FSR_VXSAT) >> FSR_VXSAT_SHIFT;
-}
 riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
 return RISCV_EXCP_NONE;
 }
-- 
2.25.1




[PATCH v10 18/77] target/riscv: rvv-1.0: remove amo operations instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Vector AMOs are removed from standard vector extensions. Will be added
later as separate Zvamo extension, but will need a different encoding
from earlier proposal.

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   |  27 -
 target/riscv/insn32.decode  |  24 
 target/riscv/insn_trans/trans_rvv.c.inc | 140 
 target/riscv/vector_helper.c| 125 -
 4 files changed, 316 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index d25cf725c57..ecb6af6cd99 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -274,33 +274,6 @@ DEF_HELPER_5(vlhuff_v_w, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vlhuff_v_d, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vlwuff_v_w, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vlwuff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_6(vamoswapw_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoswapd_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoaddw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoaddd_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoxorw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoxord_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoandw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoandd_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoorw_v_d,   void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoord_v_d,   void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamominw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomind_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxd_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamominuw_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamominud_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxuw_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxud_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoswapw_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoaddw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoxorw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoandw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoorw_v_w,   void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamominw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamominuw_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxuw_v_w, void, ptr, ptr, tl, ptr, env, i32)
 
 DEF_HELPER_6(vadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 6c4cde216bc..3d57255fffb 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -49,7 +49,6 @@
 &atomicaq rl rs2 rs1 rd
 &rmrr  vm rd rs1 rs2
 &rmr   vm rd rs2
-&rwdvm vm wd rd rs1 rs2
 &r2nfvmvm rd rs1 nf
 &rnfvm vm rd rs1 rs2 nf
 
@@ -79,7 +78,6 @@
 @r_vm.. vm:1 . . ... . ... &rmrr %rs2 %rs1 %rd
 @r_vm_1  .. . . . ... . ...&rmrr vm=1 %rs2 %rs1 %rd
 @r_vm_0  .. . . . ... . ...&rmrr vm=0 %rs2 %rs1 %rd
-@r_wdvm  . wd:1 vm:1 . . ... . ... &rwdvm %rs2 %rs1 %rd
 @r2_zimm . zimm:11  . ... . ... %rs1 %rd
 @r2_s...   . . ... . ... %rs2 %rs1
 
@@ -340,17 +338,6 @@ vsxh_v ... -11 . . . 101 . 0100111 @r_nfvm
 vsxw_v ... -11 . . . 110 . 0100111 @r_nfvm
 vsxe_v ... -11 . . . 111 . 0100111 @r_nfvm
 
-#*** Vector AMO operations are encoded under the standard AMO major opcode ***
-vamoswapw_v 1 . . . . 110 . 010 @r_wdvm
-vamoaddw_v  0 . . . . 110 . 010 @r_wdvm
-vamoxorw_v  00100 . . . . 110 . 010 @r_wdvm
-vamoandw_v  01100 . . . . 110 . 010 @r_wdvm
-vamoorw_v   01000 . . . . 110 . 010 @r_wdvm
-vamominw_v  1 . . . . 110 . 010 @r_wdvm
-vamomaxw_v  10100 . . . . 110 . 010 @r_wdvm
-vamominuw_v 11000 . . . . 110 . 010 @r_wdvm
-vamomaxuw_v 11100 . . . . 110 . 010 @r_wdvm
-
 # *** new major opcode OP-V ***
 vadd_vv 00 . . . 000 . 1010111 @r_vm
 vadd_vx 00 . . . 100 . 1010111 @r_vm
@@ -649,17 +636,6 @@ vcompress_vm010111 - . . 010 . 1010111 @r
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
 
-#*** Vector AMO operations (in addition to Zvamo) ***
-vamoswapd_v 1 . . . . 111 . 010 @r_wdvm
-vamoaddd_v  0 . . . ...

[PATCH v10 23/77] target/riscv: rvv-1.0: fault-only-first unit stride load

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   | 26 ++---
 target/riscv/insn32.decode  | 14 ++---
 target/riscv/insn_trans/trans_rvv.c.inc | 33 +++
 target/riscv/vector_helper.c| 74 +++--
 4 files changed, 38 insertions(+), 109 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 1beca6dc0d7..57560b8c04d 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -168,28 +168,10 @@ DEF_HELPER_6(vsxei64_8_v, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(vsxei64_16_v, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vsxei64_32_v, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vsxei64_64_v, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_5(vlbff_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbff_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhff_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vleff_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vleff_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vleff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vleff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbuff_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbuff_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbuff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbuff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhuff_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhuff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhuff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwuff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwuff_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(vle8ff_v, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(vle16ff_v, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(vle32ff_v, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(vle64ff_v, void, ptr, ptr, tl, env, i32)
 
 DEF_HELPER_6(vadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index f34194d31c4..180d97ecba3 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -314,14 +314,6 @@ vsse16_v... 010 . . . 101 . 0100111 @r_nfvm
 vsse32_v... 010 . . . 110 . 0100111 @r_nfvm
 vsse64_v... 010 . . . 111 . 0100111 @r_nfvm
 
-vlbff_v... 100 . 1 . 000 . 111 @r2_nfvm
-vlhff_v... 100 . 1 . 101 . 111 @r2_nfvm
-vlwff_v... 100 . 1 . 110 . 111 @r2_nfvm
-vleff_v... 000 . 1 . 111 . 111 @r2_nfvm
-vlbuff_v   ... 000 . 1 . 000 . 111 @r2_nfvm
-vlhuff_v   ... 000 . 1 . 101 . 111 @r2_nfvm
-vlwuff_v   ... 000 . 1 . 110 . 111 @r2_nfvm
-
 # Vector ordered-indexed and unordered-indexed load insns.
 vlxei8_v  ... 0-1 . . . 000 . 111 @r_nfvm
 vlxei16_v ... 0-1 . . . 101 . 111 @r_nfvm
@@ -334,6 +326,12 @@ vsxei16_v ... 0-1 . . . 101 . 0100111 
@r_nfvm
 vsxei32_v ... 0-1 . . . 110 . 0100111 @r_nfvm
 vsxei64_v ... 0-1 . . . 111 . 0100111 @r_nfvm
 
+# Vector unit-stride fault-only-first load insns.
+vle8ff_v  ... 000 . 1 . 000 . 111 @r2_nfvm
+vle16ff_v ... 000 . 1 . 101 . 111 @r2_nfvm
+vle32ff_v ... 000 . 1 . 110 . 111 @r2_nfvm
+vle64ff_v ... 000 . 1 . 111 . 111 @r2_nfvm
+
 # *** new major opcode OP-V ***
 vadd_vv 00 . . . 000 . 1010111 @r_vm
 vadd_vx 00 . . . 100 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 6946d03340d..5b5285b33f7 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -935,28 +935,16 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, 
uint32_t data,
 return true;
 }
 
-static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
+static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew)
 {
 uint32_t data = 0;
 gen_helper_ldst_us *fn;
-static gen_helper_ldst_us * const fns[7][4] = {
-{ gen_helper_vlbff_v_b,  gen_helper_vlbff_v_h,
-  gen_helper_vlbff_v_w,  gen_helper_vlbff_v_d },
-{ NULL,  gen_helper_vlhff_v_h,
-  gen_helper_vlhff_v_w,  gen_helper_vlhff_v_d },
-{ NULL,  NULL,
-  gen_helper_vlwff_v_w,  gen_helper_vlwff_v_d

[PATCH v10 27/77] target/riscv: rvv-1.0: floating-point square-root instruction

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn32.decode | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 7d8441d1f21..92a0e6fe51e 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -563,7 +563,7 @@ vfwmsac_vv  10 . . . 001 . 1010111 @r_vm
 vfwmsac_vf  10 . . . 101 . 1010111 @r_vm
 vfwnmsac_vv 11 . . . 001 . 1010111 @r_vm
 vfwnmsac_vf 11 . . . 101 . 1010111 @r_vm
-vfsqrt_v100011 . . 0 001 . 1010111 @r2_vm
+vfsqrt_v010011 . . 0 001 . 1010111 @r2_vm
 vfmin_vv000100 . . . 001 . 1010111 @r_vm
 vfmin_vf000100 . . . 101 . 1010111 @r_vm
 vfmax_vv000110 . . . 001 . 1010111 @r_vm
-- 
2.25.1




[PATCH v10 28/77] target/riscv: rvv-1.0: floating-point classify instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn32.decode | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 92a0e6fe51e..f61eaf7c6ba 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -586,7 +586,7 @@ vmfgt_vf011101 . . . 101 . 1010111 @r_vm
 vmfge_vf01 . . . 101 . 1010111 @r_vm
 vmford_vv   011010 . . . 001 . 1010111 @r_vm
 vmford_vf   011010 . . . 101 . 1010111 @r_vm
-vfclass_v   100011 . . 1 001 . 1010111 @r2_vm
+vfclass_v   010011 . . 1 001 . 1010111 @r2_vm
 vfmerge_vfm 010111 0 . . 101 . 1010111 @r_vm_0
 vfmv_v_f010111 1 0 . 101 . 1010111 @r2
 vfcvt_xu_f_v100010 . . 0 001 . 1010111 @r2_vm
-- 
2.25.1




[PATCH v10 24/77] target/riscv: rvv-1.0: load/store whole register instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Add the following instructions:

* vlre.v
* vsr.v

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   | 21 
 target/riscv/insn32.decode  | 22 
 target/riscv/insn_trans/trans_rvv.c.inc | 68 +
 target/riscv/vector_helper.c| 65 +++
 4 files changed, 176 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 57560b8c04d..b8894d61510 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -173,6 +173,27 @@ DEF_HELPER_5(vle16ff_v, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vle32ff_v, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vle64ff_v, void, ptr, ptr, tl, env, i32)
 
+DEF_HELPER_4(vl1re8_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl1re16_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl1re32_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl1re64_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl2re8_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl2re16_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl2re32_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl2re64_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl4re8_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl4re16_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl4re32_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl4re64_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl8re8_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl8re16_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl8re32_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl8re64_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vs1r_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vs2r_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vs4r_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vs8r_v, void, ptr, tl, env, i32)
+
 DEF_HELPER_6(vadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 180d97ecba3..7d8441d1f21 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -332,6 +332,28 @@ vle16ff_v ... 000 . 1 . 101 . 111 
@r2_nfvm
 vle32ff_v ... 000 . 1 . 110 . 111 @r2_nfvm
 vle64ff_v ... 000 . 1 . 111 . 111 @r2_nfvm
 
+# Vector whole register insns
+vl1re8_v  000 000 1 01000 . 000 . 111 @r2
+vl1re16_v 000 000 1 01000 . 101 . 111 @r2
+vl1re32_v 000 000 1 01000 . 110 . 111 @r2
+vl1re64_v 000 000 1 01000 . 111 . 111 @r2
+vl2re8_v  001 000 1 01000 . 000 . 111 @r2
+vl2re16_v 001 000 1 01000 . 101 . 111 @r2
+vl2re32_v 001 000 1 01000 . 110 . 111 @r2
+vl2re64_v 001 000 1 01000 . 111 . 111 @r2
+vl4re8_v  011 000 1 01000 . 000 . 111 @r2
+vl4re16_v 011 000 1 01000 . 101 . 111 @r2
+vl4re32_v 011 000 1 01000 . 110 . 111 @r2
+vl4re64_v 011 000 1 01000 . 111 . 111 @r2
+vl8re8_v  111 000 1 01000 . 000 . 111 @r2
+vl8re16_v 111 000 1 01000 . 101 . 111 @r2
+vl8re32_v 111 000 1 01000 . 110 . 111 @r2
+vl8re64_v 111 000 1 01000 . 111 . 111 @r2
+vs1r_v000 000 1 01000 . 000 . 0100111 @r2
+vs2r_v001 000 1 01000 . 000 . 0100111 @r2
+vs4r_v011 000 1 01000 . 000 . 0100111 @r2
+vs8r_v111 000 1 01000 . 000 . 0100111 @r2
+
 # *** new major opcode OP-V ***
 vadd_vv 00 . . . 000 . 1010111 @r_vm
 vadd_vx 00 . . . 100 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 5b5285b33f7..5e8e49d43f4 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -960,6 +960,74 @@ GEN_VEXT_TRANS(vle16ff_v, MO_16, r2nfvm, ldff_op, 
ld_us_check)
 GEN_VEXT_TRANS(vle32ff_v, MO_32, r2nfvm, ldff_op, ld_us_check)
 GEN_VEXT_TRANS(vle64ff_v, MO_64, r2nfvm, ldff_op, ld_us_check)
 
+/*
+ * load and store whole register instructions
+ */
+typedef void gen_helper_ldst_whole(TCGv_ptr, TCGv, TCGv_env, TCGv_i32);
+
+static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,
+ gen_helper_ldst_whole *fn, DisasContext *s,
+ bool is_store)
+{
+TCGv_ptr dest;
+TCGv base;
+TCGv_i32 desc;
+
+uint32_t data = FIELD_DP32(0, VDATA, NF, nf);
+dest = tcg_temp_new_ptr();
+desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+
+base = get_gpr(s, rs1, EXT_NONE);
+tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
+
+fn(dest, base, cpu_env, desc);
+
+tcg_temp_free_ptr(dest);
+
+if (!is_store) {
+mark_vs_dirty(s);
+}
+
+return true;
+}
+
+/*
+ * load and store whole register instructions ignore vtype and vl s

[PATCH v10 21/77] target/riscv: rvv-1.0: index load and store instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   |  67 +++
 target/riscv/insn32.decode  |  21 +++--
 target/riscv/insn_trans/trans_rvv.c.inc | 110 +---
 target/riscv/vector_helper.c|  98 +
 4 files changed, 145 insertions(+), 151 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 5a760fa4a32..1beca6dc0d7 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -136,41 +136,38 @@ DEF_HELPER_6(vsse8_v, void, ptr, ptr, tl, tl, env, i32)
 DEF_HELPER_6(vsse16_v, void, ptr, ptr, tl, tl, env, i32)
 DEF_HELPER_6(vsse32_v, void, ptr, ptr, tl, tl, env, i32)
 DEF_HELPER_6(vsse64_v, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlxb_v_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxb_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxb_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxb_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxh_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxh_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxh_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxw_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxw_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxe_v_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxe_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxe_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxe_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxbu_v_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxbu_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxbu_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxbu_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxhu_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxhu_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxhu_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxwu_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxwu_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxb_v_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxb_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxb_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxb_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxh_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxh_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxh_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxw_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxw_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxe_v_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxe_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxe_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxe_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei8_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei8_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei8_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei8_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei16_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei16_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei16_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei16_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei32_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei32_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei32_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei32_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei64_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei64_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei64_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei64_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei8_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei8_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei8_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei8_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei16_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei16_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei16_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei16_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei32_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei32_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei32_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei32_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei64_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei64_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei64_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei64_64_v, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_5(vlbff_v_b, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vlbff_v_h, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5

[PATCH v10 35/77] target/riscv: rvv-1.0: register gather instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

* Add vrgatherei16.vv instruction.

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   |  4 
 target/riscv/insn32.decode  |  1 +
 target/riscv/insn_trans/trans_rvv.c.inc | 27 ++---
 target/riscv/vector_helper.c| 23 -
 4 files changed, 43 insertions(+), 12 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 7646567eb27..bd0768d048f 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1059,6 +1059,10 @@ DEF_HELPER_6(vrgather_vv_b, void, ptr, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_6(vrgather_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vrgather_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vrgather_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrgatherei16_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrgatherei16_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrgatherei16_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrgatherei16_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vrgather_vx_b, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vrgather_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vrgather_vx_w, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index ab274dcde12..4653a9679ef 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -645,6 +645,7 @@ vslidedown_vx   00 . . . 100 . 1010111 @r_vm
 vslidedown_vi   00 . . . 011 . 1010111 @r_vm
 vslide1down_vx  00 . . . 110 . 1010111 @r_vm
 vrgather_vv 001100 . . . 000 . 1010111 @r_vm
+vrgatherei16_vv 001110 . . . 000 . 1010111 @r_vm
 vrgather_vx 001100 . . . 100 . 1010111 @r_vm
 vrgather_vi 001100 . . . 011 . 1010111 @r_vm
 vcompress_vm010111 - . . 010 . 1010111 @r
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 4207cc4e6b8..322fc5c4aae 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3090,7 +3090,25 @@ static bool vrgather_vv_check(DisasContext *s, arg_rmrr 
*a)
require_vm(a->vm, a->rd);
 }
 
+static bool vrgatherei16_vv_check(DisasContext *s, arg_rmrr *a)
+{
+int8_t emul = MO_16 - s->sew + s->lmul;
+return require_rvv(s) &&
+   vext_check_isa_ill(s) &&
+   (emul >= -3 && emul <= 3) &&
+   require_align(a->rd, s->lmul) &&
+   require_align(a->rs1, emul) &&
+   require_align(a->rs2, s->lmul) &&
+   (a->rd != a->rs2 && a->rd != a->rs1) &&
+   !is_overlapped(a->rd, 1 << MAX(s->lmul, 0),
+  a->rs1, 1 << MAX(emul, 0)) &&
+   !is_overlapped(a->rd, 1 << MAX(s->lmul, 0),
+  a->rs2, 1 << MAX(s->lmul, 0)) &&
+   require_vm(a->vm, a->rd);
+}
+
 GEN_OPIVV_TRANS(vrgather_vv, vrgather_vv_check)
+GEN_OPIVV_TRANS(vrgatherei16_vv, vrgatherei16_vv_check)
 
 static bool vrgather_vx_check(DisasContext *s, arg_rmrr *a)
 {
@@ -3110,7 +3128,8 @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr 
*a)
 }
 
 if (a->vm && s->vl_eq_vlmax) {
-int vlmax = s->vlen;
+int scale = s->lmul - (s->sew + 3);
+int vlmax = scale < 0 ? s->vlen >> -scale : s->vlen << scale;
 TCGv_i64 dest = tcg_temp_new_i64();
 
 if (a->rs1 == 0) {
@@ -3141,8 +3160,10 @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr 
*a)
 }
 
 if (a->vm && s->vl_eq_vlmax) {
-if (a->rs1 >= s->vlen) {
-tcg_gen_gvec_dup_imm(SEW64, vreg_ofs(s, a->rd),
+int scale = s->lmul - (s->sew + 3);
+int vlmax = scale < 0 ? s->vlen >> -scale : s->vlen << scale;
+if (a->rs1 >= vlmax) {
+tcg_gen_gvec_dup_imm(MO_64, vreg_ofs(s, a->rd),
  MAXSZ(s), MAXSZ(s), 0);
 } else {
 tcg_gen_gvec_dup_mem(s->sew, vreg_ofs(s, a->rd),
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index b0dc971a860..86d03d8e395 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4460,11 +4460,11 @@ GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_w, uint32_t, H4)
 GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_d, uint64_t, H8)
 
 /* Vector Register Gather Instruction */
-#define GEN_VEXT_VRGATHER_VV(NAME, ETYPE, H)  \
+#define GEN_VEXT_VRGATHER_VV(NAME, TS1, TS2, HS1, HS2)\
 void HELPER(NAME)(void *vd, void *v0, void *vs1, void *

[PATCH v10 26/77] target/riscv: rvv-1.0: take fractional LMUL into vector max elements calculation

2021-11-28 Thread frank . chang
From: Frank Chang 

Update vext_get_vlmax() and MAXSZ() to take fractional LMUL into
calculation for RVV 1.0.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h  | 27 -
 target/riscv/cpu_helper.c   | 16 ---
 target/riscv/insn_trans/trans_rvv.c.inc | 12 ++-
 3 files changed, 42 insertions(+), 13 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 709b7c3abbb..11a0f41b27e 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -430,18 +430,27 @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
 #endif
 
 /*
- * A simplification for VLMAX
- * = (1 << LMUL) * VLEN / (8 * (1 << SEW))
- * = (VLEN << LMUL) / (8 << SEW)
- * = (VLEN << LMUL) >> (SEW + 3)
- * = VLEN >> (SEW + 3 - LMUL)
+ * Encode LMUL to lmul as follows:
+ * LMULvlmullmul
+ *  1   000   0
+ *  2   001   1
+ *  4   010   2
+ *  8   011   3
+ *  -   100   -
+ * 1/8  101  -3
+ * 1/4  110  -2
+ * 1/2  111  -1
+ *
+ * then, we can calculate VLMAX = vlen >> (vsew + 3 - lmul)
+ * e.g. vlen = 256 bits, SEW = 16, LMUL = 1/8
+ *  => VLMAX = vlen >> (1 + 3 - (-3))
+ *   = 256 >> 7
+ *   = 2
  */
 static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
 {
-uint8_t sew, lmul;
-
-sew = FIELD_EX64(vtype, VTYPE, VSEW);
-lmul = FIELD_EX64(vtype, VTYPE, VLMUL);
+uint8_t sew = FIELD_EX64(vtype, VTYPE, VSEW);
+int8_t lmul = sextract32(FIELD_EX64(vtype, VTYPE, VLMUL), 0, 3);
 return cpu->cfg.vlen >> (sew + 3 - lmul);
 }
 
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 7149657edf9..cb58b06dfe7 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -75,12 +75,22 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 *cs_base = 0;
 
 if (riscv_has_ext(env, RVV)) {
+/*
+ * If env->vl equals to VLMAX, we can use generic vector operation
+ * expanders (GVEC) to accerlate the vector operations.
+ * However, as LMUL could be a fractional number. The maximum
+ * vector size can be operated might be less than 8 bytes,
+ * which is not supported by GVEC. So we set vl_eq_vlmax flag to true
+ * only when maxsz >= 8 bytes.
+ */
 uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype);
-bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl);
+uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
+uint32_t maxsz = vlmax << sew;
+bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl) &&
+   (maxsz >= 8);
 flags = FIELD_DP32(flags, TB_FLAGS, VILL,
 FIELD_EX64(env->vtype, VTYPE, VILL));
-flags = FIELD_DP32(flags, TB_FLAGS, SEW,
-FIELD_EX64(env->vtype, VTYPE, VSEW));
+flags = FIELD_DP32(flags, TB_FLAGS, SEW, sew);
 flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
 FIELD_EX64(env->vtype, VTYPE, VLMUL));
 flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax);
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index e12db9aae8b..5c04ac90dae 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1049,7 +1049,17 @@ GEN_LDST_WHOLE_TRANS(vs8r_v, 8, true)
 /*
  *** Vector Integer Arithmetic Instructions
  */
-#define MAXSZ(s) (s->vlen >> (3 - s->lmul))
+
+/*
+ * MAXSZ returns the maximum vector size can be operated in bytes,
+ * which is used in GVEC IR when vl_eq_vlmax flag is set to true
+ * to accerlate vector operation.
+ */
+static inline uint32_t MAXSZ(DisasContext *s)
+{
+int scale = s->lmul - 3;
+return scale < 0 ? s->vlen >> -scale : s->vlen << scale;
+}
 
 static bool opivv_check(DisasContext *s, arg_rmrr *a)
 {
-- 
2.25.1




[PATCH v10 25/77] target/riscv: rvv-1.0: update vext_max_elems() for load/store insns

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 32 ++--
 target/riscv/vector_helper.c| 99 ++---
 2 files changed, 80 insertions(+), 51 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 5e8e49d43f4..e12db9aae8b 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -540,6 +540,12 @@ static bool trans_##NAME(DisasContext *s, arg_##ARGTYPE * 
a) \
 return false;\
 }
 
+static uint8_t vext_get_emul(DisasContext *s, uint8_t eew)
+{
+int8_t emul = eew - s->sew + s->lmul;
+return emul < 0 ? 0 : emul;
+}
+
 /*
  *** unit stride load and store
  */
@@ -604,8 +610,14 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, 
uint8_t eew)
 return false;
 }
 
+/*
+ * Vector load/store instructions have the EEW encoded
+ * directly in the instructions. The maximum vector size is
+ * calculated with EMUL rather than LMUL.
+ */
+uint8_t emul = vext_get_emul(s, eew);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 return ldst_us_trans(a->rd, a->rs1, data, fn, s, false);
 }
@@ -640,8 +652,9 @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, 
uint8_t eew)
 return false;
 }
 
+uint8_t emul = vext_get_emul(s, eew);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 return ldst_us_trans(a->rd, a->rs1, data, fn, s, true);
 }
@@ -711,8 +724,9 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, 
uint8_t eew)
 return false;
 }
 
+uint8_t emul = vext_get_emul(s, eew);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
 }
@@ -739,8 +753,9 @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, 
uint8_t eew)
 gen_helper_vsse32_v,  gen_helper_vsse64_v
 };
 
+uint8_t emul = vext_get_emul(s, eew);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 fn = fns[eew];
 if (fn == NULL) {
@@ -836,8 +851,9 @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, 
uint8_t eew)
 
 fn = fns[eew][s->sew];
 
+uint8_t emul = vext_get_emul(s, s->sew);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
 }
@@ -887,8 +903,9 @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, 
uint8_t eew)
 
 fn = fns[eew][s->sew];
 
+uint8_t emul = vext_get_emul(s, s->sew);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, true);
 }
@@ -949,8 +966,9 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t 
eew)
 return false;
 }
 
+uint8_t emul = vext_get_emul(s, eew);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 return ldff_trans(a->rd, a->rs1, data, fn, s);
 }
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 9a39a0e2d26..f9919273dca 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -17,6 +17,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/host-utils.h"
 #include "cpu.h"
 #include "exec/memop.h"
 #include "exec/exec-all.h"
@@ -116,14 +117,21 @@ static inline int32_t vext_lmul(uint32_t desc)
 }
 
 /*
- * Get vector group length in bytes. Its range is [64, 2048].
+ * Get the maximum number of elements can be operated.
  *
- * As simd_desc support at most 256, the max vlen is 512 bits.
- * So vlen in bytes is encoded as maxsz.
+ * esz: log2 of element size in bytes.
  */
-static inline uint32_t vext_maxsz(uint32_t desc)
+static inline uint32_t vext_max_elems(uint32_t desc, 

[PATCH v10 29/77] target/riscv: rvv-1.0: count population in mask instruction

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   | 2 +-
 target/riscv/insn32.decode  | 2 +-
 target/riscv/insn_trans/trans_rvv.c.inc | 7 ---
 target/riscv/vector_helper.c| 6 +++---
 4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index b8894d61510..3f30882aec4 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1020,7 +1020,7 @@ DEF_HELPER_6(vmnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmornot_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmxnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
 
-DEF_HELPER_4(vmpopc_m, tl, ptr, ptr, env, i32)
+DEF_HELPER_4(vcpop_m, tl, ptr, ptr, env, i32)
 
 DEF_HELPER_4(vmfirst_m, tl, ptr, ptr, env, i32)
 
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index f61eaf7c6ba..e748f7ca714 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -627,7 +627,7 @@ vmor_mm 011010 - . . 010 . 1010111 @r
 vmnor_mm00 - . . 010 . 1010111 @r
 vmornot_mm  011100 - . . 010 . 1010111 @r
 vmxnor_mm   01 - . . 010 . 1010111 @r
-vmpopc_m010100 . . - 010 . 1010111 @r2_vm
+vcpop_m 01 . . 1 010 . 1010111 @r2_vm
 vmfirst_m   010101 . . - 010 . 1010111 @r2_vm
 vmsbf_m 010110 . . 1 010 . 1010111 @r2_vm
 vmsif_m 010110 . . 00011 010 . 1010111 @r2_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 5c04ac90dae..b53cd2e6f37 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2664,8 +2664,8 @@ GEN_MM_TRANS(vmnor_mm)
 GEN_MM_TRANS(vmornot_mm)
 GEN_MM_TRANS(vmxnor_mm)
 
-/* Vector mask population count vmpopc */
-static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
+/* Vector count population in mask vcpop */
+static bool trans_vcpop_m(DisasContext *s, arg_rmr *a)
 {
 if (require_rvv(s) &&
 vext_check_isa_ill(s)) {
@@ -2684,11 +2684,12 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
 tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
 tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
-gen_helper_vmpopc_m(dst, mask, src2, cpu_env, desc);
+gen_helper_vcpop_m(dst, mask, src2, cpu_env, desc);
 gen_set_gpr(s, a->rd, dst);
 
 tcg_temp_free_ptr(mask);
 tcg_temp_free_ptr(src2);
+
 return true;
 }
 return false;
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index f9919273dca..9451112b3da 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4214,9 +4214,9 @@ GEN_VEXT_MASK_VV(vmnor_mm, DO_NOR)
 GEN_VEXT_MASK_VV(vmornot_mm, DO_ORNOT)
 GEN_VEXT_MASK_VV(vmxnor_mm, DO_XNOR)
 
-/* Vector mask population count vmpopc */
-target_ulong HELPER(vmpopc_m)(void *v0, void *vs2, CPURISCVState *env,
-  uint32_t desc)
+/* Vector count population in mask vcpop */
+target_ulong HELPER(vcpop_m)(void *v0, void *vs2, CPURISCVState *env,
+ uint32_t desc)
 {
 target_ulong cnt = 0;
 uint32_t vm = vext_vm(desc);
-- 
2.25.1




[PATCH v10 42/77] target/riscv: rvv-1.0: single-width bit shift instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Truncate vsll.vi, vsrl.vi, vsra.vi's immediate values to lg2(SEW) bits.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 0076ce5a0a9..48942129135 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1685,9 +1685,9 @@ GEN_OPIVX_GVEC_SHIFT_TRANS(vsll_vx,  shls)
 GEN_OPIVX_GVEC_SHIFT_TRANS(vsrl_vx,  shrs)
 GEN_OPIVX_GVEC_SHIFT_TRANS(vsra_vx,  sars)
 
-GEN_OPIVI_GVEC_TRANS(vsll_vi, IMM_ZX, vsll_vx, shli)
-GEN_OPIVI_GVEC_TRANS(vsrl_vi, IMM_ZX, vsrl_vx, shri)
-GEN_OPIVI_GVEC_TRANS(vsra_vi, IMM_ZX, vsra_vx, sari)
+GEN_OPIVI_GVEC_TRANS(vsll_vi, IMM_TRUNC_SEW, vsll_vx, shli)
+GEN_OPIVI_GVEC_TRANS(vsrl_vi, IMM_TRUNC_SEW, vsrl_vx, shri)
+GEN_OPIVI_GVEC_TRANS(vsra_vi, IMM_TRUNC_SEW, vsra_vx, sari)
 
 /* Vector Narrowing Integer Right Shift Instructions */
 static bool opivv_narrow_check(DisasContext *s, arg_rmrr *a)
-- 
2.25.1




[PATCH v10 32/77] target/riscv: rvv-1.0: iota instruction

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn32.decode  |  2 +-
 target/riscv/insn_trans/trans_rvv.c.inc | 10 --
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index d139c0aade7..3ac5162aeb7 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -632,7 +632,7 @@ vfirst_m01 . . 10001 010 . 1010111 
@r2_vm
 vmsbf_m 010100 . . 1 010 . 1010111 @r2_vm
 vmsif_m 010100 . . 00011 010 . 1010111 @r2_vm
 vmsof_m 010100 . . 00010 010 . 1010111 @r2_vm
-viota_m 010110 . . 1 010 . 1010111 @r2_vm
+viota_m 010100 . . 1 010 . 1010111 @r2_vm
 vid_v   010110 . 0 10001 010 . 1010111 @r1_vm
 vext_x_v001100 1 . . 010 . 1010111 @r
 vmv_s_x 001101 1 0 . 110 . 1010111 @r2
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 9206e6f06c8..80cbf0cadb8 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2757,12 +2757,18 @@ GEN_M_TRANS(vmsbf_m)
 GEN_M_TRANS(vmsif_m)
 GEN_M_TRANS(vmsof_m)
 
-/* Vector Iota Instruction */
+/*
+ * Vector Iota Instruction
+ *
+ * 1. The destination register cannot overlap the source register.
+ * 2. If masked, cannot overlap the mask register ('v0').
+ * 3. An illegal instruction exception is raised if vstart is non-zero.
+ */
 static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
 {
 if (require_rvv(s) &&
 vext_check_isa_ill(s) &&
-require_noover(a->rd, s->lmul, a->rs2, 0) &&
+!is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) &&
 require_vm(a->vm, a->rd) &&
 require_align(a->rd, s->lmul)) {
 uint32_t data = 0;
-- 
2.25.1




[PATCH v10 30/77] target/riscv: rvv-1.0: find-first-set mask bit instruction

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   | 2 +-
 target/riscv/insn32.decode  | 2 +-
 target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
 target/riscv/vector_helper.c| 6 +++---
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 3f30882aec4..7646567eb27 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1022,7 +1022,7 @@ DEF_HELPER_6(vmxnor_mm, void, ptr, ptr, ptr, ptr, env, 
i32)
 
 DEF_HELPER_4(vcpop_m, tl, ptr, ptr, env, i32)
 
-DEF_HELPER_4(vmfirst_m, tl, ptr, ptr, env, i32)
+DEF_HELPER_4(vfirst_m, tl, ptr, ptr, env, i32)
 
 DEF_HELPER_5(vmsbf_m, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vmsif_m, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index e748f7ca714..4df2aa9cddc 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -628,7 +628,7 @@ vmnor_mm00 - . . 010 . 1010111 @r
 vmornot_mm  011100 - . . 010 . 1010111 @r
 vmxnor_mm   01 - . . 010 . 1010111 @r
 vcpop_m 01 . . 1 010 . 1010111 @r2_vm
-vmfirst_m   010101 . . - 010 . 1010111 @r2_vm
+vfirst_m01 . . 10001 010 . 1010111 @r2_vm
 vmsbf_m 010110 . . 1 010 . 1010111 @r2_vm
 vmsif_m 010110 . . 00011 010 . 1010111 @r2_vm
 vmsof_m 010110 . . 00010 010 . 1010111 @r2_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index b53cd2e6f37..3645bb96356 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2696,7 +2696,7 @@ static bool trans_vcpop_m(DisasContext *s, arg_rmr *a)
 }
 
 /* vmfirst find-first-set mask bit */
-static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
+static bool trans_vfirst_m(DisasContext *s, arg_rmr *a)
 {
 if (require_rvv(s) &&
 vext_check_isa_ill(s)) {
@@ -2715,7 +2715,7 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
 tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
 tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
-gen_helper_vmfirst_m(dst, mask, src2, cpu_env, desc);
+gen_helper_vfirst_m(dst, mask, src2, cpu_env, desc);
 gen_set_gpr(s, a->rd, dst);
 
 tcg_temp_free_ptr(mask);
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 9451112b3da..f97783acf05 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4233,9 +4233,9 @@ target_ulong HELPER(vcpop_m)(void *v0, void *vs2, 
CPURISCVState *env,
 return cnt;
 }
 
-/* vmfirst find-first-set mask bit*/
-target_ulong HELPER(vmfirst_m)(void *v0, void *vs2, CPURISCVState *env,
-   uint32_t desc)
+/* vfirst find-first-set mask bit*/
+target_ulong HELPER(vfirst_m)(void *v0, void *vs2, CPURISCVState *env,
+  uint32_t desc)
 {
 uint32_t vm = vext_vm(desc);
 uint32_t vl = env->vl;
-- 
2.25.1




[PATCH v10 33/77] target/riscv: rvv-1.0: element index instruction

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn32.decode | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 3ac5162aeb7..ab274dcde12 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -633,7 +633,7 @@ vmsbf_m 010100 . . 1 010 . 1010111 
@r2_vm
 vmsif_m 010100 . . 00011 010 . 1010111 @r2_vm
 vmsof_m 010100 . . 00010 010 . 1010111 @r2_vm
 viota_m 010100 . . 1 010 . 1010111 @r2_vm
-vid_v   010110 . 0 10001 010 . 1010111 @r1_vm
+vid_v   010100 . 0 10001 010 . 1010111 @r1_vm
 vext_x_v001100 1 . . 010 . 1010111 @r
 vmv_s_x 001101 1 0 . 110 . 1010111 @r2
 vfmv_f_s001100 1 . 0 001 . 1010111 @r2rd
-- 
2.25.1




[PATCH v10 49/77] target/riscv: rvv-1.0: mask-register logical instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 3 ++-
 target/riscv/vector_helper.c| 4 
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 804f423d5bb..5c0c3d25478 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2652,7 +2652,8 @@ GEN_OPFVV_WIDEN_TRANS(vfwredsum_vs, reduction_check)
 #define GEN_MM_TRANS(NAME) \
 static bool trans_##NAME(DisasContext *s, arg_r *a)\
 {  \
-if (vext_check_isa_ill(s)) {   \
+if (require_rvv(s) &&  \
+vext_check_isa_ill(s)) {   \
 uint32_t data = 0; \
 gen_helper_gvec_4_ptr *fn = gen_helper_##NAME; \
 TCGLabel *over = gen_new_label();  \
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 71d7b1e8796..f883fdf4749 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4231,7 +4231,6 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,  
\
   void *vs2, CPURISCVState *env,  \
   uint32_t desc)  \
 { \
-uint32_t vlmax = env_archcpu(env)->cfg.vlen;  \
 uint32_t vl = env->vl;\
 uint32_t i;   \
 int a, b; \
@@ -4241,9 +4240,6 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,  
\
 b = vext_elem_mask(vs2, i);   \
 vext_set_elem_mask(vd, i, OP(b, a));  \
 } \
-for (; i < vlmax; i++) {  \
-vext_set_elem_mask(vd, i, 0); \
-} \
 }
 
 #define DO_NAND(N, M)  (!(N & M))
-- 
2.25.1




[PATCH v10 31/77] target/riscv: rvv-1.0: set-X-first mask bit instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn32.decode  | 6 +++---
 target/riscv/insn_trans/trans_rvv.c.inc | 5 -
 target/riscv/vector_helper.c| 4 
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 4df2aa9cddc..d139c0aade7 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -629,9 +629,9 @@ vmornot_mm  011100 - . . 010 . 1010111 @r
 vmxnor_mm   01 - . . 010 . 1010111 @r
 vcpop_m 01 . . 1 010 . 1010111 @r2_vm
 vfirst_m01 . . 10001 010 . 1010111 @r2_vm
-vmsbf_m 010110 . . 1 010 . 1010111 @r2_vm
-vmsif_m 010110 . . 00011 010 . 1010111 @r2_vm
-vmsof_m 010110 . . 00010 010 . 1010111 @r2_vm
+vmsbf_m 010100 . . 1 010 . 1010111 @r2_vm
+vmsif_m 010100 . . 00011 010 . 1010111 @r2_vm
+vmsof_m 010100 . . 00010 010 . 1010111 @r2_vm
 viota_m 010110 . . 1 010 . 1010111 @r2_vm
 vid_v   010110 . 0 10001 010 . 1010111 @r1_vm
 vext_x_v001100 1 . . 010 . 1010111 @r
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 3645bb96356..9206e6f06c8 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2731,7 +2731,10 @@ static bool trans_vfirst_m(DisasContext *s, arg_rmr *a)
 #define GEN_M_TRANS(NAME)  \
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 {  \
-if (vext_check_isa_ill(s)) {   \
+if (require_rvv(s) &&  \
+vext_check_isa_ill(s) &&   \
+require_vm(a->vm, a->rd) &&\
+(a->rd != a->rs2)) {   \
 uint32_t data = 0; \
 gen_helper_gvec_3_ptr *fn = gen_helper_##NAME; \
 TCGLabel *over = gen_new_label();  \
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index f97783acf05..b0dc971a860 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4260,7 +4260,6 @@ enum set_mask_type {
 static void vmsetm(void *vd, void *v0, void *vs2, CPURISCVState *env,
uint32_t desc, enum set_mask_type type)
 {
-uint32_t vlmax = env_archcpu(env)->cfg.vlen;
 uint32_t vm = vext_vm(desc);
 uint32_t vl = env->vl;
 int i;
@@ -4290,9 +4289,6 @@ static void vmsetm(void *vd, void *v0, void *vs2, 
CPURISCVState *env,
 }
 }
 }
-for (; i < vlmax; i++) {
-vext_set_elem_mask(vd, i, 0);
-}
 }
 
 void HELPER(vmsbf_m)(void *vd, void *v0, void *vs2, CPURISCVState *env,
-- 
2.25.1




[PATCH v10 37/77] target/riscv: rvv-1.0: floating-point move instruction

2021-11-28 Thread frank . chang
From: Frank Chang 

NaN-boxed the scalar floating-point register based on RVV 1.0's rules.

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index c250943dde8..2c8002af543 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2461,9 +2461,15 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f 
*a)
 require_rvf(s) &&
 vext_check_isa_ill(s) &&
 require_align(a->rd, s->lmul)) {
+TCGv_i64 t1;
+
 if (s->vl_eq_vlmax) {
+t1 = tcg_temp_new_i64();
+/* NaN-box f[rs1] */
+do_nanbox(s, t1, cpu_fpr[a->rs1]);
+
 tcg_gen_gvec_dup_i64(s->sew, vreg_ofs(s, a->rd),
- MAXSZ(s), MAXSZ(s), cpu_fpr[a->rs1]);
+ MAXSZ(s), MAXSZ(s), t1);
 mark_vs_dirty(s);
 } else {
 TCGv_ptr dest;
@@ -2477,15 +2483,21 @@ static bool trans_vfmv_v_f(DisasContext *s, 
arg_vfmv_v_f *a)
 TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 
+t1 = tcg_temp_new_i64();
+/* NaN-box f[rs1] */
+do_nanbox(s, t1, cpu_fpr[a->rs1]);
+
 dest = tcg_temp_new_ptr();
 desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
-fns[s->sew - 1](dest, cpu_fpr[a->rs1], cpu_env, desc);
+
+fns[s->sew - 1](dest, t1, cpu_env, desc);
 
 tcg_temp_free_ptr(dest);
 mark_vs_dirty(s);
 gen_set_label(over);
 }
+tcg_temp_free_i64(t1);
 return true;
 }
 return false;
-- 
2.25.1




[PATCH v10 36/77] target/riscv: rvv-1.0: integer scalar move instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

* Remove "vmv.s.x: dothing if rs1 == 0" constraint.
* Add vmv.x.s instruction.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Acked-by: Alistair Francis 
---
 target/riscv/insn32.decode  |  3 +-
 target/riscv/insn_trans/trans_rvv.c.inc | 43 -
 2 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 4653a9679ef..e33ec82fdf8 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -634,8 +634,9 @@ vmsif_m 010100 . . 00011 010 . 1010111 
@r2_vm
 vmsof_m 010100 . . 00010 010 . 1010111 @r2_vm
 viota_m 010100 . . 1 010 . 1010111 @r2_vm
 vid_v   010100 . 0 10001 010 . 1010111 @r1_vm
+vmv_x_s 01 1 . 0 010 . 1010111 @r2rd
+vmv_s_x 01 1 0 . 110 . 1010111 @r2
 vext_x_v001100 1 . . 010 . 1010111 @r
-vmv_s_x 001101 1 0 . 110 . 1010111 @r2
 vfmv_f_s001100 1 . 0 001 . 1010111 @r2rd
 vfmv_s_f001101 1 0 . 101 . 1010111 @r2
 vslideup_vx 001110 . . . 100 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 322fc5c4aae..c250943dde8 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2978,27 +2978,54 @@ static void vec_element_storei(DisasContext *s, int 
vreg,
 store_element(val, cpu_env, endian_ofs(s, vreg, idx), s->sew);
 }
 
+/* vmv.x.s rd, vs2 # x[rd] = vs2[0] */
+static bool trans_vmv_x_s(DisasContext *s, arg_vmv_x_s *a)
+{
+if (require_rvv(s) &&
+vext_check_isa_ill(s)) {
+TCGv_i64 t1;
+TCGv dest;
+
+t1 = tcg_temp_new_i64();
+dest = tcg_temp_new();
+/*
+ * load vreg and sign-extend to 64 bits,
+ * then truncate to XLEN bits before storing to gpr.
+ */
+vec_element_loadi(s, t1, a->rs2, 0, true);
+tcg_gen_trunc_i64_tl(dest, t1);
+gen_set_gpr(s, a->rd, dest);
+tcg_temp_free_i64(t1);
+tcg_temp_free(dest);
+
+return true;
+}
+return false;
+}
+
 /* vmv.s.x vd, rs1 # vd[0] = rs1 */
 static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
 {
-if (vext_check_isa_ill(s)) {
+if (require_rvv(s) &&
+vext_check_isa_ill(s)) {
 /* This instruction ignores LMUL and vector register groups */
-int maxsz = s->vlen >> 3;
 TCGv_i64 t1;
+TCGv s1;
 TCGLabel *over = gen_new_label();
 
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
-tcg_gen_gvec_dup_imm(SEW64, vreg_ofs(s, a->rd), maxsz, maxsz, 0);
-if (a->rs1 == 0) {
-goto done;
-}
 
 t1 = tcg_temp_new_i64();
-tcg_gen_extu_tl_i64(t1, cpu_gpr[a->rs1]);
+
+/*
+ * load gpr and sign-extend to 64 bits,
+ * then truncate to SEW bits when storing to vreg.
+ */
+s1 = get_gpr(s, a->rs1, EXT_NONE);
+tcg_gen_ext_tl_i64(t1, s1);
 vec_element_storei(s, a->rd, 0, t1);
 tcg_temp_free_i64(t1);
 mark_vs_dirty(s);
-done:
 gen_set_label(over);
 return true;
 }
-- 
2.25.1




[PATCH v10 54/77] target/riscv: rvv-1.0: widening floating-point reduction instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 998247d71d9..b43234ed3ff 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2648,7 +2648,14 @@ GEN_OPFVV_TRANS(vfredmax_vs, freduction_check)
 GEN_OPFVV_TRANS(vfredmin_vs, freduction_check)
 
 /* Vector Widening Floating-Point Reduction Instructions */
-GEN_OPFVV_WIDEN_TRANS(vfwredsum_vs, reduction_check)
+static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
+{
+return reduction_widen_check(s, a) &&
+   require_scale_rvf(s) &&
+   (s->sew != MO_8);
+}
+
+GEN_OPFVV_WIDEN_TRANS(vfwredsum_vs, freduction_widen_check)
 
 /*
  *** Vector Mask Operations
-- 
2.25.1




[PATCH v10 40/77] target/riscv: rvv-1.0: integer extension instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Add the following instructions:

* vzext.vf2
* vzext.vf4
* vzext.vf8
* vsext.vf2
* vsext.vf4
* vsext.vf8

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 14 +
 target/riscv/insn32.decode  |  8 +++
 target/riscv/insn_trans/trans_rvv.c.inc | 80 +
 target/riscv/vector_helper.c| 31 ++
 4 files changed, 133 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index bd0768d048f..878d82caf61 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1072,3 +1072,17 @@ DEF_HELPER_6(vcompress_vm_b, void, ptr, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_6(vcompress_vm_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vcompress_vm_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vcompress_vm_d, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vzext_vf2_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vzext_vf2_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vzext_vf2_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vzext_vf4_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vzext_vf4_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vzext_vf8_d, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vsext_vf2_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsext_vf2_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsext_vf2_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsext_vf4_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsext_vf4_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsext_vf8_d, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 06a80763112..a6f9e5dcc66 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -655,6 +655,14 @@ vmv2r_v 100111 1 . 1 011 . 1010111 
@r2rd
 vmv4r_v 100111 1 . 00011 011 . 1010111 @r2rd
 vmv8r_v 100111 1 . 00111 011 . 1010111 @r2rd
 
+# Vector Integer Extension
+vzext_vf2   010010 . . 00110 010 . 1010111 @r2_vm
+vzext_vf4   010010 . . 00100 010 . 1010111 @r2_vm
+vzext_vf8   010010 . . 00010 010 . 1010111 @r2_vm
+vsext_vf2   010010 . . 00111 010 . 1010111 @r2_vm
+vsext_vf4   010010 . . 00101 010 . 1010111 @r2_vm
+vsext_vf8   010010 . . 00011 010 . 1010111 @r2_vm
+
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
 
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 91e7c14ec44..5285e21cc09 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3284,3 +3284,83 @@ GEN_VMV_WHOLE_TRANS(vmv1r_v, 1)
 GEN_VMV_WHOLE_TRANS(vmv2r_v, 2)
 GEN_VMV_WHOLE_TRANS(vmv4r_v, 4)
 GEN_VMV_WHOLE_TRANS(vmv8r_v, 8)
+
+static bool int_ext_check(DisasContext *s, arg_rmr *a, uint8_t div)
+{
+uint8_t from = (s->sew + 3) - div;
+bool ret = require_rvv(s) &&
+(from >= 3 && from <= 8) &&
+(a->rd != a->rs2) &&
+require_align(a->rd, s->lmul) &&
+require_align(a->rs2, s->lmul - div) &&
+require_vm(a->vm, a->rd) &&
+require_noover(a->rd, s->lmul, a->rs2, s->lmul - div);
+return ret;
+}
+
+static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
+{
+uint32_t data = 0;
+gen_helper_gvec_3_ptr *fn;
+TCGLabel *over = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+
+static gen_helper_gvec_3_ptr * const fns[6][4] = {
+{
+NULL, gen_helper_vzext_vf2_h,
+gen_helper_vzext_vf2_w, gen_helper_vzext_vf2_d
+},
+{
+NULL, NULL,
+gen_helper_vzext_vf4_w, gen_helper_vzext_vf4_d,
+},
+{
+NULL, NULL,
+NULL, gen_helper_vzext_vf8_d
+},
+{
+NULL, gen_helper_vsext_vf2_h,
+gen_helper_vsext_vf2_w, gen_helper_vsext_vf2_d
+},
+{
+NULL, NULL,
+gen_helper_vsext_vf4_w, gen_helper_vsext_vf4_d,
+},
+{
+NULL, NULL,
+NULL, gen_helper_vsext_vf8_d
+}
+};
+
+fn = fns[seq][s->sew];
+if (fn == NULL) {
+return false;
+}
+
+data = FIELD_DP32(data, VDATA, VM, a->vm);
+
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
+   vreg_ofs(s, a->rs2), cpu_env,
+   s->vlen / 8, s->vlen / 8, data, fn);
+
+mark_vs_dirty(s);
+gen_set_label(over);
+return true;
+}
+
+/* Vector Integer Extension */
+#define GEN_INT_EXT_TRANS(NAME, DIV, SEQ) \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
+{ 

[PATCH v10 39/77] target/riscv: rvv-1.0: whole register move instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Add the following instructions:

* vmv1r.v
* vmv2r.v
* vmv4r.v
* vmv8r.v

Signed-off-by: Frank Chang 
Acked-by: Alistair Francis 
---
 target/riscv/insn32.decode  |  4 
 target/riscv/insn_trans/trans_rvv.c.inc | 25 +
 2 files changed, 29 insertions(+)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index ab5fdbf9be8..06a80763112 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -650,6 +650,10 @@ vrgatherei16_vv 001110 . . . 000 . 1010111 
@r_vm
 vrgather_vx 001100 . . . 100 . 1010111 @r_vm
 vrgather_vi 001100 . . . 011 . 1010111 @r_vm
 vcompress_vm010111 - . . 010 . 1010111 @r
+vmv1r_v 100111 1 . 0 011 . 1010111 @r2rd
+vmv2r_v 100111 1 . 1 011 . 1010111 @r2rd
+vmv4r_v 100111 1 . 00011 011 . 1010111 @r2rd
+vmv8r_v 100111 1 . 00111 011 . 1010111 @r2rd
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 89f88a0ea70..91e7c14ec44 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3259,3 +3259,28 @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
 }
 return false;
 }
+
+/*
+ * Whole Vector Register Move Instructions ignore vtype and vl setting.
+ * Thus, we don't need to check vill bit. (Section 16.6)
+ */
+#define GEN_VMV_WHOLE_TRANS(NAME, LEN)  \
+static bool trans_##NAME(DisasContext *s, arg_##NAME * a)   \
+{   \
+if (require_rvv(s) &&   \
+QEMU_IS_ALIGNED(a->rd, LEN) &&  \
+QEMU_IS_ALIGNED(a->rs2, LEN)) { \
+/* EEW = 8 */   \
+tcg_gen_gvec_mov(MO_8, vreg_ofs(s, a->rd),  \
+ vreg_ofs(s, a->rs2),   \
+ s->vlen / 8 * LEN, s->vlen / 8 * LEN); \
+mark_vs_dirty(s);   \
+return true;\
+}   \
+return false;   \
+}
+
+GEN_VMV_WHOLE_TRANS(vmv1r_v, 1)
+GEN_VMV_WHOLE_TRANS(vmv2r_v, 2)
+GEN_VMV_WHOLE_TRANS(vmv4r_v, 4)
+GEN_VMV_WHOLE_TRANS(vmv8r_v, 8)
-- 
2.25.1




[PATCH v10 38/77] target/riscv: rvv-1.0: floating-point scalar move instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

NaN-boxed the scalar floating-point register based on RVV 1.0's rules.

Signed-off-by: Frank Chang 
Acked-by: Alistair Francis 
---
 target/riscv/insn32.decode  |  4 +--
 target/riscv/insn_trans/trans_rvv.c.inc | 38 -
 target/riscv/internals.h|  5 
 3 files changed, 21 insertions(+), 26 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index e33ec82fdf8..ab5fdbf9be8 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -637,8 +637,8 @@ vid_v   010100 . 0 10001 010 . 1010111 
@r1_vm
 vmv_x_s 01 1 . 0 010 . 1010111 @r2rd
 vmv_s_x 01 1 0 . 110 . 1010111 @r2
 vext_x_v001100 1 . . 010 . 1010111 @r
-vfmv_f_s001100 1 . 0 001 . 1010111 @r2rd
-vfmv_s_f001101 1 0 . 101 . 1010111 @r2
+vfmv_f_s01 1 . 0 001 . 1010111 @r2rd
+vfmv_s_f01 1 0 . 101 . 1010111 @r2
 vslideup_vx 001110 . . . 100 . 1010111 @r_vm
 vslideup_vi 001110 . . . 011 . 1010111 @r_vm
 vslide1up_vx001110 . . . 110 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 2c8002af543..89f88a0ea70 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3047,14 +3047,19 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x 
*a)
 /* Floating-Point Scalar Move Instructions */
 static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a)
 {
-if (!s->vill && has_ext(s, RVF) &&
-(s->mstatus_fs != 0) && (s->sew != 0)) {
-unsigned int len = 8 << s->sew;
+if (require_rvv(s) &&
+require_rvf(s) &&
+vext_check_isa_ill(s)) {
+unsigned int ofs = (8 << s->sew);
+unsigned int len = 64 - ofs;
+TCGv_i64 t_nan;
 
 vec_element_loadi(s, cpu_fpr[a->rd], a->rs2, 0, false);
-if (len < 64) {
-tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd],
-MAKE_64BIT_MASK(len, 64 - len));
+/* NaN-box f[rd] as necessary for SEW */
+if (len) {
+t_nan = tcg_constant_i64(UINT64_MAX);
+tcg_gen_deposit_i64(cpu_fpr[a->rd], cpu_fpr[a->rd],
+t_nan, ofs, len);
 }
 
 mark_fs_dirty(s);
@@ -3066,25 +3071,20 @@ static bool trans_vfmv_f_s(DisasContext *s, 
arg_vfmv_f_s *a)
 /* vfmv.s.f vd, rs1 # vd[0] = rs1 (vs2=0) */
 static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
 {
-if (!s->vill && has_ext(s, RVF) && (s->sew != 0)) {
-TCGv_i64 t1;
+if (require_rvv(s) &&
+require_rvf(s) &&
+vext_check_isa_ill(s)) {
 /* The instructions ignore LMUL and vector register group. */
-uint32_t vlmax = s->vlen >> 3;
+TCGv_i64 t1;
+TCGLabel *over = gen_new_label();
 
 /* if vl == 0, skip vector register write back */
-TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 
-/* zeroed all elements */
-tcg_gen_gvec_dup_imm(SEW64, vreg_ofs(s, a->rd), vlmax, vlmax, 0);
-
-/* NaN-box f[rs1] as necessary for SEW */
+/* NaN-box f[rs1] */
 t1 = tcg_temp_new_i64();
-if (s->sew == MO_64 && !has_ext(s, RVD)) {
-tcg_gen_ori_i64(t1, cpu_fpr[a->rs1], MAKE_64BIT_MASK(32, 32));
-} else {
-tcg_gen_mov_i64(t1, cpu_fpr[a->rs1]);
-}
+do_nanbox(s, t1, cpu_fpr[a->rs1]);
+
 vec_element_storei(s, a->rd, 0, t1);
 tcg_temp_free_i64(t1);
 mark_vs_dirty(s);
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 81f5dfa477a..ac062dc0b4e 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -32,11 +32,6 @@ target_ulong fclass_h(uint64_t frs1);
 target_ulong fclass_s(uint64_t frs1);
 target_ulong fclass_d(uint64_t frs1);
 
-#define SEW8  0
-#define SEW16 1
-#define SEW32 2
-#define SEW64 3
-
 #ifndef CONFIG_USER_ONLY
 extern const VMStateDescription vmstate_riscv_cpu;
 #endif
-- 
2.25.1




[PATCH v10 56/77] target/riscv: rvv-1.0: remove widening saturating scaled multiply-add

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   |  22 ---
 target/riscv/insn32.decode  |   7 -
 target/riscv/insn_trans/trans_rvv.c.inc |   9 --
 target/riscv/vector_helper.c| 205 
 4 files changed, 243 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 3ea21b4a578..af79570da8f 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -686,28 +686,6 @@ DEF_HELPER_6(vsmul_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vsmul_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vsmul_vx_d, void, ptr, ptr, tl, ptr, env, i32)
 
-DEF_HELPER_6(vwsmaccu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vwsmaccu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vwsmaccu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vwsmacc_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vwsmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vwsmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vwsmaccsu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vwsmaccsu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vwsmaccsu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vwsmaccu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vwsmaccu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vwsmaccu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vwsmacc_vx_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vwsmacc_vx_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vwsmacc_vx_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vwsmaccsu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vwsmaccsu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vwsmaccsu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vwsmaccus_vx_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vwsmaccus_vx_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vwsmaccus_vx_w, void, ptr, ptr, tl, ptr, env, i32)
-
 DEF_HELPER_6(vssrl_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vssrl_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vssrl_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index eeab6b00a1b..aee3a6cd01f 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -503,13 +503,6 @@ vasubu_vv   001010 . . . 010 . 1010111 
@r_vm
 vasubu_vx   001010 . . . 110 . 1010111 @r_vm
 vsmul_vv100111 . . . 000 . 1010111 @r_vm
 vsmul_vx100111 . . . 100 . 1010111 @r_vm
-vwsmaccu_vv 00 . . . 000 . 1010111 @r_vm
-vwsmaccu_vx 00 . . . 100 . 1010111 @r_vm
-vwsmacc_vv  01 . . . 000 . 1010111 @r_vm
-vwsmacc_vx  01 . . . 100 . 1010111 @r_vm
-vwsmaccsu_vv10 . . . 000 . 1010111 @r_vm
-vwsmaccsu_vx10 . . . 100 . 1010111 @r_vm
-vwsmaccus_vx11 . . . 100 . 1010111 @r_vm
 vssrl_vv101010 . . . 000 . 1010111 @r_vm
 vssrl_vx101010 . . . 100 . 1010111 @r_vm
 vssrl_vi101010 . . . 011 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 03716ad7066..119c82ca47e 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2016,15 +2016,6 @@ GEN_OPIVX_TRANS(vasubu_vx,  opivx_check)
 GEN_OPIVV_TRANS(vsmul_vv, opivv_check)
 GEN_OPIVX_TRANS(vsmul_vx,  opivx_check)
 
-/* Vector Widening Saturating Scaled Multiply-Add */
-GEN_OPIVV_WIDEN_TRANS(vwsmaccu_vv, opivv_widen_check)
-GEN_OPIVV_WIDEN_TRANS(vwsmacc_vv, opivv_widen_check)
-GEN_OPIVV_WIDEN_TRANS(vwsmaccsu_vv, opivv_widen_check)
-GEN_OPIVX_WIDEN_TRANS(vwsmaccu_vx)
-GEN_OPIVX_WIDEN_TRANS(vwsmacc_vx)
-GEN_OPIVX_WIDEN_TRANS(vwsmaccsu_vx)
-GEN_OPIVX_WIDEN_TRANS(vwsmaccus_vx)
-
 /* Vector Single-Width Scaling Shift Instructions */
 GEN_OPIVV_TRANS(vssrl_vv, opivv_check)
 GEN_OPIVV_TRANS(vssra_vv, opivv_check)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 79a2c3ff3ac..128406aa780 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -2494,211 +2494,6 @@ GEN_VEXT_VX_RM(vsmul_vx_h, 2, 2)
 GEN_VEXT_VX_RM(vsmul_vx_w, 4, 4)
 GEN_VEXT_VX_RM(vsmul_vx_d, 8, 8)
 
-/* Vector Widening Saturating Scaled Multiply-Add */
-static inline uint16_t
-vwsmaccu8(CPURISCVState *env, int vxrm, uint8_t a, uint8_t b,
-  uint16_t c)
-{
-uint8_t round;
-uint16_t res = (uint16_t)a * b;
-
-round = get_round(vxrm, res, 4);
-res   = (res >> 4) + round;
-return saddu16(env, vxrm, c, res);
-}
-
-static inline uint32_t
-vwsmaccu16(CPURISCVState *env, int vxrm, uint16_t a, uint16_t b,
-   uint32_t c)
-{
-uint8_t round;
-uint32_t res = (uint

[PATCH v10 55/77] target/riscv: rvv-1.0: single-width scaling shift instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

log(SEW) truncate vssra.vi immediate value.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index b43234ed3ff..03716ad7066 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2030,8 +2030,8 @@ GEN_OPIVV_TRANS(vssrl_vv, opivv_check)
 GEN_OPIVV_TRANS(vssra_vv, opivv_check)
 GEN_OPIVX_TRANS(vssrl_vx,  opivx_check)
 GEN_OPIVX_TRANS(vssra_vx,  opivx_check)
-GEN_OPIVI_TRANS(vssrl_vi, IMM_ZX, vssrl_vx, opivx_check)
-GEN_OPIVI_TRANS(vssra_vi, IMM_SX, vssra_vx, opivx_check)
+GEN_OPIVI_TRANS(vssrl_vi, IMM_TRUNC_SEW, vssrl_vx, opivx_check)
+GEN_OPIVI_TRANS(vssra_vi, IMM_TRUNC_SEW, vssra_vx, opivx_check)
 
 /* Vector Narrowing Fixed-Point Clip Instructions */
 GEN_OPIWV_NARROW_TRANS(vnclipu_wv)
-- 
2.25.1




[PATCH v10 43/77] target/riscv: rvv-1.0: integer add-with-carry/subtract-with-borrow

2021-11-28 Thread frank . chang
From: Frank Chang 

* Only do carry-in or borrow-in if is masked (vm=0).
* Remove clear function from helper functions as the tail elements
  are unchanged in RVV 1.0.

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn32.decode  | 20 ++--
 target/riscv/insn_trans/trans_rvv.c.inc |  2 +-
 target/riscv/vector_helper.c| 21 ++---
 3 files changed, 17 insertions(+), 26 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index f83c8daf24e..9c4089d7a7b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -378,16 +378,16 @@ vwsubu_wv   110110 . . . 010 . 1010111 
@r_vm
 vwsubu_wx   110110 . . . 110 . 1010111 @r_vm
 vwsub_wv110111 . . . 010 . 1010111 @r_vm
 vwsub_wx110111 . . . 110 . 1010111 @r_vm
-vadc_vvm01 1 . . 000 . 1010111 @r_vm_1
-vadc_vxm01 1 . . 100 . 1010111 @r_vm_1
-vadc_vim01 1 . . 011 . 1010111 @r_vm_1
-vmadc_vvm   010001 1 . . 000 . 1010111 @r_vm_1
-vmadc_vxm   010001 1 . . 100 . 1010111 @r_vm_1
-vmadc_vim   010001 1 . . 011 . 1010111 @r_vm_1
-vsbc_vvm010010 1 . . 000 . 1010111 @r_vm_1
-vsbc_vxm010010 1 . . 100 . 1010111 @r_vm_1
-vmsbc_vvm   010011 1 . . 000 . 1010111 @r_vm_1
-vmsbc_vxm   010011 1 . . 100 . 1010111 @r_vm_1
+vadc_vvm01 0 . . 000 . 1010111 @r_vm_1
+vadc_vxm01 0 . . 100 . 1010111 @r_vm_1
+vadc_vim01 0 . . 011 . 1010111 @r_vm_1
+vmadc_vvm   010001 . . . 000 . 1010111 @r_vm
+vmadc_vxm   010001 . . . 100 . 1010111 @r_vm
+vmadc_vim   010001 . . . 011 . 1010111 @r_vm
+vsbc_vvm010010 0 . . 000 . 1010111 @r_vm_1
+vsbc_vxm010010 0 . . 100 . 1010111 @r_vm_1
+vmsbc_vvm   010011 . . . 000 . 1010111 @r_vm
+vmsbc_vxm   010011 . . . 100 . 1010111 @r_vm
 vand_vv 001001 . . . 000 . 1010111 @r_vm
 vand_vx 001001 . . . 100 . 1010111 @r_vm
 vand_vi 001001 . . . 011 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 48942129135..357615a11c3 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1547,7 +1547,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 
 /*
  * For vadc and vsbc, an illegal instruction exception is raised if the
- * destination vector register is v0 and LMUL > 1. (Section 12.3)
+ * destination vector register is v0 and LMUL > 1. (Section 12.4)
  */
 static bool opivv_vadc_check(DisasContext *s, arg_rmrr *a)
 {
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 6891f28116f..54405d898b9 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -944,7 +944,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, 
  \
 for (i = 0; i < vl; i++) {\
 ETYPE s1 = *((ETYPE *)vs1 + H(i));\
 ETYPE s2 = *((ETYPE *)vs2 + H(i));\
-uint8_t carry = vext_elem_mask(v0, i);\
+ETYPE carry = vext_elem_mask(v0, i);  \
   \
 *((ETYPE *)vd + H(i)) = DO_OP(s2, s1, carry); \
 } \
@@ -969,7 +969,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void 
*vs2,\
  \
 for (i = 0; i < vl; i++) {   \
 ETYPE s2 = *((ETYPE *)vs2 + H(i));   \
-uint8_t carry = vext_elem_mask(v0, i);   \
+ETYPE carry = vext_elem_mask(v0, i); \
  \
 *((ETYPE *)vd + H(i)) = DO_OP(s2, (ETYPE)(target_long)s1, carry);\
 }\
@@ -994,20 +994,15 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
   CPURISCVState *env, uint32_t desc)  \
 { \
 uint32_t vl = env->vl;\
-uint32_t vlmax = vext_max_elems(desc, \
-ctzl(sizeof(ETYPE))); \
+uint32_t vm = vext_vm(desc);  \

[PATCH v10 41/77] target/riscv: rvv-1.0: single-width averaging add and subtract instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Add the following instructions:

* vaaddu.vv
* vaaddu.vx
* vasubu.vv
* vasubu.vx

Remove the following instructions:

* vadd.vi

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 16 ++
 target/riscv/insn32.decode  | 13 +++--
 target/riscv/insn_trans/trans_rvv.c.inc |  5 +-
 target/riscv/vector_helper.c| 74 +
 4 files changed, 102 insertions(+), 6 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 878d82caf61..f2e8d107d2f 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -648,18 +648,34 @@ DEF_HELPER_6(vaadd_vv_b, void, ptr, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_6(vaadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vaadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vaadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vasub_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vasub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vasub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vasub_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vasubu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vasubu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vasubu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vasubu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vaadd_vx_b, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vaadd_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vaadd_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vaadd_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vasub_vx_b, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vasub_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vasub_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vasub_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vasubu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vasubu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vasubu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vasubu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
 
 DEF_HELPER_6(vsmul_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vsmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index a6f9e5dcc66..f83c8daf24e 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -493,11 +493,14 @@ vssubu_vv   100010 . . . 000 . 1010111 
@r_vm
 vssubu_vx   100010 . . . 100 . 1010111 @r_vm
 vssub_vv100011 . . . 000 . 1010111 @r_vm
 vssub_vx100011 . . . 100 . 1010111 @r_vm
-vaadd_vv100100 . . . 000 . 1010111 @r_vm
-vaadd_vx100100 . . . 100 . 1010111 @r_vm
-vaadd_vi100100 . . . 011 . 1010111 @r_vm
-vasub_vv100110 . . . 000 . 1010111 @r_vm
-vasub_vx100110 . . . 100 . 1010111 @r_vm
+vaadd_vv001001 . . . 010 . 1010111 @r_vm
+vaadd_vx001001 . . . 110 . 1010111 @r_vm
+vaaddu_vv   001000 . . . 010 . 1010111 @r_vm
+vaaddu_vx   001000 . . . 110 . 1010111 @r_vm
+vasub_vv001011 . . . 010 . 1010111 @r_vm
+vasub_vx001011 . . . 110 . 1010111 @r_vm
+vasubu_vv   001010 . . . 010 . 1010111 @r_vm
+vasubu_vx   001010 . . . 110 . 1010111 @r_vm
 vsmul_vv100111 . . . 000 . 1010111 @r_vm
 vsmul_vx100111 . . . 100 . 1010111 @r_vm
 vwsmaccu_vv 00 . . . 000 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 5285e21cc09..0076ce5a0a9 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2004,10 +2004,13 @@ GEN_OPIVI_TRANS(vsadd_vi, IMM_SX, vsadd_vx, opivx_check)
 
 /* Vector Single-Width Averaging Add and Subtract */
 GEN_OPIVV_TRANS(vaadd_vv, opivv_check)
+GEN_OPIVV_TRANS(vaaddu_vv, opivv_check)
 GEN_OPIVV_TRANS(vasub_vv, opivv_check)
+GEN_OPIVV_TRANS(vasubu_vv, opivv_check)
 GEN_OPIVX_TRANS(vaadd_vx,  opivx_check)
+GEN_OPIVX_TRANS(vaaddu_vx,  opivx_check)
 GEN_OPIVX_TRANS(vasub_vx,  opivx_check)
-GEN_OPIVI_TRANS(vaadd_vi, 0, vaadd_vx, opivx_check)
+GEN_OPIVX_TRANS(vasubu_vx,  opivx_check)
 
 /* Vector Single-Width Fractional

[PATCH v10 61/77] target/riscv: rvv-1.0: floating-point/integer type-convert instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Add the following instructions:

* vfcvt.rtz.xu.f.v
* vfcvt.rtz.x.f.v

Also adjust GEN_OPFV_TRANS() to accept multiple floating-point rounding
modes.

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn32.decode  | 11 ++--
 target/riscv/insn_trans/trans_rvv.c.inc | 84 +++--
 2 files changed, 59 insertions(+), 36 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 20b3095f56c..02064f8ec98 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -585,10 +585,13 @@ vmfge_vf01 . . . 101 . 1010111 
@r_vm
 vfclass_v   010011 . . 1 001 . 1010111 @r2_vm
 vfmerge_vfm 010111 0 . . 101 . 1010111 @r_vm_0
 vfmv_v_f010111 1 0 . 101 . 1010111 @r2
-vfcvt_xu_f_v100010 . . 0 001 . 1010111 @r2_vm
-vfcvt_x_f_v 100010 . . 1 001 . 1010111 @r2_vm
-vfcvt_f_xu_v100010 . . 00010 001 . 1010111 @r2_vm
-vfcvt_f_x_v 100010 . . 00011 001 . 1010111 @r2_vm
+
+vfcvt_xu_f_v   010010 . . 0 001 . 1010111 @r2_vm
+vfcvt_x_f_v010010 . . 1 001 . 1010111 @r2_vm
+vfcvt_f_xu_v   010010 . . 00010 001 . 1010111 @r2_vm
+vfcvt_f_x_v010010 . . 00011 001 . 1010111 @r2_vm
+vfcvt_rtz_xu_f_v   010010 . . 00110 001 . 1010111 @r2_vm
+vfcvt_rtz_x_f_v010010 . . 00111 001 . 1010111 @r2_vm
 vfwcvt_xu_f_v   100010 . . 01000 001 . 1010111 @r2_vm
 vfwcvt_x_f_v100010 . . 01001 001 . 1010111 @r2_vm
 vfwcvt_f_xu_v   100010 . . 01010 001 . 1010111 @r2_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 047be5d5c47..4bc4dfa69fc 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1,5 +1,4 @@
 /*
- * RISC-V translation routines for the RVV Standard Extension.
  *
  * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
  *
@@ -2369,34 +2368,41 @@ static bool opfv_check(DisasContext *s, arg_rmr *a)
vext_check_ss(s, a->rd, a->rs2, a->vm);
 }
 
-#define GEN_OPFV_TRANS(NAME, CHECK)\
-static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
-{  \
-if (CHECK(s, a)) { \
-uint32_t data = 0; \
-static gen_helper_gvec_3_ptr * const fns[3] = {\
-gen_helper_##NAME##_h, \
-gen_helper_##NAME##_w, \
-gen_helper_##NAME##_d, \
-}; \
-TCGLabel *over = gen_new_label();  \
-gen_set_rm(s, RISCV_FRM_DYN);  \
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);  \
-   \
-data = FIELD_DP32(data, VDATA, VM, a->vm); \
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
-tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
-   vreg_ofs(s, a->rs2), cpu_env,   \
-   s->vlen / 8, s->vlen / 8, data, \
-   fns[s->sew - 1]);   \
-mark_vs_dirty(s);  \
-gen_set_label(over);   \
-return true;   \
-}  \
-return false;  \
+static bool do_opfv(DisasContext *s, arg_rmr *a,
+gen_helper_gvec_3_ptr *fn,
+bool (*checkfn)(DisasContext *, arg_rmr *),
+int rm)
+{
+if (checkfn(s, a)) {
+uint32_t data = 0;
+TCGLabel *over = gen_new_label();
+gen_set_rm(s, rm);
+tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+
+data = FIELD_DP32(data, VDATA, VM, a->vm);
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
+   vreg_ofs(s, a->rs2), cpu_env,
+   s->vlen / 8, s->vlen / 8, data, fn);
+mark_vs_dirty(s);
+gen_set_label(over);
+return true;
+}
+return false;
+}
+
+#define GEN_OPFV_TRANS(NAME, CHECK, FRM)   \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
+{  \

[PATCH v10 57/77] target/riscv: rvv-1.0: remove vmford.vv and vmford.vf

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 6 --
 target/riscv/insn32.decode  | 2 --
 target/riscv/insn_trans/trans_rvv.c.inc | 2 --
 target/riscv/vector_helper.c| 7 ---
 4 files changed, 17 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index af79570da8f..1727075dce4 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -902,12 +902,6 @@ DEF_HELPER_6(vmfgt_vf_d, void, ptr, ptr, i64, ptr, env, 
i32)
 DEF_HELPER_6(vmfge_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfge_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfge_vf_d, void, ptr, ptr, i64, ptr, env, i32)
-DEF_HELPER_6(vmford_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vmford_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vmford_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vmford_vf_h, void, ptr, ptr, i64, ptr, env, i32)
-DEF_HELPER_6(vmford_vf_w, void, ptr, ptr, i64, ptr, env, i32)
-DEF_HELPER_6(vmford_vf_d, void, ptr, ptr, i64, ptr, env, i32)
 
 DEF_HELPER_5(vfclass_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfclass_v_w, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index aee3a6cd01f..82484fda751 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -582,8 +582,6 @@ vmfle_vv011001 . . . 001 . 1010111 @r_vm
 vmfle_vf011001 . . . 101 . 1010111 @r_vm
 vmfgt_vf011101 . . . 101 . 1010111 @r_vm
 vmfge_vf01 . . . 101 . 1010111 @r_vm
-vmford_vv   011010 . . . 001 . 1010111 @r_vm
-vmford_vf   011010 . . . 101 . 1010111 @r_vm
 vfclass_v   010011 . . 1 001 . 1010111 @r2_vm
 vfmerge_vfm 010111 0 . . 101 . 1010111 @r_vm_0
 vfmv_v_f010111 1 0 . 101 . 1010111 @r2
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 119c82ca47e..4c5f813ccf9 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2425,7 +2425,6 @@ GEN_OPFVV_TRANS(vmfeq_vv, opfvv_cmp_check)
 GEN_OPFVV_TRANS(vmfne_vv, opfvv_cmp_check)
 GEN_OPFVV_TRANS(vmflt_vv, opfvv_cmp_check)
 GEN_OPFVV_TRANS(vmfle_vv, opfvv_cmp_check)
-GEN_OPFVV_TRANS(vmford_vv, opfvv_cmp_check)
 
 static bool opfvf_cmp_check(DisasContext *s, arg_rmrr *a)
 {
@@ -2441,7 +2440,6 @@ GEN_OPFVF_TRANS(vmflt_vf, opfvf_cmp_check)
 GEN_OPFVF_TRANS(vmfle_vf, opfvf_cmp_check)
 GEN_OPFVF_TRANS(vmfgt_vf, opfvf_cmp_check)
 GEN_OPFVF_TRANS(vmfge_vf, opfvf_cmp_check)
-GEN_OPFVF_TRANS(vmford_vf, opfvf_cmp_check)
 
 /* Vector Floating-Point Classify Instruction */
 GEN_OPFV_TRANS(vfclass_v, opfv_check)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 128406aa780..aed230e1ad8 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3630,13 +3630,6 @@ GEN_VEXT_CMP_VF(vmfge_vf_h, uint16_t, H2, vmfge16)
 GEN_VEXT_CMP_VF(vmfge_vf_w, uint32_t, H4, vmfge32)
 GEN_VEXT_CMP_VF(vmfge_vf_d, uint64_t, H8, vmfge64)
 
-GEN_VEXT_CMP_VV_ENV(vmford_vv_h, uint16_t, H2, !float16_unordered_quiet)
-GEN_VEXT_CMP_VV_ENV(vmford_vv_w, uint32_t, H4, !float32_unordered_quiet)
-GEN_VEXT_CMP_VV_ENV(vmford_vv_d, uint64_t, H8, !float64_unordered_quiet)
-GEN_VEXT_CMP_VF(vmford_vf_h, uint16_t, H2, !float16_unordered_quiet)
-GEN_VEXT_CMP_VF(vmford_vf_w, uint32_t, H4, !float32_unordered_quiet)
-GEN_VEXT_CMP_VF(vmford_vf_d, uint64_t, H8, !float64_unordered_quiet)
-
 /* Vector Floating-Point Classify Instruction */
 #define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
 static void do_##NAME(void *vd, void *vs2, int i)  \
-- 
2.25.1




[PATCH v10 47/77] target/riscv: rvv-1.0: integer comparison instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

* Sign-extend vmselu.vi and vmsgtu.vi immediate values.
* Remove "set tail elements to zeros" as tail elements can be unchanged
  for either VTA to have undisturbed or agnostic setting.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
 target/riscv/vector_helper.c| 9 -
 2 files changed, 2 insertions(+), 11 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index ed4554b6a1d..804f423d5bb 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1809,9 +1809,9 @@ GEN_OPIVX_TRANS(vmsgt_vx, opivx_cmp_check)
 
 GEN_OPIVI_TRANS(vmseq_vi, IMM_SX, vmseq_vx, opivx_cmp_check)
 GEN_OPIVI_TRANS(vmsne_vi, IMM_SX, vmsne_vx, opivx_cmp_check)
-GEN_OPIVI_TRANS(vmsleu_vi, IMM_ZX, vmsleu_vx, opivx_cmp_check)
+GEN_OPIVI_TRANS(vmsleu_vi, IMM_SX, vmsleu_vx, opivx_cmp_check)
 GEN_OPIVI_TRANS(vmsle_vi, IMM_SX, vmsle_vx, opivx_cmp_check)
-GEN_OPIVI_TRANS(vmsgtu_vi, IMM_ZX, vmsgtu_vx, opivx_cmp_check)
+GEN_OPIVI_TRANS(vmsgtu_vi, IMM_SX, vmsgtu_vx, opivx_cmp_check)
 GEN_OPIVI_TRANS(vmsgt_vi, IMM_SX, vmsgt_vx, opivx_cmp_check)
 
 /* Vector Integer Min/Max Instructions */
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index e885d4d3539..277a5e4120a 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -1190,8 +1190,6 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
 { \
 uint32_t vm = vext_vm(desc);  \
 uint32_t vl = env->vl;\
-uint32_t vlmax = vext_max_elems(desc, \
-ctzl(sizeof(ETYPE))); \
 uint32_t i;   \
   \
 for (i = 0; i < vl; i++) {\
@@ -1202,9 +1200,6 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
 } \
 vext_set_elem_mask(vd, i, DO_OP(s2, s1)); \
 } \
-for (; i < vlmax; i++) {  \
-vext_set_elem_mask(vd, i, 0); \
-} \
 }
 
 GEN_VEXT_CMP_VV(vmseq_vv_b, uint8_t,  H1, DO_MSEQ)
@@ -1243,7 +1238,6 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, 
void *vs2,   \
 {   \
 uint32_t vm = vext_vm(desc);\
 uint32_t vl = env->vl;  \
-uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \
 uint32_t i; \
 \
 for (i = 0; i < vl; i++) {  \
@@ -1254,9 +1248,6 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, 
void *vs2,   \
 vext_set_elem_mask(vd, i,   \
 DO_OP(s2, (ETYPE)(target_long)s1)); \
 }   \
-for (; i < vlmax; i++) {\
-vext_set_elem_mask(vd, i, 0);   \
-}   \
 }
 
 GEN_VEXT_CMP_VX(vmseq_vx_b, uint8_t,  H1, DO_MSEQ)
-- 
2.25.1




[PATCH v10 45/77] target/riscv: rvv-1.0: widening integer multiply-add instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn32.decode | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index a3f1101cd63..7548b71efdb 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -474,9 +474,9 @@ vwmaccu_vv  00 . . . 010 . 1010111 @r_vm
 vwmaccu_vx  00 . . . 110 . 1010111 @r_vm
 vwmacc_vv   01 . . . 010 . 1010111 @r_vm
 vwmacc_vx   01 . . . 110 . 1010111 @r_vm
-vwmaccsu_vv 10 . . . 010 . 1010111 @r_vm
-vwmaccsu_vx 10 . . . 110 . 1010111 @r_vm
-vwmaccus_vx 11 . . . 110 . 1010111 @r_vm
+vwmaccsu_vv 11 . . . 010 . 1010111 @r_vm
+vwmaccsu_vx 11 . . . 110 . 1010111 @r_vm
+vwmaccus_vx 10 . . . 110 . 1010111 @r_vm
 vmv_v_v 010111 1 0 . 000 . 1010111 @r2
 vmv_v_x 010111 1 0 . 100 . 1010111 @r2
 vmv_v_i 010111 1 0 . 011 . 1010111 @r2
-- 
2.25.1




[PATCH v10 62/77] target/riscv: rvv-1.0: widening floating-point/integer type-convert

2021-11-28 Thread frank . chang
From: Frank Chang 

Add the following instructions:

* vfwcvt.rtz.xu.f.v
* vfwcvt.rtz.x.f.v

Also adjust GEN_OPFV_WIDEN_TRANS() to accept multiple floating-point
rounding modes.

Signed-off-by: Frank Chang 
Acked-by: Alistair Francis 
---
 target/riscv/helper.h   |  2 +
 target/riscv/insn32.decode  | 13 +++---
 target/riscv/insn_trans/trans_rvv.c.inc | 55 +
 target/riscv/vector_helper.c|  7 +++-
 4 files changed, 63 insertions(+), 14 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 1727075dce4..53cf88cd402 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -928,8 +928,10 @@ DEF_HELPER_5(vfwcvt_xu_f_v_h, void, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_5(vfwcvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_x_f_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_x_f_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_f_xu_v_b, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_f_x_v_b, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 02064f8ec98..664d0fb3716 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -592,11 +592,14 @@ vfcvt_f_xu_v   010010 . . 00010 001 . 1010111 
@r2_vm
 vfcvt_f_x_v010010 . . 00011 001 . 1010111 @r2_vm
 vfcvt_rtz_xu_f_v   010010 . . 00110 001 . 1010111 @r2_vm
 vfcvt_rtz_x_f_v010010 . . 00111 001 . 1010111 @r2_vm
-vfwcvt_xu_f_v   100010 . . 01000 001 . 1010111 @r2_vm
-vfwcvt_x_f_v100010 . . 01001 001 . 1010111 @r2_vm
-vfwcvt_f_xu_v   100010 . . 01010 001 . 1010111 @r2_vm
-vfwcvt_f_x_v100010 . . 01011 001 . 1010111 @r2_vm
-vfwcvt_f_f_v100010 . . 01100 001 . 1010111 @r2_vm
+
+vfwcvt_xu_f_v  010010 . . 01000 001 . 1010111 @r2_vm
+vfwcvt_x_f_v   010010 . . 01001 001 . 1010111 @r2_vm
+vfwcvt_f_xu_v  010010 . . 01010 001 . 1010111 @r2_vm
+vfwcvt_f_x_v   010010 . . 01011 001 . 1010111 @r2_vm
+vfwcvt_f_f_v   010010 . . 01100 001 . 1010111 @r2_vm
+vfwcvt_rtz_xu_f_v  010010 . . 01110 001 . 1010111 @r2_vm
+vfwcvt_rtz_x_f_v   010010 . . 0 001 . 1010111 @r2_vm
 vfncvt_xu_f_v   100010 . . 1 001 . 1010111 @r2_vm
 vfncvt_x_f_v100010 . . 10001 001 . 1010111 @r2_vm
 vfncvt_f_xu_v   100010 . . 10010 001 . 1010111 @r2_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 4bc4dfa69fc..b4cf044450d 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2536,12 +2536,55 @@ static bool opfv_widen_check(DisasContext *s, arg_rmr 
*a)
vext_check_ds(s, a->rd, a->rs2, a->vm);
 }
 
-#define GEN_OPFV_WIDEN_TRANS(NAME) \
+#define GEN_OPFV_WIDEN_TRANS(NAME, HELPER, FRM)\
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 {  \
 if (opfv_widen_check(s, a)) {  \
 uint32_t data = 0; \
 static gen_helper_gvec_3_ptr * const fns[2] = {\
+gen_helper_##HELPER##_h,   \
+gen_helper_##HELPER##_w,   \
+}; \
+TCGLabel *over = gen_new_label();  \
+gen_set_rm(s, FRM);\
+tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);  \
+   \
+data = FIELD_DP32(data, VDATA, VM, a->vm); \
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
+   vreg_ofs(s, a->rs2), cpu_env,   \
+   s->vlen / 8, s->vlen / 8, data, \
+   fns[s->sew - 1]);   \
+mark_vs_dirty(s);  \
+gen_set_label(over);   \
+return true;   \
+}  \
+return false;  \
+}
+
+GEN_OPFV_WIDEN_TRANS(vfwcvt_xu_f_v

[PATCH v10 58/77] target/riscv: rvv-1.0: remove integer extract instruction

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn32.decode  |  1 -
 target/riscv/insn_trans/trans_rvv.c.inc | 23 ---
 2 files changed, 24 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 82484fda751..20b3095f56c 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -632,7 +632,6 @@ viota_m 010100 . . 1 010 . 1010111 
@r2_vm
 vid_v   010100 . 0 10001 010 . 1010111 @r1_vm
 vmv_x_s 01 1 . 0 010 . 1010111 @r2rd
 vmv_s_x 01 1 0 . 110 . 1010111 @r2
-vext_x_v001100 1 . . 010 . 1010111 @r
 vfmv_f_s01 1 . 0 001 . 1010111 @r2rd
 vfmv_s_f01 1 0 . 101 . 1010111 @r2
 vslideup_vx 001110 . . . 100 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 4c5f813ccf9..1ce5a10b6a8 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2840,8 +2840,6 @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
  *** Vector Permutation Instructions
  */
 
-/* Integer Extract Instruction */
-
 static void load_element(TCGv_i64 dest, TCGv_ptr base,
  int ofs, int sew, bool sign)
 {
@@ -2941,27 +2939,6 @@ static void vec_element_loadi(DisasContext *s, TCGv_i64 
dest,
 load_element(dest, cpu_env, endian_ofs(s, vreg, idx), s->sew, sign);
 }
 
-static bool trans_vext_x_v(DisasContext *s, arg_r *a)
-{
-TCGv_i64 tmp = tcg_temp_new_i64();
-TCGv dest = dest_gpr(s, a->rd);
-
-if (a->rs1 == 0) {
-/* Special case vmv.x.s rd, vs2. */
-vec_element_loadi(s, tmp, a->rs2, 0, false);
-} else {
-/* This instruction ignores LMUL and vector register groups */
-int vlmax = s->vlen >> (3 + s->sew);
-vec_element_loadx(s, tmp, a->rs2, cpu_gpr[a->rs1], vlmax);
-}
-
-tcg_gen_trunc_i64_tl(dest, tmp);
-gen_set_gpr(s, a->rd, dest);
-
-tcg_temp_free_i64(tmp);
-return true;
-}
-
 /* Integer Scalar Move Instruction */
 
 static void store_element(TCGv_i64 val, TCGv_ptr base,
-- 
2.25.1




[PATCH v10 48/77] target/riscv: rvv-1.0: floating-point compare instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/vector_helper.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 277a5e4120a..71d7b1e8796 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3710,8 +3710,6 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
 { \
 uint32_t vm = vext_vm(desc);  \
 uint32_t vl = env->vl;\
-uint32_t vlmax = vext_max_elems(desc, \
-ctzl(sizeof(ETYPE))); \
 uint32_t i;   \
   \
 for (i = 0; i < vl; i++) {\
@@ -3723,9 +3721,6 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
 vext_set_elem_mask(vd, i, \
DO_OP(s2, s1, &env->fp_status));   \
 } \
-for (; i < vlmax; i++) {  \
-vext_set_elem_mask(vd, i, 0); \
-} \
 }
 
 GEN_VEXT_CMP_VV_ENV(vmfeq_vv_h, uint16_t, H2, float16_eq_quiet)
@@ -3738,7 +3733,6 @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void 
*vs2,   \
 {   \
 uint32_t vm = vext_vm(desc);\
 uint32_t vl = env->vl;  \
-uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \
 uint32_t i; \
 \
 for (i = 0; i < vl; i++) {  \
@@ -3749,9 +3743,6 @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void 
*vs2,   \
 vext_set_elem_mask(vd, i,   \
DO_OP(s2, (ETYPE)s1, &env->fp_status));  \
 }   \
-for (; i < vlmax; i++) {\
-vext_set_elem_mask(vd, i, 0);   \
-}   \
 }
 
 GEN_VEXT_CMP_VF(vmfeq_vf_h, uint16_t, H2, float16_eq_quiet)
-- 
2.25.1




[PATCH v10 50/77] target/riscv: rvv-1.0: slide instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

* Remove clear function from helper functions as the tail elements
  are unchanged in RVV 1.0.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/vector_helper.c | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index f883fdf4749..d79f59e443e 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4430,17 +4430,22 @@ GEN_VEXT_VSLIDEUP_VX(vslideup_vx_d, uint64_t, H8)
 void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
   CPURISCVState *env, uint32_t desc)  \
 { \
-uint32_t vlmax = env_archcpu(env)->cfg.vlen;  \
+uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE)));   \
 uint32_t vm = vext_vm(desc);  \
 uint32_t vl = env->vl;\
-target_ulong offset = s1, i;  \
+target_ulong i_max, i;\
   \
-for (i = 0; i < vl; ++i) {\
-target_ulong j = i + offset;  \
-if (!vm && !vext_elem_mask(v0, i)) {  \
-continue; \
+i_max = MIN(s1 < vlmax ? vlmax - s1 : 0, vl); \
+for (i = 0; i < i_max; ++i) { \
+if (vm || vext_elem_mask(v0, i)) {\
+*((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + s1));  \
+} \
+} \
+  \
+for (i = i_max; i < vl; ++i) {\
+if (vm || vext_elem_mask(v0, i)) {\
+*((ETYPE *)vd + H(i)) = 0;\
 } \
-*((ETYPE *)vd + H(i)) = j >= vlmax ? 0 : *((ETYPE *)vs2 + H(j));  \
 } \
 }
 
-- 
2.25.1




[PATCH v10 65/77] target/riscv: rvv-1.0: relax RV_VLEN_MAX to 1024-bits

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h  | 2 +-
 target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
 target/riscv/vector_helper.c| 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 11a0f41b27e..5d93ccdfa71 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -100,7 +100,7 @@ typedef struct CPURISCVState CPURISCVState;
 #include "pmp.h"
 #endif
 
-#define RV_VLEN_MAX 256
+#define RV_VLEN_MAX 1024
 
 FIELD(VTYPE, VLMUL, 0, 3)
 FIELD(VTYPE, VSEW, 3, 3)
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 42e94491184..be3f9f13275 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -567,8 +567,8 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, 
uint32_t data,
 base = get_gpr(s, rs1, EXT_NONE);
 
 /*
- * As simd_desc supports at most 256 bytes, and in this implementation,
- * the max vector group length is 2048 bytes. So split it into two parts.
+ * As simd_desc supports at most 2048 bytes, and in this implementation,
+ * the max vector group length is 4096 bytes. So split it into two parts.
  *
  * The first part is vlen in bytes, encoded in maxsz of simd_desc.
  * The second part is lmul, encoded in data of simd_desc.
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index a78f36b4b3b..e61c8731425 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -124,7 +124,7 @@ static inline int32_t vext_lmul(uint32_t desc)
 static inline uint32_t vext_max_elems(uint32_t desc, uint32_t esz)
 {
 /*
- * As simd_desc support at most 256 bytes, the max vlen is 256 bits.
+ * As simd_desc support at most 2048 bytes, the max vlen is 1024 bits.
  * so vlen in bytes (vlenb) is encoded as maxsz.
  */
 uint32_t vlenb = simd_maxsz(desc);
-- 
2.25.1




[PATCH v10 51/77] target/riscv: rvv-1.0: floating-point slide instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Add the following instructions:

* vfslide1up.vf
* vfslide1down.vf

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   |   7 ++
 target/riscv/insn32.decode  |   2 +
 target/riscv/insn_trans/trans_rvv.c.inc |  16 +++
 target/riscv/vector_helper.c| 141 
 4 files changed, 121 insertions(+), 45 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 304c12494d4..012d0343771 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1071,6 +1071,13 @@ DEF_HELPER_6(vslide1down_vx_h, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(vslide1down_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vslide1down_vx_d, void, ptr, ptr, tl, ptr, env, i32)
 
+DEF_HELPER_6(vfslide1up_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfslide1up_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfslide1up_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfslide1down_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfslide1down_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfslide1down_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+
 DEF_HELPER_6(vrgather_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vrgather_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vrgather_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 7548b71efdb..c5cc14c45c4 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -577,6 +577,8 @@ vfsgnjn_vv  001001 . . . 001 . 1010111 @r_vm
 vfsgnjn_vf  001001 . . . 101 . 1010111 @r_vm
 vfsgnjx_vv  001010 . . . 001 . 1010111 @r_vm
 vfsgnjx_vf  001010 . . . 101 . 1010111 @r_vm
+vfslide1up_vf   001110 . . . 101 . 1010111 @r_vm
+vfslide1down_vf 00 . . . 101 . 1010111 @r_vm
 vmfeq_vv011000 . . . 001 . 1010111 @r_vm
 vmfeq_vf011000 . . . 101 . 1010111 @r_vm
 vmfne_vv011100 . . . 001 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 5c0c3d25478..597a367444a 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3121,6 +3121,22 @@ GEN_OPIVX_TRANS(vslidedown_vx, slidedown_check)
 GEN_OPIVX_TRANS(vslide1down_vx, slidedown_check)
 GEN_OPIVI_TRANS(vslidedown_vi, IMM_ZX, vslidedown_vx, slidedown_check)
 
+/* Vector Floating-Point Slide Instructions */
+static bool fslideup_check(DisasContext *s, arg_rmrr *a)
+{
+return slideup_check(s, a) &&
+   require_rvf(s);
+}
+
+static bool fslidedown_check(DisasContext *s, arg_rmrr *a)
+{
+return slidedown_check(s, a) &&
+   require_rvf(s);
+}
+
+GEN_OPFVF_TRANS(vfslide1up_vf, fslideup_check)
+GEN_OPFVF_TRANS(vfslide1down_vf, fslidedown_check)
+
 /* Vector Register Gather Instruction */
 static bool vrgather_vv_check(DisasContext *s, arg_rmrr *a)
 {
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index d79f59e443e..7fa5189af4e 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4455,57 +4455,108 @@ GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_h, uint16_t, H2)
 GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_w, uint32_t, H4)
 GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_d, uint64_t, H8)
 
-#define GEN_VEXT_VSLIDE1UP_VX(NAME, ETYPE, H) \
-void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
-  CPURISCVState *env, uint32_t desc)  \
-{ \
-uint32_t vm = vext_vm(desc);  \
-uint32_t vl = env->vl;\
-uint32_t i;   \
-  \
-for (i = 0; i < vl; i++) {\
-if (!vm && !vext_elem_mask(v0, i)) {  \
-continue; \
-} \
-if (i == 0) { \
-*((ETYPE *)vd + H(i)) = s1;   \
-} else {  \
-*((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - 1));   \
-} \
-} \
+#define GEN_VEXT_VSLIE1UP(ESZ, H)   \
+static void vslide1up_##ESZ(vo

[PATCH v10 53/77] target/riscv: rvv-1.0: single-width floating-point reduction

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 12 +---
 target/riscv/vector_helper.c| 12 ++--
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index f5588d9832c..998247d71d9 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2637,9 +2637,15 @@ GEN_OPIVV_WIDEN_TRANS(vwredsum_vs, reduction_widen_check)
 GEN_OPIVV_WIDEN_TRANS(vwredsumu_vs, reduction_widen_check)
 
 /* Vector Single-Width Floating-Point Reduction Instructions */
-GEN_OPFVV_TRANS(vfredsum_vs, reduction_check)
-GEN_OPFVV_TRANS(vfredmax_vs, reduction_check)
-GEN_OPFVV_TRANS(vfredmin_vs, reduction_check)
+static bool freduction_check(DisasContext *s, arg_rmrr *a)
+{
+return reduction_check(s, a) &&
+   require_rvf(s);
+}
+
+GEN_OPFVV_TRANS(vfredsum_vs, freduction_check)
+GEN_OPFVV_TRANS(vfredmax_vs, freduction_check)
+GEN_OPFVV_TRANS(vfredmin_vs, freduction_check)
 
 /* Vector Widening Floating-Point Reduction Instructions */
 GEN_OPFVV_WIDEN_TRANS(vfwredsum_vs, reduction_check)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index c95c8bd9db3..79a2c3ff3ac 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4173,14 +4173,14 @@ GEN_VEXT_FRED(vfredsum_vs_w, uint32_t, uint32_t, H4, 
H4, float32_add)
 GEN_VEXT_FRED(vfredsum_vs_d, uint64_t, uint64_t, H8, H8, float64_add)
 
 /* Maximum value */
-GEN_VEXT_FRED(vfredmax_vs_h, uint16_t, uint16_t, H2, H2, float16_maxnum)
-GEN_VEXT_FRED(vfredmax_vs_w, uint32_t, uint32_t, H4, H4, float32_maxnum)
-GEN_VEXT_FRED(vfredmax_vs_d, uint64_t, uint64_t, H8, H8, float64_maxnum)
+GEN_VEXT_FRED(vfredmax_vs_h, uint16_t, uint16_t, H2, H2, 
float16_maximum_number)
+GEN_VEXT_FRED(vfredmax_vs_w, uint32_t, uint32_t, H4, H4, 
float32_maximum_number)
+GEN_VEXT_FRED(vfredmax_vs_d, uint64_t, uint64_t, H8, H8, 
float64_maximum_number)
 
 /* Minimum value */
-GEN_VEXT_FRED(vfredmin_vs_h, uint16_t, uint16_t, H2, H2, float16_minnum)
-GEN_VEXT_FRED(vfredmin_vs_w, uint32_t, uint32_t, H4, H4, float32_minnum)
-GEN_VEXT_FRED(vfredmin_vs_d, uint64_t, uint64_t, H8, H8, float64_minnum)
+GEN_VEXT_FRED(vfredmin_vs_h, uint16_t, uint16_t, H2, H2, 
float16_minimum_number)
+GEN_VEXT_FRED(vfredmin_vs_w, uint32_t, uint32_t, H4, H4, 
float32_minimum_number)
+GEN_VEXT_FRED(vfredmin_vs_d, uint64_t, uint64_t, H8, H8, 
float64_minimum_number)
 
 /* Vector Widening Floating-Point Reduction Instructions */
 /* Unordered reduce 2*SEW = 2*SEW + sum(promote(SEW)) */
-- 
2.25.1




[PATCH v10 71/77] target/riscv: rvv-1.0: rename r2_zimm to r2_zimm11

2021-11-28 Thread frank . chang
From: Frank Chang 

Rename r2_zimm to r2_zimm11 for the upcoming vsetivli instruction.
vsetivli has 10-bits of zimm but vsetvli has 11-bits of zimm.

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn32.decode | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 952768f8ded..d7c6bc9af26 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -78,7 +78,7 @@
 @r_vm.. vm:1 . . ... . ... &rmrr %rs2 %rs1 %rd
 @r_vm_1  .. . . . ... . ...&rmrr vm=1 %rs2 %rs1 %rd
 @r_vm_0  .. . . . ... . ...&rmrr vm=0 %rs2 %rs1 %rd
-@r2_zimm . zimm:11  . ... . ... %rs1 %rd
+@r2_zimm11 . zimm:11  . ... . ... %rs1 %rd
 @r2_s...   . . ... . ... %rs2 %rs1
 
 @hfence_gvma ... . .   ... . ... %rs2 %rs1
@@ -671,7 +671,7 @@ vsext_vf2   010010 . . 00111 010 . 1010111 
@r2_vm
 vsext_vf4   010010 . . 00101 010 . 1010111 @r2_vm
 vsext_vf8   010010 . . 00011 010 . 1010111 @r2_vm
 
-vsetvli 0 ... . 111 . 1010111  @r2_zimm
+vsetvli 0 ... . 111 . 1010111  @r2_zimm11
 vsetvl  100 . . 111 . 1010111  @r
 
 # *** RV32 Zba Standard Extension ***
-- 
2.25.1




[PATCH v10 52/77] target/riscv: rvv-1.0: narrowing fixed-point clip instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 24 ++--
 target/riscv/insn32.decode  | 12 +++---
 target/riscv/insn_trans/trans_rvv.c.inc | 12 +++---
 target/riscv/vector_helper.c| 52 -
 4 files changed, 50 insertions(+), 50 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 012d0343771..3ea21b4a578 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -725,18 +725,18 @@ DEF_HELPER_6(vssra_vx_h, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(vssra_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vssra_vx_d, void, ptr, ptr, tl, ptr, env, i32)
 
-DEF_HELPER_6(vnclip_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnclip_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnclip_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnclipu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnclipu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnclipu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnclipu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnclipu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnclipu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnclip_vx_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnclip_vx_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnclip_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnclip_wv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnclip_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnclip_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnclipu_wv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnclipu_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnclipu_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnclipu_wx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnclipu_wx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnclipu_wx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnclip_wx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnclip_wx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnclip_wx_w, void, ptr, ptr, tl, ptr, env, i32)
 
 DEF_HELPER_6(vfadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index c5cc14c45c4..eeab6b00a1b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -516,12 +516,12 @@ vssrl_vi101010 . . . 011 . 1010111 
@r_vm
 vssra_vv101011 . . . 000 . 1010111 @r_vm
 vssra_vx101011 . . . 100 . 1010111 @r_vm
 vssra_vi101011 . . . 011 . 1010111 @r_vm
-vnclipu_vv  101110 . . . 000 . 1010111 @r_vm
-vnclipu_vx  101110 . . . 100 . 1010111 @r_vm
-vnclipu_vi  101110 . . . 011 . 1010111 @r_vm
-vnclip_vv   10 . . . 000 . 1010111 @r_vm
-vnclip_vx   10 . . . 100 . 1010111 @r_vm
-vnclip_vi   10 . . . 011 . 1010111 @r_vm
+vnclipu_wv  101110 . . . 000 . 1010111 @r_vm
+vnclipu_wx  101110 . . . 100 . 1010111 @r_vm
+vnclipu_wi  101110 . . . 011 . 1010111 @r_vm
+vnclip_wv   10 . . . 000 . 1010111 @r_vm
+vnclip_wx   10 . . . 100 . 1010111 @r_vm
+vnclip_wi   10 . . . 011 . 1010111 @r_vm
 vfadd_vv00 . . . 001 . 1010111 @r_vm
 vfadd_vf00 . . . 101 . 1010111 @r_vm
 vfsub_vv10 . . . 001 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 597a367444a..f5588d9832c 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2034,12 +2034,12 @@ GEN_OPIVI_TRANS(vssrl_vi, IMM_ZX, vssrl_vx, opivx_check)
 GEN_OPIVI_TRANS(vssra_vi, IMM_SX, vssra_vx, opivx_check)
 
 /* Vector Narrowing Fixed-Point Clip Instructions */
-GEN_OPIWV_NARROW_TRANS(vnclipu_vv)
-GEN_OPIWV_NARROW_TRANS(vnclip_vv)
-GEN_OPIWX_NARROW_TRANS(vnclipu_vx)
-GEN_OPIWX_NARROW_TRANS(vnclip_vx)
-GEN_OPIWI_NARROW_TRANS(vnclipu_vi, IMM_ZX, vnclipu_vx)
-GEN_OPIWI_NARROW_TRANS(vnclip_vi, IMM_ZX, vnclip_vx)
+GEN_OPIWV_NARROW_TRANS(vnclipu_wv)
+GEN_OPIWV_NARROW_TRANS(vnclip_wv)
+GEN_OPIWX_NARROW_TRANS(vnclipu_wx)
+GEN_OPIWX_NARROW_TRANS(vnclip_wx)
+GEN_OPIWI_NARROW_TRANS(vnclipu_wi, IMM_ZX, vnclipu_wx)
+GEN_OPIWI_NARROW_TRANS(vnclip_wi, IMM_ZX, vnclip_wx)
 
 /*
  *** Vector Float Point Arithmetic Instructions
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 7fa5189af4e..c95c8bd9db3 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -2875,19 +2875,19 @@ vnclip32(CPURISCVState *env, int vxrm, int64_t a, 
int32_t b

[PATCH v10 75/77] target/riscv: rvv-1.0: rename vmandnot.mm and vmornot.mm to vmandn.mm and vmorn.mm

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   | 4 ++--
 target/riscv/insn32.decode  | 4 ++--
 target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
 target/riscv/vector_helper.c| 4 ++--
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 6e58343af35..c15497e4a15 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1016,11 +1016,11 @@ DEF_HELPER_6(vfwredsum_vs_w, void, ptr, ptr, ptr, ptr, 
env, i32)
 
 DEF_HELPER_6(vmand_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmnand_mm, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vmandnot_mm, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmandn_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmxor_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmor_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vmornot_mm, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vmorn_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmxnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
 
 DEF_HELPER_4(vcpop_m, tl, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 1a4a2871464..8617307b29a 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -635,11 +635,11 @@ vfredmax_vs 000111 . . . 001 . 1010111 
@r_vm
 vfwredsum_vs1100-1 . . . 001 . 1010111 @r_vm
 vmand_mm011001 - . . 010 . 1010111 @r
 vmnand_mm   011101 - . . 010 . 1010111 @r
-vmandnot_mm 011000 - . . 010 . 1010111 @r
+vmandn_mm   011000 - . . 010 . 1010111 @r
 vmxor_mm011011 - . . 010 . 1010111 @r
 vmor_mm 011010 - . . 010 . 1010111 @r
 vmnor_mm00 - . . 010 . 1010111 @r
-vmornot_mm  011100 - . . 010 . 1010111 @r
+vmorn_mm011100 - . . 010 . 1010111 @r
 vmxnor_mm   01 - . . 010 . 1010111 @r
 vcpop_m 01 . . 1 010 . 1010111 @r2_vm
 vfirst_m01 . . 10001 010 . 1010111 @r2_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 97b1dc10265..33ef7926e64 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2862,11 +2862,11 @@ static bool trans_##NAME(DisasContext *s, arg_r *a) 
   \
 
 GEN_MM_TRANS(vmand_mm)
 GEN_MM_TRANS(vmnand_mm)
-GEN_MM_TRANS(vmandnot_mm)
+GEN_MM_TRANS(vmandn_mm)
 GEN_MM_TRANS(vmxor_mm)
 GEN_MM_TRANS(vmor_mm)
 GEN_MM_TRANS(vmnor_mm)
-GEN_MM_TRANS(vmornot_mm)
+GEN_MM_TRANS(vmorn_mm)
 GEN_MM_TRANS(vmxnor_mm)
 
 /* Vector count population in mask vcpop */
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 4c1a1310e63..ad505ec9b21 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4470,11 +4470,11 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,
  \
 
 GEN_VEXT_MASK_VV(vmand_mm, DO_AND)
 GEN_VEXT_MASK_VV(vmnand_mm, DO_NAND)
-GEN_VEXT_MASK_VV(vmandnot_mm, DO_ANDNOT)
+GEN_VEXT_MASK_VV(vmandn_mm, DO_ANDNOT)
 GEN_VEXT_MASK_VV(vmxor_mm, DO_XOR)
 GEN_VEXT_MASK_VV(vmor_mm, DO_OR)
 GEN_VEXT_MASK_VV(vmnor_mm, DO_NOR)
-GEN_VEXT_MASK_VV(vmornot_mm, DO_ORNOT)
+GEN_VEXT_MASK_VV(vmorn_mm, DO_ORNOT)
 GEN_VEXT_MASK_VV(vmxnor_mm, DO_XNOR)
 
 /* Vector count population in mask vcpop */
-- 
2.25.1




[PATCH v10 15/77] target/riscv: rvv-1.0: update check functions

2021-11-28 Thread frank . chang
From: Frank Chang 

Update check functions with RVV 1.0 rules.

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 715 +---
 1 file changed, 507 insertions(+), 208 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index ecd4b89c6b1..bef37dd888e 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -19,11 +19,112 @@
 #include "tcg/tcg-gvec-desc.h"
 #include "internals.h"
 
+static inline bool is_overlapped(const int8_t astart, int8_t asize,
+ const int8_t bstart, int8_t bsize)
+{
+const int8_t aend = astart + asize;
+const int8_t bend = bstart + bsize;
+
+return MAX(aend, bend) - MIN(astart, bstart) < asize + bsize;
+}
+
+static bool require_rvv(DisasContext *s)
+{
+return s->mstatus_vs != 0;
+}
+
+static bool require_rvf(DisasContext *s)
+{
+if (s->mstatus_fs == 0) {
+return false;
+}
+
+switch (s->sew) {
+case MO_16:
+case MO_32:
+return has_ext(s, RVF);
+case MO_64:
+return has_ext(s, RVD);
+default:
+return false;
+}
+}
+
+static bool require_scale_rvf(DisasContext *s)
+{
+if (s->mstatus_fs == 0) {
+return false;
+}
+
+switch (s->sew) {
+case MO_8:
+case MO_16:
+return has_ext(s, RVF);
+case MO_32:
+return has_ext(s, RVD);
+default:
+return false;
+}
+}
+
+/* Destination vector register group cannot overlap source mask register. */
+static bool require_vm(int vm, int vd)
+{
+return (vm != 0 || vd != 0);
+}
+
+/*
+ * Vector register should aligned with the passed-in LMUL (EMUL).
+ * If LMUL < 0, i.e. fractional LMUL, any vector register is allowed.
+ */
+static bool require_align(const int8_t val, const int8_t lmul)
+{
+return lmul <= 0 || extract32(val, 0, lmul) == 0;
+}
+
+/*
+ * A destination vector register group can overlap a source vector
+ * register group only if one of the following holds:
+ *  1. The destination EEW equals the source EEW.
+ *  2. The destination EEW is smaller than the source EEW and the overlap
+ * is in the lowest-numbered part of the source register group.
+ *  3. The destination EEW is greater than the source EEW, the source EMUL
+ * is at least 1, and the overlap is in the highest-numbered part of
+ * the destination register group.
+ * (Section 5.2)
+ *
+ * This function returns true if one of the following holds:
+ *  * Destination vector register group does not overlap a source vector
+ *register group.
+ *  * Rule 3 met.
+ * For rule 1, overlap is allowed so this function doesn't need to be called.
+ * For rule 2, (vd == vs). Caller has to check whether: (vd != vs) before
+ * calling this function.
+ */
+static bool require_noover(const int8_t dst, const int8_t dst_lmul,
+   const int8_t src, const int8_t src_lmul)
+{
+int8_t dst_size = dst_lmul <= 0 ? 1 : 1 << dst_lmul;
+int8_t src_size = src_lmul <= 0 ? 1 : 1 << src_lmul;
+
+/* Destination EEW is greater than the source EEW, check rule 3. */
+if (dst_size > src_size) {
+if (dst < src &&
+src_lmul >= 0 &&
+is_overlapped(dst, dst_size, src, src_size) &&
+!is_overlapped(dst, dst_size, src + src_size, src_size)) {
+return true;
+}
+}
+
+return !is_overlapped(dst, dst_size, src, src_size);
+}
+
 static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
 {
 TCGv s1, s2, dst;
 
-if (!has_ext(ctx, RVV)) {
+if (!require_rvv(ctx) || !has_ext(ctx, RVV)) {
 return false;
 }
 
@@ -51,7 +152,7 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
 {
 TCGv s1, s2, dst;
 
-if (!has_ext(ctx, RVV)) {
+if (!require_rvv(ctx) || !has_ext(ctx, RVV)) {
 return false;
 }
 
@@ -82,6 +183,237 @@ static uint32_t vreg_ofs(DisasContext *s, int reg)
 
 /* check functions */
 
+static bool vext_check_ss(DisasContext *s, int vd, int vs, int vm)
+{
+return require_vm(vm, vd) &&
+require_align(vd, s->lmul) &&
+require_align(vs, s->lmul);
+}
+
+/*
+ * Check function for vector instruction with format:
+ * single-width result and single-width sources (SEW = SEW op SEW)
+ *
+ * Rules to be checked here:
+ *   1. Destination vector register group for a masked vector
+ *  instruction cannot overlap the source mask register (v0).
+ *  (Section 5.3)
+ *   2. Destination vector register number is multiples of LMUL.
+ *  (Section 3.4.2)
+ *   3. Source (vs2, vs1) vector register number are multiples of LMUL.
+ *  (Section 3.4.2)
+ */
+static bool vext_check_sss(DisasContext *s, int vd, int vs1, int vs2, int vm)
+{
+return vext_check_ss(s, vd, vs2, vm) 

[PATCH v10 59/77] target/riscv: rvv-1.0: floating-point min/max instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/vector_helper.c | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index aed230e1ad8..cc95b692558 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3387,28 +3387,28 @@ GEN_VEXT_V_ENV(vfsqrt_v_w, 4, 4)
 GEN_VEXT_V_ENV(vfsqrt_v_d, 8, 8)
 
 /* Vector Floating-Point MIN/MAX Instructions */
-RVVCALL(OPFVV2, vfmin_vv_h, OP_UUU_H, H2, H2, H2, float16_minnum)
-RVVCALL(OPFVV2, vfmin_vv_w, OP_UUU_W, H4, H4, H4, float32_minnum)
-RVVCALL(OPFVV2, vfmin_vv_d, OP_UUU_D, H8, H8, H8, float64_minnum)
+RVVCALL(OPFVV2, vfmin_vv_h, OP_UUU_H, H2, H2, H2, float16_minimum_number)
+RVVCALL(OPFVV2, vfmin_vv_w, OP_UUU_W, H4, H4, H4, float32_minimum_number)
+RVVCALL(OPFVV2, vfmin_vv_d, OP_UUU_D, H8, H8, H8, float64_minimum_number)
 GEN_VEXT_VV_ENV(vfmin_vv_h, 2, 2)
 GEN_VEXT_VV_ENV(vfmin_vv_w, 4, 4)
 GEN_VEXT_VV_ENV(vfmin_vv_d, 8, 8)
-RVVCALL(OPFVF2, vfmin_vf_h, OP_UUU_H, H2, H2, float16_minnum)
-RVVCALL(OPFVF2, vfmin_vf_w, OP_UUU_W, H4, H4, float32_minnum)
-RVVCALL(OPFVF2, vfmin_vf_d, OP_UUU_D, H8, H8, float64_minnum)
+RVVCALL(OPFVF2, vfmin_vf_h, OP_UUU_H, H2, H2, float16_minimum_number)
+RVVCALL(OPFVF2, vfmin_vf_w, OP_UUU_W, H4, H4, float32_minimum_number)
+RVVCALL(OPFVF2, vfmin_vf_d, OP_UUU_D, H8, H8, float64_minimum_number)
 GEN_VEXT_VF(vfmin_vf_h, 2, 2)
 GEN_VEXT_VF(vfmin_vf_w, 4, 4)
 GEN_VEXT_VF(vfmin_vf_d, 8, 8)
 
-RVVCALL(OPFVV2, vfmax_vv_h, OP_UUU_H, H2, H2, H2, float16_maxnum)
-RVVCALL(OPFVV2, vfmax_vv_w, OP_UUU_W, H4, H4, H4, float32_maxnum)
-RVVCALL(OPFVV2, vfmax_vv_d, OP_UUU_D, H8, H8, H8, float64_maxnum)
+RVVCALL(OPFVV2, vfmax_vv_h, OP_UUU_H, H2, H2, H2, float16_maximum_number)
+RVVCALL(OPFVV2, vfmax_vv_w, OP_UUU_W, H4, H4, H4, float32_maximum_number)
+RVVCALL(OPFVV2, vfmax_vv_d, OP_UUU_D, H8, H8, H8, float64_maximum_number)
 GEN_VEXT_VV_ENV(vfmax_vv_h, 2, 2)
 GEN_VEXT_VV_ENV(vfmax_vv_w, 4, 4)
 GEN_VEXT_VV_ENV(vfmax_vv_d, 8, 8)
-RVVCALL(OPFVF2, vfmax_vf_h, OP_UUU_H, H2, H2, float16_maxnum)
-RVVCALL(OPFVF2, vfmax_vf_w, OP_UUU_W, H4, H4, float32_maxnum)
-RVVCALL(OPFVF2, vfmax_vf_d, OP_UUU_D, H8, H8, float64_maxnum)
+RVVCALL(OPFVF2, vfmax_vf_h, OP_UUU_H, H2, H2, float16_maximum_number)
+RVVCALL(OPFVF2, vfmax_vf_w, OP_UUU_W, H4, H4, float32_maximum_number)
+RVVCALL(OPFVF2, vfmax_vf_d, OP_UUU_D, H8, H8, float64_maximum_number)
 GEN_VEXT_VF(vfmax_vf_h, 2, 2)
 GEN_VEXT_VF(vfmax_vf_w, 4, 4)
 GEN_VEXT_VF(vfmax_vf_d, 8, 8)
-- 
2.25.1




[PATCH v10 01/77] target/riscv: drop vector 0.7.1 and add 1.0 support

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Bin Meng 
---
 target/riscv/cpu.c | 16 
 target/riscv/cpu.h |  2 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index f7fda686863..c760ea08621 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -523,7 +523,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 ext |= RVH;
 }
 if (cpu->cfg.ext_v) {
-int vext_version = VEXT_VERSION_0_07_1;
+int vext_version = VEXT_VERSION_1_00_0;
 ext |= RVV;
 if (!is_power_of_2(cpu->cfg.vlen)) {
 error_setg(errp,
@@ -548,8 +548,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 if (cpu->cfg.vext_spec) {
-if (!g_strcmp0(cpu->cfg.vext_spec, "v0.7.1")) {
-vext_version = VEXT_VERSION_0_07_1;
+if (!g_strcmp0(cpu->cfg.vext_spec, "v1.0")) {
+vext_version = VEXT_VERSION_1_00_0;
 } else {
 error_setg(errp,
"Unsupported vector spec version '%s'",
@@ -558,7 +558,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 } else {
 qemu_log("vector version is not specified, "
-"use the default value v0.7.1\n");
+ "use the default value v1.0\n");
 }
 set_vext_version(env, vext_version);
 }
@@ -626,6 +626,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("c", RISCVCPU, cfg.ext_c, true),
 DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true),
 DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
+DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
 DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
 DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
 DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
@@ -635,6 +636,9 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
 
 DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
+DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
+DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
+DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
 
 /* These are experimental so mark with 'x-' */
 DEFINE_PROP_BOOL("x-zba", RISCVCPU, cfg.ext_zba, false),
@@ -643,10 +647,6 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("x-zbs", RISCVCPU, cfg.ext_zbs, false),
 DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
 DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
-DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false),
-DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
-DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
-DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
 /* ePMP 0.9.3 */
 DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
 
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index ef677f90922..5ea2004ae02 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -81,7 +81,7 @@ enum {
 #define PRIV_VERSION_1_10_0 0x00011000
 #define PRIV_VERSION_1_11_0 0x00011100
 
-#define VEXT_VERSION_0_07_1 0x0701
+#define VEXT_VERSION_1_00_0 0x0001
 
 enum {
 TRANSLATE_SUCCESS,
-- 
2.25.1




[PATCH v10 12/77] target/riscv: rvv-1.0: remove MLEN calculations

2021-11-28 Thread frank . chang
From: Frank Chang 

As in RVV 1.0 design, MLEN is hardcoded with value 1 (Section 4.5).
Thus, remove all MLEN related calculations.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc |  35 +---
 target/riscv/internals.h|   9 +-
 target/riscv/translate.c|   2 -
 target/riscv/vector_helper.c| 252 ++--
 4 files changed, 111 insertions(+), 187 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index bc1d4a5f235..ecd4b89c6b1 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -237,7 +237,6 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, 
uint8_t seq)
 return false;
 }
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
@@ -290,7 +289,6 @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, 
uint8_t seq)
 return false;
 }
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
@@ -374,7 +372,6 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, 
uint8_t seq)
 return false;
 }
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
@@ -413,7 +410,6 @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, 
uint8_t seq)
   gen_helper_vsse_v_w,  gen_helper_vsse_v_d }
 };
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
@@ -504,7 +500,6 @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, 
uint8_t seq)
 return false;
 }
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
@@ -556,7 +551,6 @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, 
uint8_t seq)
 return false;
 }
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
@@ -632,7 +626,6 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t 
seq)
 return false;
 }
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
@@ -740,7 +733,6 @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t 
seq)
 g_assert_not_reached();
 }
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, WD, a->wd);
@@ -823,7 +815,6 @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn 
*gvec_fn,
 } else {
 uint32_t data = 0;
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
@@ -868,7 +859,6 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t 
vs2, uint32_t vm,
 src2 = tcg_temp_new_ptr();
 src1 = get_gpr(s, rs1, EXT_NONE);
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
@@ -1012,7 +1002,6 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, 
uint32_t vs2, uint32_t vm,
 } else {
 src1 = tcg_constant_tl(sextract64(imm, 0, 5));
 }
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
@@ -1105,7 +1094,6 @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
 TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 tcg_gen_gvec_4_p

[PATCH v10 60/77] target/riscv: introduce floating-point rounding mode enum

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/fpu_helper.c   | 12 ++--
 target/riscv/insn_trans/trans_rvv.c.inc | 18 +-
 target/riscv/internals.h|  9 +
 3 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index 388e23ca670..dec39d4a9ed 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -55,23 +55,23 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t 
rm)
 {
 int softrm;
 
-if (rm == 7) {
+if (rm == RISCV_FRM_DYN) {
 rm = env->frm;
 }
 switch (rm) {
-case 0:
+case RISCV_FRM_RNE:
 softrm = float_round_nearest_even;
 break;
-case 1:
+case RISCV_FRM_RTZ:
 softrm = float_round_to_zero;
 break;
-case 2:
+case RISCV_FRM_RDN:
 softrm = float_round_down;
 break;
-case 3:
+case RISCV_FRM_RUP:
 softrm = float_round_up;
 break;
-case 4:
+case RISCV_FRM_RMM:
 softrm = float_round_ties_away;
 break;
 default:
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 1ce5a10b6a8..047be5d5c47 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2088,7 +2088,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 gen_helper_##NAME##_d, \
 }; \
 TCGLabel *over = gen_new_label();  \
-gen_set_rm(s, 7);  \
+gen_set_rm(s, RISCV_FRM_DYN);  \
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);  \
\
 data = FIELD_DP32(data, VDATA, VM, a->vm); \
@@ -2167,7 +2167,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
\
 gen_helper_##NAME##_w,\
 gen_helper_##NAME##_d,\
 };\
-gen_set_rm(s, 7); \
+gen_set_rm(s, RISCV_FRM_DYN); \
 data = FIELD_DP32(data, VDATA, VM, a->vm);\
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);\
 return opfvf_trans(a->rd, a->rs1, a->rs2, data,   \
@@ -2199,7 +2199,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
   \
 gen_helper_##NAME##_h, gen_helper_##NAME##_w,\
 };   \
 TCGLabel *over = gen_new_label();\
-gen_set_rm(s, 7);\
+gen_set_rm(s, RISCV_FRM_DYN);\
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);\
  \
 data = FIELD_DP32(data, VDATA, VM, a->vm);   \
@@ -2236,7 +2236,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
   \
 static gen_helper_opfvf *const fns[2] = {\
 gen_helper_##NAME##_h, gen_helper_##NAME##_w,\
 };   \
-gen_set_rm(s, 7);\
+gen_set_rm(s, RISCV_FRM_DYN);\
 data = FIELD_DP32(data, VDATA, VM, a->vm);   \
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);   \
 return opfvf_trans(a->rd, a->rs1, a->rs2, data,  \
@@ -2266,7 +2266,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 gen_helper_##NAME##_h, gen_helper_##NAME##_w,  \
 }; \
 TCGLabel *over = gen_new_label();  \
-gen_set_rm(s, 7);  \
+gen_set_rm(s, RISCV_FRM_DYN);  \
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);  \
\
 data = FIELD_DP32(data, VDATA, VM, a->vm); \
@@ -2303,7 +2303,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
   \
 static gen_helper_opfvf *const fns[2] = {\
 gen_helper_##NAME##_h, gen_helper_##NAME##_w,\
 };   \
-gen_set_rm(s, 7); 

[PATCH v10 64/77] target/riscv: rvv-1.0: narrowing floating-point/integer type-convert

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Acked-by: Alistair Francis 
---
 target/riscv/helper.h   | 22 -
 target/riscv/insn32.decode  | 15 ---
 target/riscv/insn_trans/trans_rvv.c.inc | 59 +
 target/riscv/vector_helper.c| 45 ++-
 4 files changed, 97 insertions(+), 44 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 606bf72d5cb..1a0d817f0f5 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -938,16 +938,18 @@ DEF_HELPER_5(vfwcvt_f_x_v_w, void, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_5(vfwcvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
 
-DEF_HELPER_5(vfncvt_xu_f_v_h, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_x_f_v_h, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_x_f_v_w, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_xu_f_w_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_xu_f_w_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_xu_f_w_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_x_f_w_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_x_f_w_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_x_f_w_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_xu_w_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_xu_w_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_x_w_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_x_w_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_f_w_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_f_w_w, void, ptr, ptr, ptr, env, i32)
 
 DEF_HELPER_6(vredsum_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 664d0fb3716..c4fdc76a269 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -600,11 +600,16 @@ vfwcvt_f_x_v   010010 . . 01011 001 . 1010111 
@r2_vm
 vfwcvt_f_f_v   010010 . . 01100 001 . 1010111 @r2_vm
 vfwcvt_rtz_xu_f_v  010010 . . 01110 001 . 1010111 @r2_vm
 vfwcvt_rtz_x_f_v   010010 . . 0 001 . 1010111 @r2_vm
-vfncvt_xu_f_v   100010 . . 1 001 . 1010111 @r2_vm
-vfncvt_x_f_v100010 . . 10001 001 . 1010111 @r2_vm
-vfncvt_f_xu_v   100010 . . 10010 001 . 1010111 @r2_vm
-vfncvt_f_x_v100010 . . 10011 001 . 1010111 @r2_vm
-vfncvt_f_f_v100010 . . 10100 001 . 1010111 @r2_vm
+
+vfncvt_xu_f_w  010010 . . 1 001 . 1010111 @r2_vm
+vfncvt_x_f_w   010010 . . 10001 001 . 1010111 @r2_vm
+vfncvt_f_xu_w  010010 . . 10010 001 . 1010111 @r2_vm
+vfncvt_f_x_w   010010 . . 10011 001 . 1010111 @r2_vm
+vfncvt_f_f_w   010010 . . 10100 001 . 1010111 @r2_vm
+vfncvt_rod_f_f_w   010010 . . 10101 001 . 1010111 @r2_vm
+vfncvt_rtz_xu_f_w  010010 . . 10110 001 . 1010111 @r2_vm
+vfncvt_rtz_x_f_w   010010 . . 10111 001 . 1010111 @r2_vm
+
 vredsum_vs  00 . . . 010 . 1010111 @r_vm
 vredand_vs  01 . . . 010 . 1010111 @r_vm
 vredor_vs   10 . . . 010 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index b4cf044450d..42e94491184 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2623,17 +2623,17 @@ static bool opfv_narrow_check(DisasContext *s, arg_rmr 
*a)
vext_check_sd(s, a->rd, a->rs2, a->vm);
 }
 
-#define GEN_OPFV_NARROW_TRANS(NAME)\
+#define GEN_OPFV_NARROW_TRANS(NAME, HELPER, FRM)   \
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 {  \
 if (opfv_narrow_check(s, a)) { \
 uint32_t data = 0; \
 static gen_helper_gvec_3_ptr * const fns[2] = {\
-gen_helper_##NAME##_h, \
-gen_helper_##NAME##_w, \
+gen_helper_##HELPER##_h,   \
+gen_helper_##HELPER##_w,   \
 }; \
 TCGLabel *over = gen_

[PATCH v10 63/77] target/riscv: add "set round to odd" rounding mode helper function

2021-11-28 Thread frank . chang
From: Frank Chang 

helper_set_rounding_mode() is responsible for SIGILL, and "round to odd"
should be an interface private to translation, so add a new independent
helper_set_rod_rounding_mode().

Signed-off-by: Frank Chang 
Acked-by: Alistair Francis 
---
 target/riscv/fpu_helper.c | 5 +
 target/riscv/helper.h | 1 +
 target/riscv/internals.h  | 1 +
 target/riscv/translate.c  | 7 +++
 4 files changed, 14 insertions(+)

diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index dec39d4a9ed..4a5982d5945 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -81,6 +81,11 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t 
rm)
 set_float_rounding_mode(softrm, &env->fp_status);
 }
 
+void helper_set_rod_rounding_mode(CPURISCVState *env)
+{
+set_float_rounding_mode(float_round_to_odd, &env->fp_status);
+}
+
 static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
uint64_t rs3, int flags)
 {
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 53cf88cd402..606bf72d5cb 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -3,6 +3,7 @@ DEF_HELPER_2(raise_exception, noreturn, env, i32)
 
 /* Floating Point - rounding mode */
 DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32)
+DEF_HELPER_FLAGS_1(set_rod_rounding_mode, TCG_CALL_NO_WG, void, env)
 
 /* Floating Point - fused */
 DEF_HELPER_FLAGS_4(fmadd_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index db105d4d640..065e8162a2f 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -43,6 +43,7 @@ enum {
 RISCV_FRM_RUP = 3,  /* Round Up */
 RISCV_FRM_RMM = 4,  /* Round to Nearest, ties to Max Magnitude */
 RISCV_FRM_DYN = 7,  /* Dynamic rounding mode */
+RISCV_FRM_ROD = 8,  /* Round to Odd */
 };
 
 static inline uint64_t nanbox_s(float32 f)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 3688e80d03e..b4df21bda3c 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -30,6 +30,7 @@
 #include "exec/log.h"
 
 #include "instmap.h"
+#include "internals.h"
 
 /* global register indices */
 static TCGv cpu_gpr[32], cpu_pc, cpu_vl;
@@ -403,6 +404,12 @@ static void gen_set_rm(DisasContext *ctx, int rm)
 return;
 }
 ctx->frm = rm;
+
+if (rm == RISCV_FRM_ROD) {
+gen_helper_set_rod_rounding_mode(cpu_env);
+return;
+}
+
 gen_helper_set_rounding_mode(cpu_env, tcg_constant_i32(rm));
 }
 
-- 
2.25.1




[PATCH v10 02/77] target/riscv: Use FIELD_EX32() to extract wd field

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 12c31aa4b4d..70f589813ed 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -98,7 +98,7 @@ static inline uint32_t vext_lmul(uint32_t desc)
 
 static uint32_t vext_wd(uint32_t desc)
 {
-return (simd_data(desc) >> 11) & 0x1;
+return FIELD_EX32(simd_data(desc), VDATA, WD);
 }
 
 /*
-- 
2.25.1




[PATCH v10 44/77] target/riscv: rvv-1.0: narrowing integer right shift instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 24 +++---
 target/riscv/insn32.decode  | 12 +++
 target/riscv/insn_trans/trans_rvv.c.inc | 42 -
 target/riscv/vector_helper.c| 24 +++---
 4 files changed, 51 insertions(+), 51 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index f2e8d107d2f..304c12494d4 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -351,18 +351,18 @@ DEF_HELPER_6(vsra_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vsra_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vsra_vx_d, void, ptr, ptr, tl, ptr, env, i32)
 
-DEF_HELPER_6(vnsrl_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnsrl_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnsrl_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnsra_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnsra_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnsra_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnsrl_vx_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnsrl_vx_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnsrl_vx_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnsra_vx_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnsra_vx_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnsra_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnsrl_wv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnsrl_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnsrl_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnsra_wv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnsra_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnsra_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnsrl_wx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnsrl_wx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnsrl_wx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnsra_wx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnsra_wx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnsra_wx_w, void, ptr, ptr, tl, ptr, env, i32)
 
 DEF_HELPER_6(vmseq_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmseq_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 9c4089d7a7b..a3f1101cd63 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -406,12 +406,12 @@ vsrl_vi 101000 . . . 011 . 1010111 
@r_vm
 vsra_vv 101001 . . . 000 . 1010111 @r_vm
 vsra_vx 101001 . . . 100 . 1010111 @r_vm
 vsra_vi 101001 . . . 011 . 1010111 @r_vm
-vnsrl_vv101100 . . . 000 . 1010111 @r_vm
-vnsrl_vx101100 . . . 100 . 1010111 @r_vm
-vnsrl_vi101100 . . . 011 . 1010111 @r_vm
-vnsra_vv101101 . . . 000 . 1010111 @r_vm
-vnsra_vx101101 . . . 100 . 1010111 @r_vm
-vnsra_vi101101 . . . 011 . 1010111 @r_vm
+vnsrl_wv101100 . . . 000 . 1010111 @r_vm
+vnsrl_wx101100 . . . 100 . 1010111 @r_vm
+vnsrl_wi101100 . . . 011 . 1010111 @r_vm
+vnsra_wv101101 . . . 000 . 1010111 @r_vm
+vnsra_wx101101 . . . 100 . 1010111 @r_vm
+vnsra_wi101101 . . . 011 . 1010111 @r_vm
 vmseq_vv011000 . . . 000 . 1010111 @r_vm
 vmseq_vx011000 . . . 100 . 1010111 @r_vm
 vmseq_vi011000 . . . 011 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 357615a11c3..f6202835ff4 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1690,7 +1690,7 @@ GEN_OPIVI_GVEC_TRANS(vsrl_vi, IMM_TRUNC_SEW, vsrl_vx, 
shri)
 GEN_OPIVI_GVEC_TRANS(vsra_vi, IMM_TRUNC_SEW, vsra_vx, sari)
 
 /* Vector Narrowing Integer Right Shift Instructions */
-static bool opivv_narrow_check(DisasContext *s, arg_rmrr *a)
+static bool opiwv_narrow_check(DisasContext *s, arg_rmrr *a)
 {
 return require_rvv(s) &&
vext_check_isa_ill(s) &&
@@ -1698,10 +1698,10 @@ static bool opivv_narrow_check(DisasContext *s, 
arg_rmrr *a)
 }
 
 /* OPIVV with NARROW */
-#define GEN_OPIVV_NARROW_TRANS(NAME)   \
+#define GEN_OPIWV_NARROW_TRANS(NAME)   \
 static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
 {  \
-if (opivv_narrow_check(s, a)) {\
+if (opiwv_narrow_check(s, a)) {\
 uint32_t data = 0; \
 static gen_helper_gvec_4_p

[PATCH v10 72/77] target/riscv: rvv-1.0: add vsetivli instruction

2021-11-28 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn32.decode  |  2 ++
 target/riscv/insn_trans/trans_rvv.c.inc | 27 +
 2 files changed, 29 insertions(+)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index d7c6bc9af26..3b6524bad91 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -79,6 +79,7 @@
 @r_vm_1  .. . . . ... . ...&rmrr vm=1 %rs2 %rs1 %rd
 @r_vm_0  .. . . . ... . ...&rmrr vm=0 %rs2 %rs1 %rd
 @r2_zimm11 . zimm:11  . ... . ... %rs1 %rd
+@r2_zimm10 .. zimm:10  . ... . ... %rs1 %rd
 @r2_s...   . . ... . ... %rs2 %rs1
 
 @hfence_gvma ... . .   ... . ... %rs2 %rs1
@@ -672,6 +673,7 @@ vsext_vf4   010010 . . 00101 010 . 1010111 
@r2_vm
 vsext_vf8   010010 . . 00011 010 . 1010111 @r2_vm
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm11
+vsetivli11 .. . 111 . 1010111  @r2_zimm10
 vsetvl  100 . . 111 . 1010111  @r
 
 # *** RV32 Zba Standard Extension ***
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index ff8f6df8f7b..e540b5d33c2 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -160,6 +160,26 @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, 
TCGv s2)
 return true;
 }
 
+static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
+{
+TCGv dst;
+
+if (!require_rvv(s) || !has_ext(s, RVV)) {
+return false;
+}
+
+dst = dest_gpr(s, rd);
+
+gen_helper_vsetvl(dst, cpu_env, s1, s2);
+gen_set_gpr(s, rd, dst);
+mark_vs_dirty(s);
+tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn);
+tcg_gen_lookup_and_goto_ptr();
+s->base.is_jmp = DISAS_NORETURN;
+
+return true;
+}
+
 static bool trans_vsetvl(DisasContext *s, arg_vsetvl *a)
 {
 TCGv s2 = get_gpr(s, a->rs2, EXT_ZERO);
@@ -172,6 +192,13 @@ static bool trans_vsetvli(DisasContext *s, arg_vsetvli *a)
 return do_vsetvl(s, a->rd, a->rs1, s2);
 }
 
+static bool trans_vsetivli(DisasContext *s, arg_vsetivli *a)
+{
+TCGv s1 = tcg_const_tl(a->rs1);
+TCGv s2 = tcg_const_tl(a->zimm);
+return do_vsetivli(s, a->rd, s1, s2);
+}
+
 /* vector register offset from env */
 static uint32_t vreg_ofs(DisasContext *s, int reg)
 {
-- 
2.25.1




[PATCH v10 66/77] target/riscv: rvv-1.0: implement vstart CSR

2021-11-28 Thread frank . chang
From: Frank Chang 

* Update and check vstart value for vector instructions.
* Add whole register move instruction helper functions as we have to
  call helper function for case where vstart is not zero.
* Remove probe_pages() calls in vector load/store instructions
  (except fault-only-first loads) to raise the memory access exception
  at the exact processed vector element.

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/csr.c  |   6 +-
 target/riscv/helper.h   |   5 +
 target/riscv/insn_trans/trans_rvv.c.inc |  75 ++---
 target/riscv/translate.c|   6 +-
 target/riscv/vector_helper.c| 210 +++-
 5 files changed, 199 insertions(+), 103 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 3dfbc177381..146447eac5d 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -343,7 +343,11 @@ static RISCVException write_vstart(CPURISCVState *env, int 
csrno,
 #if !defined(CONFIG_USER_ONLY)
 env->mstatus |= MSTATUS_VS;
 #endif
-env->vstart = val;
+/*
+ * The vstart CSR is defined to have only enough writable bits
+ * to hold the largest element index, i.e. lg2(VLEN) bits.
+ */
+env->vstart = val & ~(~0ULL << ctzl(env_archcpu(env)->cfg.vlen));
 return RISCV_EXCP_NONE;
 }
 
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 1a0d817f0f5..a717a87a0e0 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1073,6 +1073,11 @@ DEF_HELPER_6(vcompress_vm_h, void, ptr, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_6(vcompress_vm_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vcompress_vm_d, void, ptr, ptr, ptr, ptr, env, i32)
 
+DEF_HELPER_4(vmv1r_v, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vmv2r_v, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vmv4r_v, void, ptr, ptr, env, i32)
+DEF_HELPER_4(vmv8r_v, void, ptr, ptr, env, i32)
+
 DEF_HELPER_5(vzext_vf2_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vzext_vf2_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vzext_vf2_d, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index be3f9f13275..7589c8ce32a 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -490,7 +490,7 @@ static bool vext_check_sds(DisasContext *s, int vd, int 
vs1, int vs2, int vm)
  */
 static bool vext_check_reduction(DisasContext *s, int vs2)
 {
-return require_align(vs2, s->lmul);
+return require_align(vs2, s->lmul) && (s->vstart == 0);
 }
 
 /*
@@ -2786,7 +2786,8 @@ GEN_MM_TRANS(vmxnor_mm)
 static bool trans_vcpop_m(DisasContext *s, arg_rmr *a)
 {
 if (require_rvv(s) &&
-vext_check_isa_ill(s)) {
+vext_check_isa_ill(s) &&
+s->vstart == 0) {
 TCGv_ptr src2, mask;
 TCGv dst;
 TCGv_i32 desc;
@@ -2817,7 +2818,8 @@ static bool trans_vcpop_m(DisasContext *s, arg_rmr *a)
 static bool trans_vfirst_m(DisasContext *s, arg_rmr *a)
 {
 if (require_rvv(s) &&
-vext_check_isa_ill(s)) {
+vext_check_isa_ill(s) &&
+s->vstart == 0) {
 TCGv_ptr src2, mask;
 TCGv dst;
 TCGv_i32 desc;
@@ -2852,7 +2854,8 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) 
 \
 if (require_rvv(s) &&  \
 vext_check_isa_ill(s) &&   \
 require_vm(a->vm, a->rd) &&\
-(a->rd != a->rs2)) {   \
+(a->rd != a->rs2) &&   \
+(s->vstart == 0)) {\
 uint32_t data = 0; \
 gen_helper_gvec_3_ptr *fn = gen_helper_##NAME; \
 TCGLabel *over = gen_new_label();  \
@@ -2888,7 +2891,8 @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
 vext_check_isa_ill(s) &&
 !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) &&
 require_vm(a->vm, a->rd) &&
-require_align(a->rd, s->lmul)) {
+require_align(a->rd, s->lmul) &&
+(s->vstart == 0)) {
 uint32_t data = 0;
 TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
@@ -3109,6 +3113,7 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
 TCGLabel *over = gen_new_label();
 
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
 t1 = tcg_temp_new_i64();
 
@@ -3161,8 +3166,9 @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f 
*a)

[PATCH v10 73/77] target/riscv: rvv-1.0: add evl parameter to vext_ldst_us()

2021-11-28 Thread frank . chang
From: Frank Chang 

Add supports of Vector unit-stride mask load/store instructions
(vlm.v, vsm.v), which has:
evl (effective vector length) = ceil(env->vl / 8).

The new instructions operate the same as unmasked byte loads and stores.
Add evl parameter to reuse vext_ldst_us().

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 946dca53ffd..83373ca6fc6 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -279,15 +279,15 @@ GEN_VEXT_ST_STRIDE(vsse64_v, int64_t, ste_d)
 /* unmasked unit-stride load and store operation*/
 static void
 vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
- vext_ldst_elem_fn *ldst_elem,
- uint32_t esz, uintptr_t ra, MMUAccessType access_type)
+ vext_ldst_elem_fn *ldst_elem, uint32_t esz, uint32_t evl,
+ uintptr_t ra, MMUAccessType access_type)
 {
 uint32_t i, k;
 uint32_t nf = vext_nf(desc);
 uint32_t max_elems = vext_max_elems(desc, esz);
 
 /* load bytes from guest memory */
-for (i = env->vstart; i < env->vl; i++, env->vstart++) {
+for (i = env->vstart; i < evl; i++, env->vstart++) {
 k = 0;
 while (k < nf) {
 target_ulong addr = base + ((i * nf + k) << esz);
@@ -316,7 +316,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong base,
\
   CPURISCVState *env, uint32_t desc)\
 {   \
 vext_ldst_us(vd, base, env, desc, LOAD_FN,  \
- ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_LOAD);  \
+ ctzl(sizeof(ETYPE)), env->vl, GETPC(), MMU_DATA_LOAD); \
 }
 
 GEN_VEXT_LD_US(vle8_v,  int8_t,  lde_b)
@@ -324,20 +324,20 @@ GEN_VEXT_LD_US(vle16_v, int16_t, lde_h)
 GEN_VEXT_LD_US(vle32_v, int32_t, lde_w)
 GEN_VEXT_LD_US(vle64_v, int64_t, lde_d)
 
-#define GEN_VEXT_ST_US(NAME, ETYPE, STORE_FN)   \
-void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong base, \
- CPURISCVState *env, uint32_t desc) \
-{   \
-uint32_t stride = vext_nf(desc) << ctzl(sizeof(ETYPE)); \
-vext_ldst_stride(vd, v0, base, stride, env, desc, false, STORE_FN,  \
- ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_STORE); \
-}   \
-\
-void HELPER(NAME)(void *vd, void *v0, target_ulong base,\
-  CPURISCVState *env, uint32_t desc)\
-{   \
-vext_ldst_us(vd, base, env, desc, STORE_FN, \
- ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_STORE); \
+#define GEN_VEXT_ST_US(NAME, ETYPE, STORE_FN)\
+void HELPER(NAME##_mask)(void *vd, void *v0, target_ulong base,  \
+ CPURISCVState *env, uint32_t desc)  \
+{\
+uint32_t stride = vext_nf(desc) << ctzl(sizeof(ETYPE));  \
+vext_ldst_stride(vd, v0, base, stride, env, desc, false, STORE_FN,   \
+ ctzl(sizeof(ETYPE)), GETPC(), MMU_DATA_STORE);  \
+}\
+ \
+void HELPER(NAME)(void *vd, void *v0, target_ulong base, \
+  CPURISCVState *env, uint32_t desc) \
+{\
+vext_ldst_us(vd, base, env, desc, STORE_FN,  \
+ ctzl(sizeof(ETYPE)), env->vl, GETPC(), MMU_DATA_STORE); \
 }
 
 GEN_VEXT_ST_US(vse8_v,  int8_t,  ste_b)
-- 
2.25.1




[PATCH v10 67/77] target/riscv: rvv-1.0: trigger illegal instruction exception if frm is not valid

2021-11-28 Thread frank . chang
From: Frank Chang 

If the frm field contains an invalid rounding mode (101-111),
attempting to execute any vector floating-point instruction, even
those that do not depend on the rounding mode, will raise an illegal
instruction exception.

Call gen_set_rm() with DYN rounding mode to check and trigger illegal
instruction exception if frm field contains invalid value at run-time
for vector floating-point instructions.

Signed-off-by: Frank Chang 
Acked-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 7589c8ce32a..53c8573f117 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2374,6 +2374,10 @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
 int rm)
 {
 if (checkfn(s, a)) {
+if (rm != RISCV_FRM_DYN) {
+gen_set_rm(s, RISCV_FRM_DYN);
+}
+
 uint32_t data = 0;
 TCGLabel *over = gen_new_label();
 gen_set_rm(s, rm);
@@ -2459,6 +2463,8 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f 
*a)
 require_rvf(s) &&
 vext_check_isa_ill(s) &&
 require_align(a->rd, s->lmul)) {
+gen_set_rm(s, RISCV_FRM_DYN);
+
 TCGv_i64 t1;
 
 if (s->vl_eq_vlmax) {
@@ -2540,6 +2546,10 @@ static bool opfv_widen_check(DisasContext *s, arg_rmr *a)
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 {  \
 if (opfv_widen_check(s, a)) {  \
+if (FRM != RISCV_FRM_DYN) {\
+gen_set_rm(s, RISCV_FRM_DYN);  \
+}  \
+   \
 uint32_t data = 0; \
 static gen_helper_gvec_3_ptr * const fns[2] = {\
 gen_helper_##HELPER##_h,   \
@@ -2627,6 +2637,10 @@ static bool opfv_narrow_check(DisasContext *s, arg_rmr 
*a)
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 {  \
 if (opfv_narrow_check(s, a)) { \
+if (FRM != RISCV_FRM_DYN) {\
+gen_set_rm(s, RISCV_FRM_DYN);  \
+}  \
+   \
 uint32_t data = 0; \
 static gen_helper_gvec_3_ptr * const fns[2] = {\
 gen_helper_##HELPER##_h,   \
@@ -2668,6 +2682,10 @@ static bool opxfv_narrow_check(DisasContext *s, arg_rmr 
*a)
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 {  \
 if (opxfv_narrow_check(s, a)) {\
+if (FRM != RISCV_FRM_DYN) {\
+gen_set_rm(s, RISCV_FRM_DYN);  \
+}  \
+   \
 uint32_t data = 0; \
 static gen_helper_gvec_3_ptr * const fns[3] = {\
 gen_helper_##HELPER##_b,   \
@@ -3138,6 +3156,8 @@ static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s 
*a)
 if (require_rvv(s) &&
 require_rvf(s) &&
 vext_check_isa_ill(s)) {
+gen_set_rm(s, RISCV_FRM_DYN);
+
 unsigned int ofs = (8 << s->sew);
 unsigned int len = 64 - ofs;
 TCGv_i64 t_nan;
@@ -3162,6 +3182,8 @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f 
*a)
 if (require_rvv(s) &&
 require_rvf(s) &&
 vext_check_isa_ill(s)) {
+gen_set_rm(s, RISCV_FRM_DYN);
+
 /* The instructions ignore LMUL and vector register group. */
 TCGv_i64 t1;
 TCGLabel *over = gen_new_label();
-- 
2.25.1




[PATCH v10 77/77] target/riscv: rvv-1.0: Add ELEN checks for widening and narrowing instructions

2021-11-28 Thread frank . chang
From: Frank Chang 

SEW has the limitation which cannot exceed ELEN.

Widening instructions have a destination group with EEW = 2*SEW
and narrowing instructions have a source operand with EEW = 2*SEW.
Both of the instructions have the limitation of: 2*SEW <= ELEN.

Signed-off-by: Frank Chang 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 17 +++--
 target/riscv/translate.c|  2 ++
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 47eb3119cbe..5e3f7fdb77c 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -386,9 +386,10 @@ static bool vext_check_mss(DisasContext *s, int vd, int 
vs1, int vs2)
  *  can not be greater than 8 vector registers (Section 5.2):
  *  => LMUL < 8.
  *  => SEW < 64.
- *   2. Destination vector register number is multiples of 2 * LMUL.
+ *   2. Double-width SEW cannot greater than ELEN.
+ *   3. Destination vector register number is multiples of 2 * LMUL.
  *  (Section 3.4.2)
- *   3. Destination vector register group for a masked vector
+ *   4. Destination vector register group for a masked vector
  *  instruction cannot overlap the source mask register (v0).
  *  (Section 5.3)
  */
@@ -396,6 +397,7 @@ static bool vext_wide_check_common(DisasContext *s, int vd, 
int vm)
 {
 return (s->lmul <= 2) &&
(s->sew < MO_64) &&
+   ((s->sew + 1) <= (s->elen >> 4)) &&
require_align(vd, s->lmul + 1) &&
require_vm(vm, vd);
 }
@@ -409,11 +411,12 @@ static bool vext_wide_check_common(DisasContext *s, int 
vd, int vm)
  *  can not be greater than 8 vector registers (Section 5.2):
  *  => LMUL < 8.
  *  => SEW < 64.
- *   2. Source vector register number is multiples of 2 * LMUL.
+ *   2. Double-width SEW cannot greater than ELEN.
+ *   3. Source vector register number is multiples of 2 * LMUL.
  *  (Section 3.4.2)
- *   3. Destination vector register number is multiples of LMUL.
+ *   4. Destination vector register number is multiples of LMUL.
  *  (Section 3.4.2)
- *   4. Destination vector register group for a masked vector
+ *   5. Destination vector register group for a masked vector
  *  instruction cannot overlap the source mask register (v0).
  *  (Section 5.3)
  */
@@ -422,6 +425,7 @@ static bool vext_narrow_check_common(DisasContext *s, int 
vd, int vs2,
 {
 return (s->lmul <= 2) &&
(s->sew < MO_64) &&
+   ((s->sew + 1) <= (s->elen >> 4)) &&
require_align(vs2, s->lmul + 1) &&
require_align(vd, s->lmul) &&
require_vm(vm, vd);
@@ -2806,7 +2810,8 @@ GEN_OPIVV_TRANS(vredxor_vs, reduction_check)
 /* Vector Widening Integer Reduction Instructions */
 static bool reduction_widen_check(DisasContext *s, arg_rmrr *a)
 {
-return reduction_check(s, a) && (s->sew < MO_64);
+return reduction_check(s, a) && (s->sew < MO_64) &&
+   ((s->sew + 1) <= (s->elen >> 4));
 }
 
 GEN_OPIVV_WIDEN_TRANS(vwredsum_vs, reduction_widen_check)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 68edaaf6ac7..5df6c0d800b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -96,6 +96,7 @@ typedef struct DisasContext {
 int8_t lmul;
 uint8_t sew;
 uint16_t vlen;
+uint16_t elen;
 target_ulong vstart;
 bool vl_eq_vlmax;
 uint8_t ntemp;
@@ -705,6 +706,7 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->ext_zfh = cpu->cfg.ext_zfh;
 ctx->ext_zfhmin = cpu->cfg.ext_zfhmin;
 ctx->vlen = cpu->cfg.vlen;
+ctx->elen = cpu->cfg.elen;
 ctx->mstatus_hs_fs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_FS);
 ctx->mstatus_hs_vs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_VS);
 ctx->hlsx = FIELD_EX32(tb_flags, TB_FLAGS, HLSX);
-- 
2.25.1




[PATCH v10 68/77] target/riscv: gdb: support vector registers for rv64 & rv32

2021-11-28 Thread frank . chang
From: Hsiangkai Wang 

Signed-off-by: Hsiangkai Wang 
Signed-off-by: Greentime Hu 
Signed-off-by: Frank Chang 
Acked-by: Alistair Francis 
---
 target/riscv/cpu.c |   2 +
 target/riscv/cpu.h |   1 +
 target/riscv/gdbstub.c | 184 +
 3 files changed, 187 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c760ea08621..860f356bd99 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -675,6 +675,8 @@ static const char *riscv_gdb_get_dynamic_xml(CPUState *cs, 
const char *xmlname)
 
 if (strcmp(xmlname, "riscv-csr.xml") == 0) {
 return cpu->dyn_csr_xml;
+} else if (strcmp(xmlname, "riscv-vector.xml") == 0) {
+return cpu->dyn_vreg_xml;
 }
 
 return NULL;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5d93ccdfa71..dc10f27093b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -291,6 +291,7 @@ struct RISCVCPU {
 CPURISCVState env;
 
 char *dyn_csr_xml;
+char *dyn_vreg_xml;
 
 /* Configuration Settings */
 struct {
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index 23429179e2e..881ab333924 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -20,6 +20,32 @@
 #include "exec/gdbstub.h"
 #include "cpu.h"
 
+struct TypeSize {
+const char *gdb_type;
+const char *id;
+int size;
+const char suffix;
+};
+
+static const struct TypeSize vec_lanes[] = {
+/* quads */
+{ "uint128", "quads", 128, 'q' },
+/* 64 bit */
+{ "uint64", "longs", 64, 'l' },
+/* 32 bit */
+{ "uint32", "words", 32, 'w' },
+/* 16 bit */
+{ "uint16", "shorts", 16, 's' },
+/*
+ * TODO: currently there is no reliable way of telling
+ * if the remote gdb actually understands ieee_half so
+ * we don't expose it in the target description for now.
+ * { "ieee_half", 16, 'h', 'f' },
+ */
+/* bytes */
+{ "uint8", "bytes", 8, 'b' },
+};
+
 int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
 {
 RISCVCPU *cpu = RISCV_CPU(cs);
@@ -101,6 +127,96 @@ static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t 
*mem_buf, int n)
 return 0;
 }
 
+/*
+ * Convert register index number passed by GDB to the correspond
+ * vector CSR number. Vector CSRs are defined after vector registers
+ * in dynamic generated riscv-vector.xml, thus the starting register index
+ * of vector CSRs is 32.
+ * Return 0 if register index number is out of range.
+ */
+static int riscv_gdb_vector_csrno(int num_regs)
+{
+/*
+ * The order of vector CSRs in the switch case
+ * should match with the order defined in csr_ops[].
+ */
+switch (num_regs) {
+case 32:
+return CSR_VSTART;
+case 33:
+return CSR_VXSAT;
+case 34:
+return CSR_VXRM;
+case 35:
+return CSR_VCSR;
+case 36:
+return CSR_VL;
+case 37:
+return CSR_VTYPE;
+case 38:
+return CSR_VLENB;
+default:
+/* Unknown register. */
+return 0;
+}
+}
+
+static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n)
+{
+uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
+if (n < 32) {
+int i;
+int cnt = 0;
+for (i = 0; i < vlenb; i += 8) {
+cnt += gdb_get_reg64(buf,
+ env->vreg[(n * vlenb + i) / 8]);
+}
+return cnt;
+}
+
+int csrno = riscv_gdb_vector_csrno(n);
+
+if (!csrno) {
+return 0;
+}
+
+target_ulong val = 0;
+int result = riscv_csrrw_debug(env, csrno, &val, 0, 0);
+
+if (result == 0) {
+return gdb_get_regl(buf, val);
+}
+
+return 0;
+}
+
+static int riscv_gdb_set_vector(CPURISCVState *env, uint8_t *mem_buf, int n)
+{
+uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
+if (n < 32) {
+int i;
+for (i = 0; i < vlenb; i += 8) {
+env->vreg[(n * vlenb + i) / 8] = ldq_p(mem_buf + i);
+}
+return vlenb;
+}
+
+int csrno = riscv_gdb_vector_csrno(n);
+
+if (!csrno) {
+return 0;
+}
+
+target_ulong val = ldtul_p(mem_buf);
+int result = riscv_csrrw_debug(env, csrno, NULL, val, -1);
+
+if (result == 0) {
+return sizeof(target_ulong);
+}
+
+return 0;
+}
+
 static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n)
 {
 if (n < CSR_TABLE_SIZE) {
@@ -187,6 +303,68 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int 
base_reg)
 return CSR_TABLE_SIZE;
 }
 
+static int ricsv_gen_dynamic_vector_xml(CPUState *cs, int base_reg)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+GString *s = g_string_new(NULL);
+g_autop

[PATCH v10 69/77] target/riscv: rvv-1.0: floating-point reciprocal square-root estimate instruction

2021-11-28 Thread frank . chang
From: Frank Chang 

Implement the floating-point reciprocal square-root estimate to 7 bits
instruction.

Signed-off-by: Frank Chang 
---
 target/riscv/helper.h   |   4 +
 target/riscv/insn32.decode  |   1 +
 target/riscv/insn_trans/trans_rvv.c.inc |   1 +
 target/riscv/vector_helper.c| 183 
 4 files changed, 189 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index a717a87a0e0..bdf06dfb24d 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -841,6 +841,10 @@ DEF_HELPER_5(vfsqrt_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfsqrt_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfsqrt_v_d, void, ptr, ptr, ptr, env, i32)
 
+DEF_HELPER_5(vfrsqrt7_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfrsqrt7_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfrsqrt7_v_d, void, ptr, ptr, ptr, env, i32)
+
 DEF_HELPER_6(vfmin_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmin_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmin_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index c4fdc76a269..6e5f288943a 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -560,6 +560,7 @@ vfwmsac_vf  10 . . . 101 . 1010111 @r_vm
 vfwnmsac_vv 11 . . . 001 . 1010111 @r_vm
 vfwnmsac_vf 11 . . . 101 . 1010111 @r_vm
 vfsqrt_v010011 . . 0 001 . 1010111 @r2_vm
+vfrsqrt7_v  010011 . . 00100 001 . 1010111 @r2_vm
 vfmin_vv000100 . . . 001 . 1010111 @r_vm
 vfmin_vf000100 . . . 101 . 1010111 @r_vm
 vfmax_vv000110 . . . 001 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 53c8573f117..8fe718610a9 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2407,6 +2407,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 }
 
 GEN_OPFV_TRANS(vfsqrt_v, opfv_check, RISCV_FRM_DYN)
+GEN_OPFV_TRANS(vfrsqrt7_v, opfv_check, RISCV_FRM_DYN)
 
 /* Vector Floating-Point MIN/MAX Instructions */
 GEN_OPFVV_TRANS(vfmin_vv, opfvv_check)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 22848d6b683..d5f3229bcb4 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -18,6 +18,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/host-utils.h"
+#include "qemu/bitops.h"
 #include "cpu.h"
 #include "exec/memop.h"
 #include "exec/exec-all.h"
@@ -3404,6 +3405,188 @@ GEN_VEXT_V_ENV(vfsqrt_v_h, 2, 2)
 GEN_VEXT_V_ENV(vfsqrt_v_w, 4, 4)
 GEN_VEXT_V_ENV(vfsqrt_v_d, 8, 8)
 
+/*
+ * Vector Floating-Point Reciprocal Square-Root Estimate Instruction
+ *
+ * Adapted from riscv-v-spec recip.c:
+ * https://github.com/riscv/riscv-v-spec/blob/master/recip.c
+ */
+static uint64_t frsqrt7(uint64_t f, int exp_size, int frac_size)
+{
+uint64_t sign = extract64(f, frac_size + exp_size, 1);
+uint64_t exp = extract64(f, frac_size, exp_size);
+uint64_t frac = extract64(f, 0, frac_size);
+
+const uint8_t lookup_table[] = {
+52, 51, 50, 48, 47, 46, 44, 43,
+42, 41, 40, 39, 38, 36, 35, 34,
+33, 32, 31, 30, 30, 29, 28, 27,
+26, 25, 24, 23, 23, 22, 21, 20,
+19, 19, 18, 17, 16, 16, 15, 14,
+14, 13, 12, 12, 11, 10, 10, 9,
+9, 8, 7, 7, 6, 6, 5, 4,
+4, 3, 3, 2, 2, 1, 1, 0,
+127, 125, 123, 121, 119, 118, 116, 114,
+113, 111, 109, 108, 106, 105, 103, 102,
+100, 99, 97, 96, 95, 93, 92, 91,
+90, 88, 87, 86, 85, 84, 83, 82,
+80, 79, 78, 77, 76, 75, 74, 73,
+72, 71, 70, 70, 69, 68, 67, 66,
+65, 64, 63, 63, 62, 61, 60, 59,
+59, 58, 57, 56, 56, 55, 54, 53
+};
+const int precision = 7;
+
+if (exp == 0 && frac != 0) { /* subnormal */
+/* Normalize the subnormal. */
+while (extract64(frac, frac_size - 1, 1) == 0) {
+exp--;
+frac <<= 1;
+}
+
+frac = (frac << 1) & MAKE_64BIT_MASK(0, frac_size);
+}
+
+int idx = ((exp & 1) << (precision - 1)) |
+(frac >> (frac_size - precision + 1));
+uint64_t out_frac = (uint64_t)(lookup_table[idx]) <<
+(frac_size - precision);
+uint64_t out_exp = (3 * MAKE_64BIT_MASK(0, exp_size - 1) + ~exp) / 2;
+
+uint64_t val = 0;
+val = deposit64(val, 0, frac_size, out_frac);
+val = deposit64(val, frac_size, exp_size, out_exp);
+val = deposit64(val, frac_size + exp_size, 1, sign);
+return val;
+}
+
+static float16 frsqrt7_h(float16 f, float_status *s)
+{
+int exp_size = 5, frac_size = 10;
+bool sign = float16_is_neg(f);
+
+/*
+ * frsqrt7(sNaN) = ca

[PATCH v10 70/77] target/riscv: rvv-1.0: floating-point reciprocal estimate instruction

2021-11-28 Thread frank . chang
From: Frank Chang 

Implement the floating-point reciprocal estimate to 7 bits instruction.

Signed-off-by: Frank Chang 
---
 target/riscv/helper.h   |   4 +
 target/riscv/insn32.decode  |   1 +
 target/riscv/insn_trans/trans_rvv.c.inc |   1 +
 target/riscv/vector_helper.c| 191 
 4 files changed, 197 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index bdf06dfb24d..ab283d12b79 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -845,6 +845,10 @@ DEF_HELPER_5(vfrsqrt7_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfrsqrt7_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfrsqrt7_v_d, void, ptr, ptr, ptr, env, i32)
 
+DEF_HELPER_5(vfrec7_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfrec7_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfrec7_v_d, void, ptr, ptr, ptr, env, i32)
+
 DEF_HELPER_6(vfmin_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmin_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmin_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 6e5f288943a..952768f8ded 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -561,6 +561,7 @@ vfwnmsac_vv 11 . . . 001 . 1010111 @r_vm
 vfwnmsac_vf 11 . . . 101 . 1010111 @r_vm
 vfsqrt_v010011 . . 0 001 . 1010111 @r2_vm
 vfrsqrt7_v  010011 . . 00100 001 . 1010111 @r2_vm
+vfrec7_v010011 . . 00101 001 . 1010111 @r2_vm
 vfmin_vv000100 . . . 001 . 1010111 @r_vm
 vfmin_vf000100 . . . 101 . 1010111 @r_vm
 vfmax_vv000110 . . . 001 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 8fe718610a9..ff8f6df8f7b 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2408,6 +2408,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 
 GEN_OPFV_TRANS(vfsqrt_v, opfv_check, RISCV_FRM_DYN)
 GEN_OPFV_TRANS(vfrsqrt7_v, opfv_check, RISCV_FRM_DYN)
+GEN_OPFV_TRANS(vfrec7_v, opfv_check, RISCV_FRM_DYN)
 
 /* Vector Floating-Point MIN/MAX Instructions */
 GEN_OPFVV_TRANS(vfmin_vv, opfvv_check)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index d5f3229bcb4..946dca53ffd 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3587,6 +3587,197 @@ GEN_VEXT_V_ENV(vfrsqrt7_v_h, 2, 2)
 GEN_VEXT_V_ENV(vfrsqrt7_v_w, 4, 4)
 GEN_VEXT_V_ENV(vfrsqrt7_v_d, 8, 8)
 
+/*
+ * Vector Floating-Point Reciprocal Estimate Instruction
+ *
+ * Adapted from riscv-v-spec recip.c:
+ * https://github.com/riscv/riscv-v-spec/blob/master/recip.c
+ */
+static uint64_t frec7(uint64_t f, int exp_size, int frac_size,
+  float_status *s)
+{
+uint64_t sign = extract64(f, frac_size + exp_size, 1);
+uint64_t exp = extract64(f, frac_size, exp_size);
+uint64_t frac = extract64(f, 0, frac_size);
+
+const uint8_t lookup_table[] = {
+127, 125, 123, 121, 119, 117, 116, 114,
+112, 110, 109, 107, 105, 104, 102, 100,
+99, 97, 96, 94, 93, 91, 90, 88,
+87, 85, 84, 83, 81, 80, 79, 77,
+76, 75, 74, 72, 71, 70, 69, 68,
+66, 65, 64, 63, 62, 61, 60, 59,
+58, 57, 56, 55, 54, 53, 52, 51,
+50, 49, 48, 47, 46, 45, 44, 43,
+42, 41, 40, 40, 39, 38, 37, 36,
+35, 35, 34, 33, 32, 31, 31, 30,
+29, 28, 28, 27, 26, 25, 25, 24,
+23, 23, 22, 21, 21, 20, 19, 19,
+18, 17, 17, 16, 15, 15, 14, 14,
+13, 12, 12, 11, 11, 10, 9, 9,
+8, 8, 7, 7, 6, 5, 5, 4,
+4, 3, 3, 2, 2, 1, 1, 0
+};
+const int precision = 7;
+
+if (exp == 0 && frac != 0) { /* subnormal */
+/* Normalize the subnormal. */
+while (extract64(frac, frac_size - 1, 1) == 0) {
+exp--;
+frac <<= 1;
+}
+
+frac = (frac << 1) & MAKE_64BIT_MASK(0, frac_size);
+
+if (exp != 0 && exp != UINT64_MAX) {
+/*
+ * Overflow to inf or max value of same sign,
+ * depending on sign and rounding mode.
+ */
+s->float_exception_flags |= (float_flag_inexact |
+ float_flag_overflow);
+
+if ((s->float_rounding_mode == float_round_to_zero) ||
+((s->float_rounding_mode == float_round_down) && !sign) ||
+((s->float_rounding_mode == float_round_up) && sign)) {
+/* Return greatest/negative finite value. */
+return (sign << (exp_size + frac_size)) |
+(MAKE_64BIT_MASK(frac_size, exp_size) - 1);
+} else {
+/* Return +-inf. */
+return (sign << 

  1   2   3   4   5   6   7   8   9   10   >