From 1c69cb4e7552be2984ba67861f35938ef8024f0c Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Tue, 21 Jun 2022 14:34:29 -0300 Subject: [PATCH 01/34] ppc/pnv: move root port attach to pnv_phb4_realize() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Creating a root port is something related to the PHB, not the PEC. It also makes the logic more in line with what pnv-phb3 does. Reviewed-by: Frederic Barrat Reviewed-by: Cédric Le Goater Signed-off-by: Daniel Henrique Barboza Message-Id: <20220621173436.165912-2-danielhb413@gmail.com> --- hw/pci-host/pnv_phb4.c | 4 ++++ hw/pci-host/pnv_phb4_pec.c | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c index 6594016121..23ad8de7ee 100644 --- a/hw/pci-host/pnv_phb4.c +++ b/hw/pci-host/pnv_phb4.c @@ -1547,6 +1547,7 @@ static void pnv_phb4_instance_init(Object *obj) static void pnv_phb4_realize(DeviceState *dev, Error **errp) { PnvPHB4 *phb = PNV_PHB4(dev); + PnvPhb4PecClass *pecc = PNV_PHB4_PEC_GET_CLASS(phb->pec); PCIHostState *pci = PCI_HOST_BRIDGE(dev); XiveSource *xsrc = &phb->xsrc; int nr_irqs; @@ -1583,6 +1584,9 @@ static void pnv_phb4_realize(DeviceState *dev, Error **errp) pci_setup_iommu(pci->bus, pnv_phb4_dma_iommu, phb); pci->bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE; + /* Add a single Root port if running with defaults */ + pnv_phb_attach_root_port(pci, pecc->rp_model); + /* Setup XIVE Source */ if (phb->big_phb) { nr_irqs = PNV_PHB4_MAX_INTs; diff --git a/hw/pci-host/pnv_phb4_pec.c b/hw/pci-host/pnv_phb4_pec.c index 8b7e823fa5..c9aaf1c28e 100644 --- a/hw/pci-host/pnv_phb4_pec.c +++ b/hw/pci-host/pnv_phb4_pec.c @@ -130,9 +130,6 @@ static void pnv_pec_default_phb_realize(PnvPhb4PecState *pec, if (!sysbus_realize(SYS_BUS_DEVICE(phb), errp)) { return; } - - /* Add a single Root port if running with defaults */ - pnv_phb_attach_root_port(PCI_HOST_BRIDGE(phb), pecc->rp_model); } static void pnv_pec_realize(DeviceState *dev, Error **errp) From 8625164a3866064da0e37aabef7cab40311fd929 Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Tue, 21 Jun 2022 14:34:30 -0300 Subject: [PATCH 02/34] ppc/pnv: attach phb3/phb4 root ports in QOM tree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At this moment we leave the pnv-phb3(4)-root-port unattached in QOM: /unattached (container) (...) /device[2] (pnv-phb3-root-port) /bus master container[0] (memory-region) /bus master[0] (memory-region) /pci_bridge_io[0] (memory-region) /pci_bridge_io[1] (memory-region) /pci_bridge_mem[0] (memory-region) /pci_bridge_pci[0] (memory-region) /pci_bridge_pref_mem[0] (memory-region) /pci_bridge_vga_io_hi[0] (memory-region) /pci_bridge_vga_io_lo[0] (memory-region) /pci_bridge_vga_mem[0] (memory-region) /pcie.0 (PCIE) Let's make changes in pnv_phb_attach_root_port() to attach the created root ports to its corresponding PHB. This is the result afterwards: /pnv-phb3[0] (pnv-phb3) /lsi (ics) /msi (phb3-msi) /msi32[0] (memory-region) /msi64[0] (memory-region) /pbcq (pnv-pbcq) (...) /phb3_iommu[0] (pnv-phb3-iommu-memory-region) /pnv-phb3-root.0 (pnv-phb3-root) /pnv-phb3-root-port[0] (pnv-phb3-root-port) /bus master container[0] (memory-region) /bus master[0] (memory-region) /pci_bridge_io[0] (memory-region) /pci_bridge_io[1] (memory-region) /pci_bridge_mem[0] (memory-region) /pci_bridge_pci[0] (memory-region) /pci_bridge_pref_mem[0] (memory-region) /pci_bridge_vga_io_hi[0] (memory-region) /pci_bridge_vga_io_lo[0] (memory-region) /pci_bridge_vga_mem[0] (memory-region) /pcie.0 (PCIE) Reviewed-by: Frederic Barrat Reviewed-by: Cédric Le Goater Signed-off-by: Daniel Henrique Barboza Message-Id: <20220621173436.165912-3-danielhb413@gmail.com> --- hw/pci-host/pnv_phb3.c | 2 +- hw/pci-host/pnv_phb4.c | 2 +- hw/ppc/pnv.c | 7 ++++++- include/hw/ppc/pnv.h | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c index 26ac9b7123..4ba660f8b9 100644 --- a/hw/pci-host/pnv_phb3.c +++ b/hw/pci-host/pnv_phb3.c @@ -1052,7 +1052,7 @@ static void pnv_phb3_realize(DeviceState *dev, Error **errp) pci_setup_iommu(pci->bus, pnv_phb3_dma_iommu, phb); - pnv_phb_attach_root_port(PCI_HOST_BRIDGE(phb), TYPE_PNV_PHB3_ROOT_PORT); + pnv_phb_attach_root_port(pci, TYPE_PNV_PHB3_ROOT_PORT, phb->phb_id); } void pnv_phb3_update_regions(PnvPHB3 *phb) diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c index 23ad8de7ee..ffd9d8a947 100644 --- a/hw/pci-host/pnv_phb4.c +++ b/hw/pci-host/pnv_phb4.c @@ -1585,7 +1585,7 @@ static void pnv_phb4_realize(DeviceState *dev, Error **errp) pci->bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE; /* Add a single Root port if running with defaults */ - pnv_phb_attach_root_port(pci, pecc->rp_model); + pnv_phb_attach_root_port(pci, pecc->rp_model, phb->phb_id); /* Setup XIVE Source */ if (phb->big_phb) { diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 7c08a78d6c..40e0cbd84d 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1190,9 +1190,14 @@ static void pnv_chip_icp_realize(Pnv8Chip *chip8, Error **errp) } /* Attach a root port device */ -void pnv_phb_attach_root_port(PCIHostState *pci, const char *name) +void pnv_phb_attach_root_port(PCIHostState *pci, const char *name, int index) { PCIDevice *root = pci_new(PCI_DEVFN(0, 0), name); + g_autofree char *default_id = g_strdup_printf("%s[%d]", name, index); + const char *dev_id = DEVICE(root)->id; + + object_property_add_child(OBJECT(pci->bus), dev_id ? dev_id : default_id, + OBJECT(root)); pci_realize_and_unref(root, pci->bus, &error_fatal); } diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index 86cb7d7f97..033890a23f 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -189,7 +189,7 @@ DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER10, TYPE_PNV_CHIP_POWER10) PowerPCCPU *pnv_chip_find_cpu(PnvChip *chip, uint32_t pir); -void pnv_phb_attach_root_port(PCIHostState *pci, const char *name); +void pnv_phb_attach_root_port(PCIHostState *pci, const char *name, int index); #define TYPE_PNV_MACHINE MACHINE_TYPE_NAME("powernv") typedef struct PnvMachineClass PnvMachineClass; From 792e8bb629c6c11e99b092d10790a6d027d7f2d2 Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Tue, 21 Jun 2022 14:34:31 -0300 Subject: [PATCH 03/34] ppc/pnv: assign pnv-phb-root-port chassis/slot earlier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is not advisable to execute an object_dynamic_cast() to poke into bus->qbus.parent and follow it up with a C cast into the PnvPHB type we think we got. In fact this is not needed. There is nothing sophisticated being done with the PHB object retrieved during root_port_realize() for both PHB3 and PHB4. We're retrieving a PHB reference just to access phb->chip_id and phb->phb_id and use them to define the chassis/slot of the root port. phb->phb_id is already being passed to pnv_phb_attach_root_port() via the 'index' parameter. Let's also add a 'chip_id' parameter to this function and assign chassis and slot right there. This will spare us from the hassle of accessing the PHB object inside realize(). Signed-off-by: Daniel Henrique Barboza Reviewed-by: Cédric Le Goater Reviewed-by: Frederic Barrat Message-Id: <20220621173436.165912-4-danielhb413@gmail.com> --- hw/pci-host/pnv_phb3.c | 18 ++---------------- hw/pci-host/pnv_phb4.c | 18 ++---------------- hw/ppc/pnv.c | 15 +++++++++++++-- include/hw/ppc/pnv.h | 3 ++- 4 files changed, 19 insertions(+), 35 deletions(-) diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c index 4ba660f8b9..afe5698167 100644 --- a/hw/pci-host/pnv_phb3.c +++ b/hw/pci-host/pnv_phb3.c @@ -1052,7 +1052,8 @@ static void pnv_phb3_realize(DeviceState *dev, Error **errp) pci_setup_iommu(pci->bus, pnv_phb3_dma_iommu, phb); - pnv_phb_attach_root_port(pci, TYPE_PNV_PHB3_ROOT_PORT, phb->phb_id); + pnv_phb_attach_root_port(pci, TYPE_PNV_PHB3_ROOT_PORT, + phb->phb_id, phb->chip_id); } void pnv_phb3_update_regions(PnvPHB3 *phb) @@ -1139,23 +1140,8 @@ static void pnv_phb3_root_port_realize(DeviceState *dev, Error **errp) { PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev); PCIDevice *pci = PCI_DEVICE(dev); - PCIBus *bus = pci_get_bus(pci); - PnvPHB3 *phb = NULL; Error *local_err = NULL; - phb = (PnvPHB3 *) object_dynamic_cast(OBJECT(bus->qbus.parent), - TYPE_PNV_PHB3); - - if (!phb) { - error_setg(errp, -"pnv_phb3_root_port devices must be connected to pnv-phb3 buses"); - return; - } - - /* Set unique chassis/slot values for the root port */ - qdev_prop_set_uint8(&pci->qdev, "chassis", phb->chip_id); - qdev_prop_set_uint16(&pci->qdev, "slot", phb->phb_id); - rpc->parent_realize(dev, &local_err); if (local_err) { error_propagate(errp, local_err); diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c index ffd9d8a947..725b3d740b 100644 --- a/hw/pci-host/pnv_phb4.c +++ b/hw/pci-host/pnv_phb4.c @@ -1585,7 +1585,8 @@ static void pnv_phb4_realize(DeviceState *dev, Error **errp) pci->bus->flags |= PCI_BUS_EXTENDED_CONFIG_SPACE; /* Add a single Root port if running with defaults */ - pnv_phb_attach_root_port(pci, pecc->rp_model, phb->phb_id); + pnv_phb_attach_root_port(pci, pecc->rp_model, + phb->phb_id, phb->chip_id); /* Setup XIVE Source */ if (phb->big_phb) { @@ -1781,23 +1782,8 @@ static void pnv_phb4_root_port_reset(DeviceState *dev) static void pnv_phb4_root_port_realize(DeviceState *dev, Error **errp) { PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev); - PCIDevice *pci = PCI_DEVICE(dev); - PCIBus *bus = pci_get_bus(pci); - PnvPHB4 *phb = NULL; Error *local_err = NULL; - phb = (PnvPHB4 *) object_dynamic_cast(OBJECT(bus->qbus.parent), - TYPE_PNV_PHB4); - - if (!phb) { - error_setg(errp, "%s must be connected to pnv-phb4 buses", dev->id); - return; - } - - /* Set unique chassis/slot values for the root port */ - qdev_prop_set_uint8(&pci->qdev, "chassis", phb->chip_id); - qdev_prop_set_uint16(&pci->qdev, "slot", phb->phb_id); - rpc->parent_realize(dev, &local_err); if (local_err) { error_propagate(errp, local_err); diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 40e0cbd84d..c5e63bede7 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1189,8 +1189,15 @@ static void pnv_chip_icp_realize(Pnv8Chip *chip8, Error **errp) } } -/* Attach a root port device */ -void pnv_phb_attach_root_port(PCIHostState *pci, const char *name, int index) +/* + * Attach a root port device. + * + * 'index' will be used both as a PCIE slot value and to calculate + * QOM id. 'chip_id' is going to be used as PCIE chassis for the + * root port. + */ +void pnv_phb_attach_root_port(PCIHostState *pci, const char *name, + int index, int chip_id) { PCIDevice *root = pci_new(PCI_DEVFN(0, 0), name); g_autofree char *default_id = g_strdup_printf("%s[%d]", name, index); @@ -1199,6 +1206,10 @@ void pnv_phb_attach_root_port(PCIHostState *pci, const char *name, int index) object_property_add_child(OBJECT(pci->bus), dev_id ? dev_id : default_id, OBJECT(root)); + /* Set unique chassis/slot values for the root port */ + qdev_prop_set_uint8(DEVICE(root), "chassis", chip_id); + qdev_prop_set_uint16(DEVICE(root), "slot", index); + pci_realize_and_unref(root, pci->bus, &error_fatal); } diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index 033890a23f..b991194223 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -189,7 +189,8 @@ DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER10, TYPE_PNV_CHIP_POWER10) PowerPCCPU *pnv_chip_find_cpu(PnvChip *chip, uint32_t pir); -void pnv_phb_attach_root_port(PCIHostState *pci, const char *name, int index); +void pnv_phb_attach_root_port(PCIHostState *pci, const char *name, + int index, int chip_id); #define TYPE_PNV_MACHINE MACHINE_TYPE_NAME("powernv") typedef struct PnvMachineClass PnvMachineClass; From da6be50136800dee59e22ac95a6ee10c154e1210 Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Tue, 21 Jun 2022 14:34:32 -0300 Subject: [PATCH 04/34] ppc/pnv: make pnv_ics_get() use the chip8->phbs[] array MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function is working today by getting all the child objects of the chip, interacting with each of them to check whether the child is a PHB, and then doing what needs to be done. We have all the chip PHBs in the phbs[] array so interacting with all child objects is unneeded. Open code pnv_ics_get_phb_ics() into pnv_ics_get() and remove both pnv_ics_get_phb_ics() and the ForeachPhb3Args struct. Reviewed-by: Cédric Le Goater Reviewed-by: Frederic Barrat Signed-off-by: Daniel Henrique Barboza Message-Id: <20220621173436.165912-5-danielhb413@gmail.com> --- hw/ppc/pnv.c | 38 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index c5e63bede7..e6cea789f8 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1950,44 +1950,28 @@ PowerPCCPU *pnv_chip_find_cpu(PnvChip *chip, uint32_t pir) return NULL; } -typedef struct ForeachPhb3Args { - int irq; - ICSState *ics; -} ForeachPhb3Args; - -static int pnv_ics_get_child(Object *child, void *opaque) -{ - ForeachPhb3Args *args = opaque; - PnvPHB3 *phb3 = (PnvPHB3 *) object_dynamic_cast(child, TYPE_PNV_PHB3); - - if (phb3) { - if (ics_valid_irq(&phb3->lsis, args->irq)) { - args->ics = &phb3->lsis; - } - if (ics_valid_irq(ICS(&phb3->msis), args->irq)) { - args->ics = ICS(&phb3->msis); - } - } - return args->ics ? 1 : 0; -} - static ICSState *pnv_ics_get(XICSFabric *xi, int irq) { PnvMachineState *pnv = PNV_MACHINE(xi); - ForeachPhb3Args args = { irq, NULL }; - int i; + int i, j; for (i = 0; i < pnv->num_chips; i++) { - PnvChip *chip = pnv->chips[i]; Pnv8Chip *chip8 = PNV8_CHIP(pnv->chips[i]); if (ics_valid_irq(&chip8->psi.ics, irq)) { return &chip8->psi.ics; } - object_child_foreach(OBJECT(chip), pnv_ics_get_child, &args); - if (args.ics) { - return args.ics; + for (j = 0; j < chip8->num_phbs; j++) { + PnvPHB3 *phb3 = &chip8->phbs[j]; + + if (ics_valid_irq(&phb3->lsis, irq)) { + return &phb3->lsis; + } + + if (ics_valid_irq(ICS(&phb3->msis), irq)) { + return ICS(&phb3->msis); + } } } return NULL; From ca45948991c1d22b30197cc741799f2543d42c37 Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Tue, 21 Jun 2022 14:34:33 -0300 Subject: [PATCH 05/34] ppc/pnv: make pnv_ics_resend() use chip8->phbs[] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pnv_ics_resend() is scrolling through all the child objects of the chip to search for the PHBs. It's faster and simpler to just use the phbs[] array. pnv_ics_resend_child() was folded into pnv_ics_resend() since it's too simple to justify its own function. Reviewed-by: Cédric Le Goater Reviewed-by: Frederic Barrat Signed-off-by: Daniel Henrique Barboza Message-Id: <20220621173436.165912-6-danielhb413@gmail.com> --- hw/ppc/pnv.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index e6cea789f8..74a6c88dd2 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1990,28 +1990,22 @@ PnvChip *pnv_get_chip(PnvMachineState *pnv, uint32_t chip_id) return NULL; } -static int pnv_ics_resend_child(Object *child, void *opaque) -{ - PnvPHB3 *phb3 = (PnvPHB3 *) object_dynamic_cast(child, TYPE_PNV_PHB3); - - if (phb3) { - ics_resend(&phb3->lsis); - ics_resend(ICS(&phb3->msis)); - } - return 0; -} - static void pnv_ics_resend(XICSFabric *xi) { PnvMachineState *pnv = PNV_MACHINE(xi); - int i; + int i, j; for (i = 0; i < pnv->num_chips; i++) { - PnvChip *chip = pnv->chips[i]; Pnv8Chip *chip8 = PNV8_CHIP(pnv->chips[i]); ics_resend(&chip8->psi.ics); - object_child_foreach(OBJECT(chip), pnv_ics_resend_child, NULL); + + for (j = 0; j < chip8->num_phbs; j++) { + PnvPHB3 *phb3 = &chip8->phbs[j]; + + ics_resend(&phb3->lsis); + ics_resend(ICS(&phb3->msis)); + } } } From 8a69bca77a417167b743b8077c91ee43c52709cf Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Tue, 21 Jun 2022 14:34:34 -0300 Subject: [PATCH 06/34] ppc/pnv: make pnv_chip_power8_pic_print_info() use chip8->phbs[] It's inneficient to scroll all child objects when we have all PHBs available in chip8->phbs[]. pnv_chip_power8_pic_print_info_child() ended up folded into pic_print_info() for simplicity. Reviewed-by: Frederic Barrat Signed-off-by: Daniel Henrique Barboza Message-Id: <20220621173436.165912-7-danielhb413@gmail.com> --- hw/ppc/pnv.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 74a6c88dd2..d3f77c8367 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -652,25 +652,19 @@ static ISABus *pnv_isa_create(PnvChip *chip, Error **errp) return PNV_CHIP_GET_CLASS(chip)->isa_create(chip, errp); } -static int pnv_chip_power8_pic_print_info_child(Object *child, void *opaque) -{ - Monitor *mon = opaque; - PnvPHB3 *phb3 = (PnvPHB3 *) object_dynamic_cast(child, TYPE_PNV_PHB3); - - if (phb3) { - pnv_phb3_msi_pic_print_info(&phb3->msis, mon); - ics_pic_print_info(&phb3->lsis, mon); - } - return 0; -} - static void pnv_chip_power8_pic_print_info(PnvChip *chip, Monitor *mon) { Pnv8Chip *chip8 = PNV8_CHIP(chip); + int i; ics_pic_print_info(&chip8->psi.ics, mon); - object_child_foreach(OBJECT(chip), - pnv_chip_power8_pic_print_info_child, mon); + + for (i = 0; i < chip8->num_phbs; i++) { + PnvPHB3 *phb3 = &chip8->phbs[i]; + + pnv_phb3_msi_pic_print_info(&phb3->msis, mon); + ics_pic_print_info(&phb3->lsis, mon); + } } static int pnv_chip_power9_pic_print_info_child(Object *child, void *opaque) From 71cd3e5ecb33e5f8842552bcf91aceb964bbd33c Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Tue, 21 Jun 2022 14:34:35 -0300 Subject: [PATCH 07/34] ppc/pnv: remove 'INTERFACE_PCIE_DEVICE' from phb3 root bus It's unneeded. No other PCIE_BUS implements this interface. Reviewed-by: Frederic Barrat Fixes: 9ae1329ee2fe ("ppc/pnv: Add models for POWER8 PHB3 PCIe Host bridge") Signed-off-by: Daniel Henrique Barboza Message-Id: <20220621173436.165912-8-danielhb413@gmail.com> --- hw/pci-host/pnv_phb3.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c index afe5698167..d58d3c1701 100644 --- a/hw/pci-host/pnv_phb3.c +++ b/hw/pci-host/pnv_phb3.c @@ -1130,10 +1130,6 @@ static const TypeInfo pnv_phb3_root_bus_info = { .name = TYPE_PNV_PHB3_ROOT_BUS, .parent = TYPE_PCIE_BUS, .class_init = pnv_phb3_root_bus_class_init, - .interfaces = (InterfaceInfo[]) { - { INTERFACE_PCIE_DEVICE }, - { } - }, }; static void pnv_phb3_root_port_realize(DeviceState *dev, Error **errp) From 21870aab36355ff5a1a0dbdb06d2071f3214cab2 Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Tue, 21 Jun 2022 14:34:36 -0300 Subject: [PATCH 08/34] ppc/pnv: remove 'INTERFACE_PCIE_DEVICE' from phb4 root bus It's unneeded. No other PCIE_BUS implements this interface. Reviewed-by: Frederic Barrat Fixes: 4f9924c4d4cf ("ppc/pnv: Add models for POWER9 PHB4 PCIe Host bridge") Signed-off-by: Daniel Henrique Barboza Message-Id: <20220621173436.165912-9-danielhb413@gmail.com> --- hw/pci-host/pnv_phb4.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c index 725b3d740b..d225ab5b0f 100644 --- a/hw/pci-host/pnv_phb4.c +++ b/hw/pci-host/pnv_phb4.c @@ -1752,10 +1752,6 @@ static const TypeInfo pnv_phb4_root_bus_info = { .name = TYPE_PNV_PHB4_ROOT_BUS, .parent = TYPE_PCIE_BUS, .class_init = pnv_phb4_root_bus_class_init, - .interfaces = (InterfaceInfo[]) { - { INTERFACE_PCIE_DEVICE }, - { } - }, }; static void pnv_phb4_root_port_reset(DeviceState *dev) From 59f11543e2ccd5cab283732a7c59aeeaa6790138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Wed, 22 Jun 2022 16:32:03 -0300 Subject: [PATCH 09/34] target/ppc: Change FPSCR_* to follow POWER ISA numbering convention MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FPSCR_* bit values in QEMU are in the 'inverted' order from what Power ISA defines (e.g. FPSCR.FI is bit 46 but is defined as 17 in cpu.h). Now that PPC_BIT_NR macro was introduced to fix this situation for the MSR bits, we can use it for the FPSCR bits too. Also, adjust the comments to make then fit in 80 columns Signed-off-by: Víctor Colombo Reviewed-by: Fabiano Rosas Message-Id: <20220622193203.127698-1-victor.colombo@eldorado.org.br> [danielhb: fixed 'exceptio' typo in target/ppc/cpu.h] Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu.h | 72 ++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 6d78078f37..e109b5902b 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -694,42 +694,42 @@ enum { /*****************************************************************************/ /* Floating point status and control register */ -#define FPSCR_DRN2 34 /* Decimal Floating-Point rounding control */ -#define FPSCR_DRN1 33 /* Decimal Floating-Point rounding control */ -#define FPSCR_DRN0 32 /* Decimal Floating-Point rounding control */ -#define FPSCR_FX 31 /* Floating-point exception summary */ -#define FPSCR_FEX 30 /* Floating-point enabled exception summary */ -#define FPSCR_VX 29 /* Floating-point invalid operation exception summ. */ -#define FPSCR_OX 28 /* Floating-point overflow exception */ -#define FPSCR_UX 27 /* Floating-point underflow exception */ -#define FPSCR_ZX 26 /* Floating-point zero divide exception */ -#define FPSCR_XX 25 /* Floating-point inexact exception */ -#define FPSCR_VXSNAN 24 /* Floating-point invalid operation exception (sNan) */ -#define FPSCR_VXISI 23 /* Floating-point invalid operation exception (inf) */ -#define FPSCR_VXIDI 22 /* Floating-point invalid operation exception (inf) */ -#define FPSCR_VXZDZ 21 /* Floating-point invalid operation exception (zero) */ -#define FPSCR_VXIMZ 20 /* Floating-point invalid operation exception (inf) */ -#define FPSCR_VXVC 19 /* Floating-point invalid operation exception (comp) */ -#define FPSCR_FR 18 /* Floating-point fraction rounded */ -#define FPSCR_FI 17 /* Floating-point fraction inexact */ -#define FPSCR_C 16 /* Floating-point result class descriptor */ -#define FPSCR_FL 15 /* Floating-point less than or negative */ -#define FPSCR_FG 14 /* Floating-point greater than or negative */ -#define FPSCR_FE 13 /* Floating-point equal or zero */ -#define FPSCR_FU 12 /* Floating-point unordered or NaN */ -#define FPSCR_FPCC 12 /* Floating-point condition code */ -#define FPSCR_FPRF 12 /* Floating-point result flags */ -#define FPSCR_VXSOFT 10 /* Floating-point invalid operation exception (soft) */ -#define FPSCR_VXSQRT 9 /* Floating-point invalid operation exception (sqrt) */ -#define FPSCR_VXCVI 8 /* Floating-point invalid operation exception (int) */ -#define FPSCR_VE 7 /* Floating-point invalid operation exception enable */ -#define FPSCR_OE 6 /* Floating-point overflow exception enable */ -#define FPSCR_UE 5 /* Floating-point underflow exception enable */ -#define FPSCR_ZE 4 /* Floating-point zero divide exception enable */ -#define FPSCR_XE 3 /* Floating-point inexact exception enable */ -#define FPSCR_NI 2 /* Floating-point non-IEEE mode */ -#define FPSCR_RN1 1 -#define FPSCR_RN0 0 /* Floating-point rounding control */ +#define FPSCR_DRN2 PPC_BIT_NR(29) /* Decimal Floating-Point rounding ctrl. */ +#define FPSCR_DRN1 PPC_BIT_NR(30) /* Decimal Floating-Point rounding ctrl. */ +#define FPSCR_DRN0 PPC_BIT_NR(31) /* Decimal Floating-Point rounding ctrl. */ +#define FPSCR_FX PPC_BIT_NR(32) /* Floating-point exception summary */ +#define FPSCR_FEX PPC_BIT_NR(33) /* Floating-point enabled exception summ.*/ +#define FPSCR_VX PPC_BIT_NR(34) /* Floating-point invalid op. excp. summ.*/ +#define FPSCR_OX PPC_BIT_NR(35) /* Floating-point overflow exception */ +#define FPSCR_UX PPC_BIT_NR(36) /* Floating-point underflow exception */ +#define FPSCR_ZX PPC_BIT_NR(37) /* Floating-point zero divide exception */ +#define FPSCR_XX PPC_BIT_NR(38) /* Floating-point inexact exception */ +#define FPSCR_VXSNAN PPC_BIT_NR(39) /* Floating-point invalid op. excp (sNan)*/ +#define FPSCR_VXISI PPC_BIT_NR(40) /* Floating-point invalid op. excp (inf) */ +#define FPSCR_VXIDI PPC_BIT_NR(41) /* Floating-point invalid op. excp (inf) */ +#define FPSCR_VXZDZ PPC_BIT_NR(42) /* Floating-point invalid op. excp (zero)*/ +#define FPSCR_VXIMZ PPC_BIT_NR(43) /* Floating-point invalid op. excp (inf) */ +#define FPSCR_VXVC PPC_BIT_NR(44) /* Floating-point invalid op. excp (comp)*/ +#define FPSCR_FR PPC_BIT_NR(45) /* Floating-point fraction rounded */ +#define FPSCR_FI PPC_BIT_NR(46) /* Floating-point fraction inexact */ +#define FPSCR_C PPC_BIT_NR(47) /* Floating-point result class descriptor*/ +#define FPSCR_FL PPC_BIT_NR(48) /* Floating-point less than or negative */ +#define FPSCR_FG PPC_BIT_NR(49) /* Floating-point greater than or neg. */ +#define FPSCR_FE PPC_BIT_NR(50) /* Floating-point equal or zero */ +#define FPSCR_FU PPC_BIT_NR(51) /* Floating-point unordered or NaN */ +#define FPSCR_FPCC PPC_BIT_NR(51) /* Floating-point condition code */ +#define FPSCR_FPRF PPC_BIT_NR(51) /* Floating-point result flags */ +#define FPSCR_VXSOFT PPC_BIT_NR(53) /* Floating-point invalid op. excp (soft)*/ +#define FPSCR_VXSQRT PPC_BIT_NR(54) /* Floating-point invalid op. excp (sqrt)*/ +#define FPSCR_VXCVI PPC_BIT_NR(55) /* Floating-point invalid op. excp (int) */ +#define FPSCR_VE PPC_BIT_NR(56) /* Floating-point invalid op. excp enable*/ +#define FPSCR_OE PPC_BIT_NR(57) /* Floating-point overflow excp. enable */ +#define FPSCR_UE PPC_BIT_NR(58) /* Floating-point underflow excp. enable */ +#define FPSCR_ZE PPC_BIT_NR(59) /* Floating-point zero divide excp enable*/ +#define FPSCR_XE PPC_BIT_NR(60) /* Floating-point inexact excp. enable */ +#define FPSCR_NI PPC_BIT_NR(61) /* Floating-point non-IEEE mode */ +#define FPSCR_RN1 PPC_BIT_NR(62) +#define FPSCR_RN0 PPC_BIT_NR(63) /* Floating-point rounding control */ /* Invalid operation exception summary */ #define FPSCR_IX ((1 << FPSCR_VXSNAN) | (1 << FPSCR_VXISI) | \ (1 << FPSCR_VXIDI) | (1 << FPSCR_VXZDZ) | \ From 31cc81f72801bcda02c866ff94ed8baf6b84506d Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Wed, 22 Jun 2022 15:29:55 +1000 Subject: [PATCH 10/34] spapr/ddw: Reset DMA when the last non-default window is removed PAPR+/LoPAPR says: === The platform must restore the default DMA window for the PE on a call to the ibm,remove-pe-dma-window RTAS call when all of the following are true: a. The call removes the last DMA window remaining for the PE. b. The DMA window being removed is not the default window === This resets DMA as PAPR mandates. Signed-off-by: Alexey Kardashevskiy Reviewed-by: Daniel Henrique Barboza Message-Id: <20220622052955.1069903-1-aik@ozlabs.ru> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/spapr_iommu.c | 3 ++- hw/ppc/spapr_pci.c | 1 + hw/ppc/spapr_rtas_ddw.c | 15 +++++++++++++++ include/hw/ppc/spapr.h | 1 + 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index 81e5a1aea3..63e34d457a 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -279,7 +279,7 @@ static const VMStateDescription vmstate_spapr_tce_table_ex = { static const VMStateDescription vmstate_spapr_tce_table = { .name = "spapr_iommu", - .version_id = 2, + .version_id = 3, .minimum_version_id = 2, .pre_save = spapr_tce_table_pre_save, .post_load = spapr_tce_table_post_load, @@ -292,6 +292,7 @@ static const VMStateDescription vmstate_spapr_tce_table = { VMSTATE_BOOL(bypass, SpaprTceTable), VMSTATE_VARRAY_UINT32_ALLOC(mig_table, SpaprTceTable, mig_nb_table, 0, vmstate_info_uint64, uint64_t), + VMSTATE_BOOL_V(def_win, SpaprTceTable, 3), VMSTATE_END_OF_LIST() }, diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index b2f5fbef0c..5e95d7940f 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -2067,6 +2067,7 @@ void spapr_phb_dma_reset(SpaprPhbState *sphb) tcet = spapr_tce_find_by_liobn(sphb->dma_liobn[0]); spapr_tce_table_enable(tcet, SPAPR_TCE_PAGE_SHIFT, sphb->dma_win_addr, sphb->dma_win_size >> SPAPR_TCE_PAGE_SHIFT); + tcet->def_win = true; } static void spapr_phb_reset(DeviceState *qdev) diff --git a/hw/ppc/spapr_rtas_ddw.c b/hw/ppc/spapr_rtas_ddw.c index 13d339c807..bb7d91b6d1 100644 --- a/hw/ppc/spapr_rtas_ddw.c +++ b/hw/ppc/spapr_rtas_ddw.c @@ -215,6 +215,7 @@ static void rtas_ibm_remove_pe_dma_window(PowerPCCPU *cpu, SpaprPhbState *sphb; SpaprTceTable *tcet; uint32_t liobn; + bool def_win_removed; if ((nargs != 1) || (nret != 1)) { goto param_error_exit; @@ -231,9 +232,23 @@ static void rtas_ibm_remove_pe_dma_window(PowerPCCPU *cpu, goto param_error_exit; } + def_win_removed = tcet->def_win; spapr_tce_table_disable(tcet); trace_spapr_iommu_ddw_remove(liobn); + /* + * PAPR+/LoPAPR says: + * The platform must restore the default DMA window for the PE on a call + * to the ibm,remove-pe-dma-window RTAS call when all of the following + * are true: + * a. The call removes the last DMA window remaining for the PE. + * b. The DMA window being removed is not the default window + */ + if (spapr_phb_get_active_win_num(sphb) == 0 && !def_win_removed) { + spapr_phb_dma_reset(sphb); + trace_spapr_iommu_ddw_reset(sphb->buid, 0); + } + rtas_st(rets, 0, RTAS_OUT_SUCCESS); return; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 072dda2c72..4ba2b27b8c 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -902,6 +902,7 @@ struct SpaprTceTable { bool bypass; bool need_vfio; bool skipping_replay; + bool def_win; int fd; MemoryRegion root; IOMMUMemoryRegion iommu; From c0e765dafb474f7e60e43c229cb772cbbaf3b90e Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Thu, 23 Jun 2022 17:31:36 +1000 Subject: [PATCH 11/34] spapr/ddw: Implement 64bit query extension PAPR 2.8 (2018) defines an extension to return 64bit value for the largest TCE block in "ibm,query-pe-dma-window". Recent Linux kernels support this already. This adds the extension and supports the older format. This advertises a bigger window for the new format as the biggest window with 2M pages below the start of the 64bit window as it is the maximum we will see in practice. Signed-off-by: Alexey Kardashevskiy Reviewed-by: Daniel Henrique Barboza Message-Id: <20220623073136.1380214-1-aik@ozlabs.ru> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/spapr_pci.c | 5 +++-- hw/ppc/spapr_rtas_ddw.c | 19 +++++++++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 5e95d7940f..67e9d468aa 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -2360,8 +2360,9 @@ int spapr_dt_phb(SpaprMachineState *spapr, SpaprPhbState *phb, cpu_to_be32(RTAS_IBM_REMOVE_PE_DMA_WINDOW) }; uint32_t ddw_extensions[] = { - cpu_to_be32(1), - cpu_to_be32(RTAS_IBM_RESET_PE_DMA_WINDOW) + cpu_to_be32(2), + cpu_to_be32(RTAS_IBM_RESET_PE_DMA_WINDOW), + cpu_to_be32(1), /* 1: ibm,query-pe-dma-window 6 outputs, PAPR 2.8 */ }; SpaprTceTable *tcet; SpaprDrc *drc; diff --git a/hw/ppc/spapr_rtas_ddw.c b/hw/ppc/spapr_rtas_ddw.c index bb7d91b6d1..7ba11382bc 100644 --- a/hw/ppc/spapr_rtas_ddw.c +++ b/hw/ppc/spapr_rtas_ddw.c @@ -100,7 +100,7 @@ static void rtas_ibm_query_pe_dma_window(PowerPCCPU *cpu, uint64_t buid; uint32_t avail, addr, pgmask = 0; - if ((nargs != 3) || (nret != 5)) { + if ((nargs != 3) || ((nret != 5) && (nret != 6))) { goto param_error_exit; } @@ -118,9 +118,20 @@ static void rtas_ibm_query_pe_dma_window(PowerPCCPU *cpu, rtas_st(rets, 0, RTAS_OUT_SUCCESS); rtas_st(rets, 1, avail); - rtas_st(rets, 2, 0x80000000); /* The largest window we can possibly have */ - rtas_st(rets, 3, pgmask); - rtas_st(rets, 4, 0); /* DMA migration mask, not supported */ + if (nret == 6) { + /* + * Set the Max TCE number as 1<<(58-21) = 0x20.0000.0000 + * 1<<59 is the huge window start and 21 is 2M page shift. + */ + rtas_st(rets, 2, 0x00000020); + rtas_st(rets, 3, 0x00000000); + rtas_st(rets, 4, pgmask); + rtas_st(rets, 5, 0); /* DMA migration mask, not supported */ + } else { + rtas_st(rets, 2, 0x80000000); + rtas_st(rets, 3, pgmask); + rtas_st(rets, 4, 0); /* DMA migration mask, not supported */ + } trace_spapr_iommu_ddw_query(buid, addr, avail, 0x80000000, pgmask); return; From e82ca8acdd5021ccd7c0c0fe7e25fae7e3909b4b Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Mon, 6 Jun 2022 12:00:31 -0300 Subject: [PATCH 12/34] target/ppc: use int128.h methods in vpmsumd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also drop VECTOR_FOR_INORDER_I usage since there is no need to access the elements in any particular order, and move the instruction to decodetree. Signed-off-by: Matheus Ferst Reviewed-by: Víctor Colombo Message-Id: <20220606150037.338931-2-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 +- target/ppc/insn32.decode | 4 +++ target/ppc/int_helper.c | 46 ++++++----------------------- target/ppc/translate/vmx-impl.c.inc | 3 +- target/ppc/translate/vmx-ops.c.inc | 1 - 5 files changed, 16 insertions(+), 40 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index d627cfe6ed..39ad114c97 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -318,7 +318,7 @@ DEF_HELPER_FLAGS_3(vbpermq, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(vpmsumb, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(vpmsumh, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(vpmsumw, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vpmsumd, TCG_CALL_NO_RWG, void, avr, avr, avr) +DEF_HELPER_FLAGS_3(VPMSUMD, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_2(vextublx, TCG_CALL_NO_RWG, tl, tl, avr) DEF_HELPER_FLAGS_2(vextuhlx, TCG_CALL_NO_RWG, tl, tl, avr) DEF_HELPER_FLAGS_2(vextuwlx, TCG_CALL_NO_RWG, tl, tl, avr) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 6ea48d5163..0772729c6e 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -426,6 +426,10 @@ DSCLIQ 111111 ..... ..... ...... 001000010 . @Z22_tap_sh_rc DSCRI 111011 ..... ..... ...... 001100010 . @Z22_ta_sh_rc DSCRIQ 111111 ..... ..... ...... 001100010 . @Z22_tap_sh_rc +## Vector Exclusive-OR-based Instructions + +VPMSUMD 000100 ..... ..... ..... 10011001000 @VX + ## Vector Integer Instructions VCMPEQUB 000100 ..... ..... ..... . 0000000110 @VC diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 3ae03f73d3..1476e51651 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -1484,52 +1484,24 @@ PMSUM(vpmsumb, u8, u16, uint16_t) PMSUM(vpmsumh, u16, u32, uint32_t) PMSUM(vpmsumw, u32, u64, uint64_t) -void helper_vpmsumd(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) +void helper_VPMSUMD(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { - -#ifdef CONFIG_INT128 int i, j; - __uint128_t prod[2]; + Int128 tmp, prod[2] = {int128_zero(), int128_zero()}; - VECTOR_FOR_INORDER_I(i, u64) { - prod[i] = 0; - for (j = 0; j < 64; j++) { - if (a->u64[i] & (1ull << j)) { - prod[i] ^= (((__uint128_t)b->u64[i]) << j); + for (j = 0; j < 64; j++) { + for (i = 0; i < ARRAY_SIZE(r->u64); i++) { + if (a->VsrD(i) & (1ull << j)) { + tmp = int128_make64(b->VsrD(i)); + tmp = int128_lshift(tmp, j); + prod[i] = int128_xor(prod[i], tmp); } } } - r->u128 = prod[0] ^ prod[1]; - -#else - int i, j; - ppc_avr_t prod[2]; - - VECTOR_FOR_INORDER_I(i, u64) { - prod[i].VsrD(1) = prod[i].VsrD(0) = 0; - for (j = 0; j < 64; j++) { - if (a->u64[i] & (1ull << j)) { - ppc_avr_t bshift; - if (j == 0) { - bshift.VsrD(0) = 0; - bshift.VsrD(1) = b->u64[i]; - } else { - bshift.VsrD(0) = b->u64[i] >> (64 - j); - bshift.VsrD(1) = b->u64[i] << j; - } - prod[i].VsrD(1) ^= bshift.VsrD(1); - prod[i].VsrD(0) ^= bshift.VsrD(0); - } - } - } - - r->VsrD(1) = prod[0].VsrD(1) ^ prod[1].VsrD(1); - r->VsrD(0) = prod[0].VsrD(0) ^ prod[1].VsrD(0); -#endif + r->s128 = int128_xor(prod[0], prod[1]); } - #if HOST_BIG_ENDIAN #define PKBIG 1 #else diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index 0b563bed37..4c2a36405b 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -2717,7 +2717,6 @@ GEN_VXFORM_TRANS(vgbbd, 6, 20); GEN_VXFORM(vpmsumb, 4, 16) GEN_VXFORM(vpmsumh, 4, 17) GEN_VXFORM(vpmsumw, 4, 18) -GEN_VXFORM(vpmsumd, 4, 19) #define GEN_BCD(op) \ static void gen_##op(DisasContext *ctx) \ @@ -3101,6 +3100,8 @@ static bool do_vx_helper(DisasContext *ctx, arg_VX *a, return true; } +TRANS_FLAGS2(ALTIVEC_207, VPMSUMD, do_vx_helper, gen_helper_VPMSUMD) + static bool do_vx_vmuleo(DisasContext *ctx, arg_VX *a, bool even, void (*gen_mul)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64)) { diff --git a/target/ppc/translate/vmx-ops.c.inc b/target/ppc/translate/vmx-ops.c.inc index d7cc57868e..26c1d957ee 100644 --- a/target/ppc/translate/vmx-ops.c.inc +++ b/target/ppc/translate/vmx-ops.c.inc @@ -237,7 +237,6 @@ GEN_VXFORM_207(vgbbd, 6, 20), GEN_VXFORM_207(vpmsumb, 4, 16), GEN_VXFORM_207(vpmsumh, 4, 17), GEN_VXFORM_207(vpmsumw, 4, 18), -GEN_VXFORM_207(vpmsumd, 4, 19), GEN_VXFORM_207(vsbox, 4, 23), From 7ca042868744a5efca902473d600d205e9e104b2 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Mon, 6 Jun 2022 12:00:32 -0300 Subject: [PATCH 13/34] target/ppc: use int128.h methods in vadduqm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And also move the insn to decodetree. Signed-off-by: Matheus Ferst Reviewed-by: Víctor Colombo Message-Id: <20220606150037.338931-3-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 +- target/ppc/insn32.decode | 2 ++ target/ppc/int_helper.c | 8 ++------ target/ppc/translate/vmx-impl.c.inc | 3 ++- target/ppc/translate/vmx-ops.c.inc | 1 - 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 39ad114c97..c6fbe4b6da 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -204,7 +204,7 @@ DEF_HELPER_FLAGS_5(vadduws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_5(vsububs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_5(vsubuhs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_5(vsubuws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) -DEF_HELPER_FLAGS_3(vadduqm, TCG_CALL_NO_RWG, void, avr, avr, avr) +DEF_HELPER_FLAGS_3(VADDUQM, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_4(vaddecuq, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_FLAGS_4(vaddeuqm, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_FLAGS_3(vaddcuq, TCG_CALL_NO_RWG, void, avr, avr, avr) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 0772729c6e..d6bfc2c768 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -550,6 +550,8 @@ VRLQNM 000100 ..... ..... ..... 00101000101 @VX ## Vector Integer Arithmetic Instructions +VADDUQM 000100 ..... ..... ..... 00100000000 @VX + VEXTSB2W 000100 ..... 10000 ..... 11000000010 @VX_tb VEXTSH2W 000100 ..... 10001 ..... 11000000010 @VX_tb VEXTSB2D 000100 ..... 11000 ..... 11000000010 @VX_tb diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 1476e51651..7de69f00b5 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -2224,13 +2224,9 @@ static int avr_qw_addc(ppc_avr_t *t, ppc_avr_t a, ppc_avr_t b) #endif -void helper_vadduqm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) +void helper_VADDUQM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { -#ifdef CONFIG_INT128 - r->u128 = a->u128 + b->u128; -#else - avr_qw_add(r, *a, *b); -#endif + r->s128 = int128_add(a->s128, b->s128); } void helper_vaddeuqm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index 4c2a36405b..3fb48404d9 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -1234,7 +1234,6 @@ GEN_VXFORM_SAT(vsubuws, MO_32, sub, ussub, 0, 26); GEN_VXFORM_SAT(vsubsbs, MO_8, sub, sssub, 0, 28); GEN_VXFORM_SAT(vsubshs, MO_16, sub, sssub, 0, 29); GEN_VXFORM_SAT(vsubsws, MO_32, sub, sssub, 0, 30); -GEN_VXFORM(vadduqm, 0, 4); GEN_VXFORM(vaddcuq, 0, 5); GEN_VXFORM3(vaddeuqm, 30, 0); GEN_VXFORM3(vaddecuq, 30, 0); @@ -3100,6 +3099,8 @@ static bool do_vx_helper(DisasContext *ctx, arg_VX *a, return true; } +TRANS_FLAGS2(ALTIVEC_207, VADDUQM, do_vx_helper, gen_helper_VADDUQM) + TRANS_FLAGS2(ALTIVEC_207, VPMSUMD, do_vx_helper, gen_helper_VPMSUMD) static bool do_vx_vmuleo(DisasContext *ctx, arg_VX *a, bool even, diff --git a/target/ppc/translate/vmx-ops.c.inc b/target/ppc/translate/vmx-ops.c.inc index 26c1d957ee..065b0ba414 100644 --- a/target/ppc/translate/vmx-ops.c.inc +++ b/target/ppc/translate/vmx-ops.c.inc @@ -126,7 +126,6 @@ GEN_VXFORM(vsubuws, 0, 26), GEN_VXFORM_DUAL(vsubsbs, bcdtrunc, 0, 28, PPC_ALTIVEC, PPC2_ISA300), GEN_VXFORM(vsubshs, 0, 29), GEN_VXFORM_DUAL(vsubsws, xpnd04_2, 0, 30, PPC_ALTIVEC, PPC_NONE), -GEN_VXFORM_207(vadduqm, 0, 4), GEN_VXFORM_207(vaddcuq, 0, 5), GEN_VXFORM_DUAL(vaddeuqm, vaddecuq, 30, 0xFF, PPC_NONE, PPC2_ALTIVEC_207), GEN_VXFORM_DUAL(vsubuqm, bcdtrunc, 0, 20, PPC2_ALTIVEC_207, PPC2_ISA300), From 896d92c81d638bfd040ee249629bbc48b2ce883f Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Mon, 6 Jun 2022 12:00:33 -0300 Subject: [PATCH 14/34] target/ppc: use int128.h methods in vaddecuq and vaddeuqm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And also move the insns to decodetree and remove the now unused avr_qw_addc method. Signed-off-by: Matheus Ferst Reviewed-by: Víctor Colombo Message-Id: <20220606150037.338931-4-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 4 +-- target/ppc/insn32.decode | 3 ++ target/ppc/int_helper.c | 53 +++++------------------------ target/ppc/translate/vmx-impl.c.inc | 7 ++-- target/ppc/translate/vmx-ops.c.inc | 1 - 5 files changed, 17 insertions(+), 51 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index c6fbe4b6da..f699adbedc 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -205,8 +205,8 @@ DEF_HELPER_FLAGS_5(vsububs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_5(vsubuhs, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_5(vsubuws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_3(VADDUQM, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_4(vaddecuq, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) -DEF_HELPER_FLAGS_4(vaddeuqm, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) +DEF_HELPER_FLAGS_4(VADDECUQ, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) +DEF_HELPER_FLAGS_4(VADDEUQM, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_FLAGS_3(vaddcuq, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(vsubuqm, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_4(vsubecuq, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index d6bfc2c768..139aa3caeb 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -552,6 +552,9 @@ VRLQNM 000100 ..... ..... ..... 00101000101 @VX VADDUQM 000100 ..... ..... ..... 00100000000 @VX +VADDEUQM 000100 ..... ..... ..... ..... 111100 @VA +VADDECUQ 000100 ..... ..... ..... ..... 111101 @VA + VEXTSB2W 000100 ..... 10000 ..... 11000000010 @VX_tb VEXTSH2W 000100 ..... 10001 ..... 11000000010 @VX_tb VEXTSB2D 000100 ..... 11000 ..... 11000000010 @VX_tb diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 7de69f00b5..ecfe413ae1 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -2212,16 +2212,6 @@ static void avr_qw_add(ppc_avr_t *t, ppc_avr_t a, ppc_avr_t b) (~a.VsrD(1) < b.VsrD(1)); } -static int avr_qw_addc(ppc_avr_t *t, ppc_avr_t a, ppc_avr_t b) -{ - ppc_avr_t not_a; - t->VsrD(1) = a.VsrD(1) + b.VsrD(1); - t->VsrD(0) = a.VsrD(0) + b.VsrD(0) + - (~a.VsrD(1) < b.VsrD(1)); - avr_qw_not(¬_a, a); - return avr_qw_cmpu(not_a, b) < 0; -} - #endif void helper_VADDUQM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) @@ -2229,23 +2219,10 @@ void helper_VADDUQM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) r->s128 = int128_add(a->s128, b->s128); } -void helper_vaddeuqm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) +void helper_VADDEUQM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) { -#ifdef CONFIG_INT128 - r->u128 = a->u128 + b->u128 + (c->u128 & 1); -#else - - if (c->VsrD(1) & 1) { - ppc_avr_t tmp; - - tmp.VsrD(0) = 0; - tmp.VsrD(1) = c->VsrD(1) & 1; - avr_qw_add(&tmp, *a, tmp); - avr_qw_add(r, tmp, *b); - } else { - avr_qw_add(r, *a, *b); - } -#endif + r->s128 = int128_add(int128_add(a->s128, b->s128), + int128_make64(int128_getlo(c->s128) & 1)); } void helper_vaddcuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) @@ -2262,30 +2239,18 @@ void helper_vaddcuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) #endif } -void helper_vaddecuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) +void helper_VADDECUQ(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) { -#ifdef CONFIG_INT128 - int carry_out = (~a->u128 < b->u128); - if (!carry_out && (c->u128 & 1)) { - carry_out = ((a->u128 + b->u128 + 1) == 0) && - ((a->u128 != 0) || (b->u128 != 0)); - } - r->u128 = carry_out; -#else - - int carry_in = c->VsrD(1) & 1; - int carry_out = 0; - ppc_avr_t tmp; - - carry_out = avr_qw_addc(&tmp, *a, *b); + bool carry_out = int128_ult(int128_not(a->s128), b->s128), + carry_in = int128_getlo(c->s128) & 1; if (!carry_out && carry_in) { - ppc_avr_t one = QW_ONE; - carry_out = avr_qw_addc(&tmp, tmp, one); + carry_out = (int128_nz(a->s128) || int128_nz(b->s128)) && + int128_eq(int128_add(a->s128, b->s128), int128_makes64(-1)); } + r->VsrD(0) = 0; r->VsrD(1) = carry_out; -#endif } void helper_vsubuqm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index 3fb48404d9..4ec6b841b3 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -1235,10 +1235,6 @@ GEN_VXFORM_SAT(vsubsbs, MO_8, sub, sssub, 0, 28); GEN_VXFORM_SAT(vsubshs, MO_16, sub, sssub, 0, 29); GEN_VXFORM_SAT(vsubsws, MO_32, sub, sssub, 0, 30); GEN_VXFORM(vaddcuq, 0, 5); -GEN_VXFORM3(vaddeuqm, 30, 0); -GEN_VXFORM3(vaddecuq, 30, 0); -GEN_VXFORM_DUAL(vaddeuqm, PPC_NONE, PPC2_ALTIVEC_207, \ - vaddecuq, PPC_NONE, PPC2_ALTIVEC_207) GEN_VXFORM(vsubuqm, 0, 20); GEN_VXFORM(vsubcuq, 0, 21); GEN_VXFORM3(vsubeuqm, 31, 0); @@ -2571,6 +2567,9 @@ static bool do_va_helper(DisasContext *ctx, arg_VA *a, return true; } +TRANS_FLAGS2(ALTIVEC_207, VADDECUQ, do_va_helper, gen_helper_VADDECUQ) +TRANS_FLAGS2(ALTIVEC_207, VADDEUQM, do_va_helper, gen_helper_VADDEUQM) + TRANS_FLAGS(ALTIVEC, VPERM, do_va_helper, gen_helper_VPERM) TRANS_FLAGS2(ISA300, VPERMR, do_va_helper, gen_helper_VPERMR) diff --git a/target/ppc/translate/vmx-ops.c.inc b/target/ppc/translate/vmx-ops.c.inc index 065b0ba414..f8a512f920 100644 --- a/target/ppc/translate/vmx-ops.c.inc +++ b/target/ppc/translate/vmx-ops.c.inc @@ -127,7 +127,6 @@ GEN_VXFORM_DUAL(vsubsbs, bcdtrunc, 0, 28, PPC_ALTIVEC, PPC2_ISA300), GEN_VXFORM(vsubshs, 0, 29), GEN_VXFORM_DUAL(vsubsws, xpnd04_2, 0, 30, PPC_ALTIVEC, PPC_NONE), GEN_VXFORM_207(vaddcuq, 0, 5), -GEN_VXFORM_DUAL(vaddeuqm, vaddecuq, 30, 0xFF, PPC_NONE, PPC2_ALTIVEC_207), GEN_VXFORM_DUAL(vsubuqm, bcdtrunc, 0, 20, PPC2_ALTIVEC_207, PPC2_ISA300), GEN_VXFORM_DUAL(vsubcuq, bcdutrunc, 0, 21, PPC2_ALTIVEC_207, PPC2_ISA300), GEN_VXFORM_DUAL(vsubeuqm, vsubecuq, 31, 0xFF, PPC_NONE, PPC2_ALTIVEC_207), From 8290ea509f62e4742a76d409091f398a80ba0b5b Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Mon, 6 Jun 2022 12:00:34 -0300 Subject: [PATCH 15/34] target/ppc: use int128.h methods in vaddcuq MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And also move the insn to decodetree. Signed-off-by: Matheus Ferst Reviewed-by: Víctor Colombo Message-Id: <20220606150037.338931-5-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 +- target/ppc/insn32.decode | 1 + target/ppc/int_helper.c | 12 ++---------- target/ppc/translate/vmx-impl.c.inc | 2 +- target/ppc/translate/vmx-ops.c.inc | 1 - 5 files changed, 5 insertions(+), 13 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index f699adbedc..f6b1b2fad2 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -207,7 +207,7 @@ DEF_HELPER_FLAGS_5(vsubuws, TCG_CALL_NO_RWG, void, avr, avr, avr, avr, i32) DEF_HELPER_FLAGS_3(VADDUQM, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_4(VADDECUQ, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_FLAGS_4(VADDEUQM, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) -DEF_HELPER_FLAGS_3(vaddcuq, TCG_CALL_NO_RWG, void, avr, avr, avr) +DEF_HELPER_FLAGS_3(VADDCUQ, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(vsubuqm, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_4(vsubecuq, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_FLAGS_4(vsubeuqm, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 139aa3caeb..35252ddd4f 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -550,6 +550,7 @@ VRLQNM 000100 ..... ..... ..... 00101000101 @VX ## Vector Integer Arithmetic Instructions +VADDCUQ 000100 ..... ..... ..... 00101000000 @VX VADDUQM 000100 ..... ..... ..... 00100000000 @VX VADDEUQM 000100 ..... ..... ..... ..... 111100 @VA diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index ecfe413ae1..279333a814 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -2225,18 +2225,10 @@ void helper_VADDEUQM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) int128_make64(int128_getlo(c->s128) & 1)); } -void helper_vaddcuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) +void helper_VADDCUQ(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { -#ifdef CONFIG_INT128 - r->u128 = (~a->u128 < b->u128); -#else - ppc_avr_t not_a; - - avr_qw_not(¬_a, *a); - + r->VsrD(1) = int128_ult(int128_not(a->s128), b->s128); r->VsrD(0) = 0; - r->VsrD(1) = (avr_qw_cmpu(not_a, *b) < 0); -#endif } void helper_VADDECUQ(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index 4ec6b841b3..8c0e5bcc03 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -1234,7 +1234,6 @@ GEN_VXFORM_SAT(vsubuws, MO_32, sub, ussub, 0, 26); GEN_VXFORM_SAT(vsubsbs, MO_8, sub, sssub, 0, 28); GEN_VXFORM_SAT(vsubshs, MO_16, sub, sssub, 0, 29); GEN_VXFORM_SAT(vsubsws, MO_32, sub, sssub, 0, 30); -GEN_VXFORM(vaddcuq, 0, 5); GEN_VXFORM(vsubuqm, 0, 20); GEN_VXFORM(vsubcuq, 0, 21); GEN_VXFORM3(vsubeuqm, 31, 0); @@ -3098,6 +3097,7 @@ static bool do_vx_helper(DisasContext *ctx, arg_VX *a, return true; } +TRANS_FLAGS2(ALTIVEC_207, VADDCUQ, do_vx_helper, gen_helper_VADDCUQ) TRANS_FLAGS2(ALTIVEC_207, VADDUQM, do_vx_helper, gen_helper_VADDUQM) TRANS_FLAGS2(ALTIVEC_207, VPMSUMD, do_vx_helper, gen_helper_VPMSUMD) diff --git a/target/ppc/translate/vmx-ops.c.inc b/target/ppc/translate/vmx-ops.c.inc index f8a512f920..33e05929cb 100644 --- a/target/ppc/translate/vmx-ops.c.inc +++ b/target/ppc/translate/vmx-ops.c.inc @@ -126,7 +126,6 @@ GEN_VXFORM(vsubuws, 0, 26), GEN_VXFORM_DUAL(vsubsbs, bcdtrunc, 0, 28, PPC_ALTIVEC, PPC2_ISA300), GEN_VXFORM(vsubshs, 0, 29), GEN_VXFORM_DUAL(vsubsws, xpnd04_2, 0, 30, PPC_ALTIVEC, PPC_NONE), -GEN_VXFORM_207(vaddcuq, 0, 5), GEN_VXFORM_DUAL(vsubuqm, bcdtrunc, 0, 20, PPC2_ALTIVEC_207, PPC2_ISA300), GEN_VXFORM_DUAL(vsubcuq, bcdutrunc, 0, 21, PPC2_ALTIVEC_207, PPC2_ISA300), GEN_VXFORM_DUAL(vsubeuqm, vsubecuq, 31, 0xFF, PPC_NONE, PPC2_ALTIVEC_207), From b132be53a4ba6a0a40d5643d791822f958a36e53 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Mon, 6 Jun 2022 12:00:35 -0300 Subject: [PATCH 16/34] target/ppc: use int128.h methods in vsubuqm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And also move the insn to decodetree Signed-off-by: Matheus Ferst Reviewed-by: Víctor Colombo Message-Id: <20220606150037.338931-6-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 +- target/ppc/insn32.decode | 2 ++ target/ppc/int_helper.c | 19 ++----------------- target/ppc/translate/vmx-impl.c.inc | 5 ++--- target/ppc/translate/vmx-ops.c.inc | 2 +- 5 files changed, 8 insertions(+), 22 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index f6b1b2fad2..1c02ad85e5 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -208,7 +208,7 @@ DEF_HELPER_FLAGS_3(VADDUQM, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_4(VADDECUQ, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_FLAGS_4(VADDEUQM, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_FLAGS_3(VADDCUQ, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_3(vsubuqm, TCG_CALL_NO_RWG, void, avr, avr, avr) +DEF_HELPER_FLAGS_3(VSUBUQM, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_4(vsubecuq, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_FLAGS_4(vsubeuqm, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_FLAGS_3(vsubcuq, TCG_CALL_NO_RWG, void, avr, avr, avr) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 35252ddd4f..a8d3a5a8a1 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -556,6 +556,8 @@ VADDUQM 000100 ..... ..... ..... 00100000000 @VX VADDEUQM 000100 ..... ..... ..... ..... 111100 @VA VADDECUQ 000100 ..... ..... ..... ..... 111101 @VA +VSUBUQM 000100 ..... ..... ..... 10100000000 @VX + VEXTSB2W 000100 ..... 10000 ..... 11000000010 @VX_tb VEXTSH2W 000100 ..... 10001 ..... 11000000010 @VX_tb VEXTSB2D 000100 ..... 11000 ..... 11000000010 @VX_tb diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 279333a814..159b831d97 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -2176,12 +2176,6 @@ VGENERIC_DO(popcntd, u64) #undef VGENERIC_DO -#if HOST_BIG_ENDIAN -#define QW_ONE { .u64 = { 0, 1 } } -#else -#define QW_ONE { .u64 = { 1, 0 } } -#endif - #ifndef CONFIG_INT128 static inline void avr_qw_not(ppc_avr_t *t, ppc_avr_t a) @@ -2245,18 +2239,9 @@ void helper_VADDECUQ(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) r->VsrD(1) = carry_out; } -void helper_vsubuqm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) +void helper_VSUBUQM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { -#ifdef CONFIG_INT128 - r->u128 = a->u128 - b->u128; -#else - ppc_avr_t tmp; - ppc_avr_t one = QW_ONE; - - avr_qw_not(&tmp, *b); - avr_qw_add(&tmp, *a, tmp); - avr_qw_add(r, tmp, one); -#endif + r->s128 = int128_sub(a->s128, b->s128); } void helper_vsubeuqm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index 8c0e5bcc03..1e665534c3 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -1234,7 +1234,6 @@ GEN_VXFORM_SAT(vsubuws, MO_32, sub, ussub, 0, 26); GEN_VXFORM_SAT(vsubsbs, MO_8, sub, sssub, 0, 28); GEN_VXFORM_SAT(vsubshs, MO_16, sub, sssub, 0, 29); GEN_VXFORM_SAT(vsubsws, MO_32, sub, sssub, 0, 30); -GEN_VXFORM(vsubuqm, 0, 20); GEN_VXFORM(vsubcuq, 0, 21); GEN_VXFORM3(vsubeuqm, 31, 0); GEN_VXFORM3(vsubecuq, 31, 0); @@ -2858,8 +2857,6 @@ GEN_VXFORM_DUAL(vsubuwm, PPC_ALTIVEC, PPC_NONE, \ bcdus, PPC_NONE, PPC2_ISA300) GEN_VXFORM_DUAL(vsubsbs, PPC_ALTIVEC, PPC_NONE, \ bcdtrunc, PPC_NONE, PPC2_ISA300) -GEN_VXFORM_DUAL(vsubuqm, PPC2_ALTIVEC_207, PPC_NONE, \ - bcdtrunc, PPC_NONE, PPC2_ISA300) GEN_VXFORM_DUAL(vsubcuq, PPC2_ALTIVEC_207, PPC_NONE, \ bcdutrunc, PPC_NONE, PPC2_ISA300) @@ -3102,6 +3099,8 @@ TRANS_FLAGS2(ALTIVEC_207, VADDUQM, do_vx_helper, gen_helper_VADDUQM) TRANS_FLAGS2(ALTIVEC_207, VPMSUMD, do_vx_helper, gen_helper_VPMSUMD) +TRANS_FLAGS2(ALTIVEC_207, VSUBUQM, do_vx_helper, gen_helper_VSUBUQM) + static bool do_vx_vmuleo(DisasContext *ctx, arg_VX *a, bool even, void (*gen_mul)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64)) { diff --git a/target/ppc/translate/vmx-ops.c.inc b/target/ppc/translate/vmx-ops.c.inc index 33e05929cb..9feef9afee 100644 --- a/target/ppc/translate/vmx-ops.c.inc +++ b/target/ppc/translate/vmx-ops.c.inc @@ -126,7 +126,7 @@ GEN_VXFORM(vsubuws, 0, 26), GEN_VXFORM_DUAL(vsubsbs, bcdtrunc, 0, 28, PPC_ALTIVEC, PPC2_ISA300), GEN_VXFORM(vsubshs, 0, 29), GEN_VXFORM_DUAL(vsubsws, xpnd04_2, 0, 30, PPC_ALTIVEC, PPC_NONE), -GEN_VXFORM_DUAL(vsubuqm, bcdtrunc, 0, 20, PPC2_ALTIVEC_207, PPC2_ISA300), +GEN_VXFORM_300(bcdtrunc, 0, 20), GEN_VXFORM_DUAL(vsubcuq, bcdutrunc, 0, 21, PPC2_ALTIVEC_207, PPC2_ISA300), GEN_VXFORM_DUAL(vsubeuqm, vsubecuq, 31, 0xFF, PPC_NONE, PPC2_ALTIVEC_207), GEN_VXFORM(vsl, 2, 7), From e6a5ad43deea6242d6b108ca12beac9465e5ab3b Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Mon, 6 Jun 2022 12:00:36 -0300 Subject: [PATCH 17/34] target/ppc: use int128.h methods in vsubecuq and vsubeuqm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And also move the insns to decodetree. Signed-off-by: Matheus Ferst Reviewed-by: Víctor Colombo Message-Id: <20220606150037.338931-7-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 4 +-- target/ppc/insn32.decode | 3 +++ target/ppc/int_helper.c | 38 +++++++---------------------- target/ppc/translate/vmx-impl.c.inc | 7 +++--- target/ppc/translate/vmx-ops.c.inc | 1 - 5 files changed, 17 insertions(+), 36 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 1c02ad85e5..04ced6ef70 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -209,8 +209,8 @@ DEF_HELPER_FLAGS_4(VADDECUQ, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_FLAGS_4(VADDEUQM, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_FLAGS_3(VADDCUQ, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(VSUBUQM, TCG_CALL_NO_RWG, void, avr, avr, avr) -DEF_HELPER_FLAGS_4(vsubecuq, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) -DEF_HELPER_FLAGS_4(vsubeuqm, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) +DEF_HELPER_FLAGS_4(VSUBECUQ, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) +DEF_HELPER_FLAGS_4(VSUBEUQM, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_FLAGS_3(vsubcuq, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_4(vsldoi, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) DEF_HELPER_FLAGS_3(vextractub, TCG_CALL_NO_RWG, void, avr, avr, i32) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index a8d3a5a8a1..5e6f3b668e 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -558,6 +558,9 @@ VADDECUQ 000100 ..... ..... ..... ..... 111101 @VA VSUBUQM 000100 ..... ..... ..... 10100000000 @VX +VSUBECUQ 000100 ..... ..... ..... ..... 111111 @VA +VSUBEUQM 000100 ..... ..... ..... ..... 111110 @VA + VEXTSB2W 000100 ..... 10000 ..... 11000000010 @VX_tb VEXTSH2W 000100 ..... 10001 ..... 11000000010 @VX_tb VEXTSB2D 000100 ..... 11000 ..... 11000000010 @VX_tb diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index 159b831d97..a93398fde4 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -2244,20 +2244,10 @@ void helper_VSUBUQM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) r->s128 = int128_sub(a->s128, b->s128); } -void helper_vsubeuqm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) +void helper_VSUBEUQM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) { -#ifdef CONFIG_INT128 - r->u128 = a->u128 + ~b->u128 + (c->u128 & 1); -#else - ppc_avr_t tmp, sum; - - avr_qw_not(&tmp, *b); - avr_qw_add(&sum, *a, tmp); - - tmp.VsrD(0) = 0; - tmp.VsrD(1) = c->VsrD(1) & 1; - avr_qw_add(r, sum, tmp); -#endif + r->s128 = int128_add(int128_add(a->s128, int128_not(b->s128)), + int128_make64(int128_getlo(c->s128) & 1)); } void helper_vsubcuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) @@ -2278,25 +2268,15 @@ void helper_vsubcuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) #endif } -void helper_vsubecuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) +void helper_VSUBECUQ(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) { -#ifdef CONFIG_INT128 - r->u128 = - (~a->u128 < ~b->u128) || - ((c->u128 & 1) && (a->u128 + ~b->u128 == (__uint128_t)-1)); -#else - int carry_in = c->VsrD(1) & 1; - int carry_out = (avr_qw_cmpu(*a, *b) > 0); - if (!carry_out && carry_in) { - ppc_avr_t tmp; - avr_qw_not(&tmp, *b); - avr_qw_add(&tmp, *a, tmp); - carry_out = ((tmp.VsrD(0) == -1ull) && (tmp.VsrD(1) == -1ull)); - } + Int128 tmp = int128_not(b->s128); + bool carry_out = int128_ult(int128_not(a->s128), tmp), + carry_in = int128_getlo(c->s128) & 1; + r->VsrD(1) = carry_out || (carry_in && int128_eq(int128_add(a->s128, tmp), + int128_makes64(-1))); r->VsrD(0) = 0; - r->VsrD(1) = carry_out; -#endif } #define BCD_PLUS_PREF_1 0xC diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index 1e665534c3..671992f7d1 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -1235,10 +1235,6 @@ GEN_VXFORM_SAT(vsubsbs, MO_8, sub, sssub, 0, 28); GEN_VXFORM_SAT(vsubshs, MO_16, sub, sssub, 0, 29); GEN_VXFORM_SAT(vsubsws, MO_32, sub, sssub, 0, 30); GEN_VXFORM(vsubcuq, 0, 21); -GEN_VXFORM3(vsubeuqm, 31, 0); -GEN_VXFORM3(vsubecuq, 31, 0); -GEN_VXFORM_DUAL(vsubeuqm, PPC_NONE, PPC2_ALTIVEC_207, \ - vsubecuq, PPC_NONE, PPC2_ALTIVEC_207) GEN_VXFORM_TRANS(vsl, 2, 7); GEN_VXFORM_TRANS(vsr, 2, 11); GEN_VXFORM_ENV(vpkuhum, 7, 0); @@ -2568,6 +2564,9 @@ static bool do_va_helper(DisasContext *ctx, arg_VA *a, TRANS_FLAGS2(ALTIVEC_207, VADDECUQ, do_va_helper, gen_helper_VADDECUQ) TRANS_FLAGS2(ALTIVEC_207, VADDEUQM, do_va_helper, gen_helper_VADDEUQM) +TRANS_FLAGS2(ALTIVEC_207, VSUBEUQM, do_va_helper, gen_helper_VSUBEUQM) +TRANS_FLAGS2(ALTIVEC_207, VSUBECUQ, do_va_helper, gen_helper_VSUBECUQ) + TRANS_FLAGS(ALTIVEC, VPERM, do_va_helper, gen_helper_VPERM) TRANS_FLAGS2(ISA300, VPERMR, do_va_helper, gen_helper_VPERMR) diff --git a/target/ppc/translate/vmx-ops.c.inc b/target/ppc/translate/vmx-ops.c.inc index 9feef9afee..9395806f3d 100644 --- a/target/ppc/translate/vmx-ops.c.inc +++ b/target/ppc/translate/vmx-ops.c.inc @@ -128,7 +128,6 @@ GEN_VXFORM(vsubshs, 0, 29), GEN_VXFORM_DUAL(vsubsws, xpnd04_2, 0, 30, PPC_ALTIVEC, PPC_NONE), GEN_VXFORM_300(bcdtrunc, 0, 20), GEN_VXFORM_DUAL(vsubcuq, bcdutrunc, 0, 21, PPC2_ALTIVEC_207, PPC2_ISA300), -GEN_VXFORM_DUAL(vsubeuqm, vsubecuq, 31, 0xFF, PPC_NONE, PPC2_ALTIVEC_207), GEN_VXFORM(vsl, 2, 7), GEN_VXFORM(vsr, 2, 11), GEN_VXFORM(vpkuhum, 7, 0), From b7d30fae5b4fe672c31f567358947990c37cd957 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Mon, 6 Jun 2022 12:00:37 -0300 Subject: [PATCH 18/34] target/ppc: use int128.h methods in vsubcuq MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And also move the insn to decodetree and remove the now unused avr_qw_not, avr_qw_cmpu, and avr_qw_add methods. Signed-off-by: Matheus Ferst Reviewed-by: Víctor Colombo Message-Id: <20220606150037.338931-8-matheus.ferst@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/helper.h | 2 +- target/ppc/insn32.decode | 1 + target/ppc/int_helper.c | 51 +++-------------------------- target/ppc/translate/vmx-impl.c.inc | 5 +-- target/ppc/translate/vmx-ops.c.inc | 2 +- 5 files changed, 9 insertions(+), 52 deletions(-) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 04ced6ef70..84a41d85b0 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -211,7 +211,7 @@ DEF_HELPER_FLAGS_3(VADDCUQ, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_3(VSUBUQM, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_4(VSUBECUQ, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) DEF_HELPER_FLAGS_4(VSUBEUQM, TCG_CALL_NO_RWG, void, avr, avr, avr, avr) -DEF_HELPER_FLAGS_3(vsubcuq, TCG_CALL_NO_RWG, void, avr, avr, avr) +DEF_HELPER_FLAGS_3(VSUBCUQ, TCG_CALL_NO_RWG, void, avr, avr, avr) DEF_HELPER_FLAGS_4(vsldoi, TCG_CALL_NO_RWG, void, avr, avr, avr, i32) DEF_HELPER_FLAGS_3(vextractub, TCG_CALL_NO_RWG, void, avr, avr, i32) DEF_HELPER_FLAGS_3(vextractuh, TCG_CALL_NO_RWG, void, avr, avr, i32) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 5e6f3b668e..65a6a42f78 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -556,6 +556,7 @@ VADDUQM 000100 ..... ..... ..... 00100000000 @VX VADDEUQM 000100 ..... ..... ..... ..... 111100 @VA VADDECUQ 000100 ..... ..... ..... ..... 111101 @VA +VSUBCUQ 000100 ..... ..... ..... 10101000000 @VX VSUBUQM 000100 ..... ..... ..... 10100000000 @VX VSUBECUQ 000100 ..... ..... ..... ..... 111111 @VA diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index a93398fde4..d905f07d02 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -2176,38 +2176,6 @@ VGENERIC_DO(popcntd, u64) #undef VGENERIC_DO -#ifndef CONFIG_INT128 - -static inline void avr_qw_not(ppc_avr_t *t, ppc_avr_t a) -{ - t->u64[0] = ~a.u64[0]; - t->u64[1] = ~a.u64[1]; -} - -static int avr_qw_cmpu(ppc_avr_t a, ppc_avr_t b) -{ - if (a.VsrD(0) < b.VsrD(0)) { - return -1; - } else if (a.VsrD(0) > b.VsrD(0)) { - return 1; - } else if (a.VsrD(1) < b.VsrD(1)) { - return -1; - } else if (a.VsrD(1) > b.VsrD(1)) { - return 1; - } else { - return 0; - } -} - -static void avr_qw_add(ppc_avr_t *t, ppc_avr_t a, ppc_avr_t b) -{ - t->VsrD(1) = a.VsrD(1) + b.VsrD(1); - t->VsrD(0) = a.VsrD(0) + b.VsrD(0) + - (~a.VsrD(1) < b.VsrD(1)); -} - -#endif - void helper_VADDUQM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { r->s128 = int128_add(a->s128, b->s128); @@ -2250,22 +2218,13 @@ void helper_VSUBEUQM(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) int128_make64(int128_getlo(c->s128) & 1)); } -void helper_vsubcuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) +void helper_VSUBCUQ(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { -#ifdef CONFIG_INT128 - r->u128 = (~a->u128 < ~b->u128) || - (a->u128 + ~b->u128 == (__uint128_t)-1); -#else - int carry = (avr_qw_cmpu(*a, *b) > 0); - if (!carry) { - ppc_avr_t tmp; - avr_qw_not(&tmp, *b); - avr_qw_add(&tmp, *a, tmp); - carry = ((tmp.VsrSD(0) == -1ull) && (tmp.VsrSD(1) == -1ull)); - } + Int128 tmp = int128_not(b->s128); + + r->VsrD(1) = int128_ult(int128_not(a->s128), tmp) || + int128_eq(int128_add(a->s128, tmp), int128_makes64(-1)); r->VsrD(0) = 0; - r->VsrD(1) = carry; -#endif } void helper_VSUBECUQ(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) diff --git a/target/ppc/translate/vmx-impl.c.inc b/target/ppc/translate/vmx-impl.c.inc index 671992f7d1..e644ad3236 100644 --- a/target/ppc/translate/vmx-impl.c.inc +++ b/target/ppc/translate/vmx-impl.c.inc @@ -1234,7 +1234,6 @@ GEN_VXFORM_SAT(vsubuws, MO_32, sub, ussub, 0, 26); GEN_VXFORM_SAT(vsubsbs, MO_8, sub, sssub, 0, 28); GEN_VXFORM_SAT(vsubshs, MO_16, sub, sssub, 0, 29); GEN_VXFORM_SAT(vsubsws, MO_32, sub, sssub, 0, 30); -GEN_VXFORM(vsubcuq, 0, 21); GEN_VXFORM_TRANS(vsl, 2, 7); GEN_VXFORM_TRANS(vsr, 2, 11); GEN_VXFORM_ENV(vpkuhum, 7, 0); @@ -2856,9 +2855,6 @@ GEN_VXFORM_DUAL(vsubuwm, PPC_ALTIVEC, PPC_NONE, \ bcdus, PPC_NONE, PPC2_ISA300) GEN_VXFORM_DUAL(vsubsbs, PPC_ALTIVEC, PPC_NONE, \ bcdtrunc, PPC_NONE, PPC2_ISA300) -GEN_VXFORM_DUAL(vsubcuq, PPC2_ALTIVEC_207, PPC_NONE, \ - bcdutrunc, PPC_NONE, PPC2_ISA300) - static void gen_vsbox(DisasContext *ctx) { @@ -3098,6 +3094,7 @@ TRANS_FLAGS2(ALTIVEC_207, VADDUQM, do_vx_helper, gen_helper_VADDUQM) TRANS_FLAGS2(ALTIVEC_207, VPMSUMD, do_vx_helper, gen_helper_VPMSUMD) +TRANS_FLAGS2(ALTIVEC_207, VSUBCUQ, do_vx_helper, gen_helper_VSUBCUQ) TRANS_FLAGS2(ALTIVEC_207, VSUBUQM, do_vx_helper, gen_helper_VSUBUQM) static bool do_vx_vmuleo(DisasContext *ctx, arg_VX *a, bool even, diff --git a/target/ppc/translate/vmx-ops.c.inc b/target/ppc/translate/vmx-ops.c.inc index 9395806f3d..a3a0fd0650 100644 --- a/target/ppc/translate/vmx-ops.c.inc +++ b/target/ppc/translate/vmx-ops.c.inc @@ -127,7 +127,7 @@ GEN_VXFORM_DUAL(vsubsbs, bcdtrunc, 0, 28, PPC_ALTIVEC, PPC2_ISA300), GEN_VXFORM(vsubshs, 0, 29), GEN_VXFORM_DUAL(vsubsws, xpnd04_2, 0, 30, PPC_ALTIVEC, PPC_NONE), GEN_VXFORM_300(bcdtrunc, 0, 20), -GEN_VXFORM_DUAL(vsubcuq, bcdutrunc, 0, 21, PPC2_ALTIVEC_207, PPC2_ISA300), +GEN_VXFORM_300(bcdutrunc, 0, 21), GEN_VXFORM(vsl, 2, 7), GEN_VXFORM(vsr, 2, 11), GEN_VXFORM(vpkuhum, 7, 0), From 95444afcab4dd7ecd117b67aae5af8f8665be0ff Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Tue, 28 Jun 2022 18:05:44 +1000 Subject: [PATCH 19/34] ppc: Define SETFIELD for the ppc target It keeps repeating, move it to the header. This uses __builtin_ffsll() to allow using the macros in #define. This is not using the QEMU's FIELD macros as this would require changing all such macros found in skiboot (the PPC PowerNV firmware). Signed-off-by: Alexey Kardashevskiy Reviewed-by: Daniel Henrique Barboza Message-Id: <20220628080544.1509428-1-aik@ozlabs.ru> Signed-off-by: Daniel Henrique Barboza --- hw/intc/pnv_xive.c | 20 -------------------- hw/intc/pnv_xive2.c | 20 -------------------- hw/pci-host/pnv_phb4.c | 16 ---------------- include/hw/pci-host/pnv_phb3_regs.h | 16 ---------------- target/ppc/cpu.h | 12 ++++++++++++ 5 files changed, 12 insertions(+), 72 deletions(-) diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c index 1ce1d7b07d..c7b75ed12e 100644 --- a/hw/intc/pnv_xive.c +++ b/hw/intc/pnv_xive.c @@ -66,26 +66,6 @@ static const XiveVstInfo vst_infos[] = { qemu_log_mask(LOG_GUEST_ERROR, "XIVE[%x] - " fmt "\n", \ (xive)->chip->chip_id, ## __VA_ARGS__); -/* - * QEMU version of the GETFIELD/SETFIELD macros - * - * TODO: It might be better to use the existing extract64() and - * deposit64() but this means that all the register definitions will - * change and become incompatible with the ones found in skiboot. - * - * Keep it as it is for now until we find a common ground. - */ -static inline uint64_t GETFIELD(uint64_t mask, uint64_t word) -{ - return (word & mask) >> ctz64(mask); -} - -static inline uint64_t SETFIELD(uint64_t mask, uint64_t word, - uint64_t value) -{ - return (word & ~mask) | ((value << ctz64(mask)) & mask); -} - /* * When PC_TCTXT_CHIPID_OVERRIDE is configured, the PC_TCTXT_CHIPID * field overrides the hardwired chip ID in the Powerbus operations diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c index f31c53c28d..f22ce5ca59 100644 --- a/hw/intc/pnv_xive2.c +++ b/hw/intc/pnv_xive2.c @@ -75,26 +75,6 @@ static const XiveVstInfo vst_infos[] = { qemu_log_mask(LOG_GUEST_ERROR, "XIVE[%x] - " fmt "\n", \ (xive)->chip->chip_id, ## __VA_ARGS__); -/* - * QEMU version of the GETFIELD/SETFIELD macros - * - * TODO: It might be better to use the existing extract64() and - * deposit64() but this means that all the register definitions will - * change and become incompatible with the ones found in skiboot. - * - * Keep it as it is for now until we find a common ground. - */ -static inline uint64_t GETFIELD(uint64_t mask, uint64_t word) -{ - return (word & mask) >> ctz64(mask); -} - -static inline uint64_t SETFIELD(uint64_t mask, uint64_t word, - uint64_t value) -{ - return (word & ~mask) | ((value << ctz64(mask)) & mask); -} - /* * TODO: Document block id override */ diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c index d225ab5b0f..67ddde4a6e 100644 --- a/hw/pci-host/pnv_phb4.c +++ b/hw/pci-host/pnv_phb4.c @@ -31,22 +31,6 @@ qemu_log_mask(LOG_GUEST_ERROR, "phb4_pec[%d:%d]: " fmt "\n", \ (pec)->chip_id, (pec)->index, ## __VA_ARGS__) -/* - * QEMU version of the GETFIELD/SETFIELD macros - * - * These are common with the PnvXive model. - */ -static inline uint64_t GETFIELD(uint64_t mask, uint64_t word) -{ - return (word & mask) >> ctz64(mask); -} - -static inline uint64_t SETFIELD(uint64_t mask, uint64_t word, - uint64_t value) -{ - return (word & ~mask) | ((value << ctz64(mask)) & mask); -} - static PCIDevice *pnv_phb4_find_cfg_dev(PnvPHB4 *phb) { PCIHostState *pci = PCI_HOST_BRIDGE(phb); diff --git a/include/hw/pci-host/pnv_phb3_regs.h b/include/hw/pci-host/pnv_phb3_regs.h index a174ef1f70..38f8ce9d74 100644 --- a/include/hw/pci-host/pnv_phb3_regs.h +++ b/include/hw/pci-host/pnv_phb3_regs.h @@ -12,22 +12,6 @@ #include "qemu/host-utils.h" -/* - * QEMU version of the GETFIELD/SETFIELD macros - * - * These are common with the PnvXive model. - */ -static inline uint64_t GETFIELD(uint64_t mask, uint64_t word) -{ - return (word & mask) >> ctz64(mask); -} - -static inline uint64_t SETFIELD(uint64_t mask, uint64_t word, - uint64_t value) -{ - return (word & ~mask) | ((value << ctz64(mask)) & mask); -} - /* * PBCQ XSCOM registers */ diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index e109b5902b..b38c651af4 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -47,6 +47,18 @@ PPC_BIT32(bs)) #define PPC_BITMASK8(bs, be) ((PPC_BIT8(bs) - PPC_BIT8(be)) | PPC_BIT8(bs)) +/* + * QEMU version of the GETFIELD/SETFIELD macros from skiboot + * + * It might be better to use the existing extract64() and + * deposit64() but this means that all the register definitions will + * change and become incompatible with the ones found in skiboot. + */ +#define MASK_TO_LSH(m) (__builtin_ffsll(m) - 1) +#define GETFIELD(m, v) (((v) & (m)) >> MASK_TO_LSH(m)) +#define SETFIELD(m, v, val) \ + (((v) & ~(m)) | ((((typeof(v))(val)) << MASK_TO_LSH(m)) & (m))) + /*****************************************************************************/ /* Exception vectors definitions */ enum { From 81b205cecf30d5e1e1c2ece1f7121855e4e0fb1e Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Wed, 22 Jun 2022 15:10:08 +1000 Subject: [PATCH 20/34] ppc/spapr: Implement H_WATCHDOG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new PAPR 2.12 defines a watchdog facility managed via the new H_WATCHDOG hypercall. This adds H_WATCHDOG support which a proposed driver for pseries uses: https://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=303120 This was tested by running QEMU with a debug kernel and command line: -append \ "pseries-wdt.timeout=60 pseries-wdt.nowayout=1 pseries-wdt.action=2" and running "echo V > /dev/watchdog0" inside the VM. Signed-off-by: Alexey Kardashevskiy Reviewed-by: Cédric Le Goater Reviewed-by: Daniel Henrique Barboza Message-Id: <20220622051008.1067464-1-aik@ozlabs.ru> Signed-off-by: Daniel Henrique Barboza --- hw/ppc/spapr.c | 4 + hw/watchdog/meson.build | 1 + hw/watchdog/spapr_watchdog.c | 274 +++++++++++++++++++++++++++++++++++ hw/watchdog/trace-events | 7 + include/hw/ppc/spapr.h | 25 +++- 5 files changed, 310 insertions(+), 1 deletion(-) create mode 100644 hw/watchdog/spapr_watchdog.c diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index fd4942e881..9a5382d527 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -898,6 +898,8 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt) add_str(hypertas, "hcall-hpt-resize"); } + add_str(hypertas, "hcall-watchdog"); + _FDT(fdt_setprop(fdt, rtas, "ibm,hypertas-functions", hypertas->str, hypertas->len)); g_string_free(hypertas, TRUE); @@ -3051,6 +3053,8 @@ static void spapr_machine_init(MachineState *machine) spapr->vof->fw_size = fw_size; /* for claim() on itself */ spapr_register_hypercall(KVMPPC_H_VOF_CLIENT, spapr_h_vof_client); } + + spapr_watchdog_init(spapr); } #define DEFAULT_KVM_TYPE "auto" diff --git a/hw/watchdog/meson.build b/hw/watchdog/meson.build index 054c403dea..8974b5cf4c 100644 --- a/hw/watchdog/meson.build +++ b/hw/watchdog/meson.build @@ -6,3 +6,4 @@ softmmu_ss.add(when: 'CONFIG_WDT_DIAG288', if_true: files('wdt_diag288.c')) softmmu_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('wdt_aspeed.c')) softmmu_ss.add(when: 'CONFIG_WDT_IMX2', if_true: files('wdt_imx2.c')) softmmu_ss.add(when: 'CONFIG_WDT_SBSA', if_true: files('sbsa_gwdt.c')) +specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_watchdog.c')) diff --git a/hw/watchdog/spapr_watchdog.c b/hw/watchdog/spapr_watchdog.c new file mode 100644 index 0000000000..55ff1f03c1 --- /dev/null +++ b/hw/watchdog/spapr_watchdog.c @@ -0,0 +1,274 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "target/ppc/cpu.h" +#include "migration/vmstate.h" +#include "trace.h" + +#include "hw/ppc/spapr.h" + +#define FIELD_BE(reg, field, start, len) \ + FIELD(reg, field, 64 - (start + len), len) + +/* + * Bits 47: "leaveOtherWatchdogsRunningOnTimeout", specified on + * the "Start watchdog" operation, + * 0 - stop out-standing watchdogs on timeout, + * 1 - leave outstanding watchdogs running on timeout + */ +FIELD_BE(PSERIES_WDTF, LEAVE_OTHER, 47, 1) + +/* Bits 48-55: "operation" */ +FIELD_BE(PSERIES_WDTF, OP, 48, 8) +#define PSERIES_WDTF_OP_START 0x1 +#define PSERIES_WDTF_OP_STOP 0x2 +#define PSERIES_WDTF_OP_QUERY 0x3 +#define PSERIES_WDTF_OP_QUERY_LPM 0x4 + +/* Bits 56-63: "timeoutAction" */ +FIELD_BE(PSERIES_WDTF, ACTION, 56, 8) +#define PSERIES_WDTF_ACTION_HARD_POWER_OFF 0x1 +#define PSERIES_WDTF_ACTION_HARD_RESTART 0x2 +#define PSERIES_WDTF_ACTION_DUMP_RESTART 0x3 + +FIELD_BE(PSERIES_WDTF, RESERVED, 0, 47) + +/* Special watchdogNumber for the "stop all watchdogs" operation */ +#define PSERIES_WDT_STOP_ALL ((uint64_t)~0) + +/* + * For the "Query watchdog capabilities" operation, a uint64 structure + * defined as: + * Bits 0-15: The minimum supported timeout in milliseconds + * Bits 16-31: The number of watchdogs supported + * Bits 32-63: Reserved + */ +FIELD_BE(PSERIES_WDTQ, MIN_TIMEOUT, 0, 16) +FIELD_BE(PSERIES_WDTQ, NUM, 16, 16) + +/* + * For the "Query watchdog LPM requirement" operation: + * 1 = The given "watchdogNumber" must be stopped prior to suspending + * 2 = The given "watchdogNumber" does not have to be stopped prior to + * suspending + */ +#define PSERIES_WDTQL_STOPPED 1 +#define PSERIES_WDTQL_QUERY_NOT_STOPPED 2 + +#define WDT_MIN_TIMEOUT 1 /* 1ms */ + +static target_ulong watchdog_stop(unsigned watchdogNumber, SpaprWatchdog *w) +{ + target_ulong ret = H_NOOP; + + if (timer_pending(&w->timer)) { + timer_del(&w->timer); + ret = H_SUCCESS; + } + trace_spapr_watchdog_stop(watchdogNumber, ret); + + return ret; +} + +static target_ulong watchdog_stop_all(SpaprMachineState *spapr) +{ + target_ulong ret = H_NOOP; + int i; + + for (i = 1; i <= ARRAY_SIZE(spapr->wds); ++i) { + target_ulong r = watchdog_stop(i, &spapr->wds[i - 1]); + + if (r != H_NOOP && r != H_SUCCESS) { + ret = r; + } + } + + return ret; +} + +static void watchdog_expired(void *pw) +{ + SpaprWatchdog *w = pw; + CPUState *cs; + SpaprMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); + unsigned num = w - spapr->wds; + + g_assert(num < ARRAY_SIZE(spapr->wds)); + trace_spapr_watchdog_expired(num, w->action); + switch (w->action) { + case PSERIES_WDTF_ACTION_HARD_POWER_OFF: + qemu_system_vmstop_request(RUN_STATE_SHUTDOWN); + break; + case PSERIES_WDTF_ACTION_HARD_RESTART: + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); + break; + case PSERIES_WDTF_ACTION_DUMP_RESTART: + CPU_FOREACH(cs) { + async_run_on_cpu(cs, spapr_do_system_reset_on_cpu, RUN_ON_CPU_NULL); + } + break; + } + if (!w->leave_others) { + watchdog_stop_all(spapr); + } +} + +static target_ulong h_watchdog(PowerPCCPU *cpu, + SpaprMachineState *spapr, + target_ulong opcode, target_ulong *args) +{ + target_ulong ret = H_SUCCESS; + target_ulong flags = args[0]; + target_ulong watchdogNumber = args[1]; /* 1-Based per PAPR */ + target_ulong timeoutInMs = args[2]; + unsigned operation = FIELD_EX64(flags, PSERIES_WDTF, OP); + unsigned timeoutAction = FIELD_EX64(flags, PSERIES_WDTF, ACTION); + SpaprWatchdog *w; + + if (FIELD_EX64(flags, PSERIES_WDTF, RESERVED)) { + return H_PARAMETER; + } + + switch (operation) { + case PSERIES_WDTF_OP_START: + if (watchdogNumber > ARRAY_SIZE(spapr->wds)) { + return H_P2; + } + if (timeoutInMs <= WDT_MIN_TIMEOUT) { + return H_P3; + } + + w = &spapr->wds[watchdogNumber - 1]; + switch (timeoutAction) { + case PSERIES_WDTF_ACTION_HARD_POWER_OFF: + case PSERIES_WDTF_ACTION_HARD_RESTART: + case PSERIES_WDTF_ACTION_DUMP_RESTART: + w->action = timeoutAction; + break; + default: + return H_PARAMETER; + } + w->leave_others = FIELD_EX64(flags, PSERIES_WDTF, LEAVE_OTHER); + timer_mod(&w->timer, + qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + timeoutInMs); + trace_spapr_watchdog_start(flags, watchdogNumber, timeoutInMs); + break; + case PSERIES_WDTF_OP_STOP: + if (watchdogNumber == PSERIES_WDT_STOP_ALL) { + ret = watchdog_stop_all(spapr); + } else if (watchdogNumber <= ARRAY_SIZE(spapr->wds)) { + ret = watchdog_stop(watchdogNumber, + &spapr->wds[watchdogNumber - 1]); + } else { + return H_P2; + } + break; + case PSERIES_WDTF_OP_QUERY: + args[0] = FIELD_DP64(0, PSERIES_WDTQ, MIN_TIMEOUT, WDT_MIN_TIMEOUT); + args[0] = FIELD_DP64(args[0], PSERIES_WDTQ, NUM, + ARRAY_SIZE(spapr->wds)); + trace_spapr_watchdog_query(args[0]); + break; + case PSERIES_WDTF_OP_QUERY_LPM: + if (watchdogNumber > ARRAY_SIZE(spapr->wds)) { + return H_P2; + } + args[0] = PSERIES_WDTQL_QUERY_NOT_STOPPED; + trace_spapr_watchdog_query_lpm(args[0]); + break; + default: + return H_PARAMETER; + } + + return ret; +} + +void spapr_watchdog_init(SpaprMachineState *spapr) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(spapr->wds); ++i) { + char name[16]; + SpaprWatchdog *w = &spapr->wds[i]; + + snprintf(name, sizeof(name) - 1, "wdt%d", i + 1); + object_initialize_child_with_props(OBJECT(spapr), name, w, + sizeof(SpaprWatchdog), + TYPE_SPAPR_WDT, + &error_fatal, NULL); + qdev_realize(DEVICE(w), NULL, &error_fatal); + } +} + +static bool watchdog_needed(void *opaque) +{ + SpaprWatchdog *w = opaque; + + return timer_pending(&w->timer); +} + +static const VMStateDescription vmstate_wdt = { + .name = "spapr_watchdog", + .version_id = 1, + .minimum_version_id = 1, + .needed = watchdog_needed, + .fields = (VMStateField[]) { + VMSTATE_TIMER(timer, SpaprWatchdog), + VMSTATE_UINT8(action, SpaprWatchdog), + VMSTATE_UINT8(leave_others, SpaprWatchdog), + VMSTATE_END_OF_LIST() + } +}; + +static void spapr_wdt_realize(DeviceState *dev, Error **errp) +{ + SpaprWatchdog *w = SPAPR_WDT(dev); + Object *o = OBJECT(dev); + + timer_init_ms(&w->timer, QEMU_CLOCK_VIRTUAL, watchdog_expired, w); + + object_property_add_uint64_ptr(o, "expire", + (uint64_t *)&w->timer.expire_time, + OBJ_PROP_FLAG_READ); + object_property_add_uint8_ptr(o, "action", &w->action, OBJ_PROP_FLAG_READ); + object_property_add_uint8_ptr(o, "leaveOtherWatchdogsRunningOnTimeout", + &w->leave_others, OBJ_PROP_FLAG_READ); +} + +static void spapr_wdt_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + + dc->realize = spapr_wdt_realize; + dc->vmsd = &vmstate_wdt; + dc->user_creatable = false; +} + +static const TypeInfo spapr_wdt_info = { + .name = TYPE_SPAPR_WDT, + .parent = TYPE_DEVICE, + .instance_size = sizeof(SpaprWatchdog), + .class_init = spapr_wdt_class_init, +}; + +static void spapr_watchdog_register_types(void) +{ + spapr_register_hypercall(H_WATCHDOG, h_watchdog); + type_register_static(&spapr_wdt_info); +} + +type_init(spapr_watchdog_register_types) diff --git a/hw/watchdog/trace-events b/hw/watchdog/trace-events index e7523e22aa..89ccbcfdfd 100644 --- a/hw/watchdog/trace-events +++ b/hw/watchdog/trace-events @@ -9,3 +9,10 @@ cmsdk_apb_watchdog_lock(uint32_t lock) "CMSDK APB watchdog: lock %" PRIu32 # wdt-aspeed.c aspeed_wdt_read(uint64_t addr, uint32_t size) "@0x%" PRIx64 " size=%d" aspeed_wdt_write(uint64_t addr, uint32_t size, uint64_t data) "@0x%" PRIx64 " size=%d value=0x%"PRIx64 + +# spapr_watchdog.c +spapr_watchdog_start(uint64_t flags, uint64_t num, uint64_t timeout) "Flags 0x%" PRIx64 " num=%" PRId64 " %" PRIu64 "ms" +spapr_watchdog_stop(uint64_t num, uint64_t ret) "num=%" PRIu64 " ret=%" PRId64 +spapr_watchdog_query(uint64_t caps) "caps=0x%" PRIx64 +spapr_watchdog_query_lpm(uint64_t caps) "caps=0x%" PRIx64 +spapr_watchdog_expired(uint64_t num, unsigned action) "num=%" PRIu64 " action=%u" diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 4ba2b27b8c..530d739b1d 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -164,6 +164,21 @@ struct SpaprMachineClass { SpaprIrq *irq; }; +#define WDT_MAX_WATCHDOGS 4 /* Maximum number of watchdog devices */ + +#define TYPE_SPAPR_WDT "spapr-wdt" +OBJECT_DECLARE_SIMPLE_TYPE(SpaprWatchdog, SPAPR_WDT) + +typedef struct SpaprWatchdog { + /*< private >*/ + DeviceState parent_obj; + /*< public >*/ + + QEMUTimer timer; + uint8_t action; /* One of PSERIES_WDTF_ACTION_xxx */ + uint8_t leave_others; /* leaveOtherWatchdogsRunningOnTimeout */ +} SpaprWatchdog; + /** * SpaprMachineState: */ @@ -264,6 +279,8 @@ struct SpaprMachineState { uint32_t FORM2_assoc_array[NUMA_NODES_MAX_NUM][FORM2_NUMA_ASSOC_SIZE]; Error *fwnmi_migration_blocker; + + SpaprWatchdog wds[WDT_MAX_WATCHDOGS]; }; #define H_SUCCESS 0 @@ -344,6 +361,7 @@ struct SpaprMachineState { #define H_P7 -60 #define H_P8 -61 #define H_P9 -62 +#define H_NOOP -63 #define H_UNSUPPORTED -67 #define H_OVERLAP -68 #define H_UNSUPPORTED_FLAG -256 @@ -564,8 +582,9 @@ struct SpaprMachineState { #define H_SCM_HEALTH 0x400 #define H_RPT_INVALIDATE 0x448 #define H_SCM_FLUSH 0x44C +#define H_WATCHDOG 0x45C -#define MAX_HCALL_OPCODE H_SCM_FLUSH +#define MAX_HCALL_OPCODE H_WATCHDOG /* The hcalls above are standardized in PAPR and implemented by pHyp * as well. @@ -1028,6 +1047,7 @@ extern const VMStateDescription vmstate_spapr_cap_large_decr; extern const VMStateDescription vmstate_spapr_cap_ccf_assist; extern const VMStateDescription vmstate_spapr_cap_fwnmi; extern const VMStateDescription vmstate_spapr_cap_rpt_invalidate; +extern const VMStateDescription vmstate_spapr_wdt; static inline uint8_t spapr_get_cap(SpaprMachineState *spapr, int cap) { @@ -1064,4 +1084,7 @@ target_ulong spapr_vof_client_architecture_support(MachineState *ms, target_ulong ovec_addr); void spapr_vof_client_dt_finalize(SpaprMachineState *spapr, void *fdt); +/* H_WATCHDOG */ +void spapr_watchdog_init(SpaprMachineState *spapr); + #endif /* HW_SPAPR_H */ From bbecdb22aede8cd465b1a414747097571c21d9c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Wed, 29 Jun 2022 13:28:54 -0300 Subject: [PATCH 21/34] target/ppc: Fix insn32.decode style issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some lines in insn32.decode have inconsistent alignment when compared to others. Fix this by changing the alignment of some lines, making it more consistent throughout the file. Signed-off-by: Víctor Colombo Reviewed-by: Richard Henderson Message-Id: <20220629162904.105060-2-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/insn32.decode | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 65a6a42f78..1a425ab28f 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -21,11 +21,11 @@ @A ...... frt:5 fra:5 frb:5 frc:5 ..... rc:1 &A &D rt ra si:int64_t -@D ...... rt:5 ra:5 si:s16 &D +@D ...... rt:5 ra:5 si:s16 &D &D_bf bf l:bool ra imm -@D_bfs ...... bf:3 - l:1 ra:5 imm:s16 &D_bf -@D_bfu ...... bf:3 - l:1 ra:5 imm:16 &D_bf +@D_bfs ...... bf:3 . l:1 ra:5 imm:s16 &D_bf +@D_bfu ...... bf:3 . l:1 ra:5 imm:16 &D_bf %dq_si 4:s12 !function=times_16 %dq_rtp 22:4 !function=times_2 @@ -38,7 +38,7 @@ @DQ_TSXP ...... ..... ra:5 ............ .... &D si=%dq_si rt=%rt_tsxp %ds_si 2:s14 !function=times_4 -@DS ...... rt:5 ra:5 .............. .. &D si=%ds_si +@DS ...... rt:5 ra:5 .............. .. &D si=%ds_si %ds_rtp 22:4 !function=times_2 @DS_rtp ...... ....0 ra:5 .............. .. &D rt=%ds_rtp si=%ds_si @@ -49,10 +49,10 @@ &DX rt d %dx_d 6:s10 16:5 0:1 -@DX ...... rt:5 ..... .......... ..... . &DX d=%dx_d +@DX ...... rt:5 ..... .......... ..... . &DX d=%dx_d &VA vrt vra vrb rc -@VA ...... vrt:5 vra:5 vrb:5 rc:5 ...... &VA +@VA ...... vrt:5 vra:5 vrb:5 rc:5 ...... &VA &VC vrt vra vrb rc:bool @VC ...... vrt:5 vra:5 vrb:5 rc:1 .......... &VC @@ -61,7 +61,7 @@ @VN ...... vrt:5 vra:5 vrb:5 .. sh:3 ...... &VN &VX vrt vra vrb -@VX ...... vrt:5 vra:5 vrb:5 .......... . &VX +@VX ...... vrt:5 vra:5 vrb:5 .......... . &VX &VX_bf bf vra vrb @VX_bf ...... bf:3 .. vra:5 vrb:5 ........... &VX_bf @@ -76,13 +76,13 @@ @VX_tb_rc ...... vrt:5 ..... vrb:5 rc:1 .......... &VX_tb_rc &VX_uim4 vrt uim vrb -@VX_uim4 ...... vrt:5 . uim:4 vrb:5 ........... &VX_uim4 +@VX_uim4 ...... vrt:5 . uim:4 vrb:5 ........... &VX_uim4 &VX_tb vrt vrb -@VX_tb ...... vrt:5 ..... vrb:5 ........... &VX_tb +@VX_tb ...... vrt:5 ..... vrb:5 ........... &VX_tb &X rt ra rb -@X ...... rt:5 ra:5 rb:5 .......... . &X +@X ...... rt:5 ra:5 rb:5 .......... . &X &X_rc rt ra rb rc:bool @X_rc ...... rt:5 ra:5 rb:5 .......... rc:1 &X_rc @@ -107,7 +107,7 @@ @X_t_bp_rc ...... rt:5 ..... ....0 .......... rc:1 &X_tb_rc rb=%x_frbp &X_bi rt bi -@X_bi ...... rt:5 bi:5 ----- .......... - &X_bi +@X_bi ...... rt:5 bi:5 ..... .......... . &X_bi &X_bf bf ra rb @X_bf ...... bf:3 .. ra:5 rb:5 .......... . &X_bf @@ -122,7 +122,7 @@ @X_bf_uim_bp ...... bf:3 . uim:6 ....0 .......... . &X_bf_uim rb=%x_frbp &X_bfl bf l:bool ra rb -@X_bfl ...... bf:3 - l:1 ra:5 rb:5 ..........- &X_bfl +@X_bfl ...... bf:3 . l:1 ra:5 rb:5 .......... . &X_bfl %x_xt 0:1 21:5 &X_imm5 xt imm:uint8_t vrb From bf8adfd88b547680aa857c46098f3a1e94373160 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Wed, 29 Jun 2022 13:28:55 -0300 Subject: [PATCH 22/34] target/ppc: Move mffscrn[i] to decodetree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Colombo Reviewed-by: Matheus Ferst Message-Id: <20220629162904.105060-3-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/insn32.decode | 8 +++ target/ppc/internal.h | 3 -- target/ppc/translate/fp-impl.c.inc | 85 +++++++++++++++--------------- target/ppc/translate/fp-ops.c.inc | 4 -- 4 files changed, 51 insertions(+), 49 deletions(-) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 1a425ab28f..f63098d024 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -124,6 +124,9 @@ &X_bfl bf l:bool ra rb @X_bfl ...... bf:3 . l:1 ra:5 rb:5 .......... . &X_bfl +&X_imm2 rt imm +@X_imm2 ...... rt:5 ..... ... imm:2 .......... . &X_imm2 + %x_xt 0:1 21:5 &X_imm5 xt imm:uint8_t vrb @X_imm5 ...... ..... imm:5 vrb:5 .......... . &X_imm5 xt=%x_xt @@ -334,6 +337,11 @@ SETBCR 011111 ..... ..... ----- 0110100000 - @X_bi SETNBC 011111 ..... ..... ----- 0111000000 - @X_bi SETNBCR 011111 ..... ..... ----- 0111100000 - @X_bi +### Move To/From FPSCR + +MFFSCRN 111111 ..... 10110 ..... 1001000111 - @X_tb +MFFSCRNI 111111 ..... 10111 ---.. 1001000111 - @X_imm2 + ### Decimal Floating-Point Arithmetic Instructions DADD 111011 ..... ..... ..... 0000000010 . @X_rc diff --git a/target/ppc/internal.h b/target/ppc/internal.h index 2add128cd1..467f3046c8 100644 --- a/target/ppc/internal.h +++ b/target/ppc/internal.h @@ -159,9 +159,6 @@ EXTRACT_HELPER(FPL, 25, 1); EXTRACT_HELPER(FPFLM, 17, 8); EXTRACT_HELPER(FPW, 16, 1); -/* mffscrni */ -EXTRACT_HELPER(RM, 11, 2); - /* addpcis */ EXTRACT_HELPER_SPLIT_3(DX, 10, 6, 6, 5, 16, 1, 1, 0, 0) #if defined(TARGET_PPC64) diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc index f9b58b844e..bcb7ec2689 100644 --- a/target/ppc/translate/fp-impl.c.inc +++ b/target/ppc/translate/fp-impl.c.inc @@ -685,71 +685,72 @@ static void gen_mffsce(DisasContext *ctx) tcg_temp_free_i64(t0); } -static void gen_helper_mffscrn(DisasContext *ctx, TCGv_i64 t1) +static TCGv_i64 place_from_fpscr(int rt, uint64_t mask) { - TCGv_i64 t0 = tcg_temp_new_i64(); - TCGv_i32 mask = tcg_const_i32(0x0001); + TCGv_i64 fpscr = tcg_temp_new_i64(); + TCGv_i64 fpscr_masked = tcg_temp_new_i64(); - gen_reset_fpstatus(); - tcg_gen_extu_tl_i64(t0, cpu_fpscr); - tcg_gen_andi_i64(t0, t0, FP_DRN | FP_ENABLES | FP_RN); - set_fpr(rD(ctx->opcode), t0); + tcg_gen_extu_tl_i64(fpscr, cpu_fpscr); + tcg_gen_andi_i64(fpscr_masked, fpscr, mask); + set_fpr(rt, fpscr_masked); - /* Mask FPSCR value to clear RN. */ - tcg_gen_andi_i64(t0, t0, ~FP_RN); + tcg_temp_free_i64(fpscr_masked); - /* Merge RN into FPSCR value. */ - tcg_gen_or_i64(t0, t0, t1); - - gen_helper_store_fpscr(cpu_env, t0, mask); - - tcg_temp_free_i32(mask); - tcg_temp_free_i64(t0); + return fpscr; } -/* mffscrn */ -static void gen_mffscrn(DisasContext *ctx) +static void store_fpscr_masked(TCGv_i64 fpscr, uint64_t clear_mask, + TCGv_i64 set_mask, uint32_t store_mask) { - TCGv_i64 t1; + TCGv_i64 fpscr_masked = tcg_temp_new_i64(); + TCGv_i32 st_mask = tcg_constant_i32(store_mask); - if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) { - return gen_mffs(ctx); - } + tcg_gen_andi_i64(fpscr_masked, fpscr, ~clear_mask); + tcg_gen_or_i64(fpscr_masked, fpscr_masked, set_mask); + gen_helper_store_fpscr(cpu_env, fpscr_masked, st_mask); - if (unlikely(!ctx->fpu_enabled)) { - gen_exception(ctx, POWERPC_EXCP_FPU); - return; - } + tcg_temp_free_i64(fpscr_masked); +} + +static bool trans_MFFSCRN(DisasContext *ctx, arg_X_tb *a) +{ + TCGv_i64 t1, fpscr; + + REQUIRE_INSNS_FLAGS2(ctx, ISA300); + REQUIRE_FPU(ctx); t1 = tcg_temp_new_i64(); - get_fpr(t1, rB(ctx->opcode)); - /* Mask FRB to get just RN. */ + get_fpr(t1, a->rb); tcg_gen_andi_i64(t1, t1, FP_RN); - gen_helper_mffscrn(ctx, t1); + gen_reset_fpstatus(); + fpscr = place_from_fpscr(a->rt, FP_DRN | FP_ENABLES | FP_NI | FP_RN); + store_fpscr_masked(fpscr, FP_RN, t1, 0x0001); tcg_temp_free_i64(t1); + tcg_temp_free_i64(fpscr); + + return true; } -/* mffscrni */ -static void gen_mffscrni(DisasContext *ctx) +static bool trans_MFFSCRNI(DisasContext *ctx, arg_X_imm2 *a) { - TCGv_i64 t1; + TCGv_i64 t1, fpscr; - if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) { - return gen_mffs(ctx); - } + REQUIRE_INSNS_FLAGS2(ctx, ISA300); + REQUIRE_FPU(ctx); - if (unlikely(!ctx->fpu_enabled)) { - gen_exception(ctx, POWERPC_EXCP_FPU); - return; - } + t1 = tcg_temp_new_i64(); + tcg_gen_movi_i64(t1, a->imm); - t1 = tcg_const_i64((uint64_t)RM(ctx->opcode)); - - gen_helper_mffscrn(ctx, t1); + gen_reset_fpstatus(); + fpscr = place_from_fpscr(a->rt, FP_DRN | FP_ENABLES | FP_NI | FP_RN); + store_fpscr_masked(fpscr, FP_RN, t1, 0x0001); tcg_temp_free_i64(t1); + tcg_temp_free_i64(fpscr); + + return true; } /* mtfsb0 */ diff --git a/target/ppc/translate/fp-ops.c.inc b/target/ppc/translate/fp-ops.c.inc index 0538ab2d2d..a27a1be9f5 100644 --- a/target/ppc/translate/fp-ops.c.inc +++ b/target/ppc/translate/fp-ops.c.inc @@ -79,10 +79,6 @@ GEN_HANDLER_E_2(mffsce, 0x3F, 0x07, 0x12, 0x01, 0x00000000, PPC_FLOAT, PPC2_ISA300), GEN_HANDLER_E_2(mffsl, 0x3F, 0x07, 0x12, 0x18, 0x00000000, PPC_FLOAT, PPC2_ISA300), -GEN_HANDLER_E_2(mffscrn, 0x3F, 0x07, 0x12, 0x16, 0x00000000, PPC_FLOAT, - PPC_NONE), -GEN_HANDLER_E_2(mffscrni, 0x3F, 0x07, 0x12, 0x17, 0x00000000, PPC_FLOAT, - PPC_NONE), GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT), GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT), GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00000000, PPC_FLOAT), From 394c2e2fda70da722f20fb60412d6c0ca4bfaa03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Wed, 29 Jun 2022 13:28:56 -0300 Subject: [PATCH 23/34] target/ppc: Move mffsce to decodetree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Colombo Reviewed-by: Matheus Ferst Message-Id: <20220629162904.105060-4-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/insn32.decode | 4 +++ target/ppc/translate/fp-impl.c.inc | 46 +++++++++++------------------- target/ppc/translate/fp-ops.c.inc | 2 -- 3 files changed, 20 insertions(+), 32 deletions(-) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index f63098d024..7cb7faabac 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -94,6 +94,9 @@ @X_tp_a_bp_rc ...... ....0 ra:5 ....0 .......... rc:1 &X_rc rt=%x_frtp rb=%x_frbp +&X_t rt +@X_t ...... rt:5 ..... ..... .......... . &X_t + &X_tb rt rb @X_tb ...... rt:5 ..... rb:5 .......... . &X_tb @@ -339,6 +342,7 @@ SETNBCR 011111 ..... ..... ----- 0111100000 - @X_bi ### Move To/From FPSCR +MFFSCE 111111 ..... 00001 ----- 1001000111 - @X_t MFFSCRN 111111 ..... 10110 ..... 1001000111 - @X_tb MFFSCRNI 111111 ..... 10111 ---.. 1001000111 - @X_imm2 diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc index bcb7ec2689..64e26b9b42 100644 --- a/target/ppc/translate/fp-impl.c.inc +++ b/target/ppc/translate/fp-impl.c.inc @@ -655,36 +655,6 @@ static void gen_mffsl(DisasContext *ctx) tcg_temp_free_i64(t0); } -/* mffsce */ -static void gen_mffsce(DisasContext *ctx) -{ - TCGv_i64 t0; - TCGv_i32 mask; - - if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) { - return gen_mffs(ctx); - } - - if (unlikely(!ctx->fpu_enabled)) { - gen_exception(ctx, POWERPC_EXCP_FPU); - return; - } - - t0 = tcg_temp_new_i64(); - - gen_reset_fpstatus(); - tcg_gen_extu_tl_i64(t0, cpu_fpscr); - set_fpr(rD(ctx->opcode), t0); - - /* Clear exception enable bits in the FPSCR. */ - tcg_gen_andi_i64(t0, t0, ~FP_ENABLES); - mask = tcg_const_i32(0x0003); - gen_helper_store_fpscr(cpu_env, t0, mask); - - tcg_temp_free_i32(mask); - tcg_temp_free_i64(t0); -} - static TCGv_i64 place_from_fpscr(int rt, uint64_t mask) { TCGv_i64 fpscr = tcg_temp_new_i64(); @@ -712,6 +682,22 @@ static void store_fpscr_masked(TCGv_i64 fpscr, uint64_t clear_mask, tcg_temp_free_i64(fpscr_masked); } +static bool trans_MFFSCE(DisasContext *ctx, arg_X_t *a) +{ + TCGv_i64 fpscr; + + REQUIRE_INSNS_FLAGS2(ctx, ISA300); + REQUIRE_FPU(ctx); + + gen_reset_fpstatus(); + fpscr = place_from_fpscr(a->rt, UINT64_MAX); + store_fpscr_masked(fpscr, FP_ENABLES, tcg_constant_i64(0), 0x0003); + + tcg_temp_free_i64(fpscr); + + return true; +} + static bool trans_MFFSCRN(DisasContext *ctx, arg_X_tb *a) { TCGv_i64 t1, fpscr; diff --git a/target/ppc/translate/fp-ops.c.inc b/target/ppc/translate/fp-ops.c.inc index a27a1be9f5..a76943b8bf 100644 --- a/target/ppc/translate/fp-ops.c.inc +++ b/target/ppc/translate/fp-ops.c.inc @@ -75,8 +75,6 @@ GEN_HANDLER_E(fmrgew, 0x3F, 0x06, 0x1E, 0x00000001, PPC_NONE, PPC2_VSX207), GEN_HANDLER_E(fmrgow, 0x3F, 0x06, 0x1A, 0x00000001, PPC_NONE, PPC2_VSX207), GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT), GEN_HANDLER_E_2(mffs, 0x3F, 0x07, 0x12, 0x00, 0x00000000, PPC_FLOAT, PPC_NONE), -GEN_HANDLER_E_2(mffsce, 0x3F, 0x07, 0x12, 0x01, 0x00000000, PPC_FLOAT, - PPC2_ISA300), GEN_HANDLER_E_2(mffsl, 0x3F, 0x07, 0x12, 0x18, 0x00000000, PPC_FLOAT, PPC2_ISA300), GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT), From 3e5bce70efe6bd1f684efbb21fd2a316cbf0657e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Wed, 29 Jun 2022 13:28:57 -0300 Subject: [PATCH 24/34] target/ppc: Move mffsl to decodetree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Colombo Reviewed-by: Matheus Ferst Message-Id: <20220629162904.105060-5-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/insn32.decode | 1 + target/ppc/translate/fp-impl.c.inc | 38 +++++++++++++----------------- target/ppc/translate/fp-ops.c.inc | 2 -- 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 7cb7faabac..6b68689357 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -345,6 +345,7 @@ SETNBCR 011111 ..... ..... ----- 0111100000 - @X_bi MFFSCE 111111 ..... 00001 ----- 1001000111 - @X_t MFFSCRN 111111 ..... 10110 ..... 1001000111 - @X_tb MFFSCRNI 111111 ..... 10111 ---.. 1001000111 - @X_imm2 +MFFSL 111111 ..... 11000 ----- 1001000111 - @X_t ### Decimal Floating-Point Arithmetic Instructions diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc index 64e26b9b42..4f4d57c611 100644 --- a/target/ppc/translate/fp-impl.c.inc +++ b/target/ppc/translate/fp-impl.c.inc @@ -633,28 +633,6 @@ static void gen_mffs(DisasContext *ctx) tcg_temp_free_i64(t0); } -/* mffsl */ -static void gen_mffsl(DisasContext *ctx) -{ - TCGv_i64 t0; - - if (unlikely(!(ctx->insns_flags2 & PPC2_ISA300))) { - return gen_mffs(ctx); - } - - if (unlikely(!ctx->fpu_enabled)) { - gen_exception(ctx, POWERPC_EXCP_FPU); - return; - } - t0 = tcg_temp_new_i64(); - gen_reset_fpstatus(); - tcg_gen_extu_tl_i64(t0, cpu_fpscr); - /* Mask everything except mode, status, and enables. */ - tcg_gen_andi_i64(t0, t0, FP_DRN | FP_STATUS | FP_ENABLES | FP_RN); - set_fpr(rD(ctx->opcode), t0); - tcg_temp_free_i64(t0); -} - static TCGv_i64 place_from_fpscr(int rt, uint64_t mask) { TCGv_i64 fpscr = tcg_temp_new_i64(); @@ -739,6 +717,22 @@ static bool trans_MFFSCRNI(DisasContext *ctx, arg_X_imm2 *a) return true; } +static bool trans_MFFSL(DisasContext *ctx, arg_X_t *a) +{ + TCGv_i64 fpscr; + + REQUIRE_INSNS_FLAGS2(ctx, ISA300); + REQUIRE_FPU(ctx); + + gen_reset_fpstatus(); + fpscr = place_from_fpscr(a->rt, + FP_DRN | FP_STATUS | FP_ENABLES | FP_NI | FP_RN); + + tcg_temp_free_i64(fpscr); + + return true; +} + /* mtfsb0 */ static void gen_mtfsb0(DisasContext *ctx) { diff --git a/target/ppc/translate/fp-ops.c.inc b/target/ppc/translate/fp-ops.c.inc index a76943b8bf..f8c35124ae 100644 --- a/target/ppc/translate/fp-ops.c.inc +++ b/target/ppc/translate/fp-ops.c.inc @@ -75,8 +75,6 @@ GEN_HANDLER_E(fmrgew, 0x3F, 0x06, 0x1E, 0x00000001, PPC_NONE, PPC2_VSX207), GEN_HANDLER_E(fmrgow, 0x3F, 0x06, 0x1A, 0x00000001, PPC_NONE, PPC2_VSX207), GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT), GEN_HANDLER_E_2(mffs, 0x3F, 0x07, 0x12, 0x00, 0x00000000, PPC_FLOAT, PPC_NONE), -GEN_HANDLER_E_2(mffsl, 0x3F, 0x07, 0x12, 0x18, 0x00000000, PPC_FLOAT, - PPC2_ISA300), GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT), GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT), GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00000000, PPC_FLOAT), From f80d04d548d97fbbf5d4084dcc7d59a9bba387ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Wed, 29 Jun 2022 13:28:58 -0300 Subject: [PATCH 25/34] target/ppc: Move mffs[.] to decodetree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Colombo Reviewed-by: Matheus Ferst Message-Id: <20220629162904.105060-6-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/insn32.decode | 4 ++++ target/ppc/translate/fp-impl.c.inc | 35 +++++++++++++++--------------- target/ppc/translate/fp-ops.c.inc | 1 - 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 6b68689357..7d219f000f 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -100,6 +100,9 @@ &X_tb rt rb @X_tb ...... rt:5 ..... rb:5 .......... . &X_tb +&X_t_rc rt rc:bool +@X_t_rc ...... rt:5 ..... ..... .......... rc:1 &X_t_rc + &X_tb_rc rt rb rc:bool @X_tb_rc ...... rt:5 ..... rb:5 .......... rc:1 &X_tb_rc @@ -342,6 +345,7 @@ SETNBCR 011111 ..... ..... ----- 0111100000 - @X_bi ### Move To/From FPSCR +MFFS 111111 ..... 00000 ----- 1001000111 . @X_t_rc MFFSCE 111111 ..... 00001 ----- 1001000111 - @X_t MFFSCRN 111111 ..... 10110 ..... 1001000111 - @X_tb MFFSCRNI 111111 ..... 10111 ---.. 1001000111 - @X_imm2 diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc index 4f4d57c611..d6231358f8 100644 --- a/target/ppc/translate/fp-impl.c.inc +++ b/target/ppc/translate/fp-impl.c.inc @@ -615,24 +615,6 @@ static void gen_mcrfs(DisasContext *ctx) tcg_temp_free_i64(tnew_fpscr); } -/* mffs */ -static void gen_mffs(DisasContext *ctx) -{ - TCGv_i64 t0; - if (unlikely(!ctx->fpu_enabled)) { - gen_exception(ctx, POWERPC_EXCP_FPU); - return; - } - t0 = tcg_temp_new_i64(); - gen_reset_fpstatus(); - tcg_gen_extu_tl_i64(t0, cpu_fpscr); - set_fpr(rD(ctx->opcode), t0); - if (unlikely(Rc(ctx->opcode))) { - gen_set_cr1_from_fpscr(ctx); - } - tcg_temp_free_i64(t0); -} - static TCGv_i64 place_from_fpscr(int rt, uint64_t mask) { TCGv_i64 fpscr = tcg_temp_new_i64(); @@ -660,6 +642,23 @@ static void store_fpscr_masked(TCGv_i64 fpscr, uint64_t clear_mask, tcg_temp_free_i64(fpscr_masked); } +static bool trans_MFFS(DisasContext *ctx, arg_X_t_rc *a) +{ + TCGv_i64 fpscr; + + REQUIRE_FPU(ctx); + + gen_reset_fpstatus(); + fpscr = place_from_fpscr(a->rt, UINT64_MAX); + if (a->rc) { + gen_set_cr1_from_fpscr(ctx); + } + + tcg_temp_free_i64(fpscr); + + return true; +} + static bool trans_MFFSCE(DisasContext *ctx, arg_X_t *a) { TCGv_i64 fpscr; diff --git a/target/ppc/translate/fp-ops.c.inc b/target/ppc/translate/fp-ops.c.inc index f8c35124ae..1b65f5ab73 100644 --- a/target/ppc/translate/fp-ops.c.inc +++ b/target/ppc/translate/fp-ops.c.inc @@ -74,7 +74,6 @@ GEN_HANDLER_E(fcpsgn, 0x3F, 0x08, 0x00, 0x00000000, PPC_NONE, PPC2_ISA205), GEN_HANDLER_E(fmrgew, 0x3F, 0x06, 0x1E, 0x00000001, PPC_NONE, PPC2_VSX207), GEN_HANDLER_E(fmrgow, 0x3F, 0x06, 0x1A, 0x00000001, PPC_NONE, PPC2_VSX207), GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT), -GEN_HANDLER_E_2(mffs, 0x3F, 0x07, 0x12, 0x00, 0x00000000, PPC_FLOAT, PPC_NONE), GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT), GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT), GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00000000, PPC_FLOAT), From 6cef305fe7d9982d68b23923fc1f2ab0fd3eac56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Wed, 29 Jun 2022 13:28:59 -0300 Subject: [PATCH 26/34] target/ppc: Implement mffscdrn[i] instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Colombo Reviewed-by: Matheus Ferst Message-Id: <20220629162904.105060-7-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/insn32.decode | 5 ++++ target/ppc/translate/fp-impl.c.inc | 41 ++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 7d219f000f..e5770bcc16 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -133,6 +133,9 @@ &X_imm2 rt imm @X_imm2 ...... rt:5 ..... ... imm:2 .......... . &X_imm2 +&X_imm3 rt imm +@X_imm3 ...... rt:5 ..... .. imm:3 .......... . &X_imm3 + %x_xt 0:1 21:5 &X_imm5 xt imm:uint8_t vrb @X_imm5 ...... ..... imm:5 vrb:5 .......... . &X_imm5 xt=%x_xt @@ -348,7 +351,9 @@ SETNBCR 011111 ..... ..... ----- 0111100000 - @X_bi MFFS 111111 ..... 00000 ----- 1001000111 . @X_t_rc MFFSCE 111111 ..... 00001 ----- 1001000111 - @X_t MFFSCRN 111111 ..... 10110 ..... 1001000111 - @X_tb +MFFSCDRN 111111 ..... 10100 ..... 1001000111 - @X_tb MFFSCRNI 111111 ..... 10111 ---.. 1001000111 - @X_imm2 +MFFSCDRNI 111111 ..... 10101 --... 1001000111 - @X_imm3 MFFSL 111111 ..... 11000 ----- 1001000111 - @X_t ### Decimal Floating-Point Arithmetic Instructions diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc index d6231358f8..319513d001 100644 --- a/target/ppc/translate/fp-impl.c.inc +++ b/target/ppc/translate/fp-impl.c.inc @@ -696,6 +696,27 @@ static bool trans_MFFSCRN(DisasContext *ctx, arg_X_tb *a) return true; } +static bool trans_MFFSCDRN(DisasContext *ctx, arg_X_tb *a) +{ + TCGv_i64 t1, fpscr; + + REQUIRE_INSNS_FLAGS2(ctx, ISA300); + REQUIRE_FPU(ctx); + + t1 = tcg_temp_new_i64(); + get_fpr(t1, a->rb); + tcg_gen_andi_i64(t1, t1, FP_DRN); + + gen_reset_fpstatus(); + fpscr = place_from_fpscr(a->rt, FP_DRN | FP_ENABLES | FP_NI | FP_RN); + store_fpscr_masked(fpscr, FP_DRN, t1, 0x0100); + + tcg_temp_free_i64(t1); + tcg_temp_free_i64(fpscr); + + return true; +} + static bool trans_MFFSCRNI(DisasContext *ctx, arg_X_imm2 *a) { TCGv_i64 t1, fpscr; @@ -716,6 +737,26 @@ static bool trans_MFFSCRNI(DisasContext *ctx, arg_X_imm2 *a) return true; } +static bool trans_MFFSCDRNI(DisasContext *ctx, arg_X_imm3 *a) +{ + TCGv_i64 t1, fpscr; + + REQUIRE_INSNS_FLAGS2(ctx, ISA300); + REQUIRE_FPU(ctx); + + t1 = tcg_temp_new_i64(); + tcg_gen_movi_i64(t1, (uint64_t)a->imm << FPSCR_DRN0); + + gen_reset_fpstatus(); + fpscr = place_from_fpscr(a->rt, FP_DRN | FP_ENABLES | FP_NI | FP_RN); + store_fpscr_masked(fpscr, FP_DRN, t1, 0x0100); + + tcg_temp_free_i64(t1); + tcg_temp_free_i64(fpscr); + + return true; +} + static bool trans_MFFSL(DisasContext *ctx, arg_X_t *a) { TCGv_i64 fpscr; From 7141a173c83414c4e1a4cda2d9ff1eaa6dccfee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Colombo?= Date: Wed, 29 Jun 2022 13:29:00 -0300 Subject: [PATCH 27/34] tests/tcg/ppc64: Add mffsce test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add mffsce test to check both the return value and the new fpscr stored in the cpu. Signed-off-by: Víctor Colombo Reviewed-by: Matheus Ferst Message-Id: <20220629162904.105060-8-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- tests/tcg/ppc64/Makefile.target | 1 + tests/tcg/ppc64le/Makefile.target | 1 + tests/tcg/ppc64le/mffsce.c | 37 +++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 tests/tcg/ppc64le/mffsce.c diff --git a/tests/tcg/ppc64/Makefile.target b/tests/tcg/ppc64/Makefile.target index babd209573..331fae628e 100644 --- a/tests/tcg/ppc64/Makefile.target +++ b/tests/tcg/ppc64/Makefile.target @@ -11,6 +11,7 @@ endif $(PPC64_TESTS): CFLAGS += -mpower8-vector PPC64_TESTS += mtfsf +PPC64_TESTS += mffsce ifneq ($(CROSS_CC_HAS_POWER10),) PPC64_TESTS += byte_reverse sha512-vector diff --git a/tests/tcg/ppc64le/Makefile.target b/tests/tcg/ppc64le/Makefile.target index 5b0eb5e870..6ca3003f02 100644 --- a/tests/tcg/ppc64le/Makefile.target +++ b/tests/tcg/ppc64le/Makefile.target @@ -24,6 +24,7 @@ run-sha512-vector: QEMU_OPTS+=-cpu POWER10 run-plugin-sha512-vector-with-%: QEMU_OPTS+=-cpu POWER10 PPC64LE_TESTS += mtfsf +PPC64LE_TESTS += mffsce PPC64LE_TESTS += signal_save_restore_xer PPC64LE_TESTS += xxspltw diff --git a/tests/tcg/ppc64le/mffsce.c b/tests/tcg/ppc64le/mffsce.c new file mode 100644 index 0000000000..20d882cb45 --- /dev/null +++ b/tests/tcg/ppc64le/mffsce.c @@ -0,0 +1,37 @@ +#include +#include +#include + +#define MTFSF(FLM, FRB) asm volatile ("mtfsf %0, %1" :: "i" (FLM), "f" (FRB)) +#define MFFS(FRT) asm("mffs %0" : "=f" (FRT)) +#define MFFSCE(FRT) asm("mffsce %0" : "=f" (FRT)) + +#define PPC_BIT_NR(nr) (63 - (nr)) + +#define FP_VE (1ull << PPC_BIT_NR(56)) +#define FP_UE (1ull << PPC_BIT_NR(58)) +#define FP_ZE (1ull << PPC_BIT_NR(59)) +#define FP_XE (1ull << PPC_BIT_NR(60)) +#define FP_NI (1ull << PPC_BIT_NR(61)) +#define FP_RN1 (1ull << PPC_BIT_NR(63)) + +int main(void) +{ + uint64_t frt, fpscr; + uint64_t test_value = FP_VE | FP_UE | FP_ZE | + FP_XE | FP_NI | FP_RN1; + MTFSF(0b11111111, test_value); /* set test value to cpu fpscr */ + MFFSCE(frt); + MFFS(fpscr); /* read the value that mffsce stored to cpu fpscr */ + + /* the returned value should be as the cpu fpscr was before */ + assert((frt & 0xff) == test_value); + + /* + * the cpu fpscr last 3 bits should be unchanged + * and enable bits should be unset + */ + assert((fpscr & 0xff) == (test_value & 0x7)); + + return 0; +} From 4dc5f8abdc8e0024bc4cef80b3b2db2c853d8df7 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Wed, 29 Jun 2022 13:29:01 -0300 Subject: [PATCH 28/34] target/ppc: Add flag for ISA v2.06 BCDA instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds an insns_flags2 for the BCD assist instructions introduced in Power ISA 2.06. These instructions are not listed in the manuals for e5500[1] and e6500[2], so the flag is only added for POWER7/8/9/10 models. [1] https://www.nxp.com/files-static/32bit/doc/ref_manual/EREF_RM.pdf [2] https://www.nxp.com/docs/en/reference-manual/E6500RM.pdf Signed-off-by: Matheus Ferst Signed-off-by: Víctor Colombo Reviewed-by: Richard Henderson Message-Id: <20220629162904.105060-9-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu.h | 5 ++++- target/ppc/cpu_init.c | 10 ++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index b38c651af4..7aaff9dcc5 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -2289,6 +2289,8 @@ enum { PPC2_ISA310 = 0x0000000000100000ULL, /* lwsync instruction */ PPC2_MEM_LWSYNC = 0x0000000000200000ULL, + /* ISA 2.06 BCD assist instructions */ + PPC2_BCDA_ISA206 = 0x0000000000400000ULL, #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \ PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \ @@ -2297,7 +2299,8 @@ enum { PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | \ PPC2_ALTIVEC_207 | PPC2_ISA207S | PPC2_DFP | \ PPC2_FP_CVT_S64 | PPC2_TM | PPC2_PM_ISA206 | \ - PPC2_ISA300 | PPC2_ISA310 | PPC2_MEM_LWSYNC) + PPC2_ISA300 | PPC2_ISA310 | PPC2_MEM_LWSYNC | \ + PPC2_BCDA_ISA206) }; /*****************************************************************************/ diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index c16cb8dbe7..bdfb1a5c6f 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -5985,7 +5985,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64 | - PPC2_PM_ISA206 | PPC2_MEM_LWSYNC; + PPC2_PM_ISA206 | PPC2_MEM_LWSYNC | PPC2_BCDA_ISA206; pcc->msr_mask = (1ull << MSR_SF) | (1ull << MSR_VR) | (1ull << MSR_VSX) | @@ -6159,7 +6159,8 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | - PPC2_TM | PPC2_PM_ISA206 | PPC2_MEM_LWSYNC; + PPC2_TM | PPC2_PM_ISA206 | PPC2_MEM_LWSYNC | + PPC2_BCDA_ISA206; pcc->msr_mask = (1ull << MSR_SF) | (1ull << MSR_HV) | (1ull << MSR_TM) | @@ -6379,7 +6380,8 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | - PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL | PPC2_MEM_LWSYNC; + PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL | PPC2_MEM_LWSYNC | + PPC2_BCDA_ISA206; pcc->msr_mask = (1ull << MSR_SF) | (1ull << MSR_HV) | (1ull << MSR_TM) | @@ -6597,7 +6599,7 @@ POWERPC_FAMILY(POWER10)(ObjectClass *oc, void *data) PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_TM | PPC2_ISA300 | PPC2_PRCNTL | PPC2_ISA310 | - PPC2_MEM_LWSYNC; + PPC2_MEM_LWSYNC | PPC2_BCDA_ISA206; pcc->msr_mask = (1ull << MSR_SF) | (1ull << MSR_HV) | (1ull << MSR_TM) | From 6addef4d272684ba624c9fcaf66bc67e5fc4a93f Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Wed, 29 Jun 2022 13:29:02 -0300 Subject: [PATCH 29/34] target/ppc: implement addg6s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements the following Power ISA v2.06 instruction: addg6s: Add and Generate Sixes Signed-off-by: Matheus Ferst Signed-off-by: Víctor Colombo Reviewed-by: Víctor Colombo Message-Id: <20220629162904.105060-10-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/insn32.decode | 4 +++ target/ppc/translate/fixedpoint-impl.c.inc | 37 ++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index e5770bcc16..af8ba9ca9b 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -311,6 +311,10 @@ CNTTZDM 011111 ..... ..... ..... 1000111011 - @X PDEPD 011111 ..... ..... ..... 0010011100 - @X PEXTD 011111 ..... ..... ..... 0010111100 - @X +## BCD Assist + +ADDG6S 011111 ..... ..... ..... - 001001010 - @X + ### Float-Point Load Instructions LFS 110000 ..... ..... ................ @D diff --git a/target/ppc/translate/fixedpoint-impl.c.inc b/target/ppc/translate/fixedpoint-impl.c.inc index 1aab32be03..490e49cfc7 100644 --- a/target/ppc/translate/fixedpoint-impl.c.inc +++ b/target/ppc/translate/fixedpoint-impl.c.inc @@ -492,3 +492,40 @@ static bool trans_PEXTD(DisasContext *ctx, arg_X *a) #endif return true; } + +static bool trans_ADDG6S(DisasContext *ctx, arg_X *a) +{ + const uint64_t carry_bits = 0x1111111111111111ULL; + TCGv t0, t1, carry, zero = tcg_constant_tl(0); + + REQUIRE_INSNS_FLAGS2(ctx, BCDA_ISA206); + + t0 = tcg_temp_new(); + t1 = tcg_const_tl(0); + carry = tcg_const_tl(0); + + for (int i = 0; i < 16; i++) { + tcg_gen_shri_tl(t0, cpu_gpr[a->ra], i * 4); + tcg_gen_andi_tl(t0, t0, 0xf); + tcg_gen_add_tl(t1, t1, t0); + + tcg_gen_shri_tl(t0, cpu_gpr[a->rb], i * 4); + tcg_gen_andi_tl(t0, t0, 0xf); + tcg_gen_add_tl(t1, t1, t0); + + tcg_gen_andi_tl(t1, t1, 0x10); + tcg_gen_setcond_tl(TCG_COND_NE, t1, t1, zero); + + tcg_gen_shli_tl(t0, t1, i * 4); + tcg_gen_or_tl(carry, carry, t0); + } + + tcg_gen_xori_tl(carry, carry, (target_long)carry_bits); + tcg_gen_muli_tl(cpu_gpr[a->rt], carry, 6); + + tcg_temp_free(t0); + tcg_temp_free(t1); + tcg_temp_free(carry); + + return true; +} From 38d3690bda3fe217ea72903859907916a5429c6e Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Wed, 29 Jun 2022 13:29:03 -0300 Subject: [PATCH 30/34] target/ppc: implement cbcdtd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements the Convert Binary Coded Decimal To Declets instruction. Since libdecnumber doesn't expose the methods for direct conversion (decDigitsToDPD, BCD2DPD, etc.), the BCD values are converted to decimal32 format, from which the declets are extracted. Where the behavior is undefined, we try to match the result observed in a POWER9 DD2.3. Reviewed-by: Richard Henderson Signed-off-by: Matheus Ferst Signed-off-by: Víctor Colombo Message-Id: <20220629162904.105060-11-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/dfp_helper.c | 39 ++++++++++++++++++++++ target/ppc/helper.h | 1 + target/ppc/insn32.decode | 4 +++ target/ppc/translate/fixedpoint-impl.c.inc | 7 ++++ 4 files changed, 51 insertions(+) diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c index 0d01ac3de0..db9e994c8c 100644 --- a/target/ppc/dfp_helper.c +++ b/target/ppc/dfp_helper.c @@ -1391,3 +1391,42 @@ DFP_HELPER_SHIFT(DSCLI, 64, 1) DFP_HELPER_SHIFT(DSCLIQ, 128, 1) DFP_HELPER_SHIFT(DSCRI, 64, 0) DFP_HELPER_SHIFT(DSCRIQ, 128, 0) + +target_ulong helper_CBCDTD(target_ulong s) +{ + uint64_t res = 0; + uint32_t dec32; + uint8_t bcd[6]; + int w, i, offs; + decNumber a; + decContext context; + + decContextDefault(&context, DEC_INIT_DECIMAL32); + + for (w = 1; w >= 0; w--) { + res <<= 32; + decNumberZero(&a); + /* Extract each BCD field of word "w" */ + for (i = 5; i >= 0; i--) { + offs = 4 * (5 - i) + 32 * w; + bcd[i] = extract64(s, offs, 4); + if (bcd[i] > 9) { + /* + * If the field value is greater than 9, the results are + * undefined. We could use a fixed value like 0 or 9, but + * an and with 9 seems to better match the hardware behavior. + */ + bcd[i] &= 9; + } + } + + /* Create a decNumber with the BCD values and convert to decimal32 */ + decNumberSetBCD(&a, bcd, 6); + decimal32FromNumber((decimal32 *)&dec32, &a, &context); + + /* Extract the two declets from the decimal32 value */ + res |= dec32 & 0xfffff; + } + + return res; +} diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 84a41d85b0..583c8dd0c2 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -54,6 +54,7 @@ DEF_HELPER_3(sraw, tl, env, tl, tl) DEF_HELPER_FLAGS_2(CFUGED, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(PDEPD, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(PEXTD, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_1(CBCDTD, TCG_CALL_NO_RWG_SE, tl, tl) #if defined(TARGET_PPC64) DEF_HELPER_FLAGS_2(cmpeqb, TCG_CALL_NO_RWG_SE, i32, tl, tl) DEF_HELPER_FLAGS_1(popcntw, TCG_CALL_NO_RWG_SE, tl, tl) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index af8ba9ca9b..65bcaf657f 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -87,6 +87,9 @@ &X_rc rt ra rb rc:bool @X_rc ...... rt:5 ra:5 rb:5 .......... rc:1 &X_rc +&X_sa rs ra +@X_sa ...... rs:5 ra:5 ..... .......... . &X_sa + %x_frtp 22:4 !function=times_2 %x_frap 17:4 !function=times_2 %x_frbp 12:4 !function=times_2 @@ -314,6 +317,7 @@ PEXTD 011111 ..... ..... ..... 0010111100 - @X ## BCD Assist ADDG6S 011111 ..... ..... ..... - 001001010 - @X +CBCDTD 011111 ..... ..... ----- 0100111010 - @X_sa ### Float-Point Load Instructions diff --git a/target/ppc/translate/fixedpoint-impl.c.inc b/target/ppc/translate/fixedpoint-impl.c.inc index 490e49cfc7..892c9d2568 100644 --- a/target/ppc/translate/fixedpoint-impl.c.inc +++ b/target/ppc/translate/fixedpoint-impl.c.inc @@ -529,3 +529,10 @@ static bool trans_ADDG6S(DisasContext *ctx, arg_X *a) return true; } + +static bool trans_CBCDTD(DisasContext *ctx, arg_X_sa *a) +{ + REQUIRE_INSNS_FLAGS2(ctx, BCDA_ISA206); + gen_helper_CBCDTD(cpu_gpr[a->ra], cpu_gpr[a->rs]); + return true; +} From 6b924d4afcab8d4284910483d16dcf803a24f657 Mon Sep 17 00:00:00 2001 From: Matheus Ferst Date: Wed, 29 Jun 2022 13:29:04 -0300 Subject: [PATCH 31/34] target/ppc: implement cdtbcd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements the Convert Declets To Binary Coded Decimal instruction. Since libdecnumber doesn't expose the methods for direct conversion (decDigitsFromDPD, DPD2BCD, etc), a positive decimal32 with zero exponent is used as an intermediate value to convert the declets. Reviewed-by: Richard Henderson Signed-off-by: Matheus Ferst Signed-off-by: Víctor Colombo Message-Id: <20220629162904.105060-12-victor.colombo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza --- target/ppc/dfp_helper.c | 26 ++++++++++++++++++++++ target/ppc/helper.h | 1 + target/ppc/insn32.decode | 1 + target/ppc/translate/fixedpoint-impl.c.inc | 7 ++++++ 4 files changed, 35 insertions(+) diff --git a/target/ppc/dfp_helper.c b/target/ppc/dfp_helper.c index db9e994c8c..5ba74b2124 100644 --- a/target/ppc/dfp_helper.c +++ b/target/ppc/dfp_helper.c @@ -1392,6 +1392,32 @@ DFP_HELPER_SHIFT(DSCLIQ, 128, 1) DFP_HELPER_SHIFT(DSCRI, 64, 0) DFP_HELPER_SHIFT(DSCRIQ, 128, 0) +target_ulong helper_CDTBCD(target_ulong s) +{ + uint64_t res = 0; + uint32_t dec32, declets; + uint8_t bcd[6]; + int i, w, sh; + decNumber a; + + for (w = 1; w >= 0; w--) { + res <<= 32; + declets = extract64(s, 32 * w, 20); + if (declets) { + /* decimal32 with zero exponent and word "w" declets */ + dec32 = (0x225ULL << 20) | declets; + decimal32ToNumber((decimal32 *)&dec32, &a); + decNumberGetBCD(&a, bcd); + for (i = 0; i < a.digits; i++) { + sh = 4 * (a.digits - 1 - i); + res |= (uint64_t)bcd[i] << sh; + } + } + } + + return res; +} + target_ulong helper_CBCDTD(target_ulong s) { uint64_t res = 0; diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 583c8dd0c2..ed0641a234 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -54,6 +54,7 @@ DEF_HELPER_3(sraw, tl, env, tl, tl) DEF_HELPER_FLAGS_2(CFUGED, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(PDEPD, TCG_CALL_NO_RWG_SE, i64, i64, i64) DEF_HELPER_FLAGS_2(PEXTD, TCG_CALL_NO_RWG_SE, i64, i64, i64) +DEF_HELPER_FLAGS_1(CDTBCD, TCG_CALL_NO_RWG_SE, tl, tl) DEF_HELPER_FLAGS_1(CBCDTD, TCG_CALL_NO_RWG_SE, tl, tl) #if defined(TARGET_PPC64) DEF_HELPER_FLAGS_2(cmpeqb, TCG_CALL_NO_RWG_SE, i32, tl, tl) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index 65bcaf657f..f7653ef9d5 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -317,6 +317,7 @@ PEXTD 011111 ..... ..... ..... 0010111100 - @X ## BCD Assist ADDG6S 011111 ..... ..... ..... - 001001010 - @X +CDTBCD 011111 ..... ..... ----- 0100011010 - @X_sa CBCDTD 011111 ..... ..... ----- 0100111010 - @X_sa ### Float-Point Load Instructions diff --git a/target/ppc/translate/fixedpoint-impl.c.inc b/target/ppc/translate/fixedpoint-impl.c.inc index 892c9d2568..cb0097bedb 100644 --- a/target/ppc/translate/fixedpoint-impl.c.inc +++ b/target/ppc/translate/fixedpoint-impl.c.inc @@ -530,6 +530,13 @@ static bool trans_ADDG6S(DisasContext *ctx, arg_X *a) return true; } +static bool trans_CDTBCD(DisasContext *ctx, arg_X_sa *a) +{ + REQUIRE_INSNS_FLAGS2(ctx, BCDA_ISA206); + gen_helper_CDTBCD(cpu_gpr[a->ra], cpu_gpr[a->rs]); + return true; +} + static bool trans_CBCDTD(DisasContext *ctx, arg_X_sa *a) { REQUIRE_INSNS_FLAGS2(ctx, BCDA_ISA206); From c7e89de13224c1e6409152602ac760ac91f606b4 Mon Sep 17 00:00:00 2001 From: Murilo Opsfelder Araujo Date: Tue, 28 Jun 2022 17:55:13 -0300 Subject: [PATCH 32/34] target/ppc: Return default CPU for max CPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All ppc CPUs represent hardware that exists in the real world, i.e.: we do not have a "max" CPU with all possible emulated features enabled. Return the default CPU type for the machine because that has greater chance of being useful as the "max" CPU. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1038 Cc: Cédric Le Goater Cc: Daniel Henrique Barboza Cc: Daniel P. Berrangé Cc: Greg Kurz Cc: Matheus K. Ferst Cc: Thomas Huth Signed-off-by: Murilo Opsfelder Araujo Signed-off-by: Fabiano Rosas Reviewed-by: Víctor Colombo Message-Id: <20220628205513.81917-1-muriloo@linux.ibm.com> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu-models.c | 1 - target/ppc/cpu_init.c | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c index 976be5e0d1..05589eb21d 100644 --- a/target/ppc/cpu-models.c +++ b/target/ppc/cpu-models.c @@ -879,7 +879,6 @@ PowerPCCPUAlias ppc_cpu_aliases[] = { { "755", "755_v2.8" }, { "goldfinger", "755_v2.8" }, { "7400", "7400_v2.9" }, - { "max", "7400_v2.9" }, { "g4", "7400_v2.9" }, { "7410", "7410_v1.4" }, { "nitro", "7410_v1.4" }, diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index bdfb1a5c6f..86ad28466a 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c @@ -47,6 +47,10 @@ #include "spr_common.h" #include "power8-pmu.h" +#ifndef CONFIG_USER_ONLY +#include "hw/boards.h" +#endif + /* #define PPC_DEBUG_SPR */ /* #define USE_APPLE_GDB */ @@ -6965,6 +6969,21 @@ static ObjectClass *ppc_cpu_class_by_name(const char *name) } } + /* + * All ppc CPUs represent hardware that exists in the real world, i.e.: we + * do not have a "max" CPU with all possible emulated features enabled. + * Return the default CPU type for the machine because that has greater + * chance of being useful as the "max" CPU. + */ +#if !defined(CONFIG_USER_ONLY) + if (strcmp(name, "max") == 0) { + MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); + if (mc) { + return object_class_by_name(mc->default_cpu_type); + } + } +#endif + cpu_model = g_ascii_strdown(name, -1); p = ppc_cpu_lookup_alias(cpu_model); if (p) { From 7886605961d0a9c40ada0c28dee5fa0b42a30836 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 5 Jul 2022 17:10:30 +0200 Subject: [PATCH 33/34] target/ppc/cpu-models: Remove the "default" CPU alias MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QEMU emulates a *lot* of PowerPC-based machines - having a CPU that is named "default" and cannot be used with most of those machines sounds just wrong. Thus let's remove this old and confusing alias now. Signed-off-by: Thomas Huth Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater Message-Id: <20220705151030.662140-1-thuth@redhat.com> Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu-models.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c index 05589eb21d..8538493061 100644 --- a/target/ppc/cpu-models.c +++ b/target/ppc/cpu-models.c @@ -917,6 +917,6 @@ PowerPCCPUAlias ppc_cpu_aliases[] = { #endif { "ppc32", "604" }, { "ppc", "604" }, - { "default", "604" }, + { NULL, NULL } }; From 0b83377f46042529adbbf3a77f7ffb6f1e8a0aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 3 Jul 2022 21:50:29 +0200 Subject: [PATCH 34/34] target/ppc: Fix MPC8555 and MPC8560 core type to e500v1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 80d11f4467c4 ("Add definitions for Freescale PowerPC implementations") changed core type of MPC8555 and MPC8560 from e500v1 to e500v2. But both MPC8555 and MPC8560 have just e500v1 cores, there are no features of e500v2 cores. It can be verified by reading NXP documentations: https://www.nxp.com/docs/en/data-sheet/MPC8555EEC.pdf https://www.nxp.com/docs/en/data-sheet/MPC8560EC.pdf https://www.nxp.com/docs/en/reference-manual/MPC8555ERM.pdf https://www.nxp.com/docs/en/reference-manual/MPC8560RM.pdf Therefore fix core type of MPC8555 and MPC8560 back to e500v1. Just for completeness, here is list of all Motorola/Freescale/NXP processors which were released and have e500v1 or e500v2 cores: e500v1: MPC8540 MPC8541 MPC8555 MPC8560 e500v2: BSC9131 BSC9132 C291 C292 C293 MPC8533 MPC8535 MPC8536 MPC8543 MPC8544 MPC8545 MPC8547 MPC8548 MPC8567 MPC8568 MPC8569 MPC8572 P1010 P1011 P1012 P1013 P1014 P1015 P1016 P1020 P1021 P1022 P1024 P1025 P2010 P2020 Sorted alphabetically; not by release date / generation / feature set. All this is from public information available on NXP website. Seems that qemu has support only for some subset of MPC85xx processors. Historically processors with e500 cores have mpc85xx family codename and lot of software have them in mpc85xx architecture subdirectory. Note that GCC uses -mcpu=8540 option for specifying e500v1 core and -mcpu=8548 option for specifying e500v2 core. So sometimes (mpc)8540 is alias for e500v1 and (mpc)8548 is alias for e500v2. Fixes: 80d11f4467c4 ("Add definitions for Freescale PowerPC implementations") Signed-off-by: Pali Rohár Reviewed-by: Daniel Henrique Barboza Message-Id: <20220703195029.23793-1-pali@kernel.org> [danielhb: added more context in the commit msg] Signed-off-by: Daniel Henrique Barboza --- target/ppc/cpu-models.c | 14 +++++++------- target/ppc/cpu-models.h | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c index 8538493061..912b037c63 100644 --- a/target/ppc/cpu-models.c +++ b/target/ppc/cpu-models.c @@ -385,19 +385,19 @@ POWERPC_DEF_SVR("mpc8548e_v21", "MPC8548E v2.1", CPU_POWERPC_MPC8548E_v21, POWERPC_SVR_8548E_v21, e500v2) POWERPC_DEF_SVR("mpc8555_v10", "MPC8555 v1.0", - CPU_POWERPC_MPC8555_v10, POWERPC_SVR_8555_v10, e500v2) + CPU_POWERPC_MPC8555_v10, POWERPC_SVR_8555_v10, e500v1) POWERPC_DEF_SVR("mpc8555_v11", "MPC8555 v1.1", - CPU_POWERPC_MPC8555_v11, POWERPC_SVR_8555_v11, e500v2) + CPU_POWERPC_MPC8555_v11, POWERPC_SVR_8555_v11, e500v1) POWERPC_DEF_SVR("mpc8555e_v10", "MPC8555E v1.0", - CPU_POWERPC_MPC8555E_v10, POWERPC_SVR_8555E_v10, e500v2) + CPU_POWERPC_MPC8555E_v10, POWERPC_SVR_8555E_v10, e500v1) POWERPC_DEF_SVR("mpc8555e_v11", "MPC8555E v1.1", - CPU_POWERPC_MPC8555E_v11, POWERPC_SVR_8555E_v11, e500v2) + CPU_POWERPC_MPC8555E_v11, POWERPC_SVR_8555E_v11, e500v1) POWERPC_DEF_SVR("mpc8560_v10", "MPC8560 v1.0", - CPU_POWERPC_MPC8560_v10, POWERPC_SVR_8560_v10, e500v2) + CPU_POWERPC_MPC8560_v10, POWERPC_SVR_8560_v10, e500v1) POWERPC_DEF_SVR("mpc8560_v20", "MPC8560 v2.0", - CPU_POWERPC_MPC8560_v20, POWERPC_SVR_8560_v20, e500v2) + CPU_POWERPC_MPC8560_v20, POWERPC_SVR_8560_v20, e500v1) POWERPC_DEF_SVR("mpc8560_v21", "MPC8560 v2.1", - CPU_POWERPC_MPC8560_v21, POWERPC_SVR_8560_v21, e500v2) + CPU_POWERPC_MPC8560_v21, POWERPC_SVR_8560_v21, e500v1) POWERPC_DEF_SVR("mpc8567", "MPC8567", CPU_POWERPC_MPC8567, POWERPC_SVR_8567, e500v2) POWERPC_DEF_SVR("mpc8567e", "MPC8567E", diff --git a/target/ppc/cpu-models.h b/target/ppc/cpu-models.h index 76775a74a9..1326493a9a 100644 --- a/target/ppc/cpu-models.h +++ b/target/ppc/cpu-models.h @@ -184,13 +184,13 @@ enum { #define CPU_POWERPC_MPC8548E_v11 CPU_POWERPC_e500v2_v11 #define CPU_POWERPC_MPC8548E_v20 CPU_POWERPC_e500v2_v20 #define CPU_POWERPC_MPC8548E_v21 CPU_POWERPC_e500v2_v21 -#define CPU_POWERPC_MPC8555_v10 CPU_POWERPC_e500v2_v10 -#define CPU_POWERPC_MPC8555_v11 CPU_POWERPC_e500v2_v11 -#define CPU_POWERPC_MPC8555E_v10 CPU_POWERPC_e500v2_v10 -#define CPU_POWERPC_MPC8555E_v11 CPU_POWERPC_e500v2_v11 -#define CPU_POWERPC_MPC8560_v10 CPU_POWERPC_e500v2_v10 -#define CPU_POWERPC_MPC8560_v20 CPU_POWERPC_e500v2_v20 -#define CPU_POWERPC_MPC8560_v21 CPU_POWERPC_e500v2_v21 +#define CPU_POWERPC_MPC8555_v10 CPU_POWERPC_e500v1_v20 +#define CPU_POWERPC_MPC8555_v11 CPU_POWERPC_e500v1_v20 +#define CPU_POWERPC_MPC8555E_v10 CPU_POWERPC_e500v1_v20 +#define CPU_POWERPC_MPC8555E_v11 CPU_POWERPC_e500v1_v20 +#define CPU_POWERPC_MPC8560_v10 CPU_POWERPC_e500v1_v10 +#define CPU_POWERPC_MPC8560_v20 CPU_POWERPC_e500v1_v20 +#define CPU_POWERPC_MPC8560_v21 CPU_POWERPC_e500v1_v20 #define CPU_POWERPC_MPC8567 CPU_POWERPC_e500v2_v22 #define CPU_POWERPC_MPC8567E CPU_POWERPC_e500v2_v22 #define CPU_POWERPC_MPC8568 CPU_POWERPC_e500v2_v22