mirror of https://gitee.com/openkylin/qemu.git
Fixes and improvements in tcg and the zPCI code.
-----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEEw9DWbcNiT/aowBjO3s9rk8bwL68FAlxZu3kSHGNvaHVja0By ZWRoYXQuY29tAAoJEN7Pa5PG8C+vDEAP/i/o+KhHpQUxx2bG33TxqjnMvFql9Rry 7nAEvRpz6WwA9PsX6ZoW2teyu+HvqMG/7SDcbjaEAinWoGdmd8Nw476UnOBGInGW aw/JsDujyntM+V58ZbJZlaiimzv3nqCx0+L0vf9M/6gcRjFH0gTzQ/TxBwWbS1SL yU1qbSMQy8RzNJLJ2opHX38QK+ZQVNPUuR0xKuWTV4RCxnlimfrmGZWp0h4k56NA HvQJfbqqTAbEgEZvdOlqxBqed0SU4whCQdS92gzTVHqQmh+FIS2XkHwao7qzrOMu S+AivuzqU5yeROszYvnartrD3vvYiAQdFHQ4/xVYR8Sbr1LWuxKkTmjO7dZpTpzU lXxy+ZXlYchfnyLAdtDXU3TAjiaw0dWtW16WeDu4Jfbt5vV/lQwxbaV2zzJWqeD7 Bik9OvwdUjOW216cTz1z3g/1QxWmetE4vgTPJRkrDhBgb2fKF9hm3eD/SdKC6laD HxhG6D4FQ6McAlzm1ES+SPQ4zOByQL7uZGuCO0F3mogUrsa0LIpW6HBRtIU6L1qR 1M8RkMdBqSrpUhbjIsj/ic/42ykPKpuLs2E9wFMhv06voyzDiUWIkclai/vgJnwx pPQjQayqL39iACp4YxYqoe9Cf7hn5YkQcQZfv+vWw4OYX4PO4lP1SuPMOhnYFLE0 Cz2ghigKsJ2O =E3i4 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20190205' into staging Fixes and improvements in tcg and the zPCI code. # gpg: Signature made Tue 05 Feb 2019 16:36:09 GMT # gpg: using RSA key C3D0D66DC3624FF6A8C018CEDECF6B93C6F02FAF # gpg: issuer "cohuck@redhat.com" # gpg: Good signature from "Cornelia Huck <conny@cornelia-huck.de>" [unknown] # gpg: aka "Cornelia Huck <huckc@linux.vnet.ibm.com>" [full] # gpg: aka "Cornelia Huck <cornelia.huck@de.ibm.com>" [full] # gpg: aka "Cornelia Huck <cohuck@kernel.org>" [unknown] # gpg: aka "Cornelia Huck <cohuck@redhat.com>" [unknown] # Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0 18CE DECF 6B93 C6F0 2FAF * remotes/cohuck/tags/s390x-20190205: s390x/pci: Unplug remaining requested devices on pcihost reset s390x/pci: Warn when adding PCI devices without the 'zpci' feature s390x/pci: Fix hotplugging of PCI bridges s390x/pci: Fix primary bus number for PCI bridges s390x/tcg: Don't model FP registers as globals s390x/pci: mark zpci devices as unmigratable s390x/pci: Drop release timer and replace it with a flag s390x/pci: Introduce unplug requests and split unplug handler s390x: remove direct reference to mem_path global from s390x code target/s390x: define TCG_GUEST_DEFAULT_MO for MTTCG Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
9669c97562
|
@ -148,6 +148,22 @@ out:
|
|||
psccb->header.response_code = cpu_to_be16(rc);
|
||||
}
|
||||
|
||||
static void s390_pci_perform_unplug(S390PCIBusDevice *pbdev)
|
||||
{
|
||||
HotplugHandler *hotplug_ctrl;
|
||||
|
||||
/* Unplug the PCI device */
|
||||
if (pbdev->pdev) {
|
||||
hotplug_ctrl = qdev_get_hotplug_handler(DEVICE(pbdev->pdev));
|
||||
hotplug_handler_unplug(hotplug_ctrl, DEVICE(pbdev->pdev),
|
||||
&error_abort);
|
||||
}
|
||||
|
||||
/* Unplug the zPCI device */
|
||||
hotplug_ctrl = qdev_get_hotplug_handler(DEVICE(pbdev));
|
||||
hotplug_handler_unplug(hotplug_ctrl, DEVICE(pbdev), &error_abort);
|
||||
}
|
||||
|
||||
void s390_pci_sclp_deconfigure(SCCB *sccb)
|
||||
{
|
||||
IoaCfgSccb *psccb = (IoaCfgSccb *)sccb;
|
||||
|
@ -178,8 +194,8 @@ void s390_pci_sclp_deconfigure(SCCB *sccb)
|
|||
pbdev->state = ZPCI_FS_STANDBY;
|
||||
rc = SCLP_RC_NORMAL_COMPLETION;
|
||||
|
||||
if (pbdev->release_timer) {
|
||||
qdev_unplug(DEVICE(pbdev->pdev), NULL);
|
||||
if (pbdev->unplug_requested) {
|
||||
s390_pci_perform_unplug(pbdev);
|
||||
}
|
||||
}
|
||||
out:
|
||||
|
@ -217,6 +233,24 @@ S390PCIBusDevice *s390_pci_find_dev_by_target(S390pciState *s,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static S390PCIBusDevice *s390_pci_find_dev_by_pci(S390pciState *s,
|
||||
PCIDevice *pci_dev)
|
||||
{
|
||||
S390PCIBusDevice *pbdev;
|
||||
|
||||
if (!pci_dev) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH(pbdev, &s->zpci_devs, link) {
|
||||
if (pbdev->pdev == pci_dev) {
|
||||
return pbdev;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
S390PCIBusDevice *s390_pci_find_dev_by_idx(S390pciState *s, uint32_t idx)
|
||||
{
|
||||
return g_hash_table_lookup(s->zpci_table, &idx);
|
||||
|
@ -826,6 +860,12 @@ static void s390_pcihost_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
|||
{
|
||||
S390pciState *s = S390_PCI_HOST_BRIDGE(hotplug_dev);
|
||||
|
||||
if (!s390_has_feat(S390_FEAT_ZPCI)) {
|
||||
warn_report("Plugging a PCI/zPCI device without the 'zpci' CPU "
|
||||
"feature enabled; the guest will not be able to see/use "
|
||||
"this device");
|
||||
}
|
||||
|
||||
if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
|
||||
PCIDevice *pdev = PCI_DEVICE(dev);
|
||||
|
||||
|
@ -843,6 +883,21 @@ static void s390_pcihost_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
|||
}
|
||||
}
|
||||
|
||||
static void s390_pci_update_subordinate(PCIDevice *dev, uint32_t nr)
|
||||
{
|
||||
uint32_t old_nr;
|
||||
|
||||
pci_default_write_config(dev, PCI_SUBORDINATE_BUS, nr, 1);
|
||||
while (!pci_bus_is_root(pci_get_bus(dev))) {
|
||||
dev = pci_get_bus(dev)->parent_dev;
|
||||
|
||||
old_nr = pci_default_read_config(dev, PCI_SUBORDINATE_BUS, 1);
|
||||
if (old_nr < nr) {
|
||||
pci_default_write_config(dev, PCI_SUBORDINATE_BUS, nr, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void s390_pcihost_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
Error **errp)
|
||||
{
|
||||
|
@ -851,25 +906,21 @@ static void s390_pcihost_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
|||
S390PCIBusDevice *pbdev = NULL;
|
||||
|
||||
if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {
|
||||
BusState *bus;
|
||||
PCIBridge *pb = PCI_BRIDGE(dev);
|
||||
PCIDevice *pdev = PCI_DEVICE(dev);
|
||||
|
||||
pdev = PCI_DEVICE(dev);
|
||||
pci_bridge_map_irq(pb, dev->id, s390_pci_map_irq);
|
||||
pci_setup_iommu(&pb->sec_bus, s390_pci_dma_iommu, s);
|
||||
|
||||
bus = BUS(&pb->sec_bus);
|
||||
qbus_set_hotplug_handler(bus, DEVICE(s), errp);
|
||||
qbus_set_hotplug_handler(BUS(&pb->sec_bus), DEVICE(s), errp);
|
||||
|
||||
if (dev->hotplugged) {
|
||||
pci_default_write_config(pdev, PCI_PRIMARY_BUS, s->bus_no, 1);
|
||||
pci_default_write_config(pdev, PCI_PRIMARY_BUS,
|
||||
pci_dev_bus_num(pdev), 1);
|
||||
s->bus_no += 1;
|
||||
pci_default_write_config(pdev, PCI_SECONDARY_BUS, s->bus_no, 1);
|
||||
do {
|
||||
pdev = pci_get_bus(pdev)->parent_dev;
|
||||
pci_default_write_config(pdev, PCI_SUBORDINATE_BUS,
|
||||
s->bus_no, 1);
|
||||
} while (pci_get_bus(pdev) && pci_dev_bus_num(pdev));
|
||||
|
||||
s390_pci_update_subordinate(pdev, s->bus_no);
|
||||
}
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
|
||||
pdev = PCI_DEVICE(dev);
|
||||
|
@ -925,99 +976,96 @@ static void s390_pcihost_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
|||
}
|
||||
}
|
||||
|
||||
static void s390_pcihost_timer_cb(void *opaque)
|
||||
{
|
||||
S390PCIBusDevice *pbdev = opaque;
|
||||
|
||||
if (pbdev->summary_ind) {
|
||||
pci_dereg_irqs(pbdev);
|
||||
}
|
||||
if (pbdev->iommu->enabled) {
|
||||
pci_dereg_ioat(pbdev->iommu);
|
||||
}
|
||||
|
||||
pbdev->state = ZPCI_FS_STANDBY;
|
||||
s390_pci_generate_plug_event(HP_EVENT_CONFIGURED_TO_STBRES,
|
||||
pbdev->fh, pbdev->fid);
|
||||
qdev_unplug(DEVICE(pbdev), NULL);
|
||||
}
|
||||
|
||||
static void s390_pcihost_unplug(HotplugHandler *hotplug_dev, DeviceState *dev,
|
||||
Error **errp)
|
||||
{
|
||||
S390pciState *s = S390_PCI_HOST_BRIDGE(hotplug_dev);
|
||||
PCIDevice *pci_dev = NULL;
|
||||
PCIBus *bus;
|
||||
int32_t devfn;
|
||||
S390PCIBusDevice *pbdev = NULL;
|
||||
|
||||
if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
|
||||
PCIDevice *pci_dev = PCI_DEVICE(dev);
|
||||
PCIBus *bus;
|
||||
int32_t devfn;
|
||||
|
||||
pbdev = s390_pci_find_dev_by_pci(s, PCI_DEVICE(dev));
|
||||
g_assert(pbdev);
|
||||
|
||||
s390_pci_generate_plug_event(HP_EVENT_STANDBY_TO_RESERVED,
|
||||
pbdev->fh, pbdev->fid);
|
||||
bus = pci_get_bus(pci_dev);
|
||||
devfn = pci_dev->devfn;
|
||||
object_unparent(OBJECT(pci_dev));
|
||||
|
||||
s390_pci_msix_free(pbdev);
|
||||
s390_pci_iommu_free(s, bus, devfn);
|
||||
pbdev->pdev = NULL;
|
||||
pbdev->state = ZPCI_FS_RESERVED;
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) {
|
||||
pbdev = S390_PCI_DEVICE(dev);
|
||||
pbdev->fid = 0;
|
||||
QTAILQ_REMOVE(&s->zpci_devs, pbdev, link);
|
||||
g_hash_table_remove(s->zpci_table, &pbdev->idx);
|
||||
object_unparent(OBJECT(pbdev));
|
||||
}
|
||||
}
|
||||
|
||||
static void s390_pcihost_unplug_request(HotplugHandler *hotplug_dev,
|
||||
DeviceState *dev,
|
||||
Error **errp)
|
||||
{
|
||||
S390pciState *s = S390_PCI_HOST_BRIDGE(hotplug_dev);
|
||||
S390PCIBusDevice *pbdev;
|
||||
|
||||
if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {
|
||||
error_setg(errp, "PCI bridge hot unplug currently not supported");
|
||||
return;
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
|
||||
pci_dev = PCI_DEVICE(dev);
|
||||
|
||||
QTAILQ_FOREACH(pbdev, &s->zpci_devs, link) {
|
||||
if (pbdev->pdev == pci_dev) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(pbdev != NULL);
|
||||
/*
|
||||
* Redirect the unplug request to the zPCI device and remember that
|
||||
* we've checked the PCI device already (to prevent endless recursion).
|
||||
*/
|
||||
pbdev = s390_pci_find_dev_by_pci(s, PCI_DEVICE(dev));
|
||||
g_assert(pbdev);
|
||||
pbdev->pci_unplug_request_processed = true;
|
||||
qdev_unplug(DEVICE(pbdev), errp);
|
||||
} else if (object_dynamic_cast(OBJECT(dev), TYPE_S390_PCI_DEVICE)) {
|
||||
pbdev = S390_PCI_DEVICE(dev);
|
||||
pci_dev = pbdev->pdev;
|
||||
|
||||
/*
|
||||
* If unplug was initially requested for the zPCI device, we
|
||||
* first have to redirect to the PCI device, which will in return
|
||||
* redirect back to us after performing its checks (if the request
|
||||
* is not blocked, e.g. because it's a PCI bridge).
|
||||
*/
|
||||
if (pbdev->pdev && !pbdev->pci_unplug_request_processed) {
|
||||
qdev_unplug(DEVICE(pbdev->pdev), errp);
|
||||
return;
|
||||
}
|
||||
pbdev->pci_unplug_request_processed = false;
|
||||
|
||||
switch (pbdev->state) {
|
||||
case ZPCI_FS_STANDBY:
|
||||
case ZPCI_FS_RESERVED:
|
||||
s390_pci_perform_unplug(pbdev);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Allow to send multiple requests, e.g. if the guest crashed
|
||||
* before releasing the device, we would not be able to send
|
||||
* another request to the same VM (e.g. fresh OS).
|
||||
*/
|
||||
pbdev->unplug_requested = true;
|
||||
s390_pci_generate_plug_event(HP_EVENT_DECONFIGURE_REQUEST,
|
||||
pbdev->fh, pbdev->fid);
|
||||
}
|
||||
} else {
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
switch (pbdev->state) {
|
||||
case ZPCI_FS_RESERVED:
|
||||
goto out;
|
||||
case ZPCI_FS_STANDBY:
|
||||
break;
|
||||
default:
|
||||
if (pbdev->release_timer) {
|
||||
return;
|
||||
}
|
||||
s390_pci_generate_plug_event(HP_EVENT_DECONFIGURE_REQUEST,
|
||||
pbdev->fh, pbdev->fid);
|
||||
pbdev->release_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
|
||||
s390_pcihost_timer_cb,
|
||||
pbdev);
|
||||
timer_mod(pbdev->release_timer,
|
||||
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + HOT_UNPLUG_TIMEOUT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pbdev->release_timer) {
|
||||
timer_del(pbdev->release_timer);
|
||||
timer_free(pbdev->release_timer);
|
||||
pbdev->release_timer = NULL;
|
||||
}
|
||||
|
||||
s390_pci_generate_plug_event(HP_EVENT_STANDBY_TO_RESERVED,
|
||||
pbdev->fh, pbdev->fid);
|
||||
bus = pci_get_bus(pci_dev);
|
||||
devfn = pci_dev->devfn;
|
||||
object_unparent(OBJECT(pci_dev));
|
||||
fmb_timer_free(pbdev);
|
||||
s390_pci_msix_free(pbdev);
|
||||
s390_pci_iommu_free(s, bus, devfn);
|
||||
pbdev->pdev = NULL;
|
||||
pbdev->state = ZPCI_FS_RESERVED;
|
||||
out:
|
||||
pbdev->fid = 0;
|
||||
QTAILQ_REMOVE(&s->zpci_devs, pbdev, link);
|
||||
g_hash_table_remove(s->zpci_table, &pbdev->idx);
|
||||
object_unparent(OBJECT(pbdev));
|
||||
}
|
||||
|
||||
static void s390_pci_enumerate_bridge(PCIBus *bus, PCIDevice *pdev,
|
||||
void *opaque)
|
||||
{
|
||||
S390pciState *s = opaque;
|
||||
unsigned int primary = s->bus_no;
|
||||
unsigned int subordinate = 0xff;
|
||||
PCIBus *sec_bus = NULL;
|
||||
|
||||
if ((pci_default_read_config(pdev, PCI_HEADER_TYPE, 1) !=
|
||||
|
@ -1026,7 +1074,7 @@ static void s390_pci_enumerate_bridge(PCIBus *bus, PCIDevice *pdev,
|
|||
}
|
||||
|
||||
(s->bus_no)++;
|
||||
pci_default_write_config(pdev, PCI_PRIMARY_BUS, primary, 1);
|
||||
pci_default_write_config(pdev, PCI_PRIMARY_BUS, pci_dev_bus_num(pdev), 1);
|
||||
pci_default_write_config(pdev, PCI_SECONDARY_BUS, s->bus_no, 1);
|
||||
pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, s->bus_no, 1);
|
||||
|
||||
|
@ -1035,7 +1083,7 @@ static void s390_pci_enumerate_bridge(PCIBus *bus, PCIDevice *pdev,
|
|||
return;
|
||||
}
|
||||
|
||||
pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, subordinate, 1);
|
||||
/* Assign numbers to all child bridges. The last is the highest number. */
|
||||
pci_for_each_device(sec_bus, pci_bus_num(sec_bus),
|
||||
s390_pci_enumerate_bridge, s);
|
||||
pci_default_write_config(pdev, PCI_SUBORDINATE_BUS, s->bus_no, 1);
|
||||
|
@ -1045,7 +1093,26 @@ static void s390_pcihost_reset(DeviceState *dev)
|
|||
{
|
||||
S390pciState *s = S390_PCI_HOST_BRIDGE(dev);
|
||||
PCIBus *bus = s->parent_obj.bus;
|
||||
S390PCIBusDevice *pbdev, *next;
|
||||
|
||||
/* Process all pending unplug requests */
|
||||
QTAILQ_FOREACH_SAFE(pbdev, &s->zpci_devs, link, next) {
|
||||
if (pbdev->unplug_requested) {
|
||||
if (pbdev->summary_ind) {
|
||||
pci_dereg_irqs(pbdev);
|
||||
}
|
||||
if (pbdev->iommu->enabled) {
|
||||
pci_dereg_ioat(pbdev->iommu);
|
||||
}
|
||||
pbdev->state = ZPCI_FS_STANDBY;
|
||||
s390_pci_perform_unplug(pbdev);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* When resetting a PCI bridge, the assigned numbers are set to 0. So
|
||||
* on every system reset, we also have to reassign numbers.
|
||||
*/
|
||||
s->bus_no = 0;
|
||||
pci_for_each_device(bus, pci_bus_num(bus), s390_pci_enumerate_bridge, s);
|
||||
}
|
||||
|
@ -1059,6 +1126,7 @@ static void s390_pcihost_class_init(ObjectClass *klass, void *data)
|
|||
dc->realize = s390_pcihost_realize;
|
||||
hc->pre_plug = s390_pcihost_pre_plug;
|
||||
hc->plug = s390_pcihost_plug;
|
||||
hc->unplug_request = s390_pcihost_unplug_request;
|
||||
hc->unplug = s390_pcihost_unplug;
|
||||
msi_nonbroken = true;
|
||||
}
|
||||
|
@ -1219,6 +1287,15 @@ static Property s390_pci_device_properties[] = {
|
|||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static const VMStateDescription s390_pci_device_vmstate = {
|
||||
.name = TYPE_S390_PCI_DEVICE,
|
||||
/*
|
||||
* TODO: add state handling here, so migration works at least with
|
||||
* emulated pci devices on s390x
|
||||
*/
|
||||
.unmigratable = 1,
|
||||
};
|
||||
|
||||
static void s390_pci_device_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
|
@ -1229,6 +1306,7 @@ static void s390_pci_device_class_init(ObjectClass *klass, void *data)
|
|||
dc->bus_type = TYPE_S390_PCI_BUS;
|
||||
dc->realize = s390_pci_device_realize;
|
||||
dc->props = s390_pci_device_properties;
|
||||
dc->vmsd = &s390_pci_device_vmstate;
|
||||
}
|
||||
|
||||
static const TypeInfo s390_pci_device_info = {
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#define ZPCI_MAX_UID 0xffff
|
||||
#define UID_UNDEFINED 0
|
||||
#define UID_CHECKING_ENABLED 0x01
|
||||
#define HOT_UNPLUG_TIMEOUT (NANOSECONDS_PER_SECOND * 60 * 5)
|
||||
|
||||
#define S390_PCI_HOST_BRIDGE(obj) \
|
||||
OBJECT_CHECK(S390pciState, (obj), TYPE_S390_PCI_HOST_BRIDGE)
|
||||
|
@ -335,7 +334,8 @@ struct S390PCIBusDevice {
|
|||
MemoryRegion msix_notify_mr;
|
||||
IndAddr *summary_ind;
|
||||
IndAddr *indicator;
|
||||
QEMUTimer *release_timer;
|
||||
bool pci_unplug_request_processed;
|
||||
bool unplug_requested;
|
||||
QTAILQ_ENTRY(S390PCIBusDevice) link;
|
||||
};
|
||||
|
||||
|
|
|
@ -35,6 +35,10 @@
|
|||
#define CPUArchState struct CPUS390XState
|
||||
|
||||
#include "exec/cpu-defs.h"
|
||||
|
||||
/* The z/Architecture has a strong memory model with some store-after-load re-ordering */
|
||||
#define TCG_GUEST_DEFAULT_MO (TCG_MO_ALL & ~TCG_MO_ST_LD)
|
||||
|
||||
#define TARGET_PAGE_BITS 12
|
||||
|
||||
#define TARGET_PHYS_ADDR_SPACE_BITS 64
|
||||
|
|
|
@ -33,10 +33,10 @@
|
|||
C(0xe308, AG, RXY_a, Z, r1, m2_64, r1, 0, add, adds64)
|
||||
C(0xe318, AGF, RXY_a, Z, r1, m2_32s, r1, 0, add, adds64)
|
||||
F(0xb30a, AEBR, RRE, Z, e1, e2, new, e1, aeb, f32, IF_BFP)
|
||||
F(0xb31a, ADBR, RRE, Z, f1_o, f2_o, f1, 0, adb, f64, IF_BFP)
|
||||
F(0xb34a, AXBR, RRE, Z, 0, x2_o, x1, 0, axb, f128, IF_BFP)
|
||||
F(0xb31a, ADBR, RRE, Z, f1, f2, new, f1, adb, f64, IF_BFP)
|
||||
F(0xb34a, AXBR, RRE, Z, x2h, x2l, x1, x1, axb, f128, IF_BFP)
|
||||
F(0xed0a, AEB, RXE, Z, e1, m2_32u, new, e1, aeb, f32, IF_BFP)
|
||||
F(0xed1a, ADB, RXE, Z, f1_o, m2_64, f1, 0, adb, f64, IF_BFP)
|
||||
F(0xed1a, ADB, RXE, Z, f1, m2_64, new, f1, adb, f64, IF_BFP)
|
||||
/* ADD HIGH */
|
||||
C(0xb9c8, AHHHR, RRF_a, HW, r2_sr32, r3_sr32, new, r1_32h, add, adds32)
|
||||
C(0xb9d8, AHHLR, RRF_a, HW, r2_sr32, r3, new, r1_32h, add, adds32)
|
||||
|
@ -154,7 +154,7 @@
|
|||
C(0xb241, CKSM, RRE, Z, r1_o, ra2, new, r1_32, cksm, 0)
|
||||
|
||||
/* COPY SIGN */
|
||||
F(0xb372, CPSDR, RRF_b, FPSSH, f3_o, f2_o, f1, 0, cps, 0, IF_AFP1 | IF_AFP2 | IF_AFP3)
|
||||
F(0xb372, CPSDR, RRF_b, FPSSH, f3, f2, new, f1, cps, 0, IF_AFP1 | IF_AFP2 | IF_AFP3)
|
||||
|
||||
/* COMPARE */
|
||||
C(0x1900, CR, RR_a, Z, r1_o, r2_o, 0, 0, 0, cmps32)
|
||||
|
@ -165,16 +165,16 @@
|
|||
C(0xe320, CG, RXY_a, Z, r1_o, m2_64, 0, 0, 0, cmps64)
|
||||
C(0xe330, CGF, RXY_a, Z, r1_o, m2_32s, 0, 0, 0, cmps64)
|
||||
F(0xb309, CEBR, RRE, Z, e1, e2, 0, 0, ceb, 0, IF_BFP)
|
||||
F(0xb319, CDBR, RRE, Z, f1_o, f2_o, 0, 0, cdb, 0, IF_BFP)
|
||||
F(0xb349, CXBR, RRE, Z, x1_o, x2_o, 0, 0, cxb, 0, IF_BFP)
|
||||
F(0xb319, CDBR, RRE, Z, f1, f2, 0, 0, cdb, 0, IF_BFP)
|
||||
F(0xb349, CXBR, RRE, Z, x2h, x2l, x1, 0, cxb, 0, IF_BFP)
|
||||
F(0xed09, CEB, RXE, Z, e1, m2_32u, 0, 0, ceb, 0, IF_BFP)
|
||||
F(0xed19, CDB, RXE, Z, f1_o, m2_64, 0, 0, cdb, 0, IF_BFP)
|
||||
F(0xed19, CDB, RXE, Z, f1, m2_64, 0, 0, cdb, 0, IF_BFP)
|
||||
/* COMPARE AND SIGNAL */
|
||||
F(0xb308, KEBR, RRE, Z, e1, e2, 0, 0, keb, 0, IF_BFP)
|
||||
F(0xb318, KDBR, RRE, Z, f1_o, f2_o, 0, 0, kdb, 0, IF_BFP)
|
||||
F(0xb348, KXBR, RRE, Z, x1_o, x2_o, 0, 0, kxb, 0, IF_BFP)
|
||||
F(0xb318, KDBR, RRE, Z, f1, f2, 0, 0, kdb, 0, IF_BFP)
|
||||
F(0xb348, KXBR, RRE, Z, x2h, x2l, x1, 0, kxb, 0, IF_BFP)
|
||||
F(0xed08, KEB, RXE, Z, e1, m2_32u, 0, 0, keb, 0, IF_BFP)
|
||||
F(0xed18, KDB, RXE, Z, f1_o, m2_64, 0, 0, kdb, 0, IF_BFP)
|
||||
F(0xed18, KDB, RXE, Z, f1, m2_64, 0, 0, kdb, 0, IF_BFP)
|
||||
/* COMPARE IMMEDIATE */
|
||||
C(0xc20d, CFI, RIL_a, EI, r1, i2, 0, 0, 0, cmps32)
|
||||
C(0xc20c, CGFI, RIL_a, EI, r1, i2, 0, 0, 0, cmps64)
|
||||
|
@ -292,32 +292,32 @@
|
|||
C(0xe326, CVDY, RXY_a, LD, r1_o, a2, 0, 0, cvd, 0)
|
||||
/* CONVERT TO FIXED */
|
||||
F(0xb398, CFEBR, RRF_e, Z, 0, e2, new, r1_32, cfeb, 0, IF_BFP)
|
||||
F(0xb399, CFDBR, RRF_e, Z, 0, f2_o, new, r1_32, cfdb, 0, IF_BFP)
|
||||
F(0xb39a, CFXBR, RRF_e, Z, 0, x2_o, new, r1_32, cfxb, 0, IF_BFP)
|
||||
F(0xb399, CFDBR, RRF_e, Z, 0, f2, new, r1_32, cfdb, 0, IF_BFP)
|
||||
F(0xb39a, CFXBR, RRF_e, Z, x2h, x2l, new, r1_32, cfxb, 0, IF_BFP)
|
||||
F(0xb3a8, CGEBR, RRF_e, Z, 0, e2, r1, 0, cgeb, 0, IF_BFP)
|
||||
F(0xb3a9, CGDBR, RRF_e, Z, 0, f2_o, r1, 0, cgdb, 0, IF_BFP)
|
||||
F(0xb3aa, CGXBR, RRF_e, Z, 0, x2_o, r1, 0, cgxb, 0, IF_BFP)
|
||||
F(0xb3a9, CGDBR, RRF_e, Z, 0, f2, r1, 0, cgdb, 0, IF_BFP)
|
||||
F(0xb3aa, CGXBR, RRF_e, Z, x2h, x2l, r1, 0, cgxb, 0, IF_BFP)
|
||||
/* CONVERT FROM FIXED */
|
||||
F(0xb394, CEFBR, RRF_e, Z, 0, r2_32s, new, e1, cegb, 0, IF_BFP)
|
||||
F(0xb395, CDFBR, RRF_e, Z, 0, r2_32s, f1, 0, cdgb, 0, IF_BFP)
|
||||
F(0xb396, CXFBR, RRF_e, Z, 0, r2_32s, x1, 0, cxgb, 0, IF_BFP)
|
||||
F(0xb395, CDFBR, RRF_e, Z, 0, r2_32s, new, f1, cdgb, 0, IF_BFP)
|
||||
F(0xb396, CXFBR, RRF_e, Z, 0, r2_32s, new_P, x1, cxgb, 0, IF_BFP)
|
||||
F(0xb3a4, CEGBR, RRF_e, Z, 0, r2_o, new, e1, cegb, 0, IF_BFP)
|
||||
F(0xb3a5, CDGBR, RRF_e, Z, 0, r2_o, f1, 0, cdgb, 0, IF_BFP)
|
||||
F(0xb3a6, CXGBR, RRF_e, Z, 0, r2_o, x1, 0, cxgb, 0, IF_BFP)
|
||||
F(0xb3a5, CDGBR, RRF_e, Z, 0, r2_o, new, f1, cdgb, 0, IF_BFP)
|
||||
F(0xb3a6, CXGBR, RRF_e, Z, 0, r2_o, new_P, x1, cxgb, 0, IF_BFP)
|
||||
/* CONVERT TO LOGICAL */
|
||||
F(0xb39c, CLFEBR, RRF_e, FPE, 0, e2, new, r1_32, clfeb, 0, IF_BFP)
|
||||
F(0xb39d, CLFDBR, RRF_e, FPE, 0, f2_o, new, r1_32, clfdb, 0, IF_BFP)
|
||||
F(0xb39e, CLFXBR, RRF_e, FPE, 0, x2_o, new, r1_32, clfxb, 0, IF_BFP)
|
||||
F(0xb39d, CLFDBR, RRF_e, FPE, 0, f2, new, r1_32, clfdb, 0, IF_BFP)
|
||||
F(0xb39e, CLFXBR, RRF_e, FPE, x2h, x2l, new, r1_32, clfxb, 0, IF_BFP)
|
||||
F(0xb3ac, CLGEBR, RRF_e, FPE, 0, e2, r1, 0, clgeb, 0, IF_BFP)
|
||||
F(0xb3ad, CLGDBR, RRF_e, FPE, 0, f2_o, r1, 0, clgdb, 0, IF_BFP)
|
||||
F(0xb3ae, CLGXBR, RRF_e, FPE, 0, x2_o, r1, 0, clgxb, 0, IF_BFP)
|
||||
F(0xb3ad, CLGDBR, RRF_e, FPE, 0, f2, r1, 0, clgdb, 0, IF_BFP)
|
||||
F(0xb3ae, CLGXBR, RRF_e, FPE, x2h, x2l, r1, 0, clgxb, 0, IF_BFP)
|
||||
/* CONVERT FROM LOGICAL */
|
||||
F(0xb390, CELFBR, RRF_e, FPE, 0, r2_32u, new, e1, celgb, 0, IF_BFP)
|
||||
F(0xb391, CDLFBR, RRF_e, FPE, 0, r2_32u, f1, 0, cdlgb, 0, IF_BFP)
|
||||
F(0xb392, CXLFBR, RRF_e, FPE, 0, r2_32u, x1, 0, cxlgb, 0, IF_BFP)
|
||||
F(0xb391, CDLFBR, RRF_e, FPE, 0, r2_32u, new, f1, cdlgb, 0, IF_BFP)
|
||||
F(0xb392, CXLFBR, RRF_e, FPE, 0, r2_32u, new_P, x1, cxlgb, 0, IF_BFP)
|
||||
F(0xb3a0, CELGBR, RRF_e, FPE, 0, r2_o, new, e1, celgb, 0, IF_BFP)
|
||||
F(0xb3a1, CDLGBR, RRF_e, FPE, 0, r2_o, f1, 0, cdlgb, 0, IF_BFP)
|
||||
F(0xb3a2, CXLGBR, RRF_e, FPE, 0, r2_o, x1, 0, cxlgb, 0, IF_BFP)
|
||||
F(0xb3a1, CDLGBR, RRF_e, FPE, 0, r2_o, new, f1, cdlgb, 0, IF_BFP)
|
||||
F(0xb3a2, CXLGBR, RRF_e, FPE, 0, r2_o, new_P, x1, cxlgb, 0, IF_BFP)
|
||||
|
||||
/* CONVERT UTF-8 TO UTF-16 */
|
||||
D(0xb2a7, CU12, RRF_c, Z, 0, 0, 0, 0, cuXX, 0, 12)
|
||||
|
@ -336,10 +336,10 @@
|
|||
C(0x1d00, DR, RR_a, Z, r1_D32, r2_32s, new_P, r1_P32, divs32, 0)
|
||||
C(0x5d00, D, RX_a, Z, r1_D32, m2_32s, new_P, r1_P32, divs32, 0)
|
||||
F(0xb30d, DEBR, RRE, Z, e1, e2, new, e1, deb, 0, IF_BFP)
|
||||
F(0xb31d, DDBR, RRE, Z, f1_o, f2_o, f1, 0, ddb, 0, IF_BFP)
|
||||
F(0xb34d, DXBR, RRE, Z, 0, x2_o, x1, 0, dxb, 0, IF_BFP)
|
||||
F(0xb31d, DDBR, RRE, Z, f1, f2, new, f1, ddb, 0, IF_BFP)
|
||||
F(0xb34d, DXBR, RRE, Z, x2h, x2l, x1, x1, dxb, 0, IF_BFP)
|
||||
F(0xed0d, DEB, RXE, Z, e1, m2_32u, new, e1, deb, 0, IF_BFP)
|
||||
F(0xed1d, DDB, RXE, Z, f1_o, m2_64, f1, 0, ddb, 0, IF_BFP)
|
||||
F(0xed1d, DDB, RXE, Z, f1, m2_64, new, f1, ddb, 0, IF_BFP)
|
||||
/* DIVIDE LOGICAL */
|
||||
C(0xb997, DLR, RRE, Z, r1_D32, r2_32u, new_P, r1_P32, divu32, 0)
|
||||
C(0xe397, DL, RXY_a, Z, r1_D32, m2_32u, new_P, r1_P32, divu32, 0)
|
||||
|
@ -410,13 +410,13 @@
|
|||
C(0xb914, LGFR, RRE, Z, 0, r2_32s, 0, r1, mov2, 0)
|
||||
C(0xe304, LG, RXY_a, Z, 0, a2, r1, 0, ld64, 0)
|
||||
C(0xe314, LGF, RXY_a, Z, 0, a2, r1, 0, ld32s, 0)
|
||||
F(0x2800, LDR, RR_a, Z, 0, f2_o, 0, f1, mov2, 0, IF_AFP1 | IF_AFP2)
|
||||
F(0x2800, LDR, RR_a, Z, 0, f2, 0, f1, mov2, 0, IF_AFP1 | IF_AFP2)
|
||||
F(0x6800, LD, RX_a, Z, 0, m2_64, 0, f1, mov2, 0, IF_AFP1)
|
||||
F(0xed65, LDY, RXY_a, LD, 0, m2_64, 0, f1, mov2, 0, IF_AFP1)
|
||||
F(0x3800, LER, RR_a, Z, 0, e2, 0, cond_e1e2, mov2, 0, IF_AFP1 | IF_AFP2)
|
||||
F(0x7800, LE, RX_a, Z, 0, m2_32u, 0, e1, mov2, 0, IF_AFP1)
|
||||
F(0xed64, LEY, RXY_a, LD, 0, m2_32u, 0, e1, mov2, 0, IF_AFP1)
|
||||
F(0xb365, LXR, RRE, Z, 0, x2_o, 0, x1, movx, 0, IF_AFP1)
|
||||
F(0xb365, LXR, RRE, Z, x2h, x2l, 0, x1, movx, 0, IF_AFP1)
|
||||
/* LOAD IMMEDIATE */
|
||||
C(0xc001, LGFI, RIL_a, EI, 0, i2, 0, r1, mov2, 0)
|
||||
/* LOAD RELATIVE LONG */
|
||||
|
@ -454,8 +454,8 @@
|
|||
C(0xe302, LTG, RXY_a, EI, 0, a2, r1, 0, ld64, s64)
|
||||
C(0xe332, LTGF, RXY_a, GIE, 0, a2, r1, 0, ld32s, s64)
|
||||
F(0xb302, LTEBR, RRE, Z, 0, e2, 0, cond_e1e2, mov2, f32, IF_BFP)
|
||||
F(0xb312, LTDBR, RRE, Z, 0, f2_o, 0, f1, mov2, f64, IF_BFP)
|
||||
F(0xb342, LTXBR, RRE, Z, 0, x2_o, 0, x1, movx, f128, IF_BFP)
|
||||
F(0xb312, LTDBR, RRE, Z, 0, f2, 0, f1, mov2, f64, IF_BFP)
|
||||
F(0xb342, LTXBR, RRE, Z, x2h, x2l, 0, x1, movx, f128, IF_BFP)
|
||||
/* LOAD AND TRAP */
|
||||
C(0xe39f, LAT, RXY_a, LAT, 0, m2_32u, r1, 0, lat, 0)
|
||||
C(0xe385, LGAT, RXY_a, LAT, 0, a2, r1, 0, lgat, 0)
|
||||
|
@ -476,9 +476,9 @@
|
|||
C(0xb903, LCGR, RRE, Z, 0, r2, r1, 0, neg, neg64)
|
||||
C(0xb913, LCGFR, RRE, Z, 0, r2_32s, r1, 0, neg, neg64)
|
||||
F(0xb303, LCEBR, RRE, Z, 0, e2, new, e1, negf32, f32, IF_BFP)
|
||||
F(0xb313, LCDBR, RRE, Z, 0, f2_o, f1, 0, negf64, f64, IF_BFP)
|
||||
F(0xb343, LCXBR, RRE, Z, 0, x2_o, x1, 0, negf128, f128, IF_BFP)
|
||||
F(0xb373, LCDFR, RRE, FPSSH, 0, f2_o, f1, 0, negf64, 0, IF_AFP1 | IF_AFP2)
|
||||
F(0xb313, LCDBR, RRE, Z, 0, f2, new, f1, negf64, f64, IF_BFP)
|
||||
F(0xb343, LCXBR, RRE, Z, x2h, x2l, new_P, x1, negf128, f128, IF_BFP)
|
||||
F(0xb373, LCDFR, RRE, FPSSH, 0, f2, new, f1, negf64, 0, IF_AFP1 | IF_AFP2)
|
||||
/* LOAD HALFWORD */
|
||||
C(0xb927, LHR, RRE, EI, 0, r2_16s, 0, r1_32, mov2, 0)
|
||||
C(0xb907, LGHR, RRE, EI, 0, r2_16s, 0, r1, mov2, 0)
|
||||
|
@ -537,15 +537,15 @@
|
|||
/* LOAD FPR FROM GR */
|
||||
F(0xb3c1, LDGR, RRE, FPRGR, 0, r2_o, 0, f1, mov2, 0, IF_AFP1)
|
||||
/* LOAD GR FROM FPR */
|
||||
F(0xb3cd, LGDR, RRE, FPRGR, 0, f2_o, 0, r1, mov2, 0, IF_AFP2)
|
||||
F(0xb3cd, LGDR, RRE, FPRGR, 0, f2, 0, r1, mov2, 0, IF_AFP2)
|
||||
/* LOAD NEGATIVE */
|
||||
C(0x1100, LNR, RR_a, Z, 0, r2_32s, new, r1_32, nabs, nabs32)
|
||||
C(0xb901, LNGR, RRE, Z, 0, r2, r1, 0, nabs, nabs64)
|
||||
C(0xb911, LNGFR, RRE, Z, 0, r2_32s, r1, 0, nabs, nabs64)
|
||||
F(0xb301, LNEBR, RRE, Z, 0, e2, new, e1, nabsf32, f32, IF_BFP)
|
||||
F(0xb311, LNDBR, RRE, Z, 0, f2_o, f1, 0, nabsf64, f64, IF_BFP)
|
||||
F(0xb341, LNXBR, RRE, Z, 0, x2_o, x1, 0, nabsf128, f128, IF_BFP)
|
||||
F(0xb371, LNDFR, RRE, FPSSH, 0, f2_o, f1, 0, nabsf64, 0, IF_AFP1 | IF_AFP2)
|
||||
F(0xb311, LNDBR, RRE, Z, 0, f2, new, f1, nabsf64, f64, IF_BFP)
|
||||
F(0xb341, LNXBR, RRE, Z, x2h, x2l, new_P, x1, nabsf128, f128, IF_BFP)
|
||||
F(0xb371, LNDFR, RRE, FPSSH, 0, f2, new, f1, nabsf64, 0, IF_AFP1 | IF_AFP2)
|
||||
/* LOAD ON CONDITION */
|
||||
C(0xb9f2, LOCR, RRF_c, LOC, r1, r2, new, r1_32, loc, 0)
|
||||
C(0xb9e2, LOCGR, RRF_c, LOC, r1, r2, r1, 0, loc, 0)
|
||||
|
@ -568,9 +568,9 @@
|
|||
C(0xb900, LPGR, RRE, Z, 0, r2, r1, 0, abs, abs64)
|
||||
C(0xb910, LPGFR, RRE, Z, 0, r2_32s, r1, 0, abs, abs64)
|
||||
F(0xb300, LPEBR, RRE, Z, 0, e2, new, e1, absf32, f32, IF_BFP)
|
||||
F(0xb310, LPDBR, RRE, Z, 0, f2_o, f1, 0, absf64, f64, IF_BFP)
|
||||
F(0xb340, LPXBR, RRE, Z, 0, x2_o, x1, 0, absf128, f128, IF_BFP)
|
||||
F(0xb370, LPDFR, RRE, FPSSH, 0, f2_o, f1, 0, absf64, 0, IF_AFP1 | IF_AFP2)
|
||||
F(0xb310, LPDBR, RRE, Z, 0, f2, new, f1, absf64, f64, IF_BFP)
|
||||
F(0xb340, LPXBR, RRE, Z, x2h, x2l, new_P, x1, absf128, f128, IF_BFP)
|
||||
F(0xb370, LPDFR, RRE, FPSSH, 0, f2, new, f1, absf64, 0, IF_AFP1 | IF_AFP2)
|
||||
/* LOAD REVERSED */
|
||||
C(0xb91f, LRVR, RRE, Z, 0, r2_32u, new, r1_32, rev32, 0)
|
||||
C(0xb90f, LRVGR, RRE, Z, 0, r2_o, r1, 0, rev64, 0)
|
||||
|
@ -588,20 +588,20 @@
|
|||
F(0xb2bd, LFAS, S, IEEEE_SIM, 0, m2_32u, 0, 0, sfas, 0, IF_DFP)
|
||||
/* LOAD FP INTEGER */
|
||||
F(0xb357, FIEBR, RRF_e, Z, 0, e2, new, e1, fieb, 0, IF_BFP)
|
||||
F(0xb35f, FIDBR, RRF_e, Z, 0, f2_o, f1, 0, fidb, 0, IF_BFP)
|
||||
F(0xb347, FIXBR, RRF_e, Z, 0, x2_o, x1, 0, fixb, 0, IF_BFP)
|
||||
F(0xb35f, FIDBR, RRF_e, Z, 0, f2, new, f1, fidb, 0, IF_BFP)
|
||||
F(0xb347, FIXBR, RRF_e, Z, x2h, x2l, new_P, x1, fixb, 0, IF_BFP)
|
||||
|
||||
/* LOAD LENGTHENED */
|
||||
F(0xb304, LDEBR, RRE, Z, 0, e2, f1, 0, ldeb, 0, IF_BFP)
|
||||
F(0xb305, LXDBR, RRE, Z, 0, f2_o, x1, 0, lxdb, 0, IF_BFP)
|
||||
F(0xb306, LXEBR, RRE, Z, 0, e2, x1, 0, lxeb, 0, IF_BFP)
|
||||
F(0xed04, LDEB, RXE, Z, 0, m2_32u, f1, 0, ldeb, 0, IF_BFP)
|
||||
F(0xed05, LXDB, RXE, Z, 0, m2_64, x1, 0, lxdb, 0, IF_BFP)
|
||||
F(0xed06, LXEB, RXE, Z, 0, m2_32u, x1, 0, lxeb, 0, IF_BFP)
|
||||
F(0xb304, LDEBR, RRE, Z, 0, e2, new, f1, ldeb, 0, IF_BFP)
|
||||
F(0xb305, LXDBR, RRE, Z, 0, f2, new_P, x1, lxdb, 0, IF_BFP)
|
||||
F(0xb306, LXEBR, RRE, Z, 0, e2, new_P, x1, lxeb, 0, IF_BFP)
|
||||
F(0xed04, LDEB, RXE, Z, 0, m2_32u, new, f1, ldeb, 0, IF_BFP)
|
||||
F(0xed05, LXDB, RXE, Z, 0, m2_64, new_P, x1, lxdb, 0, IF_BFP)
|
||||
F(0xed06, LXEB, RXE, Z, 0, m2_32u, new_P, x1, lxeb, 0, IF_BFP)
|
||||
/* LOAD ROUNDED */
|
||||
F(0xb344, LEDBR, RRE, Z, 0, f2_o, new, e1, ledb, 0, IF_BFP)
|
||||
F(0xb345, LDXBR, RRE, Z, 0, x2_o, f1, 0, ldxb, 0, IF_BFP)
|
||||
F(0xb346, LEXBR, RRE, Z, 0, x2_o, new, e1, lexb, 0, IF_BFP)
|
||||
F(0xb344, LEDBR, RRE, Z, 0, f2, new, e1, ledb, 0, IF_BFP)
|
||||
F(0xb345, LDXBR, RRE, Z, x2h, x2l, new, f1, ldxb, 0, IF_BFP)
|
||||
F(0xb346, LEXBR, RRE, Z, x2h, x2l, new, e1, lexb, 0, IF_BFP)
|
||||
|
||||
/* LOAD MULTIPLE */
|
||||
C(0x9800, LM, RS_a, Z, 0, a2, 0, 0, lm32, 0)
|
||||
|
@ -648,14 +648,14 @@
|
|||
C(0x5c00, M, RX_a, Z, r1p1_32s, m2_32s, new, r1_D32, mul, 0)
|
||||
C(0xe35c, MFY, RXY_a, GIE, r1p1_32s, m2_32s, new, r1_D32, mul, 0)
|
||||
F(0xb317, MEEBR, RRE, Z, e1, e2, new, e1, meeb, 0, IF_BFP)
|
||||
F(0xb31c, MDBR, RRE, Z, f1_o, f2_o, f1, 0, mdb, 0, IF_BFP)
|
||||
F(0xb34c, MXBR, RRE, Z, 0, x2_o, x1, 0, mxb, 0, IF_BFP)
|
||||
F(0xb30c, MDEBR, RRE, Z, f1_o, e2, f1, 0, mdeb, 0, IF_BFP)
|
||||
F(0xb307, MXDBR, RRE, Z, 0, f2_o, x1, 0, mxdb, 0, IF_BFP)
|
||||
F(0xb31c, MDBR, RRE, Z, f1, f2, new, f1, mdb, 0, IF_BFP)
|
||||
F(0xb34c, MXBR, RRE, Z, x2h, x2l, x1, x1, mxb, 0, IF_BFP)
|
||||
F(0xb30c, MDEBR, RRE, Z, f1, e2, new, f1, mdeb, 0, IF_BFP)
|
||||
F(0xb307, MXDBR, RRE, Z, 0, f2, x1, x1, mxdb, 0, IF_BFP)
|
||||
F(0xed17, MEEB, RXE, Z, e1, m2_32u, new, e1, meeb, 0, IF_BFP)
|
||||
F(0xed1c, MDB, RXE, Z, f1_o, m2_64, f1, 0, mdb, 0, IF_BFP)
|
||||
F(0xed0c, MDEB, RXE, Z, f1_o, m2_32u, f1, 0, mdeb, 0, IF_BFP)
|
||||
F(0xed07, MXDB, RXE, Z, 0, m2_64, x1, 0, mxdb, 0, IF_BFP)
|
||||
F(0xed1c, MDB, RXE, Z, f1, m2_64, new, f1, mdb, 0, IF_BFP)
|
||||
F(0xed0c, MDEB, RXE, Z, f1, m2_32u, new, f1, mdeb, 0, IF_BFP)
|
||||
F(0xed07, MXDB, RXE, Z, 0, m2_64, x1, x1, mxdb, 0, IF_BFP)
|
||||
/* MULTIPLY HALFWORD */
|
||||
C(0x4c00, MH, RX_a, Z, r1_o, m2_16s, new, r1_32, mul, 0)
|
||||
C(0xe37c, MHY, RXY_a, GIE, r1_o, m2_16s, new, r1_32, mul, 0)
|
||||
|
@ -681,14 +681,14 @@
|
|||
|
||||
/* MULTIPLY AND ADD */
|
||||
F(0xb30e, MAEBR, RRD, Z, e1, e2, new, e1, maeb, 0, IF_BFP)
|
||||
F(0xb31e, MADBR, RRD, Z, f1_o, f2_o, f1, 0, madb, 0, IF_BFP)
|
||||
F(0xb31e, MADBR, RRD, Z, f1, f2, new, f1, madb, 0, IF_BFP)
|
||||
F(0xed0e, MAEB, RXF, Z, e1, m2_32u, new, e1, maeb, 0, IF_BFP)
|
||||
F(0xed1e, MADB, RXF, Z, f1_o, m2_64, f1, 0, madb, 0, IF_BFP)
|
||||
F(0xed1e, MADB, RXF, Z, f1, m2_64, new, f1, madb, 0, IF_BFP)
|
||||
/* MULTIPLY AND SUBTRACT */
|
||||
F(0xb30f, MSEBR, RRD, Z, e1, e2, new, e1, mseb, 0, IF_BFP)
|
||||
F(0xb31f, MSDBR, RRD, Z, f1_o, f2_o, f1, 0, msdb, 0, IF_BFP)
|
||||
F(0xb31f, MSDBR, RRD, Z, f1, f2, new, f1, msdb, 0, IF_BFP)
|
||||
F(0xed0f, MSEB, RXF, Z, e1, m2_32u, new, e1, mseb, 0, IF_BFP)
|
||||
F(0xed1f, MSDB, RXF, Z, f1_o, m2_64, f1, 0, msdb, 0, IF_BFP)
|
||||
F(0xed1f, MSDB, RXF, Z, f1, m2_64, new, f1, msdb, 0, IF_BFP)
|
||||
|
||||
/* OR */
|
||||
C(0x1600, OR, RR_a, Z, r1, r2, new, r1_32, or, nz32)
|
||||
|
@ -793,17 +793,17 @@
|
|||
|
||||
/* SQUARE ROOT */
|
||||
F(0xb314, SQEBR, RRE, Z, 0, e2, new, e1, sqeb, 0, IF_BFP)
|
||||
F(0xb315, SQDBR, RRE, Z, 0, f2_o, f1, 0, sqdb, 0, IF_BFP)
|
||||
F(0xb316, SQXBR, RRE, Z, 0, x2_o, x1, 0, sqxb, 0, IF_BFP)
|
||||
F(0xb315, SQDBR, RRE, Z, 0, f2, new, f1, sqdb, 0, IF_BFP)
|
||||
F(0xb316, SQXBR, RRE, Z, x2h, x2l, new, x1, sqxb, 0, IF_BFP)
|
||||
F(0xed14, SQEB, RXE, Z, 0, m2_32u, new, e1, sqeb, 0, IF_BFP)
|
||||
F(0xed15, SQDB, RXE, Z, 0, m2_64, f1, 0, sqdb, 0, IF_BFP)
|
||||
F(0xed15, SQDB, RXE, Z, 0, m2_64, new, f1, sqdb, 0, IF_BFP)
|
||||
|
||||
/* STORE */
|
||||
C(0x5000, ST, RX_a, Z, r1_o, a2, 0, 0, st32, 0)
|
||||
C(0xe350, STY, RXY_a, LD, r1_o, a2, 0, 0, st32, 0)
|
||||
C(0xe324, STG, RXY_a, Z, r1_o, a2, 0, 0, st64, 0)
|
||||
F(0x6000, STD, RX_a, Z, f1_o, a2, 0, 0, st64, 0, IF_AFP1)
|
||||
F(0xed67, STDY, RXY_a, LD, f1_o, a2, 0, 0, st64, 0, IF_AFP1)
|
||||
F(0x6000, STD, RX_a, Z, f1, a2, 0, 0, st64, 0, IF_AFP1)
|
||||
F(0xed67, STDY, RXY_a, LD, f1, a2, 0, 0, st64, 0, IF_AFP1)
|
||||
F(0x7000, STE, RX_a, Z, e1, a2, 0, 0, st32, 0, IF_AFP1)
|
||||
F(0xed66, STEY, RXY_a, LD, e1, a2, 0, 0, st32, 0, IF_AFP1)
|
||||
/* STORE RELATIVE LONG */
|
||||
|
@ -865,10 +865,10 @@
|
|||
C(0xe309, SG, RXY_a, Z, r1, m2_64, r1, 0, sub, subs64)
|
||||
C(0xe319, SGF, RXY_a, Z, r1, m2_32s, r1, 0, sub, subs64)
|
||||
F(0xb30b, SEBR, RRE, Z, e1, e2, new, e1, seb, f32, IF_BFP)
|
||||
F(0xb31b, SDBR, RRE, Z, f1_o, f2_o, f1, 0, sdb, f64, IF_BFP)
|
||||
F(0xb34b, SXBR, RRE, Z, 0, x2_o, x1, 0, sxb, f128, IF_BFP)
|
||||
F(0xb31b, SDBR, RRE, Z, f1, f2, new, f1, sdb, f64, IF_BFP)
|
||||
F(0xb34b, SXBR, RRE, Z, x2h, x2l, x1, x1, sxb, f128, IF_BFP)
|
||||
F(0xed0b, SEB, RXE, Z, e1, m2_32u, new, e1, seb, f32, IF_BFP)
|
||||
F(0xed1b, SDB, RXE, Z, f1_o, m2_64, f1, 0, sdb, f64, IF_BFP)
|
||||
F(0xed1b, SDB, RXE, Z, f1, m2_64, new, f1, sdb, f64, IF_BFP)
|
||||
/* SUBTRACT HALFWORD */
|
||||
C(0x4b00, SH, RX_a, Z, r1, m2_16s, new, r1_32, sub, subs32)
|
||||
C(0xe37b, SHY, RXY_a, LD, r1, m2_16s, new, r1_32, sub, subs32)
|
||||
|
@ -908,8 +908,8 @@
|
|||
|
||||
/* TEST DATA CLASS */
|
||||
F(0xed10, TCEB, RXE, Z, e1, a2, 0, 0, tceb, 0, IF_BFP)
|
||||
F(0xed11, TCDB, RXE, Z, f1_o, a2, 0, 0, tcdb, 0, IF_BFP)
|
||||
F(0xed12, TCXB, RXE, Z, x1_o, a2, 0, 0, tcxb, 0, IF_BFP)
|
||||
F(0xed11, TCDB, RXE, Z, f1, a2, 0, 0, tcdb, 0, IF_BFP)
|
||||
F(0xed12, TCXB, RXE, Z, 0, a2, x1, 0, tcxb, 0, IF_BFP)
|
||||
|
||||
/* TEST DECIMAL */
|
||||
C(0xebc0, TP, RSL, E2, la1, 0, 0, 0, tp, 0)
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "hw/hw.h"
|
||||
#include "sysemu/device_tree.h"
|
||||
#include "exec/gdbstub.h"
|
||||
#include "exec/ram_addr.h"
|
||||
#include "trace.h"
|
||||
#include "hw/s390x/s390-pci-inst.h"
|
||||
#include "hw/s390x/s390-pci-bus.h"
|
||||
|
@ -287,7 +288,7 @@ void kvm_s390_crypto_reset(void)
|
|||
|
||||
static int kvm_s390_configure_mempath_backing(KVMState *s)
|
||||
{
|
||||
size_t path_psize = qemu_mempath_getpagesize(mem_path);
|
||||
size_t path_psize = qemu_getrampagesize();
|
||||
|
||||
if (path_psize == 4 * KiB) {
|
||||
return 0;
|
||||
|
@ -319,7 +320,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
|
|||
{
|
||||
MachineClass *mc = MACHINE_GET_CLASS(ms);
|
||||
|
||||
if (mem_path && kvm_s390_configure_mempath_backing(s)) {
|
||||
if (kvm_s390_configure_mempath_backing(s)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -111,9 +111,8 @@ static TCGv_i64 cc_src;
|
|||
static TCGv_i64 cc_dst;
|
||||
static TCGv_i64 cc_vr;
|
||||
|
||||
static char cpu_reg_names[32][4];
|
||||
static char cpu_reg_names[16][4];
|
||||
static TCGv_i64 regs[16];
|
||||
static TCGv_i64 fregs[16];
|
||||
|
||||
void s390x_translate_init(void)
|
||||
{
|
||||
|
@ -144,13 +143,53 @@ void s390x_translate_init(void)
|
|||
offsetof(CPUS390XState, regs[i]),
|
||||
cpu_reg_names[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
snprintf(cpu_reg_names[i + 16], sizeof(cpu_reg_names[0]), "f%d", i);
|
||||
fregs[i] = tcg_global_mem_new(cpu_env,
|
||||
offsetof(CPUS390XState, vregs[i][0].d),
|
||||
cpu_reg_names[i + 16]);
|
||||
}
|
||||
static inline int vec_reg_offset(uint8_t reg, uint8_t enr, TCGMemOp size)
|
||||
{
|
||||
const uint8_t es = 1 << size;
|
||||
int offs = enr * es;
|
||||
|
||||
g_assert(reg < 32);
|
||||
/*
|
||||
* vregs[n][0] is the lowest 8 byte and vregs[n][1] the highest 8 byte
|
||||
* of the 16 byte vector, on both, little and big endian systems.
|
||||
*
|
||||
* Big Endian (target/possible host)
|
||||
* B: [ 0][ 1][ 2][ 3][ 4][ 5][ 6][ 7] - [ 8][ 9][10][11][12][13][14][15]
|
||||
* HW: [ 0][ 1][ 2][ 3] - [ 4][ 5][ 6][ 7]
|
||||
* W: [ 0][ 1] - [ 2][ 3]
|
||||
* DW: [ 0] - [ 1]
|
||||
*
|
||||
* Little Endian (possible host)
|
||||
* B: [ 7][ 6][ 5][ 4][ 3][ 2][ 1][ 0] - [15][14][13][12][11][10][ 9][ 8]
|
||||
* HW: [ 3][ 2][ 1][ 0] - [ 7][ 6][ 5][ 4]
|
||||
* W: [ 1][ 0] - [ 3][ 2]
|
||||
* DW: [ 0] - [ 1]
|
||||
*
|
||||
* For 16 byte elements, the two 8 byte halves will not form a host
|
||||
* int128 if the host is little endian, since they're in the wrong order.
|
||||
* Some operations (e.g. xor) do not care. For operations like addition,
|
||||
* the two 8 byte elements have to be loaded separately. Let's force all
|
||||
* 16 byte operations to handle it in a special way.
|
||||
*/
|
||||
g_assert(size <= MO_64);
|
||||
#ifndef HOST_WORDS_BIGENDIAN
|
||||
offs ^= (8 - es);
|
||||
#endif
|
||||
return offs + offsetof(CPUS390XState, vregs[reg][0].d);
|
||||
}
|
||||
|
||||
static inline int freg64_offset(uint8_t reg)
|
||||
{
|
||||
g_assert(reg < 16);
|
||||
return vec_reg_offset(reg, 0, MO_64);
|
||||
}
|
||||
|
||||
static inline int freg32_offset(uint8_t reg)
|
||||
{
|
||||
g_assert(reg < 16);
|
||||
return vec_reg_offset(reg, 0, MO_32);
|
||||
}
|
||||
|
||||
static TCGv_i64 load_reg(int reg)
|
||||
|
@ -160,10 +199,19 @@ static TCGv_i64 load_reg(int reg)
|
|||
return r;
|
||||
}
|
||||
|
||||
static TCGv_i64 load_freg(int reg)
|
||||
{
|
||||
TCGv_i64 r = tcg_temp_new_i64();
|
||||
|
||||
tcg_gen_ld_i64(r, cpu_env, freg64_offset(reg));
|
||||
return r;
|
||||
}
|
||||
|
||||
static TCGv_i64 load_freg32_i64(int reg)
|
||||
{
|
||||
TCGv_i64 r = tcg_temp_new_i64();
|
||||
tcg_gen_shri_i64(r, fregs[reg], 32);
|
||||
|
||||
tcg_gen_ld32u_i64(r, cpu_env, freg32_offset(reg));
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -174,7 +222,7 @@ static void store_reg(int reg, TCGv_i64 v)
|
|||
|
||||
static void store_freg(int reg, TCGv_i64 v)
|
||||
{
|
||||
tcg_gen_mov_i64(fregs[reg], v);
|
||||
tcg_gen_st_i64(v, cpu_env, freg64_offset(reg));
|
||||
}
|
||||
|
||||
static void store_reg32_i64(int reg, TCGv_i64 v)
|
||||
|
@ -190,7 +238,7 @@ static void store_reg32h_i64(int reg, TCGv_i64 v)
|
|||
|
||||
static void store_freg32_i64(int reg, TCGv_i64 v)
|
||||
{
|
||||
tcg_gen_deposit_i64(fregs[reg], fregs[reg], v, 32, 32);
|
||||
tcg_gen_st32_i64(v, cpu_env, freg32_offset(reg));
|
||||
}
|
||||
|
||||
static void return_low128(TCGv_i64 dest)
|
||||
|
@ -3325,8 +3373,9 @@ static DisasJumpType op_maeb(DisasContext *s, DisasOps *o)
|
|||
|
||||
static DisasJumpType op_madb(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
int r3 = get_field(s->fields, r3);
|
||||
gen_helper_madb(o->out, cpu_env, o->in1, o->in2, fregs[r3]);
|
||||
TCGv_i64 r3 = load_freg(get_field(s->fields, r3));
|
||||
gen_helper_madb(o->out, cpu_env, o->in1, o->in2, r3);
|
||||
tcg_temp_free_i64(r3);
|
||||
return DISAS_NEXT;
|
||||
}
|
||||
|
||||
|
@ -3340,8 +3389,9 @@ static DisasJumpType op_mseb(DisasContext *s, DisasOps *o)
|
|||
|
||||
static DisasJumpType op_msdb(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
int r3 = get_field(s->fields, r3);
|
||||
gen_helper_msdb(o->out, cpu_env, o->in1, o->in2, fregs[r3]);
|
||||
TCGv_i64 r3 = load_freg(get_field(s->fields, r3));
|
||||
gen_helper_msdb(o->out, cpu_env, o->in1, o->in2, r3);
|
||||
tcg_temp_free_i64(r3);
|
||||
return DISAS_NEXT;
|
||||
}
|
||||
|
||||
|
@ -5085,19 +5135,11 @@ static void prep_r1_P(DisasContext *s, DisasFields *f, DisasOps *o)
|
|||
}
|
||||
#define SPEC_prep_r1_P SPEC_r1_even
|
||||
|
||||
static void prep_f1(DisasContext *s, DisasFields *f, DisasOps *o)
|
||||
{
|
||||
o->out = fregs[get_field(f, r1)];
|
||||
o->g_out = true;
|
||||
}
|
||||
#define SPEC_prep_f1 0
|
||||
|
||||
/* Whenever we need x1 in addition to other inputs, we'll load it to out/out2 */
|
||||
static void prep_x1(DisasContext *s, DisasFields *f, DisasOps *o)
|
||||
{
|
||||
int r1 = get_field(f, r1);
|
||||
o->out = fregs[r1];
|
||||
o->out2 = fregs[r1 + 2];
|
||||
o->g_out = o->g_out2 = true;
|
||||
o->out = load_freg(get_field(f, r1));
|
||||
o->out2 = load_freg(get_field(f, r1) + 2);
|
||||
}
|
||||
#define SPEC_prep_x1 SPEC_r1_f128
|
||||
|
||||
|
@ -5393,28 +5435,24 @@ static void in1_e1(DisasContext *s, DisasFields *f, DisasOps *o)
|
|||
}
|
||||
#define SPEC_in1_e1 0
|
||||
|
||||
static void in1_f1_o(DisasContext *s, DisasFields *f, DisasOps *o)
|
||||
static void in1_f1(DisasContext *s, DisasFields *f, DisasOps *o)
|
||||
{
|
||||
o->in1 = fregs[get_field(f, r1)];
|
||||
o->g_in1 = true;
|
||||
o->in1 = load_freg(get_field(f, r1));
|
||||
}
|
||||
#define SPEC_in1_f1_o 0
|
||||
#define SPEC_in1_f1 0
|
||||
|
||||
static void in1_x1_o(DisasContext *s, DisasFields *f, DisasOps *o)
|
||||
/* Load the high double word of an extended (128-bit) format FP number */
|
||||
static void in1_x2h(DisasContext *s, DisasFields *f, DisasOps *o)
|
||||
{
|
||||
int r1 = get_field(f, r1);
|
||||
o->out = fregs[r1];
|
||||
o->out2 = fregs[r1 + 2];
|
||||
o->g_out = o->g_out2 = true;
|
||||
o->in1 = load_freg(get_field(f, r2));
|
||||
}
|
||||
#define SPEC_in1_x1_o SPEC_r1_f128
|
||||
#define SPEC_in1_x2h SPEC_r2_f128
|
||||
|
||||
static void in1_f3_o(DisasContext *s, DisasFields *f, DisasOps *o)
|
||||
static void in1_f3(DisasContext *s, DisasFields *f, DisasOps *o)
|
||||
{
|
||||
o->in1 = fregs[get_field(f, r3)];
|
||||
o->g_in1 = true;
|
||||
o->in1 = load_freg(get_field(f, r3));
|
||||
}
|
||||
#define SPEC_in1_f3_o 0
|
||||
#define SPEC_in1_f3 0
|
||||
|
||||
static void in1_la1(DisasContext *s, DisasFields *f, DisasOps *o)
|
||||
{
|
||||
|
@ -5599,21 +5637,18 @@ static void in2_e2(DisasContext *s, DisasFields *f, DisasOps *o)
|
|||
}
|
||||
#define SPEC_in2_e2 0
|
||||
|
||||
static void in2_f2_o(DisasContext *s, DisasFields *f, DisasOps *o)
|
||||
static void in2_f2(DisasContext *s, DisasFields *f, DisasOps *o)
|
||||
{
|
||||
o->in2 = fregs[get_field(f, r2)];
|
||||
o->g_in2 = true;
|
||||
o->in2 = load_freg(get_field(f, r2));
|
||||
}
|
||||
#define SPEC_in2_f2_o 0
|
||||
#define SPEC_in2_f2 0
|
||||
|
||||
static void in2_x2_o(DisasContext *s, DisasFields *f, DisasOps *o)
|
||||
/* Load the low double word of an extended (128-bit) format FP number */
|
||||
static void in2_x2l(DisasContext *s, DisasFields *f, DisasOps *o)
|
||||
{
|
||||
int r2 = get_field(f, r2);
|
||||
o->in1 = fregs[r2];
|
||||
o->in2 = fregs[r2 + 2];
|
||||
o->g_in1 = o->g_in2 = true;
|
||||
o->in2 = load_freg(get_field(f, r2) + 2);
|
||||
}
|
||||
#define SPEC_in2_x2_o SPEC_r2_f128
|
||||
#define SPEC_in2_x2l SPEC_r2_f128
|
||||
|
||||
static void in2_ra2(DisasContext *s, DisasFields *f, DisasOps *o)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue