aboutsummaryrefslogtreecommitdiff
path: root/target-ppc
diff options
context:
space:
mode:
authorThomas Huth <thuth@redhat.com>2016-10-11 08:56:52 +0200
committerThomas Huth <thuth@redhat.com>2016-12-20 21:52:12 +0100
commitfcf5ef2ab52c621a4617ebbef36bf43b4003f4c0 (patch)
tree2b450d96b01455df8ed908bf8f26ddc388a03380 /target-ppc
parent82ecffa8c050bf5bbc13329e9b65eac1caa5b55c (diff)
Move target-* CPU file into a target/ folder
We've currently got 18 architectures in QEMU, and thus 18 target-xxx folders in the root folder of the QEMU source tree. More architectures (e.g. RISC-V, AVR) are likely to be included soon, too, so the main folder of the QEMU sources slowly gets quite overcrowded with the target-xxx folders. To disburden the main folder a little bit, let's move the target-xxx folders into a dedicated target/ folder, so that target-xxx/ simply becomes target/xxx/ instead. Acked-by: Laurent Vivier <laurent@vivier.eu> [m68k part] Acked-by: Bastian Koppelmann <kbastian@mail.uni-paderborn.de> [tricore part] Acked-by: Michael Walle <michael@walle.cc> [lm32 part] Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com> [s390x part] Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com> [s390x part] Acked-by: Eduardo Habkost <ehabkost@redhat.com> [i386 part] Acked-by: Artyom Tarasenko <atar4qemu@gmail.com> [sparc part] Acked-by: Richard Henderson <rth@twiddle.net> [alpha part] Acked-by: Max Filippov <jcmvbkbc@gmail.com> [xtensa part] Reviewed-by: David Gibson <david@gibson.dropbear.id.au> [ppc part] Acked-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> [cris&microblaze part] Acked-by: Guan Xuetao <gxt@mprc.pku.edu.cn> [unicore32 part] Signed-off-by: Thomas Huth <thuth@redhat.com>
Diffstat (limited to 'target-ppc')
-rw-r--r--target-ppc/Makefile.objs17
-rw-r--r--target-ppc/STATUS550
-rw-r--r--target-ppc/arch_dump.c286
-rw-r--r--target-ppc/cpu-models.c1426
-rw-r--r--target-ppc/cpu-models.h754
-rw-r--r--target-ppc/cpu-qom.h219
-rw-r--r--target-ppc/cpu.h2454
-rw-r--r--target-ppc/dfp_helper.c1331
-rw-r--r--target-ppc/excp_helper.c1142
-rw-r--r--target-ppc/fpu_helper.c2789
-rw-r--r--target-ppc/gdbstub.c321
-rw-r--r--target-ppc/helper.h742
-rw-r--r--target-ppc/helper_regs.h189
-rw-r--r--target-ppc/int_helper.c3126
-rw-r--r--target-ppc/internal.h50
-rw-r--r--target-ppc/kvm-stub.c20
-rw-r--r--target-ppc/kvm.c2674
-rw-r--r--target-ppc/kvm_ppc.h330
-rw-r--r--target-ppc/machine.c615
-rw-r--r--target-ppc/mem_helper.c310
-rw-r--r--target-ppc/mfrom_table.c79
-rw-r--r--target-ppc/mfrom_table_gen.c32
-rw-r--r--target-ppc/misc_helper.c210
-rw-r--r--target-ppc/mmu-hash32.c568
-rw-r--r--target-ppc/mmu-hash32.h112
-rw-r--r--target-ppc/mmu-hash64.c1059
-rw-r--r--target-ppc/mmu-hash64.h136
-rw-r--r--target-ppc/mmu_helper.c2907
-rw-r--r--target-ppc/monitor.c147
-rw-r--r--target-ppc/timebase_helper.c176
-rw-r--r--target-ppc/trace-events5
-rw-r--r--target-ppc/translate.c7200
-rw-r--r--target-ppc/translate/dfp-impl.inc.c232
-rw-r--r--target-ppc/translate/dfp-ops.inc.c165
-rw-r--r--target-ppc/translate/fp-impl.inc.c1070
-rw-r--r--target-ppc/translate/fp-ops.inc.c111
-rw-r--r--target-ppc/translate/spe-impl.inc.c1229
-rw-r--r--target-ppc/translate/spe-ops.inc.c105
-rw-r--r--target-ppc/translate/vmx-impl.inc.c1113
-rw-r--r--target-ppc/translate/vmx-ops.inc.c294
-rw-r--r--target-ppc/translate/vsx-impl.inc.c1009
-rw-r--r--target-ppc/translate/vsx-ops.inc.c300
-rw-r--r--target-ppc/translate_init.c10601
-rw-r--r--target-ppc/user_only_helper.c47
44 files changed, 0 insertions, 48252 deletions
diff --git a/target-ppc/Makefile.objs b/target-ppc/Makefile.objs
deleted file mode 100644
index e667e69701..0000000000
--- a/target-ppc/Makefile.objs
+++ /dev/null
@@ -1,17 +0,0 @@
-obj-y += cpu-models.o
-obj-y += translate.o
-ifeq ($(CONFIG_SOFTMMU),y)
-obj-y += machine.o mmu_helper.o mmu-hash32.o monitor.o
-obj-$(TARGET_PPC64) += mmu-hash64.o arch_dump.o
-endif
-obj-$(CONFIG_KVM) += kvm.o
-obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
-obj-y += dfp_helper.o
-obj-y += excp_helper.o
-obj-y += fpu_helper.o
-obj-y += int_helper.o
-obj-y += timebase_helper.o
-obj-y += misc_helper.o
-obj-y += mem_helper.o
-obj-$(CONFIG_USER_ONLY) += user_only_helper.o
-obj-y += gdbstub.o
diff --git a/target-ppc/STATUS b/target-ppc/STATUS
deleted file mode 100644
index a4d48a7ca2..0000000000
--- a/target-ppc/STATUS
+++ /dev/null
@@ -1,550 +0,0 @@
-PowerPC emulation status.
-The goal of this file is to provide a reference status to avoid regressions.
-
-===============================================================================
-PowerPC core emulation status
-
-INSN: instruction set.
- OK => all instructions are emulated
- KO => some insns are missing or some should be removed
- ? => unchecked
-SPR: special purpose registers set
- OK => all SPR registered (but some may be fake)
- KO => some SPR are missing or should be removed
- ? => unchecked
-MSR: MSR bits definitions
- OK => all MSR bits properly defined
- KO => MSR definition is incorrect
- ? => unchecked
-IRQ: input signals definitions (mostly interrupts)
- OK => input signals are properly defined
- KO => input signals are not implemented (system emulation does not work)
- ? => input signals definitions may be incorrect
-MMU: MMU model implementation
- OK => MMU model is implemented and Linux is able to boot
- KO => MMU model not implemented or bugged
- ? => MMU model not tested
-EXCP: exceptions model implementation
- OK => exception model is implemented and Linux is able to boot
- KO => exception model not implemented or known to be buggy
- ? => exception model may be incorrect or is untested
-
-Embedded PowerPC cores
-***
-PowerPC 401:
-INSN OK
-SPR OK 401A1
-MSR OK
-IRQ KO partially implemented
-MMU OK
-EXCP ?
-
-PowerPC 401x2:
-INSN OK
-SPR OK 401B2 401C2 401D2 401E2 401F2
-MSR OK
-IRQ KO partially implemented
-MMU OK
-EXCP ?
-
-PowerPC IOP480:
-INSN OK
-SPR OK IOP480
-MSR OK
-IRQ KO partially implemented
-MMU OK
-EXCP ?
-
-To be checked: 401G2 401B3 Cobra
-
-***
-PowerPC 403:
-INSN OK
-SPR OK 403GA 403GB
-MMU OK
-MSR OK
-IRQ KO not implemented
-EXCP ?
-
-PowerPC 403GCX:
-INSN OK
-SPR OK 403GCX
-MMU OK
-MSR OK
-IRQ KO not implemented
-EXCP ?
-
-To be checked: 403GC
-
-***
-PowerPC 405:
-Checked: 405CRa 405CRb 405CRc 405EP 405GPa 405GPb 405GPc 405GPd 405GPe 405GPR
- Npe405H Npe405H2 Npe405L
-INSN OK
-SPR OK
-MSR OK
-IRQ OK
-MMU OK
-EXCP OK
-Remarks: Linux 2.4 boots (at least 1 proprietary firmware).
- uboot seems to freeze at boot time.
-To be checked: 405D2 405D4 405EZ 405LP Npe4GS3 STB03 STB04 STB25
- x2vp4 x2vp7 x2vp20 x2vp50
-
-XXX: find what is IBM e407b4
-
-***
-PowerPC 440:
-Checked: 440EPa 440EPb 440GXa 440GXb 440GXc 440GXf 440SP 440SP2
-INSN OK
-SPR OK
-MSR OK
-IRQ KO not implemented
-MMU ?
-EXCP ?
-
-PowerPC 440GP:
-Checked: 440GPb 440GPc
-INSN OK
-SPR OK
-MSR OK
-IRQ KO not implemented
-MMU ?
-EXCP ?
-
-PowerPC 440x4:
-Checked: 440A4 440B4 440G4 440H4
-INSN OK
-SPR OK
-MSR OK
-IRQ KO not implemented
-MMU ?
-EXCP ?
-
-PowerPC 440x5:
-Checked: 440A5 440F5 440G5 440H6 440GRa
-INSN OK
-SPR OK
-MSR OK
-IRQ KO not implemented
-MMU ?
-EXCP ?
-
-To be checked: 440EPx 440GRx 440SPE
-
-***
-PowerPC 460: (disabled: lack of detailed specifications)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-PowerPC 460F: (disabled: lack of detailed specifications)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-***
-PowerPC e200: (not implemented)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-***
-PowerPC e300: (not implemented)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-***
-PowerPC e500: (not implemented)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-***
-PowerPC e600: (not implemented)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-***
-32 bits PowerPC
-PowerPC 601: (601 601v2)
-INSN OK
-SPR OK is HID15 only on 601v2 ?
-MSR OK
-IRQ KO not implemented
-MMU ?
-EXCP ?
-Remarks: some instructions should have a specific behavior (not implemented)
-
-PowerPC 602: 602
-INSN OK
-SPR OK
-MSR OK
-IRQ OK
-MMU ?
-EXCP ? at least timer and external interrupt are OK
-Remarks: Linux 2.4 crashes when entering user-mode.
- Linux 2.6.22 boots on this CPU but does not recognize it.
-
-PowerPC 603: (603)
-INSN OK
-SPR OK
-MSR OK
-IRQ OK
-MMU OK
-EXCP OK
-Remarks: Linux 2.4 boots and properly recognizes the CPU
- Linux 2.6.22 idem.
-
-PowerPC 603e: (603e11)
-INSN OK
-SPR OK
-MSR OK
-IRQ OK
-MMU OK
-EXCP OK
-Remarks: Linux 2.4 boots and properly recognizes the CPU
- Linux 2.6.22 idem.
-
-PowerPC G2:
-INSN OK
-SPR OK
-MSR OK
-IRQ OK
-MMU OK
-EXCP OK
-Remarks: Linux 2.4 boots, recognizes the CPU as a 82xx.
- Linux 2.6.22 idem.
-
-PowerPC G2le:
-INSN OK
-SPR OK
-MSR OK
-IRQ OK
-MMU OK
-EXCP OK
-Remarks: Linux 2.4 does not boots. Same symptoms as 602.
- Linux 2.6.22 boots and properly recognizes the CPU.
-
-PowerPC 604:
-INSN OK
-SPR OK
-MSR OK
-IRQ OK
-MMU OK
-EXCP OK
-Remarks: Linux 2.4 boots and properly recognizes the CPU.
- Linux 2.6.22 idem.
-
-PowerPC 7x0:
-INSN OK
-SPR OK
-MSR OK
-IRQ OK
-MMU OK
-EXCP OK
-Remarks: Linux 2.4 boots and properly recognizes the CPU.
- Linux 2.6.22 idem.
-
-PowerPC 750fx:
-INSN OK
-SPR OK
-MSR OK
-IRQ OK
-MMU OK
-EXCP OK
-Remarks: Linux 2.4 boots but does not properly recognizes the CPU.
- Linux 2.6.22 boots and properly recognizes the CPU.
-
-PowerPC 7x5:
-INSN ?
-SPR ?
-MSR ?
-IRQ OK
-MMU ?
-EXCP OK
-Remarks: Linux 2.4 does not boot.
- Linux 2.6.22 idem.
-
-PowerPC 7400:
-INSN KO Altivec missing
-SPR OK
-MSR OK
-IRQ OK
-MMU OK
-EXCP ? Altivec, ...
-Remarks: Linux 2.4 boots and properly recognize the CPU.
- Linux 2.6.22 idem.
-
-PowerPC 7410:
-INSN KO Altivec missing
-SPR OK
-MSR OK
-IRQ OK
-MMU OK
-EXCP ? Altivec, ...
-Remarks: Linux 2.4 boots and properly recognize the CPU.
- Linux 2.6.22 idem.
- Note that UM says tlbld & tlbli are implemented but this may be a mistake
- as TLB loads are managed by the hardware and the CPU does not implement the
- needed registers.
-
-PowerPC 7441:
-INSN KO Altivec missing
-SPR OK
-MSR OK
-IRQ OK
-MMU OK
-EXCP ? Altivec, ...
-Remarks: Linux does not have the code to handle TLB miss on this CPU
- Linux 2.6.22 idem.
-
-PowerPC 7450/7451:
-INSN KO Altivec missing
-SPR OK
-MSR OK
-IRQ OK
-MMU OK
-EXCP ? Altivec, ...
-Remarks: Linux does not have the code to handle TLB miss on this CPU
- Linux 2.6.22 idem.
-
-PowerPC 7445/7447:
-INSN KO Altivec missing
-SPR OK
-MSR OK
-IRQ OK
-MMU OK
-EXCP ? Altivec, ...
-Remarks: Linux does not have the code to handle TLB miss on this CPU
- Linux 2.6.22 idem.
-
-PowerPC 7455/7457:
-INSN KO Altivec missing
-SPR OK
-MSR OK
-IRQ OK
-MMU OK
-EXCP ? Altivec, ...
-Remarks: Linux does not have the code to handle TLB miss on this CPU
- Linux 2.6.22 idem.
-
-64 bits PowerPC
-PowerPC 620: (disabled)
-INSN KO
-SPR KO
-MSR ?
-IRQ KO
-MMU KO
-EXCP KO
-Remarks: not much documentation for this implementation...
-
-PowerPC 970:
-INSN KO Altivec missing and more
-SPR KO
-MSR ?
-IRQ OK
-MMU OK
-EXCP KO partially implemented
-Remarks: Should be able to boot but there is no hw platform currently emulated.
-
-PowerPC 970FX:
-INSN KO Altivec missing and more
-SPR KO
-MSR ?
-IRQ OK
-MMU OK
-EXCP KO partially implemented
-Remarks: Should be able to boot but there is no hw platform currently emulated.
-
-PowerPC Cell:
-INSN KO Altivec missing and more
-SPR KO
-MSR ?
-IRQ ?
-MMU ?
-EXCP ? partially implemented
-Remarks: As the core is mostly a 970, should be able to boot.
- SPE are not implemented.
-
-PowerPC 630: (disabled: lack of detailed specifications)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-PowerPC 631: (disabled: lack of detailed specifications)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-POWER4: (disabled: lack of detailed specifications)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-POWER4+: (disabled: lack of detailed specifications)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-POWER5: (disabled: lack of detailed specifications)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-POWER5+: (disabled: lack of detailed specifications)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-POWER6: (disabled: lack of detailed specifications)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-RS64: (disabled: lack of detailed specifications)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-RS64-II: (disabled: lack of detailed specifications)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-RS64-III: (disabled: lack of detailed specifications)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-RS64-IV: (disabled: lack of detailed specifications)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-Original POWER
-POWER: (disabled: lack of detailed specifications)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-POWER2: (disabled: lack of detailed specifications)
-INSN KO
-SPR KO
-MSR KO
-IRQ KO
-MMU KO
-EXCP KO
-
-===============================================================================
-PowerPC microcontrollers emulation status
-
-Implemementation should be sufficient to boot Linux:
-(there seem to be problems with uboot freezing at some point)
-- PowerPC 405CR
-- PowerPC 405EP
-
-TODO:
-- PowerPC 401 microcontrollers emulation
-- PowerPC 403 microcontrollers emulation
-- more PowerPC 405 microcontrollers emulation
-- Fixes / more features for implemented PowerPC 405 microcontrollers emulation
-- PowerPC 440 microcontrollers emulation
-- e200 microcontrollers emulation
-- e300 microcontrollers emulation
-- e500 microcontrollers emulation
-- e600 microcontrollers emulation
-
-===============================================================================
-PowerPC based platforms emulation status
-
-* PREP platform (RS/6000 7043...) - TO BE CHECKED (broken)
-- Gentoo Linux live CDROM 1.4
-- Debian Linux 3.0
-- Mandrake Linux 9
-
-* heathrow PowerMac platform (beige PowerMac) - TO BE CHECKED (broken)
-- Gentoo Linux live CDROM 1.4
-- Debian Linux 3.0
-- Mandrake Linux 9
-
-* mac99 platform (white and blue PowerMac, ...)
-- Gentoo Linux live CDROM 1.4 - boots, compiles linux kernel
-- Debian Linux woody - boots from CDROM and HDD
-- Mandrake Linux 9 - boots from CDROM, freezes during install
-- Knoppix 2003-07-13_4 boots from CDROM, pb with X configuration
- distribution bug: X runs with a properly hand-coded configuration.
-- rock Linux 2.0 runs from CDROM
-
-* Linux 2.6 support seems deadly broken (used to boot...).
-
-* PowerPC 405EP reference boards:
-- can boot Linux 2.4 & 2.6.
- Need to provide a flash image ready to boot for reproductible tests.
-
-TODO:
-- URGENT: fix PreP and heathrow platforms
-- PowerPC 64 reference platform
-- MCA based RS/6000 emulation
-- CHRP emulation (not PowerMac)
-- PPAR emulation
-- ePPAR emulation
-- misc PowerPC reference boards emulation
-
-===============================================================================
diff --git a/target-ppc/arch_dump.c b/target-ppc/arch_dump.c
deleted file mode 100644
index 40282a1f50..0000000000
--- a/target-ppc/arch_dump.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * writing ELF notes for ppc64 arch
- *
- *
- * Copyright IBM, Corp. 2013
- *
- * Authors:
- * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2. See
- * the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "elf.h"
-#include "exec/cpu-all.h"
-#include "sysemu/dump.h"
-#include "sysemu/kvm.h"
-
-struct PPC64UserRegStruct {
- uint64_t gpr[32];
- uint64_t nip;
- uint64_t msr;
- uint64_t orig_gpr3;
- uint64_t ctr;
- uint64_t link;
- uint64_t xer;
- uint64_t ccr;
- uint64_t softe;
- uint64_t trap;
- uint64_t dar;
- uint64_t dsisr;
- uint64_t result;
-} QEMU_PACKED;
-
-struct PPC64ElfPrstatus {
- char pad1[112];
- struct PPC64UserRegStruct pr_reg;
- uint64_t pad2[4];
-} QEMU_PACKED;
-
-
-struct PPC64ElfFpregset {
- uint64_t fpr[32];
- uint64_t fpscr;
-} QEMU_PACKED;
-
-
-struct PPC64ElfVmxregset {
- ppc_avr_t avr[32];
- ppc_avr_t vscr;
- union {
- ppc_avr_t unused;
- uint32_t value;
- } vrsave;
-} QEMU_PACKED;
-
-struct PPC64ElfVsxregset {
- uint64_t vsr[32];
-} QEMU_PACKED;
-
-struct PPC64ElfSperegset {
- uint32_t evr[32];
- uint64_t spe_acc;
- uint32_t spe_fscr;
-} QEMU_PACKED;
-
-typedef struct noteStruct {
- Elf64_Nhdr hdr;
- char name[5];
- char pad3[3];
- union {
- struct PPC64ElfPrstatus prstatus;
- struct PPC64ElfFpregset fpregset;
- struct PPC64ElfVmxregset vmxregset;
- struct PPC64ElfVsxregset vsxregset;
- struct PPC64ElfSperegset speregset;
- } contents;
-} QEMU_PACKED Note;
-
-typedef struct NoteFuncArg {
- Note note;
- DumpState *state;
-} NoteFuncArg;
-
-static void ppc64_write_elf64_prstatus(NoteFuncArg *arg, PowerPCCPU *cpu)
-{
- int i;
- uint64_t cr;
- struct PPC64ElfPrstatus *prstatus;
- struct PPC64UserRegStruct *reg;
- Note *note = &arg->note;
- DumpState *s = arg->state;
-
- note->hdr.n_type = cpu_to_dump32(s, NT_PRSTATUS);
-
- prstatus = &note->contents.prstatus;
- memset(prstatus, 0, sizeof(*prstatus));
- reg = &prstatus->pr_reg;
-
- for (i = 0; i < 32; i++) {
- reg->gpr[i] = cpu_to_dump64(s, cpu->env.gpr[i]);
- }
- reg->nip = cpu_to_dump64(s, cpu->env.nip);
- reg->msr = cpu_to_dump64(s, cpu->env.msr);
- reg->ctr = cpu_to_dump64(s, cpu->env.ctr);
- reg->link = cpu_to_dump64(s, cpu->env.lr);
- reg->xer = cpu_to_dump64(s, cpu_read_xer(&cpu->env));
-
- cr = 0;
- for (i = 0; i < 8; i++) {
- cr |= (cpu->env.crf[i] & 15) << (4 * (7 - i));
- }
- reg->ccr = cpu_to_dump64(s, cr);
-}
-
-static void ppc64_write_elf64_fpregset(NoteFuncArg *arg, PowerPCCPU *cpu)
-{
- int i;
- struct PPC64ElfFpregset *fpregset;
- Note *note = &arg->note;
- DumpState *s = arg->state;
-
- note->hdr.n_type = cpu_to_dump32(s, NT_PRFPREG);
-
- fpregset = &note->contents.fpregset;
- memset(fpregset, 0, sizeof(*fpregset));
-
- for (i = 0; i < 32; i++) {
- fpregset->fpr[i] = cpu_to_dump64(s, cpu->env.fpr[i]);
- }
- fpregset->fpscr = cpu_to_dump64(s, cpu->env.fpscr);
-}
-
-static void ppc64_write_elf64_vmxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
-{
- int i;
- struct PPC64ElfVmxregset *vmxregset;
- Note *note = &arg->note;
- DumpState *s = arg->state;
-
- note->hdr.n_type = cpu_to_dump32(s, NT_PPC_VMX);
- vmxregset = &note->contents.vmxregset;
- memset(vmxregset, 0, sizeof(*vmxregset));
-
- for (i = 0; i < 32; i++) {
- bool needs_byteswap;
-
-#ifdef HOST_WORDS_BIGENDIAN
- needs_byteswap = s->dump_info.d_endian == ELFDATA2LSB;
-#else
- needs_byteswap = s->dump_info.d_endian == ELFDATA2MSB;
-#endif
-
- if (needs_byteswap) {
- vmxregset->avr[i].u64[0] = bswap64(cpu->env.avr[i].u64[1]);
- vmxregset->avr[i].u64[1] = bswap64(cpu->env.avr[i].u64[0]);
- } else {
- vmxregset->avr[i].u64[0] = cpu->env.avr[i].u64[0];
- vmxregset->avr[i].u64[1] = cpu->env.avr[i].u64[1];
- }
- }
- vmxregset->vscr.u32[3] = cpu_to_dump32(s, cpu->env.vscr);
-}
-static void ppc64_write_elf64_vsxregset(NoteFuncArg *arg, PowerPCCPU *cpu)
-{
- int i;
- struct PPC64ElfVsxregset *vsxregset;
- Note *note = &arg->note;
- DumpState *s = arg->state;
-
- note->hdr.n_type = cpu_to_dump32(s, NT_PPC_VSX);
- vsxregset = &note->contents.vsxregset;
- memset(vsxregset, 0, sizeof(*vsxregset));
-
- for (i = 0; i < 32; i++) {
- vsxregset->vsr[i] = cpu_to_dump64(s, cpu->env.vsr[i]);
- }
-}
-static void ppc64_write_elf64_speregset(NoteFuncArg *arg, PowerPCCPU *cpu)
-{
- struct PPC64ElfSperegset *speregset;
- Note *note = &arg->note;
- DumpState *s = arg->state;
-
- note->hdr.n_type = cpu_to_dump32(s, NT_PPC_SPE);
- speregset = &note->contents.speregset;
- memset(speregset, 0, sizeof(*speregset));
-
- speregset->spe_acc = cpu_to_dump64(s, cpu->env.spe_acc);
- speregset->spe_fscr = cpu_to_dump32(s, cpu->env.spe_fscr);
-}
-
-static const struct NoteFuncDescStruct {
- int contents_size;
- void (*note_contents_func)(NoteFuncArg *arg, PowerPCCPU *cpu);
-} note_func[] = {
- {sizeof(((Note *)0)->contents.prstatus), ppc64_write_elf64_prstatus},
- {sizeof(((Note *)0)->contents.fpregset), ppc64_write_elf64_fpregset},
- {sizeof(((Note *)0)->contents.vmxregset), ppc64_write_elf64_vmxregset},
- {sizeof(((Note *)0)->contents.vsxregset), ppc64_write_elf64_vsxregset},
- {sizeof(((Note *)0)->contents.speregset), ppc64_write_elf64_speregset},
- { 0, NULL}
-};
-
-typedef struct NoteFuncDescStruct NoteFuncDesc;
-
-int cpu_get_dump_info(ArchDumpInfo *info,
- const struct GuestPhysBlockList *guest_phys_blocks)
-{
- PowerPCCPU *cpu = POWERPC_CPU(first_cpu);
- PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
-
- info->d_machine = EM_PPC64;
- info->d_class = ELFCLASS64;
- if ((*pcc->interrupts_big_endian)(cpu)) {
- info->d_endian = ELFDATA2MSB;
- } else {
- info->d_endian = ELFDATA2LSB;
- }
- /* 64KB is the max page size for pseries kernel */
- if (strncmp(object_get_typename(qdev_get_machine()),
- "pseries-", 8) == 0) {
- info->page_size = (1U << 16);
- }
-
- return 0;
-}
-
-ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
-{
- int name_size = 8; /* "CORE" or "QEMU" rounded */
- size_t elf_note_size = 0;
- int note_head_size;
- const NoteFuncDesc *nf;
-
- if (class != ELFCLASS64) {
- return -1;
- }
- assert(machine == EM_PPC64);
-
- note_head_size = sizeof(Elf64_Nhdr);
-
- for (nf = note_func; nf->note_contents_func; nf++) {
- elf_note_size = elf_note_size + note_head_size + name_size +
- nf->contents_size;
- }
-
- return (elf_note_size) * nr_cpus;
-}
-
-static int ppc64_write_all_elf64_notes(const char *note_name,
- WriteCoreDumpFunction f,
- PowerPCCPU *cpu, int id,
- void *opaque)
-{
- NoteFuncArg arg = { .state = opaque };
- int ret = -1;
- int note_size;
- const NoteFuncDesc *nf;
-
- for (nf = note_func; nf->note_contents_func; nf++) {
- arg.note.hdr.n_namesz = cpu_to_dump32(opaque, sizeof(arg.note.name));
- arg.note.hdr.n_descsz = cpu_to_dump32(opaque, nf->contents_size);
- strncpy(arg.note.name, note_name, sizeof(arg.note.name));
-
- (*nf->note_contents_func)(&arg, cpu);
-
- note_size =
- sizeof(arg.note) - sizeof(arg.note.contents) + nf->contents_size;
- ret = f(&arg.note, note_size, opaque);
- if (ret < 0) {
- return -1;
- }
- }
- return 0;
-}
-
-int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
- int cpuid, void *opaque)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- return ppc64_write_all_elf64_notes("CORE", f, cpu, cpuid, opaque);
-}
diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c
deleted file mode 100644
index 506dee1ee8..0000000000
--- a/target-ppc/cpu-models.c
+++ /dev/null
@@ -1,1426 +0,0 @@
-/*
- * PowerPC CPU initialization for qemu.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- * Copyright 2011 Freescale Semiconductor, Inc.
- * Copyright 2013 SUSE LINUX Products GmbH
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-
-/* A lot of PowerPC definition have been included here.
- * Most of them are not usable for now but have been kept
- * inside "#if defined(TODO) ... #endif" statements to make tests easier.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "cpu-models.h"
-
-#if defined(CONFIG_USER_ONLY)
-#define TODO_USER_ONLY 1
-#endif
-
-/***************************************************************************/
-/* PowerPC CPU definitions */
-#define POWERPC_DEF_PREFIX(pvr, svr, type) \
- glue(glue(glue(glue(pvr, _), svr), _), type)
-#define POWERPC_DEF_SVR(_name, _desc, _pvr, _svr, _type) \
- static void \
- glue(POWERPC_DEF_PREFIX(_pvr, _svr, _type), _cpu_class_init) \
- (ObjectClass *oc, void *data) \
- { \
- DeviceClass *dc = DEVICE_CLASS(oc); \
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); \
- \
- pcc->pvr = _pvr; \
- pcc->svr = _svr; \
- dc->desc = _desc; \
- } \
- \
- static const TypeInfo \
- glue(POWERPC_DEF_PREFIX(_pvr, _svr, _type), _cpu_type_info) = { \
- .name = _name "-" TYPE_POWERPC_CPU, \
- .parent = stringify(_type) "-family-" TYPE_POWERPC_CPU, \
- .class_init = \
- glue(POWERPC_DEF_PREFIX(_pvr, _svr, _type), _cpu_class_init), \
- }; \
- \
- static void \
- glue(POWERPC_DEF_PREFIX(_pvr, _svr, _type), _cpu_register_types)(void) \
- { \
- type_register_static( \
- &glue(POWERPC_DEF_PREFIX(_pvr, _svr, _type), _cpu_type_info)); \
- } \
- \
- type_init( \
- glue(POWERPC_DEF_PREFIX(_pvr, _svr, _type), _cpu_register_types))
-
-#define POWERPC_DEF(_name, _pvr, _type, _desc) \
- POWERPC_DEF_SVR(_name, _desc, _pvr, POWERPC_SVR_NONE, _type)
-
- /* Embedded PowerPC */
- /* PowerPC 401 family */
- POWERPC_DEF("401", CPU_POWERPC_401, 401,
- "Generic PowerPC 401")
- /* PowerPC 401 cores */
- POWERPC_DEF("401A1", CPU_POWERPC_401A1, 401,
- "PowerPC 401A1")
- POWERPC_DEF("401B2", CPU_POWERPC_401B2, 401x2,
- "PowerPC 401B2")
-#if defined(TODO)
- POWERPC_DEF("401B3", CPU_POWERPC_401B3, 401x3,
- "PowerPC 401B3")
-#endif
- POWERPC_DEF("401C2", CPU_POWERPC_401C2, 401x2,
- "PowerPC 401C2")
- POWERPC_DEF("401D2", CPU_POWERPC_401D2, 401x2,
- "PowerPC 401D2")
- POWERPC_DEF("401E2", CPU_POWERPC_401E2, 401x2,
- "PowerPC 401E2")
- POWERPC_DEF("401F2", CPU_POWERPC_401F2, 401x2,
- "PowerPC 401F2")
- /* XXX: to be checked */
- POWERPC_DEF("401G2", CPU_POWERPC_401G2, 401x2,
- "PowerPC 401G2")
- /* PowerPC 401 microcontrollers */
-#if defined(TODO)
- POWERPC_DEF("401GF", CPU_POWERPC_401GF, 401,
- "PowerPC 401GF")
-#endif
- POWERPC_DEF("IOP480", CPU_POWERPC_IOP480, IOP480,
- "IOP480 (401 microcontroller)")
- POWERPC_DEF("Cobra", CPU_POWERPC_COBRA, 401,
- "IBM Processor for Network Resources")
-#if defined(TODO)
- POWERPC_DEF("Xipchip", CPU_POWERPC_XIPCHIP, 401,
- NULL)
-#endif
- /* PowerPC 403 family */
- /* PowerPC 403 microcontrollers */
- POWERPC_DEF("403GA", CPU_POWERPC_403GA, 403,
- "PowerPC 403 GA")
- POWERPC_DEF("403GB", CPU_POWERPC_403GB, 403,
- "PowerPC 403 GB")
- POWERPC_DEF("403GC", CPU_POWERPC_403GC, 403,
- "PowerPC 403 GC")
- POWERPC_DEF("403GCX", CPU_POWERPC_403GCX, 403GCX,
- "PowerPC 403 GCX")
-#if defined(TODO)
- POWERPC_DEF("403GP", CPU_POWERPC_403GP, 403,
- "PowerPC 403 GP")
-#endif
- /* PowerPC 405 family */
- /* PowerPC 405 cores */
-#if defined(TODO)
- POWERPC_DEF("405A3", CPU_POWERPC_405A3, 405,
- "PowerPC 405 A3")
-#endif
-#if defined(TODO)
- POWERPC_DEF("405A4", CPU_POWERPC_405A4, 405,
- "PowerPC 405 A4")
-#endif
-#if defined(TODO)
- POWERPC_DEF("405B3", CPU_POWERPC_405B3, 405,
- "PowerPC 405 B3")
-#endif
-#if defined(TODO)
- POWERPC_DEF("405B4", CPU_POWERPC_405B4, 405,
- "PowerPC 405 B4")
-#endif
-#if defined(TODO)
- POWERPC_DEF("405C3", CPU_POWERPC_405C3, 405,
- "PowerPC 405 C3")
-#endif
-#if defined(TODO)
- POWERPC_DEF("405C4", CPU_POWERPC_405C4, 405,
- "PowerPC 405 C4")
-#endif
- POWERPC_DEF("405D2", CPU_POWERPC_405D2, 405,
- "PowerPC 405 D2")
-#if defined(TODO)
- POWERPC_DEF("405D3", CPU_POWERPC_405D3, 405,
- "PowerPC 405 D3")
-#endif
- POWERPC_DEF("405D4", CPU_POWERPC_405D4, 405,
- "PowerPC 405 D4")
-#if defined(TODO)
- POWERPC_DEF("405D5", CPU_POWERPC_405D5, 405,
- "PowerPC 405 D5")
-#endif
-#if defined(TODO)
- POWERPC_DEF("405E4", CPU_POWERPC_405E4, 405,
- "PowerPC 405 E4")
-#endif
-#if defined(TODO)
- POWERPC_DEF("405F4", CPU_POWERPC_405F4, 405,
- "PowerPC 405 F4")
-#endif
-#if defined(TODO)
- POWERPC_DEF("405F5", CPU_POWERPC_405F5, 405,
- "PowerPC 405 F5")
-#endif
-#if defined(TODO)
- POWERPC_DEF("405F6", CPU_POWERPC_405F6, 405,
- "PowerPC 405 F6")
-#endif
- /* PowerPC 405 microcontrollers */
- POWERPC_DEF("405CRa", CPU_POWERPC_405CRa, 405,
- "PowerPC 405 CRa")
- POWERPC_DEF("405CRb", CPU_POWERPC_405CRb, 405,
- "PowerPC 405 CRb")
- POWERPC_DEF("405CRc", CPU_POWERPC_405CRc, 405,
- "PowerPC 405 CRc")
- POWERPC_DEF("405EP", CPU_POWERPC_405EP, 405,
- "PowerPC 405 EP")
-#if defined(TODO)
- POWERPC_DEF("405EXr", CPU_POWERPC_405EXr, 405,
- "PowerPC 405 EXr")
-#endif
- POWERPC_DEF("405EZ", CPU_POWERPC_405EZ, 405,
- "PowerPC 405 EZ")
-#if defined(TODO)
- POWERPC_DEF("405FX", CPU_POWERPC_405FX, 405,
- "PowerPC 405 FX")
-#endif
- POWERPC_DEF("405GPa", CPU_POWERPC_405GPa, 405,
- "PowerPC 405 GPa")
- POWERPC_DEF("405GPb", CPU_POWERPC_405GPb, 405,
- "PowerPC 405 GPb")
- POWERPC_DEF("405GPc", CPU_POWERPC_405GPc, 405,
- "PowerPC 405 GPc")
- POWERPC_DEF("405GPd", CPU_POWERPC_405GPd, 405,
- "PowerPC 405 GPd")
- POWERPC_DEF("405GPR", CPU_POWERPC_405GPR, 405,
- "PowerPC 405 GPR")
-#if defined(TODO)
- POWERPC_DEF("405H", CPU_POWERPC_405H, 405,
- "PowerPC 405 H")
-#endif
-#if defined(TODO)
- POWERPC_DEF("405L", CPU_POWERPC_405L, 405,
- "PowerPC 405 L")
-#endif
- POWERPC_DEF("405LP", CPU_POWERPC_405LP, 405,
- "PowerPC 405 LP")
-#if defined(TODO)
- POWERPC_DEF("405PM", CPU_POWERPC_405PM, 405,
- "PowerPC 405 PM")
-#endif
-#if defined(TODO)
- POWERPC_DEF("405PS", CPU_POWERPC_405PS, 405,
- "PowerPC 405 PS")
-#endif
-#if defined(TODO)
- POWERPC_DEF("405S", CPU_POWERPC_405S, 405,
- "PowerPC 405 S")
-#endif
- POWERPC_DEF("Npe405H", CPU_POWERPC_NPE405H, 405,
- "Npe405 H")
- POWERPC_DEF("Npe405H2", CPU_POWERPC_NPE405H2, 405,
- "Npe405 H2")
- POWERPC_DEF("Npe405L", CPU_POWERPC_NPE405L, 405,
- "Npe405 L")
- POWERPC_DEF("Npe4GS3", CPU_POWERPC_NPE4GS3, 405,
- "Npe4GS3")
-#if defined(TODO)
- POWERPC_DEF("Npcxx1", CPU_POWERPC_NPCxx1, 405,
- NULL)
-#endif
-#if defined(TODO)
- POWERPC_DEF("Npr161", CPU_POWERPC_NPR161, 405,
- NULL)
-#endif
-#if defined(TODO)
- POWERPC_DEF("LC77700", CPU_POWERPC_LC77700, 405,
- "PowerPC LC77700 (Sanyo)")
-#endif
- /* PowerPC 401/403/405 based set-top-box microcontrollers */
-#if defined(TODO)
- POWERPC_DEF("STB01000", CPU_POWERPC_STB01000, 401x2,
- "STB010000")
-#endif
-#if defined(TODO)
- POWERPC_DEF("STB01010", CPU_POWERPC_STB01010, 401x2,
- "STB01010")
-#endif
-#if defined(TODO)
- POWERPC_DEF("STB0210", CPU_POWERPC_STB0210, 401x3,
- "STB0210")
-#endif
- POWERPC_DEF("STB03", CPU_POWERPC_STB03, 405,
- "STB03xx")
-#if defined(TODO)
- POWERPC_DEF("STB043", CPU_POWERPC_STB043, 405,
- "STB043x")
-#endif
-#if defined(TODO)
- POWERPC_DEF("STB045", CPU_POWERPC_STB045, 405,
- "STB045x")
-#endif
- POWERPC_DEF("STB04", CPU_POWERPC_STB04, 405,
- "STB04xx")
- POWERPC_DEF("STB25", CPU_POWERPC_STB25, 405,
- "STB25xx")
-#if defined(TODO)
- POWERPC_DEF("STB130", CPU_POWERPC_STB130, 405,
- "STB130")
-#endif
- /* Xilinx PowerPC 405 cores */
- POWERPC_DEF("x2vp4", CPU_POWERPC_X2VP4, 405,
- NULL)
- POWERPC_DEF("x2vp20", CPU_POWERPC_X2VP20, 405,
- NULL)
-#if defined(TODO)
- POWERPC_DEF("zl10310", CPU_POWERPC_ZL10310, 405,
- "Zarlink ZL10310")
-#endif
-#if defined(TODO)
- POWERPC_DEF("zl10311", CPU_POWERPC_ZL10311, 405,
- "Zarlink ZL10311")
-#endif
-#if defined(TODO)
- POWERPC_DEF("zl10320", CPU_POWERPC_ZL10320, 405,
- "Zarlink ZL10320")
-#endif
-#if defined(TODO)
- POWERPC_DEF("zl10321", CPU_POWERPC_ZL10321, 405,
- "Zarlink ZL10321")
-#endif
- /* PowerPC 440 family */
-#if defined(TODO_USER_ONLY)
- POWERPC_DEF("440", CPU_POWERPC_440, 440GP,
- "Generic PowerPC 440")
-#endif
- /* PowerPC 440 cores */
-#if defined(TODO)
- POWERPC_DEF("440A4", CPU_POWERPC_440A4, 440x4,
- "PowerPC 440 A4")
-#endif
- POWERPC_DEF("440-Xilinx", CPU_POWERPC_440_XILINX, 440x5,
- "PowerPC 440 Xilinx 5")
-
- POWERPC_DEF("440-Xilinx-w-dfpu", CPU_POWERPC_440_XILINX, 440x5wDFPU,
- "PowerPC 440 Xilinx 5 With a Double Prec. FPU")
-#if defined(TODO)
- POWERPC_DEF("440A5", CPU_POWERPC_440A5, 440x5,
- "PowerPC 440 A5")
-#endif
-#if defined(TODO)
- POWERPC_DEF("440B4", CPU_POWERPC_440B4, 440x4,
- "PowerPC 440 B4")
-#endif
-#if defined(TODO)
- POWERPC_DEF("440G4", CPU_POWERPC_440G4, 440x4,
- "PowerPC 440 G4")
-#endif
-#if defined(TODO)
- POWERPC_DEF("440F5", CPU_POWERPC_440F5, 440x5,
- "PowerPC 440 F5")
-#endif
-#if defined(TODO)
- POWERPC_DEF("440G5", CPU_POWERPC_440G5, 440x5,
- "PowerPC 440 G5")
-#endif
-#if defined(TODO)
- POWERPC_DEF("440H4", CPU_POWERPC_440H4, 440x4,
- "PowerPC 440H4")
-#endif
-#if defined(TODO)
- POWERPC_DEF("440H6", CPU_POWERPC_440H6, 440Gx5,
- "PowerPC 440H6")
-#endif
- /* PowerPC 440 microcontrollers */
- POWERPC_DEF("440EPa", CPU_POWERPC_440EPa, 440EP,
- "PowerPC 440 EPa")
- POWERPC_DEF("440EPb", CPU_POWERPC_440EPb, 440EP,
- "PowerPC 440 EPb")
- POWERPC_DEF("440EPX", CPU_POWERPC_440EPX, 440EP,
- "PowerPC 440 EPX")
-#if defined(TODO_USER_ONLY)
- POWERPC_DEF("440GPb", CPU_POWERPC_440GPb, 440GP,
- "PowerPC 440 GPb")
-#endif
-#if defined(TODO_USER_ONLY)
- POWERPC_DEF("440GPc", CPU_POWERPC_440GPc, 440GP,
- "PowerPC 440 GPc")
-#endif
-#if defined(TODO_USER_ONLY)
- POWERPC_DEF("440GRa", CPU_POWERPC_440GRa, 440x5,
- "PowerPC 440 GRa")
-#endif
-#if defined(TODO_USER_ONLY)
- POWERPC_DEF("440GRX", CPU_POWERPC_440GRX, 440x5,
- "PowerPC 440 GRX")
-#endif
-#if defined(TODO_USER_ONLY)
- POWERPC_DEF("440GXa", CPU_POWERPC_440GXa, 440EP,
- "PowerPC 440 GXa")
-#endif
-#if defined(TODO_USER_ONLY)
- POWERPC_DEF("440GXb", CPU_POWERPC_440GXb, 440EP,
- "PowerPC 440 GXb")
-#endif
-#if defined(TODO_USER_ONLY)
- POWERPC_DEF("440GXc", CPU_POWERPC_440GXc, 440EP,
- "PowerPC 440 GXc")
-#endif
-#if defined(TODO_USER_ONLY)
- POWERPC_DEF("440GXf", CPU_POWERPC_440GXf, 440EP,
- "PowerPC 440 GXf")
-#endif
-#if defined(TODO)
- POWERPC_DEF("440S", CPU_POWERPC_440S, 440,
- "PowerPC 440 S")
-#endif
-#if defined(TODO_USER_ONLY)
- POWERPC_DEF("440SP", CPU_POWERPC_440SP, 440EP,
- "PowerPC 440 SP")
-#endif
-#if defined(TODO_USER_ONLY)
- POWERPC_DEF("440SP2", CPU_POWERPC_440SP2, 440EP,
- "PowerPC 440 SP2")
-#endif
-#if defined(TODO_USER_ONLY)
- POWERPC_DEF("440SPE", CPU_POWERPC_440SPE, 440EP,
- "PowerPC 440 SPE")
-#endif
- /* PowerPC 460 family */
-#if defined(TODO)
- POWERPC_DEF("464", CPU_POWERPC_464, 460,
- "Generic PowerPC 464")
-#endif
- /* PowerPC 464 microcontrollers */
-#if defined(TODO)
- POWERPC_DEF("464H90", CPU_POWERPC_464H90, 460,
- "PowerPC 464H90")
-#endif
-#if defined(TODO)
- POWERPC_DEF("464H90F", CPU_POWERPC_464H90F, 460F,
- "PowerPC 464H90F")
-#endif
- /* Freescale embedded PowerPC cores */
- /* MPC5xx family (aka RCPU) */
-#if defined(TODO_USER_ONLY)
- POWERPC_DEF("MPC5xx", CPU_POWERPC_MPC5xx, MPC5xx,
- "Generic MPC5xx core")
-#endif
- /* MPC8xx family (aka PowerQUICC) */
-#if defined(TODO_USER_ONLY)
- POWERPC_DEF("MPC8xx", CPU_POWERPC_MPC8xx, MPC8xx,
- "Generic MPC8xx core")
-#endif
- /* MPC82xx family (aka PowerQUICC-II) */
- POWERPC_DEF("G2", CPU_POWERPC_G2, G2,
- "PowerPC G2 core")
- POWERPC_DEF("G2H4", CPU_POWERPC_G2H4, G2,
- "PowerPC G2 H4 core")
- POWERPC_DEF("G2GP", CPU_POWERPC_G2gp, G2,
- "PowerPC G2 GP core")
- POWERPC_DEF("G2LS", CPU_POWERPC_G2ls, G2,
- "PowerPC G2 LS core")
- POWERPC_DEF("G2HiP3", CPU_POWERPC_G2_HIP3, G2,
- "PowerPC G2 HiP3 core")
- POWERPC_DEF("G2HiP4", CPU_POWERPC_G2_HIP4, G2,
- "PowerPC G2 HiP4 core")
- POWERPC_DEF("MPC603", CPU_POWERPC_MPC603, 603E,
- "PowerPC MPC603 core")
- POWERPC_DEF("G2le", CPU_POWERPC_G2LE, G2LE,
- "PowerPC G2le core (same as G2 plus little-endian mode support)")
- POWERPC_DEF("G2leGP", CPU_POWERPC_G2LEgp, G2LE,
- "PowerPC G2LE GP core")
- POWERPC_DEF("G2leLS", CPU_POWERPC_G2LEls, G2LE,
- "PowerPC G2LE LS core")
- POWERPC_DEF("G2leGP1", CPU_POWERPC_G2LEgp1, G2LE,
- "PowerPC G2LE GP1 core")
- POWERPC_DEF("G2leGP3", CPU_POWERPC_G2LEgp3, G2LE,
- "PowerPC G2LE GP3 core")
- /* PowerPC G2 microcontrollers */
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5121", "MPC5121",
- CPU_POWERPC_MPC5121, POWERPC_SVR_5121, G2LE)
-#endif
- POWERPC_DEF_SVR("MPC5200_v10", "MPC5200 v1.0",
- CPU_POWERPC_MPC5200_v10, POWERPC_SVR_5200_v10, G2LE)
- POWERPC_DEF_SVR("MPC5200_v11", "MPC5200 v1.1",
- CPU_POWERPC_MPC5200_v11, POWERPC_SVR_5200_v11, G2LE)
- POWERPC_DEF_SVR("MPC5200_v12", "MPC5200 v1.2",
- CPU_POWERPC_MPC5200_v12, POWERPC_SVR_5200_v12, G2LE)
- POWERPC_DEF_SVR("MPC5200B_v20", "MPC5200B v2.0",
- CPU_POWERPC_MPC5200B_v20, POWERPC_SVR_5200B_v20, G2LE)
- POWERPC_DEF_SVR("MPC5200B_v21", "MPC5200B v2.1",
- CPU_POWERPC_MPC5200B_v21, POWERPC_SVR_5200B_v21, G2LE)
- /* e200 family */
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC55xx", "Generic MPC55xx core",
- CPU_POWERPC_MPC55xx, POWERPC_SVR_55xx, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF("e200z0", CPU_POWERPC_e200z0, e200,
- "PowerPC e200z0 core")
-#endif
-#if defined(TODO)
- POWERPC_DEF("e200z1", CPU_POWERPC_e200z1, e200,
- "PowerPC e200z1 core")
-#endif
-#if defined(TODO)
- POWERPC_DEF("e200z3", CPU_POWERPC_e200z3, e200,
- "PowerPC e200z3 core")
-#endif
- POWERPC_DEF("e200z5", CPU_POWERPC_e200z5, e200,
- "PowerPC e200z5 core")
- POWERPC_DEF("e200z6", CPU_POWERPC_e200z6, e200,
- "PowerPC e200z6 core")
- /* PowerPC e200 microcontrollers */
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5514E", "MPC5514E",
- CPU_POWERPC_MPC5514E, POWERPC_SVR_5514E, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5514E_v0", "MPC5514E v0",
- CPU_POWERPC_MPC5514E_v0, POWERPC_SVR_5514E_v0, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5514E_v1", "MPC5514E v1",
- CPU_POWERPC_MPC5514E_v1, POWERPC_SVR_5514E_v1, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5514G", "MPC5514G",
- CPU_POWERPC_MPC5514G, POWERPC_SVR_5514G, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5514G_v0", "MPC5514G v0",
- CPU_POWERPC_MPC5514G_v0, POWERPC_SVR_5514G_v0, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5514G_v1", "MPC5514G v1",
- CPU_POWERPC_MPC5514G_v1, POWERPC_SVR_5514G_v1, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5515S", "MPC5515S",
- CPU_POWERPC_MPC5515S, POWERPC_SVR_5515S, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5516E", "MPC5516E",
- CPU_POWERPC_MPC5516E, POWERPC_SVR_5516E, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5516E_v0", "MPC5516E v0",
- CPU_POWERPC_MPC5516E_v0, POWERPC_SVR_5516E_v0, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5516E_v1", "MPC5516E v1",
- CPU_POWERPC_MPC5516E_v1, POWERPC_SVR_5516E_v1, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5516G", "MPC5516G",
- CPU_POWERPC_MPC5516G, POWERPC_SVR_5516G, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5516G_v0", "MPC5516G v0",
- CPU_POWERPC_MPC5516G_v0, POWERPC_SVR_5516G_v0, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5516G_v1", "MPC5516G v1",
- CPU_POWERPC_MPC5516G_v1, POWERPC_SVR_5516G_v1, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5516S", "MPC5516S",
- CPU_POWERPC_MPC5516S, POWERPC_SVR_5516S, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5533", "MPC5533",
- CPU_POWERPC_MPC5533, POWERPC_SVR_5533, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5534", "MPC5534",
- CPU_POWERPC_MPC5534, POWERPC_SVR_5534, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5553", "MPC5553",
- CPU_POWERPC_MPC5553, POWERPC_SVR_5553, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5554", "MPC5554",
- CPU_POWERPC_MPC5554, POWERPC_SVR_5554, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5561", "MPC5561",
- CPU_POWERPC_MPC5561, POWERPC_SVR_5561, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5565", "MPC5565",
- CPU_POWERPC_MPC5565, POWERPC_SVR_5565, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5566", "MPC5566",
- CPU_POWERPC_MPC5566, POWERPC_SVR_5566, e200)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC5567", "MPC5567",
- CPU_POWERPC_MPC5567, POWERPC_SVR_5567, e200)
-#endif
- /* e300 family */
- POWERPC_DEF("e300c1", CPU_POWERPC_e300c1, e300,
- "PowerPC e300c1 core")
- POWERPC_DEF("e300c2", CPU_POWERPC_e300c2, e300,
- "PowerPC e300c2 core")
- POWERPC_DEF("e300c3", CPU_POWERPC_e300c3, e300,
- "PowerPC e300c3 core")
- POWERPC_DEF("e300c4", CPU_POWERPC_e300c4, e300,
- "PowerPC e300c4 core")
- /* PowerPC e300 microcontrollers */
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC8313", "MPC8313",
- CPU_POWERPC_MPC831x, POWERPC_SVR_8313, e300)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC8313E", "MPC8313E",
- CPU_POWERPC_MPC831x, POWERPC_SVR_8313E, e300)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC8314", "MPC8314",
- CPU_POWERPC_MPC831x, POWERPC_SVR_8314, e300)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC8314E", "MPC8314E",
- CPU_POWERPC_MPC831x, POWERPC_SVR_8314E, e300)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC8315", "MPC8315",
- CPU_POWERPC_MPC831x, POWERPC_SVR_8315, e300)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC8315E", "MPC8315E",
- CPU_POWERPC_MPC831x, POWERPC_SVR_8315E, e300)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC8321", "MPC8321",
- CPU_POWERPC_MPC832x, POWERPC_SVR_8321, e300)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC8321E", "MPC8321E",
- CPU_POWERPC_MPC832x, POWERPC_SVR_8321E, e300)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC8323", "MPC8323",
- CPU_POWERPC_MPC832x, POWERPC_SVR_8323, e300)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC8323E", "MPC8323E",
- CPU_POWERPC_MPC832x, POWERPC_SVR_8323E, e300)
-#endif
- POWERPC_DEF_SVR("MPC8343", "MPC8343",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8343, e300)
- POWERPC_DEF_SVR("MPC8343A", "MPC8343A",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8343A, e300)
- POWERPC_DEF_SVR("MPC8343E", "MPC8343E",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8343E, e300)
- POWERPC_DEF_SVR("MPC8343EA", "MPC8343EA",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8343EA, e300)
- POWERPC_DEF_SVR("MPC8347T", "MPC8347T",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347T, e300)
- POWERPC_DEF_SVR("MPC8347P", "MPC8347P",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347P, e300)
- POWERPC_DEF_SVR("MPC8347AT", "MPC8347AT",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347AT, e300)
- POWERPC_DEF_SVR("MPC8347AP", "MPC8347AP",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347AP, e300)
- POWERPC_DEF_SVR("MPC8347ET", "MPC8347ET",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347ET, e300)
- POWERPC_DEF_SVR("MPC8347EP", "MPC8343EP",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347EP, e300)
- POWERPC_DEF_SVR("MPC8347EAT", "MPC8347EAT",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347EAT, e300)
- POWERPC_DEF_SVR("MPC8347EAP", "MPC8343EAP",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8347EAP, e300)
- POWERPC_DEF_SVR("MPC8349", "MPC8349",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8349, e300)
- POWERPC_DEF_SVR("MPC8349A", "MPC8349A",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8349A, e300)
- POWERPC_DEF_SVR("MPC8349E", "MPC8349E",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8349E, e300)
- POWERPC_DEF_SVR("MPC8349EA", "MPC8349EA",
- CPU_POWERPC_MPC834x, POWERPC_SVR_8349EA, e300)
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC8358E", "MPC8358E",
- CPU_POWERPC_MPC835x, POWERPC_SVR_8358E, e300)
-#endif
-#if defined(TODO)
- POWERPC_DEF_SVR("MPC8360E", "MPC8360E",
- CPU_POWERPC_MPC836x, POWERPC_SVR_8360E, e300)
-#endif
- POWERPC_DEF_SVR("MPC8377", "MPC8377",
- CPU_POWERPC_MPC837x, POWERPC_SVR_8377, e300)
- POWERPC_DEF_SVR("MPC8377E", "MPC8377E",
- CPU_POWERPC_MPC837x, POWERPC_SVR_8377E, e300)
- POWERPC_DEF_SVR("MPC8378", "MPC8378",
- CPU_POWERPC_MPC837x, POWERPC_SVR_8378, e300)
- POWERPC_DEF_SVR("MPC8378E", "MPC8378E",
- CPU_POWERPC_MPC837x, POWERPC_SVR_8378E, e300)
- POWERPC_DEF_SVR("MPC8379", "MPC8379",
- CPU_POWERPC_MPC837x, POWERPC_SVR_8379, e300)
- POWERPC_DEF_SVR("MPC8379E", "MPC8379E",
- CPU_POWERPC_MPC837x, POWERPC_SVR_8379E, e300)
- /* e500 family */
- POWERPC_DEF_SVR("e500_v10", "PowerPC e500 v1.0 core",
- CPU_POWERPC_e500v1_v10, POWERPC_SVR_E500, e500v1);
- POWERPC_DEF_SVR("e500_v20", "PowerPC e500 v2.0 core",
- CPU_POWERPC_e500v1_v20, POWERPC_SVR_E500, e500v1);
- POWERPC_DEF_SVR("e500v2_v10", "PowerPC e500v2 v1.0 core",
- CPU_POWERPC_e500v2_v10, POWERPC_SVR_E500, e500v2);
- POWERPC_DEF_SVR("e500v2_v20", "PowerPC e500v2 v2.0 core",
- CPU_POWERPC_e500v2_v20, POWERPC_SVR_E500, e500v2);
- POWERPC_DEF_SVR("e500v2_v21", "PowerPC e500v2 v2.1 core",
- CPU_POWERPC_e500v2_v21, POWERPC_SVR_E500, e500v2);
- POWERPC_DEF_SVR("e500v2_v22", "PowerPC e500v2 v2.2 core",
- CPU_POWERPC_e500v2_v22, POWERPC_SVR_E500, e500v2);
- POWERPC_DEF_SVR("e500v2_v30", "PowerPC e500v2 v3.0 core",
- CPU_POWERPC_e500v2_v30, POWERPC_SVR_E500, e500v2);
- POWERPC_DEF_SVR("e500mc", "e500mc",
- CPU_POWERPC_e500mc, POWERPC_SVR_E500, e500mc)
-#ifdef TARGET_PPC64
- POWERPC_DEF_SVR("e5500", "e5500",
- CPU_POWERPC_e5500, POWERPC_SVR_E500, e5500)
-#endif
- /* PowerPC e500 microcontrollers */
- POWERPC_DEF_SVR("MPC8533_v10", "MPC8533 v1.0",
- CPU_POWERPC_MPC8533_v10, POWERPC_SVR_8533_v10, e500v2)
- POWERPC_DEF_SVR("MPC8533_v11", "MPC8533 v1.1",
- CPU_POWERPC_MPC8533_v11, POWERPC_SVR_8533_v11, e500v2)
- POWERPC_DEF_SVR("MPC8533E_v10", "MPC8533E v1.0",
- CPU_POWERPC_MPC8533E_v10, POWERPC_SVR_8533E_v10, e500v2)
- POWERPC_DEF_SVR("MPC8533E_v11", "MPC8533E v1.1",
- CPU_POWERPC_MPC8533E_v11, POWERPC_SVR_8533E_v11, e500v2)
- POWERPC_DEF_SVR("MPC8540_v10", "MPC8540 v1.0",
- CPU_POWERPC_MPC8540_v10, POWERPC_SVR_8540_v10, e500v1)
- POWERPC_DEF_SVR("MPC8540_v20", "MPC8540 v2.0",
- CPU_POWERPC_MPC8540_v20, POWERPC_SVR_8540_v20, e500v1)
- POWERPC_DEF_SVR("MPC8540_v21", "MPC8540 v2.1",
- CPU_POWERPC_MPC8540_v21, POWERPC_SVR_8540_v21, e500v1)
- POWERPC_DEF_SVR("MPC8541_v10", "MPC8541 v1.0",
- CPU_POWERPC_MPC8541_v10, POWERPC_SVR_8541_v10, e500v1)
- POWERPC_DEF_SVR("MPC8541_v11", "MPC8541 v1.1",
- CPU_POWERPC_MPC8541_v11, POWERPC_SVR_8541_v11, e500v1)
- POWERPC_DEF_SVR("MPC8541E_v10", "MPC8541E v1.0",
- CPU_POWERPC_MPC8541E_v10, POWERPC_SVR_8541E_v10, e500v1)
- POWERPC_DEF_SVR("MPC8541E_v11", "MPC8541E v1.1",
- CPU_POWERPC_MPC8541E_v11, POWERPC_SVR_8541E_v11, e500v1)
- POWERPC_DEF_SVR("MPC8543_v10", "MPC8543 v1.0",
- CPU_POWERPC_MPC8543_v10, POWERPC_SVR_8543_v10, e500v2)
- POWERPC_DEF_SVR("MPC8543_v11", "MPC8543 v1.1",
- CPU_POWERPC_MPC8543_v11, POWERPC_SVR_8543_v11, e500v2)
- POWERPC_DEF_SVR("MPC8543_v20", "MPC8543 v2.0",
- CPU_POWERPC_MPC8543_v20, POWERPC_SVR_8543_v20, e500v2)
- POWERPC_DEF_SVR("MPC8543_v21", "MPC8543 v2.1",
- CPU_POWERPC_MPC8543_v21, POWERPC_SVR_8543_v21, e500v2)
- POWERPC_DEF_SVR("MPC8543E_v10", "MPC8543E v1.0",
- CPU_POWERPC_MPC8543E_v10, POWERPC_SVR_8543E_v10, e500v2)
- POWERPC_DEF_SVR("MPC8543E_v11", "MPC8543E v1.1",
- CPU_POWERPC_MPC8543E_v11, POWERPC_SVR_8543E_v11, e500v2)
- POWERPC_DEF_SVR("MPC8543E_v20", "MPC8543E v2.0",
- CPU_POWERPC_MPC8543E_v20, POWERPC_SVR_8543E_v20, e500v2)
- POWERPC_DEF_SVR("MPC8543E_v21", "MPC8543E v2.1",
- CPU_POWERPC_MPC8543E_v21, POWERPC_SVR_8543E_v21, e500v2)
- POWERPC_DEF_SVR("MPC8544_v10", "MPC8544 v1.0",
- CPU_POWERPC_MPC8544_v10, POWERPC_SVR_8544_v10, e500v2)
- POWERPC_DEF_SVR("MPC8544_v11", "MPC8544 v1.1",
- CPU_POWERPC_MPC8544_v11, POWERPC_SVR_8544_v11, e500v2)
- POWERPC_DEF_SVR("MPC8544E_v10", "MPC8544E v1.0",
- CPU_POWERPC_MPC8544E_v10, POWERPC_SVR_8544E_v10, e500v2)
- POWERPC_DEF_SVR("MPC8544E_v11", "MPC8544E v1.1",
- CPU_POWERPC_MPC8544E_v11, POWERPC_SVR_8544E_v11, e500v2)
- POWERPC_DEF_SVR("MPC8545_v20", "MPC8545 v2.0",
- CPU_POWERPC_MPC8545_v20, POWERPC_SVR_8545_v20, e500v2)
- POWERPC_DEF_SVR("MPC8545_v21", "MPC8545 v2.1",
- CPU_POWERPC_MPC8545_v21, POWERPC_SVR_8545_v21, e500v2)
- POWERPC_DEF_SVR("MPC8545E_v20", "MPC8545E v2.0",
- CPU_POWERPC_MPC8545E_v20, POWERPC_SVR_8545E_v20, e500v2)
- POWERPC_DEF_SVR("MPC8545E_v21", "MPC8545E v2.1",
- CPU_POWERPC_MPC8545E_v21, POWERPC_SVR_8545E_v21, e500v2)
- POWERPC_DEF_SVR("MPC8547E_v20", "MPC8547E v2.0",
- CPU_POWERPC_MPC8547E_v20, POWERPC_SVR_8547E_v20, e500v2)
- POWERPC_DEF_SVR("MPC8547E_v21", "MPC8547E v2.1",
- CPU_POWERPC_MPC8547E_v21, POWERPC_SVR_8547E_v21, e500v2)
- POWERPC_DEF_SVR("MPC8548_v10", "MPC8548 v1.0",
- CPU_POWERPC_MPC8548_v10, POWERPC_SVR_8548_v10, e500v2)
- POWERPC_DEF_SVR("MPC8548_v11", "MPC8548 v1.1",
- CPU_POWERPC_MPC8548_v11, POWERPC_SVR_8548_v11, e500v2)
- POWERPC_DEF_SVR("MPC8548_v20", "MPC8548 v2.0",
- CPU_POWERPC_MPC8548_v20, POWERPC_SVR_8548_v20, e500v2)
- POWERPC_DEF_SVR("MPC8548_v21", "MPC8548 v2.1",
- CPU_POWERPC_MPC8548_v21, POWERPC_SVR_8548_v21, e500v2)
- POWERPC_DEF_SVR("MPC8548E_v10", "MPC8548E v1.0",
- CPU_POWERPC_MPC8548E_v10, POWERPC_SVR_8548E_v10, e500v2)
- POWERPC_DEF_SVR("MPC8548E_v11", "MPC8548E v1.1",
- CPU_POWERPC_MPC8548E_v11, POWERPC_SVR_8548E_v11, e500v2)
- POWERPC_DEF_SVR("MPC8548E_v20", "MPC8548E v2.0",
- CPU_POWERPC_MPC8548E_v20, POWERPC_SVR_8548E_v20, e500v2)
- 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)
- POWERPC_DEF_SVR("MPC8555_v11", "MPC8555 v1.1",
- CPU_POWERPC_MPC8555_v11, POWERPC_SVR_8555_v11, e500v2)
- POWERPC_DEF_SVR("MPC8555E_v10", "MPC8555E v1.0",
- CPU_POWERPC_MPC8555E_v10, POWERPC_SVR_8555E_v10, e500v2)
- POWERPC_DEF_SVR("MPC8555E_v11", "MPC8555E v1.1",
- CPU_POWERPC_MPC8555E_v11, POWERPC_SVR_8555E_v11, e500v2)
- POWERPC_DEF_SVR("MPC8560_v10", "MPC8560 v1.0",
- CPU_POWERPC_MPC8560_v10, POWERPC_SVR_8560_v10, e500v2)
- POWERPC_DEF_SVR("MPC8560_v20", "MPC8560 v2.0",
- CPU_POWERPC_MPC8560_v20, POWERPC_SVR_8560_v20, e500v2)
- POWERPC_DEF_SVR("MPC8560_v21", "MPC8560 v2.1",
- CPU_POWERPC_MPC8560_v21, POWERPC_SVR_8560_v21, e500v2)
- POWERPC_DEF_SVR("MPC8567", "MPC8567",
- CPU_POWERPC_MPC8567, POWERPC_SVR_8567, e500v2)
- POWERPC_DEF_SVR("MPC8567E", "MPC8567E",
- CPU_POWERPC_MPC8567E, POWERPC_SVR_8567E, e500v2)
- POWERPC_DEF_SVR("MPC8568", "MPC8568",
- CPU_POWERPC_MPC8568, POWERPC_SVR_8568, e500v2)
- POWERPC_DEF_SVR("MPC8568E", "MPC8568E",
- CPU_POWERPC_MPC8568E, POWERPC_SVR_8568E, e500v2)
- POWERPC_DEF_SVR("MPC8572", "MPC8572",
- CPU_POWERPC_MPC8572, POWERPC_SVR_8572, e500v2)
- POWERPC_DEF_SVR("MPC8572E", "MPC8572E",
- CPU_POWERPC_MPC8572E, POWERPC_SVR_8572E, e500v2)
- /* e600 family */
- POWERPC_DEF("e600", CPU_POWERPC_e600, e600,
- "PowerPC e600 core")
- /* PowerPC e600 microcontrollers */
- POWERPC_DEF_SVR("MPC8610", "MPC8610",
- CPU_POWERPC_MPC8610, POWERPC_SVR_8610, e600)
- POWERPC_DEF_SVR("MPC8641", "MPC8641",
- CPU_POWERPC_MPC8641, POWERPC_SVR_8641, e600)
- POWERPC_DEF_SVR("MPC8641D", "MPC8641D",
- CPU_POWERPC_MPC8641D, POWERPC_SVR_8641D, e600)
- /* 32 bits "classic" PowerPC */
- /* PowerPC 6xx family */
- POWERPC_DEF("601_v0", CPU_POWERPC_601_v0, 601,
- "PowerPC 601v0")
- POWERPC_DEF("601_v1", CPU_POWERPC_601_v1, 601,
- "PowerPC 601v1")
- POWERPC_DEF("601_v2", CPU_POWERPC_601_v2, 601v,
- "PowerPC 601v2")
- POWERPC_DEF("602", CPU_POWERPC_602, 602,
- "PowerPC 602")
- POWERPC_DEF("603", CPU_POWERPC_603, 603,
- "PowerPC 603")
- POWERPC_DEF("603e_v1.1", CPU_POWERPC_603E_v11, 603E,
- "PowerPC 603e v1.1")
- POWERPC_DEF("603e_v1.2", CPU_POWERPC_603E_v12, 603E,
- "PowerPC 603e v1.2")
- POWERPC_DEF("603e_v1.3", CPU_POWERPC_603E_v13, 603E,
- "PowerPC 603e v1.3")
- POWERPC_DEF("603e_v1.4", CPU_POWERPC_603E_v14, 603E,
- "PowerPC 603e v1.4")
- POWERPC_DEF("603e_v2.2", CPU_POWERPC_603E_v22, 603E,
- "PowerPC 603e v2.2")
- POWERPC_DEF("603e_v3", CPU_POWERPC_603E_v3, 603E,
- "PowerPC 603e v3")
- POWERPC_DEF("603e_v4", CPU_POWERPC_603E_v4, 603E,
- "PowerPC 603e v4")
- POWERPC_DEF("603e_v4.1", CPU_POWERPC_603E_v41, 603E,
- "PowerPC 603e v4.1")
- POWERPC_DEF("603e7", CPU_POWERPC_603E7, 603E,
- "PowerPC 603e (aka PID7)")
- POWERPC_DEF("603e7t", CPU_POWERPC_603E7t, 603E,
- "PowerPC 603e7t")
- POWERPC_DEF("603e7v", CPU_POWERPC_603E7v, 603E,
- "PowerPC 603e7v")
- POWERPC_DEF("603e7v1", CPU_POWERPC_603E7v1, 603E,
- "PowerPC 603e7v1")
- POWERPC_DEF("603e7v2", CPU_POWERPC_603E7v2, 603E,
- "PowerPC 603e7v2")
- POWERPC_DEF("603p", CPU_POWERPC_603P, 603E,
- "PowerPC 603p (aka PID7v)")
- POWERPC_DEF("604", CPU_POWERPC_604, 604,
- "PowerPC 604")
- POWERPC_DEF("604e_v1.0", CPU_POWERPC_604E_v10, 604E,
- "PowerPC 604e v1.0")
- POWERPC_DEF("604e_v2.2", CPU_POWERPC_604E_v22, 604E,
- "PowerPC 604e v2.2")
- POWERPC_DEF("604e_v2.4", CPU_POWERPC_604E_v24, 604E,
- "PowerPC 604e v2.4")
- POWERPC_DEF("604r", CPU_POWERPC_604R, 604E,
- "PowerPC 604r (aka PIDA)")
-#if defined(TODO)
- POWERPC_DEF("604ev", CPU_POWERPC_604EV, 604E,
- "PowerPC 604ev")
-#endif
- /* PowerPC 7xx family */
- POWERPC_DEF("740_v1.0", CPU_POWERPC_7x0_v10, 740,
- "PowerPC 740 v1.0 (G3)")
- POWERPC_DEF("750_v1.0", CPU_POWERPC_7x0_v10, 750,
- "PowerPC 750 v1.0 (G3)")
- POWERPC_DEF("740_v2.0", CPU_POWERPC_7x0_v20, 740,
- "PowerPC 740 v2.0 (G3)")
- POWERPC_DEF("750_v2.0", CPU_POWERPC_7x0_v20, 750,
- "PowerPC 750 v2.0 (G3)")
- POWERPC_DEF("740_v2.1", CPU_POWERPC_7x0_v21, 740,
- "PowerPC 740 v2.1 (G3)")
- POWERPC_DEF("750_v2.1", CPU_POWERPC_7x0_v21, 750,
- "PowerPC 750 v2.1 (G3)")
- POWERPC_DEF("740_v2.2", CPU_POWERPC_7x0_v22, 740,
- "PowerPC 740 v2.2 (G3)")
- POWERPC_DEF("750_v2.2", CPU_POWERPC_7x0_v22, 750,
- "PowerPC 750 v2.2 (G3)")
- POWERPC_DEF("740_v3.0", CPU_POWERPC_7x0_v30, 740,
- "PowerPC 740 v3.0 (G3)")
- POWERPC_DEF("750_v3.0", CPU_POWERPC_7x0_v30, 750,
- "PowerPC 750 v3.0 (G3)")
- POWERPC_DEF("740_v3.1", CPU_POWERPC_7x0_v31, 740,
- "PowerPC 740 v3.1 (G3)")
- POWERPC_DEF("750_v3.1", CPU_POWERPC_7x0_v31, 750,
- "PowerPC 750 v3.1 (G3)")
- POWERPC_DEF("740e", CPU_POWERPC_740E, 740,
- "PowerPC 740E (G3)")
- POWERPC_DEF("750e", CPU_POWERPC_750E, 750,
- "PowerPC 750E (G3)")
- POWERPC_DEF("740p", CPU_POWERPC_7x0P, 740,
- "PowerPC 740P (G3)")
- POWERPC_DEF("750p", CPU_POWERPC_7x0P, 750,
- "PowerPC 750P (G3)")
- POWERPC_DEF("750cl_v1.0", CPU_POWERPC_750CL_v10, 750cl,
- "PowerPC 750CL v1.0")
- POWERPC_DEF("750cl_v2.0", CPU_POWERPC_750CL_v20, 750cl,
- "PowerPC 750CL v2.0")
- POWERPC_DEF("750cx_v1.0", CPU_POWERPC_750CX_v10, 750cx,
- "PowerPC 750CX v1.0 (G3 embedded)")
- POWERPC_DEF("750cx_v2.0", CPU_POWERPC_750CX_v20, 750cx,
- "PowerPC 750CX v2.1 (G3 embedded)")
- POWERPC_DEF("750cx_v2.1", CPU_POWERPC_750CX_v21, 750cx,
- "PowerPC 750CX v2.1 (G3 embedded)")
- POWERPC_DEF("750cx_v2.2", CPU_POWERPC_750CX_v22, 750cx,
- "PowerPC 750CX v2.2 (G3 embedded)")
- POWERPC_DEF("750cxe_v2.1", CPU_POWERPC_750CXE_v21, 750cx,
- "PowerPC 750CXe v2.1 (G3 embedded)")
- POWERPC_DEF("750cxe_v2.2", CPU_POWERPC_750CXE_v22, 750cx,
- "PowerPC 750CXe v2.2 (G3 embedded)")
- POWERPC_DEF("750cxe_v2.3", CPU_POWERPC_750CXE_v23, 750cx,
- "PowerPC 750CXe v2.3 (G3 embedded)")
- POWERPC_DEF("750cxe_v2.4", CPU_POWERPC_750CXE_v24, 750cx,
- "PowerPC 750CXe v2.4 (G3 embedded)")
- POWERPC_DEF("750cxe_v2.4b", CPU_POWERPC_750CXE_v24b, 750cx,
- "PowerPC 750CXe v2.4b (G3 embedded)")
- POWERPC_DEF("750cxe_v3.0", CPU_POWERPC_750CXE_v30, 750cx,
- "PowerPC 750CXe v3.0 (G3 embedded)")
- POWERPC_DEF("750cxe_v3.1", CPU_POWERPC_750CXE_v31, 750cx,
- "PowerPC 750CXe v3.1 (G3 embedded)")
- POWERPC_DEF("750cxe_v3.1b", CPU_POWERPC_750CXE_v31b, 750cx,
- "PowerPC 750CXe v3.1b (G3 embedded)")
- POWERPC_DEF("750cxr", CPU_POWERPC_750CXR, 750cx,
- "PowerPC 750CXr (G3 embedded)")
- POWERPC_DEF("750fl", CPU_POWERPC_750FL, 750fx,
- "PowerPC 750FL (G3 embedded)")
- POWERPC_DEF("750fx_v1.0", CPU_POWERPC_750FX_v10, 750fx,
- "PowerPC 750FX v1.0 (G3 embedded)")
- POWERPC_DEF("750fx_v2.0", CPU_POWERPC_750FX_v20, 750fx,
- "PowerPC 750FX v2.0 (G3 embedded)")
- POWERPC_DEF("750fx_v2.1", CPU_POWERPC_750FX_v21, 750fx,
- "PowerPC 750FX v2.1 (G3 embedded)")
- POWERPC_DEF("750fx_v2.2", CPU_POWERPC_750FX_v22, 750fx,
- "PowerPC 750FX v2.2 (G3 embedded)")
- POWERPC_DEF("750fx_v2.3", CPU_POWERPC_750FX_v23, 750fx,
- "PowerPC 750FX v2.3 (G3 embedded)")
- POWERPC_DEF("750gl", CPU_POWERPC_750GL, 750gx,
- "PowerPC 750GL (G3 embedded)")
- POWERPC_DEF("750gx_v1.0", CPU_POWERPC_750GX_v10, 750gx,
- "PowerPC 750GX v1.0 (G3 embedded)")
- POWERPC_DEF("750gx_v1.1", CPU_POWERPC_750GX_v11, 750gx,
- "PowerPC 750GX v1.1 (G3 embedded)")
- POWERPC_DEF("750gx_v1.2", CPU_POWERPC_750GX_v12, 750gx,
- "PowerPC 750GX v1.2 (G3 embedded)")
- POWERPC_DEF("750l_v2.0", CPU_POWERPC_750L_v20, 750,
- "PowerPC 750L v2.0 (G3 embedded)")
- POWERPC_DEF("750l_v2.1", CPU_POWERPC_750L_v21, 750,
- "PowerPC 750L v2.1 (G3 embedded)")
- POWERPC_DEF("750l_v2.2", CPU_POWERPC_750L_v22, 750,
- "PowerPC 750L v2.2 (G3 embedded)")
- POWERPC_DEF("750l_v3.0", CPU_POWERPC_750L_v30, 750,
- "PowerPC 750L v3.0 (G3 embedded)")
- POWERPC_DEF("750l_v3.2", CPU_POWERPC_750L_v32, 750,
- "PowerPC 750L v3.2 (G3 embedded)")
- POWERPC_DEF("745_v1.0", CPU_POWERPC_7x5_v10, 745,
- "PowerPC 745 v1.0")
- POWERPC_DEF("755_v1.0", CPU_POWERPC_7x5_v10, 755,
- "PowerPC 755 v1.0")
- POWERPC_DEF("745_v1.1", CPU_POWERPC_7x5_v11, 745,
- "PowerPC 745 v1.1")
- POWERPC_DEF("755_v1.1", CPU_POWERPC_7x5_v11, 755,
- "PowerPC 755 v1.1")
- POWERPC_DEF("745_v2.0", CPU_POWERPC_7x5_v20, 745,
- "PowerPC 745 v2.0")
- POWERPC_DEF("755_v2.0", CPU_POWERPC_7x5_v20, 755,
- "PowerPC 755 v2.0")
- POWERPC_DEF("745_v2.1", CPU_POWERPC_7x5_v21, 745,
- "PowerPC 745 v2.1")
- POWERPC_DEF("755_v2.1", CPU_POWERPC_7x5_v21, 755,
- "PowerPC 755 v2.1")
- POWERPC_DEF("745_v2.2", CPU_POWERPC_7x5_v22, 745,
- "PowerPC 745 v2.2")
- POWERPC_DEF("755_v2.2", CPU_POWERPC_7x5_v22, 755,
- "PowerPC 755 v2.2")
- POWERPC_DEF("745_v2.3", CPU_POWERPC_7x5_v23, 745,
- "PowerPC 745 v2.3")
- POWERPC_DEF("755_v2.3", CPU_POWERPC_7x5_v23, 755,
- "PowerPC 755 v2.3")
- POWERPC_DEF("745_v2.4", CPU_POWERPC_7x5_v24, 745,
- "PowerPC 745 v2.4")
- POWERPC_DEF("755_v2.4", CPU_POWERPC_7x5_v24, 755,
- "PowerPC 755 v2.4")
- POWERPC_DEF("745_v2.5", CPU_POWERPC_7x5_v25, 745,
- "PowerPC 745 v2.5")
- POWERPC_DEF("755_v2.5", CPU_POWERPC_7x5_v25, 755,
- "PowerPC 755 v2.5")
- POWERPC_DEF("745_v2.6", CPU_POWERPC_7x5_v26, 745,
- "PowerPC 745 v2.6")
- POWERPC_DEF("755_v2.6", CPU_POWERPC_7x5_v26, 755,
- "PowerPC 755 v2.6")
- POWERPC_DEF("745_v2.7", CPU_POWERPC_7x5_v27, 745,
- "PowerPC 745 v2.7")
- POWERPC_DEF("755_v2.7", CPU_POWERPC_7x5_v27, 755,
- "PowerPC 755 v2.7")
- POWERPC_DEF("745_v2.8", CPU_POWERPC_7x5_v28, 745,
- "PowerPC 745 v2.8")
- POWERPC_DEF("755_v2.8", CPU_POWERPC_7x5_v28, 755,
- "PowerPC 755 v2.8")
-#if defined(TODO)
- POWERPC_DEF("745p", CPU_POWERPC_7x5P, 745,
- "PowerPC 745P (G3)")
- POWERPC_DEF("755p", CPU_POWERPC_7x5P, 755,
- "PowerPC 755P (G3)")
-#endif
- /* PowerPC 74xx family */
- POWERPC_DEF("7400_v1.0", CPU_POWERPC_7400_v10, 7400,
- "PowerPC 7400 v1.0 (G4)")
- POWERPC_DEF("7400_v1.1", CPU_POWERPC_7400_v11, 7400,
- "PowerPC 7400 v1.1 (G4)")
- POWERPC_DEF("7400_v2.0", CPU_POWERPC_7400_v20, 7400,
- "PowerPC 7400 v2.0 (G4)")
- POWERPC_DEF("7400_v2.1", CPU_POWERPC_7400_v21, 7400,
- "PowerPC 7400 v2.1 (G4)")
- POWERPC_DEF("7400_v2.2", CPU_POWERPC_7400_v22, 7400,
- "PowerPC 7400 v2.2 (G4)")
- POWERPC_DEF("7400_v2.6", CPU_POWERPC_7400_v26, 7400,
- "PowerPC 7400 v2.6 (G4)")
- POWERPC_DEF("7400_v2.7", CPU_POWERPC_7400_v27, 7400,
- "PowerPC 7400 v2.7 (G4)")
- POWERPC_DEF("7400_v2.8", CPU_POWERPC_7400_v28, 7400,
- "PowerPC 7400 v2.8 (G4)")
- POWERPC_DEF("7400_v2.9", CPU_POWERPC_7400_v29, 7400,
- "PowerPC 7400 v2.9 (G4)")
- POWERPC_DEF("7410_v1.0", CPU_POWERPC_7410_v10, 7410,
- "PowerPC 7410 v1.0 (G4)")
- POWERPC_DEF("7410_v1.1", CPU_POWERPC_7410_v11, 7410,
- "PowerPC 7410 v1.1 (G4)")
- POWERPC_DEF("7410_v1.2", CPU_POWERPC_7410_v12, 7410,
- "PowerPC 7410 v1.2 (G4)")
- POWERPC_DEF("7410_v1.3", CPU_POWERPC_7410_v13, 7410,
- "PowerPC 7410 v1.3 (G4)")
- POWERPC_DEF("7410_v1.4", CPU_POWERPC_7410_v14, 7410,
- "PowerPC 7410 v1.4 (G4)")
- POWERPC_DEF("7448_v1.0", CPU_POWERPC_7448_v10, 7400,
- "PowerPC 7448 v1.0 (G4)")
- POWERPC_DEF("7448_v1.1", CPU_POWERPC_7448_v11, 7400,
- "PowerPC 7448 v1.1 (G4)")
- POWERPC_DEF("7448_v2.0", CPU_POWERPC_7448_v20, 7400,
- "PowerPC 7448 v2.0 (G4)")
- POWERPC_DEF("7448_v2.1", CPU_POWERPC_7448_v21, 7400,
- "PowerPC 7448 v2.1 (G4)")
- POWERPC_DEF("7450_v1.0", CPU_POWERPC_7450_v10, 7450,
- "PowerPC 7450 v1.0 (G4)")
- POWERPC_DEF("7450_v1.1", CPU_POWERPC_7450_v11, 7450,
- "PowerPC 7450 v1.1 (G4)")
- POWERPC_DEF("7450_v1.2", CPU_POWERPC_7450_v12, 7450,
- "PowerPC 7450 v1.2 (G4)")
- POWERPC_DEF("7450_v2.0", CPU_POWERPC_7450_v20, 7450,
- "PowerPC 7450 v2.0 (G4)")
- POWERPC_DEF("7450_v2.1", CPU_POWERPC_7450_v21, 7450,
- "PowerPC 7450 v2.1 (G4)")
- POWERPC_DEF("7441_v2.1", CPU_POWERPC_7450_v21, 7440,
- "PowerPC 7441 v2.1 (G4)")
- POWERPC_DEF("7441_v2.3", CPU_POWERPC_74x1_v23, 7440,
- "PowerPC 7441 v2.3 (G4)")
- POWERPC_DEF("7451_v2.3", CPU_POWERPC_74x1_v23, 7450,
- "PowerPC 7451 v2.3 (G4)")
- POWERPC_DEF("7441_v2.10", CPU_POWERPC_74x1_v210, 7440,
- "PowerPC 7441 v2.10 (G4)")
- POWERPC_DEF("7451_v2.10", CPU_POWERPC_74x1_v210, 7450,
- "PowerPC 7451 v2.10 (G4)")
- POWERPC_DEF("7445_v1.0", CPU_POWERPC_74x5_v10, 7445,
- "PowerPC 7445 v1.0 (G4)")
- POWERPC_DEF("7455_v1.0", CPU_POWERPC_74x5_v10, 7455,
- "PowerPC 7455 v1.0 (G4)")
- POWERPC_DEF("7445_v2.1", CPU_POWERPC_74x5_v21, 7445,
- "PowerPC 7445 v2.1 (G4)")
- POWERPC_DEF("7455_v2.1", CPU_POWERPC_74x5_v21, 7455,
- "PowerPC 7455 v2.1 (G4)")
- POWERPC_DEF("7445_v3.2", CPU_POWERPC_74x5_v32, 7445,
- "PowerPC 7445 v3.2 (G4)")
- POWERPC_DEF("7455_v3.2", CPU_POWERPC_74x5_v32, 7455,
- "PowerPC 7455 v3.2 (G4)")
- POWERPC_DEF("7445_v3.3", CPU_POWERPC_74x5_v33, 7445,
- "PowerPC 7445 v3.3 (G4)")
- POWERPC_DEF("7455_v3.3", CPU_POWERPC_74x5_v33, 7455,
- "PowerPC 7455 v3.3 (G4)")
- POWERPC_DEF("7445_v3.4", CPU_POWERPC_74x5_v34, 7445,
- "PowerPC 7445 v3.4 (G4)")
- POWERPC_DEF("7455_v3.4", CPU_POWERPC_74x5_v34, 7455,
- "PowerPC 7455 v3.4 (G4)")
- POWERPC_DEF("7447_v1.0", CPU_POWERPC_74x7_v10, 7445,
- "PowerPC 7447 v1.0 (G4)")
- POWERPC_DEF("7457_v1.0", CPU_POWERPC_74x7_v10, 7455,
- "PowerPC 7457 v1.0 (G4)")
- POWERPC_DEF("7447_v1.1", CPU_POWERPC_74x7_v11, 7445,
- "PowerPC 7447 v1.1 (G4)")
- POWERPC_DEF("7457_v1.1", CPU_POWERPC_74x7_v11, 7455,
- "PowerPC 7457 v1.1 (G4)")
- POWERPC_DEF("7457_v1.2", CPU_POWERPC_74x7_v12, 7455,
- "PowerPC 7457 v1.2 (G4)")
- POWERPC_DEF("7447A_v1.0", CPU_POWERPC_74x7A_v10, 7445,
- "PowerPC 7447A v1.0 (G4)")
- POWERPC_DEF("7457A_v1.0", CPU_POWERPC_74x7A_v10, 7455,
- "PowerPC 7457A v1.0 (G4)")
- POWERPC_DEF("7447A_v1.1", CPU_POWERPC_74x7A_v11, 7445,
- "PowerPC 7447A v1.1 (G4)")
- POWERPC_DEF("7457A_v1.1", CPU_POWERPC_74x7A_v11, 7455,
- "PowerPC 7457A v1.1 (G4)")
- POWERPC_DEF("7447A_v1.2", CPU_POWERPC_74x7A_v12, 7445,
- "PowerPC 7447A v1.2 (G4)")
- POWERPC_DEF("7457A_v1.2", CPU_POWERPC_74x7A_v12, 7455,
- "PowerPC 7457A v1.2 (G4)")
- /* 64 bits PowerPC */
-#if defined (TARGET_PPC64)
-#if defined(TODO)
- POWERPC_DEF("620", CPU_POWERPC_620, 620,
- "PowerPC 620")
- POWERPC_DEF("630", CPU_POWERPC_630, 630,
- "PowerPC 630 (POWER3)")
-#endif
-#if defined(TODO)
- POWERPC_DEF("631", CPU_POWERPC_631, 631,
- "PowerPC 631 (Power 3+)")
-#endif
-#if defined(TODO)
- POWERPC_DEF("POWER4", CPU_POWERPC_POWER4, POWER4,
- "POWER4")
-#endif
-#if defined(TODO)
- POWERPC_DEF("POWER4+", CPU_POWERPC_POWER4P, POWER4P,
- "POWER4p")
-#endif
-#if defined(TODO)
- POWERPC_DEF("POWER5", CPU_POWERPC_POWER5, POWER5,
- "POWER5")
-#endif
- POWERPC_DEF("POWER5+_v2.1", CPU_POWERPC_POWER5P_v21, POWER5P,
- "POWER5+ v2.1")
-#if defined(TODO)
- POWERPC_DEF("POWER6", CPU_POWERPC_POWER6, POWER6,
- "POWER6")
-#endif
- POWERPC_DEF("POWER7_v2.3", CPU_POWERPC_POWER7_v23, POWER7,
- "POWER7 v2.3")
- POWERPC_DEF("POWER7+_v2.1", CPU_POWERPC_POWER7P_v21, POWER7,
- "POWER7+ v2.1")
- POWERPC_DEF("POWER8E_v2.1", CPU_POWERPC_POWER8E_v21, POWER8,
- "POWER8E v2.1")
- POWERPC_DEF("POWER8_v2.0", CPU_POWERPC_POWER8_v20, POWER8,
- "POWER8 v2.0")
- POWERPC_DEF("POWER8NVL_v1.0",CPU_POWERPC_POWER8NVL_v10, POWER8,
- "POWER8NVL v1.0")
- POWERPC_DEF("970_v2.2", CPU_POWERPC_970_v22, 970,
- "PowerPC 970 v2.2")
-
- POWERPC_DEF("POWER9_v1.0", CPU_POWERPC_POWER9_BASE, POWER9,
- "POWER9 v1.0")
-
- POWERPC_DEF("970fx_v1.0", CPU_POWERPC_970FX_v10, 970,
- "PowerPC 970FX v1.0 (G5)")
- POWERPC_DEF("970fx_v2.0", CPU_POWERPC_970FX_v20, 970,
- "PowerPC 970FX v2.0 (G5)")
- POWERPC_DEF("970fx_v2.1", CPU_POWERPC_970FX_v21, 970,
- "PowerPC 970FX v2.1 (G5)")
- POWERPC_DEF("970fx_v3.0", CPU_POWERPC_970FX_v30, 970,
- "PowerPC 970FX v3.0 (G5)")
- POWERPC_DEF("970fx_v3.1", CPU_POWERPC_970FX_v31, 970,
- "PowerPC 970FX v3.1 (G5)")
- POWERPC_DEF("970mp_v1.0", CPU_POWERPC_970MP_v10, 970,
- "PowerPC 970MP v1.0")
- POWERPC_DEF("970mp_v1.1", CPU_POWERPC_970MP_v11, 970,
- "PowerPC 970MP v1.1")
-#if defined(TODO)
- POWERPC_DEF("Cell", CPU_POWERPC_CELL, 970,
- "PowerPC Cell")
-#endif
-#if defined(TODO)
- POWERPC_DEF("Cell_v1.0", CPU_POWERPC_CELL_v10, 970,
- "PowerPC Cell v1.0")
-#endif
-#if defined(TODO)
- POWERPC_DEF("Cell_v2.0", CPU_POWERPC_CELL_v20, 970,
- "PowerPC Cell v2.0")
-#endif
-#if defined(TODO)
- POWERPC_DEF("Cell_v3.0", CPU_POWERPC_CELL_v30, 970,
- "PowerPC Cell v3.0")
-#endif
-#if defined(TODO)
- POWERPC_DEF("Cell_v3.1", CPU_POWERPC_CELL_v31, 970,
- "PowerPC Cell v3.1")
-#endif
-#if defined(TODO)
- POWERPC_DEF("Cell_v3.2", CPU_POWERPC_CELL_v32, 970,
- "PowerPC Cell v3.2")
-#endif
-#if defined(TODO)
- /* This one seems to support the whole POWER2 instruction set
- * and the PowerPC 64 one.
- */
- /* What about A10 & A30 ? */
- POWERPC_DEF("RS64", CPU_POWERPC_RS64, RS64,
- "RS64 (Apache/A35)")
-#endif
-#if defined(TODO)
- POWERPC_DEF("RS64-II", CPU_POWERPC_RS64II, RS64,
- "RS64-II (NorthStar/A50)")
-#endif
-#if defined(TODO)
- POWERPC_DEF("RS64-III", CPU_POWERPC_RS64III, RS64,
- "RS64-III (Pulsar)")
-#endif
-#if defined(TODO)
- POWERPC_DEF("RS64-IV", CPU_POWERPC_RS64IV, RS64,
- "RS64-IV (IceStar/IStar/SStar)")
-#endif
-#endif /* defined (TARGET_PPC64) */
- /* POWER */
-#if defined(TODO)
- POWERPC_DEF("POWER", CPU_POWERPC_POWER, POWER,
- "Original POWER")
-#endif
-#if defined(TODO)
- POWERPC_DEF("POWER2", CPU_POWERPC_POWER2, POWER,
- "POWER2")
-#endif
- /* PA semi cores */
-#if defined(TODO)
- POWERPC_DEF("PA6T", CPU_POWERPC_PA6T, PA6T,
- "PA PA6T")
-#endif
-
-
-/***************************************************************************/
-/* PowerPC CPU aliases */
-
-PowerPCCPUAlias ppc_cpu_aliases[] = {
- { "403", "403GC" },
- { "405", "405D4" },
- { "405CR", "405CRc" },
- { "405GP", "405GPd" },
- { "405GPe", "405CRc" },
- { "x2vp7", "x2vp4" },
- { "x2vp50", "x2vp20" },
-
- { "440EP", "440EPb" },
- { "440GP", "440GPc" },
- { "440GR", "440GRa" },
- { "440GX", "440GXf" },
-
- { "RCPU", "MPC5xx" },
- /* MPC5xx microcontrollers */
- { "MGT560", "MPC5xx" },
- { "MPC509", "MPC5xx" },
- { "MPC533", "MPC5xx" },
- { "MPC534", "MPC5xx" },
- { "MPC555", "MPC5xx" },
- { "MPC556", "MPC5xx" },
- { "MPC560", "MPC5xx" },
- { "MPC561", "MPC5xx" },
- { "MPC562", "MPC5xx" },
- { "MPC563", "MPC5xx" },
- { "MPC564", "MPC5xx" },
- { "MPC565", "MPC5xx" },
- { "MPC566", "MPC5xx" },
-
- { "PowerQUICC", "MPC8xx" },
- /* MPC8xx microcontrollers */
- { "MGT823", "MPC8xx" },
- { "MPC821", "MPC8xx" },
- { "MPC823", "MPC8xx" },
- { "MPC850", "MPC8xx" },
- { "MPC852T", "MPC8xx" },
- { "MPC855T", "MPC8xx" },
- { "MPC857", "MPC8xx" },
- { "MPC859", "MPC8xx" },
- { "MPC860", "MPC8xx" },
- { "MPC862", "MPC8xx" },
- { "MPC866", "MPC8xx" },
- { "MPC870", "MPC8xx" },
- { "MPC875", "MPC8xx" },
- { "MPC880", "MPC8xx" },
- { "MPC885", "MPC8xx" },
-
- /* PowerPC MPC603 microcontrollers */
- { "MPC8240", "603" },
-
- { "MPC52xx", "MPC5200" },
- { "MPC5200", "MPC5200_v12" },
- { "MPC5200B", "MPC5200B_v21" },
-
- { "MPC82xx", "MPC8280" },
- { "PowerQUICC-II", "MPC82xx" },
- { "MPC8241", "G2HiP4" },
- { "MPC8245", "G2HiP4" },
- { "MPC8247", "G2leGP3" },
- { "MPC8248", "G2leGP3" },
- { "MPC8250", "MPC8250_HiP4" },
- { "MPC8250_HiP3", "G2HiP3" },
- { "MPC8250_HiP4", "G2HiP4" },
- { "MPC8255", "MPC8255_HiP4" },
- { "MPC8255_HiP3", "G2HiP3" },
- { "MPC8255_HiP4", "G2HiP4" },
- { "MPC8260", "MPC8260_HiP4" },
- { "MPC8260_HiP3", "G2HiP3" },
- { "MPC8260_HiP4", "G2HiP4" },
- { "MPC8264", "MPC8264_HiP4" },
- { "MPC8264_HiP3", "G2HiP3" },
- { "MPC8264_HiP4", "G2HiP4" },
- { "MPC8265", "MPC8265_HiP4" },
- { "MPC8265_HiP3", "G2HiP3" },
- { "MPC8265_HiP4", "G2HiP4" },
- { "MPC8266", "MPC8266_HiP4" },
- { "MPC8266_HiP3", "G2HiP3" },
- { "MPC8266_HiP4", "G2HiP4" },
- { "MPC8270", "G2leGP3" },
- { "MPC8271", "G2leGP3" },
- { "MPC8272", "G2leGP3" },
- { "MPC8275", "G2leGP3" },
- { "MPC8280", "G2leGP3" },
- { "e200", "e200z6" },
- { "e300", "e300c3" },
- { "MPC8347", "MPC8347T" },
- { "MPC8347A", "MPC8347AT" },
- { "MPC8347E", "MPC8347ET" },
- { "MPC8347EA", "MPC8347EAT" },
- { "e500", "e500v2_v22" },
- { "e500v1", "e500_v20" },
- { "e500v2", "e500v2_v22" },
- { "MPC8533", "MPC8533_v11" },
- { "MPC8533E", "MPC8533E_v11" },
- { "MPC8540", "MPC8540_v21" },
- { "MPC8541", "MPC8541_v11" },
- { "MPC8541E", "MPC8541E_v11" },
- { "MPC8543", "MPC8543_v21" },
- { "MPC8543E", "MPC8543E_v21" },
- { "MPC8544", "MPC8544_v11" },
- { "MPC8544E", "MPC8544E_v11" },
- { "MPC8545", "MPC8545_v21" },
- { "MPC8545E", "MPC8545E_v21" },
- { "MPC8547E", "MPC8547E_v21" },
- { "MPC8548", "MPC8548_v21" },
- { "MPC8548E", "MPC8548E_v21" },
- { "MPC8555", "MPC8555_v11" },
- { "MPC8555E", "MPC8555E_v11" },
- { "MPC8560", "MPC8560_v21" },
- { "601", "601_v2" },
- { "601v", "601_v2" },
- { "Vanilla", "603" },
- { "603e", "603e_v4.1" },
- { "Stretch", "603e" },
- { "Vaillant", "603e7v" },
- { "603r", "603e7t" },
- { "Goldeneye", "603r" },
- { "604e", "604e_v2.4" },
- { "Sirocco", "604e" },
- { "Mach5", "604r" },
- { "740", "740_v3.1" },
- { "Arthur", "740" },
- { "750", "750_v3.1" },
- { "Typhoon", "750" },
- { "G3", "750" },
- { "Conan/Doyle", "750p" },
- { "750cl", "750cl_v2.0" },
- { "750cx", "750cx_v2.2" },
- { "750cxe", "750cxe_v3.1b" },
- { "750fx", "750fx_v2.3" },
- { "750gx", "750gx_v1.2" },
- { "750l", "750l_v3.2" },
- { "LoneStar", "750l" },
- { "745", "745_v2.8" },
- { "755", "755_v2.8" },
- { "Goldfinger", "755" },
- { "7400", "7400_v2.9" },
- { "Max", "7400" },
- { "G4", "7400" },
- { "7410", "7410_v1.4" },
- { "Nitro", "7410" },
- { "7448", "7448_v2.1" },
- { "7450", "7450_v2.1" },
- { "Vger", "7450" },
- { "7441", "7441_v2.3" },
- { "7451", "7451_v2.3" },
- { "7445", "7445_v3.2" },
- { "7455", "7455_v3.2" },
- { "Apollo6", "7455" },
- { "7447", "7447_v1.2" },
- { "7457", "7457_v1.2" },
- { "Apollo7", "7457" },
- { "7447A", "7447A_v1.2" },
- { "7457A", "7457A_v1.2" },
- { "Apollo7PM", "7457A_v1.0" },
-#if defined(TARGET_PPC64)
- { "Trident", "620" },
- { "POWER3", "630" },
- { "Boxer", "POWER3" },
- { "Dino", "POWER3" },
- { "POWER3+", "631" },
- { "POWER5gr", "POWER5" },
- { "POWER5+", "POWER5+_v2.1" },
- { "POWER5gs", "POWER5+_v2.1" },
- { "POWER7", "POWER7_v2.3" },
- { "POWER7+", "POWER7+_v2.1" },
- { "POWER8E", "POWER8E_v2.1" },
- { "POWER8", "POWER8_v2.0" },
- { "POWER8NVL", "POWER8NVL_v1.0" },
- { "POWER9", "POWER9_v1.0" },
- { "970", "970_v2.2" },
- { "970fx", "970fx_v3.1" },
- { "970mp", "970mp_v1.1" },
- { "Apache", "RS64" },
- { "A35", "RS64" },
- { "NorthStar", "RS64-II" },
- { "A50", "RS64-II" },
- { "Pulsar", "RS64-III" },
- { "IceStar", "RS64-IV" },
- { "IStar", "RS64-IV" },
- { "SStar", "RS64-IV" },
-#endif
- { "RIOS", "POWER" },
- { "RSC", "POWER" },
- { "RSC3308", "POWER" },
- { "RSC4608", "POWER" },
- { "RSC2", "POWER2" },
- { "P2SC", "POWER2" },
-
- /* Generic PowerPCs */
-#if defined(TARGET_PPC64)
- { "ppc64", "970fx" },
-#endif
- { "ppc32", "604" },
- { "ppc", "ppc32" },
- { "default", "ppc" },
- { NULL, NULL }
-};
diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h
deleted file mode 100644
index aafbbd7d5d..0000000000
--- a/target-ppc/cpu-models.h
+++ /dev/null
@@ -1,754 +0,0 @@
-/*
- * PowerPC CPU initialization for qemu.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- * Copyright 2011 Freescale Semiconductor, Inc.
- * Copyright 2013 SUSE LINUX Products GmbH
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-#ifndef TARGET_PPC_CPU_MODELS_H
-#define TARGET_PPC_CPU_MODELS_H
-
-/**
- * PowerPCCPUAlias:
- * @alias: The alias name.
- * @model: The CPU model @alias refers to.
- *
- * A mapping entry from CPU @alias to CPU @model.
- */
-typedef struct PowerPCCPUAlias {
- const char *alias;
- const char *model;
- ObjectClass *oc;
-} PowerPCCPUAlias;
-
-extern PowerPCCPUAlias ppc_cpu_aliases[];
-
-/*****************************************************************************/
-/* PVR definitions for most known PowerPC */
-enum {
- /* PowerPC 401 family */
- /* Generic PowerPC 401 */
-#define CPU_POWERPC_401 CPU_POWERPC_401G2
- /* PowerPC 401 cores */
- CPU_POWERPC_401A1 = 0x00210000,
- CPU_POWERPC_401B2 = 0x00220000,
-#if 0
- CPU_POWERPC_401B3 = xxx,
-#endif
- CPU_POWERPC_401C2 = 0x00230000,
- CPU_POWERPC_401D2 = 0x00240000,
- CPU_POWERPC_401E2 = 0x00250000,
- CPU_POWERPC_401F2 = 0x00260000,
- CPU_POWERPC_401G2 = 0x00270000,
- /* PowerPC 401 microcontrolers */
-#if 0
- CPU_POWERPC_401GF = xxx,
-#endif
-#define CPU_POWERPC_IOP480 CPU_POWERPC_401B2
- /* IBM Processor for Network Resources */
- CPU_POWERPC_COBRA = 0x10100000, /* XXX: 405 ? */
-#if 0
- CPU_POWERPC_XIPCHIP = xxx,
-#endif
- /* PowerPC 403 family */
- /* PowerPC 403 microcontrollers */
- CPU_POWERPC_403GA = 0x00200011,
- CPU_POWERPC_403GB = 0x00200100,
- CPU_POWERPC_403GC = 0x00200200,
- CPU_POWERPC_403GCX = 0x00201400,
-#if 0
- CPU_POWERPC_403GP = xxx,
-#endif
- /* PowerPC 405 family */
- /* PowerPC 405 cores */
-#if 0
- CPU_POWERPC_405A3 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405A4 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405B3 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405B4 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405C3 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405C4 = xxx,
-#endif
- CPU_POWERPC_405D2 = 0x20010000,
-#if 0
- CPU_POWERPC_405D3 = xxx,
-#endif
- CPU_POWERPC_405D4 = 0x41810000,
-#if 0
- CPU_POWERPC_405D5 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405E4 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405F4 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405F5 = xxx,
-#endif
-#if 0
- CPU_POWERPC_405F6 = xxx,
-#endif
- /* PowerPC 405 microcontrolers */
- /* XXX: missing 0x200108a0 */
- CPU_POWERPC_405CRa = 0x40110041,
- CPU_POWERPC_405CRb = 0x401100C5,
- CPU_POWERPC_405CRc = 0x40110145,
- CPU_POWERPC_405EP = 0x51210950,
-#if 0
- CPU_POWERPC_405EXr = xxx,
-#endif
- CPU_POWERPC_405EZ = 0x41511460, /* 0x51210950 ? */
-#if 0
- CPU_POWERPC_405FX = xxx,
-#endif
- CPU_POWERPC_405GPa = 0x40110000,
- CPU_POWERPC_405GPb = 0x40110040,
- CPU_POWERPC_405GPc = 0x40110082,
- CPU_POWERPC_405GPd = 0x401100C4,
- CPU_POWERPC_405GPR = 0x50910951,
-#if 0
- CPU_POWERPC_405H = xxx,
-#endif
-#if 0
- CPU_POWERPC_405L = xxx,
-#endif
- CPU_POWERPC_405LP = 0x41F10000,
-#if 0
- CPU_POWERPC_405PM = xxx,
-#endif
-#if 0
- CPU_POWERPC_405PS = xxx,
-#endif
-#if 0
- CPU_POWERPC_405S = xxx,
-#endif
- /* IBM network processors */
- CPU_POWERPC_NPE405H = 0x414100C0,
- CPU_POWERPC_NPE405H2 = 0x41410140,
- CPU_POWERPC_NPE405L = 0x416100C0,
- CPU_POWERPC_NPE4GS3 = 0x40B10000,
-#if 0
- CPU_POWERPC_NPCxx1 = xxx,
-#endif
-#if 0
- CPU_POWERPC_NPR161 = xxx,
-#endif
-#if 0
- CPU_POWERPC_LC77700 = xxx,
-#endif
- /* IBM STBxxx (PowerPC 401/403/405 core based microcontrollers) */
-#if 0
- CPU_POWERPC_STB01000 = xxx,
-#endif
-#if 0
- CPU_POWERPC_STB01010 = xxx,
-#endif
-#if 0
- CPU_POWERPC_STB0210 = xxx, /* 401B3 */
-#endif
- CPU_POWERPC_STB03 = 0x40310000, /* 0x40130000 ? */
-#if 0
- CPU_POWERPC_STB043 = xxx,
-#endif
-#if 0
- CPU_POWERPC_STB045 = xxx,
-#endif
- CPU_POWERPC_STB04 = 0x41810000,
- CPU_POWERPC_STB25 = 0x51510950,
-#if 0
- CPU_POWERPC_STB130 = xxx,
-#endif
- /* Xilinx cores */
- CPU_POWERPC_X2VP4 = 0x20010820,
- CPU_POWERPC_X2VP20 = 0x20010860,
-#if 0
- CPU_POWERPC_ZL10310 = xxx,
-#endif
-#if 0
- CPU_POWERPC_ZL10311 = xxx,
-#endif
-#if 0
- CPU_POWERPC_ZL10320 = xxx,
-#endif
-#if 0
- CPU_POWERPC_ZL10321 = xxx,
-#endif
- /* PowerPC 440 family */
- /* Generic PowerPC 440 */
-#define CPU_POWERPC_440 CPU_POWERPC_440GXf
- /* PowerPC 440 cores */
-#if 0
- CPU_POWERPC_440A4 = xxx,
-#endif
- CPU_POWERPC_440_XILINX = 0x7ff21910,
-#if 0
- CPU_POWERPC_440A5 = xxx,
-#endif
-#if 0
- CPU_POWERPC_440B4 = xxx,
-#endif
-#if 0
- CPU_POWERPC_440F5 = xxx,
-#endif
-#if 0
- CPU_POWERPC_440G5 = xxx,
-#endif
-#if 0
- CPU_POWERPC_440H4 = xxx,
-#endif
-#if 0
- CPU_POWERPC_440H6 = xxx,
-#endif
- /* PowerPC 440 microcontrolers */
- CPU_POWERPC_440EPa = 0x42221850,
- CPU_POWERPC_440EPb = 0x422218D3,
- CPU_POWERPC_440GPb = 0x40120440,
- CPU_POWERPC_440GPc = 0x40120481,
-#define CPU_POWERPC_440GRa CPU_POWERPC_440EPb
- CPU_POWERPC_440GRX = 0x200008D0,
-#define CPU_POWERPC_440EPX CPU_POWERPC_440GRX
- CPU_POWERPC_440GXa = 0x51B21850,
- CPU_POWERPC_440GXb = 0x51B21851,
- CPU_POWERPC_440GXc = 0x51B21892,
- CPU_POWERPC_440GXf = 0x51B21894,
-#if 0
- CPU_POWERPC_440S = xxx,
-#endif
- CPU_POWERPC_440SP = 0x53221850,
- CPU_POWERPC_440SP2 = 0x53221891,
- CPU_POWERPC_440SPE = 0x53421890,
- /* PowerPC 460 family */
-#if 0
- /* Generic PowerPC 464 */
-#define CPU_POWERPC_464 CPU_POWERPC_464H90
-#endif
- /* PowerPC 464 microcontrolers */
-#if 0
- CPU_POWERPC_464H90 = xxx,
-#endif
-#if 0
- CPU_POWERPC_464H90FP = xxx,
-#endif
- /* Freescale embedded PowerPC cores */
- /* PowerPC MPC 5xx cores (aka RCPU) */
- CPU_POWERPC_MPC5xx = 0x00020020,
- /* PowerPC MPC 8xx cores (aka PowerQUICC) */
- CPU_POWERPC_MPC8xx = 0x00500000,
- /* G2 cores (aka PowerQUICC-II) */
- CPU_POWERPC_G2 = 0x00810011,
- CPU_POWERPC_G2H4 = 0x80811010,
- CPU_POWERPC_G2gp = 0x80821010,
- CPU_POWERPC_G2ls = 0x90810010,
- CPU_POWERPC_MPC603 = 0x00810100,
- CPU_POWERPC_G2_HIP3 = 0x00810101,
- CPU_POWERPC_G2_HIP4 = 0x80811014,
- /* G2_LE core (aka PowerQUICC-II) */
- CPU_POWERPC_G2LE = 0x80820010,
- CPU_POWERPC_G2LEgp = 0x80822010,
- CPU_POWERPC_G2LEls = 0xA0822010,
- CPU_POWERPC_G2LEgp1 = 0x80822011,
- CPU_POWERPC_G2LEgp3 = 0x80822013,
- /* MPC52xx microcontrollers */
- /* XXX: MPC 5121 ? */
-#define CPU_POWERPC_MPC5200_v10 CPU_POWERPC_G2LEgp1
-#define CPU_POWERPC_MPC5200_v11 CPU_POWERPC_G2LEgp1
-#define CPU_POWERPC_MPC5200_v12 CPU_POWERPC_G2LEgp1
-#define CPU_POWERPC_MPC5200B_v20 CPU_POWERPC_G2LEgp1
-#define CPU_POWERPC_MPC5200B_v21 CPU_POWERPC_G2LEgp1
- /* e200 family */
- /* e200 cores */
-#if 0
- CPU_POWERPC_e200z0 = xxx,
-#endif
-#if 0
- CPU_POWERPC_e200z1 = xxx,
-#endif
-#if 0 /* ? */
- CPU_POWERPC_e200z3 = 0x81120000,
-#endif
- CPU_POWERPC_e200z5 = 0x81000000,
- CPU_POWERPC_e200z6 = 0x81120000,
- /* MPC55xx microcontrollers */
-#define CPU_POWERPC_MPC55xx CPU_POWERPC_MPC5567
-#if 0
-#define CPU_POWERPC_MPC5514E CPU_POWERPC_MPC5514E_v1
-#define CPU_POWERPC_MPC5514E_v0 CPU_POWERPC_e200z0
-#define CPU_POWERPC_MPC5514E_v1 CPU_POWERPC_e200z1
-#define CPU_POWERPC_MPC5514G CPU_POWERPC_MPC5514G_v1
-#define CPU_POWERPC_MPC5514G_v0 CPU_POWERPC_e200z0
-#define CPU_POWERPC_MPC5514G_v1 CPU_POWERPC_e200z1
-#define CPU_POWERPC_MPC5515S CPU_POWERPC_e200z1
-#define CPU_POWERPC_MPC5516E CPU_POWERPC_MPC5516E_v1
-#define CPU_POWERPC_MPC5516E_v0 CPU_POWERPC_e200z0
-#define CPU_POWERPC_MPC5516E_v1 CPU_POWERPC_e200z1
-#define CPU_POWERPC_MPC5516G CPU_POWERPC_MPC5516G_v1
-#define CPU_POWERPC_MPC5516G_v0 CPU_POWERPC_e200z0
-#define CPU_POWERPC_MPC5516G_v1 CPU_POWERPC_e200z1
-#define CPU_POWERPC_MPC5516S CPU_POWERPC_e200z1
-#endif
-#if 0
-#define CPU_POWERPC_MPC5533 CPU_POWERPC_e200z3
-#define CPU_POWERPC_MPC5534 CPU_POWERPC_e200z3
-#endif
-#define CPU_POWERPC_MPC5553 CPU_POWERPC_e200z6
-#define CPU_POWERPC_MPC5554 CPU_POWERPC_e200z6
-#define CPU_POWERPC_MPC5561 CPU_POWERPC_e200z6
-#define CPU_POWERPC_MPC5565 CPU_POWERPC_e200z6
-#define CPU_POWERPC_MPC5566 CPU_POWERPC_e200z6
-#define CPU_POWERPC_MPC5567 CPU_POWERPC_e200z6
- /* e300 family */
- /* e300 cores */
- CPU_POWERPC_e300c1 = 0x00830010,
- CPU_POWERPC_e300c2 = 0x00840010,
- CPU_POWERPC_e300c3 = 0x00850010,
- CPU_POWERPC_e300c4 = 0x00860010,
- /* MPC83xx microcontrollers */
-#define CPU_POWERPC_MPC831x CPU_POWERPC_e300c3
-#define CPU_POWERPC_MPC832x CPU_POWERPC_e300c2
-#define CPU_POWERPC_MPC834x CPU_POWERPC_e300c1
-#define CPU_POWERPC_MPC835x CPU_POWERPC_e300c1
-#define CPU_POWERPC_MPC836x CPU_POWERPC_e300c1
-#define CPU_POWERPC_MPC837x CPU_POWERPC_e300c4
- /* e500 family */
- /* e500 cores */
-#define CPU_POWERPC_e500 CPU_POWERPC_e500v2_v22
- CPU_POWERPC_e500v1_v10 = 0x80200010,
- CPU_POWERPC_e500v1_v20 = 0x80200020,
- CPU_POWERPC_e500v2_v10 = 0x80210010,
- CPU_POWERPC_e500v2_v11 = 0x80210011,
- CPU_POWERPC_e500v2_v20 = 0x80210020,
- CPU_POWERPC_e500v2_v21 = 0x80210021,
- CPU_POWERPC_e500v2_v22 = 0x80210022,
- CPU_POWERPC_e500v2_v30 = 0x80210030,
- CPU_POWERPC_e500mc = 0x80230020,
- CPU_POWERPC_e5500 = 0x80240020,
- /* MPC85xx microcontrollers */
-#define CPU_POWERPC_MPC8533_v10 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8533_v11 CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_MPC8533E_v10 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8533E_v11 CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_MPC8540_v10 CPU_POWERPC_e500v1_v10
-#define CPU_POWERPC_MPC8540_v20 CPU_POWERPC_e500v1_v20
-#define CPU_POWERPC_MPC8540_v21 CPU_POWERPC_e500v1_v20
-#define CPU_POWERPC_MPC8541_v10 CPU_POWERPC_e500v1_v20
-#define CPU_POWERPC_MPC8541_v11 CPU_POWERPC_e500v1_v20
-#define CPU_POWERPC_MPC8541E_v10 CPU_POWERPC_e500v1_v20
-#define CPU_POWERPC_MPC8541E_v11 CPU_POWERPC_e500v1_v20
-#define CPU_POWERPC_MPC8543_v10 CPU_POWERPC_e500v2_v10
-#define CPU_POWERPC_MPC8543_v11 CPU_POWERPC_e500v2_v11
-#define CPU_POWERPC_MPC8543_v20 CPU_POWERPC_e500v2_v20
-#define CPU_POWERPC_MPC8543_v21 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8543E_v10 CPU_POWERPC_e500v2_v10
-#define CPU_POWERPC_MPC8543E_v11 CPU_POWERPC_e500v2_v11
-#define CPU_POWERPC_MPC8543E_v20 CPU_POWERPC_e500v2_v20
-#define CPU_POWERPC_MPC8543E_v21 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8544_v10 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8544_v11 CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_MPC8544E_v11 CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_MPC8544E_v10 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8545_v10 CPU_POWERPC_e500v2_v10
-#define CPU_POWERPC_MPC8545_v20 CPU_POWERPC_e500v2_v20
-#define CPU_POWERPC_MPC8545_v21 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8545E_v10 CPU_POWERPC_e500v2_v10
-#define CPU_POWERPC_MPC8545E_v20 CPU_POWERPC_e500v2_v20
-#define CPU_POWERPC_MPC8545E_v21 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8547E_v10 CPU_POWERPC_e500v2_v10
-#define CPU_POWERPC_MPC8547E_v20 CPU_POWERPC_e500v2_v20
-#define CPU_POWERPC_MPC8547E_v21 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8548_v10 CPU_POWERPC_e500v2_v10
-#define CPU_POWERPC_MPC8548_v11 CPU_POWERPC_e500v2_v11
-#define CPU_POWERPC_MPC8548_v20 CPU_POWERPC_e500v2_v20
-#define CPU_POWERPC_MPC8548_v21 CPU_POWERPC_e500v2_v21
-#define CPU_POWERPC_MPC8548E_v10 CPU_POWERPC_e500v2_v10
-#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_MPC8567 CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_MPC8567E CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_MPC8568 CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_MPC8568E CPU_POWERPC_e500v2_v22
-#define CPU_POWERPC_MPC8572 CPU_POWERPC_e500v2_v30
-#define CPU_POWERPC_MPC8572E CPU_POWERPC_e500v2_v30
- /* e600 family */
- /* e600 cores */
- CPU_POWERPC_e600 = 0x80040010,
- /* MPC86xx microcontrollers */
-#define CPU_POWERPC_MPC8610 CPU_POWERPC_e600
-#define CPU_POWERPC_MPC8641 CPU_POWERPC_e600
-#define CPU_POWERPC_MPC8641D CPU_POWERPC_e600
- /* PowerPC 6xx cores */
- CPU_POWERPC_601_v0 = 0x00010001,
- CPU_POWERPC_601_v1 = 0x00010001,
- CPU_POWERPC_601_v2 = 0x00010002,
- CPU_POWERPC_602 = 0x00050100,
- CPU_POWERPC_603 = 0x00030100,
- CPU_POWERPC_603E_v11 = 0x00060101,
- CPU_POWERPC_603E_v12 = 0x00060102,
- CPU_POWERPC_603E_v13 = 0x00060103,
- CPU_POWERPC_603E_v14 = 0x00060104,
- CPU_POWERPC_603E_v22 = 0x00060202,
- CPU_POWERPC_603E_v3 = 0x00060300,
- CPU_POWERPC_603E_v4 = 0x00060400,
- CPU_POWERPC_603E_v41 = 0x00060401,
- CPU_POWERPC_603E7t = 0x00071201,
- CPU_POWERPC_603E7v = 0x00070100,
- CPU_POWERPC_603E7v1 = 0x00070101,
- CPU_POWERPC_603E7v2 = 0x00070201,
- CPU_POWERPC_603E7 = 0x00070200,
- CPU_POWERPC_603P = 0x00070000,
- /* XXX: missing 0x00040303 (604) */
- CPU_POWERPC_604 = 0x00040103,
- /* XXX: missing 0x00091203 */
- /* XXX: missing 0x00092110 */
- /* XXX: missing 0x00092120 */
- CPU_POWERPC_604E_v10 = 0x00090100,
- CPU_POWERPC_604E_v22 = 0x00090202,
- CPU_POWERPC_604E_v24 = 0x00090204,
- /* XXX: missing 0x000a0100 */
- /* XXX: missing 0x00093102 */
- CPU_POWERPC_604R = 0x000a0101,
-#if 0
- CPU_POWERPC_604EV = xxx, /* XXX: same as 604R ? */
-#endif
- /* PowerPC 740/750 cores (aka G3) */
- /* XXX: missing 0x00084202 */
- CPU_POWERPC_7x0_v10 = 0x00080100,
- CPU_POWERPC_7x0_v20 = 0x00080200,
- CPU_POWERPC_7x0_v21 = 0x00080201,
- CPU_POWERPC_7x0_v22 = 0x00080202,
- CPU_POWERPC_7x0_v30 = 0x00080300,
- CPU_POWERPC_7x0_v31 = 0x00080301,
- CPU_POWERPC_740E = 0x00080100,
- CPU_POWERPC_750E = 0x00080200,
- CPU_POWERPC_7x0P = 0x10080000,
- /* XXX: missing 0x00087010 (CL ?) */
- CPU_POWERPC_750CL_v10 = 0x00087200,
- CPU_POWERPC_750CL_v20 = 0x00087210, /* aka rev E */
- CPU_POWERPC_750CX_v10 = 0x00082100,
- CPU_POWERPC_750CX_v20 = 0x00082200,
- CPU_POWERPC_750CX_v21 = 0x00082201,
- CPU_POWERPC_750CX_v22 = 0x00082202,
- CPU_POWERPC_750CXE_v21 = 0x00082211,
- CPU_POWERPC_750CXE_v22 = 0x00082212,
- CPU_POWERPC_750CXE_v23 = 0x00082213,
- CPU_POWERPC_750CXE_v24 = 0x00082214,
- CPU_POWERPC_750CXE_v24b = 0x00083214,
- CPU_POWERPC_750CXE_v30 = 0x00082310,
- CPU_POWERPC_750CXE_v31 = 0x00082311,
- CPU_POWERPC_750CXE_v31b = 0x00083311,
- CPU_POWERPC_750CXR = 0x00083410,
- CPU_POWERPC_750FL = 0x70000203,
- CPU_POWERPC_750FX_v10 = 0x70000100,
- CPU_POWERPC_750FX_v20 = 0x70000200,
- CPU_POWERPC_750FX_v21 = 0x70000201,
- CPU_POWERPC_750FX_v22 = 0x70000202,
- CPU_POWERPC_750FX_v23 = 0x70000203,
- CPU_POWERPC_750GL = 0x70020102,
- CPU_POWERPC_750GX_v10 = 0x70020100,
- CPU_POWERPC_750GX_v11 = 0x70020101,
- CPU_POWERPC_750GX_v12 = 0x70020102,
- CPU_POWERPC_750L_v20 = 0x00088200,
- CPU_POWERPC_750L_v21 = 0x00088201,
- CPU_POWERPC_750L_v22 = 0x00088202,
- CPU_POWERPC_750L_v30 = 0x00088300,
- CPU_POWERPC_750L_v32 = 0x00088302,
- /* PowerPC 745/755 cores */
- CPU_POWERPC_7x5_v10 = 0x00083100,
- CPU_POWERPC_7x5_v11 = 0x00083101,
- CPU_POWERPC_7x5_v20 = 0x00083200,
- CPU_POWERPC_7x5_v21 = 0x00083201,
- CPU_POWERPC_7x5_v22 = 0x00083202, /* aka D */
- CPU_POWERPC_7x5_v23 = 0x00083203, /* aka E */
- CPU_POWERPC_7x5_v24 = 0x00083204,
- CPU_POWERPC_7x5_v25 = 0x00083205,
- CPU_POWERPC_7x5_v26 = 0x00083206,
- CPU_POWERPC_7x5_v27 = 0x00083207,
- CPU_POWERPC_7x5_v28 = 0x00083208,
-#if 0
- CPU_POWERPC_7x5P = xxx,
-#endif
- /* PowerPC 74xx cores (aka G4) */
- /* XXX: missing 0x000C1101 */
- CPU_POWERPC_7400_v10 = 0x000C0100,
- CPU_POWERPC_7400_v11 = 0x000C0101,
- CPU_POWERPC_7400_v20 = 0x000C0200,
- CPU_POWERPC_7400_v21 = 0x000C0201,
- CPU_POWERPC_7400_v22 = 0x000C0202,
- CPU_POWERPC_7400_v26 = 0x000C0206,
- CPU_POWERPC_7400_v27 = 0x000C0207,
- CPU_POWERPC_7400_v28 = 0x000C0208,
- CPU_POWERPC_7400_v29 = 0x000C0209,
- CPU_POWERPC_7410_v10 = 0x800C1100,
- CPU_POWERPC_7410_v11 = 0x800C1101,
- CPU_POWERPC_7410_v12 = 0x800C1102, /* aka C */
- CPU_POWERPC_7410_v13 = 0x800C1103, /* aka D */
- CPU_POWERPC_7410_v14 = 0x800C1104, /* aka E */
- CPU_POWERPC_7448_v10 = 0x80040100,
- CPU_POWERPC_7448_v11 = 0x80040101,
- CPU_POWERPC_7448_v20 = 0x80040200,
- CPU_POWERPC_7448_v21 = 0x80040201,
- CPU_POWERPC_7450_v10 = 0x80000100,
- CPU_POWERPC_7450_v11 = 0x80000101,
- CPU_POWERPC_7450_v12 = 0x80000102,
- CPU_POWERPC_7450_v20 = 0x80000200, /* aka A, B, C, D: 2.04 */
- CPU_POWERPC_7450_v21 = 0x80000201, /* aka E */
- CPU_POWERPC_74x1_v23 = 0x80000203, /* aka G: 2.3 */
- /* XXX: this entry might be a bug in some documentation */
- CPU_POWERPC_74x1_v210 = 0x80000210, /* aka G: 2.3 ? */
- CPU_POWERPC_74x5_v10 = 0x80010100,
- /* XXX: missing 0x80010200 */
- CPU_POWERPC_74x5_v21 = 0x80010201, /* aka C: 2.1 */
- CPU_POWERPC_74x5_v32 = 0x80010302,
- CPU_POWERPC_74x5_v33 = 0x80010303, /* aka F: 3.3 */
- CPU_POWERPC_74x5_v34 = 0x80010304, /* aka G: 3.4 */
- CPU_POWERPC_74x7_v10 = 0x80020100, /* aka A: 1.0 */
- CPU_POWERPC_74x7_v11 = 0x80020101, /* aka B: 1.1 */
- CPU_POWERPC_74x7_v12 = 0x80020102, /* aka C: 1.2 */
- CPU_POWERPC_74x7A_v10 = 0x80030100, /* aka A: 1.0 */
- CPU_POWERPC_74x7A_v11 = 0x80030101, /* aka B: 1.1 */
- CPU_POWERPC_74x7A_v12 = 0x80030102, /* aka C: 1.2 */
- /* 64 bits PowerPC */
-#if defined(TARGET_PPC64)
- CPU_POWERPC_620 = 0x00140000,
- CPU_POWERPC_630 = 0x00400000,
- CPU_POWERPC_631 = 0x00410104,
- CPU_POWERPC_POWER4 = 0x00350000,
- CPU_POWERPC_POWER4P = 0x00380000,
- /* XXX: missing 0x003A0201 */
- CPU_POWERPC_POWER5 = 0x003A0203,
- CPU_POWERPC_POWER5P_v21 = 0x003B0201,
- CPU_POWERPC_POWER6 = 0x003E0000,
- CPU_POWERPC_POWER_SERVER_MASK = 0xFFFF0000,
- CPU_POWERPC_POWER7_BASE = 0x003F0000,
- CPU_POWERPC_POWER7_v23 = 0x003F0203,
- CPU_POWERPC_POWER7P_BASE = 0x004A0000,
- CPU_POWERPC_POWER7P_v21 = 0x004A0201,
- CPU_POWERPC_POWER8E_BASE = 0x004B0000,
- CPU_POWERPC_POWER8E_v21 = 0x004B0201,
- CPU_POWERPC_POWER8_BASE = 0x004D0000,
- CPU_POWERPC_POWER8_v20 = 0x004D0200,
- CPU_POWERPC_POWER8NVL_BASE = 0x004C0000,
- CPU_POWERPC_POWER8NVL_v10 = 0x004C0100,
- CPU_POWERPC_POWER9_BASE = 0x004E0000,
- CPU_POWERPC_970_v22 = 0x00390202,
- CPU_POWERPC_970FX_v10 = 0x00391100,
- CPU_POWERPC_970FX_v20 = 0x003C0200,
- CPU_POWERPC_970FX_v21 = 0x003C0201,
- CPU_POWERPC_970FX_v30 = 0x003C0300,
- CPU_POWERPC_970FX_v31 = 0x003C0301,
- CPU_POWERPC_970MP_v10 = 0x00440100,
- CPU_POWERPC_970MP_v11 = 0x00440101,
-#define CPU_POWERPC_CELL CPU_POWERPC_CELL_v32
- CPU_POWERPC_CELL_v10 = 0x00700100,
- CPU_POWERPC_CELL_v20 = 0x00700400,
- CPU_POWERPC_CELL_v30 = 0x00700500,
- CPU_POWERPC_CELL_v31 = 0x00700501,
-#define CPU_POWERPC_CELL_v32 CPU_POWERPC_CELL_v31
- CPU_POWERPC_RS64 = 0x00330000,
- CPU_POWERPC_RS64II = 0x00340000,
- CPU_POWERPC_RS64III = 0x00360000,
- CPU_POWERPC_RS64IV = 0x00370000,
-#endif /* defined(TARGET_PPC64) */
- /* Original POWER */
- /* XXX: should be POWER (RIOS), RSC3308, RSC4608,
- * POWER2 (RIOS2) & RSC2 (P2SC) here
- */
-#if 0
- CPU_POWER = xxx, /* 0x20000 ? 0x30000 for RSC ? */
-#endif
-#if 0
- CPU_POWER2 = xxx, /* 0x40000 ? */
-#endif
- /* PA Semi core */
- CPU_POWERPC_PA6T = 0x00900000,
-};
-
-/* Logical PVR definitions for sPAPR */
-enum {
- CPU_POWERPC_LOGICAL_2_04 = 0x0F000001,
- CPU_POWERPC_LOGICAL_2_05 = 0x0F000002,
- CPU_POWERPC_LOGICAL_2_06 = 0x0F000003,
- CPU_POWERPC_LOGICAL_2_06_PLUS = 0x0F100003,
- CPU_POWERPC_LOGICAL_2_07 = 0x0F000004,
- CPU_POWERPC_LOGICAL_2_08 = 0x0F000005,
-};
-
-/* System version register (used on MPC 8xxx) */
-enum {
- POWERPC_SVR_NONE = 0x00000000,
- POWERPC_SVR_5200_v10 = 0x80110010,
- POWERPC_SVR_5200_v11 = 0x80110011,
- POWERPC_SVR_5200_v12 = 0x80110012,
- POWERPC_SVR_5200B_v20 = 0x80110020,
- POWERPC_SVR_5200B_v21 = 0x80110021,
-#define POWERPC_SVR_55xx POWERPC_SVR_5567
-#if 0
- POWERPC_SVR_5533 = xxx,
-#endif
-#if 0
- POWERPC_SVR_5534 = xxx,
-#endif
-#if 0
- POWERPC_SVR_5553 = xxx,
-#endif
-#if 0
- POWERPC_SVR_5554 = xxx,
-#endif
-#if 0
- POWERPC_SVR_5561 = xxx,
-#endif
-#if 0
- POWERPC_SVR_5565 = xxx,
-#endif
-#if 0
- POWERPC_SVR_5566 = xxx,
-#endif
-#if 0
- POWERPC_SVR_5567 = xxx,
-#endif
-#if 0
- POWERPC_SVR_8313 = xxx,
-#endif
-#if 0
- POWERPC_SVR_8313E = xxx,
-#endif
-#if 0
- POWERPC_SVR_8314 = xxx,
-#endif
-#if 0
- POWERPC_SVR_8314E = xxx,
-#endif
-#if 0
- POWERPC_SVR_8315 = xxx,
-#endif
-#if 0
- POWERPC_SVR_8315E = xxx,
-#endif
-#if 0
- POWERPC_SVR_8321 = xxx,
-#endif
-#if 0
- POWERPC_SVR_8321E = xxx,
-#endif
-#if 0
- POWERPC_SVR_8323 = xxx,
-#endif
-#if 0
- POWERPC_SVR_8323E = xxx,
-#endif
- POWERPC_SVR_8343 = 0x80570010,
- POWERPC_SVR_8343A = 0x80570030,
- POWERPC_SVR_8343E = 0x80560010,
- POWERPC_SVR_8343EA = 0x80560030,
- POWERPC_SVR_8347P = 0x80550010, /* PBGA package */
- POWERPC_SVR_8347T = 0x80530010, /* TBGA package */
- POWERPC_SVR_8347AP = 0x80550030, /* PBGA package */
- POWERPC_SVR_8347AT = 0x80530030, /* TBGA package */
- POWERPC_SVR_8347EP = 0x80540010, /* PBGA package */
- POWERPC_SVR_8347ET = 0x80520010, /* TBGA package */
- POWERPC_SVR_8347EAP = 0x80540030, /* PBGA package */
- POWERPC_SVR_8347EAT = 0x80520030, /* TBGA package */
- POWERPC_SVR_8349 = 0x80510010,
- POWERPC_SVR_8349A = 0x80510030,
- POWERPC_SVR_8349E = 0x80500010,
- POWERPC_SVR_8349EA = 0x80500030,
-#if 0
- POWERPC_SVR_8358E = xxx,
-#endif
-#if 0
- POWERPC_SVR_8360E = xxx,
-#endif
-#define POWERPC_SVR_E500 0x40000000
- POWERPC_SVR_8377 = 0x80C70010 | POWERPC_SVR_E500,
- POWERPC_SVR_8377E = 0x80C60010 | POWERPC_SVR_E500,
- POWERPC_SVR_8378 = 0x80C50010 | POWERPC_SVR_E500,
- POWERPC_SVR_8378E = 0x80C40010 | POWERPC_SVR_E500,
- POWERPC_SVR_8379 = 0x80C30010 | POWERPC_SVR_E500,
- POWERPC_SVR_8379E = 0x80C00010 | POWERPC_SVR_E500,
- POWERPC_SVR_8533_v10 = 0x80340010 | POWERPC_SVR_E500,
- POWERPC_SVR_8533_v11 = 0x80340011 | POWERPC_SVR_E500,
- POWERPC_SVR_8533E_v10 = 0x803C0010 | POWERPC_SVR_E500,
- POWERPC_SVR_8533E_v11 = 0x803C0011 | POWERPC_SVR_E500,
- POWERPC_SVR_8540_v10 = 0x80300010 | POWERPC_SVR_E500,
- POWERPC_SVR_8540_v20 = 0x80300020 | POWERPC_SVR_E500,
- POWERPC_SVR_8540_v21 = 0x80300021 | POWERPC_SVR_E500,
- POWERPC_SVR_8541_v10 = 0x80720010 | POWERPC_SVR_E500,
- POWERPC_SVR_8541_v11 = 0x80720011 | POWERPC_SVR_E500,
- POWERPC_SVR_8541E_v10 = 0x807A0010 | POWERPC_SVR_E500,
- POWERPC_SVR_8541E_v11 = 0x807A0011 | POWERPC_SVR_E500,
- POWERPC_SVR_8543_v10 = 0x80320010 | POWERPC_SVR_E500,
- POWERPC_SVR_8543_v11 = 0x80320011 | POWERPC_SVR_E500,
- POWERPC_SVR_8543_v20 = 0x80320020 | POWERPC_SVR_E500,
- POWERPC_SVR_8543_v21 = 0x80320021 | POWERPC_SVR_E500,
- POWERPC_SVR_8543E_v10 = 0x803A0010 | POWERPC_SVR_E500,
- POWERPC_SVR_8543E_v11 = 0x803A0011 | POWERPC_SVR_E500,
- POWERPC_SVR_8543E_v20 = 0x803A0020 | POWERPC_SVR_E500,
- POWERPC_SVR_8543E_v21 = 0x803A0021 | POWERPC_SVR_E500,
- POWERPC_SVR_8544_v10 = 0x80340110 | POWERPC_SVR_E500,
- POWERPC_SVR_8544_v11 = 0x80340111 | POWERPC_SVR_E500,
- POWERPC_SVR_8544E_v10 = 0x803C0110 | POWERPC_SVR_E500,
- POWERPC_SVR_8544E_v11 = 0x803C0111 | POWERPC_SVR_E500,
- POWERPC_SVR_8545_v20 = 0x80310220 | POWERPC_SVR_E500,
- POWERPC_SVR_8545_v21 = 0x80310221 | POWERPC_SVR_E500,
- POWERPC_SVR_8545E_v20 = 0x80390220 | POWERPC_SVR_E500,
- POWERPC_SVR_8545E_v21 = 0x80390221 | POWERPC_SVR_E500,
- POWERPC_SVR_8547E_v20 = 0x80390120 | POWERPC_SVR_E500,
- POWERPC_SVR_8547E_v21 = 0x80390121 | POWERPC_SVR_E500,
- POWERPC_SVR_8548_v10 = 0x80310010 | POWERPC_SVR_E500,
- POWERPC_SVR_8548_v11 = 0x80310011 | POWERPC_SVR_E500,
- POWERPC_SVR_8548_v20 = 0x80310020 | POWERPC_SVR_E500,
- POWERPC_SVR_8548_v21 = 0x80310021 | POWERPC_SVR_E500,
- POWERPC_SVR_8548E_v10 = 0x80390010 | POWERPC_SVR_E500,
- POWERPC_SVR_8548E_v11 = 0x80390011 | POWERPC_SVR_E500,
- POWERPC_SVR_8548E_v20 = 0x80390020 | POWERPC_SVR_E500,
- POWERPC_SVR_8548E_v21 = 0x80390021 | POWERPC_SVR_E500,
- POWERPC_SVR_8555_v10 = 0x80710010 | POWERPC_SVR_E500,
- POWERPC_SVR_8555_v11 = 0x80710011 | POWERPC_SVR_E500,
- POWERPC_SVR_8555E_v10 = 0x80790010 | POWERPC_SVR_E500,
- POWERPC_SVR_8555E_v11 = 0x80790011 | POWERPC_SVR_E500,
- POWERPC_SVR_8560_v10 = 0x80700010 | POWERPC_SVR_E500,
- POWERPC_SVR_8560_v20 = 0x80700020 | POWERPC_SVR_E500,
- POWERPC_SVR_8560_v21 = 0x80700021 | POWERPC_SVR_E500,
- POWERPC_SVR_8567 = 0x80750111 | POWERPC_SVR_E500,
- POWERPC_SVR_8567E = 0x807D0111 | POWERPC_SVR_E500,
- POWERPC_SVR_8568 = 0x80750011 | POWERPC_SVR_E500,
- POWERPC_SVR_8568E = 0x807D0011 | POWERPC_SVR_E500,
- POWERPC_SVR_8572 = 0x80E00010 | POWERPC_SVR_E500,
- POWERPC_SVR_8572E = 0x80E80010 | POWERPC_SVR_E500,
- POWERPC_SVR_8610 = 0x80A00011,
- POWERPC_SVR_8641 = 0x80900021,
- POWERPC_SVR_8641D = 0x80900121,
-};
-
-#endif
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
deleted file mode 100644
index d46c31a15d..0000000000
--- a/target-ppc/cpu-qom.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * QEMU PowerPC CPU
- *
- * Copyright (c) 2012 SUSE LINUX Products GmbH
- *
- * 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
- * <http://www.gnu.org/licenses/lgpl-2.1.html>
- */
-#ifndef QEMU_PPC_CPU_QOM_H
-#define QEMU_PPC_CPU_QOM_H
-
-#include "qom/cpu.h"
-
-#ifdef TARGET_PPC64
-#define TYPE_POWERPC_CPU "powerpc64-cpu"
-#elif defined(TARGET_PPCEMB)
-#define TYPE_POWERPC_CPU "embedded-powerpc-cpu"
-#else
-#define TYPE_POWERPC_CPU "powerpc-cpu"
-#endif
-
-#define POWERPC_CPU_CLASS(klass) \
- OBJECT_CLASS_CHECK(PowerPCCPUClass, (klass), TYPE_POWERPC_CPU)
-#define POWERPC_CPU(obj) \
- OBJECT_CHECK(PowerPCCPU, (obj), TYPE_POWERPC_CPU)
-#define POWERPC_CPU_GET_CLASS(obj) \
- OBJECT_GET_CLASS(PowerPCCPUClass, (obj), TYPE_POWERPC_CPU)
-
-typedef struct PowerPCCPU PowerPCCPU;
-typedef struct CPUPPCState CPUPPCState;
-typedef struct ppc_tb_t ppc_tb_t;
-typedef struct ppc_dcr_t ppc_dcr_t;
-
-/*****************************************************************************/
-/* MMU model */
-typedef enum powerpc_mmu_t powerpc_mmu_t;
-enum powerpc_mmu_t {
- POWERPC_MMU_UNKNOWN = 0x00000000,
- /* Standard 32 bits PowerPC MMU */
- POWERPC_MMU_32B = 0x00000001,
- /* PowerPC 6xx MMU with software TLB */
- POWERPC_MMU_SOFT_6xx = 0x00000002,
- /* PowerPC 74xx MMU with software TLB */
- POWERPC_MMU_SOFT_74xx = 0x00000003,
- /* PowerPC 4xx MMU with software TLB */
- POWERPC_MMU_SOFT_4xx = 0x00000004,
- /* PowerPC 4xx MMU with software TLB and zones protections */
- POWERPC_MMU_SOFT_4xx_Z = 0x00000005,
- /* PowerPC MMU in real mode only */
- POWERPC_MMU_REAL = 0x00000006,
- /* Freescale MPC8xx MMU model */
- POWERPC_MMU_MPC8xx = 0x00000007,
- /* BookE MMU model */
- POWERPC_MMU_BOOKE = 0x00000008,
- /* BookE 2.06 MMU model */
- POWERPC_MMU_BOOKE206 = 0x00000009,
- /* PowerPC 601 MMU model (specific BATs format) */
- POWERPC_MMU_601 = 0x0000000A,
-#define POWERPC_MMU_64 0x00010000
-#define POWERPC_MMU_1TSEG 0x00020000
-#define POWERPC_MMU_AMR 0x00040000
-#define POWERPC_MMU_64K 0x00080000
- /* 64 bits PowerPC MMU */
- POWERPC_MMU_64B = POWERPC_MMU_64 | 0x00000001,
- /* Architecture 2.03 and later (has LPCR) */
- POWERPC_MMU_2_03 = POWERPC_MMU_64 | 0x00000002,
- /* Architecture 2.06 variant */
- POWERPC_MMU_2_06 = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
- | POWERPC_MMU_64K
- | POWERPC_MMU_AMR | 0x00000003,
- /* Architecture 2.06 "degraded" (no 1T segments) */
- POWERPC_MMU_2_06a = POWERPC_MMU_64 | POWERPC_MMU_AMR
- | 0x00000003,
- /* Architecture 2.07 variant */
- POWERPC_MMU_2_07 = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
- | POWERPC_MMU_64K
- | POWERPC_MMU_AMR | 0x00000004,
- /* FIXME Add POWERPC_MMU_3_OO defines */
- /* Architecture 2.07 "degraded" (no 1T segments) */
- POWERPC_MMU_2_07a = POWERPC_MMU_64 | POWERPC_MMU_AMR
- | 0x00000004,
-};
-
-/*****************************************************************************/
-/* Exception model */
-typedef enum powerpc_excp_t powerpc_excp_t;
-enum powerpc_excp_t {
- POWERPC_EXCP_UNKNOWN = 0,
- /* Standard PowerPC exception model */
- POWERPC_EXCP_STD,
- /* PowerPC 40x exception model */
- POWERPC_EXCP_40x,
- /* PowerPC 601 exception model */
- POWERPC_EXCP_601,
- /* PowerPC 602 exception model */
- POWERPC_EXCP_602,
- /* PowerPC 603 exception model */
- POWERPC_EXCP_603,
- /* PowerPC 603e exception model */
- POWERPC_EXCP_603E,
- /* PowerPC G2 exception model */
- POWERPC_EXCP_G2,
- /* PowerPC 604 exception model */
- POWERPC_EXCP_604,
- /* PowerPC 7x0 exception model */
- POWERPC_EXCP_7x0,
- /* PowerPC 7x5 exception model */
- POWERPC_EXCP_7x5,
- /* PowerPC 74xx exception model */
- POWERPC_EXCP_74xx,
- /* BookE exception model */
- POWERPC_EXCP_BOOKE,
- /* PowerPC 970 exception model */
- POWERPC_EXCP_970,
- /* POWER7 exception model */
- POWERPC_EXCP_POWER7,
- /* POWER8 exception model */
- POWERPC_EXCP_POWER8,
-};
-
-/*****************************************************************************/
-/* PM instructions */
-typedef enum {
- PPC_PM_DOZE,
- PPC_PM_NAP,
- PPC_PM_SLEEP,
- PPC_PM_RVWINKLE,
-} powerpc_pm_insn_t;
-
-/*****************************************************************************/
-/* Input pins model */
-typedef enum powerpc_input_t powerpc_input_t;
-enum powerpc_input_t {
- PPC_FLAGS_INPUT_UNKNOWN = 0,
- /* PowerPC 6xx bus */
- PPC_FLAGS_INPUT_6xx,
- /* BookE bus */
- PPC_FLAGS_INPUT_BookE,
- /* PowerPC 405 bus */
- PPC_FLAGS_INPUT_405,
- /* PowerPC 970 bus */
- PPC_FLAGS_INPUT_970,
- /* PowerPC POWER7 bus */
- PPC_FLAGS_INPUT_POWER7,
- /* PowerPC 401 bus */
- PPC_FLAGS_INPUT_401,
- /* Freescale RCPU bus */
- PPC_FLAGS_INPUT_RCPU,
-};
-
-struct ppc_segment_page_sizes;
-
-/**
- * PowerPCCPUClass:
- * @parent_realize: The parent class' realize handler.
- * @parent_reset: The parent class' reset handler.
- *
- * A PowerPC CPU model.
- */
-typedef struct PowerPCCPUClass {
- /*< private >*/
- CPUClass parent_class;
- /*< public >*/
-
- DeviceRealize parent_realize;
- DeviceUnrealize parent_unrealize;
- void (*parent_reset)(CPUState *cpu);
-
- uint32_t pvr;
- bool (*pvr_match)(struct PowerPCCPUClass *pcc, uint32_t pvr);
- uint64_t pcr_mask; /* Available bits in PCR register */
- uint64_t pcr_supported; /* Bits for supported PowerISA versions */
- uint32_t svr;
- uint64_t insns_flags;
- uint64_t insns_flags2;
- uint64_t msr_mask;
- powerpc_mmu_t mmu_model;
- powerpc_excp_t excp_model;
- powerpc_input_t bus_model;
- uint32_t flags;
- int bfd_mach;
- uint32_t l1_dcache_size, l1_icache_size;
- const struct ppc_segment_page_sizes *sps;
- void (*init_proc)(CPUPPCState *env);
- int (*check_pow)(CPUPPCState *env);
- int (*handle_mmu_fault)(PowerPCCPU *cpu, vaddr eaddr, int rwx, int mmu_idx);
- bool (*interrupts_big_endian)(PowerPCCPU *cpu);
-} PowerPCCPUClass;
-
-#ifndef CONFIG_USER_ONLY
-typedef struct PPCTimebase {
- uint64_t guest_timebase;
- int64_t time_of_the_day_ns;
-} PPCTimebase;
-
-extern const struct VMStateDescription vmstate_ppc_timebase;
-
-#define VMSTATE_PPC_TIMEBASE_V(_field, _state, _version) { \
- .name = (stringify(_field)), \
- .version_id = (_version), \
- .size = sizeof(PPCTimebase), \
- .vmsd = &vmstate_ppc_timebase, \
- .flags = VMS_STRUCT, \
- .offset = vmstate_offset_value(_state, _field, PPCTimebase), \
-}
-#endif
-
-#endif
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
deleted file mode 100644
index 2a50c43689..0000000000
--- a/target-ppc/cpu.h
+++ /dev/null
@@ -1,2454 +0,0 @@
-/*
- * PowerPC emulation cpu definitions for qemu.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef PPC_CPU_H
-#define PPC_CPU_H
-
-#include "qemu-common.h"
-
-//#define PPC_EMULATE_32BITS_HYPV
-
-#if defined (TARGET_PPC64)
-/* PowerPC 64 definitions */
-#define TARGET_LONG_BITS 64
-#define TARGET_PAGE_BITS 12
-
-/* Note that the official physical address space bits is 62-M where M
- is implementation dependent. I've not looked up M for the set of
- cpus we emulate at the system level. */
-#define TARGET_PHYS_ADDR_SPACE_BITS 62
-
-/* Note that the PPC environment architecture talks about 80 bit virtual
- addresses, with segmentation. Obviously that's not all visible to a
- single process, which is all we're concerned with here. */
-#ifdef TARGET_ABI32
-# define TARGET_VIRT_ADDR_SPACE_BITS 32
-#else
-# define TARGET_VIRT_ADDR_SPACE_BITS 64
-#endif
-
-#define TARGET_PAGE_BITS_64K 16
-#define TARGET_PAGE_BITS_16M 24
-
-#else /* defined (TARGET_PPC64) */
-/* PowerPC 32 definitions */
-#define TARGET_LONG_BITS 32
-
-#if defined(TARGET_PPCEMB)
-/* Specific definitions for PowerPC embedded */
-/* BookE have 36 bits physical address space */
-#if defined(CONFIG_USER_ONLY)
-/* It looks like a lot of Linux programs assume page size
- * is 4kB long. This is evil, but we have to deal with it...
- */
-#define TARGET_PAGE_BITS 12
-#else /* defined(CONFIG_USER_ONLY) */
-/* Pages can be 1 kB small */
-#define TARGET_PAGE_BITS 10
-#endif /* defined(CONFIG_USER_ONLY) */
-#else /* defined(TARGET_PPCEMB) */
-/* "standard" PowerPC 32 definitions */
-#define TARGET_PAGE_BITS 12
-#endif /* defined(TARGET_PPCEMB) */
-
-#define TARGET_PHYS_ADDR_SPACE_BITS 36
-#define TARGET_VIRT_ADDR_SPACE_BITS 32
-
-#endif /* defined (TARGET_PPC64) */
-
-#define CPUArchState struct CPUPPCState
-
-#include "exec/cpu-defs.h"
-#include "cpu-qom.h"
-#include "fpu/softfloat.h"
-
-#if defined (TARGET_PPC64)
-#define PPC_ELF_MACHINE EM_PPC64
-#else
-#define PPC_ELF_MACHINE EM_PPC
-#endif
-
-/*****************************************************************************/
-/* Exception vectors definitions */
-enum {
- POWERPC_EXCP_NONE = -1,
- /* The 64 first entries are used by the PowerPC embedded specification */
- POWERPC_EXCP_CRITICAL = 0, /* Critical input */
- POWERPC_EXCP_MCHECK = 1, /* Machine check exception */
- POWERPC_EXCP_DSI = 2, /* Data storage exception */
- POWERPC_EXCP_ISI = 3, /* Instruction storage exception */
- POWERPC_EXCP_EXTERNAL = 4, /* External input */
- POWERPC_EXCP_ALIGN = 5, /* Alignment exception */
- POWERPC_EXCP_PROGRAM = 6, /* Program exception */
- POWERPC_EXCP_FPU = 7, /* Floating-point unavailable exception */
- POWERPC_EXCP_SYSCALL = 8, /* System call exception */
- POWERPC_EXCP_APU = 9, /* Auxiliary processor unavailable */
- POWERPC_EXCP_DECR = 10, /* Decrementer exception */
- POWERPC_EXCP_FIT = 11, /* Fixed-interval timer interrupt */
- POWERPC_EXCP_WDT = 12, /* Watchdog timer interrupt */
- POWERPC_EXCP_DTLB = 13, /* Data TLB miss */
- POWERPC_EXCP_ITLB = 14, /* Instruction TLB miss */
- POWERPC_EXCP_DEBUG = 15, /* Debug interrupt */
- /* Vectors 16 to 31 are reserved */
- POWERPC_EXCP_SPEU = 32, /* SPE/embedded floating-point unavailable */
- POWERPC_EXCP_EFPDI = 33, /* Embedded floating-point data interrupt */
- POWERPC_EXCP_EFPRI = 34, /* Embedded floating-point round interrupt */
- POWERPC_EXCP_EPERFM = 35, /* Embedded performance monitor interrupt */
- POWERPC_EXCP_DOORI = 36, /* Embedded doorbell interrupt */
- POWERPC_EXCP_DOORCI = 37, /* Embedded doorbell critical interrupt */
- POWERPC_EXCP_GDOORI = 38, /* Embedded guest doorbell interrupt */
- POWERPC_EXCP_GDOORCI = 39, /* Embedded guest doorbell critical interrupt*/
- POWERPC_EXCP_HYPPRIV = 41, /* Embedded hypervisor priv instruction */
- /* Vectors 42 to 63 are reserved */
- /* Exceptions defined in the PowerPC server specification */
- /* Server doorbell variants */
-#define POWERPC_EXCP_SDOOR POWERPC_EXCP_GDOORI
-#define POWERPC_EXCP_SDOOR_HV POWERPC_EXCP_DOORI
- POWERPC_EXCP_RESET = 64, /* System reset exception */
- POWERPC_EXCP_DSEG = 65, /* Data segment exception */
- POWERPC_EXCP_ISEG = 66, /* Instruction segment exception */
- POWERPC_EXCP_HDECR = 67, /* Hypervisor decrementer exception */
- POWERPC_EXCP_TRACE = 68, /* Trace exception */
- POWERPC_EXCP_HDSI = 69, /* Hypervisor data storage exception */
- POWERPC_EXCP_HISI = 70, /* Hypervisor instruction storage exception */
- POWERPC_EXCP_HDSEG = 71, /* Hypervisor data segment exception */
- POWERPC_EXCP_HISEG = 72, /* Hypervisor instruction segment exception */
- POWERPC_EXCP_VPU = 73, /* Vector unavailable exception */
- /* 40x specific exceptions */
- POWERPC_EXCP_PIT = 74, /* Programmable interval timer interrupt */
- /* 601 specific exceptions */
- POWERPC_EXCP_IO = 75, /* IO error exception */
- POWERPC_EXCP_RUNM = 76, /* Run mode exception */
- /* 602 specific exceptions */
- POWERPC_EXCP_EMUL = 77, /* Emulation trap exception */
- /* 602/603 specific exceptions */
- POWERPC_EXCP_IFTLB = 78, /* Instruction fetch TLB miss */
- POWERPC_EXCP_DLTLB = 79, /* Data load TLB miss */
- POWERPC_EXCP_DSTLB = 80, /* Data store TLB miss */
- /* Exceptions available on most PowerPC */
- POWERPC_EXCP_FPA = 81, /* Floating-point assist exception */
- POWERPC_EXCP_DABR = 82, /* Data address breakpoint */
- POWERPC_EXCP_IABR = 83, /* Instruction address breakpoint */
- POWERPC_EXCP_SMI = 84, /* System management interrupt */
- POWERPC_EXCP_PERFM = 85, /* Embedded performance monitor interrupt */
- /* 7xx/74xx specific exceptions */
- POWERPC_EXCP_THERM = 86, /* Thermal interrupt */
- /* 74xx specific exceptions */
- POWERPC_EXCP_VPUA = 87, /* Vector assist exception */
- /* 970FX specific exceptions */
- POWERPC_EXCP_SOFTP = 88, /* Soft patch exception */
- POWERPC_EXCP_MAINT = 89, /* Maintenance exception */
- /* Freescale embedded cores specific exceptions */
- POWERPC_EXCP_MEXTBR = 90, /* Maskable external breakpoint */
- POWERPC_EXCP_NMEXTBR = 91, /* Non maskable external breakpoint */
- POWERPC_EXCP_ITLBE = 92, /* Instruction TLB error */
- POWERPC_EXCP_DTLBE = 93, /* Data TLB error */
- /* VSX Unavailable (Power ISA 2.06 and later) */
- POWERPC_EXCP_VSXU = 94, /* VSX Unavailable */
- POWERPC_EXCP_FU = 95, /* Facility Unavailable */
- /* Additional ISA 2.06 and later server exceptions */
- POWERPC_EXCP_HV_EMU = 96, /* HV emulation assistance */
- POWERPC_EXCP_HV_MAINT = 97, /* HMI */
- POWERPC_EXCP_HV_FU = 98, /* Hypervisor Facility unavailable */
- /* EOL */
- POWERPC_EXCP_NB = 99,
- /* QEMU exceptions: used internally during code translation */
- POWERPC_EXCP_STOP = 0x200, /* stop translation */
- POWERPC_EXCP_BRANCH = 0x201, /* branch instruction */
- /* QEMU exceptions: special cases we want to stop translation */
- POWERPC_EXCP_SYNC = 0x202, /* context synchronizing instruction */
- POWERPC_EXCP_SYSCALL_USER = 0x203, /* System call in user mode only */
- POWERPC_EXCP_STCX = 0x204 /* Conditional stores in user mode */
-};
-
-/* Exceptions error codes */
-enum {
- /* Exception subtypes for POWERPC_EXCP_ALIGN */
- POWERPC_EXCP_ALIGN_FP = 0x01, /* FP alignment exception */
- POWERPC_EXCP_ALIGN_LST = 0x02, /* Unaligned mult/extern load/store */
- POWERPC_EXCP_ALIGN_LE = 0x03, /* Multiple little-endian access */
- POWERPC_EXCP_ALIGN_PROT = 0x04, /* Access cross protection boundary */
- POWERPC_EXCP_ALIGN_BAT = 0x05, /* Access cross a BAT/seg boundary */
- POWERPC_EXCP_ALIGN_CACHE = 0x06, /* Impossible dcbz access */
- /* Exception subtypes for POWERPC_EXCP_PROGRAM */
- /* FP exceptions */
- POWERPC_EXCP_FP = 0x10,
- POWERPC_EXCP_FP_OX = 0x01, /* FP overflow */
- POWERPC_EXCP_FP_UX = 0x02, /* FP underflow */
- POWERPC_EXCP_FP_ZX = 0x03, /* FP divide by zero */
- POWERPC_EXCP_FP_XX = 0x04, /* FP inexact */
- POWERPC_EXCP_FP_VXSNAN = 0x05, /* FP invalid SNaN op */
- POWERPC_EXCP_FP_VXISI = 0x06, /* FP invalid infinite subtraction */
- POWERPC_EXCP_FP_VXIDI = 0x07, /* FP invalid infinite divide */
- POWERPC_EXCP_FP_VXZDZ = 0x08, /* FP invalid zero divide */
- POWERPC_EXCP_FP_VXIMZ = 0x09, /* FP invalid infinite * zero */
- POWERPC_EXCP_FP_VXVC = 0x0A, /* FP invalid compare */
- POWERPC_EXCP_FP_VXSOFT = 0x0B, /* FP invalid operation */
- POWERPC_EXCP_FP_VXSQRT = 0x0C, /* FP invalid square root */
- POWERPC_EXCP_FP_VXCVI = 0x0D, /* FP invalid integer conversion */
- /* Invalid instruction */
- POWERPC_EXCP_INVAL = 0x20,
- POWERPC_EXCP_INVAL_INVAL = 0x01, /* Invalid instruction */
- POWERPC_EXCP_INVAL_LSWX = 0x02, /* Invalid lswx instruction */
- POWERPC_EXCP_INVAL_SPR = 0x03, /* Invalid SPR access */
- POWERPC_EXCP_INVAL_FP = 0x04, /* Unimplemented mandatory fp instr */
- /* Privileged instruction */
- POWERPC_EXCP_PRIV = 0x30,
- POWERPC_EXCP_PRIV_OPC = 0x01, /* Privileged operation exception */
- POWERPC_EXCP_PRIV_REG = 0x02, /* Privileged register exception */
- /* Trap */
- POWERPC_EXCP_TRAP = 0x40,
-};
-
-#define PPC_INPUT(env) (env->bus_model)
-
-/*****************************************************************************/
-typedef struct opc_handler_t opc_handler_t;
-
-/*****************************************************************************/
-/* Types used to describe some PowerPC registers */
-typedef struct DisasContext DisasContext;
-typedef struct ppc_spr_t ppc_spr_t;
-typedef union ppc_avr_t ppc_avr_t;
-typedef union ppc_tlb_t ppc_tlb_t;
-
-/* SPR access micro-ops generations callbacks */
-struct ppc_spr_t {
- void (*uea_read)(DisasContext *ctx, int gpr_num, int spr_num);
- void (*uea_write)(DisasContext *ctx, int spr_num, int gpr_num);
-#if !defined(CONFIG_USER_ONLY)
- void (*oea_read)(DisasContext *ctx, int gpr_num, int spr_num);
- void (*oea_write)(DisasContext *ctx, int spr_num, int gpr_num);
- void (*hea_read)(DisasContext *ctx, int gpr_num, int spr_num);
- void (*hea_write)(DisasContext *ctx, int spr_num, int gpr_num);
-#endif
- const char *name;
- target_ulong default_value;
-#ifdef CONFIG_KVM
- /* We (ab)use the fact that all the SPRs will have ids for the
- * ONE_REG interface will have KVM_REG_PPC to use 0 as meaning,
- * don't sync this */
- uint64_t one_reg_id;
-#endif
-};
-
-/* Altivec registers (128 bits) */
-union ppc_avr_t {
- float32 f[4];
- uint8_t u8[16];
- uint16_t u16[8];
- uint32_t u32[4];
- int8_t s8[16];
- int16_t s16[8];
- int32_t s32[4];
- uint64_t u64[2];
- int64_t s64[2];
-#ifdef CONFIG_INT128
- __uint128_t u128;
-#endif
-};
-
-#if !defined(CONFIG_USER_ONLY)
-/* Software TLB cache */
-typedef struct ppc6xx_tlb_t ppc6xx_tlb_t;
-struct ppc6xx_tlb_t {
- target_ulong pte0;
- target_ulong pte1;
- target_ulong EPN;
-};
-
-typedef struct ppcemb_tlb_t ppcemb_tlb_t;
-struct ppcemb_tlb_t {
- uint64_t RPN;
- target_ulong EPN;
- target_ulong PID;
- target_ulong size;
- uint32_t prot;
- uint32_t attr; /* Storage attributes */
-};
-
-typedef struct ppcmas_tlb_t {
- uint32_t mas8;
- uint32_t mas1;
- uint64_t mas2;
- uint64_t mas7_3;
-} ppcmas_tlb_t;
-
-union ppc_tlb_t {
- ppc6xx_tlb_t *tlb6;
- ppcemb_tlb_t *tlbe;
- ppcmas_tlb_t *tlbm;
-};
-
-/* possible TLB variants */
-#define TLB_NONE 0
-#define TLB_6XX 1
-#define TLB_EMB 2
-#define TLB_MAS 3
-#endif
-
-#define SDR_32_HTABORG 0xFFFF0000UL
-#define SDR_32_HTABMASK 0x000001FFUL
-
-#if defined(TARGET_PPC64)
-#define SDR_64_HTABORG 0xFFFFFFFFFFFC0000ULL
-#define SDR_64_HTABSIZE 0x000000000000001FULL
-#endif /* defined(TARGET_PPC64 */
-
-typedef struct ppc_slb_t ppc_slb_t;
-struct ppc_slb_t {
- uint64_t esid;
- uint64_t vsid;
- const struct ppc_one_seg_page_size *sps;
-};
-
-#define MAX_SLB_ENTRIES 64
-#define SEGMENT_SHIFT_256M 28
-#define SEGMENT_MASK_256M (~((1ULL << SEGMENT_SHIFT_256M) - 1))
-
-#define SEGMENT_SHIFT_1T 40
-#define SEGMENT_MASK_1T (~((1ULL << SEGMENT_SHIFT_1T) - 1))
-
-
-/*****************************************************************************/
-/* Machine state register bits definition */
-#define MSR_SF 63 /* Sixty-four-bit mode hflags */
-#define MSR_TAG 62 /* Tag-active mode (POWERx ?) */
-#define MSR_ISF 61 /* Sixty-four-bit interrupt mode on 630 */
-#define MSR_SHV 60 /* hypervisor state hflags */
-#define MSR_TS0 34 /* Transactional state, 2 bits (Book3s) */
-#define MSR_TS1 33
-#define MSR_TM 32 /* Transactional Memory Available (Book3s) */
-#define MSR_CM 31 /* Computation mode for BookE hflags */
-#define MSR_ICM 30 /* Interrupt computation mode for BookE */
-#define MSR_THV 29 /* hypervisor state for 32 bits PowerPC hflags */
-#define MSR_GS 28 /* guest state for BookE */
-#define MSR_UCLE 26 /* User-mode cache lock enable for BookE */
-#define MSR_VR 25 /* altivec available x hflags */
-#define MSR_SPE 25 /* SPE enable for BookE x hflags */
-#define MSR_AP 23 /* Access privilege state on 602 hflags */
-#define MSR_VSX 23 /* Vector Scalar Extension (ISA 2.06 and later) x hflags */
-#define MSR_SA 22 /* Supervisor access mode on 602 hflags */
-#define MSR_KEY 19 /* key bit on 603e */
-#define MSR_POW 18 /* Power management */
-#define MSR_TGPR 17 /* TGPR usage on 602/603 x */
-#define MSR_CE 17 /* Critical interrupt enable on embedded PowerPC x */
-#define MSR_ILE 16 /* Interrupt little-endian mode */
-#define MSR_EE 15 /* External interrupt enable */
-#define MSR_PR 14 /* Problem state hflags */
-#define MSR_FP 13 /* Floating point available hflags */
-#define MSR_ME 12 /* Machine check interrupt enable */
-#define MSR_FE0 11 /* Floating point exception mode 0 hflags */
-#define MSR_SE 10 /* Single-step trace enable x hflags */
-#define MSR_DWE 10 /* Debug wait enable on 405 x */
-#define MSR_UBLE 10 /* User BTB lock enable on e500 x */
-#define MSR_BE 9 /* Branch trace enable x hflags */
-#define MSR_DE 9 /* Debug interrupts enable on embedded PowerPC x */
-#define MSR_FE1 8 /* Floating point exception mode 1 hflags */
-#define MSR_AL 7 /* AL bit on POWER */
-#define MSR_EP 6 /* Exception prefix on 601 */
-#define MSR_IR 5 /* Instruction relocate */
-#define MSR_DR 4 /* Data relocate */
-#define MSR_IS 5 /* Instruction address space (BookE) */
-#define MSR_DS 4 /* Data address space (BookE) */
-#define MSR_PE 3 /* Protection enable on 403 */
-#define MSR_PX 2 /* Protection exclusive on 403 x */
-#define MSR_PMM 2 /* Performance monitor mark on POWER x */
-#define MSR_RI 1 /* Recoverable interrupt 1 */
-#define MSR_LE 0 /* Little-endian mode 1 hflags */
-
-/* LPCR bits */
-#define LPCR_VPM0 (1ull << (63 - 0))
-#define LPCR_VPM1 (1ull << (63 - 1))
-#define LPCR_ISL (1ull << (63 - 2))
-#define LPCR_KBV (1ull << (63 - 3))
-#define LPCR_DPFD_SHIFT (63 - 11)
-#define LPCR_DPFD (0x3ull << LPCR_DPFD_SHIFT)
-#define LPCR_VRMASD_SHIFT (63 - 16)
-#define LPCR_VRMASD (0x1full << LPCR_VRMASD_SHIFT)
-#define LPCR_RMLS_SHIFT (63 - 37)
-#define LPCR_RMLS (0xfull << LPCR_RMLS_SHIFT)
-#define LPCR_ILE (1ull << (63 - 38))
-#define LPCR_AIL_SHIFT (63 - 40) /* Alternate interrupt location */
-#define LPCR_AIL (3ull << LPCR_AIL_SHIFT)
-#define LPCR_ONL (1ull << (63 - 45))
-#define LPCR_P7_PECE0 (1ull << (63 - 49))
-#define LPCR_P7_PECE1 (1ull << (63 - 50))
-#define LPCR_P7_PECE2 (1ull << (63 - 51))
-#define LPCR_P8_PECE0 (1ull << (63 - 47))
-#define LPCR_P8_PECE1 (1ull << (63 - 48))
-#define LPCR_P8_PECE2 (1ull << (63 - 49))
-#define LPCR_P8_PECE3 (1ull << (63 - 50))
-#define LPCR_P8_PECE4 (1ull << (63 - 51))
-#define LPCR_MER (1ull << (63 - 52))
-#define LPCR_TC (1ull << (63 - 54))
-#define LPCR_LPES0 (1ull << (63 - 60))
-#define LPCR_LPES1 (1ull << (63 - 61))
-#define LPCR_RMI (1ull << (63 - 62))
-#define LPCR_HDICE (1ull << (63 - 63))
-
-#define msr_sf ((env->msr >> MSR_SF) & 1)
-#define msr_isf ((env->msr >> MSR_ISF) & 1)
-#define msr_shv ((env->msr >> MSR_SHV) & 1)
-#define msr_cm ((env->msr >> MSR_CM) & 1)
-#define msr_icm ((env->msr >> MSR_ICM) & 1)
-#define msr_thv ((env->msr >> MSR_THV) & 1)
-#define msr_gs ((env->msr >> MSR_GS) & 1)
-#define msr_ucle ((env->msr >> MSR_UCLE) & 1)
-#define msr_vr ((env->msr >> MSR_VR) & 1)
-#define msr_spe ((env->msr >> MSR_SPE) & 1)
-#define msr_ap ((env->msr >> MSR_AP) & 1)
-#define msr_vsx ((env->msr >> MSR_VSX) & 1)
-#define msr_sa ((env->msr >> MSR_SA) & 1)
-#define msr_key ((env->msr >> MSR_KEY) & 1)
-#define msr_pow ((env->msr >> MSR_POW) & 1)
-#define msr_tgpr ((env->msr >> MSR_TGPR) & 1)
-#define msr_ce ((env->msr >> MSR_CE) & 1)
-#define msr_ile ((env->msr >> MSR_ILE) & 1)
-#define msr_ee ((env->msr >> MSR_EE) & 1)
-#define msr_pr ((env->msr >> MSR_PR) & 1)
-#define msr_fp ((env->msr >> MSR_FP) & 1)
-#define msr_me ((env->msr >> MSR_ME) & 1)
-#define msr_fe0 ((env->msr >> MSR_FE0) & 1)
-#define msr_se ((env->msr >> MSR_SE) & 1)
-#define msr_dwe ((env->msr >> MSR_DWE) & 1)
-#define msr_uble ((env->msr >> MSR_UBLE) & 1)
-#define msr_be ((env->msr >> MSR_BE) & 1)
-#define msr_de ((env->msr >> MSR_DE) & 1)
-#define msr_fe1 ((env->msr >> MSR_FE1) & 1)
-#define msr_al ((env->msr >> MSR_AL) & 1)
-#define msr_ep ((env->msr >> MSR_EP) & 1)
-#define msr_ir ((env->msr >> MSR_IR) & 1)
-#define msr_dr ((env->msr >> MSR_DR) & 1)
-#define msr_is ((env->msr >> MSR_IS) & 1)
-#define msr_ds ((env->msr >> MSR_DS) & 1)
-#define msr_pe ((env->msr >> MSR_PE) & 1)
-#define msr_px ((env->msr >> MSR_PX) & 1)
-#define msr_pmm ((env->msr >> MSR_PMM) & 1)
-#define msr_ri ((env->msr >> MSR_RI) & 1)
-#define msr_le ((env->msr >> MSR_LE) & 1)
-#define msr_ts ((env->msr >> MSR_TS1) & 3)
-#define msr_tm ((env->msr >> MSR_TM) & 1)
-
-/* Hypervisor bit is more specific */
-#if defined(TARGET_PPC64)
-#define MSR_HVB (1ULL << MSR_SHV)
-#define msr_hv msr_shv
-#else
-#if defined(PPC_EMULATE_32BITS_HYPV)
-#define MSR_HVB (1ULL << MSR_THV)
-#define msr_hv msr_thv
-#else
-#define MSR_HVB (0ULL)
-#define msr_hv (0)
-#endif
-#endif
-
-/* Facility Status and Control (FSCR) bits */
-#define FSCR_EBB (63 - 56) /* Event-Based Branch Facility */
-#define FSCR_TAR (63 - 55) /* Target Address Register */
-/* Interrupt cause mask and position in FSCR. HFSCR has the same format */
-#define FSCR_IC_MASK (0xFFULL)
-#define FSCR_IC_POS (63 - 7)
-#define FSCR_IC_DSCR_SPR3 2
-#define FSCR_IC_PMU 3
-#define FSCR_IC_BHRB 4
-#define FSCR_IC_TM 5
-#define FSCR_IC_EBB 7
-#define FSCR_IC_TAR 8
-
-/* Exception state register bits definition */
-#define ESR_PIL (1 << (63 - 36)) /* Illegal Instruction */
-#define ESR_PPR (1 << (63 - 37)) /* Privileged Instruction */
-#define ESR_PTR (1 << (63 - 38)) /* Trap */
-#define ESR_FP (1 << (63 - 39)) /* Floating-Point Operation */
-#define ESR_ST (1 << (63 - 40)) /* Store Operation */
-#define ESR_AP (1 << (63 - 44)) /* Auxiliary Processor Operation */
-#define ESR_PUO (1 << (63 - 45)) /* Unimplemented Operation */
-#define ESR_BO (1 << (63 - 46)) /* Byte Ordering */
-#define ESR_PIE (1 << (63 - 47)) /* Imprecise exception */
-#define ESR_DATA (1 << (63 - 53)) /* Data Access (Embedded page table) */
-#define ESR_TLBI (1 << (63 - 54)) /* TLB Ineligible (Embedded page table) */
-#define ESR_PT (1 << (63 - 55)) /* Page Table (Embedded page table) */
-#define ESR_SPV (1 << (63 - 56)) /* SPE/VMX operation */
-#define ESR_EPID (1 << (63 - 57)) /* External Process ID operation */
-#define ESR_VLEMI (1 << (63 - 58)) /* VLE operation */
-#define ESR_MIF (1 << (63 - 62)) /* Misaligned instruction (VLE) */
-
-/* Transaction EXception And Summary Register bits */
-#define TEXASR_FAILURE_PERSISTENT (63 - 7)
-#define TEXASR_DISALLOWED (63 - 8)
-#define TEXASR_NESTING_OVERFLOW (63 - 9)
-#define TEXASR_FOOTPRINT_OVERFLOW (63 - 10)
-#define TEXASR_SELF_INDUCED_CONFLICT (63 - 11)
-#define TEXASR_NON_TRANSACTIONAL_CONFLICT (63 - 12)
-#define TEXASR_TRANSACTION_CONFLICT (63 - 13)
-#define TEXASR_TRANSLATION_INVALIDATION_CONFLICT (63 - 14)
-#define TEXASR_IMPLEMENTATION_SPECIFIC (63 - 15)
-#define TEXASR_INSTRUCTION_FETCH_CONFLICT (63 - 16)
-#define TEXASR_ABORT (63 - 31)
-#define TEXASR_SUSPENDED (63 - 32)
-#define TEXASR_PRIVILEGE_HV (63 - 34)
-#define TEXASR_PRIVILEGE_PR (63 - 35)
-#define TEXASR_FAILURE_SUMMARY (63 - 36)
-#define TEXASR_TFIAR_EXACT (63 - 37)
-#define TEXASR_ROT (63 - 38)
-#define TEXASR_TRANSACTION_LEVEL (63 - 52) /* 12 bits */
-
-enum {
- POWERPC_FLAG_NONE = 0x00000000,
- /* Flag for MSR bit 25 signification (VRE/SPE) */
- POWERPC_FLAG_SPE = 0x00000001,
- POWERPC_FLAG_VRE = 0x00000002,
- /* Flag for MSR bit 17 signification (TGPR/CE) */
- POWERPC_FLAG_TGPR = 0x00000004,
- POWERPC_FLAG_CE = 0x00000008,
- /* Flag for MSR bit 10 signification (SE/DWE/UBLE) */
- POWERPC_FLAG_SE = 0x00000010,
- POWERPC_FLAG_DWE = 0x00000020,
- POWERPC_FLAG_UBLE = 0x00000040,
- /* Flag for MSR bit 9 signification (BE/DE) */
- POWERPC_FLAG_BE = 0x00000080,
- POWERPC_FLAG_DE = 0x00000100,
- /* Flag for MSR bit 2 signification (PX/PMM) */
- POWERPC_FLAG_PX = 0x00000200,
- POWERPC_FLAG_PMM = 0x00000400,
- /* Flag for special features */
- /* Decrementer clock: RTC clock (POWER, 601) or bus clock */
- POWERPC_FLAG_RTC_CLK = 0x00010000,
- POWERPC_FLAG_BUS_CLK = 0x00020000,
- /* Has CFAR */
- POWERPC_FLAG_CFAR = 0x00040000,
- /* Has VSX */
- POWERPC_FLAG_VSX = 0x00080000,
- /* Has Transaction Memory (ISA 2.07) */
- POWERPC_FLAG_TM = 0x00100000,
-};
-
-/*****************************************************************************/
-/* Floating point status and control register */
-#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 undeflow 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_RN 0 /* Floating-point rounding control */
-#define fpscr_fex (((env->fpscr) >> FPSCR_FEX) & 0x1)
-#define fpscr_vx (((env->fpscr) >> FPSCR_VX) & 0x1)
-#define fpscr_ox (((env->fpscr) >> FPSCR_OX) & 0x1)
-#define fpscr_ux (((env->fpscr) >> FPSCR_UX) & 0x1)
-#define fpscr_zx (((env->fpscr) >> FPSCR_ZX) & 0x1)
-#define fpscr_xx (((env->fpscr) >> FPSCR_XX) & 0x1)
-#define fpscr_vxsnan (((env->fpscr) >> FPSCR_VXSNAN) & 0x1)
-#define fpscr_vxisi (((env->fpscr) >> FPSCR_VXISI) & 0x1)
-#define fpscr_vxidi (((env->fpscr) >> FPSCR_VXIDI) & 0x1)
-#define fpscr_vxzdz (((env->fpscr) >> FPSCR_VXZDZ) & 0x1)
-#define fpscr_vximz (((env->fpscr) >> FPSCR_VXIMZ) & 0x1)
-#define fpscr_vxvc (((env->fpscr) >> FPSCR_VXVC) & 0x1)
-#define fpscr_fpcc (((env->fpscr) >> FPSCR_FPCC) & 0xF)
-#define fpscr_vxsoft (((env->fpscr) >> FPSCR_VXSOFT) & 0x1)
-#define fpscr_vxsqrt (((env->fpscr) >> FPSCR_VXSQRT) & 0x1)
-#define fpscr_vxcvi (((env->fpscr) >> FPSCR_VXCVI) & 0x1)
-#define fpscr_ve (((env->fpscr) >> FPSCR_VE) & 0x1)
-#define fpscr_oe (((env->fpscr) >> FPSCR_OE) & 0x1)
-#define fpscr_ue (((env->fpscr) >> FPSCR_UE) & 0x1)
-#define fpscr_ze (((env->fpscr) >> FPSCR_ZE) & 0x1)
-#define fpscr_xe (((env->fpscr) >> FPSCR_XE) & 0x1)
-#define fpscr_ni (((env->fpscr) >> FPSCR_NI) & 0x1)
-#define fpscr_rn (((env->fpscr) >> FPSCR_RN) & 0x3)
-/* Invalid operation exception summary */
-#define fpscr_ix ((env->fpscr) & ((1 << FPSCR_VXSNAN) | (1 << FPSCR_VXISI) | \
- (1 << FPSCR_VXIDI) | (1 << FPSCR_VXZDZ) | \
- (1 << FPSCR_VXIMZ) | (1 << FPSCR_VXVC) | \
- (1 << FPSCR_VXSOFT) | (1 << FPSCR_VXSQRT) | \
- (1 << FPSCR_VXCVI)))
-/* exception summary */
-#define fpscr_ex (((env->fpscr) >> FPSCR_XX) & 0x1F)
-/* enabled exception summary */
-#define fpscr_eex (((env->fpscr) >> FPSCR_XX) & ((env->fpscr) >> FPSCR_XE) & \
- 0x1F)
-
-#define FP_FX (1ull << FPSCR_FX)
-#define FP_FEX (1ull << FPSCR_FEX)
-#define FP_VX (1ull << FPSCR_VX)
-#define FP_OX (1ull << FPSCR_OX)
-#define FP_UX (1ull << FPSCR_UX)
-#define FP_ZX (1ull << FPSCR_ZX)
-#define FP_XX (1ull << FPSCR_XX)
-#define FP_VXSNAN (1ull << FPSCR_VXSNAN)
-#define FP_VXISI (1ull << FPSCR_VXISI)
-#define FP_VXIDI (1ull << FPSCR_VXIDI)
-#define FP_VXZDZ (1ull << FPSCR_VXZDZ)
-#define FP_VXIMZ (1ull << FPSCR_VXIMZ)
-#define FP_VXVC (1ull << FPSCR_VXVC)
-#define FP_FR (1ull << FSPCR_FR)
-#define FP_FI (1ull << FPSCR_FI)
-#define FP_C (1ull << FPSCR_C)
-#define FP_FL (1ull << FPSCR_FL)
-#define FP_FG (1ull << FPSCR_FG)
-#define FP_FE (1ull << FPSCR_FE)
-#define FP_FU (1ull << FPSCR_FU)
-#define FP_FPCC (FP_FL | FP_FG | FP_FE | FP_FU)
-#define FP_FPRF (FP_C | FP_FL | FP_FG | FP_FE | FP_FU)
-#define FP_VXSOFT (1ull << FPSCR_VXSOFT)
-#define FP_VXSQRT (1ull << FPSCR_VXSQRT)
-#define FP_VXCVI (1ull << FPSCR_VXCVI)
-#define FP_VE (1ull << FPSCR_VE)
-#define FP_OE (1ull << FPSCR_OE)
-#define FP_UE (1ull << FPSCR_UE)
-#define FP_ZE (1ull << FPSCR_ZE)
-#define FP_XE (1ull << FPSCR_XE)
-#define FP_NI (1ull << FPSCR_NI)
-#define FP_RN1 (1ull << FPSCR_RN1)
-#define FP_RN (1ull << FPSCR_RN)
-
-/* the exception bits which can be cleared by mcrfs - includes FX */
-#define FP_EX_CLEAR_BITS (FP_FX | FP_OX | FP_UX | FP_ZX | \
- FP_XX | FP_VXSNAN | FP_VXISI | FP_VXIDI | \
- FP_VXZDZ | FP_VXIMZ | FP_VXVC | FP_VXSOFT | \
- FP_VXSQRT | FP_VXCVI)
-
-/*****************************************************************************/
-/* Vector status and control register */
-#define VSCR_NJ 16 /* Vector non-java */
-#define VSCR_SAT 0 /* Vector saturation */
-#define vscr_nj (((env->vscr) >> VSCR_NJ) & 0x1)
-#define vscr_sat (((env->vscr) >> VSCR_SAT) & 0x1)
-
-/*****************************************************************************/
-/* BookE e500 MMU registers */
-
-#define MAS0_NV_SHIFT 0
-#define MAS0_NV_MASK (0xfff << MAS0_NV_SHIFT)
-
-#define MAS0_WQ_SHIFT 12
-#define MAS0_WQ_MASK (3 << MAS0_WQ_SHIFT)
-/* Write TLB entry regardless of reservation */
-#define MAS0_WQ_ALWAYS (0 << MAS0_WQ_SHIFT)
-/* Write TLB entry only already in use */
-#define MAS0_WQ_COND (1 << MAS0_WQ_SHIFT)
-/* Clear TLB entry */
-#define MAS0_WQ_CLR_RSRV (2 << MAS0_WQ_SHIFT)
-
-#define MAS0_HES_SHIFT 14
-#define MAS0_HES (1 << MAS0_HES_SHIFT)
-
-#define MAS0_ESEL_SHIFT 16
-#define MAS0_ESEL_MASK (0xfff << MAS0_ESEL_SHIFT)
-
-#define MAS0_TLBSEL_SHIFT 28
-#define MAS0_TLBSEL_MASK (3 << MAS0_TLBSEL_SHIFT)
-#define MAS0_TLBSEL_TLB0 (0 << MAS0_TLBSEL_SHIFT)
-#define MAS0_TLBSEL_TLB1 (1 << MAS0_TLBSEL_SHIFT)
-#define MAS0_TLBSEL_TLB2 (2 << MAS0_TLBSEL_SHIFT)
-#define MAS0_TLBSEL_TLB3 (3 << MAS0_TLBSEL_SHIFT)
-
-#define MAS0_ATSEL_SHIFT 31
-#define MAS0_ATSEL (1 << MAS0_ATSEL_SHIFT)
-#define MAS0_ATSEL_TLB 0
-#define MAS0_ATSEL_LRAT MAS0_ATSEL
-
-#define MAS1_TSIZE_SHIFT 7
-#define MAS1_TSIZE_MASK (0x1f << MAS1_TSIZE_SHIFT)
-
-#define MAS1_TS_SHIFT 12
-#define MAS1_TS (1 << MAS1_TS_SHIFT)
-
-#define MAS1_IND_SHIFT 13
-#define MAS1_IND (1 << MAS1_IND_SHIFT)
-
-#define MAS1_TID_SHIFT 16
-#define MAS1_TID_MASK (0x3fff << MAS1_TID_SHIFT)
-
-#define MAS1_IPROT_SHIFT 30
-#define MAS1_IPROT (1 << MAS1_IPROT_SHIFT)
-
-#define MAS1_VALID_SHIFT 31
-#define MAS1_VALID 0x80000000
-
-#define MAS2_EPN_SHIFT 12
-#define MAS2_EPN_MASK (~0ULL << MAS2_EPN_SHIFT)
-
-#define MAS2_ACM_SHIFT 6
-#define MAS2_ACM (1 << MAS2_ACM_SHIFT)
-
-#define MAS2_VLE_SHIFT 5
-#define MAS2_VLE (1 << MAS2_VLE_SHIFT)
-
-#define MAS2_W_SHIFT 4
-#define MAS2_W (1 << MAS2_W_SHIFT)
-
-#define MAS2_I_SHIFT 3
-#define MAS2_I (1 << MAS2_I_SHIFT)
-
-#define MAS2_M_SHIFT 2
-#define MAS2_M (1 << MAS2_M_SHIFT)
-
-#define MAS2_G_SHIFT 1
-#define MAS2_G (1 << MAS2_G_SHIFT)
-
-#define MAS2_E_SHIFT 0
-#define MAS2_E (1 << MAS2_E_SHIFT)
-
-#define MAS3_RPN_SHIFT 12
-#define MAS3_RPN_MASK (0xfffff << MAS3_RPN_SHIFT)
-
-#define MAS3_U0 0x00000200
-#define MAS3_U1 0x00000100
-#define MAS3_U2 0x00000080
-#define MAS3_U3 0x00000040
-#define MAS3_UX 0x00000020
-#define MAS3_SX 0x00000010
-#define MAS3_UW 0x00000008
-#define MAS3_SW 0x00000004
-#define MAS3_UR 0x00000002
-#define MAS3_SR 0x00000001
-#define MAS3_SPSIZE_SHIFT 1
-#define MAS3_SPSIZE_MASK (0x3e << MAS3_SPSIZE_SHIFT)
-
-#define MAS4_TLBSELD_SHIFT MAS0_TLBSEL_SHIFT
-#define MAS4_TLBSELD_MASK MAS0_TLBSEL_MASK
-#define MAS4_TIDSELD_MASK 0x00030000
-#define MAS4_TIDSELD_PID0 0x00000000
-#define MAS4_TIDSELD_PID1 0x00010000
-#define MAS4_TIDSELD_PID2 0x00020000
-#define MAS4_TIDSELD_PIDZ 0x00030000
-#define MAS4_INDD 0x00008000 /* Default IND */
-#define MAS4_TSIZED_SHIFT MAS1_TSIZE_SHIFT
-#define MAS4_TSIZED_MASK MAS1_TSIZE_MASK
-#define MAS4_ACMD 0x00000040
-#define MAS4_VLED 0x00000020
-#define MAS4_WD 0x00000010
-#define MAS4_ID 0x00000008
-#define MAS4_MD 0x00000004
-#define MAS4_GD 0x00000002
-#define MAS4_ED 0x00000001
-#define MAS4_WIMGED_MASK 0x0000001f /* Default WIMGE */
-#define MAS4_WIMGED_SHIFT 0
-
-#define MAS5_SGS 0x80000000
-#define MAS5_SLPID_MASK 0x00000fff
-
-#define MAS6_SPID0 0x3fff0000
-#define MAS6_SPID1 0x00007ffe
-#define MAS6_ISIZE(x) MAS1_TSIZE(x)
-#define MAS6_SAS 0x00000001
-#define MAS6_SPID MAS6_SPID0
-#define MAS6_SIND 0x00000002 /* Indirect page */
-#define MAS6_SIND_SHIFT 1
-#define MAS6_SPID_MASK 0x3fff0000
-#define MAS6_SPID_SHIFT 16
-#define MAS6_ISIZE_MASK 0x00000f80
-#define MAS6_ISIZE_SHIFT 7
-
-#define MAS7_RPN 0xffffffff
-
-#define MAS8_TGS 0x80000000
-#define MAS8_VF 0x40000000
-#define MAS8_TLBPID 0x00000fff
-
-/* Bit definitions for MMUCFG */
-#define MMUCFG_MAVN 0x00000003 /* MMU Architecture Version Number */
-#define MMUCFG_MAVN_V1 0x00000000 /* v1.0 */
-#define MMUCFG_MAVN_V2 0x00000001 /* v2.0 */
-#define MMUCFG_NTLBS 0x0000000c /* Number of TLBs */
-#define MMUCFG_PIDSIZE 0x000007c0 /* PID Reg Size */
-#define MMUCFG_TWC 0x00008000 /* TLB Write Conditional (v2.0) */
-#define MMUCFG_LRAT 0x00010000 /* LRAT Supported (v2.0) */
-#define MMUCFG_RASIZE 0x00fe0000 /* Real Addr Size */
-#define MMUCFG_LPIDSIZE 0x0f000000 /* LPID Reg Size */
-
-/* Bit definitions for MMUCSR0 */
-#define MMUCSR0_TLB1FI 0x00000002 /* TLB1 Flash invalidate */
-#define MMUCSR0_TLB0FI 0x00000004 /* TLB0 Flash invalidate */
-#define MMUCSR0_TLB2FI 0x00000040 /* TLB2 Flash invalidate */
-#define MMUCSR0_TLB3FI 0x00000020 /* TLB3 Flash invalidate */
-#define MMUCSR0_TLBFI (MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \
- MMUCSR0_TLB2FI | MMUCSR0_TLB3FI)
-#define MMUCSR0_TLB0PS 0x00000780 /* TLB0 Page Size */
-#define MMUCSR0_TLB1PS 0x00007800 /* TLB1 Page Size */
-#define MMUCSR0_TLB2PS 0x00078000 /* TLB2 Page Size */
-#define MMUCSR0_TLB3PS 0x00780000 /* TLB3 Page Size */
-
-/* TLBnCFG encoding */
-#define TLBnCFG_N_ENTRY 0x00000fff /* number of entries */
-#define TLBnCFG_HES 0x00002000 /* HW select supported */
-#define TLBnCFG_AVAIL 0x00004000 /* variable page size */
-#define TLBnCFG_IPROT 0x00008000 /* IPROT supported */
-#define TLBnCFG_GTWE 0x00010000 /* Guest can write */
-#define TLBnCFG_IND 0x00020000 /* IND entries supported */
-#define TLBnCFG_PT 0x00040000 /* Can load from page table */
-#define TLBnCFG_MINSIZE 0x00f00000 /* Minimum Page Size (v1.0) */
-#define TLBnCFG_MINSIZE_SHIFT 20
-#define TLBnCFG_MAXSIZE 0x000f0000 /* Maximum Page Size (v1.0) */
-#define TLBnCFG_MAXSIZE_SHIFT 16
-#define TLBnCFG_ASSOC 0xff000000 /* Associativity */
-#define TLBnCFG_ASSOC_SHIFT 24
-
-/* TLBnPS encoding */
-#define TLBnPS_4K 0x00000004
-#define TLBnPS_8K 0x00000008
-#define TLBnPS_16K 0x00000010
-#define TLBnPS_32K 0x00000020
-#define TLBnPS_64K 0x00000040
-#define TLBnPS_128K 0x00000080
-#define TLBnPS_256K 0x00000100
-#define TLBnPS_512K 0x00000200
-#define TLBnPS_1M 0x00000400
-#define TLBnPS_2M 0x00000800
-#define TLBnPS_4M 0x00001000
-#define TLBnPS_8M 0x00002000
-#define TLBnPS_16M 0x00004000
-#define TLBnPS_32M 0x00008000
-#define TLBnPS_64M 0x00010000
-#define TLBnPS_128M 0x00020000
-#define TLBnPS_256M 0x00040000
-#define TLBnPS_512M 0x00080000
-#define TLBnPS_1G 0x00100000
-#define TLBnPS_2G 0x00200000
-#define TLBnPS_4G 0x00400000
-#define TLBnPS_8G 0x00800000
-#define TLBnPS_16G 0x01000000
-#define TLBnPS_32G 0x02000000
-#define TLBnPS_64G 0x04000000
-#define TLBnPS_128G 0x08000000
-#define TLBnPS_256G 0x10000000
-
-/* tlbilx action encoding */
-#define TLBILX_T_ALL 0
-#define TLBILX_T_TID 1
-#define TLBILX_T_FULLMATCH 3
-#define TLBILX_T_CLASS0 4
-#define TLBILX_T_CLASS1 5
-#define TLBILX_T_CLASS2 6
-#define TLBILX_T_CLASS3 7
-
-/* BookE 2.06 helper defines */
-
-#define BOOKE206_FLUSH_TLB0 (1 << 0)
-#define BOOKE206_FLUSH_TLB1 (1 << 1)
-#define BOOKE206_FLUSH_TLB2 (1 << 2)
-#define BOOKE206_FLUSH_TLB3 (1 << 3)
-
-/* number of possible TLBs */
-#define BOOKE206_MAX_TLBN 4
-
-/*****************************************************************************/
-/* Embedded.Processor Control */
-
-#define DBELL_TYPE_SHIFT 27
-#define DBELL_TYPE_MASK (0x1f << DBELL_TYPE_SHIFT)
-#define DBELL_TYPE_DBELL (0x00 << DBELL_TYPE_SHIFT)
-#define DBELL_TYPE_DBELL_CRIT (0x01 << DBELL_TYPE_SHIFT)
-#define DBELL_TYPE_G_DBELL (0x02 << DBELL_TYPE_SHIFT)
-#define DBELL_TYPE_G_DBELL_CRIT (0x03 << DBELL_TYPE_SHIFT)
-#define DBELL_TYPE_G_DBELL_MC (0x04 << DBELL_TYPE_SHIFT)
-
-#define DBELL_BRDCAST (1 << 26)
-#define DBELL_LPIDTAG_SHIFT 14
-#define DBELL_LPIDTAG_MASK (0xfff << DBELL_LPIDTAG_SHIFT)
-#define DBELL_PIRTAG_MASK 0x3fff
-
-/*****************************************************************************/
-/* Segment page size information, used by recent hash MMUs
- * The format of this structure mirrors kvm_ppc_smmu_info
- */
-
-#define PPC_PAGE_SIZES_MAX_SZ 8
-
-struct ppc_one_page_size {
- uint32_t page_shift; /* Page shift (or 0) */
- uint32_t pte_enc; /* Encoding in the HPTE (>>12) */
-};
-
-struct ppc_one_seg_page_size {
- uint32_t page_shift; /* Base page shift of segment (or 0) */
- uint32_t slb_enc; /* SLB encoding for BookS */
- struct ppc_one_page_size enc[PPC_PAGE_SIZES_MAX_SZ];
-};
-
-struct ppc_segment_page_sizes {
- struct ppc_one_seg_page_size sps[PPC_PAGE_SIZES_MAX_SZ];
-};
-
-
-/*****************************************************************************/
-/* The whole PowerPC CPU context */
-#define NB_MMU_MODES 8
-
-#define PPC_CPU_OPCODES_LEN 0x40
-#define PPC_CPU_INDIRECT_OPCODES_LEN 0x20
-
-struct CPUPPCState {
- /* First are the most commonly used resources
- * during translated code execution
- */
- /* general purpose registers */
- target_ulong gpr[32];
- /* Storage for GPR MSB, used by the SPE extension */
- target_ulong gprh[32];
- /* LR */
- target_ulong lr;
- /* CTR */
- target_ulong ctr;
- /* condition register */
- uint32_t crf[8];
-#if defined(TARGET_PPC64)
- /* CFAR */
- target_ulong cfar;
-#endif
- /* XER (with SO, OV, CA split out) */
- target_ulong xer;
- target_ulong so;
- target_ulong ov;
- target_ulong ca;
- /* Reservation address */
- target_ulong reserve_addr;
- /* Reservation value */
- target_ulong reserve_val;
- target_ulong reserve_val2;
- /* Reservation store address */
- target_ulong reserve_ea;
- /* Reserved store source register and size */
- target_ulong reserve_info;
-
- /* Those ones are used in supervisor mode only */
- /* machine state register */
- target_ulong msr;
- /* temporary general purpose registers */
- target_ulong tgpr[4]; /* Used to speed-up TLB assist handlers */
-
- /* Floating point execution context */
- float_status fp_status;
- /* floating point registers */
- float64 fpr[32];
- /* floating point status and control register */
- target_ulong fpscr;
-
- /* Next instruction pointer */
- target_ulong nip;
-
- int access_type; /* when a memory exception occurs, the access
- type is stored here */
-
- CPU_COMMON
-
- /* MMU context - only relevant for full system emulation */
-#if !defined(CONFIG_USER_ONLY)
-#if defined(TARGET_PPC64)
- /* PowerPC 64 SLB area */
- ppc_slb_t slb[MAX_SLB_ENTRIES];
- int32_t slb_nr;
- /* tcg TLB needs flush (deferred slb inval instruction typically) */
-#endif
- /* segment registers */
- hwaddr htab_base;
- /* mask used to normalize hash value to PTEG index */
- hwaddr htab_mask;
- target_ulong sr[32];
- /* externally stored hash table */
- uint8_t *external_htab;
- /* BATs */
- uint32_t nb_BATs;
- target_ulong DBAT[2][8];
- target_ulong IBAT[2][8];
- /* PowerPC TLB registers (for 4xx, e500 and 60x software driven TLBs) */
- int32_t nb_tlb; /* Total number of TLB */
- int tlb_per_way; /* Speed-up helper: used to avoid divisions at run time */
- int nb_ways; /* Number of ways in the TLB set */
- int last_way; /* Last used way used to allocate TLB in a LRU way */
- int id_tlbs; /* If 1, MMU has separated TLBs for instructions & data */
- int nb_pids; /* Number of available PID registers */
- int tlb_type; /* Type of TLB we're dealing with */
- ppc_tlb_t tlb; /* TLB is optional. Allocate them only if needed */
- /* 403 dedicated access protection registers */
- target_ulong pb[4];
- bool tlb_dirty; /* Set to non-zero when modifying TLB */
- bool kvm_sw_tlb; /* non-zero if KVM SW TLB API is active */
- uint32_t tlb_need_flush; /* Delayed flush needed */
-#define TLB_NEED_LOCAL_FLUSH 0x1
-#define TLB_NEED_GLOBAL_FLUSH 0x2
-#endif
-
- /* Other registers */
- /* Special purpose registers */
- target_ulong spr[1024];
- ppc_spr_t spr_cb[1024];
- /* Altivec registers */
- ppc_avr_t avr[32];
- uint32_t vscr;
- /* VSX registers */
- uint64_t vsr[32];
- /* SPE registers */
- uint64_t spe_acc;
- uint32_t spe_fscr;
- /* SPE and Altivec can share a status since they will never be used
- * simultaneously */
- float_status vec_status;
-
- /* Internal devices resources */
- /* Time base and decrementer */
- ppc_tb_t *tb_env;
- /* Device control registers */
- ppc_dcr_t *dcr_env;
-
- int dcache_line_size;
- int icache_line_size;
-
- /* Those resources are used during exception processing */
- /* CPU model definition */
- target_ulong msr_mask;
- powerpc_mmu_t mmu_model;
- powerpc_excp_t excp_model;
- powerpc_input_t bus_model;
- int bfd_mach;
- uint32_t flags;
- uint64_t insns_flags;
- uint64_t insns_flags2;
-#if defined(TARGET_PPC64)
- struct ppc_segment_page_sizes sps;
- ppc_slb_t vrma_slb;
- target_ulong rmls;
- bool ci_large_pages;
-#endif
-
-#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
- uint64_t vpa_addr;
- uint64_t slb_shadow_addr, slb_shadow_size;
- uint64_t dtl_addr, dtl_size;
-#endif /* TARGET_PPC64 */
-
- int error_code;
- uint32_t pending_interrupts;
-#if !defined(CONFIG_USER_ONLY)
- /* This is the IRQ controller, which is implementation dependent
- * and only relevant when emulating a complete machine.
- */
- uint32_t irq_input_state;
- void **irq_inputs;
- /* Exception vectors */
- target_ulong excp_vectors[POWERPC_EXCP_NB];
- target_ulong excp_prefix;
- target_ulong ivor_mask;
- target_ulong ivpr_mask;
- target_ulong hreset_vector;
- hwaddr mpic_iack;
- /* true when the external proxy facility mode is enabled */
- bool mpic_proxy;
- /* set when the processor has an HV mode, thus HV priv
- * instructions and SPRs are diallowed if MSR:HV is 0
- */
- bool has_hv_mode;
- /* On P7/P8, set when in PM state, we need to handle resume
- * in a special way (such as routing some resume causes to
- * 0x100), so flag this here.
- */
- bool in_pm_state;
-#endif
-
- /* Those resources are used only during code translation */
- /* opcode handlers */
- opc_handler_t *opcodes[PPC_CPU_OPCODES_LEN];
-
- /* Those resources are used only in QEMU core */
- target_ulong hflags; /* hflags is a MSR & HFLAGS_MASK */
- target_ulong hflags_nmsr; /* specific hflags, not coming from MSR */
- int immu_idx; /* precomputed MMU index to speed up insn access */
- int dmmu_idx; /* precomputed MMU index to speed up data accesses */
-
- /* Power management */
- int (*check_pow)(CPUPPCState *env);
-
-#if !defined(CONFIG_USER_ONLY)
- void *load_info; /* Holds boot loading state. */
-#endif
-
- /* booke timers */
-
- /* Specifies bit locations of the Time Base used to signal a fixed timer
- * exception on a transition from 0 to 1. (watchdog or fixed-interval timer)
- *
- * 0 selects the least significant bit.
- * 63 selects the most significant bit.
- */
- uint8_t fit_period[4];
- uint8_t wdt_period[4];
-
- /* Transactional memory state */
- target_ulong tm_gpr[32];
- ppc_avr_t tm_vsr[64];
- uint64_t tm_cr;
- uint64_t tm_lr;
- uint64_t tm_ctr;
- uint64_t tm_fpscr;
- uint64_t tm_amr;
- uint64_t tm_ppr;
- uint64_t tm_vrsave;
- uint32_t tm_vscr;
- uint64_t tm_dscr;
- uint64_t tm_tar;
-};
-
-#define SET_FIT_PERIOD(a_, b_, c_, d_) \
-do { \
- env->fit_period[0] = (a_); \
- env->fit_period[1] = (b_); \
- env->fit_period[2] = (c_); \
- env->fit_period[3] = (d_); \
- } while (0)
-
-#define SET_WDT_PERIOD(a_, b_, c_, d_) \
-do { \
- env->wdt_period[0] = (a_); \
- env->wdt_period[1] = (b_); \
- env->wdt_period[2] = (c_); \
- env->wdt_period[3] = (d_); \
- } while (0)
-
-/**
- * PowerPCCPU:
- * @env: #CPUPPCState
- * @cpu_dt_id: CPU index used in the device tree. KVM uses this index too
- * @max_compat: Maximal supported logical PVR from the command line
- * @cpu_version: Current logical PVR, zero if in "raw" mode
- *
- * A PowerPC CPU.
- */
-struct PowerPCCPU {
- /*< private >*/
- CPUState parent_obj;
- /*< public >*/
-
- CPUPPCState env;
- int cpu_dt_id;
- uint32_t max_compat;
- uint32_t cpu_version;
-
- /* Fields related to migration compatibility hacks */
- bool pre_2_8_migration;
- target_ulong mig_msr_mask;
- uint64_t mig_insns_flags;
- uint64_t mig_insns_flags2;
- uint32_t mig_nb_BATs;
-};
-
-static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
-{
- return container_of(env, PowerPCCPU, env);
-}
-
-#define ENV_GET_CPU(e) CPU(ppc_env_get_cpu(e))
-
-#define ENV_OFFSET offsetof(PowerPCCPU, env)
-
-PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr);
-PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr);
-
-void ppc_cpu_do_interrupt(CPUState *cpu);
-bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
-void ppc_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
- int flags);
-void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
- fprintf_function cpu_fprintf, int flags);
-hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
-int ppc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
-int ppc_cpu_gdb_read_register_apple(CPUState *cpu, uint8_t *buf, int reg);
-int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-int ppc_cpu_gdb_write_register_apple(CPUState *cpu, uint8_t *buf, int reg);
-int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
- int cpuid, void *opaque);
-#ifndef CONFIG_USER_ONLY
-void ppc_cpu_do_system_reset(CPUState *cs);
-extern const struct VMStateDescription vmstate_ppc_cpu;
-#endif
-
-/*****************************************************************************/
-PowerPCCPU *cpu_ppc_init(const char *cpu_model);
-void ppc_translate_init(void);
-const char *ppc_cpu_lookup_alias(const char *alias);
-/* you can call this signal handler from your SIGBUS and SIGSEGV
- signal handlers to inform the virtual CPU of exceptions. non zero
- is returned if the signal was handled by the virtual CPU. */
-int cpu_ppc_signal_handler (int host_signum, void *pinfo,
- void *puc);
-#if defined(CONFIG_USER_ONLY)
-int ppc_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
- int mmu_idx);
-#endif
-
-#if !defined(CONFIG_USER_ONLY)
-void ppc_store_sdr1 (CPUPPCState *env, target_ulong value);
-#endif /* !defined(CONFIG_USER_ONLY) */
-void ppc_store_msr (CPUPPCState *env, target_ulong value);
-
-void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf);
-int ppc_get_compat_smt_threads(PowerPCCPU *cpu);
-#if defined(TARGET_PPC64)
-void ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version, Error **errp);
-#endif
-
-/* Time-base and decrementer management */
-#ifndef NO_CPU_IO_DEFS
-uint64_t cpu_ppc_load_tbl (CPUPPCState *env);
-uint32_t cpu_ppc_load_tbu (CPUPPCState *env);
-void cpu_ppc_store_tbu (CPUPPCState *env, uint32_t value);
-void cpu_ppc_store_tbl (CPUPPCState *env, uint32_t value);
-uint64_t cpu_ppc_load_atbl (CPUPPCState *env);
-uint32_t cpu_ppc_load_atbu (CPUPPCState *env);
-void cpu_ppc_store_atbl (CPUPPCState *env, uint32_t value);
-void cpu_ppc_store_atbu (CPUPPCState *env, uint32_t value);
-bool ppc_decr_clear_on_delivery(CPUPPCState *env);
-uint32_t cpu_ppc_load_decr (CPUPPCState *env);
-void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value);
-uint32_t cpu_ppc_load_hdecr (CPUPPCState *env);
-void cpu_ppc_store_hdecr (CPUPPCState *env, uint32_t value);
-uint64_t cpu_ppc_load_purr (CPUPPCState *env);
-uint32_t cpu_ppc601_load_rtcl (CPUPPCState *env);
-uint32_t cpu_ppc601_load_rtcu (CPUPPCState *env);
-#if !defined(CONFIG_USER_ONLY)
-void cpu_ppc601_store_rtcl (CPUPPCState *env, uint32_t value);
-void cpu_ppc601_store_rtcu (CPUPPCState *env, uint32_t value);
-target_ulong load_40x_pit (CPUPPCState *env);
-void store_40x_pit (CPUPPCState *env, target_ulong val);
-void store_40x_dbcr0 (CPUPPCState *env, uint32_t val);
-void store_40x_sler (CPUPPCState *env, uint32_t val);
-void store_booke_tcr (CPUPPCState *env, target_ulong val);
-void store_booke_tsr (CPUPPCState *env, target_ulong val);
-void ppc_tlb_invalidate_all (CPUPPCState *env);
-void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr);
-void cpu_ppc_set_papr(PowerPCCPU *cpu);
-#endif
-#endif
-
-void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask);
-
-static inline uint64_t ppc_dump_gpr(CPUPPCState *env, int gprn)
-{
- uint64_t gprv;
-
- gprv = env->gpr[gprn];
- if (env->flags & POWERPC_FLAG_SPE) {
- /* If the CPU implements the SPE extension, we have to get the
- * high bits of the GPR from the gprh storage area
- */
- gprv &= 0xFFFFFFFFULL;
- gprv |= (uint64_t)env->gprh[gprn] << 32;
- }
-
- return gprv;
-}
-
-/* Device control registers */
-int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, uint32_t *valp);
-int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val);
-
-#define cpu_init(cpu_model) CPU(cpu_ppc_init(cpu_model))
-
-#define cpu_signal_handler cpu_ppc_signal_handler
-#define cpu_list ppc_cpu_list
-
-/* MMU modes definitions */
-#define MMU_USER_IDX 0
-static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch)
-{
- return ifetch ? env->immu_idx : env->dmmu_idx;
-}
-
-#include "exec/cpu-all.h"
-
-/*****************************************************************************/
-/* CRF definitions */
-#define CRF_LT 3
-#define CRF_GT 2
-#define CRF_EQ 1
-#define CRF_SO 0
-#define CRF_CH (1 << CRF_LT)
-#define CRF_CL (1 << CRF_GT)
-#define CRF_CH_OR_CL (1 << CRF_EQ)
-#define CRF_CH_AND_CL (1 << CRF_SO)
-
-/* XER definitions */
-#define XER_SO 31
-#define XER_OV 30
-#define XER_CA 29
-#define XER_CMP 8
-#define XER_BC 0
-#define xer_so (env->so)
-#define xer_ov (env->ov)
-#define xer_ca (env->ca)
-#define xer_cmp ((env->xer >> XER_CMP) & 0xFF)
-#define xer_bc ((env->xer >> XER_BC) & 0x7F)
-
-/* SPR definitions */
-#define SPR_MQ (0x000)
-#define SPR_XER (0x001)
-#define SPR_601_VRTCU (0x004)
-#define SPR_601_VRTCL (0x005)
-#define SPR_601_UDECR (0x006)
-#define SPR_LR (0x008)
-#define SPR_CTR (0x009)
-#define SPR_UAMR (0x00C)
-#define SPR_DSCR (0x011)
-#define SPR_DSISR (0x012)
-#define SPR_DAR (0x013) /* DAE for PowerPC 601 */
-#define SPR_601_RTCU (0x014)
-#define SPR_601_RTCL (0x015)
-#define SPR_DECR (0x016)
-#define SPR_SDR1 (0x019)
-#define SPR_SRR0 (0x01A)
-#define SPR_SRR1 (0x01B)
-#define SPR_CFAR (0x01C)
-#define SPR_AMR (0x01D)
-#define SPR_ACOP (0x01F)
-#define SPR_BOOKE_PID (0x030)
-#define SPR_BOOKS_PID (0x030)
-#define SPR_BOOKE_DECAR (0x036)
-#define SPR_BOOKE_CSRR0 (0x03A)
-#define SPR_BOOKE_CSRR1 (0x03B)
-#define SPR_BOOKE_DEAR (0x03D)
-#define SPR_IAMR (0x03D)
-#define SPR_BOOKE_ESR (0x03E)
-#define SPR_BOOKE_IVPR (0x03F)
-#define SPR_MPC_EIE (0x050)
-#define SPR_MPC_EID (0x051)
-#define SPR_MPC_NRI (0x052)
-#define SPR_TFHAR (0x080)
-#define SPR_TFIAR (0x081)
-#define SPR_TEXASR (0x082)
-#define SPR_TEXASRU (0x083)
-#define SPR_UCTRL (0x088)
-#define SPR_MPC_CMPA (0x090)
-#define SPR_MPC_CMPB (0x091)
-#define SPR_MPC_CMPC (0x092)
-#define SPR_MPC_CMPD (0x093)
-#define SPR_MPC_ECR (0x094)
-#define SPR_MPC_DER (0x095)
-#define SPR_MPC_COUNTA (0x096)
-#define SPR_MPC_COUNTB (0x097)
-#define SPR_CTRL (0x098)
-#define SPR_MPC_CMPE (0x098)
-#define SPR_MPC_CMPF (0x099)
-#define SPR_FSCR (0x099)
-#define SPR_MPC_CMPG (0x09A)
-#define SPR_MPC_CMPH (0x09B)
-#define SPR_MPC_LCTRL1 (0x09C)
-#define SPR_MPC_LCTRL2 (0x09D)
-#define SPR_UAMOR (0x09D)
-#define SPR_MPC_ICTRL (0x09E)
-#define SPR_MPC_BAR (0x09F)
-#define SPR_PSPB (0x09F)
-#define SPR_DAWR (0x0B4)
-#define SPR_RPR (0x0BA)
-#define SPR_CIABR (0x0BB)
-#define SPR_DAWRX (0x0BC)
-#define SPR_HFSCR (0x0BE)
-#define SPR_VRSAVE (0x100)
-#define SPR_USPRG0 (0x100)
-#define SPR_USPRG1 (0x101)
-#define SPR_USPRG2 (0x102)
-#define SPR_USPRG3 (0x103)
-#define SPR_USPRG4 (0x104)
-#define SPR_USPRG5 (0x105)
-#define SPR_USPRG6 (0x106)
-#define SPR_USPRG7 (0x107)
-#define SPR_VTBL (0x10C)
-#define SPR_VTBU (0x10D)
-#define SPR_SPRG0 (0x110)
-#define SPR_SPRG1 (0x111)
-#define SPR_SPRG2 (0x112)
-#define SPR_SPRG3 (0x113)
-#define SPR_SPRG4 (0x114)
-#define SPR_SCOMC (0x114)
-#define SPR_SPRG5 (0x115)
-#define SPR_SCOMD (0x115)
-#define SPR_SPRG6 (0x116)
-#define SPR_SPRG7 (0x117)
-#define SPR_ASR (0x118)
-#define SPR_EAR (0x11A)
-#define SPR_TBL (0x11C)
-#define SPR_TBU (0x11D)
-#define SPR_TBU40 (0x11E)
-#define SPR_SVR (0x11E)
-#define SPR_BOOKE_PIR (0x11E)
-#define SPR_PVR (0x11F)
-#define SPR_HSPRG0 (0x130)
-#define SPR_BOOKE_DBSR (0x130)
-#define SPR_HSPRG1 (0x131)
-#define SPR_HDSISR (0x132)
-#define SPR_HDAR (0x133)
-#define SPR_BOOKE_EPCR (0x133)
-#define SPR_SPURR (0x134)
-#define SPR_BOOKE_DBCR0 (0x134)
-#define SPR_IBCR (0x135)
-#define SPR_PURR (0x135)
-#define SPR_BOOKE_DBCR1 (0x135)
-#define SPR_DBCR (0x136)
-#define SPR_HDEC (0x136)
-#define SPR_BOOKE_DBCR2 (0x136)
-#define SPR_HIOR (0x137)
-#define SPR_MBAR (0x137)
-#define SPR_RMOR (0x138)
-#define SPR_BOOKE_IAC1 (0x138)
-#define SPR_HRMOR (0x139)
-#define SPR_BOOKE_IAC2 (0x139)
-#define SPR_HSRR0 (0x13A)
-#define SPR_BOOKE_IAC3 (0x13A)
-#define SPR_HSRR1 (0x13B)
-#define SPR_BOOKE_IAC4 (0x13B)
-#define SPR_BOOKE_DAC1 (0x13C)
-#define SPR_MMCRH (0x13C)
-#define SPR_DABR2 (0x13D)
-#define SPR_BOOKE_DAC2 (0x13D)
-#define SPR_TFMR (0x13D)
-#define SPR_BOOKE_DVC1 (0x13E)
-#define SPR_LPCR (0x13E)
-#define SPR_BOOKE_DVC2 (0x13F)
-#define SPR_LPIDR (0x13F)
-#define SPR_BOOKE_TSR (0x150)
-#define SPR_HMER (0x150)
-#define SPR_HMEER (0x151)
-#define SPR_PCR (0x152)
-#define SPR_BOOKE_LPIDR (0x152)
-#define SPR_BOOKE_TCR (0x154)
-#define SPR_BOOKE_TLB0PS (0x158)
-#define SPR_BOOKE_TLB1PS (0x159)
-#define SPR_BOOKE_TLB2PS (0x15A)
-#define SPR_BOOKE_TLB3PS (0x15B)
-#define SPR_AMOR (0x15D)
-#define SPR_BOOKE_MAS7_MAS3 (0x174)
-#define SPR_BOOKE_IVOR0 (0x190)
-#define SPR_BOOKE_IVOR1 (0x191)
-#define SPR_BOOKE_IVOR2 (0x192)
-#define SPR_BOOKE_IVOR3 (0x193)
-#define SPR_BOOKE_IVOR4 (0x194)
-#define SPR_BOOKE_IVOR5 (0x195)
-#define SPR_BOOKE_IVOR6 (0x196)
-#define SPR_BOOKE_IVOR7 (0x197)
-#define SPR_BOOKE_IVOR8 (0x198)
-#define SPR_BOOKE_IVOR9 (0x199)
-#define SPR_BOOKE_IVOR10 (0x19A)
-#define SPR_BOOKE_IVOR11 (0x19B)
-#define SPR_BOOKE_IVOR12 (0x19C)
-#define SPR_BOOKE_IVOR13 (0x19D)
-#define SPR_BOOKE_IVOR14 (0x19E)
-#define SPR_BOOKE_IVOR15 (0x19F)
-#define SPR_BOOKE_IVOR38 (0x1B0)
-#define SPR_BOOKE_IVOR39 (0x1B1)
-#define SPR_BOOKE_IVOR40 (0x1B2)
-#define SPR_BOOKE_IVOR41 (0x1B3)
-#define SPR_BOOKE_IVOR42 (0x1B4)
-#define SPR_BOOKE_GIVOR2 (0x1B8)
-#define SPR_BOOKE_GIVOR3 (0x1B9)
-#define SPR_BOOKE_GIVOR4 (0x1BA)
-#define SPR_BOOKE_GIVOR8 (0x1BB)
-#define SPR_BOOKE_GIVOR13 (0x1BC)
-#define SPR_BOOKE_GIVOR14 (0x1BD)
-#define SPR_TIR (0x1BE)
-#define SPR_BOOKE_SPEFSCR (0x200)
-#define SPR_Exxx_BBEAR (0x201)
-#define SPR_Exxx_BBTAR (0x202)
-#define SPR_Exxx_L1CFG0 (0x203)
-#define SPR_Exxx_L1CFG1 (0x204)
-#define SPR_Exxx_NPIDR (0x205)
-#define SPR_ATBL (0x20E)
-#define SPR_ATBU (0x20F)
-#define SPR_IBAT0U (0x210)
-#define SPR_BOOKE_IVOR32 (0x210)
-#define SPR_RCPU_MI_GRA (0x210)
-#define SPR_IBAT0L (0x211)
-#define SPR_BOOKE_IVOR33 (0x211)
-#define SPR_IBAT1U (0x212)
-#define SPR_BOOKE_IVOR34 (0x212)
-#define SPR_IBAT1L (0x213)
-#define SPR_BOOKE_IVOR35 (0x213)
-#define SPR_IBAT2U (0x214)
-#define SPR_BOOKE_IVOR36 (0x214)
-#define SPR_IBAT2L (0x215)
-#define SPR_BOOKE_IVOR37 (0x215)
-#define SPR_IBAT3U (0x216)
-#define SPR_IBAT3L (0x217)
-#define SPR_DBAT0U (0x218)
-#define SPR_RCPU_L2U_GRA (0x218)
-#define SPR_DBAT0L (0x219)
-#define SPR_DBAT1U (0x21A)
-#define SPR_DBAT1L (0x21B)
-#define SPR_DBAT2U (0x21C)
-#define SPR_DBAT2L (0x21D)
-#define SPR_DBAT3U (0x21E)
-#define SPR_DBAT3L (0x21F)
-#define SPR_IBAT4U (0x230)
-#define SPR_RPCU_BBCMCR (0x230)
-#define SPR_MPC_IC_CST (0x230)
-#define SPR_Exxx_CTXCR (0x230)
-#define SPR_IBAT4L (0x231)
-#define SPR_MPC_IC_ADR (0x231)
-#define SPR_Exxx_DBCR3 (0x231)
-#define SPR_IBAT5U (0x232)
-#define SPR_MPC_IC_DAT (0x232)
-#define SPR_Exxx_DBCNT (0x232)
-#define SPR_IBAT5L (0x233)
-#define SPR_IBAT6U (0x234)
-#define SPR_IBAT6L (0x235)
-#define SPR_IBAT7U (0x236)
-#define SPR_IBAT7L (0x237)
-#define SPR_DBAT4U (0x238)
-#define SPR_RCPU_L2U_MCR (0x238)
-#define SPR_MPC_DC_CST (0x238)
-#define SPR_Exxx_ALTCTXCR (0x238)
-#define SPR_DBAT4L (0x239)
-#define SPR_MPC_DC_ADR (0x239)
-#define SPR_DBAT5U (0x23A)
-#define SPR_BOOKE_MCSRR0 (0x23A)
-#define SPR_MPC_DC_DAT (0x23A)
-#define SPR_DBAT5L (0x23B)
-#define SPR_BOOKE_MCSRR1 (0x23B)
-#define SPR_DBAT6U (0x23C)
-#define SPR_BOOKE_MCSR (0x23C)
-#define SPR_DBAT6L (0x23D)
-#define SPR_Exxx_MCAR (0x23D)
-#define SPR_DBAT7U (0x23E)
-#define SPR_BOOKE_DSRR0 (0x23E)
-#define SPR_DBAT7L (0x23F)
-#define SPR_BOOKE_DSRR1 (0x23F)
-#define SPR_BOOKE_SPRG8 (0x25C)
-#define SPR_BOOKE_SPRG9 (0x25D)
-#define SPR_BOOKE_MAS0 (0x270)
-#define SPR_BOOKE_MAS1 (0x271)
-#define SPR_BOOKE_MAS2 (0x272)
-#define SPR_BOOKE_MAS3 (0x273)
-#define SPR_BOOKE_MAS4 (0x274)
-#define SPR_BOOKE_MAS5 (0x275)
-#define SPR_BOOKE_MAS6 (0x276)
-#define SPR_BOOKE_PID1 (0x279)
-#define SPR_BOOKE_PID2 (0x27A)
-#define SPR_MPC_DPDR (0x280)
-#define SPR_MPC_IMMR (0x288)
-#define SPR_BOOKE_TLB0CFG (0x2B0)
-#define SPR_BOOKE_TLB1CFG (0x2B1)
-#define SPR_BOOKE_TLB2CFG (0x2B2)
-#define SPR_BOOKE_TLB3CFG (0x2B3)
-#define SPR_BOOKE_EPR (0x2BE)
-#define SPR_PERF0 (0x300)
-#define SPR_RCPU_MI_RBA0 (0x300)
-#define SPR_MPC_MI_CTR (0x300)
-#define SPR_POWER_USIER (0x300)
-#define SPR_PERF1 (0x301)
-#define SPR_RCPU_MI_RBA1 (0x301)
-#define SPR_POWER_UMMCR2 (0x301)
-#define SPR_PERF2 (0x302)
-#define SPR_RCPU_MI_RBA2 (0x302)
-#define SPR_MPC_MI_AP (0x302)
-#define SPR_POWER_UMMCRA (0x302)
-#define SPR_PERF3 (0x303)
-#define SPR_RCPU_MI_RBA3 (0x303)
-#define SPR_MPC_MI_EPN (0x303)
-#define SPR_POWER_UPMC1 (0x303)
-#define SPR_PERF4 (0x304)
-#define SPR_POWER_UPMC2 (0x304)
-#define SPR_PERF5 (0x305)
-#define SPR_MPC_MI_TWC (0x305)
-#define SPR_POWER_UPMC3 (0x305)
-#define SPR_PERF6 (0x306)
-#define SPR_MPC_MI_RPN (0x306)
-#define SPR_POWER_UPMC4 (0x306)
-#define SPR_PERF7 (0x307)
-#define SPR_POWER_UPMC5 (0x307)
-#define SPR_PERF8 (0x308)
-#define SPR_RCPU_L2U_RBA0 (0x308)
-#define SPR_MPC_MD_CTR (0x308)
-#define SPR_POWER_UPMC6 (0x308)
-#define SPR_PERF9 (0x309)
-#define SPR_RCPU_L2U_RBA1 (0x309)
-#define SPR_MPC_MD_CASID (0x309)
-#define SPR_970_UPMC7 (0X309)
-#define SPR_PERFA (0x30A)
-#define SPR_RCPU_L2U_RBA2 (0x30A)
-#define SPR_MPC_MD_AP (0x30A)
-#define SPR_970_UPMC8 (0X30A)
-#define SPR_PERFB (0x30B)
-#define SPR_RCPU_L2U_RBA3 (0x30B)
-#define SPR_MPC_MD_EPN (0x30B)
-#define SPR_POWER_UMMCR0 (0X30B)
-#define SPR_PERFC (0x30C)
-#define SPR_MPC_MD_TWB (0x30C)
-#define SPR_POWER_USIAR (0X30C)
-#define SPR_PERFD (0x30D)
-#define SPR_MPC_MD_TWC (0x30D)
-#define SPR_POWER_USDAR (0X30D)
-#define SPR_PERFE (0x30E)
-#define SPR_MPC_MD_RPN (0x30E)
-#define SPR_POWER_UMMCR1 (0X30E)
-#define SPR_PERFF (0x30F)
-#define SPR_MPC_MD_TW (0x30F)
-#define SPR_UPERF0 (0x310)
-#define SPR_POWER_SIER (0x310)
-#define SPR_UPERF1 (0x311)
-#define SPR_POWER_MMCR2 (0x311)
-#define SPR_UPERF2 (0x312)
-#define SPR_POWER_MMCRA (0X312)
-#define SPR_UPERF3 (0x313)
-#define SPR_POWER_PMC1 (0X313)
-#define SPR_UPERF4 (0x314)
-#define SPR_POWER_PMC2 (0X314)
-#define SPR_UPERF5 (0x315)
-#define SPR_POWER_PMC3 (0X315)
-#define SPR_UPERF6 (0x316)
-#define SPR_POWER_PMC4 (0X316)
-#define SPR_UPERF7 (0x317)
-#define SPR_POWER_PMC5 (0X317)
-#define SPR_UPERF8 (0x318)
-#define SPR_POWER_PMC6 (0X318)
-#define SPR_UPERF9 (0x319)
-#define SPR_970_PMC7 (0X319)
-#define SPR_UPERFA (0x31A)
-#define SPR_970_PMC8 (0X31A)
-#define SPR_UPERFB (0x31B)
-#define SPR_POWER_MMCR0 (0X31B)
-#define SPR_UPERFC (0x31C)
-#define SPR_POWER_SIAR (0X31C)
-#define SPR_UPERFD (0x31D)
-#define SPR_POWER_SDAR (0X31D)
-#define SPR_UPERFE (0x31E)
-#define SPR_POWER_MMCR1 (0X31E)
-#define SPR_UPERFF (0x31F)
-#define SPR_RCPU_MI_RA0 (0x320)
-#define SPR_MPC_MI_DBCAM (0x320)
-#define SPR_BESCRS (0x320)
-#define SPR_RCPU_MI_RA1 (0x321)
-#define SPR_MPC_MI_DBRAM0 (0x321)
-#define SPR_BESCRSU (0x321)
-#define SPR_RCPU_MI_RA2 (0x322)
-#define SPR_MPC_MI_DBRAM1 (0x322)
-#define SPR_BESCRR (0x322)
-#define SPR_RCPU_MI_RA3 (0x323)
-#define SPR_BESCRRU (0x323)
-#define SPR_EBBHR (0x324)
-#define SPR_EBBRR (0x325)
-#define SPR_BESCR (0x326)
-#define SPR_RCPU_L2U_RA0 (0x328)
-#define SPR_MPC_MD_DBCAM (0x328)
-#define SPR_RCPU_L2U_RA1 (0x329)
-#define SPR_MPC_MD_DBRAM0 (0x329)
-#define SPR_RCPU_L2U_RA2 (0x32A)
-#define SPR_MPC_MD_DBRAM1 (0x32A)
-#define SPR_RCPU_L2U_RA3 (0x32B)
-#define SPR_TAR (0x32F)
-#define SPR_IC (0x350)
-#define SPR_VTB (0x351)
-#define SPR_MMCRC (0x353)
-#define SPR_440_INV0 (0x370)
-#define SPR_440_INV1 (0x371)
-#define SPR_440_INV2 (0x372)
-#define SPR_440_INV3 (0x373)
-#define SPR_440_ITV0 (0x374)
-#define SPR_440_ITV1 (0x375)
-#define SPR_440_ITV2 (0x376)
-#define SPR_440_ITV3 (0x377)
-#define SPR_440_CCR1 (0x378)
-#define SPR_TACR (0x378)
-#define SPR_TCSCR (0x379)
-#define SPR_CSIGR (0x37a)
-#define SPR_DCRIPR (0x37B)
-#define SPR_POWER_SPMC1 (0x37C)
-#define SPR_POWER_SPMC2 (0x37D)
-#define SPR_POWER_MMCRS (0x37E)
-#define SPR_WORT (0x37F)
-#define SPR_PPR (0x380)
-#define SPR_750_GQR0 (0x390)
-#define SPR_440_DNV0 (0x390)
-#define SPR_750_GQR1 (0x391)
-#define SPR_440_DNV1 (0x391)
-#define SPR_750_GQR2 (0x392)
-#define SPR_440_DNV2 (0x392)
-#define SPR_750_GQR3 (0x393)
-#define SPR_440_DNV3 (0x393)
-#define SPR_750_GQR4 (0x394)
-#define SPR_440_DTV0 (0x394)
-#define SPR_750_GQR5 (0x395)
-#define SPR_440_DTV1 (0x395)
-#define SPR_750_GQR6 (0x396)
-#define SPR_440_DTV2 (0x396)
-#define SPR_750_GQR7 (0x397)
-#define SPR_440_DTV3 (0x397)
-#define SPR_750_THRM4 (0x398)
-#define SPR_750CL_HID2 (0x398)
-#define SPR_440_DVLIM (0x398)
-#define SPR_750_WPAR (0x399)
-#define SPR_440_IVLIM (0x399)
-#define SPR_TSCR (0x399)
-#define SPR_750_DMAU (0x39A)
-#define SPR_750_DMAL (0x39B)
-#define SPR_440_RSTCFG (0x39B)
-#define SPR_BOOKE_DCDBTRL (0x39C)
-#define SPR_BOOKE_DCDBTRH (0x39D)
-#define SPR_BOOKE_ICDBTRL (0x39E)
-#define SPR_BOOKE_ICDBTRH (0x39F)
-#define SPR_74XX_UMMCR2 (0x3A0)
-#define SPR_7XX_UPMC5 (0x3A1)
-#define SPR_7XX_UPMC6 (0x3A2)
-#define SPR_UBAMR (0x3A7)
-#define SPR_7XX_UMMCR0 (0x3A8)
-#define SPR_7XX_UPMC1 (0x3A9)
-#define SPR_7XX_UPMC2 (0x3AA)
-#define SPR_7XX_USIAR (0x3AB)
-#define SPR_7XX_UMMCR1 (0x3AC)
-#define SPR_7XX_UPMC3 (0x3AD)
-#define SPR_7XX_UPMC4 (0x3AE)
-#define SPR_USDA (0x3AF)
-#define SPR_40x_ZPR (0x3B0)
-#define SPR_BOOKE_MAS7 (0x3B0)
-#define SPR_74XX_MMCR2 (0x3B0)
-#define SPR_7XX_PMC5 (0x3B1)
-#define SPR_40x_PID (0x3B1)
-#define SPR_7XX_PMC6 (0x3B2)
-#define SPR_440_MMUCR (0x3B2)
-#define SPR_4xx_CCR0 (0x3B3)
-#define SPR_BOOKE_EPLC (0x3B3)
-#define SPR_405_IAC3 (0x3B4)
-#define SPR_BOOKE_EPSC (0x3B4)
-#define SPR_405_IAC4 (0x3B5)
-#define SPR_405_DVC1 (0x3B6)
-#define SPR_405_DVC2 (0x3B7)
-#define SPR_BAMR (0x3B7)
-#define SPR_7XX_MMCR0 (0x3B8)
-#define SPR_7XX_PMC1 (0x3B9)
-#define SPR_40x_SGR (0x3B9)
-#define SPR_7XX_PMC2 (0x3BA)
-#define SPR_40x_DCWR (0x3BA)
-#define SPR_7XX_SIAR (0x3BB)
-#define SPR_405_SLER (0x3BB)
-#define SPR_7XX_MMCR1 (0x3BC)
-#define SPR_405_SU0R (0x3BC)
-#define SPR_401_SKR (0x3BC)
-#define SPR_7XX_PMC3 (0x3BD)
-#define SPR_405_DBCR1 (0x3BD)
-#define SPR_7XX_PMC4 (0x3BE)
-#define SPR_SDA (0x3BF)
-#define SPR_403_VTBL (0x3CC)
-#define SPR_403_VTBU (0x3CD)
-#define SPR_DMISS (0x3D0)
-#define SPR_DCMP (0x3D1)
-#define SPR_HASH1 (0x3D2)
-#define SPR_HASH2 (0x3D3)
-#define SPR_BOOKE_ICDBDR (0x3D3)
-#define SPR_TLBMISS (0x3D4)
-#define SPR_IMISS (0x3D4)
-#define SPR_40x_ESR (0x3D4)
-#define SPR_PTEHI (0x3D5)
-#define SPR_ICMP (0x3D5)
-#define SPR_40x_DEAR (0x3D5)
-#define SPR_PTELO (0x3D6)
-#define SPR_RPA (0x3D6)
-#define SPR_40x_EVPR (0x3D6)
-#define SPR_L3PM (0x3D7)
-#define SPR_403_CDBCR (0x3D7)
-#define SPR_L3ITCR0 (0x3D8)
-#define SPR_TCR (0x3D8)
-#define SPR_40x_TSR (0x3D8)
-#define SPR_IBR (0x3DA)
-#define SPR_40x_TCR (0x3DA)
-#define SPR_ESASRR (0x3DB)
-#define SPR_40x_PIT (0x3DB)
-#define SPR_403_TBL (0x3DC)
-#define SPR_403_TBU (0x3DD)
-#define SPR_SEBR (0x3DE)
-#define SPR_40x_SRR2 (0x3DE)
-#define SPR_SER (0x3DF)
-#define SPR_40x_SRR3 (0x3DF)
-#define SPR_L3OHCR (0x3E8)
-#define SPR_L3ITCR1 (0x3E9)
-#define SPR_L3ITCR2 (0x3EA)
-#define SPR_L3ITCR3 (0x3EB)
-#define SPR_HID0 (0x3F0)
-#define SPR_40x_DBSR (0x3F0)
-#define SPR_HID1 (0x3F1)
-#define SPR_IABR (0x3F2)
-#define SPR_40x_DBCR0 (0x3F2)
-#define SPR_601_HID2 (0x3F2)
-#define SPR_Exxx_L1CSR0 (0x3F2)
-#define SPR_ICTRL (0x3F3)
-#define SPR_HID2 (0x3F3)
-#define SPR_750CL_HID4 (0x3F3)
-#define SPR_Exxx_L1CSR1 (0x3F3)
-#define SPR_440_DBDR (0x3F3)
-#define SPR_LDSTDB (0x3F4)
-#define SPR_750_TDCL (0x3F4)
-#define SPR_40x_IAC1 (0x3F4)
-#define SPR_MMUCSR0 (0x3F4)
-#define SPR_970_HID4 (0x3F4)
-#define SPR_DABR (0x3F5)
-#define DABR_MASK (~(target_ulong)0x7)
-#define SPR_Exxx_BUCSR (0x3F5)
-#define SPR_40x_IAC2 (0x3F5)
-#define SPR_601_HID5 (0x3F5)
-#define SPR_40x_DAC1 (0x3F6)
-#define SPR_MSSCR0 (0x3F6)
-#define SPR_970_HID5 (0x3F6)
-#define SPR_MSSSR0 (0x3F7)
-#define SPR_MSSCR1 (0x3F7)
-#define SPR_DABRX (0x3F7)
-#define SPR_40x_DAC2 (0x3F7)
-#define SPR_MMUCFG (0x3F7)
-#define SPR_LDSTCR (0x3F8)
-#define SPR_L2PMCR (0x3F8)
-#define SPR_750FX_HID2 (0x3F8)
-#define SPR_Exxx_L1FINV0 (0x3F8)
-#define SPR_L2CR (0x3F9)
-#define SPR_L3CR (0x3FA)
-#define SPR_750_TDCH (0x3FA)
-#define SPR_IABR2 (0x3FA)
-#define SPR_40x_DCCR (0x3FA)
-#define SPR_ICTC (0x3FB)
-#define SPR_40x_ICCR (0x3FB)
-#define SPR_THRM1 (0x3FC)
-#define SPR_403_PBL1 (0x3FC)
-#define SPR_SP (0x3FD)
-#define SPR_THRM2 (0x3FD)
-#define SPR_403_PBU1 (0x3FD)
-#define SPR_604_HID13 (0x3FD)
-#define SPR_LT (0x3FE)
-#define SPR_THRM3 (0x3FE)
-#define SPR_RCPU_FPECR (0x3FE)
-#define SPR_403_PBL2 (0x3FE)
-#define SPR_PIR (0x3FF)
-#define SPR_403_PBU2 (0x3FF)
-#define SPR_601_HID15 (0x3FF)
-#define SPR_604_HID15 (0x3FF)
-#define SPR_E500_SVR (0x3FF)
-
-/* Disable MAS Interrupt Updates for Hypervisor */
-#define EPCR_DMIUH (1 << 22)
-/* Disable Guest TLB Management Instructions */
-#define EPCR_DGTMI (1 << 23)
-/* Guest Interrupt Computation Mode */
-#define EPCR_GICM (1 << 24)
-/* Interrupt Computation Mode */
-#define EPCR_ICM (1 << 25)
-/* Disable Embedded Hypervisor Debug */
-#define EPCR_DUVD (1 << 26)
-/* Instruction Storage Interrupt Directed to Guest State */
-#define EPCR_ISIGS (1 << 27)
-/* Data Storage Interrupt Directed to Guest State */
-#define EPCR_DSIGS (1 << 28)
-/* Instruction TLB Error Interrupt Directed to Guest State */
-#define EPCR_ITLBGS (1 << 29)
-/* Data TLB Error Interrupt Directed to Guest State */
-#define EPCR_DTLBGS (1 << 30)
-/* External Input Interrupt Directed to Guest State */
-#define EPCR_EXTGS (1 << 31)
-
-#define L1CSR0_CPE 0x00010000 /* Data Cache Parity Enable */
-#define L1CSR0_CUL 0x00000400 /* (D-)Cache Unable to Lock */
-#define L1CSR0_DCLFR 0x00000100 /* D-Cache Lock Flash Reset */
-#define L1CSR0_DCFI 0x00000002 /* Data Cache Flash Invalidate */
-#define L1CSR0_DCE 0x00000001 /* Data Cache Enable */
-
-#define L1CSR1_CPE 0x00010000 /* Instruction Cache Parity Enable */
-#define L1CSR1_ICUL 0x00000400 /* I-Cache Unable to Lock */
-#define L1CSR1_ICLFR 0x00000100 /* I-Cache Lock Flash Reset */
-#define L1CSR1_ICFI 0x00000002 /* Instruction Cache Flash Invalidate */
-#define L1CSR1_ICE 0x00000001 /* Instruction Cache Enable */
-
-/* HID0 bits */
-#define HID0_DEEPNAP (1 << 24) /* pre-2.06 */
-#define HID0_DOZE (1 << 23) /* pre-2.06 */
-#define HID0_NAP (1 << 22) /* pre-2.06 */
-#define HID0_HILE (1ull << (63 - 19)) /* POWER8 */
-
-/*****************************************************************************/
-/* PowerPC Instructions types definitions */
-enum {
- PPC_NONE = 0x0000000000000000ULL,
- /* PowerPC base instructions set */
- PPC_INSNS_BASE = 0x0000000000000001ULL,
- /* integer operations instructions */
-#define PPC_INTEGER PPC_INSNS_BASE
- /* flow control instructions */
-#define PPC_FLOW PPC_INSNS_BASE
- /* virtual memory instructions */
-#define PPC_MEM PPC_INSNS_BASE
- /* ld/st with reservation instructions */
-#define PPC_RES PPC_INSNS_BASE
- /* spr/msr access instructions */
-#define PPC_MISC PPC_INSNS_BASE
- /* Deprecated instruction sets */
- /* Original POWER instruction set */
- PPC_POWER = 0x0000000000000002ULL,
- /* POWER2 instruction set extension */
- PPC_POWER2 = 0x0000000000000004ULL,
- /* Power RTC support */
- PPC_POWER_RTC = 0x0000000000000008ULL,
- /* Power-to-PowerPC bridge (601) */
- PPC_POWER_BR = 0x0000000000000010ULL,
- /* 64 bits PowerPC instruction set */
- PPC_64B = 0x0000000000000020ULL,
- /* New 64 bits extensions (PowerPC 2.0x) */
- PPC_64BX = 0x0000000000000040ULL,
- /* 64 bits hypervisor extensions */
- PPC_64H = 0x0000000000000080ULL,
- /* New wait instruction (PowerPC 2.0x) */
- PPC_WAIT = 0x0000000000000100ULL,
- /* Time base mftb instruction */
- PPC_MFTB = 0x0000000000000200ULL,
-
- /* Fixed-point unit extensions */
- /* PowerPC 602 specific */
- PPC_602_SPEC = 0x0000000000000400ULL,
- /* isel instruction */
- PPC_ISEL = 0x0000000000000800ULL,
- /* popcntb instruction */
- PPC_POPCNTB = 0x0000000000001000ULL,
- /* string load / store */
- PPC_STRING = 0x0000000000002000ULL,
- /* real mode cache inhibited load / store */
- PPC_CILDST = 0x0000000000004000ULL,
-
- /* Floating-point unit extensions */
- /* Optional floating point instructions */
- PPC_FLOAT = 0x0000000000010000ULL,
- /* New floating-point extensions (PowerPC 2.0x) */
- PPC_FLOAT_EXT = 0x0000000000020000ULL,
- PPC_FLOAT_FSQRT = 0x0000000000040000ULL,
- PPC_FLOAT_FRES = 0x0000000000080000ULL,
- PPC_FLOAT_FRSQRTE = 0x0000000000100000ULL,
- PPC_FLOAT_FRSQRTES = 0x0000000000200000ULL,
- PPC_FLOAT_FSEL = 0x0000000000400000ULL,
- PPC_FLOAT_STFIWX = 0x0000000000800000ULL,
-
- /* Vector/SIMD extensions */
- /* Altivec support */
- PPC_ALTIVEC = 0x0000000001000000ULL,
- /* PowerPC 2.03 SPE extension */
- PPC_SPE = 0x0000000002000000ULL,
- /* PowerPC 2.03 SPE single-precision floating-point extension */
- PPC_SPE_SINGLE = 0x0000000004000000ULL,
- /* PowerPC 2.03 SPE double-precision floating-point extension */
- PPC_SPE_DOUBLE = 0x0000000008000000ULL,
-
- /* Optional memory control instructions */
- PPC_MEM_TLBIA = 0x0000000010000000ULL,
- PPC_MEM_TLBIE = 0x0000000020000000ULL,
- PPC_MEM_TLBSYNC = 0x0000000040000000ULL,
- /* sync instruction */
- PPC_MEM_SYNC = 0x0000000080000000ULL,
- /* eieio instruction */
- PPC_MEM_EIEIO = 0x0000000100000000ULL,
-
- /* Cache control instructions */
- PPC_CACHE = 0x0000000200000000ULL,
- /* icbi instruction */
- PPC_CACHE_ICBI = 0x0000000400000000ULL,
- /* dcbz instruction */
- PPC_CACHE_DCBZ = 0x0000000800000000ULL,
- /* dcba instruction */
- PPC_CACHE_DCBA = 0x0000002000000000ULL,
- /* Freescale cache locking instructions */
- PPC_CACHE_LOCK = 0x0000004000000000ULL,
-
- /* MMU related extensions */
- /* external control instructions */
- PPC_EXTERN = 0x0000010000000000ULL,
- /* segment register access instructions */
- PPC_SEGMENT = 0x0000020000000000ULL,
- /* PowerPC 6xx TLB management instructions */
- PPC_6xx_TLB = 0x0000040000000000ULL,
- /* PowerPC 74xx TLB management instructions */
- PPC_74xx_TLB = 0x0000080000000000ULL,
- /* PowerPC 40x TLB management instructions */
- PPC_40x_TLB = 0x0000100000000000ULL,
- /* segment register access instructions for PowerPC 64 "bridge" */
- PPC_SEGMENT_64B = 0x0000200000000000ULL,
- /* SLB management */
- PPC_SLBI = 0x0000400000000000ULL,
-
- /* Embedded PowerPC dedicated instructions */
- PPC_WRTEE = 0x0001000000000000ULL,
- /* PowerPC 40x exception model */
- PPC_40x_EXCP = 0x0002000000000000ULL,
- /* PowerPC 405 Mac instructions */
- PPC_405_MAC = 0x0004000000000000ULL,
- /* PowerPC 440 specific instructions */
- PPC_440_SPEC = 0x0008000000000000ULL,
- /* BookE (embedded) PowerPC specification */
- PPC_BOOKE = 0x0010000000000000ULL,
- /* mfapidi instruction */
- PPC_MFAPIDI = 0x0020000000000000ULL,
- /* tlbiva instruction */
- PPC_TLBIVA = 0x0040000000000000ULL,
- /* tlbivax instruction */
- PPC_TLBIVAX = 0x0080000000000000ULL,
- /* PowerPC 4xx dedicated instructions */
- PPC_4xx_COMMON = 0x0100000000000000ULL,
- /* PowerPC 40x ibct instructions */
- PPC_40x_ICBT = 0x0200000000000000ULL,
- /* rfmci is not implemented in all BookE PowerPC */
- PPC_RFMCI = 0x0400000000000000ULL,
- /* rfdi instruction */
- PPC_RFDI = 0x0800000000000000ULL,
- /* DCR accesses */
- PPC_DCR = 0x1000000000000000ULL,
- /* DCR extended accesse */
- PPC_DCRX = 0x2000000000000000ULL,
- /* user-mode DCR access, implemented in PowerPC 460 */
- PPC_DCRUX = 0x4000000000000000ULL,
- /* popcntw and popcntd instructions */
- PPC_POPCNTWD = 0x8000000000000000ULL,
-
-#define PPC_TCG_INSNS (PPC_INSNS_BASE | PPC_POWER | PPC_POWER2 \
- | PPC_POWER_RTC | PPC_POWER_BR | PPC_64B \
- | PPC_64BX | PPC_64H | PPC_WAIT | PPC_MFTB \
- | PPC_602_SPEC | PPC_ISEL | PPC_POPCNTB \
- | PPC_STRING | PPC_FLOAT | PPC_FLOAT_EXT \
- | PPC_FLOAT_FSQRT | PPC_FLOAT_FRES \
- | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES \
- | PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX \
- | PPC_ALTIVEC | PPC_SPE | PPC_SPE_SINGLE \
- | PPC_SPE_DOUBLE | PPC_MEM_TLBIA \
- | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC \
- | PPC_MEM_SYNC | PPC_MEM_EIEIO \
- | PPC_CACHE | PPC_CACHE_ICBI \
- | PPC_CACHE_DCBZ \
- | PPC_CACHE_DCBA | PPC_CACHE_LOCK \
- | PPC_EXTERN | PPC_SEGMENT | PPC_6xx_TLB \
- | PPC_74xx_TLB | PPC_40x_TLB | PPC_SEGMENT_64B \
- | PPC_SLBI | PPC_WRTEE | PPC_40x_EXCP \
- | PPC_405_MAC | PPC_440_SPEC | PPC_BOOKE \
- | PPC_MFAPIDI | PPC_TLBIVA | PPC_TLBIVAX \
- | PPC_4xx_COMMON | PPC_40x_ICBT | PPC_RFMCI \
- | PPC_RFDI | PPC_DCR | PPC_DCRX | PPC_DCRUX \
- | PPC_POPCNTWD | PPC_CILDST)
-
- /* extended type values */
-
- /* BookE 2.06 PowerPC specification */
- PPC2_BOOKE206 = 0x0000000000000001ULL,
- /* VSX (extensions to Altivec / VMX) */
- PPC2_VSX = 0x0000000000000002ULL,
- /* Decimal Floating Point (DFP) */
- PPC2_DFP = 0x0000000000000004ULL,
- /* Embedded.Processor Control */
- PPC2_PRCNTL = 0x0000000000000008ULL,
- /* Byte-reversed, indexed, double-word load and store */
- PPC2_DBRX = 0x0000000000000010ULL,
- /* Book I 2.05 PowerPC specification */
- PPC2_ISA205 = 0x0000000000000020ULL,
- /* VSX additions in ISA 2.07 */
- PPC2_VSX207 = 0x0000000000000040ULL,
- /* ISA 2.06B bpermd */
- PPC2_PERM_ISA206 = 0x0000000000000080ULL,
- /* ISA 2.06B divide extended variants */
- PPC2_DIVE_ISA206 = 0x0000000000000100ULL,
- /* ISA 2.06B larx/stcx. instructions */
- PPC2_ATOMIC_ISA206 = 0x0000000000000200ULL,
- /* ISA 2.06B floating point integer conversion */
- PPC2_FP_CVT_ISA206 = 0x0000000000000400ULL,
- /* ISA 2.06B floating point test instructions */
- PPC2_FP_TST_ISA206 = 0x0000000000000800ULL,
- /* ISA 2.07 bctar instruction */
- PPC2_BCTAR_ISA207 = 0x0000000000001000ULL,
- /* ISA 2.07 load/store quadword */
- PPC2_LSQ_ISA207 = 0x0000000000002000ULL,
- /* ISA 2.07 Altivec */
- PPC2_ALTIVEC_207 = 0x0000000000004000ULL,
- /* PowerISA 2.07 Book3s specification */
- PPC2_ISA207S = 0x0000000000008000ULL,
- /* Double precision floating point conversion for signed integer 64 */
- PPC2_FP_CVT_S64 = 0x0000000000010000ULL,
- /* Transactional Memory (ISA 2.07, Book II) */
- PPC2_TM = 0x0000000000020000ULL,
- /* Server PM instructgions (ISA 2.06, Book III) */
- PPC2_PM_ISA206 = 0x0000000000040000ULL,
- /* POWER ISA 3.0 */
- PPC2_ISA300 = 0x0000000000080000ULL,
-
-#define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
- PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
- PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 | \
- PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206 | \
- PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | \
- PPC2_ALTIVEC_207 | PPC2_ISA207S | PPC2_DFP | \
- PPC2_FP_CVT_S64 | PPC2_TM | PPC2_PM_ISA206 | \
- PPC2_ISA300)
-};
-
-/*****************************************************************************/
-/* Memory access type :
- * may be needed for precise access rights control and precise exceptions.
- */
-enum {
- /* 1 bit to define user level / supervisor access */
- ACCESS_USER = 0x00,
- ACCESS_SUPER = 0x01,
- /* Type of instruction that generated the access */
- ACCESS_CODE = 0x10, /* Code fetch access */
- ACCESS_INT = 0x20, /* Integer load/store access */
- ACCESS_FLOAT = 0x30, /* floating point load/store access */
- ACCESS_RES = 0x40, /* load/store with reservation */
- ACCESS_EXT = 0x50, /* external access */
- ACCESS_CACHE = 0x60, /* Cache manipulation */
-};
-
-/* Hardware interruption sources:
- * all those exception can be raised simulteaneously
- */
-/* Input pins definitions */
-enum {
- /* 6xx bus input pins */
- PPC6xx_INPUT_HRESET = 0,
- PPC6xx_INPUT_SRESET = 1,
- PPC6xx_INPUT_CKSTP_IN = 2,
- PPC6xx_INPUT_MCP = 3,
- PPC6xx_INPUT_SMI = 4,
- PPC6xx_INPUT_INT = 5,
- PPC6xx_INPUT_TBEN = 6,
- PPC6xx_INPUT_WAKEUP = 7,
- PPC6xx_INPUT_NB,
-};
-
-enum {
- /* Embedded PowerPC input pins */
- PPCBookE_INPUT_HRESET = 0,
- PPCBookE_INPUT_SRESET = 1,
- PPCBookE_INPUT_CKSTP_IN = 2,
- PPCBookE_INPUT_MCP = 3,
- PPCBookE_INPUT_SMI = 4,
- PPCBookE_INPUT_INT = 5,
- PPCBookE_INPUT_CINT = 6,
- PPCBookE_INPUT_NB,
-};
-
-enum {
- /* PowerPC E500 input pins */
- PPCE500_INPUT_RESET_CORE = 0,
- PPCE500_INPUT_MCK = 1,
- PPCE500_INPUT_CINT = 3,
- PPCE500_INPUT_INT = 4,
- PPCE500_INPUT_DEBUG = 6,
- PPCE500_INPUT_NB,
-};
-
-enum {
- /* PowerPC 40x input pins */
- PPC40x_INPUT_RESET_CORE = 0,
- PPC40x_INPUT_RESET_CHIP = 1,
- PPC40x_INPUT_RESET_SYS = 2,
- PPC40x_INPUT_CINT = 3,
- PPC40x_INPUT_INT = 4,
- PPC40x_INPUT_HALT = 5,
- PPC40x_INPUT_DEBUG = 6,
- PPC40x_INPUT_NB,
-};
-
-enum {
- /* RCPU input pins */
- PPCRCPU_INPUT_PORESET = 0,
- PPCRCPU_INPUT_HRESET = 1,
- PPCRCPU_INPUT_SRESET = 2,
- PPCRCPU_INPUT_IRQ0 = 3,
- PPCRCPU_INPUT_IRQ1 = 4,
- PPCRCPU_INPUT_IRQ2 = 5,
- PPCRCPU_INPUT_IRQ3 = 6,
- PPCRCPU_INPUT_IRQ4 = 7,
- PPCRCPU_INPUT_IRQ5 = 8,
- PPCRCPU_INPUT_IRQ6 = 9,
- PPCRCPU_INPUT_IRQ7 = 10,
- PPCRCPU_INPUT_NB,
-};
-
-#if defined(TARGET_PPC64)
-enum {
- /* PowerPC 970 input pins */
- PPC970_INPUT_HRESET = 0,
- PPC970_INPUT_SRESET = 1,
- PPC970_INPUT_CKSTP = 2,
- PPC970_INPUT_TBEN = 3,
- PPC970_INPUT_MCP = 4,
- PPC970_INPUT_INT = 5,
- PPC970_INPUT_THINT = 6,
- PPC970_INPUT_NB,
-};
-
-enum {
- /* POWER7 input pins */
- POWER7_INPUT_INT = 0,
- /* POWER7 probably has other inputs, but we don't care about them
- * for any existing machine. We can wire these up when we need
- * them */
- POWER7_INPUT_NB,
-};
-#endif
-
-/* Hardware exceptions definitions */
-enum {
- /* External hardware exception sources */
- PPC_INTERRUPT_RESET = 0, /* Reset exception */
- PPC_INTERRUPT_WAKEUP, /* Wakeup exception */
- PPC_INTERRUPT_MCK, /* Machine check exception */
- PPC_INTERRUPT_EXT, /* External interrupt */
- PPC_INTERRUPT_SMI, /* System management interrupt */
- PPC_INTERRUPT_CEXT, /* Critical external interrupt */
- PPC_INTERRUPT_DEBUG, /* External debug exception */
- PPC_INTERRUPT_THERM, /* Thermal exception */
- /* Internal hardware exception sources */
- PPC_INTERRUPT_DECR, /* Decrementer exception */
- PPC_INTERRUPT_HDECR, /* Hypervisor decrementer exception */
- PPC_INTERRUPT_PIT, /* Programmable inteval timer interrupt */
- PPC_INTERRUPT_FIT, /* Fixed interval timer interrupt */
- PPC_INTERRUPT_WDT, /* Watchdog timer interrupt */
- PPC_INTERRUPT_CDOORBELL, /* Critical doorbell interrupt */
- PPC_INTERRUPT_DOORBELL, /* Doorbell interrupt */
- PPC_INTERRUPT_PERFM, /* Performance monitor interrupt */
- PPC_INTERRUPT_HMI, /* Hypervisor Maintainance interrupt */
- PPC_INTERRUPT_HDOORBELL, /* Hypervisor Doorbell interrupt */
-};
-
-/* Processor Compatibility mask (PCR) */
-enum {
- PCR_COMPAT_2_05 = 1ull << (63-62),
- PCR_COMPAT_2_06 = 1ull << (63-61),
- PCR_COMPAT_2_07 = 1ull << (63-60),
- PCR_VEC_DIS = 1ull << (63-0), /* Vec. disable (bit NA since POWER8) */
- PCR_VSX_DIS = 1ull << (63-1), /* VSX disable (bit NA since POWER8) */
- PCR_TM_DIS = 1ull << (63-2), /* Trans. memory disable (POWER8) */
-};
-
-/* HMER/HMEER */
-enum {
- HMER_MALFUNCTION_ALERT = 1ull << (63 - 0),
- HMER_PROC_RECV_DONE = 1ull << (63 - 2),
- HMER_PROC_RECV_ERROR_MASKED = 1ull << (63 - 3),
- HMER_TFAC_ERROR = 1ull << (63 - 4),
- HMER_TFMR_PARITY_ERROR = 1ull << (63 - 5),
- HMER_XSCOM_FAIL = 1ull << (63 - 8),
- HMER_XSCOM_DONE = 1ull << (63 - 9),
- HMER_PROC_RECV_AGAIN = 1ull << (63 - 11),
- HMER_WARN_RISE = 1ull << (63 - 14),
- HMER_WARN_FALL = 1ull << (63 - 15),
- HMER_SCOM_FIR_HMI = 1ull << (63 - 16),
- HMER_TRIG_FIR_HMI = 1ull << (63 - 17),
- HMER_HYP_RESOURCE_ERR = 1ull << (63 - 20),
- HMER_XSCOM_STATUS_MASK = 7ull << (63 - 23),
- HMER_XSCOM_STATUS_LSH = (63 - 23),
-};
-
-/* Alternate Interrupt Location (AIL) */
-enum {
- AIL_NONE = 0,
- AIL_RESERVED = 1,
- AIL_0001_8000 = 2,
- AIL_C000_0000_0000_4000 = 3,
-};
-
-/*****************************************************************************/
-
-static inline target_ulong cpu_read_xer(CPUPPCState *env)
-{
- return env->xer | (env->so << XER_SO) | (env->ov << XER_OV) | (env->ca << XER_CA);
-}
-
-static inline void cpu_write_xer(CPUPPCState *env, target_ulong xer)
-{
- env->so = (xer >> XER_SO) & 1;
- env->ov = (xer >> XER_OV) & 1;
- env->ca = (xer >> XER_CA) & 1;
- env->xer = xer & ~((1u << XER_SO) | (1u << XER_OV) | (1u << XER_CA));
-}
-
-static inline void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc,
- target_ulong *cs_base, uint32_t *flags)
-{
- *pc = env->nip;
- *cs_base = 0;
- *flags = env->hflags;
-}
-
-void QEMU_NORETURN raise_exception(CPUPPCState *env, uint32_t exception);
-void QEMU_NORETURN raise_exception_ra(CPUPPCState *env, uint32_t exception,
- uintptr_t raddr);
-void QEMU_NORETURN raise_exception_err(CPUPPCState *env, uint32_t exception,
- uint32_t error_code);
-void QEMU_NORETURN raise_exception_err_ra(CPUPPCState *env, uint32_t exception,
- uint32_t error_code, uintptr_t raddr);
-
-#if !defined(CONFIG_USER_ONLY)
-static inline int booke206_tlbm_id(CPUPPCState *env, ppcmas_tlb_t *tlbm)
-{
- uintptr_t tlbml = (uintptr_t)tlbm;
- uintptr_t tlbl = (uintptr_t)env->tlb.tlbm;
-
- return (tlbml - tlbl) / sizeof(env->tlb.tlbm[0]);
-}
-
-static inline int booke206_tlb_size(CPUPPCState *env, int tlbn)
-{
- uint32_t tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn];
- int r = tlbncfg & TLBnCFG_N_ENTRY;
- return r;
-}
-
-static inline int booke206_tlb_ways(CPUPPCState *env, int tlbn)
-{
- uint32_t tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn];
- int r = tlbncfg >> TLBnCFG_ASSOC_SHIFT;
- return r;
-}
-
-static inline int booke206_tlbm_to_tlbn(CPUPPCState *env, ppcmas_tlb_t *tlbm)
-{
- int id = booke206_tlbm_id(env, tlbm);
- int end = 0;
- int i;
-
- for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
- end += booke206_tlb_size(env, i);
- if (id < end) {
- return i;
- }
- }
-
- cpu_abort(CPU(ppc_env_get_cpu(env)), "Unknown TLBe: %d\n", id);
- return 0;
-}
-
-static inline int booke206_tlbm_to_way(CPUPPCState *env, ppcmas_tlb_t *tlb)
-{
- int tlbn = booke206_tlbm_to_tlbn(env, tlb);
- int tlbid = booke206_tlbm_id(env, tlb);
- return tlbid & (booke206_tlb_ways(env, tlbn) - 1);
-}
-
-static inline ppcmas_tlb_t *booke206_get_tlbm(CPUPPCState *env, const int tlbn,
- target_ulong ea, int way)
-{
- int r;
- uint32_t ways = booke206_tlb_ways(env, tlbn);
- int ways_bits = ctz32(ways);
- int tlb_bits = ctz32(booke206_tlb_size(env, tlbn));
- int i;
-
- way &= ways - 1;
- ea >>= MAS2_EPN_SHIFT;
- ea &= (1 << (tlb_bits - ways_bits)) - 1;
- r = (ea << ways_bits) | way;
-
- if (r >= booke206_tlb_size(env, tlbn)) {
- return NULL;
- }
-
- /* bump up to tlbn index */
- for (i = 0; i < tlbn; i++) {
- r += booke206_tlb_size(env, i);
- }
-
- return &env->tlb.tlbm[r];
-}
-
-/* returns bitmap of supported page sizes for a given TLB */
-static inline uint32_t booke206_tlbnps(CPUPPCState *env, const int tlbn)
-{
- bool mav2 = false;
- uint32_t ret = 0;
-
- if (mav2) {
- ret = env->spr[SPR_BOOKE_TLB0PS + tlbn];
- } else {
- uint32_t tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn];
- uint32_t min = (tlbncfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT;
- uint32_t max = (tlbncfg & TLBnCFG_MAXSIZE) >> TLBnCFG_MAXSIZE_SHIFT;
- int i;
- for (i = min; i <= max; i++) {
- ret |= (1 << (i << 1));
- }
- }
-
- return ret;
-}
-
-#endif
-
-static inline bool msr_is_64bit(CPUPPCState *env, target_ulong msr)
-{
- if (env->mmu_model == POWERPC_MMU_BOOKE206) {
- return msr & (1ULL << MSR_CM);
- }
-
- return msr & (1ULL << MSR_SF);
-}
-
-/**
- * Check whether register rx is in the range between start and
- * start + nregs (as needed by the LSWX and LSWI instructions)
- */
-static inline bool lsw_reg_in_range(int start, int nregs, int rx)
-{
- return (start + nregs <= 32 && rx >= start && rx < start + nregs) ||
- (start + nregs > 32 && (rx >= start || rx < start + nregs - 32));
-}
-
-extern void (*cpu_ppc_hypercall)(PowerPCCPU *);
-
-void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
-
-/**
- * ppc_get_vcpu_dt_id:
- * @cs: a PowerPCCPU struct.
- *
- * Returns a device-tree ID for a CPU.
- */
-int ppc_get_vcpu_dt_id(PowerPCCPU *cpu);
-
-/**
- * ppc_get_vcpu_by_dt_id:
- * @cpu_dt_id: a device tree id
- *
- * Searches for a CPU by @cpu_dt_id.
- *
- * Returns: a PowerPCCPU struct
- */
-PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id);
-
-void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len);
-#endif /* PPC_CPU_H */
diff --git a/target-ppc/dfp_helper.c b/target-ppc/dfp_helper.c
deleted file mode 100644
index 9164fe701b..0000000000
--- a/target-ppc/dfp_helper.c
+++ /dev/null
@@ -1,1331 +0,0 @@
-/*
- * PowerPC Decimal Floating Point (DPF) emulation helpers for QEMU.
- *
- * Copyright (c) 2014 IBM Corporation.
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-
-#define DECNUMDIGITS 34
-#include "libdecnumber/decContext.h"
-#include "libdecnumber/decNumber.h"
-#include "libdecnumber/dpd/decimal32.h"
-#include "libdecnumber/dpd/decimal64.h"
-#include "libdecnumber/dpd/decimal128.h"
-
-#if defined(HOST_WORDS_BIGENDIAN)
-#define HI_IDX 0
-#define LO_IDX 1
-#else
-#define HI_IDX 1
-#define LO_IDX 0
-#endif
-
-struct PPC_DFP {
- CPUPPCState *env;
- uint64_t t64[2], a64[2], b64[2];
- decNumber t, a, b;
- decContext context;
- uint8_t crbf;
-};
-
-static void dfp_prepare_rounding_mode(decContext *context, uint64_t fpscr)
-{
- enum rounding rnd;
-
- switch ((fpscr >> 32) & 0x7) {
- case 0:
- rnd = DEC_ROUND_HALF_EVEN;
- break;
- case 1:
- rnd = DEC_ROUND_DOWN;
- break;
- case 2:
- rnd = DEC_ROUND_CEILING;
- break;
- case 3:
- rnd = DEC_ROUND_FLOOR;
- break;
- case 4:
- rnd = DEC_ROUND_HALF_UP;
- break;
- case 5:
- rnd = DEC_ROUND_HALF_DOWN;
- break;
- case 6:
- rnd = DEC_ROUND_UP;
- break;
- case 7:
- rnd = DEC_ROUND_05UP;
- break;
- default:
- g_assert_not_reached();
- }
-
- decContextSetRounding(context, rnd);
-}
-
-static void dfp_set_round_mode_from_immediate(uint8_t r, uint8_t rmc,
- struct PPC_DFP *dfp)
-{
- enum rounding rnd;
- if (r == 0) {
- switch (rmc & 3) {
- case 0:
- rnd = DEC_ROUND_HALF_EVEN;
- break;
- case 1:
- rnd = DEC_ROUND_DOWN;
- break;
- case 2:
- rnd = DEC_ROUND_HALF_UP;
- break;
- case 3: /* use FPSCR rounding mode */
- return;
- default:
- assert(0); /* cannot get here */
- }
- } else { /* r == 1 */
- switch (rmc & 3) {
- case 0:
- rnd = DEC_ROUND_CEILING;
- break;
- case 1:
- rnd = DEC_ROUND_FLOOR;
- break;
- case 2:
- rnd = DEC_ROUND_UP;
- break;
- case 3:
- rnd = DEC_ROUND_HALF_DOWN;
- break;
- default:
- assert(0); /* cannot get here */
- }
- }
- decContextSetRounding(&dfp->context, rnd);
-}
-
-static void dfp_prepare_decimal64(struct PPC_DFP *dfp, uint64_t *a,
- uint64_t *b, CPUPPCState *env)
-{
- decContextDefault(&dfp->context, DEC_INIT_DECIMAL64);
- dfp_prepare_rounding_mode(&dfp->context, env->fpscr);
- dfp->env = env;
-
- if (a) {
- dfp->a64[0] = *a;
- decimal64ToNumber((decimal64 *)dfp->a64, &dfp->a);
- } else {
- dfp->a64[0] = 0;
- decNumberZero(&dfp->a);
- }
-
- if (b) {
- dfp->b64[0] = *b;
- decimal64ToNumber((decimal64 *)dfp->b64, &dfp->b);
- } else {
- dfp->b64[0] = 0;
- decNumberZero(&dfp->b);
- }
-}
-
-static void dfp_prepare_decimal128(struct PPC_DFP *dfp, uint64_t *a,
- uint64_t *b, CPUPPCState *env)
-{
- decContextDefault(&dfp->context, DEC_INIT_DECIMAL128);
- dfp_prepare_rounding_mode(&dfp->context, env->fpscr);
- dfp->env = env;
-
- if (a) {
- dfp->a64[0] = a[HI_IDX];
- dfp->a64[1] = a[LO_IDX];
- decimal128ToNumber((decimal128 *)dfp->a64, &dfp->a);
- } else {
- dfp->a64[0] = dfp->a64[1] = 0;
- decNumberZero(&dfp->a);
- }
-
- if (b) {
- dfp->b64[0] = b[HI_IDX];
- dfp->b64[1] = b[LO_IDX];
- decimal128ToNumber((decimal128 *)dfp->b64, &dfp->b);
- } else {
- dfp->b64[0] = dfp->b64[1] = 0;
- decNumberZero(&dfp->b);
- }
-}
-
-static void dfp_set_FPSCR_flag(struct PPC_DFP *dfp, uint64_t flag,
- uint64_t enabled)
-{
- dfp->env->fpscr |= (flag | FP_FX);
- if (dfp->env->fpscr & enabled) {
- dfp->env->fpscr |= FP_FEX;
- }
-}
-
-static void dfp_set_FPRF_from_FRT_with_context(struct PPC_DFP *dfp,
- decContext *context)
-{
- uint64_t fprf = 0;
-
- /* construct FPRF */
- switch (decNumberClass(&dfp->t, context)) {
- case DEC_CLASS_SNAN:
- fprf = 0x01;
- break;
- case DEC_CLASS_QNAN:
- fprf = 0x11;
- break;
- case DEC_CLASS_NEG_INF:
- fprf = 0x09;
- break;
- case DEC_CLASS_NEG_NORMAL:
- fprf = 0x08;
- break;
- case DEC_CLASS_NEG_SUBNORMAL:
- fprf = 0x18;
- break;
- case DEC_CLASS_NEG_ZERO:
- fprf = 0x12;
- break;
- case DEC_CLASS_POS_ZERO:
- fprf = 0x02;
- break;
- case DEC_CLASS_POS_SUBNORMAL:
- fprf = 0x14;
- break;
- case DEC_CLASS_POS_NORMAL:
- fprf = 0x04;
- break;
- case DEC_CLASS_POS_INF:
- fprf = 0x05;
- break;
- default:
- assert(0); /* should never get here */
- }
- dfp->env->fpscr &= ~(0x1F << 12);
- dfp->env->fpscr |= (fprf << 12);
-}
-
-static void dfp_set_FPRF_from_FRT(struct PPC_DFP *dfp)
-{
- dfp_set_FPRF_from_FRT_with_context(dfp, &dfp->context);
-}
-
-static void dfp_set_FPRF_from_FRT_short(struct PPC_DFP *dfp)
-{
- decContext shortContext;
- decContextDefault(&shortContext, DEC_INIT_DECIMAL32);
- dfp_set_FPRF_from_FRT_with_context(dfp, &shortContext);
-}
-
-static void dfp_set_FPRF_from_FRT_long(struct PPC_DFP *dfp)
-{
- decContext longContext;
- decContextDefault(&longContext, DEC_INIT_DECIMAL64);
- dfp_set_FPRF_from_FRT_with_context(dfp, &longContext);
-}
-
-static void dfp_check_for_OX(struct PPC_DFP *dfp)
-{
- if (dfp->context.status & DEC_Overflow) {
- dfp_set_FPSCR_flag(dfp, FP_OX, FP_OE);
- }
-}
-
-static void dfp_check_for_UX(struct PPC_DFP *dfp)
-{
- if (dfp->context.status & DEC_Underflow) {
- dfp_set_FPSCR_flag(dfp, FP_UX, FP_UE);
- }
-}
-
-static void dfp_check_for_XX(struct PPC_DFP *dfp)
-{
- if (dfp->context.status & DEC_Inexact) {
- dfp_set_FPSCR_flag(dfp, FP_XX | FP_FI, FP_XE);
- }
-}
-
-static void dfp_check_for_ZX(struct PPC_DFP *dfp)
-{
- if (dfp->context.status & DEC_Division_by_zero) {
- dfp_set_FPSCR_flag(dfp, FP_ZX, FP_ZE);
- }
-}
-
-static void dfp_check_for_VXSNAN(struct PPC_DFP *dfp)
-{
- if (dfp->context.status & DEC_Invalid_operation) {
- if (decNumberIsSNaN(&dfp->a) || decNumberIsSNaN(&dfp->b)) {
- dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXSNAN, FP_VE);
- }
- }
-}
-
-static void dfp_check_for_VXSNAN_and_convert_to_QNaN(struct PPC_DFP *dfp)
-{
- if (decNumberIsSNaN(&dfp->t)) {
- dfp->t.bits &= ~DECSNAN;
- dfp->t.bits |= DECNAN;
- dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXSNAN, FP_VE);
- }
-}
-
-static void dfp_check_for_VXISI(struct PPC_DFP *dfp, int testForSameSign)
-{
- if (dfp->context.status & DEC_Invalid_operation) {
- if (decNumberIsInfinite(&dfp->a) && decNumberIsInfinite(&dfp->b)) {
- int same = decNumberClass(&dfp->a, &dfp->context) ==
- decNumberClass(&dfp->b, &dfp->context);
- if ((same && testForSameSign) || (!same && !testForSameSign)) {
- dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXISI, FP_VE);
- }
- }
- }
-}
-
-static void dfp_check_for_VXISI_add(struct PPC_DFP *dfp)
-{
- dfp_check_for_VXISI(dfp, 0);
-}
-
-static void dfp_check_for_VXISI_subtract(struct PPC_DFP *dfp)
-{
- dfp_check_for_VXISI(dfp, 1);
-}
-
-static void dfp_check_for_VXIMZ(struct PPC_DFP *dfp)
-{
- if (dfp->context.status & DEC_Invalid_operation) {
- if ((decNumberIsInfinite(&dfp->a) && decNumberIsZero(&dfp->b)) ||
- (decNumberIsInfinite(&dfp->b) && decNumberIsZero(&dfp->a))) {
- dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXIMZ, FP_VE);
- }
- }
-}
-
-static void dfp_check_for_VXZDZ(struct PPC_DFP *dfp)
-{
- if (dfp->context.status & DEC_Division_undefined) {
- dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXZDZ, FP_VE);
- }
-}
-
-static void dfp_check_for_VXIDI(struct PPC_DFP *dfp)
-{
- if (dfp->context.status & DEC_Invalid_operation) {
- if (decNumberIsInfinite(&dfp->a) && decNumberIsInfinite(&dfp->b)) {
- dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXIDI, FP_VE);
- }
- }
-}
-
-static void dfp_check_for_VXVC(struct PPC_DFP *dfp)
-{
- if (decNumberIsNaN(&dfp->a) || decNumberIsNaN(&dfp->b)) {
- dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXVC, FP_VE);
- }
-}
-
-static void dfp_check_for_VXCVI(struct PPC_DFP *dfp)
-{
- if ((dfp->context.status & DEC_Invalid_operation) &&
- (!decNumberIsSNaN(&dfp->a)) &&
- (!decNumberIsSNaN(&dfp->b))) {
- dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FP_VE);
- }
-}
-
-static void dfp_set_CRBF_from_T(struct PPC_DFP *dfp)
-{
- if (decNumberIsNaN(&dfp->t)) {
- dfp->crbf = 1;
- } else if (decNumberIsZero(&dfp->t)) {
- dfp->crbf = 2;
- } else if (decNumberIsNegative(&dfp->t)) {
- dfp->crbf = 8;
- } else {
- dfp->crbf = 4;
- }
-}
-
-static void dfp_set_FPCC_from_CRBF(struct PPC_DFP *dfp)
-{
- dfp->env->fpscr &= ~(0xF << 12);
- dfp->env->fpscr |= (dfp->crbf << 12);
-}
-
-static inline void dfp_makeQNaN(decNumber *dn)
-{
- dn->bits &= ~DECSPECIAL;
- dn->bits |= DECNAN;
-}
-
-static inline int dfp_get_digit(decNumber *dn, int n)
-{
- assert(DECDPUN == 3);
- int unit = n / DECDPUN;
- int dig = n % DECDPUN;
- switch (dig) {
- case 0:
- return dn->lsu[unit] % 10;
- case 1:
- return (dn->lsu[unit] / 10) % 10;
- case 2:
- return dn->lsu[unit] / 100;
- }
- g_assert_not_reached();
-}
-
-#define DFP_HELPER_TAB(op, dnop, postprocs, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \
-{ \
- struct PPC_DFP dfp; \
- dfp_prepare_decimal##size(&dfp, a, b, env); \
- dnop(&dfp.t, &dfp.a, &dfp.b, &dfp.context); \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
- postprocs(&dfp); \
- if (size == 64) { \
- t[0] = dfp.t64[0]; \
- } else if (size == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
-}
-
-static void ADD_PPs(struct PPC_DFP *dfp)
-{
- dfp_set_FPRF_from_FRT(dfp);
- dfp_check_for_OX(dfp);
- dfp_check_for_UX(dfp);
- dfp_check_for_XX(dfp);
- dfp_check_for_VXSNAN(dfp);
- dfp_check_for_VXISI_add(dfp);
-}
-
-DFP_HELPER_TAB(dadd, decNumberAdd, ADD_PPs, 64)
-DFP_HELPER_TAB(daddq, decNumberAdd, ADD_PPs, 128)
-
-static void SUB_PPs(struct PPC_DFP *dfp)
-{
- dfp_set_FPRF_from_FRT(dfp);
- dfp_check_for_OX(dfp);
- dfp_check_for_UX(dfp);
- dfp_check_for_XX(dfp);
- dfp_check_for_VXSNAN(dfp);
- dfp_check_for_VXISI_subtract(dfp);
-}
-
-DFP_HELPER_TAB(dsub, decNumberSubtract, SUB_PPs, 64)
-DFP_HELPER_TAB(dsubq, decNumberSubtract, SUB_PPs, 128)
-
-static void MUL_PPs(struct PPC_DFP *dfp)
-{
- dfp_set_FPRF_from_FRT(dfp);
- dfp_check_for_OX(dfp);
- dfp_check_for_UX(dfp);
- dfp_check_for_XX(dfp);
- dfp_check_for_VXSNAN(dfp);
- dfp_check_for_VXIMZ(dfp);
-}
-
-DFP_HELPER_TAB(dmul, decNumberMultiply, MUL_PPs, 64)
-DFP_HELPER_TAB(dmulq, decNumberMultiply, MUL_PPs, 128)
-
-static void DIV_PPs(struct PPC_DFP *dfp)
-{
- dfp_set_FPRF_from_FRT(dfp);
- dfp_check_for_OX(dfp);
- dfp_check_for_UX(dfp);
- dfp_check_for_ZX(dfp);
- dfp_check_for_XX(dfp);
- dfp_check_for_VXSNAN(dfp);
- dfp_check_for_VXZDZ(dfp);
- dfp_check_for_VXIDI(dfp);
-}
-
-DFP_HELPER_TAB(ddiv, decNumberDivide, DIV_PPs, 64)
-DFP_HELPER_TAB(ddivq, decNumberDivide, DIV_PPs, 128)
-
-#define DFP_HELPER_BF_AB(op, dnop, postprocs, size) \
-uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b) \
-{ \
- struct PPC_DFP dfp; \
- dfp_prepare_decimal##size(&dfp, a, b, env); \
- dnop(&dfp.t, &dfp.a, &dfp.b, &dfp.context); \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
- postprocs(&dfp); \
- return dfp.crbf; \
-}
-
-static void CMPU_PPs(struct PPC_DFP *dfp)
-{
- dfp_set_CRBF_from_T(dfp);
- dfp_set_FPCC_from_CRBF(dfp);
- dfp_check_for_VXSNAN(dfp);
-}
-
-DFP_HELPER_BF_AB(dcmpu, decNumberCompare, CMPU_PPs, 64)
-DFP_HELPER_BF_AB(dcmpuq, decNumberCompare, CMPU_PPs, 128)
-
-static void CMPO_PPs(struct PPC_DFP *dfp)
-{
- dfp_set_CRBF_from_T(dfp);
- dfp_set_FPCC_from_CRBF(dfp);
- dfp_check_for_VXSNAN(dfp);
- dfp_check_for_VXVC(dfp);
-}
-
-DFP_HELPER_BF_AB(dcmpo, decNumberCompare, CMPO_PPs, 64)
-DFP_HELPER_BF_AB(dcmpoq, decNumberCompare, CMPO_PPs, 128)
-
-#define DFP_HELPER_TSTDC(op, size) \
-uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint32_t dcm) \
-{ \
- struct PPC_DFP dfp; \
- int match = 0; \
- \
- dfp_prepare_decimal##size(&dfp, a, 0, env); \
- \
- match |= (dcm & 0x20) && decNumberIsZero(&dfp.a); \
- match |= (dcm & 0x10) && decNumberIsSubnormal(&dfp.a, &dfp.context); \
- match |= (dcm & 0x08) && decNumberIsNormal(&dfp.a, &dfp.context); \
- match |= (dcm & 0x04) && decNumberIsInfinite(&dfp.a); \
- match |= (dcm & 0x02) && decNumberIsQNaN(&dfp.a); \
- match |= (dcm & 0x01) && decNumberIsSNaN(&dfp.a); \
- \
- if (decNumberIsNegative(&dfp.a)) { \
- dfp.crbf = match ? 0xA : 0x8; \
- } else { \
- dfp.crbf = match ? 0x2 : 0x0; \
- } \
- \
- dfp_set_FPCC_from_CRBF(&dfp); \
- return dfp.crbf; \
-}
-
-DFP_HELPER_TSTDC(dtstdc, 64)
-DFP_HELPER_TSTDC(dtstdcq, 128)
-
-#define DFP_HELPER_TSTDG(op, size) \
-uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint32_t dcm) \
-{ \
- struct PPC_DFP dfp; \
- int minexp, maxexp, nzero_digits, nzero_idx, is_negative, is_zero, \
- is_extreme_exp, is_subnormal, is_normal, leftmost_is_nonzero, \
- match; \
- \
- dfp_prepare_decimal##size(&dfp, a, 0, env); \
- \
- if ((size) == 64) { \
- minexp = -398; \
- maxexp = 369; \
- nzero_digits = 16; \
- nzero_idx = 5; \
- } else if ((size) == 128) { \
- minexp = -6176; \
- maxexp = 6111; \
- nzero_digits = 34; \
- nzero_idx = 11; \
- } \
- \
- is_negative = decNumberIsNegative(&dfp.a); \
- is_zero = decNumberIsZero(&dfp.a); \
- is_extreme_exp = (dfp.a.exponent == maxexp) || \
- (dfp.a.exponent == minexp); \
- is_subnormal = decNumberIsSubnormal(&dfp.a, &dfp.context); \
- is_normal = decNumberIsNormal(&dfp.a, &dfp.context); \
- leftmost_is_nonzero = (dfp.a.digits == nzero_digits) && \
- (dfp.a.lsu[nzero_idx] != 0); \
- match = 0; \
- \
- match |= (dcm & 0x20) && is_zero && !is_extreme_exp; \
- match |= (dcm & 0x10) && is_zero && is_extreme_exp; \
- match |= (dcm & 0x08) && \
- (is_subnormal || (is_normal && is_extreme_exp)); \
- match |= (dcm & 0x04) && is_normal && !is_extreme_exp && \
- !leftmost_is_nonzero; \
- match |= (dcm & 0x02) && is_normal && !is_extreme_exp && \
- leftmost_is_nonzero; \
- match |= (dcm & 0x01) && decNumberIsSpecial(&dfp.a); \
- \
- if (is_negative) { \
- dfp.crbf = match ? 0xA : 0x8; \
- } else { \
- dfp.crbf = match ? 0x2 : 0x0; \
- } \
- \
- dfp_set_FPCC_from_CRBF(&dfp); \
- return dfp.crbf; \
-}
-
-DFP_HELPER_TSTDG(dtstdg, 64)
-DFP_HELPER_TSTDG(dtstdgq, 128)
-
-#define DFP_HELPER_TSTEX(op, size) \
-uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b) \
-{ \
- struct PPC_DFP dfp; \
- int expa, expb, a_is_special, b_is_special; \
- \
- dfp_prepare_decimal##size(&dfp, a, b, env); \
- \
- expa = dfp.a.exponent; \
- expb = dfp.b.exponent; \
- a_is_special = decNumberIsSpecial(&dfp.a); \
- b_is_special = decNumberIsSpecial(&dfp.b); \
- \
- if (a_is_special || b_is_special) { \
- int atype = a_is_special ? (decNumberIsNaN(&dfp.a) ? 4 : 2) : 1; \
- int btype = b_is_special ? (decNumberIsNaN(&dfp.b) ? 4 : 2) : 1; \
- dfp.crbf = (atype ^ btype) ? 0x1 : 0x2; \
- } else if (expa < expb) { \
- dfp.crbf = 0x8; \
- } else if (expa > expb) { \
- dfp.crbf = 0x4; \
- } else { \
- dfp.crbf = 0x2; \
- } \
- \
- dfp_set_FPCC_from_CRBF(&dfp); \
- return dfp.crbf; \
-}
-
-DFP_HELPER_TSTEX(dtstex, 64)
-DFP_HELPER_TSTEX(dtstexq, 128)
-
-#define DFP_HELPER_TSTSF(op, size) \
-uint32_t helper_##op(CPUPPCState *env, uint64_t *a, uint64_t *b) \
-{ \
- struct PPC_DFP dfp; \
- unsigned k; \
- \
- dfp_prepare_decimal##size(&dfp, 0, b, env); \
- \
- k = *a & 0x3F; \
- \
- if (unlikely(decNumberIsSpecial(&dfp.b))) { \
- dfp.crbf = 1; \
- } else if (k == 0) { \
- dfp.crbf = 4; \
- } else if (unlikely(decNumberIsZero(&dfp.b))) { \
- /* Zero has no sig digits */ \
- dfp.crbf = 4; \
- } else { \
- unsigned nsd = dfp.b.digits; \
- if (k < nsd) { \
- dfp.crbf = 8; \
- } else if (k > nsd) { \
- dfp.crbf = 4; \
- } else { \
- dfp.crbf = 2; \
- } \
- } \
- \
- dfp_set_FPCC_from_CRBF(&dfp); \
- return dfp.crbf; \
-}
-
-DFP_HELPER_TSTSF(dtstsf, 64)
-DFP_HELPER_TSTSF(dtstsfq, 128)
-
-#define DFP_HELPER_TSTSFI(op, size) \
-uint32_t helper_##op(CPUPPCState *env, uint32_t a, uint64_t *b) \
-{ \
- struct PPC_DFP dfp; \
- unsigned uim; \
- \
- dfp_prepare_decimal##size(&dfp, 0, b, env); \
- \
- uim = a & 0x3F; \
- \
- if (unlikely(decNumberIsSpecial(&dfp.b))) { \
- dfp.crbf = 1; \
- } else if (uim == 0) { \
- dfp.crbf = 4; \
- } else if (unlikely(decNumberIsZero(&dfp.b))) { \
- /* Zero has no sig digits */ \
- dfp.crbf = 4; \
- } else { \
- unsigned nsd = dfp.b.digits; \
- if (uim < nsd) { \
- dfp.crbf = 8; \
- } else if (uim > nsd) { \
- dfp.crbf = 4; \
- } else { \
- dfp.crbf = 2; \
- } \
- } \
- \
- dfp_set_FPCC_from_CRBF(&dfp); \
- return dfp.crbf; \
-}
-
-DFP_HELPER_TSTSFI(dtstsfi, 64)
-DFP_HELPER_TSTSFI(dtstsfiq, 128)
-
-static void QUA_PPs(struct PPC_DFP *dfp)
-{
- dfp_set_FPRF_from_FRT(dfp);
- dfp_check_for_XX(dfp);
- dfp_check_for_VXSNAN(dfp);
- dfp_check_for_VXCVI(dfp);
-}
-
-static void dfp_quantize(uint8_t rmc, struct PPC_DFP *dfp)
-{
- dfp_set_round_mode_from_immediate(0, rmc, dfp);
- decNumberQuantize(&dfp->t, &dfp->b, &dfp->a, &dfp->context);
- if (decNumberIsSNaN(&dfp->a)) {
- dfp->t = dfp->a;
- dfp_makeQNaN(&dfp->t);
- } else if (decNumberIsSNaN(&dfp->b)) {
- dfp->t = dfp->b;
- dfp_makeQNaN(&dfp->t);
- } else if (decNumberIsQNaN(&dfp->a)) {
- dfp->t = dfp->a;
- } else if (decNumberIsQNaN(&dfp->b)) {
- dfp->t = dfp->b;
- }
-}
-
-#define DFP_HELPER_QUAI(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, \
- uint32_t te, uint32_t rmc) \
-{ \
- struct PPC_DFP dfp; \
- \
- dfp_prepare_decimal##size(&dfp, 0, b, env); \
- \
- decNumberFromUInt32(&dfp.a, 1); \
- dfp.a.exponent = (int32_t)((int8_t)(te << 3) >> 3); \
- \
- dfp_quantize(rmc, &dfp); \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
- &dfp.context); \
- QUA_PPs(&dfp); \
- \
- if (size == 64) { \
- t[0] = dfp.t64[0]; \
- } else if (size == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
-}
-
-DFP_HELPER_QUAI(dquai, 64)
-DFP_HELPER_QUAI(dquaiq, 128)
-
-#define DFP_HELPER_QUA(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, \
- uint64_t *b, uint32_t rmc) \
-{ \
- struct PPC_DFP dfp; \
- \
- dfp_prepare_decimal##size(&dfp, a, b, env); \
- \
- dfp_quantize(rmc, &dfp); \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
- &dfp.context); \
- QUA_PPs(&dfp); \
- \
- if (size == 64) { \
- t[0] = dfp.t64[0]; \
- } else if (size == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
-}
-
-DFP_HELPER_QUA(dqua, 64)
-DFP_HELPER_QUA(dquaq, 128)
-
-static void _dfp_reround(uint8_t rmc, int32_t ref_sig, int32_t xmax,
- struct PPC_DFP *dfp)
-{
- int msd_orig, msd_rslt;
-
- if (unlikely((ref_sig == 0) || (dfp->b.digits <= ref_sig))) {
- dfp->t = dfp->b;
- if (decNumberIsSNaN(&dfp->b)) {
- dfp_makeQNaN(&dfp->t);
- dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXSNAN, FPSCR_VE);
- }
- return;
- }
-
- /* Reround is equivalent to quantizing b with 1**E(n) where */
- /* n = exp(b) + numDigits(b) - reference_significance. */
-
- decNumberFromUInt32(&dfp->a, 1);
- dfp->a.exponent = dfp->b.exponent + dfp->b.digits - ref_sig;
-
- if (unlikely(dfp->a.exponent > xmax)) {
- dfp->t.digits = 0;
- dfp->t.bits &= ~DECNEG;
- dfp_makeQNaN(&dfp->t);
- dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FPSCR_VE);
- return;
- }
-
- dfp_quantize(rmc, dfp);
-
- msd_orig = dfp_get_digit(&dfp->b, dfp->b.digits-1);
- msd_rslt = dfp_get_digit(&dfp->t, dfp->t.digits-1);
-
- /* If the quantization resulted in rounding up to the next magnitude, */
- /* then we need to shift the significand and adjust the exponent. */
-
- if (unlikely((msd_orig == 9) && (msd_rslt == 1))) {
-
- decNumber negone;
-
- decNumberFromInt32(&negone, -1);
- decNumberShift(&dfp->t, &dfp->t, &negone, &dfp->context);
- dfp->t.exponent++;
-
- if (unlikely(dfp->t.exponent > xmax)) {
- dfp_makeQNaN(&dfp->t);
- dfp->t.digits = 0;
- dfp_set_FPSCR_flag(dfp, FP_VX | FP_VXCVI, FP_VE);
- /* Inhibit XX in this case */
- decContextClearStatus(&dfp->context, DEC_Inexact);
- }
- }
-}
-
-#define DFP_HELPER_RRND(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, \
- uint64_t *b, uint32_t rmc) \
-{ \
- struct PPC_DFP dfp; \
- int32_t ref_sig = *a & 0x3F; \
- int32_t xmax = ((size) == 64) ? 369 : 6111; \
- \
- dfp_prepare_decimal##size(&dfp, 0, b, env); \
- \
- _dfp_reround(rmc, ref_sig, xmax, &dfp); \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
- &dfp.context); \
- QUA_PPs(&dfp); \
- \
- if (size == 64) { \
- t[0] = dfp.t64[0]; \
- } else if (size == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
-}
-
-DFP_HELPER_RRND(drrnd, 64)
-DFP_HELPER_RRND(drrndq, 128)
-
-#define DFP_HELPER_RINT(op, postprocs, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, \
- uint32_t r, uint32_t rmc) \
-{ \
- struct PPC_DFP dfp; \
- \
- dfp_prepare_decimal##size(&dfp, 0, b, env); \
- \
- dfp_set_round_mode_from_immediate(r, rmc, &dfp); \
- decNumberToIntegralExact(&dfp.t, &dfp.b, &dfp.context); \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
- postprocs(&dfp); \
- \
- if (size == 64) { \
- t[0] = dfp.t64[0]; \
- } else if (size == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
-}
-
-static void RINTX_PPs(struct PPC_DFP *dfp)
-{
- dfp_set_FPRF_from_FRT(dfp);
- dfp_check_for_XX(dfp);
- dfp_check_for_VXSNAN(dfp);
-}
-
-DFP_HELPER_RINT(drintx, RINTX_PPs, 64)
-DFP_HELPER_RINT(drintxq, RINTX_PPs, 128)
-
-static void RINTN_PPs(struct PPC_DFP *dfp)
-{
- dfp_set_FPRF_from_FRT(dfp);
- dfp_check_for_VXSNAN(dfp);
-}
-
-DFP_HELPER_RINT(drintn, RINTN_PPs, 64)
-DFP_HELPER_RINT(drintnq, RINTN_PPs, 128)
-
-void helper_dctdp(CPUPPCState *env, uint64_t *t, uint64_t *b)
-{
- struct PPC_DFP dfp;
- uint32_t b_short = *b;
- dfp_prepare_decimal64(&dfp, 0, 0, env);
- decimal32ToNumber((decimal32 *)&b_short, &dfp.t);
- decimal64FromNumber((decimal64 *)t, &dfp.t, &dfp.context);
- dfp_set_FPRF_from_FRT(&dfp);
-}
-
-void helper_dctqpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
-{
- struct PPC_DFP dfp;
- dfp_prepare_decimal128(&dfp, 0, 0, env);
- decimal64ToNumber((decimal64 *)b, &dfp.t);
-
- dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp);
- dfp_set_FPRF_from_FRT(&dfp);
-
- decimal128FromNumber((decimal128 *)&dfp.t64, &dfp.t, &dfp.context);
- t[0] = dfp.t64[HI_IDX];
- t[1] = dfp.t64[LO_IDX];
-}
-
-void helper_drsp(CPUPPCState *env, uint64_t *t, uint64_t *b)
-{
- struct PPC_DFP dfp;
- uint32_t t_short = 0;
- dfp_prepare_decimal64(&dfp, 0, b, env);
- decimal32FromNumber((decimal32 *)&t_short, &dfp.b, &dfp.context);
- decimal32ToNumber((decimal32 *)&t_short, &dfp.t);
-
- dfp_set_FPRF_from_FRT_short(&dfp);
- dfp_check_for_OX(&dfp);
- dfp_check_for_UX(&dfp);
- dfp_check_for_XX(&dfp);
-
- *t = t_short;
-}
-
-void helper_drdpq(CPUPPCState *env, uint64_t *t, uint64_t *b)
-{
- struct PPC_DFP dfp;
- dfp_prepare_decimal128(&dfp, 0, b, env);
- decimal64FromNumber((decimal64 *)&dfp.t64, &dfp.b, &dfp.context);
- decimal64ToNumber((decimal64 *)&dfp.t64, &dfp.t);
-
- dfp_check_for_VXSNAN_and_convert_to_QNaN(&dfp);
- dfp_set_FPRF_from_FRT_long(&dfp);
- dfp_check_for_OX(&dfp);
- dfp_check_for_UX(&dfp);
- dfp_check_for_XX(&dfp);
-
- decimal64FromNumber((decimal64 *)dfp.t64, &dfp.t, &dfp.context);
- t[0] = dfp.t64[0];
- t[1] = 0;
-}
-
-#define DFP_HELPER_CFFIX(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \
-{ \
- struct PPC_DFP dfp; \
- dfp_prepare_decimal##size(&dfp, 0, b, env); \
- decNumberFromInt64(&dfp.t, (int64_t)(*b)); \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, &dfp.context); \
- CFFIX_PPs(&dfp); \
- \
- if (size == 64) { \
- t[0] = dfp.t64[0]; \
- } else if (size == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
-}
-
-static void CFFIX_PPs(struct PPC_DFP *dfp)
-{
- dfp_set_FPRF_from_FRT(dfp);
- dfp_check_for_XX(dfp);
-}
-
-DFP_HELPER_CFFIX(dcffix, 64)
-DFP_HELPER_CFFIX(dcffixq, 128)
-
-#define DFP_HELPER_CTFIX(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \
-{ \
- struct PPC_DFP dfp; \
- dfp_prepare_decimal##size(&dfp, 0, b, env); \
- \
- if (unlikely(decNumberIsSpecial(&dfp.b))) { \
- uint64_t invalid_flags = FP_VX | FP_VXCVI; \
- if (decNumberIsInfinite(&dfp.b)) { \
- dfp.t64[0] = decNumberIsNegative(&dfp.b) ? INT64_MIN : INT64_MAX; \
- } else { /* NaN */ \
- dfp.t64[0] = INT64_MIN; \
- if (decNumberIsSNaN(&dfp.b)) { \
- invalid_flags |= FP_VXSNAN; \
- } \
- } \
- dfp_set_FPSCR_flag(&dfp, invalid_flags, FP_VE); \
- } else if (unlikely(decNumberIsZero(&dfp.b))) { \
- dfp.t64[0] = 0; \
- } else { \
- decNumberToIntegralExact(&dfp.b, &dfp.b, &dfp.context); \
- dfp.t64[0] = decNumberIntegralToInt64(&dfp.b, &dfp.context); \
- if (decContextTestStatus(&dfp.context, DEC_Invalid_operation)) { \
- dfp.t64[0] = decNumberIsNegative(&dfp.b) ? INT64_MIN : INT64_MAX; \
- dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FP_VE); \
- } else { \
- dfp_check_for_XX(&dfp); \
- } \
- } \
- \
- *t = dfp.t64[0]; \
-}
-
-DFP_HELPER_CTFIX(dctfix, 64)
-DFP_HELPER_CTFIX(dctfixq, 128)
-
-static inline void dfp_set_bcd_digit_64(uint64_t *t, uint8_t digit,
- unsigned n)
-{
- *t |= ((uint64_t)(digit & 0xF) << (n << 2));
-}
-
-static inline void dfp_set_bcd_digit_128(uint64_t *t, uint8_t digit,
- unsigned n)
-{
- t[(n & 0x10) ? HI_IDX : LO_IDX] |=
- ((uint64_t)(digit & 0xF) << ((n & 15) << 2));
-}
-
-static inline void dfp_set_sign_64(uint64_t *t, uint8_t sgn)
-{
- *t <<= 4;
- *t |= (sgn & 0xF);
-}
-
-static inline void dfp_set_sign_128(uint64_t *t, uint8_t sgn)
-{
- t[HI_IDX] <<= 4;
- t[HI_IDX] |= (t[LO_IDX] >> 60);
- t[LO_IDX] <<= 4;
- t[LO_IDX] |= (sgn & 0xF);
-}
-
-#define DFP_HELPER_DEDPD(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t sp) \
-{ \
- struct PPC_DFP dfp; \
- uint8_t digits[34]; \
- int i, N; \
- \
- dfp_prepare_decimal##size(&dfp, 0, b, env); \
- \
- decNumberGetBCD(&dfp.b, digits); \
- dfp.t64[0] = dfp.t64[1] = 0; \
- N = dfp.b.digits; \
- \
- for (i = 0; (i < N) && (i < (size)/4); i++) { \
- dfp_set_bcd_digit_##size(dfp.t64, digits[N-i-1], i); \
- } \
- \
- if (sp & 2) { \
- uint8_t sgn; \
- \
- if (decNumberIsNegative(&dfp.b)) { \
- sgn = 0xD; \
- } else { \
- sgn = ((sp & 1) ? 0xF : 0xC); \
- } \
- dfp_set_sign_##size(dfp.t64, sgn); \
- } \
- \
- if (size == 64) { \
- t[0] = dfp.t64[0]; \
- } else if (size == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
-}
-
-DFP_HELPER_DEDPD(ddedpd, 64)
-DFP_HELPER_DEDPD(ddedpdq, 128)
-
-static inline uint8_t dfp_get_bcd_digit_64(uint64_t *t, unsigned n)
-{
- return *t >> ((n << 2) & 63) & 15;
-}
-
-static inline uint8_t dfp_get_bcd_digit_128(uint64_t *t, unsigned n)
-{
- return t[(n & 0x10) ? HI_IDX : LO_IDX] >> ((n << 2) & 63) & 15;
-}
-
-#define DFP_HELPER_ENBCD(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b, uint32_t s) \
-{ \
- struct PPC_DFP dfp; \
- uint8_t digits[32]; \
- int n = 0, offset = 0, sgn = 0, nonzero = 0; \
- \
- dfp_prepare_decimal##size(&dfp, 0, b, env); \
- \
- decNumberZero(&dfp.t); \
- \
- if (s) { \
- uint8_t sgnNibble = dfp_get_bcd_digit_##size(dfp.b64, offset++); \
- switch (sgnNibble) { \
- case 0xD: \
- case 0xB: \
- sgn = 1; \
- break; \
- case 0xC: \
- case 0xF: \
- case 0xA: \
- case 0xE: \
- sgn = 0; \
- break; \
- default: \
- dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE); \
- return; \
- } \
- } \
- \
- while (offset < (size)/4) { \
- n++; \
- digits[(size)/4-n] = dfp_get_bcd_digit_##size(dfp.b64, offset++); \
- if (digits[(size)/4-n] > 10) { \
- dfp_set_FPSCR_flag(&dfp, FP_VX | FP_VXCVI, FPSCR_VE); \
- return; \
- } else { \
- nonzero |= (digits[(size)/4-n] > 0); \
- } \
- } \
- \
- if (nonzero) { \
- decNumberSetBCD(&dfp.t, digits+((size)/4)-n, n); \
- } \
- \
- if (s && sgn) { \
- dfp.t.bits |= DECNEG; \
- } \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
- &dfp.context); \
- dfp_set_FPRF_from_FRT(&dfp); \
- if ((size) == 64) { \
- t[0] = dfp.t64[0]; \
- } else if ((size) == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
-}
-
-DFP_HELPER_ENBCD(denbcd, 64)
-DFP_HELPER_ENBCD(denbcdq, 128)
-
-#define DFP_HELPER_XEX(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *b) \
-{ \
- struct PPC_DFP dfp; \
- \
- dfp_prepare_decimal##size(&dfp, 0, b, env); \
- \
- if (unlikely(decNumberIsSpecial(&dfp.b))) { \
- if (decNumberIsInfinite(&dfp.b)) { \
- *t = -1; \
- } else if (decNumberIsSNaN(&dfp.b)) { \
- *t = -3; \
- } else if (decNumberIsQNaN(&dfp.b)) { \
- *t = -2; \
- } else { \
- assert(0); \
- } \
- } else { \
- if ((size) == 64) { \
- *t = dfp.b.exponent + 398; \
- } else if ((size) == 128) { \
- *t = dfp.b.exponent + 6176; \
- } else { \
- assert(0); \
- } \
- } \
-}
-
-DFP_HELPER_XEX(dxex, 64)
-DFP_HELPER_XEX(dxexq, 128)
-
-static void dfp_set_raw_exp_64(uint64_t *t, uint64_t raw)
-{
- *t &= 0x8003ffffffffffffULL;
- *t |= (raw << (63-13));
-}
-
-static void dfp_set_raw_exp_128(uint64_t *t, uint64_t raw)
-{
- t[HI_IDX] &= 0x80003fffffffffffULL;
- t[HI_IDX] |= (raw << (63-17));
-}
-
-#define DFP_HELPER_IEX(op, size) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, uint64_t *b) \
-{ \
- struct PPC_DFP dfp; \
- uint64_t raw_qnan, raw_snan, raw_inf, max_exp; \
- int bias; \
- int64_t exp = *((int64_t *)a); \
- \
- dfp_prepare_decimal##size(&dfp, 0, b, env); \
- \
- if ((size) == 64) { \
- max_exp = 767; \
- raw_qnan = 0x1F00; \
- raw_snan = 0x1F80; \
- raw_inf = 0x1E00; \
- bias = 398; \
- } else if ((size) == 128) { \
- max_exp = 12287; \
- raw_qnan = 0x1f000; \
- raw_snan = 0x1f800; \
- raw_inf = 0x1e000; \
- bias = 6176; \
- } else { \
- assert(0); \
- } \
- \
- if (unlikely((exp < 0) || (exp > max_exp))) { \
- dfp.t64[0] = dfp.b64[0]; \
- dfp.t64[1] = dfp.b64[1]; \
- if (exp == -1) { \
- dfp_set_raw_exp_##size(dfp.t64, raw_inf); \
- } else if (exp == -3) { \
- dfp_set_raw_exp_##size(dfp.t64, raw_snan); \
- } else { \
- dfp_set_raw_exp_##size(dfp.t64, raw_qnan); \
- } \
- } else { \
- dfp.t = dfp.b; \
- if (unlikely(decNumberIsSpecial(&dfp.t))) { \
- dfp.t.bits &= ~DECSPECIAL; \
- } \
- dfp.t.exponent = exp - bias; \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
- &dfp.context); \
- } \
- if (size == 64) { \
- t[0] = dfp.t64[0]; \
- } else if (size == 128) { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
-}
-
-DFP_HELPER_IEX(diex, 64)
-DFP_HELPER_IEX(diexq, 128)
-
-static void dfp_clear_lmd_from_g5msb(uint64_t *t)
-{
-
- /* The most significant 5 bits of the PowerPC DFP format combine bits */
- /* from the left-most decimal digit (LMD) and the biased exponent. */
- /* This routine clears the LMD bits while preserving the exponent */
- /* bits. See "Figure 80: Encoding of bits 0:4 of the G field for */
- /* Finite Numbers" in the Power ISA for additional details. */
-
- uint64_t g5msb = (*t >> 58) & 0x1F;
-
- if ((g5msb >> 3) < 3) { /* LMD in [0-7] ? */
- *t &= ~(7ULL << 58);
- } else {
- switch (g5msb & 7) {
- case 0:
- case 1:
- g5msb = 0;
- break;
- case 2:
- case 3:
- g5msb = 0x8;
- break;
- case 4:
- case 5:
- g5msb = 0x10;
- break;
- case 6:
- g5msb = 0x1E;
- break;
- case 7:
- g5msb = 0x1F;
- break;
- }
-
- *t &= ~(0x1fULL << 58);
- *t |= (g5msb << 58);
- }
-}
-
-#define DFP_HELPER_SHIFT(op, size, shift_left) \
-void helper_##op(CPUPPCState *env, uint64_t *t, uint64_t *a, \
- uint32_t sh) \
-{ \
- struct PPC_DFP dfp; \
- unsigned max_digits = ((size) == 64) ? 16 : 34; \
- \
- dfp_prepare_decimal##size(&dfp, a, 0, env); \
- \
- if (sh <= max_digits) { \
- \
- decNumber shd; \
- unsigned special = dfp.a.bits & DECSPECIAL; \
- \
- if (shift_left) { \
- decNumberFromUInt32(&shd, sh); \
- } else { \
- decNumberFromInt32(&shd, -((int32_t)sh)); \
- } \
- \
- dfp.a.bits &= ~DECSPECIAL; \
- decNumberShift(&dfp.t, &dfp.a, &shd, &dfp.context); \
- \
- dfp.t.bits |= special; \
- if (special && (dfp.t.digits >= max_digits)) { \
- dfp.t.digits = max_digits - 1; \
- } \
- \
- decimal##size##FromNumber((decimal##size *)dfp.t64, &dfp.t, \
- &dfp.context); \
- } else { \
- if ((size) == 64) { \
- dfp.t64[0] = dfp.a64[0] & 0xFFFC000000000000ULL; \
- dfp_clear_lmd_from_g5msb(dfp.t64); \
- } else { \
- dfp.t64[HI_IDX] = dfp.a64[HI_IDX] & \
- 0xFFFFC00000000000ULL; \
- dfp_clear_lmd_from_g5msb(dfp.t64 + HI_IDX); \
- dfp.t64[LO_IDX] = 0; \
- } \
- } \
- \
- if ((size) == 64) { \
- t[0] = dfp.t64[0]; \
- } else { \
- t[0] = dfp.t64[HI_IDX]; \
- t[1] = dfp.t64[LO_IDX]; \
- } \
-}
-
-DFP_HELPER_SHIFT(dscli, 64, 1)
-DFP_HELPER_SHIFT(dscliq, 128, 1)
-DFP_HELPER_SHIFT(dscri, 64, 0)
-DFP_HELPER_SHIFT(dscriq, 128, 0)
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
deleted file mode 100644
index 93369d4fe5..0000000000
--- a/target-ppc/excp_helper.c
+++ /dev/null
@@ -1,1142 +0,0 @@
-/*
- * PowerPC exception emulation helpers for QEMU.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
-
-#include "helper_regs.h"
-
-//#define DEBUG_OP
-//#define DEBUG_SOFTWARE_TLB
-//#define DEBUG_EXCEPTIONS
-
-#ifdef DEBUG_EXCEPTIONS
-# define LOG_EXCP(...) qemu_log(__VA_ARGS__)
-#else
-# define LOG_EXCP(...) do { } while (0)
-#endif
-
-/*****************************************************************************/
-/* PowerPC Hypercall emulation */
-
-void (*cpu_ppc_hypercall)(PowerPCCPU *);
-
-/*****************************************************************************/
-/* Exception processing */
-#if defined(CONFIG_USER_ONLY)
-void ppc_cpu_do_interrupt(CPUState *cs)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
-
- cs->exception_index = POWERPC_EXCP_NONE;
- env->error_code = 0;
-}
-
-static void ppc_hw_interrupt(CPUPPCState *env)
-{
- CPUState *cs = CPU(ppc_env_get_cpu(env));
-
- cs->exception_index = POWERPC_EXCP_NONE;
- env->error_code = 0;
-}
-#else /* defined(CONFIG_USER_ONLY) */
-static inline void dump_syscall(CPUPPCState *env)
-{
- qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 " r3=%016" PRIx64
- " r4=%016" PRIx64 " r5=%016" PRIx64 " r6=%016" PRIx64
- " nip=" TARGET_FMT_lx "\n",
- ppc_dump_gpr(env, 0), ppc_dump_gpr(env, 3),
- ppc_dump_gpr(env, 4), ppc_dump_gpr(env, 5),
- ppc_dump_gpr(env, 6), env->nip);
-}
-
-/* Note that this function should be greatly optimized
- * when called with a constant excp, from ppc_hw_interrupt
- */
-static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
-{
- CPUState *cs = CPU(cpu);
- CPUPPCState *env = &cpu->env;
- target_ulong msr, new_msr, vector;
- int srr0, srr1, asrr0, asrr1, lev, ail;
- bool lpes0;
-
- qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx
- " => %08x (%02x)\n", env->nip, excp, env->error_code);
-
- /* new srr1 value excluding must-be-zero bits */
- if (excp_model == POWERPC_EXCP_BOOKE) {
- msr = env->msr;
- } else {
- msr = env->msr & ~0x783f0000ULL;
- }
-
- /* new interrupt handler msr preserves existing HV and ME unless
- * explicitly overriden
- */
- new_msr = env->msr & (((target_ulong)1 << MSR_ME) | MSR_HVB);
-
- /* target registers */
- srr0 = SPR_SRR0;
- srr1 = SPR_SRR1;
- asrr0 = -1;
- asrr1 = -1;
-
- /* check for special resume at 0x100 from doze/nap/sleep/winkle on P7/P8 */
- if (env->in_pm_state) {
- env->in_pm_state = false;
-
- /* Pretend to be returning from doze always as we don't lose state */
- msr |= (0x1ull << (63 - 47));
-
- /* Non-machine check are routed to 0x100 with a wakeup cause
- * encoded in SRR1
- */
- if (excp != POWERPC_EXCP_MCHECK) {
- switch (excp) {
- case POWERPC_EXCP_RESET:
- msr |= 0x4ull << (63 - 45);
- break;
- case POWERPC_EXCP_EXTERNAL:
- msr |= 0x8ull << (63 - 45);
- break;
- case POWERPC_EXCP_DECR:
- msr |= 0x6ull << (63 - 45);
- break;
- case POWERPC_EXCP_SDOOR:
- msr |= 0x5ull << (63 - 45);
- break;
- case POWERPC_EXCP_SDOOR_HV:
- msr |= 0x3ull << (63 - 45);
- break;
- case POWERPC_EXCP_HV_MAINT:
- msr |= 0xaull << (63 - 45);
- break;
- default:
- cpu_abort(cs, "Unsupported exception %d in Power Save mode\n",
- excp);
- }
- excp = POWERPC_EXCP_RESET;
- }
- }
-
- /* Exception targetting modifiers
- *
- * LPES0 is supported on POWER7/8
- * LPES1 is not supported (old iSeries mode)
- *
- * On anything else, we behave as if LPES0 is 1
- * (externals don't alter MSR:HV)
- *
- * AIL is initialized here but can be cleared by
- * selected exceptions
- */
-#if defined(TARGET_PPC64)
- if (excp_model == POWERPC_EXCP_POWER7 ||
- excp_model == POWERPC_EXCP_POWER8) {
- lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
- if (excp_model == POWERPC_EXCP_POWER8) {
- ail = (env->spr[SPR_LPCR] & LPCR_AIL) >> LPCR_AIL_SHIFT;
- } else {
- ail = 0;
- }
- } else
-#endif /* defined(TARGET_PPC64) */
- {
- lpes0 = true;
- ail = 0;
- }
-
- /* Hypervisor emulation assistance interrupt only exists on server
- * arch 2.05 server or later. We also don't want to generate it if
- * we don't have HVB in msr_mask (PAPR mode).
- */
- if (excp == POWERPC_EXCP_HV_EMU
-#if defined(TARGET_PPC64)
- && !((env->mmu_model & POWERPC_MMU_64) && (env->msr_mask & MSR_HVB))
-#endif /* defined(TARGET_PPC64) */
-
- ) {
- excp = POWERPC_EXCP_PROGRAM;
- }
-
- switch (excp) {
- case POWERPC_EXCP_NONE:
- /* Should never happen */
- return;
- case POWERPC_EXCP_CRITICAL: /* Critical input */
- switch (excp_model) {
- case POWERPC_EXCP_40x:
- srr0 = SPR_40x_SRR2;
- srr1 = SPR_40x_SRR3;
- break;
- case POWERPC_EXCP_BOOKE:
- srr0 = SPR_BOOKE_CSRR0;
- srr1 = SPR_BOOKE_CSRR1;
- break;
- case POWERPC_EXCP_G2:
- break;
- default:
- goto excp_invalid;
- }
- break;
- case POWERPC_EXCP_MCHECK: /* Machine check exception */
- if (msr_me == 0) {
- /* Machine check exception is not enabled.
- * Enter checkstop state.
- */
- fprintf(stderr, "Machine check while not allowed. "
- "Entering checkstop state\n");
- if (qemu_log_separate()) {
- qemu_log("Machine check while not allowed. "
- "Entering checkstop state\n");
- }
- cs->halted = 1;
- cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
- }
- if (env->msr_mask & MSR_HVB) {
- /* ISA specifies HV, but can be delivered to guest with HV clear
- * (e.g., see FWNMI in PAPR).
- */
- new_msr |= (target_ulong)MSR_HVB;
- }
- ail = 0;
-
- /* machine check exceptions don't have ME set */
- new_msr &= ~((target_ulong)1 << MSR_ME);
-
- /* XXX: should also have something loaded in DAR / DSISR */
- switch (excp_model) {
- case POWERPC_EXCP_40x:
- srr0 = SPR_40x_SRR2;
- srr1 = SPR_40x_SRR3;
- break;
- case POWERPC_EXCP_BOOKE:
- /* FIXME: choose one or the other based on CPU type */
- srr0 = SPR_BOOKE_MCSRR0;
- srr1 = SPR_BOOKE_MCSRR1;
- asrr0 = SPR_BOOKE_CSRR0;
- asrr1 = SPR_BOOKE_CSRR1;
- break;
- default:
- break;
- }
- break;
- case POWERPC_EXCP_DSI: /* Data storage exception */
- LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx
- "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
- break;
- case POWERPC_EXCP_ISI: /* Instruction storage exception */
- LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx
- "\n", msr, env->nip);
- msr |= env->error_code;
- break;
- case POWERPC_EXCP_EXTERNAL: /* External input */
- cs = CPU(cpu);
-
- if (!lpes0) {
- new_msr |= (target_ulong)MSR_HVB;
- new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
- srr0 = SPR_HSRR0;
- srr1 = SPR_HSRR1;
- }
- if (env->mpic_proxy) {
- /* IACK the IRQ on delivery */
- env->spr[SPR_BOOKE_EPR] = ldl_phys(cs->as, env->mpic_iack);
- }
- break;
- case POWERPC_EXCP_ALIGN: /* Alignment exception */
- /* Get rS/rD and rA from faulting opcode */
- /* Note: the opcode fields will not be set properly for a direct
- * store load/store, but nobody cares as nobody actually uses
- * direct store segments.
- */
- env->spr[SPR_DSISR] |= (env->error_code & 0x03FF0000) >> 16;
- break;
- case POWERPC_EXCP_PROGRAM: /* Program exception */
- switch (env->error_code & ~0xF) {
- case POWERPC_EXCP_FP:
- if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
- LOG_EXCP("Ignore floating point exception\n");
- cs->exception_index = POWERPC_EXCP_NONE;
- env->error_code = 0;
- return;
- }
-
- /* FP exceptions always have NIP pointing to the faulting
- * instruction, so always use store_next and claim we are
- * precise in the MSR.
- */
- msr |= 0x00100000;
- break;
- case POWERPC_EXCP_INVAL:
- LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);
- msr |= 0x00080000;
- env->spr[SPR_BOOKE_ESR] = ESR_PIL;
- break;
- case POWERPC_EXCP_PRIV:
- msr |= 0x00040000;
- env->spr[SPR_BOOKE_ESR] = ESR_PPR;
- break;
- case POWERPC_EXCP_TRAP:
- msr |= 0x00020000;
- env->spr[SPR_BOOKE_ESR] = ESR_PTR;
- break;
- default:
- /* Should never occur */
- cpu_abort(cs, "Invalid program exception %d. Aborting\n",
- env->error_code);
- break;
- }
- break;
- case POWERPC_EXCP_SYSCALL: /* System call exception */
- dump_syscall(env);
- lev = env->error_code;
-
- /* We need to correct the NIP which in this case is supposed
- * to point to the next instruction
- */
- env->nip += 4;
-
- /* "PAPR mode" built-in hypercall emulation */
- if ((lev == 1) && cpu_ppc_hypercall) {
- cpu_ppc_hypercall(cpu);
- return;
- }
- if (lev == 1) {
- new_msr |= (target_ulong)MSR_HVB;
- }
- break;
- case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
- case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
- case POWERPC_EXCP_DECR: /* Decrementer exception */
- break;
- case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
- /* FIT on 4xx */
- LOG_EXCP("FIT exception\n");
- break;
- case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
- LOG_EXCP("WDT exception\n");
- switch (excp_model) {
- case POWERPC_EXCP_BOOKE:
- srr0 = SPR_BOOKE_CSRR0;
- srr1 = SPR_BOOKE_CSRR1;
- break;
- default:
- break;
- }
- break;
- case POWERPC_EXCP_DTLB: /* Data TLB error */
- case POWERPC_EXCP_ITLB: /* Instruction TLB error */
- break;
- case POWERPC_EXCP_DEBUG: /* Debug interrupt */
- switch (excp_model) {
- case POWERPC_EXCP_BOOKE:
- /* FIXME: choose one or the other based on CPU type */
- srr0 = SPR_BOOKE_DSRR0;
- srr1 = SPR_BOOKE_DSRR1;
- asrr0 = SPR_BOOKE_CSRR0;
- asrr1 = SPR_BOOKE_CSRR1;
- break;
- default:
- break;
- }
- /* XXX: TODO */
- cpu_abort(cs, "Debug exception is not implemented yet !\n");
- break;
- case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable */
- env->spr[SPR_BOOKE_ESR] = ESR_SPV;
- break;
- case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */
- /* XXX: TODO */
- cpu_abort(cs, "Embedded floating point data exception "
- "is not implemented yet !\n");
- env->spr[SPR_BOOKE_ESR] = ESR_SPV;
- break;
- case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */
- /* XXX: TODO */
- cpu_abort(cs, "Embedded floating point round exception "
- "is not implemented yet !\n");
- env->spr[SPR_BOOKE_ESR] = ESR_SPV;
- break;
- case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */
- /* XXX: TODO */
- cpu_abort(cs,
- "Performance counter exception is not implemented yet !\n");
- break;
- case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */
- break;
- case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */
- srr0 = SPR_BOOKE_CSRR0;
- srr1 = SPR_BOOKE_CSRR1;
- break;
- case POWERPC_EXCP_RESET: /* System reset exception */
- /* A power-saving exception sets ME, otherwise it is unchanged */
- if (msr_pow) {
- /* indicate that we resumed from power save mode */
- msr |= 0x10000;
- new_msr |= ((target_ulong)1 << MSR_ME);
- }
- if (env->msr_mask & MSR_HVB) {
- /* ISA specifies HV, but can be delivered to guest with HV clear
- * (e.g., see FWNMI in PAPR, NMI injection in QEMU).
- */
- new_msr |= (target_ulong)MSR_HVB;
- } else {
- if (msr_pow) {
- cpu_abort(cs, "Trying to deliver power-saving system reset "
- "exception %d with no HV support\n", excp);
- }
- }
- ail = 0;
- break;
- case POWERPC_EXCP_DSEG: /* Data segment exception */
- case POWERPC_EXCP_ISEG: /* Instruction segment exception */
- case POWERPC_EXCP_TRACE: /* Trace exception */
- break;
- case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
- case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
- case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */
- case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
- case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */
- case POWERPC_EXCP_HV_EMU:
- srr0 = SPR_HSRR0;
- srr1 = SPR_HSRR1;
- new_msr |= (target_ulong)MSR_HVB;
- new_msr |= env->msr & ((target_ulong)1 << MSR_RI);
- break;
- case POWERPC_EXCP_VPU: /* Vector unavailable exception */
- case POWERPC_EXCP_VSXU: /* VSX unavailable exception */
- case POWERPC_EXCP_FU: /* Facility unavailable exception */
-#ifdef TARGET_PPC64
- env->spr[SPR_FSCR] |= ((target_ulong)env->error_code << 56);
-#endif
- break;
- case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */
- LOG_EXCP("PIT exception\n");
- break;
- case POWERPC_EXCP_IO: /* IO error exception */
- /* XXX: TODO */
- cpu_abort(cs, "601 IO error exception is not implemented yet !\n");
- break;
- case POWERPC_EXCP_RUNM: /* Run mode exception */
- /* XXX: TODO */
- cpu_abort(cs, "601 run mode exception is not implemented yet !\n");
- break;
- case POWERPC_EXCP_EMUL: /* Emulation trap exception */
- /* XXX: TODO */
- cpu_abort(cs, "602 emulation trap exception "
- "is not implemented yet !\n");
- break;
- case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
- switch (excp_model) {
- case POWERPC_EXCP_602:
- case POWERPC_EXCP_603:
- case POWERPC_EXCP_603E:
- case POWERPC_EXCP_G2:
- goto tlb_miss_tgpr;
- case POWERPC_EXCP_7x5:
- goto tlb_miss;
- case POWERPC_EXCP_74xx:
- goto tlb_miss_74xx;
- default:
- cpu_abort(cs, "Invalid instruction TLB miss exception\n");
- break;
- }
- break;
- case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
- switch (excp_model) {
- case POWERPC_EXCP_602:
- case POWERPC_EXCP_603:
- case POWERPC_EXCP_603E:
- case POWERPC_EXCP_G2:
- goto tlb_miss_tgpr;
- case POWERPC_EXCP_7x5:
- goto tlb_miss;
- case POWERPC_EXCP_74xx:
- goto tlb_miss_74xx;
- default:
- cpu_abort(cs, "Invalid data load TLB miss exception\n");
- break;
- }
- break;
- case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
- switch (excp_model) {
- case POWERPC_EXCP_602:
- case POWERPC_EXCP_603:
- case POWERPC_EXCP_603E:
- case POWERPC_EXCP_G2:
- tlb_miss_tgpr:
- /* Swap temporary saved registers with GPRs */
- if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {
- new_msr |= (target_ulong)1 << MSR_TGPR;
- hreg_swap_gpr_tgpr(env);
- }
- goto tlb_miss;
- case POWERPC_EXCP_7x5:
- tlb_miss:
-#if defined(DEBUG_SOFTWARE_TLB)
- if (qemu_log_enabled()) {
- const char *es;
- target_ulong *miss, *cmp;
- int en;
-
- if (excp == POWERPC_EXCP_IFTLB) {
- es = "I";
- en = 'I';
- miss = &env->spr[SPR_IMISS];
- cmp = &env->spr[SPR_ICMP];
- } else {
- if (excp == POWERPC_EXCP_DLTLB) {
- es = "DL";
- } else {
- es = "DS";
- }
- en = 'D';
- miss = &env->spr[SPR_DMISS];
- cmp = &env->spr[SPR_DCMP];
- }
- qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
- TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "
- TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
- env->spr[SPR_HASH1], env->spr[SPR_HASH2],
- env->error_code);
- }
-#endif
- msr |= env->crf[0] << 28;
- msr |= env->error_code; /* key, D/I, S/L bits */
- /* Set way using a LRU mechanism */
- msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
- break;
- case POWERPC_EXCP_74xx:
- tlb_miss_74xx:
-#if defined(DEBUG_SOFTWARE_TLB)
- if (qemu_log_enabled()) {
- const char *es;
- target_ulong *miss, *cmp;
- int en;
-
- if (excp == POWERPC_EXCP_IFTLB) {
- es = "I";
- en = 'I';
- miss = &env->spr[SPR_TLBMISS];
- cmp = &env->spr[SPR_PTEHI];
- } else {
- if (excp == POWERPC_EXCP_DLTLB) {
- es = "DL";
- } else {
- es = "DS";
- }
- en = 'D';
- miss = &env->spr[SPR_TLBMISS];
- cmp = &env->spr[SPR_PTEHI];
- }
- qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "
- TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,
- env->error_code);
- }
-#endif
- msr |= env->error_code; /* key bit */
- break;
- default:
- cpu_abort(cs, "Invalid data store TLB miss exception\n");
- break;
- }
- break;
- case POWERPC_EXCP_FPA: /* Floating-point assist exception */
- /* XXX: TODO */
- cpu_abort(cs, "Floating point assist exception "
- "is not implemented yet !\n");
- break;
- case POWERPC_EXCP_DABR: /* Data address breakpoint */
- /* XXX: TODO */
- cpu_abort(cs, "DABR exception is not implemented yet !\n");
- break;
- case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
- /* XXX: TODO */
- cpu_abort(cs, "IABR exception is not implemented yet !\n");
- break;
- case POWERPC_EXCP_SMI: /* System management interrupt */
- /* XXX: TODO */
- cpu_abort(cs, "SMI exception is not implemented yet !\n");
- break;
- case POWERPC_EXCP_THERM: /* Thermal interrupt */
- /* XXX: TODO */
- cpu_abort(cs, "Thermal management exception "
- "is not implemented yet !\n");
- break;
- case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */
- /* XXX: TODO */
- cpu_abort(cs,
- "Performance counter exception is not implemented yet !\n");
- break;
- case POWERPC_EXCP_VPUA: /* Vector assist exception */
- /* XXX: TODO */
- cpu_abort(cs, "VPU assist exception is not implemented yet !\n");
- break;
- case POWERPC_EXCP_SOFTP: /* Soft patch exception */
- /* XXX: TODO */
- cpu_abort(cs,
- "970 soft-patch exception is not implemented yet !\n");
- break;
- case POWERPC_EXCP_MAINT: /* Maintenance exception */
- /* XXX: TODO */
- cpu_abort(cs,
- "970 maintenance exception is not implemented yet !\n");
- break;
- case POWERPC_EXCP_MEXTBR: /* Maskable external breakpoint */
- /* XXX: TODO */
- cpu_abort(cs, "Maskable external exception "
- "is not implemented yet !\n");
- break;
- case POWERPC_EXCP_NMEXTBR: /* Non maskable external breakpoint */
- /* XXX: TODO */
- cpu_abort(cs, "Non maskable external exception "
- "is not implemented yet !\n");
- break;
- default:
- excp_invalid:
- cpu_abort(cs, "Invalid PowerPC exception %d. Aborting\n", excp);
- break;
- }
-
- /* Save PC */
- env->spr[srr0] = env->nip;
-
- /* Save MSR */
- env->spr[srr1] = msr;
-
- /* Sanity check */
- if (!(env->msr_mask & MSR_HVB)) {
- if (new_msr & MSR_HVB) {
- cpu_abort(cs, "Trying to deliver HV exception (MSR) %d with "
- "no HV support\n", excp);
- }
- if (srr0 == SPR_HSRR0) {
- cpu_abort(cs, "Trying to deliver HV exception (HSRR) %d with "
- "no HV support\n", excp);
- }
- }
-
- /* If any alternate SRR register are defined, duplicate saved values */
- if (asrr0 != -1) {
- env->spr[asrr0] = env->spr[srr0];
- }
- if (asrr1 != -1) {
- env->spr[asrr1] = env->spr[srr1];
- }
-
- /* Sort out endianness of interrupt, this differs depending on the
- * CPU, the HV mode, etc...
- */
-#ifdef TARGET_PPC64
- if (excp_model == POWERPC_EXCP_POWER7) {
- if (!(new_msr & MSR_HVB) && (env->spr[SPR_LPCR] & LPCR_ILE)) {
- new_msr |= (target_ulong)1 << MSR_LE;
- }
- } else if (excp_model == POWERPC_EXCP_POWER8) {
- if (new_msr & MSR_HVB) {
- if (env->spr[SPR_HID0] & HID0_HILE) {
- new_msr |= (target_ulong)1 << MSR_LE;
- }
- } else if (env->spr[SPR_LPCR] & LPCR_ILE) {
- new_msr |= (target_ulong)1 << MSR_LE;
- }
- } else if (msr_ile) {
- new_msr |= (target_ulong)1 << MSR_LE;
- }
-#else
- if (msr_ile) {
- new_msr |= (target_ulong)1 << MSR_LE;
- }
-#endif
-
- /* Jump to handler */
- vector = env->excp_vectors[excp];
- if (vector == (target_ulong)-1ULL) {
- cpu_abort(cs, "Raised an exception without defined vector %d\n",
- excp);
- }
- vector |= env->excp_prefix;
-
- /* AIL only works if there is no HV transition and we are running with
- * translations enabled
- */
- if (!((msr >> MSR_IR) & 1) || !((msr >> MSR_DR) & 1) ||
- ((new_msr & MSR_HVB) && !(msr & MSR_HVB))) {
- ail = 0;
- }
- /* Handle AIL */
- if (ail) {
- new_msr |= (1 << MSR_IR) | (1 << MSR_DR);
- switch(ail) {
- case AIL_0001_8000:
- vector |= 0x18000;
- break;
- case AIL_C000_0000_0000_4000:
- vector |= 0xc000000000004000ull;
- break;
- default:
- cpu_abort(cs, "Invalid AIL combination %d\n", ail);
- break;
- }
- }
-
-#if defined(TARGET_PPC64)
- if (excp_model == POWERPC_EXCP_BOOKE) {
- if (env->spr[SPR_BOOKE_EPCR] & EPCR_ICM) {
- /* Cat.64-bit: EPCR.ICM is copied to MSR.CM */
- new_msr |= (target_ulong)1 << MSR_CM;
- } else {
- vector = (uint32_t)vector;
- }
- } else {
- if (!msr_isf && !(env->mmu_model & POWERPC_MMU_64)) {
- vector = (uint32_t)vector;
- } else {
- new_msr |= (target_ulong)1 << MSR_SF;
- }
- }
-#endif
- /* We don't use hreg_store_msr here as already have treated
- * any special case that could occur. Just store MSR and update hflags
- *
- * Note: We *MUST* not use hreg_store_msr() as-is anyway because it
- * will prevent setting of the HV bit which some exceptions might need
- * to do.
- */
- env->msr = new_msr & env->msr_mask;
- hreg_compute_hflags(env);
- env->nip = vector;
- /* Reset exception state */
- cs->exception_index = POWERPC_EXCP_NONE;
- env->error_code = 0;
-
- /* Any interrupt is context synchronizing, check if TCG TLB
- * needs a delayed flush on ppc64
- */
- check_tlb_flush(env, false);
-}
-
-void ppc_cpu_do_interrupt(CPUState *cs)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
-
- powerpc_excp(cpu, env->excp_model, cs->exception_index);
-}
-
-static void ppc_hw_interrupt(CPUPPCState *env)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
-#if 0
- CPUState *cs = CPU(cpu);
-
- qemu_log_mask(CPU_LOG_INT, "%s: %p pending %08x req %08x me %d ee %d\n",
- __func__, env, env->pending_interrupts,
- cs->interrupt_request, (int)msr_me, (int)msr_ee);
-#endif
- /* External reset */
- if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
- env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
- powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET);
- return;
- }
- /* Machine check exception */
- if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
- env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
- powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_MCHECK);
- return;
- }
-#if 0 /* TODO */
- /* External debug exception */
- if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
- env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
- powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DEBUG);
- return;
- }
-#endif
- /* Hypervisor decrementer exception */
- if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
- /* LPCR will be clear when not supported so this will work */
- bool hdice = !!(env->spr[SPR_LPCR] & LPCR_HDICE);
- if ((msr_ee != 0 || msr_hv == 0) && hdice) {
- /* HDEC clears on delivery */
- env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
- powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HDECR);
- return;
- }
- }
- /* Extermal interrupt can ignore MSR:EE under some circumstances */
- if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
- bool lpes0 = !!(env->spr[SPR_LPCR] & LPCR_LPES0);
- if (msr_ee != 0 || (env->has_hv_mode && msr_hv == 0 && !lpes0)) {
- powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EXTERNAL);
- return;
- }
- }
- if (msr_ce != 0) {
- /* External critical interrupt */
- if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
- /* Taking a critical external interrupt does not clear the external
- * critical interrupt status
- */
-#if 0
- env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CEXT);
-#endif
- powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_CRITICAL);
- return;
- }
- }
- if (msr_ee != 0) {
- /* Watchdog timer on embedded PowerPC */
- if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
- env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
- powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_WDT);
- return;
- }
- if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
- env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
- powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORCI);
- return;
- }
- /* Fixed interval timer on embedded PowerPC */
- if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
- env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
- powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_FIT);
- return;
- }
- /* Programmable interval timer on embedded PowerPC */
- if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
- env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
- powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PIT);
- return;
- }
- /* Decrementer exception */
- if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
- if (ppc_decr_clear_on_delivery(env)) {
- env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
- }
- powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DECR);
- return;
- }
- if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
- env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
- powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI);
- return;
- }
- if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
- env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
- powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PERFM);
- return;
- }
- /* Thermal interrupt */
- if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
- env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
- powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_THERM);
- return;
- }
- }
-}
-
-void ppc_cpu_do_system_reset(CPUState *cs)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
-
- powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET);
-}
-#endif /* !CONFIG_USER_ONLY */
-
-bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
-
- if (interrupt_request & CPU_INTERRUPT_HARD) {
- ppc_hw_interrupt(env);
- if (env->pending_interrupts == 0) {
- cs->interrupt_request &= ~CPU_INTERRUPT_HARD;
- }
- return true;
- }
- return false;
-}
-
-#if defined(DEBUG_OP)
-static void cpu_dump_rfi(target_ulong RA, target_ulong msr)
-{
- qemu_log("Return from exception at " TARGET_FMT_lx " with flags "
- TARGET_FMT_lx "\n", RA, msr);
-}
-#endif
-
-/*****************************************************************************/
-/* Exceptions processing helpers */
-
-void raise_exception_err_ra(CPUPPCState *env, uint32_t exception,
- uint32_t error_code, uintptr_t raddr)
-{
- CPUState *cs = CPU(ppc_env_get_cpu(env));
-
- cs->exception_index = exception;
- env->error_code = error_code;
- cpu_loop_exit_restore(cs, raddr);
-}
-
-void raise_exception_err(CPUPPCState *env, uint32_t exception,
- uint32_t error_code)
-{
- raise_exception_err_ra(env, exception, error_code, 0);
-}
-
-void raise_exception(CPUPPCState *env, uint32_t exception)
-{
- raise_exception_err_ra(env, exception, 0, 0);
-}
-
-void raise_exception_ra(CPUPPCState *env, uint32_t exception,
- uintptr_t raddr)
-{
- raise_exception_err_ra(env, exception, 0, raddr);
-}
-
-void helper_raise_exception_err(CPUPPCState *env, uint32_t exception,
- uint32_t error_code)
-{
- raise_exception_err_ra(env, exception, error_code, 0);
-}
-
-void helper_raise_exception(CPUPPCState *env, uint32_t exception)
-{
- raise_exception_err_ra(env, exception, 0, 0);
-}
-
-#if !defined(CONFIG_USER_ONLY)
-void helper_store_msr(CPUPPCState *env, target_ulong val)
-{
- uint32_t excp = hreg_store_msr(env, val, 0);
-
- if (excp != 0) {
- CPUState *cs = CPU(ppc_env_get_cpu(env));
- cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
- raise_exception(env, excp);
- }
-}
-
-#if defined(TARGET_PPC64)
-void helper_pminsn(CPUPPCState *env, powerpc_pm_insn_t insn)
-{
- CPUState *cs;
-
- cs = CPU(ppc_env_get_cpu(env));
- cs->halted = 1;
- env->in_pm_state = true;
-
- /* The architecture specifies that HDEC interrupts are
- * discarded in PM states
- */
- env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
-
- /* Technically, nap doesn't set EE, but if we don't set it
- * then ppc_hw_interrupt() won't deliver. We could add some
- * other tests there based on LPCR but it's simpler to just
- * whack EE in. It will be cleared by the 0x100 at wakeup
- * anyway. It will still be observable by the guest in SRR1
- * but this doesn't seem to be a problem.
- */
- env->msr |= (1ull << MSR_EE);
- raise_exception(env, EXCP_HLT);
-}
-#endif /* defined(TARGET_PPC64) */
-
-static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr)
-{
- CPUState *cs = CPU(ppc_env_get_cpu(env));
-
- /* MSR:POW cannot be set by any form of rfi */
- msr &= ~(1ULL << MSR_POW);
-
-#if defined(TARGET_PPC64)
- /* Switching to 32-bit ? Crop the nip */
- if (!msr_is_64bit(env, msr)) {
- nip = (uint32_t)nip;
- }
-#else
- nip = (uint32_t)nip;
-#endif
- /* XXX: beware: this is false if VLE is supported */
- env->nip = nip & ~((target_ulong)0x00000003);
- hreg_store_msr(env, msr, 1);
-#if defined(DEBUG_OP)
- cpu_dump_rfi(env->nip, env->msr);
-#endif
- /* No need to raise an exception here,
- * as rfi is always the last insn of a TB
- */
- cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
-
- /* Context synchronizing: check if TCG TLB needs flush */
- check_tlb_flush(env, false);
-}
-
-void helper_rfi(CPUPPCState *env)
-{
- do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1] & 0xfffffffful);
-}
-
-#define MSR_BOOK3S_MASK
-#if defined(TARGET_PPC64)
-void helper_rfid(CPUPPCState *env)
-{
- /* The architeture defines a number of rules for which bits
- * can change but in practice, we handle this in hreg_store_msr()
- * which will be called by do_rfi(), so there is no need to filter
- * here
- */
- do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
-}
-
-void helper_hrfid(CPUPPCState *env)
-{
- do_rfi(env, env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
-}
-#endif
-
-/*****************************************************************************/
-/* Embedded PowerPC specific helpers */
-void helper_40x_rfci(CPUPPCState *env)
-{
- do_rfi(env, env->spr[SPR_40x_SRR2], env->spr[SPR_40x_SRR3]);
-}
-
-void helper_rfci(CPUPPCState *env)
-{
- do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1]);
-}
-
-void helper_rfdi(CPUPPCState *env)
-{
- /* FIXME: choose CSRR1 or DSRR1 based on cpu type */
- do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1]);
-}
-
-void helper_rfmci(CPUPPCState *env)
-{
- /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */
- do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
-}
-#endif
-
-void helper_tw(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
- uint32_t flags)
-{
- if (!likely(!(((int32_t)arg1 < (int32_t)arg2 && (flags & 0x10)) ||
- ((int32_t)arg1 > (int32_t)arg2 && (flags & 0x08)) ||
- ((int32_t)arg1 == (int32_t)arg2 && (flags & 0x04)) ||
- ((uint32_t)arg1 < (uint32_t)arg2 && (flags & 0x02)) ||
- ((uint32_t)arg1 > (uint32_t)arg2 && (flags & 0x01))))) {
- raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_TRAP, GETPC());
- }
-}
-
-#if defined(TARGET_PPC64)
-void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2,
- uint32_t flags)
-{
- if (!likely(!(((int64_t)arg1 < (int64_t)arg2 && (flags & 0x10)) ||
- ((int64_t)arg1 > (int64_t)arg2 && (flags & 0x08)) ||
- ((int64_t)arg1 == (int64_t)arg2 && (flags & 0x04)) ||
- ((uint64_t)arg1 < (uint64_t)arg2 && (flags & 0x02)) ||
- ((uint64_t)arg1 > (uint64_t)arg2 && (flags & 0x01))))) {
- raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_TRAP, GETPC());
- }
-}
-#endif
-
-#if !defined(CONFIG_USER_ONLY)
-/*****************************************************************************/
-/* PowerPC 601 specific instructions (POWER bridge) */
-
-void helper_rfsvc(CPUPPCState *env)
-{
- do_rfi(env, env->lr, env->ctr & 0x0000FFFF);
-}
-
-/* Embedded.Processor Control */
-static int dbell2irq(target_ulong rb)
-{
- int msg = rb & DBELL_TYPE_MASK;
- int irq = -1;
-
- switch (msg) {
- case DBELL_TYPE_DBELL:
- irq = PPC_INTERRUPT_DOORBELL;
- break;
- case DBELL_TYPE_DBELL_CRIT:
- irq = PPC_INTERRUPT_CDOORBELL;
- break;
- case DBELL_TYPE_G_DBELL:
- case DBELL_TYPE_G_DBELL_CRIT:
- case DBELL_TYPE_G_DBELL_MC:
- /* XXX implement */
- default:
- break;
- }
-
- return irq;
-}
-
-void helper_msgclr(CPUPPCState *env, target_ulong rb)
-{
- int irq = dbell2irq(rb);
-
- if (irq < 0) {
- return;
- }
-
- env->pending_interrupts &= ~(1 << irq);
-}
-
-void helper_msgsnd(target_ulong rb)
-{
- int irq = dbell2irq(rb);
- int pir = rb & DBELL_PIRTAG_MASK;
- CPUState *cs;
-
- if (irq < 0) {
- return;
- }
-
- CPU_FOREACH(cs) {
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *cenv = &cpu->env;
-
- if ((rb & DBELL_BRDCAST) || (cenv->spr[SPR_BOOKE_PIR] == pir)) {
- cenv->pending_interrupts |= 1 << irq;
- cpu_interrupt(cs, CPU_INTERRUPT_HARD);
- }
- }
-}
-#endif
diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
deleted file mode 100644
index 8a389e19af..0000000000
--- a/target-ppc/fpu_helper.c
+++ /dev/null
@@ -1,2789 +0,0 @@
-/*
- * PowerPC floating point and SPE emulation helpers for QEMU.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "exec/exec-all.h"
-
-#define float64_snan_to_qnan(x) ((x) | 0x0008000000000000ULL)
-#define float32_snan_to_qnan(x) ((x) | 0x00400000)
-
-/*****************************************************************************/
-/* Floating point operations helpers */
-uint64_t helper_float32_to_float64(CPUPPCState *env, uint32_t arg)
-{
- CPU_FloatU f;
- CPU_DoubleU d;
-
- f.l = arg;
- d.d = float32_to_float64(f.f, &env->fp_status);
- return d.ll;
-}
-
-uint32_t helper_float64_to_float32(CPUPPCState *env, uint64_t arg)
-{
- CPU_FloatU f;
- CPU_DoubleU d;
-
- d.ll = arg;
- f.f = float64_to_float32(d.d, &env->fp_status);
- return f.l;
-}
-
-static inline int isden(float64 d)
-{
- CPU_DoubleU u;
-
- u.d = d;
-
- return ((u.ll >> 52) & 0x7FF) == 0;
-}
-
-static inline int ppc_float32_get_unbiased_exp(float32 f)
-{
- return ((f >> 23) & 0xFF) - 127;
-}
-
-static inline int ppc_float64_get_unbiased_exp(float64 f)
-{
- return ((f >> 52) & 0x7FF) - 1023;
-}
-
-void helper_compute_fprf(CPUPPCState *env, uint64_t arg)
-{
- CPU_DoubleU farg;
- int isneg;
- int fprf;
-
- farg.ll = arg;
- isneg = float64_is_neg(farg.d);
- if (unlikely(float64_is_any_nan(farg.d))) {
- if (float64_is_signaling_nan(farg.d, &env->fp_status)) {
- /* Signaling NaN: flags are undefined */
- fprf = 0x00;
- } else {
- /* Quiet NaN */
- fprf = 0x11;
- }
- } else if (unlikely(float64_is_infinity(farg.d))) {
- /* +/- infinity */
- if (isneg) {
- fprf = 0x09;
- } else {
- fprf = 0x05;
- }
- } else {
- if (float64_is_zero(farg.d)) {
- /* +/- zero */
- if (isneg) {
- fprf = 0x12;
- } else {
- fprf = 0x02;
- }
- } else {
- if (isden(farg.d)) {
- /* Denormalized numbers */
- fprf = 0x10;
- } else {
- /* Normalized numbers */
- fprf = 0x00;
- }
- if (isneg) {
- fprf |= 0x08;
- } else {
- fprf |= 0x04;
- }
- }
- }
- /* We update FPSCR_FPRF */
- env->fpscr &= ~(0x1F << FPSCR_FPRF);
- env->fpscr |= fprf << FPSCR_FPRF;
-}
-
-/* Floating-point invalid operations exception */
-static inline __attribute__((__always_inline__))
-uint64_t float_invalid_op_excp(CPUPPCState *env, int op, int set_fpcc)
-{
- CPUState *cs = CPU(ppc_env_get_cpu(env));
- uint64_t ret = 0;
- int ve;
-
- ve = fpscr_ve;
- switch (op) {
- case POWERPC_EXCP_FP_VXSNAN:
- env->fpscr |= 1 << FPSCR_VXSNAN;
- break;
- case POWERPC_EXCP_FP_VXSOFT:
- env->fpscr |= 1 << FPSCR_VXSOFT;
- break;
- case POWERPC_EXCP_FP_VXISI:
- /* Magnitude subtraction of infinities */
- env->fpscr |= 1 << FPSCR_VXISI;
- goto update_arith;
- case POWERPC_EXCP_FP_VXIDI:
- /* Division of infinity by infinity */
- env->fpscr |= 1 << FPSCR_VXIDI;
- goto update_arith;
- case POWERPC_EXCP_FP_VXZDZ:
- /* Division of zero by zero */
- env->fpscr |= 1 << FPSCR_VXZDZ;
- goto update_arith;
- case POWERPC_EXCP_FP_VXIMZ:
- /* Multiplication of zero by infinity */
- env->fpscr |= 1 << FPSCR_VXIMZ;
- goto update_arith;
- case POWERPC_EXCP_FP_VXVC:
- /* Ordered comparison of NaN */
- env->fpscr |= 1 << FPSCR_VXVC;
- if (set_fpcc) {
- env->fpscr &= ~(0xF << FPSCR_FPCC);
- env->fpscr |= 0x11 << FPSCR_FPCC;
- }
- /* We must update the target FPR before raising the exception */
- if (ve != 0) {
- cs->exception_index = POWERPC_EXCP_PROGRAM;
- env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_VXVC;
- /* Update the floating-point enabled exception summary */
- env->fpscr |= 1 << FPSCR_FEX;
- /* Exception is differed */
- ve = 0;
- }
- break;
- case POWERPC_EXCP_FP_VXSQRT:
- /* Square root of a negative number */
- env->fpscr |= 1 << FPSCR_VXSQRT;
- update_arith:
- env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
- if (ve == 0) {
- /* Set the result to quiet NaN */
- ret = 0x7FF8000000000000ULL;
- if (set_fpcc) {
- env->fpscr &= ~(0xF << FPSCR_FPCC);
- env->fpscr |= 0x11 << FPSCR_FPCC;
- }
- }
- break;
- case POWERPC_EXCP_FP_VXCVI:
- /* Invalid conversion */
- env->fpscr |= 1 << FPSCR_VXCVI;
- env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
- if (ve == 0) {
- /* Set the result to quiet NaN */
- ret = 0x7FF8000000000000ULL;
- if (set_fpcc) {
- env->fpscr &= ~(0xF << FPSCR_FPCC);
- env->fpscr |= 0x11 << FPSCR_FPCC;
- }
- }
- break;
- }
- /* Update the floating-point invalid operation summary */
- env->fpscr |= 1 << FPSCR_VX;
- /* Update the floating-point exception summary */
- env->fpscr |= FP_FX;
- if (ve != 0) {
- /* Update the floating-point enabled exception summary */
- env->fpscr |= 1 << FPSCR_FEX;
- if (msr_fe0 != 0 || msr_fe1 != 0) {
- /* GETPC() works here because this is inline */
- raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_FP | op, GETPC());
- }
- }
- return ret;
-}
-
-static inline void float_zero_divide_excp(CPUPPCState *env, uintptr_t raddr)
-{
- env->fpscr |= 1 << FPSCR_ZX;
- env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));
- /* Update the floating-point exception summary */
- env->fpscr |= FP_FX;
- if (fpscr_ze != 0) {
- /* Update the floating-point enabled exception summary */
- env->fpscr |= 1 << FPSCR_FEX;
- if (msr_fe0 != 0 || msr_fe1 != 0) {
- raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_FP | POWERPC_EXCP_FP_ZX,
- raddr);
- }
- }
-}
-
-static inline void float_overflow_excp(CPUPPCState *env)
-{
- CPUState *cs = CPU(ppc_env_get_cpu(env));
-
- env->fpscr |= 1 << FPSCR_OX;
- /* Update the floating-point exception summary */
- env->fpscr |= FP_FX;
- if (fpscr_oe != 0) {
- /* XXX: should adjust the result */
- /* Update the floating-point enabled exception summary */
- env->fpscr |= 1 << FPSCR_FEX;
- /* We must update the target FPR before raising the exception */
- cs->exception_index = POWERPC_EXCP_PROGRAM;
- env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_OX;
- } else {
- env->fpscr |= 1 << FPSCR_XX;
- env->fpscr |= 1 << FPSCR_FI;
- }
-}
-
-static inline void float_underflow_excp(CPUPPCState *env)
-{
- CPUState *cs = CPU(ppc_env_get_cpu(env));
-
- env->fpscr |= 1 << FPSCR_UX;
- /* Update the floating-point exception summary */
- env->fpscr |= FP_FX;
- if (fpscr_ue != 0) {
- /* XXX: should adjust the result */
- /* Update the floating-point enabled exception summary */
- env->fpscr |= 1 << FPSCR_FEX;
- /* We must update the target FPR before raising the exception */
- cs->exception_index = POWERPC_EXCP_PROGRAM;
- env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_UX;
- }
-}
-
-static inline void float_inexact_excp(CPUPPCState *env)
-{
- CPUState *cs = CPU(ppc_env_get_cpu(env));
-
- env->fpscr |= 1 << FPSCR_XX;
- /* Update the floating-point exception summary */
- env->fpscr |= FP_FX;
- if (fpscr_xe != 0) {
- /* Update the floating-point enabled exception summary */
- env->fpscr |= 1 << FPSCR_FEX;
- /* We must update the target FPR before raising the exception */
- cs->exception_index = POWERPC_EXCP_PROGRAM;
- env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_XX;
- }
-}
-
-static inline void fpscr_set_rounding_mode(CPUPPCState *env)
-{
- int rnd_type;
-
- /* Set rounding mode */
- switch (fpscr_rn) {
- case 0:
- /* Best approximation (round to nearest) */
- rnd_type = float_round_nearest_even;
- break;
- case 1:
- /* Smaller magnitude (round toward zero) */
- rnd_type = float_round_to_zero;
- break;
- case 2:
- /* Round toward +infinite */
- rnd_type = float_round_up;
- break;
- default:
- case 3:
- /* Round toward -infinite */
- rnd_type = float_round_down;
- break;
- }
- set_float_rounding_mode(rnd_type, &env->fp_status);
-}
-
-void helper_fpscr_clrbit(CPUPPCState *env, uint32_t bit)
-{
- int prev;
-
- prev = (env->fpscr >> bit) & 1;
- env->fpscr &= ~(1 << bit);
- if (prev == 1) {
- switch (bit) {
- case FPSCR_RN1:
- case FPSCR_RN:
- fpscr_set_rounding_mode(env);
- break;
- default:
- break;
- }
- }
-}
-
-void helper_fpscr_setbit(CPUPPCState *env, uint32_t bit)
-{
- CPUState *cs = CPU(ppc_env_get_cpu(env));
- int prev;
-
- prev = (env->fpscr >> bit) & 1;
- env->fpscr |= 1 << bit;
- if (prev == 0) {
- switch (bit) {
- case FPSCR_VX:
- env->fpscr |= FP_FX;
- if (fpscr_ve) {
- goto raise_ve;
- }
- break;
- case FPSCR_OX:
- env->fpscr |= FP_FX;
- if (fpscr_oe) {
- goto raise_oe;
- }
- break;
- case FPSCR_UX:
- env->fpscr |= FP_FX;
- if (fpscr_ue) {
- goto raise_ue;
- }
- break;
- case FPSCR_ZX:
- env->fpscr |= FP_FX;
- if (fpscr_ze) {
- goto raise_ze;
- }
- break;
- case FPSCR_XX:
- env->fpscr |= FP_FX;
- if (fpscr_xe) {
- goto raise_xe;
- }
- break;
- case FPSCR_VXSNAN:
- case FPSCR_VXISI:
- case FPSCR_VXIDI:
- case FPSCR_VXZDZ:
- case FPSCR_VXIMZ:
- case FPSCR_VXVC:
- case FPSCR_VXSOFT:
- case FPSCR_VXSQRT:
- case FPSCR_VXCVI:
- env->fpscr |= 1 << FPSCR_VX;
- env->fpscr |= FP_FX;
- if (fpscr_ve != 0) {
- goto raise_ve;
- }
- break;
- case FPSCR_VE:
- if (fpscr_vx != 0) {
- raise_ve:
- env->error_code = POWERPC_EXCP_FP;
- if (fpscr_vxsnan) {
- env->error_code |= POWERPC_EXCP_FP_VXSNAN;
- }
- if (fpscr_vxisi) {
- env->error_code |= POWERPC_EXCP_FP_VXISI;
- }
- if (fpscr_vxidi) {
- env->error_code |= POWERPC_EXCP_FP_VXIDI;
- }
- if (fpscr_vxzdz) {
- env->error_code |= POWERPC_EXCP_FP_VXZDZ;
- }
- if (fpscr_vximz) {
- env->error_code |= POWERPC_EXCP_FP_VXIMZ;
- }
- if (fpscr_vxvc) {
- env->error_code |= POWERPC_EXCP_FP_VXVC;
- }
- if (fpscr_vxsoft) {
- env->error_code |= POWERPC_EXCP_FP_VXSOFT;
- }
- if (fpscr_vxsqrt) {
- env->error_code |= POWERPC_EXCP_FP_VXSQRT;
- }
- if (fpscr_vxcvi) {
- env->error_code |= POWERPC_EXCP_FP_VXCVI;
- }
- goto raise_excp;
- }
- break;
- case FPSCR_OE:
- if (fpscr_ox != 0) {
- raise_oe:
- env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_OX;
- goto raise_excp;
- }
- break;
- case FPSCR_UE:
- if (fpscr_ux != 0) {
- raise_ue:
- env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_UX;
- goto raise_excp;
- }
- break;
- case FPSCR_ZE:
- if (fpscr_zx != 0) {
- raise_ze:
- env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_ZX;
- goto raise_excp;
- }
- break;
- case FPSCR_XE:
- if (fpscr_xx != 0) {
- raise_xe:
- env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_XX;
- goto raise_excp;
- }
- break;
- case FPSCR_RN1:
- case FPSCR_RN:
- fpscr_set_rounding_mode(env);
- break;
- default:
- break;
- raise_excp:
- /* Update the floating-point enabled exception summary */
- env->fpscr |= 1 << FPSCR_FEX;
- /* We have to update Rc1 before raising the exception */
- cs->exception_index = POWERPC_EXCP_PROGRAM;
- break;
- }
- }
-}
-
-void helper_store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
-{
- CPUState *cs = CPU(ppc_env_get_cpu(env));
- target_ulong prev, new;
- int i;
-
- prev = env->fpscr;
- new = (target_ulong)arg;
- new &= ~0x60000000LL;
- new |= prev & 0x60000000LL;
- for (i = 0; i < sizeof(target_ulong) * 2; i++) {
- if (mask & (1 << i)) {
- env->fpscr &= ~(0xFLL << (4 * i));
- env->fpscr |= new & (0xFLL << (4 * i));
- }
- }
- /* Update VX and FEX */
- if (fpscr_ix != 0) {
- env->fpscr |= 1 << FPSCR_VX;
- } else {
- env->fpscr &= ~(1 << FPSCR_VX);
- }
- if ((fpscr_ex & fpscr_eex) != 0) {
- env->fpscr |= 1 << FPSCR_FEX;
- cs->exception_index = POWERPC_EXCP_PROGRAM;
- /* XXX: we should compute it properly */
- env->error_code = POWERPC_EXCP_FP;
- } else {
- env->fpscr &= ~(1 << FPSCR_FEX);
- }
- fpscr_set_rounding_mode(env);
-}
-
-void store_fpscr(CPUPPCState *env, uint64_t arg, uint32_t mask)
-{
- helper_store_fpscr(env, arg, mask);
-}
-
-static void do_float_check_status(CPUPPCState *env, uintptr_t raddr)
-{
- CPUState *cs = CPU(ppc_env_get_cpu(env));
- int status = get_float_exception_flags(&env->fp_status);
-
- if (status & float_flag_divbyzero) {
- float_zero_divide_excp(env, raddr);
- } else if (status & float_flag_overflow) {
- float_overflow_excp(env);
- } else if (status & float_flag_underflow) {
- float_underflow_excp(env);
- } else if (status & float_flag_inexact) {
- float_inexact_excp(env);
- }
-
- if (cs->exception_index == POWERPC_EXCP_PROGRAM &&
- (env->error_code & POWERPC_EXCP_FP)) {
- /* Differred floating-point exception after target FPR update */
- if (msr_fe0 != 0 || msr_fe1 != 0) {
- raise_exception_err_ra(env, cs->exception_index,
- env->error_code, raddr);
- }
- }
-}
-
-static inline __attribute__((__always_inline__))
-void float_check_status(CPUPPCState *env)
-{
- /* GETPC() works here because this is inline */
- do_float_check_status(env, GETPC());
-}
-
-void helper_float_check_status(CPUPPCState *env)
-{
- do_float_check_status(env, GETPC());
-}
-
-void helper_reset_fpstatus(CPUPPCState *env)
-{
- set_float_exception_flags(0, &env->fp_status);
-}
-
-/* fadd - fadd. */
-uint64_t helper_fadd(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
-{
- CPU_DoubleU farg1, farg2;
-
- farg1.ll = arg1;
- farg2.ll = arg2;
-
- if (unlikely(float64_is_infinity(farg1.d) && float64_is_infinity(farg2.d) &&
- float64_is_neg(farg1.d) != float64_is_neg(farg2.d))) {
- /* Magnitude subtraction of infinities */
- farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
- } else {
- if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
- float64_is_signaling_nan(farg2.d, &env->fp_status))) {
- /* sNaN addition */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
- }
- farg1.d = float64_add(farg1.d, farg2.d, &env->fp_status);
- }
-
- return farg1.ll;
-}
-
-/* fsub - fsub. */
-uint64_t helper_fsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
-{
- CPU_DoubleU farg1, farg2;
-
- farg1.ll = arg1;
- farg2.ll = arg2;
-
- if (unlikely(float64_is_infinity(farg1.d) && float64_is_infinity(farg2.d) &&
- float64_is_neg(farg1.d) == float64_is_neg(farg2.d))) {
- /* Magnitude subtraction of infinities */
- farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
- } else {
- if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
- float64_is_signaling_nan(farg2.d, &env->fp_status))) {
- /* sNaN subtraction */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
- }
- farg1.d = float64_sub(farg1.d, farg2.d, &env->fp_status);
- }
-
- return farg1.ll;
-}
-
-/* fmul - fmul. */
-uint64_t helper_fmul(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
-{
- CPU_DoubleU farg1, farg2;
-
- farg1.ll = arg1;
- farg2.ll = arg2;
-
- if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d)) ||
- (float64_is_zero(farg1.d) && float64_is_infinity(farg2.d)))) {
- /* Multiplication of zero by infinity */
- farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
- } else {
- if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
- float64_is_signaling_nan(farg2.d, &env->fp_status))) {
- /* sNaN multiplication */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
- }
- farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status);
- }
-
- return farg1.ll;
-}
-
-/* fdiv - fdiv. */
-uint64_t helper_fdiv(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
-{
- CPU_DoubleU farg1, farg2;
-
- farg1.ll = arg1;
- farg2.ll = arg2;
-
- if (unlikely(float64_is_infinity(farg1.d) &&
- float64_is_infinity(farg2.d))) {
- /* Division of infinity by infinity */
- farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, 1);
- } else if (unlikely(float64_is_zero(farg1.d) && float64_is_zero(farg2.d))) {
- /* Division of zero by zero */
- farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, 1);
- } else {
- if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
- float64_is_signaling_nan(farg2.d, &env->fp_status))) {
- /* sNaN division */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
- }
- farg1.d = float64_div(farg1.d, farg2.d, &env->fp_status);
- }
-
- return farg1.ll;
-}
-
-
-#define FPU_FCTI(op, cvt, nanval) \
-uint64_t helper_##op(CPUPPCState *env, uint64_t arg) \
-{ \
- CPU_DoubleU farg; \
- \
- farg.ll = arg; \
- farg.ll = float64_to_##cvt(farg.d, &env->fp_status); \
- \
- if (unlikely(env->fp_status.float_exception_flags)) { \
- if (float64_is_any_nan(arg)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); \
- if (float64_is_signaling_nan(arg, &env->fp_status)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); \
- } \
- farg.ll = nanval; \
- } else if (env->fp_status.float_exception_flags & \
- float_flag_invalid) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); \
- } \
- float_check_status(env); \
- } \
- return farg.ll; \
- }
-
-FPU_FCTI(fctiw, int32, 0x80000000U)
-FPU_FCTI(fctiwz, int32_round_to_zero, 0x80000000U)
-FPU_FCTI(fctiwu, uint32, 0x00000000U)
-FPU_FCTI(fctiwuz, uint32_round_to_zero, 0x00000000U)
-FPU_FCTI(fctid, int64, 0x8000000000000000ULL)
-FPU_FCTI(fctidz, int64_round_to_zero, 0x8000000000000000ULL)
-FPU_FCTI(fctidu, uint64, 0x0000000000000000ULL)
-FPU_FCTI(fctiduz, uint64_round_to_zero, 0x0000000000000000ULL)
-
-#define FPU_FCFI(op, cvtr, is_single) \
-uint64_t helper_##op(CPUPPCState *env, uint64_t arg) \
-{ \
- CPU_DoubleU farg; \
- \
- if (is_single) { \
- float32 tmp = cvtr(arg, &env->fp_status); \
- farg.d = float32_to_float64(tmp, &env->fp_status); \
- } else { \
- farg.d = cvtr(arg, &env->fp_status); \
- } \
- float_check_status(env); \
- return farg.ll; \
-}
-
-FPU_FCFI(fcfid, int64_to_float64, 0)
-FPU_FCFI(fcfids, int64_to_float32, 1)
-FPU_FCFI(fcfidu, uint64_to_float64, 0)
-FPU_FCFI(fcfidus, uint64_to_float32, 1)
-
-static inline uint64_t do_fri(CPUPPCState *env, uint64_t arg,
- int rounding_mode)
-{
- CPU_DoubleU farg;
-
- farg.ll = arg;
-
- if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
- /* sNaN round */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
- farg.ll = arg | 0x0008000000000000ULL;
- } else {
- int inexact = get_float_exception_flags(&env->fp_status) &
- float_flag_inexact;
- set_float_rounding_mode(rounding_mode, &env->fp_status);
- farg.ll = float64_round_to_int(farg.d, &env->fp_status);
- /* Restore rounding mode from FPSCR */
- fpscr_set_rounding_mode(env);
-
- /* fri* does not set FPSCR[XX] */
- if (!inexact) {
- env->fp_status.float_exception_flags &= ~float_flag_inexact;
- }
- }
- float_check_status(env);
- return farg.ll;
-}
-
-uint64_t helper_frin(CPUPPCState *env, uint64_t arg)
-{
- return do_fri(env, arg, float_round_ties_away);
-}
-
-uint64_t helper_friz(CPUPPCState *env, uint64_t arg)
-{
- return do_fri(env, arg, float_round_to_zero);
-}
-
-uint64_t helper_frip(CPUPPCState *env, uint64_t arg)
-{
- return do_fri(env, arg, float_round_up);
-}
-
-uint64_t helper_frim(CPUPPCState *env, uint64_t arg)
-{
- return do_fri(env, arg, float_round_down);
-}
-
-/* fmadd - fmadd. */
-uint64_t helper_fmadd(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
- uint64_t arg3)
-{
- CPU_DoubleU farg1, farg2, farg3;
-
- farg1.ll = arg1;
- farg2.ll = arg2;
- farg3.ll = arg3;
-
- if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d)) ||
- (float64_is_zero(farg1.d) && float64_is_infinity(farg2.d)))) {
- /* Multiplication of zero by infinity */
- farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
- } else {
- if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
- float64_is_signaling_nan(farg2.d, &env->fp_status) ||
- float64_is_signaling_nan(farg3.d, &env->fp_status))) {
- /* sNaN operation */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
- }
- /* This is the way the PowerPC specification defines it */
- float128 ft0_128, ft1_128;
-
- ft0_128 = float64_to_float128(farg1.d, &env->fp_status);
- ft1_128 = float64_to_float128(farg2.d, &env->fp_status);
- ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status);
- if (unlikely(float128_is_infinity(ft0_128) &&
- float64_is_infinity(farg3.d) &&
- float128_is_neg(ft0_128) != float64_is_neg(farg3.d))) {
- /* Magnitude subtraction of infinities */
- farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
- } else {
- ft1_128 = float64_to_float128(farg3.d, &env->fp_status);
- ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status);
- farg1.d = float128_to_float64(ft0_128, &env->fp_status);
- }
- }
-
- return farg1.ll;
-}
-
-/* fmsub - fmsub. */
-uint64_t helper_fmsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
- uint64_t arg3)
-{
- CPU_DoubleU farg1, farg2, farg3;
-
- farg1.ll = arg1;
- farg2.ll = arg2;
- farg3.ll = arg3;
-
- if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d)) ||
- (float64_is_zero(farg1.d) &&
- float64_is_infinity(farg2.d)))) {
- /* Multiplication of zero by infinity */
- farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
- } else {
- if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
- float64_is_signaling_nan(farg2.d, &env->fp_status) ||
- float64_is_signaling_nan(farg3.d, &env->fp_status))) {
- /* sNaN operation */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
- }
- /* This is the way the PowerPC specification defines it */
- float128 ft0_128, ft1_128;
-
- ft0_128 = float64_to_float128(farg1.d, &env->fp_status);
- ft1_128 = float64_to_float128(farg2.d, &env->fp_status);
- ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status);
- if (unlikely(float128_is_infinity(ft0_128) &&
- float64_is_infinity(farg3.d) &&
- float128_is_neg(ft0_128) == float64_is_neg(farg3.d))) {
- /* Magnitude subtraction of infinities */
- farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
- } else {
- ft1_128 = float64_to_float128(farg3.d, &env->fp_status);
- ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status);
- farg1.d = float128_to_float64(ft0_128, &env->fp_status);
- }
- }
- return farg1.ll;
-}
-
-/* fnmadd - fnmadd. */
-uint64_t helper_fnmadd(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
- uint64_t arg3)
-{
- CPU_DoubleU farg1, farg2, farg3;
-
- farg1.ll = arg1;
- farg2.ll = arg2;
- farg3.ll = arg3;
-
- if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d)) ||
- (float64_is_zero(farg1.d) && float64_is_infinity(farg2.d)))) {
- /* Multiplication of zero by infinity */
- farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
- } else {
- if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
- float64_is_signaling_nan(farg2.d, &env->fp_status) ||
- float64_is_signaling_nan(farg3.d, &env->fp_status))) {
- /* sNaN operation */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
- }
- /* This is the way the PowerPC specification defines it */
- float128 ft0_128, ft1_128;
-
- ft0_128 = float64_to_float128(farg1.d, &env->fp_status);
- ft1_128 = float64_to_float128(farg2.d, &env->fp_status);
- ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status);
- if (unlikely(float128_is_infinity(ft0_128) &&
- float64_is_infinity(farg3.d) &&
- float128_is_neg(ft0_128) != float64_is_neg(farg3.d))) {
- /* Magnitude subtraction of infinities */
- farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
- } else {
- ft1_128 = float64_to_float128(farg3.d, &env->fp_status);
- ft0_128 = float128_add(ft0_128, ft1_128, &env->fp_status);
- farg1.d = float128_to_float64(ft0_128, &env->fp_status);
- }
- if (likely(!float64_is_any_nan(farg1.d))) {
- farg1.d = float64_chs(farg1.d);
- }
- }
- return farg1.ll;
-}
-
-/* fnmsub - fnmsub. */
-uint64_t helper_fnmsub(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
- uint64_t arg3)
-{
- CPU_DoubleU farg1, farg2, farg3;
-
- farg1.ll = arg1;
- farg2.ll = arg2;
- farg3.ll = arg3;
-
- if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d)) ||
- (float64_is_zero(farg1.d) &&
- float64_is_infinity(farg2.d)))) {
- /* Multiplication of zero by infinity */
- farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, 1);
- } else {
- if (unlikely(float64_is_signaling_nan(farg1.d, &env->fp_status) ||
- float64_is_signaling_nan(farg2.d, &env->fp_status) ||
- float64_is_signaling_nan(farg3.d, &env->fp_status))) {
- /* sNaN operation */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
- }
- /* This is the way the PowerPC specification defines it */
- float128 ft0_128, ft1_128;
-
- ft0_128 = float64_to_float128(farg1.d, &env->fp_status);
- ft1_128 = float64_to_float128(farg2.d, &env->fp_status);
- ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status);
- if (unlikely(float128_is_infinity(ft0_128) &&
- float64_is_infinity(farg3.d) &&
- float128_is_neg(ft0_128) == float64_is_neg(farg3.d))) {
- /* Magnitude subtraction of infinities */
- farg1.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, 1);
- } else {
- ft1_128 = float64_to_float128(farg3.d, &env->fp_status);
- ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status);
- farg1.d = float128_to_float64(ft0_128, &env->fp_status);
- }
- if (likely(!float64_is_any_nan(farg1.d))) {
- farg1.d = float64_chs(farg1.d);
- }
- }
- return farg1.ll;
-}
-
-/* frsp - frsp. */
-uint64_t helper_frsp(CPUPPCState *env, uint64_t arg)
-{
- CPU_DoubleU farg;
- float32 f32;
-
- farg.ll = arg;
-
- if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
- /* sNaN square root */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
- }
- f32 = float64_to_float32(farg.d, &env->fp_status);
- farg.d = float32_to_float64(f32, &env->fp_status);
-
- return farg.ll;
-}
-
-/* fsqrt - fsqrt. */
-uint64_t helper_fsqrt(CPUPPCState *env, uint64_t arg)
-{
- CPU_DoubleU farg;
-
- farg.ll = arg;
-
- if (unlikely(float64_is_any_nan(farg.d))) {
- if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
- /* sNaN reciprocal square root */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
- farg.ll = float64_snan_to_qnan(farg.ll);
- }
- } else if (unlikely(float64_is_neg(farg.d) && !float64_is_zero(farg.d))) {
- /* Square root of a negative nonzero number */
- farg.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1);
- } else {
- farg.d = float64_sqrt(farg.d, &env->fp_status);
- }
- return farg.ll;
-}
-
-/* fre - fre. */
-uint64_t helper_fre(CPUPPCState *env, uint64_t arg)
-{
- CPU_DoubleU farg;
-
- farg.ll = arg;
-
- if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
- /* sNaN reciprocal */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
- }
- farg.d = float64_div(float64_one, farg.d, &env->fp_status);
- return farg.d;
-}
-
-/* fres - fres. */
-uint64_t helper_fres(CPUPPCState *env, uint64_t arg)
-{
- CPU_DoubleU farg;
- float32 f32;
-
- farg.ll = arg;
-
- if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
- /* sNaN reciprocal */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
- }
- farg.d = float64_div(float64_one, farg.d, &env->fp_status);
- f32 = float64_to_float32(farg.d, &env->fp_status);
- farg.d = float32_to_float64(f32, &env->fp_status);
-
- return farg.ll;
-}
-
-/* frsqrte - frsqrte. */
-uint64_t helper_frsqrte(CPUPPCState *env, uint64_t arg)
-{
- CPU_DoubleU farg;
-
- farg.ll = arg;
-
- if (unlikely(float64_is_any_nan(farg.d))) {
- if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
- /* sNaN reciprocal square root */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
- farg.ll = float64_snan_to_qnan(farg.ll);
- }
- } else if (unlikely(float64_is_neg(farg.d) && !float64_is_zero(farg.d))) {
- /* Reciprocal square root of a negative nonzero number */
- farg.ll = float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, 1);
- } else {
- farg.d = float64_sqrt(farg.d, &env->fp_status);
- farg.d = float64_div(float64_one, farg.d, &env->fp_status);
- }
-
- return farg.ll;
-}
-
-/* fsel - fsel. */
-uint64_t helper_fsel(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
- uint64_t arg3)
-{
- CPU_DoubleU farg1;
-
- farg1.ll = arg1;
-
- if ((!float64_is_neg(farg1.d) || float64_is_zero(farg1.d)) &&
- !float64_is_any_nan(farg1.d)) {
- return arg2;
- } else {
- return arg3;
- }
-}
-
-uint32_t helper_ftdiv(uint64_t fra, uint64_t frb)
-{
- int fe_flag = 0;
- int fg_flag = 0;
-
- if (unlikely(float64_is_infinity(fra) ||
- float64_is_infinity(frb) ||
- float64_is_zero(frb))) {
- fe_flag = 1;
- fg_flag = 1;
- } else {
- int e_a = ppc_float64_get_unbiased_exp(fra);
- int e_b = ppc_float64_get_unbiased_exp(frb);
-
- if (unlikely(float64_is_any_nan(fra) ||
- float64_is_any_nan(frb))) {
- fe_flag = 1;
- } else if ((e_b <= -1022) || (e_b >= 1021)) {
- fe_flag = 1;
- } else if (!float64_is_zero(fra) &&
- (((e_a - e_b) >= 1023) ||
- ((e_a - e_b) <= -1021) ||
- (e_a <= -970))) {
- fe_flag = 1;
- }
-
- if (unlikely(float64_is_zero_or_denormal(frb))) {
- /* XB is not zero because of the above check and */
- /* so must be denormalized. */
- fg_flag = 1;
- }
- }
-
- return 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0);
-}
-
-uint32_t helper_ftsqrt(uint64_t frb)
-{
- int fe_flag = 0;
- int fg_flag = 0;
-
- if (unlikely(float64_is_infinity(frb) || float64_is_zero(frb))) {
- fe_flag = 1;
- fg_flag = 1;
- } else {
- int e_b = ppc_float64_get_unbiased_exp(frb);
-
- if (unlikely(float64_is_any_nan(frb))) {
- fe_flag = 1;
- } else if (unlikely(float64_is_zero(frb))) {
- fe_flag = 1;
- } else if (unlikely(float64_is_neg(frb))) {
- fe_flag = 1;
- } else if (!float64_is_zero(frb) && (e_b <= (-1022+52))) {
- fe_flag = 1;
- }
-
- if (unlikely(float64_is_zero_or_denormal(frb))) {
- /* XB is not zero because of the above check and */
- /* therefore must be denormalized. */
- fg_flag = 1;
- }
- }
-
- return 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0);
-}
-
-void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
- uint32_t crfD)
-{
- CPU_DoubleU farg1, farg2;
- uint32_t ret = 0;
-
- farg1.ll = arg1;
- farg2.ll = arg2;
-
- if (unlikely(float64_is_any_nan(farg1.d) ||
- float64_is_any_nan(farg2.d))) {
- ret = 0x01UL;
- } else if (float64_lt(farg1.d, farg2.d, &env->fp_status)) {
- ret = 0x08UL;
- } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) {
- ret = 0x04UL;
- } else {
- ret = 0x02UL;
- }
-
- env->fpscr &= ~(0x0F << FPSCR_FPRF);
- env->fpscr |= ret << FPSCR_FPRF;
- env->crf[crfD] = ret;
- if (unlikely(ret == 0x01UL
- && (float64_is_signaling_nan(farg1.d, &env->fp_status) ||
- float64_is_signaling_nan(farg2.d, &env->fp_status)))) {
- /* sNaN comparison */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);
- }
-}
-
-void helper_fcmpo(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
- uint32_t crfD)
-{
- CPU_DoubleU farg1, farg2;
- uint32_t ret = 0;
-
- farg1.ll = arg1;
- farg2.ll = arg2;
-
- if (unlikely(float64_is_any_nan(farg1.d) ||
- float64_is_any_nan(farg2.d))) {
- ret = 0x01UL;
- } else if (float64_lt(farg1.d, farg2.d, &env->fp_status)) {
- ret = 0x08UL;
- } else if (!float64_le(farg1.d, farg2.d, &env->fp_status)) {
- ret = 0x04UL;
- } else {
- ret = 0x02UL;
- }
-
- env->fpscr &= ~(0x0F << FPSCR_FPRF);
- env->fpscr |= ret << FPSCR_FPRF;
- env->crf[crfD] = ret;
- if (unlikely(ret == 0x01UL)) {
- if (float64_is_signaling_nan(farg1.d, &env->fp_status) ||
- float64_is_signaling_nan(farg2.d, &env->fp_status)) {
- /* sNaN comparison */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN |
- POWERPC_EXCP_FP_VXVC, 1);
- } else {
- /* qNaN comparison */
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 1);
- }
- }
-}
-
-/* Single-precision floating-point conversions */
-static inline uint32_t efscfsi(CPUPPCState *env, uint32_t val)
-{
- CPU_FloatU u;
-
- u.f = int32_to_float32(val, &env->vec_status);
-
- return u.l;
-}
-
-static inline uint32_t efscfui(CPUPPCState *env, uint32_t val)
-{
- CPU_FloatU u;
-
- u.f = uint32_to_float32(val, &env->vec_status);
-
- return u.l;
-}
-
-static inline int32_t efsctsi(CPUPPCState *env, uint32_t val)
-{
- CPU_FloatU u;
-
- u.l = val;
- /* NaN are not treated the same way IEEE 754 does */
- if (unlikely(float32_is_quiet_nan(u.f, &env->vec_status))) {
- return 0;
- }
-
- return float32_to_int32(u.f, &env->vec_status);
-}
-
-static inline uint32_t efsctui(CPUPPCState *env, uint32_t val)
-{
- CPU_FloatU u;
-
- u.l = val;
- /* NaN are not treated the same way IEEE 754 does */
- if (unlikely(float32_is_quiet_nan(u.f, &env->vec_status))) {
- return 0;
- }
-
- return float32_to_uint32(u.f, &env->vec_status);
-}
-
-static inline uint32_t efsctsiz(CPUPPCState *env, uint32_t val)
-{
- CPU_FloatU u;
-
- u.l = val;
- /* NaN are not treated the same way IEEE 754 does */
- if (unlikely(float32_is_quiet_nan(u.f, &env->vec_status))) {
- return 0;
- }
-
- return float32_to_int32_round_to_zero(u.f, &env->vec_status);
-}
-
-static inline uint32_t efsctuiz(CPUPPCState *env, uint32_t val)
-{
- CPU_FloatU u;
-
- u.l = val;
- /* NaN are not treated the same way IEEE 754 does */
- if (unlikely(float32_is_quiet_nan(u.f, &env->vec_status))) {
- return 0;
- }
-
- return float32_to_uint32_round_to_zero(u.f, &env->vec_status);
-}
-
-static inline uint32_t efscfsf(CPUPPCState *env, uint32_t val)
-{
- CPU_FloatU u;
- float32 tmp;
-
- u.f = int32_to_float32(val, &env->vec_status);
- tmp = int64_to_float32(1ULL << 32, &env->vec_status);
- u.f = float32_div(u.f, tmp, &env->vec_status);
-
- return u.l;
-}
-
-static inline uint32_t efscfuf(CPUPPCState *env, uint32_t val)
-{
- CPU_FloatU u;
- float32 tmp;
-
- u.f = uint32_to_float32(val, &env->vec_status);
- tmp = uint64_to_float32(1ULL << 32, &env->vec_status);
- u.f = float32_div(u.f, tmp, &env->vec_status);
-
- return u.l;
-}
-
-static inline uint32_t efsctsf(CPUPPCState *env, uint32_t val)
-{
- CPU_FloatU u;
- float32 tmp;
-
- u.l = val;
- /* NaN are not treated the same way IEEE 754 does */
- if (unlikely(float32_is_quiet_nan(u.f, &env->vec_status))) {
- return 0;
- }
- tmp = uint64_to_float32(1ULL << 32, &env->vec_status);
- u.f = float32_mul(u.f, tmp, &env->vec_status);
-
- return float32_to_int32(u.f, &env->vec_status);
-}
-
-static inline uint32_t efsctuf(CPUPPCState *env, uint32_t val)
-{
- CPU_FloatU u;
- float32 tmp;
-
- u.l = val;
- /* NaN are not treated the same way IEEE 754 does */
- if (unlikely(float32_is_quiet_nan(u.f, &env->vec_status))) {
- return 0;
- }
- tmp = uint64_to_float32(1ULL << 32, &env->vec_status);
- u.f = float32_mul(u.f, tmp, &env->vec_status);
-
- return float32_to_uint32(u.f, &env->vec_status);
-}
-
-#define HELPER_SPE_SINGLE_CONV(name) \
- uint32_t helper_e##name(CPUPPCState *env, uint32_t val) \
- { \
- return e##name(env, val); \
- }
-/* efscfsi */
-HELPER_SPE_SINGLE_CONV(fscfsi);
-/* efscfui */
-HELPER_SPE_SINGLE_CONV(fscfui);
-/* efscfuf */
-HELPER_SPE_SINGLE_CONV(fscfuf);
-/* efscfsf */
-HELPER_SPE_SINGLE_CONV(fscfsf);
-/* efsctsi */
-HELPER_SPE_SINGLE_CONV(fsctsi);
-/* efsctui */
-HELPER_SPE_SINGLE_CONV(fsctui);
-/* efsctsiz */
-HELPER_SPE_SINGLE_CONV(fsctsiz);
-/* efsctuiz */
-HELPER_SPE_SINGLE_CONV(fsctuiz);
-/* efsctsf */
-HELPER_SPE_SINGLE_CONV(fsctsf);
-/* efsctuf */
-HELPER_SPE_SINGLE_CONV(fsctuf);
-
-#define HELPER_SPE_VECTOR_CONV(name) \
- uint64_t helper_ev##name(CPUPPCState *env, uint64_t val) \
- { \
- return ((uint64_t)e##name(env, val >> 32) << 32) | \
- (uint64_t)e##name(env, val); \
- }
-/* evfscfsi */
-HELPER_SPE_VECTOR_CONV(fscfsi);
-/* evfscfui */
-HELPER_SPE_VECTOR_CONV(fscfui);
-/* evfscfuf */
-HELPER_SPE_VECTOR_CONV(fscfuf);
-/* evfscfsf */
-HELPER_SPE_VECTOR_CONV(fscfsf);
-/* evfsctsi */
-HELPER_SPE_VECTOR_CONV(fsctsi);
-/* evfsctui */
-HELPER_SPE_VECTOR_CONV(fsctui);
-/* evfsctsiz */
-HELPER_SPE_VECTOR_CONV(fsctsiz);
-/* evfsctuiz */
-HELPER_SPE_VECTOR_CONV(fsctuiz);
-/* evfsctsf */
-HELPER_SPE_VECTOR_CONV(fsctsf);
-/* evfsctuf */
-HELPER_SPE_VECTOR_CONV(fsctuf);
-
-/* Single-precision floating-point arithmetic */
-static inline uint32_t efsadd(CPUPPCState *env, uint32_t op1, uint32_t op2)
-{
- CPU_FloatU u1, u2;
-
- u1.l = op1;
- u2.l = op2;
- u1.f = float32_add(u1.f, u2.f, &env->vec_status);
- return u1.l;
-}
-
-static inline uint32_t efssub(CPUPPCState *env, uint32_t op1, uint32_t op2)
-{
- CPU_FloatU u1, u2;
-
- u1.l = op1;
- u2.l = op2;
- u1.f = float32_sub(u1.f, u2.f, &env->vec_status);
- return u1.l;
-}
-
-static inline uint32_t efsmul(CPUPPCState *env, uint32_t op1, uint32_t op2)
-{
- CPU_FloatU u1, u2;
-
- u1.l = op1;
- u2.l = op2;
- u1.f = float32_mul(u1.f, u2.f, &env->vec_status);
- return u1.l;
-}
-
-static inline uint32_t efsdiv(CPUPPCState *env, uint32_t op1, uint32_t op2)
-{
- CPU_FloatU u1, u2;
-
- u1.l = op1;
- u2.l = op2;
- u1.f = float32_div(u1.f, u2.f, &env->vec_status);
- return u1.l;
-}
-
-#define HELPER_SPE_SINGLE_ARITH(name) \
- uint32_t helper_e##name(CPUPPCState *env, uint32_t op1, uint32_t op2) \
- { \
- return e##name(env, op1, op2); \
- }
-/* efsadd */
-HELPER_SPE_SINGLE_ARITH(fsadd);
-/* efssub */
-HELPER_SPE_SINGLE_ARITH(fssub);
-/* efsmul */
-HELPER_SPE_SINGLE_ARITH(fsmul);
-/* efsdiv */
-HELPER_SPE_SINGLE_ARITH(fsdiv);
-
-#define HELPER_SPE_VECTOR_ARITH(name) \
- uint64_t helper_ev##name(CPUPPCState *env, uint64_t op1, uint64_t op2) \
- { \
- return ((uint64_t)e##name(env, op1 >> 32, op2 >> 32) << 32) | \
- (uint64_t)e##name(env, op1, op2); \
- }
-/* evfsadd */
-HELPER_SPE_VECTOR_ARITH(fsadd);
-/* evfssub */
-HELPER_SPE_VECTOR_ARITH(fssub);
-/* evfsmul */
-HELPER_SPE_VECTOR_ARITH(fsmul);
-/* evfsdiv */
-HELPER_SPE_VECTOR_ARITH(fsdiv);
-
-/* Single-precision floating-point comparisons */
-static inline uint32_t efscmplt(CPUPPCState *env, uint32_t op1, uint32_t op2)
-{
- CPU_FloatU u1, u2;
-
- u1.l = op1;
- u2.l = op2;
- return float32_lt(u1.f, u2.f, &env->vec_status) ? 4 : 0;
-}
-
-static inline uint32_t efscmpgt(CPUPPCState *env, uint32_t op1, uint32_t op2)
-{
- CPU_FloatU u1, u2;
-
- u1.l = op1;
- u2.l = op2;
- return float32_le(u1.f, u2.f, &env->vec_status) ? 0 : 4;
-}
-
-static inline uint32_t efscmpeq(CPUPPCState *env, uint32_t op1, uint32_t op2)
-{
- CPU_FloatU u1, u2;
-
- u1.l = op1;
- u2.l = op2;
- return float32_eq(u1.f, u2.f, &env->vec_status) ? 4 : 0;
-}
-
-static inline uint32_t efststlt(CPUPPCState *env, uint32_t op1, uint32_t op2)
-{
- /* XXX: TODO: ignore special values (NaN, infinites, ...) */
- return efscmplt(env, op1, op2);
-}
-
-static inline uint32_t efststgt(CPUPPCState *env, uint32_t op1, uint32_t op2)
-{
- /* XXX: TODO: ignore special values (NaN, infinites, ...) */
- return efscmpgt(env, op1, op2);
-}
-
-static inline uint32_t efststeq(CPUPPCState *env, uint32_t op1, uint32_t op2)
-{
- /* XXX: TODO: ignore special values (NaN, infinites, ...) */
- return efscmpeq(env, op1, op2);
-}
-
-#define HELPER_SINGLE_SPE_CMP(name) \
- uint32_t helper_e##name(CPUPPCState *env, uint32_t op1, uint32_t op2) \
- { \
- return e##name(env, op1, op2); \
- }
-/* efststlt */
-HELPER_SINGLE_SPE_CMP(fststlt);
-/* efststgt */
-HELPER_SINGLE_SPE_CMP(fststgt);
-/* efststeq */
-HELPER_SINGLE_SPE_CMP(fststeq);
-/* efscmplt */
-HELPER_SINGLE_SPE_CMP(fscmplt);
-/* efscmpgt */
-HELPER_SINGLE_SPE_CMP(fscmpgt);
-/* efscmpeq */
-HELPER_SINGLE_SPE_CMP(fscmpeq);
-
-static inline uint32_t evcmp_merge(int t0, int t1)
-{
- return (t0 << 3) | (t1 << 2) | ((t0 | t1) << 1) | (t0 & t1);
-}
-
-#define HELPER_VECTOR_SPE_CMP(name) \
- uint32_t helper_ev##name(CPUPPCState *env, uint64_t op1, uint64_t op2) \
- { \
- return evcmp_merge(e##name(env, op1 >> 32, op2 >> 32), \
- e##name(env, op1, op2)); \
- }
-/* evfststlt */
-HELPER_VECTOR_SPE_CMP(fststlt);
-/* evfststgt */
-HELPER_VECTOR_SPE_CMP(fststgt);
-/* evfststeq */
-HELPER_VECTOR_SPE_CMP(fststeq);
-/* evfscmplt */
-HELPER_VECTOR_SPE_CMP(fscmplt);
-/* evfscmpgt */
-HELPER_VECTOR_SPE_CMP(fscmpgt);
-/* evfscmpeq */
-HELPER_VECTOR_SPE_CMP(fscmpeq);
-
-/* Double-precision floating-point conversion */
-uint64_t helper_efdcfsi(CPUPPCState *env, uint32_t val)
-{
- CPU_DoubleU u;
-
- u.d = int32_to_float64(val, &env->vec_status);
-
- return u.ll;
-}
-
-uint64_t helper_efdcfsid(CPUPPCState *env, uint64_t val)
-{
- CPU_DoubleU u;
-
- u.d = int64_to_float64(val, &env->vec_status);
-
- return u.ll;
-}
-
-uint64_t helper_efdcfui(CPUPPCState *env, uint32_t val)
-{
- CPU_DoubleU u;
-
- u.d = uint32_to_float64(val, &env->vec_status);
-
- return u.ll;
-}
-
-uint64_t helper_efdcfuid(CPUPPCState *env, uint64_t val)
-{
- CPU_DoubleU u;
-
- u.d = uint64_to_float64(val, &env->vec_status);
-
- return u.ll;
-}
-
-uint32_t helper_efdctsi(CPUPPCState *env, uint64_t val)
-{
- CPU_DoubleU u;
-
- u.ll = val;
- /* NaN are not treated the same way IEEE 754 does */
- if (unlikely(float64_is_any_nan(u.d))) {
- return 0;
- }
-
- return float64_to_int32(u.d, &env->vec_status);
-}
-
-uint32_t helper_efdctui(CPUPPCState *env, uint64_t val)
-{
- CPU_DoubleU u;
-
- u.ll = val;
- /* NaN are not treated the same way IEEE 754 does */
- if (unlikely(float64_is_any_nan(u.d))) {
- return 0;
- }
-
- return float64_to_uint32(u.d, &env->vec_status);
-}
-
-uint32_t helper_efdctsiz(CPUPPCState *env, uint64_t val)
-{
- CPU_DoubleU u;
-
- u.ll = val;
- /* NaN are not treated the same way IEEE 754 does */
- if (unlikely(float64_is_any_nan(u.d))) {
- return 0;
- }
-
- return float64_to_int32_round_to_zero(u.d, &env->vec_status);
-}
-
-uint64_t helper_efdctsidz(CPUPPCState *env, uint64_t val)
-{
- CPU_DoubleU u;
-
- u.ll = val;
- /* NaN are not treated the same way IEEE 754 does */
- if (unlikely(float64_is_any_nan(u.d))) {
- return 0;
- }
-
- return float64_to_int64_round_to_zero(u.d, &env->vec_status);
-}
-
-uint32_t helper_efdctuiz(CPUPPCState *env, uint64_t val)
-{
- CPU_DoubleU u;
-
- u.ll = val;
- /* NaN are not treated the same way IEEE 754 does */
- if (unlikely(float64_is_any_nan(u.d))) {
- return 0;
- }
-
- return float64_to_uint32_round_to_zero(u.d, &env->vec_status);
-}
-
-uint64_t helper_efdctuidz(CPUPPCState *env, uint64_t val)
-{
- CPU_DoubleU u;
-
- u.ll = val;
- /* NaN are not treated the same way IEEE 754 does */
- if (unlikely(float64_is_any_nan(u.d))) {
- return 0;
- }
-
- return float64_to_uint64_round_to_zero(u.d, &env->vec_status);
-}
-
-uint64_t helper_efdcfsf(CPUPPCState *env, uint32_t val)
-{
- CPU_DoubleU u;
- float64 tmp;
-
- u.d = int32_to_float64(val, &env->vec_status);
- tmp = int64_to_float64(1ULL << 32, &env->vec_status);
- u.d = float64_div(u.d, tmp, &env->vec_status);
-
- return u.ll;
-}
-
-uint64_t helper_efdcfuf(CPUPPCState *env, uint32_t val)
-{
- CPU_DoubleU u;
- float64 tmp;
-
- u.d = uint32_to_float64(val, &env->vec_status);
- tmp = int64_to_float64(1ULL << 32, &env->vec_status);
- u.d = float64_div(u.d, tmp, &env->vec_status);
-
- return u.ll;
-}
-
-uint32_t helper_efdctsf(CPUPPCState *env, uint64_t val)
-{
- CPU_DoubleU u;
- float64 tmp;
-
- u.ll = val;
- /* NaN are not treated the same way IEEE 754 does */
- if (unlikely(float64_is_any_nan(u.d))) {
- return 0;
- }
- tmp = uint64_to_float64(1ULL << 32, &env->vec_status);
- u.d = float64_mul(u.d, tmp, &env->vec_status);
-
- return float64_to_int32(u.d, &env->vec_status);
-}
-
-uint32_t helper_efdctuf(CPUPPCState *env, uint64_t val)
-{
- CPU_DoubleU u;
- float64 tmp;
-
- u.ll = val;
- /* NaN are not treated the same way IEEE 754 does */
- if (unlikely(float64_is_any_nan(u.d))) {
- return 0;
- }
- tmp = uint64_to_float64(1ULL << 32, &env->vec_status);
- u.d = float64_mul(u.d, tmp, &env->vec_status);
-
- return float64_to_uint32(u.d, &env->vec_status);
-}
-
-uint32_t helper_efscfd(CPUPPCState *env, uint64_t val)
-{
- CPU_DoubleU u1;
- CPU_FloatU u2;
-
- u1.ll = val;
- u2.f = float64_to_float32(u1.d, &env->vec_status);
-
- return u2.l;
-}
-
-uint64_t helper_efdcfs(CPUPPCState *env, uint32_t val)
-{
- CPU_DoubleU u2;
- CPU_FloatU u1;
-
- u1.l = val;
- u2.d = float32_to_float64(u1.f, &env->vec_status);
-
- return u2.ll;
-}
-
-/* Double precision fixed-point arithmetic */
-uint64_t helper_efdadd(CPUPPCState *env, uint64_t op1, uint64_t op2)
-{
- CPU_DoubleU u1, u2;
-
- u1.ll = op1;
- u2.ll = op2;
- u1.d = float64_add(u1.d, u2.d, &env->vec_status);
- return u1.ll;
-}
-
-uint64_t helper_efdsub(CPUPPCState *env, uint64_t op1, uint64_t op2)
-{
- CPU_DoubleU u1, u2;
-
- u1.ll = op1;
- u2.ll = op2;
- u1.d = float64_sub(u1.d, u2.d, &env->vec_status);
- return u1.ll;
-}
-
-uint64_t helper_efdmul(CPUPPCState *env, uint64_t op1, uint64_t op2)
-{
- CPU_DoubleU u1, u2;
-
- u1.ll = op1;
- u2.ll = op2;
- u1.d = float64_mul(u1.d, u2.d, &env->vec_status);
- return u1.ll;
-}
-
-uint64_t helper_efddiv(CPUPPCState *env, uint64_t op1, uint64_t op2)
-{
- CPU_DoubleU u1, u2;
-
- u1.ll = op1;
- u2.ll = op2;
- u1.d = float64_div(u1.d, u2.d, &env->vec_status);
- return u1.ll;
-}
-
-/* Double precision floating point helpers */
-uint32_t helper_efdtstlt(CPUPPCState *env, uint64_t op1, uint64_t op2)
-{
- CPU_DoubleU u1, u2;
-
- u1.ll = op1;
- u2.ll = op2;
- return float64_lt(u1.d, u2.d, &env->vec_status) ? 4 : 0;
-}
-
-uint32_t helper_efdtstgt(CPUPPCState *env, uint64_t op1, uint64_t op2)
-{
- CPU_DoubleU u1, u2;
-
- u1.ll = op1;
- u2.ll = op2;
- return float64_le(u1.d, u2.d, &env->vec_status) ? 0 : 4;
-}
-
-uint32_t helper_efdtsteq(CPUPPCState *env, uint64_t op1, uint64_t op2)
-{
- CPU_DoubleU u1, u2;
-
- u1.ll = op1;
- u2.ll = op2;
- return float64_eq_quiet(u1.d, u2.d, &env->vec_status) ? 4 : 0;
-}
-
-uint32_t helper_efdcmplt(CPUPPCState *env, uint64_t op1, uint64_t op2)
-{
- /* XXX: TODO: test special values (NaN, infinites, ...) */
- return helper_efdtstlt(env, op1, op2);
-}
-
-uint32_t helper_efdcmpgt(CPUPPCState *env, uint64_t op1, uint64_t op2)
-{
- /* XXX: TODO: test special values (NaN, infinites, ...) */
- return helper_efdtstgt(env, op1, op2);
-}
-
-uint32_t helper_efdcmpeq(CPUPPCState *env, uint64_t op1, uint64_t op2)
-{
- /* XXX: TODO: test special values (NaN, infinites, ...) */
- return helper_efdtsteq(env, op1, op2);
-}
-
-#define DECODE_SPLIT(opcode, shift1, nb1, shift2, nb2) \
- (((((opcode) >> (shift1)) & ((1 << (nb1)) - 1)) << nb2) | \
- (((opcode) >> (shift2)) & ((1 << (nb2)) - 1)))
-
-#define xT(opcode) DECODE_SPLIT(opcode, 0, 1, 21, 5)
-#define xA(opcode) DECODE_SPLIT(opcode, 2, 1, 16, 5)
-#define xB(opcode) DECODE_SPLIT(opcode, 1, 1, 11, 5)
-#define xC(opcode) DECODE_SPLIT(opcode, 3, 1, 6, 5)
-#define BF(opcode) (((opcode) >> (31-8)) & 7)
-
-typedef union _ppc_vsr_t {
- uint64_t u64[2];
- uint32_t u32[4];
- float32 f32[4];
- float64 f64[2];
-} ppc_vsr_t;
-
-#if defined(HOST_WORDS_BIGENDIAN)
-#define VsrW(i) u32[i]
-#define VsrD(i) u64[i]
-#else
-#define VsrW(i) u32[3-(i)]
-#define VsrD(i) u64[1-(i)]
-#endif
-
-static void getVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
-{
- if (n < 32) {
- vsr->VsrD(0) = env->fpr[n];
- vsr->VsrD(1) = env->vsr[n];
- } else {
- vsr->u64[0] = env->avr[n-32].u64[0];
- vsr->u64[1] = env->avr[n-32].u64[1];
- }
-}
-
-static void putVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env)
-{
- if (n < 32) {
- env->fpr[n] = vsr->VsrD(0);
- env->vsr[n] = vsr->VsrD(1);
- } else {
- env->avr[n-32].u64[0] = vsr->u64[0];
- env->avr[n-32].u64[1] = vsr->u64[1];
- }
-}
-
-#define float64_to_float64(x, env) x
-
-
-/* VSX_ADD_SUB - VSX floating point add/subract
- * name - instruction mnemonic
- * op - operation (add or sub)
- * nels - number of elements (1, 2 or 4)
- * tp - type (float32 or float64)
- * fld - vsr_t field (VsrD(*) or VsrW(*))
- * sfprf - set FPRF
- */
-#define VSX_ADD_SUB(name, op, nels, tp, fld, sfprf, r2sp) \
-void helper_##name(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xt, xa, xb; \
- int i; \
- \
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- helper_reset_fpstatus(env); \
- \
- for (i = 0; i < nels; i++) { \
- float_status tstat = env->fp_status; \
- set_float_exception_flags(0, &tstat); \
- xt.fld = tp##_##op(xa.fld, xb.fld, &tstat); \
- env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
- \
- if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
- if (tp##_is_infinity(xa.fld) && tp##_is_infinity(xb.fld)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf); \
- } else if (tp##_is_signaling_nan(xa.fld, &tstat) || \
- tp##_is_signaling_nan(xb.fld, &tstat)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \
- } \
- } \
- \
- if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
- } \
- \
- if (sfprf) { \
- helper_compute_fprf(env, xt.fld); \
- } \
- } \
- putVSR(xT(opcode), &xt, env); \
- float_check_status(env); \
-}
-
-VSX_ADD_SUB(xsadddp, add, 1, float64, VsrD(0), 1, 0)
-VSX_ADD_SUB(xsaddsp, add, 1, float64, VsrD(0), 1, 1)
-VSX_ADD_SUB(xvadddp, add, 2, float64, VsrD(i), 0, 0)
-VSX_ADD_SUB(xvaddsp, add, 4, float32, VsrW(i), 0, 0)
-VSX_ADD_SUB(xssubdp, sub, 1, float64, VsrD(0), 1, 0)
-VSX_ADD_SUB(xssubsp, sub, 1, float64, VsrD(0), 1, 1)
-VSX_ADD_SUB(xvsubdp, sub, 2, float64, VsrD(i), 0, 0)
-VSX_ADD_SUB(xvsubsp, sub, 4, float32, VsrW(i), 0, 0)
-
-/* VSX_MUL - VSX floating point multiply
- * op - instruction mnemonic
- * nels - number of elements (1, 2 or 4)
- * tp - type (float32 or float64)
- * fld - vsr_t field (VsrD(*) or VsrW(*))
- * sfprf - set FPRF
- */
-#define VSX_MUL(op, nels, tp, fld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xt, xa, xb; \
- int i; \
- \
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- helper_reset_fpstatus(env); \
- \
- for (i = 0; i < nels; i++) { \
- float_status tstat = env->fp_status; \
- set_float_exception_flags(0, &tstat); \
- xt.fld = tp##_mul(xa.fld, xb.fld, &tstat); \
- env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
- \
- if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
- if ((tp##_is_infinity(xa.fld) && tp##_is_zero(xb.fld)) || \
- (tp##_is_infinity(xb.fld) && tp##_is_zero(xa.fld))) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, sfprf); \
- } else if (tp##_is_signaling_nan(xa.fld, &tstat) || \
- tp##_is_signaling_nan(xb.fld, &tstat)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \
- } \
- } \
- \
- if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
- } \
- \
- if (sfprf) { \
- helper_compute_fprf(env, xt.fld); \
- } \
- } \
- \
- putVSR(xT(opcode), &xt, env); \
- float_check_status(env); \
-}
-
-VSX_MUL(xsmuldp, 1, float64, VsrD(0), 1, 0)
-VSX_MUL(xsmulsp, 1, float64, VsrD(0), 1, 1)
-VSX_MUL(xvmuldp, 2, float64, VsrD(i), 0, 0)
-VSX_MUL(xvmulsp, 4, float32, VsrW(i), 0, 0)
-
-/* VSX_DIV - VSX floating point divide
- * op - instruction mnemonic
- * nels - number of elements (1, 2 or 4)
- * tp - type (float32 or float64)
- * fld - vsr_t field (VsrD(*) or VsrW(*))
- * sfprf - set FPRF
- */
-#define VSX_DIV(op, nels, tp, fld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xt, xa, xb; \
- int i; \
- \
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- helper_reset_fpstatus(env); \
- \
- for (i = 0; i < nels; i++) { \
- float_status tstat = env->fp_status; \
- set_float_exception_flags(0, &tstat); \
- xt.fld = tp##_div(xa.fld, xb.fld, &tstat); \
- env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
- \
- if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
- if (tp##_is_infinity(xa.fld) && tp##_is_infinity(xb.fld)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, sfprf); \
- } else if (tp##_is_zero(xa.fld) && \
- tp##_is_zero(xb.fld)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, sfprf); \
- } else if (tp##_is_signaling_nan(xa.fld, &tstat) || \
- tp##_is_signaling_nan(xb.fld, &tstat)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \
- } \
- } \
- \
- if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
- } \
- \
- if (sfprf) { \
- helper_compute_fprf(env, xt.fld); \
- } \
- } \
- \
- putVSR(xT(opcode), &xt, env); \
- float_check_status(env); \
-}
-
-VSX_DIV(xsdivdp, 1, float64, VsrD(0), 1, 0)
-VSX_DIV(xsdivsp, 1, float64, VsrD(0), 1, 1)
-VSX_DIV(xvdivdp, 2, float64, VsrD(i), 0, 0)
-VSX_DIV(xvdivsp, 4, float32, VsrW(i), 0, 0)
-
-/* VSX_RE - VSX floating point reciprocal estimate
- * op - instruction mnemonic
- * nels - number of elements (1, 2 or 4)
- * tp - type (float32 or float64)
- * fld - vsr_t field (VsrD(*) or VsrW(*))
- * sfprf - set FPRF
- */
-#define VSX_RE(op, nels, tp, fld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xt, xb; \
- int i; \
- \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- helper_reset_fpstatus(env); \
- \
- for (i = 0; i < nels; i++) { \
- if (unlikely(tp##_is_signaling_nan(xb.fld, &env->fp_status))) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \
- } \
- xt.fld = tp##_div(tp##_one, xb.fld, &env->fp_status); \
- \
- if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
- } \
- \
- if (sfprf) { \
- helper_compute_fprf(env, xt.fld); \
- } \
- } \
- \
- putVSR(xT(opcode), &xt, env); \
- float_check_status(env); \
-}
-
-VSX_RE(xsredp, 1, float64, VsrD(0), 1, 0)
-VSX_RE(xsresp, 1, float64, VsrD(0), 1, 1)
-VSX_RE(xvredp, 2, float64, VsrD(i), 0, 0)
-VSX_RE(xvresp, 4, float32, VsrW(i), 0, 0)
-
-/* VSX_SQRT - VSX floating point square root
- * op - instruction mnemonic
- * nels - number of elements (1, 2 or 4)
- * tp - type (float32 or float64)
- * fld - vsr_t field (VsrD(*) or VsrW(*))
- * sfprf - set FPRF
- */
-#define VSX_SQRT(op, nels, tp, fld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xt, xb; \
- int i; \
- \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- helper_reset_fpstatus(env); \
- \
- for (i = 0; i < nels; i++) { \
- float_status tstat = env->fp_status; \
- set_float_exception_flags(0, &tstat); \
- xt.fld = tp##_sqrt(xb.fld, &tstat); \
- env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
- \
- if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
- if (tp##_is_neg(xb.fld) && !tp##_is_zero(xb.fld)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf); \
- } else if (tp##_is_signaling_nan(xb.fld, &tstat)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \
- } \
- } \
- \
- if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
- } \
- \
- if (sfprf) { \
- helper_compute_fprf(env, xt.fld); \
- } \
- } \
- \
- putVSR(xT(opcode), &xt, env); \
- float_check_status(env); \
-}
-
-VSX_SQRT(xssqrtdp, 1, float64, VsrD(0), 1, 0)
-VSX_SQRT(xssqrtsp, 1, float64, VsrD(0), 1, 1)
-VSX_SQRT(xvsqrtdp, 2, float64, VsrD(i), 0, 0)
-VSX_SQRT(xvsqrtsp, 4, float32, VsrW(i), 0, 0)
-
-/* VSX_RSQRTE - VSX floating point reciprocal square root estimate
- * op - instruction mnemonic
- * nels - number of elements (1, 2 or 4)
- * tp - type (float32 or float64)
- * fld - vsr_t field (VsrD(*) or VsrW(*))
- * sfprf - set FPRF
- */
-#define VSX_RSQRTE(op, nels, tp, fld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xt, xb; \
- int i; \
- \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- helper_reset_fpstatus(env); \
- \
- for (i = 0; i < nels; i++) { \
- float_status tstat = env->fp_status; \
- set_float_exception_flags(0, &tstat); \
- xt.fld = tp##_sqrt(xb.fld, &tstat); \
- xt.fld = tp##_div(tp##_one, xt.fld, &tstat); \
- env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
- \
- if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
- if (tp##_is_neg(xb.fld) && !tp##_is_zero(xb.fld)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf); \
- } else if (tp##_is_signaling_nan(xb.fld, &tstat)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \
- } \
- } \
- \
- if (r2sp) { \
- xt.fld = helper_frsp(env, xt.fld); \
- } \
- \
- if (sfprf) { \
- helper_compute_fprf(env, xt.fld); \
- } \
- } \
- \
- putVSR(xT(opcode), &xt, env); \
- float_check_status(env); \
-}
-
-VSX_RSQRTE(xsrsqrtedp, 1, float64, VsrD(0), 1, 0)
-VSX_RSQRTE(xsrsqrtesp, 1, float64, VsrD(0), 1, 1)
-VSX_RSQRTE(xvrsqrtedp, 2, float64, VsrD(i), 0, 0)
-VSX_RSQRTE(xvrsqrtesp, 4, float32, VsrW(i), 0, 0)
-
-/* VSX_TDIV - VSX floating point test for divide
- * op - instruction mnemonic
- * nels - number of elements (1, 2 or 4)
- * tp - type (float32 or float64)
- * fld - vsr_t field (VsrD(*) or VsrW(*))
- * emin - minimum unbiased exponent
- * emax - maximum unbiased exponent
- * nbits - number of fraction bits
- */
-#define VSX_TDIV(op, nels, tp, fld, emin, emax, nbits) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xa, xb; \
- int i; \
- int fe_flag = 0; \
- int fg_flag = 0; \
- \
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- \
- for (i = 0; i < nels; i++) { \
- if (unlikely(tp##_is_infinity(xa.fld) || \
- tp##_is_infinity(xb.fld) || \
- tp##_is_zero(xb.fld))) { \
- fe_flag = 1; \
- fg_flag = 1; \
- } else { \
- int e_a = ppc_##tp##_get_unbiased_exp(xa.fld); \
- int e_b = ppc_##tp##_get_unbiased_exp(xb.fld); \
- \
- if (unlikely(tp##_is_any_nan(xa.fld) || \
- tp##_is_any_nan(xb.fld))) { \
- fe_flag = 1; \
- } else if ((e_b <= emin) || (e_b >= (emax-2))) { \
- fe_flag = 1; \
- } else if (!tp##_is_zero(xa.fld) && \
- (((e_a - e_b) >= emax) || \
- ((e_a - e_b) <= (emin+1)) || \
- (e_a <= (emin+nbits)))) { \
- fe_flag = 1; \
- } \
- \
- if (unlikely(tp##_is_zero_or_denormal(xb.fld))) { \
- /* XB is not zero because of the above check and */ \
- /* so must be denormalized. */ \
- fg_flag = 1; \
- } \
- } \
- } \
- \
- env->crf[BF(opcode)] = 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0); \
-}
-
-VSX_TDIV(xstdivdp, 1, float64, VsrD(0), -1022, 1023, 52)
-VSX_TDIV(xvtdivdp, 2, float64, VsrD(i), -1022, 1023, 52)
-VSX_TDIV(xvtdivsp, 4, float32, VsrW(i), -126, 127, 23)
-
-/* VSX_TSQRT - VSX floating point test for square root
- * op - instruction mnemonic
- * nels - number of elements (1, 2 or 4)
- * tp - type (float32 or float64)
- * fld - vsr_t field (VsrD(*) or VsrW(*))
- * emin - minimum unbiased exponent
- * emax - maximum unbiased exponent
- * nbits - number of fraction bits
- */
-#define VSX_TSQRT(op, nels, tp, fld, emin, nbits) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xa, xb; \
- int i; \
- int fe_flag = 0; \
- int fg_flag = 0; \
- \
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- \
- for (i = 0; i < nels; i++) { \
- if (unlikely(tp##_is_infinity(xb.fld) || \
- tp##_is_zero(xb.fld))) { \
- fe_flag = 1; \
- fg_flag = 1; \
- } else { \
- int e_b = ppc_##tp##_get_unbiased_exp(xb.fld); \
- \
- if (unlikely(tp##_is_any_nan(xb.fld))) { \
- fe_flag = 1; \
- } else if (unlikely(tp##_is_zero(xb.fld))) { \
- fe_flag = 1; \
- } else if (unlikely(tp##_is_neg(xb.fld))) { \
- fe_flag = 1; \
- } else if (!tp##_is_zero(xb.fld) && \
- (e_b <= (emin+nbits))) { \
- fe_flag = 1; \
- } \
- \
- if (unlikely(tp##_is_zero_or_denormal(xb.fld))) { \
- /* XB is not zero because of the above check and */ \
- /* therefore must be denormalized. */ \
- fg_flag = 1; \
- } \
- } \
- } \
- \
- env->crf[BF(opcode)] = 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0); \
-}
-
-VSX_TSQRT(xstsqrtdp, 1, float64, VsrD(0), -1022, 52)
-VSX_TSQRT(xvtsqrtdp, 2, float64, VsrD(i), -1022, 52)
-VSX_TSQRT(xvtsqrtsp, 4, float32, VsrW(i), -126, 23)
-
-/* VSX_MADD - VSX floating point muliply/add variations
- * op - instruction mnemonic
- * nels - number of elements (1, 2 or 4)
- * tp - type (float32 or float64)
- * fld - vsr_t field (VsrD(*) or VsrW(*))
- * maddflgs - flags for the float*muladd routine that control the
- * various forms (madd, msub, nmadd, nmsub)
- * afrm - A form (1=A, 0=M)
- * sfprf - set FPRF
- */
-#define VSX_MADD(op, nels, tp, fld, maddflgs, afrm, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xt_in, xa, xb, xt_out; \
- ppc_vsr_t *b, *c; \
- int i; \
- \
- if (afrm) { /* AxB + T */ \
- b = &xb; \
- c = &xt_in; \
- } else { /* AxT + B */ \
- b = &xt_in; \
- c = &xb; \
- } \
- \
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt_in, env); \
- \
- xt_out = xt_in; \
- \
- helper_reset_fpstatus(env); \
- \
- for (i = 0; i < nels; i++) { \
- float_status tstat = env->fp_status; \
- set_float_exception_flags(0, &tstat); \
- if (r2sp && (tstat.float_rounding_mode == float_round_nearest_even)) {\
- /* Avoid double rounding errors by rounding the intermediate */ \
- /* result to odd. */ \
- set_float_rounding_mode(float_round_to_zero, &tstat); \
- xt_out.fld = tp##_muladd(xa.fld, b->fld, c->fld, \
- maddflgs, &tstat); \
- xt_out.fld |= (get_float_exception_flags(&tstat) & \
- float_flag_inexact) != 0; \
- } else { \
- xt_out.fld = tp##_muladd(xa.fld, b->fld, c->fld, \
- maddflgs, &tstat); \
- } \
- env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
- \
- if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \
- if (tp##_is_signaling_nan(xa.fld, &tstat) || \
- tp##_is_signaling_nan(b->fld, &tstat) || \
- tp##_is_signaling_nan(c->fld, &tstat)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \
- tstat.float_exception_flags &= ~float_flag_invalid; \
- } \
- if ((tp##_is_infinity(xa.fld) && tp##_is_zero(b->fld)) || \
- (tp##_is_zero(xa.fld) && tp##_is_infinity(b->fld))) { \
- xt_out.fld = float64_to_##tp(float_invalid_op_excp(env, \
- POWERPC_EXCP_FP_VXIMZ, sfprf), &env->fp_status); \
- tstat.float_exception_flags &= ~float_flag_invalid; \
- } \
- if ((tstat.float_exception_flags & float_flag_invalid) && \
- ((tp##_is_infinity(xa.fld) || \
- tp##_is_infinity(b->fld)) && \
- tp##_is_infinity(c->fld))) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf); \
- } \
- } \
- \
- if (r2sp) { \
- xt_out.fld = helper_frsp(env, xt_out.fld); \
- } \
- \
- if (sfprf) { \
- helper_compute_fprf(env, xt_out.fld); \
- } \
- } \
- putVSR(xT(opcode), &xt_out, env); \
- float_check_status(env); \
-}
-
-#define MADD_FLGS 0
-#define MSUB_FLGS float_muladd_negate_c
-#define NMADD_FLGS float_muladd_negate_result
-#define NMSUB_FLGS (float_muladd_negate_c | float_muladd_negate_result)
-
-VSX_MADD(xsmaddadp, 1, float64, VsrD(0), MADD_FLGS, 1, 1, 0)
-VSX_MADD(xsmaddmdp, 1, float64, VsrD(0), MADD_FLGS, 0, 1, 0)
-VSX_MADD(xsmsubadp, 1, float64, VsrD(0), MSUB_FLGS, 1, 1, 0)
-VSX_MADD(xsmsubmdp, 1, float64, VsrD(0), MSUB_FLGS, 0, 1, 0)
-VSX_MADD(xsnmaddadp, 1, float64, VsrD(0), NMADD_FLGS, 1, 1, 0)
-VSX_MADD(xsnmaddmdp, 1, float64, VsrD(0), NMADD_FLGS, 0, 1, 0)
-VSX_MADD(xsnmsubadp, 1, float64, VsrD(0), NMSUB_FLGS, 1, 1, 0)
-VSX_MADD(xsnmsubmdp, 1, float64, VsrD(0), NMSUB_FLGS, 0, 1, 0)
-
-VSX_MADD(xsmaddasp, 1, float64, VsrD(0), MADD_FLGS, 1, 1, 1)
-VSX_MADD(xsmaddmsp, 1, float64, VsrD(0), MADD_FLGS, 0, 1, 1)
-VSX_MADD(xsmsubasp, 1, float64, VsrD(0), MSUB_FLGS, 1, 1, 1)
-VSX_MADD(xsmsubmsp, 1, float64, VsrD(0), MSUB_FLGS, 0, 1, 1)
-VSX_MADD(xsnmaddasp, 1, float64, VsrD(0), NMADD_FLGS, 1, 1, 1)
-VSX_MADD(xsnmaddmsp, 1, float64, VsrD(0), NMADD_FLGS, 0, 1, 1)
-VSX_MADD(xsnmsubasp, 1, float64, VsrD(0), NMSUB_FLGS, 1, 1, 1)
-VSX_MADD(xsnmsubmsp, 1, float64, VsrD(0), NMSUB_FLGS, 0, 1, 1)
-
-VSX_MADD(xvmaddadp, 2, float64, VsrD(i), MADD_FLGS, 1, 0, 0)
-VSX_MADD(xvmaddmdp, 2, float64, VsrD(i), MADD_FLGS, 0, 0, 0)
-VSX_MADD(xvmsubadp, 2, float64, VsrD(i), MSUB_FLGS, 1, 0, 0)
-VSX_MADD(xvmsubmdp, 2, float64, VsrD(i), MSUB_FLGS, 0, 0, 0)
-VSX_MADD(xvnmaddadp, 2, float64, VsrD(i), NMADD_FLGS, 1, 0, 0)
-VSX_MADD(xvnmaddmdp, 2, float64, VsrD(i), NMADD_FLGS, 0, 0, 0)
-VSX_MADD(xvnmsubadp, 2, float64, VsrD(i), NMSUB_FLGS, 1, 0, 0)
-VSX_MADD(xvnmsubmdp, 2, float64, VsrD(i), NMSUB_FLGS, 0, 0, 0)
-
-VSX_MADD(xvmaddasp, 4, float32, VsrW(i), MADD_FLGS, 1, 0, 0)
-VSX_MADD(xvmaddmsp, 4, float32, VsrW(i), MADD_FLGS, 0, 0, 0)
-VSX_MADD(xvmsubasp, 4, float32, VsrW(i), MSUB_FLGS, 1, 0, 0)
-VSX_MADD(xvmsubmsp, 4, float32, VsrW(i), MSUB_FLGS, 0, 0, 0)
-VSX_MADD(xvnmaddasp, 4, float32, VsrW(i), NMADD_FLGS, 1, 0, 0)
-VSX_MADD(xvnmaddmsp, 4, float32, VsrW(i), NMADD_FLGS, 0, 0, 0)
-VSX_MADD(xvnmsubasp, 4, float32, VsrW(i), NMSUB_FLGS, 1, 0, 0)
-VSX_MADD(xvnmsubmsp, 4, float32, VsrW(i), NMSUB_FLGS, 0, 0, 0)
-
-/* VSX_SCALAR_CMP_DP - VSX scalar floating point compare double precision
- * op - instruction mnemonic
- * cmp - comparison operation
- * exp - expected result of comparison
- * svxvc - set VXVC bit
- */
-#define VSX_SCALAR_CMP_DP(op, cmp, exp, svxvc) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xt, xa, xb; \
- bool vxsnan_flag = false, vxvc_flag = false, vex_flag = false; \
- \
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
- if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) || \
- float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \
- vxsnan_flag = true; \
- if (fpscr_ve == 0 && svxvc) { \
- vxvc_flag = true; \
- } \
- } else if (svxvc) { \
- vxvc_flag = float64_is_quiet_nan(xa.VsrD(0), &env->fp_status) || \
- float64_is_quiet_nan(xb.VsrD(0), &env->fp_status); \
- } \
- if (vxsnan_flag) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
- } \
- if (vxvc_flag) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \
- } \
- vex_flag = fpscr_ve && (vxvc_flag || vxsnan_flag); \
- \
- if (!vex_flag) { \
- if (float64_##cmp(xb.VsrD(0), xa.VsrD(0), &env->fp_status) == exp) { \
- xt.VsrD(0) = -1; \
- xt.VsrD(1) = 0; \
- } else { \
- xt.VsrD(0) = 0; \
- xt.VsrD(1) = 0; \
- } \
- } \
- putVSR(xT(opcode), &xt, env); \
- helper_float_check_status(env); \
-}
-
-VSX_SCALAR_CMP_DP(xscmpeqdp, eq, 1, 0)
-VSX_SCALAR_CMP_DP(xscmpgedp, le, 1, 1)
-VSX_SCALAR_CMP_DP(xscmpgtdp, lt, 1, 1)
-VSX_SCALAR_CMP_DP(xscmpnedp, eq, 0, 0)
-
-#define VSX_SCALAR_CMP(op, ordered) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xa, xb; \
- uint32_t cc = 0; \
- \
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- \
- if (unlikely(float64_is_any_nan(xa.VsrD(0)) || \
- float64_is_any_nan(xb.VsrD(0)))) { \
- if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) || \
- float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
- } \
- if (ordered) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \
- } \
- cc = 1; \
- } else { \
- if (float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status)) { \
- cc = 8; \
- } else if (!float64_le(xa.VsrD(0), xb.VsrD(0), \
- &env->fp_status)) { \
- cc = 4; \
- } else { \
- cc = 2; \
- } \
- } \
- \
- env->fpscr &= ~(0x0F << FPSCR_FPRF); \
- env->fpscr |= cc << FPSCR_FPRF; \
- env->crf[BF(opcode)] = cc; \
- \
- float_check_status(env); \
-}
-
-VSX_SCALAR_CMP(xscmpodp, 1)
-VSX_SCALAR_CMP(xscmpudp, 0)
-
-/* VSX_MAX_MIN - VSX floating point maximum/minimum
- * name - instruction mnemonic
- * op - operation (max or min)
- * nels - number of elements (1, 2 or 4)
- * tp - type (float32 or float64)
- * fld - vsr_t field (VsrD(*) or VsrW(*))
- */
-#define VSX_MAX_MIN(name, op, nels, tp, fld) \
-void helper_##name(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xt, xa, xb; \
- int i; \
- \
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
- for (i = 0; i < nels; i++) { \
- xt.fld = tp##_##op(xa.fld, xb.fld, &env->fp_status); \
- if (unlikely(tp##_is_signaling_nan(xa.fld, &env->fp_status) || \
- tp##_is_signaling_nan(xb.fld, &env->fp_status))) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
- } \
- } \
- \
- putVSR(xT(opcode), &xt, env); \
- float_check_status(env); \
-}
-
-VSX_MAX_MIN(xsmaxdp, maxnum, 1, float64, VsrD(0))
-VSX_MAX_MIN(xvmaxdp, maxnum, 2, float64, VsrD(i))
-VSX_MAX_MIN(xvmaxsp, maxnum, 4, float32, VsrW(i))
-VSX_MAX_MIN(xsmindp, minnum, 1, float64, VsrD(0))
-VSX_MAX_MIN(xvmindp, minnum, 2, float64, VsrD(i))
-VSX_MAX_MIN(xvminsp, minnum, 4, float32, VsrW(i))
-
-/* VSX_CMP - VSX floating point compare
- * op - instruction mnemonic
- * nels - number of elements (1, 2 or 4)
- * tp - type (float32 or float64)
- * fld - vsr_t field (VsrD(*) or VsrW(*))
- * cmp - comparison operation
- * svxvc - set VXVC bit
- * exp - expected result of comparison
- */
-#define VSX_CMP(op, nels, tp, fld, cmp, svxvc, exp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xt, xa, xb; \
- int i; \
- int all_true = 1; \
- int all_false = 1; \
- \
- getVSR(xA(opcode), &xa, env); \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
- for (i = 0; i < nels; i++) { \
- if (unlikely(tp##_is_any_nan(xa.fld) || \
- tp##_is_any_nan(xb.fld))) { \
- if (tp##_is_signaling_nan(xa.fld, &env->fp_status) || \
- tp##_is_signaling_nan(xb.fld, &env->fp_status)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
- } \
- if (svxvc) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \
- } \
- xt.fld = 0; \
- all_true = 0; \
- } else { \
- if (tp##_##cmp(xb.fld, xa.fld, &env->fp_status) == exp) { \
- xt.fld = -1; \
- all_false = 0; \
- } else { \
- xt.fld = 0; \
- all_true = 0; \
- } \
- } \
- } \
- \
- putVSR(xT(opcode), &xt, env); \
- if ((opcode >> (31-21)) & 1) { \
- env->crf[6] = (all_true ? 0x8 : 0) | (all_false ? 0x2 : 0); \
- } \
- float_check_status(env); \
- }
-
-VSX_CMP(xvcmpeqdp, 2, float64, VsrD(i), eq, 0, 1)
-VSX_CMP(xvcmpgedp, 2, float64, VsrD(i), le, 1, 1)
-VSX_CMP(xvcmpgtdp, 2, float64, VsrD(i), lt, 1, 1)
-VSX_CMP(xvcmpnedp, 2, float64, VsrD(i), eq, 0, 0)
-VSX_CMP(xvcmpeqsp, 4, float32, VsrW(i), eq, 0, 1)
-VSX_CMP(xvcmpgesp, 4, float32, VsrW(i), le, 1, 1)
-VSX_CMP(xvcmpgtsp, 4, float32, VsrW(i), lt, 1, 1)
-VSX_CMP(xvcmpnesp, 4, float32, VsrW(i), eq, 0, 0)
-
-/* VSX_CVT_FP_TO_FP - VSX floating point/floating point conversion
- * op - instruction mnemonic
- * nels - number of elements (1, 2 or 4)
- * stp - source type (float32 or float64)
- * ttp - target type (float32 or float64)
- * sfld - source vsr_t field
- * tfld - target vsr_t field (f32 or f64)
- * sfprf - set FPRF
- */
-#define VSX_CVT_FP_TO_FP(op, nels, stp, ttp, sfld, tfld, sfprf) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xt, xb; \
- int i; \
- \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
- for (i = 0; i < nels; i++) { \
- xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \
- if (unlikely(stp##_is_signaling_nan(xb.sfld, \
- &env->fp_status))) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
- xt.tfld = ttp##_snan_to_qnan(xt.tfld); \
- } \
- if (sfprf) { \
- helper_compute_fprf(env, ttp##_to_float64(xt.tfld, \
- &env->fp_status)); \
- } \
- } \
- \
- putVSR(xT(opcode), &xt, env); \
- float_check_status(env); \
-}
-
-VSX_CVT_FP_TO_FP(xscvdpsp, 1, float64, float32, VsrD(0), VsrW(0), 1)
-VSX_CVT_FP_TO_FP(xscvspdp, 1, float32, float64, VsrW(0), VsrD(0), 1)
-VSX_CVT_FP_TO_FP(xvcvdpsp, 2, float64, float32, VsrD(i), VsrW(2*i), 0)
-VSX_CVT_FP_TO_FP(xvcvspdp, 2, float32, float64, VsrW(2*i), VsrD(i), 0)
-
-uint64_t helper_xscvdpspn(CPUPPCState *env, uint64_t xb)
-{
- float_status tstat = env->fp_status;
- set_float_exception_flags(0, &tstat);
-
- return (uint64_t)float64_to_float32(xb, &tstat) << 32;
-}
-
-uint64_t helper_xscvspdpn(CPUPPCState *env, uint64_t xb)
-{
- float_status tstat = env->fp_status;
- set_float_exception_flags(0, &tstat);
-
- return float32_to_float64(xb >> 32, &tstat);
-}
-
-/* VSX_CVT_FP_TO_INT - VSX floating point to integer conversion
- * op - instruction mnemonic
- * nels - number of elements (1, 2 or 4)
- * stp - source type (float32 or float64)
- * ttp - target type (int32, uint32, int64 or uint64)
- * sfld - source vsr_t field
- * tfld - target vsr_t field
- * rnan - resulting NaN
- */
-#define VSX_CVT_FP_TO_INT(op, nels, stp, ttp, sfld, tfld, rnan) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xt, xb; \
- int i; \
- \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
- for (i = 0; i < nels; i++) { \
- if (unlikely(stp##_is_any_nan(xb.sfld))) { \
- if (stp##_is_signaling_nan(xb.sfld, &env->fp_status)) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
- } \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0); \
- xt.tfld = rnan; \
- } else { \
- xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld, \
- &env->fp_status); \
- if (env->fp_status.float_exception_flags & float_flag_invalid) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0); \
- } \
- } \
- } \
- \
- putVSR(xT(opcode), &xt, env); \
- float_check_status(env); \
-}
-
-VSX_CVT_FP_TO_INT(xscvdpsxds, 1, float64, int64, VsrD(0), VsrD(0), \
- 0x8000000000000000ULL)
-VSX_CVT_FP_TO_INT(xscvdpsxws, 1, float64, int32, VsrD(0), VsrW(1), \
- 0x80000000U)
-VSX_CVT_FP_TO_INT(xscvdpuxds, 1, float64, uint64, VsrD(0), VsrD(0), 0ULL)
-VSX_CVT_FP_TO_INT(xscvdpuxws, 1, float64, uint32, VsrD(0), VsrW(1), 0U)
-VSX_CVT_FP_TO_INT(xvcvdpsxds, 2, float64, int64, VsrD(i), VsrD(i), \
- 0x8000000000000000ULL)
-VSX_CVT_FP_TO_INT(xvcvdpsxws, 2, float64, int32, VsrD(i), VsrW(2*i), \
- 0x80000000U)
-VSX_CVT_FP_TO_INT(xvcvdpuxds, 2, float64, uint64, VsrD(i), VsrD(i), 0ULL)
-VSX_CVT_FP_TO_INT(xvcvdpuxws, 2, float64, uint32, VsrD(i), VsrW(2*i), 0U)
-VSX_CVT_FP_TO_INT(xvcvspsxds, 2, float32, int64, VsrW(2*i), VsrD(i), \
- 0x8000000000000000ULL)
-VSX_CVT_FP_TO_INT(xvcvspsxws, 4, float32, int32, VsrW(i), VsrW(i), 0x80000000U)
-VSX_CVT_FP_TO_INT(xvcvspuxds, 2, float32, uint64, VsrW(2*i), VsrD(i), 0ULL)
-VSX_CVT_FP_TO_INT(xvcvspuxws, 4, float32, uint32, VsrW(i), VsrW(i), 0U)
-
-/* VSX_CVT_INT_TO_FP - VSX integer to floating point conversion
- * op - instruction mnemonic
- * nels - number of elements (1, 2 or 4)
- * stp - source type (int32, uint32, int64 or uint64)
- * ttp - target type (float32 or float64)
- * sfld - source vsr_t field
- * tfld - target vsr_t field
- * jdef - definition of the j index (i or 2*i)
- * sfprf - set FPRF
- */
-#define VSX_CVT_INT_TO_FP(op, nels, stp, ttp, sfld, tfld, sfprf, r2sp) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xt, xb; \
- int i; \
- \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
- for (i = 0; i < nels; i++) { \
- xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \
- if (r2sp) { \
- xt.tfld = helper_frsp(env, xt.tfld); \
- } \
- if (sfprf) { \
- helper_compute_fprf(env, xt.tfld); \
- } \
- } \
- \
- putVSR(xT(opcode), &xt, env); \
- float_check_status(env); \
-}
-
-VSX_CVT_INT_TO_FP(xscvsxddp, 1, int64, float64, VsrD(0), VsrD(0), 1, 0)
-VSX_CVT_INT_TO_FP(xscvuxddp, 1, uint64, float64, VsrD(0), VsrD(0), 1, 0)
-VSX_CVT_INT_TO_FP(xscvsxdsp, 1, int64, float64, VsrD(0), VsrD(0), 1, 1)
-VSX_CVT_INT_TO_FP(xscvuxdsp, 1, uint64, float64, VsrD(0), VsrD(0), 1, 1)
-VSX_CVT_INT_TO_FP(xvcvsxddp, 2, int64, float64, VsrD(i), VsrD(i), 0, 0)
-VSX_CVT_INT_TO_FP(xvcvuxddp, 2, uint64, float64, VsrD(i), VsrD(i), 0, 0)
-VSX_CVT_INT_TO_FP(xvcvsxwdp, 2, int32, float64, VsrW(2*i), VsrD(i), 0, 0)
-VSX_CVT_INT_TO_FP(xvcvuxwdp, 2, uint64, float64, VsrW(2*i), VsrD(i), 0, 0)
-VSX_CVT_INT_TO_FP(xvcvsxdsp, 2, int64, float32, VsrD(i), VsrW(2*i), 0, 0)
-VSX_CVT_INT_TO_FP(xvcvuxdsp, 2, uint64, float32, VsrD(i), VsrW(2*i), 0, 0)
-VSX_CVT_INT_TO_FP(xvcvsxwsp, 4, int32, float32, VsrW(i), VsrW(i), 0, 0)
-VSX_CVT_INT_TO_FP(xvcvuxwsp, 4, uint32, float32, VsrW(i), VsrW(i), 0, 0)
-
-/* For "use current rounding mode", define a value that will not be one of
- * the existing rounding model enums.
- */
-#define FLOAT_ROUND_CURRENT (float_round_nearest_even + float_round_down + \
- float_round_up + float_round_to_zero)
-
-/* VSX_ROUND - VSX floating point round
- * op - instruction mnemonic
- * nels - number of elements (1, 2 or 4)
- * tp - type (float32 or float64)
- * fld - vsr_t field (VsrD(*) or VsrW(*))
- * rmode - rounding mode
- * sfprf - set FPRF
- */
-#define VSX_ROUND(op, nels, tp, fld, rmode, sfprf) \
-void helper_##op(CPUPPCState *env, uint32_t opcode) \
-{ \
- ppc_vsr_t xt, xb; \
- int i; \
- getVSR(xB(opcode), &xb, env); \
- getVSR(xT(opcode), &xt, env); \
- \
- if (rmode != FLOAT_ROUND_CURRENT) { \
- set_float_rounding_mode(rmode, &env->fp_status); \
- } \
- \
- for (i = 0; i < nels; i++) { \
- if (unlikely(tp##_is_signaling_nan(xb.fld, \
- &env->fp_status))) { \
- float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \
- xt.fld = tp##_snan_to_qnan(xb.fld); \
- } else { \
- xt.fld = tp##_round_to_int(xb.fld, &env->fp_status); \
- } \
- if (sfprf) { \
- helper_compute_fprf(env, xt.fld); \
- } \
- } \
- \
- /* If this is not a "use current rounding mode" instruction, \
- * then inhibit setting of the XX bit and restore rounding \
- * mode from FPSCR */ \
- if (rmode != FLOAT_ROUND_CURRENT) { \
- fpscr_set_rounding_mode(env); \
- env->fp_status.float_exception_flags &= ~float_flag_inexact; \
- } \
- \
- putVSR(xT(opcode), &xt, env); \
- float_check_status(env); \
-}
-
-VSX_ROUND(xsrdpi, 1, float64, VsrD(0), float_round_ties_away, 1)
-VSX_ROUND(xsrdpic, 1, float64, VsrD(0), FLOAT_ROUND_CURRENT, 1)
-VSX_ROUND(xsrdpim, 1, float64, VsrD(0), float_round_down, 1)
-VSX_ROUND(xsrdpip, 1, float64, VsrD(0), float_round_up, 1)
-VSX_ROUND(xsrdpiz, 1, float64, VsrD(0), float_round_to_zero, 1)
-
-VSX_ROUND(xvrdpi, 2, float64, VsrD(i), float_round_ties_away, 0)
-VSX_ROUND(xvrdpic, 2, float64, VsrD(i), FLOAT_ROUND_CURRENT, 0)
-VSX_ROUND(xvrdpim, 2, float64, VsrD(i), float_round_down, 0)
-VSX_ROUND(xvrdpip, 2, float64, VsrD(i), float_round_up, 0)
-VSX_ROUND(xvrdpiz, 2, float64, VsrD(i), float_round_to_zero, 0)
-
-VSX_ROUND(xvrspi, 4, float32, VsrW(i), float_round_ties_away, 0)
-VSX_ROUND(xvrspic, 4, float32, VsrW(i), FLOAT_ROUND_CURRENT, 0)
-VSX_ROUND(xvrspim, 4, float32, VsrW(i), float_round_down, 0)
-VSX_ROUND(xvrspip, 4, float32, VsrW(i), float_round_up, 0)
-VSX_ROUND(xvrspiz, 4, float32, VsrW(i), float_round_to_zero, 0)
-
-uint64_t helper_xsrsp(CPUPPCState *env, uint64_t xb)
-{
- helper_reset_fpstatus(env);
-
- uint64_t xt = helper_frsp(env, xb);
-
- helper_compute_fprf(env, xt);
- float_check_status(env);
- return xt;
-}
diff --git a/target-ppc/gdbstub.c b/target-ppc/gdbstub.c
deleted file mode 100644
index 7a338136a8..0000000000
--- a/target-ppc/gdbstub.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * PowerPC gdb server stub
- *
- * Copyright (c) 2003-2005 Fabrice Bellard
- * Copyright (c) 2013 SUSE LINUX Products GmbH
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "exec/gdbstub.h"
-
-static int ppc_gdb_register_len_apple(int n)
-{
- switch (n) {
- case 0 ... 31:
- /* gprs */
- return 8;
- case 32 ... 63:
- /* fprs */
- return 8;
- case 64 ... 95:
- return 16;
- case 64+32: /* nip */
- case 65+32: /* msr */
- case 67+32: /* lr */
- case 68+32: /* ctr */
- case 69+32: /* xer */
- case 70+32: /* fpscr */
- return 8;
- case 66+32: /* cr */
- return 4;
- default:
- return 0;
- }
-}
-
-static int ppc_gdb_register_len(int n)
-{
- switch (n) {
- case 0 ... 31:
- /* gprs */
- return sizeof(target_ulong);
- case 32 ... 63:
- /* fprs */
- if (gdb_has_xml) {
- return 0;
- }
- return 8;
- case 66:
- /* cr */
- return 4;
- case 64:
- /* nip */
- case 65:
- /* msr */
- case 67:
- /* lr */
- case 68:
- /* ctr */
- case 69:
- /* xer */
- return sizeof(target_ulong);
- case 70:
- /* fpscr */
- if (gdb_has_xml) {
- return 0;
- }
- return sizeof(target_ulong);
- default:
- return 0;
- }
-}
-
-/* We need to present the registers to gdb in the "current" memory ordering.
- For user-only mode we get this for free; TARGET_WORDS_BIGENDIAN is set to
- the proper ordering for the binary, and cannot be changed.
- For system mode, TARGET_WORDS_BIGENDIAN is always set, and we must check
- the current mode of the chip to see if we're running in little-endian. */
-void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len)
-{
-#ifndef CONFIG_USER_ONLY
- if (!msr_le) {
- /* do nothing */
- } else if (len == 4) {
- bswap32s((uint32_t *)mem_buf);
- } else if (len == 8) {
- bswap64s((uint64_t *)mem_buf);
- } else {
- g_assert_not_reached();
- }
-#endif
-}
-
-/* Old gdb always expects FP registers. Newer (xml-aware) gdb only
- * expects whatever the target description contains. Due to a
- * historical mishap the FP registers appear in between core integer
- * regs and PC, MSR, CR, and so forth. We hack round this by giving the
- * FP regs zero size when talking to a newer gdb.
- */
-
-int ppc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- int r = ppc_gdb_register_len(n);
-
- if (!r) {
- return r;
- }
-
- if (n < 32) {
- /* gprs */
- gdb_get_regl(mem_buf, env->gpr[n]);
- } else if (n < 64) {
- /* fprs */
- stfq_p(mem_buf, env->fpr[n-32]);
- } else {
- switch (n) {
- case 64:
- gdb_get_regl(mem_buf, env->nip);
- break;
- case 65:
- gdb_get_regl(mem_buf, env->msr);
- break;
- case 66:
- {
- uint32_t cr = 0;
- int i;
- for (i = 0; i < 8; i++) {
- cr |= env->crf[i] << (32 - ((i + 1) * 4));
- }
- gdb_get_reg32(mem_buf, cr);
- break;
- }
- case 67:
- gdb_get_regl(mem_buf, env->lr);
- break;
- case 68:
- gdb_get_regl(mem_buf, env->ctr);
- break;
- case 69:
- gdb_get_regl(mem_buf, env->xer);
- break;
- case 70:
- gdb_get_reg32(mem_buf, env->fpscr);
- break;
- }
- }
- ppc_maybe_bswap_register(env, mem_buf, r);
- return r;
-}
-
-int ppc_cpu_gdb_read_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- int r = ppc_gdb_register_len_apple(n);
-
- if (!r) {
- return r;
- }
-
- if (n < 32) {
- /* gprs */
- gdb_get_reg64(mem_buf, env->gpr[n]);
- } else if (n < 64) {
- /* fprs */
- stfq_p(mem_buf, env->fpr[n-32]);
- } else if (n < 96) {
- /* Altivec */
- stq_p(mem_buf, n - 64);
- stq_p(mem_buf + 8, 0);
- } else {
- switch (n) {
- case 64 + 32:
- gdb_get_reg64(mem_buf, env->nip);
- break;
- case 65 + 32:
- gdb_get_reg64(mem_buf, env->msr);
- break;
- case 66 + 32:
- {
- uint32_t cr = 0;
- int i;
- for (i = 0; i < 8; i++) {
- cr |= env->crf[i] << (32 - ((i + 1) * 4));
- }
- gdb_get_reg32(mem_buf, cr);
- break;
- }
- case 67 + 32:
- gdb_get_reg64(mem_buf, env->lr);
- break;
- case 68 + 32:
- gdb_get_reg64(mem_buf, env->ctr);
- break;
- case 69 + 32:
- gdb_get_reg64(mem_buf, env->xer);
- break;
- case 70 + 32:
- gdb_get_reg64(mem_buf, env->fpscr);
- break;
- }
- }
- ppc_maybe_bswap_register(env, mem_buf, r);
- return r;
-}
-
-int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- int r = ppc_gdb_register_len(n);
-
- if (!r) {
- return r;
- }
- ppc_maybe_bswap_register(env, mem_buf, r);
- if (n < 32) {
- /* gprs */
- env->gpr[n] = ldtul_p(mem_buf);
- } else if (n < 64) {
- /* fprs */
- env->fpr[n-32] = ldfq_p(mem_buf);
- } else {
- switch (n) {
- case 64:
- env->nip = ldtul_p(mem_buf);
- break;
- case 65:
- ppc_store_msr(env, ldtul_p(mem_buf));
- break;
- case 66:
- {
- uint32_t cr = ldl_p(mem_buf);
- int i;
- for (i = 0; i < 8; i++) {
- env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
- }
- break;
- }
- case 67:
- env->lr = ldtul_p(mem_buf);
- break;
- case 68:
- env->ctr = ldtul_p(mem_buf);
- break;
- case 69:
- env->xer = ldtul_p(mem_buf);
- break;
- case 70:
- /* fpscr */
- store_fpscr(env, ldtul_p(mem_buf), 0xffffffff);
- break;
- }
- }
- return r;
-}
-int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- int r = ppc_gdb_register_len_apple(n);
-
- if (!r) {
- return r;
- }
- ppc_maybe_bswap_register(env, mem_buf, r);
- if (n < 32) {
- /* gprs */
- env->gpr[n] = ldq_p(mem_buf);
- } else if (n < 64) {
- /* fprs */
- env->fpr[n-32] = ldfq_p(mem_buf);
- } else {
- switch (n) {
- case 64 + 32:
- env->nip = ldq_p(mem_buf);
- break;
- case 65 + 32:
- ppc_store_msr(env, ldq_p(mem_buf));
- break;
- case 66 + 32:
- {
- uint32_t cr = ldl_p(mem_buf);
- int i;
- for (i = 0; i < 8; i++) {
- env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
- }
- break;
- }
- case 67 + 32:
- env->lr = ldq_p(mem_buf);
- break;
- case 68 + 32:
- env->ctr = ldq_p(mem_buf);
- break;
- case 69 + 32:
- env->xer = ldq_p(mem_buf);
- break;
- case 70 + 32:
- /* fpscr */
- store_fpscr(env, ldq_p(mem_buf), 0xffffffff);
- break;
- }
- }
- return r;
-}
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
deleted file mode 100644
index da00f0ab49..0000000000
--- a/target-ppc/helper.h
+++ /dev/null
@@ -1,742 +0,0 @@
-DEF_HELPER_FLAGS_3(raise_exception_err, TCG_CALL_NO_WG, void, env, i32, i32)
-DEF_HELPER_FLAGS_2(raise_exception, TCG_CALL_NO_WG, void, env, i32)
-DEF_HELPER_FLAGS_4(tw, TCG_CALL_NO_WG, void, env, tl, tl, i32)
-#if defined(TARGET_PPC64)
-DEF_HELPER_FLAGS_4(td, TCG_CALL_NO_WG, void, env, tl, tl, i32)
-#endif
-#if !defined(CONFIG_USER_ONLY)
-DEF_HELPER_2(store_msr, void, env, tl)
-DEF_HELPER_1(rfi, void, env)
-DEF_HELPER_1(rfsvc, void, env)
-DEF_HELPER_1(40x_rfci, void, env)
-DEF_HELPER_1(rfci, void, env)
-DEF_HELPER_1(rfdi, void, env)
-DEF_HELPER_1(rfmci, void, env)
-#if defined(TARGET_PPC64)
-DEF_HELPER_2(pminsn, void, env, i32)
-DEF_HELPER_1(rfid, void, env)
-DEF_HELPER_1(hrfid, void, env)
-DEF_HELPER_2(store_lpcr, void, env, tl)
-#endif
-DEF_HELPER_1(check_tlb_flush_local, void, env)
-DEF_HELPER_1(check_tlb_flush_global, void, env)
-#endif
-
-DEF_HELPER_3(lmw, void, env, tl, i32)
-DEF_HELPER_FLAGS_3(stmw, TCG_CALL_NO_WG, void, env, tl, i32)
-DEF_HELPER_4(lsw, void, env, tl, i32, i32)
-DEF_HELPER_5(lswx, void, env, tl, i32, i32, i32)
-DEF_HELPER_FLAGS_4(stsw, TCG_CALL_NO_WG, void, env, tl, i32, i32)
-DEF_HELPER_FLAGS_3(dcbz, TCG_CALL_NO_WG, void, env, tl, i32)
-DEF_HELPER_FLAGS_2(icbi, TCG_CALL_NO_WG, void, env, tl)
-DEF_HELPER_5(lscbx, tl, env, tl, i32, i32, i32)
-
-#if defined(TARGET_PPC64)
-DEF_HELPER_4(divdeu, i64, env, i64, i64, i32)
-DEF_HELPER_4(divde, i64, env, i64, i64, i32)
-#endif
-DEF_HELPER_4(divweu, tl, env, tl, tl, i32)
-DEF_HELPER_4(divwe, tl, env, tl, tl, i32)
-
-DEF_HELPER_FLAGS_1(cntlzw, TCG_CALL_NO_RWG_SE, tl, tl)
-DEF_HELPER_FLAGS_1(cnttzw, TCG_CALL_NO_RWG_SE, tl, tl)
-DEF_HELPER_FLAGS_1(popcntb, TCG_CALL_NO_RWG_SE, tl, tl)
-DEF_HELPER_FLAGS_1(popcntw, TCG_CALL_NO_RWG_SE, tl, tl)
-DEF_HELPER_FLAGS_2(cmpb, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-DEF_HELPER_3(sraw, tl, env, tl, tl)
-#if defined(TARGET_PPC64)
-DEF_HELPER_FLAGS_2(cmpeqb, TCG_CALL_NO_RWG_SE, i32, tl, tl)
-DEF_HELPER_FLAGS_1(cntlzd, TCG_CALL_NO_RWG_SE, tl, tl)
-DEF_HELPER_FLAGS_1(cnttzd, TCG_CALL_NO_RWG_SE, tl, tl)
-DEF_HELPER_FLAGS_1(popcntd, TCG_CALL_NO_RWG_SE, tl, tl)
-DEF_HELPER_FLAGS_2(bpermd, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_3(srad, tl, env, tl, tl)
-DEF_HELPER_0(darn32, tl)
-DEF_HELPER_0(darn64, tl)
-#endif
-
-DEF_HELPER_FLAGS_1(cntlsw32, TCG_CALL_NO_RWG_SE, i32, i32)
-DEF_HELPER_FLAGS_1(cntlzw32, TCG_CALL_NO_RWG_SE, i32, i32)
-DEF_HELPER_FLAGS_2(brinc, TCG_CALL_NO_RWG_SE, tl, tl, tl)
-
-DEF_HELPER_1(float_check_status, void, env)
-DEF_HELPER_1(reset_fpstatus, void, env)
-DEF_HELPER_2(compute_fprf, void, env, i64)
-DEF_HELPER_3(store_fpscr, void, env, i64, i32)
-DEF_HELPER_2(fpscr_clrbit, void, env, i32)
-DEF_HELPER_2(fpscr_setbit, void, env, i32)
-DEF_HELPER_2(float64_to_float32, i32, env, i64)
-DEF_HELPER_2(float32_to_float64, i64, env, i32)
-
-DEF_HELPER_4(fcmpo, void, env, i64, i64, i32)
-DEF_HELPER_4(fcmpu, void, env, i64, i64, i32)
-
-DEF_HELPER_2(fctiw, i64, env, i64)
-DEF_HELPER_2(fctiwu, i64, env, i64)
-DEF_HELPER_2(fctiwz, i64, env, i64)
-DEF_HELPER_2(fctiwuz, i64, env, i64)
-DEF_HELPER_2(fcfid, i64, env, i64)
-DEF_HELPER_2(fcfidu, i64, env, i64)
-DEF_HELPER_2(fcfids, i64, env, i64)
-DEF_HELPER_2(fcfidus, i64, env, i64)
-DEF_HELPER_2(fctid, i64, env, i64)
-DEF_HELPER_2(fctidu, i64, env, i64)
-DEF_HELPER_2(fctidz, i64, env, i64)
-DEF_HELPER_2(fctiduz, i64, env, i64)
-DEF_HELPER_2(frsp, i64, env, i64)
-DEF_HELPER_2(frin, i64, env, i64)
-DEF_HELPER_2(friz, i64, env, i64)
-DEF_HELPER_2(frip, i64, env, i64)
-DEF_HELPER_2(frim, i64, env, i64)
-
-DEF_HELPER_3(fadd, i64, env, i64, i64)
-DEF_HELPER_3(fsub, i64, env, i64, i64)
-DEF_HELPER_3(fmul, i64, env, i64, i64)
-DEF_HELPER_3(fdiv, i64, env, i64, i64)
-DEF_HELPER_4(fmadd, i64, env, i64, i64, i64)
-DEF_HELPER_4(fmsub, i64, env, i64, i64, i64)
-DEF_HELPER_4(fnmadd, i64, env, i64, i64, i64)
-DEF_HELPER_4(fnmsub, i64, env, i64, i64, i64)
-DEF_HELPER_2(fsqrt, i64, env, i64)
-DEF_HELPER_2(fre, i64, env, i64)
-DEF_HELPER_2(fres, i64, env, i64)
-DEF_HELPER_2(frsqrte, i64, env, i64)
-DEF_HELPER_4(fsel, i64, env, i64, i64, i64)
-
-DEF_HELPER_FLAGS_2(ftdiv, TCG_CALL_NO_RWG_SE, i32, i64, i64)
-DEF_HELPER_FLAGS_1(ftsqrt, TCG_CALL_NO_RWG_SE, i32, i64)
-
-#define dh_alias_avr ptr
-#define dh_ctype_avr ppc_avr_t *
-#define dh_is_signed_avr dh_is_signed_ptr
-
-DEF_HELPER_3(vaddubm, void, avr, avr, avr)
-DEF_HELPER_3(vadduhm, void, avr, avr, avr)
-DEF_HELPER_3(vadduwm, void, avr, avr, avr)
-DEF_HELPER_3(vaddudm, void, avr, avr, avr)
-DEF_HELPER_3(vsububm, void, avr, avr, avr)
-DEF_HELPER_3(vsubuhm, void, avr, avr, avr)
-DEF_HELPER_3(vsubuwm, void, avr, avr, avr)
-DEF_HELPER_3(vsubudm, void, avr, avr, avr)
-DEF_HELPER_3(vavgub, void, avr, avr, avr)
-DEF_HELPER_3(vavguh, void, avr, avr, avr)
-DEF_HELPER_3(vavguw, void, avr, avr, avr)
-DEF_HELPER_3(vabsdub, void, avr, avr, avr)
-DEF_HELPER_3(vabsduh, void, avr, avr, avr)
-DEF_HELPER_3(vabsduw, void, avr, avr, avr)
-DEF_HELPER_3(vavgsb, void, avr, avr, avr)
-DEF_HELPER_3(vavgsh, void, avr, avr, avr)
-DEF_HELPER_3(vavgsw, void, avr, avr, avr)
-DEF_HELPER_3(vminsb, void, avr, avr, avr)
-DEF_HELPER_3(vminsh, void, avr, avr, avr)
-DEF_HELPER_3(vminsw, void, avr, avr, avr)
-DEF_HELPER_3(vminsd, void, avr, avr, avr)
-DEF_HELPER_3(vmaxsb, void, avr, avr, avr)
-DEF_HELPER_3(vmaxsh, void, avr, avr, avr)
-DEF_HELPER_3(vmaxsw, void, avr, avr, avr)
-DEF_HELPER_3(vmaxsd, void, avr, avr, avr)
-DEF_HELPER_3(vminub, void, avr, avr, avr)
-DEF_HELPER_3(vminuh, void, avr, avr, avr)
-DEF_HELPER_3(vminuw, void, avr, avr, avr)
-DEF_HELPER_3(vminud, void, avr, avr, avr)
-DEF_HELPER_3(vmaxub, void, avr, avr, avr)
-DEF_HELPER_3(vmaxuh, void, avr, avr, avr)
-DEF_HELPER_3(vmaxuw, void, avr, avr, avr)
-DEF_HELPER_3(vmaxud, void, avr, avr, avr)
-DEF_HELPER_4(vcmpequb, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpequh, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpequw, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpequd, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpneb, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpneh, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpnew, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpnezb, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpnezh, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpnezw, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtub, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtuh, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtuw, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtud, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtsb, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtsh, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtsw, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtsd, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpeqfp, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgefp, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtfp, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpbfp, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpequb_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpequh_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpequw_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpequd_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpneb_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpneh_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpnew_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpnezb_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpnezh_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpnezw_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtub_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtuh_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtuw_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtud_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtsb_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtsh_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtsw_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtsd_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpeqfp_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgefp_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpgtfp_dot, void, env, avr, avr, avr)
-DEF_HELPER_4(vcmpbfp_dot, void, env, avr, avr, avr)
-DEF_HELPER_3(vmrglb, void, avr, avr, avr)
-DEF_HELPER_3(vmrglh, void, avr, avr, avr)
-DEF_HELPER_3(vmrglw, void, avr, avr, avr)
-DEF_HELPER_3(vmrghb, void, avr, avr, avr)
-DEF_HELPER_3(vmrghh, void, avr, avr, avr)
-DEF_HELPER_3(vmrghw, void, avr, avr, avr)
-DEF_HELPER_3(vmulesb, void, avr, avr, avr)
-DEF_HELPER_3(vmulesh, void, avr, avr, avr)
-DEF_HELPER_3(vmulesw, void, avr, avr, avr)
-DEF_HELPER_3(vmuleub, void, avr, avr, avr)
-DEF_HELPER_3(vmuleuh, void, avr, avr, avr)
-DEF_HELPER_3(vmuleuw, void, avr, avr, avr)
-DEF_HELPER_3(vmulosb, void, avr, avr, avr)
-DEF_HELPER_3(vmulosh, void, avr, avr, avr)
-DEF_HELPER_3(vmulosw, void, avr, avr, avr)
-DEF_HELPER_3(vmuloub, void, avr, avr, avr)
-DEF_HELPER_3(vmulouh, void, avr, avr, avr)
-DEF_HELPER_3(vmulouw, void, avr, avr, avr)
-DEF_HELPER_3(vmuluwm, void, avr, avr, avr)
-DEF_HELPER_3(vsrab, void, avr, avr, avr)
-DEF_HELPER_3(vsrah, void, avr, avr, avr)
-DEF_HELPER_3(vsraw, void, avr, avr, avr)
-DEF_HELPER_3(vsrad, void, avr, avr, avr)
-DEF_HELPER_3(vsrb, void, avr, avr, avr)
-DEF_HELPER_3(vsrh, void, avr, avr, avr)
-DEF_HELPER_3(vsrw, void, avr, avr, avr)
-DEF_HELPER_3(vsrd, void, avr, avr, avr)
-DEF_HELPER_3(vslb, void, avr, avr, avr)
-DEF_HELPER_3(vslh, void, avr, avr, avr)
-DEF_HELPER_3(vslw, void, avr, avr, avr)
-DEF_HELPER_3(vsld, void, avr, avr, avr)
-DEF_HELPER_3(vslo, void, avr, avr, avr)
-DEF_HELPER_3(vsro, void, avr, avr, avr)
-DEF_HELPER_3(vsrv, void, avr, avr, avr)
-DEF_HELPER_3(vslv, void, avr, avr, avr)
-DEF_HELPER_3(vaddcuw, void, avr, avr, avr)
-DEF_HELPER_2(vprtybw, void, avr, avr)
-DEF_HELPER_2(vprtybd, void, avr, avr)
-DEF_HELPER_2(vprtybq, void, avr, avr)
-DEF_HELPER_3(vsubcuw, void, avr, avr, avr)
-DEF_HELPER_2(lvsl, void, avr, tl)
-DEF_HELPER_2(lvsr, void, avr, tl)
-DEF_HELPER_4(vaddsbs, void, env, avr, avr, avr)
-DEF_HELPER_4(vaddshs, void, env, avr, avr, avr)
-DEF_HELPER_4(vaddsws, void, env, avr, avr, avr)
-DEF_HELPER_4(vsubsbs, void, env, avr, avr, avr)
-DEF_HELPER_4(vsubshs, void, env, avr, avr, avr)
-DEF_HELPER_4(vsubsws, void, env, avr, avr, avr)
-DEF_HELPER_4(vaddubs, void, env, avr, avr, avr)
-DEF_HELPER_4(vadduhs, void, env, avr, avr, avr)
-DEF_HELPER_4(vadduws, void, env, avr, avr, avr)
-DEF_HELPER_4(vsububs, void, env, avr, avr, avr)
-DEF_HELPER_4(vsubuhs, void, env, avr, avr, avr)
-DEF_HELPER_4(vsubuws, void, env, avr, avr, avr)
-DEF_HELPER_3(vadduqm, void, avr, avr, avr)
-DEF_HELPER_4(vaddecuq, void, avr, avr, avr, avr)
-DEF_HELPER_4(vaddeuqm, void, avr, avr, avr, avr)
-DEF_HELPER_3(vaddcuq, void, avr, avr, avr)
-DEF_HELPER_3(vsubuqm, void, avr, avr, avr)
-DEF_HELPER_4(vsubecuq, void, avr, avr, avr, avr)
-DEF_HELPER_4(vsubeuqm, void, avr, avr, avr, avr)
-DEF_HELPER_3(vsubcuq, void, avr, avr, avr)
-DEF_HELPER_3(vrlb, void, avr, avr, avr)
-DEF_HELPER_3(vrlh, void, avr, avr, avr)
-DEF_HELPER_3(vrlw, void, avr, avr, avr)
-DEF_HELPER_3(vrld, void, avr, avr, avr)
-DEF_HELPER_3(vsl, void, avr, avr, avr)
-DEF_HELPER_3(vsr, void, avr, avr, avr)
-DEF_HELPER_4(vsldoi, void, avr, avr, avr, i32)
-DEF_HELPER_2(vspltisb, void, avr, i32)
-DEF_HELPER_2(vspltish, void, avr, i32)
-DEF_HELPER_2(vspltisw, void, avr, i32)
-DEF_HELPER_3(vspltb, void, avr, avr, i32)
-DEF_HELPER_3(vsplth, void, avr, avr, i32)
-DEF_HELPER_3(vspltw, void, avr, avr, i32)
-DEF_HELPER_3(vextractub, void, avr, avr, i32)
-DEF_HELPER_3(vextractuh, void, avr, avr, i32)
-DEF_HELPER_3(vextractuw, void, avr, avr, i32)
-DEF_HELPER_3(vextractd, void, avr, avr, i32)
-DEF_HELPER_3(vinsertb, void, avr, avr, i32)
-DEF_HELPER_3(vinserth, void, avr, avr, i32)
-DEF_HELPER_3(vinsertw, void, avr, avr, i32)
-DEF_HELPER_3(vinsertd, void, avr, avr, i32)
-DEF_HELPER_2(vextsb2w, void, avr, avr)
-DEF_HELPER_2(vextsh2w, void, avr, avr)
-DEF_HELPER_2(vextsb2d, void, avr, avr)
-DEF_HELPER_2(vextsh2d, void, avr, avr)
-DEF_HELPER_2(vextsw2d, void, avr, avr)
-DEF_HELPER_2(vnegw, void, avr, avr)
-DEF_HELPER_2(vnegd, void, avr, avr)
-DEF_HELPER_2(vupkhpx, void, avr, avr)
-DEF_HELPER_2(vupklpx, void, avr, avr)
-DEF_HELPER_2(vupkhsb, void, avr, avr)
-DEF_HELPER_2(vupkhsh, void, avr, avr)
-DEF_HELPER_2(vupkhsw, void, avr, avr)
-DEF_HELPER_2(vupklsb, void, avr, avr)
-DEF_HELPER_2(vupklsh, void, avr, avr)
-DEF_HELPER_2(vupklsw, void, avr, avr)
-DEF_HELPER_5(vmsumubm, void, env, avr, avr, avr, avr)
-DEF_HELPER_5(vmsummbm, void, env, avr, avr, avr, avr)
-DEF_HELPER_5(vsel, void, env, avr, avr, avr, avr)
-DEF_HELPER_5(vperm, void, env, avr, avr, avr, avr)
-DEF_HELPER_5(vpermr, void, env, avr, avr, avr, avr)
-DEF_HELPER_4(vpkshss, void, env, avr, avr, avr)
-DEF_HELPER_4(vpkshus, void, env, avr, avr, avr)
-DEF_HELPER_4(vpkswss, void, env, avr, avr, avr)
-DEF_HELPER_4(vpkswus, void, env, avr, avr, avr)
-DEF_HELPER_4(vpksdss, void, env, avr, avr, avr)
-DEF_HELPER_4(vpksdus, void, env, avr, avr, avr)
-DEF_HELPER_4(vpkuhus, void, env, avr, avr, avr)
-DEF_HELPER_4(vpkuwus, void, env, avr, avr, avr)
-DEF_HELPER_4(vpkudus, void, env, avr, avr, avr)
-DEF_HELPER_4(vpkuhum, void, env, avr, avr, avr)
-DEF_HELPER_4(vpkuwum, void, env, avr, avr, avr)
-DEF_HELPER_4(vpkudum, void, env, avr, avr, avr)
-DEF_HELPER_3(vpkpx, void, avr, avr, avr)
-DEF_HELPER_5(vmhaddshs, void, env, avr, avr, avr, avr)
-DEF_HELPER_5(vmhraddshs, void, env, avr, avr, avr, avr)
-DEF_HELPER_5(vmsumuhm, void, env, avr, avr, avr, avr)
-DEF_HELPER_5(vmsumuhs, void, env, avr, avr, avr, avr)
-DEF_HELPER_5(vmsumshm, void, env, avr, avr, avr, avr)
-DEF_HELPER_5(vmsumshs, void, env, avr, avr, avr, avr)
-DEF_HELPER_4(vmladduhm, void, avr, avr, avr, avr)
-DEF_HELPER_2(mtvscr, void, env, avr)
-DEF_HELPER_3(lvebx, void, env, avr, tl)
-DEF_HELPER_3(lvehx, void, env, avr, tl)
-DEF_HELPER_3(lvewx, void, env, avr, tl)
-DEF_HELPER_3(stvebx, void, env, avr, tl)
-DEF_HELPER_3(stvehx, void, env, avr, tl)
-DEF_HELPER_3(stvewx, void, env, avr, tl)
-DEF_HELPER_4(vsumsws, void, env, avr, avr, avr)
-DEF_HELPER_4(vsum2sws, void, env, avr, avr, avr)
-DEF_HELPER_4(vsum4sbs, void, env, avr, avr, avr)
-DEF_HELPER_4(vsum4shs, void, env, avr, avr, avr)
-DEF_HELPER_4(vsum4ubs, void, env, avr, avr, avr)
-DEF_HELPER_4(vaddfp, void, env, avr, avr, avr)
-DEF_HELPER_4(vsubfp, void, env, avr, avr, avr)
-DEF_HELPER_4(vmaxfp, void, env, avr, avr, avr)
-DEF_HELPER_4(vminfp, void, env, avr, avr, avr)
-DEF_HELPER_3(vrefp, void, env, avr, avr)
-DEF_HELPER_3(vrsqrtefp, void, env, avr, avr)
-DEF_HELPER_3(vrlwmi, void, avr, avr, avr)
-DEF_HELPER_3(vrldmi, void, avr, avr, avr)
-DEF_HELPER_3(vrldnm, void, avr, avr, avr)
-DEF_HELPER_3(vrlwnm, void, avr, avr, avr)
-DEF_HELPER_5(vmaddfp, void, env, avr, avr, avr, avr)
-DEF_HELPER_5(vnmsubfp, void, env, avr, avr, avr, avr)
-DEF_HELPER_3(vexptefp, void, env, avr, avr)
-DEF_HELPER_3(vlogefp, void, env, avr, avr)
-DEF_HELPER_3(vrfim, void, env, avr, avr)
-DEF_HELPER_3(vrfin, void, env, avr, avr)
-DEF_HELPER_3(vrfip, void, env, avr, avr)
-DEF_HELPER_3(vrfiz, void, env, avr, avr)
-DEF_HELPER_4(vcfux, void, env, avr, avr, i32)
-DEF_HELPER_4(vcfsx, void, env, avr, avr, i32)
-DEF_HELPER_4(vctuxs, void, env, avr, avr, i32)
-DEF_HELPER_4(vctsxs, void, env, avr, avr, i32)
-
-DEF_HELPER_2(vclzb, void, avr, avr)
-DEF_HELPER_2(vclzh, void, avr, avr)
-DEF_HELPER_2(vclzw, void, avr, avr)
-DEF_HELPER_2(vclzd, void, avr, avr)
-DEF_HELPER_2(vctzb, void, avr, avr)
-DEF_HELPER_2(vctzh, void, avr, avr)
-DEF_HELPER_2(vctzw, void, avr, avr)
-DEF_HELPER_2(vctzd, void, avr, avr)
-DEF_HELPER_2(vpopcntb, void, avr, avr)
-DEF_HELPER_2(vpopcnth, void, avr, avr)
-DEF_HELPER_2(vpopcntw, void, avr, avr)
-DEF_HELPER_2(vpopcntd, void, avr, avr)
-DEF_HELPER_1(vclzlsbb, tl, avr)
-DEF_HELPER_1(vctzlsbb, tl, avr)
-DEF_HELPER_3(vbpermd, void, avr, avr, avr)
-DEF_HELPER_3(vbpermq, void, avr, avr, avr)
-DEF_HELPER_2(vgbbd, void, avr, avr)
-DEF_HELPER_3(vpmsumb, void, avr, avr, avr)
-DEF_HELPER_3(vpmsumh, void, avr, avr, avr)
-DEF_HELPER_3(vpmsumw, void, avr, avr, avr)
-DEF_HELPER_3(vpmsumd, void, avr, avr, avr)
-
-DEF_HELPER_2(vsbox, void, avr, avr)
-DEF_HELPER_3(vcipher, void, avr, avr, avr)
-DEF_HELPER_3(vcipherlast, void, avr, avr, avr)
-DEF_HELPER_3(vncipher, void, avr, avr, avr)
-DEF_HELPER_3(vncipherlast, void, avr, avr, avr)
-DEF_HELPER_3(vshasigmaw, void, avr, avr, i32)
-DEF_HELPER_3(vshasigmad, void, avr, avr, i32)
-DEF_HELPER_4(vpermxor, void, avr, avr, avr, avr)
-
-DEF_HELPER_4(bcdadd, i32, avr, avr, avr, i32)
-DEF_HELPER_4(bcdsub, i32, avr, avr, avr, i32)
-DEF_HELPER_3(bcdcfn, i32, avr, avr, i32)
-DEF_HELPER_3(bcdctn, i32, avr, avr, i32)
-DEF_HELPER_3(bcdcfz, i32, avr, avr, i32)
-DEF_HELPER_3(bcdctz, i32, avr, avr, i32)
-
-DEF_HELPER_2(xsadddp, void, env, i32)
-DEF_HELPER_2(xssubdp, void, env, i32)
-DEF_HELPER_2(xsmuldp, void, env, i32)
-DEF_HELPER_2(xsdivdp, void, env, i32)
-DEF_HELPER_2(xsredp, void, env, i32)
-DEF_HELPER_2(xssqrtdp, void, env, i32)
-DEF_HELPER_2(xsrsqrtedp, void, env, i32)
-DEF_HELPER_2(xstdivdp, void, env, i32)
-DEF_HELPER_2(xstsqrtdp, void, env, i32)
-DEF_HELPER_2(xsmaddadp, void, env, i32)
-DEF_HELPER_2(xsmaddmdp, void, env, i32)
-DEF_HELPER_2(xsmsubadp, void, env, i32)
-DEF_HELPER_2(xsmsubmdp, void, env, i32)
-DEF_HELPER_2(xsnmaddadp, void, env, i32)
-DEF_HELPER_2(xsnmaddmdp, void, env, i32)
-DEF_HELPER_2(xsnmsubadp, void, env, i32)
-DEF_HELPER_2(xsnmsubmdp, void, env, i32)
-DEF_HELPER_2(xscmpeqdp, void, env, i32)
-DEF_HELPER_2(xscmpgtdp, void, env, i32)
-DEF_HELPER_2(xscmpgedp, void, env, i32)
-DEF_HELPER_2(xscmpnedp, void, env, i32)
-DEF_HELPER_2(xscmpodp, void, env, i32)
-DEF_HELPER_2(xscmpudp, void, env, i32)
-DEF_HELPER_2(xsmaxdp, void, env, i32)
-DEF_HELPER_2(xsmindp, void, env, i32)
-DEF_HELPER_2(xscvdpsp, void, env, i32)
-DEF_HELPER_2(xscvdpspn, i64, env, i64)
-DEF_HELPER_2(xscvspdp, void, env, i32)
-DEF_HELPER_2(xscvspdpn, i64, env, i64)
-DEF_HELPER_2(xscvdpsxds, void, env, i32)
-DEF_HELPER_2(xscvdpsxws, void, env, i32)
-DEF_HELPER_2(xscvdpuxds, void, env, i32)
-DEF_HELPER_2(xscvdpuxws, void, env, i32)
-DEF_HELPER_2(xscvsxddp, void, env, i32)
-DEF_HELPER_2(xscvuxdsp, void, env, i32)
-DEF_HELPER_2(xscvsxdsp, void, env, i32)
-DEF_HELPER_2(xscvuxddp, void, env, i32)
-DEF_HELPER_2(xsrdpi, void, env, i32)
-DEF_HELPER_2(xsrdpic, void, env, i32)
-DEF_HELPER_2(xsrdpim, void, env, i32)
-DEF_HELPER_2(xsrdpip, void, env, i32)
-DEF_HELPER_2(xsrdpiz, void, env, i32)
-
-DEF_HELPER_2(xsaddsp, void, env, i32)
-DEF_HELPER_2(xssubsp, void, env, i32)
-DEF_HELPER_2(xsmulsp, void, env, i32)
-DEF_HELPER_2(xsdivsp, void, env, i32)
-DEF_HELPER_2(xsresp, void, env, i32)
-DEF_HELPER_2(xsrsp, i64, env, i64)
-DEF_HELPER_2(xssqrtsp, void, env, i32)
-DEF_HELPER_2(xsrsqrtesp, void, env, i32)
-DEF_HELPER_2(xsmaddasp, void, env, i32)
-DEF_HELPER_2(xsmaddmsp, void, env, i32)
-DEF_HELPER_2(xsmsubasp, void, env, i32)
-DEF_HELPER_2(xsmsubmsp, void, env, i32)
-DEF_HELPER_2(xsnmaddasp, void, env, i32)
-DEF_HELPER_2(xsnmaddmsp, void, env, i32)
-DEF_HELPER_2(xsnmsubasp, void, env, i32)
-DEF_HELPER_2(xsnmsubmsp, void, env, i32)
-
-DEF_HELPER_2(xvadddp, void, env, i32)
-DEF_HELPER_2(xvsubdp, void, env, i32)
-DEF_HELPER_2(xvmuldp, void, env, i32)
-DEF_HELPER_2(xvdivdp, void, env, i32)
-DEF_HELPER_2(xvredp, void, env, i32)
-DEF_HELPER_2(xvsqrtdp, void, env, i32)
-DEF_HELPER_2(xvrsqrtedp, void, env, i32)
-DEF_HELPER_2(xvtdivdp, void, env, i32)
-DEF_HELPER_2(xvtsqrtdp, void, env, i32)
-DEF_HELPER_2(xvmaddadp, void, env, i32)
-DEF_HELPER_2(xvmaddmdp, void, env, i32)
-DEF_HELPER_2(xvmsubadp, void, env, i32)
-DEF_HELPER_2(xvmsubmdp, void, env, i32)
-DEF_HELPER_2(xvnmaddadp, void, env, i32)
-DEF_HELPER_2(xvnmaddmdp, void, env, i32)
-DEF_HELPER_2(xvnmsubadp, void, env, i32)
-DEF_HELPER_2(xvnmsubmdp, void, env, i32)
-DEF_HELPER_2(xvmaxdp, void, env, i32)
-DEF_HELPER_2(xvmindp, void, env, i32)
-DEF_HELPER_2(xvcmpeqdp, void, env, i32)
-DEF_HELPER_2(xvcmpgedp, void, env, i32)
-DEF_HELPER_2(xvcmpgtdp, void, env, i32)
-DEF_HELPER_2(xvcmpnedp, void, env, i32)
-DEF_HELPER_2(xvcvdpsp, void, env, i32)
-DEF_HELPER_2(xvcvdpsxds, void, env, i32)
-DEF_HELPER_2(xvcvdpsxws, void, env, i32)
-DEF_HELPER_2(xvcvdpuxds, void, env, i32)
-DEF_HELPER_2(xvcvdpuxws, void, env, i32)
-DEF_HELPER_2(xvcvsxddp, void, env, i32)
-DEF_HELPER_2(xvcvuxddp, void, env, i32)
-DEF_HELPER_2(xvcvsxwdp, void, env, i32)
-DEF_HELPER_2(xvcvuxwdp, void, env, i32)
-DEF_HELPER_2(xvrdpi, void, env, i32)
-DEF_HELPER_2(xvrdpic, void, env, i32)
-DEF_HELPER_2(xvrdpim, void, env, i32)
-DEF_HELPER_2(xvrdpip, void, env, i32)
-DEF_HELPER_2(xvrdpiz, void, env, i32)
-
-DEF_HELPER_2(xvaddsp, void, env, i32)
-DEF_HELPER_2(xvsubsp, void, env, i32)
-DEF_HELPER_2(xvmulsp, void, env, i32)
-DEF_HELPER_2(xvdivsp, void, env, i32)
-DEF_HELPER_2(xvresp, void, env, i32)
-DEF_HELPER_2(xvsqrtsp, void, env, i32)
-DEF_HELPER_2(xvrsqrtesp, void, env, i32)
-DEF_HELPER_2(xvtdivsp, void, env, i32)
-DEF_HELPER_2(xvtsqrtsp, void, env, i32)
-DEF_HELPER_2(xvmaddasp, void, env, i32)
-DEF_HELPER_2(xvmaddmsp, void, env, i32)
-DEF_HELPER_2(xvmsubasp, void, env, i32)
-DEF_HELPER_2(xvmsubmsp, void, env, i32)
-DEF_HELPER_2(xvnmaddasp, void, env, i32)
-DEF_HELPER_2(xvnmaddmsp, void, env, i32)
-DEF_HELPER_2(xvnmsubasp, void, env, i32)
-DEF_HELPER_2(xvnmsubmsp, void, env, i32)
-DEF_HELPER_2(xvmaxsp, void, env, i32)
-DEF_HELPER_2(xvminsp, void, env, i32)
-DEF_HELPER_2(xvcmpeqsp, void, env, i32)
-DEF_HELPER_2(xvcmpgesp, void, env, i32)
-DEF_HELPER_2(xvcmpgtsp, void, env, i32)
-DEF_HELPER_2(xvcmpnesp, void, env, i32)
-DEF_HELPER_2(xvcvspdp, void, env, i32)
-DEF_HELPER_2(xvcvspsxds, void, env, i32)
-DEF_HELPER_2(xvcvspsxws, void, env, i32)
-DEF_HELPER_2(xvcvspuxds, void, env, i32)
-DEF_HELPER_2(xvcvspuxws, void, env, i32)
-DEF_HELPER_2(xvcvsxdsp, void, env, i32)
-DEF_HELPER_2(xvcvuxdsp, void, env, i32)
-DEF_HELPER_2(xvcvsxwsp, void, env, i32)
-DEF_HELPER_2(xvcvuxwsp, void, env, i32)
-DEF_HELPER_2(xvrspi, void, env, i32)
-DEF_HELPER_2(xvrspic, void, env, i32)
-DEF_HELPER_2(xvrspim, void, env, i32)
-DEF_HELPER_2(xvrspip, void, env, i32)
-DEF_HELPER_2(xvrspiz, void, env, i32)
-
-DEF_HELPER_2(efscfsi, i32, env, i32)
-DEF_HELPER_2(efscfui, i32, env, i32)
-DEF_HELPER_2(efscfuf, i32, env, i32)
-DEF_HELPER_2(efscfsf, i32, env, i32)
-DEF_HELPER_2(efsctsi, i32, env, i32)
-DEF_HELPER_2(efsctui, i32, env, i32)
-DEF_HELPER_2(efsctsiz, i32, env, i32)
-DEF_HELPER_2(efsctuiz, i32, env, i32)
-DEF_HELPER_2(efsctsf, i32, env, i32)
-DEF_HELPER_2(efsctuf, i32, env, i32)
-DEF_HELPER_2(evfscfsi, i64, env, i64)
-DEF_HELPER_2(evfscfui, i64, env, i64)
-DEF_HELPER_2(evfscfuf, i64, env, i64)
-DEF_HELPER_2(evfscfsf, i64, env, i64)
-DEF_HELPER_2(evfsctsi, i64, env, i64)
-DEF_HELPER_2(evfsctui, i64, env, i64)
-DEF_HELPER_2(evfsctsiz, i64, env, i64)
-DEF_HELPER_2(evfsctuiz, i64, env, i64)
-DEF_HELPER_2(evfsctsf, i64, env, i64)
-DEF_HELPER_2(evfsctuf, i64, env, i64)
-DEF_HELPER_3(efsadd, i32, env, i32, i32)
-DEF_HELPER_3(efssub, i32, env, i32, i32)
-DEF_HELPER_3(efsmul, i32, env, i32, i32)
-DEF_HELPER_3(efsdiv, i32, env, i32, i32)
-DEF_HELPER_3(evfsadd, i64, env, i64, i64)
-DEF_HELPER_3(evfssub, i64, env, i64, i64)
-DEF_HELPER_3(evfsmul, i64, env, i64, i64)
-DEF_HELPER_3(evfsdiv, i64, env, i64, i64)
-DEF_HELPER_3(efststlt, i32, env, i32, i32)
-DEF_HELPER_3(efststgt, i32, env, i32, i32)
-DEF_HELPER_3(efststeq, i32, env, i32, i32)
-DEF_HELPER_3(efscmplt, i32, env, i32, i32)
-DEF_HELPER_3(efscmpgt, i32, env, i32, i32)
-DEF_HELPER_3(efscmpeq, i32, env, i32, i32)
-DEF_HELPER_3(evfststlt, i32, env, i64, i64)
-DEF_HELPER_3(evfststgt, i32, env, i64, i64)
-DEF_HELPER_3(evfststeq, i32, env, i64, i64)
-DEF_HELPER_3(evfscmplt, i32, env, i64, i64)
-DEF_HELPER_3(evfscmpgt, i32, env, i64, i64)
-DEF_HELPER_3(evfscmpeq, i32, env, i64, i64)
-DEF_HELPER_2(efdcfsi, i64, env, i32)
-DEF_HELPER_2(efdcfsid, i64, env, i64)
-DEF_HELPER_2(efdcfui, i64, env, i32)
-DEF_HELPER_2(efdcfuid, i64, env, i64)
-DEF_HELPER_2(efdctsi, i32, env, i64)
-DEF_HELPER_2(efdctui, i32, env, i64)
-DEF_HELPER_2(efdctsiz, i32, env, i64)
-DEF_HELPER_2(efdctsidz, i64, env, i64)
-DEF_HELPER_2(efdctuiz, i32, env, i64)
-DEF_HELPER_2(efdctuidz, i64, env, i64)
-DEF_HELPER_2(efdcfsf, i64, env, i32)
-DEF_HELPER_2(efdcfuf, i64, env, i32)
-DEF_HELPER_2(efdctsf, i32, env, i64)
-DEF_HELPER_2(efdctuf, i32, env, i64)
-DEF_HELPER_2(efscfd, i32, env, i64)
-DEF_HELPER_2(efdcfs, i64, env, i32)
-DEF_HELPER_3(efdadd, i64, env, i64, i64)
-DEF_HELPER_3(efdsub, i64, env, i64, i64)
-DEF_HELPER_3(efdmul, i64, env, i64, i64)
-DEF_HELPER_3(efddiv, i64, env, i64, i64)
-DEF_HELPER_3(efdtstlt, i32, env, i64, i64)
-DEF_HELPER_3(efdtstgt, i32, env, i64, i64)
-DEF_HELPER_3(efdtsteq, i32, env, i64, i64)
-DEF_HELPER_3(efdcmplt, i32, env, i64, i64)
-DEF_HELPER_3(efdcmpgt, i32, env, i64, i64)
-DEF_HELPER_3(efdcmpeq, i32, env, i64, i64)
-
-#if !defined(CONFIG_USER_ONLY)
-DEF_HELPER_2(4xx_tlbre_hi, tl, env, tl)
-DEF_HELPER_2(4xx_tlbre_lo, tl, env, tl)
-DEF_HELPER_3(4xx_tlbwe_hi, void, env, tl, tl)
-DEF_HELPER_3(4xx_tlbwe_lo, void, env, tl, tl)
-DEF_HELPER_2(4xx_tlbsx, tl, env, tl)
-DEF_HELPER_3(440_tlbre, tl, env, i32, tl)
-DEF_HELPER_4(440_tlbwe, void, env, i32, tl, tl)
-DEF_HELPER_2(440_tlbsx, tl, env, tl)
-DEF_HELPER_1(booke206_tlbre, void, env)
-DEF_HELPER_1(booke206_tlbwe, void, env)
-DEF_HELPER_2(booke206_tlbsx, void, env, tl)
-DEF_HELPER_2(booke206_tlbivax, void, env, tl)
-DEF_HELPER_2(booke206_tlbilx0, void, env, tl)
-DEF_HELPER_2(booke206_tlbilx1, void, env, tl)
-DEF_HELPER_2(booke206_tlbilx3, void, env, tl)
-DEF_HELPER_2(booke206_tlbflush, void, env, tl)
-DEF_HELPER_3(booke_setpid, void, env, i32, tl)
-DEF_HELPER_2(6xx_tlbd, void, env, tl)
-DEF_HELPER_2(6xx_tlbi, void, env, tl)
-DEF_HELPER_2(74xx_tlbd, void, env, tl)
-DEF_HELPER_2(74xx_tlbi, void, env, tl)
-DEF_HELPER_FLAGS_1(tlbia, TCG_CALL_NO_RWG, void, env)
-DEF_HELPER_FLAGS_2(tlbie, TCG_CALL_NO_RWG, void, env, tl)
-DEF_HELPER_FLAGS_2(tlbiva, TCG_CALL_NO_RWG, void, env, tl)
-#if defined(TARGET_PPC64)
-DEF_HELPER_FLAGS_3(store_slb, TCG_CALL_NO_RWG, void, env, tl, tl)
-DEF_HELPER_2(load_slb_esid, tl, env, tl)
-DEF_HELPER_2(load_slb_vsid, tl, env, tl)
-DEF_HELPER_2(find_slb_vsid, tl, env, tl)
-DEF_HELPER_FLAGS_1(slbia, TCG_CALL_NO_RWG, void, env)
-DEF_HELPER_FLAGS_2(slbie, TCG_CALL_NO_RWG, void, env, tl)
-#endif
-DEF_HELPER_FLAGS_2(load_sr, TCG_CALL_NO_RWG, tl, env, tl)
-DEF_HELPER_FLAGS_3(store_sr, TCG_CALL_NO_RWG, void, env, tl, tl)
-
-DEF_HELPER_FLAGS_1(602_mfrom, TCG_CALL_NO_RWG_SE, tl, tl)
-DEF_HELPER_1(msgsnd, void, tl)
-DEF_HELPER_2(msgclr, void, env, tl)
-#endif
-
-DEF_HELPER_4(dlmzb, tl, env, tl, tl, i32)
-DEF_HELPER_FLAGS_2(clcs, TCG_CALL_NO_RWG_SE, tl, env, i32)
-#if !defined(CONFIG_USER_ONLY)
-DEF_HELPER_2(rac, tl, env, tl)
-#endif
-DEF_HELPER_3(div, tl, env, tl, tl)
-DEF_HELPER_3(divo, tl, env, tl, tl)
-DEF_HELPER_3(divs, tl, env, tl, tl)
-DEF_HELPER_3(divso, tl, env, tl, tl)
-
-DEF_HELPER_2(load_dcr, tl, env, tl)
-DEF_HELPER_3(store_dcr, void, env, tl, tl)
-
-DEF_HELPER_2(load_dump_spr, void, env, i32)
-DEF_HELPER_2(store_dump_spr, void, env, i32)
-DEF_HELPER_4(fscr_facility_check, void, env, i32, i32, i32)
-DEF_HELPER_4(msr_facility_check, void, env, i32, i32, i32)
-DEF_HELPER_FLAGS_1(load_tbl, TCG_CALL_NO_RWG, tl, env)
-DEF_HELPER_FLAGS_1(load_tbu, TCG_CALL_NO_RWG, tl, env)
-DEF_HELPER_FLAGS_1(load_atbl, TCG_CALL_NO_RWG, tl, env)
-DEF_HELPER_FLAGS_1(load_atbu, TCG_CALL_NO_RWG, tl, env)
-DEF_HELPER_FLAGS_1(load_601_rtcl, TCG_CALL_NO_RWG, tl, env)
-DEF_HELPER_FLAGS_1(load_601_rtcu, TCG_CALL_NO_RWG, tl, env)
-#if !defined(CONFIG_USER_ONLY)
-#if defined(TARGET_PPC64)
-DEF_HELPER_FLAGS_1(load_purr, TCG_CALL_NO_RWG, tl, env)
-#endif
-DEF_HELPER_2(store_sdr1, void, env, tl)
-DEF_HELPER_FLAGS_2(store_tbl, TCG_CALL_NO_RWG, void, env, tl)
-DEF_HELPER_FLAGS_2(store_tbu, TCG_CALL_NO_RWG, void, env, tl)
-DEF_HELPER_FLAGS_2(store_atbl, TCG_CALL_NO_RWG, void, env, tl)
-DEF_HELPER_FLAGS_2(store_atbu, TCG_CALL_NO_RWG, void, env, tl)
-DEF_HELPER_FLAGS_2(store_601_rtcl, TCG_CALL_NO_RWG, void, env, tl)
-DEF_HELPER_FLAGS_2(store_601_rtcu, TCG_CALL_NO_RWG, void, env, tl)
-DEF_HELPER_FLAGS_1(load_decr, TCG_CALL_NO_RWG, tl, env)
-DEF_HELPER_FLAGS_2(store_decr, TCG_CALL_NO_RWG, void, env, tl)
-DEF_HELPER_FLAGS_1(load_hdecr, TCG_CALL_NO_RWG, tl, env)
-DEF_HELPER_FLAGS_2(store_hdecr, TCG_CALL_NO_RWG, void, env, tl)
-DEF_HELPER_2(store_hid0_601, void, env, tl)
-DEF_HELPER_3(store_403_pbr, void, env, i32, tl)
-DEF_HELPER_FLAGS_1(load_40x_pit, TCG_CALL_NO_RWG, tl, env)
-DEF_HELPER_FLAGS_2(store_40x_pit, TCG_CALL_NO_RWG, void, env, tl)
-DEF_HELPER_2(store_40x_dbcr0, void, env, tl)
-DEF_HELPER_2(store_40x_sler, void, env, tl)
-DEF_HELPER_FLAGS_2(store_booke_tcr, TCG_CALL_NO_RWG, void, env, tl)
-DEF_HELPER_FLAGS_2(store_booke_tsr, TCG_CALL_NO_RWG, void, env, tl)
-DEF_HELPER_3(store_ibatl, void, env, i32, tl)
-DEF_HELPER_3(store_ibatu, void, env, i32, tl)
-DEF_HELPER_3(store_dbatl, void, env, i32, tl)
-DEF_HELPER_3(store_dbatu, void, env, i32, tl)
-DEF_HELPER_3(store_601_batl, void, env, i32, tl)
-DEF_HELPER_3(store_601_batu, void, env, i32, tl)
-#endif
-
-#define dh_alias_fprp ptr
-#define dh_ctype_fprp uint64_t *
-#define dh_is_signed_fprp dh_is_signed_ptr
-
-DEF_HELPER_4(dadd, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(daddq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dsub, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dsubq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dmul, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dmulq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(ddiv, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(ddivq, void, env, fprp, fprp, fprp)
-DEF_HELPER_3(dcmpo, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpoq, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpu, i32, env, fprp, fprp)
-DEF_HELPER_3(dcmpuq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstdc, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdcq, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdg, i32, env, fprp, i32)
-DEF_HELPER_3(dtstdgq, i32, env, fprp, i32)
-DEF_HELPER_3(dtstex, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstexq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsf, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsfq, i32, env, fprp, fprp)
-DEF_HELPER_3(dtstsfi, i32, env, i32, fprp)
-DEF_HELPER_3(dtstsfiq, i32, env, i32, fprp)
-DEF_HELPER_5(dquai, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(dquaiq, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(dqua, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(dquaq, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drrnd, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drrndq, void, env, fprp, fprp, fprp, i32)
-DEF_HELPER_5(drintx, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintxq, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintn, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_5(drintnq, void, env, fprp, fprp, i32, i32)
-DEF_HELPER_3(dctdp, void, env, fprp, fprp)
-DEF_HELPER_3(dctqpq, void, env, fprp, fprp)
-DEF_HELPER_3(drsp, void, env, fprp, fprp)
-DEF_HELPER_3(drdpq, void, env, fprp, fprp)
-DEF_HELPER_3(dcffix, void, env, fprp, fprp)
-DEF_HELPER_3(dcffixq, void, env, fprp, fprp)
-DEF_HELPER_3(dctfix, void, env, fprp, fprp)
-DEF_HELPER_3(dctfixq, void, env, fprp, fprp)
-DEF_HELPER_4(ddedpd, void, env, fprp, fprp, i32)
-DEF_HELPER_4(ddedpdq, void, env, fprp, fprp, i32)
-DEF_HELPER_4(denbcd, void, env, fprp, fprp, i32)
-DEF_HELPER_4(denbcdq, void, env, fprp, fprp, i32)
-DEF_HELPER_3(dxex, void, env, fprp, fprp)
-DEF_HELPER_3(dxexq, void, env, fprp, fprp)
-DEF_HELPER_4(diex, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(diexq, void, env, fprp, fprp, fprp)
-DEF_HELPER_4(dscri, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscriq, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscli, void, env, fprp, fprp, i32)
-DEF_HELPER_4(dscliq, void, env, fprp, fprp, i32)
-
-DEF_HELPER_1(tbegin, void, env)
-DEF_HELPER_FLAGS_1(fixup_thrm, TCG_CALL_NO_RWG, void, env)
diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h
deleted file mode 100644
index 62138163a5..0000000000
--- a/target-ppc/helper_regs.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * PowerPC emulation special registers manipulation helpers for qemu.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef HELPER_REGS_H
-#define HELPER_REGS_H
-
-/* Swap temporary saved registers with GPRs */
-static inline void hreg_swap_gpr_tgpr(CPUPPCState *env)
-{
- target_ulong tmp;
-
- tmp = env->gpr[0];
- env->gpr[0] = env->tgpr[0];
- env->tgpr[0] = tmp;
- tmp = env->gpr[1];
- env->gpr[1] = env->tgpr[1];
- env->tgpr[1] = tmp;
- tmp = env->gpr[2];
- env->gpr[2] = env->tgpr[2];
- env->tgpr[2] = tmp;
- tmp = env->gpr[3];
- env->gpr[3] = env->tgpr[3];
- env->tgpr[3] = tmp;
-}
-
-static inline void hreg_compute_mem_idx(CPUPPCState *env)
-{
- /* This is our encoding for server processors. The architecture
- * specifies that there is no such thing as userspace with
- * translation off, however it appears that MacOS does it and
- * some 32-bit CPUs support it. Weird...
- *
- * 0 = Guest User space virtual mode
- * 1 = Guest Kernel space virtual mode
- * 2 = Guest User space real mode
- * 3 = Guest Kernel space real mode
- * 4 = HV User space virtual mode
- * 5 = HV Kernel space virtual mode
- * 6 = HV User space real mode
- * 7 = HV Kernel space real mode
- *
- * For BookE, we need 8 MMU modes as follow:
- *
- * 0 = AS 0 HV User space
- * 1 = AS 0 HV Kernel space
- * 2 = AS 1 HV User space
- * 3 = AS 1 HV Kernel space
- * 4 = AS 0 Guest User space
- * 5 = AS 0 Guest Kernel space
- * 6 = AS 1 Guest User space
- * 7 = AS 1 Guest Kernel space
- */
- if (env->mmu_model & POWERPC_MMU_BOOKE) {
- env->immu_idx = env->dmmu_idx = msr_pr ? 0 : 1;
- env->immu_idx += msr_is ? 2 : 0;
- env->dmmu_idx += msr_ds ? 2 : 0;
- env->immu_idx += msr_gs ? 4 : 0;
- env->dmmu_idx += msr_gs ? 4 : 0;
- } else {
- env->immu_idx = env->dmmu_idx = msr_pr ? 0 : 1;
- env->immu_idx += msr_ir ? 0 : 2;
- env->dmmu_idx += msr_dr ? 0 : 2;
- env->immu_idx += msr_hv ? 4 : 0;
- env->dmmu_idx += msr_hv ? 4 : 0;
- }
-}
-
-static inline void hreg_compute_hflags(CPUPPCState *env)
-{
- target_ulong hflags_mask;
-
- /* We 'forget' FE0 & FE1: we'll never generate imprecise exceptions */
- hflags_mask = (1 << MSR_VR) | (1 << MSR_AP) | (1 << MSR_SA) |
- (1 << MSR_PR) | (1 << MSR_FP) | (1 << MSR_SE) | (1 << MSR_BE) |
- (1 << MSR_LE) | (1 << MSR_VSX) | (1 << MSR_IR) | (1 << MSR_DR);
- hflags_mask |= (1ULL << MSR_CM) | (1ULL << MSR_SF) | MSR_HVB;
- hreg_compute_mem_idx(env);
- env->hflags = env->msr & hflags_mask;
- /* Merge with hflags coming from other registers */
- env->hflags |= env->hflags_nmsr;
-}
-
-static inline int hreg_store_msr(CPUPPCState *env, target_ulong value,
- int alter_hv)
-{
- int excp;
-#if !defined(CONFIG_USER_ONLY)
- CPUState *cs = CPU(ppc_env_get_cpu(env));
-#endif
-
- excp = 0;
- value &= env->msr_mask;
-#if !defined(CONFIG_USER_ONLY)
- /* Neither mtmsr nor guest state can alter HV */
- if (!alter_hv || !(env->msr & MSR_HVB)) {
- value &= ~MSR_HVB;
- value |= env->msr & MSR_HVB;
- }
- if (((value >> MSR_IR) & 1) != msr_ir ||
- ((value >> MSR_DR) & 1) != msr_dr) {
- cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
- }
- if ((env->mmu_model & POWERPC_MMU_BOOKE) &&
- ((value >> MSR_GS) & 1) != msr_gs) {
- cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
- }
- if (unlikely((env->flags & POWERPC_FLAG_TGPR) &&
- ((value ^ env->msr) & (1 << MSR_TGPR)))) {
- /* Swap temporary saved registers with GPRs */
- hreg_swap_gpr_tgpr(env);
- }
- if (unlikely((value >> MSR_EP) & 1) != msr_ep) {
- /* Change the exception prefix on PowerPC 601 */
- env->excp_prefix = ((value >> MSR_EP) & 1) * 0xFFF00000;
- }
- /* If PR=1 then EE, IR and DR must be 1
- *
- * Note: We only enforce this on 64-bit server processors.
- * It appears that:
- * - 32-bit implementations supports PR=1 and EE/DR/IR=0 and MacOS
- * exploits it.
- * - 64-bit embedded implementations do not need any operation to be
- * performed when PR is set.
- */
- if ((env->insns_flags & PPC_SEGMENT_64B) && ((value >> MSR_PR) & 1)) {
- value |= (1 << MSR_EE) | (1 << MSR_DR) | (1 << MSR_IR);
- }
-#endif
- env->msr = value;
- hreg_compute_hflags(env);
-#if !defined(CONFIG_USER_ONLY)
- if (unlikely(msr_pow == 1)) {
- if (!env->pending_interrupts && (*env->check_pow)(env)) {
- cs->halted = 1;
- excp = EXCP_HALTED;
- }
- }
-#endif
-
- return excp;
-}
-
-#if !defined(CONFIG_USER_ONLY)
-static inline void check_tlb_flush(CPUPPCState *env, bool global)
-{
- CPUState *cs = CPU(ppc_env_get_cpu(env));
- if (env->tlb_need_flush & TLB_NEED_LOCAL_FLUSH) {
- tlb_flush(cs, 1);
- env->tlb_need_flush &= ~TLB_NEED_LOCAL_FLUSH;
- }
-
- /* Propagate TLB invalidations to other CPUs when the guest uses broadcast
- * TLB invalidation instructions.
- */
- if (global && (env->tlb_need_flush & TLB_NEED_GLOBAL_FLUSH)) {
- CPUState *other_cs;
- CPU_FOREACH(other_cs) {
- if (other_cs != cs) {
- PowerPCCPU *cpu = POWERPC_CPU(other_cs);
- CPUPPCState *other_env = &cpu->env;
-
- other_env->tlb_need_flush &= ~TLB_NEED_LOCAL_FLUSH;
- tlb_flush(other_cs, 1);
- }
- }
- env->tlb_need_flush &= ~TLB_NEED_GLOBAL_FLUSH;
- }
-}
-#else
-static inline void check_tlb_flush(CPUPPCState *env, bool global) { }
-#endif
-
-#endif /* HELPER_REGS_H */
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
deleted file mode 100644
index 2d57c9a1c2..0000000000
--- a/target-ppc/int_helper.c
+++ /dev/null
@@ -1,3126 +0,0 @@
-/*
- * PowerPC integer and vector emulation helpers for QEMU.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "internal.h"
-#include "exec/exec-all.h"
-#include "qemu/host-utils.h"
-#include "exec/helper-proto.h"
-#include "crypto/aes.h"
-
-#include "helper_regs.h"
-/*****************************************************************************/
-/* Fixed point operations helpers */
-
-target_ulong helper_divweu(CPUPPCState *env, target_ulong ra, target_ulong rb,
- uint32_t oe)
-{
- uint64_t rt = 0;
- int overflow = 0;
-
- uint64_t dividend = (uint64_t)ra << 32;
- uint64_t divisor = (uint32_t)rb;
-
- if (unlikely(divisor == 0)) {
- overflow = 1;
- } else {
- rt = dividend / divisor;
- overflow = rt > UINT32_MAX;
- }
-
- if (unlikely(overflow)) {
- rt = 0; /* Undefined */
- }
-
- if (oe) {
- if (unlikely(overflow)) {
- env->so = env->ov = 1;
- } else {
- env->ov = 0;
- }
- }
-
- return (target_ulong)rt;
-}
-
-target_ulong helper_divwe(CPUPPCState *env, target_ulong ra, target_ulong rb,
- uint32_t oe)
-{
- int64_t rt = 0;
- int overflow = 0;
-
- int64_t dividend = (int64_t)ra << 32;
- int64_t divisor = (int64_t)((int32_t)rb);
-
- if (unlikely((divisor == 0) ||
- ((divisor == -1ull) && (dividend == INT64_MIN)))) {
- overflow = 1;
- } else {
- rt = dividend / divisor;
- overflow = rt != (int32_t)rt;
- }
-
- if (unlikely(overflow)) {
- rt = 0; /* Undefined */
- }
-
- if (oe) {
- if (unlikely(overflow)) {
- env->so = env->ov = 1;
- } else {
- env->ov = 0;
- }
- }
-
- return (target_ulong)rt;
-}
-
-#if defined(TARGET_PPC64)
-
-uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, uint64_t rb, uint32_t oe)
-{
- uint64_t rt = 0;
- int overflow = 0;
-
- overflow = divu128(&rt, &ra, rb);
-
- if (unlikely(overflow)) {
- rt = 0; /* Undefined */
- }
-
- if (oe) {
- if (unlikely(overflow)) {
- env->so = env->ov = 1;
- } else {
- env->ov = 0;
- }
- }
-
- return rt;
-}
-
-uint64_t helper_divde(CPUPPCState *env, uint64_t rau, uint64_t rbu, uint32_t oe)
-{
- int64_t rt = 0;
- int64_t ra = (int64_t)rau;
- int64_t rb = (int64_t)rbu;
- int overflow = divs128(&rt, &ra, rb);
-
- if (unlikely(overflow)) {
- rt = 0; /* Undefined */
- }
-
- if (oe) {
-
- if (unlikely(overflow)) {
- env->so = env->ov = 1;
- } else {
- env->ov = 0;
- }
- }
-
- return rt;
-}
-
-#endif
-
-
-target_ulong helper_cntlzw(target_ulong t)
-{
- return clz32(t);
-}
-
-target_ulong helper_cnttzw(target_ulong t)
-{
- return ctz32(t);
-}
-
-#if defined(TARGET_PPC64)
-/* if x = 0xab, returns 0xababababababababa */
-#define pattern(x) (((x) & 0xff) * (~(target_ulong)0 / 0xff))
-
-/* substract 1 from each byte, and with inverse, check if MSB is set at each
- * byte.
- * i.e. ((0x00 - 0x01) & ~(0x00)) & 0x80
- * (0xFF & 0xFF) & 0x80 = 0x80 (zero found)
- */
-#define haszero(v) (((v) - pattern(0x01)) & ~(v) & pattern(0x80))
-
-/* When you XOR the pattern and there is a match, that byte will be zero */
-#define hasvalue(x, n) (haszero((x) ^ pattern(n)))
-
-uint32_t helper_cmpeqb(target_ulong ra, target_ulong rb)
-{
- return hasvalue(rb, ra) ? 1 << CRF_GT : 0;
-}
-
-#undef pattern
-#undef haszero
-#undef hasvalue
-
-target_ulong helper_cntlzd(target_ulong t)
-{
- return clz64(t);
-}
-
-target_ulong helper_cnttzd(target_ulong t)
-{
- return ctz64(t);
-}
-
-/* Return invalid random number.
- *
- * FIXME: Add rng backend or other mechanism to get cryptographically suitable
- * random number
- */
-target_ulong helper_darn32(void)
-{
- return -1;
-}
-
-target_ulong helper_darn64(void)
-{
- return -1;
-}
-
-#endif
-
-#if defined(TARGET_PPC64)
-
-uint64_t helper_bpermd(uint64_t rs, uint64_t rb)
-{
- int i;
- uint64_t ra = 0;
-
- for (i = 0; i < 8; i++) {
- int index = (rs >> (i*8)) & 0xFF;
- if (index < 64) {
- if (rb & (1ull << (63-index))) {
- ra |= 1 << i;
- }
- }
- }
- return ra;
-}
-
-#endif
-
-target_ulong helper_cmpb(target_ulong rs, target_ulong rb)
-{
- target_ulong mask = 0xff;
- target_ulong ra = 0;
- int i;
-
- for (i = 0; i < sizeof(target_ulong); i++) {
- if ((rs & mask) == (rb & mask)) {
- ra |= mask;
- }
- mask <<= 8;
- }
- return ra;
-}
-
-/* shift right arithmetic helper */
-target_ulong helper_sraw(CPUPPCState *env, target_ulong value,
- target_ulong shift)
-{
- int32_t ret;
-
- if (likely(!(shift & 0x20))) {
- if (likely((uint32_t)shift != 0)) {
- shift &= 0x1f;
- ret = (int32_t)value >> shift;
- if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
- env->ca = 0;
- } else {
- env->ca = 1;
- }
- } else {
- ret = (int32_t)value;
- env->ca = 0;
- }
- } else {
- ret = (int32_t)value >> 31;
- env->ca = (ret != 0);
- }
- return (target_long)ret;
-}
-
-#if defined(TARGET_PPC64)
-target_ulong helper_srad(CPUPPCState *env, target_ulong value,
- target_ulong shift)
-{
- int64_t ret;
-
- if (likely(!(shift & 0x40))) {
- if (likely((uint64_t)shift != 0)) {
- shift &= 0x3f;
- ret = (int64_t)value >> shift;
- if (likely(ret >= 0 || (value & ((1ULL << shift) - 1)) == 0)) {
- env->ca = 0;
- } else {
- env->ca = 1;
- }
- } else {
- ret = (int64_t)value;
- env->ca = 0;
- }
- } else {
- ret = (int64_t)value >> 63;
- env->ca = (ret != 0);
- }
- return ret;
-}
-#endif
-
-#if defined(TARGET_PPC64)
-target_ulong helper_popcntb(target_ulong val)
-{
- val = (val & 0x5555555555555555ULL) + ((val >> 1) &
- 0x5555555555555555ULL);
- val = (val & 0x3333333333333333ULL) + ((val >> 2) &
- 0x3333333333333333ULL);
- val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) &
- 0x0f0f0f0f0f0f0f0fULL);
- return val;
-}
-
-target_ulong helper_popcntw(target_ulong val)
-{
- val = (val & 0x5555555555555555ULL) + ((val >> 1) &
- 0x5555555555555555ULL);
- val = (val & 0x3333333333333333ULL) + ((val >> 2) &
- 0x3333333333333333ULL);
- val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) &
- 0x0f0f0f0f0f0f0f0fULL);
- val = (val & 0x00ff00ff00ff00ffULL) + ((val >> 8) &
- 0x00ff00ff00ff00ffULL);
- val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) &
- 0x0000ffff0000ffffULL);
- return val;
-}
-
-target_ulong helper_popcntd(target_ulong val)
-{
- return ctpop64(val);
-}
-#else
-target_ulong helper_popcntb(target_ulong val)
-{
- val = (val & 0x55555555) + ((val >> 1) & 0x55555555);
- val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
- val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f);
- return val;
-}
-
-target_ulong helper_popcntw(target_ulong val)
-{
- val = (val & 0x55555555) + ((val >> 1) & 0x55555555);
- val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
- val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f);
- val = (val & 0x00ff00ff) + ((val >> 8) & 0x00ff00ff);
- val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff);
- return val;
-}
-#endif
-
-/*****************************************************************************/
-/* PowerPC 601 specific instructions (POWER bridge) */
-target_ulong helper_div(CPUPPCState *env, target_ulong arg1, target_ulong arg2)
-{
- uint64_t tmp = (uint64_t)arg1 << 32 | env->spr[SPR_MQ];
-
- if (((int32_t)tmp == INT32_MIN && (int32_t)arg2 == (int32_t)-1) ||
- (int32_t)arg2 == 0) {
- env->spr[SPR_MQ] = 0;
- return INT32_MIN;
- } else {
- env->spr[SPR_MQ] = tmp % arg2;
- return tmp / (int32_t)arg2;
- }
-}
-
-target_ulong helper_divo(CPUPPCState *env, target_ulong arg1,
- target_ulong arg2)
-{
- uint64_t tmp = (uint64_t)arg1 << 32 | env->spr[SPR_MQ];
-
- if (((int32_t)tmp == INT32_MIN && (int32_t)arg2 == (int32_t)-1) ||
- (int32_t)arg2 == 0) {
- env->so = env->ov = 1;
- env->spr[SPR_MQ] = 0;
- return INT32_MIN;
- } else {
- env->spr[SPR_MQ] = tmp % arg2;
- tmp /= (int32_t)arg2;
- if ((int32_t)tmp != tmp) {
- env->so = env->ov = 1;
- } else {
- env->ov = 0;
- }
- return tmp;
- }
-}
-
-target_ulong helper_divs(CPUPPCState *env, target_ulong arg1,
- target_ulong arg2)
-{
- if (((int32_t)arg1 == INT32_MIN && (int32_t)arg2 == (int32_t)-1) ||
- (int32_t)arg2 == 0) {
- env->spr[SPR_MQ] = 0;
- return INT32_MIN;
- } else {
- env->spr[SPR_MQ] = (int32_t)arg1 % (int32_t)arg2;
- return (int32_t)arg1 / (int32_t)arg2;
- }
-}
-
-target_ulong helper_divso(CPUPPCState *env, target_ulong arg1,
- target_ulong arg2)
-{
- if (((int32_t)arg1 == INT32_MIN && (int32_t)arg2 == (int32_t)-1) ||
- (int32_t)arg2 == 0) {
- env->so = env->ov = 1;
- env->spr[SPR_MQ] = 0;
- return INT32_MIN;
- } else {
- env->ov = 0;
- env->spr[SPR_MQ] = (int32_t)arg1 % (int32_t)arg2;
- return (int32_t)arg1 / (int32_t)arg2;
- }
-}
-
-/*****************************************************************************/
-/* 602 specific instructions */
-/* mfrom is the most crazy instruction ever seen, imho ! */
-/* Real implementation uses a ROM table. Do the same */
-/* Extremely decomposed:
- * -arg / 256
- * return 256 * log10(10 + 1.0) + 0.5
- */
-#if !defined(CONFIG_USER_ONLY)
-target_ulong helper_602_mfrom(target_ulong arg)
-{
- if (likely(arg < 602)) {
-#include "mfrom_table.c"
- return mfrom_ROM_table[arg];
- } else {
- return 0;
- }
-}
-#endif
-
-/*****************************************************************************/
-/* Altivec extension helpers */
-#if defined(HOST_WORDS_BIGENDIAN)
-#define HI_IDX 0
-#define LO_IDX 1
-#define AVRB(i) u8[i]
-#define AVRW(i) u32[i]
-#else
-#define HI_IDX 1
-#define LO_IDX 0
-#define AVRB(i) u8[15-(i)]
-#define AVRW(i) u32[3-(i)]
-#endif
-
-#if defined(HOST_WORDS_BIGENDIAN)
-#define VECTOR_FOR_INORDER_I(index, element) \
- for (index = 0; index < ARRAY_SIZE(r->element); index++)
-#else
-#define VECTOR_FOR_INORDER_I(index, element) \
- for (index = ARRAY_SIZE(r->element)-1; index >= 0; index--)
-#endif
-
-/* Saturating arithmetic helpers. */
-#define SATCVT(from, to, from_type, to_type, min, max) \
- static inline to_type cvt##from##to(from_type x, int *sat) \
- { \
- to_type r; \
- \
- if (x < (from_type)min) { \
- r = min; \
- *sat = 1; \
- } else if (x > (from_type)max) { \
- r = max; \
- *sat = 1; \
- } else { \
- r = x; \
- } \
- return r; \
- }
-#define SATCVTU(from, to, from_type, to_type, min, max) \
- static inline to_type cvt##from##to(from_type x, int *sat) \
- { \
- to_type r; \
- \
- if (x > (from_type)max) { \
- r = max; \
- *sat = 1; \
- } else { \
- r = x; \
- } \
- return r; \
- }
-SATCVT(sh, sb, int16_t, int8_t, INT8_MIN, INT8_MAX)
-SATCVT(sw, sh, int32_t, int16_t, INT16_MIN, INT16_MAX)
-SATCVT(sd, sw, int64_t, int32_t, INT32_MIN, INT32_MAX)
-
-SATCVTU(uh, ub, uint16_t, uint8_t, 0, UINT8_MAX)
-SATCVTU(uw, uh, uint32_t, uint16_t, 0, UINT16_MAX)
-SATCVTU(ud, uw, uint64_t, uint32_t, 0, UINT32_MAX)
-SATCVT(sh, ub, int16_t, uint8_t, 0, UINT8_MAX)
-SATCVT(sw, uh, int32_t, uint16_t, 0, UINT16_MAX)
-SATCVT(sd, uw, int64_t, uint32_t, 0, UINT32_MAX)
-#undef SATCVT
-#undef SATCVTU
-
-void helper_lvsl(ppc_avr_t *r, target_ulong sh)
-{
- int i, j = (sh & 0xf);
-
- VECTOR_FOR_INORDER_I(i, u8) {
- r->u8[i] = j++;
- }
-}
-
-void helper_lvsr(ppc_avr_t *r, target_ulong sh)
-{
- int i, j = 0x10 - (sh & 0xf);
-
- VECTOR_FOR_INORDER_I(i, u8) {
- r->u8[i] = j++;
- }
-}
-
-void helper_mtvscr(CPUPPCState *env, ppc_avr_t *r)
-{
-#if defined(HOST_WORDS_BIGENDIAN)
- env->vscr = r->u32[3];
-#else
- env->vscr = r->u32[0];
-#endif
- set_flush_to_zero(vscr_nj, &env->vec_status);
-}
-
-void helper_vaddcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(r->u32); i++) {
- r->u32[i] = ~a->u32[i] < b->u32[i];
- }
-}
-
-/* vprtybw */
-void helper_vprtybw(ppc_avr_t *r, ppc_avr_t *b)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(r->u32); i++) {
- uint64_t res = b->u32[i] ^ (b->u32[i] >> 16);
- res ^= res >> 8;
- r->u32[i] = res & 1;
- }
-}
-
-/* vprtybd */
-void helper_vprtybd(ppc_avr_t *r, ppc_avr_t *b)
-{
- int i;
- for (i = 0; i < ARRAY_SIZE(r->u64); i++) {
- uint64_t res = b->u64[i] ^ (b->u64[i] >> 32);
- res ^= res >> 16;
- res ^= res >> 8;
- r->u64[i] = res & 1;
- }
-}
-
-/* vprtybq */
-void helper_vprtybq(ppc_avr_t *r, ppc_avr_t *b)
-{
- uint64_t res = b->u64[0] ^ b->u64[1];
- res ^= res >> 32;
- res ^= res >> 16;
- res ^= res >> 8;
- r->u64[LO_IDX] = res & 1;
- r->u64[HI_IDX] = 0;
-}
-
-#define VARITH_DO(name, op, element) \
- void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
- { \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
- r->element[i] = a->element[i] op b->element[i]; \
- } \
- }
-#define VARITH(suffix, element) \
- VARITH_DO(add##suffix, +, element) \
- VARITH_DO(sub##suffix, -, element)
-VARITH(ubm, u8)
-VARITH(uhm, u16)
-VARITH(uwm, u32)
-VARITH(udm, u64)
-VARITH_DO(muluwm, *, u32)
-#undef VARITH_DO
-#undef VARITH
-
-#define VARITHFP(suffix, func) \
- void helper_v##suffix(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, \
- ppc_avr_t *b) \
- { \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(r->f); i++) { \
- r->f[i] = func(a->f[i], b->f[i], &env->vec_status); \
- } \
- }
-VARITHFP(addfp, float32_add)
-VARITHFP(subfp, float32_sub)
-VARITHFP(minfp, float32_min)
-VARITHFP(maxfp, float32_max)
-#undef VARITHFP
-
-#define VARITHFPFMA(suffix, type) \
- void helper_v##suffix(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, \
- ppc_avr_t *b, ppc_avr_t *c) \
- { \
- int i; \
- for (i = 0; i < ARRAY_SIZE(r->f); i++) { \
- r->f[i] = float32_muladd(a->f[i], c->f[i], b->f[i], \
- type, &env->vec_status); \
- } \
- }
-VARITHFPFMA(maddfp, 0);
-VARITHFPFMA(nmsubfp, float_muladd_negate_result | float_muladd_negate_c);
-#undef VARITHFPFMA
-
-#define VARITHSAT_CASE(type, op, cvt, element) \
- { \
- type result = (type)a->element[i] op (type)b->element[i]; \
- r->element[i] = cvt(result, &sat); \
- }
-
-#define VARITHSAT_DO(name, op, optype, cvt, element) \
- void helper_v##name(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, \
- ppc_avr_t *b) \
- { \
- int sat = 0; \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
- switch (sizeof(r->element[0])) { \
- case 1: \
- VARITHSAT_CASE(optype, op, cvt, element); \
- break; \
- case 2: \
- VARITHSAT_CASE(optype, op, cvt, element); \
- break; \
- case 4: \
- VARITHSAT_CASE(optype, op, cvt, element); \
- break; \
- } \
- } \
- if (sat) { \
- env->vscr |= (1 << VSCR_SAT); \
- } \
- }
-#define VARITHSAT_SIGNED(suffix, element, optype, cvt) \
- VARITHSAT_DO(adds##suffix##s, +, optype, cvt, element) \
- VARITHSAT_DO(subs##suffix##s, -, optype, cvt, element)
-#define VARITHSAT_UNSIGNED(suffix, element, optype, cvt) \
- VARITHSAT_DO(addu##suffix##s, +, optype, cvt, element) \
- VARITHSAT_DO(subu##suffix##s, -, optype, cvt, element)
-VARITHSAT_SIGNED(b, s8, int16_t, cvtshsb)
-VARITHSAT_SIGNED(h, s16, int32_t, cvtswsh)
-VARITHSAT_SIGNED(w, s32, int64_t, cvtsdsw)
-VARITHSAT_UNSIGNED(b, u8, uint16_t, cvtshub)
-VARITHSAT_UNSIGNED(h, u16, uint32_t, cvtswuh)
-VARITHSAT_UNSIGNED(w, u32, uint64_t, cvtsduw)
-#undef VARITHSAT_CASE
-#undef VARITHSAT_DO
-#undef VARITHSAT_SIGNED
-#undef VARITHSAT_UNSIGNED
-
-#define VAVG_DO(name, element, etype) \
- void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
- { \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
- etype x = (etype)a->element[i] + (etype)b->element[i] + 1; \
- r->element[i] = x >> 1; \
- } \
- }
-
-#define VAVG(type, signed_element, signed_type, unsigned_element, \
- unsigned_type) \
- VAVG_DO(avgs##type, signed_element, signed_type) \
- VAVG_DO(avgu##type, unsigned_element, unsigned_type)
-VAVG(b, s8, int16_t, u8, uint16_t)
-VAVG(h, s16, int32_t, u16, uint32_t)
-VAVG(w, s32, int64_t, u32, uint64_t)
-#undef VAVG_DO
-#undef VAVG
-
-#define VABSDU_DO(name, element) \
-void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
-{ \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
- r->element[i] = (a->element[i] > b->element[i]) ? \
- (a->element[i] - b->element[i]) : \
- (b->element[i] - a->element[i]); \
- } \
-}
-
-/* VABSDU - Vector absolute difference unsigned
- * name - instruction mnemonic suffix (b: byte, h: halfword, w: word)
- * element - element type to access from vector
- */
-#define VABSDU(type, element) \
- VABSDU_DO(absdu##type, element)
-VABSDU(b, u8)
-VABSDU(h, u16)
-VABSDU(w, u32)
-#undef VABSDU_DO
-#undef VABSDU
-
-#define VCF(suffix, cvt, element) \
- void helper_vcf##suffix(CPUPPCState *env, ppc_avr_t *r, \
- ppc_avr_t *b, uint32_t uim) \
- { \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(r->f); i++) { \
- float32 t = cvt(b->element[i], &env->vec_status); \
- r->f[i] = float32_scalbn(t, -uim, &env->vec_status); \
- } \
- }
-VCF(ux, uint32_to_float32, u32)
-VCF(sx, int32_to_float32, s32)
-#undef VCF
-
-#define VCMP_DO(suffix, compare, element, record) \
- void helper_vcmp##suffix(CPUPPCState *env, ppc_avr_t *r, \
- ppc_avr_t *a, ppc_avr_t *b) \
- { \
- uint64_t ones = (uint64_t)-1; \
- uint64_t all = ones; \
- uint64_t none = 0; \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
- uint64_t result = (a->element[i] compare b->element[i] ? \
- ones : 0x0); \
- switch (sizeof(a->element[0])) { \
- case 8: \
- r->u64[i] = result; \
- break; \
- case 4: \
- r->u32[i] = result; \
- break; \
- case 2: \
- r->u16[i] = result; \
- break; \
- case 1: \
- r->u8[i] = result; \
- break; \
- } \
- all &= result; \
- none |= result; \
- } \
- if (record) { \
- env->crf[6] = ((all != 0) << 3) | ((none == 0) << 1); \
- } \
- }
-#define VCMP(suffix, compare, element) \
- VCMP_DO(suffix, compare, element, 0) \
- VCMP_DO(suffix##_dot, compare, element, 1)
-VCMP(equb, ==, u8)
-VCMP(equh, ==, u16)
-VCMP(equw, ==, u32)
-VCMP(equd, ==, u64)
-VCMP(gtub, >, u8)
-VCMP(gtuh, >, u16)
-VCMP(gtuw, >, u32)
-VCMP(gtud, >, u64)
-VCMP(gtsb, >, s8)
-VCMP(gtsh, >, s16)
-VCMP(gtsw, >, s32)
-VCMP(gtsd, >, s64)
-#undef VCMP_DO
-#undef VCMP
-
-#define VCMPNE_DO(suffix, element, etype, cmpzero, record) \
-void helper_vcmpne##suffix(CPUPPCState *env, ppc_avr_t *r, \
- ppc_avr_t *a, ppc_avr_t *b) \
-{ \
- etype ones = (etype)-1; \
- etype all = ones; \
- etype result, none = 0; \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
- if (cmpzero) { \
- result = ((a->element[i] == 0) \
- || (b->element[i] == 0) \
- || (a->element[i] != b->element[i]) ? \
- ones : 0x0); \
- } else { \
- result = (a->element[i] != b->element[i]) ? ones : 0x0; \
- } \
- r->element[i] = result; \
- all &= result; \
- none |= result; \
- } \
- if (record) { \
- env->crf[6] = ((all != 0) << 3) | ((none == 0) << 1); \
- } \
-}
-
-/* VCMPNEZ - Vector compare not equal to zero
- * suffix - instruction mnemonic suffix (b: byte, h: halfword, w: word)
- * element - element type to access from vector
- */
-#define VCMPNE(suffix, element, etype, cmpzero) \
- VCMPNE_DO(suffix, element, etype, cmpzero, 0) \
- VCMPNE_DO(suffix##_dot, element, etype, cmpzero, 1)
-VCMPNE(zb, u8, uint8_t, 1)
-VCMPNE(zh, u16, uint16_t, 1)
-VCMPNE(zw, u32, uint32_t, 1)
-VCMPNE(b, u8, uint8_t, 0)
-VCMPNE(h, u16, uint16_t, 0)
-VCMPNE(w, u32, uint32_t, 0)
-#undef VCMPNE_DO
-#undef VCMPNE
-
-#define VCMPFP_DO(suffix, compare, order, record) \
- void helper_vcmp##suffix(CPUPPCState *env, ppc_avr_t *r, \
- ppc_avr_t *a, ppc_avr_t *b) \
- { \
- uint32_t ones = (uint32_t)-1; \
- uint32_t all = ones; \
- uint32_t none = 0; \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(r->f); i++) { \
- uint32_t result; \
- int rel = float32_compare_quiet(a->f[i], b->f[i], \
- &env->vec_status); \
- if (rel == float_relation_unordered) { \
- result = 0; \
- } else if (rel compare order) { \
- result = ones; \
- } else { \
- result = 0; \
- } \
- r->u32[i] = result; \
- all &= result; \
- none |= result; \
- } \
- if (record) { \
- env->crf[6] = ((all != 0) << 3) | ((none == 0) << 1); \
- } \
- }
-#define VCMPFP(suffix, compare, order) \
- VCMPFP_DO(suffix, compare, order, 0) \
- VCMPFP_DO(suffix##_dot, compare, order, 1)
-VCMPFP(eqfp, ==, float_relation_equal)
-VCMPFP(gefp, !=, float_relation_less)
-VCMPFP(gtfp, ==, float_relation_greater)
-#undef VCMPFP_DO
-#undef VCMPFP
-
-static inline void vcmpbfp_internal(CPUPPCState *env, ppc_avr_t *r,
- ppc_avr_t *a, ppc_avr_t *b, int record)
-{
- int i;
- int all_in = 0;
-
- for (i = 0; i < ARRAY_SIZE(r->f); i++) {
- int le_rel = float32_compare_quiet(a->f[i], b->f[i], &env->vec_status);
- if (le_rel == float_relation_unordered) {
- r->u32[i] = 0xc0000000;
- all_in = 1;
- } else {
- float32 bneg = float32_chs(b->f[i]);
- int ge_rel = float32_compare_quiet(a->f[i], bneg, &env->vec_status);
- int le = le_rel != float_relation_greater;
- int ge = ge_rel != float_relation_less;
-
- r->u32[i] = ((!le) << 31) | ((!ge) << 30);
- all_in |= (!le | !ge);
- }
- }
- if (record) {
- env->crf[6] = (all_in == 0) << 1;
- }
-}
-
-void helper_vcmpbfp(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- vcmpbfp_internal(env, r, a, b, 0);
-}
-
-void helper_vcmpbfp_dot(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a,
- ppc_avr_t *b)
-{
- vcmpbfp_internal(env, r, a, b, 1);
-}
-
-#define VCT(suffix, satcvt, element) \
- void helper_vct##suffix(CPUPPCState *env, ppc_avr_t *r, \
- ppc_avr_t *b, uint32_t uim) \
- { \
- int i; \
- int sat = 0; \
- float_status s = env->vec_status; \
- \
- set_float_rounding_mode(float_round_to_zero, &s); \
- for (i = 0; i < ARRAY_SIZE(r->f); i++) { \
- if (float32_is_any_nan(b->f[i])) { \
- r->element[i] = 0; \
- } else { \
- float64 t = float32_to_float64(b->f[i], &s); \
- int64_t j; \
- \
- t = float64_scalbn(t, uim, &s); \
- j = float64_to_int64(t, &s); \
- r->element[i] = satcvt(j, &sat); \
- } \
- } \
- if (sat) { \
- env->vscr |= (1 << VSCR_SAT); \
- } \
- }
-VCT(uxs, cvtsduw, u32)
-VCT(sxs, cvtsdsw, s32)
-#undef VCT
-
-target_ulong helper_vclzlsbb(ppc_avr_t *r)
-{
- target_ulong count = 0;
- int i;
- VECTOR_FOR_INORDER_I(i, u8) {
- if (r->u8[i] & 0x01) {
- break;
- }
- count++;
- }
- return count;
-}
-
-target_ulong helper_vctzlsbb(ppc_avr_t *r)
-{
- target_ulong count = 0;
- int i;
-#if defined(HOST_WORDS_BIGENDIAN)
- for (i = ARRAY_SIZE(r->u8) - 1; i >= 0; i--) {
-#else
- for (i = 0; i < ARRAY_SIZE(r->u8); i++) {
-#endif
- if (r->u8[i] & 0x01) {
- break;
- }
- count++;
- }
- return count;
-}
-
-void helper_vmhaddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a,
- ppc_avr_t *b, ppc_avr_t *c)
-{
- int sat = 0;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(r->s16); i++) {
- int32_t prod = a->s16[i] * b->s16[i];
- int32_t t = (int32_t)c->s16[i] + (prod >> 15);
-
- r->s16[i] = cvtswsh(t, &sat);
- }
-
- if (sat) {
- env->vscr |= (1 << VSCR_SAT);
- }
-}
-
-void helper_vmhraddshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a,
- ppc_avr_t *b, ppc_avr_t *c)
-{
- int sat = 0;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(r->s16); i++) {
- int32_t prod = a->s16[i] * b->s16[i] + 0x00004000;
- int32_t t = (int32_t)c->s16[i] + (prod >> 15);
- r->s16[i] = cvtswsh(t, &sat);
- }
-
- if (sat) {
- env->vscr |= (1 << VSCR_SAT);
- }
-}
-
-#define VMINMAX_DO(name, compare, element) \
- void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
- { \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
- if (a->element[i] compare b->element[i]) { \
- r->element[i] = b->element[i]; \
- } else { \
- r->element[i] = a->element[i]; \
- } \
- } \
- }
-#define VMINMAX(suffix, element) \
- VMINMAX_DO(min##suffix, >, element) \
- VMINMAX_DO(max##suffix, <, element)
-VMINMAX(sb, s8)
-VMINMAX(sh, s16)
-VMINMAX(sw, s32)
-VMINMAX(sd, s64)
-VMINMAX(ub, u8)
-VMINMAX(uh, u16)
-VMINMAX(uw, u32)
-VMINMAX(ud, u64)
-#undef VMINMAX_DO
-#undef VMINMAX
-
-void helper_vmladduhm(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(r->s16); i++) {
- int32_t prod = a->s16[i] * b->s16[i];
- r->s16[i] = (int16_t) (prod + c->s16[i]);
- }
-}
-
-#define VMRG_DO(name, element, highp) \
- void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
- { \
- ppc_avr_t result; \
- int i; \
- size_t n_elems = ARRAY_SIZE(r->element); \
- \
- for (i = 0; i < n_elems / 2; i++) { \
- if (highp) { \
- result.element[i*2+HI_IDX] = a->element[i]; \
- result.element[i*2+LO_IDX] = b->element[i]; \
- } else { \
- result.element[n_elems - i * 2 - (1 + HI_IDX)] = \
- b->element[n_elems - i - 1]; \
- result.element[n_elems - i * 2 - (1 + LO_IDX)] = \
- a->element[n_elems - i - 1]; \
- } \
- } \
- *r = result; \
- }
-#if defined(HOST_WORDS_BIGENDIAN)
-#define MRGHI 0
-#define MRGLO 1
-#else
-#define MRGHI 1
-#define MRGLO 0
-#endif
-#define VMRG(suffix, element) \
- VMRG_DO(mrgl##suffix, element, MRGHI) \
- VMRG_DO(mrgh##suffix, element, MRGLO)
-VMRG(b, u8)
-VMRG(h, u16)
-VMRG(w, u32)
-#undef VMRG_DO
-#undef VMRG
-#undef MRGHI
-#undef MRGLO
-
-void helper_vmsummbm(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a,
- ppc_avr_t *b, ppc_avr_t *c)
-{
- int32_t prod[16];
- int i;
-
- for (i = 0; i < ARRAY_SIZE(r->s8); i++) {
- prod[i] = (int32_t)a->s8[i] * b->u8[i];
- }
-
- VECTOR_FOR_INORDER_I(i, s32) {
- r->s32[i] = c->s32[i] + prod[4 * i] + prod[4 * i + 1] +
- prod[4 * i + 2] + prod[4 * i + 3];
- }
-}
-
-void helper_vmsumshm(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a,
- ppc_avr_t *b, ppc_avr_t *c)
-{
- int32_t prod[8];
- int i;
-
- for (i = 0; i < ARRAY_SIZE(r->s16); i++) {
- prod[i] = a->s16[i] * b->s16[i];
- }
-
- VECTOR_FOR_INORDER_I(i, s32) {
- r->s32[i] = c->s32[i] + prod[2 * i] + prod[2 * i + 1];
- }
-}
-
-void helper_vmsumshs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a,
- ppc_avr_t *b, ppc_avr_t *c)
-{
- int32_t prod[8];
- int i;
- int sat = 0;
-
- for (i = 0; i < ARRAY_SIZE(r->s16); i++) {
- prod[i] = (int32_t)a->s16[i] * b->s16[i];
- }
-
- VECTOR_FOR_INORDER_I(i, s32) {
- int64_t t = (int64_t)c->s32[i] + prod[2 * i] + prod[2 * i + 1];
-
- r->u32[i] = cvtsdsw(t, &sat);
- }
-
- if (sat) {
- env->vscr |= (1 << VSCR_SAT);
- }
-}
-
-void helper_vmsumubm(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a,
- ppc_avr_t *b, ppc_avr_t *c)
-{
- uint16_t prod[16];
- int i;
-
- for (i = 0; i < ARRAY_SIZE(r->u8); i++) {
- prod[i] = a->u8[i] * b->u8[i];
- }
-
- VECTOR_FOR_INORDER_I(i, u32) {
- r->u32[i] = c->u32[i] + prod[4 * i] + prod[4 * i + 1] +
- prod[4 * i + 2] + prod[4 * i + 3];
- }
-}
-
-void helper_vmsumuhm(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a,
- ppc_avr_t *b, ppc_avr_t *c)
-{
- uint32_t prod[8];
- int i;
-
- for (i = 0; i < ARRAY_SIZE(r->u16); i++) {
- prod[i] = a->u16[i] * b->u16[i];
- }
-
- VECTOR_FOR_INORDER_I(i, u32) {
- r->u32[i] = c->u32[i] + prod[2 * i] + prod[2 * i + 1];
- }
-}
-
-void helper_vmsumuhs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a,
- ppc_avr_t *b, ppc_avr_t *c)
-{
- uint32_t prod[8];
- int i;
- int sat = 0;
-
- for (i = 0; i < ARRAY_SIZE(r->u16); i++) {
- prod[i] = a->u16[i] * b->u16[i];
- }
-
- VECTOR_FOR_INORDER_I(i, s32) {
- uint64_t t = (uint64_t)c->u32[i] + prod[2 * i] + prod[2 * i + 1];
-
- r->u32[i] = cvtuduw(t, &sat);
- }
-
- if (sat) {
- env->vscr |= (1 << VSCR_SAT);
- }
-}
-
-#define VMUL_DO(name, mul_element, prod_element, cast, evenp) \
- void helper_v##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
- { \
- int i; \
- \
- VECTOR_FOR_INORDER_I(i, prod_element) { \
- if (evenp) { \
- r->prod_element[i] = \
- (cast)a->mul_element[i * 2 + HI_IDX] * \
- (cast)b->mul_element[i * 2 + HI_IDX]; \
- } else { \
- r->prod_element[i] = \
- (cast)a->mul_element[i * 2 + LO_IDX] * \
- (cast)b->mul_element[i * 2 + LO_IDX]; \
- } \
- } \
- }
-#define VMUL(suffix, mul_element, prod_element, cast) \
- VMUL_DO(mule##suffix, mul_element, prod_element, cast, 1) \
- VMUL_DO(mulo##suffix, mul_element, prod_element, cast, 0)
-VMUL(sb, s8, s16, int16_t)
-VMUL(sh, s16, s32, int32_t)
-VMUL(sw, s32, s64, int64_t)
-VMUL(ub, u8, u16, uint16_t)
-VMUL(uh, u16, u32, uint32_t)
-VMUL(uw, u32, u64, uint64_t)
-#undef VMUL_DO
-#undef VMUL
-
-void helper_vperm(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b,
- ppc_avr_t *c)
-{
- ppc_avr_t result;
- int i;
-
- VECTOR_FOR_INORDER_I(i, u8) {
- int s = c->u8[i] & 0x1f;
-#if defined(HOST_WORDS_BIGENDIAN)
- int index = s & 0xf;
-#else
- int index = 15 - (s & 0xf);
-#endif
-
- if (s & 0x10) {
- result.u8[i] = b->u8[index];
- } else {
- result.u8[i] = a->u8[index];
- }
- }
- *r = result;
-}
-
-void helper_vpermr(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b,
- ppc_avr_t *c)
-{
- ppc_avr_t result;
- int i;
-
- VECTOR_FOR_INORDER_I(i, u8) {
- int s = c->u8[i] & 0x1f;
-#if defined(HOST_WORDS_BIGENDIAN)
- int index = 15 - (s & 0xf);
-#else
- int index = s & 0xf;
-#endif
-
- if (s & 0x10) {
- result.u8[i] = a->u8[index];
- } else {
- result.u8[i] = b->u8[index];
- }
- }
- *r = result;
-}
-
-#if defined(HOST_WORDS_BIGENDIAN)
-#define VBPERMQ_INDEX(avr, i) ((avr)->u8[(i)])
-#define VBPERMD_INDEX(i) (i)
-#define VBPERMQ_DW(index) (((index) & 0x40) != 0)
-#define EXTRACT_BIT(avr, i, index) (extract64((avr)->u64[i], index, 1))
-#else
-#define VBPERMQ_INDEX(avr, i) ((avr)->u8[15-(i)])
-#define VBPERMD_INDEX(i) (1 - i)
-#define VBPERMQ_DW(index) (((index) & 0x40) == 0)
-#define EXTRACT_BIT(avr, i, index) \
- (extract64((avr)->u64[1 - i], 63 - index, 1))
-#endif
-
-void helper_vbpermd(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- int i, j;
- ppc_avr_t result = { .u64 = { 0, 0 } };
- VECTOR_FOR_INORDER_I(i, u64) {
- for (j = 0; j < 8; j++) {
- int index = VBPERMQ_INDEX(b, (i * 8) + j);
- if (index < 64 && EXTRACT_BIT(a, i, index)) {
- result.u64[VBPERMD_INDEX(i)] |= (0x80 >> j);
- }
- }
- }
- *r = result;
-}
-
-void helper_vbpermq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- int i;
- uint64_t perm = 0;
-
- VECTOR_FOR_INORDER_I(i, u8) {
- int index = VBPERMQ_INDEX(b, i);
-
- if (index < 128) {
- uint64_t mask = (1ull << (63-(index & 0x3F)));
- if (a->u64[VBPERMQ_DW(index)] & mask) {
- perm |= (0x8000 >> i);
- }
- }
- }
-
- r->u64[HI_IDX] = perm;
- r->u64[LO_IDX] = 0;
-}
-
-#undef VBPERMQ_INDEX
-#undef VBPERMQ_DW
-
-static const uint64_t VGBBD_MASKS[256] = {
- 0x0000000000000000ull, /* 00 */
- 0x0000000000000080ull, /* 01 */
- 0x0000000000008000ull, /* 02 */
- 0x0000000000008080ull, /* 03 */
- 0x0000000000800000ull, /* 04 */
- 0x0000000000800080ull, /* 05 */
- 0x0000000000808000ull, /* 06 */
- 0x0000000000808080ull, /* 07 */
- 0x0000000080000000ull, /* 08 */
- 0x0000000080000080ull, /* 09 */
- 0x0000000080008000ull, /* 0A */
- 0x0000000080008080ull, /* 0B */
- 0x0000000080800000ull, /* 0C */
- 0x0000000080800080ull, /* 0D */
- 0x0000000080808000ull, /* 0E */
- 0x0000000080808080ull, /* 0F */
- 0x0000008000000000ull, /* 10 */
- 0x0000008000000080ull, /* 11 */
- 0x0000008000008000ull, /* 12 */
- 0x0000008000008080ull, /* 13 */
- 0x0000008000800000ull, /* 14 */
- 0x0000008000800080ull, /* 15 */
- 0x0000008000808000ull, /* 16 */
- 0x0000008000808080ull, /* 17 */
- 0x0000008080000000ull, /* 18 */
- 0x0000008080000080ull, /* 19 */
- 0x0000008080008000ull, /* 1A */
- 0x0000008080008080ull, /* 1B */
- 0x0000008080800000ull, /* 1C */
- 0x0000008080800080ull, /* 1D */
- 0x0000008080808000ull, /* 1E */
- 0x0000008080808080ull, /* 1F */
- 0x0000800000000000ull, /* 20 */
- 0x0000800000000080ull, /* 21 */
- 0x0000800000008000ull, /* 22 */
- 0x0000800000008080ull, /* 23 */
- 0x0000800000800000ull, /* 24 */
- 0x0000800000800080ull, /* 25 */
- 0x0000800000808000ull, /* 26 */
- 0x0000800000808080ull, /* 27 */
- 0x0000800080000000ull, /* 28 */
- 0x0000800080000080ull, /* 29 */
- 0x0000800080008000ull, /* 2A */
- 0x0000800080008080ull, /* 2B */
- 0x0000800080800000ull, /* 2C */
- 0x0000800080800080ull, /* 2D */
- 0x0000800080808000ull, /* 2E */
- 0x0000800080808080ull, /* 2F */
- 0x0000808000000000ull, /* 30 */
- 0x0000808000000080ull, /* 31 */
- 0x0000808000008000ull, /* 32 */
- 0x0000808000008080ull, /* 33 */
- 0x0000808000800000ull, /* 34 */
- 0x0000808000800080ull, /* 35 */
- 0x0000808000808000ull, /* 36 */
- 0x0000808000808080ull, /* 37 */
- 0x0000808080000000ull, /* 38 */
- 0x0000808080000080ull, /* 39 */
- 0x0000808080008000ull, /* 3A */
- 0x0000808080008080ull, /* 3B */
- 0x0000808080800000ull, /* 3C */
- 0x0000808080800080ull, /* 3D */
- 0x0000808080808000ull, /* 3E */
- 0x0000808080808080ull, /* 3F */
- 0x0080000000000000ull, /* 40 */
- 0x0080000000000080ull, /* 41 */
- 0x0080000000008000ull, /* 42 */
- 0x0080000000008080ull, /* 43 */
- 0x0080000000800000ull, /* 44 */
- 0x0080000000800080ull, /* 45 */
- 0x0080000000808000ull, /* 46 */
- 0x0080000000808080ull, /* 47 */
- 0x0080000080000000ull, /* 48 */
- 0x0080000080000080ull, /* 49 */
- 0x0080000080008000ull, /* 4A */
- 0x0080000080008080ull, /* 4B */
- 0x0080000080800000ull, /* 4C */
- 0x0080000080800080ull, /* 4D */
- 0x0080000080808000ull, /* 4E */
- 0x0080000080808080ull, /* 4F */
- 0x0080008000000000ull, /* 50 */
- 0x0080008000000080ull, /* 51 */
- 0x0080008000008000ull, /* 52 */
- 0x0080008000008080ull, /* 53 */
- 0x0080008000800000ull, /* 54 */
- 0x0080008000800080ull, /* 55 */
- 0x0080008000808000ull, /* 56 */
- 0x0080008000808080ull, /* 57 */
- 0x0080008080000000ull, /* 58 */
- 0x0080008080000080ull, /* 59 */
- 0x0080008080008000ull, /* 5A */
- 0x0080008080008080ull, /* 5B */
- 0x0080008080800000ull, /* 5C */
- 0x0080008080800080ull, /* 5D */
- 0x0080008080808000ull, /* 5E */
- 0x0080008080808080ull, /* 5F */
- 0x0080800000000000ull, /* 60 */
- 0x0080800000000080ull, /* 61 */
- 0x0080800000008000ull, /* 62 */
- 0x0080800000008080ull, /* 63 */
- 0x0080800000800000ull, /* 64 */
- 0x0080800000800080ull, /* 65 */
- 0x0080800000808000ull, /* 66 */
- 0x0080800000808080ull, /* 67 */
- 0x0080800080000000ull, /* 68 */
- 0x0080800080000080ull, /* 69 */
- 0x0080800080008000ull, /* 6A */
- 0x0080800080008080ull, /* 6B */
- 0x0080800080800000ull, /* 6C */
- 0x0080800080800080ull, /* 6D */
- 0x0080800080808000ull, /* 6E */
- 0x0080800080808080ull, /* 6F */
- 0x0080808000000000ull, /* 70 */
- 0x0080808000000080ull, /* 71 */
- 0x0080808000008000ull, /* 72 */
- 0x0080808000008080ull, /* 73 */
- 0x0080808000800000ull, /* 74 */
- 0x0080808000800080ull, /* 75 */
- 0x0080808000808000ull, /* 76 */
- 0x0080808000808080ull, /* 77 */
- 0x0080808080000000ull, /* 78 */
- 0x0080808080000080ull, /* 79 */
- 0x0080808080008000ull, /* 7A */
- 0x0080808080008080ull, /* 7B */
- 0x0080808080800000ull, /* 7C */
- 0x0080808080800080ull, /* 7D */
- 0x0080808080808000ull, /* 7E */
- 0x0080808080808080ull, /* 7F */
- 0x8000000000000000ull, /* 80 */
- 0x8000000000000080ull, /* 81 */
- 0x8000000000008000ull, /* 82 */
- 0x8000000000008080ull, /* 83 */
- 0x8000000000800000ull, /* 84 */
- 0x8000000000800080ull, /* 85 */
- 0x8000000000808000ull, /* 86 */
- 0x8000000000808080ull, /* 87 */
- 0x8000000080000000ull, /* 88 */
- 0x8000000080000080ull, /* 89 */
- 0x8000000080008000ull, /* 8A */
- 0x8000000080008080ull, /* 8B */
- 0x8000000080800000ull, /* 8C */
- 0x8000000080800080ull, /* 8D */
- 0x8000000080808000ull, /* 8E */
- 0x8000000080808080ull, /* 8F */
- 0x8000008000000000ull, /* 90 */
- 0x8000008000000080ull, /* 91 */
- 0x8000008000008000ull, /* 92 */
- 0x8000008000008080ull, /* 93 */
- 0x8000008000800000ull, /* 94 */
- 0x8000008000800080ull, /* 95 */
- 0x8000008000808000ull, /* 96 */
- 0x8000008000808080ull, /* 97 */
- 0x8000008080000000ull, /* 98 */
- 0x8000008080000080ull, /* 99 */
- 0x8000008080008000ull, /* 9A */
- 0x8000008080008080ull, /* 9B */
- 0x8000008080800000ull, /* 9C */
- 0x8000008080800080ull, /* 9D */
- 0x8000008080808000ull, /* 9E */
- 0x8000008080808080ull, /* 9F */
- 0x8000800000000000ull, /* A0 */
- 0x8000800000000080ull, /* A1 */
- 0x8000800000008000ull, /* A2 */
- 0x8000800000008080ull, /* A3 */
- 0x8000800000800000ull, /* A4 */
- 0x8000800000800080ull, /* A5 */
- 0x8000800000808000ull, /* A6 */
- 0x8000800000808080ull, /* A7 */
- 0x8000800080000000ull, /* A8 */
- 0x8000800080000080ull, /* A9 */
- 0x8000800080008000ull, /* AA */
- 0x8000800080008080ull, /* AB */
- 0x8000800080800000ull, /* AC */
- 0x8000800080800080ull, /* AD */
- 0x8000800080808000ull, /* AE */
- 0x8000800080808080ull, /* AF */
- 0x8000808000000000ull, /* B0 */
- 0x8000808000000080ull, /* B1 */
- 0x8000808000008000ull, /* B2 */
- 0x8000808000008080ull, /* B3 */
- 0x8000808000800000ull, /* B4 */
- 0x8000808000800080ull, /* B5 */
- 0x8000808000808000ull, /* B6 */
- 0x8000808000808080ull, /* B7 */
- 0x8000808080000000ull, /* B8 */
- 0x8000808080000080ull, /* B9 */
- 0x8000808080008000ull, /* BA */
- 0x8000808080008080ull, /* BB */
- 0x8000808080800000ull, /* BC */
- 0x8000808080800080ull, /* BD */
- 0x8000808080808000ull, /* BE */
- 0x8000808080808080ull, /* BF */
- 0x8080000000000000ull, /* C0 */
- 0x8080000000000080ull, /* C1 */
- 0x8080000000008000ull, /* C2 */
- 0x8080000000008080ull, /* C3 */
- 0x8080000000800000ull, /* C4 */
- 0x8080000000800080ull, /* C5 */
- 0x8080000000808000ull, /* C6 */
- 0x8080000000808080ull, /* C7 */
- 0x8080000080000000ull, /* C8 */
- 0x8080000080000080ull, /* C9 */
- 0x8080000080008000ull, /* CA */
- 0x8080000080008080ull, /* CB */
- 0x8080000080800000ull, /* CC */
- 0x8080000080800080ull, /* CD */
- 0x8080000080808000ull, /* CE */
- 0x8080000080808080ull, /* CF */
- 0x8080008000000000ull, /* D0 */
- 0x8080008000000080ull, /* D1 */
- 0x8080008000008000ull, /* D2 */
- 0x8080008000008080ull, /* D3 */
- 0x8080008000800000ull, /* D4 */
- 0x8080008000800080ull, /* D5 */
- 0x8080008000808000ull, /* D6 */
- 0x8080008000808080ull, /* D7 */
- 0x8080008080000000ull, /* D8 */
- 0x8080008080000080ull, /* D9 */
- 0x8080008080008000ull, /* DA */
- 0x8080008080008080ull, /* DB */
- 0x8080008080800000ull, /* DC */
- 0x8080008080800080ull, /* DD */
- 0x8080008080808000ull, /* DE */
- 0x8080008080808080ull, /* DF */
- 0x8080800000000000ull, /* E0 */
- 0x8080800000000080ull, /* E1 */
- 0x8080800000008000ull, /* E2 */
- 0x8080800000008080ull, /* E3 */
- 0x8080800000800000ull, /* E4 */
- 0x8080800000800080ull, /* E5 */
- 0x8080800000808000ull, /* E6 */
- 0x8080800000808080ull, /* E7 */
- 0x8080800080000000ull, /* E8 */
- 0x8080800080000080ull, /* E9 */
- 0x8080800080008000ull, /* EA */
- 0x8080800080008080ull, /* EB */
- 0x8080800080800000ull, /* EC */
- 0x8080800080800080ull, /* ED */
- 0x8080800080808000ull, /* EE */
- 0x8080800080808080ull, /* EF */
- 0x8080808000000000ull, /* F0 */
- 0x8080808000000080ull, /* F1 */
- 0x8080808000008000ull, /* F2 */
- 0x8080808000008080ull, /* F3 */
- 0x8080808000800000ull, /* F4 */
- 0x8080808000800080ull, /* F5 */
- 0x8080808000808000ull, /* F6 */
- 0x8080808000808080ull, /* F7 */
- 0x8080808080000000ull, /* F8 */
- 0x8080808080000080ull, /* F9 */
- 0x8080808080008000ull, /* FA */
- 0x8080808080008080ull, /* FB */
- 0x8080808080800000ull, /* FC */
- 0x8080808080800080ull, /* FD */
- 0x8080808080808000ull, /* FE */
- 0x8080808080808080ull, /* FF */
-};
-
-void helper_vgbbd(ppc_avr_t *r, ppc_avr_t *b)
-{
- int i;
- uint64_t t[2] = { 0, 0 };
-
- VECTOR_FOR_INORDER_I(i, u8) {
-#if defined(HOST_WORDS_BIGENDIAN)
- t[i>>3] |= VGBBD_MASKS[b->u8[i]] >> (i & 7);
-#else
- t[i>>3] |= VGBBD_MASKS[b->u8[i]] >> (7-(i & 7));
-#endif
- }
-
- r->u64[0] = t[0];
- r->u64[1] = t[1];
-}
-
-#define PMSUM(name, srcfld, trgfld, trgtyp) \
-void helper_##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
-{ \
- int i, j; \
- trgtyp prod[sizeof(ppc_avr_t)/sizeof(a->srcfld[0])]; \
- \
- VECTOR_FOR_INORDER_I(i, srcfld) { \
- prod[i] = 0; \
- for (j = 0; j < sizeof(a->srcfld[0]) * 8; j++) { \
- if (a->srcfld[i] & (1ull<<j)) { \
- prod[i] ^= ((trgtyp)b->srcfld[i] << j); \
- } \
- } \
- } \
- \
- VECTOR_FOR_INORDER_I(i, trgfld) { \
- r->trgfld[i] = prod[2*i] ^ prod[2*i+1]; \
- } \
-}
-
-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)
-{
-
-#ifdef CONFIG_INT128
- int i, j;
- __uint128_t prod[2];
-
- 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);
- }
- }
- }
-
- r->u128 = prod[0] ^ prod[1];
-
-#else
- int i, j;
- ppc_avr_t prod[2];
-
- VECTOR_FOR_INORDER_I(i, u64) {
- prod[i].u64[LO_IDX] = prod[i].u64[HI_IDX] = 0;
- for (j = 0; j < 64; j++) {
- if (a->u64[i] & (1ull<<j)) {
- ppc_avr_t bshift;
- if (j == 0) {
- bshift.u64[HI_IDX] = 0;
- bshift.u64[LO_IDX] = b->u64[i];
- } else {
- bshift.u64[HI_IDX] = b->u64[i] >> (64-j);
- bshift.u64[LO_IDX] = b->u64[i] << j;
- }
- prod[i].u64[LO_IDX] ^= bshift.u64[LO_IDX];
- prod[i].u64[HI_IDX] ^= bshift.u64[HI_IDX];
- }
- }
- }
-
- r->u64[LO_IDX] = prod[0].u64[LO_IDX] ^ prod[1].u64[LO_IDX];
- r->u64[HI_IDX] = prod[0].u64[HI_IDX] ^ prod[1].u64[HI_IDX];
-#endif
-}
-
-
-#if defined(HOST_WORDS_BIGENDIAN)
-#define PKBIG 1
-#else
-#define PKBIG 0
-#endif
-void helper_vpkpx(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- int i, j;
- ppc_avr_t result;
-#if defined(HOST_WORDS_BIGENDIAN)
- const ppc_avr_t *x[2] = { a, b };
-#else
- const ppc_avr_t *x[2] = { b, a };
-#endif
-
- VECTOR_FOR_INORDER_I(i, u64) {
- VECTOR_FOR_INORDER_I(j, u32) {
- uint32_t e = x[i]->u32[j];
-
- result.u16[4*i+j] = (((e >> 9) & 0xfc00) |
- ((e >> 6) & 0x3e0) |
- ((e >> 3) & 0x1f));
- }
- }
- *r = result;
-}
-
-#define VPK(suffix, from, to, cvt, dosat) \
- void helper_vpk##suffix(CPUPPCState *env, ppc_avr_t *r, \
- ppc_avr_t *a, ppc_avr_t *b) \
- { \
- int i; \
- int sat = 0; \
- ppc_avr_t result; \
- ppc_avr_t *a0 = PKBIG ? a : b; \
- ppc_avr_t *a1 = PKBIG ? b : a; \
- \
- VECTOR_FOR_INORDER_I(i, from) { \
- result.to[i] = cvt(a0->from[i], &sat); \
- result.to[i+ARRAY_SIZE(r->from)] = cvt(a1->from[i], &sat); \
- } \
- *r = result; \
- if (dosat && sat) { \
- env->vscr |= (1 << VSCR_SAT); \
- } \
- }
-#define I(x, y) (x)
-VPK(shss, s16, s8, cvtshsb, 1)
-VPK(shus, s16, u8, cvtshub, 1)
-VPK(swss, s32, s16, cvtswsh, 1)
-VPK(swus, s32, u16, cvtswuh, 1)
-VPK(sdss, s64, s32, cvtsdsw, 1)
-VPK(sdus, s64, u32, cvtsduw, 1)
-VPK(uhus, u16, u8, cvtuhub, 1)
-VPK(uwus, u32, u16, cvtuwuh, 1)
-VPK(udus, u64, u32, cvtuduw, 1)
-VPK(uhum, u16, u8, I, 0)
-VPK(uwum, u32, u16, I, 0)
-VPK(udum, u64, u32, I, 0)
-#undef I
-#undef VPK
-#undef PKBIG
-
-void helper_vrefp(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *b)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(r->f); i++) {
- r->f[i] = float32_div(float32_one, b->f[i], &env->vec_status);
- }
-}
-
-#define VRFI(suffix, rounding) \
- void helper_vrfi##suffix(CPUPPCState *env, ppc_avr_t *r, \
- ppc_avr_t *b) \
- { \
- int i; \
- float_status s = env->vec_status; \
- \
- set_float_rounding_mode(rounding, &s); \
- for (i = 0; i < ARRAY_SIZE(r->f); i++) { \
- r->f[i] = float32_round_to_int (b->f[i], &s); \
- } \
- }
-VRFI(n, float_round_nearest_even)
-VRFI(m, float_round_down)
-VRFI(p, float_round_up)
-VRFI(z, float_round_to_zero)
-#undef VRFI
-
-#define VROTATE(suffix, element, mask) \
- void helper_vrl##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
- { \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
- unsigned int shift = b->element[i] & mask; \
- r->element[i] = (a->element[i] << shift) | \
- (a->element[i] >> (sizeof(a->element[0]) * 8 - shift)); \
- } \
- }
-VROTATE(b, u8, 0x7)
-VROTATE(h, u16, 0xF)
-VROTATE(w, u32, 0x1F)
-VROTATE(d, u64, 0x3F)
-#undef VROTATE
-
-void helper_vrsqrtefp(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *b)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(r->f); i++) {
- float32 t = float32_sqrt(b->f[i], &env->vec_status);
-
- r->f[i] = float32_div(float32_one, t, &env->vec_status);
- }
-}
-
-#define VRLMI(name, size, element, insert) \
-void helper_##name(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
-{ \
- int i; \
- for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
- uint##size##_t src1 = a->element[i]; \
- uint##size##_t src2 = b->element[i]; \
- uint##size##_t src3 = r->element[i]; \
- uint##size##_t begin, end, shift, mask, rot_val; \
- \
- shift = extract##size(src2, 0, 6); \
- end = extract##size(src2, 8, 6); \
- begin = extract##size(src2, 16, 6); \
- rot_val = rol##size(src1, shift); \
- mask = mask_u##size(begin, end); \
- if (insert) { \
- r->element[i] = (rot_val & mask) | (src3 & ~mask); \
- } else { \
- r->element[i] = (rot_val & mask); \
- } \
- } \
-}
-
-VRLMI(vrldmi, 64, u64, 1);
-VRLMI(vrlwmi, 32, u32, 1);
-VRLMI(vrldnm, 64, u64, 0);
-VRLMI(vrlwnm, 32, u32, 0);
-
-void helper_vsel(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b,
- ppc_avr_t *c)
-{
- r->u64[0] = (a->u64[0] & ~c->u64[0]) | (b->u64[0] & c->u64[0]);
- r->u64[1] = (a->u64[1] & ~c->u64[1]) | (b->u64[1] & c->u64[1]);
-}
-
-void helper_vexptefp(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *b)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(r->f); i++) {
- r->f[i] = float32_exp2(b->f[i], &env->vec_status);
- }
-}
-
-void helper_vlogefp(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *b)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(r->f); i++) {
- r->f[i] = float32_log2(b->f[i], &env->vec_status);
- }
-}
-
-/* The specification says that the results are undefined if all of the
- * shift counts are not identical. We check to make sure that they are
- * to conform to what real hardware appears to do. */
-#define VSHIFT(suffix, leftp) \
- void helper_vs##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
- { \
- int shift = b->u8[LO_IDX*15] & 0x7; \
- int doit = 1; \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(r->u8); i++) { \
- doit = doit && ((b->u8[i] & 0x7) == shift); \
- } \
- if (doit) { \
- if (shift == 0) { \
- *r = *a; \
- } else if (leftp) { \
- uint64_t carry = a->u64[LO_IDX] >> (64 - shift); \
- \
- r->u64[HI_IDX] = (a->u64[HI_IDX] << shift) | carry; \
- r->u64[LO_IDX] = a->u64[LO_IDX] << shift; \
- } else { \
- uint64_t carry = a->u64[HI_IDX] << (64 - shift); \
- \
- r->u64[LO_IDX] = (a->u64[LO_IDX] >> shift) | carry; \
- r->u64[HI_IDX] = a->u64[HI_IDX] >> shift; \
- } \
- } \
- }
-VSHIFT(l, 1)
-VSHIFT(r, 0)
-#undef VSHIFT
-
-#define VSL(suffix, element, mask) \
- void helper_vsl##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
- { \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
- unsigned int shift = b->element[i] & mask; \
- \
- r->element[i] = a->element[i] << shift; \
- } \
- }
-VSL(b, u8, 0x7)
-VSL(h, u16, 0x0F)
-VSL(w, u32, 0x1F)
-VSL(d, u64, 0x3F)
-#undef VSL
-
-void helper_vslv(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- int i;
- unsigned int shift, bytes, size;
-
- size = ARRAY_SIZE(r->u8);
- for (i = 0; i < size; i++) {
- shift = b->u8[i] & 0x7; /* extract shift value */
- bytes = (a->u8[i] << 8) + /* extract adjacent bytes */
- (((i + 1) < size) ? a->u8[i + 1] : 0);
- r->u8[i] = (bytes << shift) >> 8; /* shift and store result */
- }
-}
-
-void helper_vsrv(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- int i;
- unsigned int shift, bytes;
-
- /* Use reverse order, as destination and source register can be same. Its
- * being modified in place saving temporary, reverse order will guarantee
- * that computed result is not fed back.
- */
- for (i = ARRAY_SIZE(r->u8) - 1; i >= 0; i--) {
- shift = b->u8[i] & 0x7; /* extract shift value */
- bytes = ((i ? a->u8[i - 1] : 0) << 8) + a->u8[i];
- /* extract adjacent bytes */
- r->u8[i] = (bytes >> shift) & 0xFF; /* shift and store result */
- }
-}
-
-void helper_vsldoi(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t shift)
-{
- int sh = shift & 0xf;
- int i;
- ppc_avr_t result;
-
-#if defined(HOST_WORDS_BIGENDIAN)
- for (i = 0; i < ARRAY_SIZE(r->u8); i++) {
- int index = sh + i;
- if (index > 0xf) {
- result.u8[i] = b->u8[index - 0x10];
- } else {
- result.u8[i] = a->u8[index];
- }
- }
-#else
- for (i = 0; i < ARRAY_SIZE(r->u8); i++) {
- int index = (16 - sh) + i;
- if (index > 0xf) {
- result.u8[i] = a->u8[index - 0x10];
- } else {
- result.u8[i] = b->u8[index];
- }
- }
-#endif
- *r = result;
-}
-
-void helper_vslo(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- int sh = (b->u8[LO_IDX*0xf] >> 3) & 0xf;
-
-#if defined(HOST_WORDS_BIGENDIAN)
- memmove(&r->u8[0], &a->u8[sh], 16 - sh);
- memset(&r->u8[16-sh], 0, sh);
-#else
- memmove(&r->u8[sh], &a->u8[0], 16 - sh);
- memset(&r->u8[0], 0, sh);
-#endif
-}
-
-/* Experimental testing shows that hardware masks the immediate. */
-#define _SPLAT_MASKED(element) (splat & (ARRAY_SIZE(r->element) - 1))
-#if defined(HOST_WORDS_BIGENDIAN)
-#define SPLAT_ELEMENT(element) _SPLAT_MASKED(element)
-#else
-#define SPLAT_ELEMENT(element) \
- (ARRAY_SIZE(r->element) - 1 - _SPLAT_MASKED(element))
-#endif
-#define VSPLT(suffix, element) \
- void helper_vsplt##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t splat) \
- { \
- uint32_t s = b->element[SPLAT_ELEMENT(element)]; \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
- r->element[i] = s; \
- } \
- }
-VSPLT(b, u8)
-VSPLT(h, u16)
-VSPLT(w, u32)
-#undef VSPLT
-#undef SPLAT_ELEMENT
-#undef _SPLAT_MASKED
-#if defined(HOST_WORDS_BIGENDIAN)
-#define VINSERT(suffix, element) \
- void helper_vinsert##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t index) \
- { \
- memmove(&r->u8[index], &b->u8[8 - sizeof(r->element)], \
- sizeof(r->element[0])); \
- }
-#else
-#define VINSERT(suffix, element) \
- void helper_vinsert##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t index) \
- { \
- uint32_t d = (16 - index) - sizeof(r->element[0]); \
- memmove(&r->u8[d], &b->u8[8], sizeof(r->element[0])); \
- }
-#endif
-VINSERT(b, u8)
-VINSERT(h, u16)
-VINSERT(w, u32)
-VINSERT(d, u64)
-#undef VINSERT
-#if defined(HOST_WORDS_BIGENDIAN)
-#define VEXTRACT(suffix, element) \
- void helper_vextract##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t index) \
- { \
- uint32_t es = sizeof(r->element[0]); \
- memmove(&r->u8[8 - es], &b->u8[index], es); \
- memset(&r->u8[8], 0, 8); \
- memset(&r->u8[0], 0, 8 - es); \
- }
-#else
-#define VEXTRACT(suffix, element) \
- void helper_vextract##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t index) \
- { \
- uint32_t es = sizeof(r->element[0]); \
- uint32_t s = (16 - index) - es; \
- memmove(&r->u8[8], &b->u8[s], es); \
- memset(&r->u8[0], 0, 8); \
- memset(&r->u8[8 + es], 0, 8 - es); \
- }
-#endif
-VEXTRACT(ub, u8)
-VEXTRACT(uh, u16)
-VEXTRACT(uw, u32)
-VEXTRACT(d, u64)
-#undef VEXTRACT
-
-#define VEXT_SIGNED(name, element, mask, cast, recast) \
-void helper_##name(ppc_avr_t *r, ppc_avr_t *b) \
-{ \
- int i; \
- VECTOR_FOR_INORDER_I(i, element) { \
- r->element[i] = (recast)((cast)(b->element[i] & mask)); \
- } \
-}
-VEXT_SIGNED(vextsb2w, s32, UINT8_MAX, int8_t, int32_t)
-VEXT_SIGNED(vextsb2d, s64, UINT8_MAX, int8_t, int64_t)
-VEXT_SIGNED(vextsh2w, s32, UINT16_MAX, int16_t, int32_t)
-VEXT_SIGNED(vextsh2d, s64, UINT16_MAX, int16_t, int64_t)
-VEXT_SIGNED(vextsw2d, s64, UINT32_MAX, int32_t, int64_t)
-#undef VEXT_SIGNED
-
-#define VNEG(name, element) \
-void helper_##name(ppc_avr_t *r, ppc_avr_t *b) \
-{ \
- int i; \
- VECTOR_FOR_INORDER_I(i, element) { \
- r->element[i] = -b->element[i]; \
- } \
-}
-VNEG(vnegw, s32)
-VNEG(vnegd, s64)
-#undef VNEG
-
-#define VSPLTI(suffix, element, splat_type) \
- void helper_vspltis##suffix(ppc_avr_t *r, uint32_t splat) \
- { \
- splat_type x = (int8_t)(splat << 3) >> 3; \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
- r->element[i] = x; \
- } \
- }
-VSPLTI(b, s8, int8_t)
-VSPLTI(h, s16, int16_t)
-VSPLTI(w, s32, int32_t)
-#undef VSPLTI
-
-#define VSR(suffix, element, mask) \
- void helper_vsr##suffix(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
- { \
- int i; \
- \
- for (i = 0; i < ARRAY_SIZE(r->element); i++) { \
- unsigned int shift = b->element[i] & mask; \
- r->element[i] = a->element[i] >> shift; \
- } \
- }
-VSR(ab, s8, 0x7)
-VSR(ah, s16, 0xF)
-VSR(aw, s32, 0x1F)
-VSR(ad, s64, 0x3F)
-VSR(b, u8, 0x7)
-VSR(h, u16, 0xF)
-VSR(w, u32, 0x1F)
-VSR(d, u64, 0x3F)
-#undef VSR
-
-void helper_vsro(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- int sh = (b->u8[LO_IDX * 0xf] >> 3) & 0xf;
-
-#if defined(HOST_WORDS_BIGENDIAN)
- memmove(&r->u8[sh], &a->u8[0], 16 - sh);
- memset(&r->u8[0], 0, sh);
-#else
- memmove(&r->u8[0], &a->u8[sh], 16 - sh);
- memset(&r->u8[16 - sh], 0, sh);
-#endif
-}
-
-void helper_vsubcuw(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(r->u32); i++) {
- r->u32[i] = a->u32[i] >= b->u32[i];
- }
-}
-
-void helper_vsumsws(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- int64_t t;
- int i, upper;
- ppc_avr_t result;
- int sat = 0;
-
-#if defined(HOST_WORDS_BIGENDIAN)
- upper = ARRAY_SIZE(r->s32)-1;
-#else
- upper = 0;
-#endif
- t = (int64_t)b->s32[upper];
- for (i = 0; i < ARRAY_SIZE(r->s32); i++) {
- t += a->s32[i];
- result.s32[i] = 0;
- }
- result.s32[upper] = cvtsdsw(t, &sat);
- *r = result;
-
- if (sat) {
- env->vscr |= (1 << VSCR_SAT);
- }
-}
-
-void helper_vsum2sws(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- int i, j, upper;
- ppc_avr_t result;
- int sat = 0;
-
-#if defined(HOST_WORDS_BIGENDIAN)
- upper = 1;
-#else
- upper = 0;
-#endif
- for (i = 0; i < ARRAY_SIZE(r->u64); i++) {
- int64_t t = (int64_t)b->s32[upper + i * 2];
-
- result.u64[i] = 0;
- for (j = 0; j < ARRAY_SIZE(r->u64); j++) {
- t += a->s32[2 * i + j];
- }
- result.s32[upper + i * 2] = cvtsdsw(t, &sat);
- }
-
- *r = result;
- if (sat) {
- env->vscr |= (1 << VSCR_SAT);
- }
-}
-
-void helper_vsum4sbs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- int i, j;
- int sat = 0;
-
- for (i = 0; i < ARRAY_SIZE(r->s32); i++) {
- int64_t t = (int64_t)b->s32[i];
-
- for (j = 0; j < ARRAY_SIZE(r->s32); j++) {
- t += a->s8[4 * i + j];
- }
- r->s32[i] = cvtsdsw(t, &sat);
- }
-
- if (sat) {
- env->vscr |= (1 << VSCR_SAT);
- }
-}
-
-void helper_vsum4shs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- int sat = 0;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(r->s32); i++) {
- int64_t t = (int64_t)b->s32[i];
-
- t += a->s16[2 * i] + a->s16[2 * i + 1];
- r->s32[i] = cvtsdsw(t, &sat);
- }
-
- if (sat) {
- env->vscr |= (1 << VSCR_SAT);
- }
-}
-
-void helper_vsum4ubs(CPUPPCState *env, ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- int i, j;
- int sat = 0;
-
- for (i = 0; i < ARRAY_SIZE(r->u32); i++) {
- uint64_t t = (uint64_t)b->u32[i];
-
- for (j = 0; j < ARRAY_SIZE(r->u32); j++) {
- t += a->u8[4 * i + j];
- }
- r->u32[i] = cvtuduw(t, &sat);
- }
-
- if (sat) {
- env->vscr |= (1 << VSCR_SAT);
- }
-}
-
-#if defined(HOST_WORDS_BIGENDIAN)
-#define UPKHI 1
-#define UPKLO 0
-#else
-#define UPKHI 0
-#define UPKLO 1
-#endif
-#define VUPKPX(suffix, hi) \
- void helper_vupk##suffix(ppc_avr_t *r, ppc_avr_t *b) \
- { \
- int i; \
- ppc_avr_t result; \
- \
- for (i = 0; i < ARRAY_SIZE(r->u32); i++) { \
- uint16_t e = b->u16[hi ? i : i+4]; \
- uint8_t a = (e >> 15) ? 0xff : 0; \
- uint8_t r = (e >> 10) & 0x1f; \
- uint8_t g = (e >> 5) & 0x1f; \
- uint8_t b = e & 0x1f; \
- \
- result.u32[i] = (a << 24) | (r << 16) | (g << 8) | b; \
- } \
- *r = result; \
- }
-VUPKPX(lpx, UPKLO)
-VUPKPX(hpx, UPKHI)
-#undef VUPKPX
-
-#define VUPK(suffix, unpacked, packee, hi) \
- void helper_vupk##suffix(ppc_avr_t *r, ppc_avr_t *b) \
- { \
- int i; \
- ppc_avr_t result; \
- \
- if (hi) { \
- for (i = 0; i < ARRAY_SIZE(r->unpacked); i++) { \
- result.unpacked[i] = b->packee[i]; \
- } \
- } else { \
- for (i = ARRAY_SIZE(r->unpacked); i < ARRAY_SIZE(r->packee); \
- i++) { \
- result.unpacked[i - ARRAY_SIZE(r->unpacked)] = b->packee[i]; \
- } \
- } \
- *r = result; \
- }
-VUPK(hsb, s16, s8, UPKHI)
-VUPK(hsh, s32, s16, UPKHI)
-VUPK(hsw, s64, s32, UPKHI)
-VUPK(lsb, s16, s8, UPKLO)
-VUPK(lsh, s32, s16, UPKLO)
-VUPK(lsw, s64, s32, UPKLO)
-#undef VUPK
-#undef UPKHI
-#undef UPKLO
-
-#define VGENERIC_DO(name, element) \
- void helper_v##name(ppc_avr_t *r, ppc_avr_t *b) \
- { \
- int i; \
- \
- VECTOR_FOR_INORDER_I(i, element) { \
- r->element[i] = name(b->element[i]); \
- } \
- }
-
-#define clzb(v) ((v) ? clz32((uint32_t)(v) << 24) : 8)
-#define clzh(v) ((v) ? clz32((uint32_t)(v) << 16) : 16)
-#define clzw(v) clz32((v))
-#define clzd(v) clz64((v))
-
-VGENERIC_DO(clzb, u8)
-VGENERIC_DO(clzh, u16)
-VGENERIC_DO(clzw, u32)
-VGENERIC_DO(clzd, u64)
-
-#undef clzb
-#undef clzh
-#undef clzw
-#undef clzd
-
-#define ctzb(v) ((v) ? ctz32(v) : 8)
-#define ctzh(v) ((v) ? ctz32(v) : 16)
-#define ctzw(v) ctz32((v))
-#define ctzd(v) ctz64((v))
-
-VGENERIC_DO(ctzb, u8)
-VGENERIC_DO(ctzh, u16)
-VGENERIC_DO(ctzw, u32)
-VGENERIC_DO(ctzd, u64)
-
-#undef ctzb
-#undef ctzh
-#undef ctzw
-#undef ctzd
-
-#define popcntb(v) ctpop8(v)
-#define popcnth(v) ctpop16(v)
-#define popcntw(v) ctpop32(v)
-#define popcntd(v) ctpop64(v)
-
-VGENERIC_DO(popcntb, u8)
-VGENERIC_DO(popcnth, u16)
-VGENERIC_DO(popcntw, u32)
-VGENERIC_DO(popcntd, u64)
-
-#undef popcntb
-#undef popcnth
-#undef popcntw
-#undef popcntd
-
-#undef VGENERIC_DO
-
-#if defined(HOST_WORDS_BIGENDIAN)
-#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)
-{
- 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.u64[HI_IDX] < b.u64[HI_IDX]) {
- return -1;
- } else if (a.u64[HI_IDX] > b.u64[HI_IDX]) {
- return 1;
- } else if (a.u64[LO_IDX] < b.u64[LO_IDX]) {
- return -1;
- } else if (a.u64[LO_IDX] > b.u64[LO_IDX]) {
- return 1;
- } else {
- return 0;
- }
-}
-
-static void avr_qw_add(ppc_avr_t *t, ppc_avr_t a, ppc_avr_t b)
-{
- t->u64[LO_IDX] = a.u64[LO_IDX] + b.u64[LO_IDX];
- t->u64[HI_IDX] = a.u64[HI_IDX] + b.u64[HI_IDX] +
- (~a.u64[LO_IDX] < b.u64[LO_IDX]);
-}
-
-static int avr_qw_addc(ppc_avr_t *t, ppc_avr_t a, ppc_avr_t b)
-{
- ppc_avr_t not_a;
- t->u64[LO_IDX] = a.u64[LO_IDX] + b.u64[LO_IDX];
- t->u64[HI_IDX] = a.u64[HI_IDX] + b.u64[HI_IDX] +
- (~a.u64[LO_IDX] < b.u64[LO_IDX]);
- avr_qw_not(&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)
-{
-#ifdef CONFIG_INT128
- r->u128 = a->u128 + b->u128;
-#else
- avr_qw_add(r, *a, *b);
-#endif
-}
-
-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->u64[LO_IDX] & 1) {
- ppc_avr_t tmp;
-
- tmp.u64[HI_IDX] = 0;
- tmp.u64[LO_IDX] = c->u64[LO_IDX] & 1;
- avr_qw_add(&tmp, *a, tmp);
- avr_qw_add(r, tmp, *b);
- } else {
- avr_qw_add(r, *a, *b);
- }
-#endif
-}
-
-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(&not_a, *a);
-
- r->u64[HI_IDX] = 0;
- r->u64[LO_IDX] = (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)
-{
-#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->u64[LO_IDX] & 1;
- int carry_out = 0;
- ppc_avr_t tmp;
-
- carry_out = avr_qw_addc(&tmp, *a, *b);
-
- if (!carry_out && carry_in) {
- ppc_avr_t one = QW_ONE;
- carry_out = avr_qw_addc(&tmp, tmp, one);
- }
- r->u64[HI_IDX] = 0;
- r->u64[LO_IDX] = carry_out;
-#endif
-}
-
-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
-}
-
-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.u64[HI_IDX] = 0;
- tmp.u64[LO_IDX] = c->u64[LO_IDX] & 1;
- avr_qw_add(r, sum, tmp);
-#endif
-}
-
-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.s64[HI_IDX] == -1ull) && (tmp.s64[LO_IDX] == -1ull));
- }
- r->u64[HI_IDX] = 0;
- r->u64[LO_IDX] = carry;
-#endif
-}
-
-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->u64[LO_IDX] & 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.u64[HI_IDX] == -1ull) && (tmp.u64[LO_IDX] == -1ull));
- }
-
- r->u64[HI_IDX] = 0;
- r->u64[LO_IDX] = carry_out;
-#endif
-}
-
-#define BCD_PLUS_PREF_1 0xC
-#define BCD_PLUS_PREF_2 0xF
-#define BCD_PLUS_ALT_1 0xA
-#define BCD_NEG_PREF 0xD
-#define BCD_NEG_ALT 0xB
-#define BCD_PLUS_ALT_2 0xE
-#define NATIONAL_PLUS 0x2B
-#define NATIONAL_NEG 0x2D
-
-#if defined(HOST_WORDS_BIGENDIAN)
-#define BCD_DIG_BYTE(n) (15 - (n/2))
-#else
-#define BCD_DIG_BYTE(n) (n/2)
-#endif
-
-static int bcd_get_sgn(ppc_avr_t *bcd)
-{
- switch (bcd->u8[BCD_DIG_BYTE(0)] & 0xF) {
- case BCD_PLUS_PREF_1:
- case BCD_PLUS_PREF_2:
- case BCD_PLUS_ALT_1:
- case BCD_PLUS_ALT_2:
- {
- return 1;
- }
-
- case BCD_NEG_PREF:
- case BCD_NEG_ALT:
- {
- return -1;
- }
-
- default:
- {
- return 0;
- }
- }
-}
-
-static int bcd_preferred_sgn(int sgn, int ps)
-{
- if (sgn >= 0) {
- return (ps == 0) ? BCD_PLUS_PREF_1 : BCD_PLUS_PREF_2;
- } else {
- return BCD_NEG_PREF;
- }
-}
-
-static uint8_t bcd_get_digit(ppc_avr_t *bcd, int n, int *invalid)
-{
- uint8_t result;
- if (n & 1) {
- result = bcd->u8[BCD_DIG_BYTE(n)] >> 4;
- } else {
- result = bcd->u8[BCD_DIG_BYTE(n)] & 0xF;
- }
-
- if (unlikely(result > 9)) {
- *invalid = true;
- }
- return result;
-}
-
-static void bcd_put_digit(ppc_avr_t *bcd, uint8_t digit, int n)
-{
- if (n & 1) {
- bcd->u8[BCD_DIG_BYTE(n)] &= 0x0F;
- bcd->u8[BCD_DIG_BYTE(n)] |= (digit<<4);
- } else {
- bcd->u8[BCD_DIG_BYTE(n)] &= 0xF0;
- bcd->u8[BCD_DIG_BYTE(n)] |= digit;
- }
-}
-
-static int bcd_cmp_zero(ppc_avr_t *bcd)
-{
- if (bcd->u64[HI_IDX] == 0 && (bcd->u64[LO_IDX] >> 4) == 0) {
- return 1 << CRF_EQ;
- } else {
- return (bcd_get_sgn(bcd) == 1) ? 1 << CRF_GT : 1 << CRF_LT;
- }
-}
-
-static uint16_t get_national_digit(ppc_avr_t *reg, int n)
-{
-#if defined(HOST_WORDS_BIGENDIAN)
- return reg->u16[7 - n];
-#else
- return reg->u16[n];
-#endif
-}
-
-static void set_national_digit(ppc_avr_t *reg, uint8_t val, int n)
-{
-#if defined(HOST_WORDS_BIGENDIAN)
- reg->u16[7 - n] = val;
-#else
- reg->u16[n] = val;
-#endif
-}
-
-static int bcd_cmp_mag(ppc_avr_t *a, ppc_avr_t *b)
-{
- int i;
- int invalid = 0;
- for (i = 31; i > 0; i--) {
- uint8_t dig_a = bcd_get_digit(a, i, &invalid);
- uint8_t dig_b = bcd_get_digit(b, i, &invalid);
- if (unlikely(invalid)) {
- return 0; /* doesn't matter */
- } else if (dig_a > dig_b) {
- return 1;
- } else if (dig_a < dig_b) {
- return -1;
- }
- }
-
- return 0;
-}
-
-static int bcd_add_mag(ppc_avr_t *t, ppc_avr_t *a, ppc_avr_t *b, int *invalid,
- int *overflow)
-{
- int carry = 0;
- int i;
- int is_zero = 1;
- for (i = 1; i <= 31; i++) {
- uint8_t digit = bcd_get_digit(a, i, invalid) +
- bcd_get_digit(b, i, invalid) + carry;
- is_zero &= (digit == 0);
- if (digit > 9) {
- carry = 1;
- digit -= 10;
- } else {
- carry = 0;
- }
-
- bcd_put_digit(t, digit, i);
-
- if (unlikely(*invalid)) {
- return -1;
- }
- }
-
- *overflow = carry;
- return is_zero;
-}
-
-static int bcd_sub_mag(ppc_avr_t *t, ppc_avr_t *a, ppc_avr_t *b, int *invalid,
- int *overflow)
-{
- int carry = 0;
- int i;
- int is_zero = 1;
- for (i = 1; i <= 31; i++) {
- uint8_t digit = bcd_get_digit(a, i, invalid) -
- bcd_get_digit(b, i, invalid) + carry;
- is_zero &= (digit == 0);
- if (digit & 0x80) {
- carry = -1;
- digit += 10;
- } else {
- carry = 0;
- }
-
- bcd_put_digit(t, digit, i);
-
- if (unlikely(*invalid)) {
- return -1;
- }
- }
-
- *overflow = carry;
- return is_zero;
-}
-
-uint32_t helper_bcdadd(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
-{
-
- int sgna = bcd_get_sgn(a);
- int sgnb = bcd_get_sgn(b);
- int invalid = (sgna == 0) || (sgnb == 0);
- int overflow = 0;
- int zero = 0;
- uint32_t cr = 0;
- ppc_avr_t result = { .u64 = { 0, 0 } };
-
- if (!invalid) {
- if (sgna == sgnb) {
- result.u8[BCD_DIG_BYTE(0)] = bcd_preferred_sgn(sgna, ps);
- zero = bcd_add_mag(&result, a, b, &invalid, &overflow);
- cr = (sgna > 0) ? 1 << CRF_GT : 1 << CRF_LT;
- } else if (bcd_cmp_mag(a, b) > 0) {
- result.u8[BCD_DIG_BYTE(0)] = bcd_preferred_sgn(sgna, ps);
- zero = bcd_sub_mag(&result, a, b, &invalid, &overflow);
- cr = (sgna > 0) ? 1 << CRF_GT : 1 << CRF_LT;
- } else {
- result.u8[BCD_DIG_BYTE(0)] = bcd_preferred_sgn(sgnb, ps);
- zero = bcd_sub_mag(&result, b, a, &invalid, &overflow);
- cr = (sgnb > 0) ? 1 << CRF_GT : 1 << CRF_LT;
- }
- }
-
- if (unlikely(invalid)) {
- result.u64[HI_IDX] = result.u64[LO_IDX] = -1;
- cr = 1 << CRF_SO;
- } else if (overflow) {
- cr |= 1 << CRF_SO;
- } else if (zero) {
- cr = 1 << CRF_EQ;
- }
-
- *r = result;
-
- return cr;
-}
-
-uint32_t helper_bcdsub(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
-{
- ppc_avr_t bcopy = *b;
- int sgnb = bcd_get_sgn(b);
- if (sgnb < 0) {
- bcd_put_digit(&bcopy, BCD_PLUS_PREF_1, 0);
- } else if (sgnb > 0) {
- bcd_put_digit(&bcopy, BCD_NEG_PREF, 0);
- }
- /* else invalid ... defer to bcdadd code for proper handling */
-
- return helper_bcdadd(r, a, &bcopy, ps);
-}
-
-uint32_t helper_bcdcfn(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps)
-{
- int i;
- int cr = 0;
- uint16_t national = 0;
- uint16_t sgnb = get_national_digit(b, 0);
- ppc_avr_t ret = { .u64 = { 0, 0 } };
- int invalid = (sgnb != NATIONAL_PLUS && sgnb != NATIONAL_NEG);
-
- for (i = 1; i < 8; i++) {
- national = get_national_digit(b, i);
- if (unlikely(national < 0x30 || national > 0x39)) {
- invalid = 1;
- break;
- }
-
- bcd_put_digit(&ret, national & 0xf, i);
- }
-
- if (sgnb == NATIONAL_PLUS) {
- bcd_put_digit(&ret, (ps == 0) ? BCD_PLUS_PREF_1 : BCD_PLUS_PREF_2, 0);
- } else {
- bcd_put_digit(&ret, BCD_NEG_PREF, 0);
- }
-
- cr = bcd_cmp_zero(&ret);
-
- if (unlikely(invalid)) {
- cr = 1 << CRF_SO;
- }
-
- *r = ret;
-
- return cr;
-}
-
-uint32_t helper_bcdctn(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps)
-{
- int i;
- int cr = 0;
- int sgnb = bcd_get_sgn(b);
- int invalid = (sgnb == 0);
- ppc_avr_t ret = { .u64 = { 0, 0 } };
-
- int ox_flag = (b->u64[HI_IDX] != 0) || ((b->u64[LO_IDX] >> 32) != 0);
-
- for (i = 1; i < 8; i++) {
- set_national_digit(&ret, 0x30 + bcd_get_digit(b, i, &invalid), i);
-
- if (unlikely(invalid)) {
- break;
- }
- }
- set_national_digit(&ret, (sgnb == -1) ? NATIONAL_NEG : NATIONAL_PLUS, 0);
-
- cr = bcd_cmp_zero(b);
-
- if (ox_flag) {
- cr |= 1 << CRF_SO;
- }
-
- if (unlikely(invalid)) {
- cr = 1 << CRF_SO;
- }
-
- *r = ret;
-
- return cr;
-}
-
-uint32_t helper_bcdcfz(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps)
-{
- int i;
- int cr = 0;
- int invalid = 0;
- int zone_digit = 0;
- int zone_lead = ps ? 0xF : 0x3;
- int digit = 0;
- ppc_avr_t ret = { .u64 = { 0, 0 } };
- int sgnb = b->u8[BCD_DIG_BYTE(0)] >> 4;
-
- if (unlikely((sgnb < 0xA) && ps)) {
- invalid = 1;
- }
-
- for (i = 0; i < 16; i++) {
- zone_digit = (i * 2) ? b->u8[BCD_DIG_BYTE(i * 2)] >> 4 : zone_lead;
- digit = b->u8[BCD_DIG_BYTE(i * 2)] & 0xF;
- if (unlikely(zone_digit != zone_lead || digit > 0x9)) {
- invalid = 1;
- break;
- }
-
- bcd_put_digit(&ret, digit, i + 1);
- }
-
- if ((ps && (sgnb == 0xB || sgnb == 0xD)) ||
- (!ps && (sgnb & 0x4))) {
- bcd_put_digit(&ret, BCD_NEG_PREF, 0);
- } else {
- bcd_put_digit(&ret, BCD_PLUS_PREF_1, 0);
- }
-
- cr = bcd_cmp_zero(&ret);
-
- if (unlikely(invalid)) {
- cr = 1 << CRF_SO;
- }
-
- *r = ret;
-
- return cr;
-}
-
-uint32_t helper_bcdctz(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps)
-{
- int i;
- int cr = 0;
- uint8_t digit = 0;
- int sgnb = bcd_get_sgn(b);
- int zone_lead = (ps) ? 0xF0 : 0x30;
- int invalid = (sgnb == 0);
- ppc_avr_t ret = { .u64 = { 0, 0 } };
-
- int ox_flag = ((b->u64[HI_IDX] >> 4) != 0);
-
- for (i = 0; i < 16; i++) {
- digit = bcd_get_digit(b, i + 1, &invalid);
-
- if (unlikely(invalid)) {
- break;
- }
-
- ret.u8[BCD_DIG_BYTE(i * 2)] = zone_lead + digit;
- }
-
- if (ps) {
- bcd_put_digit(&ret, (sgnb == 1) ? 0xC : 0xD, 1);
- } else {
- bcd_put_digit(&ret, (sgnb == 1) ? 0x3 : 0x7, 1);
- }
-
- cr = bcd_cmp_zero(b);
-
- if (ox_flag) {
- cr |= 1 << CRF_SO;
- }
-
- if (unlikely(invalid)) {
- cr = 1 << CRF_SO;
- }
-
- *r = ret;
-
- return cr;
-}
-
-void helper_vsbox(ppc_avr_t *r, ppc_avr_t *a)
-{
- int i;
- VECTOR_FOR_INORDER_I(i, u8) {
- r->u8[i] = AES_sbox[a->u8[i]];
- }
-}
-
-void helper_vcipher(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- ppc_avr_t result;
- int i;
-
- VECTOR_FOR_INORDER_I(i, u32) {
- result.AVRW(i) = b->AVRW(i) ^
- (AES_Te0[a->AVRB(AES_shifts[4*i + 0])] ^
- AES_Te1[a->AVRB(AES_shifts[4*i + 1])] ^
- AES_Te2[a->AVRB(AES_shifts[4*i + 2])] ^
- AES_Te3[a->AVRB(AES_shifts[4*i + 3])]);
- }
- *r = result;
-}
-
-void helper_vcipherlast(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- ppc_avr_t result;
- int i;
-
- VECTOR_FOR_INORDER_I(i, u8) {
- result.AVRB(i) = b->AVRB(i) ^ (AES_sbox[a->AVRB(AES_shifts[i])]);
- }
- *r = result;
-}
-
-void helper_vncipher(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- /* This differs from what is written in ISA V2.07. The RTL is */
- /* incorrect and will be fixed in V2.07B. */
- int i;
- ppc_avr_t tmp;
-
- VECTOR_FOR_INORDER_I(i, u8) {
- tmp.AVRB(i) = b->AVRB(i) ^ AES_isbox[a->AVRB(AES_ishifts[i])];
- }
-
- VECTOR_FOR_INORDER_I(i, u32) {
- r->AVRW(i) =
- AES_imc[tmp.AVRB(4*i + 0)][0] ^
- AES_imc[tmp.AVRB(4*i + 1)][1] ^
- AES_imc[tmp.AVRB(4*i + 2)][2] ^
- AES_imc[tmp.AVRB(4*i + 3)][3];
- }
-}
-
-void helper_vncipherlast(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
- ppc_avr_t result;
- int i;
-
- VECTOR_FOR_INORDER_I(i, u8) {
- result.AVRB(i) = b->AVRB(i) ^ (AES_isbox[a->AVRB(AES_ishifts[i])]);
- }
- *r = result;
-}
-
-#define ROTRu32(v, n) (((v) >> (n)) | ((v) << (32-n)))
-#if defined(HOST_WORDS_BIGENDIAN)
-#define EL_IDX(i) (i)
-#else
-#define EL_IDX(i) (3 - (i))
-#endif
-
-void helper_vshasigmaw(ppc_avr_t *r, ppc_avr_t *a, uint32_t st_six)
-{
- int st = (st_six & 0x10) != 0;
- int six = st_six & 0xF;
- int i;
-
- VECTOR_FOR_INORDER_I(i, u32) {
- if (st == 0) {
- if ((six & (0x8 >> i)) == 0) {
- r->u32[EL_IDX(i)] = ROTRu32(a->u32[EL_IDX(i)], 7) ^
- ROTRu32(a->u32[EL_IDX(i)], 18) ^
- (a->u32[EL_IDX(i)] >> 3);
- } else { /* six.bit[i] == 1 */
- r->u32[EL_IDX(i)] = ROTRu32(a->u32[EL_IDX(i)], 17) ^
- ROTRu32(a->u32[EL_IDX(i)], 19) ^
- (a->u32[EL_IDX(i)] >> 10);
- }
- } else { /* st == 1 */
- if ((six & (0x8 >> i)) == 0) {
- r->u32[EL_IDX(i)] = ROTRu32(a->u32[EL_IDX(i)], 2) ^
- ROTRu32(a->u32[EL_IDX(i)], 13) ^
- ROTRu32(a->u32[EL_IDX(i)], 22);
- } else { /* six.bit[i] == 1 */
- r->u32[EL_IDX(i)] = ROTRu32(a->u32[EL_IDX(i)], 6) ^
- ROTRu32(a->u32[EL_IDX(i)], 11) ^
- ROTRu32(a->u32[EL_IDX(i)], 25);
- }
- }
- }
-}
-
-#undef ROTRu32
-#undef EL_IDX
-
-#define ROTRu64(v, n) (((v) >> (n)) | ((v) << (64-n)))
-#if defined(HOST_WORDS_BIGENDIAN)
-#define EL_IDX(i) (i)
-#else
-#define EL_IDX(i) (1 - (i))
-#endif
-
-void helper_vshasigmad(ppc_avr_t *r, ppc_avr_t *a, uint32_t st_six)
-{
- int st = (st_six & 0x10) != 0;
- int six = st_six & 0xF;
- int i;
-
- VECTOR_FOR_INORDER_I(i, u64) {
- if (st == 0) {
- if ((six & (0x8 >> (2*i))) == 0) {
- r->u64[EL_IDX(i)] = ROTRu64(a->u64[EL_IDX(i)], 1) ^
- ROTRu64(a->u64[EL_IDX(i)], 8) ^
- (a->u64[EL_IDX(i)] >> 7);
- } else { /* six.bit[2*i] == 1 */
- r->u64[EL_IDX(i)] = ROTRu64(a->u64[EL_IDX(i)], 19) ^
- ROTRu64(a->u64[EL_IDX(i)], 61) ^
- (a->u64[EL_IDX(i)] >> 6);
- }
- } else { /* st == 1 */
- if ((six & (0x8 >> (2*i))) == 0) {
- r->u64[EL_IDX(i)] = ROTRu64(a->u64[EL_IDX(i)], 28) ^
- ROTRu64(a->u64[EL_IDX(i)], 34) ^
- ROTRu64(a->u64[EL_IDX(i)], 39);
- } else { /* six.bit[2*i] == 1 */
- r->u64[EL_IDX(i)] = ROTRu64(a->u64[EL_IDX(i)], 14) ^
- ROTRu64(a->u64[EL_IDX(i)], 18) ^
- ROTRu64(a->u64[EL_IDX(i)], 41);
- }
- }
- }
-}
-
-#undef ROTRu64
-#undef EL_IDX
-
-void helper_vpermxor(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
-{
- ppc_avr_t result;
- int i;
-
- VECTOR_FOR_INORDER_I(i, u8) {
- int indexA = c->u8[i] >> 4;
- int indexB = c->u8[i] & 0xF;
-#if defined(HOST_WORDS_BIGENDIAN)
- result.u8[i] = a->u8[indexA] ^ b->u8[indexB];
-#else
- result.u8[i] = a->u8[15-indexA] ^ b->u8[15-indexB];
-#endif
- }
- *r = result;
-}
-
-#undef VECTOR_FOR_INORDER_I
-#undef HI_IDX
-#undef LO_IDX
-
-/*****************************************************************************/
-/* SPE extension helpers */
-/* Use a table to make this quicker */
-static const uint8_t hbrev[16] = {
- 0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE,
- 0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF,
-};
-
-static inline uint8_t byte_reverse(uint8_t val)
-{
- return hbrev[val >> 4] | (hbrev[val & 0xF] << 4);
-}
-
-static inline uint32_t word_reverse(uint32_t val)
-{
- return byte_reverse(val >> 24) | (byte_reverse(val >> 16) << 8) |
- (byte_reverse(val >> 8) << 16) | (byte_reverse(val) << 24);
-}
-
-#define MASKBITS 16 /* Random value - to be fixed (implementation dependent) */
-target_ulong helper_brinc(target_ulong arg1, target_ulong arg2)
-{
- uint32_t a, b, d, mask;
-
- mask = UINT32_MAX >> (32 - MASKBITS);
- a = arg1 & mask;
- b = arg2 & mask;
- d = word_reverse(1 + word_reverse(a | ~b));
- return (arg1 & ~mask) | (d & b);
-}
-
-uint32_t helper_cntlsw32(uint32_t val)
-{
- if (val & 0x80000000) {
- return clz32(~val);
- } else {
- return clz32(val);
- }
-}
-
-uint32_t helper_cntlzw32(uint32_t val)
-{
- return clz32(val);
-}
-
-/* 440 specific */
-target_ulong helper_dlmzb(CPUPPCState *env, target_ulong high,
- target_ulong low, uint32_t update_Rc)
-{
- target_ulong mask;
- int i;
-
- i = 1;
- for (mask = 0xFF000000; mask != 0; mask = mask >> 8) {
- if ((high & mask) == 0) {
- if (update_Rc) {
- env->crf[0] = 0x4;
- }
- goto done;
- }
- i++;
- }
- for (mask = 0xFF000000; mask != 0; mask = mask >> 8) {
- if ((low & mask) == 0) {
- if (update_Rc) {
- env->crf[0] = 0x8;
- }
- goto done;
- }
- i++;
- }
- i = 8;
- if (update_Rc) {
- env->crf[0] = 0x2;
- }
- done:
- env->xer = (env->xer & ~0x7F) | i;
- if (update_Rc) {
- env->crf[0] |= xer_so;
- }
- return i;
-}
diff --git a/target-ppc/internal.h b/target-ppc/internal.h
deleted file mode 100644
index 1ff4896c45..0000000000
--- a/target-ppc/internal.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * PowerPC interal definitions for qemu.
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-
-#ifndef PPC_INTERNAL_H
-#define PPC_INTERNAL_H
-
-#define FUNC_MASK(name, ret_type, size, max_val) \
-static inline ret_type name(uint##size##_t start, \
- uint##size##_t end) \
-{ \
- ret_type ret, max_bit = size - 1; \
- \
- if (likely(start == 0)) { \
- ret = max_val << (max_bit - end); \
- } else if (likely(end == max_bit)) { \
- ret = max_val >> start; \
- } else { \
- ret = (((uint##size##_t)(-1ULL)) >> (start)) ^ \
- (((uint##size##_t)(-1ULL) >> (end)) >> 1); \
- if (unlikely(start > end)) { \
- return ~ret; \
- } \
- } \
- \
- return ret; \
-}
-
-#if defined(TARGET_PPC64)
-FUNC_MASK(MASK, target_ulong, 64, UINT64_MAX);
-#else
-FUNC_MASK(MASK, target_ulong, 32, UINT32_MAX);
-#endif
-FUNC_MASK(mask_u32, uint32_t, 32, UINT32_MAX);
-FUNC_MASK(mask_u64, uint64_t, 64, UINT64_MAX);
-
-#endif /* PPC_INTERNAL_H */
diff --git a/target-ppc/kvm-stub.c b/target-ppc/kvm-stub.c
deleted file mode 100644
index efeafca1df..0000000000
--- a/target-ppc/kvm-stub.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * QEMU KVM PPC specific function stubs
- *
- * Copyright Freescale Inc. 2013
- *
- * Author: Alexander Graf <agraf@suse.de>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "hw/ppc/openpic.h"
-
-int kvm_openpic_connect_vcpu(DeviceState *d, CPUState *cs)
-{
- return -EINVAL;
-}
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
deleted file mode 100644
index 9c4834c4fc..0000000000
--- a/target-ppc/kvm.c
+++ /dev/null
@@ -1,2674 +0,0 @@
-/*
- * PowerPC implementation of KVM hooks
- *
- * Copyright IBM Corp. 2007
- * Copyright (C) 2011 Freescale Semiconductor, Inc.
- *
- * Authors:
- * Jerone Young <jyoung5@us.ibm.com>
- * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
- * Hollis Blanchard <hollisb@us.ibm.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu/osdep.h"
-#include <dirent.h>
-#include <sys/ioctl.h>
-#include <sys/vfs.h>
-
-#include <linux/kvm.h>
-
-#include "qemu-common.h"
-#include "qemu/error-report.h"
-#include "cpu.h"
-#include "qemu/timer.h"
-#include "sysemu/sysemu.h"
-#include "sysemu/kvm.h"
-#include "sysemu/numa.h"
-#include "kvm_ppc.h"
-#include "sysemu/cpus.h"
-#include "sysemu/device_tree.h"
-#include "mmu-hash64.h"
-
-#include "hw/sysbus.h"
-#include "hw/ppc/spapr.h"
-#include "hw/ppc/spapr_vio.h"
-#include "hw/ppc/spapr_cpu_core.h"
-#include "hw/ppc/ppc.h"
-#include "sysemu/watchdog.h"
-#include "trace.h"
-#include "exec/gdbstub.h"
-#include "exec/memattrs.h"
-#include "sysemu/hostmem.h"
-#include "qemu/cutils.h"
-#if defined(TARGET_PPC64)
-#include "hw/ppc/spapr_cpu_core.h"
-#endif
-
-//#define DEBUG_KVM
-
-#ifdef DEBUG_KVM
-#define DPRINTF(fmt, ...) \
- do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...) \
- do { } while (0)
-#endif
-
-#define PROC_DEVTREE_CPU "/proc/device-tree/cpus/"
-
-const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
- KVM_CAP_LAST_INFO
-};
-
-static int cap_interrupt_unset = false;
-static int cap_interrupt_level = false;
-static int cap_segstate;
-static int cap_booke_sregs;
-static int cap_ppc_smt;
-static int cap_ppc_rma;
-static int cap_spapr_tce;
-static int cap_spapr_multitce;
-static int cap_spapr_vfio;
-static int cap_hior;
-static int cap_one_reg;
-static int cap_epr;
-static int cap_ppc_watchdog;
-static int cap_papr;
-static int cap_htab_fd;
-static int cap_fixup_hcalls;
-static int cap_htm; /* Hardware transactional memory support */
-
-static uint32_t debug_inst_opcode;
-
-/* XXX We have a race condition where we actually have a level triggered
- * interrupt, but the infrastructure can't expose that yet, so the guest
- * takes but ignores it, goes to sleep and never gets notified that there's
- * still an interrupt pending.
- *
- * As a quick workaround, let's just wake up again 20 ms after we injected
- * an interrupt. That way we can assure that we're always reinjecting
- * interrupts in case the guest swallowed them.
- */
-static QEMUTimer *idle_timer;
-
-static void kvm_kick_cpu(void *opaque)
-{
- PowerPCCPU *cpu = opaque;
-
- qemu_cpu_kick(CPU(cpu));
-}
-
-/* Check whether we are running with KVM-PR (instead of KVM-HV). This
- * should only be used for fallback tests - generally we should use
- * explicit capabilities for the features we want, rather than
- * assuming what is/isn't available depending on the KVM variant. */
-static bool kvmppc_is_pr(KVMState *ks)
-{
- /* Assume KVM-PR if the GET_PVINFO capability is available */
- return kvm_check_extension(ks, KVM_CAP_PPC_GET_PVINFO) != 0;
-}
-
-static int kvm_ppc_register_host_cpu_type(void);
-
-int kvm_arch_init(MachineState *ms, KVMState *s)
-{
- cap_interrupt_unset = kvm_check_extension(s, KVM_CAP_PPC_UNSET_IRQ);
- cap_interrupt_level = kvm_check_extension(s, KVM_CAP_PPC_IRQ_LEVEL);
- cap_segstate = kvm_check_extension(s, KVM_CAP_PPC_SEGSTATE);
- cap_booke_sregs = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_SREGS);
- cap_ppc_smt = kvm_check_extension(s, KVM_CAP_PPC_SMT);
- cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
- cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
- cap_spapr_multitce = kvm_check_extension(s, KVM_CAP_SPAPR_MULTITCE);
- cap_spapr_vfio = false;
- cap_one_reg = kvm_check_extension(s, KVM_CAP_ONE_REG);
- cap_hior = kvm_check_extension(s, KVM_CAP_PPC_HIOR);
- cap_epr = kvm_check_extension(s, KVM_CAP_PPC_EPR);
- cap_ppc_watchdog = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_WATCHDOG);
- /* Note: we don't set cap_papr here, because this capability is
- * only activated after this by kvmppc_set_papr() */
- cap_htab_fd = kvm_check_extension(s, KVM_CAP_PPC_HTAB_FD);
- cap_fixup_hcalls = kvm_check_extension(s, KVM_CAP_PPC_FIXUP_HCALL);
- cap_htm = kvm_vm_check_extension(s, KVM_CAP_PPC_HTM);
-
- if (!cap_interrupt_level) {
- fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the "
- "VM to stall at times!\n");
- }
-
- kvm_ppc_register_host_cpu_type();
-
- return 0;
-}
-
-static int kvm_arch_sync_sregs(PowerPCCPU *cpu)
-{
- CPUPPCState *cenv = &cpu->env;
- CPUState *cs = CPU(cpu);
- struct kvm_sregs sregs;
- int ret;
-
- if (cenv->excp_model == POWERPC_EXCP_BOOKE) {
- /* What we're really trying to say is "if we're on BookE, we use
- the native PVR for now". This is the only sane way to check
- it though, so we potentially confuse users that they can run
- BookE guests on BookS. Let's hope nobody dares enough :) */
- return 0;
- } else {
- if (!cap_segstate) {
- fprintf(stderr, "kvm error: missing PVR setting capability\n");
- return -ENOSYS;
- }
- }
-
- ret = kvm_vcpu_ioctl(cs, KVM_GET_SREGS, &sregs);
- if (ret) {
- return ret;
- }
-
- sregs.pvr = cenv->spr[SPR_PVR];
- return kvm_vcpu_ioctl(cs, KVM_SET_SREGS, &sregs);
-}
-
-/* Set up a shared TLB array with KVM */
-static int kvm_booke206_tlb_init(PowerPCCPU *cpu)
-{
- CPUPPCState *env = &cpu->env;
- CPUState *cs = CPU(cpu);
- struct kvm_book3e_206_tlb_params params = {};
- struct kvm_config_tlb cfg = {};
- unsigned int entries = 0;
- int ret, i;
-
- if (!kvm_enabled() ||
- !kvm_check_extension(cs->kvm_state, KVM_CAP_SW_TLB)) {
- return 0;
- }
-
- assert(ARRAY_SIZE(params.tlb_sizes) == BOOKE206_MAX_TLBN);
-
- for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
- params.tlb_sizes[i] = booke206_tlb_size(env, i);
- params.tlb_ways[i] = booke206_tlb_ways(env, i);
- entries += params.tlb_sizes[i];
- }
-
- assert(entries == env->nb_tlb);
- assert(sizeof(struct kvm_book3e_206_tlb_entry) == sizeof(ppcmas_tlb_t));
-
- env->tlb_dirty = true;
-
- cfg.array = (uintptr_t)env->tlb.tlbm;
- cfg.array_len = sizeof(ppcmas_tlb_t) * entries;
- cfg.params = (uintptr_t)&params;
- cfg.mmu_type = KVM_MMU_FSL_BOOKE_NOHV;
-
- ret = kvm_vcpu_enable_cap(cs, KVM_CAP_SW_TLB, 0, (uintptr_t)&cfg);
- if (ret < 0) {
- fprintf(stderr, "%s: couldn't enable KVM_CAP_SW_TLB: %s\n",
- __func__, strerror(-ret));
- return ret;
- }
-
- env->kvm_sw_tlb = true;
- return 0;
-}
-
-
-#if defined(TARGET_PPC64)
-static void kvm_get_fallback_smmu_info(PowerPCCPU *cpu,
- struct kvm_ppc_smmu_info *info)
-{
- CPUPPCState *env = &cpu->env;
- CPUState *cs = CPU(cpu);
-
- memset(info, 0, sizeof(*info));
-
- /* We don't have the new KVM_PPC_GET_SMMU_INFO ioctl, so
- * need to "guess" what the supported page sizes are.
- *
- * For that to work we make a few assumptions:
- *
- * - Check whether we are running "PR" KVM which only supports 4K
- * and 16M pages, but supports them regardless of the backing
- * store characteritics. We also don't support 1T segments.
- *
- * This is safe as if HV KVM ever supports that capability or PR
- * KVM grows supports for more page/segment sizes, those versions
- * will have implemented KVM_CAP_PPC_GET_SMMU_INFO and thus we
- * will not hit this fallback
- *
- * - Else we are running HV KVM. This means we only support page
- * sizes that fit in the backing store. Additionally we only
- * advertize 64K pages if the processor is ARCH 2.06 and we assume
- * P7 encodings for the SLB and hash table. Here too, we assume
- * support for any newer processor will mean a kernel that
- * implements KVM_CAP_PPC_GET_SMMU_INFO and thus doesn't hit
- * this fallback.
- */
- if (kvmppc_is_pr(cs->kvm_state)) {
- /* No flags */
- info->flags = 0;
- info->slb_size = 64;
-
- /* Standard 4k base page size segment */
- info->sps[0].page_shift = 12;
- info->sps[0].slb_enc = 0;
- info->sps[0].enc[0].page_shift = 12;
- info->sps[0].enc[0].pte_enc = 0;
-
- /* Standard 16M large page size segment */
- info->sps[1].page_shift = 24;
- info->sps[1].slb_enc = SLB_VSID_L;
- info->sps[1].enc[0].page_shift = 24;
- info->sps[1].enc[0].pte_enc = 0;
- } else {
- int i = 0;
-
- /* HV KVM has backing store size restrictions */
- info->flags = KVM_PPC_PAGE_SIZES_REAL;
-
- if (env->mmu_model & POWERPC_MMU_1TSEG) {
- info->flags |= KVM_PPC_1T_SEGMENTS;
- }
-
- if (env->mmu_model == POWERPC_MMU_2_06 ||
- env->mmu_model == POWERPC_MMU_2_07) {
- info->slb_size = 32;
- } else {
- info->slb_size = 64;
- }
-
- /* Standard 4k base page size segment */
- info->sps[i].page_shift = 12;
- info->sps[i].slb_enc = 0;
- info->sps[i].enc[0].page_shift = 12;
- info->sps[i].enc[0].pte_enc = 0;
- i++;
-
- /* 64K on MMU 2.06 and later */
- if (env->mmu_model == POWERPC_MMU_2_06 ||
- env->mmu_model == POWERPC_MMU_2_07) {
- info->sps[i].page_shift = 16;
- info->sps[i].slb_enc = 0x110;
- info->sps[i].enc[0].page_shift = 16;
- info->sps[i].enc[0].pte_enc = 1;
- i++;
- }
-
- /* Standard 16M large page size segment */
- info->sps[i].page_shift = 24;
- info->sps[i].slb_enc = SLB_VSID_L;
- info->sps[i].enc[0].page_shift = 24;
- info->sps[i].enc[0].pte_enc = 0;
- }
-}
-
-static void kvm_get_smmu_info(PowerPCCPU *cpu, struct kvm_ppc_smmu_info *info)
-{
- CPUState *cs = CPU(cpu);
- int ret;
-
- if (kvm_check_extension(cs->kvm_state, KVM_CAP_PPC_GET_SMMU_INFO)) {
- ret = kvm_vm_ioctl(cs->kvm_state, KVM_PPC_GET_SMMU_INFO, info);
- if (ret == 0) {
- return;
- }
- }
-
- kvm_get_fallback_smmu_info(cpu, info);
-}
-
-static long gethugepagesize(const char *mem_path)
-{
- struct statfs fs;
- int ret;
-
- do {
- ret = statfs(mem_path, &fs);
- } while (ret != 0 && errno == EINTR);
-
- if (ret != 0) {
- fprintf(stderr, "Couldn't statfs() memory path: %s\n",
- strerror(errno));
- exit(1);
- }
-
-#define HUGETLBFS_MAGIC 0x958458f6
-
- if (fs.f_type != HUGETLBFS_MAGIC) {
- /* Explicit mempath, but it's ordinary pages */
- return getpagesize();
- }
-
- /* It's hugepage, return the huge page size */
- return fs.f_bsize;
-}
-
-/*
- * FIXME TOCTTOU: this iterates over memory backends' mem-path, which
- * may or may not name the same files / on the same filesystem now as
- * when we actually open and map them. Iterate over the file
- * descriptors instead, and use qemu_fd_getpagesize().
- */
-static int find_max_supported_pagesize(Object *obj, void *opaque)
-{
- char *mem_path;
- long *hpsize_min = opaque;
-
- if (object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) {
- mem_path = object_property_get_str(obj, "mem-path", NULL);
- if (mem_path) {
- long hpsize = gethugepagesize(mem_path);
- if (hpsize < *hpsize_min) {
- *hpsize_min = hpsize;
- }
- } else {
- *hpsize_min = getpagesize();
- }
- }
-
- return 0;
-}
-
-static long getrampagesize(void)
-{
- long hpsize = LONG_MAX;
- long mainrampagesize;
- Object *memdev_root;
-
- if (mem_path) {
- mainrampagesize = gethugepagesize(mem_path);
- } else {
- mainrampagesize = getpagesize();
- }
-
- /* it's possible we have memory-backend objects with
- * hugepage-backed RAM. these may get mapped into system
- * address space via -numa parameters or memory hotplug
- * hooks. we want to take these into account, but we
- * also want to make sure these supported hugepage
- * sizes are applicable across the entire range of memory
- * we may boot from, so we take the min across all
- * backends, and assume normal pages in cases where a
- * backend isn't backed by hugepages.
- */
- memdev_root = object_resolve_path("/objects", NULL);
- if (memdev_root) {
- object_child_foreach(memdev_root, find_max_supported_pagesize, &hpsize);
- }
- if (hpsize == LONG_MAX) {
- /* No additional memory regions found ==> Report main RAM page size */
- return mainrampagesize;
- }
-
- /* If NUMA is disabled or the NUMA nodes are not backed with a
- * memory-backend, then there is at least one node using "normal" RAM,
- * so if its page size is smaller we have got to report that size instead.
- */
- if (hpsize > mainrampagesize &&
- (nb_numa_nodes == 0 || numa_info[0].node_memdev == NULL)) {
- static bool warned;
- if (!warned) {
- error_report("Huge page support disabled (n/a for main memory).");
- warned = true;
- }
- return mainrampagesize;
- }
-
- return hpsize;
-}
-
-static bool kvm_valid_page_size(uint32_t flags, long rampgsize, uint32_t shift)
-{
- if (!(flags & KVM_PPC_PAGE_SIZES_REAL)) {
- return true;
- }
-
- return (1ul << shift) <= rampgsize;
-}
-
-static void kvm_fixup_page_sizes(PowerPCCPU *cpu)
-{
- static struct kvm_ppc_smmu_info smmu_info;
- static bool has_smmu_info;
- CPUPPCState *env = &cpu->env;
- long rampagesize;
- int iq, ik, jq, jk;
- bool has_64k_pages = false;
-
- /* We only handle page sizes for 64-bit server guests for now */
- if (!(env->mmu_model & POWERPC_MMU_64)) {
- return;
- }
-
- /* Collect MMU info from kernel if not already */
- if (!has_smmu_info) {
- kvm_get_smmu_info(cpu, &smmu_info);
- has_smmu_info = true;
- }
-
- rampagesize = getrampagesize();
-
- /* Convert to QEMU form */
- memset(&env->sps, 0, sizeof(env->sps));
-
- /* If we have HV KVM, we need to forbid CI large pages if our
- * host page size is smaller than 64K.
- */
- if (smmu_info.flags & KVM_PPC_PAGE_SIZES_REAL) {
- env->ci_large_pages = getpagesize() >= 0x10000;
- }
-
- /*
- * XXX This loop should be an entry wide AND of the capabilities that
- * the selected CPU has with the capabilities that KVM supports.
- */
- for (ik = iq = 0; ik < KVM_PPC_PAGE_SIZES_MAX_SZ; ik++) {
- struct ppc_one_seg_page_size *qsps = &env->sps.sps[iq];
- struct kvm_ppc_one_seg_page_size *ksps = &smmu_info.sps[ik];
-
- if (!kvm_valid_page_size(smmu_info.flags, rampagesize,
- ksps->page_shift)) {
- continue;
- }
- qsps->page_shift = ksps->page_shift;
- qsps->slb_enc = ksps->slb_enc;
- for (jk = jq = 0; jk < KVM_PPC_PAGE_SIZES_MAX_SZ; jk++) {
- if (!kvm_valid_page_size(smmu_info.flags, rampagesize,
- ksps->enc[jk].page_shift)) {
- continue;
- }
- if (ksps->enc[jk].page_shift == 16) {
- has_64k_pages = true;
- }
- qsps->enc[jq].page_shift = ksps->enc[jk].page_shift;
- qsps->enc[jq].pte_enc = ksps->enc[jk].pte_enc;
- if (++jq >= PPC_PAGE_SIZES_MAX_SZ) {
- break;
- }
- }
- if (++iq >= PPC_PAGE_SIZES_MAX_SZ) {
- break;
- }
- }
- env->slb_nr = smmu_info.slb_size;
- if (!(smmu_info.flags & KVM_PPC_1T_SEGMENTS)) {
- env->mmu_model &= ~POWERPC_MMU_1TSEG;
- }
- if (!has_64k_pages) {
- env->mmu_model &= ~POWERPC_MMU_64K;
- }
-}
-#else /* defined (TARGET_PPC64) */
-
-static inline void kvm_fixup_page_sizes(PowerPCCPU *cpu)
-{
-}
-
-#endif /* !defined (TARGET_PPC64) */
-
-unsigned long kvm_arch_vcpu_id(CPUState *cpu)
-{
- return ppc_get_vcpu_dt_id(POWERPC_CPU(cpu));
-}
-
-/* e500 supports 2 h/w breakpoint and 2 watchpoint.
- * book3s supports only 1 watchpoint, so array size
- * of 4 is sufficient for now.
- */
-#define MAX_HW_BKPTS 4
-
-static struct HWBreakpoint {
- target_ulong addr;
- int type;
-} hw_debug_points[MAX_HW_BKPTS];
-
-static CPUWatchpoint hw_watchpoint;
-
-/* Default there is no breakpoint and watchpoint supported */
-static int max_hw_breakpoint;
-static int max_hw_watchpoint;
-static int nb_hw_breakpoint;
-static int nb_hw_watchpoint;
-
-static void kvmppc_hw_debug_points_init(CPUPPCState *cenv)
-{
- if (cenv->excp_model == POWERPC_EXCP_BOOKE) {
- max_hw_breakpoint = 2;
- max_hw_watchpoint = 2;
- }
-
- if ((max_hw_breakpoint + max_hw_watchpoint) > MAX_HW_BKPTS) {
- fprintf(stderr, "Error initializing h/w breakpoints\n");
- return;
- }
-}
-
-int kvm_arch_init_vcpu(CPUState *cs)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *cenv = &cpu->env;
- int ret;
-
- /* Gather server mmu info from KVM and update the CPU state */
- kvm_fixup_page_sizes(cpu);
-
- /* Synchronize sregs with kvm */
- ret = kvm_arch_sync_sregs(cpu);
- if (ret) {
- if (ret == -EINVAL) {
- error_report("Register sync failed... If you're using kvm-hv.ko,"
- " only \"-cpu host\" is possible");
- }
- return ret;
- }
-
- idle_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, kvm_kick_cpu, cpu);
-
- switch (cenv->mmu_model) {
- case POWERPC_MMU_BOOKE206:
- /* This target supports access to KVM's guest TLB */
- ret = kvm_booke206_tlb_init(cpu);
- break;
- case POWERPC_MMU_2_07:
- if (!cap_htm && !kvmppc_is_pr(cs->kvm_state)) {
- /* KVM-HV has transactional memory on POWER8 also without the
- * KVM_CAP_PPC_HTM extension, so enable it here instead. */
- cap_htm = true;
- }
- break;
- default:
- break;
- }
-
- kvm_get_one_reg(cs, KVM_REG_PPC_DEBUG_INST, &debug_inst_opcode);
- kvmppc_hw_debug_points_init(cenv);
-
- return ret;
-}
-
-static void kvm_sw_tlb_put(PowerPCCPU *cpu)
-{
- CPUPPCState *env = &cpu->env;
- CPUState *cs = CPU(cpu);
- struct kvm_dirty_tlb dirty_tlb;
- unsigned char *bitmap;
- int ret;
-
- if (!env->kvm_sw_tlb) {
- return;
- }
-
- bitmap = g_malloc((env->nb_tlb + 7) / 8);
- memset(bitmap, 0xFF, (env->nb_tlb + 7) / 8);
-
- dirty_tlb.bitmap = (uintptr_t)bitmap;
- dirty_tlb.num_dirty = env->nb_tlb;
-
- ret = kvm_vcpu_ioctl(cs, KVM_DIRTY_TLB, &dirty_tlb);
- if (ret) {
- fprintf(stderr, "%s: KVM_DIRTY_TLB: %s\n",
- __func__, strerror(-ret));
- }
-
- g_free(bitmap);
-}
-
-static void kvm_get_one_spr(CPUState *cs, uint64_t id, int spr)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- union {
- uint32_t u32;
- uint64_t u64;
- } val;
- struct kvm_one_reg reg = {
- .id = id,
- .addr = (uintptr_t) &val,
- };
- int ret;
-
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
- if (ret != 0) {
- trace_kvm_failed_spr_get(spr, strerror(errno));
- } else {
- switch (id & KVM_REG_SIZE_MASK) {
- case KVM_REG_SIZE_U32:
- env->spr[spr] = val.u32;
- break;
-
- case KVM_REG_SIZE_U64:
- env->spr[spr] = val.u64;
- break;
-
- default:
- /* Don't handle this size yet */
- abort();
- }
- }
-}
-
-static void kvm_put_one_spr(CPUState *cs, uint64_t id, int spr)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- union {
- uint32_t u32;
- uint64_t u64;
- } val;
- struct kvm_one_reg reg = {
- .id = id,
- .addr = (uintptr_t) &val,
- };
- int ret;
-
- switch (id & KVM_REG_SIZE_MASK) {
- case KVM_REG_SIZE_U32:
- val.u32 = env->spr[spr];
- break;
-
- case KVM_REG_SIZE_U64:
- val.u64 = env->spr[spr];
- break;
-
- default:
- /* Don't handle this size yet */
- abort();
- }
-
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
- if (ret != 0) {
- trace_kvm_failed_spr_set(spr, strerror(errno));
- }
-}
-
-static int kvm_put_fp(CPUState *cs)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- struct kvm_one_reg reg;
- int i;
- int ret;
-
- if (env->insns_flags & PPC_FLOAT) {
- uint64_t fpscr = env->fpscr;
- bool vsx = !!(env->insns_flags2 & PPC2_VSX);
-
- reg.id = KVM_REG_PPC_FPSCR;
- reg.addr = (uintptr_t)&fpscr;
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
- if (ret < 0) {
- DPRINTF("Unable to set FPSCR to KVM: %s\n", strerror(errno));
- return ret;
- }
-
- for (i = 0; i < 32; i++) {
- uint64_t vsr[2];
-
-#ifdef HOST_WORDS_BIGENDIAN
- vsr[0] = float64_val(env->fpr[i]);
- vsr[1] = env->vsr[i];
-#else
- vsr[0] = env->vsr[i];
- vsr[1] = float64_val(env->fpr[i]);
-#endif
- reg.addr = (uintptr_t) &vsr;
- reg.id = vsx ? KVM_REG_PPC_VSR(i) : KVM_REG_PPC_FPR(i);
-
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
- if (ret < 0) {
- DPRINTF("Unable to set %s%d to KVM: %s\n", vsx ? "VSR" : "FPR",
- i, strerror(errno));
- return ret;
- }
- }
- }
-
- if (env->insns_flags & PPC_ALTIVEC) {
- reg.id = KVM_REG_PPC_VSCR;
- reg.addr = (uintptr_t)&env->vscr;
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
- if (ret < 0) {
- DPRINTF("Unable to set VSCR to KVM: %s\n", strerror(errno));
- return ret;
- }
-
- for (i = 0; i < 32; i++) {
- reg.id = KVM_REG_PPC_VR(i);
- reg.addr = (uintptr_t)&env->avr[i];
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
- if (ret < 0) {
- DPRINTF("Unable to set VR%d to KVM: %s\n", i, strerror(errno));
- return ret;
- }
- }
- }
-
- return 0;
-}
-
-static int kvm_get_fp(CPUState *cs)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- struct kvm_one_reg reg;
- int i;
- int ret;
-
- if (env->insns_flags & PPC_FLOAT) {
- uint64_t fpscr;
- bool vsx = !!(env->insns_flags2 & PPC2_VSX);
-
- reg.id = KVM_REG_PPC_FPSCR;
- reg.addr = (uintptr_t)&fpscr;
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
- if (ret < 0) {
- DPRINTF("Unable to get FPSCR from KVM: %s\n", strerror(errno));
- return ret;
- } else {
- env->fpscr = fpscr;
- }
-
- for (i = 0; i < 32; i++) {
- uint64_t vsr[2];
-
- reg.addr = (uintptr_t) &vsr;
- reg.id = vsx ? KVM_REG_PPC_VSR(i) : KVM_REG_PPC_FPR(i);
-
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
- if (ret < 0) {
- DPRINTF("Unable to get %s%d from KVM: %s\n",
- vsx ? "VSR" : "FPR", i, strerror(errno));
- return ret;
- } else {
-#ifdef HOST_WORDS_BIGENDIAN
- env->fpr[i] = vsr[0];
- if (vsx) {
- env->vsr[i] = vsr[1];
- }
-#else
- env->fpr[i] = vsr[1];
- if (vsx) {
- env->vsr[i] = vsr[0];
- }
-#endif
- }
- }
- }
-
- if (env->insns_flags & PPC_ALTIVEC) {
- reg.id = KVM_REG_PPC_VSCR;
- reg.addr = (uintptr_t)&env->vscr;
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
- if (ret < 0) {
- DPRINTF("Unable to get VSCR from KVM: %s\n", strerror(errno));
- return ret;
- }
-
- for (i = 0; i < 32; i++) {
- reg.id = KVM_REG_PPC_VR(i);
- reg.addr = (uintptr_t)&env->avr[i];
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
- if (ret < 0) {
- DPRINTF("Unable to get VR%d from KVM: %s\n",
- i, strerror(errno));
- return ret;
- }
- }
- }
-
- return 0;
-}
-
-#if defined(TARGET_PPC64)
-static int kvm_get_vpa(CPUState *cs)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- struct kvm_one_reg reg;
- int ret;
-
- reg.id = KVM_REG_PPC_VPA_ADDR;
- reg.addr = (uintptr_t)&env->vpa_addr;
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
- if (ret < 0) {
- DPRINTF("Unable to get VPA address from KVM: %s\n", strerror(errno));
- return ret;
- }
-
- assert((uintptr_t)&env->slb_shadow_size
- == ((uintptr_t)&env->slb_shadow_addr + 8));
- reg.id = KVM_REG_PPC_VPA_SLB;
- reg.addr = (uintptr_t)&env->slb_shadow_addr;
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
- if (ret < 0) {
- DPRINTF("Unable to get SLB shadow state from KVM: %s\n",
- strerror(errno));
- return ret;
- }
-
- assert((uintptr_t)&env->dtl_size == ((uintptr_t)&env->dtl_addr + 8));
- reg.id = KVM_REG_PPC_VPA_DTL;
- reg.addr = (uintptr_t)&env->dtl_addr;
- ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
- if (ret < 0) {
- DPRINTF("Unable to get dispatch trace log state from KVM: %s\n",
- strerror(errno));
- return ret;
- }
-
- return 0;
-}
-
-static int kvm_put_vpa(CPUState *cs)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- struct kvm_one_reg reg;
- int ret;
-
- /* SLB shadow or DTL can't be registered unless a master VPA is
- * registered. That means when restoring state, if a VPA *is*
- * registered, we need to set that up first. If not, we need to
- * deregister the others before deregistering the master VPA */
- assert(env->vpa_addr || !(env->slb_shadow_addr || env->dtl_addr));
-
- if (env->vpa_addr) {
- reg.id = KVM_REG_PPC_VPA_ADDR;
- reg.addr = (uintptr_t)&env->vpa_addr;
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
- if (ret < 0) {
- DPRINTF("Unable to set VPA address to KVM: %s\n", strerror(errno));
- return ret;
- }
- }
-
- assert((uintptr_t)&env->slb_shadow_size
- == ((uintptr_t)&env->slb_shadow_addr + 8));
- reg.id = KVM_REG_PPC_VPA_SLB;
- reg.addr = (uintptr_t)&env->slb_shadow_addr;
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
- if (ret < 0) {
- DPRINTF("Unable to set SLB shadow state to KVM: %s\n", strerror(errno));
- return ret;
- }
-
- assert((uintptr_t)&env->dtl_size == ((uintptr_t)&env->dtl_addr + 8));
- reg.id = KVM_REG_PPC_VPA_DTL;
- reg.addr = (uintptr_t)&env->dtl_addr;
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
- if (ret < 0) {
- DPRINTF("Unable to set dispatch trace log state to KVM: %s\n",
- strerror(errno));
- return ret;
- }
-
- if (!env->vpa_addr) {
- reg.id = KVM_REG_PPC_VPA_ADDR;
- reg.addr = (uintptr_t)&env->vpa_addr;
- ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
- if (ret < 0) {
- DPRINTF("Unable to set VPA address to KVM: %s\n", strerror(errno));
- return ret;
- }
- }
-
- return 0;
-}
-#endif /* TARGET_PPC64 */
-
-int kvmppc_put_books_sregs(PowerPCCPU *cpu)
-{
- CPUPPCState *env = &cpu->env;
- struct kvm_sregs sregs;
- int i;
-
- sregs.pvr = env->spr[SPR_PVR];
-
- sregs.u.s.sdr1 = env->spr[SPR_SDR1];
-
- /* Sync SLB */
-#ifdef TARGET_PPC64
- for (i = 0; i < ARRAY_SIZE(env->slb); i++) {
- sregs.u.s.ppc64.slb[i].slbe = env->slb[i].esid;
- if (env->slb[i].esid & SLB_ESID_V) {
- sregs.u.s.ppc64.slb[i].slbe |= i;
- }
- sregs.u.s.ppc64.slb[i].slbv = env->slb[i].vsid;
- }
-#endif
-
- /* Sync SRs */
- for (i = 0; i < 16; i++) {
- sregs.u.s.ppc32.sr[i] = env->sr[i];
- }
-
- /* Sync BATs */
- for (i = 0; i < 8; i++) {
- /* Beware. We have to swap upper and lower bits here */
- sregs.u.s.ppc32.dbat[i] = ((uint64_t)env->DBAT[0][i] << 32)
- | env->DBAT[1][i];
- sregs.u.s.ppc32.ibat[i] = ((uint64_t)env->IBAT[0][i] << 32)
- | env->IBAT[1][i];
- }
-
- return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_SREGS, &sregs);
-}
-
-int kvm_arch_put_registers(CPUState *cs, int level)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- struct kvm_regs regs;
- int ret;
- int i;
-
- ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &regs);
- if (ret < 0) {
- return ret;
- }
-
- regs.ctr = env->ctr;
- regs.lr = env->lr;
- regs.xer = cpu_read_xer(env);
- regs.msr = env->msr;
- regs.pc = env->nip;
-
- regs.srr0 = env->spr[SPR_SRR0];
- regs.srr1 = env->spr[SPR_SRR1];
-
- regs.sprg0 = env->spr[SPR_SPRG0];
- regs.sprg1 = env->spr[SPR_SPRG1];
- regs.sprg2 = env->spr[SPR_SPRG2];
- regs.sprg3 = env->spr[SPR_SPRG3];
- regs.sprg4 = env->spr[SPR_SPRG4];
- regs.sprg5 = env->spr[SPR_SPRG5];
- regs.sprg6 = env->spr[SPR_SPRG6];
- regs.sprg7 = env->spr[SPR_SPRG7];
-
- regs.pid = env->spr[SPR_BOOKE_PID];
-
- for (i = 0;i < 32; i++)
- regs.gpr[i] = env->gpr[i];
-
- regs.cr = 0;
- for (i = 0; i < 8; i++) {
- regs.cr |= (env->crf[i] & 15) << (4 * (7 - i));
- }
-
- ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, &regs);
- if (ret < 0)
- return ret;
-
- kvm_put_fp(cs);
-
- if (env->tlb_dirty) {
- kvm_sw_tlb_put(cpu);
- env->tlb_dirty = false;
- }
-
- if (cap_segstate && (level >= KVM_PUT_RESET_STATE)) {
- ret = kvmppc_put_books_sregs(cpu);
- if (ret < 0) {
- return ret;
- }
- }
-
- if (cap_hior && (level >= KVM_PUT_RESET_STATE)) {
- kvm_put_one_spr(cs, KVM_REG_PPC_HIOR, SPR_HIOR);
- }
-
- if (cap_one_reg) {
- int i;
-
- /* We deliberately ignore errors here, for kernels which have
- * the ONE_REG calls, but don't support the specific
- * registers, there's a reasonable chance things will still
- * work, at least until we try to migrate. */
- for (i = 0; i < 1024; i++) {
- uint64_t id = env->spr_cb[i].one_reg_id;
-
- if (id != 0) {
- kvm_put_one_spr(cs, id, i);
- }
- }
-
-#ifdef TARGET_PPC64
- if (msr_ts) {
- for (i = 0; i < ARRAY_SIZE(env->tm_gpr); i++) {
- kvm_set_one_reg(cs, KVM_REG_PPC_TM_GPR(i), &env->tm_gpr[i]);
- }
- for (i = 0; i < ARRAY_SIZE(env->tm_vsr); i++) {
- kvm_set_one_reg(cs, KVM_REG_PPC_TM_VSR(i), &env->tm_vsr[i]);
- }
- kvm_set_one_reg(cs, KVM_REG_PPC_TM_CR, &env->tm_cr);
- kvm_set_one_reg(cs, KVM_REG_PPC_TM_LR, &env->tm_lr);
- kvm_set_one_reg(cs, KVM_REG_PPC_TM_CTR, &env->tm_ctr);
- kvm_set_one_reg(cs, KVM_REG_PPC_TM_FPSCR, &env->tm_fpscr);
- kvm_set_one_reg(cs, KVM_REG_PPC_TM_AMR, &env->tm_amr);
- kvm_set_one_reg(cs, KVM_REG_PPC_TM_PPR, &env->tm_ppr);
- kvm_set_one_reg(cs, KVM_REG_PPC_TM_VRSAVE, &env->tm_vrsave);
- kvm_set_one_reg(cs, KVM_REG_PPC_TM_VSCR, &env->tm_vscr);
- kvm_set_one_reg(cs, KVM_REG_PPC_TM_DSCR, &env->tm_dscr);
- kvm_set_one_reg(cs, KVM_REG_PPC_TM_TAR, &env->tm_tar);
- }
-
- if (cap_papr) {
- if (kvm_put_vpa(cs) < 0) {
- DPRINTF("Warning: Unable to set VPA information to KVM\n");
- }
- }
-
- kvm_set_one_reg(cs, KVM_REG_PPC_TB_OFFSET, &env->tb_env->tb_offset);
-#endif /* TARGET_PPC64 */
- }
-
- return ret;
-}
-
-static void kvm_sync_excp(CPUPPCState *env, int vector, int ivor)
-{
- env->excp_vectors[vector] = env->spr[ivor] + env->spr[SPR_BOOKE_IVPR];
-}
-
-static int kvmppc_get_booke_sregs(PowerPCCPU *cpu)
-{
- CPUPPCState *env = &cpu->env;
- struct kvm_sregs sregs;
- int ret;
-
- ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_SREGS, &sregs);
- if (ret < 0) {
- return ret;
- }
-
- if (sregs.u.e.features & KVM_SREGS_E_BASE) {
- env->spr[SPR_BOOKE_CSRR0] = sregs.u.e.csrr0;
- env->spr[SPR_BOOKE_CSRR1] = sregs.u.e.csrr1;
- env->spr[SPR_BOOKE_ESR] = sregs.u.e.esr;
- env->spr[SPR_BOOKE_DEAR] = sregs.u.e.dear;
- env->spr[SPR_BOOKE_MCSR] = sregs.u.e.mcsr;
- env->spr[SPR_BOOKE_TSR] = sregs.u.e.tsr;
- env->spr[SPR_BOOKE_TCR] = sregs.u.e.tcr;
- env->spr[SPR_DECR] = sregs.u.e.dec;
- env->spr[SPR_TBL] = sregs.u.e.tb & 0xffffffff;
- env->spr[SPR_TBU] = sregs.u.e.tb >> 32;
- env->spr[SPR_VRSAVE] = sregs.u.e.vrsave;
- }
-
- if (sregs.u.e.features & KVM_SREGS_E_ARCH206) {
- env->spr[SPR_BOOKE_PIR] = sregs.u.e.pir;
- env->spr[SPR_BOOKE_MCSRR0] = sregs.u.e.mcsrr0;
- env->spr[SPR_BOOKE_MCSRR1] = sregs.u.e.mcsrr1;
- env->spr[SPR_BOOKE_DECAR] = sregs.u.e.decar;
- env->spr[SPR_BOOKE_IVPR] = sregs.u.e.ivpr;
- }
-
- if (sregs.u.e.features & KVM_SREGS_E_64) {
- env->spr[SPR_BOOKE_EPCR] = sregs.u.e.epcr;
- }
-
- if (sregs.u.e.features & KVM_SREGS_E_SPRG8) {
- env->spr[SPR_BOOKE_SPRG8] = sregs.u.e.sprg8;
- }
-
- if (sregs.u.e.features & KVM_SREGS_E_IVOR) {
- env->spr[SPR_BOOKE_IVOR0] = sregs.u.e.ivor_low[0];
- kvm_sync_excp(env, POWERPC_EXCP_CRITICAL, SPR_BOOKE_IVOR0);
- env->spr[SPR_BOOKE_IVOR1] = sregs.u.e.ivor_low[1];
- kvm_sync_excp(env, POWERPC_EXCP_MCHECK, SPR_BOOKE_IVOR1);
- env->spr[SPR_BOOKE_IVOR2] = sregs.u.e.ivor_low[2];
- kvm_sync_excp(env, POWERPC_EXCP_DSI, SPR_BOOKE_IVOR2);
- env->spr[SPR_BOOKE_IVOR3] = sregs.u.e.ivor_low[3];
- kvm_sync_excp(env, POWERPC_EXCP_ISI, SPR_BOOKE_IVOR3);
- env->spr[SPR_BOOKE_IVOR4] = sregs.u.e.ivor_low[4];
- kvm_sync_excp(env, POWERPC_EXCP_EXTERNAL, SPR_BOOKE_IVOR4);
- env->spr[SPR_BOOKE_IVOR5] = sregs.u.e.ivor_low[5];
- kvm_sync_excp(env, POWERPC_EXCP_ALIGN, SPR_BOOKE_IVOR5);
- env->spr[SPR_BOOKE_IVOR6] = sregs.u.e.ivor_low[6];
- kvm_sync_excp(env, POWERPC_EXCP_PROGRAM, SPR_BOOKE_IVOR6);
- env->spr[SPR_BOOKE_IVOR7] = sregs.u.e.ivor_low[7];
- kvm_sync_excp(env, POWERPC_EXCP_FPU, SPR_BOOKE_IVOR7);
- env->spr[SPR_BOOKE_IVOR8] = sregs.u.e.ivor_low[8];
- kvm_sync_excp(env, POWERPC_EXCP_SYSCALL, SPR_BOOKE_IVOR8);
- env->spr[SPR_BOOKE_IVOR9] = sregs.u.e.ivor_low[9];
- kvm_sync_excp(env, POWERPC_EXCP_APU, SPR_BOOKE_IVOR9);
- env->spr[SPR_BOOKE_IVOR10] = sregs.u.e.ivor_low[10];
- kvm_sync_excp(env, POWERPC_EXCP_DECR, SPR_BOOKE_IVOR10);
- env->spr[SPR_BOOKE_IVOR11] = sregs.u.e.ivor_low[11];
- kvm_sync_excp(env, POWERPC_EXCP_FIT, SPR_BOOKE_IVOR11);
- env->spr[SPR_BOOKE_IVOR12] = sregs.u.e.ivor_low[12];
- kvm_sync_excp(env, POWERPC_EXCP_WDT, SPR_BOOKE_IVOR12);
- env->spr[SPR_BOOKE_IVOR13] = sregs.u.e.ivor_low[13];
- kvm_sync_excp(env, POWERPC_EXCP_DTLB, SPR_BOOKE_IVOR13);
- env->spr[SPR_BOOKE_IVOR14] = sregs.u.e.ivor_low[14];
- kvm_sync_excp(env, POWERPC_EXCP_ITLB, SPR_BOOKE_IVOR14);
- env->spr[SPR_BOOKE_IVOR15] = sregs.u.e.ivor_low[15];
- kvm_sync_excp(env, POWERPC_EXCP_DEBUG, SPR_BOOKE_IVOR15);
-
- if (sregs.u.e.features & KVM_SREGS_E_SPE) {
- env->spr[SPR_BOOKE_IVOR32] = sregs.u.e.ivor_high[0];
- kvm_sync_excp(env, POWERPC_EXCP_SPEU, SPR_BOOKE_IVOR32);
- env->spr[SPR_BOOKE_IVOR33] = sregs.u.e.ivor_high[1];
- kvm_sync_excp(env, POWERPC_EXCP_EFPDI, SPR_BOOKE_IVOR33);
- env->spr[SPR_BOOKE_IVOR34] = sregs.u.e.ivor_high[2];
- kvm_sync_excp(env, POWERPC_EXCP_EFPRI, SPR_BOOKE_IVOR34);
- }
-
- if (sregs.u.e.features & KVM_SREGS_E_PM) {
- env->spr[SPR_BOOKE_IVOR35] = sregs.u.e.ivor_high[3];
- kvm_sync_excp(env, POWERPC_EXCP_EPERFM, SPR_BOOKE_IVOR35);
- }
-
- if (sregs.u.e.features & KVM_SREGS_E_PC) {
- env->spr[SPR_BOOKE_IVOR36] = sregs.u.e.ivor_high[4];
- kvm_sync_excp(env, POWERPC_EXCP_DOORI, SPR_BOOKE_IVOR36);
- env->spr[SPR_BOOKE_IVOR37] = sregs.u.e.ivor_high[5];
- kvm_sync_excp(env, POWERPC_EXCP_DOORCI, SPR_BOOKE_IVOR37);
- }
- }
-
- if (sregs.u.e.features & KVM_SREGS_E_ARCH206_MMU) {
- env->spr[SPR_BOOKE_MAS0] = sregs.u.e.mas0;
- env->spr[SPR_BOOKE_MAS1] = sregs.u.e.mas1;
- env->spr[SPR_BOOKE_MAS2] = sregs.u.e.mas2;
- env->spr[SPR_BOOKE_MAS3] = sregs.u.e.mas7_3 & 0xffffffff;
- env->spr[SPR_BOOKE_MAS4] = sregs.u.e.mas4;
- env->spr[SPR_BOOKE_MAS6] = sregs.u.e.mas6;
- env->spr[SPR_BOOKE_MAS7] = sregs.u.e.mas7_3 >> 32;
- env->spr[SPR_MMUCFG] = sregs.u.e.mmucfg;
- env->spr[SPR_BOOKE_TLB0CFG] = sregs.u.e.tlbcfg[0];
- env->spr[SPR_BOOKE_TLB1CFG] = sregs.u.e.tlbcfg[1];
- }
-
- if (sregs.u.e.features & KVM_SREGS_EXP) {
- env->spr[SPR_BOOKE_EPR] = sregs.u.e.epr;
- }
-
- if (sregs.u.e.features & KVM_SREGS_E_PD) {
- env->spr[SPR_BOOKE_EPLC] = sregs.u.e.eplc;
- env->spr[SPR_BOOKE_EPSC] = sregs.u.e.epsc;
- }
-
- if (sregs.u.e.impl_id == KVM_SREGS_E_IMPL_FSL) {
- env->spr[SPR_E500_SVR] = sregs.u.e.impl.fsl.svr;
- env->spr[SPR_Exxx_MCAR] = sregs.u.e.impl.fsl.mcar;
- env->spr[SPR_HID0] = sregs.u.e.impl.fsl.hid0;
-
- if (sregs.u.e.impl.fsl.features & KVM_SREGS_E_FSL_PIDn) {
- env->spr[SPR_BOOKE_PID1] = sregs.u.e.impl.fsl.pid1;
- env->spr[SPR_BOOKE_PID2] = sregs.u.e.impl.fsl.pid2;
- }
- }
-
- return 0;
-}
-
-static int kvmppc_get_books_sregs(PowerPCCPU *cpu)
-{
- CPUPPCState *env = &cpu->env;
- struct kvm_sregs sregs;
- int ret;
- int i;
-
- ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_SREGS, &sregs);
- if (ret < 0) {
- return ret;
- }
-
- if (!env->external_htab) {
- ppc_store_sdr1(env, sregs.u.s.sdr1);
- }
-
- /* Sync SLB */
-#ifdef TARGET_PPC64
- /*
- * The packed SLB array we get from KVM_GET_SREGS only contains
- * information about valid entries. So we flush our internal copy
- * to get rid of stale ones, then put all valid SLB entries back
- * in.
- */
- memset(env->slb, 0, sizeof(env->slb));
- for (i = 0; i < ARRAY_SIZE(env->slb); i++) {
- target_ulong rb = sregs.u.s.ppc64.slb[i].slbe;
- target_ulong rs = sregs.u.s.ppc64.slb[i].slbv;
- /*
- * Only restore valid entries
- */
- if (rb & SLB_ESID_V) {
- ppc_store_slb(cpu, rb & 0xfff, rb & ~0xfffULL, rs);
- }
- }
-#endif
-
- /* Sync SRs */
- for (i = 0; i < 16; i++) {
- env->sr[i] = sregs.u.s.ppc32.sr[i];
- }
-
- /* Sync BATs */
- for (i = 0; i < 8; i++) {
- env->DBAT[0][i] = sregs.u.s.ppc32.dbat[i] & 0xffffffff;
- env->DBAT[1][i] = sregs.u.s.ppc32.dbat[i] >> 32;
- env->IBAT[0][i] = sregs.u.s.ppc32.ibat[i] & 0xffffffff;
- env->IBAT[1][i] = sregs.u.s.ppc32.ibat[i] >> 32;
- }
-
- return 0;
-}
-
-int kvm_arch_get_registers(CPUState *cs)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- struct kvm_regs regs;
- uint32_t cr;
- int i, ret;
-
- ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &regs);
- if (ret < 0)
- return ret;
-
- cr = regs.cr;
- for (i = 7; i >= 0; i--) {
- env->crf[i] = cr & 15;
- cr >>= 4;
- }
-
- env->ctr = regs.ctr;
- env->lr = regs.lr;
- cpu_write_xer(env, regs.xer);
- env->msr = regs.msr;
- env->nip = regs.pc;
-
- env->spr[SPR_SRR0] = regs.srr0;
- env->spr[SPR_SRR1] = regs.srr1;
-
- env->spr[SPR_SPRG0] = regs.sprg0;
- env->spr[SPR_SPRG1] = regs.sprg1;
- env->spr[SPR_SPRG2] = regs.sprg2;
- env->spr[SPR_SPRG3] = regs.sprg3;
- env->spr[SPR_SPRG4] = regs.sprg4;
- env->spr[SPR_SPRG5] = regs.sprg5;
- env->spr[SPR_SPRG6] = regs.sprg6;
- env->spr[SPR_SPRG7] = regs.sprg7;
-
- env->spr[SPR_BOOKE_PID] = regs.pid;
-
- for (i = 0;i < 32; i++)
- env->gpr[i] = regs.gpr[i];
-
- kvm_get_fp(cs);
-
- if (cap_booke_sregs) {
- ret = kvmppc_get_booke_sregs(cpu);
- if (ret < 0) {
- return ret;
- }
- }
-
- if (cap_segstate) {
- ret = kvmppc_get_books_sregs(cpu);
- if (ret < 0) {
- return ret;
- }
- }
-
- if (cap_hior) {
- kvm_get_one_spr(cs, KVM_REG_PPC_HIOR, SPR_HIOR);
- }
-
- if (cap_one_reg) {
- int i;
-
- /* We deliberately ignore errors here, for kernels which have
- * the ONE_REG calls, but don't support the specific
- * registers, there's a reasonable chance things will still
- * work, at least until we try to migrate. */
- for (i = 0; i < 1024; i++) {
- uint64_t id = env->spr_cb[i].one_reg_id;
-
- if (id != 0) {
- kvm_get_one_spr(cs, id, i);
- }
- }
-
-#ifdef TARGET_PPC64
- if (msr_ts) {
- for (i = 0; i < ARRAY_SIZE(env->tm_gpr); i++) {
- kvm_get_one_reg(cs, KVM_REG_PPC_TM_GPR(i), &env->tm_gpr[i]);
- }
- for (i = 0; i < ARRAY_SIZE(env->tm_vsr); i++) {
- kvm_get_one_reg(cs, KVM_REG_PPC_TM_VSR(i), &env->tm_vsr[i]);
- }
- kvm_get_one_reg(cs, KVM_REG_PPC_TM_CR, &env->tm_cr);
- kvm_get_one_reg(cs, KVM_REG_PPC_TM_LR, &env->tm_lr);
- kvm_get_one_reg(cs, KVM_REG_PPC_TM_CTR, &env->tm_ctr);
- kvm_get_one_reg(cs, KVM_REG_PPC_TM_FPSCR, &env->tm_fpscr);
- kvm_get_one_reg(cs, KVM_REG_PPC_TM_AMR, &env->tm_amr);
- kvm_get_one_reg(cs, KVM_REG_PPC_TM_PPR, &env->tm_ppr);
- kvm_get_one_reg(cs, KVM_REG_PPC_TM_VRSAVE, &env->tm_vrsave);
- kvm_get_one_reg(cs, KVM_REG_PPC_TM_VSCR, &env->tm_vscr);
- kvm_get_one_reg(cs, KVM_REG_PPC_TM_DSCR, &env->tm_dscr);
- kvm_get_one_reg(cs, KVM_REG_PPC_TM_TAR, &env->tm_tar);
- }
-
- if (cap_papr) {
- if (kvm_get_vpa(cs) < 0) {
- DPRINTF("Warning: Unable to get VPA information from KVM\n");
- }
- }
-
- kvm_get_one_reg(cs, KVM_REG_PPC_TB_OFFSET, &env->tb_env->tb_offset);
-#endif
- }
-
- return 0;
-}
-
-int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level)
-{
- unsigned virq = level ? KVM_INTERRUPT_SET_LEVEL : KVM_INTERRUPT_UNSET;
-
- if (irq != PPC_INTERRUPT_EXT) {
- return 0;
- }
-
- if (!kvm_enabled() || !cap_interrupt_unset || !cap_interrupt_level) {
- return 0;
- }
-
- kvm_vcpu_ioctl(CPU(cpu), KVM_INTERRUPT, &virq);
-
- return 0;
-}
-
-#if defined(TARGET_PPCEMB)
-#define PPC_INPUT_INT PPC40x_INPUT_INT
-#elif defined(TARGET_PPC64)
-#define PPC_INPUT_INT PPC970_INPUT_INT
-#else
-#define PPC_INPUT_INT PPC6xx_INPUT_INT
-#endif
-
-void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- int r;
- unsigned irq;
-
- qemu_mutex_lock_iothread();
-
- /* PowerPC QEMU tracks the various core input pins (interrupt, critical
- * interrupt, reset, etc) in PPC-specific env->irq_input_state. */
- if (!cap_interrupt_level &&
- run->ready_for_interrupt_injection &&
- (cs->interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->irq_input_state & (1<<PPC_INPUT_INT)))
- {
- /* For now KVM disregards the 'irq' argument. However, in the
- * future KVM could cache it in-kernel to avoid a heavyweight exit
- * when reading the UIC.
- */
- irq = KVM_INTERRUPT_SET;
-
- DPRINTF("injected interrupt %d\n", irq);
- r = kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &irq);
- if (r < 0) {
- printf("cpu %d fail inject %x\n", cs->cpu_index, irq);
- }
-
- /* Always wake up soon in case the interrupt was level based */
- timer_mod(idle_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- (NANOSECONDS_PER_SECOND / 50));
- }
-
- /* We don't know if there are more interrupts pending after this. However,
- * the guest will return to userspace in the course of handling this one
- * anyways, so we will get a chance to deliver the rest. */
-
- qemu_mutex_unlock_iothread();
-}
-
-MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
-{
- return MEMTXATTRS_UNSPECIFIED;
-}
-
-int kvm_arch_process_async_events(CPUState *cs)
-{
- return cs->halted;
-}
-
-static int kvmppc_handle_halt(PowerPCCPU *cpu)
-{
- CPUState *cs = CPU(cpu);
- CPUPPCState *env = &cpu->env;
-
- if (!(cs->interrupt_request & CPU_INTERRUPT_HARD) && (msr_ee)) {
- cs->halted = 1;
- cs->exception_index = EXCP_HLT;
- }
-
- return 0;
-}
-
-/* map dcr access to existing qemu dcr emulation */
-static int kvmppc_handle_dcr_read(CPUPPCState *env, uint32_t dcrn, uint32_t *data)
-{
- if (ppc_dcr_read(env->dcr_env, dcrn, data) < 0)
- fprintf(stderr, "Read to unhandled DCR (0x%x)\n", dcrn);
-
- return 0;
-}
-
-static int kvmppc_handle_dcr_write(CPUPPCState *env, uint32_t dcrn, uint32_t data)
-{
- if (ppc_dcr_write(env->dcr_env, dcrn, data) < 0)
- fprintf(stderr, "Write to unhandled DCR (0x%x)\n", dcrn);
-
- return 0;
-}
-
-int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
-{
- /* Mixed endian case is not handled */
- uint32_t sc = debug_inst_opcode;
-
- if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn,
- sizeof(sc), 0) ||
- cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&sc, sizeof(sc), 1)) {
- return -EINVAL;
- }
-
- return 0;
-}
-
-int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
-{
- uint32_t sc;
-
- if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&sc, sizeof(sc), 0) ||
- sc != debug_inst_opcode ||
- cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn,
- sizeof(sc), 1)) {
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int find_hw_breakpoint(target_ulong addr, int type)
-{
- int n;
-
- assert((nb_hw_breakpoint + nb_hw_watchpoint)
- <= ARRAY_SIZE(hw_debug_points));
-
- for (n = 0; n < nb_hw_breakpoint + nb_hw_watchpoint; n++) {
- if (hw_debug_points[n].addr == addr &&
- hw_debug_points[n].type == type) {
- return n;
- }
- }
-
- return -1;
-}
-
-static int find_hw_watchpoint(target_ulong addr, int *flag)
-{
- int n;
-
- n = find_hw_breakpoint(addr, GDB_WATCHPOINT_ACCESS);
- if (n >= 0) {
- *flag = BP_MEM_ACCESS;
- return n;
- }
-
- n = find_hw_breakpoint(addr, GDB_WATCHPOINT_WRITE);
- if (n >= 0) {
- *flag = BP_MEM_WRITE;
- return n;
- }
-
- n = find_hw_breakpoint(addr, GDB_WATCHPOINT_READ);
- if (n >= 0) {
- *flag = BP_MEM_READ;
- return n;
- }
-
- return -1;
-}
-
-int kvm_arch_insert_hw_breakpoint(target_ulong addr,
- target_ulong len, int type)
-{
- if ((nb_hw_breakpoint + nb_hw_watchpoint) >= ARRAY_SIZE(hw_debug_points)) {
- return -ENOBUFS;
- }
-
- hw_debug_points[nb_hw_breakpoint + nb_hw_watchpoint].addr = addr;
- hw_debug_points[nb_hw_breakpoint + nb_hw_watchpoint].type = type;
-
- switch (type) {
- case GDB_BREAKPOINT_HW:
- if (nb_hw_breakpoint >= max_hw_breakpoint) {
- return -ENOBUFS;
- }
-
- if (find_hw_breakpoint(addr, type) >= 0) {
- return -EEXIST;
- }
-
- nb_hw_breakpoint++;
- break;
-
- case GDB_WATCHPOINT_WRITE:
- case GDB_WATCHPOINT_READ:
- case GDB_WATCHPOINT_ACCESS:
- if (nb_hw_watchpoint >= max_hw_watchpoint) {
- return -ENOBUFS;
- }
-
- if (find_hw_breakpoint(addr, type) >= 0) {
- return -EEXIST;
- }
-
- nb_hw_watchpoint++;
- break;
-
- default:
- return -ENOSYS;
- }
-
- return 0;
-}
-
-int kvm_arch_remove_hw_breakpoint(target_ulong addr,
- target_ulong len, int type)
-{
- int n;
-
- n = find_hw_breakpoint(addr, type);
- if (n < 0) {
- return -ENOENT;
- }
-
- switch (type) {
- case GDB_BREAKPOINT_HW:
- nb_hw_breakpoint--;
- break;
-
- case GDB_WATCHPOINT_WRITE:
- case GDB_WATCHPOINT_READ:
- case GDB_WATCHPOINT_ACCESS:
- nb_hw_watchpoint--;
- break;
-
- default:
- return -ENOSYS;
- }
- hw_debug_points[n] = hw_debug_points[nb_hw_breakpoint + nb_hw_watchpoint];
-
- return 0;
-}
-
-void kvm_arch_remove_all_hw_breakpoints(void)
-{
- nb_hw_breakpoint = nb_hw_watchpoint = 0;
-}
-
-void kvm_arch_update_guest_debug(CPUState *cs, struct kvm_guest_debug *dbg)
-{
- int n;
-
- /* Software Breakpoint updates */
- if (kvm_sw_breakpoints_active(cs)) {
- dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP;
- }
-
- assert((nb_hw_breakpoint + nb_hw_watchpoint)
- <= ARRAY_SIZE(hw_debug_points));
- assert((nb_hw_breakpoint + nb_hw_watchpoint) <= ARRAY_SIZE(dbg->arch.bp));
-
- if (nb_hw_breakpoint + nb_hw_watchpoint > 0) {
- dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP;
- memset(dbg->arch.bp, 0, sizeof(dbg->arch.bp));
- for (n = 0; n < nb_hw_breakpoint + nb_hw_watchpoint; n++) {
- switch (hw_debug_points[n].type) {
- case GDB_BREAKPOINT_HW:
- dbg->arch.bp[n].type = KVMPPC_DEBUG_BREAKPOINT;
- break;
- case GDB_WATCHPOINT_WRITE:
- dbg->arch.bp[n].type = KVMPPC_DEBUG_WATCH_WRITE;
- break;
- case GDB_WATCHPOINT_READ:
- dbg->arch.bp[n].type = KVMPPC_DEBUG_WATCH_READ;
- break;
- case GDB_WATCHPOINT_ACCESS:
- dbg->arch.bp[n].type = KVMPPC_DEBUG_WATCH_WRITE |
- KVMPPC_DEBUG_WATCH_READ;
- break;
- default:
- cpu_abort(cs, "Unsupported breakpoint type\n");
- }
- dbg->arch.bp[n].addr = hw_debug_points[n].addr;
- }
- }
-}
-
-static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run)
-{
- CPUState *cs = CPU(cpu);
- CPUPPCState *env = &cpu->env;
- struct kvm_debug_exit_arch *arch_info = &run->debug.arch;
- int handle = 0;
- int n;
- int flag = 0;
-
- if (cs->singlestep_enabled) {
- handle = 1;
- } else if (arch_info->status) {
- if (nb_hw_breakpoint + nb_hw_watchpoint > 0) {
- if (arch_info->status & KVMPPC_DEBUG_BREAKPOINT) {
- n = find_hw_breakpoint(arch_info->address, GDB_BREAKPOINT_HW);
- if (n >= 0) {
- handle = 1;
- }
- } else if (arch_info->status & (KVMPPC_DEBUG_WATCH_READ |
- KVMPPC_DEBUG_WATCH_WRITE)) {
- n = find_hw_watchpoint(arch_info->address, &flag);
- if (n >= 0) {
- handle = 1;
- cs->watchpoint_hit = &hw_watchpoint;
- hw_watchpoint.vaddr = hw_debug_points[n].addr;
- hw_watchpoint.flags = flag;
- }
- }
- }
- } else if (kvm_find_sw_breakpoint(cs, arch_info->address)) {
- handle = 1;
- } else {
- /* QEMU is not able to handle debug exception, so inject
- * program exception to guest;
- * Yes program exception NOT debug exception !!
- * When QEMU is using debug resources then debug exception must
- * be always set. To achieve this we set MSR_DE and also set
- * MSRP_DEP so guest cannot change MSR_DE.
- * When emulating debug resource for guest we want guest
- * to control MSR_DE (enable/disable debug interrupt on need).
- * Supporting both configurations are NOT possible.
- * So the result is that we cannot share debug resources
- * between QEMU and Guest on BOOKE architecture.
- * In the current design QEMU gets the priority over guest,
- * this means that if QEMU is using debug resources then guest
- * cannot use them;
- * For software breakpoint QEMU uses a privileged instruction;
- * So there cannot be any reason that we are here for guest
- * set debug exception, only possibility is guest executed a
- * privileged / illegal instruction and that's why we are
- * injecting a program interrupt.
- */
-
- cpu_synchronize_state(cs);
- /* env->nip is PC, so increment this by 4 to use
- * ppc_cpu_do_interrupt(), which set srr0 = env->nip - 4.
- */
- env->nip += 4;
- cs->exception_index = POWERPC_EXCP_PROGRAM;
- env->error_code = POWERPC_EXCP_INVAL;
- ppc_cpu_do_interrupt(cs);
- }
-
- return handle;
-}
-
-int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- int ret;
-
- qemu_mutex_lock_iothread();
-
- switch (run->exit_reason) {
- case KVM_EXIT_DCR:
- if (run->dcr.is_write) {
- DPRINTF("handle dcr write\n");
- ret = kvmppc_handle_dcr_write(env, run->dcr.dcrn, run->dcr.data);
- } else {
- DPRINTF("handle dcr read\n");
- ret = kvmppc_handle_dcr_read(env, run->dcr.dcrn, &run->dcr.data);
- }
- break;
- case KVM_EXIT_HLT:
- DPRINTF("handle halt\n");
- ret = kvmppc_handle_halt(cpu);
- break;
-#if defined(TARGET_PPC64)
- case KVM_EXIT_PAPR_HCALL:
- DPRINTF("handle PAPR hypercall\n");
- run->papr_hcall.ret = spapr_hypercall(cpu,
- run->papr_hcall.nr,
- run->papr_hcall.args);
- ret = 0;
- break;
-#endif
- case KVM_EXIT_EPR:
- DPRINTF("handle epr\n");
- run->epr.epr = ldl_phys(cs->as, env->mpic_iack);
- ret = 0;
- break;
- case KVM_EXIT_WATCHDOG:
- DPRINTF("handle watchdog expiry\n");
- watchdog_perform_action();
- ret = 0;
- break;
-
- case KVM_EXIT_DEBUG:
- DPRINTF("handle debug exception\n");
- if (kvm_handle_debug(cpu, run)) {
- ret = EXCP_DEBUG;
- break;
- }
- /* re-enter, this exception was guest-internal */
- ret = 0;
- break;
-
- default:
- fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
- ret = -1;
- break;
- }
-
- qemu_mutex_unlock_iothread();
- return ret;
-}
-
-int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits)
-{
- CPUState *cs = CPU(cpu);
- uint32_t bits = tsr_bits;
- struct kvm_one_reg reg = {
- .id = KVM_REG_PPC_OR_TSR,
- .addr = (uintptr_t) &bits,
- };
-
- return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
-}
-
-int kvmppc_clear_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits)
-{
-
- CPUState *cs = CPU(cpu);
- uint32_t bits = tsr_bits;
- struct kvm_one_reg reg = {
- .id = KVM_REG_PPC_CLEAR_TSR,
- .addr = (uintptr_t) &bits,
- };
-
- return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
-}
-
-int kvmppc_set_tcr(PowerPCCPU *cpu)
-{
- CPUState *cs = CPU(cpu);
- CPUPPCState *env = &cpu->env;
- uint32_t tcr = env->spr[SPR_BOOKE_TCR];
-
- struct kvm_one_reg reg = {
- .id = KVM_REG_PPC_TCR,
- .addr = (uintptr_t) &tcr,
- };
-
- return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
-}
-
-int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu)
-{
- CPUState *cs = CPU(cpu);
- int ret;
-
- if (!kvm_enabled()) {
- return -1;
- }
-
- if (!cap_ppc_watchdog) {
- printf("warning: KVM does not support watchdog");
- return -1;
- }
-
- ret = kvm_vcpu_enable_cap(cs, KVM_CAP_PPC_BOOKE_WATCHDOG, 0);
- if (ret < 0) {
- fprintf(stderr, "%s: couldn't enable KVM_CAP_PPC_BOOKE_WATCHDOG: %s\n",
- __func__, strerror(-ret));
- return ret;
- }
-
- return ret;
-}
-
-static int read_cpuinfo(const char *field, char *value, int len)
-{
- FILE *f;
- int ret = -1;
- int field_len = strlen(field);
- char line[512];
-
- f = fopen("/proc/cpuinfo", "r");
- if (!f) {
- return -1;
- }
-
- do {
- if (!fgets(line, sizeof(line), f)) {
- break;
- }
- if (!strncmp(line, field, field_len)) {
- pstrcpy(value, len, line);
- ret = 0;
- break;
- }
- } while(*line);
-
- fclose(f);
-
- return ret;
-}
-
-uint32_t kvmppc_get_tbfreq(void)
-{
- char line[512];
- char *ns;
- uint32_t retval = NANOSECONDS_PER_SECOND;
-
- if (read_cpuinfo("timebase", line, sizeof(line))) {
- return retval;
- }
-
- if (!(ns = strchr(line, ':'))) {
- return retval;
- }
-
- ns++;
-
- return atoi(ns);
-}
-
-bool kvmppc_get_host_serial(char **value)
-{
- return g_file_get_contents("/proc/device-tree/system-id", value, NULL,
- NULL);
-}
-
-bool kvmppc_get_host_model(char **value)
-{
- return g_file_get_contents("/proc/device-tree/model", value, NULL, NULL);
-}
-
-/* Try to find a device tree node for a CPU with clock-frequency property */
-static int kvmppc_find_cpu_dt(char *buf, int buf_len)
-{
- struct dirent *dirp;
- DIR *dp;
-
- if ((dp = opendir(PROC_DEVTREE_CPU)) == NULL) {
- printf("Can't open directory " PROC_DEVTREE_CPU "\n");
- return -1;
- }
-
- buf[0] = '\0';
- while ((dirp = readdir(dp)) != NULL) {
- FILE *f;
- snprintf(buf, buf_len, "%s%s/clock-frequency", PROC_DEVTREE_CPU,
- dirp->d_name);
- f = fopen(buf, "r");
- if (f) {
- snprintf(buf, buf_len, "%s%s", PROC_DEVTREE_CPU, dirp->d_name);
- fclose(f);
- break;
- }
- buf[0] = '\0';
- }
- closedir(dp);
- if (buf[0] == '\0') {
- printf("Unknown host!\n");
- return -1;
- }
-
- return 0;
-}
-
-static uint64_t kvmppc_read_int_dt(const char *filename)
-{
- union {
- uint32_t v32;
- uint64_t v64;
- } u;
- FILE *f;
- int len;
-
- f = fopen(filename, "rb");
- if (!f) {
- return -1;
- }
-
- len = fread(&u, 1, sizeof(u), f);
- fclose(f);
- switch (len) {
- case 4:
- /* property is a 32-bit quantity */
- return be32_to_cpu(u.v32);
- case 8:
- return be64_to_cpu(u.v64);
- }
-
- return 0;
-}
-
-/* Read a CPU node property from the host device tree that's a single
- * integer (32-bit or 64-bit). Returns 0 if anything goes wrong
- * (can't find or open the property, or doesn't understand the
- * format) */
-static uint64_t kvmppc_read_int_cpu_dt(const char *propname)
-{
- char buf[PATH_MAX], *tmp;
- uint64_t val;
-
- if (kvmppc_find_cpu_dt(buf, sizeof(buf))) {
- return -1;
- }
-
- tmp = g_strdup_printf("%s/%s", buf, propname);
- val = kvmppc_read_int_dt(tmp);
- g_free(tmp);
-
- return val;
-}
-
-uint64_t kvmppc_get_clockfreq(void)
-{
- return kvmppc_read_int_cpu_dt("clock-frequency");
-}
-
-uint32_t kvmppc_get_vmx(void)
-{
- return kvmppc_read_int_cpu_dt("ibm,vmx");
-}
-
-uint32_t kvmppc_get_dfp(void)
-{
- return kvmppc_read_int_cpu_dt("ibm,dfp");
-}
-
-static int kvmppc_get_pvinfo(CPUPPCState *env, struct kvm_ppc_pvinfo *pvinfo)
- {
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- CPUState *cs = CPU(cpu);
-
- if (kvm_vm_check_extension(cs->kvm_state, KVM_CAP_PPC_GET_PVINFO) &&
- !kvm_vm_ioctl(cs->kvm_state, KVM_PPC_GET_PVINFO, pvinfo)) {
- return 0;
- }
-
- return 1;
-}
-
-int kvmppc_get_hasidle(CPUPPCState *env)
-{
- struct kvm_ppc_pvinfo pvinfo;
-
- if (!kvmppc_get_pvinfo(env, &pvinfo) &&
- (pvinfo.flags & KVM_PPC_PVINFO_FLAGS_EV_IDLE)) {
- return 1;
- }
-
- return 0;
-}
-
-int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len)
-{
- uint32_t *hc = (uint32_t*)buf;
- struct kvm_ppc_pvinfo pvinfo;
-
- if (!kvmppc_get_pvinfo(env, &pvinfo)) {
- memcpy(buf, pvinfo.hcall, buf_len);
- return 0;
- }
-
- /*
- * Fallback to always fail hypercalls regardless of endianness:
- *
- * tdi 0,r0,72 (becomes b .+8 in wrong endian, nop in good endian)
- * li r3, -1
- * b .+8 (becomes nop in wrong endian)
- * bswap32(li r3, -1)
- */
-
- hc[0] = cpu_to_be32(0x08000048);
- hc[1] = cpu_to_be32(0x3860ffff);
- hc[2] = cpu_to_be32(0x48000008);
- hc[3] = cpu_to_be32(bswap32(0x3860ffff));
-
- return 1;
-}
-
-static inline int kvmppc_enable_hcall(KVMState *s, target_ulong hcall)
-{
- return kvm_vm_enable_cap(s, KVM_CAP_PPC_ENABLE_HCALL, 0, hcall, 1);
-}
-
-void kvmppc_enable_logical_ci_hcalls(void)
-{
- /*
- * FIXME: it would be nice if we could detect the cases where
- * we're using a device which requires the in kernel
- * implementation of these hcalls, but the kernel lacks them and
- * produce a warning.
- */
- kvmppc_enable_hcall(kvm_state, H_LOGICAL_CI_LOAD);
- kvmppc_enable_hcall(kvm_state, H_LOGICAL_CI_STORE);
-}
-
-void kvmppc_enable_set_mode_hcall(void)
-{
- kvmppc_enable_hcall(kvm_state, H_SET_MODE);
-}
-
-void kvmppc_enable_clear_ref_mod_hcalls(void)
-{
- kvmppc_enable_hcall(kvm_state, H_CLEAR_REF);
- kvmppc_enable_hcall(kvm_state, H_CLEAR_MOD);
-}
-
-void kvmppc_set_papr(PowerPCCPU *cpu)
-{
- CPUState *cs = CPU(cpu);
- int ret;
-
- ret = kvm_vcpu_enable_cap(cs, KVM_CAP_PPC_PAPR, 0);
- if (ret) {
- error_report("This vCPU type or KVM version does not support PAPR");
- exit(1);
- }
-
- /* Update the capability flag so we sync the right information
- * with kvm */
- cap_papr = 1;
-}
-
-int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version)
-{
- return kvm_set_one_reg(CPU(cpu), KVM_REG_PPC_ARCH_COMPAT, &cpu_version);
-}
-
-void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy)
-{
- CPUState *cs = CPU(cpu);
- int ret;
-
- ret = kvm_vcpu_enable_cap(cs, KVM_CAP_PPC_EPR, 0, mpic_proxy);
- if (ret && mpic_proxy) {
- error_report("This KVM version does not support EPR");
- exit(1);
- }
-}
-
-int kvmppc_smt_threads(void)
-{
- return cap_ppc_smt ? cap_ppc_smt : 1;
-}
-
-#ifdef TARGET_PPC64
-off_t kvmppc_alloc_rma(void **rma)
-{
- off_t size;
- int fd;
- struct kvm_allocate_rma ret;
-
- /* If cap_ppc_rma == 0, contiguous RMA allocation is not supported
- * if cap_ppc_rma == 1, contiguous RMA allocation is supported, but
- * not necessary on this hardware
- * if cap_ppc_rma == 2, contiguous RMA allocation is needed on this hardware
- *
- * FIXME: We should allow the user to force contiguous RMA
- * allocation in the cap_ppc_rma==1 case.
- */
- if (cap_ppc_rma < 2) {
- return 0;
- }
-
- fd = kvm_vm_ioctl(kvm_state, KVM_ALLOCATE_RMA, &ret);
- if (fd < 0) {
- fprintf(stderr, "KVM: Error on KVM_ALLOCATE_RMA: %s\n",
- strerror(errno));
- return -1;
- }
-
- size = MIN(ret.rma_size, 256ul << 20);
-
- *rma = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- if (*rma == MAP_FAILED) {
- fprintf(stderr, "KVM: Error mapping RMA: %s\n", strerror(errno));
- return -1;
- };
-
- return size;
-}
-
-uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift)
-{
- struct kvm_ppc_smmu_info info;
- long rampagesize, best_page_shift;
- int i;
-
- if (cap_ppc_rma >= 2) {
- return current_size;
- }
-
- /* Find the largest hardware supported page size that's less than
- * or equal to the (logical) backing page size of guest RAM */
- kvm_get_smmu_info(POWERPC_CPU(first_cpu), &info);
- rampagesize = getrampagesize();
- best_page_shift = 0;
-
- for (i = 0; i < KVM_PPC_PAGE_SIZES_MAX_SZ; i++) {
- struct kvm_ppc_one_seg_page_size *sps = &info.sps[i];
-
- if (!sps->page_shift) {
- continue;
- }
-
- if ((sps->page_shift > best_page_shift)
- && ((1UL << sps->page_shift) <= rampagesize)) {
- best_page_shift = sps->page_shift;
- }
- }
-
- return MIN(current_size,
- 1ULL << (best_page_shift + hash_shift - 7));
-}
-#endif
-
-bool kvmppc_spapr_use_multitce(void)
-{
- return cap_spapr_multitce;
-}
-
-void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd,
- bool need_vfio)
-{
- struct kvm_create_spapr_tce args = {
- .liobn = liobn,
- .window_size = window_size,
- };
- long len;
- int fd;
- void *table;
-
- /* Must set fd to -1 so we don't try to munmap when called for
- * destroying the table, which the upper layers -will- do
- */
- *pfd = -1;
- if (!cap_spapr_tce || (need_vfio && !cap_spapr_vfio)) {
- return NULL;
- }
-
- fd = kvm_vm_ioctl(kvm_state, KVM_CREATE_SPAPR_TCE, &args);
- if (fd < 0) {
- fprintf(stderr, "KVM: Failed to create TCE table for liobn 0x%x\n",
- liobn);
- return NULL;
- }
-
- len = (window_size / SPAPR_TCE_PAGE_SIZE) * sizeof(uint64_t);
- /* FIXME: round this up to page size */
-
- table = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- if (table == MAP_FAILED) {
- fprintf(stderr, "KVM: Failed to map TCE table for liobn 0x%x\n",
- liobn);
- close(fd);
- return NULL;
- }
-
- *pfd = fd;
- return table;
-}
-
-int kvmppc_remove_spapr_tce(void *table, int fd, uint32_t nb_table)
-{
- long len;
-
- if (fd < 0) {
- return -1;
- }
-
- len = nb_table * sizeof(uint64_t);
- if ((munmap(table, len) < 0) ||
- (close(fd) < 0)) {
- fprintf(stderr, "KVM: Unexpected error removing TCE table: %s",
- strerror(errno));
- /* Leak the table */
- }
-
- return 0;
-}
-
-int kvmppc_reset_htab(int shift_hint)
-{
- uint32_t shift = shift_hint;
-
- if (!kvm_enabled()) {
- /* Full emulation, tell caller to allocate htab itself */
- return 0;
- }
- if (kvm_check_extension(kvm_state, KVM_CAP_PPC_ALLOC_HTAB)) {
- int ret;
- ret = kvm_vm_ioctl(kvm_state, KVM_PPC_ALLOCATE_HTAB, &shift);
- if (ret == -ENOTTY) {
- /* At least some versions of PR KVM advertise the
- * capability, but don't implement the ioctl(). Oops.
- * Return 0 so that we allocate the htab in qemu, as is
- * correct for PR. */
- return 0;
- } else if (ret < 0) {
- return ret;
- }
- return shift;
- }
-
- /* We have a kernel that predates the htab reset calls. For PR
- * KVM, we need to allocate the htab ourselves, for an HV KVM of
- * this era, it has allocated a 16MB fixed size hash table already. */
- if (kvmppc_is_pr(kvm_state)) {
- /* PR - tell caller to allocate htab */
- return 0;
- } else {
- /* HV - assume 16MB kernel allocated htab */
- return 24;
- }
-}
-
-static inline uint32_t mfpvr(void)
-{
- uint32_t pvr;
-
- asm ("mfpvr %0"
- : "=r"(pvr));
- return pvr;
-}
-
-static void alter_insns(uint64_t *word, uint64_t flags, bool on)
-{
- if (on) {
- *word |= flags;
- } else {
- *word &= ~flags;
- }
-}
-
-static void kvmppc_host_cpu_initfn(Object *obj)
-{
- assert(kvm_enabled());
-}
-
-static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
- uint32_t vmx = kvmppc_get_vmx();
- uint32_t dfp = kvmppc_get_dfp();
- uint32_t dcache_size = kvmppc_read_int_cpu_dt("d-cache-size");
- uint32_t icache_size = kvmppc_read_int_cpu_dt("i-cache-size");
-
- /* Now fix up the class with information we can query from the host */
- pcc->pvr = mfpvr();
-
- if (vmx != -1) {
- /* Only override when we know what the host supports */
- alter_insns(&pcc->insns_flags, PPC_ALTIVEC, vmx > 0);
- alter_insns(&pcc->insns_flags2, PPC2_VSX, vmx > 1);
- }
- if (dfp != -1) {
- /* Only override when we know what the host supports */
- alter_insns(&pcc->insns_flags2, PPC2_DFP, dfp);
- }
-
- if (dcache_size != -1) {
- pcc->l1_dcache_size = dcache_size;
- }
-
- if (icache_size != -1) {
- pcc->l1_icache_size = icache_size;
- }
-
- /* Reason: kvmppc_host_cpu_initfn() dies when !kvm_enabled() */
- dc->cannot_destroy_with_object_finalize_yet = true;
-}
-
-bool kvmppc_has_cap_epr(void)
-{
- return cap_epr;
-}
-
-bool kvmppc_has_cap_htab_fd(void)
-{
- return cap_htab_fd;
-}
-
-bool kvmppc_has_cap_fixup_hcalls(void)
-{
- return cap_fixup_hcalls;
-}
-
-bool kvmppc_has_cap_htm(void)
-{
- return cap_htm;
-}
-
-static PowerPCCPUClass *ppc_cpu_get_family_class(PowerPCCPUClass *pcc)
-{
- ObjectClass *oc = OBJECT_CLASS(pcc);
-
- while (oc && !object_class_is_abstract(oc)) {
- oc = object_class_get_parent(oc);
- }
- assert(oc);
-
- return POWERPC_CPU_CLASS(oc);
-}
-
-PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void)
-{
- uint32_t host_pvr = mfpvr();
- PowerPCCPUClass *pvr_pcc;
-
- pvr_pcc = ppc_cpu_class_by_pvr(host_pvr);
- if (pvr_pcc == NULL) {
- pvr_pcc = ppc_cpu_class_by_pvr_mask(host_pvr);
- }
-
- return pvr_pcc;
-}
-
-static int kvm_ppc_register_host_cpu_type(void)
-{
- TypeInfo type_info = {
- .name = TYPE_HOST_POWERPC_CPU,
- .instance_init = kvmppc_host_cpu_initfn,
- .class_init = kvmppc_host_cpu_class_init,
- };
- PowerPCCPUClass *pvr_pcc;
- DeviceClass *dc;
-
- pvr_pcc = kvm_ppc_get_host_cpu_class();
- if (pvr_pcc == NULL) {
- return -1;
- }
- type_info.parent = object_class_get_name(OBJECT_CLASS(pvr_pcc));
- type_register(&type_info);
-
- /* Register generic family CPU class for a family */
- pvr_pcc = ppc_cpu_get_family_class(pvr_pcc);
- dc = DEVICE_CLASS(pvr_pcc);
- type_info.parent = object_class_get_name(OBJECT_CLASS(pvr_pcc));
- type_info.name = g_strdup_printf("%s-"TYPE_POWERPC_CPU, dc->desc);
- type_register(&type_info);
-
-#if defined(TARGET_PPC64)
- type_info.name = g_strdup_printf("%s-"TYPE_SPAPR_CPU_CORE, "host");
- type_info.parent = TYPE_SPAPR_CPU_CORE,
- type_info.instance_size = sizeof(sPAPRCPUCore);
- type_info.instance_init = NULL;
- type_info.class_init = spapr_cpu_core_class_init;
- type_info.class_data = (void *) "host";
- type_register(&type_info);
- g_free((void *)type_info.name);
-
- /* Register generic spapr CPU family class for current host CPU type */
- type_info.name = g_strdup_printf("%s-"TYPE_SPAPR_CPU_CORE, dc->desc);
- type_info.class_data = (void *) dc->desc;
- type_register(&type_info);
- g_free((void *)type_info.name);
-#endif
-
- return 0;
-}
-
-int kvmppc_define_rtas_kernel_token(uint32_t token, const char *function)
-{
- struct kvm_rtas_token_args args = {
- .token = token,
- };
-
- if (!kvm_check_extension(kvm_state, KVM_CAP_PPC_RTAS)) {
- return -ENOENT;
- }
-
- strncpy(args.name, function, sizeof(args.name));
-
- return kvm_vm_ioctl(kvm_state, KVM_PPC_RTAS_DEFINE_TOKEN, &args);
-}
-
-int kvmppc_get_htab_fd(bool write)
-{
- struct kvm_get_htab_fd s = {
- .flags = write ? KVM_GET_HTAB_WRITE : 0,
- .start_index = 0,
- };
-
- if (!cap_htab_fd) {
- fprintf(stderr, "KVM version doesn't support saving the hash table\n");
- return -1;
- }
-
- return kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &s);
-}
-
-int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize, int64_t max_ns)
-{
- int64_t starttime = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
- uint8_t buf[bufsize];
- ssize_t rc;
-
- do {
- rc = read(fd, buf, bufsize);
- if (rc < 0) {
- fprintf(stderr, "Error reading data from KVM HTAB fd: %s\n",
- strerror(errno));
- return rc;
- } else if (rc) {
- uint8_t *buffer = buf;
- ssize_t n = rc;
- while (n) {
- struct kvm_get_htab_header *head =
- (struct kvm_get_htab_header *) buffer;
- size_t chunksize = sizeof(*head) +
- HASH_PTE_SIZE_64 * head->n_valid;
-
- qemu_put_be32(f, head->index);
- qemu_put_be16(f, head->n_valid);
- qemu_put_be16(f, head->n_invalid);
- qemu_put_buffer(f, (void *)(head + 1),
- HASH_PTE_SIZE_64 * head->n_valid);
-
- buffer += chunksize;
- n -= chunksize;
- }
- }
- } while ((rc != 0)
- && ((max_ns < 0)
- || ((qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - starttime) < max_ns)));
-
- return (rc == 0) ? 1 : 0;
-}
-
-int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index,
- uint16_t n_valid, uint16_t n_invalid)
-{
- struct kvm_get_htab_header *buf;
- size_t chunksize = sizeof(*buf) + n_valid*HASH_PTE_SIZE_64;
- ssize_t rc;
-
- buf = alloca(chunksize);
- buf->index = index;
- buf->n_valid = n_valid;
- buf->n_invalid = n_invalid;
-
- qemu_get_buffer(f, (void *)(buf + 1), HASH_PTE_SIZE_64*n_valid);
-
- rc = write(fd, buf, chunksize);
- if (rc < 0) {
- fprintf(stderr, "Error writing KVM hash table: %s\n",
- strerror(errno));
- return rc;
- }
- if (rc != chunksize) {
- /* We should never get a short write on a single chunk */
- fprintf(stderr, "Short write, restoring KVM hash table\n");
- return -1;
- }
- return 0;
-}
-
-bool kvm_arch_stop_on_emulation_error(CPUState *cpu)
-{
- return true;
-}
-
-int kvm_arch_on_sigbus_vcpu(CPUState *cpu, int code, void *addr)
-{
- return 1;
-}
-
-int kvm_arch_on_sigbus(int code, void *addr)
-{
- return 1;
-}
-
-void kvm_arch_init_irq_routing(KVMState *s)
-{
-}
-
-struct kvm_get_htab_buf {
- struct kvm_get_htab_header header;
- /*
- * We require one extra byte for read
- */
- target_ulong hpte[(HPTES_PER_GROUP * 2) + 1];
-};
-
-uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu, target_ulong pte_index)
-{
- int htab_fd;
- struct kvm_get_htab_fd ghf;
- struct kvm_get_htab_buf *hpte_buf;
-
- ghf.flags = 0;
- ghf.start_index = pte_index;
- htab_fd = kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf);
- if (htab_fd < 0) {
- goto error_out;
- }
-
- hpte_buf = g_malloc0(sizeof(*hpte_buf));
- /*
- * Read the hpte group
- */
- if (read(htab_fd, hpte_buf, sizeof(*hpte_buf)) < 0) {
- goto out_close;
- }
-
- close(htab_fd);
- return (uint64_t)(uintptr_t) hpte_buf->hpte;
-
-out_close:
- g_free(hpte_buf);
- close(htab_fd);
-error_out:
- return 0;
-}
-
-void kvmppc_hash64_free_pteg(uint64_t token)
-{
- struct kvm_get_htab_buf *htab_buf;
-
- htab_buf = container_of((void *)(uintptr_t) token, struct kvm_get_htab_buf,
- hpte);
- g_free(htab_buf);
- return;
-}
-
-void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index,
- target_ulong pte0, target_ulong pte1)
-{
- int htab_fd;
- struct kvm_get_htab_fd ghf;
- struct kvm_get_htab_buf hpte_buf;
-
- ghf.flags = 0;
- ghf.start_index = 0; /* Ignored */
- htab_fd = kvm_vm_ioctl(kvm_state, KVM_PPC_GET_HTAB_FD, &ghf);
- if (htab_fd < 0) {
- goto error_out;
- }
-
- hpte_buf.header.n_valid = 1;
- hpte_buf.header.n_invalid = 0;
- hpte_buf.header.index = pte_index;
- hpte_buf.hpte[0] = pte0;
- hpte_buf.hpte[1] = pte1;
- /*
- * Write the hpte entry.
- * CAUTION: write() has the warn_unused_result attribute. Hence we
- * need to check the return value, even though we do nothing.
- */
- if (write(htab_fd, &hpte_buf, sizeof(hpte_buf)) < 0) {
- goto out_close;
- }
-
-out_close:
- close(htab_fd);
- return;
-
-error_out:
- return;
-}
-
-int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
- uint64_t address, uint32_t data, PCIDevice *dev)
-{
- return 0;
-}
-
-int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
- int vector, PCIDevice *dev)
-{
- return 0;
-}
-
-int kvm_arch_release_virq_post(int virq)
-{
- return 0;
-}
-
-int kvm_arch_msi_data_to_gsi(uint32_t data)
-{
- return data & 0xffff;
-}
-
-int kvmppc_enable_hwrng(void)
-{
- if (!kvm_enabled() || !kvm_check_extension(kvm_state, KVM_CAP_PPC_HWRNG)) {
- return -1;
- }
-
- return kvmppc_enable_hcall(kvm_state, H_RANDOM);
-}
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
deleted file mode 100644
index bd1d78bfbe..0000000000
--- a/target-ppc/kvm_ppc.h
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- * Copyright 2008 IBM Corporation.
- * Authors: Hollis Blanchard <hollisb@us.ibm.com>
- *
- * This work is licensed under the GNU GPL license version 2 or later.
- *
- */
-
-#ifndef KVM_PPC_H
-#define KVM_PPC_H
-
-#define TYPE_HOST_POWERPC_CPU "host-" TYPE_POWERPC_CPU
-
-#ifdef CONFIG_KVM
-
-uint32_t kvmppc_get_tbfreq(void);
-uint64_t kvmppc_get_clockfreq(void);
-uint32_t kvmppc_get_vmx(void);
-uint32_t kvmppc_get_dfp(void);
-bool kvmppc_get_host_model(char **buf);
-bool kvmppc_get_host_serial(char **buf);
-int kvmppc_get_hasidle(CPUPPCState *env);
-int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len);
-int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level);
-void kvmppc_enable_logical_ci_hcalls(void);
-void kvmppc_enable_set_mode_hcall(void);
-void kvmppc_enable_clear_ref_mod_hcalls(void);
-void kvmppc_set_papr(PowerPCCPU *cpu);
-int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version);
-void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy);
-int kvmppc_smt_threads(void);
-int kvmppc_clear_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits);
-int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits);
-int kvmppc_set_tcr(PowerPCCPU *cpu);
-int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu);
-#ifndef CONFIG_USER_ONLY
-off_t kvmppc_alloc_rma(void **rma);
-bool kvmppc_spapr_use_multitce(void);
-void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd,
- bool need_vfio);
-int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size);
-int kvmppc_reset_htab(int shift_hint);
-uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift);
-#endif /* !CONFIG_USER_ONLY */
-bool kvmppc_has_cap_epr(void);
-int kvmppc_define_rtas_kernel_token(uint32_t token, const char *function);
-bool kvmppc_has_cap_htab_fd(void);
-int kvmppc_get_htab_fd(bool write);
-int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize, int64_t max_ns);
-int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index,
- uint16_t n_valid, uint16_t n_invalid);
-uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu, target_ulong pte_index);
-void kvmppc_hash64_free_pteg(uint64_t token);
-
-void kvmppc_hash64_write_pte(CPUPPCState *env, target_ulong pte_index,
- target_ulong pte0, target_ulong pte1);
-bool kvmppc_has_cap_fixup_hcalls(void);
-bool kvmppc_has_cap_htm(void);
-int kvmppc_enable_hwrng(void);
-int kvmppc_put_books_sregs(PowerPCCPU *cpu);
-PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void);
-
-#else
-
-static inline uint32_t kvmppc_get_tbfreq(void)
-{
- return 0;
-}
-
-static inline bool kvmppc_get_host_model(char **buf)
-{
- return false;
-}
-
-static inline bool kvmppc_get_host_serial(char **buf)
-{
- return false;
-}
-
-static inline uint64_t kvmppc_get_clockfreq(void)
-{
- return 0;
-}
-
-static inline uint32_t kvmppc_get_vmx(void)
-{
- return 0;
-}
-
-static inline uint32_t kvmppc_get_dfp(void)
-{
- return 0;
-}
-
-static inline int kvmppc_get_hasidle(CPUPPCState *env)
-{
- return 0;
-}
-
-static inline int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len)
-{
- return -1;
-}
-
-static inline int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level)
-{
- return -1;
-}
-
-static inline void kvmppc_enable_logical_ci_hcalls(void)
-{
-}
-
-static inline void kvmppc_enable_set_mode_hcall(void)
-{
-}
-
-static inline void kvmppc_enable_clear_ref_mod_hcalls(void)
-{
-}
-
-static inline void kvmppc_set_papr(PowerPCCPU *cpu)
-{
-}
-
-static inline int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version)
-{
- return 0;
-}
-
-static inline void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy)
-{
-}
-
-static inline int kvmppc_smt_threads(void)
-{
- return 1;
-}
-
-static inline int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits)
-{
- return 0;
-}
-
-static inline int kvmppc_clear_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits)
-{
- return 0;
-}
-
-static inline int kvmppc_set_tcr(PowerPCCPU *cpu)
-{
- return 0;
-}
-
-static inline int kvmppc_booke_watchdog_enable(PowerPCCPU *cpu)
-{
- return -1;
-}
-
-#ifndef CONFIG_USER_ONLY
-static inline off_t kvmppc_alloc_rma(void **rma)
-{
- return 0;
-}
-
-static inline bool kvmppc_spapr_use_multitce(void)
-{
- return false;
-}
-
-static inline void *kvmppc_create_spapr_tce(uint32_t liobn,
- uint32_t window_size, int *fd,
- bool need_vfio)
-{
- return NULL;
-}
-
-static inline int kvmppc_remove_spapr_tce(void *table, int pfd,
- uint32_t nb_table)
-{
- return -1;
-}
-
-static inline int kvmppc_reset_htab(int shift_hint)
-{
- return 0;
-}
-
-static inline uint64_t kvmppc_rma_size(uint64_t current_size,
- unsigned int hash_shift)
-{
- return ram_size;
-}
-
-#endif /* !CONFIG_USER_ONLY */
-
-static inline bool kvmppc_has_cap_epr(void)
-{
- return false;
-}
-
-static inline int kvmppc_define_rtas_kernel_token(uint32_t token,
- const char *function)
-{
- return -1;
-}
-
-static inline bool kvmppc_has_cap_htab_fd(void)
-{
- return false;
-}
-
-static inline int kvmppc_get_htab_fd(bool write)
-{
- return -1;
-}
-
-static inline int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize,
- int64_t max_ns)
-{
- abort();
-}
-
-static inline int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t index,
- uint16_t n_valid, uint16_t n_invalid)
-{
- abort();
-}
-
-static inline uint64_t kvmppc_hash64_read_pteg(PowerPCCPU *cpu,
- target_ulong pte_index)
-{
- abort();
-}
-
-static inline void kvmppc_hash64_free_pteg(uint64_t token)
-{
- abort();
-}
-
-static inline void kvmppc_hash64_write_pte(CPUPPCState *env,
- target_ulong pte_index,
- target_ulong pte0, target_ulong pte1)
-{
- abort();
-}
-
-static inline bool kvmppc_has_cap_fixup_hcalls(void)
-{
- abort();
-}
-
-static inline bool kvmppc_has_cap_htm(void)
-{
- return false;
-}
-
-static inline int kvmppc_enable_hwrng(void)
-{
- return -1;
-}
-
-static inline int kvmppc_put_books_sregs(PowerPCCPU *cpu)
-{
- abort();
-}
-
-static inline PowerPCCPUClass *kvm_ppc_get_host_cpu_class(void)
-{
- return NULL;
-}
-
-#endif
-
-#ifndef CONFIG_KVM
-
-#define kvmppc_eieio() do { } while (0)
-
-static inline void kvmppc_dcbst_range(PowerPCCPU *cpu, uint8_t *addr, int len)
-{
-}
-
-static inline void kvmppc_icbi_range(PowerPCCPU *cpu, uint8_t *addr, int len)
-{
-}
-
-#else /* CONFIG_KVM */
-
-#define kvmppc_eieio() \
- do { \
- if (kvm_enabled()) { \
- asm volatile("eieio" : : : "memory"); \
- } \
- } while (0)
-
-/* Store data cache blocks back to memory */
-static inline void kvmppc_dcbst_range(PowerPCCPU *cpu, uint8_t *addr, int len)
-{
- uint8_t *p;
-
- for (p = addr; p < addr + len; p += cpu->env.dcache_line_size) {
- asm volatile("dcbst 0,%0" : : "r"(p) : "memory");
- }
-}
-
-/* Invalidate instruction cache blocks */
-static inline void kvmppc_icbi_range(PowerPCCPU *cpu, uint8_t *addr, int len)
-{
- uint8_t *p;
-
- for (p = addr; p < addr + len; p += cpu->env.icache_line_size) {
- asm volatile("icbi 0,%0" : : "r"(p));
- }
-}
-
-#endif /* CONFIG_KVM */
-
-#ifndef KVM_INTERRUPT_SET
-#define KVM_INTERRUPT_SET -1
-#endif
-
-#ifndef KVM_INTERRUPT_UNSET
-#define KVM_INTERRUPT_UNSET -2
-#endif
-
-#ifndef KVM_INTERRUPT_SET_LEVEL
-#define KVM_INTERRUPT_SET_LEVEL -3
-#endif
-
-#endif /* KVM_PPC_H */
diff --git a/target-ppc/machine.c b/target-ppc/machine.c
deleted file mode 100644
index 18c16d2512..0000000000
--- a/target-ppc/machine.c
+++ /dev/null
@@ -1,615 +0,0 @@
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "hw/hw.h"
-#include "hw/boards.h"
-#include "sysemu/kvm.h"
-#include "helper_regs.h"
-#include "mmu-hash64.h"
-#include "migration/cpu.h"
-
-static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)
-{
- PowerPCCPU *cpu = opaque;
- CPUPPCState *env = &cpu->env;
- unsigned int i, j;
- target_ulong sdr1;
- uint32_t fpscr;
- target_ulong xer;
-
- for (i = 0; i < 32; i++)
- qemu_get_betls(f, &env->gpr[i]);
-#if !defined(TARGET_PPC64)
- for (i = 0; i < 32; i++)
- qemu_get_betls(f, &env->gprh[i]);
-#endif
- qemu_get_betls(f, &env->lr);
- qemu_get_betls(f, &env->ctr);
- for (i = 0; i < 8; i++)
- qemu_get_be32s(f, &env->crf[i]);
- qemu_get_betls(f, &xer);
- cpu_write_xer(env, xer);
- qemu_get_betls(f, &env->reserve_addr);
- qemu_get_betls(f, &env->msr);
- for (i = 0; i < 4; i++)
- qemu_get_betls(f, &env->tgpr[i]);
- for (i = 0; i < 32; i++) {
- union {
- float64 d;
- uint64_t l;
- } u;
- u.l = qemu_get_be64(f);
- env->fpr[i] = u.d;
- }
- qemu_get_be32s(f, &fpscr);
- env->fpscr = fpscr;
- qemu_get_sbe32s(f, &env->access_type);
-#if defined(TARGET_PPC64)
- qemu_get_betls(f, &env->spr[SPR_ASR]);
- qemu_get_sbe32s(f, &env->slb_nr);
-#endif
- qemu_get_betls(f, &sdr1);
- for (i = 0; i < 32; i++)
- qemu_get_betls(f, &env->sr[i]);
- for (i = 0; i < 2; i++)
- for (j = 0; j < 8; j++)
- qemu_get_betls(f, &env->DBAT[i][j]);
- for (i = 0; i < 2; i++)
- for (j = 0; j < 8; j++)
- qemu_get_betls(f, &env->IBAT[i][j]);
- qemu_get_sbe32s(f, &env->nb_tlb);
- qemu_get_sbe32s(f, &env->tlb_per_way);
- qemu_get_sbe32s(f, &env->nb_ways);
- qemu_get_sbe32s(f, &env->last_way);
- qemu_get_sbe32s(f, &env->id_tlbs);
- qemu_get_sbe32s(f, &env->nb_pids);
- if (env->tlb.tlb6) {
- // XXX assumes 6xx
- for (i = 0; i < env->nb_tlb; i++) {
- qemu_get_betls(f, &env->tlb.tlb6[i].pte0);
- qemu_get_betls(f, &env->tlb.tlb6[i].pte1);
- qemu_get_betls(f, &env->tlb.tlb6[i].EPN);
- }
- }
- for (i = 0; i < 4; i++)
- qemu_get_betls(f, &env->pb[i]);
- for (i = 0; i < 1024; i++)
- qemu_get_betls(f, &env->spr[i]);
- if (!env->external_htab) {
- ppc_store_sdr1(env, sdr1);
- }
- qemu_get_be32s(f, &env->vscr);
- qemu_get_be64s(f, &env->spe_acc);
- qemu_get_be32s(f, &env->spe_fscr);
- qemu_get_betls(f, &env->msr_mask);
- qemu_get_be32s(f, &env->flags);
- qemu_get_sbe32s(f, &env->error_code);
- qemu_get_be32s(f, &env->pending_interrupts);
- qemu_get_be32s(f, &env->irq_input_state);
- for (i = 0; i < POWERPC_EXCP_NB; i++)
- qemu_get_betls(f, &env->excp_vectors[i]);
- qemu_get_betls(f, &env->excp_prefix);
- qemu_get_betls(f, &env->ivor_mask);
- qemu_get_betls(f, &env->ivpr_mask);
- qemu_get_betls(f, &env->hreset_vector);
- qemu_get_betls(f, &env->nip);
- qemu_get_betls(f, &env->hflags);
- qemu_get_betls(f, &env->hflags_nmsr);
- qemu_get_sbe32(f); /* Discard unused mmu_idx */
- qemu_get_sbe32(f); /* Discard unused power_mode */
-
- /* Recompute mmu indices */
- hreg_compute_mem_idx(env);
-
- return 0;
-}
-
-static int get_avr(QEMUFile *f, void *pv, size_t size)
-{
- ppc_avr_t *v = pv;
-
- v->u64[0] = qemu_get_be64(f);
- v->u64[1] = qemu_get_be64(f);
-
- return 0;
-}
-
-static void put_avr(QEMUFile *f, void *pv, size_t size)
-{
- ppc_avr_t *v = pv;
-
- qemu_put_be64(f, v->u64[0]);
- qemu_put_be64(f, v->u64[1]);
-}
-
-static const VMStateInfo vmstate_info_avr = {
- .name = "avr",
- .get = get_avr,
- .put = put_avr,
-};
-
-#define VMSTATE_AVR_ARRAY_V(_f, _s, _n, _v) \
- VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_avr, ppc_avr_t)
-
-#define VMSTATE_AVR_ARRAY(_f, _s, _n) \
- VMSTATE_AVR_ARRAY_V(_f, _s, _n, 0)
-
-static bool cpu_pre_2_8_migration(void *opaque, int version_id)
-{
- PowerPCCPU *cpu = opaque;
-
- return cpu->pre_2_8_migration;
-}
-
-static void cpu_pre_save(void *opaque)
-{
- PowerPCCPU *cpu = opaque;
- CPUPPCState *env = &cpu->env;
- int i;
- uint64_t insns_compat_mask =
- PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB
- | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES
- | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES
- | PPC_FLOAT_STFIWX | PPC_FLOAT_EXT
- | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ
- | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC
- | PPC_64B | PPC_64BX | PPC_ALTIVEC
- | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD;
- uint64_t insns_compat_mask2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX
- | PPC2_PERM_ISA206 | PPC2_DIVE_ISA206
- | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206
- | PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207
- | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207
- | PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_TM;
-
- env->spr[SPR_LR] = env->lr;
- env->spr[SPR_CTR] = env->ctr;
- env->spr[SPR_XER] = cpu_read_xer(env);
-#if defined(TARGET_PPC64)
- env->spr[SPR_CFAR] = env->cfar;
-#endif
- env->spr[SPR_BOOKE_SPEFSCR] = env->spe_fscr;
-
- for (i = 0; (i < 4) && (i < env->nb_BATs); i++) {
- env->spr[SPR_DBAT0U + 2*i] = env->DBAT[0][i];
- env->spr[SPR_DBAT0U + 2*i + 1] = env->DBAT[1][i];
- env->spr[SPR_IBAT0U + 2*i] = env->IBAT[0][i];
- env->spr[SPR_IBAT0U + 2*i + 1] = env->IBAT[1][i];
- }
- for (i = 0; (i < 4) && ((i+4) < env->nb_BATs); i++) {
- env->spr[SPR_DBAT4U + 2*i] = env->DBAT[0][i+4];
- env->spr[SPR_DBAT4U + 2*i + 1] = env->DBAT[1][i+4];
- env->spr[SPR_IBAT4U + 2*i] = env->IBAT[0][i+4];
- env->spr[SPR_IBAT4U + 2*i + 1] = env->IBAT[1][i+4];
- }
-
- /* Hacks for migration compatibility between 2.6, 2.7 & 2.8 */
- if (cpu->pre_2_8_migration) {
- cpu->mig_msr_mask = env->msr_mask;
- cpu->mig_insns_flags = env->insns_flags & insns_compat_mask;
- cpu->mig_insns_flags2 = env->insns_flags2 & insns_compat_mask2;
- cpu->mig_nb_BATs = env->nb_BATs;
- }
-}
-
-static int cpu_post_load(void *opaque, int version_id)
-{
- PowerPCCPU *cpu = opaque;
- CPUPPCState *env = &cpu->env;
- int i;
- target_ulong msr;
-
- /*
- * We always ignore the source PVR. The user or management
- * software has to take care of running QEMU in a compatible mode.
- */
- env->spr[SPR_PVR] = env->spr_cb[SPR_PVR].default_value;
- env->lr = env->spr[SPR_LR];
- env->ctr = env->spr[SPR_CTR];
- cpu_write_xer(env, env->spr[SPR_XER]);
-#if defined(TARGET_PPC64)
- env->cfar = env->spr[SPR_CFAR];
-#endif
- env->spe_fscr = env->spr[SPR_BOOKE_SPEFSCR];
-
- for (i = 0; (i < 4) && (i < env->nb_BATs); i++) {
- env->DBAT[0][i] = env->spr[SPR_DBAT0U + 2*i];
- env->DBAT[1][i] = env->spr[SPR_DBAT0U + 2*i + 1];
- env->IBAT[0][i] = env->spr[SPR_IBAT0U + 2*i];
- env->IBAT[1][i] = env->spr[SPR_IBAT0U + 2*i + 1];
- }
- for (i = 0; (i < 4) && ((i+4) < env->nb_BATs); i++) {
- env->DBAT[0][i+4] = env->spr[SPR_DBAT4U + 2*i];
- env->DBAT[1][i+4] = env->spr[SPR_DBAT4U + 2*i + 1];
- env->IBAT[0][i+4] = env->spr[SPR_IBAT4U + 2*i];
- env->IBAT[1][i+4] = env->spr[SPR_IBAT4U + 2*i + 1];
- }
-
- if (!env->external_htab) {
- /* Restore htab_base and htab_mask variables */
- ppc_store_sdr1(env, env->spr[SPR_SDR1]);
- }
-
- /* Invalidate all msr bits except MSR_TGPR/MSR_HVB before restoring */
- msr = env->msr;
- env->msr ^= ~((1ULL << MSR_TGPR) | MSR_HVB);
- ppc_store_msr(env, msr);
-
- hreg_compute_mem_idx(env);
-
- return 0;
-}
-
-static bool fpu_needed(void *opaque)
-{
- PowerPCCPU *cpu = opaque;
-
- return (cpu->env.insns_flags & PPC_FLOAT);
-}
-
-static const VMStateDescription vmstate_fpu = {
- .name = "cpu/fpu",
- .version_id = 1,
- .minimum_version_id = 1,
- .needed = fpu_needed,
- .fields = (VMStateField[]) {
- VMSTATE_FLOAT64_ARRAY(env.fpr, PowerPCCPU, 32),
- VMSTATE_UINTTL(env.fpscr, PowerPCCPU),
- VMSTATE_END_OF_LIST()
- },
-};
-
-static bool altivec_needed(void *opaque)
-{
- PowerPCCPU *cpu = opaque;
-
- return (cpu->env.insns_flags & PPC_ALTIVEC);
-}
-
-static const VMStateDescription vmstate_altivec = {
- .name = "cpu/altivec",
- .version_id = 1,
- .minimum_version_id = 1,
- .needed = altivec_needed,
- .fields = (VMStateField[]) {
- VMSTATE_AVR_ARRAY(env.avr, PowerPCCPU, 32),
- VMSTATE_UINT32(env.vscr, PowerPCCPU),
- VMSTATE_END_OF_LIST()
- },
-};
-
-static bool vsx_needed(void *opaque)
-{
- PowerPCCPU *cpu = opaque;
-
- return (cpu->env.insns_flags2 & PPC2_VSX);
-}
-
-static const VMStateDescription vmstate_vsx = {
- .name = "cpu/vsx",
- .version_id = 1,
- .minimum_version_id = 1,
- .needed = vsx_needed,
- .fields = (VMStateField[]) {
- VMSTATE_UINT64_ARRAY(env.vsr, PowerPCCPU, 32),
- VMSTATE_END_OF_LIST()
- },
-};
-
-#ifdef TARGET_PPC64
-/* Transactional memory state */
-static bool tm_needed(void *opaque)
-{
- PowerPCCPU *cpu = opaque;
- CPUPPCState *env = &cpu->env;
- return msr_ts;
-}
-
-static const VMStateDescription vmstate_tm = {
- .name = "cpu/tm",
- .version_id = 1,
- .minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .needed = tm_needed,
- .fields = (VMStateField []) {
- VMSTATE_UINTTL_ARRAY(env.tm_gpr, PowerPCCPU, 32),
- VMSTATE_AVR_ARRAY(env.tm_vsr, PowerPCCPU, 64),
- VMSTATE_UINT64(env.tm_cr, PowerPCCPU),
- VMSTATE_UINT64(env.tm_lr, PowerPCCPU),
- VMSTATE_UINT64(env.tm_ctr, PowerPCCPU),
- VMSTATE_UINT64(env.tm_fpscr, PowerPCCPU),
- VMSTATE_UINT64(env.tm_amr, PowerPCCPU),
- VMSTATE_UINT64(env.tm_ppr, PowerPCCPU),
- VMSTATE_UINT64(env.tm_vrsave, PowerPCCPU),
- VMSTATE_UINT32(env.tm_vscr, PowerPCCPU),
- VMSTATE_UINT64(env.tm_dscr, PowerPCCPU),
- VMSTATE_UINT64(env.tm_tar, PowerPCCPU),
- VMSTATE_END_OF_LIST()
- },
-};
-#endif
-
-static bool sr_needed(void *opaque)
-{
-#ifdef TARGET_PPC64
- PowerPCCPU *cpu = opaque;
-
- return !(cpu->env.mmu_model & POWERPC_MMU_64);
-#else
- return true;
-#endif
-}
-
-static const VMStateDescription vmstate_sr = {
- .name = "cpu/sr",
- .version_id = 1,
- .minimum_version_id = 1,
- .needed = sr_needed,
- .fields = (VMStateField[]) {
- VMSTATE_UINTTL_ARRAY(env.sr, PowerPCCPU, 32),
- VMSTATE_END_OF_LIST()
- },
-};
-
-#ifdef TARGET_PPC64
-static int get_slbe(QEMUFile *f, void *pv, size_t size)
-{
- ppc_slb_t *v = pv;
-
- v->esid = qemu_get_be64(f);
- v->vsid = qemu_get_be64(f);
-
- return 0;
-}
-
-static void put_slbe(QEMUFile *f, void *pv, size_t size)
-{
- ppc_slb_t *v = pv;
-
- qemu_put_be64(f, v->esid);
- qemu_put_be64(f, v->vsid);
-}
-
-static const VMStateInfo vmstate_info_slbe = {
- .name = "slbe",
- .get = get_slbe,
- .put = put_slbe,
-};
-
-#define VMSTATE_SLB_ARRAY_V(_f, _s, _n, _v) \
- VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_slbe, ppc_slb_t)
-
-#define VMSTATE_SLB_ARRAY(_f, _s, _n) \
- VMSTATE_SLB_ARRAY_V(_f, _s, _n, 0)
-
-static bool slb_needed(void *opaque)
-{
- PowerPCCPU *cpu = opaque;
-
- /* We don't support any of the old segment table based 64-bit CPUs */
- return (cpu->env.mmu_model & POWERPC_MMU_64);
-}
-
-static int slb_post_load(void *opaque, int version_id)
-{
- PowerPCCPU *cpu = opaque;
- CPUPPCState *env = &cpu->env;
- int i;
-
- /* We've pulled in the raw esid and vsid values from the migration
- * stream, but we need to recompute the page size pointers */
- for (i = 0; i < env->slb_nr; i++) {
- if (ppc_store_slb(cpu, i, env->slb[i].esid, env->slb[i].vsid) < 0) {
- /* Migration source had bad values in its SLB */
- return -1;
- }
- }
-
- return 0;
-}
-
-static const VMStateDescription vmstate_slb = {
- .name = "cpu/slb",
- .version_id = 1,
- .minimum_version_id = 1,
- .needed = slb_needed,
- .post_load = slb_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_INT32_EQUAL(env.slb_nr, PowerPCCPU),
- VMSTATE_SLB_ARRAY(env.slb, PowerPCCPU, MAX_SLB_ENTRIES),
- VMSTATE_END_OF_LIST()
- }
-};
-#endif /* TARGET_PPC64 */
-
-static const VMStateDescription vmstate_tlb6xx_entry = {
- .name = "cpu/tlb6xx_entry",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINTTL(pte0, ppc6xx_tlb_t),
- VMSTATE_UINTTL(pte1, ppc6xx_tlb_t),
- VMSTATE_UINTTL(EPN, ppc6xx_tlb_t),
- VMSTATE_END_OF_LIST()
- },
-};
-
-static bool tlb6xx_needed(void *opaque)
-{
- PowerPCCPU *cpu = opaque;
- CPUPPCState *env = &cpu->env;
-
- return env->nb_tlb && (env->tlb_type == TLB_6XX);
-}
-
-static const VMStateDescription vmstate_tlb6xx = {
- .name = "cpu/tlb6xx",
- .version_id = 1,
- .minimum_version_id = 1,
- .needed = tlb6xx_needed,
- .fields = (VMStateField[]) {
- VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU),
- VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlb6, PowerPCCPU,
- env.nb_tlb,
- vmstate_tlb6xx_entry,
- ppc6xx_tlb_t),
- VMSTATE_UINTTL_ARRAY(env.tgpr, PowerPCCPU, 4),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static const VMStateDescription vmstate_tlbemb_entry = {
- .name = "cpu/tlbemb_entry",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT64(RPN, ppcemb_tlb_t),
- VMSTATE_UINTTL(EPN, ppcemb_tlb_t),
- VMSTATE_UINTTL(PID, ppcemb_tlb_t),
- VMSTATE_UINTTL(size, ppcemb_tlb_t),
- VMSTATE_UINT32(prot, ppcemb_tlb_t),
- VMSTATE_UINT32(attr, ppcemb_tlb_t),
- VMSTATE_END_OF_LIST()
- },
-};
-
-static bool tlbemb_needed(void *opaque)
-{
- PowerPCCPU *cpu = opaque;
- CPUPPCState *env = &cpu->env;
-
- return env->nb_tlb && (env->tlb_type == TLB_EMB);
-}
-
-static bool pbr403_needed(void *opaque)
-{
- PowerPCCPU *cpu = opaque;
- uint32_t pvr = cpu->env.spr[SPR_PVR];
-
- return (pvr & 0xffff0000) == 0x00200000;
-}
-
-static const VMStateDescription vmstate_pbr403 = {
- .name = "cpu/pbr403",
- .version_id = 1,
- .minimum_version_id = 1,
- .needed = pbr403_needed,
- .fields = (VMStateField[]) {
- VMSTATE_UINTTL_ARRAY(env.pb, PowerPCCPU, 4),
- VMSTATE_END_OF_LIST()
- },
-};
-
-static const VMStateDescription vmstate_tlbemb = {
- .name = "cpu/tlb6xx",
- .version_id = 1,
- .minimum_version_id = 1,
- .needed = tlbemb_needed,
- .fields = (VMStateField[]) {
- VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU),
- VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlbe, PowerPCCPU,
- env.nb_tlb,
- vmstate_tlbemb_entry,
- ppcemb_tlb_t),
- /* 403 protection registers */
- VMSTATE_END_OF_LIST()
- },
- .subsections = (const VMStateDescription*[]) {
- &vmstate_pbr403,
- NULL
- }
-};
-
-static const VMStateDescription vmstate_tlbmas_entry = {
- .name = "cpu/tlbmas_entry",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField[]) {
- VMSTATE_UINT32(mas8, ppcmas_tlb_t),
- VMSTATE_UINT32(mas1, ppcmas_tlb_t),
- VMSTATE_UINT64(mas2, ppcmas_tlb_t),
- VMSTATE_UINT64(mas7_3, ppcmas_tlb_t),
- VMSTATE_END_OF_LIST()
- },
-};
-
-static bool tlbmas_needed(void *opaque)
-{
- PowerPCCPU *cpu = opaque;
- CPUPPCState *env = &cpu->env;
-
- return env->nb_tlb && (env->tlb_type == TLB_MAS);
-}
-
-static const VMStateDescription vmstate_tlbmas = {
- .name = "cpu/tlbmas",
- .version_id = 1,
- .minimum_version_id = 1,
- .needed = tlbmas_needed,
- .fields = (VMStateField[]) {
- VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU),
- VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlbm, PowerPCCPU,
- env.nb_tlb,
- vmstate_tlbmas_entry,
- ppcmas_tlb_t),
- VMSTATE_END_OF_LIST()
- }
-};
-
-const VMStateDescription vmstate_ppc_cpu = {
- .name = "cpu",
- .version_id = 5,
- .minimum_version_id = 5,
- .minimum_version_id_old = 4,
- .load_state_old = cpu_load_old,
- .pre_save = cpu_pre_save,
- .post_load = cpu_post_load,
- .fields = (VMStateField[]) {
- VMSTATE_UNUSED(sizeof(target_ulong)), /* was _EQUAL(env.spr[SPR_PVR]) */
-
- /* User mode architected state */
- VMSTATE_UINTTL_ARRAY(env.gpr, PowerPCCPU, 32),
-#if !defined(TARGET_PPC64)
- VMSTATE_UINTTL_ARRAY(env.gprh, PowerPCCPU, 32),
-#endif
- VMSTATE_UINT32_ARRAY(env.crf, PowerPCCPU, 8),
- VMSTATE_UINTTL(env.nip, PowerPCCPU),
-
- /* SPRs */
- VMSTATE_UINTTL_ARRAY(env.spr, PowerPCCPU, 1024),
- VMSTATE_UINT64(env.spe_acc, PowerPCCPU),
-
- /* Reservation */
- VMSTATE_UINTTL(env.reserve_addr, PowerPCCPU),
-
- /* Supervisor mode architected state */
- VMSTATE_UINTTL(env.msr, PowerPCCPU),
-
- /* Internal state */
- VMSTATE_UINTTL(env.hflags_nmsr, PowerPCCPU),
- /* FIXME: access_type? */
-
- /* Sanity checking */
- VMSTATE_UINTTL_TEST(mig_msr_mask, PowerPCCPU, cpu_pre_2_8_migration),
- VMSTATE_UINT64_TEST(mig_insns_flags, PowerPCCPU, cpu_pre_2_8_migration),
- VMSTATE_UINT64_TEST(mig_insns_flags2, PowerPCCPU,
- cpu_pre_2_8_migration),
- VMSTATE_UINT32_TEST(mig_nb_BATs, PowerPCCPU, cpu_pre_2_8_migration),
- VMSTATE_END_OF_LIST()
- },
- .subsections = (const VMStateDescription*[]) {
- &vmstate_fpu,
- &vmstate_altivec,
- &vmstate_vsx,
- &vmstate_sr,
-#ifdef TARGET_PPC64
- &vmstate_tm,
- &vmstate_slb,
-#endif /* TARGET_PPC64 */
- &vmstate_tlb6xx,
- &vmstate_tlbemb,
- &vmstate_tlbmas,
- NULL
- }
-};
diff --git a/target-ppc/mem_helper.c b/target-ppc/mem_helper.c
deleted file mode 100644
index 1ab8a6eab4..0000000000
--- a/target-ppc/mem_helper.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * PowerPC memory access emulation helpers for QEMU.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "qemu/host-utils.h"
-#include "exec/helper-proto.h"
-
-#include "helper_regs.h"
-#include "exec/cpu_ldst.h"
-
-//#define DEBUG_OP
-
-static inline bool needs_byteswap(const CPUPPCState *env)
-{
-#if defined(TARGET_WORDS_BIGENDIAN)
- return msr_le;
-#else
- return !msr_le;
-#endif
-}
-
-/*****************************************************************************/
-/* Memory load and stores */
-
-static inline target_ulong addr_add(CPUPPCState *env, target_ulong addr,
- target_long arg)
-{
-#if defined(TARGET_PPC64)
- if (!msr_is_64bit(env, env->msr)) {
- return (uint32_t)(addr + arg);
- } else
-#endif
- {
- return addr + arg;
- }
-}
-
-void helper_lmw(CPUPPCState *env, target_ulong addr, uint32_t reg)
-{
- for (; reg < 32; reg++) {
- if (needs_byteswap(env)) {
- env->gpr[reg] = bswap32(cpu_ldl_data_ra(env, addr, GETPC()));
- } else {
- env->gpr[reg] = cpu_ldl_data_ra(env, addr, GETPC());
- }
- addr = addr_add(env, addr, 4);
- }
-}
-
-void helper_stmw(CPUPPCState *env, target_ulong addr, uint32_t reg)
-{
- for (; reg < 32; reg++) {
- if (needs_byteswap(env)) {
- cpu_stl_data_ra(env, addr, bswap32((uint32_t)env->gpr[reg]),
- GETPC());
- } else {
- cpu_stl_data_ra(env, addr, (uint32_t)env->gpr[reg], GETPC());
- }
- addr = addr_add(env, addr, 4);
- }
-}
-
-static void do_lsw(CPUPPCState *env, target_ulong addr, uint32_t nb,
- uint32_t reg, uintptr_t raddr)
-{
- int sh;
-
- for (; nb > 3; nb -= 4) {
- env->gpr[reg] = cpu_ldl_data_ra(env, addr, raddr);
- reg = (reg + 1) % 32;
- addr = addr_add(env, addr, 4);
- }
- if (unlikely(nb > 0)) {
- env->gpr[reg] = 0;
- for (sh = 24; nb > 0; nb--, sh -= 8) {
- env->gpr[reg] |= cpu_ldub_data_ra(env, addr, raddr) << sh;
- addr = addr_add(env, addr, 1);
- }
- }
-}
-
-void helper_lsw(CPUPPCState *env, target_ulong addr, uint32_t nb, uint32_t reg)
-{
- do_lsw(env, addr, nb, reg, GETPC());
-}
-
-/* PPC32 specification says we must generate an exception if
- * rA is in the range of registers to be loaded.
- * In an other hand, IBM says this is valid, but rA won't be loaded.
- * For now, I'll follow the spec...
- */
-void helper_lswx(CPUPPCState *env, target_ulong addr, uint32_t reg,
- uint32_t ra, uint32_t rb)
-{
- if (likely(xer_bc != 0)) {
- int num_used_regs = (xer_bc + 3) / 4;
- if (unlikely((ra != 0 && lsw_reg_in_range(reg, num_used_regs, ra)) ||
- lsw_reg_in_range(reg, num_used_regs, rb))) {
- raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL |
- POWERPC_EXCP_INVAL_LSWX, GETPC());
- } else {
- do_lsw(env, addr, xer_bc, reg, GETPC());
- }
- }
-}
-
-void helper_stsw(CPUPPCState *env, target_ulong addr, uint32_t nb,
- uint32_t reg)
-{
- int sh;
-
- for (; nb > 3; nb -= 4) {
- cpu_stl_data_ra(env, addr, env->gpr[reg], GETPC());
- reg = (reg + 1) % 32;
- addr = addr_add(env, addr, 4);
- }
- if (unlikely(nb > 0)) {
- for (sh = 24; nb > 0; nb--, sh -= 8) {
- cpu_stb_data_ra(env, addr, (env->gpr[reg] >> sh) & 0xFF, GETPC());
- addr = addr_add(env, addr, 1);
- }
- }
-}
-
-void helper_dcbz(CPUPPCState *env, target_ulong addr, uint32_t opcode)
-{
- target_ulong mask, dcbz_size = env->dcache_line_size;
- uint32_t i;
- void *haddr;
-
-#if defined(TARGET_PPC64)
- /* Check for dcbz vs dcbzl on 970 */
- if (env->excp_model == POWERPC_EXCP_970 &&
- !(opcode & 0x00200000) && ((env->spr[SPR_970_HID5] >> 7) & 0x3) == 1) {
- dcbz_size = 32;
- }
-#endif
-
- /* Align address */
- mask = ~(dcbz_size - 1);
- addr &= mask;
-
- /* Check reservation */
- if ((env->reserve_addr & mask) == (addr & mask)) {
- env->reserve_addr = (target_ulong)-1ULL;
- }
-
- /* Try fast path translate */
- haddr = tlb_vaddr_to_host(env, addr, MMU_DATA_STORE, env->dmmu_idx);
- if (haddr) {
- memset(haddr, 0, dcbz_size);
- } else {
- /* Slow path */
- for (i = 0; i < dcbz_size; i += 8) {
- cpu_stq_data_ra(env, addr + i, 0, GETPC());
- }
- }
-}
-
-void helper_icbi(CPUPPCState *env, target_ulong addr)
-{
- addr &= ~(env->dcache_line_size - 1);
- /* Invalidate one cache line :
- * PowerPC specification says this is to be treated like a load
- * (not a fetch) by the MMU. To be sure it will be so,
- * do the load "by hand".
- */
- cpu_ldl_data_ra(env, addr, GETPC());
-}
-
-/* XXX: to be tested */
-target_ulong helper_lscbx(CPUPPCState *env, target_ulong addr, uint32_t reg,
- uint32_t ra, uint32_t rb)
-{
- int i, c, d;
-
- d = 24;
- for (i = 0; i < xer_bc; i++) {
- c = cpu_ldub_data_ra(env, addr, GETPC());
- addr = addr_add(env, addr, 1);
- /* ra (if not 0) and rb are never modified */
- if (likely(reg != rb && (ra == 0 || reg != ra))) {
- env->gpr[reg] = (env->gpr[reg] & ~(0xFF << d)) | (c << d);
- }
- if (unlikely(c == xer_cmp)) {
- break;
- }
- if (likely(d != 0)) {
- d -= 8;
- } else {
- d = 24;
- reg++;
- reg = reg & 0x1F;
- }
- }
- return i;
-}
-
-/*****************************************************************************/
-/* Altivec extension helpers */
-#if defined(HOST_WORDS_BIGENDIAN)
-#define HI_IDX 0
-#define LO_IDX 1
-#else
-#define HI_IDX 1
-#define LO_IDX 0
-#endif
-
-/* We use msr_le to determine index ordering in a vector. However,
- byteswapping is not simply controlled by msr_le. We also need to take
- into account endianness of the target. This is done for the little-endian
- PPC64 user-mode target. */
-
-#define LVE(name, access, swap, element) \
- void helper_##name(CPUPPCState *env, ppc_avr_t *r, \
- target_ulong addr) \
- { \
- size_t n_elems = ARRAY_SIZE(r->element); \
- int adjust = HI_IDX*(n_elems - 1); \
- int sh = sizeof(r->element[0]) >> 1; \
- int index = (addr & 0xf) >> sh; \
- if (msr_le) { \
- index = n_elems - index - 1; \
- } \
- \
- if (needs_byteswap(env)) { \
- r->element[LO_IDX ? index : (adjust - index)] = \
- swap(access(env, addr, GETPC())); \
- } else { \
- r->element[LO_IDX ? index : (adjust - index)] = \
- access(env, addr, GETPC()); \
- } \
- }
-#define I(x) (x)
-LVE(lvebx, cpu_ldub_data_ra, I, u8)
-LVE(lvehx, cpu_lduw_data_ra, bswap16, u16)
-LVE(lvewx, cpu_ldl_data_ra, bswap32, u32)
-#undef I
-#undef LVE
-
-#define STVE(name, access, swap, element) \
- void helper_##name(CPUPPCState *env, ppc_avr_t *r, \
- target_ulong addr) \
- { \
- size_t n_elems = ARRAY_SIZE(r->element); \
- int adjust = HI_IDX * (n_elems - 1); \
- int sh = sizeof(r->element[0]) >> 1; \
- int index = (addr & 0xf) >> sh; \
- if (msr_le) { \
- index = n_elems - index - 1; \
- } \
- \
- if (needs_byteswap(env)) { \
- access(env, addr, swap(r->element[LO_IDX ? index : \
- (adjust - index)]), \
- GETPC()); \
- } else { \
- access(env, addr, r->element[LO_IDX ? index : \
- (adjust - index)], GETPC()); \
- } \
- }
-#define I(x) (x)
-STVE(stvebx, cpu_stb_data_ra, I, u8)
-STVE(stvehx, cpu_stw_data_ra, bswap16, u16)
-STVE(stvewx, cpu_stl_data_ra, bswap32, u32)
-#undef I
-#undef LVE
-
-#undef HI_IDX
-#undef LO_IDX
-
-void helper_tbegin(CPUPPCState *env)
-{
- /* As a degenerate implementation, always fail tbegin. The reason
- * given is "Nesting overflow". The "persistent" bit is set,
- * providing a hint to the error handler to not retry. The TFIAR
- * captures the address of the failure, which is this tbegin
- * instruction. Instruction execution will continue with the
- * next instruction in memory, which is precisely what we want.
- */
-
- env->spr[SPR_TEXASR] =
- (1ULL << TEXASR_FAILURE_PERSISTENT) |
- (1ULL << TEXASR_NESTING_OVERFLOW) |
- (msr_hv << TEXASR_PRIVILEGE_HV) |
- (msr_pr << TEXASR_PRIVILEGE_PR) |
- (1ULL << TEXASR_FAILURE_SUMMARY) |
- (1ULL << TEXASR_TFIAR_EXACT);
- env->spr[SPR_TFIAR] = env->nip | (msr_hv << 1) | msr_pr;
- env->spr[SPR_TFHAR] = env->nip + 4;
- env->crf[0] = 0xB; /* 0b1010 = transaction failure */
-}
diff --git a/target-ppc/mfrom_table.c b/target-ppc/mfrom_table.c
deleted file mode 100644
index 6a1fa375c9..0000000000
--- a/target-ppc/mfrom_table.c
+++ /dev/null
@@ -1,79 +0,0 @@
-static const uint8_t mfrom_ROM_table[602] =
-{
- 77, 77, 76, 76, 75, 75, 74, 74,
- 73, 73, 72, 72, 71, 71, 70, 70,
- 69, 69, 68, 68, 68, 67, 67, 66,
- 66, 65, 65, 64, 64, 64, 63, 63,
- 62, 62, 61, 61, 61, 60, 60, 59,
- 59, 58, 58, 58, 57, 57, 56, 56,
- 56, 55, 55, 54, 54, 54, 53, 53,
- 53, 52, 52, 51, 51, 51, 50, 50,
- 50, 49, 49, 49, 48, 48, 47, 47,
- 47, 46, 46, 46, 45, 45, 45, 44,
- 44, 44, 43, 43, 43, 42, 42, 42,
- 42, 41, 41, 41, 40, 40, 40, 39,
- 39, 39, 39, 38, 38, 38, 37, 37,
- 37, 37, 36, 36, 36, 35, 35, 35,
- 35, 34, 34, 34, 34, 33, 33, 33,
- 33, 32, 32, 32, 32, 31, 31, 31,
- 31, 30, 30, 30, 30, 29, 29, 29,
- 29, 28, 28, 28, 28, 28, 27, 27,
- 27, 27, 26, 26, 26, 26, 26, 25,
- 25, 25, 25, 25, 24, 24, 24, 24,
- 24, 23, 23, 23, 23, 23, 23, 22,
- 22, 22, 22, 22, 21, 21, 21, 21,
- 21, 21, 20, 20, 20, 20, 20, 20,
- 19, 19, 19, 19, 19, 19, 19, 18,
- 18, 18, 18, 18, 18, 17, 17, 17,
- 17, 17, 17, 17, 16, 16, 16, 16,
- 16, 16, 16, 16, 15, 15, 15, 15,
- 15, 15, 15, 15, 14, 14, 14, 14,
- 14, 14, 14, 14, 13, 13, 13, 13,
- 13, 13, 13, 13, 13, 12, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 11,
- 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 9, 9, 9,
- 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8,
- 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 3,
- 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 0,
-};
diff --git a/target-ppc/mfrom_table_gen.c b/target-ppc/mfrom_table_gen.c
deleted file mode 100644
index 631791808e..0000000000
--- a/target-ppc/mfrom_table_gen.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#define _GNU_SOURCE
-#include "qemu/osdep.h"
-#include <math.h>
-
-int main (void)
-{
- double d;
- uint8_t n;
- int i;
-
- printf("static const uint8_t mfrom_ROM_table[602] =\n{\n ");
- for (i = 0; i < 602; i++) {
- /* Extremely decomposed:
- * -T0 / 256
- * T0 = 256 * log10(10 + 1.0) + 0.5
- */
- d = -i;
- d /= 256.0;
- d = exp10(d);
- d += 1.0;
- d = log10(d);
- d *= 256;
- d += 0.5;
- n = d;
- printf("%3d, ", n);
- if ((i & 7) == 7)
- printf("\n ");
- }
- printf("\n};\n");
-
- return 0;
-}
diff --git a/target-ppc/misc_helper.c b/target-ppc/misc_helper.c
deleted file mode 100644
index 1e6e705a4e..0000000000
--- a/target-ppc/misc_helper.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Miscellaneous PowerPC emulation helpers for QEMU.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "exec/helper-proto.h"
-
-#include "helper_regs.h"
-
-/*****************************************************************************/
-/* SPR accesses */
-void helper_load_dump_spr(CPUPPCState *env, uint32_t sprn)
-{
- qemu_log("Read SPR %d %03x => " TARGET_FMT_lx "\n", sprn, sprn,
- env->spr[sprn]);
-}
-
-void helper_store_dump_spr(CPUPPCState *env, uint32_t sprn)
-{
- qemu_log("Write SPR %d %03x <= " TARGET_FMT_lx "\n", sprn, sprn,
- env->spr[sprn]);
-}
-
-#ifdef TARGET_PPC64
-static void raise_fu_exception(CPUPPCState *env, uint32_t bit,
- uint32_t sprn, uint32_t cause,
- uintptr_t raddr)
-{
- qemu_log("Facility SPR %d is unavailable (SPR FSCR:%d)\n", sprn, bit);
-
- env->spr[SPR_FSCR] &= ~((target_ulong)FSCR_IC_MASK << FSCR_IC_POS);
- cause &= FSCR_IC_MASK;
- env->spr[SPR_FSCR] |= (target_ulong)cause << FSCR_IC_POS;
-
- raise_exception_err_ra(env, POWERPC_EXCP_FU, 0, raddr);
-}
-#endif
-
-void helper_fscr_facility_check(CPUPPCState *env, uint32_t bit,
- uint32_t sprn, uint32_t cause)
-{
-#ifdef TARGET_PPC64
- if (env->spr[SPR_FSCR] & (1ULL << bit)) {
- /* Facility is enabled, continue */
- return;
- }
- raise_fu_exception(env, bit, sprn, cause, GETPC());
-#endif
-}
-
-void helper_msr_facility_check(CPUPPCState *env, uint32_t bit,
- uint32_t sprn, uint32_t cause)
-{
-#ifdef TARGET_PPC64
- if (env->msr & (1ULL << bit)) {
- /* Facility is enabled, continue */
- return;
- }
- raise_fu_exception(env, bit, sprn, cause, GETPC());
-#endif
-}
-
-#if !defined(CONFIG_USER_ONLY)
-
-void helper_store_sdr1(CPUPPCState *env, target_ulong val)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
-
- if (!env->external_htab) {
- if (env->spr[SPR_SDR1] != val) {
- ppc_store_sdr1(env, val);
- tlb_flush(CPU(cpu), 1);
- }
- }
-}
-
-void helper_store_hid0_601(CPUPPCState *env, target_ulong val)
-{
- target_ulong hid0;
-
- hid0 = env->spr[SPR_HID0];
- if ((val ^ hid0) & 0x00000008) {
- /* Change current endianness */
- env->hflags &= ~(1 << MSR_LE);
- env->hflags_nmsr &= ~(1 << MSR_LE);
- env->hflags_nmsr |= (1 << MSR_LE) & (((val >> 3) & 1) << MSR_LE);
- env->hflags |= env->hflags_nmsr;
- qemu_log("%s: set endianness to %c => " TARGET_FMT_lx "\n", __func__,
- val & 0x8 ? 'l' : 'b', env->hflags);
- }
- env->spr[SPR_HID0] = (uint32_t)val;
-}
-
-void helper_store_403_pbr(CPUPPCState *env, uint32_t num, target_ulong value)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
-
- if (likely(env->pb[num] != value)) {
- env->pb[num] = value;
- /* Should be optimized */
- tlb_flush(CPU(cpu), 1);
- }
-}
-
-void helper_store_40x_dbcr0(CPUPPCState *env, target_ulong val)
-{
- store_40x_dbcr0(env, val);
-}
-
-void helper_store_40x_sler(CPUPPCState *env, target_ulong val)
-{
- store_40x_sler(env, val);
-}
-#endif
-/*****************************************************************************/
-/* PowerPC 601 specific instructions (POWER bridge) */
-
-target_ulong helper_clcs(CPUPPCState *env, uint32_t arg)
-{
- switch (arg) {
- case 0x0CUL:
- /* Instruction cache line size */
- return env->icache_line_size;
- break;
- case 0x0DUL:
- /* Data cache line size */
- return env->dcache_line_size;
- break;
- case 0x0EUL:
- /* Minimum cache line size */
- return (env->icache_line_size < env->dcache_line_size) ?
- env->icache_line_size : env->dcache_line_size;
- break;
- case 0x0FUL:
- /* Maximum cache line size */
- return (env->icache_line_size > env->dcache_line_size) ?
- env->icache_line_size : env->dcache_line_size;
- break;
- default:
- /* Undefined */
- return 0;
- break;
- }
-}
-
-/*****************************************************************************/
-/* Special registers manipulation */
-
-/* GDBstub can read and write MSR... */
-void ppc_store_msr(CPUPPCState *env, target_ulong value)
-{
- hreg_store_msr(env, value, 0);
-}
-
-/* This code is lifted from MacOnLinux. It is called whenever
- * THRM1,2 or 3 is read an fixes up the values in such a way
- * that will make MacOS not hang. These registers exist on some
- * 75x and 74xx processors.
- */
-void helper_fixup_thrm(CPUPPCState *env)
-{
- target_ulong v, t;
- int i;
-
-#define THRM1_TIN (1 << 31)
-#define THRM1_TIV (1 << 30)
-#define THRM1_THRES(x) (((x) & 0x7f) << 23)
-#define THRM1_TID (1 << 2)
-#define THRM1_TIE (1 << 1)
-#define THRM1_V (1 << 0)
-#define THRM3_E (1 << 0)
-
- if (!(env->spr[SPR_THRM3] & THRM3_E)) {
- return;
- }
-
- /* Note: Thermal interrupts are unimplemented */
- for (i = SPR_THRM1; i <= SPR_THRM2; i++) {
- v = env->spr[i];
- if (!(v & THRM1_V)) {
- continue;
- }
- v |= THRM1_TIV;
- v &= ~THRM1_TIN;
- t = v & THRM1_THRES(127);
- if ((v & THRM1_TID) && t < THRM1_THRES(24)) {
- v |= THRM1_TIN;
- }
- if (!(v & THRM1_TID) && t > THRM1_THRES(24)) {
- v |= THRM1_TIN;
- }
- env->spr[i] = v;
- }
-}
diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c
deleted file mode 100644
index 29bace622a..0000000000
--- a/target-ppc/mmu-hash32.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * PowerPC MMU, TLB and BAT emulation helpers for QEMU.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- * Copyright (c) 2013 David Gibson, IBM Corporation
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "exec/helper-proto.h"
-#include "sysemu/kvm.h"
-#include "kvm_ppc.h"
-#include "mmu-hash32.h"
-#include "exec/log.h"
-
-//#define DEBUG_BAT
-
-#ifdef DEBUG_BATS
-# define LOG_BATS(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__)
-#else
-# define LOG_BATS(...) do { } while (0)
-#endif
-
-struct mmu_ctx_hash32 {
- hwaddr raddr; /* Real address */
- int prot; /* Protection bits */
- int key; /* Access key */
-};
-
-static int ppc_hash32_pp_prot(int key, int pp, int nx)
-{
- int prot;
-
- if (key == 0) {
- switch (pp) {
- case 0x0:
- case 0x1:
- case 0x2:
- prot = PAGE_READ | PAGE_WRITE;
- break;
-
- case 0x3:
- prot = PAGE_READ;
- break;
-
- default:
- abort();
- }
- } else {
- switch (pp) {
- case 0x0:
- prot = 0;
- break;
-
- case 0x1:
- case 0x3:
- prot = PAGE_READ;
- break;
-
- case 0x2:
- prot = PAGE_READ | PAGE_WRITE;
- break;
-
- default:
- abort();
- }
- }
- if (nx == 0) {
- prot |= PAGE_EXEC;
- }
-
- return prot;
-}
-
-static int ppc_hash32_pte_prot(PowerPCCPU *cpu,
- target_ulong sr, ppc_hash_pte32_t pte)
-{
- CPUPPCState *env = &cpu->env;
- unsigned pp, key;
-
- key = !!(msr_pr ? (sr & SR32_KP) : (sr & SR32_KS));
- pp = pte.pte1 & HPTE32_R_PP;
-
- return ppc_hash32_pp_prot(key, pp, !!(sr & SR32_NX));
-}
-
-static target_ulong hash32_bat_size(PowerPCCPU *cpu,
- target_ulong batu, target_ulong batl)
-{
- CPUPPCState *env = &cpu->env;
-
- if ((msr_pr && !(batu & BATU32_VP))
- || (!msr_pr && !(batu & BATU32_VS))) {
- return 0;
- }
-
- return BATU32_BEPI & ~((batu & BATU32_BL) << 15);
-}
-
-static int hash32_bat_prot(PowerPCCPU *cpu,
- target_ulong batu, target_ulong batl)
-{
- int pp, prot;
-
- prot = 0;
- pp = batl & BATL32_PP;
- if (pp != 0) {
- prot = PAGE_READ | PAGE_EXEC;
- if (pp == 0x2) {
- prot |= PAGE_WRITE;
- }
- }
- return prot;
-}
-
-static target_ulong hash32_bat_601_size(PowerPCCPU *cpu,
- target_ulong batu, target_ulong batl)
-{
- if (!(batl & BATL32_601_V)) {
- return 0;
- }
-
- return BATU32_BEPI & ~((batl & BATL32_601_BL) << 17);
-}
-
-static int hash32_bat_601_prot(PowerPCCPU *cpu,
- target_ulong batu, target_ulong batl)
-{
- CPUPPCState *env = &cpu->env;
- int key, pp;
-
- pp = batu & BATU32_601_PP;
- if (msr_pr == 0) {
- key = !!(batu & BATU32_601_KS);
- } else {
- key = !!(batu & BATU32_601_KP);
- }
- return ppc_hash32_pp_prot(key, pp, 0);
-}
-
-static hwaddr ppc_hash32_bat_lookup(PowerPCCPU *cpu, target_ulong ea, int rwx,
- int *prot)
-{
- CPUPPCState *env = &cpu->env;
- target_ulong *BATlt, *BATut;
- int i;
-
- LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
- rwx == 2 ? 'I' : 'D', ea);
- if (rwx == 2) {
- BATlt = env->IBAT[1];
- BATut = env->IBAT[0];
- } else {
- BATlt = env->DBAT[1];
- BATut = env->DBAT[0];
- }
- for (i = 0; i < env->nb_BATs; i++) {
- target_ulong batu = BATut[i];
- target_ulong batl = BATlt[i];
- target_ulong mask;
-
- if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
- mask = hash32_bat_601_size(cpu, batu, batl);
- } else {
- mask = hash32_bat_size(cpu, batu, batl);
- }
- LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
- " BATl " TARGET_FMT_lx "\n", __func__,
- type == ACCESS_CODE ? 'I' : 'D', i, ea, batu, batl);
-
- if (mask && ((ea & mask) == (batu & BATU32_BEPI))) {
- hwaddr raddr = (batl & mask) | (ea & ~mask);
-
- if (unlikely(env->mmu_model == POWERPC_MMU_601)) {
- *prot = hash32_bat_601_prot(cpu, batu, batl);
- } else {
- *prot = hash32_bat_prot(cpu, batu, batl);
- }
-
- return raddr & TARGET_PAGE_MASK;
- }
- }
-
- /* No hit */
-#if defined(DEBUG_BATS)
- if (qemu_log_enabled()) {
- LOG_BATS("no BAT match for " TARGET_FMT_lx ":\n", ea);
- for (i = 0; i < 4; i++) {
- BATu = &BATut[i];
- BATl = &BATlt[i];
- BEPIu = *BATu & BATU32_BEPIU;
- BEPIl = *BATu & BATU32_BEPIL;
- bl = (*BATu & 0x00001FFC) << 15;
- LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
- " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
- TARGET_FMT_lx " " TARGET_FMT_lx "\n",
- __func__, type == ACCESS_CODE ? 'I' : 'D', i, ea,
- *BATu, *BATl, BEPIu, BEPIl, bl);
- }
- }
-#endif
-
- return -1;
-}
-
-static int ppc_hash32_direct_store(PowerPCCPU *cpu, target_ulong sr,
- target_ulong eaddr, int rwx,
- hwaddr *raddr, int *prot)
-{
- CPUState *cs = CPU(cpu);
- CPUPPCState *env = &cpu->env;
- int key = !!(msr_pr ? (sr & SR32_KP) : (sr & SR32_KS));
-
- qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
-
- if ((sr & 0x1FF00000) >> 20 == 0x07f) {
- /* Memory-forced I/O controller interface access */
- /* If T=1 and BUID=x'07F', the 601 performs a memory access
- * to SR[28-31] LA[4-31], bypassing all protection mechanisms.
- */
- *raddr = ((sr & 0xF) << 28) | (eaddr & 0x0FFFFFFF);
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- return 0;
- }
-
- if (rwx == 2) {
- /* No code fetch is allowed in direct-store areas */
- cs->exception_index = POWERPC_EXCP_ISI;
- env->error_code = 0x10000000;
- return 1;
- }
-
- switch (env->access_type) {
- case ACCESS_INT:
- /* Integer load/store : only access allowed */
- break;
- case ACCESS_FLOAT:
- /* Floating point load/store */
- cs->exception_index = POWERPC_EXCP_ALIGN;
- env->error_code = POWERPC_EXCP_ALIGN_FP;
- env->spr[SPR_DAR] = eaddr;
- return 1;
- case ACCESS_RES:
- /* lwarx, ldarx or srwcx. */
- env->error_code = 0;
- env->spr[SPR_DAR] = eaddr;
- if (rwx == 1) {
- env->spr[SPR_DSISR] = 0x06000000;
- } else {
- env->spr[SPR_DSISR] = 0x04000000;
- }
- return 1;
- case ACCESS_CACHE:
- /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
- /* Should make the instruction do no-op.
- * As it already do no-op, it's quite easy :-)
- */
- *raddr = eaddr;
- return 0;
- case ACCESS_EXT:
- /* eciwx or ecowx */
- cs->exception_index = POWERPC_EXCP_DSI;
- env->error_code = 0;
- env->spr[SPR_DAR] = eaddr;
- if (rwx == 1) {
- env->spr[SPR_DSISR] = 0x06100000;
- } else {
- env->spr[SPR_DSISR] = 0x04100000;
- }
- return 1;
- default:
- cpu_abort(cs, "ERROR: instruction should not need "
- "address translation\n");
- }
- if ((rwx == 1 || key != 1) && (rwx == 0 || key != 0)) {
- *raddr = eaddr;
- return 0;
- } else {
- cs->exception_index = POWERPC_EXCP_DSI;
- env->error_code = 0;
- env->spr[SPR_DAR] = eaddr;
- if (rwx == 1) {
- env->spr[SPR_DSISR] = 0x0a000000;
- } else {
- env->spr[SPR_DSISR] = 0x08000000;
- }
- return 1;
- }
-}
-
-hwaddr get_pteg_offset32(PowerPCCPU *cpu, hwaddr hash)
-{
- CPUPPCState *env = &cpu->env;
-
- return (hash * HASH_PTEG_SIZE_32) & env->htab_mask;
-}
-
-static hwaddr ppc_hash32_pteg_search(PowerPCCPU *cpu, hwaddr pteg_off,
- bool secondary, target_ulong ptem,
- ppc_hash_pte32_t *pte)
-{
- hwaddr pte_offset = pteg_off;
- target_ulong pte0, pte1;
- int i;
-
- for (i = 0; i < HPTES_PER_GROUP; i++) {
- pte0 = ppc_hash32_load_hpte0(cpu, pte_offset);
- pte1 = ppc_hash32_load_hpte1(cpu, pte_offset);
-
- if ((pte0 & HPTE32_V_VALID)
- && (secondary == !!(pte0 & HPTE32_V_SECONDARY))
- && HPTE32_V_COMPARE(pte0, ptem)) {
- pte->pte0 = pte0;
- pte->pte1 = pte1;
- return pte_offset;
- }
-
- pte_offset += HASH_PTE_SIZE_32;
- }
-
- return -1;
-}
-
-static hwaddr ppc_hash32_htab_lookup(PowerPCCPU *cpu,
- target_ulong sr, target_ulong eaddr,
- ppc_hash_pte32_t *pte)
-{
- CPUPPCState *env = &cpu->env;
- hwaddr pteg_off, pte_offset;
- hwaddr hash;
- uint32_t vsid, pgidx, ptem;
-
- vsid = sr & SR32_VSID;
- pgidx = (eaddr & ~SEGMENT_MASK_256M) >> TARGET_PAGE_BITS;
- hash = vsid ^ pgidx;
- ptem = (vsid << 7) | (pgidx >> 10);
-
- /* Page address translation */
- qemu_log_mask(CPU_LOG_MMU, "htab_base " TARGET_FMT_plx
- " htab_mask " TARGET_FMT_plx
- " hash " TARGET_FMT_plx "\n",
- env->htab_base, env->htab_mask, hash);
-
- /* Primary PTEG lookup */
- qemu_log_mask(CPU_LOG_MMU, "0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
- " vsid=%" PRIx32 " ptem=%" PRIx32
- " hash=" TARGET_FMT_plx "\n",
- env->htab_base, env->htab_mask, vsid, ptem, hash);
- pteg_off = get_pteg_offset32(cpu, hash);
- pte_offset = ppc_hash32_pteg_search(cpu, pteg_off, 0, ptem, pte);
- if (pte_offset == -1) {
- /* Secondary PTEG lookup */
- qemu_log_mask(CPU_LOG_MMU, "1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
- " vsid=%" PRIx32 " api=%" PRIx32
- " hash=" TARGET_FMT_plx "\n", env->htab_base,
- env->htab_mask, vsid, ptem, ~hash);
- pteg_off = get_pteg_offset32(cpu, ~hash);
- pte_offset = ppc_hash32_pteg_search(cpu, pteg_off, 1, ptem, pte);
- }
-
- return pte_offset;
-}
-
-static hwaddr ppc_hash32_pte_raddr(target_ulong sr, ppc_hash_pte32_t pte,
- target_ulong eaddr)
-{
- hwaddr rpn = pte.pte1 & HPTE32_R_RPN;
- hwaddr mask = ~TARGET_PAGE_MASK;
-
- return (rpn & ~mask) | (eaddr & mask);
-}
-
-int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr, int rwx,
- int mmu_idx)
-{
- CPUState *cs = CPU(cpu);
- CPUPPCState *env = &cpu->env;
- target_ulong sr;
- hwaddr pte_offset;
- ppc_hash_pte32_t pte;
- int prot;
- uint32_t new_pte1;
- const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
- hwaddr raddr;
-
- assert((rwx == 0) || (rwx == 1) || (rwx == 2));
-
- /* 1. Handle real mode accesses */
- if (((rwx == 2) && (msr_ir == 0)) || ((rwx != 2) && (msr_dr == 0))) {
- /* Translation is off */
- raddr = eaddr;
- tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
- PAGE_READ | PAGE_WRITE | PAGE_EXEC, mmu_idx,
- TARGET_PAGE_SIZE);
- return 0;
- }
-
- /* 2. Check Block Address Translation entries (BATs) */
- if (env->nb_BATs != 0) {
- raddr = ppc_hash32_bat_lookup(cpu, eaddr, rwx, &prot);
- if (raddr != -1) {
- if (need_prot[rwx] & ~prot) {
- if (rwx == 2) {
- cs->exception_index = POWERPC_EXCP_ISI;
- env->error_code = 0x08000000;
- } else {
- cs->exception_index = POWERPC_EXCP_DSI;
- env->error_code = 0;
- env->spr[SPR_DAR] = eaddr;
- if (rwx == 1) {
- env->spr[SPR_DSISR] = 0x0a000000;
- } else {
- env->spr[SPR_DSISR] = 0x08000000;
- }
- }
- return 1;
- }
-
- tlb_set_page(cs, eaddr & TARGET_PAGE_MASK,
- raddr & TARGET_PAGE_MASK, prot, mmu_idx,
- TARGET_PAGE_SIZE);
- return 0;
- }
- }
-
- /* 3. Look up the Segment Register */
- sr = env->sr[eaddr >> 28];
-
- /* 4. Handle direct store segments */
- if (sr & SR32_T) {
- if (ppc_hash32_direct_store(cpu, sr, eaddr, rwx,
- &raddr, &prot) == 0) {
- tlb_set_page(cs, eaddr & TARGET_PAGE_MASK,
- raddr & TARGET_PAGE_MASK, prot, mmu_idx,
- TARGET_PAGE_SIZE);
- return 0;
- } else {
- return 1;
- }
- }
-
- /* 5. Check for segment level no-execute violation */
- if ((rwx == 2) && (sr & SR32_NX)) {
- cs->exception_index = POWERPC_EXCP_ISI;
- env->error_code = 0x10000000;
- return 1;
- }
-
- /* 6. Locate the PTE in the hash table */
- pte_offset = ppc_hash32_htab_lookup(cpu, sr, eaddr, &pte);
- if (pte_offset == -1) {
- if (rwx == 2) {
- cs->exception_index = POWERPC_EXCP_ISI;
- env->error_code = 0x40000000;
- } else {
- cs->exception_index = POWERPC_EXCP_DSI;
- env->error_code = 0;
- env->spr[SPR_DAR] = eaddr;
- if (rwx == 1) {
- env->spr[SPR_DSISR] = 0x42000000;
- } else {
- env->spr[SPR_DSISR] = 0x40000000;
- }
- }
-
- return 1;
- }
- qemu_log_mask(CPU_LOG_MMU,
- "found PTE at offset %08" HWADDR_PRIx "\n", pte_offset);
-
- /* 7. Check access permissions */
-
- prot = ppc_hash32_pte_prot(cpu, sr, pte);
-
- if (need_prot[rwx] & ~prot) {
- /* Access right violation */
- qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
- if (rwx == 2) {
- cs->exception_index = POWERPC_EXCP_ISI;
- env->error_code = 0x08000000;
- } else {
- cs->exception_index = POWERPC_EXCP_DSI;
- env->error_code = 0;
- env->spr[SPR_DAR] = eaddr;
- if (rwx == 1) {
- env->spr[SPR_DSISR] = 0x0a000000;
- } else {
- env->spr[SPR_DSISR] = 0x08000000;
- }
- }
- return 1;
- }
-
- qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n");
-
- /* 8. Update PTE referenced and changed bits if necessary */
-
- new_pte1 = pte.pte1 | HPTE32_R_R; /* set referenced bit */
- if (rwx == 1) {
- new_pte1 |= HPTE32_R_C; /* set changed (dirty) bit */
- } else {
- /* Treat the page as read-only for now, so that a later write
- * will pass through this function again to set the C bit */
- prot &= ~PAGE_WRITE;
- }
-
- if (new_pte1 != pte.pte1) {
- ppc_hash32_store_hpte1(cpu, pte_offset, new_pte1);
- }
-
- /* 9. Determine the real address from the PTE */
-
- raddr = ppc_hash32_pte_raddr(sr, pte, eaddr);
-
- tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
- prot, mmu_idx, TARGET_PAGE_SIZE);
-
- return 0;
-}
-
-hwaddr ppc_hash32_get_phys_page_debug(PowerPCCPU *cpu, target_ulong eaddr)
-{
- CPUPPCState *env = &cpu->env;
- target_ulong sr;
- hwaddr pte_offset;
- ppc_hash_pte32_t pte;
- int prot;
-
- if (msr_dr == 0) {
- /* Translation is off */
- return eaddr;
- }
-
- if (env->nb_BATs != 0) {
- hwaddr raddr = ppc_hash32_bat_lookup(cpu, eaddr, 0, &prot);
- if (raddr != -1) {
- return raddr;
- }
- }
-
- sr = env->sr[eaddr >> 28];
-
- if (sr & SR32_T) {
- /* FIXME: Add suitable debug support for Direct Store segments */
- return -1;
- }
-
- pte_offset = ppc_hash32_htab_lookup(cpu, sr, eaddr, &pte);
- if (pte_offset == -1) {
- return -1;
- }
-
- return ppc_hash32_pte_raddr(sr, pte, eaddr) & TARGET_PAGE_MASK;
-}
diff --git a/target-ppc/mmu-hash32.h b/target-ppc/mmu-hash32.h
deleted file mode 100644
index 5b9fb08d1a..0000000000
--- a/target-ppc/mmu-hash32.h
+++ /dev/null
@@ -1,112 +0,0 @@
-#ifndef MMU_HASH32_H
-#define MMU_HASH32_H
-
-#ifndef CONFIG_USER_ONLY
-
-hwaddr get_pteg_offset32(PowerPCCPU *cpu, hwaddr hash);
-hwaddr ppc_hash32_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr);
-int ppc_hash32_handle_mmu_fault(PowerPCCPU *cpu, vaddr address, int rw,
- int mmu_idx);
-
-/*
- * Segment register definitions
- */
-
-#define SR32_T 0x80000000
-#define SR32_KS 0x40000000
-#define SR32_KP 0x20000000
-#define SR32_NX 0x10000000
-#define SR32_VSID 0x00ffffff
-
-/*
- * Block Address Translation (BAT) definitions
- */
-
-#define BATU32_BEPI 0xfffe0000
-#define BATU32_BL 0x00001ffc
-#define BATU32_VS 0x00000002
-#define BATU32_VP 0x00000001
-
-
-#define BATL32_BRPN 0xfffe0000
-#define BATL32_WIMG 0x00000078
-#define BATL32_PP 0x00000003
-
-/* PowerPC 601 has slightly different BAT registers */
-
-#define BATU32_601_KS 0x00000008
-#define BATU32_601_KP 0x00000004
-#define BATU32_601_PP 0x00000003
-
-#define BATL32_601_V 0x00000040
-#define BATL32_601_BL 0x0000003f
-
-/*
- * Hash page table definitions
- */
-
-#define HPTES_PER_GROUP 8
-#define HASH_PTE_SIZE_32 8
-#define HASH_PTEG_SIZE_32 (HASH_PTE_SIZE_32 * HPTES_PER_GROUP)
-
-#define HPTE32_V_VALID 0x80000000
-#define HPTE32_V_VSID 0x7fffff80
-#define HPTE32_V_SECONDARY 0x00000040
-#define HPTE32_V_API 0x0000003f
-#define HPTE32_V_COMPARE(x, y) (!(((x) ^ (y)) & 0x7fffffbf))
-
-#define HPTE32_R_RPN 0xfffff000
-#define HPTE32_R_R 0x00000100
-#define HPTE32_R_C 0x00000080
-#define HPTE32_R_W 0x00000040
-#define HPTE32_R_I 0x00000020
-#define HPTE32_R_M 0x00000010
-#define HPTE32_R_G 0x00000008
-#define HPTE32_R_WIMG 0x00000078
-#define HPTE32_R_PP 0x00000003
-
-static inline target_ulong ppc_hash32_load_hpte0(PowerPCCPU *cpu,
- hwaddr pte_offset)
-{
- CPUPPCState *env = &cpu->env;
-
- assert(!env->external_htab); /* Not supported on 32-bit for now */
- return ldl_phys(CPU(cpu)->as, env->htab_base + pte_offset);
-}
-
-static inline target_ulong ppc_hash32_load_hpte1(PowerPCCPU *cpu,
- hwaddr pte_offset)
-{
- CPUPPCState *env = &cpu->env;
-
- assert(!env->external_htab); /* Not supported on 32-bit for now */
- return ldl_phys(CPU(cpu)->as,
- env->htab_base + pte_offset + HASH_PTE_SIZE_32 / 2);
-}
-
-static inline void ppc_hash32_store_hpte0(PowerPCCPU *cpu,
- hwaddr pte_offset, target_ulong pte0)
-{
- CPUPPCState *env = &cpu->env;
-
- assert(!env->external_htab); /* Not supported on 32-bit for now */
- stl_phys(CPU(cpu)->as, env->htab_base + pte_offset, pte0);
-}
-
-static inline void ppc_hash32_store_hpte1(PowerPCCPU *cpu,
- hwaddr pte_offset, target_ulong pte1)
-{
- CPUPPCState *env = &cpu->env;
-
- assert(!env->external_htab); /* Not supported on 32-bit for now */
- stl_phys(CPU(cpu)->as,
- env->htab_base + pte_offset + HASH_PTE_SIZE_32 / 2, pte1);
-}
-
-typedef struct {
- uint32_t pte0, pte1;
-} ppc_hash_pte32_t;
-
-#endif /* CONFIG_USER_ONLY */
-
-#endif /* MMU_HASH32_H */
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
deleted file mode 100644
index fdb7a787bf..0000000000
--- a/target-ppc/mmu-hash64.c
+++ /dev/null
@@ -1,1059 +0,0 @@
-/*
- * PowerPC MMU, TLB, SLB and BAT emulation helpers for QEMU.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- * Copyright (c) 2013 David Gibson, IBM Corporation
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
-#include "exec/helper-proto.h"
-#include "qemu/error-report.h"
-#include "sysemu/kvm.h"
-#include "kvm_ppc.h"
-#include "mmu-hash64.h"
-#include "exec/log.h"
-
-//#define DEBUG_SLB
-
-#ifdef DEBUG_SLB
-# define LOG_SLB(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__)
-#else
-# define LOG_SLB(...) do { } while (0)
-#endif
-
-/*
- * Used to indicate that a CPU has its hash page table (HPT) managed
- * within the host kernel
- */
-#define MMU_HASH64_KVM_MANAGED_HPT ((void *)-1)
-
-/*
- * SLB handling
- */
-
-static ppc_slb_t *slb_lookup(PowerPCCPU *cpu, target_ulong eaddr)
-{
- CPUPPCState *env = &cpu->env;
- uint64_t esid_256M, esid_1T;
- int n;
-
- LOG_SLB("%s: eaddr " TARGET_FMT_lx "\n", __func__, eaddr);
-
- esid_256M = (eaddr & SEGMENT_MASK_256M) | SLB_ESID_V;
- esid_1T = (eaddr & SEGMENT_MASK_1T) | SLB_ESID_V;
-
- for (n = 0; n < env->slb_nr; n++) {
- ppc_slb_t *slb = &env->slb[n];
-
- LOG_SLB("%s: slot %d %016" PRIx64 " %016"
- PRIx64 "\n", __func__, n, slb->esid, slb->vsid);
- /* We check for 1T matches on all MMUs here - if the MMU
- * doesn't have 1T segment support, we will have prevented 1T
- * entries from being inserted in the slbmte code. */
- if (((slb->esid == esid_256M) &&
- ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_256M))
- || ((slb->esid == esid_1T) &&
- ((slb->vsid & SLB_VSID_B) == SLB_VSID_B_1T))) {
- return slb;
- }
- }
-
- return NULL;
-}
-
-void dump_slb(FILE *f, fprintf_function cpu_fprintf, PowerPCCPU *cpu)
-{
- CPUPPCState *env = &cpu->env;
- int i;
- uint64_t slbe, slbv;
-
- cpu_synchronize_state(CPU(cpu));
-
- cpu_fprintf(f, "SLB\tESID\t\t\tVSID\n");
- for (i = 0; i < env->slb_nr; i++) {
- slbe = env->slb[i].esid;
- slbv = env->slb[i].vsid;
- if (slbe == 0 && slbv == 0) {
- continue;
- }
- cpu_fprintf(f, "%d\t0x%016" PRIx64 "\t0x%016" PRIx64 "\n",
- i, slbe, slbv);
- }
-}
-
-void helper_slbia(CPUPPCState *env)
-{
- int n;
-
- /* XXX: Warning: slbia never invalidates the first segment */
- for (n = 1; n < env->slb_nr; n++) {
- ppc_slb_t *slb = &env->slb[n];
-
- if (slb->esid & SLB_ESID_V) {
- slb->esid &= ~SLB_ESID_V;
- /* XXX: given the fact that segment size is 256 MB or 1TB,
- * and we still don't have a tlb_flush_mask(env, n, mask)
- * in QEMU, we just invalidate all TLBs
- */
- env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH;
- }
- }
-}
-
-void helper_slbie(CPUPPCState *env, target_ulong addr)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- ppc_slb_t *slb;
-
- slb = slb_lookup(cpu, addr);
- if (!slb) {
- return;
- }
-
- if (slb->esid & SLB_ESID_V) {
- slb->esid &= ~SLB_ESID_V;
-
- /* XXX: given the fact that segment size is 256 MB or 1TB,
- * and we still don't have a tlb_flush_mask(env, n, mask)
- * in QEMU, we just invalidate all TLBs
- */
- env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH;
- }
-}
-
-int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot,
- target_ulong esid, target_ulong vsid)
-{
- CPUPPCState *env = &cpu->env;
- ppc_slb_t *slb = &env->slb[slot];
- const struct ppc_one_seg_page_size *sps = NULL;
- int i;
-
- if (slot >= env->slb_nr) {
- return -1; /* Bad slot number */
- }
- if (esid & ~(SLB_ESID_ESID | SLB_ESID_V)) {
- return -1; /* Reserved bits set */
- }
- if (vsid & (SLB_VSID_B & ~SLB_VSID_B_1T)) {
- return -1; /* Bad segment size */
- }
- if ((vsid & SLB_VSID_B) && !(env->mmu_model & POWERPC_MMU_1TSEG)) {
- return -1; /* 1T segment on MMU that doesn't support it */
- }
-
- for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
- const struct ppc_one_seg_page_size *sps1 = &env->sps.sps[i];
-
- if (!sps1->page_shift) {
- break;
- }
-
- if ((vsid & SLB_VSID_LLP_MASK) == sps1->slb_enc) {
- sps = sps1;
- break;
- }
- }
-
- if (!sps) {
- error_report("Bad page size encoding in SLB store: slot "TARGET_FMT_lu
- " esid 0x"TARGET_FMT_lx" vsid 0x"TARGET_FMT_lx,
- slot, esid, vsid);
- return -1;
- }
-
- slb->esid = esid;
- slb->vsid = vsid;
- slb->sps = sps;
-
- LOG_SLB("%s: %d " TARGET_FMT_lx " - " TARGET_FMT_lx " => %016" PRIx64
- " %016" PRIx64 "\n", __func__, slot, esid, vsid,
- slb->esid, slb->vsid);
-
- return 0;
-}
-
-static int ppc_load_slb_esid(PowerPCCPU *cpu, target_ulong rb,
- target_ulong *rt)
-{
- CPUPPCState *env = &cpu->env;
- int slot = rb & 0xfff;
- ppc_slb_t *slb = &env->slb[slot];
-
- if (slot >= env->slb_nr) {
- return -1;
- }
-
- *rt = slb->esid;
- return 0;
-}
-
-static int ppc_load_slb_vsid(PowerPCCPU *cpu, target_ulong rb,
- target_ulong *rt)
-{
- CPUPPCState *env = &cpu->env;
- int slot = rb & 0xfff;
- ppc_slb_t *slb = &env->slb[slot];
-
- if (slot >= env->slb_nr) {
- return -1;
- }
-
- *rt = slb->vsid;
- return 0;
-}
-
-static int ppc_find_slb_vsid(PowerPCCPU *cpu, target_ulong rb,
- target_ulong *rt)
-{
- CPUPPCState *env = &cpu->env;
- ppc_slb_t *slb;
-
- if (!msr_is_64bit(env, env->msr)) {
- rb &= 0xffffffff;
- }
- slb = slb_lookup(cpu, rb);
- if (slb == NULL) {
- *rt = (target_ulong)-1ul;
- } else {
- *rt = slb->vsid;
- }
- return 0;
-}
-
-void helper_store_slb(CPUPPCState *env, target_ulong rb, target_ulong rs)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
-
- if (ppc_store_slb(cpu, rb & 0xfff, rb & ~0xfffULL, rs) < 0) {
- raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL, GETPC());
- }
-}
-
-target_ulong helper_load_slb_esid(CPUPPCState *env, target_ulong rb)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- target_ulong rt = 0;
-
- if (ppc_load_slb_esid(cpu, rb, &rt) < 0) {
- raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL, GETPC());
- }
- return rt;
-}
-
-target_ulong helper_find_slb_vsid(CPUPPCState *env, target_ulong rb)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- target_ulong rt = 0;
-
- if (ppc_find_slb_vsid(cpu, rb, &rt) < 0) {
- raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL, GETPC());
- }
- return rt;
-}
-
-target_ulong helper_load_slb_vsid(CPUPPCState *env, target_ulong rb)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- target_ulong rt = 0;
-
- if (ppc_load_slb_vsid(cpu, rb, &rt) < 0) {
- raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL, GETPC());
- }
- return rt;
-}
-
-/*
- * 64-bit hash table MMU handling
- */
-void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulong value,
- Error **errp)
-{
- CPUPPCState *env = &cpu->env;
- target_ulong htabsize = value & SDR_64_HTABSIZE;
-
- env->spr[SPR_SDR1] = value;
- if (htabsize > 28) {
- error_setg(errp,
- "Invalid HTABSIZE 0x" TARGET_FMT_lx" stored in SDR1",
- htabsize);
- htabsize = 28;
- }
- env->htab_mask = (1ULL << (htabsize + 18 - 7)) - 1;
- env->htab_base = value & SDR_64_HTABORG;
-}
-
-void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt, int shift,
- Error **errp)
-{
- CPUPPCState *env = &cpu->env;
- Error *local_err = NULL;
-
- if (hpt) {
- env->external_htab = hpt;
- } else {
- env->external_htab = MMU_HASH64_KVM_MANAGED_HPT;
- }
- ppc_hash64_set_sdr1(cpu, (target_ulong)(uintptr_t)hpt | (shift - 18),
- &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
-
- /* Not strictly necessary, but makes it clearer that an external
- * htab is in use when debugging */
- env->htab_base = -1;
-
- if (kvm_enabled()) {
- if (kvmppc_put_books_sregs(cpu) < 0) {
- error_setg(errp, "Unable to update SDR1 in KVM");
- }
- }
-}
-
-static int ppc_hash64_pte_prot(PowerPCCPU *cpu,
- ppc_slb_t *slb, ppc_hash_pte64_t pte)
-{
- CPUPPCState *env = &cpu->env;
- unsigned pp, key;
- /* Some pp bit combinations have undefined behaviour, so default
- * to no access in those cases */
- int prot = 0;
-
- key = !!(msr_pr ? (slb->vsid & SLB_VSID_KP)
- : (slb->vsid & SLB_VSID_KS));
- pp = (pte.pte1 & HPTE64_R_PP) | ((pte.pte1 & HPTE64_R_PP0) >> 61);
-
- if (key == 0) {
- switch (pp) {
- case 0x0:
- case 0x1:
- case 0x2:
- prot = PAGE_READ | PAGE_WRITE;
- break;
-
- case 0x3:
- case 0x6:
- prot = PAGE_READ;
- break;
- }
- } else {
- switch (pp) {
- case 0x0:
- case 0x6:
- prot = 0;
- break;
-
- case 0x1:
- case 0x3:
- prot = PAGE_READ;
- break;
-
- case 0x2:
- prot = PAGE_READ | PAGE_WRITE;
- break;
- }
- }
-
- /* No execute if either noexec or guarded bits set */
- if (!(pte.pte1 & HPTE64_R_N) || (pte.pte1 & HPTE64_R_G)
- || (slb->vsid & SLB_VSID_N)) {
- prot |= PAGE_EXEC;
- }
-
- return prot;
-}
-
-static int ppc_hash64_amr_prot(PowerPCCPU *cpu, ppc_hash_pte64_t pte)
-{
- CPUPPCState *env = &cpu->env;
- int key, amrbits;
- int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
-
- /* Only recent MMUs implement Virtual Page Class Key Protection */
- if (!(env->mmu_model & POWERPC_MMU_AMR)) {
- return prot;
- }
-
- key = HPTE64_R_KEY(pte.pte1);
- amrbits = (env->spr[SPR_AMR] >> 2*(31 - key)) & 0x3;
-
- /* fprintf(stderr, "AMR protection: key=%d AMR=0x%" PRIx64 "\n", key, */
- /* env->spr[SPR_AMR]); */
-
- /*
- * A store is permitted if the AMR bit is 0. Remove write
- * protection if it is set.
- */
- if (amrbits & 0x2) {
- prot &= ~PAGE_WRITE;
- }
- /*
- * A load is permitted if the AMR bit is 0. Remove read
- * protection if it is set.
- */
- if (amrbits & 0x1) {
- prot &= ~PAGE_READ;
- }
-
- return prot;
-}
-
-uint64_t ppc_hash64_start_access(PowerPCCPU *cpu, target_ulong pte_index)
-{
- uint64_t token = 0;
- hwaddr pte_offset;
-
- pte_offset = pte_index * HASH_PTE_SIZE_64;
- if (cpu->env.external_htab == MMU_HASH64_KVM_MANAGED_HPT) {
- /*
- * HTAB is controlled by KVM. Fetch the PTEG into a new buffer.
- */
- token = kvmppc_hash64_read_pteg(cpu, pte_index);
- } else if (cpu->env.external_htab) {
- /*
- * HTAB is controlled by QEMU. Just point to the internally
- * accessible PTEG.
- */
- token = (uint64_t)(uintptr_t) cpu->env.external_htab + pte_offset;
- } else if (cpu->env.htab_base) {
- token = cpu->env.htab_base + pte_offset;
- }
- return token;
-}
-
-void ppc_hash64_stop_access(PowerPCCPU *cpu, uint64_t token)
-{
- if (cpu->env.external_htab == MMU_HASH64_KVM_MANAGED_HPT) {
- kvmppc_hash64_free_pteg(token);
- }
-}
-
-static unsigned hpte_page_shift(const struct ppc_one_seg_page_size *sps,
- uint64_t pte0, uint64_t pte1)
-{
- int i;
-
- if (!(pte0 & HPTE64_V_LARGE)) {
- if (sps->page_shift != 12) {
- /* 4kiB page in a non 4kiB segment */
- return 0;
- }
- /* Normal 4kiB page */
- return 12;
- }
-
- for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
- const struct ppc_one_page_size *ps = &sps->enc[i];
- uint64_t mask;
-
- if (!ps->page_shift) {
- break;
- }
-
- if (ps->page_shift == 12) {
- /* L bit is set so this can't be a 4kiB page */
- continue;
- }
-
- mask = ((1ULL << ps->page_shift) - 1) & HPTE64_R_RPN;
-
- if ((pte1 & mask) == ((uint64_t)ps->pte_enc << HPTE64_R_RPN_SHIFT)) {
- return ps->page_shift;
- }
- }
-
- return 0; /* Bad page size encoding */
-}
-
-static hwaddr ppc_hash64_pteg_search(PowerPCCPU *cpu, hwaddr hash,
- const struct ppc_one_seg_page_size *sps,
- target_ulong ptem,
- ppc_hash_pte64_t *pte, unsigned *pshift)
-{
- CPUPPCState *env = &cpu->env;
- int i;
- uint64_t token;
- target_ulong pte0, pte1;
- target_ulong pte_index;
-
- pte_index = (hash & env->htab_mask) * HPTES_PER_GROUP;
- token = ppc_hash64_start_access(cpu, pte_index);
- if (!token) {
- return -1;
- }
- for (i = 0; i < HPTES_PER_GROUP; i++) {
- pte0 = ppc_hash64_load_hpte0(cpu, token, i);
- pte1 = ppc_hash64_load_hpte1(cpu, token, i);
-
- /* This compares V, B, H (secondary) and the AVPN */
- if (HPTE64_V_COMPARE(pte0, ptem)) {
- *pshift = hpte_page_shift(sps, pte0, pte1);
- /*
- * If there is no match, ignore the PTE, it could simply
- * be for a different segment size encoding and the
- * architecture specifies we should not match. Linux will
- * potentially leave behind PTEs for the wrong base page
- * size when demoting segments.
- */
- if (*pshift == 0) {
- continue;
- }
- /* We don't do anything with pshift yet as qemu TLB only deals
- * with 4K pages anyway
- */
- pte->pte0 = pte0;
- pte->pte1 = pte1;
- ppc_hash64_stop_access(cpu, token);
- return (pte_index + i) * HASH_PTE_SIZE_64;
- }
- }
- ppc_hash64_stop_access(cpu, token);
- /*
- * We didn't find a valid entry.
- */
- return -1;
-}
-
-static hwaddr ppc_hash64_htab_lookup(PowerPCCPU *cpu,
- ppc_slb_t *slb, target_ulong eaddr,
- ppc_hash_pte64_t *pte, unsigned *pshift)
-{
- CPUPPCState *env = &cpu->env;
- hwaddr pte_offset;
- hwaddr hash;
- uint64_t vsid, epnmask, epn, ptem;
- const struct ppc_one_seg_page_size *sps = slb->sps;
-
- /* The SLB store path should prevent any bad page size encodings
- * getting in there, so: */
- assert(sps);
-
- /* If ISL is set in LPCR we need to clamp the page size to 4K */
- if (env->spr[SPR_LPCR] & LPCR_ISL) {
- /* We assume that when using TCG, 4k is first entry of SPS */
- sps = &env->sps.sps[0];
- assert(sps->page_shift == 12);
- }
-
- epnmask = ~((1ULL << sps->page_shift) - 1);
-
- if (slb->vsid & SLB_VSID_B) {
- /* 1TB segment */
- vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT_1T;
- epn = (eaddr & ~SEGMENT_MASK_1T) & epnmask;
- hash = vsid ^ (vsid << 25) ^ (epn >> sps->page_shift);
- } else {
- /* 256M segment */
- vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
- epn = (eaddr & ~SEGMENT_MASK_256M) & epnmask;
- hash = vsid ^ (epn >> sps->page_shift);
- }
- ptem = (slb->vsid & SLB_VSID_PTEM) | ((epn >> 16) & HPTE64_V_AVPN);
- ptem |= HPTE64_V_VALID;
-
- /* Page address translation */
- qemu_log_mask(CPU_LOG_MMU,
- "htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
- " hash " TARGET_FMT_plx "\n",
- env->htab_base, env->htab_mask, hash);
-
- /* Primary PTEG lookup */
- qemu_log_mask(CPU_LOG_MMU,
- "0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
- " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
- " hash=" TARGET_FMT_plx "\n",
- env->htab_base, env->htab_mask, vsid, ptem, hash);
- pte_offset = ppc_hash64_pteg_search(cpu, hash, sps, ptem, pte, pshift);
-
- if (pte_offset == -1) {
- /* Secondary PTEG lookup */
- ptem |= HPTE64_V_SECONDARY;
- qemu_log_mask(CPU_LOG_MMU,
- "1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
- " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
- " hash=" TARGET_FMT_plx "\n", env->htab_base,
- env->htab_mask, vsid, ptem, ~hash);
-
- pte_offset = ppc_hash64_pteg_search(cpu, ~hash, sps, ptem, pte, pshift);
- }
-
- return pte_offset;
-}
-
-unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
- uint64_t pte0, uint64_t pte1)
-{
- CPUPPCState *env = &cpu->env;
- int i;
-
- if (!(pte0 & HPTE64_V_LARGE)) {
- return 12;
- }
-
- /*
- * The encodings in env->sps need to be carefully chosen so that
- * this gives an unambiguous result.
- */
- for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
- const struct ppc_one_seg_page_size *sps = &env->sps.sps[i];
- unsigned shift;
-
- if (!sps->page_shift) {
- break;
- }
-
- shift = hpte_page_shift(sps, pte0, pte1);
- if (shift) {
- return shift;
- }
- }
-
- return 0;
-}
-
-static void ppc_hash64_set_isi(CPUState *cs, CPUPPCState *env,
- uint64_t error_code)
-{
- bool vpm;
-
- if (msr_ir) {
- vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
- } else {
- vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
- }
- if (vpm && !msr_hv) {
- cs->exception_index = POWERPC_EXCP_HISI;
- } else {
- cs->exception_index = POWERPC_EXCP_ISI;
- }
- env->error_code = error_code;
-}
-
-static void ppc_hash64_set_dsi(CPUState *cs, CPUPPCState *env, uint64_t dar,
- uint64_t dsisr)
-{
- bool vpm;
-
- if (msr_dr) {
- vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM1);
- } else {
- vpm = !!(env->spr[SPR_LPCR] & LPCR_VPM0);
- }
- if (vpm && !msr_hv) {
- cs->exception_index = POWERPC_EXCP_HDSI;
- env->spr[SPR_HDAR] = dar;
- env->spr[SPR_HDSISR] = dsisr;
- } else {
- cs->exception_index = POWERPC_EXCP_DSI;
- env->spr[SPR_DAR] = dar;
- env->spr[SPR_DSISR] = dsisr;
- }
- env->error_code = 0;
-}
-
-
-int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
- int rwx, int mmu_idx)
-{
- CPUState *cs = CPU(cpu);
- CPUPPCState *env = &cpu->env;
- ppc_slb_t *slb;
- unsigned apshift;
- hwaddr pte_offset;
- ppc_hash_pte64_t pte;
- int pp_prot, amr_prot, prot;
- uint64_t new_pte1, dsisr;
- const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};
- hwaddr raddr;
-
- assert((rwx == 0) || (rwx == 1) || (rwx == 2));
-
- /* Note on LPCR usage: 970 uses HID4, but our special variant
- * of store_spr copies relevant fields into env->spr[SPR_LPCR].
- * Similarily we filter unimplemented bits when storing into
- * LPCR depending on the MMU version. This code can thus just
- * use the LPCR "as-is".
- */
-
- /* 1. Handle real mode accesses */
- if (((rwx == 2) && (msr_ir == 0)) || ((rwx != 2) && (msr_dr == 0))) {
- /* Translation is supposedly "off" */
- /* In real mode the top 4 effective address bits are (mostly) ignored */
- raddr = eaddr & 0x0FFFFFFFFFFFFFFFULL;
-
- /* In HV mode, add HRMOR if top EA bit is clear */
- if (msr_hv || !env->has_hv_mode) {
- if (!(eaddr >> 63)) {
- raddr |= env->spr[SPR_HRMOR];
- }
- } else {
- /* Otherwise, check VPM for RMA vs VRMA */
- if (env->spr[SPR_LPCR] & LPCR_VPM0) {
- slb = &env->vrma_slb;
- if (slb->sps) {
- goto skip_slb_search;
- }
- /* Not much else to do here */
- cs->exception_index = POWERPC_EXCP_MCHECK;
- env->error_code = 0;
- return 1;
- } else if (raddr < env->rmls) {
- /* RMA. Check bounds in RMLS */
- raddr |= env->spr[SPR_RMOR];
- } else {
- /* The access failed, generate the approriate interrupt */
- if (rwx == 2) {
- ppc_hash64_set_isi(cs, env, 0x08000000);
- } else {
- dsisr = 0x08000000;
- if (rwx == 1) {
- dsisr |= 0x02000000;
- }
- ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
- }
- return 1;
- }
- }
- tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
- PAGE_READ | PAGE_WRITE | PAGE_EXEC, mmu_idx,
- TARGET_PAGE_SIZE);
- return 0;
- }
-
- /* 2. Translation is on, so look up the SLB */
- slb = slb_lookup(cpu, eaddr);
- if (!slb) {
- if (rwx == 2) {
- cs->exception_index = POWERPC_EXCP_ISEG;
- env->error_code = 0;
- } else {
- cs->exception_index = POWERPC_EXCP_DSEG;
- env->error_code = 0;
- env->spr[SPR_DAR] = eaddr;
- }
- return 1;
- }
-
-skip_slb_search:
-
- /* 3. Check for segment level no-execute violation */
- if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) {
- ppc_hash64_set_isi(cs, env, 0x10000000);
- return 1;
- }
-
- /* 4. Locate the PTE in the hash table */
- pte_offset = ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte, &apshift);
- if (pte_offset == -1) {
- dsisr = 0x40000000;
- if (rwx == 2) {
- ppc_hash64_set_isi(cs, env, dsisr);
- } else {
- if (rwx == 1) {
- dsisr |= 0x02000000;
- }
- ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
- }
- return 1;
- }
- qemu_log_mask(CPU_LOG_MMU,
- "found PTE at offset %08" HWADDR_PRIx "\n", pte_offset);
-
- /* 5. Check access permissions */
-
- pp_prot = ppc_hash64_pte_prot(cpu, slb, pte);
- amr_prot = ppc_hash64_amr_prot(cpu, pte);
- prot = pp_prot & amr_prot;
-
- if ((need_prot[rwx] & ~prot) != 0) {
- /* Access right violation */
- qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
- if (rwx == 2) {
- ppc_hash64_set_isi(cs, env, 0x08000000);
- } else {
- dsisr = 0;
- if (need_prot[rwx] & ~pp_prot) {
- dsisr |= 0x08000000;
- }
- if (rwx == 1) {
- dsisr |= 0x02000000;
- }
- if (need_prot[rwx] & ~amr_prot) {
- dsisr |= 0x00200000;
- }
- ppc_hash64_set_dsi(cs, env, eaddr, dsisr);
- }
- return 1;
- }
-
- qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n");
-
- /* 6. Update PTE referenced and changed bits if necessary */
-
- new_pte1 = pte.pte1 | HPTE64_R_R; /* set referenced bit */
- if (rwx == 1) {
- new_pte1 |= HPTE64_R_C; /* set changed (dirty) bit */
- } else {
- /* Treat the page as read-only for now, so that a later write
- * will pass through this function again to set the C bit */
- prot &= ~PAGE_WRITE;
- }
-
- if (new_pte1 != pte.pte1) {
- ppc_hash64_store_hpte(cpu, pte_offset / HASH_PTE_SIZE_64,
- pte.pte0, new_pte1);
- }
-
- /* 7. Determine the real address from the PTE */
-
- raddr = deposit64(pte.pte1 & HPTE64_R_RPN, 0, apshift, eaddr);
-
- tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
- prot, mmu_idx, 1ULL << apshift);
-
- return 0;
-}
-
-hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr)
-{
- CPUPPCState *env = &cpu->env;
- ppc_slb_t *slb;
- hwaddr pte_offset, raddr;
- ppc_hash_pte64_t pte;
- unsigned apshift;
-
- /* Handle real mode */
- if (msr_dr == 0) {
- /* In real mode the top 4 effective address bits are ignored */
- raddr = addr & 0x0FFFFFFFFFFFFFFFULL;
-
- /* In HV mode, add HRMOR if top EA bit is clear */
- if ((msr_hv || !env->has_hv_mode) && !(addr >> 63)) {
- return raddr | env->spr[SPR_HRMOR];
- }
-
- /* Otherwise, check VPM for RMA vs VRMA */
- if (env->spr[SPR_LPCR] & LPCR_VPM0) {
- slb = &env->vrma_slb;
- if (!slb->sps) {
- return -1;
- }
- } else if (raddr < env->rmls) {
- /* RMA. Check bounds in RMLS */
- return raddr | env->spr[SPR_RMOR];
- } else {
- return -1;
- }
- } else {
- slb = slb_lookup(cpu, addr);
- if (!slb) {
- return -1;
- }
- }
-
- pte_offset = ppc_hash64_htab_lookup(cpu, slb, addr, &pte, &apshift);
- if (pte_offset == -1) {
- return -1;
- }
-
- return deposit64(pte.pte1 & HPTE64_R_RPN, 0, apshift, addr)
- & TARGET_PAGE_MASK;
-}
-
-void ppc_hash64_store_hpte(PowerPCCPU *cpu,
- target_ulong pte_index,
- target_ulong pte0, target_ulong pte1)
-{
- CPUPPCState *env = &cpu->env;
-
- if (env->external_htab == MMU_HASH64_KVM_MANAGED_HPT) {
- kvmppc_hash64_write_pte(env, pte_index, pte0, pte1);
- return;
- }
-
- pte_index *= HASH_PTE_SIZE_64;
- if (env->external_htab) {
- stq_p(env->external_htab + pte_index, pte0);
- stq_p(env->external_htab + pte_index + HASH_PTE_SIZE_64 / 2, pte1);
- } else {
- stq_phys(CPU(cpu)->as, env->htab_base + pte_index, pte0);
- stq_phys(CPU(cpu)->as,
- env->htab_base + pte_index + HASH_PTE_SIZE_64 / 2, pte1);
- }
-}
-
-void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu,
- target_ulong pte_index,
- target_ulong pte0, target_ulong pte1)
-{
- /*
- * XXX: given the fact that there are too many segments to
- * invalidate, and we still don't have a tlb_flush_mask(env, n,
- * mask) in QEMU, we just invalidate all TLBs
- */
- cpu->env.tlb_need_flush = TLB_NEED_GLOBAL_FLUSH | TLB_NEED_LOCAL_FLUSH;
-}
-
-void ppc_hash64_update_rmls(CPUPPCState *env)
-{
- uint64_t lpcr = env->spr[SPR_LPCR];
-
- /*
- * This is the full 4 bits encoding of POWER8. Previous
- * CPUs only support a subset of these but the filtering
- * is done when writing LPCR
- */
- switch ((lpcr & LPCR_RMLS) >> LPCR_RMLS_SHIFT) {
- case 0x8: /* 32MB */
- env->rmls = 0x2000000ull;
- break;
- case 0x3: /* 64MB */
- env->rmls = 0x4000000ull;
- break;
- case 0x7: /* 128MB */
- env->rmls = 0x8000000ull;
- break;
- case 0x4: /* 256MB */
- env->rmls = 0x10000000ull;
- break;
- case 0x2: /* 1GB */
- env->rmls = 0x40000000ull;
- break;
- case 0x1: /* 16GB */
- env->rmls = 0x400000000ull;
- break;
- default:
- /* What to do here ??? */
- env->rmls = 0;
- }
-}
-
-void ppc_hash64_update_vrma(CPUPPCState *env)
-{
- const struct ppc_one_seg_page_size *sps = NULL;
- target_ulong esid, vsid, lpcr;
- ppc_slb_t *slb = &env->vrma_slb;
- uint32_t vrmasd;
- int i;
-
- /* First clear it */
- slb->esid = slb->vsid = 0;
- slb->sps = NULL;
-
- /* Is VRMA enabled ? */
- lpcr = env->spr[SPR_LPCR];
- if (!(lpcr & LPCR_VPM0)) {
- return;
- }
-
- /* Make one up. Mostly ignore the ESID which will not be
- * needed for translation
- */
- vsid = SLB_VSID_VRMA;
- vrmasd = (lpcr & LPCR_VRMASD) >> LPCR_VRMASD_SHIFT;
- vsid |= (vrmasd << 4) & (SLB_VSID_L | SLB_VSID_LP);
- esid = SLB_ESID_V;
-
- for (i = 0; i < PPC_PAGE_SIZES_MAX_SZ; i++) {
- const struct ppc_one_seg_page_size *sps1 = &env->sps.sps[i];
-
- if (!sps1->page_shift) {
- break;
- }
-
- if ((vsid & SLB_VSID_LLP_MASK) == sps1->slb_enc) {
- sps = sps1;
- break;
- }
- }
-
- if (!sps) {
- error_report("Bad page size encoding esid 0x"TARGET_FMT_lx
- " vsid 0x"TARGET_FMT_lx, esid, vsid);
- return;
- }
-
- slb->vsid = vsid;
- slb->esid = esid;
- slb->sps = sps;
-}
-
-void helper_store_lpcr(CPUPPCState *env, target_ulong val)
-{
- uint64_t lpcr = 0;
-
- /* Filter out bits */
- switch (env->mmu_model) {
- case POWERPC_MMU_64B: /* 970 */
- if (val & 0x40) {
- lpcr |= LPCR_LPES0;
- }
- if (val & 0x8000000000000000ull) {
- lpcr |= LPCR_LPES1;
- }
- if (val & 0x20) {
- lpcr |= (0x4ull << LPCR_RMLS_SHIFT);
- }
- if (val & 0x4000000000000000ull) {
- lpcr |= (0x2ull << LPCR_RMLS_SHIFT);
- }
- if (val & 0x2000000000000000ull) {
- lpcr |= (0x1ull << LPCR_RMLS_SHIFT);
- }
- env->spr[SPR_RMOR] = ((lpcr >> 41) & 0xffffull) << 26;
-
- /* XXX We could also write LPID from HID4 here
- * but since we don't tag any translation on it
- * it doesn't actually matter
- */
- /* XXX For proper emulation of 970 we also need
- * to dig HRMOR out of HID5
- */
- break;
- case POWERPC_MMU_2_03: /* P5p */
- lpcr = val & (LPCR_RMLS | LPCR_ILE |
- LPCR_LPES0 | LPCR_LPES1 |
- LPCR_RMI | LPCR_HDICE);
- break;
- case POWERPC_MMU_2_06: /* P7 */
- lpcr = val & (LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_DPFD |
- LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
- LPCR_P7_PECE0 | LPCR_P7_PECE1 | LPCR_P7_PECE2 |
- LPCR_MER | LPCR_TC |
- LPCR_LPES0 | LPCR_LPES1 | LPCR_HDICE);
- break;
- case POWERPC_MMU_2_07: /* P8 */
- lpcr = val & (LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV |
- LPCR_DPFD | LPCR_VRMASD | LPCR_RMLS | LPCR_ILE |
- LPCR_AIL | LPCR_ONL | LPCR_P8_PECE0 | LPCR_P8_PECE1 |
- LPCR_P8_PECE2 | LPCR_P8_PECE3 | LPCR_P8_PECE4 |
- LPCR_MER | LPCR_TC | LPCR_LPES0 | LPCR_HDICE);
- break;
- default:
- ;
- }
- env->spr[SPR_LPCR] = lpcr;
- ppc_hash64_update_rmls(env);
- ppc_hash64_update_vrma(env);
-}
diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h
deleted file mode 100644
index ab5d347a53..0000000000
--- a/target-ppc/mmu-hash64.h
+++ /dev/null
@@ -1,136 +0,0 @@
-#ifndef MMU_HASH64_H
-#define MMU_HASH64_H
-
-#ifndef CONFIG_USER_ONLY
-
-#ifdef TARGET_PPC64
-void dump_slb(FILE *f, fprintf_function cpu_fprintf, PowerPCCPU *cpu);
-int ppc_store_slb(PowerPCCPU *cpu, target_ulong slot,
- target_ulong esid, target_ulong vsid);
-hwaddr ppc_hash64_get_phys_page_debug(PowerPCCPU *cpu, target_ulong addr);
-int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr address, int rw,
- int mmu_idx);
-void ppc_hash64_store_hpte(PowerPCCPU *cpu, target_ulong index,
- target_ulong pte0, target_ulong pte1);
-void ppc_hash64_tlb_flush_hpte(PowerPCCPU *cpu,
- target_ulong pte_index,
- target_ulong pte0, target_ulong pte1);
-unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu,
- uint64_t pte0, uint64_t pte1);
-void ppc_hash64_update_vrma(CPUPPCState *env);
-void ppc_hash64_update_rmls(CPUPPCState *env);
-#endif
-
-/*
- * SLB definitions
- */
-
-/* Bits in the SLB ESID word */
-#define SLB_ESID_ESID 0xFFFFFFFFF0000000ULL
-#define SLB_ESID_V 0x0000000008000000ULL /* valid */
-
-/* Bits in the SLB VSID word */
-#define SLB_VSID_SHIFT 12
-#define SLB_VSID_SHIFT_1T 24
-#define SLB_VSID_SSIZE_SHIFT 62
-#define SLB_VSID_B 0xc000000000000000ULL
-#define SLB_VSID_B_256M 0x0000000000000000ULL
-#define SLB_VSID_B_1T 0x4000000000000000ULL
-#define SLB_VSID_VSID 0x3FFFFFFFFFFFF000ULL
-#define SLB_VSID_VRMA (0x0001FFFFFF000000ULL | SLB_VSID_B_1T)
-#define SLB_VSID_PTEM (SLB_VSID_B | SLB_VSID_VSID)
-#define SLB_VSID_KS 0x0000000000000800ULL
-#define SLB_VSID_KP 0x0000000000000400ULL
-#define SLB_VSID_N 0x0000000000000200ULL /* no-execute */
-#define SLB_VSID_L 0x0000000000000100ULL
-#define SLB_VSID_C 0x0000000000000080ULL /* class */
-#define SLB_VSID_LP 0x0000000000000030ULL
-#define SLB_VSID_ATTR 0x0000000000000FFFULL
-#define SLB_VSID_LLP_MASK (SLB_VSID_L | SLB_VSID_LP)
-#define SLB_VSID_4K 0x0000000000000000ULL
-#define SLB_VSID_64K 0x0000000000000110ULL
-#define SLB_VSID_16M 0x0000000000000100ULL
-#define SLB_VSID_16G 0x0000000000000120ULL
-
-/*
- * Hash page table definitions
- */
-
-#define HPTES_PER_GROUP 8
-#define HASH_PTE_SIZE_64 16
-#define HASH_PTEG_SIZE_64 (HASH_PTE_SIZE_64 * HPTES_PER_GROUP)
-
-#define HPTE64_V_SSIZE_SHIFT 62
-#define HPTE64_V_AVPN_SHIFT 7
-#define HPTE64_V_AVPN 0x3fffffffffffff80ULL
-#define HPTE64_V_AVPN_VAL(x) (((x) & HPTE64_V_AVPN) >> HPTE64_V_AVPN_SHIFT)
-#define HPTE64_V_COMPARE(x, y) (!(((x) ^ (y)) & 0xffffffffffffff83ULL))
-#define HPTE64_V_LARGE 0x0000000000000004ULL
-#define HPTE64_V_SECONDARY 0x0000000000000002ULL
-#define HPTE64_V_VALID 0x0000000000000001ULL
-
-#define HPTE64_R_PP0 0x8000000000000000ULL
-#define HPTE64_R_TS 0x4000000000000000ULL
-#define HPTE64_R_KEY_HI 0x3000000000000000ULL
-#define HPTE64_R_RPN_SHIFT 12
-#define HPTE64_R_RPN 0x0ffffffffffff000ULL
-#define HPTE64_R_FLAGS 0x00000000000003ffULL
-#define HPTE64_R_PP 0x0000000000000003ULL
-#define HPTE64_R_N 0x0000000000000004ULL
-#define HPTE64_R_G 0x0000000000000008ULL
-#define HPTE64_R_M 0x0000000000000010ULL
-#define HPTE64_R_I 0x0000000000000020ULL
-#define HPTE64_R_W 0x0000000000000040ULL
-#define HPTE64_R_WIMG 0x0000000000000078ULL
-#define HPTE64_R_C 0x0000000000000080ULL
-#define HPTE64_R_R 0x0000000000000100ULL
-#define HPTE64_R_KEY_LO 0x0000000000000e00ULL
-#define HPTE64_R_KEY(x) ((((x) & HPTE64_R_KEY_HI) >> 60) | \
- (((x) & HPTE64_R_KEY_LO) >> 9))
-
-#define HPTE64_V_1TB_SEG 0x4000000000000000ULL
-#define HPTE64_V_VRMA_MASK 0x4001ffffff000000ULL
-
-void ppc_hash64_set_sdr1(PowerPCCPU *cpu, target_ulong value,
- Error **errp);
-void ppc_hash64_set_external_hpt(PowerPCCPU *cpu, void *hpt, int shift,
- Error **errp);
-
-uint64_t ppc_hash64_start_access(PowerPCCPU *cpu, target_ulong pte_index);
-void ppc_hash64_stop_access(PowerPCCPU *cpu, uint64_t token);
-
-static inline target_ulong ppc_hash64_load_hpte0(PowerPCCPU *cpu,
- uint64_t token, int index)
-{
- CPUPPCState *env = &cpu->env;
- uint64_t addr;
-
- addr = token + (index * HASH_PTE_SIZE_64);
- if (env->external_htab) {
- return ldq_p((const void *)(uintptr_t)addr);
- } else {
- return ldq_phys(CPU(cpu)->as, addr);
- }
-}
-
-static inline target_ulong ppc_hash64_load_hpte1(PowerPCCPU *cpu,
- uint64_t token, int index)
-{
- CPUPPCState *env = &cpu->env;
- uint64_t addr;
-
- addr = token + (index * HASH_PTE_SIZE_64) + HASH_PTE_SIZE_64/2;
- if (env->external_htab) {
- return ldq_p((const void *)(uintptr_t)addr);
- } else {
- return ldq_phys(CPU(cpu)->as, addr);
- }
-}
-
-typedef struct {
- uint64_t pte0, pte1;
-} ppc_hash_pte64_t;
-
-#endif /* CONFIG_USER_ONLY */
-
-#endif /* MMU_HASH64_H */
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
deleted file mode 100644
index d09fc0a85f..0000000000
--- a/target-ppc/mmu_helper.c
+++ /dev/null
@@ -1,2907 +0,0 @@
-/*
- * PowerPC MMU, TLB, SLB and BAT emulation helpers for QEMU.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-#include "qemu/osdep.h"
-#include "qapi/error.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "sysemu/kvm.h"
-#include "kvm_ppc.h"
-#include "mmu-hash64.h"
-#include "mmu-hash32.h"
-#include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
-#include "exec/log.h"
-#include "helper_regs.h"
-
-//#define DEBUG_MMU
-//#define DEBUG_BATS
-//#define DEBUG_SOFTWARE_TLB
-//#define DUMP_PAGE_TABLES
-//#define FLUSH_ALL_TLBS
-
-#ifdef DEBUG_MMU
-# define LOG_MMU_STATE(cpu) log_cpu_state_mask(CPU_LOG_MMU, (cpu), 0)
-#else
-# define LOG_MMU_STATE(cpu) do { } while (0)
-#endif
-
-#ifdef DEBUG_SOFTWARE_TLB
-# define LOG_SWTLB(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__)
-#else
-# define LOG_SWTLB(...) do { } while (0)
-#endif
-
-#ifdef DEBUG_BATS
-# define LOG_BATS(...) qemu_log_mask(CPU_LOG_MMU, __VA_ARGS__)
-#else
-# define LOG_BATS(...) do { } while (0)
-#endif
-
-/*****************************************************************************/
-/* PowerPC MMU emulation */
-
-/* Context used internally during MMU translations */
-typedef struct mmu_ctx_t mmu_ctx_t;
-struct mmu_ctx_t {
- hwaddr raddr; /* Real address */
- hwaddr eaddr; /* Effective address */
- int prot; /* Protection bits */
- hwaddr hash[2]; /* Pagetable hash values */
- target_ulong ptem; /* Virtual segment ID | API */
- int key; /* Access key */
- int nx; /* Non-execute area */
-};
-
-/* Common routines used by software and hardware TLBs emulation */
-static inline int pte_is_valid(target_ulong pte0)
-{
- return pte0 & 0x80000000 ? 1 : 0;
-}
-
-static inline void pte_invalidate(target_ulong *pte0)
-{
- *pte0 &= ~0x80000000;
-}
-
-#define PTE_PTEM_MASK 0x7FFFFFBF
-#define PTE_CHECK_MASK (TARGET_PAGE_MASK | 0x7B)
-
-static int pp_check(int key, int pp, int nx)
-{
- int access;
-
- /* Compute access rights */
- access = 0;
- if (key == 0) {
- switch (pp) {
- case 0x0:
- case 0x1:
- case 0x2:
- access |= PAGE_WRITE;
- /* No break here */
- case 0x3:
- access |= PAGE_READ;
- break;
- }
- } else {
- switch (pp) {
- case 0x0:
- access = 0;
- break;
- case 0x1:
- case 0x3:
- access = PAGE_READ;
- break;
- case 0x2:
- access = PAGE_READ | PAGE_WRITE;
- break;
- }
- }
- if (nx == 0) {
- access |= PAGE_EXEC;
- }
-
- return access;
-}
-
-static int check_prot(int prot, int rw, int access_type)
-{
- int ret;
-
- if (access_type == ACCESS_CODE) {
- if (prot & PAGE_EXEC) {
- ret = 0;
- } else {
- ret = -2;
- }
- } else if (rw) {
- if (prot & PAGE_WRITE) {
- ret = 0;
- } else {
- ret = -2;
- }
- } else {
- if (prot & PAGE_READ) {
- ret = 0;
- } else {
- ret = -2;
- }
- }
-
- return ret;
-}
-
-static inline int ppc6xx_tlb_pte_check(mmu_ctx_t *ctx, target_ulong pte0,
- target_ulong pte1, int h, int rw, int type)
-{
- target_ulong ptem, mmask;
- int access, ret, pteh, ptev, pp;
-
- ret = -1;
- /* Check validity and table match */
- ptev = pte_is_valid(pte0);
- pteh = (pte0 >> 6) & 1;
- if (ptev && h == pteh) {
- /* Check vsid & api */
- ptem = pte0 & PTE_PTEM_MASK;
- mmask = PTE_CHECK_MASK;
- pp = pte1 & 0x00000003;
- if (ptem == ctx->ptem) {
- if (ctx->raddr != (hwaddr)-1ULL) {
- /* all matches should have equal RPN, WIMG & PP */
- if ((ctx->raddr & mmask) != (pte1 & mmask)) {
- qemu_log_mask(CPU_LOG_MMU, "Bad RPN/WIMG/PP\n");
- return -3;
- }
- }
- /* Compute access rights */
- access = pp_check(ctx->key, pp, ctx->nx);
- /* Keep the matching PTE informations */
- ctx->raddr = pte1;
- ctx->prot = access;
- ret = check_prot(ctx->prot, rw, type);
- if (ret == 0) {
- /* Access granted */
- qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n");
- } else {
- /* Access right violation */
- qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");
- }
- }
- }
-
- return ret;
-}
-
-static int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
- int ret, int rw)
-{
- int store = 0;
-
- /* Update page flags */
- if (!(*pte1p & 0x00000100)) {
- /* Update accessed flag */
- *pte1p |= 0x00000100;
- store = 1;
- }
- if (!(*pte1p & 0x00000080)) {
- if (rw == 1 && ret == 0) {
- /* Update changed flag */
- *pte1p |= 0x00000080;
- store = 1;
- } else {
- /* Force page fault for first write access */
- ctx->prot &= ~PAGE_WRITE;
- }
- }
-
- return store;
-}
-
-/* Software driven TLB helpers */
-static inline int ppc6xx_tlb_getnum(CPUPPCState *env, target_ulong eaddr,
- int way, int is_code)
-{
- int nr;
-
- /* Select TLB num in a way from address */
- nr = (eaddr >> TARGET_PAGE_BITS) & (env->tlb_per_way - 1);
- /* Select TLB way */
- nr += env->tlb_per_way * way;
- /* 6xx have separate TLBs for instructions and data */
- if (is_code && env->id_tlbs == 1) {
- nr += env->nb_tlb;
- }
-
- return nr;
-}
-
-static inline void ppc6xx_tlb_invalidate_all(CPUPPCState *env)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- ppc6xx_tlb_t *tlb;
- int nr, max;
-
- /* LOG_SWTLB("Invalidate all TLBs\n"); */
- /* Invalidate all defined software TLB */
- max = env->nb_tlb;
- if (env->id_tlbs == 1) {
- max *= 2;
- }
- for (nr = 0; nr < max; nr++) {
- tlb = &env->tlb.tlb6[nr];
- pte_invalidate(&tlb->pte0);
- }
- tlb_flush(CPU(cpu), 1);
-}
-
-static inline void ppc6xx_tlb_invalidate_virt2(CPUPPCState *env,
- target_ulong eaddr,
- int is_code, int match_epn)
-{
-#if !defined(FLUSH_ALL_TLBS)
- CPUState *cs = CPU(ppc_env_get_cpu(env));
- ppc6xx_tlb_t *tlb;
- int way, nr;
-
- /* Invalidate ITLB + DTLB, all ways */
- for (way = 0; way < env->nb_ways; way++) {
- nr = ppc6xx_tlb_getnum(env, eaddr, way, is_code);
- tlb = &env->tlb.tlb6[nr];
- if (pte_is_valid(tlb->pte0) && (match_epn == 0 || eaddr == tlb->EPN)) {
- LOG_SWTLB("TLB invalidate %d/%d " TARGET_FMT_lx "\n", nr,
- env->nb_tlb, eaddr);
- pte_invalidate(&tlb->pte0);
- tlb_flush_page(cs, tlb->EPN);
- }
- }
-#else
- /* XXX: PowerPC specification say this is valid as well */
- ppc6xx_tlb_invalidate_all(env);
-#endif
-}
-
-static inline void ppc6xx_tlb_invalidate_virt(CPUPPCState *env,
- target_ulong eaddr, int is_code)
-{
- ppc6xx_tlb_invalidate_virt2(env, eaddr, is_code, 0);
-}
-
-static void ppc6xx_tlb_store(CPUPPCState *env, target_ulong EPN, int way,
- int is_code, target_ulong pte0, target_ulong pte1)
-{
- ppc6xx_tlb_t *tlb;
- int nr;
-
- nr = ppc6xx_tlb_getnum(env, EPN, way, is_code);
- tlb = &env->tlb.tlb6[nr];
- LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx
- " PTE1 " TARGET_FMT_lx "\n", nr, env->nb_tlb, EPN, pte0, pte1);
- /* Invalidate any pending reference in QEMU for this virtual address */
- ppc6xx_tlb_invalidate_virt2(env, EPN, is_code, 1);
- tlb->pte0 = pte0;
- tlb->pte1 = pte1;
- tlb->EPN = EPN;
- /* Store last way for LRU mechanism */
- env->last_way = way;
-}
-
-static inline int ppc6xx_tlb_check(CPUPPCState *env, mmu_ctx_t *ctx,
- target_ulong eaddr, int rw, int access_type)
-{
- ppc6xx_tlb_t *tlb;
- int nr, best, way;
- int ret;
-
- best = -1;
- ret = -1; /* No TLB found */
- for (way = 0; way < env->nb_ways; way++) {
- nr = ppc6xx_tlb_getnum(env, eaddr, way,
- access_type == ACCESS_CODE ? 1 : 0);
- tlb = &env->tlb.tlb6[nr];
- /* This test "emulates" the PTE index match for hardware TLBs */
- if ((eaddr & TARGET_PAGE_MASK) != tlb->EPN) {
- LOG_SWTLB("TLB %d/%d %s [" TARGET_FMT_lx " " TARGET_FMT_lx
- "] <> " TARGET_FMT_lx "\n", nr, env->nb_tlb,
- pte_is_valid(tlb->pte0) ? "valid" : "inval",
- tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE, eaddr);
- continue;
- }
- LOG_SWTLB("TLB %d/%d %s " TARGET_FMT_lx " <> " TARGET_FMT_lx " "
- TARGET_FMT_lx " %c %c\n", nr, env->nb_tlb,
- pte_is_valid(tlb->pte0) ? "valid" : "inval",
- tlb->EPN, eaddr, tlb->pte1,
- rw ? 'S' : 'L', access_type == ACCESS_CODE ? 'I' : 'D');
- switch (ppc6xx_tlb_pte_check(ctx, tlb->pte0, tlb->pte1, 0, rw, access_type)) {
- case -3:
- /* TLB inconsistency */
- return -1;
- case -2:
- /* Access violation */
- ret = -2;
- best = nr;
- break;
- case -1:
- default:
- /* No match */
- break;
- case 0:
- /* access granted */
- /* XXX: we should go on looping to check all TLBs consistency
- * but we can speed-up the whole thing as the
- * result would be undefined if TLBs are not consistent.
- */
- ret = 0;
- best = nr;
- goto done;
- }
- }
- if (best != -1) {
- done:
- LOG_SWTLB("found TLB at addr " TARGET_FMT_plx " prot=%01x ret=%d\n",
- ctx->raddr & TARGET_PAGE_MASK, ctx->prot, ret);
- /* Update page flags */
- pte_update_flags(ctx, &env->tlb.tlb6[best].pte1, ret, rw);
- }
-
- return ret;
-}
-
-/* Perform BAT hit & translation */
-static inline void bat_size_prot(CPUPPCState *env, target_ulong *blp,
- int *validp, int *protp, target_ulong *BATu,
- target_ulong *BATl)
-{
- target_ulong bl;
- int pp, valid, prot;
-
- bl = (*BATu & 0x00001FFC) << 15;
- valid = 0;
- prot = 0;
- if (((msr_pr == 0) && (*BATu & 0x00000002)) ||
- ((msr_pr != 0) && (*BATu & 0x00000001))) {
- valid = 1;
- pp = *BATl & 0x00000003;
- if (pp != 0) {
- prot = PAGE_READ | PAGE_EXEC;
- if (pp == 0x2) {
- prot |= PAGE_WRITE;
- }
- }
- }
- *blp = bl;
- *validp = valid;
- *protp = prot;
-}
-
-static int get_bat_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
- target_ulong virtual, int rw, int type)
-{
- target_ulong *BATlt, *BATut, *BATu, *BATl;
- target_ulong BEPIl, BEPIu, bl;
- int i, valid, prot;
- int ret = -1;
-
- LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__,
- type == ACCESS_CODE ? 'I' : 'D', virtual);
- switch (type) {
- case ACCESS_CODE:
- BATlt = env->IBAT[1];
- BATut = env->IBAT[0];
- break;
- default:
- BATlt = env->DBAT[1];
- BATut = env->DBAT[0];
- break;
- }
- for (i = 0; i < env->nb_BATs; i++) {
- BATu = &BATut[i];
- BATl = &BATlt[i];
- BEPIu = *BATu & 0xF0000000;
- BEPIl = *BATu & 0x0FFE0000;
- bat_size_prot(env, &bl, &valid, &prot, BATu, BATl);
- LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
- " BATl " TARGET_FMT_lx "\n", __func__,
- type == ACCESS_CODE ? 'I' : 'D', i, virtual, *BATu, *BATl);
- if ((virtual & 0xF0000000) == BEPIu &&
- ((virtual & 0x0FFE0000) & ~bl) == BEPIl) {
- /* BAT matches */
- if (valid != 0) {
- /* Get physical address */
- ctx->raddr = (*BATl & 0xF0000000) |
- ((virtual & 0x0FFE0000 & bl) | (*BATl & 0x0FFE0000)) |
- (virtual & 0x0001F000);
- /* Compute access rights */
- ctx->prot = prot;
- ret = check_prot(ctx->prot, rw, type);
- if (ret == 0) {
- LOG_BATS("BAT %d match: r " TARGET_FMT_plx " prot=%c%c\n",
- i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-',
- ctx->prot & PAGE_WRITE ? 'W' : '-');
- }
- break;
- }
- }
- }
- if (ret < 0) {
-#if defined(DEBUG_BATS)
- if (qemu_log_enabled()) {
- LOG_BATS("no BAT match for " TARGET_FMT_lx ":\n", virtual);
- for (i = 0; i < 4; i++) {
- BATu = &BATut[i];
- BATl = &BATlt[i];
- BEPIu = *BATu & 0xF0000000;
- BEPIl = *BATu & 0x0FFE0000;
- bl = (*BATu & 0x00001FFC) << 15;
- LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx
- " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
- TARGET_FMT_lx " " TARGET_FMT_lx "\n",
- __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,
- *BATu, *BATl, BEPIu, BEPIl, bl);
- }
- }
-#endif
- }
- /* No hit */
- return ret;
-}
-
-/* Perform segment based translation */
-static inline int get_segment_6xx_tlb(CPUPPCState *env, mmu_ctx_t *ctx,
- target_ulong eaddr, int rw, int type)
-{
- hwaddr hash;
- target_ulong vsid;
- int ds, pr, target_page_bits;
- int ret;
- target_ulong sr, pgidx;
-
- pr = msr_pr;
- ctx->eaddr = eaddr;
-
- sr = env->sr[eaddr >> 28];
- ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
- ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
- ds = sr & 0x80000000 ? 1 : 0;
- ctx->nx = sr & 0x10000000 ? 1 : 0;
- vsid = sr & 0x00FFFFFF;
- target_page_bits = TARGET_PAGE_BITS;
- qemu_log_mask(CPU_LOG_MMU,
- "Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx
- " nip=" TARGET_FMT_lx " lr=" TARGET_FMT_lx
- " ir=%d dr=%d pr=%d %d t=%d\n",
- eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir,
- (int)msr_dr, pr != 0 ? 1 : 0, rw, type);
- pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits;
- hash = vsid ^ pgidx;
- ctx->ptem = (vsid << 7) | (pgidx >> 10);
-
- qemu_log_mask(CPU_LOG_MMU,
- "pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n",
- ctx->key, ds, ctx->nx, vsid);
- ret = -1;
- if (!ds) {
- /* Check if instruction fetch is allowed, if needed */
- if (type != ACCESS_CODE || ctx->nx == 0) {
- /* Page address translation */
- qemu_log_mask(CPU_LOG_MMU, "htab_base " TARGET_FMT_plx
- " htab_mask " TARGET_FMT_plx
- " hash " TARGET_FMT_plx "\n",
- env->htab_base, env->htab_mask, hash);
- ctx->hash[0] = hash;
- ctx->hash[1] = ~hash;
-
- /* Initialize real address with an invalid value */
- ctx->raddr = (hwaddr)-1ULL;
- /* Software TLB search */
- ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
-#if defined(DUMP_PAGE_TABLES)
- if (qemu_loglevel_mask(CPU_LOG_MMU)) {
- CPUState *cs = ENV_GET_CPU(env);
- hwaddr curaddr;
- uint32_t a0, a1, a2, a3;
-
- qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx
- "\n", env->htab_base, env->htab_mask + 0x80);
- for (curaddr = env->htab_base;
- curaddr < (env->htab_base + env->htab_mask + 0x80);
- curaddr += 16) {
- a0 = ldl_phys(cs->as, curaddr);
- a1 = ldl_phys(cs->as, curaddr + 4);
- a2 = ldl_phys(cs->as, curaddr + 8);
- a3 = ldl_phys(cs->as, curaddr + 12);
- if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) {
- qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n",
- curaddr, a0, a1, a2, a3);
- }
- }
- }
-#endif
- } else {
- qemu_log_mask(CPU_LOG_MMU, "No access allowed\n");
- ret = -3;
- }
- } else {
- target_ulong sr;
-
- qemu_log_mask(CPU_LOG_MMU, "direct store...\n");
- /* Direct-store segment : absolutely *BUGGY* for now */
-
- /* Direct-store implies a 32-bit MMU.
- * Check the Segment Register's bus unit ID (BUID).
- */
- sr = env->sr[eaddr >> 28];
- if ((sr & 0x1FF00000) >> 20 == 0x07f) {
- /* Memory-forced I/O controller interface access */
- /* If T=1 and BUID=x'07F', the 601 performs a memory access
- * to SR[28-31] LA[4-31], bypassing all protection mechanisms.
- */
- ctx->raddr = ((sr & 0xF) << 28) | (eaddr & 0x0FFFFFFF);
- ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- return 0;
- }
-
- switch (type) {
- case ACCESS_INT:
- /* Integer load/store : only access allowed */
- break;
- case ACCESS_CODE:
- /* No code fetch is allowed in direct-store areas */
- return -4;
- case ACCESS_FLOAT:
- /* Floating point load/store */
- return -4;
- case ACCESS_RES:
- /* lwarx, ldarx or srwcx. */
- return -4;
- case ACCESS_CACHE:
- /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */
- /* Should make the instruction do no-op.
- * As it already do no-op, it's quite easy :-)
- */
- ctx->raddr = eaddr;
- return 0;
- case ACCESS_EXT:
- /* eciwx or ecowx */
- return -4;
- default:
- qemu_log_mask(CPU_LOG_MMU, "ERROR: instruction should not need "
- "address translation\n");
- return -4;
- }
- if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) {
- ctx->raddr = eaddr;
- ret = 2;
- } else {
- ret = -2;
- }
- }
-
- return ret;
-}
-
-/* Generic TLB check function for embedded PowerPC implementations */
-static int ppcemb_tlb_check(CPUPPCState *env, ppcemb_tlb_t *tlb,
- hwaddr *raddrp,
- target_ulong address, uint32_t pid, int ext,
- int i)
-{
- target_ulong mask;
-
- /* Check valid flag */
- if (!(tlb->prot & PAGE_VALID)) {
- return -1;
- }
- mask = ~(tlb->size - 1);
- LOG_SWTLB("%s: TLB %d address " TARGET_FMT_lx " PID %u <=> " TARGET_FMT_lx
- " " TARGET_FMT_lx " %u %x\n", __func__, i, address, pid, tlb->EPN,
- mask, (uint32_t)tlb->PID, tlb->prot);
- /* Check PID */
- if (tlb->PID != 0 && tlb->PID != pid) {
- return -1;
- }
- /* Check effective address */
- if ((address & mask) != tlb->EPN) {
- return -1;
- }
- *raddrp = (tlb->RPN & mask) | (address & ~mask);
- if (ext) {
- /* Extend the physical address to 36 bits */
- *raddrp |= (uint64_t)(tlb->RPN & 0xF) << 32;
- }
-
- return 0;
-}
-
-/* Generic TLB search function for PowerPC embedded implementations */
-static int ppcemb_tlb_search(CPUPPCState *env, target_ulong address,
- uint32_t pid)
-{
- ppcemb_tlb_t *tlb;
- hwaddr raddr;
- int i, ret;
-
- /* Default return value is no match */
- ret = -1;
- for (i = 0; i < env->nb_tlb; i++) {
- tlb = &env->tlb.tlbe[i];
- if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, 0, i) == 0) {
- ret = i;
- break;
- }
- }
-
- return ret;
-}
-
-/* Helpers specific to PowerPC 40x implementations */
-static inline void ppc4xx_tlb_invalidate_all(CPUPPCState *env)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- ppcemb_tlb_t *tlb;
- int i;
-
- for (i = 0; i < env->nb_tlb; i++) {
- tlb = &env->tlb.tlbe[i];
- tlb->prot &= ~PAGE_VALID;
- }
- tlb_flush(CPU(cpu), 1);
-}
-
-static int mmu40x_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
- target_ulong address, int rw,
- int access_type)
-{
- ppcemb_tlb_t *tlb;
- hwaddr raddr;
- int i, ret, zsel, zpr, pr;
-
- ret = -1;
- raddr = (hwaddr)-1ULL;
- pr = msr_pr;
- for (i = 0; i < env->nb_tlb; i++) {
- tlb = &env->tlb.tlbe[i];
- if (ppcemb_tlb_check(env, tlb, &raddr, address,
- env->spr[SPR_40x_PID], 0, i) < 0) {
- continue;
- }
- zsel = (tlb->attr >> 4) & 0xF;
- zpr = (env->spr[SPR_40x_ZPR] >> (30 - (2 * zsel))) & 0x3;
- LOG_SWTLB("%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
- __func__, i, zsel, zpr, rw, tlb->attr);
- /* Check execute enable bit */
- switch (zpr) {
- case 0x2:
- if (pr != 0) {
- goto check_perms;
- }
- /* No break here */
- case 0x3:
- /* All accesses granted */
- ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
- ret = 0;
- break;
- case 0x0:
- if (pr != 0) {
- /* Raise Zone protection fault. */
- env->spr[SPR_40x_ESR] = 1 << 22;
- ctx->prot = 0;
- ret = -2;
- break;
- }
- /* No break here */
- case 0x1:
- check_perms:
- /* Check from TLB entry */
- ctx->prot = tlb->prot;
- ret = check_prot(ctx->prot, rw, access_type);
- if (ret == -2) {
- env->spr[SPR_40x_ESR] = 0;
- }
- break;
- }
- if (ret >= 0) {
- ctx->raddr = raddr;
- LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
- " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
- ret);
- return 0;
- }
- }
- LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
- " %d %d\n", __func__, address, raddr, ctx->prot, ret);
-
- return ret;
-}
-
-void store_40x_sler(CPUPPCState *env, uint32_t val)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
-
- /* XXX: TO BE FIXED */
- if (val != 0x00000000) {
- cpu_abort(CPU(cpu), "Little-endian regions are not supported by now\n");
- }
- env->spr[SPR_405_SLER] = val;
-}
-
-static inline int mmubooke_check_tlb(CPUPPCState *env, ppcemb_tlb_t *tlb,
- hwaddr *raddr, int *prot,
- target_ulong address, int rw,
- int access_type, int i)
-{
- int ret, prot2;
-
- if (ppcemb_tlb_check(env, tlb, raddr, address,
- env->spr[SPR_BOOKE_PID],
- !env->nb_pids, i) >= 0) {
- goto found_tlb;
- }
-
- if (env->spr[SPR_BOOKE_PID1] &&
- ppcemb_tlb_check(env, tlb, raddr, address,
- env->spr[SPR_BOOKE_PID1], 0, i) >= 0) {
- goto found_tlb;
- }
-
- if (env->spr[SPR_BOOKE_PID2] &&
- ppcemb_tlb_check(env, tlb, raddr, address,
- env->spr[SPR_BOOKE_PID2], 0, i) >= 0) {
- goto found_tlb;
- }
-
- LOG_SWTLB("%s: TLB entry not found\n", __func__);
- return -1;
-
-found_tlb:
-
- if (msr_pr != 0) {
- prot2 = tlb->prot & 0xF;
- } else {
- prot2 = (tlb->prot >> 4) & 0xF;
- }
-
- /* Check the address space */
- if (access_type == ACCESS_CODE) {
- if (msr_ir != (tlb->attr & 1)) {
- LOG_SWTLB("%s: AS doesn't match\n", __func__);
- return -1;
- }
-
- *prot = prot2;
- if (prot2 & PAGE_EXEC) {
- LOG_SWTLB("%s: good TLB!\n", __func__);
- return 0;
- }
-
- LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, prot2);
- ret = -3;
- } else {
- if (msr_dr != (tlb->attr & 1)) {
- LOG_SWTLB("%s: AS doesn't match\n", __func__);
- return -1;
- }
-
- *prot = prot2;
- if ((!rw && prot2 & PAGE_READ) || (rw && (prot2 & PAGE_WRITE))) {
- LOG_SWTLB("%s: found TLB!\n", __func__);
- return 0;
- }
-
- LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, prot2);
- ret = -2;
- }
-
- return ret;
-}
-
-static int mmubooke_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
- target_ulong address, int rw,
- int access_type)
-{
- ppcemb_tlb_t *tlb;
- hwaddr raddr;
- int i, ret;
-
- ret = -1;
- raddr = (hwaddr)-1ULL;
- for (i = 0; i < env->nb_tlb; i++) {
- tlb = &env->tlb.tlbe[i];
- ret = mmubooke_check_tlb(env, tlb, &raddr, &ctx->prot, address, rw,
- access_type, i);
- if (!ret) {
- break;
- }
- }
-
- if (ret >= 0) {
- ctx->raddr = raddr;
- LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
- " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
- ret);
- } else {
- LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
- " %d %d\n", __func__, address, raddr, ctx->prot, ret);
- }
-
- return ret;
-}
-
-static void booke206_flush_tlb(CPUPPCState *env, int flags,
- const int check_iprot)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- int tlb_size;
- int i, j;
- ppcmas_tlb_t *tlb = env->tlb.tlbm;
-
- for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
- if (flags & (1 << i)) {
- tlb_size = booke206_tlb_size(env, i);
- for (j = 0; j < tlb_size; j++) {
- if (!check_iprot || !(tlb[j].mas1 & MAS1_IPROT)) {
- tlb[j].mas1 &= ~MAS1_VALID;
- }
- }
- }
- tlb += booke206_tlb_size(env, i);
- }
-
- tlb_flush(CPU(cpu), 1);
-}
-
-static hwaddr booke206_tlb_to_page_size(CPUPPCState *env,
- ppcmas_tlb_t *tlb)
-{
- int tlbm_size;
-
- tlbm_size = (tlb->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
-
- return 1024ULL << tlbm_size;
-}
-
-/* TLB check function for MAS based SoftTLBs */
-static int ppcmas_tlb_check(CPUPPCState *env, ppcmas_tlb_t *tlb,
- hwaddr *raddrp, target_ulong address,
- uint32_t pid)
-{
- hwaddr mask;
- uint32_t tlb_pid;
-
- if (!msr_cm) {
- /* In 32bit mode we can only address 32bit EAs */
- address = (uint32_t)address;
- }
-
- /* Check valid flag */
- if (!(tlb->mas1 & MAS1_VALID)) {
- return -1;
- }
-
- mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
- LOG_SWTLB("%s: TLB ADDR=0x" TARGET_FMT_lx " PID=0x%x MAS1=0x%x MAS2=0x%"
- PRIx64 " mask=0x%" HWADDR_PRIx " MAS7_3=0x%" PRIx64 " MAS8=0x%"
- PRIx32 "\n", __func__, address, pid, tlb->mas1, tlb->mas2, mask,
- tlb->mas7_3, tlb->mas8);
-
- /* Check PID */
- tlb_pid = (tlb->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT;
- if (tlb_pid != 0 && tlb_pid != pid) {
- return -1;
- }
-
- /* Check effective address */
- if ((address & mask) != (tlb->mas2 & MAS2_EPN_MASK)) {
- return -1;
- }
-
- if (raddrp) {
- *raddrp = (tlb->mas7_3 & mask) | (address & ~mask);
- }
-
- return 0;
-}
-
-static int mmubooke206_check_tlb(CPUPPCState *env, ppcmas_tlb_t *tlb,
- hwaddr *raddr, int *prot,
- target_ulong address, int rw,
- int access_type)
-{
- int ret;
- int prot2 = 0;
-
- if (ppcmas_tlb_check(env, tlb, raddr, address,
- env->spr[SPR_BOOKE_PID]) >= 0) {
- goto found_tlb;
- }
-
- if (env->spr[SPR_BOOKE_PID1] &&
- ppcmas_tlb_check(env, tlb, raddr, address,
- env->spr[SPR_BOOKE_PID1]) >= 0) {
- goto found_tlb;
- }
-
- if (env->spr[SPR_BOOKE_PID2] &&
- ppcmas_tlb_check(env, tlb, raddr, address,
- env->spr[SPR_BOOKE_PID2]) >= 0) {
- goto found_tlb;
- }
-
- LOG_SWTLB("%s: TLB entry not found\n", __func__);
- return -1;
-
-found_tlb:
-
- if (msr_pr != 0) {
- if (tlb->mas7_3 & MAS3_UR) {
- prot2 |= PAGE_READ;
- }
- if (tlb->mas7_3 & MAS3_UW) {
- prot2 |= PAGE_WRITE;
- }
- if (tlb->mas7_3 & MAS3_UX) {
- prot2 |= PAGE_EXEC;
- }
- } else {
- if (tlb->mas7_3 & MAS3_SR) {
- prot2 |= PAGE_READ;
- }
- if (tlb->mas7_3 & MAS3_SW) {
- prot2 |= PAGE_WRITE;
- }
- if (tlb->mas7_3 & MAS3_SX) {
- prot2 |= PAGE_EXEC;
- }
- }
-
- /* Check the address space and permissions */
- if (access_type == ACCESS_CODE) {
- if (msr_ir != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
- LOG_SWTLB("%s: AS doesn't match\n", __func__);
- return -1;
- }
-
- *prot = prot2;
- if (prot2 & PAGE_EXEC) {
- LOG_SWTLB("%s: good TLB!\n", __func__);
- return 0;
- }
-
- LOG_SWTLB("%s: no PAGE_EXEC: %x\n", __func__, prot2);
- ret = -3;
- } else {
- if (msr_dr != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
- LOG_SWTLB("%s: AS doesn't match\n", __func__);
- return -1;
- }
-
- *prot = prot2;
- if ((!rw && prot2 & PAGE_READ) || (rw && (prot2 & PAGE_WRITE))) {
- LOG_SWTLB("%s: found TLB!\n", __func__);
- return 0;
- }
-
- LOG_SWTLB("%s: PAGE_READ/WRITE doesn't match: %x\n", __func__, prot2);
- ret = -2;
- }
-
- return ret;
-}
-
-static int mmubooke206_get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
- target_ulong address, int rw,
- int access_type)
-{
- ppcmas_tlb_t *tlb;
- hwaddr raddr;
- int i, j, ret;
-
- ret = -1;
- raddr = (hwaddr)-1ULL;
-
- for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
- int ways = booke206_tlb_ways(env, i);
-
- for (j = 0; j < ways; j++) {
- tlb = booke206_get_tlbm(env, i, address, j);
- if (!tlb) {
- continue;
- }
- ret = mmubooke206_check_tlb(env, tlb, &raddr, &ctx->prot, address,
- rw, access_type);
- if (ret != -1) {
- goto found_tlb;
- }
- }
- }
-
-found_tlb:
-
- if (ret >= 0) {
- ctx->raddr = raddr;
- LOG_SWTLB("%s: access granted " TARGET_FMT_lx " => " TARGET_FMT_plx
- " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
- ret);
- } else {
- LOG_SWTLB("%s: access refused " TARGET_FMT_lx " => " TARGET_FMT_plx
- " %d %d\n", __func__, address, raddr, ctx->prot, ret);
- }
-
- return ret;
-}
-
-static const char *book3e_tsize_to_str[32] = {
- "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K",
- "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M",
- "1G", "2G", "4G", "8G", "16G", "32G", "64G", "128G", "256G", "512G",
- "1T", "2T"
-};
-
-static void mmubooke_dump_mmu(FILE *f, fprintf_function cpu_fprintf,
- CPUPPCState *env)
-{
- ppcemb_tlb_t *entry;
- int i;
-
- if (kvm_enabled() && !env->kvm_sw_tlb) {
- cpu_fprintf(f, "Cannot access KVM TLB\n");
- return;
- }
-
- cpu_fprintf(f, "\nTLB:\n");
- cpu_fprintf(f, "Effective Physical Size PID Prot "
- "Attr\n");
-
- entry = &env->tlb.tlbe[0];
- for (i = 0; i < env->nb_tlb; i++, entry++) {
- hwaddr ea, pa;
- target_ulong mask;
- uint64_t size = (uint64_t)entry->size;
- char size_buf[20];
-
- /* Check valid flag */
- if (!(entry->prot & PAGE_VALID)) {
- continue;
- }
-
- mask = ~(entry->size - 1);
- ea = entry->EPN & mask;
- pa = entry->RPN & mask;
- /* Extend the physical address to 36 bits */
- pa |= (hwaddr)(entry->RPN & 0xF) << 32;
- size /= 1024;
- if (size >= 1024) {
- snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "M", size / 1024);
- } else {
- snprintf(size_buf, sizeof(size_buf), "%3" PRId64 "k", size);
- }
- cpu_fprintf(f, "0x%016" PRIx64 " 0x%016" PRIx64 " %s %-5u %08x %08x\n",
- (uint64_t)ea, (uint64_t)pa, size_buf, (uint32_t)entry->PID,
- entry->prot, entry->attr);
- }
-
-}
-
-static void mmubooke206_dump_one_tlb(FILE *f, fprintf_function cpu_fprintf,
- CPUPPCState *env, int tlbn, int offset,
- int tlbsize)
-{
- ppcmas_tlb_t *entry;
- int i;
-
- cpu_fprintf(f, "\nTLB%d:\n", tlbn);
- cpu_fprintf(f, "Effective Physical Size TID TS SRWX"
- " URWX WIMGE U0123\n");
-
- entry = &env->tlb.tlbm[offset];
- for (i = 0; i < tlbsize; i++, entry++) {
- hwaddr ea, pa, size;
- int tsize;
-
- if (!(entry->mas1 & MAS1_VALID)) {
- continue;
- }
-
- tsize = (entry->mas1 & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
- size = 1024ULL << tsize;
- ea = entry->mas2 & ~(size - 1);
- pa = entry->mas7_3 & ~(size - 1);
-
- cpu_fprintf(f, "0x%016" PRIx64 " 0x%016" PRIx64 " %4s %-5u %1u S%c%c%c"
- "U%c%c%c %c%c%c%c%c U%c%c%c%c\n",
- (uint64_t)ea, (uint64_t)pa,
- book3e_tsize_to_str[tsize],
- (entry->mas1 & MAS1_TID_MASK) >> MAS1_TID_SHIFT,
- (entry->mas1 & MAS1_TS) >> MAS1_TS_SHIFT,
- entry->mas7_3 & MAS3_SR ? 'R' : '-',
- entry->mas7_3 & MAS3_SW ? 'W' : '-',
- entry->mas7_3 & MAS3_SX ? 'X' : '-',
- entry->mas7_3 & MAS3_UR ? 'R' : '-',
- entry->mas7_3 & MAS3_UW ? 'W' : '-',
- entry->mas7_3 & MAS3_UX ? 'X' : '-',
- entry->mas2 & MAS2_W ? 'W' : '-',
- entry->mas2 & MAS2_I ? 'I' : '-',
- entry->mas2 & MAS2_M ? 'M' : '-',
- entry->mas2 & MAS2_G ? 'G' : '-',
- entry->mas2 & MAS2_E ? 'E' : '-',
- entry->mas7_3 & MAS3_U0 ? '0' : '-',
- entry->mas7_3 & MAS3_U1 ? '1' : '-',
- entry->mas7_3 & MAS3_U2 ? '2' : '-',
- entry->mas7_3 & MAS3_U3 ? '3' : '-');
- }
-}
-
-static void mmubooke206_dump_mmu(FILE *f, fprintf_function cpu_fprintf,
- CPUPPCState *env)
-{
- int offset = 0;
- int i;
-
- if (kvm_enabled() && !env->kvm_sw_tlb) {
- cpu_fprintf(f, "Cannot access KVM TLB\n");
- return;
- }
-
- for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
- int size = booke206_tlb_size(env, i);
-
- if (size == 0) {
- continue;
- }
-
- mmubooke206_dump_one_tlb(f, cpu_fprintf, env, i, offset, size);
- offset += size;
- }
-}
-
-static void mmu6xx_dump_BATs(FILE *f, fprintf_function cpu_fprintf,
- CPUPPCState *env, int type)
-{
- target_ulong *BATlt, *BATut, *BATu, *BATl;
- target_ulong BEPIl, BEPIu, bl;
- int i;
-
- switch (type) {
- case ACCESS_CODE:
- BATlt = env->IBAT[1];
- BATut = env->IBAT[0];
- break;
- default:
- BATlt = env->DBAT[1];
- BATut = env->DBAT[0];
- break;
- }
-
- for (i = 0; i < env->nb_BATs; i++) {
- BATu = &BATut[i];
- BATl = &BATlt[i];
- BEPIu = *BATu & 0xF0000000;
- BEPIl = *BATu & 0x0FFE0000;
- bl = (*BATu & 0x00001FFC) << 15;
- cpu_fprintf(f, "%s BAT%d BATu " TARGET_FMT_lx
- " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "
- TARGET_FMT_lx " " TARGET_FMT_lx "\n",
- type == ACCESS_CODE ? "code" : "data", i,
- *BATu, *BATl, BEPIu, BEPIl, bl);
- }
-}
-
-static void mmu6xx_dump_mmu(FILE *f, fprintf_function cpu_fprintf,
- CPUPPCState *env)
-{
- ppc6xx_tlb_t *tlb;
- target_ulong sr;
- int type, way, entry, i;
-
- cpu_fprintf(f, "HTAB base = 0x%"HWADDR_PRIx"\n", env->htab_base);
- cpu_fprintf(f, "HTAB mask = 0x%"HWADDR_PRIx"\n", env->htab_mask);
-
- cpu_fprintf(f, "\nSegment registers:\n");
- for (i = 0; i < 32; i++) {
- sr = env->sr[i];
- if (sr & 0x80000000) {
- cpu_fprintf(f, "%02d T=%d Ks=%d Kp=%d BUID=0x%03x "
- "CNTLR_SPEC=0x%05x\n", i,
- sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
- sr & 0x20000000 ? 1 : 0, (uint32_t)((sr >> 20) & 0x1FF),
- (uint32_t)(sr & 0xFFFFF));
- } else {
- cpu_fprintf(f, "%02d T=%d Ks=%d Kp=%d N=%d VSID=0x%06x\n", i,
- sr & 0x80000000 ? 1 : 0, sr & 0x40000000 ? 1 : 0,
- sr & 0x20000000 ? 1 : 0, sr & 0x10000000 ? 1 : 0,
- (uint32_t)(sr & 0x00FFFFFF));
- }
- }
-
- cpu_fprintf(f, "\nBATs:\n");
- mmu6xx_dump_BATs(f, cpu_fprintf, env, ACCESS_INT);
- mmu6xx_dump_BATs(f, cpu_fprintf, env, ACCESS_CODE);
-
- if (env->id_tlbs != 1) {
- cpu_fprintf(f, "ERROR: 6xx MMU should have separated TLB"
- " for code and data\n");
- }
-
- cpu_fprintf(f, "\nTLBs [EPN EPN + SIZE]\n");
-
- for (type = 0; type < 2; type++) {
- for (way = 0; way < env->nb_ways; way++) {
- for (entry = env->nb_tlb * type + env->tlb_per_way * way;
- entry < (env->nb_tlb * type + env->tlb_per_way * (way + 1));
- entry++) {
-
- tlb = &env->tlb.tlb6[entry];
- cpu_fprintf(f, "%s TLB %02d/%02d way:%d %s ["
- TARGET_FMT_lx " " TARGET_FMT_lx "]\n",
- type ? "code" : "data", entry % env->nb_tlb,
- env->nb_tlb, way,
- pte_is_valid(tlb->pte0) ? "valid" : "inval",
- tlb->EPN, tlb->EPN + TARGET_PAGE_SIZE);
- }
- }
- }
-}
-
-void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
-{
- switch (env->mmu_model) {
- case POWERPC_MMU_BOOKE:
- mmubooke_dump_mmu(f, cpu_fprintf, env);
- break;
- case POWERPC_MMU_BOOKE206:
- mmubooke206_dump_mmu(f, cpu_fprintf, env);
- break;
- case POWERPC_MMU_SOFT_6xx:
- case POWERPC_MMU_SOFT_74xx:
- mmu6xx_dump_mmu(f, cpu_fprintf, env);
- break;
-#if defined(TARGET_PPC64)
- case POWERPC_MMU_64B:
- case POWERPC_MMU_2_03:
- case POWERPC_MMU_2_06:
- case POWERPC_MMU_2_06a:
- case POWERPC_MMU_2_07:
- case POWERPC_MMU_2_07a:
- dump_slb(f, cpu_fprintf, ppc_env_get_cpu(env));
- break;
-#endif
- default:
- qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__);
- }
-}
-
-static inline int check_physical(CPUPPCState *env, mmu_ctx_t *ctx,
- target_ulong eaddr, int rw)
-{
- int in_plb, ret;
-
- ctx->raddr = eaddr;
- ctx->prot = PAGE_READ | PAGE_EXEC;
- ret = 0;
- switch (env->mmu_model) {
- case POWERPC_MMU_SOFT_6xx:
- case POWERPC_MMU_SOFT_74xx:
- case POWERPC_MMU_SOFT_4xx:
- case POWERPC_MMU_REAL:
- case POWERPC_MMU_BOOKE:
- ctx->prot |= PAGE_WRITE;
- break;
-
- case POWERPC_MMU_SOFT_4xx_Z:
- if (unlikely(msr_pe != 0)) {
- /* 403 family add some particular protections,
- * using PBL/PBU registers for accesses with no translation.
- */
- in_plb =
- /* Check PLB validity */
- (env->pb[0] < env->pb[1] &&
- /* and address in plb area */
- eaddr >= env->pb[0] && eaddr < env->pb[1]) ||
- (env->pb[2] < env->pb[3] &&
- eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0;
- if (in_plb ^ msr_px) {
- /* Access in protected area */
- if (rw == 1) {
- /* Access is not allowed */
- ret = -2;
- }
- } else {
- /* Read-write access is allowed */
- ctx->prot |= PAGE_WRITE;
- }
- }
- break;
-
- default:
- /* Caller's checks mean we should never get here for other models */
- abort();
- return -1;
- }
-
- return ret;
-}
-
-static int get_physical_address(CPUPPCState *env, mmu_ctx_t *ctx,
- target_ulong eaddr, int rw, int access_type)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- int ret = -1;
- bool real_mode = (access_type == ACCESS_CODE && msr_ir == 0)
- || (access_type != ACCESS_CODE && msr_dr == 0);
-
-#if 0
- qemu_log("%s\n", __func__);
-#endif
-
- switch (env->mmu_model) {
- case POWERPC_MMU_SOFT_6xx:
- case POWERPC_MMU_SOFT_74xx:
- if (real_mode) {
- ret = check_physical(env, ctx, eaddr, rw);
- } else {
- /* Try to find a BAT */
- if (env->nb_BATs != 0) {
- ret = get_bat_6xx_tlb(env, ctx, eaddr, rw, access_type);
- }
- if (ret < 0) {
- /* We didn't match any BAT entry or don't have BATs */
- ret = get_segment_6xx_tlb(env, ctx, eaddr, rw, access_type);
- }
- }
- break;
-
- case POWERPC_MMU_SOFT_4xx:
- case POWERPC_MMU_SOFT_4xx_Z:
- if (real_mode) {
- ret = check_physical(env, ctx, eaddr, rw);
- } else {
- ret = mmu40x_get_physical_address(env, ctx, eaddr,
- rw, access_type);
- }
- break;
- case POWERPC_MMU_BOOKE:
- ret = mmubooke_get_physical_address(env, ctx, eaddr,
- rw, access_type);
- break;
- case POWERPC_MMU_BOOKE206:
- ret = mmubooke206_get_physical_address(env, ctx, eaddr, rw,
- access_type);
- break;
- case POWERPC_MMU_MPC8xx:
- /* XXX: TODO */
- cpu_abort(CPU(cpu), "MPC8xx MMU model is not implemented\n");
- break;
- case POWERPC_MMU_REAL:
- if (real_mode) {
- ret = check_physical(env, ctx, eaddr, rw);
- } else {
- cpu_abort(CPU(cpu), "PowerPC in real mode do not do any translation\n");
- }
- return -1;
- default:
- cpu_abort(CPU(cpu), "Unknown or invalid MMU model\n");
- return -1;
- }
-#if 0
- qemu_log("%s address " TARGET_FMT_lx " => %d " TARGET_FMT_plx "\n",
- __func__, eaddr, ret, ctx->raddr);
-#endif
-
- return ret;
-}
-
-hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- mmu_ctx_t ctx;
-
- switch (env->mmu_model) {
-#if defined(TARGET_PPC64)
- case POWERPC_MMU_64B:
- case POWERPC_MMU_2_03:
- case POWERPC_MMU_2_06:
- case POWERPC_MMU_2_06a:
- case POWERPC_MMU_2_07:
- case POWERPC_MMU_2_07a:
- return ppc_hash64_get_phys_page_debug(cpu, addr);
-#endif
-
- case POWERPC_MMU_32B:
- case POWERPC_MMU_601:
- return ppc_hash32_get_phys_page_debug(cpu, addr);
-
- default:
- ;
- }
-
- if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0)) {
-
- /* Some MMUs have separate TLBs for code and data. If we only try an
- * ACCESS_INT, we may not be able to read instructions mapped by code
- * TLBs, so we also try a ACCESS_CODE.
- */
- if (unlikely(get_physical_address(env, &ctx, addr, 0,
- ACCESS_CODE) != 0)) {
- return -1;
- }
- }
-
- return ctx.raddr & TARGET_PAGE_MASK;
-}
-
-static void booke206_update_mas_tlb_miss(CPUPPCState *env, target_ulong address,
- int rw)
-{
- env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK;
- env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK;
- env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK;
- env->spr[SPR_BOOKE_MAS3] = 0;
- env->spr[SPR_BOOKE_MAS6] = 0;
- env->spr[SPR_BOOKE_MAS7] = 0;
-
- /* AS */
- if (((rw == 2) && msr_ir) || ((rw != 2) && msr_dr)) {
- env->spr[SPR_BOOKE_MAS1] |= MAS1_TS;
- env->spr[SPR_BOOKE_MAS6] |= MAS6_SAS;
- }
-
- env->spr[SPR_BOOKE_MAS1] |= MAS1_VALID;
- env->spr[SPR_BOOKE_MAS2] |= address & MAS2_EPN_MASK;
-
- switch (env->spr[SPR_BOOKE_MAS4] & MAS4_TIDSELD_PIDZ) {
- case MAS4_TIDSELD_PID0:
- env->spr[SPR_BOOKE_MAS1] |= env->spr[SPR_BOOKE_PID] << MAS1_TID_SHIFT;
- break;
- case MAS4_TIDSELD_PID1:
- env->spr[SPR_BOOKE_MAS1] |= env->spr[SPR_BOOKE_PID1] << MAS1_TID_SHIFT;
- break;
- case MAS4_TIDSELD_PID2:
- env->spr[SPR_BOOKE_MAS1] |= env->spr[SPR_BOOKE_PID2] << MAS1_TID_SHIFT;
- break;
- }
-
- env->spr[SPR_BOOKE_MAS6] |= env->spr[SPR_BOOKE_PID] << 16;
-
- /* next victim logic */
- env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
- env->last_way++;
- env->last_way &= booke206_tlb_ways(env, 0) - 1;
- env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
-}
-
-/* Perform address translation */
-static int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address,
- int rw, int mmu_idx)
-{
- CPUState *cs = CPU(ppc_env_get_cpu(env));
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- mmu_ctx_t ctx;
- int access_type;
- int ret = 0;
-
- if (rw == 2) {
- /* code access */
- rw = 0;
- access_type = ACCESS_CODE;
- } else {
- /* data access */
- access_type = env->access_type;
- }
- ret = get_physical_address(env, &ctx, address, rw, access_type);
- if (ret == 0) {
- tlb_set_page(cs, address & TARGET_PAGE_MASK,
- ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
- mmu_idx, TARGET_PAGE_SIZE);
- ret = 0;
- } else if (ret < 0) {
- LOG_MMU_STATE(cs);
- if (access_type == ACCESS_CODE) {
- switch (ret) {
- case -1:
- /* No matches in page tables or TLB */
- switch (env->mmu_model) {
- case POWERPC_MMU_SOFT_6xx:
- cs->exception_index = POWERPC_EXCP_IFTLB;
- env->error_code = 1 << 18;
- env->spr[SPR_IMISS] = address;
- env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
- goto tlb_miss;
- case POWERPC_MMU_SOFT_74xx:
- cs->exception_index = POWERPC_EXCP_IFTLB;
- goto tlb_miss_74xx;
- case POWERPC_MMU_SOFT_4xx:
- case POWERPC_MMU_SOFT_4xx_Z:
- cs->exception_index = POWERPC_EXCP_ITLB;
- env->error_code = 0;
- env->spr[SPR_40x_DEAR] = address;
- env->spr[SPR_40x_ESR] = 0x00000000;
- break;
- case POWERPC_MMU_BOOKE206:
- booke206_update_mas_tlb_miss(env, address, rw);
- /* fall through */
- case POWERPC_MMU_BOOKE:
- cs->exception_index = POWERPC_EXCP_ITLB;
- env->error_code = 0;
- env->spr[SPR_BOOKE_DEAR] = address;
- return -1;
- case POWERPC_MMU_MPC8xx:
- /* XXX: TODO */
- cpu_abort(cs, "MPC8xx MMU model is not implemented\n");
- break;
- case POWERPC_MMU_REAL:
- cpu_abort(cs, "PowerPC in real mode should never raise "
- "any MMU exceptions\n");
- return -1;
- default:
- cpu_abort(cs, "Unknown or invalid MMU model\n");
- return -1;
- }
- break;
- case -2:
- /* Access rights violation */
- cs->exception_index = POWERPC_EXCP_ISI;
- env->error_code = 0x08000000;
- break;
- case -3:
- /* No execute protection violation */
- if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
- (env->mmu_model == POWERPC_MMU_BOOKE206)) {
- env->spr[SPR_BOOKE_ESR] = 0x00000000;
- }
- cs->exception_index = POWERPC_EXCP_ISI;
- env->error_code = 0x10000000;
- break;
- case -4:
- /* Direct store exception */
- /* No code fetch is allowed in direct-store areas */
- cs->exception_index = POWERPC_EXCP_ISI;
- env->error_code = 0x10000000;
- break;
- }
- } else {
- switch (ret) {
- case -1:
- /* No matches in page tables or TLB */
- switch (env->mmu_model) {
- case POWERPC_MMU_SOFT_6xx:
- if (rw == 1) {
- cs->exception_index = POWERPC_EXCP_DSTLB;
- env->error_code = 1 << 16;
- } else {
- cs->exception_index = POWERPC_EXCP_DLTLB;
- env->error_code = 0;
- }
- env->spr[SPR_DMISS] = address;
- env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;
- tlb_miss:
- env->error_code |= ctx.key << 19;
- env->spr[SPR_HASH1] = env->htab_base +
- get_pteg_offset32(cpu, ctx.hash[0]);
- env->spr[SPR_HASH2] = env->htab_base +
- get_pteg_offset32(cpu, ctx.hash[1]);
- break;
- case POWERPC_MMU_SOFT_74xx:
- if (rw == 1) {
- cs->exception_index = POWERPC_EXCP_DSTLB;
- } else {
- cs->exception_index = POWERPC_EXCP_DLTLB;
- }
- tlb_miss_74xx:
- /* Implement LRU algorithm */
- env->error_code = ctx.key << 19;
- env->spr[SPR_TLBMISS] = (address & ~((target_ulong)0x3)) |
- ((env->last_way + 1) & (env->nb_ways - 1));
- env->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem;
- break;
- case POWERPC_MMU_SOFT_4xx:
- case POWERPC_MMU_SOFT_4xx_Z:
- cs->exception_index = POWERPC_EXCP_DTLB;
- env->error_code = 0;
- env->spr[SPR_40x_DEAR] = address;
- if (rw) {
- env->spr[SPR_40x_ESR] = 0x00800000;
- } else {
- env->spr[SPR_40x_ESR] = 0x00000000;
- }
- break;
- case POWERPC_MMU_MPC8xx:
- /* XXX: TODO */
- cpu_abort(cs, "MPC8xx MMU model is not implemented\n");
- break;
- case POWERPC_MMU_BOOKE206:
- booke206_update_mas_tlb_miss(env, address, rw);
- /* fall through */
- case POWERPC_MMU_BOOKE:
- cs->exception_index = POWERPC_EXCP_DTLB;
- env->error_code = 0;
- env->spr[SPR_BOOKE_DEAR] = address;
- env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0;
- return -1;
- case POWERPC_MMU_REAL:
- cpu_abort(cs, "PowerPC in real mode should never raise "
- "any MMU exceptions\n");
- return -1;
- default:
- cpu_abort(cs, "Unknown or invalid MMU model\n");
- return -1;
- }
- break;
- case -2:
- /* Access rights violation */
- cs->exception_index = POWERPC_EXCP_DSI;
- env->error_code = 0;
- if (env->mmu_model == POWERPC_MMU_SOFT_4xx
- || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) {
- env->spr[SPR_40x_DEAR] = address;
- if (rw) {
- env->spr[SPR_40x_ESR] |= 0x00800000;
- }
- } else if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
- (env->mmu_model == POWERPC_MMU_BOOKE206)) {
- env->spr[SPR_BOOKE_DEAR] = address;
- env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0;
- } else {
- env->spr[SPR_DAR] = address;
- if (rw == 1) {
- env->spr[SPR_DSISR] = 0x0A000000;
- } else {
- env->spr[SPR_DSISR] = 0x08000000;
- }
- }
- break;
- case -4:
- /* Direct store exception */
- switch (access_type) {
- case ACCESS_FLOAT:
- /* Floating point load/store */
- cs->exception_index = POWERPC_EXCP_ALIGN;
- env->error_code = POWERPC_EXCP_ALIGN_FP;
- env->spr[SPR_DAR] = address;
- break;
- case ACCESS_RES:
- /* lwarx, ldarx or stwcx. */
- cs->exception_index = POWERPC_EXCP_DSI;
- env->error_code = 0;
- env->spr[SPR_DAR] = address;
- if (rw == 1) {
- env->spr[SPR_DSISR] = 0x06000000;
- } else {
- env->spr[SPR_DSISR] = 0x04000000;
- }
- break;
- case ACCESS_EXT:
- /* eciwx or ecowx */
- cs->exception_index = POWERPC_EXCP_DSI;
- env->error_code = 0;
- env->spr[SPR_DAR] = address;
- if (rw == 1) {
- env->spr[SPR_DSISR] = 0x06100000;
- } else {
- env->spr[SPR_DSISR] = 0x04100000;
- }
- break;
- default:
- printf("DSI: invalid exception (%d)\n", ret);
- cs->exception_index = POWERPC_EXCP_PROGRAM;
- env->error_code =
- POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
- env->spr[SPR_DAR] = address;
- break;
- }
- break;
- }
- }
-#if 0
- printf("%s: set exception to %d %02x\n", __func__,
- cs->exception, env->error_code);
-#endif
- ret = 1;
- }
-
- return ret;
-}
-
-/*****************************************************************************/
-/* BATs management */
-#if !defined(FLUSH_ALL_TLBS)
-static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu,
- target_ulong mask)
-{
- CPUState *cs = CPU(ppc_env_get_cpu(env));
- target_ulong base, end, page;
-
- base = BATu & ~0x0001FFFF;
- end = base + mask + 0x00020000;
- LOG_BATS("Flush BAT from " TARGET_FMT_lx " to " TARGET_FMT_lx " ("
- TARGET_FMT_lx ")\n", base, end, mask);
- for (page = base; page != end; page += TARGET_PAGE_SIZE) {
- tlb_flush_page(cs, page);
- }
- LOG_BATS("Flush done\n");
-}
-#endif
-
-static inline void dump_store_bat(CPUPPCState *env, char ID, int ul, int nr,
- target_ulong value)
-{
- LOG_BATS("Set %cBAT%d%c to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n", ID,
- nr, ul == 0 ? 'u' : 'l', value, env->nip);
-}
-
-void helper_store_ibatu(CPUPPCState *env, uint32_t nr, target_ulong value)
-{
- target_ulong mask;
-#if defined(FLUSH_ALL_TLBS)
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
-#endif
-
- dump_store_bat(env, 'I', 0, nr, value);
- if (env->IBAT[0][nr] != value) {
- mask = (value << 15) & 0x0FFE0000UL;
-#if !defined(FLUSH_ALL_TLBS)
- do_invalidate_BAT(env, env->IBAT[0][nr], mask);
-#endif
- /* When storing valid upper BAT, mask BEPI and BRPN
- * and invalidate all TLBs covered by this BAT
- */
- mask = (value << 15) & 0x0FFE0000UL;
- env->IBAT[0][nr] = (value & 0x00001FFFUL) |
- (value & ~0x0001FFFFUL & ~mask);
- env->IBAT[1][nr] = (env->IBAT[1][nr] & 0x0000007B) |
- (env->IBAT[1][nr] & ~0x0001FFFF & ~mask);
-#if !defined(FLUSH_ALL_TLBS)
- do_invalidate_BAT(env, env->IBAT[0][nr], mask);
-#else
- tlb_flush(CPU(cpu), 1);
-#endif
- }
-}
-
-void helper_store_ibatl(CPUPPCState *env, uint32_t nr, target_ulong value)
-{
- dump_store_bat(env, 'I', 1, nr, value);
- env->IBAT[1][nr] = value;
-}
-
-void helper_store_dbatu(CPUPPCState *env, uint32_t nr, target_ulong value)
-{
- target_ulong mask;
-#if defined(FLUSH_ALL_TLBS)
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
-#endif
-
- dump_store_bat(env, 'D', 0, nr, value);
- if (env->DBAT[0][nr] != value) {
- /* When storing valid upper BAT, mask BEPI and BRPN
- * and invalidate all TLBs covered by this BAT
- */
- mask = (value << 15) & 0x0FFE0000UL;
-#if !defined(FLUSH_ALL_TLBS)
- do_invalidate_BAT(env, env->DBAT[0][nr], mask);
-#endif
- mask = (value << 15) & 0x0FFE0000UL;
- env->DBAT[0][nr] = (value & 0x00001FFFUL) |
- (value & ~0x0001FFFFUL & ~mask);
- env->DBAT[1][nr] = (env->DBAT[1][nr] & 0x0000007B) |
- (env->DBAT[1][nr] & ~0x0001FFFF & ~mask);
-#if !defined(FLUSH_ALL_TLBS)
- do_invalidate_BAT(env, env->DBAT[0][nr], mask);
-#else
- tlb_flush(CPU(cpu), 1);
-#endif
- }
-}
-
-void helper_store_dbatl(CPUPPCState *env, uint32_t nr, target_ulong value)
-{
- dump_store_bat(env, 'D', 1, nr, value);
- env->DBAT[1][nr] = value;
-}
-
-void helper_store_601_batu(CPUPPCState *env, uint32_t nr, target_ulong value)
-{
- target_ulong mask;
-#if defined(FLUSH_ALL_TLBS)
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- int do_inval;
-#endif
-
- dump_store_bat(env, 'I', 0, nr, value);
- if (env->IBAT[0][nr] != value) {
-#if defined(FLUSH_ALL_TLBS)
- do_inval = 0;
-#endif
- mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
- if (env->IBAT[1][nr] & 0x40) {
- /* Invalidate BAT only if it is valid */
-#if !defined(FLUSH_ALL_TLBS)
- do_invalidate_BAT(env, env->IBAT[0][nr], mask);
-#else
- do_inval = 1;
-#endif
- }
- /* When storing valid upper BAT, mask BEPI and BRPN
- * and invalidate all TLBs covered by this BAT
- */
- env->IBAT[0][nr] = (value & 0x00001FFFUL) |
- (value & ~0x0001FFFFUL & ~mask);
- env->DBAT[0][nr] = env->IBAT[0][nr];
- if (env->IBAT[1][nr] & 0x40) {
-#if !defined(FLUSH_ALL_TLBS)
- do_invalidate_BAT(env, env->IBAT[0][nr], mask);
-#else
- do_inval = 1;
-#endif
- }
-#if defined(FLUSH_ALL_TLBS)
- if (do_inval) {
- tlb_flush(CPU(cpu), 1);
- }
-#endif
- }
-}
-
-void helper_store_601_batl(CPUPPCState *env, uint32_t nr, target_ulong value)
-{
-#if !defined(FLUSH_ALL_TLBS)
- target_ulong mask;
-#else
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- int do_inval;
-#endif
-
- dump_store_bat(env, 'I', 1, nr, value);
- if (env->IBAT[1][nr] != value) {
-#if defined(FLUSH_ALL_TLBS)
- do_inval = 0;
-#endif
- if (env->IBAT[1][nr] & 0x40) {
-#if !defined(FLUSH_ALL_TLBS)
- mask = (env->IBAT[1][nr] << 17) & 0x0FFE0000UL;
- do_invalidate_BAT(env, env->IBAT[0][nr], mask);
-#else
- do_inval = 1;
-#endif
- }
- if (value & 0x40) {
-#if !defined(FLUSH_ALL_TLBS)
- mask = (value << 17) & 0x0FFE0000UL;
- do_invalidate_BAT(env, env->IBAT[0][nr], mask);
-#else
- do_inval = 1;
-#endif
- }
- env->IBAT[1][nr] = value;
- env->DBAT[1][nr] = value;
-#if defined(FLUSH_ALL_TLBS)
- if (do_inval) {
- tlb_flush(CPU(cpu), 1);
- }
-#endif
- }
-}
-
-/*****************************************************************************/
-/* TLB management */
-void ppc_tlb_invalidate_all(CPUPPCState *env)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
-
- switch (env->mmu_model) {
- case POWERPC_MMU_SOFT_6xx:
- case POWERPC_MMU_SOFT_74xx:
- ppc6xx_tlb_invalidate_all(env);
- break;
- case POWERPC_MMU_SOFT_4xx:
- case POWERPC_MMU_SOFT_4xx_Z:
- ppc4xx_tlb_invalidate_all(env);
- break;
- case POWERPC_MMU_REAL:
- cpu_abort(CPU(cpu), "No TLB for PowerPC 4xx in real mode\n");
- break;
- case POWERPC_MMU_MPC8xx:
- /* XXX: TODO */
- cpu_abort(CPU(cpu), "MPC8xx MMU model is not implemented\n");
- break;
- case POWERPC_MMU_BOOKE:
- tlb_flush(CPU(cpu), 1);
- break;
- case POWERPC_MMU_BOOKE206:
- booke206_flush_tlb(env, -1, 0);
- break;
- case POWERPC_MMU_32B:
- case POWERPC_MMU_601:
-#if defined(TARGET_PPC64)
- case POWERPC_MMU_64B:
- case POWERPC_MMU_2_03:
- case POWERPC_MMU_2_06:
- case POWERPC_MMU_2_06a:
- case POWERPC_MMU_2_07:
- case POWERPC_MMU_2_07a:
-#endif /* defined(TARGET_PPC64) */
- env->tlb_need_flush = 0;
- tlb_flush(CPU(cpu), 1);
- break;
- default:
- /* XXX: TODO */
- cpu_abort(CPU(cpu), "Unknown MMU model %d\n", env->mmu_model);
- break;
- }
-}
-
-void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
-{
-#if !defined(FLUSH_ALL_TLBS)
- addr &= TARGET_PAGE_MASK;
- switch (env->mmu_model) {
- case POWERPC_MMU_SOFT_6xx:
- case POWERPC_MMU_SOFT_74xx:
- ppc6xx_tlb_invalidate_virt(env, addr, 0);
- if (env->id_tlbs == 1) {
- ppc6xx_tlb_invalidate_virt(env, addr, 1);
- }
- break;
- case POWERPC_MMU_32B:
- case POWERPC_MMU_601:
- /* Actual CPUs invalidate entire congruence classes based on the
- * geometry of their TLBs and some OSes take that into account,
- * we just mark the TLB to be flushed later (context synchronizing
- * event or sync instruction on 32-bit).
- */
- env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH;
- break;
-#if defined(TARGET_PPC64)
- case POWERPC_MMU_64B:
- case POWERPC_MMU_2_03:
- case POWERPC_MMU_2_06:
- case POWERPC_MMU_2_06a:
- case POWERPC_MMU_2_07:
- case POWERPC_MMU_2_07a:
- /* tlbie invalidate TLBs for all segments */
- /* XXX: given the fact that there are too many segments to invalidate,
- * and we still don't have a tlb_flush_mask(env, n, mask) in QEMU,
- * we just invalidate all TLBs
- */
- env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH;
- break;
-#endif /* defined(TARGET_PPC64) */
- default:
- /* Should never reach here with other MMU models */
- assert(0);
- }
-#else
- ppc_tlb_invalidate_all(env);
-#endif
-}
-
-/*****************************************************************************/
-/* Special registers manipulation */
-void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
-{
- qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value);
- assert(!env->external_htab);
- env->spr[SPR_SDR1] = value;
-#if defined(TARGET_PPC64)
- if (env->mmu_model & POWERPC_MMU_64) {
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- Error *local_err = NULL;
-
- ppc_hash64_set_sdr1(cpu, value, &local_err);
- if (local_err) {
- error_report_err(local_err);
- error_free(local_err);
- }
- } else
-#endif /* defined(TARGET_PPC64) */
- {
- /* FIXME: Should check for valid HTABMASK values */
- env->htab_mask = ((value & SDR_32_HTABMASK) << 16) | 0xFFFF;
- env->htab_base = value & SDR_32_HTABORG;
- }
-}
-
-/* Segment registers load and store */
-target_ulong helper_load_sr(CPUPPCState *env, target_ulong sr_num)
-{
-#if defined(TARGET_PPC64)
- if (env->mmu_model & POWERPC_MMU_64) {
- /* XXX */
- return 0;
- }
-#endif
- return env->sr[sr_num];
-}
-
-void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value)
-{
- qemu_log_mask(CPU_LOG_MMU,
- "%s: reg=%d " TARGET_FMT_lx " " TARGET_FMT_lx "\n", __func__,
- (int)srnum, value, env->sr[srnum]);
-#if defined(TARGET_PPC64)
- if (env->mmu_model & POWERPC_MMU_64) {
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- uint64_t esid, vsid;
-
- /* ESID = srnum */
- esid = ((uint64_t)(srnum & 0xf) << 28) | SLB_ESID_V;
-
- /* VSID = VSID */
- vsid = (value & 0xfffffff) << 12;
- /* flags = flags */
- vsid |= ((value >> 27) & 0xf) << 8;
-
- ppc_store_slb(cpu, srnum, esid, vsid);
- } else
-#endif
- if (env->sr[srnum] != value) {
- env->sr[srnum] = value;
-/* Invalidating 256MB of virtual memory in 4kB pages is way longer than
- flusing the whole TLB. */
-#if !defined(FLUSH_ALL_TLBS) && 0
- {
- target_ulong page, end;
- /* Invalidate 256 MB of virtual memory */
- page = (16 << 20) * srnum;
- end = page + (16 << 20);
- for (; page != end; page += TARGET_PAGE_SIZE) {
- tlb_flush_page(CPU(cpu), page);
- }
- }
-#else
- env->tlb_need_flush |= TLB_NEED_LOCAL_FLUSH;
-#endif
- }
-}
-
-/* TLB management */
-void helper_tlbia(CPUPPCState *env)
-{
- ppc_tlb_invalidate_all(env);
-}
-
-void helper_tlbie(CPUPPCState *env, target_ulong addr)
-{
- ppc_tlb_invalidate_one(env, addr);
-}
-
-void helper_tlbiva(CPUPPCState *env, target_ulong addr)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
-
- /* tlbiva instruction only exists on BookE */
- assert(env->mmu_model == POWERPC_MMU_BOOKE);
- /* XXX: TODO */
- cpu_abort(CPU(cpu), "BookE MMU model is not implemented\n");
-}
-
-/* Software driven TLBs management */
-/* PowerPC 602/603 software TLB load instructions helpers */
-static void do_6xx_tlb(CPUPPCState *env, target_ulong new_EPN, int is_code)
-{
- target_ulong RPN, CMP, EPN;
- int way;
-
- RPN = env->spr[SPR_RPA];
- if (is_code) {
- CMP = env->spr[SPR_ICMP];
- EPN = env->spr[SPR_IMISS];
- } else {
- CMP = env->spr[SPR_DCMP];
- EPN = env->spr[SPR_DMISS];
- }
- way = (env->spr[SPR_SRR1] >> 17) & 1;
- (void)EPN; /* avoid a compiler warning */
- LOG_SWTLB("%s: EPN " TARGET_FMT_lx " " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx
- " PTE1 " TARGET_FMT_lx " way %d\n", __func__, new_EPN, EPN, CMP,
- RPN, way);
- /* Store this TLB */
- ppc6xx_tlb_store(env, (uint32_t)(new_EPN & TARGET_PAGE_MASK),
- way, is_code, CMP, RPN);
-}
-
-void helper_6xx_tlbd(CPUPPCState *env, target_ulong EPN)
-{
- do_6xx_tlb(env, EPN, 0);
-}
-
-void helper_6xx_tlbi(CPUPPCState *env, target_ulong EPN)
-{
- do_6xx_tlb(env, EPN, 1);
-}
-
-/* PowerPC 74xx software TLB load instructions helpers */
-static void do_74xx_tlb(CPUPPCState *env, target_ulong new_EPN, int is_code)
-{
- target_ulong RPN, CMP, EPN;
- int way;
-
- RPN = env->spr[SPR_PTELO];
- CMP = env->spr[SPR_PTEHI];
- EPN = env->spr[SPR_TLBMISS] & ~0x3;
- way = env->spr[SPR_TLBMISS] & 0x3;
- (void)EPN; /* avoid a compiler warning */
- LOG_SWTLB("%s: EPN " TARGET_FMT_lx " " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx
- " PTE1 " TARGET_FMT_lx " way %d\n", __func__, new_EPN, EPN, CMP,
- RPN, way);
- /* Store this TLB */
- ppc6xx_tlb_store(env, (uint32_t)(new_EPN & TARGET_PAGE_MASK),
- way, is_code, CMP, RPN);
-}
-
-void helper_74xx_tlbd(CPUPPCState *env, target_ulong EPN)
-{
- do_74xx_tlb(env, EPN, 0);
-}
-
-void helper_74xx_tlbi(CPUPPCState *env, target_ulong EPN)
-{
- do_74xx_tlb(env, EPN, 1);
-}
-
-/*****************************************************************************/
-/* PowerPC 601 specific instructions (POWER bridge) */
-
-target_ulong helper_rac(CPUPPCState *env, target_ulong addr)
-{
- mmu_ctx_t ctx;
- int nb_BATs;
- target_ulong ret = 0;
-
- /* We don't have to generate many instances of this instruction,
- * as rac is supervisor only.
- */
- /* XXX: FIX THIS: Pretend we have no BAT */
- nb_BATs = env->nb_BATs;
- env->nb_BATs = 0;
- if (get_physical_address(env, &ctx, addr, 0, ACCESS_INT) == 0) {
- ret = ctx.raddr;
- }
- env->nb_BATs = nb_BATs;
- return ret;
-}
-
-static inline target_ulong booke_tlb_to_page_size(int size)
-{
- return 1024 << (2 * size);
-}
-
-static inline int booke_page_size_to_tlb(target_ulong page_size)
-{
- int size;
-
- switch (page_size) {
- case 0x00000400UL:
- size = 0x0;
- break;
- case 0x00001000UL:
- size = 0x1;
- break;
- case 0x00004000UL:
- size = 0x2;
- break;
- case 0x00010000UL:
- size = 0x3;
- break;
- case 0x00040000UL:
- size = 0x4;
- break;
- case 0x00100000UL:
- size = 0x5;
- break;
- case 0x00400000UL:
- size = 0x6;
- break;
- case 0x01000000UL:
- size = 0x7;
- break;
- case 0x04000000UL:
- size = 0x8;
- break;
- case 0x10000000UL:
- size = 0x9;
- break;
- case 0x40000000UL:
- size = 0xA;
- break;
-#if defined(TARGET_PPC64)
- case 0x000100000000ULL:
- size = 0xB;
- break;
- case 0x000400000000ULL:
- size = 0xC;
- break;
- case 0x001000000000ULL:
- size = 0xD;
- break;
- case 0x004000000000ULL:
- size = 0xE;
- break;
- case 0x010000000000ULL:
- size = 0xF;
- break;
-#endif
- default:
- size = -1;
- break;
- }
-
- return size;
-}
-
-/* Helpers for 4xx TLB management */
-#define PPC4XX_TLB_ENTRY_MASK 0x0000003f /* Mask for 64 TLB entries */
-
-#define PPC4XX_TLBHI_V 0x00000040
-#define PPC4XX_TLBHI_E 0x00000020
-#define PPC4XX_TLBHI_SIZE_MIN 0
-#define PPC4XX_TLBHI_SIZE_MAX 7
-#define PPC4XX_TLBHI_SIZE_DEFAULT 1
-#define PPC4XX_TLBHI_SIZE_SHIFT 7
-#define PPC4XX_TLBHI_SIZE_MASK 0x00000007
-
-#define PPC4XX_TLBLO_EX 0x00000200
-#define PPC4XX_TLBLO_WR 0x00000100
-#define PPC4XX_TLBLO_ATTR_MASK 0x000000FF
-#define PPC4XX_TLBLO_RPN_MASK 0xFFFFFC00
-
-target_ulong helper_4xx_tlbre_hi(CPUPPCState *env, target_ulong entry)
-{
- ppcemb_tlb_t *tlb;
- target_ulong ret;
- int size;
-
- entry &= PPC4XX_TLB_ENTRY_MASK;
- tlb = &env->tlb.tlbe[entry];
- ret = tlb->EPN;
- if (tlb->prot & PAGE_VALID) {
- ret |= PPC4XX_TLBHI_V;
- }
- size = booke_page_size_to_tlb(tlb->size);
- if (size < PPC4XX_TLBHI_SIZE_MIN || size > PPC4XX_TLBHI_SIZE_MAX) {
- size = PPC4XX_TLBHI_SIZE_DEFAULT;
- }
- ret |= size << PPC4XX_TLBHI_SIZE_SHIFT;
- env->spr[SPR_40x_PID] = tlb->PID;
- return ret;
-}
-
-target_ulong helper_4xx_tlbre_lo(CPUPPCState *env, target_ulong entry)
-{
- ppcemb_tlb_t *tlb;
- target_ulong ret;
-
- entry &= PPC4XX_TLB_ENTRY_MASK;
- tlb = &env->tlb.tlbe[entry];
- ret = tlb->RPN;
- if (tlb->prot & PAGE_EXEC) {
- ret |= PPC4XX_TLBLO_EX;
- }
- if (tlb->prot & PAGE_WRITE) {
- ret |= PPC4XX_TLBLO_WR;
- }
- return ret;
-}
-
-void helper_4xx_tlbwe_hi(CPUPPCState *env, target_ulong entry,
- target_ulong val)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- CPUState *cs = CPU(cpu);
- ppcemb_tlb_t *tlb;
- target_ulong page, end;
-
- LOG_SWTLB("%s entry %d val " TARGET_FMT_lx "\n", __func__, (int)entry,
- val);
- entry &= PPC4XX_TLB_ENTRY_MASK;
- tlb = &env->tlb.tlbe[entry];
- /* Invalidate previous TLB (if it's valid) */
- if (tlb->prot & PAGE_VALID) {
- end = tlb->EPN + tlb->size;
- LOG_SWTLB("%s: invalidate old TLB %d start " TARGET_FMT_lx " end "
- TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end);
- for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) {
- tlb_flush_page(cs, page);
- }
- }
- tlb->size = booke_tlb_to_page_size((val >> PPC4XX_TLBHI_SIZE_SHIFT)
- & PPC4XX_TLBHI_SIZE_MASK);
- /* We cannot handle TLB size < TARGET_PAGE_SIZE.
- * If this ever occurs, one should use the ppcemb target instead
- * of the ppc or ppc64 one
- */
- if ((val & PPC4XX_TLBHI_V) && tlb->size < TARGET_PAGE_SIZE) {
- cpu_abort(cs, "TLB size " TARGET_FMT_lu " < %u "
- "are not supported (%d)\n",
- tlb->size, TARGET_PAGE_SIZE, (int)((val >> 7) & 0x7));
- }
- tlb->EPN = val & ~(tlb->size - 1);
- if (val & PPC4XX_TLBHI_V) {
- tlb->prot |= PAGE_VALID;
- if (val & PPC4XX_TLBHI_E) {
- /* XXX: TO BE FIXED */
- cpu_abort(cs,
- "Little-endian TLB entries are not supported by now\n");
- }
- } else {
- tlb->prot &= ~PAGE_VALID;
- }
- tlb->PID = env->spr[SPR_40x_PID]; /* PID */
- LOG_SWTLB("%s: set up TLB %d RPN " TARGET_FMT_plx " EPN " TARGET_FMT_lx
- " size " TARGET_FMT_lx " prot %c%c%c%c PID %d\n", __func__,
- (int)entry, tlb->RPN, tlb->EPN, tlb->size,
- tlb->prot & PAGE_READ ? 'r' : '-',
- tlb->prot & PAGE_WRITE ? 'w' : '-',
- tlb->prot & PAGE_EXEC ? 'x' : '-',
- tlb->prot & PAGE_VALID ? 'v' : '-', (int)tlb->PID);
- /* Invalidate new TLB (if valid) */
- if (tlb->prot & PAGE_VALID) {
- end = tlb->EPN + tlb->size;
- LOG_SWTLB("%s: invalidate TLB %d start " TARGET_FMT_lx " end "
- TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end);
- for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) {
- tlb_flush_page(cs, page);
- }
- }
-}
-
-void helper_4xx_tlbwe_lo(CPUPPCState *env, target_ulong entry,
- target_ulong val)
-{
- ppcemb_tlb_t *tlb;
-
- LOG_SWTLB("%s entry %i val " TARGET_FMT_lx "\n", __func__, (int)entry,
- val);
- entry &= PPC4XX_TLB_ENTRY_MASK;
- tlb = &env->tlb.tlbe[entry];
- tlb->attr = val & PPC4XX_TLBLO_ATTR_MASK;
- tlb->RPN = val & PPC4XX_TLBLO_RPN_MASK;
- tlb->prot = PAGE_READ;
- if (val & PPC4XX_TLBLO_EX) {
- tlb->prot |= PAGE_EXEC;
- }
- if (val & PPC4XX_TLBLO_WR) {
- tlb->prot |= PAGE_WRITE;
- }
- LOG_SWTLB("%s: set up TLB %d RPN " TARGET_FMT_plx " EPN " TARGET_FMT_lx
- " size " TARGET_FMT_lx " prot %c%c%c%c PID %d\n", __func__,
- (int)entry, tlb->RPN, tlb->EPN, tlb->size,
- tlb->prot & PAGE_READ ? 'r' : '-',
- tlb->prot & PAGE_WRITE ? 'w' : '-',
- tlb->prot & PAGE_EXEC ? 'x' : '-',
- tlb->prot & PAGE_VALID ? 'v' : '-', (int)tlb->PID);
-}
-
-target_ulong helper_4xx_tlbsx(CPUPPCState *env, target_ulong address)
-{
- return ppcemb_tlb_search(env, address, env->spr[SPR_40x_PID]);
-}
-
-/* PowerPC 440 TLB management */
-void helper_440_tlbwe(CPUPPCState *env, uint32_t word, target_ulong entry,
- target_ulong value)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- ppcemb_tlb_t *tlb;
- target_ulong EPN, RPN, size;
- int do_flush_tlbs;
-
- LOG_SWTLB("%s word %d entry %d value " TARGET_FMT_lx "\n",
- __func__, word, (int)entry, value);
- do_flush_tlbs = 0;
- entry &= 0x3F;
- tlb = &env->tlb.tlbe[entry];
- switch (word) {
- default:
- /* Just here to please gcc */
- case 0:
- EPN = value & 0xFFFFFC00;
- if ((tlb->prot & PAGE_VALID) && EPN != tlb->EPN) {
- do_flush_tlbs = 1;
- }
- tlb->EPN = EPN;
- size = booke_tlb_to_page_size((value >> 4) & 0xF);
- if ((tlb->prot & PAGE_VALID) && tlb->size < size) {
- do_flush_tlbs = 1;
- }
- tlb->size = size;
- tlb->attr &= ~0x1;
- tlb->attr |= (value >> 8) & 1;
- if (value & 0x200) {
- tlb->prot |= PAGE_VALID;
- } else {
- if (tlb->prot & PAGE_VALID) {
- tlb->prot &= ~PAGE_VALID;
- do_flush_tlbs = 1;
- }
- }
- tlb->PID = env->spr[SPR_440_MMUCR] & 0x000000FF;
- if (do_flush_tlbs) {
- tlb_flush(CPU(cpu), 1);
- }
- break;
- case 1:
- RPN = value & 0xFFFFFC0F;
- if ((tlb->prot & PAGE_VALID) && tlb->RPN != RPN) {
- tlb_flush(CPU(cpu), 1);
- }
- tlb->RPN = RPN;
- break;
- case 2:
- tlb->attr = (tlb->attr & 0x1) | (value & 0x0000FF00);
- tlb->prot = tlb->prot & PAGE_VALID;
- if (value & 0x1) {
- tlb->prot |= PAGE_READ << 4;
- }
- if (value & 0x2) {
- tlb->prot |= PAGE_WRITE << 4;
- }
- if (value & 0x4) {
- tlb->prot |= PAGE_EXEC << 4;
- }
- if (value & 0x8) {
- tlb->prot |= PAGE_READ;
- }
- if (value & 0x10) {
- tlb->prot |= PAGE_WRITE;
- }
- if (value & 0x20) {
- tlb->prot |= PAGE_EXEC;
- }
- break;
- }
-}
-
-target_ulong helper_440_tlbre(CPUPPCState *env, uint32_t word,
- target_ulong entry)
-{
- ppcemb_tlb_t *tlb;
- target_ulong ret;
- int size;
-
- entry &= 0x3F;
- tlb = &env->tlb.tlbe[entry];
- switch (word) {
- default:
- /* Just here to please gcc */
- case 0:
- ret = tlb->EPN;
- size = booke_page_size_to_tlb(tlb->size);
- if (size < 0 || size > 0xF) {
- size = 1;
- }
- ret |= size << 4;
- if (tlb->attr & 0x1) {
- ret |= 0x100;
- }
- if (tlb->prot & PAGE_VALID) {
- ret |= 0x200;
- }
- env->spr[SPR_440_MMUCR] &= ~0x000000FF;
- env->spr[SPR_440_MMUCR] |= tlb->PID;
- break;
- case 1:
- ret = tlb->RPN;
- break;
- case 2:
- ret = tlb->attr & ~0x1;
- if (tlb->prot & (PAGE_READ << 4)) {
- ret |= 0x1;
- }
- if (tlb->prot & (PAGE_WRITE << 4)) {
- ret |= 0x2;
- }
- if (tlb->prot & (PAGE_EXEC << 4)) {
- ret |= 0x4;
- }
- if (tlb->prot & PAGE_READ) {
- ret |= 0x8;
- }
- if (tlb->prot & PAGE_WRITE) {
- ret |= 0x10;
- }
- if (tlb->prot & PAGE_EXEC) {
- ret |= 0x20;
- }
- break;
- }
- return ret;
-}
-
-target_ulong helper_440_tlbsx(CPUPPCState *env, target_ulong address)
-{
- return ppcemb_tlb_search(env, address, env->spr[SPR_440_MMUCR] & 0xFF);
-}
-
-/* PowerPC BookE 2.06 TLB management */
-
-static ppcmas_tlb_t *booke206_cur_tlb(CPUPPCState *env)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- uint32_t tlbncfg = 0;
- int esel = (env->spr[SPR_BOOKE_MAS0] & MAS0_ESEL_MASK) >> MAS0_ESEL_SHIFT;
- int ea = (env->spr[SPR_BOOKE_MAS2] & MAS2_EPN_MASK);
- int tlb;
-
- tlb = (env->spr[SPR_BOOKE_MAS0] & MAS0_TLBSEL_MASK) >> MAS0_TLBSEL_SHIFT;
- tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlb];
-
- if ((tlbncfg & TLBnCFG_HES) && (env->spr[SPR_BOOKE_MAS0] & MAS0_HES)) {
- cpu_abort(CPU(cpu), "we don't support HES yet\n");
- }
-
- return booke206_get_tlbm(env, tlb, ea, esel);
-}
-
-void helper_booke_setpid(CPUPPCState *env, uint32_t pidn, target_ulong pid)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
-
- env->spr[pidn] = pid;
- /* changing PIDs mean we're in a different address space now */
- tlb_flush(CPU(cpu), 1);
-}
-
-void helper_booke206_tlbwe(CPUPPCState *env)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- uint32_t tlbncfg, tlbn;
- ppcmas_tlb_t *tlb;
- uint32_t size_tlb, size_ps;
- target_ulong mask;
-
-
- switch (env->spr[SPR_BOOKE_MAS0] & MAS0_WQ_MASK) {
- case MAS0_WQ_ALWAYS:
- /* good to go, write that entry */
- break;
- case MAS0_WQ_COND:
- /* XXX check if reserved */
- if (0) {
- return;
- }
- break;
- case MAS0_WQ_CLR_RSRV:
- /* XXX clear entry */
- return;
- default:
- /* no idea what to do */
- return;
- }
-
- if (((env->spr[SPR_BOOKE_MAS0] & MAS0_ATSEL) == MAS0_ATSEL_LRAT) &&
- !msr_gs) {
- /* XXX we don't support direct LRAT setting yet */
- fprintf(stderr, "cpu: don't support LRAT setting yet\n");
- return;
- }
-
- tlbn = (env->spr[SPR_BOOKE_MAS0] & MAS0_TLBSEL_MASK) >> MAS0_TLBSEL_SHIFT;
- tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn];
-
- tlb = booke206_cur_tlb(env);
-
- if (!tlb) {
- raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL |
- POWERPC_EXCP_INVAL_INVAL, GETPC());
- }
-
- /* check that we support the targeted size */
- size_tlb = (env->spr[SPR_BOOKE_MAS1] & MAS1_TSIZE_MASK) >> MAS1_TSIZE_SHIFT;
- size_ps = booke206_tlbnps(env, tlbn);
- if ((env->spr[SPR_BOOKE_MAS1] & MAS1_VALID) && (tlbncfg & TLBnCFG_AVAIL) &&
- !(size_ps & (1 << size_tlb))) {
- raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL |
- POWERPC_EXCP_INVAL_INVAL, GETPC());
- }
-
- if (msr_gs) {
- cpu_abort(CPU(cpu), "missing HV implementation\n");
- }
- tlb->mas7_3 = ((uint64_t)env->spr[SPR_BOOKE_MAS7] << 32) |
- env->spr[SPR_BOOKE_MAS3];
- tlb->mas1 = env->spr[SPR_BOOKE_MAS1];
-
- /* MAV 1.0 only */
- if (!(tlbncfg & TLBnCFG_AVAIL)) {
- /* force !AVAIL TLB entries to correct page size */
- tlb->mas1 &= ~MAS1_TSIZE_MASK;
- /* XXX can be configured in MMUCSR0 */
- tlb->mas1 |= (tlbncfg & TLBnCFG_MINSIZE) >> 12;
- }
-
- /* Make a mask from TLB size to discard invalid bits in EPN field */
- mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
- /* Add a mask for page attributes */
- mask |= MAS2_ACM | MAS2_VLE | MAS2_W | MAS2_I | MAS2_M | MAS2_G | MAS2_E;
-
- if (!msr_cm) {
- /* Executing a tlbwe instruction in 32-bit mode will set
- * bits 0:31 of the TLB EPN field to zero.
- */
- mask &= 0xffffffff;
- }
-
- tlb->mas2 = env->spr[SPR_BOOKE_MAS2] & mask;
-
- if (!(tlbncfg & TLBnCFG_IPROT)) {
- /* no IPROT supported by TLB */
- tlb->mas1 &= ~MAS1_IPROT;
- }
-
- if (booke206_tlb_to_page_size(env, tlb) == TARGET_PAGE_SIZE) {
- tlb_flush_page(CPU(cpu), tlb->mas2 & MAS2_EPN_MASK);
- } else {
- tlb_flush(CPU(cpu), 1);
- }
-}
-
-static inline void booke206_tlb_to_mas(CPUPPCState *env, ppcmas_tlb_t *tlb)
-{
- int tlbn = booke206_tlbm_to_tlbn(env, tlb);
- int way = booke206_tlbm_to_way(env, tlb);
-
- env->spr[SPR_BOOKE_MAS0] = tlbn << MAS0_TLBSEL_SHIFT;
- env->spr[SPR_BOOKE_MAS0] |= way << MAS0_ESEL_SHIFT;
- env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
-
- env->spr[SPR_BOOKE_MAS1] = tlb->mas1;
- env->spr[SPR_BOOKE_MAS2] = tlb->mas2;
- env->spr[SPR_BOOKE_MAS3] = tlb->mas7_3;
- env->spr[SPR_BOOKE_MAS7] = tlb->mas7_3 >> 32;
-}
-
-void helper_booke206_tlbre(CPUPPCState *env)
-{
- ppcmas_tlb_t *tlb = NULL;
-
- tlb = booke206_cur_tlb(env);
- if (!tlb) {
- env->spr[SPR_BOOKE_MAS1] = 0;
- } else {
- booke206_tlb_to_mas(env, tlb);
- }
-}
-
-void helper_booke206_tlbsx(CPUPPCState *env, target_ulong address)
-{
- ppcmas_tlb_t *tlb = NULL;
- int i, j;
- hwaddr raddr;
- uint32_t spid, sas;
-
- spid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID_MASK) >> MAS6_SPID_SHIFT;
- sas = env->spr[SPR_BOOKE_MAS6] & MAS6_SAS;
-
- for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
- int ways = booke206_tlb_ways(env, i);
-
- for (j = 0; j < ways; j++) {
- tlb = booke206_get_tlbm(env, i, address, j);
-
- if (!tlb) {
- continue;
- }
-
- if (ppcmas_tlb_check(env, tlb, &raddr, address, spid)) {
- continue;
- }
-
- if (sas != ((tlb->mas1 & MAS1_TS) >> MAS1_TS_SHIFT)) {
- continue;
- }
-
- booke206_tlb_to_mas(env, tlb);
- return;
- }
- }
-
- /* no entry found, fill with defaults */
- env->spr[SPR_BOOKE_MAS0] = env->spr[SPR_BOOKE_MAS4] & MAS4_TLBSELD_MASK;
- env->spr[SPR_BOOKE_MAS1] = env->spr[SPR_BOOKE_MAS4] & MAS4_TSIZED_MASK;
- env->spr[SPR_BOOKE_MAS2] = env->spr[SPR_BOOKE_MAS4] & MAS4_WIMGED_MASK;
- env->spr[SPR_BOOKE_MAS3] = 0;
- env->spr[SPR_BOOKE_MAS7] = 0;
-
- if (env->spr[SPR_BOOKE_MAS6] & MAS6_SAS) {
- env->spr[SPR_BOOKE_MAS1] |= MAS1_TS;
- }
-
- env->spr[SPR_BOOKE_MAS1] |= (env->spr[SPR_BOOKE_MAS6] >> 16)
- << MAS1_TID_SHIFT;
-
- /* next victim logic */
- env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_ESEL_SHIFT;
- env->last_way++;
- env->last_way &= booke206_tlb_ways(env, 0) - 1;
- env->spr[SPR_BOOKE_MAS0] |= env->last_way << MAS0_NV_SHIFT;
-}
-
-static inline void booke206_invalidate_ea_tlb(CPUPPCState *env, int tlbn,
- uint32_t ea)
-{
- int i;
- int ways = booke206_tlb_ways(env, tlbn);
- target_ulong mask;
-
- for (i = 0; i < ways; i++) {
- ppcmas_tlb_t *tlb = booke206_get_tlbm(env, tlbn, ea, i);
- if (!tlb) {
- continue;
- }
- mask = ~(booke206_tlb_to_page_size(env, tlb) - 1);
- if (((tlb->mas2 & MAS2_EPN_MASK) == (ea & mask)) &&
- !(tlb->mas1 & MAS1_IPROT)) {
- tlb->mas1 &= ~MAS1_VALID;
- }
- }
-}
-
-void helper_booke206_tlbivax(CPUPPCState *env, target_ulong address)
-{
- CPUState *cs;
-
- if (address & 0x4) {
- /* flush all entries */
- if (address & 0x8) {
- /* flush all of TLB1 */
- booke206_flush_tlb(env, BOOKE206_FLUSH_TLB1, 1);
- } else {
- /* flush all of TLB0 */
- booke206_flush_tlb(env, BOOKE206_FLUSH_TLB0, 0);
- }
- return;
- }
-
- if (address & 0x8) {
- /* flush TLB1 entries */
- booke206_invalidate_ea_tlb(env, 1, address);
- CPU_FOREACH(cs) {
- tlb_flush(cs, 1);
- }
- } else {
- /* flush TLB0 entries */
- booke206_invalidate_ea_tlb(env, 0, address);
- CPU_FOREACH(cs) {
- tlb_flush_page(cs, address & MAS2_EPN_MASK);
- }
- }
-}
-
-void helper_booke206_tlbilx0(CPUPPCState *env, target_ulong address)
-{
- /* XXX missing LPID handling */
- booke206_flush_tlb(env, -1, 1);
-}
-
-void helper_booke206_tlbilx1(CPUPPCState *env, target_ulong address)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- int i, j;
- int tid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID);
- ppcmas_tlb_t *tlb = env->tlb.tlbm;
- int tlb_size;
-
- /* XXX missing LPID handling */
- for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
- tlb_size = booke206_tlb_size(env, i);
- for (j = 0; j < tlb_size; j++) {
- if (!(tlb[j].mas1 & MAS1_IPROT) &&
- ((tlb[j].mas1 & MAS1_TID_MASK) == tid)) {
- tlb[j].mas1 &= ~MAS1_VALID;
- }
- }
- tlb += booke206_tlb_size(env, i);
- }
- tlb_flush(CPU(cpu), 1);
-}
-
-void helper_booke206_tlbilx3(CPUPPCState *env, target_ulong address)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- int i, j;
- ppcmas_tlb_t *tlb;
- int tid = (env->spr[SPR_BOOKE_MAS6] & MAS6_SPID);
- int pid = tid >> MAS6_SPID_SHIFT;
- int sgs = env->spr[SPR_BOOKE_MAS5] & MAS5_SGS;
- int ind = (env->spr[SPR_BOOKE_MAS6] & MAS6_SIND) ? MAS1_IND : 0;
- /* XXX check for unsupported isize and raise an invalid opcode then */
- int size = env->spr[SPR_BOOKE_MAS6] & MAS6_ISIZE_MASK;
- /* XXX implement MAV2 handling */
- bool mav2 = false;
-
- /* XXX missing LPID handling */
- /* flush by pid and ea */
- for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
- int ways = booke206_tlb_ways(env, i);
-
- for (j = 0; j < ways; j++) {
- tlb = booke206_get_tlbm(env, i, address, j);
- if (!tlb) {
- continue;
- }
- if ((ppcmas_tlb_check(env, tlb, NULL, address, pid) != 0) ||
- (tlb->mas1 & MAS1_IPROT) ||
- ((tlb->mas1 & MAS1_IND) != ind) ||
- ((tlb->mas8 & MAS8_TGS) != sgs)) {
- continue;
- }
- if (mav2 && ((tlb->mas1 & MAS1_TSIZE_MASK) != size)) {
- /* XXX only check when MMUCFG[TWC] || TLBnCFG[HES] */
- continue;
- }
- /* XXX e500mc doesn't match SAS, but other cores might */
- tlb->mas1 &= ~MAS1_VALID;
- }
- }
- tlb_flush(CPU(cpu), 1);
-}
-
-void helper_booke206_tlbflush(CPUPPCState *env, target_ulong type)
-{
- int flags = 0;
-
- if (type & 2) {
- flags |= BOOKE206_FLUSH_TLB1;
- }
-
- if (type & 4) {
- flags |= BOOKE206_FLUSH_TLB0;
- }
-
- booke206_flush_tlb(env, flags, 1);
-}
-
-
-void helper_check_tlb_flush_local(CPUPPCState *env)
-{
- check_tlb_flush(env, false);
-}
-
-void helper_check_tlb_flush_global(CPUPPCState *env)
-{
- check_tlb_flush(env, true);
-}
-
-/*****************************************************************************/
-
-/* try to fill the TLB and return an exception if error. If retaddr is
- NULL, it means that the function was called in C code (i.e. not
- from generated code or from helper.c) */
-/* XXX: fix it to restore all registers */
-void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
- int mmu_idx, uintptr_t retaddr)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
- CPUPPCState *env = &cpu->env;
- int ret;
-
- if (pcc->handle_mmu_fault) {
- ret = pcc->handle_mmu_fault(cpu, addr, access_type, mmu_idx);
- } else {
- ret = cpu_ppc_handle_mmu_fault(env, addr, access_type, mmu_idx);
- }
- if (unlikely(ret != 0)) {
- raise_exception_err_ra(env, cs->exception_index, env->error_code,
- retaddr);
- }
-}
diff --git a/target-ppc/monitor.c b/target-ppc/monitor.c
deleted file mode 100644
index c2d0806dd1..0000000000
--- a/target-ppc/monitor.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * QEMU monitor
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "monitor/monitor.h"
-#include "monitor/hmp-target.h"
-#include "hmp.h"
-
-static target_long monitor_get_ccr (const struct MonitorDef *md, int val)
-{
- CPUArchState *env = mon_get_cpu_env();
- unsigned int u;
- int i;
-
- u = 0;
- for (i = 0; i < 8; i++)
- u |= env->crf[i] << (32 - (4 * (i + 1)));
-
- return u;
-}
-
-static target_long monitor_get_decr (const struct MonitorDef *md, int val)
-{
- CPUArchState *env = mon_get_cpu_env();
- return cpu_ppc_load_decr(env);
-}
-
-static target_long monitor_get_tbu (const struct MonitorDef *md, int val)
-{
- CPUArchState *env = mon_get_cpu_env();
- return cpu_ppc_load_tbu(env);
-}
-
-static target_long monitor_get_tbl (const struct MonitorDef *md, int val)
-{
- CPUArchState *env = mon_get_cpu_env();
- return cpu_ppc_load_tbl(env);
-}
-
-void hmp_info_tlb(Monitor *mon, const QDict *qdict)
-{
- CPUArchState *env1 = mon_get_cpu_env();
-
- dump_mmu((FILE*)mon, (fprintf_function)monitor_printf, env1);
-}
-
-const MonitorDef monitor_defs[] = {
- { "fpscr", offsetof(CPUPPCState, fpscr) },
- /* Next instruction pointer */
- { "nip|pc", offsetof(CPUPPCState, nip) },
- { "lr", offsetof(CPUPPCState, lr) },
- { "ctr", offsetof(CPUPPCState, ctr) },
- { "decr", 0, &monitor_get_decr, },
- { "ccr|cr", 0, &monitor_get_ccr, },
- /* Machine state register */
- { "xer", offsetof(CPUPPCState, xer) },
- { "msr", offsetof(CPUPPCState, msr) },
- { "tbu", 0, &monitor_get_tbu, },
- { "tbl", 0, &monitor_get_tbl, },
- { NULL },
-};
-
-const MonitorDef *target_monitor_defs(void)
-{
- return monitor_defs;
-}
-
-static int ppc_cpu_get_reg_num(const char *numstr, int maxnum, int *pregnum)
-{
- int regnum;
- char *endptr = NULL;
-
- if (!*numstr) {
- return false;
- }
-
- regnum = strtoul(numstr, &endptr, 10);
- if (*endptr || (regnum >= maxnum)) {
- return false;
- }
- *pregnum = regnum;
-
- return true;
-}
-
-int target_get_monitor_def(CPUState *cs, const char *name, uint64_t *pval)
-{
- int i, regnum;
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
-
- /* General purpose registers */
- if ((tolower(name[0]) == 'r') &&
- ppc_cpu_get_reg_num(name + 1, ARRAY_SIZE(env->gpr), &regnum)) {
- *pval = env->gpr[regnum];
- return 0;
- }
-
- /* Floating point registers */
- if ((tolower(name[0]) == 'f') &&
- ppc_cpu_get_reg_num(name + 1, ARRAY_SIZE(env->fpr), &regnum)) {
- *pval = env->fpr[regnum];
- return 0;
- }
-
- /* Special purpose registers */
- for (i = 0; i < ARRAY_SIZE(env->spr_cb); ++i) {
- ppc_spr_t *spr = &env->spr_cb[i];
-
- if (spr->name && (strcasecmp(name, spr->name) == 0)) {
- *pval = env->spr[i];
- return 0;
- }
- }
-
- /* Segment registers */
-#if !defined(CONFIG_USER_ONLY)
- if ((strncasecmp(name, "sr", 2) == 0) &&
- ppc_cpu_get_reg_num(name + 2, ARRAY_SIZE(env->sr), &regnum)) {
- *pval = env->sr[regnum];
- return 0;
- }
-#endif
-
- return -EINVAL;
-}
diff --git a/target-ppc/timebase_helper.c b/target-ppc/timebase_helper.c
deleted file mode 100644
index 73363e08ae..0000000000
--- a/target-ppc/timebase_helper.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * PowerPC emulation helpers for QEMU.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/helper-proto.h"
-#include "exec/exec-all.h"
-#include "qemu/log.h"
-
-/*****************************************************************************/
-/* SPR accesses */
-
-target_ulong helper_load_tbl(CPUPPCState *env)
-{
- return (target_ulong)cpu_ppc_load_tbl(env);
-}
-
-target_ulong helper_load_tbu(CPUPPCState *env)
-{
- return cpu_ppc_load_tbu(env);
-}
-
-target_ulong helper_load_atbl(CPUPPCState *env)
-{
- return (target_ulong)cpu_ppc_load_atbl(env);
-}
-
-target_ulong helper_load_atbu(CPUPPCState *env)
-{
- return cpu_ppc_load_atbu(env);
-}
-
-#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
-target_ulong helper_load_purr(CPUPPCState *env)
-{
- return (target_ulong)cpu_ppc_load_purr(env);
-}
-#endif
-
-target_ulong helper_load_601_rtcl(CPUPPCState *env)
-{
- return cpu_ppc601_load_rtcl(env);
-}
-
-target_ulong helper_load_601_rtcu(CPUPPCState *env)
-{
- return cpu_ppc601_load_rtcu(env);
-}
-
-#if !defined(CONFIG_USER_ONLY)
-void helper_store_tbl(CPUPPCState *env, target_ulong val)
-{
- cpu_ppc_store_tbl(env, val);
-}
-
-void helper_store_tbu(CPUPPCState *env, target_ulong val)
-{
- cpu_ppc_store_tbu(env, val);
-}
-
-void helper_store_atbl(CPUPPCState *env, target_ulong val)
-{
- cpu_ppc_store_atbl(env, val);
-}
-
-void helper_store_atbu(CPUPPCState *env, target_ulong val)
-{
- cpu_ppc_store_atbu(env, val);
-}
-
-void helper_store_601_rtcl(CPUPPCState *env, target_ulong val)
-{
- cpu_ppc601_store_rtcl(env, val);
-}
-
-void helper_store_601_rtcu(CPUPPCState *env, target_ulong val)
-{
- cpu_ppc601_store_rtcu(env, val);
-}
-
-target_ulong helper_load_decr(CPUPPCState *env)
-{
- return cpu_ppc_load_decr(env);
-}
-
-void helper_store_decr(CPUPPCState *env, target_ulong val)
-{
- cpu_ppc_store_decr(env, val);
-}
-
-target_ulong helper_load_hdecr(CPUPPCState *env)
-{
- return cpu_ppc_load_hdecr(env);
-}
-
-void helper_store_hdecr(CPUPPCState *env, target_ulong val)
-{
- cpu_ppc_store_hdecr(env, val);
-}
-
-target_ulong helper_load_40x_pit(CPUPPCState *env)
-{
- return load_40x_pit(env);
-}
-
-void helper_store_40x_pit(CPUPPCState *env, target_ulong val)
-{
- store_40x_pit(env, val);
-}
-
-void helper_store_booke_tcr(CPUPPCState *env, target_ulong val)
-{
- store_booke_tcr(env, val);
-}
-
-void helper_store_booke_tsr(CPUPPCState *env, target_ulong val)
-{
- store_booke_tsr(env, val);
-}
-#endif
-
-/*****************************************************************************/
-/* Embedded PowerPC specific helpers */
-
-/* XXX: to be improved to check access rights when in user-mode */
-target_ulong helper_load_dcr(CPUPPCState *env, target_ulong dcrn)
-{
- uint32_t val = 0;
-
- if (unlikely(env->dcr_env == NULL)) {
- qemu_log_mask(LOG_GUEST_ERROR, "No DCR environment\n");
- raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL |
- POWERPC_EXCP_INVAL_INVAL, GETPC());
- } else if (unlikely(ppc_dcr_read(env->dcr_env,
- (uint32_t)dcrn, &val) != 0)) {
- qemu_log_mask(LOG_GUEST_ERROR, "DCR read error %d %03x\n",
- (uint32_t)dcrn, (uint32_t)dcrn);
- raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL |
- POWERPC_EXCP_PRIV_REG, GETPC());
- }
- return val;
-}
-
-void helper_store_dcr(CPUPPCState *env, target_ulong dcrn, target_ulong val)
-{
- if (unlikely(env->dcr_env == NULL)) {
- qemu_log_mask(LOG_GUEST_ERROR, "No DCR environment\n");
- raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL |
- POWERPC_EXCP_INVAL_INVAL, GETPC());
- } else if (unlikely(ppc_dcr_write(env->dcr_env, (uint32_t)dcrn,
- (uint32_t)val) != 0)) {
- qemu_log_mask(LOG_GUEST_ERROR, "DCR write error %d %03x\n",
- (uint32_t)dcrn, (uint32_t)dcrn);
- raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM,
- POWERPC_EXCP_INVAL |
- POWERPC_EXCP_PRIV_REG, GETPC());
- }
-}
diff --git a/target-ppc/trace-events b/target-ppc/trace-events
deleted file mode 100644
index 8fcc3ce98c..0000000000
--- a/target-ppc/trace-events
+++ /dev/null
@@ -1,5 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# target-ppc/kvm.c
-kvm_failed_spr_set(int str, const char *msg) "Warning: Unable to set SPR %d to KVM: %s"
-kvm_failed_spr_get(int str, const char *msg) "Warning: Unable to retrieve SPR %d from KVM: %s"
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
deleted file mode 100644
index 59e9552d2b..0000000000
--- a/target-ppc/translate.c
+++ /dev/null
@@ -1,7200 +0,0 @@
-/*
- * PowerPC emulation for qemu: main translation routines.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- * Copyright (C) 2011 Freescale Semiconductor, Inc.
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "internal.h"
-#include "disas/disas.h"
-#include "exec/exec-all.h"
-#include "tcg-op.h"
-#include "qemu/host-utils.h"
-#include "exec/cpu_ldst.h"
-
-#include "exec/helper-proto.h"
-#include "exec/helper-gen.h"
-
-#include "trace-tcg.h"
-#include "exec/log.h"
-
-
-#define CPU_SINGLE_STEP 0x1
-#define CPU_BRANCH_STEP 0x2
-#define GDBSTUB_SINGLE_STEP 0x4
-
-/* Include definitions for instructions classes and implementations flags */
-//#define PPC_DEBUG_DISAS
-//#define DO_PPC_STATISTICS
-
-#ifdef PPC_DEBUG_DISAS
-# define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
-#else
-# define LOG_DISAS(...) do { } while (0)
-#endif
-/*****************************************************************************/
-/* Code translation helpers */
-
-/* global register indexes */
-static TCGv_env cpu_env;
-static char cpu_reg_names[10*3 + 22*4 /* GPR */
- + 10*4 + 22*5 /* SPE GPRh */
- + 10*4 + 22*5 /* FPR */
- + 2*(10*6 + 22*7) /* AVRh, AVRl */
- + 10*5 + 22*6 /* VSR */
- + 8*5 /* CRF */];
-static TCGv cpu_gpr[32];
-static TCGv cpu_gprh[32];
-static TCGv_i64 cpu_fpr[32];
-static TCGv_i64 cpu_avrh[32], cpu_avrl[32];
-static TCGv_i64 cpu_vsr[32];
-static TCGv_i32 cpu_crf[8];
-static TCGv cpu_nip;
-static TCGv cpu_msr;
-static TCGv cpu_ctr;
-static TCGv cpu_lr;
-#if defined(TARGET_PPC64)
-static TCGv cpu_cfar;
-#endif
-static TCGv cpu_xer, cpu_so, cpu_ov, cpu_ca;
-static TCGv cpu_reserve;
-static TCGv cpu_fpscr;
-static TCGv_i32 cpu_access_type;
-
-#include "exec/gen-icount.h"
-
-void ppc_translate_init(void)
-{
- int i;
- char* p;
- size_t cpu_reg_names_size;
- static int done_init = 0;
-
- if (done_init)
- return;
-
- cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
- tcg_ctx.tcg_env = cpu_env;
-
- p = cpu_reg_names;
- cpu_reg_names_size = sizeof(cpu_reg_names);
-
- for (i = 0; i < 8; i++) {
- snprintf(p, cpu_reg_names_size, "crf%d", i);
- cpu_crf[i] = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUPPCState, crf[i]), p);
- p += 5;
- cpu_reg_names_size -= 5;
- }
-
- for (i = 0; i < 32; i++) {
- snprintf(p, cpu_reg_names_size, "r%d", i);
- cpu_gpr[i] = tcg_global_mem_new(cpu_env,
- offsetof(CPUPPCState, gpr[i]), p);
- p += (i < 10) ? 3 : 4;
- cpu_reg_names_size -= (i < 10) ? 3 : 4;
- snprintf(p, cpu_reg_names_size, "r%dH", i);
- cpu_gprh[i] = tcg_global_mem_new(cpu_env,
- offsetof(CPUPPCState, gprh[i]), p);
- p += (i < 10) ? 4 : 5;
- cpu_reg_names_size -= (i < 10) ? 4 : 5;
-
- snprintf(p, cpu_reg_names_size, "fp%d", i);
- cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env,
- offsetof(CPUPPCState, fpr[i]), p);
- p += (i < 10) ? 4 : 5;
- cpu_reg_names_size -= (i < 10) ? 4 : 5;
-
- snprintf(p, cpu_reg_names_size, "avr%dH", i);
-#ifdef HOST_WORDS_BIGENDIAN
- cpu_avrh[i] = tcg_global_mem_new_i64(cpu_env,
- offsetof(CPUPPCState, avr[i].u64[0]), p);
-#else
- cpu_avrh[i] = tcg_global_mem_new_i64(cpu_env,
- offsetof(CPUPPCState, avr[i].u64[1]), p);
-#endif
- p += (i < 10) ? 6 : 7;
- cpu_reg_names_size -= (i < 10) ? 6 : 7;
-
- snprintf(p, cpu_reg_names_size, "avr%dL", i);
-#ifdef HOST_WORDS_BIGENDIAN
- cpu_avrl[i] = tcg_global_mem_new_i64(cpu_env,
- offsetof(CPUPPCState, avr[i].u64[1]), p);
-#else
- cpu_avrl[i] = tcg_global_mem_new_i64(cpu_env,
- offsetof(CPUPPCState, avr[i].u64[0]), p);
-#endif
- p += (i < 10) ? 6 : 7;
- cpu_reg_names_size -= (i < 10) ? 6 : 7;
- snprintf(p, cpu_reg_names_size, "vsr%d", i);
- cpu_vsr[i] = tcg_global_mem_new_i64(cpu_env,
- offsetof(CPUPPCState, vsr[i]), p);
- p += (i < 10) ? 5 : 6;
- cpu_reg_names_size -= (i < 10) ? 5 : 6;
- }
-
- cpu_nip = tcg_global_mem_new(cpu_env,
- offsetof(CPUPPCState, nip), "nip");
-
- cpu_msr = tcg_global_mem_new(cpu_env,
- offsetof(CPUPPCState, msr), "msr");
-
- cpu_ctr = tcg_global_mem_new(cpu_env,
- offsetof(CPUPPCState, ctr), "ctr");
-
- cpu_lr = tcg_global_mem_new(cpu_env,
- offsetof(CPUPPCState, lr), "lr");
-
-#if defined(TARGET_PPC64)
- cpu_cfar = tcg_global_mem_new(cpu_env,
- offsetof(CPUPPCState, cfar), "cfar");
-#endif
-
- cpu_xer = tcg_global_mem_new(cpu_env,
- offsetof(CPUPPCState, xer), "xer");
- cpu_so = tcg_global_mem_new(cpu_env,
- offsetof(CPUPPCState, so), "SO");
- cpu_ov = tcg_global_mem_new(cpu_env,
- offsetof(CPUPPCState, ov), "OV");
- cpu_ca = tcg_global_mem_new(cpu_env,
- offsetof(CPUPPCState, ca), "CA");
-
- cpu_reserve = tcg_global_mem_new(cpu_env,
- offsetof(CPUPPCState, reserve_addr),
- "reserve_addr");
-
- cpu_fpscr = tcg_global_mem_new(cpu_env,
- offsetof(CPUPPCState, fpscr), "fpscr");
-
- cpu_access_type = tcg_global_mem_new_i32(cpu_env,
- offsetof(CPUPPCState, access_type), "access_type");
-
- done_init = 1;
-}
-
-/* internal defines */
-struct DisasContext {
- struct TranslationBlock *tb;
- target_ulong nip;
- uint32_t opcode;
- uint32_t exception;
- /* Routine used to access memory */
- bool pr, hv, dr, le_mode;
- bool lazy_tlb_flush;
- bool need_access_type;
- int mem_idx;
- int access_type;
- /* Translation flags */
- TCGMemOp default_tcg_memop_mask;
-#if defined(TARGET_PPC64)
- bool sf_mode;
- bool has_cfar;
-#endif
- bool fpu_enabled;
- bool altivec_enabled;
- bool vsx_enabled;
- bool spe_enabled;
- bool tm_enabled;
- ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
- int singlestep_enabled;
- uint64_t insns_flags;
- uint64_t insns_flags2;
-};
-
-/* Return true iff byteswap is needed in a scalar memop */
-static inline bool need_byteswap(const DisasContext *ctx)
-{
-#if defined(TARGET_WORDS_BIGENDIAN)
- return ctx->le_mode;
-#else
- return !ctx->le_mode;
-#endif
-}
-
-/* True when active word size < size of target_long. */
-#ifdef TARGET_PPC64
-# define NARROW_MODE(C) (!(C)->sf_mode)
-#else
-# define NARROW_MODE(C) 0
-#endif
-
-struct opc_handler_t {
- /* invalid bits for instruction 1 (Rc(opcode) == 0) */
- uint32_t inval1;
- /* invalid bits for instruction 2 (Rc(opcode) == 1) */
- uint32_t inval2;
- /* instruction type */
- uint64_t type;
- /* extended instruction type */
- uint64_t type2;
- /* handler */
- void (*handler)(DisasContext *ctx);
-#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
- const char *oname;
-#endif
-#if defined(DO_PPC_STATISTICS)
- uint64_t count;
-#endif
-};
-
-static inline void gen_set_access_type(DisasContext *ctx, int access_type)
-{
- if (ctx->need_access_type && ctx->access_type != access_type) {
- tcg_gen_movi_i32(cpu_access_type, access_type);
- ctx->access_type = access_type;
- }
-}
-
-static inline void gen_update_nip(DisasContext *ctx, target_ulong nip)
-{
- if (NARROW_MODE(ctx)) {
- nip = (uint32_t)nip;
- }
- tcg_gen_movi_tl(cpu_nip, nip);
-}
-
-static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
-{
- TCGv_i32 t0, t1;
-
- /* These are all synchronous exceptions, we set the PC back to
- * the faulting instruction
- */
- if (ctx->exception == POWERPC_EXCP_NONE) {
- gen_update_nip(ctx, ctx->nip - 4);
- }
- t0 = tcg_const_i32(excp);
- t1 = tcg_const_i32(error);
- gen_helper_raise_exception_err(cpu_env, t0, t1);
- tcg_temp_free_i32(t0);
- tcg_temp_free_i32(t1);
- ctx->exception = (excp);
-}
-
-static void gen_exception(DisasContext *ctx, uint32_t excp)
-{
- TCGv_i32 t0;
-
- /* These are all synchronous exceptions, we set the PC back to
- * the faulting instruction
- */
- if (ctx->exception == POWERPC_EXCP_NONE) {
- gen_update_nip(ctx, ctx->nip - 4);
- }
- t0 = tcg_const_i32(excp);
- gen_helper_raise_exception(cpu_env, t0);
- tcg_temp_free_i32(t0);
- ctx->exception = (excp);
-}
-
-static void gen_exception_nip(DisasContext *ctx, uint32_t excp,
- target_ulong nip)
-{
- TCGv_i32 t0;
-
- gen_update_nip(ctx, nip);
- t0 = tcg_const_i32(excp);
- gen_helper_raise_exception(cpu_env, t0);
- tcg_temp_free_i32(t0);
- ctx->exception = (excp);
-}
-
-static void gen_debug_exception(DisasContext *ctx)
-{
- TCGv_i32 t0;
-
- /* These are all synchronous exceptions, we set the PC back to
- * the faulting instruction
- */
- if ((ctx->exception != POWERPC_EXCP_BRANCH) &&
- (ctx->exception != POWERPC_EXCP_SYNC)) {
- gen_update_nip(ctx, ctx->nip);
- }
- t0 = tcg_const_i32(EXCP_DEBUG);
- gen_helper_raise_exception(cpu_env, t0);
- tcg_temp_free_i32(t0);
-}
-
-static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
-{
- /* Will be converted to program check if needed */
- gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_INVAL | error);
-}
-
-static inline void gen_priv_exception(DisasContext *ctx, uint32_t error)
-{
- gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_PRIV | error);
-}
-
-static inline void gen_hvpriv_exception(DisasContext *ctx, uint32_t error)
-{
- /* Will be converted to program check if needed */
- gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_PRIV | error);
-}
-
-/* Stop translation */
-static inline void gen_stop_exception(DisasContext *ctx)
-{
- gen_update_nip(ctx, ctx->nip);
- ctx->exception = POWERPC_EXCP_STOP;
-}
-
-#ifndef CONFIG_USER_ONLY
-/* No need to update nip here, as execution flow will change */
-static inline void gen_sync_exception(DisasContext *ctx)
-{
- ctx->exception = POWERPC_EXCP_SYNC;
-}
-#endif
-
-#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
-GEN_OPCODE(name, opc1, opc2, opc3, inval, type, PPC_NONE)
-
-#define GEN_HANDLER_E(name, opc1, opc2, opc3, inval, type, type2) \
-GEN_OPCODE(name, opc1, opc2, opc3, inval, type, type2)
-
-#define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type) \
-GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, PPC_NONE)
-
-#define GEN_HANDLER2_E(name, onam, opc1, opc2, opc3, inval, type, type2) \
-GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, type2)
-
-#define GEN_HANDLER_E_2(name, opc1, opc2, opc3, opc4, inval, type, type2) \
-GEN_OPCODE3(name, opc1, opc2, opc3, opc4, inval, type, type2)
-
-#define GEN_HANDLER2_E_2(name, onam, opc1, opc2, opc3, opc4, inval, typ, typ2) \
-GEN_OPCODE4(name, onam, opc1, opc2, opc3, opc4, inval, typ, typ2)
-
-typedef struct opcode_t {
- unsigned char opc1, opc2, opc3, opc4;
-#if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
- unsigned char pad[4];
-#endif
- opc_handler_t handler;
- const char *oname;
-} opcode_t;
-
-/* Helpers for priv. check */
-#define GEN_PRIV \
- do { \
- gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; \
- } while (0)
-
-#if defined(CONFIG_USER_ONLY)
-#define CHK_HV GEN_PRIV
-#define CHK_SV GEN_PRIV
-#define CHK_HVRM GEN_PRIV
-#else
-#define CHK_HV \
- do { \
- if (unlikely(ctx->pr || !ctx->hv)) { \
- GEN_PRIV; \
- } \
- } while (0)
-#define CHK_SV \
- do { \
- if (unlikely(ctx->pr)) { \
- GEN_PRIV; \
- } \
- } while (0)
-#define CHK_HVRM \
- do { \
- if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) { \
- GEN_PRIV; \
- } \
- } while (0)
-#endif
-
-#define CHK_NONE
-
-
-/*****************************************************************************/
-/*** Instruction decoding ***/
-#define EXTRACT_HELPER(name, shift, nb) \
-static inline uint32_t name(uint32_t opcode) \
-{ \
- return (opcode >> (shift)) & ((1 << (nb)) - 1); \
-}
-
-#define EXTRACT_SHELPER(name, shift, nb) \
-static inline int32_t name(uint32_t opcode) \
-{ \
- return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1)); \
-}
-
-#define EXTRACT_HELPER_SPLIT(name, shift1, nb1, shift2, nb2) \
-static inline uint32_t name(uint32_t opcode) \
-{ \
- return (((opcode >> (shift1)) & ((1 << (nb1)) - 1)) << nb2) | \
- ((opcode >> (shift2)) & ((1 << (nb2)) - 1)); \
-}
-
-#define EXTRACT_HELPER_DXFORM(name, \
- d0_bits, shift_op_d0, shift_d0, \
- d1_bits, shift_op_d1, shift_d1, \
- d2_bits, shift_op_d2, shift_d2) \
-static inline int16_t name(uint32_t opcode) \
-{ \
- return \
- (((opcode >> (shift_op_d0)) & ((1 << (d0_bits)) - 1)) << (shift_d0)) | \
- (((opcode >> (shift_op_d1)) & ((1 << (d1_bits)) - 1)) << (shift_d1)) | \
- (((opcode >> (shift_op_d2)) & ((1 << (d2_bits)) - 1)) << (shift_d2)); \
-}
-
-
-/* Opcode part 1 */
-EXTRACT_HELPER(opc1, 26, 6);
-/* Opcode part 2 */
-EXTRACT_HELPER(opc2, 1, 5);
-/* Opcode part 3 */
-EXTRACT_HELPER(opc3, 6, 5);
-/* Opcode part 4 */
-EXTRACT_HELPER(opc4, 16, 5);
-/* Update Cr0 flags */
-EXTRACT_HELPER(Rc, 0, 1);
-/* Update Cr6 flags (Altivec) */
-EXTRACT_HELPER(Rc21, 10, 1);
-/* Destination */
-EXTRACT_HELPER(rD, 21, 5);
-/* Source */
-EXTRACT_HELPER(rS, 21, 5);
-/* First operand */
-EXTRACT_HELPER(rA, 16, 5);
-/* Second operand */
-EXTRACT_HELPER(rB, 11, 5);
-/* Third operand */
-EXTRACT_HELPER(rC, 6, 5);
-/*** Get CRn ***/
-EXTRACT_HELPER(crfD, 23, 3);
-EXTRACT_HELPER(crfS, 18, 3);
-EXTRACT_HELPER(crbD, 21, 5);
-EXTRACT_HELPER(crbA, 16, 5);
-EXTRACT_HELPER(crbB, 11, 5);
-/* SPR / TBL */
-EXTRACT_HELPER(_SPR, 11, 10);
-static inline uint32_t SPR(uint32_t opcode)
-{
- uint32_t sprn = _SPR(opcode);
-
- return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
-}
-/*** Get constants ***/
-/* 16 bits signed immediate value */
-EXTRACT_SHELPER(SIMM, 0, 16);
-/* 16 bits unsigned immediate value */
-EXTRACT_HELPER(UIMM, 0, 16);
-/* 5 bits signed immediate value */
-EXTRACT_HELPER(SIMM5, 16, 5);
-/* 5 bits signed immediate value */
-EXTRACT_HELPER(UIMM5, 16, 5);
-/* 4 bits unsigned immediate value */
-EXTRACT_HELPER(UIMM4, 16, 4);
-/* Bit count */
-EXTRACT_HELPER(NB, 11, 5);
-/* Shift count */
-EXTRACT_HELPER(SH, 11, 5);
-/* Vector shift count */
-EXTRACT_HELPER(VSH, 6, 4);
-/* Mask start */
-EXTRACT_HELPER(MB, 6, 5);
-/* Mask end */
-EXTRACT_HELPER(ME, 1, 5);
-/* Trap operand */
-EXTRACT_HELPER(TO, 21, 5);
-
-EXTRACT_HELPER(CRM, 12, 8);
-
-#ifndef CONFIG_USER_ONLY
-EXTRACT_HELPER(SR, 16, 4);
-#endif
-
-/* mtfsf/mtfsfi */
-EXTRACT_HELPER(FPBF, 23, 3);
-EXTRACT_HELPER(FPIMM, 12, 4);
-EXTRACT_HELPER(FPL, 25, 1);
-EXTRACT_HELPER(FPFLM, 17, 8);
-EXTRACT_HELPER(FPW, 16, 1);
-
-/* addpcis */
-EXTRACT_HELPER_DXFORM(DX, 10, 6, 6, 5, 16, 1, 1, 0, 0)
-#if defined(TARGET_PPC64)
-/* darn */
-EXTRACT_HELPER(L, 16, 2);
-#endif
-
-/*** Jump target decoding ***/
-/* Immediate address */
-static inline target_ulong LI(uint32_t opcode)
-{
- return (opcode >> 0) & 0x03FFFFFC;
-}
-
-static inline uint32_t BD(uint32_t opcode)
-{
- return (opcode >> 0) & 0xFFFC;
-}
-
-EXTRACT_HELPER(BO, 21, 5);
-EXTRACT_HELPER(BI, 16, 5);
-/* Absolute/relative address */
-EXTRACT_HELPER(AA, 1, 1);
-/* Link */
-EXTRACT_HELPER(LK, 0, 1);
-
-/* DFP Z22-form */
-EXTRACT_HELPER(DCM, 10, 6)
-
-/* DFP Z23-form */
-EXTRACT_HELPER(RMC, 9, 2)
-
-EXTRACT_HELPER_SPLIT(xT, 0, 1, 21, 5);
-EXTRACT_HELPER_SPLIT(xS, 0, 1, 21, 5);
-EXTRACT_HELPER_SPLIT(xA, 2, 1, 16, 5);
-EXTRACT_HELPER_SPLIT(xB, 1, 1, 11, 5);
-EXTRACT_HELPER_SPLIT(xC, 3, 1, 6, 5);
-EXTRACT_HELPER(DM, 8, 2);
-EXTRACT_HELPER(UIM, 16, 2);
-EXTRACT_HELPER(SHW, 8, 2);
-EXTRACT_HELPER(SP, 19, 2);
-EXTRACT_HELPER(IMM8, 11, 8);
-
-/*****************************************************************************/
-/* PowerPC instructions table */
-
-#if defined(DO_PPC_STATISTICS)
-#define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2) \
-{ \
- .opc1 = op1, \
- .opc2 = op2, \
- .opc3 = op3, \
- .opc4 = 0xff, \
- .handler = { \
- .inval1 = invl, \
- .type = _typ, \
- .type2 = _typ2, \
- .handler = &gen_##name, \
- .oname = stringify(name), \
- }, \
- .oname = stringify(name), \
-}
-#define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2) \
-{ \
- .opc1 = op1, \
- .opc2 = op2, \
- .opc3 = op3, \
- .opc4 = 0xff, \
- .handler = { \
- .inval1 = invl1, \
- .inval2 = invl2, \
- .type = _typ, \
- .type2 = _typ2, \
- .handler = &gen_##name, \
- .oname = stringify(name), \
- }, \
- .oname = stringify(name), \
-}
-#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2) \
-{ \
- .opc1 = op1, \
- .opc2 = op2, \
- .opc3 = op3, \
- .opc4 = 0xff, \
- .handler = { \
- .inval1 = invl, \
- .type = _typ, \
- .type2 = _typ2, \
- .handler = &gen_##name, \
- .oname = onam, \
- }, \
- .oname = onam, \
-}
-#define GEN_OPCODE3(name, op1, op2, op3, op4, invl, _typ, _typ2) \
-{ \
- .opc1 = op1, \
- .opc2 = op2, \
- .opc3 = op3, \
- .opc4 = op4, \
- .handler = { \
- .inval1 = invl, \
- .type = _typ, \
- .type2 = _typ2, \
- .handler = &gen_##name, \
- .oname = stringify(name), \
- }, \
- .oname = stringify(name), \
-}
-#define GEN_OPCODE4(name, onam, op1, op2, op3, op4, invl, _typ, _typ2) \
-{ \
- .opc1 = op1, \
- .opc2 = op2, \
- .opc3 = op3, \
- .opc4 = op4, \
- .handler = { \
- .inval1 = invl, \
- .type = _typ, \
- .type2 = _typ2, \
- .handler = &gen_##name, \
- .oname = onam, \
- }, \
- .oname = onam, \
-}
-#else
-#define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2) \
-{ \
- .opc1 = op1, \
- .opc2 = op2, \
- .opc3 = op3, \
- .opc4 = 0xff, \
- .handler = { \
- .inval1 = invl, \
- .type = _typ, \
- .type2 = _typ2, \
- .handler = &gen_##name, \
- }, \
- .oname = stringify(name), \
-}
-#define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2) \
-{ \
- .opc1 = op1, \
- .opc2 = op2, \
- .opc3 = op3, \
- .opc4 = 0xff, \
- .handler = { \
- .inval1 = invl1, \
- .inval2 = invl2, \
- .type = _typ, \
- .type2 = _typ2, \
- .handler = &gen_##name, \
- }, \
- .oname = stringify(name), \
-}
-#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2) \
-{ \
- .opc1 = op1, \
- .opc2 = op2, \
- .opc3 = op3, \
- .opc4 = 0xff, \
- .handler = { \
- .inval1 = invl, \
- .type = _typ, \
- .type2 = _typ2, \
- .handler = &gen_##name, \
- }, \
- .oname = onam, \
-}
-#define GEN_OPCODE3(name, op1, op2, op3, op4, invl, _typ, _typ2) \
-{ \
- .opc1 = op1, \
- .opc2 = op2, \
- .opc3 = op3, \
- .opc4 = op4, \
- .handler = { \
- .inval1 = invl, \
- .type = _typ, \
- .type2 = _typ2, \
- .handler = &gen_##name, \
- }, \
- .oname = stringify(name), \
-}
-#define GEN_OPCODE4(name, onam, op1, op2, op3, op4, invl, _typ, _typ2) \
-{ \
- .opc1 = op1, \
- .opc2 = op2, \
- .opc3 = op3, \
- .opc4 = op4, \
- .handler = { \
- .inval1 = invl, \
- .type = _typ, \
- .type2 = _typ2, \
- .handler = &gen_##name, \
- }, \
- .oname = onam, \
-}
-#endif
-
-/* SPR load/store helpers */
-static inline void gen_load_spr(TCGv t, int reg)
-{
- tcg_gen_ld_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg]));
-}
-
-static inline void gen_store_spr(int reg, TCGv t)
-{
- tcg_gen_st_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg]));
-}
-
-/* Invalid instruction */
-static void gen_invalid(DisasContext *ctx)
-{
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
-}
-
-static opc_handler_t invalid_handler = {
- .inval1 = 0xFFFFFFFF,
- .inval2 = 0xFFFFFFFF,
- .type = PPC_NONE,
- .type2 = PPC_NONE,
- .handler = gen_invalid,
-};
-
-/*** Integer comparison ***/
-
-static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
-{
- TCGv t0 = tcg_temp_new();
- TCGv_i32 t1 = tcg_temp_new_i32();
-
- tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_so);
-
- tcg_gen_setcond_tl((s ? TCG_COND_LT: TCG_COND_LTU), t0, arg0, arg1);
- tcg_gen_trunc_tl_i32(t1, t0);
- tcg_gen_shli_i32(t1, t1, CRF_LT);
- tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
-
- tcg_gen_setcond_tl((s ? TCG_COND_GT: TCG_COND_GTU), t0, arg0, arg1);
- tcg_gen_trunc_tl_i32(t1, t0);
- tcg_gen_shli_i32(t1, t1, CRF_GT);
- tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
-
- tcg_gen_setcond_tl(TCG_COND_EQ, t0, arg0, arg1);
- tcg_gen_trunc_tl_i32(t1, t0);
- tcg_gen_shli_i32(t1, t1, CRF_EQ);
- tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
-
- tcg_temp_free(t0);
- tcg_temp_free_i32(t1);
-}
-
-static inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
-{
- TCGv t0 = tcg_const_tl(arg1);
- gen_op_cmp(arg0, t0, s, crf);
- tcg_temp_free(t0);
-}
-
-static inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
-{
- TCGv t0, t1;
- t0 = tcg_temp_new();
- t1 = tcg_temp_new();
- if (s) {
- tcg_gen_ext32s_tl(t0, arg0);
- tcg_gen_ext32s_tl(t1, arg1);
- } else {
- tcg_gen_ext32u_tl(t0, arg0);
- tcg_gen_ext32u_tl(t1, arg1);
- }
- gen_op_cmp(t0, t1, s, crf);
- tcg_temp_free(t1);
- tcg_temp_free(t0);
-}
-
-static inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf)
-{
- TCGv t0 = tcg_const_tl(arg1);
- gen_op_cmp32(arg0, t0, s, crf);
- tcg_temp_free(t0);
-}
-
-static inline void gen_set_Rc0(DisasContext *ctx, TCGv reg)
-{
- if (NARROW_MODE(ctx)) {
- gen_op_cmpi32(reg, 0, 1, 0);
- } else {
- gen_op_cmpi(reg, 0, 1, 0);
- }
-}
-
-/* cmp */
-static void gen_cmp(DisasContext *ctx)
-{
- if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
- gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
- 1, crfD(ctx->opcode));
- } else {
- gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
- 1, crfD(ctx->opcode));
- }
-}
-
-/* cmpi */
-static void gen_cmpi(DisasContext *ctx)
-{
- if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
- gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
- 1, crfD(ctx->opcode));
- } else {
- gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
- 1, crfD(ctx->opcode));
- }
-}
-
-/* cmpl */
-static void gen_cmpl(DisasContext *ctx)
-{
- if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
- gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
- 0, crfD(ctx->opcode));
- } else {
- gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
- 0, crfD(ctx->opcode));
- }
-}
-
-/* cmpli */
-static void gen_cmpli(DisasContext *ctx)
-{
- if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
- gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
- 0, crfD(ctx->opcode));
- } else {
- gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
- 0, crfD(ctx->opcode));
- }
-}
-
-/* cmprb - range comparison: isupper, isaplha, islower*/
-static void gen_cmprb(DisasContext *ctx)
-{
- TCGv_i32 src1 = tcg_temp_new_i32();
- TCGv_i32 src2 = tcg_temp_new_i32();
- TCGv_i32 src2lo = tcg_temp_new_i32();
- TCGv_i32 src2hi = tcg_temp_new_i32();
- TCGv_i32 crf = cpu_crf[crfD(ctx->opcode)];
-
- tcg_gen_trunc_tl_i32(src1, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_trunc_tl_i32(src2, cpu_gpr[rB(ctx->opcode)]);
-
- tcg_gen_andi_i32(src1, src1, 0xFF);
- tcg_gen_ext8u_i32(src2lo, src2);
- tcg_gen_shri_i32(src2, src2, 8);
- tcg_gen_ext8u_i32(src2hi, src2);
-
- tcg_gen_setcond_i32(TCG_COND_LEU, src2lo, src2lo, src1);
- tcg_gen_setcond_i32(TCG_COND_LEU, src2hi, src1, src2hi);
- tcg_gen_and_i32(crf, src2lo, src2hi);
-
- if (ctx->opcode & 0x00200000) {
- tcg_gen_shri_i32(src2, src2, 8);
- tcg_gen_ext8u_i32(src2lo, src2);
- tcg_gen_shri_i32(src2, src2, 8);
- tcg_gen_ext8u_i32(src2hi, src2);
- tcg_gen_setcond_i32(TCG_COND_LEU, src2lo, src2lo, src1);
- tcg_gen_setcond_i32(TCG_COND_LEU, src2hi, src1, src2hi);
- tcg_gen_and_i32(src2lo, src2lo, src2hi);
- tcg_gen_or_i32(crf, crf, src2lo);
- }
- tcg_gen_shli_i32(crf, crf, CRF_GT);
- tcg_temp_free_i32(src1);
- tcg_temp_free_i32(src2);
- tcg_temp_free_i32(src2lo);
- tcg_temp_free_i32(src2hi);
-}
-
-#if defined(TARGET_PPC64)
-/* cmpeqb */
-static void gen_cmpeqb(DisasContext *ctx)
-{
- gen_helper_cmpeqb(cpu_crf[crfD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rB(ctx->opcode)]);
-}
-#endif
-
-/* isel (PowerPC 2.03 specification) */
-static void gen_isel(DisasContext *ctx)
-{
- uint32_t bi = rC(ctx->opcode);
- uint32_t mask = 0x08 >> (bi & 0x03);
- TCGv t0 = tcg_temp_new();
- TCGv zr;
-
- tcg_gen_extu_i32_tl(t0, cpu_crf[bi >> 2]);
- tcg_gen_andi_tl(t0, t0, mask);
-
- zr = tcg_const_tl(0);
- tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rD(ctx->opcode)], t0, zr,
- rA(ctx->opcode) ? cpu_gpr[rA(ctx->opcode)] : zr,
- cpu_gpr[rB(ctx->opcode)]);
- tcg_temp_free(zr);
- tcg_temp_free(t0);
-}
-
-/* cmpb: PowerPC 2.05 specification */
-static void gen_cmpb(DisasContext *ctx)
-{
- gen_helper_cmpb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
- cpu_gpr[rB(ctx->opcode)]);
-}
-
-/*** Integer arithmetic ***/
-
-static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0,
- TCGv arg1, TCGv arg2, int sub)
-{
- TCGv t0 = tcg_temp_new();
-
- tcg_gen_xor_tl(cpu_ov, arg0, arg2);
- tcg_gen_xor_tl(t0, arg1, arg2);
- if (sub) {
- tcg_gen_and_tl(cpu_ov, cpu_ov, t0);
- } else {
- tcg_gen_andc_tl(cpu_ov, cpu_ov, t0);
- }
- tcg_temp_free(t0);
- if (NARROW_MODE(ctx)) {
- tcg_gen_ext32s_tl(cpu_ov, cpu_ov);
- }
- tcg_gen_shri_tl(cpu_ov, cpu_ov, TARGET_LONG_BITS - 1);
- tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
-}
-
-/* Common add function */
-static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1,
- TCGv arg2, bool add_ca, bool compute_ca,
- bool compute_ov, bool compute_rc0)
-{
- TCGv t0 = ret;
-
- if (compute_ca || compute_ov) {
- t0 = tcg_temp_new();
- }
-
- if (compute_ca) {
- if (NARROW_MODE(ctx)) {
- /* Caution: a non-obvious corner case of the spec is that we
- must produce the *entire* 64-bit addition, but produce the
- carry into bit 32. */
- TCGv t1 = tcg_temp_new();
- tcg_gen_xor_tl(t1, arg1, arg2); /* add without carry */
- tcg_gen_add_tl(t0, arg1, arg2);
- if (add_ca) {
- tcg_gen_add_tl(t0, t0, cpu_ca);
- }
- tcg_gen_xor_tl(cpu_ca, t0, t1); /* bits changed w/ carry */
- tcg_temp_free(t1);
- tcg_gen_shri_tl(cpu_ca, cpu_ca, 32); /* extract bit 32 */
- tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
- } else {
- TCGv zero = tcg_const_tl(0);
- if (add_ca) {
- tcg_gen_add2_tl(t0, cpu_ca, arg1, zero, cpu_ca, zero);
- tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, arg2, zero);
- } else {
- tcg_gen_add2_tl(t0, cpu_ca, arg1, zero, arg2, zero);
- }
- tcg_temp_free(zero);
- }
- } else {
- tcg_gen_add_tl(t0, arg1, arg2);
- if (add_ca) {
- tcg_gen_add_tl(t0, t0, cpu_ca);
- }
- }
-
- if (compute_ov) {
- gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0);
- }
- if (unlikely(compute_rc0)) {
- gen_set_Rc0(ctx, t0);
- }
-
- if (!TCGV_EQUAL(t0, ret)) {
- tcg_gen_mov_tl(ret, t0);
- tcg_temp_free(t0);
- }
-}
-/* Add functions with two operands */
-#define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], \
- cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
- add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \
-}
-/* Add functions with one operand and one immediate */
-#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val, \
- add_ca, compute_ca, compute_ov) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- TCGv t0 = tcg_const_tl(const_val); \
- gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], \
- cpu_gpr[rA(ctx->opcode)], t0, \
- add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \
- tcg_temp_free(t0); \
-}
-
-/* add add. addo addo. */
-GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
-GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
-/* addc addc. addco addco. */
-GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
-GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
-/* adde adde. addeo addeo. */
-GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
-GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
-/* addme addme. addmeo addmeo. */
-GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
-GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
-/* addze addze. addzeo addzeo.*/
-GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
-GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
-/* addi */
-static void gen_addi(DisasContext *ctx)
-{
- target_long simm = SIMM(ctx->opcode);
-
- if (rA(ctx->opcode) == 0) {
- /* li case */
- tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm);
- } else {
- tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)],
- cpu_gpr[rA(ctx->opcode)], simm);
- }
-}
-/* addic addic.*/
-static inline void gen_op_addic(DisasContext *ctx, bool compute_rc0)
-{
- TCGv c = tcg_const_tl(SIMM(ctx->opcode));
- gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
- c, 0, 1, 0, compute_rc0);
- tcg_temp_free(c);
-}
-
-static void gen_addic(DisasContext *ctx)
-{
- gen_op_addic(ctx, 0);
-}
-
-static void gen_addic_(DisasContext *ctx)
-{
- gen_op_addic(ctx, 1);
-}
-
-/* addis */
-static void gen_addis(DisasContext *ctx)
-{
- target_long simm = SIMM(ctx->opcode);
-
- if (rA(ctx->opcode) == 0) {
- /* lis case */
- tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm << 16);
- } else {
- tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)],
- cpu_gpr[rA(ctx->opcode)], simm << 16);
- }
-}
-
-/* addpcis */
-static void gen_addpcis(DisasContext *ctx)
-{
- target_long d = DX(ctx->opcode);
-
- tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], ctx->nip + (d << 16));
-}
-
-static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, TCGv arg1,
- TCGv arg2, int sign, int compute_ov)
-{
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv_i32 t1 = tcg_temp_new_i32();
- TCGv_i32 t2 = tcg_temp_new_i32();
- TCGv_i32 t3 = tcg_temp_new_i32();
-
- tcg_gen_trunc_tl_i32(t0, arg1);
- tcg_gen_trunc_tl_i32(t1, arg2);
- if (sign) {
- tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t0, INT_MIN);
- tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, -1);
- tcg_gen_and_i32(t2, t2, t3);
- tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, 0);
- tcg_gen_or_i32(t2, t2, t3);
- tcg_gen_movi_i32(t3, 0);
- tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1);
- tcg_gen_div_i32(t3, t0, t1);
- tcg_gen_extu_i32_tl(ret, t3);
- } else {
- tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t1, 0);
- tcg_gen_movi_i32(t3, 0);
- tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1);
- tcg_gen_divu_i32(t3, t0, t1);
- tcg_gen_extu_i32_tl(ret, t3);
- }
- if (compute_ov) {
- tcg_gen_extu_i32_tl(cpu_ov, t2);
- tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
- }
- tcg_temp_free_i32(t0);
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
- tcg_temp_free_i32(t3);
-
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, ret);
-}
-/* Div functions */
-#define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- gen_op_arith_divw(ctx, cpu_gpr[rD(ctx->opcode)], \
- cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
- sign, compute_ov); \
-}
-/* divwu divwu. divwuo divwuo. */
-GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0);
-GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1);
-/* divw divw. divwo divwo. */
-GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0);
-GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1);
-
-/* div[wd]eu[o][.] */
-#define GEN_DIVE(name, hlpr, compute_ov) \
-static void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_i32 t0 = tcg_const_i32(compute_ov); \
- gen_helper_##hlpr(cpu_gpr[rD(ctx->opcode)], cpu_env, \
- cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0); \
- tcg_temp_free_i32(t0); \
- if (unlikely(Rc(ctx->opcode) != 0)) { \
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); \
- } \
-}
-
-GEN_DIVE(divweu, divweu, 0);
-GEN_DIVE(divweuo, divweu, 1);
-GEN_DIVE(divwe, divwe, 0);
-GEN_DIVE(divweo, divwe, 1);
-
-#if defined(TARGET_PPC64)
-static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1,
- TCGv arg2, int sign, int compute_ov)
-{
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
- TCGv_i64 t2 = tcg_temp_new_i64();
- TCGv_i64 t3 = tcg_temp_new_i64();
-
- tcg_gen_mov_i64(t0, arg1);
- tcg_gen_mov_i64(t1, arg2);
- if (sign) {
- tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t0, INT64_MIN);
- tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, -1);
- tcg_gen_and_i64(t2, t2, t3);
- tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, 0);
- tcg_gen_or_i64(t2, t2, t3);
- tcg_gen_movi_i64(t3, 0);
- tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1);
- tcg_gen_div_i64(ret, t0, t1);
- } else {
- tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t1, 0);
- tcg_gen_movi_i64(t3, 0);
- tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1);
- tcg_gen_divu_i64(ret, t0, t1);
- }
- if (compute_ov) {
- tcg_gen_mov_tl(cpu_ov, t2);
- tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
- }
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
- tcg_temp_free_i64(t2);
- tcg_temp_free_i64(t3);
-
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, ret);
-}
-
-#define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- gen_op_arith_divd(ctx, cpu_gpr[rD(ctx->opcode)], \
- cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
- sign, compute_ov); \
-}
-/* divwu divwu. divwuo divwuo. */
-GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0);
-GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1);
-/* divw divw. divwo divwo. */
-GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0);
-GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
-
-GEN_DIVE(divdeu, divdeu, 0);
-GEN_DIVE(divdeuo, divdeu, 1);
-GEN_DIVE(divde, divde, 0);
-GEN_DIVE(divdeo, divde, 1);
-#endif
-
-static inline void gen_op_arith_modw(DisasContext *ctx, TCGv ret, TCGv arg1,
- TCGv arg2, int sign)
-{
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv_i32 t1 = tcg_temp_new_i32();
-
- tcg_gen_trunc_tl_i32(t0, arg1);
- tcg_gen_trunc_tl_i32(t1, arg2);
- if (sign) {
- TCGv_i32 t2 = tcg_temp_new_i32();
- TCGv_i32 t3 = tcg_temp_new_i32();
- tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t0, INT_MIN);
- tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, -1);
- tcg_gen_and_i32(t2, t2, t3);
- tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, 0);
- tcg_gen_or_i32(t2, t2, t3);
- tcg_gen_movi_i32(t3, 0);
- tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1);
- tcg_gen_rem_i32(t3, t0, t1);
- tcg_gen_ext_i32_tl(ret, t3);
- tcg_temp_free_i32(t2);
- tcg_temp_free_i32(t3);
- } else {
- TCGv_i32 t2 = tcg_const_i32(1);
- TCGv_i32 t3 = tcg_const_i32(0);
- tcg_gen_movcond_i32(TCG_COND_EQ, t1, t1, t3, t2, t1);
- tcg_gen_remu_i32(t3, t0, t1);
- tcg_gen_extu_i32_tl(ret, t3);
- tcg_temp_free_i32(t2);
- tcg_temp_free_i32(t3);
- }
- tcg_temp_free_i32(t0);
- tcg_temp_free_i32(t1);
-}
-
-#define GEN_INT_ARITH_MODW(name, opc3, sign) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- gen_op_arith_modw(ctx, cpu_gpr[rD(ctx->opcode)], \
- cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
- sign); \
-}
-
-GEN_INT_ARITH_MODW(moduw, 0x08, 0);
-GEN_INT_ARITH_MODW(modsw, 0x18, 1);
-
-#if defined(TARGET_PPC64)
-static inline void gen_op_arith_modd(DisasContext *ctx, TCGv ret, TCGv arg1,
- TCGv arg2, int sign)
-{
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
-
- tcg_gen_mov_i64(t0, arg1);
- tcg_gen_mov_i64(t1, arg2);
- if (sign) {
- TCGv_i64 t2 = tcg_temp_new_i64();
- TCGv_i64 t3 = tcg_temp_new_i64();
- tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t0, INT64_MIN);
- tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, -1);
- tcg_gen_and_i64(t2, t2, t3);
- tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, 0);
- tcg_gen_or_i64(t2, t2, t3);
- tcg_gen_movi_i64(t3, 0);
- tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1);
- tcg_gen_rem_i64(ret, t0, t1);
- tcg_temp_free_i64(t2);
- tcg_temp_free_i64(t3);
- } else {
- TCGv_i64 t2 = tcg_const_i64(1);
- TCGv_i64 t3 = tcg_const_i64(0);
- tcg_gen_movcond_i64(TCG_COND_EQ, t1, t1, t3, t2, t1);
- tcg_gen_remu_i64(ret, t0, t1);
- tcg_temp_free_i64(t2);
- tcg_temp_free_i64(t3);
- }
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
-}
-
-#define GEN_INT_ARITH_MODD(name, opc3, sign) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- gen_op_arith_modd(ctx, cpu_gpr[rD(ctx->opcode)], \
- cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
- sign); \
-}
-
-GEN_INT_ARITH_MODD(modud, 0x08, 0);
-GEN_INT_ARITH_MODD(modsd, 0x18, 1);
-#endif
-
-/* mulhw mulhw. */
-static void gen_mulhw(DisasContext *ctx)
-{
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv_i32 t1 = tcg_temp_new_i32();
-
- tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_muls2_i32(t0, t1, t0, t1);
- tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);
- tcg_temp_free_i32(t0);
- tcg_temp_free_i32(t1);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* mulhwu mulhwu. */
-static void gen_mulhwu(DisasContext *ctx)
-{
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv_i32 t1 = tcg_temp_new_i32();
-
- tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_mulu2_i32(t0, t1, t0, t1);
- tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);
- tcg_temp_free_i32(t0);
- tcg_temp_free_i32(t1);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* mullw mullw. */
-static void gen_mullw(DisasContext *ctx)
-{
-#if defined(TARGET_PPC64)
- TCGv_i64 t0, t1;
- t0 = tcg_temp_new_i64();
- t1 = tcg_temp_new_i64();
- tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_mul_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
-#else
- tcg_gen_mul_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rB(ctx->opcode)]);
-#endif
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* mullwo mullwo. */
-static void gen_mullwo(DisasContext *ctx)
-{
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv_i32 t1 = tcg_temp_new_i32();
-
- tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_muls2_i32(t0, t1, t0, t1);
-#if defined(TARGET_PPC64)
- tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);
-#else
- tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], t0);
-#endif
-
- tcg_gen_sari_i32(t0, t0, 31);
- tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t1);
- tcg_gen_extu_i32_tl(cpu_ov, t0);
- tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
-
- tcg_temp_free_i32(t0);
- tcg_temp_free_i32(t1);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* mulli */
-static void gen_mulli(DisasContext *ctx)
-{
- tcg_gen_muli_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
- SIMM(ctx->opcode));
-}
-
-#if defined(TARGET_PPC64)
-/* mulhd mulhd. */
-static void gen_mulhd(DisasContext *ctx)
-{
- TCGv lo = tcg_temp_new();
- tcg_gen_muls2_tl(lo, cpu_gpr[rD(ctx->opcode)],
- cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
- tcg_temp_free(lo);
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
- }
-}
-
-/* mulhdu mulhdu. */
-static void gen_mulhdu(DisasContext *ctx)
-{
- TCGv lo = tcg_temp_new();
- tcg_gen_mulu2_tl(lo, cpu_gpr[rD(ctx->opcode)],
- cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
- tcg_temp_free(lo);
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
- }
-}
-
-/* mulld mulld. */
-static void gen_mulld(DisasContext *ctx)
-{
- tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rB(ctx->opcode)]);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* mulldo mulldo. */
-static void gen_mulldo(DisasContext *ctx)
-{
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
-
- tcg_gen_muls2_i64(t0, t1, cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_mov_i64(cpu_gpr[rD(ctx->opcode)], t0);
-
- tcg_gen_sari_i64(t0, t0, 63);
- tcg_gen_setcond_i64(TCG_COND_NE, cpu_ov, t0, t1);
- tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
-
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
-
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
- }
-}
-#endif
-
-/* Common subf function */
-static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,
- TCGv arg2, bool add_ca, bool compute_ca,
- bool compute_ov, bool compute_rc0)
-{
- TCGv t0 = ret;
-
- if (compute_ca || compute_ov) {
- t0 = tcg_temp_new();
- }
-
- if (compute_ca) {
- /* dest = ~arg1 + arg2 [+ ca]. */
- if (NARROW_MODE(ctx)) {
- /* Caution: a non-obvious corner case of the spec is that we
- must produce the *entire* 64-bit addition, but produce the
- carry into bit 32. */
- TCGv inv1 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- tcg_gen_not_tl(inv1, arg1);
- if (add_ca) {
- tcg_gen_add_tl(t0, arg2, cpu_ca);
- } else {
- tcg_gen_addi_tl(t0, arg2, 1);
- }
- tcg_gen_xor_tl(t1, arg2, inv1); /* add without carry */
- tcg_gen_add_tl(t0, t0, inv1);
- tcg_temp_free(inv1);
- tcg_gen_xor_tl(cpu_ca, t0, t1); /* bits changes w/ carry */
- tcg_temp_free(t1);
- tcg_gen_shri_tl(cpu_ca, cpu_ca, 32); /* extract bit 32 */
- tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
- } else if (add_ca) {
- TCGv zero, inv1 = tcg_temp_new();
- tcg_gen_not_tl(inv1, arg1);
- zero = tcg_const_tl(0);
- tcg_gen_add2_tl(t0, cpu_ca, arg2, zero, cpu_ca, zero);
- tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, inv1, zero);
- tcg_temp_free(zero);
- tcg_temp_free(inv1);
- } else {
- tcg_gen_setcond_tl(TCG_COND_GEU, cpu_ca, arg2, arg1);
- tcg_gen_sub_tl(t0, arg2, arg1);
- }
- } else if (add_ca) {
- /* Since we're ignoring carry-out, we can simplify the
- standard ~arg1 + arg2 + ca to arg2 - arg1 + ca - 1. */
- tcg_gen_sub_tl(t0, arg2, arg1);
- tcg_gen_add_tl(t0, t0, cpu_ca);
- tcg_gen_subi_tl(t0, t0, 1);
- } else {
- tcg_gen_sub_tl(t0, arg2, arg1);
- }
-
- if (compute_ov) {
- gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1);
- }
- if (unlikely(compute_rc0)) {
- gen_set_Rc0(ctx, t0);
- }
-
- if (!TCGV_EQUAL(t0, ret)) {
- tcg_gen_mov_tl(ret, t0);
- tcg_temp_free(t0);
- }
-}
-/* Sub functions with Two operands functions */
-#define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], \
- cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \
- add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \
-}
-/* Sub functions with one operand and one immediate */
-#define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val, \
- add_ca, compute_ca, compute_ov) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- TCGv t0 = tcg_const_tl(const_val); \
- gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], \
- cpu_gpr[rA(ctx->opcode)], t0, \
- add_ca, compute_ca, compute_ov, Rc(ctx->opcode)); \
- tcg_temp_free(t0); \
-}
-/* subf subf. subfo subfo. */
-GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
-GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
-/* subfc subfc. subfco subfco. */
-GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
-GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
-/* subfe subfe. subfeo subfo. */
-GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
-GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
-/* subfme subfme. subfmeo subfmeo. */
-GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
-GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
-/* subfze subfze. subfzeo subfzeo.*/
-GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
-GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
-
-/* subfic */
-static void gen_subfic(DisasContext *ctx)
-{
- TCGv c = tcg_const_tl(SIMM(ctx->opcode));
- gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
- c, 0, 1, 0, 0);
- tcg_temp_free(c);
-}
-
-/* neg neg. nego nego. */
-static inline void gen_op_arith_neg(DisasContext *ctx, bool compute_ov)
-{
- TCGv zero = tcg_const_tl(0);
- gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
- zero, 0, 0, compute_ov, Rc(ctx->opcode));
- tcg_temp_free(zero);
-}
-
-static void gen_neg(DisasContext *ctx)
-{
- gen_op_arith_neg(ctx, 0);
-}
-
-static void gen_nego(DisasContext *ctx)
-{
- gen_op_arith_neg(ctx, 1);
-}
-
-/*** Integer logical ***/
-#define GEN_LOGICAL2(name, tcg_op, opc, type) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], \
- cpu_gpr[rB(ctx->opcode)]); \
- if (unlikely(Rc(ctx->opcode) != 0)) \
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); \
-}
-
-#define GEN_LOGICAL1(name, tcg_op, opc, type) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); \
- if (unlikely(Rc(ctx->opcode) != 0)) \
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); \
-}
-
-/* and & and. */
-GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
-/* andc & andc. */
-GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
-
-/* andi. */
-static void gen_andi_(DisasContext *ctx)
-{
- tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode));
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* andis. */
-static void gen_andis_(DisasContext *ctx)
-{
- tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode) << 16);
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* cntlzw */
-static void gen_cntlzw(DisasContext *ctx)
-{
- gen_helper_cntlzw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* cnttzw */
-static void gen_cnttzw(DisasContext *ctx)
-{
- gen_helper_cnttzw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
- }
-}
-
-/* eqv & eqv. */
-GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
-/* extsb & extsb. */
-GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
-/* extsh & extsh. */
-GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
-/* nand & nand. */
-GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
-/* nor & nor. */
-GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
-
-#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
-static void gen_pause(DisasContext *ctx)
-{
- TCGv_i32 t0 = tcg_const_i32(0);
- tcg_gen_st_i32(t0, cpu_env,
- -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
- tcg_temp_free_i32(t0);
-
- /* Stop translation, this gives other CPUs a chance to run */
- gen_exception_nip(ctx, EXCP_HLT, ctx->nip);
-}
-#endif /* defined(TARGET_PPC64) */
-
-/* or & or. */
-static void gen_or(DisasContext *ctx)
-{
- int rs, ra, rb;
-
- rs = rS(ctx->opcode);
- ra = rA(ctx->opcode);
- rb = rB(ctx->opcode);
- /* Optimisation for mr. ri case */
- if (rs != ra || rs != rb) {
- if (rs != rb)
- tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]);
- else
- tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[ra]);
- } else if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[rs]);
-#if defined(TARGET_PPC64)
- } else if (rs != 0) { /* 0 is nop */
- int prio = 0;
-
- switch (rs) {
- case 1:
- /* Set process priority to low */
- prio = 2;
- break;
- case 6:
- /* Set process priority to medium-low */
- prio = 3;
- break;
- case 2:
- /* Set process priority to normal */
- prio = 4;
- break;
-#if !defined(CONFIG_USER_ONLY)
- case 31:
- if (!ctx->pr) {
- /* Set process priority to very low */
- prio = 1;
- }
- break;
- case 5:
- if (!ctx->pr) {
- /* Set process priority to medium-hight */
- prio = 5;
- }
- break;
- case 3:
- if (!ctx->pr) {
- /* Set process priority to high */
- prio = 6;
- }
- break;
- case 7:
- if (ctx->hv && !ctx->pr) {
- /* Set process priority to very high */
- prio = 7;
- }
- break;
-#endif
- default:
- break;
- }
- if (prio) {
- TCGv t0 = tcg_temp_new();
- gen_load_spr(t0, SPR_PPR);
- tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
- tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
- gen_store_spr(SPR_PPR, t0);
- tcg_temp_free(t0);
- }
-#if !defined(CONFIG_USER_ONLY)
- /* Pause out of TCG otherwise spin loops with smt_low eat too much
- * CPU and the kernel hangs. This applies to all encodings other
- * than no-op, e.g., miso(rs=26), yield(27), mdoio(29), mdoom(30),
- * and all currently undefined.
- */
- gen_pause(ctx);
-#endif
-#endif
- }
-}
-/* orc & orc. */
-GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
-
-/* xor & xor. */
-static void gen_xor(DisasContext *ctx)
-{
- /* Optimisation for "set to zero" case */
- if (rS(ctx->opcode) != rB(ctx->opcode))
- tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
- else
- tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* ori */
-static void gen_ori(DisasContext *ctx)
-{
- target_ulong uimm = UIMM(ctx->opcode);
-
- if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
- return;
- }
- tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
-}
-
-/* oris */
-static void gen_oris(DisasContext *ctx)
-{
- target_ulong uimm = UIMM(ctx->opcode);
-
- if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
- /* NOP */
- return;
- }
- tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
-}
-
-/* xori */
-static void gen_xori(DisasContext *ctx)
-{
- target_ulong uimm = UIMM(ctx->opcode);
-
- if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
- /* NOP */
- return;
- }
- tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
-}
-
-/* xoris */
-static void gen_xoris(DisasContext *ctx)
-{
- target_ulong uimm = UIMM(ctx->opcode);
-
- if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
- /* NOP */
- return;
- }
- tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
-}
-
-/* popcntb : PowerPC 2.03 specification */
-static void gen_popcntb(DisasContext *ctx)
-{
- gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
-}
-
-static void gen_popcntw(DisasContext *ctx)
-{
- gen_helper_popcntw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
-}
-
-#if defined(TARGET_PPC64)
-/* popcntd: PowerPC 2.06 specification */
-static void gen_popcntd(DisasContext *ctx)
-{
- gen_helper_popcntd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
-}
-#endif
-
-/* prtyw: PowerPC 2.05 specification */
-static void gen_prtyw(DisasContext *ctx)
-{
- TCGv ra = cpu_gpr[rA(ctx->opcode)];
- TCGv rs = cpu_gpr[rS(ctx->opcode)];
- TCGv t0 = tcg_temp_new();
- tcg_gen_shri_tl(t0, rs, 16);
- tcg_gen_xor_tl(ra, rs, t0);
- tcg_gen_shri_tl(t0, ra, 8);
- tcg_gen_xor_tl(ra, ra, t0);
- tcg_gen_andi_tl(ra, ra, (target_ulong)0x100000001ULL);
- tcg_temp_free(t0);
-}
-
-#if defined(TARGET_PPC64)
-/* prtyd: PowerPC 2.05 specification */
-static void gen_prtyd(DisasContext *ctx)
-{
- TCGv ra = cpu_gpr[rA(ctx->opcode)];
- TCGv rs = cpu_gpr[rS(ctx->opcode)];
- TCGv t0 = tcg_temp_new();
- tcg_gen_shri_tl(t0, rs, 32);
- tcg_gen_xor_tl(ra, rs, t0);
- tcg_gen_shri_tl(t0, ra, 16);
- tcg_gen_xor_tl(ra, ra, t0);
- tcg_gen_shri_tl(t0, ra, 8);
- tcg_gen_xor_tl(ra, ra, t0);
- tcg_gen_andi_tl(ra, ra, 1);
- tcg_temp_free(t0);
-}
-#endif
-
-#if defined(TARGET_PPC64)
-/* bpermd */
-static void gen_bpermd(DisasContext *ctx)
-{
- gen_helper_bpermd(cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
-}
-#endif
-
-#if defined(TARGET_PPC64)
-/* extsw & extsw. */
-GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
-
-/* cntlzd */
-static void gen_cntlzd(DisasContext *ctx)
-{
- gen_helper_cntlzd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* cnttzd */
-static void gen_cnttzd(DisasContext *ctx)
-{
- gen_helper_cnttzd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
- }
-}
-
-/* darn */
-static void gen_darn(DisasContext *ctx)
-{
- int l = L(ctx->opcode);
-
- if (l == 0) {
- gen_helper_darn32(cpu_gpr[rD(ctx->opcode)]);
- } else if (l <= 2) {
- /* Return 64-bit random for both CRN and RRN */
- gen_helper_darn64(cpu_gpr[rD(ctx->opcode)]);
- } else {
- tcg_gen_movi_i64(cpu_gpr[rD(ctx->opcode)], -1);
- }
-}
-#endif
-
-/*** Integer rotate ***/
-
-/* rlwimi & rlwimi. */
-static void gen_rlwimi(DisasContext *ctx)
-{
- TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
- TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
- uint32_t sh = SH(ctx->opcode);
- uint32_t mb = MB(ctx->opcode);
- uint32_t me = ME(ctx->opcode);
-
- if (sh == (31-me) && mb <= me) {
- tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1);
- } else {
- target_ulong mask;
- TCGv t1;
-
-#if defined(TARGET_PPC64)
- mb += 32;
- me += 32;
-#endif
- mask = MASK(mb, me);
-
- t1 = tcg_temp_new();
- if (mask <= 0xffffffffu) {
- TCGv_i32 t0 = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(t0, t_rs);
- tcg_gen_rotli_i32(t0, t0, sh);
- tcg_gen_extu_i32_tl(t1, t0);
- tcg_temp_free_i32(t0);
- } else {
-#if defined(TARGET_PPC64)
- tcg_gen_deposit_i64(t1, t_rs, t_rs, 32, 32);
- tcg_gen_rotli_i64(t1, t1, sh);
-#else
- g_assert_not_reached();
-#endif
- }
-
- tcg_gen_andi_tl(t1, t1, mask);
- tcg_gen_andi_tl(t_ra, t_ra, ~mask);
- tcg_gen_or_tl(t_ra, t_ra, t1);
- tcg_temp_free(t1);
- }
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, t_ra);
- }
-}
-
-/* rlwinm & rlwinm. */
-static void gen_rlwinm(DisasContext *ctx)
-{
- TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
- TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
- uint32_t sh = SH(ctx->opcode);
- uint32_t mb = MB(ctx->opcode);
- uint32_t me = ME(ctx->opcode);
-
- if (mb == 0 && me == (31 - sh)) {
- tcg_gen_shli_tl(t_ra, t_rs, sh);
- tcg_gen_ext32u_tl(t_ra, t_ra);
- } else if (sh != 0 && me == 31 && sh == (32 - mb)) {
- tcg_gen_ext32u_tl(t_ra, t_rs);
- tcg_gen_shri_tl(t_ra, t_ra, mb);
- } else {
- target_ulong mask;
-#if defined(TARGET_PPC64)
- mb += 32;
- me += 32;
-#endif
- mask = MASK(mb, me);
-
- if (mask <= 0xffffffffu) {
- TCGv_i32 t0 = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(t0, t_rs);
- tcg_gen_rotli_i32(t0, t0, sh);
- tcg_gen_andi_i32(t0, t0, mask);
- tcg_gen_extu_i32_tl(t_ra, t0);
- tcg_temp_free_i32(t0);
- } else {
-#if defined(TARGET_PPC64)
- tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32);
- tcg_gen_rotli_i64(t_ra, t_ra, sh);
- tcg_gen_andi_i64(t_ra, t_ra, mask);
-#else
- g_assert_not_reached();
-#endif
- }
- }
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, t_ra);
- }
-}
-
-/* rlwnm & rlwnm. */
-static void gen_rlwnm(DisasContext *ctx)
-{
- TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
- TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
- TCGv t_rb = cpu_gpr[rB(ctx->opcode)];
- uint32_t mb = MB(ctx->opcode);
- uint32_t me = ME(ctx->opcode);
- target_ulong mask;
-
-#if defined(TARGET_PPC64)
- mb += 32;
- me += 32;
-#endif
- mask = MASK(mb, me);
-
- if (mask <= 0xffffffffu) {
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv_i32 t1 = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(t0, t_rb);
- tcg_gen_trunc_tl_i32(t1, t_rs);
- tcg_gen_andi_i32(t0, t0, 0x1f);
- tcg_gen_rotl_i32(t1, t1, t0);
- tcg_gen_extu_i32_tl(t_ra, t1);
- tcg_temp_free_i32(t0);
- tcg_temp_free_i32(t1);
- } else {
-#if defined(TARGET_PPC64)
- TCGv_i64 t0 = tcg_temp_new_i64();
- tcg_gen_andi_i64(t0, t_rb, 0x1f);
- tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32);
- tcg_gen_rotl_i64(t_ra, t_ra, t0);
- tcg_temp_free_i64(t0);
-#else
- g_assert_not_reached();
-#endif
- }
-
- tcg_gen_andi_tl(t_ra, t_ra, mask);
-
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, t_ra);
- }
-}
-
-#if defined(TARGET_PPC64)
-#define GEN_PPC64_R2(name, opc1, opc2) \
-static void glue(gen_, name##0)(DisasContext *ctx) \
-{ \
- gen_##name(ctx, 0); \
-} \
- \
-static void glue(gen_, name##1)(DisasContext *ctx) \
-{ \
- gen_##name(ctx, 1); \
-}
-#define GEN_PPC64_R4(name, opc1, opc2) \
-static void glue(gen_, name##0)(DisasContext *ctx) \
-{ \
- gen_##name(ctx, 0, 0); \
-} \
- \
-static void glue(gen_, name##1)(DisasContext *ctx) \
-{ \
- gen_##name(ctx, 0, 1); \
-} \
- \
-static void glue(gen_, name##2)(DisasContext *ctx) \
-{ \
- gen_##name(ctx, 1, 0); \
-} \
- \
-static void glue(gen_, name##3)(DisasContext *ctx) \
-{ \
- gen_##name(ctx, 1, 1); \
-}
-
-static void gen_rldinm(DisasContext *ctx, int mb, int me, int sh)
-{
- TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
- TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
-
- if (sh != 0 && mb == 0 && me == (63 - sh)) {
- tcg_gen_shli_tl(t_ra, t_rs, sh);
- } else if (sh != 0 && me == 63 && sh == (64 - mb)) {
- tcg_gen_shri_tl(t_ra, t_rs, mb);
- } else {
- tcg_gen_rotli_tl(t_ra, t_rs, sh);
- tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me));
- }
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, t_ra);
- }
-}
-
-/* rldicl - rldicl. */
-static inline void gen_rldicl(DisasContext *ctx, int mbn, int shn)
-{
- uint32_t sh, mb;
-
- sh = SH(ctx->opcode) | (shn << 5);
- mb = MB(ctx->opcode) | (mbn << 5);
- gen_rldinm(ctx, mb, 63, sh);
-}
-GEN_PPC64_R4(rldicl, 0x1E, 0x00);
-
-/* rldicr - rldicr. */
-static inline void gen_rldicr(DisasContext *ctx, int men, int shn)
-{
- uint32_t sh, me;
-
- sh = SH(ctx->opcode) | (shn << 5);
- me = MB(ctx->opcode) | (men << 5);
- gen_rldinm(ctx, 0, me, sh);
-}
-GEN_PPC64_R4(rldicr, 0x1E, 0x02);
-
-/* rldic - rldic. */
-static inline void gen_rldic(DisasContext *ctx, int mbn, int shn)
-{
- uint32_t sh, mb;
-
- sh = SH(ctx->opcode) | (shn << 5);
- mb = MB(ctx->opcode) | (mbn << 5);
- gen_rldinm(ctx, mb, 63 - sh, sh);
-}
-GEN_PPC64_R4(rldic, 0x1E, 0x04);
-
-static void gen_rldnm(DisasContext *ctx, int mb, int me)
-{
- TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
- TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
- TCGv t_rb = cpu_gpr[rB(ctx->opcode)];
- TCGv t0;
-
- t0 = tcg_temp_new();
- tcg_gen_andi_tl(t0, t_rb, 0x3f);
- tcg_gen_rotl_tl(t_ra, t_rs, t0);
- tcg_temp_free(t0);
-
- tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me));
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, t_ra);
- }
-}
-
-/* rldcl - rldcl. */
-static inline void gen_rldcl(DisasContext *ctx, int mbn)
-{
- uint32_t mb;
-
- mb = MB(ctx->opcode) | (mbn << 5);
- gen_rldnm(ctx, mb, 63);
-}
-GEN_PPC64_R2(rldcl, 0x1E, 0x08);
-
-/* rldcr - rldcr. */
-static inline void gen_rldcr(DisasContext *ctx, int men)
-{
- uint32_t me;
-
- me = MB(ctx->opcode) | (men << 5);
- gen_rldnm(ctx, 0, me);
-}
-GEN_PPC64_R2(rldcr, 0x1E, 0x09);
-
-/* rldimi - rldimi. */
-static void gen_rldimi(DisasContext *ctx, int mbn, int shn)
-{
- TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
- TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
- uint32_t sh = SH(ctx->opcode) | (shn << 5);
- uint32_t mb = MB(ctx->opcode) | (mbn << 5);
- uint32_t me = 63 - sh;
-
- if (mb <= me) {
- tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1);
- } else {
- target_ulong mask = MASK(mb, me);
- TCGv t1 = tcg_temp_new();
-
- tcg_gen_rotli_tl(t1, t_rs, sh);
- tcg_gen_andi_tl(t1, t1, mask);
- tcg_gen_andi_tl(t_ra, t_ra, ~mask);
- tcg_gen_or_tl(t_ra, t_ra, t1);
- tcg_temp_free(t1);
- }
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, t_ra);
- }
-}
-GEN_PPC64_R4(rldimi, 0x1E, 0x06);
-#endif
-
-/*** Integer shift ***/
-
-/* slw & slw. */
-static void gen_slw(DisasContext *ctx)
-{
- TCGv t0, t1;
-
- t0 = tcg_temp_new();
- /* AND rS with a mask that is 0 when rB >= 0x20 */
-#if defined(TARGET_PPC64)
- tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
- tcg_gen_sari_tl(t0, t0, 0x3f);
-#else
- tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
- tcg_gen_sari_tl(t0, t0, 0x1f);
-#endif
- tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
- t1 = tcg_temp_new();
- tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
- tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
- tcg_temp_free(t1);
- tcg_temp_free(t0);
- tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* sraw & sraw. */
-static void gen_sraw(DisasContext *ctx)
-{
- gen_helper_sraw(cpu_gpr[rA(ctx->opcode)], cpu_env,
- cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* srawi & srawi. */
-static void gen_srawi(DisasContext *ctx)
-{
- int sh = SH(ctx->opcode);
- TCGv dst = cpu_gpr[rA(ctx->opcode)];
- TCGv src = cpu_gpr[rS(ctx->opcode)];
- if (sh == 0) {
- tcg_gen_ext32s_tl(dst, src);
- tcg_gen_movi_tl(cpu_ca, 0);
- } else {
- TCGv t0;
- tcg_gen_ext32s_tl(dst, src);
- tcg_gen_andi_tl(cpu_ca, dst, (1ULL << sh) - 1);
- t0 = tcg_temp_new();
- tcg_gen_sari_tl(t0, dst, TARGET_LONG_BITS - 1);
- tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
- tcg_temp_free(t0);
- tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
- tcg_gen_sari_tl(dst, dst, sh);
- }
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, dst);
- }
-}
-
-/* srw & srw. */
-static void gen_srw(DisasContext *ctx)
-{
- TCGv t0, t1;
-
- t0 = tcg_temp_new();
- /* AND rS with a mask that is 0 when rB >= 0x20 */
-#if defined(TARGET_PPC64)
- tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
- tcg_gen_sari_tl(t0, t0, 0x3f);
-#else
- tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
- tcg_gen_sari_tl(t0, t0, 0x1f);
-#endif
- tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
- tcg_gen_ext32u_tl(t0, t0);
- t1 = tcg_temp_new();
- tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
- tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
- tcg_temp_free(t1);
- tcg_temp_free(t0);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-#if defined(TARGET_PPC64)
-/* sld & sld. */
-static void gen_sld(DisasContext *ctx)
-{
- TCGv t0, t1;
-
- t0 = tcg_temp_new();
- /* AND rS with a mask that is 0 when rB >= 0x40 */
- tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
- tcg_gen_sari_tl(t0, t0, 0x3f);
- tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
- t1 = tcg_temp_new();
- tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
- tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
- tcg_temp_free(t1);
- tcg_temp_free(t0);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* srad & srad. */
-static void gen_srad(DisasContext *ctx)
-{
- gen_helper_srad(cpu_gpr[rA(ctx->opcode)], cpu_env,
- cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-/* sradi & sradi. */
-static inline void gen_sradi(DisasContext *ctx, int n)
-{
- int sh = SH(ctx->opcode) + (n << 5);
- TCGv dst = cpu_gpr[rA(ctx->opcode)];
- TCGv src = cpu_gpr[rS(ctx->opcode)];
- if (sh == 0) {
- tcg_gen_mov_tl(dst, src);
- tcg_gen_movi_tl(cpu_ca, 0);
- } else {
- TCGv t0;
- tcg_gen_andi_tl(cpu_ca, src, (1ULL << sh) - 1);
- t0 = tcg_temp_new();
- tcg_gen_sari_tl(t0, src, TARGET_LONG_BITS - 1);
- tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
- tcg_temp_free(t0);
- tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
- tcg_gen_sari_tl(dst, src, sh);
- }
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, dst);
- }
-}
-
-static void gen_sradi0(DisasContext *ctx)
-{
- gen_sradi(ctx, 0);
-}
-
-static void gen_sradi1(DisasContext *ctx)
-{
- gen_sradi(ctx, 1);
-}
-
-/* extswsli & extswsli. */
-static inline void gen_extswsli(DisasContext *ctx, int n)
-{
- int sh = SH(ctx->opcode) + (n << 5);
- TCGv dst = cpu_gpr[rA(ctx->opcode)];
- TCGv src = cpu_gpr[rS(ctx->opcode)];
-
- tcg_gen_ext32s_tl(dst, src);
- tcg_gen_shli_tl(dst, dst, sh);
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_Rc0(ctx, dst);
- }
-}
-
-static void gen_extswsli0(DisasContext *ctx)
-{
- gen_extswsli(ctx, 0);
-}
-
-static void gen_extswsli1(DisasContext *ctx)
-{
- gen_extswsli(ctx, 1);
-}
-
-/* srd & srd. */
-static void gen_srd(DisasContext *ctx)
-{
- TCGv t0, t1;
-
- t0 = tcg_temp_new();
- /* AND rS with a mask that is 0 when rB >= 0x40 */
- tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
- tcg_gen_sari_tl(t0, t0, 0x3f);
- tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
- t1 = tcg_temp_new();
- tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
- tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
- tcg_temp_free(t1);
- tcg_temp_free(t0);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-#endif
-
-/*** Addressing modes ***/
-/* Register indirect with immediate index : EA = (rA|0) + SIMM */
-static inline void gen_addr_imm_index(DisasContext *ctx, TCGv EA,
- target_long maskl)
-{
- target_long simm = SIMM(ctx->opcode);
-
- simm &= ~maskl;
- if (rA(ctx->opcode) == 0) {
- if (NARROW_MODE(ctx)) {
- simm = (uint32_t)simm;
- }
- tcg_gen_movi_tl(EA, simm);
- } else if (likely(simm != 0)) {
- tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
- if (NARROW_MODE(ctx)) {
- tcg_gen_ext32u_tl(EA, EA);
- }
- } else {
- if (NARROW_MODE(ctx)) {
- tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
- } else {
- tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
- }
- }
-}
-
-static inline void gen_addr_reg_index(DisasContext *ctx, TCGv EA)
-{
- if (rA(ctx->opcode) == 0) {
- if (NARROW_MODE(ctx)) {
- tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]);
- } else {
- tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
- }
- } else {
- tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
- if (NARROW_MODE(ctx)) {
- tcg_gen_ext32u_tl(EA, EA);
- }
- }
-}
-
-static inline void gen_addr_register(DisasContext *ctx, TCGv EA)
-{
- if (rA(ctx->opcode) == 0) {
- tcg_gen_movi_tl(EA, 0);
- } else if (NARROW_MODE(ctx)) {
- tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
- } else {
- tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
- }
-}
-
-static inline void gen_addr_add(DisasContext *ctx, TCGv ret, TCGv arg1,
- target_long val)
-{
- tcg_gen_addi_tl(ret, arg1, val);
- if (NARROW_MODE(ctx)) {
- tcg_gen_ext32u_tl(ret, ret);
- }
-}
-
-static inline void gen_check_align(DisasContext *ctx, TCGv EA, int mask)
-{
- TCGLabel *l1 = gen_new_label();
- TCGv t0 = tcg_temp_new();
- TCGv_i32 t1, t2;
- tcg_gen_andi_tl(t0, EA, mask);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
- t1 = tcg_const_i32(POWERPC_EXCP_ALIGN);
- t2 = tcg_const_i32(ctx->opcode & 0x03FF0000);
- gen_update_nip(ctx, ctx->nip - 4);
- gen_helper_raise_exception_err(cpu_env, t1, t2);
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
- gen_set_label(l1);
- tcg_temp_free(t0);
-}
-
-static inline void gen_align_no_le(DisasContext *ctx)
-{
- gen_exception_err(ctx, POWERPC_EXCP_ALIGN,
- (ctx->opcode & 0x03FF0000) | POWERPC_EXCP_ALIGN_LE);
-}
-
-/*** Integer load ***/
-#define DEF_MEMOP(op) ((op) | ctx->default_tcg_memop_mask)
-#define BSWAP_MEMOP(op) ((op) | (ctx->default_tcg_memop_mask ^ MO_BSWAP))
-
-#define GEN_QEMU_LOAD_TL(ldop, op) \
-static void glue(gen_qemu_, ldop)(DisasContext *ctx, \
- TCGv val, \
- TCGv addr) \
-{ \
- tcg_gen_qemu_ld_tl(val, addr, ctx->mem_idx, op); \
-}
-
-GEN_QEMU_LOAD_TL(ld8u, DEF_MEMOP(MO_UB))
-GEN_QEMU_LOAD_TL(ld16u, DEF_MEMOP(MO_UW))
-GEN_QEMU_LOAD_TL(ld16s, DEF_MEMOP(MO_SW))
-GEN_QEMU_LOAD_TL(ld32u, DEF_MEMOP(MO_UL))
-GEN_QEMU_LOAD_TL(ld32s, DEF_MEMOP(MO_SL))
-
-GEN_QEMU_LOAD_TL(ld16ur, BSWAP_MEMOP(MO_UW))
-GEN_QEMU_LOAD_TL(ld32ur, BSWAP_MEMOP(MO_UL))
-
-#define GEN_QEMU_LOAD_64(ldop, op) \
-static void glue(gen_qemu_, glue(ldop, _i64))(DisasContext *ctx, \
- TCGv_i64 val, \
- TCGv addr) \
-{ \
- tcg_gen_qemu_ld_i64(val, addr, ctx->mem_idx, op); \
-}
-
-GEN_QEMU_LOAD_64(ld8u, DEF_MEMOP(MO_UB))
-GEN_QEMU_LOAD_64(ld16u, DEF_MEMOP(MO_UW))
-GEN_QEMU_LOAD_64(ld32u, DEF_MEMOP(MO_UL))
-GEN_QEMU_LOAD_64(ld32s, DEF_MEMOP(MO_SL))
-GEN_QEMU_LOAD_64(ld64, DEF_MEMOP(MO_Q))
-
-#if defined(TARGET_PPC64)
-GEN_QEMU_LOAD_64(ld64ur, BSWAP_MEMOP(MO_Q))
-#endif
-
-#define GEN_QEMU_STORE_TL(stop, op) \
-static void glue(gen_qemu_, stop)(DisasContext *ctx, \
- TCGv val, \
- TCGv addr) \
-{ \
- tcg_gen_qemu_st_tl(val, addr, ctx->mem_idx, op); \
-}
-
-GEN_QEMU_STORE_TL(st8, DEF_MEMOP(MO_UB))
-GEN_QEMU_STORE_TL(st16, DEF_MEMOP(MO_UW))
-GEN_QEMU_STORE_TL(st32, DEF_MEMOP(MO_UL))
-
-GEN_QEMU_STORE_TL(st16r, BSWAP_MEMOP(MO_UW))
-GEN_QEMU_STORE_TL(st32r, BSWAP_MEMOP(MO_UL))
-
-#define GEN_QEMU_STORE_64(stop, op) \
-static void glue(gen_qemu_, glue(stop, _i64))(DisasContext *ctx, \
- TCGv_i64 val, \
- TCGv addr) \
-{ \
- tcg_gen_qemu_st_i64(val, addr, ctx->mem_idx, op); \
-}
-
-GEN_QEMU_STORE_64(st8, DEF_MEMOP(MO_UB))
-GEN_QEMU_STORE_64(st16, DEF_MEMOP(MO_UW))
-GEN_QEMU_STORE_64(st32, DEF_MEMOP(MO_UL))
-GEN_QEMU_STORE_64(st64, DEF_MEMOP(MO_Q))
-
-#if defined(TARGET_PPC64)
-GEN_QEMU_STORE_64(st64r, BSWAP_MEMOP(MO_Q))
-#endif
-
-#define GEN_LD(name, ldop, opc, type) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- gen_set_access_type(ctx, ACCESS_INT); \
- EA = tcg_temp_new(); \
- gen_addr_imm_index(ctx, EA, 0); \
- gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \
- tcg_temp_free(EA); \
-}
-
-#define GEN_LDU(name, ldop, opc, type) \
-static void glue(gen_, name##u)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- if (unlikely(rA(ctx->opcode) == 0 || \
- rA(ctx->opcode) == rD(ctx->opcode))) { \
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_INT); \
- EA = tcg_temp_new(); \
- if (type == PPC_64B) \
- gen_addr_imm_index(ctx, EA, 0x03); \
- else \
- gen_addr_imm_index(ctx, EA, 0); \
- gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
- tcg_temp_free(EA); \
-}
-
-#define GEN_LDUX(name, ldop, opc2, opc3, type) \
-static void glue(gen_, name##ux)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- if (unlikely(rA(ctx->opcode) == 0 || \
- rA(ctx->opcode) == rD(ctx->opcode))) { \
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_INT); \
- EA = tcg_temp_new(); \
- gen_addr_reg_index(ctx, EA); \
- gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
- tcg_temp_free(EA); \
-}
-
-#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk) \
-static void glue(gen_, name##x)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- chk; \
- gen_set_access_type(ctx, ACCESS_INT); \
- EA = tcg_temp_new(); \
- gen_addr_reg_index(ctx, EA); \
- gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA); \
- tcg_temp_free(EA); \
-}
-
-#define GEN_LDX(name, ldop, opc2, opc3, type) \
- GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_NONE)
-
-#define GEN_LDX_HVRM(name, ldop, opc2, opc3, type) \
- GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
-
-#define GEN_LDS(name, ldop, op, type) \
-GEN_LD(name, ldop, op | 0x20, type); \
-GEN_LDU(name, ldop, op | 0x21, type); \
-GEN_LDUX(name, ldop, 0x17, op | 0x01, type); \
-GEN_LDX(name, ldop, 0x17, op | 0x00, type)
-
-/* lbz lbzu lbzux lbzx */
-GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER);
-/* lha lhau lhaux lhax */
-GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER);
-/* lhz lhzu lhzux lhzx */
-GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER);
-/* lwz lwzu lwzux lwzx */
-GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER);
-#if defined(TARGET_PPC64)
-/* lwaux */
-GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B);
-/* lwax */
-GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B);
-/* ldux */
-GEN_LDUX(ld, ld64_i64, 0x15, 0x01, PPC_64B);
-/* ldx */
-GEN_LDX(ld, ld64_i64, 0x15, 0x00, PPC_64B);
-
-/* CI load/store variants */
-GEN_LDX_HVRM(ldcix, ld64_i64, 0x15, 0x1b, PPC_CILDST)
-GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x15, PPC_CILDST)
-GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
-GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
-
-static void gen_ld(DisasContext *ctx)
-{
- TCGv EA;
- if (Rc(ctx->opcode)) {
- if (unlikely(rA(ctx->opcode) == 0 ||
- rA(ctx->opcode) == rD(ctx->opcode))) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- return;
- }
- }
- gen_set_access_type(ctx, ACCESS_INT);
- EA = tcg_temp_new();
- gen_addr_imm_index(ctx, EA, 0x03);
- if (ctx->opcode & 0x02) {
- /* lwa (lwau is undefined) */
- gen_qemu_ld32s(ctx, cpu_gpr[rD(ctx->opcode)], EA);
- } else {
- /* ld - ldu */
- gen_qemu_ld64_i64(ctx, cpu_gpr[rD(ctx->opcode)], EA);
- }
- if (Rc(ctx->opcode))
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
- tcg_temp_free(EA);
-}
-
-/* lq */
-static void gen_lq(DisasContext *ctx)
-{
- int ra, rd;
- TCGv EA;
-
- /* lq is a legal user mode instruction starting in ISA 2.07 */
- bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
- bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
-
- if (!legal_in_user_mode && ctx->pr) {
- gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
-
- if (!le_is_supported && ctx->le_mode) {
- gen_align_no_le(ctx);
- return;
- }
- ra = rA(ctx->opcode);
- rd = rD(ctx->opcode);
- if (unlikely((rd & 1) || rd == ra)) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- return;
- }
-
- gen_set_access_type(ctx, ACCESS_INT);
- EA = tcg_temp_new();
- gen_addr_imm_index(ctx, EA, 0x0F);
-
- /* We only need to swap high and low halves. gen_qemu_ld64_i64 does
- necessary 64-bit byteswap already. */
- if (unlikely(ctx->le_mode)) {
- gen_qemu_ld64_i64(ctx, cpu_gpr[rd + 1], EA);
- gen_addr_add(ctx, EA, EA, 8);
- gen_qemu_ld64_i64(ctx, cpu_gpr[rd], EA);
- } else {
- gen_qemu_ld64_i64(ctx, cpu_gpr[rd], EA);
- gen_addr_add(ctx, EA, EA, 8);
- gen_qemu_ld64_i64(ctx, cpu_gpr[rd + 1], EA);
- }
- tcg_temp_free(EA);
-}
-#endif
-
-/*** Integer store ***/
-#define GEN_ST(name, stop, opc, type) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- gen_set_access_type(ctx, ACCESS_INT); \
- EA = tcg_temp_new(); \
- gen_addr_imm_index(ctx, EA, 0); \
- gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \
- tcg_temp_free(EA); \
-}
-
-#define GEN_STU(name, stop, opc, type) \
-static void glue(gen_, stop##u)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- if (unlikely(rA(ctx->opcode) == 0)) { \
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_INT); \
- EA = tcg_temp_new(); \
- if (type == PPC_64B) \
- gen_addr_imm_index(ctx, EA, 0x03); \
- else \
- gen_addr_imm_index(ctx, EA, 0); \
- gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
- tcg_temp_free(EA); \
-}
-
-#define GEN_STUX(name, stop, opc2, opc3, type) \
-static void glue(gen_, name##ux)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- if (unlikely(rA(ctx->opcode) == 0)) { \
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_INT); \
- EA = tcg_temp_new(); \
- gen_addr_reg_index(ctx, EA); \
- gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
- tcg_temp_free(EA); \
-}
-
-#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk) \
-static void glue(gen_, name##x)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- chk; \
- gen_set_access_type(ctx, ACCESS_INT); \
- EA = tcg_temp_new(); \
- gen_addr_reg_index(ctx, EA); \
- gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA); \
- tcg_temp_free(EA); \
-}
-#define GEN_STX(name, stop, opc2, opc3, type) \
- GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_NONE)
-
-#define GEN_STX_HVRM(name, stop, opc2, opc3, type) \
- GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
-
-#define GEN_STS(name, stop, op, type) \
-GEN_ST(name, stop, op | 0x20, type); \
-GEN_STU(name, stop, op | 0x21, type); \
-GEN_STUX(name, stop, 0x17, op | 0x01, type); \
-GEN_STX(name, stop, 0x17, op | 0x00, type)
-
-/* stb stbu stbux stbx */
-GEN_STS(stb, st8, 0x06, PPC_INTEGER);
-/* sth sthu sthux sthx */
-GEN_STS(sth, st16, 0x0C, PPC_INTEGER);
-/* stw stwu stwux stwx */
-GEN_STS(stw, st32, 0x04, PPC_INTEGER);
-#if defined(TARGET_PPC64)
-GEN_STUX(std, st64_i64, 0x15, 0x05, PPC_64B);
-GEN_STX(std, st64_i64, 0x15, 0x04, PPC_64B);
-GEN_STX_HVRM(stdcix, st64_i64, 0x15, 0x1f, PPC_CILDST)
-GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
-GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
-GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
-
-static void gen_std(DisasContext *ctx)
-{
- int rs;
- TCGv EA;
-
- rs = rS(ctx->opcode);
- if ((ctx->opcode & 0x3) == 0x2) { /* stq */
- bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
- bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
-
- if (!(ctx->insns_flags & PPC_64BX)) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- }
-
- if (!legal_in_user_mode && ctx->pr) {
- gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
- return;
- }
-
- if (!le_is_supported && ctx->le_mode) {
- gen_align_no_le(ctx);
- return;
- }
-
- if (unlikely(rs & 1)) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- return;
- }
- gen_set_access_type(ctx, ACCESS_INT);
- EA = tcg_temp_new();
- gen_addr_imm_index(ctx, EA, 0x03);
-
- /* We only need to swap high and low halves. gen_qemu_st64_i64 does
- necessary 64-bit byteswap already. */
- if (unlikely(ctx->le_mode)) {
- gen_qemu_st64_i64(ctx, cpu_gpr[rs + 1], EA);
- gen_addr_add(ctx, EA, EA, 8);
- gen_qemu_st64_i64(ctx, cpu_gpr[rs], EA);
- } else {
- gen_qemu_st64_i64(ctx, cpu_gpr[rs], EA);
- gen_addr_add(ctx, EA, EA, 8);
- gen_qemu_st64_i64(ctx, cpu_gpr[rs + 1], EA);
- }
- tcg_temp_free(EA);
- } else {
- /* std / stdu*/
- if (Rc(ctx->opcode)) {
- if (unlikely(rA(ctx->opcode) == 0)) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- return;
- }
- }
- gen_set_access_type(ctx, ACCESS_INT);
- EA = tcg_temp_new();
- gen_addr_imm_index(ctx, EA, 0x03);
- gen_qemu_st64_i64(ctx, cpu_gpr[rs], EA);
- if (Rc(ctx->opcode))
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
- tcg_temp_free(EA);
- }
-}
-#endif
-/*** Integer load and store with byte reverse ***/
-
-/* lhbrx */
-GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
-
-/* lwbrx */
-GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
-
-#if defined(TARGET_PPC64)
-/* ldbrx */
-GEN_LDX_E(ldbr, ld64ur_i64, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE);
-/* stdbrx */
-GEN_STX_E(stdbr, st64r_i64, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE);
-#endif /* TARGET_PPC64 */
-
-/* sthbrx */
-GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
-/* stwbrx */
-GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
-
-/*** Integer load and store multiple ***/
-
-/* lmw */
-static void gen_lmw(DisasContext *ctx)
-{
- TCGv t0;
- TCGv_i32 t1;
-
- if (ctx->le_mode) {
- gen_align_no_le(ctx);
- return;
- }
- gen_set_access_type(ctx, ACCESS_INT);
- t0 = tcg_temp_new();
- t1 = tcg_const_i32(rD(ctx->opcode));
- gen_addr_imm_index(ctx, t0, 0);
- gen_helper_lmw(cpu_env, t0, t1);
- tcg_temp_free(t0);
- tcg_temp_free_i32(t1);
-}
-
-/* stmw */
-static void gen_stmw(DisasContext *ctx)
-{
- TCGv t0;
- TCGv_i32 t1;
-
- if (ctx->le_mode) {
- gen_align_no_le(ctx);
- return;
- }
- gen_set_access_type(ctx, ACCESS_INT);
- t0 = tcg_temp_new();
- t1 = tcg_const_i32(rS(ctx->opcode));
- gen_addr_imm_index(ctx, t0, 0);
- gen_helper_stmw(cpu_env, t0, t1);
- tcg_temp_free(t0);
- tcg_temp_free_i32(t1);
-}
-
-/*** Integer load and store strings ***/
-
-/* lswi */
-/* PowerPC32 specification says we must generate an exception if
- * rA is in the range of registers to be loaded.
- * In an other hand, IBM says this is valid, but rA won't be loaded.
- * For now, I'll follow the spec...
- */
-static void gen_lswi(DisasContext *ctx)
-{
- TCGv t0;
- TCGv_i32 t1, t2;
- int nb = NB(ctx->opcode);
- int start = rD(ctx->opcode);
- int ra = rA(ctx->opcode);
- int nr;
-
- if (ctx->le_mode) {
- gen_align_no_le(ctx);
- return;
- }
- if (nb == 0)
- nb = 32;
- nr = (nb + 3) / 4;
- if (unlikely(lsw_reg_in_range(start, nr, ra))) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
- return;
- }
- gen_set_access_type(ctx, ACCESS_INT);
- t0 = tcg_temp_new();
- gen_addr_register(ctx, t0);
- t1 = tcg_const_i32(nb);
- t2 = tcg_const_i32(start);
- gen_helper_lsw(cpu_env, t0, t1, t2);
- tcg_temp_free(t0);
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-}
-
-/* lswx */
-static void gen_lswx(DisasContext *ctx)
-{
- TCGv t0;
- TCGv_i32 t1, t2, t3;
-
- if (ctx->le_mode) {
- gen_align_no_le(ctx);
- return;
- }
- gen_set_access_type(ctx, ACCESS_INT);
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- t1 = tcg_const_i32(rD(ctx->opcode));
- t2 = tcg_const_i32(rA(ctx->opcode));
- t3 = tcg_const_i32(rB(ctx->opcode));
- gen_helper_lswx(cpu_env, t0, t1, t2, t3);
- tcg_temp_free(t0);
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
- tcg_temp_free_i32(t3);
-}
-
-/* stswi */
-static void gen_stswi(DisasContext *ctx)
-{
- TCGv t0;
- TCGv_i32 t1, t2;
- int nb = NB(ctx->opcode);
-
- if (ctx->le_mode) {
- gen_align_no_le(ctx);
- return;
- }
- gen_set_access_type(ctx, ACCESS_INT);
- t0 = tcg_temp_new();
- gen_addr_register(ctx, t0);
- if (nb == 0)
- nb = 32;
- t1 = tcg_const_i32(nb);
- t2 = tcg_const_i32(rS(ctx->opcode));
- gen_helper_stsw(cpu_env, t0, t1, t2);
- tcg_temp_free(t0);
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-}
-
-/* stswx */
-static void gen_stswx(DisasContext *ctx)
-{
- TCGv t0;
- TCGv_i32 t1, t2;
-
- if (ctx->le_mode) {
- gen_align_no_le(ctx);
- return;
- }
- gen_set_access_type(ctx, ACCESS_INT);
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- t1 = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(t1, cpu_xer);
- tcg_gen_andi_i32(t1, t1, 0x7F);
- t2 = tcg_const_i32(rS(ctx->opcode));
- gen_helper_stsw(cpu_env, t0, t1, t2);
- tcg_temp_free(t0);
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
-}
-
-/*** Memory synchronisation ***/
-/* eieio */
-static void gen_eieio(DisasContext *ctx)
-{
-}
-
-#if !defined(CONFIG_USER_ONLY)
-static inline void gen_check_tlb_flush(DisasContext *ctx, bool global)
-{
- TCGv_i32 t;
- TCGLabel *l;
-
- if (!ctx->lazy_tlb_flush) {
- return;
- }
- l = gen_new_label();
- t = tcg_temp_new_i32();
- tcg_gen_ld_i32(t, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
- tcg_gen_brcondi_i32(TCG_COND_EQ, t, 0, l);
- if (global) {
- gen_helper_check_tlb_flush_global(cpu_env);
- } else {
- gen_helper_check_tlb_flush_local(cpu_env);
- }
- gen_set_label(l);
- tcg_temp_free_i32(t);
-}
-#else
-static inline void gen_check_tlb_flush(DisasContext *ctx, bool global) { }
-#endif
-
-/* isync */
-static void gen_isync(DisasContext *ctx)
-{
- /*
- * We need to check for a pending TLB flush. This can only happen in
- * kernel mode however so check MSR_PR
- */
- if (!ctx->pr) {
- gen_check_tlb_flush(ctx, false);
- }
- gen_stop_exception(ctx);
-}
-
-#define MEMOP_GET_SIZE(x) (1 << ((x) & MO_SIZE))
-
-#define LARX(name, memop) \
-static void gen_##name(DisasContext *ctx) \
-{ \
- TCGv t0; \
- TCGv gpr = cpu_gpr[rD(ctx->opcode)]; \
- int len = MEMOP_GET_SIZE(memop); \
- gen_set_access_type(ctx, ACCESS_RES); \
- t0 = tcg_temp_local_new(); \
- gen_addr_reg_index(ctx, t0); \
- if ((len) > 1) { \
- gen_check_align(ctx, t0, (len)-1); \
- } \
- tcg_gen_qemu_ld_tl(gpr, t0, ctx->mem_idx, memop); \
- tcg_gen_mov_tl(cpu_reserve, t0); \
- tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUPPCState, reserve_val)); \
- tcg_temp_free(t0); \
-}
-
-/* lwarx */
-LARX(lbarx, DEF_MEMOP(MO_UB))
-LARX(lharx, DEF_MEMOP(MO_UW))
-LARX(lwarx, DEF_MEMOP(MO_UL))
-
-#if defined(CONFIG_USER_ONLY)
-static void gen_conditional_store(DisasContext *ctx, TCGv EA,
- int reg, int memop)
-{
- TCGv t0 = tcg_temp_new();
-
- tcg_gen_st_tl(EA, cpu_env, offsetof(CPUPPCState, reserve_ea));
- tcg_gen_movi_tl(t0, (MEMOP_GET_SIZE(memop) << 5) | reg);
- tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, reserve_info));
- tcg_temp_free(t0);
- gen_exception_err(ctx, POWERPC_EXCP_STCX, 0);
-}
-#else
-static void gen_conditional_store(DisasContext *ctx, TCGv EA,
- int reg, int memop)
-{
- TCGLabel *l1;
-
- tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
- l1 = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, l1);
- tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
- tcg_gen_qemu_st_tl(cpu_gpr[reg], EA, ctx->mem_idx, memop);
- gen_set_label(l1);
- tcg_gen_movi_tl(cpu_reserve, -1);
-}
-#endif
-
-#define STCX(name, memop) \
-static void gen_##name(DisasContext *ctx) \
-{ \
- TCGv t0; \
- int len = MEMOP_GET_SIZE(memop); \
- gen_set_access_type(ctx, ACCESS_RES); \
- t0 = tcg_temp_local_new(); \
- gen_addr_reg_index(ctx, t0); \
- if (len > 1) { \
- gen_check_align(ctx, t0, (len) - 1); \
- } \
- gen_conditional_store(ctx, t0, rS(ctx->opcode), memop); \
- tcg_temp_free(t0); \
-}
-
-STCX(stbcx_, DEF_MEMOP(MO_UB))
-STCX(sthcx_, DEF_MEMOP(MO_UW))
-STCX(stwcx_, DEF_MEMOP(MO_UL))
-
-#if defined(TARGET_PPC64)
-/* ldarx */
-LARX(ldarx, DEF_MEMOP(MO_Q))
-/* stdcx. */
-STCX(stdcx_, DEF_MEMOP(MO_Q))
-
-/* lqarx */
-static void gen_lqarx(DisasContext *ctx)
-{
- TCGv EA;
- int rd = rD(ctx->opcode);
- TCGv gpr1, gpr2;
-
- if (unlikely((rd & 1) || (rd == rA(ctx->opcode)) ||
- (rd == rB(ctx->opcode)))) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- return;
- }
-
- gen_set_access_type(ctx, ACCESS_RES);
- EA = tcg_temp_local_new();
- gen_addr_reg_index(ctx, EA);
- gen_check_align(ctx, EA, 15);
- if (unlikely(ctx->le_mode)) {
- gpr1 = cpu_gpr[rd+1];
- gpr2 = cpu_gpr[rd];
- } else {
- gpr1 = cpu_gpr[rd];
- gpr2 = cpu_gpr[rd+1];
- }
- tcg_gen_qemu_ld_i64(gpr1, EA, ctx->mem_idx, DEF_MEMOP(MO_Q));
- tcg_gen_mov_tl(cpu_reserve, EA);
- gen_addr_add(ctx, EA, EA, 8);
- tcg_gen_qemu_ld_i64(gpr2, EA, ctx->mem_idx, DEF_MEMOP(MO_Q));
-
- tcg_gen_st_tl(gpr1, cpu_env, offsetof(CPUPPCState, reserve_val));
- tcg_gen_st_tl(gpr2, cpu_env, offsetof(CPUPPCState, reserve_val2));
- tcg_temp_free(EA);
-}
-
-/* stqcx. */
-static void gen_stqcx_(DisasContext *ctx)
-{
- TCGv EA;
- int reg = rS(ctx->opcode);
- int len = 16;
-#if !defined(CONFIG_USER_ONLY)
- TCGLabel *l1;
- TCGv gpr1, gpr2;
-#endif
-
- if (unlikely((rD(ctx->opcode) & 1))) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- return;
- }
- gen_set_access_type(ctx, ACCESS_RES);
- EA = tcg_temp_local_new();
- gen_addr_reg_index(ctx, EA);
- if (len > 1) {
- gen_check_align(ctx, EA, (len) - 1);
- }
-
-#if defined(CONFIG_USER_ONLY)
- gen_conditional_store(ctx, EA, reg, 16);
-#else
- tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
- l1 = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, l1);
- tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
-
- if (unlikely(ctx->le_mode)) {
- gpr1 = cpu_gpr[reg + 1];
- gpr2 = cpu_gpr[reg];
- } else {
- gpr1 = cpu_gpr[reg];
- gpr2 = cpu_gpr[reg + 1];
- }
- tcg_gen_qemu_st_tl(gpr1, EA, ctx->mem_idx, DEF_MEMOP(MO_Q));
- gen_addr_add(ctx, EA, EA, 8);
- tcg_gen_qemu_st_tl(gpr2, EA, ctx->mem_idx, DEF_MEMOP(MO_Q));
-
- gen_set_label(l1);
- tcg_gen_movi_tl(cpu_reserve, -1);
-#endif
- tcg_temp_free(EA);
-}
-
-#endif /* defined(TARGET_PPC64) */
-
-/* sync */
-static void gen_sync(DisasContext *ctx)
-{
- uint32_t l = (ctx->opcode >> 21) & 3;
-
- /*
- * We may need to check for a pending TLB flush.
- *
- * We do this on ptesync (l == 2) on ppc64 and any sync pn ppc32.
- *
- * Additionally, this can only happen in kernel mode however so
- * check MSR_PR as well.
- */
- if (((l == 2) || !(ctx->insns_flags & PPC_64B)) && !ctx->pr) {
- gen_check_tlb_flush(ctx, true);
- }
-}
-
-/* wait */
-static void gen_wait(DisasContext *ctx)
-{
- TCGv_i32 t0 = tcg_const_i32(1);
- tcg_gen_st_i32(t0, cpu_env,
- -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
- tcg_temp_free_i32(t0);
- /* Stop translation, as the CPU is supposed to sleep from now */
- gen_exception_nip(ctx, EXCP_HLT, ctx->nip);
-}
-
-#if defined(TARGET_PPC64)
-static void gen_doze(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv_i32 t;
-
- CHK_HV;
- t = tcg_const_i32(PPC_PM_DOZE);
- gen_helper_pminsn(cpu_env, t);
- tcg_temp_free_i32(t);
- gen_stop_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_nap(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv_i32 t;
-
- CHK_HV;
- t = tcg_const_i32(PPC_PM_NAP);
- gen_helper_pminsn(cpu_env, t);
- tcg_temp_free_i32(t);
- gen_stop_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_sleep(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv_i32 t;
-
- CHK_HV;
- t = tcg_const_i32(PPC_PM_SLEEP);
- gen_helper_pminsn(cpu_env, t);
- tcg_temp_free_i32(t);
- gen_stop_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_rvwinkle(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv_i32 t;
-
- CHK_HV;
- t = tcg_const_i32(PPC_PM_RVWINKLE);
- gen_helper_pminsn(cpu_env, t);
- tcg_temp_free_i32(t);
- gen_stop_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-#endif /* #if defined(TARGET_PPC64) */
-
-static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip)
-{
-#if defined(TARGET_PPC64)
- if (ctx->has_cfar)
- tcg_gen_movi_tl(cpu_cfar, nip);
-#endif
-}
-
-static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
-{
- if (unlikely(ctx->singlestep_enabled)) {
- return false;
- }
-
-#ifndef CONFIG_USER_ONLY
- return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
-#else
- return true;
-#endif
-}
-
-/*** Branch ***/
-static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
-{
- if (NARROW_MODE(ctx)) {
- dest = (uint32_t) dest;
- }
- if (use_goto_tb(ctx, dest)) {
- tcg_gen_goto_tb(n);
- tcg_gen_movi_tl(cpu_nip, dest & ~3);
- tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
- } else {
- tcg_gen_movi_tl(cpu_nip, dest & ~3);
- if (unlikely(ctx->singlestep_enabled)) {
- if ((ctx->singlestep_enabled &
- (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
- (ctx->exception == POWERPC_EXCP_BRANCH ||
- ctx->exception == POWERPC_EXCP_TRACE)) {
- gen_exception_nip(ctx, POWERPC_EXCP_TRACE, dest);
- }
- if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
- gen_debug_exception(ctx);
- }
- }
- tcg_gen_exit_tb(0);
- }
-}
-
-static inline void gen_setlr(DisasContext *ctx, target_ulong nip)
-{
- if (NARROW_MODE(ctx)) {
- nip = (uint32_t)nip;
- }
- tcg_gen_movi_tl(cpu_lr, nip);
-}
-
-/* b ba bl bla */
-static void gen_b(DisasContext *ctx)
-{
- target_ulong li, target;
-
- ctx->exception = POWERPC_EXCP_BRANCH;
- /* sign extend LI */
- li = LI(ctx->opcode);
- li = (li ^ 0x02000000) - 0x02000000;
- if (likely(AA(ctx->opcode) == 0)) {
- target = ctx->nip + li - 4;
- } else {
- target = li;
- }
- if (LK(ctx->opcode)) {
- gen_setlr(ctx, ctx->nip);
- }
- gen_update_cfar(ctx, ctx->nip - 4);
- gen_goto_tb(ctx, 0, target);
-}
-
-#define BCOND_IM 0
-#define BCOND_LR 1
-#define BCOND_CTR 2
-#define BCOND_TAR 3
-
-static inline void gen_bcond(DisasContext *ctx, int type)
-{
- uint32_t bo = BO(ctx->opcode);
- TCGLabel *l1;
- TCGv target;
-
- ctx->exception = POWERPC_EXCP_BRANCH;
- if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) {
- target = tcg_temp_local_new();
- if (type == BCOND_CTR)
- tcg_gen_mov_tl(target, cpu_ctr);
- else if (type == BCOND_TAR)
- gen_load_spr(target, SPR_TAR);
- else
- tcg_gen_mov_tl(target, cpu_lr);
- } else {
- TCGV_UNUSED(target);
- }
- if (LK(ctx->opcode))
- gen_setlr(ctx, ctx->nip);
- l1 = gen_new_label();
- if ((bo & 0x4) == 0) {
- /* Decrement and test CTR */
- TCGv temp = tcg_temp_new();
- if (unlikely(type == BCOND_CTR)) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- return;
- }
- tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
- if (NARROW_MODE(ctx)) {
- tcg_gen_ext32u_tl(temp, cpu_ctr);
- } else {
- tcg_gen_mov_tl(temp, cpu_ctr);
- }
- if (bo & 0x2) {
- tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
- } else {
- tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
- }
- tcg_temp_free(temp);
- }
- if ((bo & 0x10) == 0) {
- /* Test CR */
- uint32_t bi = BI(ctx->opcode);
- uint32_t mask = 0x08 >> (bi & 0x03);
- TCGv_i32 temp = tcg_temp_new_i32();
-
- if (bo & 0x8) {
- tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
- tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1);
- } else {
- tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
- tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);
- }
- tcg_temp_free_i32(temp);
- }
- gen_update_cfar(ctx, ctx->nip - 4);
- if (type == BCOND_IM) {
- target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
- if (likely(AA(ctx->opcode) == 0)) {
- gen_goto_tb(ctx, 0, ctx->nip + li - 4);
- } else {
- gen_goto_tb(ctx, 0, li);
- }
- if ((bo & 0x14) != 0x14) {
- gen_set_label(l1);
- gen_goto_tb(ctx, 1, ctx->nip);
- }
- } else {
- if (NARROW_MODE(ctx)) {
- tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3);
- } else {
- tcg_gen_andi_tl(cpu_nip, target, ~3);
- }
- tcg_gen_exit_tb(0);
- if ((bo & 0x14) != 0x14) {
- gen_set_label(l1);
- gen_update_nip(ctx, ctx->nip);
- tcg_gen_exit_tb(0);
- }
- }
- if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) {
- tcg_temp_free(target);
- }
-}
-
-static void gen_bc(DisasContext *ctx)
-{
- gen_bcond(ctx, BCOND_IM);
-}
-
-static void gen_bcctr(DisasContext *ctx)
-{
- gen_bcond(ctx, BCOND_CTR);
-}
-
-static void gen_bclr(DisasContext *ctx)
-{
- gen_bcond(ctx, BCOND_LR);
-}
-
-static void gen_bctar(DisasContext *ctx)
-{
- gen_bcond(ctx, BCOND_TAR);
-}
-
-/*** Condition register logical ***/
-#define GEN_CRLOGIC(name, tcg_op, opc) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- uint8_t bitmask; \
- int sh; \
- TCGv_i32 t0, t1; \
- sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03); \
- t0 = tcg_temp_new_i32(); \
- if (sh > 0) \
- tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh); \
- else if (sh < 0) \
- tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh); \
- else \
- tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]); \
- t1 = tcg_temp_new_i32(); \
- sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03); \
- if (sh > 0) \
- tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh); \
- else if (sh < 0) \
- tcg_gen_shli_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], -sh); \
- else \
- tcg_gen_mov_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2]); \
- tcg_op(t0, t0, t1); \
- bitmask = 0x08 >> (crbD(ctx->opcode) & 0x03); \
- tcg_gen_andi_i32(t0, t0, bitmask); \
- tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask); \
- tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1); \
- tcg_temp_free_i32(t0); \
- tcg_temp_free_i32(t1); \
-}
-
-/* crand */
-GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08);
-/* crandc */
-GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04);
-/* creqv */
-GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09);
-/* crnand */
-GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07);
-/* crnor */
-GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01);
-/* cror */
-GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E);
-/* crorc */
-GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D);
-/* crxor */
-GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06);
-
-/* mcrf */
-static void gen_mcrf(DisasContext *ctx)
-{
- tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]);
-}
-
-/*** System linkage ***/
-
-/* rfi (supervisor only) */
-static void gen_rfi(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- /* This instruction doesn't exist anymore on 64-bit server
- * processors compliant with arch 2.x
- */
- if (ctx->insns_flags & PPC_SEGMENT_64B) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- return;
- }
- /* Restore CPU state */
- CHK_SV;
- gen_update_cfar(ctx, ctx->nip - 4);
- gen_helper_rfi(cpu_env);
- gen_sync_exception(ctx);
-#endif
-}
-
-#if defined(TARGET_PPC64)
-static void gen_rfid(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- /* Restore CPU state */
- CHK_SV;
- gen_update_cfar(ctx, ctx->nip - 4);
- gen_helper_rfid(cpu_env);
- gen_sync_exception(ctx);
-#endif
-}
-
-static void gen_hrfid(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- /* Restore CPU state */
- CHK_HV;
- gen_helper_hrfid(cpu_env);
- gen_sync_exception(ctx);
-#endif
-}
-#endif
-
-/* sc */
-#if defined(CONFIG_USER_ONLY)
-#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
-#else
-#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
-#endif
-static void gen_sc(DisasContext *ctx)
-{
- uint32_t lev;
-
- lev = (ctx->opcode >> 5) & 0x7F;
- gen_exception_err(ctx, POWERPC_SYSCALL, lev);
-}
-
-/*** Trap ***/
-
-/* Check for unconditional traps (always or never) */
-static bool check_unconditional_trap(DisasContext *ctx)
-{
- /* Trap never */
- if (TO(ctx->opcode) == 0) {
- return true;
- }
- /* Trap always */
- if (TO(ctx->opcode) == 31) {
- gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
- return true;
- }
- return false;
-}
-
-/* tw */
-static void gen_tw(DisasContext *ctx)
-{
- TCGv_i32 t0;
-
- if (check_unconditional_trap(ctx)) {
- return;
- }
- t0 = tcg_const_i32(TO(ctx->opcode));
- gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
- t0);
- tcg_temp_free_i32(t0);
-}
-
-/* twi */
-static void gen_twi(DisasContext *ctx)
-{
- TCGv t0;
- TCGv_i32 t1;
-
- if (check_unconditional_trap(ctx)) {
- return;
- }
- t0 = tcg_const_tl(SIMM(ctx->opcode));
- t1 = tcg_const_i32(TO(ctx->opcode));
- gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
- tcg_temp_free(t0);
- tcg_temp_free_i32(t1);
-}
-
-#if defined(TARGET_PPC64)
-/* td */
-static void gen_td(DisasContext *ctx)
-{
- TCGv_i32 t0;
-
- if (check_unconditional_trap(ctx)) {
- return;
- }
- t0 = tcg_const_i32(TO(ctx->opcode));
- gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
- t0);
- tcg_temp_free_i32(t0);
-}
-
-/* tdi */
-static void gen_tdi(DisasContext *ctx)
-{
- TCGv t0;
- TCGv_i32 t1;
-
- if (check_unconditional_trap(ctx)) {
- return;
- }
- t0 = tcg_const_tl(SIMM(ctx->opcode));
- t1 = tcg_const_i32(TO(ctx->opcode));
- gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
- tcg_temp_free(t0);
- tcg_temp_free_i32(t1);
-}
-#endif
-
-/*** Processor control ***/
-
-static void gen_read_xer(TCGv dst)
-{
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- TCGv t2 = tcg_temp_new();
- tcg_gen_mov_tl(dst, cpu_xer);
- tcg_gen_shli_tl(t0, cpu_so, XER_SO);
- tcg_gen_shli_tl(t1, cpu_ov, XER_OV);
- tcg_gen_shli_tl(t2, cpu_ca, XER_CA);
- tcg_gen_or_tl(t0, t0, t1);
- tcg_gen_or_tl(dst, dst, t2);
- tcg_gen_or_tl(dst, dst, t0);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- tcg_temp_free(t2);
-}
-
-static void gen_write_xer(TCGv src)
-{
- tcg_gen_andi_tl(cpu_xer, src,
- ~((1u << XER_SO) | (1u << XER_OV) | (1u << XER_CA)));
- tcg_gen_shri_tl(cpu_so, src, XER_SO);
- tcg_gen_shri_tl(cpu_ov, src, XER_OV);
- tcg_gen_shri_tl(cpu_ca, src, XER_CA);
- tcg_gen_andi_tl(cpu_so, cpu_so, 1);
- tcg_gen_andi_tl(cpu_ov, cpu_ov, 1);
- tcg_gen_andi_tl(cpu_ca, cpu_ca, 1);
-}
-
-/* mcrxr */
-static void gen_mcrxr(DisasContext *ctx)
-{
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv_i32 t1 = tcg_temp_new_i32();
- TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)];
-
- tcg_gen_trunc_tl_i32(t0, cpu_so);
- tcg_gen_trunc_tl_i32(t1, cpu_ov);
- tcg_gen_trunc_tl_i32(dst, cpu_ca);
- tcg_gen_shli_i32(t0, t0, 3);
- tcg_gen_shli_i32(t1, t1, 2);
- tcg_gen_shli_i32(dst, dst, 1);
- tcg_gen_or_i32(dst, dst, t0);
- tcg_gen_or_i32(dst, dst, t1);
- tcg_temp_free_i32(t0);
- tcg_temp_free_i32(t1);
-
- tcg_gen_movi_tl(cpu_so, 0);
- tcg_gen_movi_tl(cpu_ov, 0);
- tcg_gen_movi_tl(cpu_ca, 0);
-}
-
-/* mfcr mfocrf */
-static void gen_mfcr(DisasContext *ctx)
-{
- uint32_t crm, crn;
-
- if (likely(ctx->opcode & 0x00100000)) {
- crm = CRM(ctx->opcode);
- if (likely(crm && ((crm & (crm - 1)) == 0))) {
- crn = ctz32 (crm);
- tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
- tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)],
- cpu_gpr[rD(ctx->opcode)], crn * 4);
- }
- } else {
- TCGv_i32 t0 = tcg_temp_new_i32();
- tcg_gen_mov_i32(t0, cpu_crf[0]);
- tcg_gen_shli_i32(t0, t0, 4);
- tcg_gen_or_i32(t0, t0, cpu_crf[1]);
- tcg_gen_shli_i32(t0, t0, 4);
- tcg_gen_or_i32(t0, t0, cpu_crf[2]);
- tcg_gen_shli_i32(t0, t0, 4);
- tcg_gen_or_i32(t0, t0, cpu_crf[3]);
- tcg_gen_shli_i32(t0, t0, 4);
- tcg_gen_or_i32(t0, t0, cpu_crf[4]);
- tcg_gen_shli_i32(t0, t0, 4);
- tcg_gen_or_i32(t0, t0, cpu_crf[5]);
- tcg_gen_shli_i32(t0, t0, 4);
- tcg_gen_or_i32(t0, t0, cpu_crf[6]);
- tcg_gen_shli_i32(t0, t0, 4);
- tcg_gen_or_i32(t0, t0, cpu_crf[7]);
- tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
- tcg_temp_free_i32(t0);
- }
-}
-
-/* mfmsr */
-static void gen_mfmsr(DisasContext *ctx)
-{
- CHK_SV;
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
-}
-
-static void spr_noaccess(DisasContext *ctx, int gprn, int sprn)
-{
-#if 0
- sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
- printf("ERROR: try to access SPR %d !\n", sprn);
-#endif
-}
-#define SPR_NOACCESS (&spr_noaccess)
-
-/* mfspr */
-static inline void gen_op_mfspr(DisasContext *ctx)
-{
- void (*read_cb)(DisasContext *ctx, int gprn, int sprn);
- uint32_t sprn = SPR(ctx->opcode);
-
-#if defined(CONFIG_USER_ONLY)
- read_cb = ctx->spr_cb[sprn].uea_read;
-#else
- if (ctx->pr) {
- read_cb = ctx->spr_cb[sprn].uea_read;
- } else if (ctx->hv) {
- read_cb = ctx->spr_cb[sprn].hea_read;
- } else {
- read_cb = ctx->spr_cb[sprn].oea_read;
- }
-#endif
- if (likely(read_cb != NULL)) {
- if (likely(read_cb != SPR_NOACCESS)) {
- (*read_cb)(ctx, rD(ctx->opcode), sprn);
- } else {
- /* Privilege exception */
- /* This is a hack to avoid warnings when running Linux:
- * this OS breaks the PowerPC virtualisation model,
- * allowing userland application to read the PVR
- */
- if (sprn != SPR_PVR) {
- fprintf(stderr, "Trying to read privileged spr %d (0x%03x) at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
- if (qemu_log_separate()) {
- qemu_log("Trying to read privileged spr %d (0x%03x) at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
- }
- }
- gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
- }
- } else {
- /* ISA 2.07 defines these as no-ops */
- if ((ctx->insns_flags2 & PPC2_ISA207S) &&
- (sprn >= 808 && sprn <= 811)) {
- /* This is a nop */
- return;
- }
- /* Not defined */
- fprintf(stderr, "Trying to read invalid spr %d (0x%03x) at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
- if (qemu_log_separate()) {
- qemu_log("Trying to read invalid spr %d (0x%03x) at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
- }
-
- /* The behaviour depends on MSR:PR and SPR# bit 0x10,
- * it can generate a priv, a hv emu or a no-op
- */
- if (sprn & 0x10) {
- if (ctx->pr) {
- gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
- }
- } else {
- if (ctx->pr || sprn == 0 || sprn == 4 || sprn == 5 || sprn == 6) {
- gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
- }
- }
- }
-}
-
-static void gen_mfspr(DisasContext *ctx)
-{
- gen_op_mfspr(ctx);
-}
-
-/* mftb */
-static void gen_mftb(DisasContext *ctx)
-{
- gen_op_mfspr(ctx);
-}
-
-/* mtcrf mtocrf*/
-static void gen_mtcrf(DisasContext *ctx)
-{
- uint32_t crm, crn;
-
- crm = CRM(ctx->opcode);
- if (likely((ctx->opcode & 0x00100000))) {
- if (crm && ((crm & (crm - 1)) == 0)) {
- TCGv_i32 temp = tcg_temp_new_i32();
- crn = ctz32 (crm);
- tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
- tcg_gen_shri_i32(temp, temp, crn * 4);
- tcg_gen_andi_i32(cpu_crf[7 - crn], temp, 0xf);
- tcg_temp_free_i32(temp);
- }
- } else {
- TCGv_i32 temp = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
- for (crn = 0 ; crn < 8 ; crn++) {
- if (crm & (1 << crn)) {
- tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
- tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
- }
- }
- tcg_temp_free_i32(temp);
- }
-}
-
-/* mtmsr */
-#if defined(TARGET_PPC64)
-static void gen_mtmsrd(DisasContext *ctx)
-{
- CHK_SV;
-
-#if !defined(CONFIG_USER_ONLY)
- if (ctx->opcode & 0x00010000) {
- /* Special form that does not need any synchronisation */
- TCGv t0 = tcg_temp_new();
- tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
- tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));
- tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
- tcg_temp_free(t0);
- } else {
- /* XXX: we need to update nip before the store
- * if we enter power saving mode, we will exit the loop
- * directly from ppc_store_msr
- */
- gen_update_nip(ctx, ctx->nip);
- gen_helper_store_msr(cpu_env, cpu_gpr[rS(ctx->opcode)]);
- /* Must stop the translation as machine state (may have) changed */
- /* Note that mtmsr is not always defined as context-synchronizing */
- gen_stop_exception(ctx);
- }
-#endif /* !defined(CONFIG_USER_ONLY) */
-}
-#endif /* defined(TARGET_PPC64) */
-
-static void gen_mtmsr(DisasContext *ctx)
-{
- CHK_SV;
-
-#if !defined(CONFIG_USER_ONLY)
- if (ctx->opcode & 0x00010000) {
- /* Special form that does not need any synchronisation */
- TCGv t0 = tcg_temp_new();
- tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
- tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));
- tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
- tcg_temp_free(t0);
- } else {
- TCGv msr = tcg_temp_new();
-
- /* XXX: we need to update nip before the store
- * if we enter power saving mode, we will exit the loop
- * directly from ppc_store_msr
- */
- gen_update_nip(ctx, ctx->nip);
-#if defined(TARGET_PPC64)
- tcg_gen_deposit_tl(msr, cpu_msr, cpu_gpr[rS(ctx->opcode)], 0, 32);
-#else
- tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]);
-#endif
- gen_helper_store_msr(cpu_env, msr);
- tcg_temp_free(msr);
- /* Must stop the translation as machine state (may have) changed */
- /* Note that mtmsr is not always defined as context-synchronizing */
- gen_stop_exception(ctx);
- }
-#endif
-}
-
-/* mtspr */
-static void gen_mtspr(DisasContext *ctx)
-{
- void (*write_cb)(DisasContext *ctx, int sprn, int gprn);
- uint32_t sprn = SPR(ctx->opcode);
-
-#if defined(CONFIG_USER_ONLY)
- write_cb = ctx->spr_cb[sprn].uea_write;
-#else
- if (ctx->pr) {
- write_cb = ctx->spr_cb[sprn].uea_write;
- } else if (ctx->hv) {
- write_cb = ctx->spr_cb[sprn].hea_write;
- } else {
- write_cb = ctx->spr_cb[sprn].oea_write;
- }
-#endif
- if (likely(write_cb != NULL)) {
- if (likely(write_cb != SPR_NOACCESS)) {
- (*write_cb)(ctx, sprn, rS(ctx->opcode));
- } else {
- /* Privilege exception */
- fprintf(stderr, "Trying to write privileged spr %d (0x%03x) at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
- if (qemu_log_separate()) {
- qemu_log("Trying to write privileged spr %d (0x%03x) at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
- }
- gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
- }
- } else {
- /* ISA 2.07 defines these as no-ops */
- if ((ctx->insns_flags2 & PPC2_ISA207S) &&
- (sprn >= 808 && sprn <= 811)) {
- /* This is a nop */
- return;
- }
-
- /* Not defined */
- if (qemu_log_separate()) {
- qemu_log("Trying to write invalid spr %d (0x%03x) at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
- }
- fprintf(stderr, "Trying to write invalid spr %d (0x%03x) at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
-
-
- /* The behaviour depends on MSR:PR and SPR# bit 0x10,
- * it can generate a priv, a hv emu or a no-op
- */
- if (sprn & 0x10) {
- if (ctx->pr) {
- gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
- }
- } else {
- if (ctx->pr || sprn == 0) {
- gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
- }
- }
- }
-}
-
-#if defined(TARGET_PPC64)
-/* setb */
-static void gen_setb(DisasContext *ctx)
-{
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv_i32 t8 = tcg_temp_new_i32();
- TCGv_i32 tm1 = tcg_temp_new_i32();
- int crf = crfS(ctx->opcode);
-
- tcg_gen_setcondi_i32(TCG_COND_GEU, t0, cpu_crf[crf], 4);
- tcg_gen_movi_i32(t8, 8);
- tcg_gen_movi_i32(tm1, -1);
- tcg_gen_movcond_i32(TCG_COND_GEU, t0, cpu_crf[crf], t8, tm1, t0);
- tcg_gen_ext_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
-
- tcg_temp_free_i32(t0);
- tcg_temp_free_i32(t8);
- tcg_temp_free_i32(tm1);
-}
-#endif
-
-/*** Cache management ***/
-
-/* dcbf */
-static void gen_dcbf(DisasContext *ctx)
-{
- /* XXX: specification says this is treated as a load by the MMU */
- TCGv t0;
- gen_set_access_type(ctx, ACCESS_CACHE);
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- gen_qemu_ld8u(ctx, t0, t0);
- tcg_temp_free(t0);
-}
-
-/* dcbi (Supervisor only) */
-static void gen_dcbi(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv EA, val;
-
- CHK_SV;
- EA = tcg_temp_new();
- gen_set_access_type(ctx, ACCESS_CACHE);
- gen_addr_reg_index(ctx, EA);
- val = tcg_temp_new();
- /* XXX: specification says this should be treated as a store by the MMU */
- gen_qemu_ld8u(ctx, val, EA);
- gen_qemu_st8(ctx, val, EA);
- tcg_temp_free(val);
- tcg_temp_free(EA);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* dcdst */
-static void gen_dcbst(DisasContext *ctx)
-{
- /* XXX: specification say this is treated as a load by the MMU */
- TCGv t0;
- gen_set_access_type(ctx, ACCESS_CACHE);
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- gen_qemu_ld8u(ctx, t0, t0);
- tcg_temp_free(t0);
-}
-
-/* dcbt */
-static void gen_dcbt(DisasContext *ctx)
-{
- /* interpreted as no-op */
- /* XXX: specification say this is treated as a load by the MMU
- * but does not generate any exception
- */
-}
-
-/* dcbtst */
-static void gen_dcbtst(DisasContext *ctx)
-{
- /* interpreted as no-op */
- /* XXX: specification say this is treated as a load by the MMU
- * but does not generate any exception
- */
-}
-
-/* dcbtls */
-static void gen_dcbtls(DisasContext *ctx)
-{
- /* Always fails locking the cache */
- TCGv t0 = tcg_temp_new();
- gen_load_spr(t0, SPR_Exxx_L1CSR0);
- tcg_gen_ori_tl(t0, t0, L1CSR0_CUL);
- gen_store_spr(SPR_Exxx_L1CSR0, t0);
- tcg_temp_free(t0);
-}
-
-/* dcbz */
-static void gen_dcbz(DisasContext *ctx)
-{
- TCGv tcgv_addr;
- TCGv_i32 tcgv_op;
-
- gen_set_access_type(ctx, ACCESS_CACHE);
- tcgv_addr = tcg_temp_new();
- tcgv_op = tcg_const_i32(ctx->opcode & 0x03FF000);
- gen_addr_reg_index(ctx, tcgv_addr);
- gen_helper_dcbz(cpu_env, tcgv_addr, tcgv_op);
- tcg_temp_free(tcgv_addr);
- tcg_temp_free_i32(tcgv_op);
-}
-
-/* dst / dstt */
-static void gen_dst(DisasContext *ctx)
-{
- if (rA(ctx->opcode) == 0) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- } else {
- /* interpreted as no-op */
- }
-}
-
-/* dstst /dststt */
-static void gen_dstst(DisasContext *ctx)
-{
- if (rA(ctx->opcode) == 0) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- } else {
- /* interpreted as no-op */
- }
-
-}
-
-/* dss / dssall */
-static void gen_dss(DisasContext *ctx)
-{
- /* interpreted as no-op */
-}
-
-/* icbi */
-static void gen_icbi(DisasContext *ctx)
-{
- TCGv t0;
- gen_set_access_type(ctx, ACCESS_CACHE);
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- gen_helper_icbi(cpu_env, t0);
- tcg_temp_free(t0);
-}
-
-/* Optional: */
-/* dcba */
-static void gen_dcba(DisasContext *ctx)
-{
- /* interpreted as no-op */
- /* XXX: specification say this is treated as a store by the MMU
- * but does not generate any exception
- */
-}
-
-/*** Segment register manipulation ***/
-/* Supervisor only: */
-
-/* mfsr */
-static void gen_mfsr(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv t0;
-
- CHK_SV;
- t0 = tcg_const_tl(SR(ctx->opcode));
- gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
- tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* mfsrin */
-static void gen_mfsrin(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv t0;
-
- CHK_SV;
- t0 = tcg_temp_new();
- tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
- tcg_gen_andi_tl(t0, t0, 0xF);
- gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
- tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* mtsr */
-static void gen_mtsr(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv t0;
-
- CHK_SV;
- t0 = tcg_const_tl(SR(ctx->opcode));
- gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
- tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* mtsrin */
-static void gen_mtsrin(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv t0;
- CHK_SV;
-
- t0 = tcg_temp_new();
- tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
- tcg_gen_andi_tl(t0, t0, 0xF);
- gen_helper_store_sr(cpu_env, t0, cpu_gpr[rD(ctx->opcode)]);
- tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-#if defined(TARGET_PPC64)
-/* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
-
-/* mfsr */
-static void gen_mfsr_64b(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv t0;
-
- CHK_SV;
- t0 = tcg_const_tl(SR(ctx->opcode));
- gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
- tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* mfsrin */
-static void gen_mfsrin_64b(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv t0;
-
- CHK_SV;
- t0 = tcg_temp_new();
- tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
- tcg_gen_andi_tl(t0, t0, 0xF);
- gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
- tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* mtsr */
-static void gen_mtsr_64b(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv t0;
-
- CHK_SV;
- t0 = tcg_const_tl(SR(ctx->opcode));
- gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
- tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* mtsrin */
-static void gen_mtsrin_64b(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv t0;
-
- CHK_SV;
- t0 = tcg_temp_new();
- tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
- tcg_gen_andi_tl(t0, t0, 0xF);
- gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
- tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* slbmte */
-static void gen_slbmte(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
-
- gen_helper_store_slb(cpu_env, cpu_gpr[rB(ctx->opcode)],
- cpu_gpr[rS(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_slbmfee(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
-
- gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env,
- cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_slbmfev(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
-
- gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
- cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_slbfee_(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
-#else
- TCGLabel *l1, *l2;
-
- if (unlikely(ctx->pr)) {
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
- gen_helper_find_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
- cpu_gpr[rB(ctx->opcode)]);
- l1 = gen_new_label();
- l2 = gen_new_label();
- tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rS(ctx->opcode)], -1, l1);
- tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_tl(cpu_gpr[rS(ctx->opcode)], 0);
- gen_set_label(l2);
-#endif
-}
-#endif /* defined(TARGET_PPC64) */
-
-/*** Lookaside buffer management ***/
-/* Optional & supervisor only: */
-
-/* tlbia */
-static void gen_tlbia(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_HV;
-
- gen_helper_tlbia(cpu_env);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* tlbiel */
-static void gen_tlbiel(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
-
- gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* tlbie */
-static void gen_tlbie(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv_i32 t1;
- CHK_HV;
-
- if (NARROW_MODE(ctx)) {
- TCGv t0 = tcg_temp_new();
- tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
- gen_helper_tlbie(cpu_env, t0);
- tcg_temp_free(t0);
- } else {
- gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
- }
- t1 = tcg_temp_new_i32();
- tcg_gen_ld_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
- tcg_gen_ori_i32(t1, t1, TLB_NEED_GLOBAL_FLUSH);
- tcg_gen_st_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
- tcg_temp_free_i32(t1);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* tlbsync */
-static void gen_tlbsync(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_HV;
-
- /* BookS does both ptesync and tlbsync make tlbsync a nop for server */
- if (ctx->insns_flags & PPC_BOOKE) {
- gen_check_tlb_flush(ctx, true);
- }
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-#if defined(TARGET_PPC64)
-/* slbia */
-static void gen_slbia(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
-
- gen_helper_slbia(cpu_env);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* slbie */
-static void gen_slbie(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
-
- gen_helper_slbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-#endif /* defined(TARGET_PPC64) */
-
-/*** External control ***/
-/* Optional: */
-
-/* eciwx */
-static void gen_eciwx(DisasContext *ctx)
-{
- TCGv t0;
- /* Should check EAR[E] ! */
- gen_set_access_type(ctx, ACCESS_EXT);
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- gen_check_align(ctx, t0, 0x03);
- gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
- tcg_temp_free(t0);
-}
-
-/* ecowx */
-static void gen_ecowx(DisasContext *ctx)
-{
- TCGv t0;
- /* Should check EAR[E] ! */
- gen_set_access_type(ctx, ACCESS_EXT);
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- gen_check_align(ctx, t0, 0x03);
- gen_qemu_st32(ctx, cpu_gpr[rD(ctx->opcode)], t0);
- tcg_temp_free(t0);
-}
-
-/* PowerPC 601 specific instructions */
-
-/* abs - abs. */
-static void gen_abs(DisasContext *ctx)
-{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);
- tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- gen_set_label(l2);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* abso - abso. */
-static void gen_abso(DisasContext *ctx)
-{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGLabel *l3 = gen_new_label();
- /* Start with XER OV disabled, the most likely case */
- tcg_gen_movi_tl(cpu_ov, 0);
- tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
- tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
- tcg_gen_movi_tl(cpu_ov, 1);
- tcg_gen_movi_tl(cpu_so, 1);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_br(l3);
- gen_set_label(l2);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- gen_set_label(l3);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* clcs */
-static void gen_clcs(DisasContext *ctx)
-{
- TCGv_i32 t0 = tcg_const_i32(rA(ctx->opcode));
- gen_helper_clcs(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
- tcg_temp_free_i32(t0);
- /* Rc=1 sets CR0 to an undefined state */
-}
-
-/* div - div. */
-static void gen_div(DisasContext *ctx)
-{
- gen_helper_div(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rB(ctx->opcode)]);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* divo - divo. */
-static void gen_divo(DisasContext *ctx)
-{
- gen_helper_divo(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rB(ctx->opcode)]);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* divs - divs. */
-static void gen_divs(DisasContext *ctx)
-{
- gen_helper_divs(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rB(ctx->opcode)]);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* divso - divso. */
-static void gen_divso(DisasContext *ctx)
-{
- gen_helper_divso(cpu_gpr[rD(ctx->opcode)], cpu_env,
- cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* doz - doz. */
-static void gen_doz(DisasContext *ctx)
-{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
- tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
- gen_set_label(l2);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* dozo - dozo. */
-static void gen_dozo(DisasContext *ctx)
-{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- TCGv t2 = tcg_temp_new();
- /* Start with XER OV disabled, the most likely case */
- tcg_gen_movi_tl(cpu_ov, 0);
- tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
- tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0);
- tcg_gen_andc_tl(t1, t1, t2);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
- tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
- tcg_gen_movi_tl(cpu_ov, 1);
- tcg_gen_movi_tl(cpu_so, 1);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
- gen_set_label(l2);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- tcg_temp_free(t2);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* dozi */
-static void gen_dozi(DisasContext *ctx)
-{
- target_long simm = SIMM(ctx->opcode);
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_LT, cpu_gpr[rA(ctx->opcode)], simm, l1);
- tcg_gen_subfi_tl(cpu_gpr[rD(ctx->opcode)], simm, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
- gen_set_label(l2);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* lscbx - lscbx. */
-static void gen_lscbx(DisasContext *ctx)
-{
- TCGv t0 = tcg_temp_new();
- TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
- TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode));
- TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
-
- gen_addr_reg_index(ctx, t0);
- gen_helper_lscbx(t0, cpu_env, t0, t1, t2, t3);
- tcg_temp_free_i32(t1);
- tcg_temp_free_i32(t2);
- tcg_temp_free_i32(t3);
- tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
- tcg_gen_or_tl(cpu_xer, cpu_xer, t0);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, t0);
- tcg_temp_free(t0);
-}
-
-/* maskg - maskg. */
-static void gen_maskg(DisasContext *ctx)
-{
- TCGLabel *l1 = gen_new_label();
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- TCGv t2 = tcg_temp_new();
- TCGv t3 = tcg_temp_new();
- tcg_gen_movi_tl(t3, 0xFFFFFFFF);
- tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
- tcg_gen_andi_tl(t1, cpu_gpr[rS(ctx->opcode)], 0x1F);
- tcg_gen_addi_tl(t2, t0, 1);
- tcg_gen_shr_tl(t2, t3, t2);
- tcg_gen_shr_tl(t3, t3, t1);
- tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], t2, t3);
- tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
- tcg_gen_neg_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- gen_set_label(l1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- tcg_temp_free(t2);
- tcg_temp_free(t3);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* maskir - maskir. */
-static void gen_maskir(DisasContext *ctx)
-{
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- tcg_gen_and_tl(t0, cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* mul - mul. */
-static void gen_mul(DisasContext *ctx)
-{
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
- TCGv t2 = tcg_temp_new();
- tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_mul_i64(t0, t0, t1);
- tcg_gen_trunc_i64_tl(t2, t0);
- gen_store_spr(SPR_MQ, t2);
- tcg_gen_shri_i64(t1, t0, 32);
- tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
- tcg_temp_free(t2);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* mulo - mulo. */
-static void gen_mulo(DisasContext *ctx)
-{
- TCGLabel *l1 = gen_new_label();
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
- TCGv t2 = tcg_temp_new();
- /* Start with XER OV disabled, the most likely case */
- tcg_gen_movi_tl(cpu_ov, 0);
- tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_mul_i64(t0, t0, t1);
- tcg_gen_trunc_i64_tl(t2, t0);
- gen_store_spr(SPR_MQ, t2);
- tcg_gen_shri_i64(t1, t0, 32);
- tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
- tcg_gen_ext32s_i64(t1, t0);
- tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
- tcg_gen_movi_tl(cpu_ov, 1);
- tcg_gen_movi_tl(cpu_so, 1);
- gen_set_label(l1);
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
- tcg_temp_free(t2);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* nabs - nabs. */
-static void gen_nabs(DisasContext *ctx)
-{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- gen_set_label(l2);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* nabso - nabso. */
-static void gen_nabso(DisasContext *ctx)
-{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- gen_set_label(l2);
- /* nabs never overflows */
- tcg_gen_movi_tl(cpu_ov, 0);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
-}
-
-/* rlmi - rlmi. */
-static void gen_rlmi(DisasContext *ctx)
-{
- uint32_t mb = MB(ctx->opcode);
- uint32_t me = ME(ctx->opcode);
- TCGv t0 = tcg_temp_new();
- tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
- tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
- tcg_gen_andi_tl(t0, t0, MASK(mb, me));
- tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~MASK(mb, me));
- tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], t0);
- tcg_temp_free(t0);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* rrib - rrib. */
-static void gen_rrib(DisasContext *ctx)
-{
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
- tcg_gen_movi_tl(t1, 0x80000000);
- tcg_gen_shr_tl(t1, t1, t0);
- tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
- tcg_gen_and_tl(t0, t0, t1);
- tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], t1);
- tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* sle - sle. */
-static void gen_sle(DisasContext *ctx)
-{
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
- tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
- tcg_gen_subfi_tl(t1, 32, t1);
- tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
- tcg_gen_or_tl(t1, t0, t1);
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
- gen_store_spr(SPR_MQ, t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* sleq - sleq. */
-static void gen_sleq(DisasContext *ctx)
-{
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- TCGv t2 = tcg_temp_new();
- tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
- tcg_gen_movi_tl(t2, 0xFFFFFFFF);
- tcg_gen_shl_tl(t2, t2, t0);
- tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
- gen_load_spr(t1, SPR_MQ);
- gen_store_spr(SPR_MQ, t0);
- tcg_gen_and_tl(t0, t0, t2);
- tcg_gen_andc_tl(t1, t1, t2);
- tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- tcg_temp_free(t2);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* sliq - sliq. */
-static void gen_sliq(DisasContext *ctx)
-{
- int sh = SH(ctx->opcode);
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
- tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
- tcg_gen_or_tl(t1, t0, t1);
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
- gen_store_spr(SPR_MQ, t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* slliq - slliq. */
-static void gen_slliq(DisasContext *ctx)
-{
- int sh = SH(ctx->opcode);
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
- gen_load_spr(t1, SPR_MQ);
- gen_store_spr(SPR_MQ, t0);
- tcg_gen_andi_tl(t0, t0, (0xFFFFFFFFU << sh));
- tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU << sh));
- tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* sllq - sllq. */
-static void gen_sllq(DisasContext *ctx)
-{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGv t0 = tcg_temp_local_new();
- TCGv t1 = tcg_temp_local_new();
- TCGv t2 = tcg_temp_local_new();
- tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
- tcg_gen_movi_tl(t1, 0xFFFFFFFF);
- tcg_gen_shl_tl(t1, t1, t2);
- tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
- gen_load_spr(t0, SPR_MQ);
- tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
- gen_load_spr(t2, SPR_MQ);
- tcg_gen_andc_tl(t1, t2, t1);
- tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
- gen_set_label(l2);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- tcg_temp_free(t2);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* slq - slq. */
-static void gen_slq(DisasContext *ctx)
-{
- TCGLabel *l1 = gen_new_label();
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
- tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
- tcg_gen_subfi_tl(t1, 32, t1);
- tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
- tcg_gen_or_tl(t1, t0, t1);
- gen_store_spr(SPR_MQ, t1);
- tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
- tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
- gen_set_label(l1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* sraiq - sraiq. */
-static void gen_sraiq(DisasContext *ctx)
-{
- int sh = SH(ctx->opcode);
- TCGLabel *l1 = gen_new_label();
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
- tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
- tcg_gen_or_tl(t0, t0, t1);
- gen_store_spr(SPR_MQ, t0);
- tcg_gen_movi_tl(cpu_ca, 0);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
- tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
- tcg_gen_movi_tl(cpu_ca, 1);
- gen_set_label(l1);
- tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* sraq - sraq. */
-static void gen_sraq(DisasContext *ctx)
-{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_local_new();
- TCGv t2 = tcg_temp_local_new();
- tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
- tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
- tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2);
- tcg_gen_subfi_tl(t2, 32, t2);
- tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2);
- tcg_gen_or_tl(t0, t0, t2);
- gen_store_spr(SPR_MQ, t0);
- tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1);
- tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]);
- tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31);
- gen_set_label(l1);
- tcg_temp_free(t0);
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
- tcg_gen_movi_tl(cpu_ca, 0);
- tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);
- tcg_gen_movi_tl(cpu_ca, 1);
- gen_set_label(l2);
- tcg_temp_free(t1);
- tcg_temp_free(t2);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* sre - sre. */
-static void gen_sre(DisasContext *ctx)
-{
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
- tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
- tcg_gen_subfi_tl(t1, 32, t1);
- tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
- tcg_gen_or_tl(t1, t0, t1);
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
- gen_store_spr(SPR_MQ, t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* srea - srea. */
-static void gen_srea(DisasContext *ctx)
-{
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
- tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
- gen_store_spr(SPR_MQ, t0);
- tcg_gen_sar_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* sreq */
-static void gen_sreq(DisasContext *ctx)
-{
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- TCGv t2 = tcg_temp_new();
- tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
- tcg_gen_movi_tl(t1, 0xFFFFFFFF);
- tcg_gen_shr_tl(t1, t1, t0);
- tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
- gen_load_spr(t2, SPR_MQ);
- gen_store_spr(SPR_MQ, t0);
- tcg_gen_and_tl(t0, t0, t1);
- tcg_gen_andc_tl(t2, t2, t1);
- tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- tcg_temp_free(t2);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* sriq */
-static void gen_sriq(DisasContext *ctx)
-{
- int sh = SH(ctx->opcode);
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
- tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
- tcg_gen_or_tl(t1, t0, t1);
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
- gen_store_spr(SPR_MQ, t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* srliq */
-static void gen_srliq(DisasContext *ctx)
-{
- int sh = SH(ctx->opcode);
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- tcg_gen_rotri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
- gen_load_spr(t1, SPR_MQ);
- gen_store_spr(SPR_MQ, t0);
- tcg_gen_andi_tl(t0, t0, (0xFFFFFFFFU >> sh));
- tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU >> sh));
- tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* srlq */
-static void gen_srlq(DisasContext *ctx)
-{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGv t0 = tcg_temp_local_new();
- TCGv t1 = tcg_temp_local_new();
- TCGv t2 = tcg_temp_local_new();
- tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
- tcg_gen_movi_tl(t1, 0xFFFFFFFF);
- tcg_gen_shr_tl(t2, t1, t2);
- tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
- gen_load_spr(t0, SPR_MQ);
- tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
- tcg_gen_and_tl(t0, t0, t2);
- gen_load_spr(t1, SPR_MQ);
- tcg_gen_andc_tl(t1, t1, t2);
- tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
- gen_set_label(l2);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- tcg_temp_free(t2);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* srq */
-static void gen_srq(DisasContext *ctx)
-{
- TCGLabel *l1 = gen_new_label();
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
- tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
- tcg_gen_subfi_tl(t1, 32, t1);
- tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
- tcg_gen_or_tl(t1, t0, t1);
- gen_store_spr(SPR_MQ, t1);
- tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
- tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
- tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
- gen_set_label(l1);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- if (unlikely(Rc(ctx->opcode) != 0))
- gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
-}
-
-/* PowerPC 602 specific instructions */
-
-/* dsa */
-static void gen_dsa(DisasContext *ctx)
-{
- /* XXX: TODO */
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
-}
-
-/* esa */
-static void gen_esa(DisasContext *ctx)
-{
- /* XXX: TODO */
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
-}
-
-/* mfrom */
-static void gen_mfrom(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* 602 - 603 - G2 TLB management */
-
-/* tlbld */
-static void gen_tlbld_6xx(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- gen_helper_6xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* tlbli */
-static void gen_tlbli_6xx(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- gen_helper_6xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* 74xx TLB management */
-
-/* tlbld */
-static void gen_tlbld_74xx(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- gen_helper_74xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* tlbli */
-static void gen_tlbli_74xx(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- gen_helper_74xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* POWER instructions not in PowerPC 601 */
-
-/* clf */
-static void gen_clf(DisasContext *ctx)
-{
- /* Cache line flush: implemented as no-op */
-}
-
-/* cli */
-static void gen_cli(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- /* Cache line invalidate: privileged and treated as no-op */
- CHK_SV;
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* dclst */
-static void gen_dclst(DisasContext *ctx)
-{
- /* Data cache line store: treated as no-op */
-}
-
-static void gen_mfsri(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- int ra = rA(ctx->opcode);
- int rd = rD(ctx->opcode);
- TCGv t0;
-
- CHK_SV;
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- tcg_gen_shri_tl(t0, t0, 28);
- tcg_gen_andi_tl(t0, t0, 0xF);
- gen_helper_load_sr(cpu_gpr[rd], cpu_env, t0);
- tcg_temp_free(t0);
- if (ra != 0 && ra != rd)
- tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_rac(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv t0;
-
- CHK_SV;
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- gen_helper_rac(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
- tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_rfsvc(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
-
- gen_helper_rfsvc(cpu_env);
- gen_sync_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* svc is not implemented for now */
-
-/* BookE specific instructions */
-
-/* XXX: not implemented on 440 ? */
-static void gen_mfapidi(DisasContext *ctx)
-{
- /* XXX: TODO */
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
-}
-
-/* XXX: not implemented on 440 ? */
-static void gen_tlbiva(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv t0;
-
- CHK_SV;
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- gen_helper_tlbiva(cpu_env, cpu_gpr[rB(ctx->opcode)]);
- tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* All 405 MAC instructions are translated here */
-static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
- int ra, int rb, int rt, int Rc)
-{
- TCGv t0, t1;
-
- t0 = tcg_temp_local_new();
- t1 = tcg_temp_local_new();
-
- switch (opc3 & 0x0D) {
- case 0x05:
- /* macchw - macchw. - macchwo - macchwo. */
- /* macchws - macchws. - macchwso - macchwso. */
- /* nmacchw - nmacchw. - nmacchwo - nmacchwo. */
- /* nmacchws - nmacchws. - nmacchwso - nmacchwso. */
- /* mulchw - mulchw. */
- tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
- tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
- tcg_gen_ext16s_tl(t1, t1);
- break;
- case 0x04:
- /* macchwu - macchwu. - macchwuo - macchwuo. */
- /* macchwsu - macchwsu. - macchwsuo - macchwsuo. */
- /* mulchwu - mulchwu. */
- tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
- tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
- tcg_gen_ext16u_tl(t1, t1);
- break;
- case 0x01:
- /* machhw - machhw. - machhwo - machhwo. */
- /* machhws - machhws. - machhwso - machhwso. */
- /* nmachhw - nmachhw. - nmachhwo - nmachhwo. */
- /* nmachhws - nmachhws. - nmachhwso - nmachhwso. */
- /* mulhhw - mulhhw. */
- tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
- tcg_gen_ext16s_tl(t0, t0);
- tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
- tcg_gen_ext16s_tl(t1, t1);
- break;
- case 0x00:
- /* machhwu - machhwu. - machhwuo - machhwuo. */
- /* machhwsu - machhwsu. - machhwsuo - machhwsuo. */
- /* mulhhwu - mulhhwu. */
- tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
- tcg_gen_ext16u_tl(t0, t0);
- tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
- tcg_gen_ext16u_tl(t1, t1);
- break;
- case 0x0D:
- /* maclhw - maclhw. - maclhwo - maclhwo. */
- /* maclhws - maclhws. - maclhwso - maclhwso. */
- /* nmaclhw - nmaclhw. - nmaclhwo - nmaclhwo. */
- /* nmaclhws - nmaclhws. - nmaclhwso - nmaclhwso. */
- /* mullhw - mullhw. */
- tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
- tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
- break;
- case 0x0C:
- /* maclhwu - maclhwu. - maclhwuo - maclhwuo. */
- /* maclhwsu - maclhwsu. - maclhwsuo - maclhwsuo. */
- /* mullhwu - mullhwu. */
- tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
- tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
- break;
- }
- if (opc2 & 0x04) {
- /* (n)multiply-and-accumulate (0x0C / 0x0E) */
- tcg_gen_mul_tl(t1, t0, t1);
- if (opc2 & 0x02) {
- /* nmultiply-and-accumulate (0x0E) */
- tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
- } else {
- /* multiply-and-accumulate (0x0C) */
- tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
- }
-
- if (opc3 & 0x12) {
- /* Check overflow and/or saturate */
- TCGLabel *l1 = gen_new_label();
-
- if (opc3 & 0x10) {
- /* Start with XER OV disabled, the most likely case */
- tcg_gen_movi_tl(cpu_ov, 0);
- }
- if (opc3 & 0x01) {
- /* Signed */
- tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
- tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
- tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
- tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
- if (opc3 & 0x02) {
- /* Saturate */
- tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
- tcg_gen_xori_tl(t0, t0, 0x7fffffff);
- }
- } else {
- /* Unsigned */
- tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
- if (opc3 & 0x02) {
- /* Saturate */
- tcg_gen_movi_tl(t0, UINT32_MAX);
- }
- }
- if (opc3 & 0x10) {
- /* Check overflow */
- tcg_gen_movi_tl(cpu_ov, 1);
- tcg_gen_movi_tl(cpu_so, 1);
- }
- gen_set_label(l1);
- tcg_gen_mov_tl(cpu_gpr[rt], t0);
- }
- } else {
- tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
- }
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- if (unlikely(Rc) != 0) {
- /* Update Rc0 */
- gen_set_Rc0(ctx, cpu_gpr[rt]);
- }
-}
-
-#define GEN_MAC_HANDLER(name, opc2, opc3) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode), \
- rD(ctx->opcode), Rc(ctx->opcode)); \
-}
-
-/* macchw - macchw. */
-GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
-/* macchwo - macchwo. */
-GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
-/* macchws - macchws. */
-GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
-/* macchwso - macchwso. */
-GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
-/* macchwsu - macchwsu. */
-GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
-/* macchwsuo - macchwsuo. */
-GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
-/* macchwu - macchwu. */
-GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
-/* macchwuo - macchwuo. */
-GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
-/* machhw - machhw. */
-GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
-/* machhwo - machhwo. */
-GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
-/* machhws - machhws. */
-GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
-/* machhwso - machhwso. */
-GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
-/* machhwsu - machhwsu. */
-GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
-/* machhwsuo - machhwsuo. */
-GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
-/* machhwu - machhwu. */
-GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
-/* machhwuo - machhwuo. */
-GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
-/* maclhw - maclhw. */
-GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
-/* maclhwo - maclhwo. */
-GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
-/* maclhws - maclhws. */
-GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
-/* maclhwso - maclhwso. */
-GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
-/* maclhwu - maclhwu. */
-GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
-/* maclhwuo - maclhwuo. */
-GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
-/* maclhwsu - maclhwsu. */
-GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
-/* maclhwsuo - maclhwsuo. */
-GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
-/* nmacchw - nmacchw. */
-GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
-/* nmacchwo - nmacchwo. */
-GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
-/* nmacchws - nmacchws. */
-GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
-/* nmacchwso - nmacchwso. */
-GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
-/* nmachhw - nmachhw. */
-GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
-/* nmachhwo - nmachhwo. */
-GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
-/* nmachhws - nmachhws. */
-GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
-/* nmachhwso - nmachhwso. */
-GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
-/* nmaclhw - nmaclhw. */
-GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
-/* nmaclhwo - nmaclhwo. */
-GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
-/* nmaclhws - nmaclhws. */
-GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
-/* nmaclhwso - nmaclhwso. */
-GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
-
-/* mulchw - mulchw. */
-GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
-/* mulchwu - mulchwu. */
-GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
-/* mulhhw - mulhhw. */
-GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
-/* mulhhwu - mulhhwu. */
-GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
-/* mullhw - mullhw. */
-GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
-/* mullhwu - mullhwu. */
-GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
-
-/* mfdcr */
-static void gen_mfdcr(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv dcrn;
-
- CHK_SV;
- dcrn = tcg_const_tl(SPR(ctx->opcode));
- gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn);
- tcg_temp_free(dcrn);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* mtdcr */
-static void gen_mtdcr(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv dcrn;
-
- CHK_SV;
- dcrn = tcg_const_tl(SPR(ctx->opcode));
- gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]);
- tcg_temp_free(dcrn);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* mfdcrx */
-/* XXX: not implemented on 440 ? */
-static void gen_mfdcrx(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
- cpu_gpr[rA(ctx->opcode)]);
- /* Note: Rc update flag set leads to undefined state of Rc0 */
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* mtdcrx */
-/* XXX: not implemented on 440 ? */
-static void gen_mtdcrx(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rS(ctx->opcode)]);
- /* Note: Rc update flag set leads to undefined state of Rc0 */
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* mfdcrux (PPC 460) : user-mode access to DCR */
-static void gen_mfdcrux(DisasContext *ctx)
-{
- gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
- cpu_gpr[rA(ctx->opcode)]);
- /* Note: Rc update flag set leads to undefined state of Rc0 */
-}
-
-/* mtdcrux (PPC 460) : user-mode access to DCR */
-static void gen_mtdcrux(DisasContext *ctx)
-{
- gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rS(ctx->opcode)]);
- /* Note: Rc update flag set leads to undefined state of Rc0 */
-}
-
-/* dccci */
-static void gen_dccci(DisasContext *ctx)
-{
- CHK_SV;
- /* interpreted as no-op */
-}
-
-/* dcread */
-static void gen_dcread(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv EA, val;
-
- CHK_SV;
- gen_set_access_type(ctx, ACCESS_CACHE);
- EA = tcg_temp_new();
- gen_addr_reg_index(ctx, EA);
- val = tcg_temp_new();
- gen_qemu_ld32u(ctx, val, EA);
- tcg_temp_free(val);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
- tcg_temp_free(EA);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* icbt */
-static void gen_icbt_40x(DisasContext *ctx)
-{
- /* interpreted as no-op */
- /* XXX: specification say this is treated as a load by the MMU
- * but does not generate any exception
- */
-}
-
-/* iccci */
-static void gen_iccci(DisasContext *ctx)
-{
- CHK_SV;
- /* interpreted as no-op */
-}
-
-/* icread */
-static void gen_icread(DisasContext *ctx)
-{
- CHK_SV;
- /* interpreted as no-op */
-}
-
-/* rfci (supervisor only) */
-static void gen_rfci_40x(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- /* Restore CPU state */
- gen_helper_40x_rfci(cpu_env);
- gen_sync_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_rfci(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- /* Restore CPU state */
- gen_helper_rfci(cpu_env);
- gen_sync_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* BookE specific */
-
-/* XXX: not implemented on 440 ? */
-static void gen_rfdi(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- /* Restore CPU state */
- gen_helper_rfdi(cpu_env);
- gen_sync_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* XXX: not implemented on 440 ? */
-static void gen_rfmci(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- /* Restore CPU state */
- gen_helper_rfmci(cpu_env);
- gen_sync_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* TLB management - PowerPC 405 implementation */
-
-/* tlbre */
-static void gen_tlbre_40x(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- switch (rB(ctx->opcode)) {
- case 0:
- gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_env,
- cpu_gpr[rA(ctx->opcode)]);
- break;
- case 1:
- gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_env,
- cpu_gpr[rA(ctx->opcode)]);
- break;
- default:
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- break;
- }
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* tlbsx - tlbsx. */
-static void gen_tlbsx_40x(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv t0;
-
- CHK_SV;
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
- tcg_temp_free(t0);
- if (Rc(ctx->opcode)) {
- TCGLabel *l1 = gen_new_label();
- tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
- tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
- gen_set_label(l1);
- }
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* tlbwe */
-static void gen_tlbwe_40x(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
-
- switch (rB(ctx->opcode)) {
- case 0:
- gen_helper_4xx_tlbwe_hi(cpu_env, cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rS(ctx->opcode)]);
- break;
- case 1:
- gen_helper_4xx_tlbwe_lo(cpu_env, cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rS(ctx->opcode)]);
- break;
- default:
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- break;
- }
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* TLB management - PowerPC 440 implementation */
-
-/* tlbre */
-static void gen_tlbre_440(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
-
- switch (rB(ctx->opcode)) {
- case 0:
- case 1:
- case 2:
- {
- TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
- gen_helper_440_tlbre(cpu_gpr[rD(ctx->opcode)], cpu_env,
- t0, cpu_gpr[rA(ctx->opcode)]);
- tcg_temp_free_i32(t0);
- }
- break;
- default:
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- break;
- }
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* tlbsx - tlbsx. */
-static void gen_tlbsx_440(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv t0;
-
- CHK_SV;
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
- tcg_temp_free(t0);
- if (Rc(ctx->opcode)) {
- TCGLabel *l1 = gen_new_label();
- tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
- tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
- tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
- gen_set_label(l1);
- }
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* tlbwe */
-static void gen_tlbwe_440(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- switch (rB(ctx->opcode)) {
- case 0:
- case 1:
- case 2:
- {
- TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
- gen_helper_440_tlbwe(cpu_env, t0, cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rS(ctx->opcode)]);
- tcg_temp_free_i32(t0);
- }
- break;
- default:
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- break;
- }
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* TLB management - PowerPC BookE 2.06 implementation */
-
-/* tlbre */
-static void gen_tlbre_booke206(DisasContext *ctx)
-{
- #if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- gen_helper_booke206_tlbre(cpu_env);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* tlbsx - tlbsx. */
-static void gen_tlbsx_booke206(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv t0;
-
- CHK_SV;
- if (rA(ctx->opcode)) {
- t0 = tcg_temp_new();
- tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]);
- } else {
- t0 = tcg_const_tl(0);
- }
-
- tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]);
- gen_helper_booke206_tlbsx(cpu_env, t0);
- tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* tlbwe */
-static void gen_tlbwe_booke206(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- gen_helper_booke206_tlbwe(cpu_env);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_tlbivax_booke206(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv t0;
-
- CHK_SV;
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- gen_helper_booke206_tlbivax(cpu_env, t0);
- tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_tlbilx_booke206(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv t0;
-
- CHK_SV;
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
-
- switch((ctx->opcode >> 21) & 0x3) {
- case 0:
- gen_helper_booke206_tlbilx0(cpu_env, t0);
- break;
- case 1:
- gen_helper_booke206_tlbilx1(cpu_env, t0);
- break;
- case 3:
- gen_helper_booke206_tlbilx3(cpu_env, t0);
- break;
- default:
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- break;
- }
-
- tcg_temp_free(t0);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-
-/* wrtee */
-static void gen_wrtee(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- TCGv t0;
-
- CHK_SV;
- t0 = tcg_temp_new();
- tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
- tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
- tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
- tcg_temp_free(t0);
- /* Stop translation to have a chance to raise an exception
- * if we just set msr_ee to 1
- */
- gen_stop_exception(ctx);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* wrteei */
-static void gen_wrteei(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- if (ctx->opcode & 0x00008000) {
- tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
- /* Stop translation to have a chance to raise an exception */
- gen_stop_exception(ctx);
- } else {
- tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
- }
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-/* PowerPC 440 specific instructions */
-
-/* dlmzb */
-static void gen_dlmzb(DisasContext *ctx)
-{
- TCGv_i32 t0 = tcg_const_i32(Rc(ctx->opcode));
- gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], cpu_env,
- cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
- tcg_temp_free_i32(t0);
-}
-
-/* mbar replaces eieio on 440 */
-static void gen_mbar(DisasContext *ctx)
-{
- /* interpreted as no-op */
-}
-
-/* msync replaces sync on 440 */
-static void gen_msync_4xx(DisasContext *ctx)
-{
- /* interpreted as no-op */
-}
-
-/* icbt */
-static void gen_icbt_440(DisasContext *ctx)
-{
- /* interpreted as no-op */
- /* XXX: specification say this is treated as a load by the MMU
- * but does not generate any exception
- */
-}
-
-/* Embedded.Processor Control */
-
-static void gen_msgclr(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-static void gen_msgsnd(DisasContext *ctx)
-{
-#if defined(CONFIG_USER_ONLY)
- GEN_PRIV;
-#else
- CHK_SV;
- gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
-#endif /* defined(CONFIG_USER_ONLY) */
-}
-
-
-#if defined(TARGET_PPC64)
-static void gen_maddld(DisasContext *ctx)
-{
- TCGv_i64 t1 = tcg_temp_new_i64();
-
- tcg_gen_mul_i64(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_add_i64(cpu_gpr[rD(ctx->opcode)], t1, cpu_gpr[rC(ctx->opcode)]);
- tcg_temp_free_i64(t1);
-}
-
-/* maddhd maddhdu */
-static void gen_maddhd_maddhdu(DisasContext *ctx)
-{
- TCGv_i64 lo = tcg_temp_new_i64();
- TCGv_i64 hi = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
-
- if (Rc(ctx->opcode)) {
- tcg_gen_mulu2_i64(lo, hi, cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_movi_i64(t1, 0);
- } else {
- tcg_gen_muls2_i64(lo, hi, cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_sari_i64(t1, cpu_gpr[rC(ctx->opcode)], 63);
- }
- tcg_gen_add2_i64(t1, cpu_gpr[rD(ctx->opcode)], lo, hi,
- cpu_gpr[rC(ctx->opcode)], t1);
- tcg_temp_free_i64(lo);
- tcg_temp_free_i64(hi);
- tcg_temp_free_i64(t1);
-}
-#endif /* defined(TARGET_PPC64) */
-
-static void gen_tbegin(DisasContext *ctx)
-{
- if (unlikely(!ctx->tm_enabled)) {
- gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);
- return;
- }
- gen_helper_tbegin(cpu_env);
-}
-
-#define GEN_TM_NOOP(name) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- if (unlikely(!ctx->tm_enabled)) { \
- gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM); \
- return; \
- } \
- /* Because tbegin always fails in QEMU, these user \
- * space instructions all have a simple implementation: \
- * \
- * CR[0] = 0b0 || MSR[TS] || 0b0 \
- * = 0b0 || 0b00 || 0b0 \
- */ \
- tcg_gen_movi_i32(cpu_crf[0], 0); \
-}
-
-GEN_TM_NOOP(tend);
-GEN_TM_NOOP(tabort);
-GEN_TM_NOOP(tabortwc);
-GEN_TM_NOOP(tabortwci);
-GEN_TM_NOOP(tabortdc);
-GEN_TM_NOOP(tabortdci);
-GEN_TM_NOOP(tsr);
-
-static void gen_tcheck(DisasContext *ctx)
-{
- if (unlikely(!ctx->tm_enabled)) {
- gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);
- return;
- }
- /* Because tbegin always fails, the tcheck implementation
- * is simple:
- *
- * CR[CRF] = TDOOMED || MSR[TS] || 0b0
- * = 0b1 || 0b00 || 0b0
- */
- tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0x8);
-}
-
-#if defined(CONFIG_USER_ONLY)
-#define GEN_TM_PRIV_NOOP(name) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); \
-}
-
-#else
-
-#define GEN_TM_PRIV_NOOP(name) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- CHK_SV; \
- if (unlikely(!ctx->tm_enabled)) { \
- gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM); \
- return; \
- } \
- /* Because tbegin always fails, the implementation is \
- * simple: \
- * \
- * CR[0] = 0b0 || MSR[TS] || 0b0 \
- * = 0b0 || 0b00 | 0b0 \
- */ \
- tcg_gen_movi_i32(cpu_crf[0], 0); \
-}
-
-#endif
-
-GEN_TM_PRIV_NOOP(treclaim);
-GEN_TM_PRIV_NOOP(trechkpt);
-
-#include "translate/fp-impl.inc.c"
-
-#include "translate/vmx-impl.inc.c"
-
-#include "translate/vsx-impl.inc.c"
-
-#include "translate/dfp-impl.inc.c"
-
-#include "translate/spe-impl.inc.c"
-
-static opcode_t opcodes[] = {
-GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
-GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
-GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
-GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400001, PPC_INTEGER),
-GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
-#if defined(TARGET_PPC64)
-GEN_HANDLER_E(cmpeqb, 0x1F, 0x00, 0x07, 0x00600000, PPC_NONE, PPC2_ISA300),
-#endif
-GEN_HANDLER_E(cmpb, 0x1F, 0x1C, 0x0F, 0x00000001, PPC_NONE, PPC2_ISA205),
-GEN_HANDLER_E(cmprb, 0x1F, 0x00, 0x06, 0x00400001, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
-GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER_E(addpcis, 0x13, 0x2, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER),
-GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER),
-GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-#if defined(TARGET_PPC64)
-GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B),
-#endif
-GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER),
-GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER),
-GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
-GEN_HANDLER_E(cnttzw, 0x1F, 0x1A, 0x10, 0x00000000, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(popcntb, 0x1F, 0x1A, 0x03, 0x0000F801, PPC_POPCNTB),
-GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD),
-GEN_HANDLER_E(prtyw, 0x1F, 0x1A, 0x04, 0x0000F801, PPC_NONE, PPC2_ISA205),
-#if defined(TARGET_PPC64)
-GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD),
-GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
-GEN_HANDLER_E(cnttzd, 0x1F, 0x1A, 0x11, 0x00000000, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E(darn, 0x1F, 0x13, 0x17, 0x001CF801, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E(prtyd, 0x1F, 0x1A, 0x05, 0x0000F801, PPC_NONE, PPC2_ISA205),
-GEN_HANDLER_E(bpermd, 0x1F, 0x1C, 0x07, 0x00000001, PPC_NONE, PPC2_PERM_ISA206),
-#endif
-GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER),
-#if defined(TARGET_PPC64)
-GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B),
-GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B),
-GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B),
-GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B),
-GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B),
-GEN_HANDLER2_E(extswsli0, "extswsli", 0x1F, 0x1A, 0x1B, 0x00000000,
- PPC_NONE, PPC2_ISA300),
-GEN_HANDLER2_E(extswsli1, "extswsli", 0x1F, 0x1B, 0x1B, 0x00000000,
- PPC_NONE, PPC2_ISA300),
-#endif
-#if defined(TARGET_PPC64)
-GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
-GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
-GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
-#endif
-GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING),
-GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING),
-GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
-GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
-GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO),
-GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
-GEN_HANDLER_E(lbarx, 0x1F, 0x14, 0x01, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
-GEN_HANDLER_E(lharx, 0x1F, 0x14, 0x03, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
-GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES),
-GEN_HANDLER_E(stbcx_, 0x1F, 0x16, 0x15, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
-GEN_HANDLER_E(sthcx_, 0x1F, 0x16, 0x16, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
-GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
-#if defined(TARGET_PPC64)
-GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B),
-GEN_HANDLER_E(lqarx, 0x1F, 0x14, 0x08, 0, PPC_NONE, PPC2_LSQ_ISA207),
-GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
-GEN_HANDLER_E(stqcx_, 0x1F, 0x16, 0x05, 0, PPC_NONE, PPC2_LSQ_ISA207),
-#endif
-GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC),
-GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT),
-GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
-GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
-GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW),
-GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW),
-GEN_HANDLER_E(bctar, 0x13, 0x10, 0x11, 0x0000E000, PPC_NONE, PPC2_BCTAR_ISA207),
-GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
-GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
-#if defined(TARGET_PPC64)
-GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
-GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
-GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
-GEN_HANDLER_E(sleep, 0x13, 0x12, 0x0e, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
-GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
-GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
-#endif
-GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
-GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
-GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
-#if defined(TARGET_PPC64)
-GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B),
-GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B),
-#endif
-GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
-GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC),
-GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC),
-GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
-GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
-GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
-#if defined(TARGET_PPC64)
-GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
-GEN_HANDLER_E(setb, 0x1F, 0x00, 0x04, 0x0003F801, PPC_NONE, PPC2_ISA300),
-#endif
-GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001EF801, PPC_MISC),
-GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000000, PPC_MISC),
-GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
-GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
-GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
-GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x00000001, PPC_CACHE),
-GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x00000001, PPC_CACHE),
-GEN_HANDLER_E(dcbtls, 0x1F, 0x06, 0x05, 0x02000001, PPC_BOOKE, PPC2_BOOKE206),
-GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ),
-GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
-GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC),
-GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
-GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI),
-GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA),
-GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
-GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
-GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT),
-GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT),
-#if defined(TARGET_PPC64)
-GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B),
-GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
- PPC_SEGMENT_64B),
-GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
-GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
- PPC_SEGMENT_64B),
-GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B),
-GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B),
-GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B),
-GEN_HANDLER2(slbfee_, "slbfee.", 0x1F, 0x13, 0x1E, 0x001F0000, PPC_SEGMENT_64B),
-#endif
-GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
-/* XXX Those instructions will need to be handled differently for
- * different ISA versions */
-GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x001F0001, PPC_MEM_TLBIE),
-GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x001F0001, PPC_MEM_TLBIE),
-GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
-#if defined(TARGET_PPC64)
-GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x031FFC01, PPC_SLBI),
-GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI),
-#endif
-GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN),
-GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN),
-GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR),
-GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR),
-GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR),
-GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR),
-GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC),
-GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC),
-GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC),
-GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB),
-GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB),
-GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB),
-GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB),
-GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER),
-GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER),
-GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER),
-GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER),
-GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER),
-GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER),
-GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
-GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
-GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2),
-GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2),
-GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
-GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
-GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2),
-GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2),
-GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI),
-GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA),
-GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR),
-GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR),
-GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX),
-GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX),
-GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX),
-GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX),
-GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON),
-GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON),
-GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT),
-GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON),
-GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON),
-GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP),
-GEN_HANDLER_E(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE, PPC2_BOOKE206),
-GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI),
-GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI),
-GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB),
-GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB),
-GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB),
-GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE),
-GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE),
-GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE),
-GEN_HANDLER2_E(tlbre_booke206, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001,
- PPC_NONE, PPC2_BOOKE206),
-GEN_HANDLER2_E(tlbsx_booke206, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000,
- PPC_NONE, PPC2_BOOKE206),
-GEN_HANDLER2_E(tlbwe_booke206, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001,
- PPC_NONE, PPC2_BOOKE206),
-GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001,
- PPC_NONE, PPC2_BOOKE206),
-GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001,
- PPC_NONE, PPC2_BOOKE206),
-GEN_HANDLER2_E(msgsnd, "msgsnd", 0x1F, 0x0E, 0x06, 0x03ff0001,
- PPC_NONE, PPC2_PRCNTL),
-GEN_HANDLER2_E(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001,
- PPC_NONE, PPC2_PRCNTL),
-GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
-GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
-GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
-GEN_HANDLER_E(mbar, 0x1F, 0x16, 0x1a, 0x001FF801,
- PPC_BOOKE, PPC2_BOOKE206),
-GEN_HANDLER(msync_4xx, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE),
-GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001,
- PPC_BOOKE, PPC2_BOOKE206),
-GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC),
-GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC),
-GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
-GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
-GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC),
-#if defined(TARGET_PPC64)
-GEN_HANDLER_E(maddhd_maddhdu, 0x04, 0x18, 0xFF, 0x00000000, PPC_NONE,
- PPC2_ISA300),
-GEN_HANDLER_E(maddld, 0x04, 0x19, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA300),
-#endif
-
-#undef GEN_INT_ARITH_ADD
-#undef GEN_INT_ARITH_ADD_CONST
-#define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov) \
-GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER),
-#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val, \
- add_ca, compute_ca, compute_ov) \
-GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER),
-GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
-GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
-GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
-GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
-GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
-GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
-GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
-GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
-GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
-GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
-
-#undef GEN_INT_ARITH_DIVW
-#define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov) \
-GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)
-GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0),
-GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1),
-GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0),
-GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1),
-GEN_HANDLER_E(divwe, 0x1F, 0x0B, 0x0D, 0, PPC_NONE, PPC2_DIVE_ISA206),
-GEN_HANDLER_E(divweo, 0x1F, 0x0B, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206),
-GEN_HANDLER_E(divweu, 0x1F, 0x0B, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
-GEN_HANDLER_E(divweuo, 0x1F, 0x0B, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
-GEN_HANDLER_E(modsw, 0x1F, 0x0B, 0x18, 0x00000001, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E(moduw, 0x1F, 0x0B, 0x08, 0x00000001, PPC_NONE, PPC2_ISA300),
-
-#if defined(TARGET_PPC64)
-#undef GEN_INT_ARITH_DIVD
-#define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov) \
-GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
-GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0),
-GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1),
-GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0),
-GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
-
-GEN_HANDLER_E(divdeu, 0x1F, 0x09, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
-GEN_HANDLER_E(divdeuo, 0x1F, 0x09, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
-GEN_HANDLER_E(divde, 0x1F, 0x09, 0x0D, 0, PPC_NONE, PPC2_DIVE_ISA206),
-GEN_HANDLER_E(divdeo, 0x1F, 0x09, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206),
-GEN_HANDLER_E(modsd, 0x1F, 0x09, 0x18, 0x00000001, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E(modud, 0x1F, 0x09, 0x08, 0x00000001, PPC_NONE, PPC2_ISA300),
-
-#undef GEN_INT_ARITH_MUL_HELPER
-#define GEN_INT_ARITH_MUL_HELPER(name, opc3) \
-GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
-GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00),
-GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02),
-GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17),
-#endif
-
-#undef GEN_INT_ARITH_SUBF
-#undef GEN_INT_ARITH_SUBF_CONST
-#define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov) \
-GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER),
-#define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val, \
- add_ca, compute_ca, compute_ov) \
-GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER),
-GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
-GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
-GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
-GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
-GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
-GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
-GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
-GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
-GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
-GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
-
-#undef GEN_LOGICAL1
-#undef GEN_LOGICAL2
-#define GEN_LOGICAL2(name, tcg_op, opc, type) \
-GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)
-#define GEN_LOGICAL1(name, tcg_op, opc, type) \
-GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)
-GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER),
-GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER),
-GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER),
-GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER),
-GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER),
-GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER),
-GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER),
-GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER),
-#if defined(TARGET_PPC64)
-GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B),
-#endif
-
-#if defined(TARGET_PPC64)
-#undef GEN_PPC64_R2
-#undef GEN_PPC64_R4
-#define GEN_PPC64_R2(name, opc1, opc2) \
-GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
-GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000, \
- PPC_64B)
-#define GEN_PPC64_R4(name, opc1, opc2) \
-GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
-GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000, \
- PPC_64B), \
-GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000, \
- PPC_64B), \
-GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000, \
- PPC_64B)
-GEN_PPC64_R4(rldicl, 0x1E, 0x00),
-GEN_PPC64_R4(rldicr, 0x1E, 0x02),
-GEN_PPC64_R4(rldic, 0x1E, 0x04),
-GEN_PPC64_R2(rldcl, 0x1E, 0x08),
-GEN_PPC64_R2(rldcr, 0x1E, 0x09),
-GEN_PPC64_R4(rldimi, 0x1E, 0x06),
-#endif
-
-#undef GEN_LD
-#undef GEN_LDU
-#undef GEN_LDUX
-#undef GEN_LDX_E
-#undef GEN_LDS
-#define GEN_LD(name, ldop, opc, type) \
-GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
-#define GEN_LDU(name, ldop, opc, type) \
-GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
-#define GEN_LDUX(name, ldop, opc2, opc3, type) \
-GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
-#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk) \
-GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
-#define GEN_LDS(name, ldop, op, type) \
-GEN_LD(name, ldop, op | 0x20, type) \
-GEN_LDU(name, ldop, op | 0x21, type) \
-GEN_LDUX(name, ldop, 0x17, op | 0x01, type) \
-GEN_LDX(name, ldop, 0x17, op | 0x00, type)
-
-GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER)
-GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER)
-GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER)
-GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER)
-#if defined(TARGET_PPC64)
-GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
-GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
-GEN_LDUX(ld, ld64_i64, 0x15, 0x01, PPC_64B)
-GEN_LDX(ld, ld64_i64, 0x15, 0x00, PPC_64B)
-GEN_LDX_E(ldbr, ld64ur_i64, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE)
-
-/* HV/P7 and later only */
-GEN_LDX_HVRM(ldcix, ld64_i64, 0x15, 0x1b, PPC_CILDST)
-GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x18, PPC_CILDST)
-GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
-GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
-#endif
-GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
-GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
-
-#undef GEN_ST
-#undef GEN_STU
-#undef GEN_STUX
-#undef GEN_STX_E
-#undef GEN_STS
-#define GEN_ST(name, stop, opc, type) \
-GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
-#define GEN_STU(name, stop, opc, type) \
-GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
-#define GEN_STUX(name, stop, opc2, opc3, type) \
-GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
-#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk) \
-GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
-#define GEN_STS(name, stop, op, type) \
-GEN_ST(name, stop, op | 0x20, type) \
-GEN_STU(name, stop, op | 0x21, type) \
-GEN_STUX(name, stop, 0x17, op | 0x01, type) \
-GEN_STX(name, stop, 0x17, op | 0x00, type)
-
-GEN_STS(stb, st8, 0x06, PPC_INTEGER)
-GEN_STS(sth, st16, 0x0C, PPC_INTEGER)
-GEN_STS(stw, st32, 0x04, PPC_INTEGER)
-#if defined(TARGET_PPC64)
-GEN_STUX(std, st64_i64, 0x15, 0x05, PPC_64B)
-GEN_STX(std, st64_i64, 0x15, 0x04, PPC_64B)
-GEN_STX_E(stdbr, st64r_i64, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE)
-GEN_STX_HVRM(stdcix, st64_i64, 0x15, 0x1f, PPC_CILDST)
-GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
-GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
-GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
-#endif
-GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
-GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
-
-#undef GEN_CRLOGIC
-#define GEN_CRLOGIC(name, tcg_op, opc) \
-GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)
-GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08),
-GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04),
-GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09),
-GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07),
-GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01),
-GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E),
-GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D),
-GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06),
-
-#undef GEN_MAC_HANDLER
-#define GEN_MAC_HANDLER(name, opc2, opc3) \
-GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)
-GEN_MAC_HANDLER(macchw, 0x0C, 0x05),
-GEN_MAC_HANDLER(macchwo, 0x0C, 0x15),
-GEN_MAC_HANDLER(macchws, 0x0C, 0x07),
-GEN_MAC_HANDLER(macchwso, 0x0C, 0x17),
-GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06),
-GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16),
-GEN_MAC_HANDLER(macchwu, 0x0C, 0x04),
-GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14),
-GEN_MAC_HANDLER(machhw, 0x0C, 0x01),
-GEN_MAC_HANDLER(machhwo, 0x0C, 0x11),
-GEN_MAC_HANDLER(machhws, 0x0C, 0x03),
-GEN_MAC_HANDLER(machhwso, 0x0C, 0x13),
-GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02),
-GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12),
-GEN_MAC_HANDLER(machhwu, 0x0C, 0x00),
-GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10),
-GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D),
-GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D),
-GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F),
-GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F),
-GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C),
-GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C),
-GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E),
-GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E),
-GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05),
-GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15),
-GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07),
-GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17),
-GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01),
-GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11),
-GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03),
-GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13),
-GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D),
-GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D),
-GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F),
-GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F),
-GEN_MAC_HANDLER(mulchw, 0x08, 0x05),
-GEN_MAC_HANDLER(mulchwu, 0x08, 0x04),
-GEN_MAC_HANDLER(mulhhw, 0x08, 0x01),
-GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00),
-GEN_MAC_HANDLER(mullhw, 0x08, 0x0D),
-GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C),
-
-GEN_HANDLER2_E(tbegin, "tbegin", 0x1F, 0x0E, 0x14, 0x01DFF800, \
- PPC_NONE, PPC2_TM),
-GEN_HANDLER2_E(tend, "tend", 0x1F, 0x0E, 0x15, 0x01FFF800, \
- PPC_NONE, PPC2_TM),
-GEN_HANDLER2_E(tabort, "tabort", 0x1F, 0x0E, 0x1C, 0x03E0F800, \
- PPC_NONE, PPC2_TM),
-GEN_HANDLER2_E(tabortwc, "tabortwc", 0x1F, 0x0E, 0x18, 0x00000000, \
- PPC_NONE, PPC2_TM),
-GEN_HANDLER2_E(tabortwci, "tabortwci", 0x1F, 0x0E, 0x1A, 0x00000000, \
- PPC_NONE, PPC2_TM),
-GEN_HANDLER2_E(tabortdc, "tabortdc", 0x1F, 0x0E, 0x19, 0x00000000, \
- PPC_NONE, PPC2_TM),
-GEN_HANDLER2_E(tabortdci, "tabortdci", 0x1F, 0x0E, 0x1B, 0x00000000, \
- PPC_NONE, PPC2_TM),
-GEN_HANDLER2_E(tsr, "tsr", 0x1F, 0x0E, 0x17, 0x03DFF800, \
- PPC_NONE, PPC2_TM),
-GEN_HANDLER2_E(tcheck, "tcheck", 0x1F, 0x0E, 0x16, 0x007FF800, \
- PPC_NONE, PPC2_TM),
-GEN_HANDLER2_E(treclaim, "treclaim", 0x1F, 0x0E, 0x1D, 0x03E0F800, \
- PPC_NONE, PPC2_TM),
-GEN_HANDLER2_E(trechkpt, "trechkpt", 0x1F, 0x0E, 0x1F, 0x03FFF800, \
- PPC_NONE, PPC2_TM),
-
-#include "translate/fp-ops.inc.c"
-
-#include "translate/vmx-ops.inc.c"
-
-#include "translate/vsx-ops.inc.c"
-
-#include "translate/dfp-ops.inc.c"
-
-#include "translate/spe-ops.inc.c"
-};
-
-#include "helper_regs.h"
-#include "translate_init.c"
-
-/*****************************************************************************/
-/* Misc PowerPC helpers */
-void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
- int flags)
-{
-#define RGPL 4
-#define RFPL 4
-
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- int i;
-
- cpu_fprintf(f, "NIP " TARGET_FMT_lx " LR " TARGET_FMT_lx " CTR "
- TARGET_FMT_lx " XER " TARGET_FMT_lx " CPU#%d\n",
- env->nip, env->lr, env->ctr, cpu_read_xer(env),
- cs->cpu_index);
- cpu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx " HF "
- TARGET_FMT_lx " iidx %d didx %d\n",
- env->msr, env->spr[SPR_HID0],
- env->hflags, env->immu_idx, env->dmmu_idx);
-#if !defined(NO_TIMER_DUMP)
- cpu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
-#if !defined(CONFIG_USER_ONLY)
- " DECR %08" PRIu32
-#endif
- "\n",
- cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
-#if !defined(CONFIG_USER_ONLY)
- , cpu_ppc_load_decr(env)
-#endif
- );
-#endif
- for (i = 0; i < 32; i++) {
- if ((i & (RGPL - 1)) == 0)
- cpu_fprintf(f, "GPR%02d", i);
- cpu_fprintf(f, " %016" PRIx64, ppc_dump_gpr(env, i));
- if ((i & (RGPL - 1)) == (RGPL - 1))
- cpu_fprintf(f, "\n");
- }
- cpu_fprintf(f, "CR ");
- for (i = 0; i < 8; i++)
- cpu_fprintf(f, "%01x", env->crf[i]);
- cpu_fprintf(f, " [");
- for (i = 0; i < 8; i++) {
- char a = '-';
- if (env->crf[i] & 0x08)
- a = 'L';
- else if (env->crf[i] & 0x04)
- a = 'G';
- else if (env->crf[i] & 0x02)
- a = 'E';
- cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
- }
- cpu_fprintf(f, " ] RES " TARGET_FMT_lx "\n",
- env->reserve_addr);
- for (i = 0; i < 32; i++) {
- if ((i & (RFPL - 1)) == 0)
- cpu_fprintf(f, "FPR%02d", i);
- cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
- if ((i & (RFPL - 1)) == (RFPL - 1))
- cpu_fprintf(f, "\n");
- }
- cpu_fprintf(f, "FPSCR " TARGET_FMT_lx "\n", env->fpscr);
-#if !defined(CONFIG_USER_ONLY)
- cpu_fprintf(f, " SRR0 " TARGET_FMT_lx " SRR1 " TARGET_FMT_lx
- " PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n",
- env->spr[SPR_SRR0], env->spr[SPR_SRR1],
- env->spr[SPR_PVR], env->spr[SPR_VRSAVE]);
-
- cpu_fprintf(f, "SPRG0 " TARGET_FMT_lx " SPRG1 " TARGET_FMT_lx
- " SPRG2 " TARGET_FMT_lx " SPRG3 " TARGET_FMT_lx "\n",
- env->spr[SPR_SPRG0], env->spr[SPR_SPRG1],
- env->spr[SPR_SPRG2], env->spr[SPR_SPRG3]);
-
- cpu_fprintf(f, "SPRG4 " TARGET_FMT_lx " SPRG5 " TARGET_FMT_lx
- " SPRG6 " TARGET_FMT_lx " SPRG7 " TARGET_FMT_lx "\n",
- env->spr[SPR_SPRG4], env->spr[SPR_SPRG5],
- env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]);
-
-#if defined(TARGET_PPC64)
- if (env->excp_model == POWERPC_EXCP_POWER7 ||
- env->excp_model == POWERPC_EXCP_POWER8) {
- cpu_fprintf(f, "HSRR0 " TARGET_FMT_lx " HSRR1 " TARGET_FMT_lx "\n",
- env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
- }
-#endif
- if (env->excp_model == POWERPC_EXCP_BOOKE) {
- cpu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx
- " MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n",
- env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
- env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
-
- cpu_fprintf(f, " TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx
- " ESR " TARGET_FMT_lx " DEAR " TARGET_FMT_lx "\n",
- env->spr[SPR_BOOKE_TCR], env->spr[SPR_BOOKE_TSR],
- env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
-
- cpu_fprintf(f, " PIR " TARGET_FMT_lx " DECAR " TARGET_FMT_lx
- " IVPR " TARGET_FMT_lx " EPCR " TARGET_FMT_lx "\n",
- env->spr[SPR_BOOKE_PIR], env->spr[SPR_BOOKE_DECAR],
- env->spr[SPR_BOOKE_IVPR], env->spr[SPR_BOOKE_EPCR]);
-
- cpu_fprintf(f, " MCSR " TARGET_FMT_lx " SPRG8 " TARGET_FMT_lx
- " EPR " TARGET_FMT_lx "\n",
- env->spr[SPR_BOOKE_MCSR], env->spr[SPR_BOOKE_SPRG8],
- env->spr[SPR_BOOKE_EPR]);
-
- /* FSL-specific */
- cpu_fprintf(f, " MCAR " TARGET_FMT_lx " PID1 " TARGET_FMT_lx
- " PID2 " TARGET_FMT_lx " SVR " TARGET_FMT_lx "\n",
- env->spr[SPR_Exxx_MCAR], env->spr[SPR_BOOKE_PID1],
- env->spr[SPR_BOOKE_PID2], env->spr[SPR_E500_SVR]);
-
- /*
- * IVORs are left out as they are large and do not change often --
- * they can be read with "p $ivor0", "p $ivor1", etc.
- */
- }
-
-#if defined(TARGET_PPC64)
- if (env->flags & POWERPC_FLAG_CFAR) {
- cpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);
- }
-#endif
-
- switch (env->mmu_model) {
- case POWERPC_MMU_32B:
- case POWERPC_MMU_601:
- case POWERPC_MMU_SOFT_6xx:
- case POWERPC_MMU_SOFT_74xx:
-#if defined(TARGET_PPC64)
- case POWERPC_MMU_64B:
- case POWERPC_MMU_2_03:
- case POWERPC_MMU_2_06:
- case POWERPC_MMU_2_06a:
- case POWERPC_MMU_2_07:
- case POWERPC_MMU_2_07a:
-#endif
- cpu_fprintf(f, " SDR1 " TARGET_FMT_lx " DAR " TARGET_FMT_lx
- " DSISR " TARGET_FMT_lx "\n", env->spr[SPR_SDR1],
- env->spr[SPR_DAR], env->spr[SPR_DSISR]);
- break;
- case POWERPC_MMU_BOOKE206:
- cpu_fprintf(f, " MAS0 " TARGET_FMT_lx " MAS1 " TARGET_FMT_lx
- " MAS2 " TARGET_FMT_lx " MAS3 " TARGET_FMT_lx "\n",
- env->spr[SPR_BOOKE_MAS0], env->spr[SPR_BOOKE_MAS1],
- env->spr[SPR_BOOKE_MAS2], env->spr[SPR_BOOKE_MAS3]);
-
- cpu_fprintf(f, " MAS4 " TARGET_FMT_lx " MAS6 " TARGET_FMT_lx
- " MAS7 " TARGET_FMT_lx " PID " TARGET_FMT_lx "\n",
- env->spr[SPR_BOOKE_MAS4], env->spr[SPR_BOOKE_MAS6],
- env->spr[SPR_BOOKE_MAS7], env->spr[SPR_BOOKE_PID]);
-
- cpu_fprintf(f, "MMUCFG " TARGET_FMT_lx " TLB0CFG " TARGET_FMT_lx
- " TLB1CFG " TARGET_FMT_lx "\n",
- env->spr[SPR_MMUCFG], env->spr[SPR_BOOKE_TLB0CFG],
- env->spr[SPR_BOOKE_TLB1CFG]);
- break;
- default:
- break;
- }
-#endif
-
-#undef RGPL
-#undef RFPL
-}
-
-void ppc_cpu_dump_statistics(CPUState *cs, FILE*f,
- fprintf_function cpu_fprintf, int flags)
-{
-#if defined(DO_PPC_STATISTICS)
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- opc_handler_t **t1, **t2, **t3, *handler;
- int op1, op2, op3;
-
- t1 = cpu->env.opcodes;
- for (op1 = 0; op1 < 64; op1++) {
- handler = t1[op1];
- if (is_indirect_opcode(handler)) {
- t2 = ind_table(handler);
- for (op2 = 0; op2 < 32; op2++) {
- handler = t2[op2];
- if (is_indirect_opcode(handler)) {
- t3 = ind_table(handler);
- for (op3 = 0; op3 < 32; op3++) {
- handler = t3[op3];
- if (handler->count == 0)
- continue;
- cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
- "%016" PRIx64 " %" PRId64 "\n",
- op1, op2, op3, op1, (op3 << 5) | op2,
- handler->oname,
- handler->count, handler->count);
- }
- } else {
- if (handler->count == 0)
- continue;
- cpu_fprintf(f, "%02x %02x (%02x %04d) %16s: "
- "%016" PRIx64 " %" PRId64 "\n",
- op1, op2, op1, op2, handler->oname,
- handler->count, handler->count);
- }
- }
- } else {
- if (handler->count == 0)
- continue;
- cpu_fprintf(f, "%02x (%02x ) %16s: %016" PRIx64
- " %" PRId64 "\n",
- op1, op1, handler->oname,
- handler->count, handler->count);
- }
- }
-#endif
-}
-
-/*****************************************************************************/
-void gen_intermediate_code(CPUPPCState *env, struct TranslationBlock *tb)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- CPUState *cs = CPU(cpu);
- DisasContext ctx, *ctxp = &ctx;
- opc_handler_t **table, *handler;
- target_ulong pc_start;
- int num_insns;
- int max_insns;
-
- pc_start = tb->pc;
- ctx.nip = pc_start;
- ctx.tb = tb;
- ctx.exception = POWERPC_EXCP_NONE;
- ctx.spr_cb = env->spr_cb;
- ctx.pr = msr_pr;
- ctx.mem_idx = env->dmmu_idx;
- ctx.dr = msr_dr;
-#if !defined(CONFIG_USER_ONLY)
- ctx.hv = msr_hv || !env->has_hv_mode;
-#endif
- ctx.insns_flags = env->insns_flags;
- ctx.insns_flags2 = env->insns_flags2;
- ctx.access_type = -1;
- ctx.need_access_type = !(env->mmu_model & POWERPC_MMU_64B);
- ctx.le_mode = !!(env->hflags & (1 << MSR_LE));
- ctx.default_tcg_memop_mask = ctx.le_mode ? MO_LE : MO_BE;
-#if defined(TARGET_PPC64)
- ctx.sf_mode = msr_is_64bit(env, env->msr);
- ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
-#endif
- if (env->mmu_model == POWERPC_MMU_32B ||
- env->mmu_model == POWERPC_MMU_601 ||
- (env->mmu_model & POWERPC_MMU_64B))
- ctx.lazy_tlb_flush = true;
-
- ctx.fpu_enabled = !!msr_fp;
- if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
- ctx.spe_enabled = !!msr_spe;
- else
- ctx.spe_enabled = false;
- if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
- ctx.altivec_enabled = !!msr_vr;
- else
- ctx.altivec_enabled = false;
- if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) {
- ctx.vsx_enabled = !!msr_vsx;
- } else {
- ctx.vsx_enabled = false;
- }
-#if defined(TARGET_PPC64)
- if ((env->flags & POWERPC_FLAG_TM) && msr_tm) {
- ctx.tm_enabled = !!msr_tm;
- } else {
- ctx.tm_enabled = false;
- }
-#endif
- if ((env->flags & POWERPC_FLAG_SE) && msr_se)
- ctx.singlestep_enabled = CPU_SINGLE_STEP;
- else
- ctx.singlestep_enabled = 0;
- if ((env->flags & POWERPC_FLAG_BE) && msr_be)
- ctx.singlestep_enabled |= CPU_BRANCH_STEP;
- if (unlikely(cs->singlestep_enabled)) {
- ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
- }
-#if defined (DO_SINGLE_STEP) && 0
- /* Single step trace mode */
- msr_se = 1;
-#endif
- num_insns = 0;
- max_insns = tb->cflags & CF_COUNT_MASK;
- if (max_insns == 0) {
- max_insns = CF_COUNT_MASK;
- }
- if (max_insns > TCG_MAX_INSNS) {
- max_insns = TCG_MAX_INSNS;
- }
-
- gen_tb_start(tb);
- tcg_clear_temp_count();
- /* Set env in case of segfault during code fetch */
- while (ctx.exception == POWERPC_EXCP_NONE && !tcg_op_buf_full()) {
- tcg_gen_insn_start(ctx.nip);
- num_insns++;
-
- if (unlikely(cpu_breakpoint_test(cs, ctx.nip, BP_ANY))) {
- gen_debug_exception(ctxp);
- /* The address covered by the breakpoint must be included in
- [tb->pc, tb->pc + tb->size) in order to for it to be
- properly cleared -- thus we increment the PC here so that
- the logic setting tb->size below does the right thing. */
- ctx.nip += 4;
- break;
- }
-
- LOG_DISAS("----------------\n");
- LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
- ctx.nip, ctx.mem_idx, (int)msr_ir);
- if (num_insns == max_insns && (tb->cflags & CF_LAST_IO))
- gen_io_start();
- if (unlikely(need_byteswap(&ctx))) {
- ctx.opcode = bswap32(cpu_ldl_code(env, ctx.nip));
- } else {
- ctx.opcode = cpu_ldl_code(env, ctx.nip);
- }
- LOG_DISAS("translate opcode %08x (%02x %02x %02x %02x) (%s)\n",
- ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
- opc3(ctx.opcode), opc4(ctx.opcode),
- ctx.le_mode ? "little" : "big");
- ctx.nip += 4;
- table = env->opcodes;
- handler = table[opc1(ctx.opcode)];
- if (is_indirect_opcode(handler)) {
- table = ind_table(handler);
- handler = table[opc2(ctx.opcode)];
- if (is_indirect_opcode(handler)) {
- table = ind_table(handler);
- handler = table[opc3(ctx.opcode)];
- if (is_indirect_opcode(handler)) {
- table = ind_table(handler);
- handler = table[opc4(ctx.opcode)];
- }
- }
- }
- /* Is opcode *REALLY* valid ? */
- if (unlikely(handler->handler == &gen_invalid)) {
- qemu_log_mask(LOG_GUEST_ERROR, "invalid/unsupported opcode: "
- "%02x - %02x - %02x - %02x (%08x) "
- TARGET_FMT_lx " %d\n",
- opc1(ctx.opcode), opc2(ctx.opcode),
- opc3(ctx.opcode), opc4(ctx.opcode),
- ctx.opcode, ctx.nip - 4, (int)msr_ir);
- } else {
- uint32_t inval;
-
- if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE) && Rc(ctx.opcode))) {
- inval = handler->inval2;
- } else {
- inval = handler->inval1;
- }
-
- if (unlikely((ctx.opcode & inval) != 0)) {
- qemu_log_mask(LOG_GUEST_ERROR, "invalid bits: %08x for opcode: "
- "%02x - %02x - %02x - %02x (%08x) "
- TARGET_FMT_lx "\n", ctx.opcode & inval,
- opc1(ctx.opcode), opc2(ctx.opcode),
- opc3(ctx.opcode), opc4(ctx.opcode),
- ctx.opcode, ctx.nip - 4);
- gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
- break;
- }
- }
- (*(handler->handler))(&ctx);
-#if defined(DO_PPC_STATISTICS)
- handler->count++;
-#endif
- /* Check trace mode exceptions */
- if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
- (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
- ctx.exception != POWERPC_SYSCALL &&
- ctx.exception != POWERPC_EXCP_TRAP &&
- ctx.exception != POWERPC_EXCP_BRANCH)) {
- gen_exception_nip(ctxp, POWERPC_EXCP_TRACE, ctx.nip);
- } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
- (cs->singlestep_enabled) ||
- singlestep ||
- num_insns >= max_insns)) {
- /* if we reach a page boundary or are single stepping, stop
- * generation
- */
- break;
- }
- if (tcg_check_temp_count()) {
- fprintf(stderr, "Opcode %02x %02x %02x %02x (%08x) leaked "
- "temporaries\n", opc1(ctx.opcode), opc2(ctx.opcode),
- opc3(ctx.opcode), opc4(ctx.opcode), ctx.opcode);
- exit(1);
- }
- }
- if (tb->cflags & CF_LAST_IO)
- gen_io_end();
- if (ctx.exception == POWERPC_EXCP_NONE) {
- gen_goto_tb(&ctx, 0, ctx.nip);
- } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
- if (unlikely(cs->singlestep_enabled)) {
- gen_debug_exception(ctxp);
- }
- /* Generate the return instruction */
- tcg_gen_exit_tb(0);
- }
- gen_tb_end(tb, num_insns);
-
- tb->size = ctx.nip - pc_start;
- tb->icount = num_insns;
-
-#if defined(DEBUG_DISAS)
- if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
- && qemu_log_in_addr_range(pc_start)) {
- int flags;
- flags = env->bfd_mach;
- flags |= ctx.le_mode << 16;
- qemu_log_lock();
- qemu_log("IN: %s\n", lookup_symbol(pc_start));
- log_target_disas(cs, pc_start, ctx.nip - pc_start, flags);
- qemu_log("\n");
- qemu_log_unlock();
- }
-#endif
-}
-
-void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb,
- target_ulong *data)
-{
- env->nip = data[0];
-}
diff --git a/target-ppc/translate/dfp-impl.inc.c b/target-ppc/translate/dfp-impl.inc.c
deleted file mode 100644
index 178d3044a7..0000000000
--- a/target-ppc/translate/dfp-impl.inc.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*** Decimal Floating Point ***/
-
-static inline TCGv_ptr gen_fprp_ptr(int reg)
-{
- TCGv_ptr r = tcg_temp_new_ptr();
- tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, fpr[reg]));
- return r;
-}
-
-#define GEN_DFP_T_A_B_Rc(name) \
-static void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_ptr rd, ra, rb; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_update_nip(ctx, ctx->nip - 4); \
- rd = gen_fprp_ptr(rD(ctx->opcode)); \
- ra = gen_fprp_ptr(rA(ctx->opcode)); \
- rb = gen_fprp_ptr(rB(ctx->opcode)); \
- gen_helper_##name(cpu_env, rd, ra, rb); \
- if (unlikely(Rc(ctx->opcode) != 0)) { \
- gen_set_cr1_from_fpscr(ctx); \
- } \
- tcg_temp_free_ptr(rd); \
- tcg_temp_free_ptr(ra); \
- tcg_temp_free_ptr(rb); \
-}
-
-#define GEN_DFP_BF_A_B(name) \
-static void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_ptr ra, rb; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_update_nip(ctx, ctx->nip - 4); \
- ra = gen_fprp_ptr(rA(ctx->opcode)); \
- rb = gen_fprp_ptr(rB(ctx->opcode)); \
- gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
- cpu_env, ra, rb); \
- tcg_temp_free_ptr(ra); \
- tcg_temp_free_ptr(rb); \
-}
-
-#define GEN_DFP_BF_I_B(name) \
-static void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_i32 uim; \
- TCGv_ptr rb; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_update_nip(ctx, ctx->nip - 4); \
- uim = tcg_const_i32(UIMM5(ctx->opcode)); \
- rb = gen_fprp_ptr(rB(ctx->opcode)); \
- gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
- cpu_env, uim, rb); \
- tcg_temp_free_i32(uim); \
- tcg_temp_free_ptr(rb); \
-}
-
-#define GEN_DFP_BF_A_DCM(name) \
-static void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_ptr ra; \
- TCGv_i32 dcm; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_update_nip(ctx, ctx->nip - 4); \
- ra = gen_fprp_ptr(rA(ctx->opcode)); \
- dcm = tcg_const_i32(DCM(ctx->opcode)); \
- gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
- cpu_env, ra, dcm); \
- tcg_temp_free_ptr(ra); \
- tcg_temp_free_i32(dcm); \
-}
-
-#define GEN_DFP_T_B_U32_U32_Rc(name, u32f1, u32f2) \
-static void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_ptr rt, rb; \
- TCGv_i32 u32_1, u32_2; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_update_nip(ctx, ctx->nip - 4); \
- rt = gen_fprp_ptr(rD(ctx->opcode)); \
- rb = gen_fprp_ptr(rB(ctx->opcode)); \
- u32_1 = tcg_const_i32(u32f1(ctx->opcode)); \
- u32_2 = tcg_const_i32(u32f2(ctx->opcode)); \
- gen_helper_##name(cpu_env, rt, rb, u32_1, u32_2); \
- if (unlikely(Rc(ctx->opcode) != 0)) { \
- gen_set_cr1_from_fpscr(ctx); \
- } \
- tcg_temp_free_ptr(rt); \
- tcg_temp_free_ptr(rb); \
- tcg_temp_free_i32(u32_1); \
- tcg_temp_free_i32(u32_2); \
-}
-
-#define GEN_DFP_T_A_B_I32_Rc(name, i32fld) \
-static void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_ptr rt, ra, rb; \
- TCGv_i32 i32; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_update_nip(ctx, ctx->nip - 4); \
- rt = gen_fprp_ptr(rD(ctx->opcode)); \
- ra = gen_fprp_ptr(rA(ctx->opcode)); \
- rb = gen_fprp_ptr(rB(ctx->opcode)); \
- i32 = tcg_const_i32(i32fld(ctx->opcode)); \
- gen_helper_##name(cpu_env, rt, ra, rb, i32); \
- if (unlikely(Rc(ctx->opcode) != 0)) { \
- gen_set_cr1_from_fpscr(ctx); \
- } \
- tcg_temp_free_ptr(rt); \
- tcg_temp_free_ptr(rb); \
- tcg_temp_free_ptr(ra); \
- tcg_temp_free_i32(i32); \
- }
-
-#define GEN_DFP_T_B_Rc(name) \
-static void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_ptr rt, rb; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_update_nip(ctx, ctx->nip - 4); \
- rt = gen_fprp_ptr(rD(ctx->opcode)); \
- rb = gen_fprp_ptr(rB(ctx->opcode)); \
- gen_helper_##name(cpu_env, rt, rb); \
- if (unlikely(Rc(ctx->opcode) != 0)) { \
- gen_set_cr1_from_fpscr(ctx); \
- } \
- tcg_temp_free_ptr(rt); \
- tcg_temp_free_ptr(rb); \
- }
-
-#define GEN_DFP_T_FPR_I32_Rc(name, fprfld, i32fld) \
-static void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_ptr rt, rs; \
- TCGv_i32 i32; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_update_nip(ctx, ctx->nip - 4); \
- rt = gen_fprp_ptr(rD(ctx->opcode)); \
- rs = gen_fprp_ptr(fprfld(ctx->opcode)); \
- i32 = tcg_const_i32(i32fld(ctx->opcode)); \
- gen_helper_##name(cpu_env, rt, rs, i32); \
- if (unlikely(Rc(ctx->opcode) != 0)) { \
- gen_set_cr1_from_fpscr(ctx); \
- } \
- tcg_temp_free_ptr(rt); \
- tcg_temp_free_ptr(rs); \
- tcg_temp_free_i32(i32); \
-}
-
-GEN_DFP_T_A_B_Rc(dadd)
-GEN_DFP_T_A_B_Rc(daddq)
-GEN_DFP_T_A_B_Rc(dsub)
-GEN_DFP_T_A_B_Rc(dsubq)
-GEN_DFP_T_A_B_Rc(dmul)
-GEN_DFP_T_A_B_Rc(dmulq)
-GEN_DFP_T_A_B_Rc(ddiv)
-GEN_DFP_T_A_B_Rc(ddivq)
-GEN_DFP_BF_A_B(dcmpu)
-GEN_DFP_BF_A_B(dcmpuq)
-GEN_DFP_BF_A_B(dcmpo)
-GEN_DFP_BF_A_B(dcmpoq)
-GEN_DFP_BF_A_DCM(dtstdc)
-GEN_DFP_BF_A_DCM(dtstdcq)
-GEN_DFP_BF_A_DCM(dtstdg)
-GEN_DFP_BF_A_DCM(dtstdgq)
-GEN_DFP_BF_A_B(dtstex)
-GEN_DFP_BF_A_B(dtstexq)
-GEN_DFP_BF_A_B(dtstsf)
-GEN_DFP_BF_A_B(dtstsfq)
-GEN_DFP_BF_I_B(dtstsfi)
-GEN_DFP_BF_I_B(dtstsfiq)
-GEN_DFP_T_B_U32_U32_Rc(dquai, SIMM5, RMC)
-GEN_DFP_T_B_U32_U32_Rc(dquaiq, SIMM5, RMC)
-GEN_DFP_T_A_B_I32_Rc(dqua, RMC)
-GEN_DFP_T_A_B_I32_Rc(dquaq, RMC)
-GEN_DFP_T_A_B_I32_Rc(drrnd, RMC)
-GEN_DFP_T_A_B_I32_Rc(drrndq, RMC)
-GEN_DFP_T_B_U32_U32_Rc(drintx, FPW, RMC)
-GEN_DFP_T_B_U32_U32_Rc(drintxq, FPW, RMC)
-GEN_DFP_T_B_U32_U32_Rc(drintn, FPW, RMC)
-GEN_DFP_T_B_U32_U32_Rc(drintnq, FPW, RMC)
-GEN_DFP_T_B_Rc(dctdp)
-GEN_DFP_T_B_Rc(dctqpq)
-GEN_DFP_T_B_Rc(drsp)
-GEN_DFP_T_B_Rc(drdpq)
-GEN_DFP_T_B_Rc(dcffix)
-GEN_DFP_T_B_Rc(dcffixq)
-GEN_DFP_T_B_Rc(dctfix)
-GEN_DFP_T_B_Rc(dctfixq)
-GEN_DFP_T_FPR_I32_Rc(ddedpd, rB, SP)
-GEN_DFP_T_FPR_I32_Rc(ddedpdq, rB, SP)
-GEN_DFP_T_FPR_I32_Rc(denbcd, rB, SP)
-GEN_DFP_T_FPR_I32_Rc(denbcdq, rB, SP)
-GEN_DFP_T_B_Rc(dxex)
-GEN_DFP_T_B_Rc(dxexq)
-GEN_DFP_T_A_B_Rc(diex)
-GEN_DFP_T_A_B_Rc(diexq)
-GEN_DFP_T_FPR_I32_Rc(dscli, rA, DCM)
-GEN_DFP_T_FPR_I32_Rc(dscliq, rA, DCM)
-GEN_DFP_T_FPR_I32_Rc(dscri, rA, DCM)
-GEN_DFP_T_FPR_I32_Rc(dscriq, rA, DCM)
-
-#undef GEN_DFP_T_A_B_Rc
-#undef GEN_DFP_BF_A_B
-#undef GEN_DFP_BF_A_DCM
-#undef GEN_DFP_T_B_U32_U32_Rc
-#undef GEN_DFP_T_A_B_I32_Rc
-#undef GEN_DFP_T_B_Rc
-#undef GEN_DFP_T_FPR_I32_Rc
diff --git a/target-ppc/translate/dfp-ops.inc.c b/target-ppc/translate/dfp-ops.inc.c
deleted file mode 100644
index 6ef38e5712..0000000000
--- a/target-ppc/translate/dfp-ops.inc.c
+++ /dev/null
@@ -1,165 +0,0 @@
-#define _GEN_DFP_LONG(name, op1, op2, mask) \
-GEN_HANDLER_E(name, 0x3B, op1, op2, mask, PPC_NONE, PPC2_DFP)
-
-#define _GEN_DFP_LONG_300(name, op1, op2, mask) \
-GEN_HANDLER_E(name, 0x3B, op1, op2, mask, PPC_NONE, PPC2_ISA300)
-
-#define _GEN_DFP_LONGx2(name, op1, op2, mask) \
-GEN_HANDLER_E(name, 0x3B, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
-GEN_HANDLER_E(name, 0x3B, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP)
-
-#define _GEN_DFP_LONGx4(name, op1, op2, mask) \
-GEN_HANDLER_E(name, 0x3B, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
-GEN_HANDLER_E(name, 0x3B, op1, 0x08 | op2, mask, PPC_NONE, PPC2_DFP), \
-GEN_HANDLER_E(name, 0x3B, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP), \
-GEN_HANDLER_E(name, 0x3B, op1, 0x18 | op2, mask, PPC_NONE, PPC2_DFP)
-
-#define _GEN_DFP_QUAD(name, op1, op2, mask) \
-GEN_HANDLER_E(name, 0x3F, op1, op2, mask, PPC_NONE, PPC2_DFP)
-
-#define _GEN_DFP_QUAD_300(name, op1, op2, mask) \
-GEN_HANDLER_E(name, 0x3F, op1, op2, mask, PPC_NONE, PPC2_ISA300)
-
-#define _GEN_DFP_QUADx2(name, op1, op2, mask) \
-GEN_HANDLER_E(name, 0x3F, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
-GEN_HANDLER_E(name, 0x3F, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP)
-
-#define _GEN_DFP_QUADx4(name, op1, op2, mask) \
-GEN_HANDLER_E(name, 0x3F, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
-GEN_HANDLER_E(name, 0x3F, op1, 0x08 | op2, mask, PPC_NONE, PPC2_DFP), \
-GEN_HANDLER_E(name, 0x3F, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP), \
-GEN_HANDLER_E(name, 0x3F, op1, 0x18 | op2, mask, PPC_NONE, PPC2_DFP)
-
-#define GEN_DFP_T_A_B_Rc(name, op1, op2) \
-_GEN_DFP_LONG(name, op1, op2, 0x00000000)
-
-#define GEN_DFP_Tp_Ap_Bp_Rc(name, op1, op2) \
-_GEN_DFP_QUAD(name, op1, op2, 0x00210800)
-
-#define GEN_DFP_Tp_A_Bp_Rc(name, op1, op2) \
-_GEN_DFP_QUAD(name, op1, op2, 0x00200800)
-
-#define GEN_DFP_T_B_Rc(name, op1, op2) \
-_GEN_DFP_LONG(name, op1, op2, 0x001F0000)
-
-#define GEN_DFP_Tp_Bp_Rc(name, op1, op2) \
-_GEN_DFP_QUAD(name, op1, op2, 0x003F0800)
-
-#define GEN_DFP_Tp_B_Rc(name, op1, op2) \
-_GEN_DFP_QUAD(name, op1, op2, 0x003F0000)
-
-#define GEN_DFP_T_Bp_Rc(name, op1, op2) \
-_GEN_DFP_QUAD(name, op1, op2, 0x001F0800)
-
-#define GEN_DFP_BF_A_B(name, op1, op2) \
-_GEN_DFP_LONG(name, op1, op2, 0x00000001)
-
-#define GEN_DFP_BF_A_B_300(name, op1, op2) \
-_GEN_DFP_LONG_300(name, op1, op2, 0x00400001)
-
-#define GEN_DFP_BF_Ap_Bp(name, op1, op2) \
-_GEN_DFP_QUAD(name, op1, op2, 0x00610801)
-
-#define GEN_DFP_BF_A_Bp(name, op1, op2) \
-_GEN_DFP_QUAD(name, op1, op2, 0x00600801)
-
-#define GEN_DFP_BF_A_Bp_300(name, op1, op2) \
-_GEN_DFP_QUAD_300(name, op1, op2, 0x00400001)
-
-#define GEN_DFP_BF_A_DCM(name, op1, op2) \
-_GEN_DFP_LONGx2(name, op1, op2, 0x00600001)
-
-#define GEN_DFP_BF_Ap_DCM(name, op1, op2) \
-_GEN_DFP_QUADx2(name, op1, op2, 0x00610001)
-
-#define GEN_DFP_T_A_B_RMC_Rc(name, op1, op2) \
-_GEN_DFP_LONGx4(name, op1, op2, 0x00000000)
-
-#define GEN_DFP_Tp_Ap_Bp_RMC_Rc(name, op1, op2) \
-_GEN_DFP_QUADx4(name, op1, op2, 0x02010800)
-
-#define GEN_DFP_Tp_A_Bp_RMC_Rc(name, op1, op2) \
-_GEN_DFP_QUADx4(name, op1, op2, 0x02000800)
-
-#define GEN_DFP_TE_T_B_RMC_Rc(name, op1, op2) \
-_GEN_DFP_LONGx4(name, op1, op2, 0x00000000)
-
-#define GEN_DFP_TE_Tp_Bp_RMC_Rc(name, op1, op2) \
-_GEN_DFP_QUADx4(name, op1, op2, 0x00200800)
-
-#define GEN_DFP_R_T_B_RMC_Rc(name, op1, op2) \
-_GEN_DFP_LONGx4(name, op1, op2, 0x001E0000)
-
-#define GEN_DFP_R_Tp_Bp_RMC_Rc(name, op1, op2) \
-_GEN_DFP_QUADx4(name, op1, op2, 0x003E0800)
-
-#define GEN_DFP_SP_T_B_Rc(name, op1, op2) \
-_GEN_DFP_LONG(name, op1, op2, 0x00070000)
-
-#define GEN_DFP_SP_Tp_Bp_Rc(name, op1, op2) \
-_GEN_DFP_QUAD(name, op1, op2, 0x00270800)
-
-#define GEN_DFP_S_T_B_Rc(name, op1, op2) \
-_GEN_DFP_LONG(name, op1, op2, 0x000F0000)
-
-#define GEN_DFP_S_Tp_Bp_Rc(name, op1, op2) \
-_GEN_DFP_QUAD(name, op1, op2, 0x002F0800)
-
-#define GEN_DFP_T_A_SH_Rc(name, op1, op2) \
-_GEN_DFP_LONGx2(name, op1, op2, 0x00000000)
-
-#define GEN_DFP_Tp_Ap_SH_Rc(name, op1, op2) \
-_GEN_DFP_QUADx2(name, op1, op2, 0x00210000)
-
-GEN_DFP_T_A_B_Rc(dadd, 0x02, 0x00),
-GEN_DFP_Tp_Ap_Bp_Rc(daddq, 0x02, 0x00),
-GEN_DFP_T_A_B_Rc(dsub, 0x02, 0x10),
-GEN_DFP_Tp_Ap_Bp_Rc(dsubq, 0x02, 0x10),
-GEN_DFP_T_A_B_Rc(dmul, 0x02, 0x01),
-GEN_DFP_Tp_Ap_Bp_Rc(dmulq, 0x02, 0x01),
-GEN_DFP_T_A_B_Rc(ddiv, 0x02, 0x11),
-GEN_DFP_Tp_Ap_Bp_Rc(ddivq, 0x02, 0x11),
-GEN_DFP_BF_A_B(dcmpu, 0x02, 0x14),
-GEN_DFP_BF_Ap_Bp(dcmpuq, 0x02, 0x14),
-GEN_DFP_BF_A_B(dcmpo, 0x02, 0x04),
-GEN_DFP_BF_Ap_Bp(dcmpoq, 0x02, 0x04),
-GEN_DFP_BF_A_DCM(dtstdc, 0x02, 0x06),
-GEN_DFP_BF_Ap_DCM(dtstdcq, 0x02, 0x06),
-GEN_DFP_BF_A_DCM(dtstdg, 0x02, 0x07),
-GEN_DFP_BF_Ap_DCM(dtstdgq, 0x02, 0x07),
-GEN_DFP_BF_A_B(dtstex, 0x02, 0x05),
-GEN_DFP_BF_Ap_Bp(dtstexq, 0x02, 0x05),
-GEN_DFP_BF_A_B(dtstsf, 0x02, 0x15),
-GEN_DFP_BF_A_Bp(dtstsfq, 0x02, 0x15),
-GEN_DFP_BF_A_B_300(dtstsfi, 0x03, 0x15),
-GEN_DFP_BF_A_Bp_300(dtstsfiq, 0x03, 0x15),
-GEN_DFP_TE_T_B_RMC_Rc(dquai, 0x03, 0x02),
-GEN_DFP_TE_Tp_Bp_RMC_Rc(dquaiq, 0x03, 0x02),
-GEN_DFP_T_A_B_RMC_Rc(dqua, 0x03, 0x00),
-GEN_DFP_Tp_Ap_Bp_RMC_Rc(dquaq, 0x03, 0x00),
-GEN_DFP_T_A_B_RMC_Rc(drrnd, 0x03, 0x01),
-GEN_DFP_Tp_A_Bp_RMC_Rc(drrndq, 0x03, 0x01),
-GEN_DFP_R_T_B_RMC_Rc(drintx, 0x03, 0x03),
-GEN_DFP_R_Tp_Bp_RMC_Rc(drintxq, 0x03, 0x03),
-GEN_DFP_R_T_B_RMC_Rc(drintn, 0x03, 0x07),
-GEN_DFP_R_Tp_Bp_RMC_Rc(drintnq, 0x03, 0x07),
-GEN_DFP_T_B_Rc(dctdp, 0x02, 0x08),
-GEN_DFP_Tp_B_Rc(dctqpq, 0x02, 0x08),
-GEN_DFP_T_B_Rc(drsp, 0x02, 0x18),
-GEN_DFP_Tp_Bp_Rc(drdpq, 0x02, 0x18),
-GEN_DFP_T_B_Rc(dcffix, 0x02, 0x19),
-GEN_DFP_Tp_B_Rc(dcffixq, 0x02, 0x19),
-GEN_DFP_T_B_Rc(dctfix, 0x02, 0x09),
-GEN_DFP_T_Bp_Rc(dctfixq, 0x02, 0x09),
-GEN_DFP_SP_T_B_Rc(ddedpd, 0x02, 0x0a),
-GEN_DFP_SP_Tp_Bp_Rc(ddedpdq, 0x02, 0x0a),
-GEN_DFP_S_T_B_Rc(denbcd, 0x02, 0x1a),
-GEN_DFP_S_Tp_Bp_Rc(denbcdq, 0x02, 0x1a),
-GEN_DFP_T_B_Rc(dxex, 0x02, 0x0b),
-GEN_DFP_T_Bp_Rc(dxexq, 0x02, 0x0b),
-GEN_DFP_T_A_B_Rc(diex, 0x02, 0x1b),
-GEN_DFP_Tp_A_Bp_Rc(diexq, 0x02, 0x1b),
-GEN_DFP_T_A_SH_Rc(dscli, 0x02, 0x02),
-GEN_DFP_Tp_Ap_SH_Rc(dscliq, 0x02, 0x02),
-GEN_DFP_T_A_SH_Rc(dscri, 0x02, 0x03),
-GEN_DFP_Tp_Ap_SH_Rc(dscriq, 0x02, 0x03),
diff --git a/target-ppc/translate/fp-impl.inc.c b/target-ppc/translate/fp-impl.inc.c
deleted file mode 100644
index 872af7b56f..0000000000
--- a/target-ppc/translate/fp-impl.inc.c
+++ /dev/null
@@ -1,1070 +0,0 @@
-/*
- * translate-fp.c
- *
- * Standard FPU translation
- */
-
-static inline void gen_reset_fpstatus(void)
-{
- gen_helper_reset_fpstatus(cpu_env);
-}
-
-static inline void gen_compute_fprf(TCGv_i64 arg)
-{
- gen_helper_compute_fprf(cpu_env, arg);
- gen_helper_float_check_status(cpu_env);
-}
-
-#if defined(TARGET_PPC64)
-static void gen_set_cr1_from_fpscr(DisasContext *ctx)
-{
- TCGv_i32 tmp = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(tmp, cpu_fpscr);
- tcg_gen_shri_i32(cpu_crf[1], tmp, 28);
- tcg_temp_free_i32(tmp);
-}
-#else
-static void gen_set_cr1_from_fpscr(DisasContext *ctx)
-{
- tcg_gen_shri_tl(cpu_crf[1], cpu_fpscr, 28);
-}
-#endif
-
-/*** Floating-Point arithmetic ***/
-#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type) \
-static void gen_f##name(DisasContext *ctx) \
-{ \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_reset_fpstatus(); \
- gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env, \
- cpu_fpr[rA(ctx->opcode)], \
- cpu_fpr[rC(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); \
- if (isfloat) { \
- gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env, \
- cpu_fpr[rD(ctx->opcode)]); \
- } \
- if (set_fprf) { \
- gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]); \
- } \
- if (unlikely(Rc(ctx->opcode) != 0)) { \
- gen_set_cr1_from_fpscr(ctx); \
- } \
-}
-
-#define GEN_FLOAT_ACB(name, op2, set_fprf, type) \
-_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type); \
-_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
-
-#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type) \
-static void gen_f##name(DisasContext *ctx) \
-{ \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_reset_fpstatus(); \
- gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env, \
- cpu_fpr[rA(ctx->opcode)], \
- cpu_fpr[rB(ctx->opcode)]); \
- if (isfloat) { \
- gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env, \
- cpu_fpr[rD(ctx->opcode)]); \
- } \
- if (set_fprf) { \
- gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]); \
- } \
- if (unlikely(Rc(ctx->opcode) != 0)) { \
- gen_set_cr1_from_fpscr(ctx); \
- } \
-}
-#define GEN_FLOAT_AB(name, op2, inval, set_fprf, type) \
-_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type); \
-_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
-
-#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type) \
-static void gen_f##name(DisasContext *ctx) \
-{ \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_reset_fpstatus(); \
- gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_env, \
- cpu_fpr[rA(ctx->opcode)], \
- cpu_fpr[rC(ctx->opcode)]); \
- if (isfloat) { \
- gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env, \
- cpu_fpr[rD(ctx->opcode)]); \
- } \
- if (set_fprf) { \
- gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]); \
- } \
- if (unlikely(Rc(ctx->opcode) != 0)) { \
- gen_set_cr1_from_fpscr(ctx); \
- } \
-}
-#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type) \
-_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type); \
-_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
-
-#define GEN_FLOAT_B(name, op2, op3, set_fprf, type) \
-static void gen_f##name(DisasContext *ctx) \
-{ \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_reset_fpstatus(); \
- gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_env, \
- cpu_fpr[rB(ctx->opcode)]); \
- if (set_fprf) { \
- gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]); \
- } \
- if (unlikely(Rc(ctx->opcode) != 0)) { \
- gen_set_cr1_from_fpscr(ctx); \
- } \
-}
-
-#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type) \
-static void gen_f##name(DisasContext *ctx) \
-{ \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_reset_fpstatus(); \
- gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_env, \
- cpu_fpr[rB(ctx->opcode)]); \
- if (set_fprf) { \
- gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]); \
- } \
- if (unlikely(Rc(ctx->opcode) != 0)) { \
- gen_set_cr1_from_fpscr(ctx); \
- } \
-}
-
-/* fadd - fadds */
-GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
-/* fdiv - fdivs */
-GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
-/* fmul - fmuls */
-GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
-
-/* fre */
-GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
-
-/* fres */
-GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
-
-/* frsqrte */
-GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
-
-/* frsqrtes */
-static void gen_frsqrtes(DisasContext *ctx)
-{
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- gen_reset_fpstatus();
- gen_helper_frsqrte(cpu_fpr[rD(ctx->opcode)], cpu_env,
- cpu_fpr[rB(ctx->opcode)]);
- gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,
- cpu_fpr[rD(ctx->opcode)]);
- gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]);
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_cr1_from_fpscr(ctx);
- }
-}
-
-/* fsel */
-_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
-/* fsub - fsubs */
-GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
-/* Optional: */
-
-/* fsqrt */
-static void gen_fsqrt(DisasContext *ctx)
-{
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- gen_reset_fpstatus();
- gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_env,
- cpu_fpr[rB(ctx->opcode)]);
- gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]);
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_cr1_from_fpscr(ctx);
- }
-}
-
-static void gen_fsqrts(DisasContext *ctx)
-{
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- gen_reset_fpstatus();
- gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_env,
- cpu_fpr[rB(ctx->opcode)]);
- gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_env,
- cpu_fpr[rD(ctx->opcode)]);
- gen_compute_fprf(cpu_fpr[rD(ctx->opcode)]);
- if (unlikely(Rc(ctx->opcode) != 0)) {
- gen_set_cr1_from_fpscr(ctx);
- }
-}
-
-/*** Floating-Point multiply-and-add ***/
-/* fmadd - fmadds */
-GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
-/* fmsub - fmsubs */
-GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
-/* fnmadd - fnmadds */
-GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
-/* fnmsub - fnmsubs */
-GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
-
-/*** Floating-Point round & convert ***/
-/* fctiw */
-GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
-/* fctiwu */
-GEN_FLOAT_B(ctiwu, 0x0E, 0x04, 0, PPC2_FP_CVT_ISA206);
-/* fctiwz */
-GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
-/* fctiwuz */
-GEN_FLOAT_B(ctiwuz, 0x0F, 0x04, 0, PPC2_FP_CVT_ISA206);
-/* frsp */
-GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
-/* fcfid */
-GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC2_FP_CVT_S64);
-/* fcfids */
-GEN_FLOAT_B(cfids, 0x0E, 0x1A, 0, PPC2_FP_CVT_ISA206);
-/* fcfidu */
-GEN_FLOAT_B(cfidu, 0x0E, 0x1E, 0, PPC2_FP_CVT_ISA206);
-/* fcfidus */
-GEN_FLOAT_B(cfidus, 0x0E, 0x1E, 0, PPC2_FP_CVT_ISA206);
-/* fctid */
-GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC2_FP_CVT_S64);
-/* fctidu */
-GEN_FLOAT_B(ctidu, 0x0E, 0x1D, 0, PPC2_FP_CVT_ISA206);
-/* fctidz */
-GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC2_FP_CVT_S64);
-/* fctidu */
-GEN_FLOAT_B(ctiduz, 0x0F, 0x1D, 0, PPC2_FP_CVT_ISA206);
-
-/* frin */
-GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
-/* friz */
-GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
-/* frip */
-GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
-/* frim */
-GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
-
-static void gen_ftdiv(DisasContext *ctx)
-{
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- gen_helper_ftdiv(cpu_crf[crfD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],
- cpu_fpr[rB(ctx->opcode)]);
-}
-
-static void gen_ftsqrt(DisasContext *ctx)
-{
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- gen_helper_ftsqrt(cpu_crf[crfD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
-}
-
-
-
-/*** Floating-Point compare ***/
-
-/* fcmpo */
-static void gen_fcmpo(DisasContext *ctx)
-{
- TCGv_i32 crf;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- gen_reset_fpstatus();
- crf = tcg_const_i32(crfD(ctx->opcode));
- gen_helper_fcmpo(cpu_env, cpu_fpr[rA(ctx->opcode)],
- cpu_fpr[rB(ctx->opcode)], crf);
- tcg_temp_free_i32(crf);
- gen_helper_float_check_status(cpu_env);
-}
-
-/* fcmpu */
-static void gen_fcmpu(DisasContext *ctx)
-{
- TCGv_i32 crf;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- gen_reset_fpstatus();
- crf = tcg_const_i32(crfD(ctx->opcode));
- gen_helper_fcmpu(cpu_env, cpu_fpr[rA(ctx->opcode)],
- cpu_fpr[rB(ctx->opcode)], crf);
- tcg_temp_free_i32(crf);
- gen_helper_float_check_status(cpu_env);
-}
-
-/*** Floating-point move ***/
-/* fabs */
-/* XXX: beware that fabs never checks for NaNs nor update FPSCR */
-static void gen_fabs(DisasContext *ctx)
-{
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- tcg_gen_andi_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)],
- ~(1ULL << 63));
- if (unlikely(Rc(ctx->opcode))) {
- gen_set_cr1_from_fpscr(ctx);
- }
-}
-
-/* fmr - fmr. */
-/* XXX: beware that fmr never checks for NaNs nor update FPSCR */
-static void gen_fmr(DisasContext *ctx)
-{
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
- if (unlikely(Rc(ctx->opcode))) {
- gen_set_cr1_from_fpscr(ctx);
- }
-}
-
-/* fnabs */
-/* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
-static void gen_fnabs(DisasContext *ctx)
-{
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- tcg_gen_ori_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)],
- 1ULL << 63);
- if (unlikely(Rc(ctx->opcode))) {
- gen_set_cr1_from_fpscr(ctx);
- }
-}
-
-/* fneg */
-/* XXX: beware that fneg never checks for NaNs nor update FPSCR */
-static void gen_fneg(DisasContext *ctx)
-{
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- tcg_gen_xori_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)],
- 1ULL << 63);
- if (unlikely(Rc(ctx->opcode))) {
- gen_set_cr1_from_fpscr(ctx);
- }
-}
-
-/* fcpsgn: PowerPC 2.05 specification */
-/* XXX: beware that fcpsgn never checks for NaNs nor update FPSCR */
-static void gen_fcpsgn(DisasContext *ctx)
-{
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- tcg_gen_deposit_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],
- cpu_fpr[rB(ctx->opcode)], 0, 63);
- if (unlikely(Rc(ctx->opcode))) {
- gen_set_cr1_from_fpscr(ctx);
- }
-}
-
-static void gen_fmrgew(DisasContext *ctx)
-{
- TCGv_i64 b0;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- b0 = tcg_temp_new_i64();
- tcg_gen_shri_i64(b0, cpu_fpr[rB(ctx->opcode)], 32);
- tcg_gen_deposit_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],
- b0, 0, 32);
- tcg_temp_free_i64(b0);
-}
-
-static void gen_fmrgow(DisasContext *ctx)
-{
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- tcg_gen_deposit_i64(cpu_fpr[rD(ctx->opcode)],
- cpu_fpr[rB(ctx->opcode)],
- cpu_fpr[rA(ctx->opcode)],
- 32, 32);
-}
-
-/*** Floating-Point status & ctrl register ***/
-
-/* mcrfs */
-static void gen_mcrfs(DisasContext *ctx)
-{
- TCGv tmp = tcg_temp_new();
- TCGv_i32 tmask;
- TCGv_i64 tnew_fpscr = tcg_temp_new_i64();
- int bfa;
- int nibble;
- int shift;
-
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- bfa = crfS(ctx->opcode);
- nibble = 7 - bfa;
- shift = 4 * nibble;
- tcg_gen_shri_tl(tmp, cpu_fpscr, shift);
- tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], tmp);
- tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf);
- tcg_temp_free(tmp);
- tcg_gen_extu_tl_i64(tnew_fpscr, cpu_fpscr);
- /* Only the exception bits (including FX) should be cleared if read */
- tcg_gen_andi_i64(tnew_fpscr, tnew_fpscr, ~((0xF << shift) & FP_EX_CLEAR_BITS));
- /* FEX and VX need to be updated, so don't set fpscr directly */
- tmask = tcg_const_i32(1 << nibble);
- gen_helper_store_fpscr(cpu_env, tnew_fpscr, tmask);
- tcg_temp_free_i32(tmask);
- tcg_temp_free_i64(tnew_fpscr);
-}
-
-/* mffs */
-static void gen_mffs(DisasContext *ctx)
-{
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- gen_reset_fpstatus();
- tcg_gen_extu_tl_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpscr);
- if (unlikely(Rc(ctx->opcode))) {
- gen_set_cr1_from_fpscr(ctx);
- }
-}
-
-/* mtfsb0 */
-static void gen_mtfsb0(DisasContext *ctx)
-{
- uint8_t crb;
-
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- crb = 31 - crbD(ctx->opcode);
- gen_reset_fpstatus();
- if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) {
- TCGv_i32 t0;
- t0 = tcg_const_i32(crb);
- gen_helper_fpscr_clrbit(cpu_env, t0);
- tcg_temp_free_i32(t0);
- }
- if (unlikely(Rc(ctx->opcode) != 0)) {
- tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
- tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
- }
-}
-
-/* mtfsb1 */
-static void gen_mtfsb1(DisasContext *ctx)
-{
- uint8_t crb;
-
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- crb = 31 - crbD(ctx->opcode);
- gen_reset_fpstatus();
- /* XXX: we pretend we can only do IEEE floating-point computations */
- if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) {
- TCGv_i32 t0;
- t0 = tcg_const_i32(crb);
- gen_helper_fpscr_setbit(cpu_env, t0);
- tcg_temp_free_i32(t0);
- }
- if (unlikely(Rc(ctx->opcode) != 0)) {
- tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
- tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
- }
- /* We can raise a differed exception */
- gen_helper_float_check_status(cpu_env);
-}
-
-/* mtfsf */
-static void gen_mtfsf(DisasContext *ctx)
-{
- TCGv_i32 t0;
- int flm, l, w;
-
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- flm = FPFLM(ctx->opcode);
- l = FPL(ctx->opcode);
- w = FPW(ctx->opcode);
- if (unlikely(w & !(ctx->insns_flags2 & PPC2_ISA205))) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- return;
- }
- gen_reset_fpstatus();
- if (l) {
- t0 = tcg_const_i32((ctx->insns_flags2 & PPC2_ISA205) ? 0xffff : 0xff);
- } else {
- t0 = tcg_const_i32(flm << (w * 8));
- }
- gen_helper_store_fpscr(cpu_env, cpu_fpr[rB(ctx->opcode)], t0);
- tcg_temp_free_i32(t0);
- if (unlikely(Rc(ctx->opcode) != 0)) {
- tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
- tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
- }
- /* We can raise a differed exception */
- gen_helper_float_check_status(cpu_env);
-}
-
-/* mtfsfi */
-static void gen_mtfsfi(DisasContext *ctx)
-{
- int bf, sh, w;
- TCGv_i64 t0;
- TCGv_i32 t1;
-
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- w = FPW(ctx->opcode);
- bf = FPBF(ctx->opcode);
- if (unlikely(w & !(ctx->insns_flags2 & PPC2_ISA205))) {
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
- return;
- }
- sh = (8 * w) + 7 - bf;
- gen_reset_fpstatus();
- t0 = tcg_const_i64(((uint64_t)FPIMM(ctx->opcode)) << (4 * sh));
- t1 = tcg_const_i32(1 << sh);
- gen_helper_store_fpscr(cpu_env, t0, t1);
- tcg_temp_free_i64(t0);
- tcg_temp_free_i32(t1);
- if (unlikely(Rc(ctx->opcode) != 0)) {
- tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
- tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
- }
- /* We can raise a differed exception */
- gen_helper_float_check_status(cpu_env);
-}
-
-/*** Floating-point load ***/
-#define GEN_LDF(name, ldop, opc, type) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_FLOAT); \
- EA = tcg_temp_new(); \
- gen_addr_imm_index(ctx, EA, 0); \
- gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA); \
- tcg_temp_free(EA); \
-}
-
-#define GEN_LDUF(name, ldop, opc, type) \
-static void glue(gen_, name##u)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- if (unlikely(rA(ctx->opcode) == 0)) { \
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_FLOAT); \
- EA = tcg_temp_new(); \
- gen_addr_imm_index(ctx, EA, 0); \
- gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA); \
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
- tcg_temp_free(EA); \
-}
-
-#define GEN_LDUXF(name, ldop, opc, type) \
-static void glue(gen_, name##ux)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- if (unlikely(rA(ctx->opcode) == 0)) { \
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_FLOAT); \
- EA = tcg_temp_new(); \
- gen_addr_reg_index(ctx, EA); \
- gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA); \
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
- tcg_temp_free(EA); \
-}
-
-#define GEN_LDXF(name, ldop, opc2, opc3, type) \
-static void glue(gen_, name##x)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_FLOAT); \
- EA = tcg_temp_new(); \
- gen_addr_reg_index(ctx, EA); \
- gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA); \
- tcg_temp_free(EA); \
-}
-
-#define GEN_LDFS(name, ldop, op, type) \
-GEN_LDF(name, ldop, op | 0x20, type); \
-GEN_LDUF(name, ldop, op | 0x21, type); \
-GEN_LDUXF(name, ldop, op | 0x01, type); \
-GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
-
-static inline void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
-{
- TCGv t0 = tcg_temp_new();
- TCGv_i32 t1 = tcg_temp_new_i32();
- gen_qemu_ld32u(ctx, t0, arg2);
- tcg_gen_trunc_tl_i32(t1, t0);
- tcg_temp_free(t0);
- gen_helper_float32_to_float64(arg1, cpu_env, t1);
- tcg_temp_free_i32(t1);
-}
-
- /* lfd lfdu lfdux lfdx */
-GEN_LDFS(lfd, ld64_i64, 0x12, PPC_FLOAT);
- /* lfs lfsu lfsux lfsx */
-GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT);
-
-/* lfdp */
-static void gen_lfdp(DisasContext *ctx)
-{
- TCGv EA;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- gen_set_access_type(ctx, ACCESS_FLOAT);
- EA = tcg_temp_new();
- gen_addr_imm_index(ctx, EA, 0);
- /* We only need to swap high and low halves. gen_qemu_ld64_i64 does
- necessary 64-bit byteswap already. */
- if (unlikely(ctx->le_mode)) {
- gen_qemu_ld64_i64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
- tcg_gen_addi_tl(EA, EA, 8);
- gen_qemu_ld64_i64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
- } else {
- gen_qemu_ld64_i64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
- tcg_gen_addi_tl(EA, EA, 8);
- gen_qemu_ld64_i64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
- }
- tcg_temp_free(EA);
-}
-
-/* lfdpx */
-static void gen_lfdpx(DisasContext *ctx)
-{
- TCGv EA;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- gen_set_access_type(ctx, ACCESS_FLOAT);
- EA = tcg_temp_new();
- gen_addr_reg_index(ctx, EA);
- /* We only need to swap high and low halves. gen_qemu_ld64_i64 does
- necessary 64-bit byteswap already. */
- if (unlikely(ctx->le_mode)) {
- gen_qemu_ld64_i64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
- tcg_gen_addi_tl(EA, EA, 8);
- gen_qemu_ld64_i64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
- } else {
- gen_qemu_ld64_i64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
- tcg_gen_addi_tl(EA, EA, 8);
- gen_qemu_ld64_i64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
- }
- tcg_temp_free(EA);
-}
-
-/* lfiwax */
-static void gen_lfiwax(DisasContext *ctx)
-{
- TCGv EA;
- TCGv t0;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- gen_set_access_type(ctx, ACCESS_FLOAT);
- EA = tcg_temp_new();
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, EA);
- gen_qemu_ld32s(ctx, t0, EA);
- tcg_gen_ext_tl_i64(cpu_fpr[rD(ctx->opcode)], t0);
- tcg_temp_free(EA);
- tcg_temp_free(t0);
-}
-
-/* lfiwzx */
-static void gen_lfiwzx(DisasContext *ctx)
-{
- TCGv EA;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- gen_set_access_type(ctx, ACCESS_FLOAT);
- EA = tcg_temp_new();
- gen_addr_reg_index(ctx, EA);
- gen_qemu_ld32u_i64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
- tcg_temp_free(EA);
-}
-/*** Floating-point store ***/
-#define GEN_STF(name, stop, opc, type) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_FLOAT); \
- EA = tcg_temp_new(); \
- gen_addr_imm_index(ctx, EA, 0); \
- gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA); \
- tcg_temp_free(EA); \
-}
-
-#define GEN_STUF(name, stop, opc, type) \
-static void glue(gen_, name##u)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- if (unlikely(rA(ctx->opcode) == 0)) { \
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_FLOAT); \
- EA = tcg_temp_new(); \
- gen_addr_imm_index(ctx, EA, 0); \
- gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA); \
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
- tcg_temp_free(EA); \
-}
-
-#define GEN_STUXF(name, stop, opc, type) \
-static void glue(gen_, name##ux)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- if (unlikely(rA(ctx->opcode) == 0)) { \
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_FLOAT); \
- EA = tcg_temp_new(); \
- gen_addr_reg_index(ctx, EA); \
- gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA); \
- tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
- tcg_temp_free(EA); \
-}
-
-#define GEN_STXF(name, stop, opc2, opc3, type) \
-static void glue(gen_, name##x)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_FLOAT); \
- EA = tcg_temp_new(); \
- gen_addr_reg_index(ctx, EA); \
- gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA); \
- tcg_temp_free(EA); \
-}
-
-#define GEN_STFS(name, stop, op, type) \
-GEN_STF(name, stop, op | 0x20, type); \
-GEN_STUF(name, stop, op | 0x21, type); \
-GEN_STUXF(name, stop, op | 0x01, type); \
-GEN_STXF(name, stop, 0x17, op | 0x00, type)
-
-static inline void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
-{
- TCGv_i32 t0 = tcg_temp_new_i32();
- TCGv t1 = tcg_temp_new();
- gen_helper_float64_to_float32(t0, cpu_env, arg1);
- tcg_gen_extu_i32_tl(t1, t0);
- tcg_temp_free_i32(t0);
- gen_qemu_st32(ctx, t1, arg2);
- tcg_temp_free(t1);
-}
-
-/* stfd stfdu stfdux stfdx */
-GEN_STFS(stfd, st64_i64, 0x16, PPC_FLOAT);
-/* stfs stfsu stfsux stfsx */
-GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT);
-
-/* stfdp */
-static void gen_stfdp(DisasContext *ctx)
-{
- TCGv EA;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- gen_set_access_type(ctx, ACCESS_FLOAT);
- EA = tcg_temp_new();
- gen_addr_imm_index(ctx, EA, 0);
- /* We only need to swap high and low halves. gen_qemu_st64_i64 does
- necessary 64-bit byteswap already. */
- if (unlikely(ctx->le_mode)) {
- gen_qemu_st64_i64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
- tcg_gen_addi_tl(EA, EA, 8);
- gen_qemu_st64_i64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
- } else {
- gen_qemu_st64_i64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
- tcg_gen_addi_tl(EA, EA, 8);
- gen_qemu_st64_i64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
- }
- tcg_temp_free(EA);
-}
-
-/* stfdpx */
-static void gen_stfdpx(DisasContext *ctx)
-{
- TCGv EA;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- gen_set_access_type(ctx, ACCESS_FLOAT);
- EA = tcg_temp_new();
- gen_addr_reg_index(ctx, EA);
- /* We only need to swap high and low halves. gen_qemu_st64_i64 does
- necessary 64-bit byteswap already. */
- if (unlikely(ctx->le_mode)) {
- gen_qemu_st64_i64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
- tcg_gen_addi_tl(EA, EA, 8);
- gen_qemu_st64_i64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
- } else {
- gen_qemu_st64_i64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
- tcg_gen_addi_tl(EA, EA, 8);
- gen_qemu_st64_i64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
- }
- tcg_temp_free(EA);
-}
-
-/* Optional: */
-static inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
-{
- TCGv t0 = tcg_temp_new();
- tcg_gen_trunc_i64_tl(t0, arg1),
- gen_qemu_st32(ctx, t0, arg2);
- tcg_temp_free(t0);
-}
-/* stfiwx */
-GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
-
-/* POWER2 specific instructions */
-/* Quad manipulation (load/store two floats at a time) */
-
-/* lfq */
-static void gen_lfq(DisasContext *ctx)
-{
- int rd = rD(ctx->opcode);
- TCGv t0;
- gen_set_access_type(ctx, ACCESS_FLOAT);
- t0 = tcg_temp_new();
- gen_addr_imm_index(ctx, t0, 0);
- gen_qemu_ld64_i64(ctx, cpu_fpr[rd], t0);
- gen_addr_add(ctx, t0, t0, 8);
- gen_qemu_ld64_i64(ctx, cpu_fpr[(rd + 1) % 32], t0);
- tcg_temp_free(t0);
-}
-
-/* lfqu */
-static void gen_lfqu(DisasContext *ctx)
-{
- int ra = rA(ctx->opcode);
- int rd = rD(ctx->opcode);
- TCGv t0, t1;
- gen_set_access_type(ctx, ACCESS_FLOAT);
- t0 = tcg_temp_new();
- t1 = tcg_temp_new();
- gen_addr_imm_index(ctx, t0, 0);
- gen_qemu_ld64_i64(ctx, cpu_fpr[rd], t0);
- gen_addr_add(ctx, t1, t0, 8);
- gen_qemu_ld64_i64(ctx, cpu_fpr[(rd + 1) % 32], t1);
- if (ra != 0)
- tcg_gen_mov_tl(cpu_gpr[ra], t0);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
-}
-
-/* lfqux */
-static void gen_lfqux(DisasContext *ctx)
-{
- int ra = rA(ctx->opcode);
- int rd = rD(ctx->opcode);
- gen_set_access_type(ctx, ACCESS_FLOAT);
- TCGv t0, t1;
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- gen_qemu_ld64_i64(ctx, cpu_fpr[rd], t0);
- t1 = tcg_temp_new();
- gen_addr_add(ctx, t1, t0, 8);
- gen_qemu_ld64_i64(ctx, cpu_fpr[(rd + 1) % 32], t1);
- tcg_temp_free(t1);
- if (ra != 0)
- tcg_gen_mov_tl(cpu_gpr[ra], t0);
- tcg_temp_free(t0);
-}
-
-/* lfqx */
-static void gen_lfqx(DisasContext *ctx)
-{
- int rd = rD(ctx->opcode);
- TCGv t0;
- gen_set_access_type(ctx, ACCESS_FLOAT);
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- gen_qemu_ld64_i64(ctx, cpu_fpr[rd], t0);
- gen_addr_add(ctx, t0, t0, 8);
- gen_qemu_ld64_i64(ctx, cpu_fpr[(rd + 1) % 32], t0);
- tcg_temp_free(t0);
-}
-
-/* stfq */
-static void gen_stfq(DisasContext *ctx)
-{
- int rd = rD(ctx->opcode);
- TCGv t0;
- gen_set_access_type(ctx, ACCESS_FLOAT);
- t0 = tcg_temp_new();
- gen_addr_imm_index(ctx, t0, 0);
- gen_qemu_st64_i64(ctx, cpu_fpr[rd], t0);
- gen_addr_add(ctx, t0, t0, 8);
- gen_qemu_st64_i64(ctx, cpu_fpr[(rd + 1) % 32], t0);
- tcg_temp_free(t0);
-}
-
-/* stfqu */
-static void gen_stfqu(DisasContext *ctx)
-{
- int ra = rA(ctx->opcode);
- int rd = rD(ctx->opcode);
- TCGv t0, t1;
- gen_set_access_type(ctx, ACCESS_FLOAT);
- t0 = tcg_temp_new();
- gen_addr_imm_index(ctx, t0, 0);
- gen_qemu_st64_i64(ctx, cpu_fpr[rd], t0);
- t1 = tcg_temp_new();
- gen_addr_add(ctx, t1, t0, 8);
- gen_qemu_st64_i64(ctx, cpu_fpr[(rd + 1) % 32], t1);
- tcg_temp_free(t1);
- if (ra != 0)
- tcg_gen_mov_tl(cpu_gpr[ra], t0);
- tcg_temp_free(t0);
-}
-
-/* stfqux */
-static void gen_stfqux(DisasContext *ctx)
-{
- int ra = rA(ctx->opcode);
- int rd = rD(ctx->opcode);
- TCGv t0, t1;
- gen_set_access_type(ctx, ACCESS_FLOAT);
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- gen_qemu_st64_i64(ctx, cpu_fpr[rd], t0);
- t1 = tcg_temp_new();
- gen_addr_add(ctx, t1, t0, 8);
- gen_qemu_st64_i64(ctx, cpu_fpr[(rd + 1) % 32], t1);
- tcg_temp_free(t1);
- if (ra != 0)
- tcg_gen_mov_tl(cpu_gpr[ra], t0);
- tcg_temp_free(t0);
-}
-
-/* stfqx */
-static void gen_stfqx(DisasContext *ctx)
-{
- int rd = rD(ctx->opcode);
- TCGv t0;
- gen_set_access_type(ctx, ACCESS_FLOAT);
- t0 = tcg_temp_new();
- gen_addr_reg_index(ctx, t0);
- gen_qemu_st64_i64(ctx, cpu_fpr[rd], t0);
- gen_addr_add(ctx, t0, t0, 8);
- gen_qemu_st64_i64(ctx, cpu_fpr[(rd + 1) % 32], t0);
- tcg_temp_free(t0);
-}
-
-#undef _GEN_FLOAT_ACB
-#undef GEN_FLOAT_ACB
-#undef _GEN_FLOAT_AB
-#undef GEN_FLOAT_AB
-#undef _GEN_FLOAT_AC
-#undef GEN_FLOAT_AC
-#undef GEN_FLOAT_B
-#undef GEN_FLOAT_BS
-
-#undef GEN_LDF
-#undef GEN_LDUF
-#undef GEN_LDUXF
-#undef GEN_LDXF
-#undef GEN_LDFS
-
-#undef GEN_STF
-#undef GEN_STUF
-#undef GEN_STUXF
-#undef GEN_STXF
-#undef GEN_STFS
diff --git a/target-ppc/translate/fp-ops.inc.c b/target-ppc/translate/fp-ops.inc.c
deleted file mode 100644
index d36ab4ecc3..0000000000
--- a/target-ppc/translate/fp-ops.inc.c
+++ /dev/null
@@ -1,111 +0,0 @@
-#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type) \
-GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)
-#define GEN_FLOAT_ACB(name, op2, set_fprf, type) \
-_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type), \
-_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type)
-#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type) \
-GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
-#define GEN_FLOAT_AB(name, op2, inval, set_fprf, type) \
-_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type), \
-_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
-#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type) \
-GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
-#define GEN_FLOAT_AC(name, op2, inval, set_fprf, type) \
-_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type), \
-_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
-#define GEN_FLOAT_B(name, op2, op3, set_fprf, type) \
-GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)
-#define GEN_FLOAT_BS(name, op1, op2, set_fprf, type) \
-GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)
-
-GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT),
-GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT),
-GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT),
-GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT),
-GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES),
-GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE),
-_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL),
-GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT),
-GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT),
-GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT),
-GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT),
-GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT),
-GEN_HANDLER_E(ftdiv, 0x3F, 0x00, 0x04, 1, PPC_NONE, PPC2_FP_TST_ISA206),
-GEN_HANDLER_E(ftsqrt, 0x3F, 0x00, 0x05, 1, PPC_NONE, PPC2_FP_TST_ISA206),
-GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT),
-GEN_HANDLER_E(fctiwu, 0x3F, 0x0E, 0x04, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
-GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT),
-GEN_HANDLER_E(fctiwuz, 0x3F, 0x0F, 0x04, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
-GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT),
-GEN_HANDLER_E(fcfid, 0x3F, 0x0E, 0x1A, 0x001F0000, PPC_NONE, PPC2_FP_CVT_S64),
-GEN_HANDLER_E(fcfids, 0x3B, 0x0E, 0x1A, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
-GEN_HANDLER_E(fcfidu, 0x3F, 0x0E, 0x1E, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
-GEN_HANDLER_E(fcfidus, 0x3B, 0x0E, 0x1E, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
-GEN_HANDLER_E(fctid, 0x3F, 0x0E, 0x19, 0x001F0000, PPC_NONE, PPC2_FP_CVT_S64),
-GEN_HANDLER_E(fctidu, 0x3F, 0x0E, 0x1D, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
-GEN_HANDLER_E(fctidz, 0x3F, 0x0F, 0x19, 0x001F0000, PPC_NONE, PPC2_FP_CVT_S64),
-GEN_HANDLER_E(fctiduz, 0x3F, 0x0F, 0x1D, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
-GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT),
-GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT),
-GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT),
-GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT),
-
-#define GEN_LDF(name, ldop, opc, type) \
-GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
-#define GEN_LDUF(name, ldop, opc, type) \
-GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
-#define GEN_LDUXF(name, ldop, opc, type) \
-GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
-#define GEN_LDXF(name, ldop, opc2, opc3, type) \
-GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
-#define GEN_LDFS(name, ldop, op, type) \
-GEN_LDF(name, ldop, op | 0x20, type) \
-GEN_LDUF(name, ldop, op | 0x21, type) \
-GEN_LDUXF(name, ldop, op | 0x01, type) \
-GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
-
-GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT)
-GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT)
-GEN_HANDLER_E(lfiwax, 0x1f, 0x17, 0x1a, 0x00000001, PPC_NONE, PPC2_ISA205),
-GEN_HANDLER_E(lfiwzx, 0x1f, 0x17, 0x1b, 0x1, PPC_NONE, PPC2_FP_CVT_ISA206),
-GEN_HANDLER_E(lfdp, 0x39, 0xFF, 0xFF, 0x00200003, PPC_NONE, PPC2_ISA205),
-GEN_HANDLER_E(lfdpx, 0x1F, 0x17, 0x18, 0x00200001, PPC_NONE, PPC2_ISA205),
-
-#define GEN_STF(name, stop, opc, type) \
-GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
-#define GEN_STUF(name, stop, opc, type) \
-GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
-#define GEN_STUXF(name, stop, opc, type) \
-GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
-#define GEN_STXF(name, stop, opc2, opc3, type) \
-GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
-#define GEN_STFS(name, stop, op, type) \
-GEN_STF(name, stop, op | 0x20, type) \
-GEN_STUF(name, stop, op | 0x21, type) \
-GEN_STUXF(name, stop, op | 0x01, type) \
-GEN_STXF(name, stop, 0x17, op | 0x00, type)
-
-GEN_STFS(stfd, st64_i64, 0x16, PPC_FLOAT)
-GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT)
-GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
-GEN_HANDLER_E(stfdp, 0x3D, 0xFF, 0xFF, 0x00200003, PPC_NONE, PPC2_ISA205),
-GEN_HANDLER_E(stfdpx, 0x1F, 0x17, 0x1C, 0x00200001, PPC_NONE, PPC2_ISA205),
-
-GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES),
-GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
-GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
-GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT),
-GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT),
-GEN_HANDLER(fabs, 0x3F, 0x08, 0x08, 0x001F0000, PPC_FLOAT),
-GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT),
-GEN_HANDLER(fnabs, 0x3F, 0x08, 0x04, 0x001F0000, PPC_FLOAT),
-GEN_HANDLER(fneg, 0x3F, 0x08, 0x01, 0x001F0000, PPC_FLOAT),
-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(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT),
-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),
-GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006e0800, PPC_FLOAT),
diff --git a/target-ppc/translate/spe-impl.inc.c b/target-ppc/translate/spe-impl.inc.c
deleted file mode 100644
index 8c1c16c63e..0000000000
--- a/target-ppc/translate/spe-impl.inc.c
+++ /dev/null
@@ -1,1229 +0,0 @@
-/*
- * translate-spe.c
- *
- * Freescale SPE extension translation
- */
-
-/*** SPE extension ***/
-/* Register moves */
-
-static inline void gen_evmra(DisasContext *ctx)
-{
-
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
-
- TCGv_i64 tmp = tcg_temp_new_i64();
-
- /* tmp := rA_lo + rA_hi << 32 */
- tcg_gen_concat_tl_i64(tmp, cpu_gpr[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
-
- /* spe_acc := tmp */
- tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
- tcg_temp_free_i64(tmp);
-
- /* rD := rA */
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
-}
-
-static inline void gen_load_gpr64(TCGv_i64 t, int reg)
-{
- tcg_gen_concat_tl_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
-}
-
-static inline void gen_store_gpr64(int reg, TCGv_i64 t)
-{
- tcg_gen_extr_i64_tl(cpu_gpr[reg], cpu_gprh[reg], t);
-}
-
-#define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \
-static void glue(gen_, name0##_##name1)(DisasContext *ctx) \
-{ \
- if (Rc(ctx->opcode)) \
- gen_##name1(ctx); \
- else \
- gen_##name0(ctx); \
-}
-
-/* Handler for undefined SPE opcodes */
-static inline void gen_speundef(DisasContext *ctx)
-{
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
-}
-
-/* SPE logic */
-#define GEN_SPEOP_LOGIC2(name, tcg_op) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- if (unlikely(!ctx->spe_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_SPEU); \
- return; \
- } \
- tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \
- cpu_gpr[rB(ctx->opcode)]); \
- tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], \
- cpu_gprh[rB(ctx->opcode)]); \
-}
-
-GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl);
-GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl);
-GEN_SPEOP_LOGIC2(evxor, tcg_gen_xor_tl);
-GEN_SPEOP_LOGIC2(evor, tcg_gen_or_tl);
-GEN_SPEOP_LOGIC2(evnor, tcg_gen_nor_tl);
-GEN_SPEOP_LOGIC2(eveqv, tcg_gen_eqv_tl);
-GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl);
-GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
-
-/* SPE logic immediate */
-#define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_i32 t0; \
- if (unlikely(!ctx->spe_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_SPEU); \
- return; \
- } \
- t0 = tcg_temp_new_i32(); \
- \
- tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
- tcg_opi(t0, t0, rB(ctx->opcode)); \
- tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
- \
- tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]); \
- tcg_opi(t0, t0, rB(ctx->opcode)); \
- tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \
- \
- tcg_temp_free_i32(t0); \
-}
-GEN_SPEOP_TCG_LOGIC_IMM2(evslwi, tcg_gen_shli_i32);
-GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu, tcg_gen_shri_i32);
-GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis, tcg_gen_sari_i32);
-GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32);
-
-/* SPE arithmetic */
-#define GEN_SPEOP_ARITH1(name, tcg_op) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_i32 t0; \
- if (unlikely(!ctx->spe_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_SPEU); \
- return; \
- } \
- t0 = tcg_temp_new_i32(); \
- \
- tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
- tcg_op(t0, t0); \
- tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
- \
- tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]); \
- tcg_op(t0, t0); \
- tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \
- \
- tcg_temp_free_i32(t0); \
-}
-
-static inline void gen_op_evabs(TCGv_i32 ret, TCGv_i32 arg1)
-{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
-
- tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
- tcg_gen_neg_i32(ret, arg1);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_mov_i32(ret, arg1);
- gen_set_label(l2);
-}
-GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
-GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
-GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
-GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
-static inline void gen_op_evrndw(TCGv_i32 ret, TCGv_i32 arg1)
-{
- tcg_gen_addi_i32(ret, arg1, 0x8000);
- tcg_gen_ext16u_i32(ret, ret);
-}
-GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw);
-GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32);
-GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
-
-#define GEN_SPEOP_ARITH2(name, tcg_op) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_i32 t0, t1; \
- if (unlikely(!ctx->spe_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_SPEU); \
- return; \
- } \
- t0 = tcg_temp_new_i32(); \
- t1 = tcg_temp_new_i32(); \
- \
- tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
- tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \
- tcg_op(t0, t0, t1); \
- tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
- \
- tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]); \
- tcg_gen_trunc_tl_i32(t1, cpu_gprh[rB(ctx->opcode)]); \
- tcg_op(t0, t0, t1); \
- tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \
- \
- tcg_temp_free_i32(t0); \
- tcg_temp_free_i32(t1); \
-}
-
-static inline void gen_op_evsrwu(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
-{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGv_i32 t0 = tcg_temp_local_new_i32();
-
- /* No error here: 6 bits are used */
- tcg_gen_andi_i32(t0, arg2, 0x3F);
- tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
- tcg_gen_shr_i32(ret, arg1, t0);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_i32(ret, 0);
- gen_set_label(l2);
- tcg_temp_free_i32(t0);
-}
-GEN_SPEOP_ARITH2(evsrwu, gen_op_evsrwu);
-static inline void gen_op_evsrws(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
-{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGv_i32 t0 = tcg_temp_local_new_i32();
-
- /* No error here: 6 bits are used */
- tcg_gen_andi_i32(t0, arg2, 0x3F);
- tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
- tcg_gen_sar_i32(ret, arg1, t0);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_i32(ret, 0);
- gen_set_label(l2);
- tcg_temp_free_i32(t0);
-}
-GEN_SPEOP_ARITH2(evsrws, gen_op_evsrws);
-static inline void gen_op_evslw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
-{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGv_i32 t0 = tcg_temp_local_new_i32();
-
- /* No error here: 6 bits are used */
- tcg_gen_andi_i32(t0, arg2, 0x3F);
- tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
- tcg_gen_shl_i32(ret, arg1, t0);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_movi_i32(ret, 0);
- gen_set_label(l2);
- tcg_temp_free_i32(t0);
-}
-GEN_SPEOP_ARITH2(evslw, gen_op_evslw);
-static inline void gen_op_evrlw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
-{
- TCGv_i32 t0 = tcg_temp_new_i32();
- tcg_gen_andi_i32(t0, arg2, 0x1F);
- tcg_gen_rotl_i32(ret, arg1, t0);
- tcg_temp_free_i32(t0);
-}
-GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
-static inline void gen_evmergehi(DisasContext *ctx)
-{
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
- tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
-}
-GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32);
-static inline void gen_op_evsubf(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
-{
- tcg_gen_sub_i32(ret, arg2, arg1);
-}
-GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
-
-/* SPE arithmetic immediate */
-#define GEN_SPEOP_ARITH_IMM2(name, tcg_op) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_i32 t0; \
- if (unlikely(!ctx->spe_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_SPEU); \
- return; \
- } \
- t0 = tcg_temp_new_i32(); \
- \
- tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]); \
- tcg_op(t0, t0, rA(ctx->opcode)); \
- tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
- \
- tcg_gen_trunc_tl_i32(t0, cpu_gprh[rB(ctx->opcode)]); \
- tcg_op(t0, t0, rA(ctx->opcode)); \
- tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0); \
- \
- tcg_temp_free_i32(t0); \
-}
-GEN_SPEOP_ARITH_IMM2(evaddiw, tcg_gen_addi_i32);
-GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32);
-
-/* SPE comparison */
-#define GEN_SPEOP_COMP(name, tcg_cond) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- if (unlikely(!ctx->spe_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_SPEU); \
- return; \
- } \
- TCGLabel *l1 = gen_new_label(); \
- TCGLabel *l2 = gen_new_label(); \
- TCGLabel *l3 = gen_new_label(); \
- TCGLabel *l4 = gen_new_label(); \
- \
- tcg_gen_ext32s_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); \
- tcg_gen_ext32s_tl(cpu_gpr[rB(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); \
- tcg_gen_ext32s_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); \
- tcg_gen_ext32s_tl(cpu_gprh[rB(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]); \
- \
- tcg_gen_brcond_tl(tcg_cond, cpu_gpr[rA(ctx->opcode)], \
- cpu_gpr[rB(ctx->opcode)], l1); \
- tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0); \
- tcg_gen_br(l2); \
- gen_set_label(l1); \
- tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], \
- CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL); \
- gen_set_label(l2); \
- tcg_gen_brcond_tl(tcg_cond, cpu_gprh[rA(ctx->opcode)], \
- cpu_gprh[rB(ctx->opcode)], l3); \
- tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], \
- ~(CRF_CH | CRF_CH_AND_CL)); \
- tcg_gen_br(l4); \
- gen_set_label(l3); \
- tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], \
- CRF_CH | CRF_CH_OR_CL); \
- gen_set_label(l4); \
-}
-GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU);
-GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT);
-GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU);
-GEN_SPEOP_COMP(evcmplts, TCG_COND_LT);
-GEN_SPEOP_COMP(evcmpeq, TCG_COND_EQ);
-
-/* SPE misc */
-static inline void gen_brinc(DisasContext *ctx)
-{
- /* Note: brinc is usable even if SPE is disabled */
- gen_helper_brinc(cpu_gpr[rD(ctx->opcode)],
- cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
-}
-static inline void gen_evmergelo(DisasContext *ctx)
-{
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
- tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
-}
-static inline void gen_evmergehilo(DisasContext *ctx)
-{
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
-}
-static inline void gen_evmergelohi(DisasContext *ctx)
-{
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
- if (rD(ctx->opcode) == rA(ctx->opcode)) {
- TCGv tmp = tcg_temp_new();
- tcg_gen_mov_tl(tmp, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
- tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], tmp);
- tcg_temp_free(tmp);
- } else {
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
- tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- }
-}
-static inline void gen_evsplati(DisasContext *ctx)
-{
- uint64_t imm = ((int32_t)(rA(ctx->opcode) << 27)) >> 27;
-
- tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], imm);
- tcg_gen_movi_tl(cpu_gprh[rD(ctx->opcode)], imm);
-}
-static inline void gen_evsplatfi(DisasContext *ctx)
-{
- uint64_t imm = rA(ctx->opcode) << 27;
-
- tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], imm);
- tcg_gen_movi_tl(cpu_gprh[rD(ctx->opcode)], imm);
-}
-
-static inline void gen_evsel(DisasContext *ctx)
-{
- TCGLabel *l1 = gen_new_label();
- TCGLabel *l2 = gen_new_label();
- TCGLabel *l3 = gen_new_label();
- TCGLabel *l4 = gen_new_label();
- TCGv_i32 t0 = tcg_temp_local_new_i32();
-
- tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);
- tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
- tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
- tcg_gen_br(l2);
- gen_set_label(l1);
- tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
- gen_set_label(l2);
- tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2);
- tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_br(l4);
- gen_set_label(l3);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
- gen_set_label(l4);
- tcg_temp_free_i32(t0);
-}
-
-static void gen_evsel0(DisasContext *ctx)
-{
- gen_evsel(ctx);
-}
-
-static void gen_evsel1(DisasContext *ctx)
-{
- gen_evsel(ctx);
-}
-
-static void gen_evsel2(DisasContext *ctx)
-{
- gen_evsel(ctx);
-}
-
-static void gen_evsel3(DisasContext *ctx)
-{
- gen_evsel(ctx);
-}
-
-/* Multiply */
-
-static inline void gen_evmwumi(DisasContext *ctx)
-{
- TCGv_i64 t0, t1;
-
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
-
- t0 = tcg_temp_new_i64();
- t1 = tcg_temp_new_i64();
-
- /* t0 := rA; t1 := rB */
- tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_ext32u_i64(t0, t0);
- tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_ext32u_i64(t1, t1);
-
- tcg_gen_mul_i64(t0, t0, t1); /* t0 := rA * rB */
-
- gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */
-
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
-}
-
-static inline void gen_evmwumia(DisasContext *ctx)
-{
- TCGv_i64 tmp;
-
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
-
- gen_evmwumi(ctx); /* rD := rA * rB */
-
- tmp = tcg_temp_new_i64();
-
- /* acc := rD */
- gen_load_gpr64(tmp, rD(ctx->opcode));
- tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
- tcg_temp_free_i64(tmp);
-}
-
-static inline void gen_evmwumiaa(DisasContext *ctx)
-{
- TCGv_i64 acc;
- TCGv_i64 tmp;
-
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
-
- gen_evmwumi(ctx); /* rD := rA * rB */
-
- acc = tcg_temp_new_i64();
- tmp = tcg_temp_new_i64();
-
- /* tmp := rD */
- gen_load_gpr64(tmp, rD(ctx->opcode));
-
- /* Load acc */
- tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
-
- /* acc := tmp + acc */
- tcg_gen_add_i64(acc, acc, tmp);
-
- /* Store acc */
- tcg_gen_st_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
-
- /* rD := acc */
- gen_store_gpr64(rD(ctx->opcode), acc);
-
- tcg_temp_free_i64(acc);
- tcg_temp_free_i64(tmp);
-}
-
-static inline void gen_evmwsmi(DisasContext *ctx)
-{
- TCGv_i64 t0, t1;
-
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
-
- t0 = tcg_temp_new_i64();
- t1 = tcg_temp_new_i64();
-
- /* t0 := rA; t1 := rB */
- tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_ext32s_i64(t0, t0);
- tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
- tcg_gen_ext32s_i64(t1, t1);
-
- tcg_gen_mul_i64(t0, t0, t1); /* t0 := rA * rB */
-
- gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */
-
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
-}
-
-static inline void gen_evmwsmia(DisasContext *ctx)
-{
- TCGv_i64 tmp;
-
- gen_evmwsmi(ctx); /* rD := rA * rB */
-
- tmp = tcg_temp_new_i64();
-
- /* acc := rD */
- gen_load_gpr64(tmp, rD(ctx->opcode));
- tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
-
- tcg_temp_free_i64(tmp);
-}
-
-static inline void gen_evmwsmiaa(DisasContext *ctx)
-{
- TCGv_i64 acc = tcg_temp_new_i64();
- TCGv_i64 tmp = tcg_temp_new_i64();
-
- gen_evmwsmi(ctx); /* rD := rA * rB */
-
- acc = tcg_temp_new_i64();
- tmp = tcg_temp_new_i64();
-
- /* tmp := rD */
- gen_load_gpr64(tmp, rD(ctx->opcode));
-
- /* Load acc */
- tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
-
- /* acc := tmp + acc */
- tcg_gen_add_i64(acc, acc, tmp);
-
- /* Store acc */
- tcg_gen_st_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
-
- /* rD := acc */
- gen_store_gpr64(rD(ctx->opcode), acc);
-
- tcg_temp_free_i64(acc);
- tcg_temp_free_i64(tmp);
-}
-
-GEN_SPE(evaddw, speundef, 0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
-GEN_SPE(evaddiw, speundef, 0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
-GEN_SPE(evsubfw, speundef, 0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
-GEN_SPE(evsubifw, speundef, 0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
-GEN_SPE(evabs, evneg, 0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
-GEN_SPE(evextsb, evextsh, 0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
-GEN_SPE(evrndw, evcntlzw, 0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
-GEN_SPE(evcntlsw, brinc, 0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE); //
-GEN_SPE(evmra, speundef, 0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE);
-GEN_SPE(speundef, evand, 0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE); ////
-GEN_SPE(evandc, speundef, 0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
-GEN_SPE(evxor, evor, 0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
-GEN_SPE(evnor, eveqv, 0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
-GEN_SPE(evmwumi, evmwsmi, 0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(evmwumia, evmwsmia, 0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(evmwumiaa, evmwsmiaa, 0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evorc, 0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE); ////
-GEN_SPE(evnand, speundef, 0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
-GEN_SPE(evsrwu, evsrws, 0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
-GEN_SPE(evsrwiu, evsrwis, 0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(evslw, speundef, 0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
-GEN_SPE(evslwi, speundef, 0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
-GEN_SPE(evrlw, evsplati, 0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE); //
-GEN_SPE(evrlwi, evsplatfi, 0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE);
-GEN_SPE(evmergehi, evmergelo, 0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
-GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
-GEN_SPE(evcmpgtu, evcmpgts, 0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE); ////
-GEN_SPE(evcmpltu, evcmplts, 0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE); ////
-GEN_SPE(evcmpeq, speundef, 0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE); ////
-
-/* SPE load and stores */
-static inline void gen_addr_spe_imm_index(DisasContext *ctx, TCGv EA, int sh)
-{
- target_ulong uimm = rB(ctx->opcode);
-
- if (rA(ctx->opcode) == 0) {
- tcg_gen_movi_tl(EA, uimm << sh);
- } else {
- tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], uimm << sh);
- if (NARROW_MODE(ctx)) {
- tcg_gen_ext32u_tl(EA, EA);
- }
- }
-}
-
-static inline void gen_op_evldd(DisasContext *ctx, TCGv addr)
-{
- TCGv_i64 t0 = tcg_temp_new_i64();
- gen_qemu_ld64_i64(ctx, t0, addr);
- gen_store_gpr64(rD(ctx->opcode), t0);
- tcg_temp_free_i64(t0);
-}
-
-static inline void gen_op_evldw(DisasContext *ctx, TCGv addr)
-{
- gen_qemu_ld32u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
- gen_addr_add(ctx, addr, addr, 4);
- gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
-}
-
-static inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
-{
- TCGv t0 = tcg_temp_new();
- gen_qemu_ld16u(ctx, t0, addr);
- tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
- gen_addr_add(ctx, addr, addr, 2);
- gen_qemu_ld16u(ctx, t0, addr);
- tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
- gen_addr_add(ctx, addr, addr, 2);
- gen_qemu_ld16u(ctx, t0, addr);
- tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
- gen_addr_add(ctx, addr, addr, 2);
- gen_qemu_ld16u(ctx, t0, addr);
- tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
- tcg_temp_free(t0);
-}
-
-static inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr)
-{
- TCGv t0 = tcg_temp_new();
- gen_qemu_ld16u(ctx, t0, addr);
- tcg_gen_shli_tl(t0, t0, 16);
- tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
- tcg_temp_free(t0);
-}
-
-static inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr)
-{
- TCGv t0 = tcg_temp_new();
- gen_qemu_ld16u(ctx, t0, addr);
- tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
- tcg_temp_free(t0);
-}
-
-static inline void gen_op_evlhhossplat(DisasContext *ctx, TCGv addr)
-{
- TCGv t0 = tcg_temp_new();
- gen_qemu_ld16s(ctx, t0, addr);
- tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
- tcg_temp_free(t0);
-}
-
-static inline void gen_op_evlwhe(DisasContext *ctx, TCGv addr)
-{
- TCGv t0 = tcg_temp_new();
- gen_qemu_ld16u(ctx, t0, addr);
- tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
- gen_addr_add(ctx, addr, addr, 2);
- gen_qemu_ld16u(ctx, t0, addr);
- tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
- tcg_temp_free(t0);
-}
-
-static inline void gen_op_evlwhou(DisasContext *ctx, TCGv addr)
-{
- gen_qemu_ld16u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
- gen_addr_add(ctx, addr, addr, 2);
- gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
-}
-
-static inline void gen_op_evlwhos(DisasContext *ctx, TCGv addr)
-{
- gen_qemu_ld16s(ctx, cpu_gprh[rD(ctx->opcode)], addr);
- gen_addr_add(ctx, addr, addr, 2);
- gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], addr);
-}
-
-static inline void gen_op_evlwwsplat(DisasContext *ctx, TCGv addr)
-{
- TCGv t0 = tcg_temp_new();
- gen_qemu_ld32u(ctx, t0, addr);
- tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
- tcg_temp_free(t0);
-}
-
-static inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
-{
- TCGv t0 = tcg_temp_new();
- gen_qemu_ld16u(ctx, t0, addr);
- tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
- tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
- gen_addr_add(ctx, addr, addr, 2);
- gen_qemu_ld16u(ctx, t0, addr);
- tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
- tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
- tcg_temp_free(t0);
-}
-
-static inline void gen_op_evstdd(DisasContext *ctx, TCGv addr)
-{
- TCGv_i64 t0 = tcg_temp_new_i64();
- gen_load_gpr64(t0, rS(ctx->opcode));
- gen_qemu_st64_i64(ctx, t0, addr);
- tcg_temp_free_i64(t0);
-}
-
-static inline void gen_op_evstdw(DisasContext *ctx, TCGv addr)
-{
- gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
- gen_addr_add(ctx, addr, addr, 4);
- gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
-}
-
-static inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
-{
- TCGv t0 = tcg_temp_new();
- tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
- gen_qemu_st16(ctx, t0, addr);
- gen_addr_add(ctx, addr, addr, 2);
- gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
- gen_addr_add(ctx, addr, addr, 2);
- tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
- gen_qemu_st16(ctx, t0, addr);
- tcg_temp_free(t0);
- gen_addr_add(ctx, addr, addr, 2);
- gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
-}
-
-static inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
-{
- TCGv t0 = tcg_temp_new();
- tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
- gen_qemu_st16(ctx, t0, addr);
- gen_addr_add(ctx, addr, addr, 2);
- tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
- gen_qemu_st16(ctx, t0, addr);
- tcg_temp_free(t0);
-}
-
-static inline void gen_op_evstwho(DisasContext *ctx, TCGv addr)
-{
- gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
- gen_addr_add(ctx, addr, addr, 2);
- gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
-}
-
-static inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr)
-{
- gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
-}
-
-static inline void gen_op_evstwwo(DisasContext *ctx, TCGv addr)
-{
- gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
-}
-
-#define GEN_SPEOP_LDST(name, opc2, sh) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- TCGv t0; \
- if (unlikely(!ctx->spe_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_SPEU); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_INT); \
- t0 = tcg_temp_new(); \
- if (Rc(ctx->opcode)) { \
- gen_addr_spe_imm_index(ctx, t0, sh); \
- } else { \
- gen_addr_reg_index(ctx, t0); \
- } \
- gen_op_##name(ctx, t0); \
- tcg_temp_free(t0); \
-}
-
-GEN_SPEOP_LDST(evldd, 0x00, 3);
-GEN_SPEOP_LDST(evldw, 0x01, 3);
-GEN_SPEOP_LDST(evldh, 0x02, 3);
-GEN_SPEOP_LDST(evlhhesplat, 0x04, 1);
-GEN_SPEOP_LDST(evlhhousplat, 0x06, 1);
-GEN_SPEOP_LDST(evlhhossplat, 0x07, 1);
-GEN_SPEOP_LDST(evlwhe, 0x08, 2);
-GEN_SPEOP_LDST(evlwhou, 0x0A, 2);
-GEN_SPEOP_LDST(evlwhos, 0x0B, 2);
-GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2);
-GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2);
-
-GEN_SPEOP_LDST(evstdd, 0x10, 3);
-GEN_SPEOP_LDST(evstdw, 0x11, 3);
-GEN_SPEOP_LDST(evstdh, 0x12, 3);
-GEN_SPEOP_LDST(evstwhe, 0x18, 2);
-GEN_SPEOP_LDST(evstwho, 0x1A, 2);
-GEN_SPEOP_LDST(evstwwe, 0x1C, 2);
-GEN_SPEOP_LDST(evstwwo, 0x1E, 2);
-
-/* Multiply and add - TODO */
-#if 0
-GEN_SPE(speundef, evmhessf, 0x01, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);//
-GEN_SPE(speundef, evmhossf, 0x03, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmheumi, evmhesmi, 0x04, 0x10, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhesmf, 0x05, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmhoumi, evmhosmi, 0x06, 0x10, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhosmf, 0x07, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhessfa, 0x11, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhossfa, 0x13, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmheumia, evmhesmia, 0x14, 0x10, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhesmfa, 0x15, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmhoumia, evmhosmia, 0x16, 0x10, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhosmfa, 0x17, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-
-GEN_SPE(speundef, evmwhssf, 0x03, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmwlumi, speundef, 0x04, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
-GEN_SPE(evmwhumi, evmwhsmi, 0x06, 0x11, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmwhsmf, 0x07, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmwssf, 0x09, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmwsmf, 0x0D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmwhssfa, 0x13, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmwlumia, speundef, 0x14, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
-GEN_SPE(evmwhumia, evmwhsmia, 0x16, 0x11, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmwhsmfa, 0x17, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmwssfa, 0x19, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmwsmfa, 0x1D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-
-GEN_SPE(evadduiaaw, evaddsiaaw, 0x00, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
-GEN_SPE(evsubfusiaaw, evsubfssiaaw, 0x01, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
-GEN_SPE(evaddumiaaw, evaddsmiaaw, 0x04, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
-GEN_SPE(evsubfumiaaw, evsubfsmiaaw, 0x05, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
-GEN_SPE(evdivws, evdivwu, 0x06, 0x13, 0x00000000, 0x00000000, PPC_SPE);
-
-GEN_SPE(evmheusiaaw, evmhessiaaw, 0x00, 0x14, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhessfaaw, 0x01, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmhousiaaw, evmhossiaaw, 0x02, 0x14, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhossfaaw, 0x03, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmheumiaaw, evmhesmiaaw, 0x04, 0x14, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhesmfaaw, 0x05, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmhoumiaaw, evmhosmiaaw, 0x06, 0x14, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhosmfaaw, 0x07, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmhegumiaa, evmhegsmiaa, 0x14, 0x14, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhegsmfaa, 0x15, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmhogumiaa, evmhogsmiaa, 0x16, 0x14, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhogsmfaa, 0x17, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-
-GEN_SPE(evmwlusiaaw, evmwlssiaaw, 0x00, 0x15, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(evmwlumiaaw, evmwlsmiaaw, 0x04, 0x15, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmwssfaa, 0x09, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmwsmfaa, 0x0D, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-
-GEN_SPE(evmheusianw, evmhessianw, 0x00, 0x16, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhessfanw, 0x01, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmhousianw, evmhossianw, 0x02, 0x16, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhossfanw, 0x03, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmheumianw, evmhesmianw, 0x04, 0x16, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhesmfanw, 0x05, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmhoumianw, evmhosmianw, 0x06, 0x16, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhosmfanw, 0x07, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmhegumian, evmhegsmian, 0x14, 0x16, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhegsmfan, 0x15, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmhigumian, evmhigsmian, 0x16, 0x16, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmhogsmfan, 0x17, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-
-GEN_SPE(evmwlusianw, evmwlssianw, 0x00, 0x17, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(evmwlumianw, evmwlsmianw, 0x04, 0x17, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmwssfan, 0x09, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-GEN_SPE(evmwumian, evmwsmian, 0x0C, 0x17, 0x00000000, 0x00000000, PPC_SPE);
-GEN_SPE(speundef, evmwsmfan, 0x0D, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
-#endif
-
-/*** SPE floating-point extension ***/
-#define GEN_SPEFPUOP_CONV_32_32(name) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_i32 t0 = tcg_temp_new_i32(); \
- tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]); \
- gen_helper_##name(t0, cpu_env, t0); \
- tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
- tcg_temp_free_i32(t0); \
-}
-#define GEN_SPEFPUOP_CONV_32_64(name) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_i64 t0 = tcg_temp_new_i64(); \
- TCGv_i32 t1 = tcg_temp_new_i32(); \
- gen_load_gpr64(t0, rB(ctx->opcode)); \
- gen_helper_##name(t1, cpu_env, t0); \
- tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1); \
- tcg_temp_free_i64(t0); \
- tcg_temp_free_i32(t1); \
-}
-#define GEN_SPEFPUOP_CONV_64_32(name) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_i64 t0 = tcg_temp_new_i64(); \
- TCGv_i32 t1 = tcg_temp_new_i32(); \
- tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \
- gen_helper_##name(t0, cpu_env, t1); \
- gen_store_gpr64(rD(ctx->opcode), t0); \
- tcg_temp_free_i64(t0); \
- tcg_temp_free_i32(t1); \
-}
-#define GEN_SPEFPUOP_CONV_64_64(name) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_i64 t0 = tcg_temp_new_i64(); \
- gen_load_gpr64(t0, rB(ctx->opcode)); \
- gen_helper_##name(t0, cpu_env, t0); \
- gen_store_gpr64(rD(ctx->opcode), t0); \
- tcg_temp_free_i64(t0); \
-}
-#define GEN_SPEFPUOP_ARITH2_32_32(name) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_i32 t0, t1; \
- if (unlikely(!ctx->spe_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_SPEU); \
- return; \
- } \
- t0 = tcg_temp_new_i32(); \
- t1 = tcg_temp_new_i32(); \
- tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
- tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \
- gen_helper_##name(t0, cpu_env, t0, t1); \
- tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0); \
- \
- tcg_temp_free_i32(t0); \
- tcg_temp_free_i32(t1); \
-}
-#define GEN_SPEFPUOP_ARITH2_64_64(name) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_i64 t0, t1; \
- if (unlikely(!ctx->spe_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_SPEU); \
- return; \
- } \
- t0 = tcg_temp_new_i64(); \
- t1 = tcg_temp_new_i64(); \
- gen_load_gpr64(t0, rA(ctx->opcode)); \
- gen_load_gpr64(t1, rB(ctx->opcode)); \
- gen_helper_##name(t0, cpu_env, t0, t1); \
- gen_store_gpr64(rD(ctx->opcode), t0); \
- tcg_temp_free_i64(t0); \
- tcg_temp_free_i64(t1); \
-}
-#define GEN_SPEFPUOP_COMP_32(name) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_i32 t0, t1; \
- if (unlikely(!ctx->spe_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_SPEU); \
- return; \
- } \
- t0 = tcg_temp_new_i32(); \
- t1 = tcg_temp_new_i32(); \
- \
- tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]); \
- tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]); \
- gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1); \
- \
- tcg_temp_free_i32(t0); \
- tcg_temp_free_i32(t1); \
-}
-#define GEN_SPEFPUOP_COMP_64(name) \
-static inline void gen_##name(DisasContext *ctx) \
-{ \
- TCGv_i64 t0, t1; \
- if (unlikely(!ctx->spe_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_SPEU); \
- return; \
- } \
- t0 = tcg_temp_new_i64(); \
- t1 = tcg_temp_new_i64(); \
- gen_load_gpr64(t0, rA(ctx->opcode)); \
- gen_load_gpr64(t1, rB(ctx->opcode)); \
- gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1); \
- tcg_temp_free_i64(t0); \
- tcg_temp_free_i64(t1); \
-}
-
-/* Single precision floating-point vectors operations */
-/* Arithmetic */
-GEN_SPEFPUOP_ARITH2_64_64(evfsadd);
-GEN_SPEFPUOP_ARITH2_64_64(evfssub);
-GEN_SPEFPUOP_ARITH2_64_64(evfsmul);
-GEN_SPEFPUOP_ARITH2_64_64(evfsdiv);
-static inline void gen_evfsabs(DisasContext *ctx)
-{
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
- tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
- ~0x80000000);
- tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
- ~0x80000000);
-}
-static inline void gen_evfsnabs(DisasContext *ctx)
-{
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
- tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
- 0x80000000);
- tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
- 0x80000000);
-}
-static inline void gen_evfsneg(DisasContext *ctx)
-{
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
- tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
- 0x80000000);
- tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
- 0x80000000);
-}
-
-/* Conversion */
-GEN_SPEFPUOP_CONV_64_64(evfscfui);
-GEN_SPEFPUOP_CONV_64_64(evfscfsi);
-GEN_SPEFPUOP_CONV_64_64(evfscfuf);
-GEN_SPEFPUOP_CONV_64_64(evfscfsf);
-GEN_SPEFPUOP_CONV_64_64(evfsctui);
-GEN_SPEFPUOP_CONV_64_64(evfsctsi);
-GEN_SPEFPUOP_CONV_64_64(evfsctuf);
-GEN_SPEFPUOP_CONV_64_64(evfsctsf);
-GEN_SPEFPUOP_CONV_64_64(evfsctuiz);
-GEN_SPEFPUOP_CONV_64_64(evfsctsiz);
-
-/* Comparison */
-GEN_SPEFPUOP_COMP_64(evfscmpgt);
-GEN_SPEFPUOP_COMP_64(evfscmplt);
-GEN_SPEFPUOP_COMP_64(evfscmpeq);
-GEN_SPEFPUOP_COMP_64(evfststgt);
-GEN_SPEFPUOP_COMP_64(evfststlt);
-GEN_SPEFPUOP_COMP_64(evfststeq);
-
-/* Opcodes definitions */
-GEN_SPE(evfsadd, evfssub, 0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
-GEN_SPE(evfsabs, evfsnabs, 0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); //
-GEN_SPE(evfsneg, speundef, 0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); //
-GEN_SPE(evfsmul, evfsdiv, 0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
-GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
-GEN_SPE(evfscmpeq, speundef, 0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
-GEN_SPE(evfscfui, evfscfsi, 0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
-GEN_SPE(evfscfuf, evfscfsf, 0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
-GEN_SPE(evfsctui, evfsctsi, 0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
-GEN_SPE(evfsctuf, evfsctsf, 0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
-GEN_SPE(evfsctuiz, speundef, 0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
-GEN_SPE(evfsctsiz, speundef, 0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
-GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
-GEN_SPE(evfststeq, speundef, 0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
-
-/* Single precision floating-point operations */
-/* Arithmetic */
-GEN_SPEFPUOP_ARITH2_32_32(efsadd);
-GEN_SPEFPUOP_ARITH2_32_32(efssub);
-GEN_SPEFPUOP_ARITH2_32_32(efsmul);
-GEN_SPEFPUOP_ARITH2_32_32(efsdiv);
-static inline void gen_efsabs(DisasContext *ctx)
-{
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
- tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL);
-}
-static inline void gen_efsnabs(DisasContext *ctx)
-{
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
- tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
-}
-static inline void gen_efsneg(DisasContext *ctx)
-{
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
- tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
-}
-
-/* Conversion */
-GEN_SPEFPUOP_CONV_32_32(efscfui);
-GEN_SPEFPUOP_CONV_32_32(efscfsi);
-GEN_SPEFPUOP_CONV_32_32(efscfuf);
-GEN_SPEFPUOP_CONV_32_32(efscfsf);
-GEN_SPEFPUOP_CONV_32_32(efsctui);
-GEN_SPEFPUOP_CONV_32_32(efsctsi);
-GEN_SPEFPUOP_CONV_32_32(efsctuf);
-GEN_SPEFPUOP_CONV_32_32(efsctsf);
-GEN_SPEFPUOP_CONV_32_32(efsctuiz);
-GEN_SPEFPUOP_CONV_32_32(efsctsiz);
-GEN_SPEFPUOP_CONV_32_64(efscfd);
-
-/* Comparison */
-GEN_SPEFPUOP_COMP_32(efscmpgt);
-GEN_SPEFPUOP_COMP_32(efscmplt);
-GEN_SPEFPUOP_COMP_32(efscmpeq);
-GEN_SPEFPUOP_COMP_32(efststgt);
-GEN_SPEFPUOP_COMP_32(efststlt);
-GEN_SPEFPUOP_COMP_32(efststeq);
-
-/* Opcodes definitions */
-GEN_SPE(efsadd, efssub, 0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
-GEN_SPE(efsabs, efsnabs, 0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); //
-GEN_SPE(efsneg, speundef, 0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); //
-GEN_SPE(efsmul, efsdiv, 0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
-GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
-GEN_SPE(efscmpeq, efscfd, 0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE); //
-GEN_SPE(efscfui, efscfsi, 0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
-GEN_SPE(efscfuf, efscfsf, 0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
-GEN_SPE(efsctui, efsctsi, 0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
-GEN_SPE(efsctuf, efsctsf, 0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
-GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
-GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
-GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
-GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
-
-/* Double precision floating-point operations */
-/* Arithmetic */
-GEN_SPEFPUOP_ARITH2_64_64(efdadd);
-GEN_SPEFPUOP_ARITH2_64_64(efdsub);
-GEN_SPEFPUOP_ARITH2_64_64(efdmul);
-GEN_SPEFPUOP_ARITH2_64_64(efddiv);
-static inline void gen_efdabs(DisasContext *ctx)
-{
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
- ~0x80000000);
-}
-static inline void gen_efdnabs(DisasContext *ctx)
-{
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
- 0x80000000);
-}
-static inline void gen_efdneg(DisasContext *ctx)
-{
- if (unlikely(!ctx->spe_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_SPEU);
- return;
- }
- tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
- tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
- 0x80000000);
-}
-
-/* Conversion */
-GEN_SPEFPUOP_CONV_64_32(efdcfui);
-GEN_SPEFPUOP_CONV_64_32(efdcfsi);
-GEN_SPEFPUOP_CONV_64_32(efdcfuf);
-GEN_SPEFPUOP_CONV_64_32(efdcfsf);
-GEN_SPEFPUOP_CONV_32_64(efdctui);
-GEN_SPEFPUOP_CONV_32_64(efdctsi);
-GEN_SPEFPUOP_CONV_32_64(efdctuf);
-GEN_SPEFPUOP_CONV_32_64(efdctsf);
-GEN_SPEFPUOP_CONV_32_64(efdctuiz);
-GEN_SPEFPUOP_CONV_32_64(efdctsiz);
-GEN_SPEFPUOP_CONV_64_32(efdcfs);
-GEN_SPEFPUOP_CONV_64_64(efdcfuid);
-GEN_SPEFPUOP_CONV_64_64(efdcfsid);
-GEN_SPEFPUOP_CONV_64_64(efdctuidz);
-GEN_SPEFPUOP_CONV_64_64(efdctsidz);
-
-/* Comparison */
-GEN_SPEFPUOP_COMP_64(efdcmpgt);
-GEN_SPEFPUOP_COMP_64(efdcmplt);
-GEN_SPEFPUOP_COMP_64(efdcmpeq);
-GEN_SPEFPUOP_COMP_64(efdtstgt);
-GEN_SPEFPUOP_COMP_64(efdtstlt);
-GEN_SPEFPUOP_COMP_64(efdtsteq);
-
-/* Opcodes definitions */
-GEN_SPE(efdadd, efdsub, 0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); //
-GEN_SPE(efdcfuid, efdcfsid, 0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
-GEN_SPE(efdabs, efdnabs, 0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE); //
-GEN_SPE(efdneg, speundef, 0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
-GEN_SPE(efdmul, efddiv, 0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); //
-GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
-GEN_SPE(efdcmpgt, efdcmplt, 0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
-GEN_SPE(efdcmpeq, efdcfs, 0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE); //
-GEN_SPE(efdcfui, efdcfsi, 0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
-GEN_SPE(efdcfuf, efdcfsf, 0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
-GEN_SPE(efdctui, efdctsi, 0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
-GEN_SPE(efdctuf, efdctsf, 0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
-GEN_SPE(efdctuiz, speundef, 0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
-GEN_SPE(efdctsiz, speundef, 0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
-GEN_SPE(efdtstgt, efdtstlt, 0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
-GEN_SPE(efdtsteq, speundef, 0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
-
-#undef GEN_SPE
-#undef GEN_SPEOP_LDST
diff --git a/target-ppc/translate/spe-ops.inc.c b/target-ppc/translate/spe-ops.inc.c
deleted file mode 100644
index 7efe8b8746..0000000000
--- a/target-ppc/translate/spe-ops.inc.c
+++ /dev/null
@@ -1,105 +0,0 @@
-GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE),
-GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE),
-GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE),
-GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE),
-
-#define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \
- GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE)
-GEN_SPE(evaddw, speundef, 0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
-GEN_SPE(evaddiw, speundef, 0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
-GEN_SPE(evsubfw, speundef, 0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
-GEN_SPE(evsubifw, speundef, 0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
-GEN_SPE(evabs, evneg, 0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
-GEN_SPE(evextsb, evextsh, 0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
-GEN_SPE(evrndw, evcntlzw, 0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
-GEN_SPE(evcntlsw, brinc, 0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE),
-GEN_SPE(evmra, speundef, 0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE),
-GEN_SPE(speundef, evand, 0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
-GEN_SPE(evandc, speundef, 0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
-GEN_SPE(evxor, evor, 0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE),
-GEN_SPE(evnor, eveqv, 0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE),
-GEN_SPE(evmwumi, evmwsmi, 0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
-GEN_SPE(evmwumia, evmwsmia, 0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
-GEN_SPE(evmwumiaa, evmwsmiaa, 0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE),
-GEN_SPE(speundef, evorc, 0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
-GEN_SPE(evnand, speundef, 0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
-GEN_SPE(evsrwu, evsrws, 0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE),
-GEN_SPE(evsrwiu, evsrwis, 0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE),
-GEN_SPE(evslw, speundef, 0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
-GEN_SPE(evslwi, speundef, 0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
-GEN_SPE(evrlw, evsplati, 0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
-GEN_SPE(evrlwi, evsplatfi, 0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
-GEN_SPE(evmergehi, evmergelo, 0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE),
-GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE),
-GEN_SPE(evcmpgtu, evcmpgts, 0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE),
-GEN_SPE(evcmpltu, evcmplts, 0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE),
-GEN_SPE(evcmpeq, speundef, 0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE),
-
-GEN_SPE(evfsadd, evfssub, 0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
-GEN_SPE(evfsabs, evfsnabs, 0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
-GEN_SPE(evfsneg, speundef, 0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
-GEN_SPE(evfsmul, evfsdiv, 0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
-GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
-GEN_SPE(evfscmpeq, speundef, 0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
-GEN_SPE(evfscfui, evfscfsi, 0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
-GEN_SPE(evfscfuf, evfscfsf, 0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
-GEN_SPE(evfsctui, evfsctsi, 0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
-GEN_SPE(evfsctuf, evfsctsf, 0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
-GEN_SPE(evfsctuiz, speundef, 0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
-GEN_SPE(evfsctsiz, speundef, 0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
-GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
-GEN_SPE(evfststeq, speundef, 0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
-
-GEN_SPE(efsadd, efssub, 0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
-GEN_SPE(efsabs, efsnabs, 0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
-GEN_SPE(efsneg, speundef, 0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
-GEN_SPE(efsmul, efsdiv, 0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
-GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
-GEN_SPE(efscmpeq, efscfd, 0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE),
-GEN_SPE(efscfui, efscfsi, 0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
-GEN_SPE(efscfuf, efscfsf, 0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
-GEN_SPE(efsctui, efsctsi, 0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
-GEN_SPE(efsctuf, efsctsf, 0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
-GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
-GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
-GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
-GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
-
-GEN_SPE(efdadd, efdsub, 0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
-GEN_SPE(efdcfuid, efdcfsid, 0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
-GEN_SPE(efdabs, efdnabs, 0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE),
-GEN_SPE(efdneg, speundef, 0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE),
-GEN_SPE(efdmul, efddiv, 0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
-GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
-GEN_SPE(efdcmpgt, efdcmplt, 0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
-GEN_SPE(efdcmpeq, efdcfs, 0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE),
-GEN_SPE(efdcfui, efdcfsi, 0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
-GEN_SPE(efdcfuf, efdcfsf, 0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
-GEN_SPE(efdctui, efdctsi, 0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
-GEN_SPE(efdctuf, efdctsf, 0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
-GEN_SPE(efdctuiz, speundef, 0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
-GEN_SPE(efdctsiz, speundef, 0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
-GEN_SPE(efdtstgt, efdtstlt, 0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
-GEN_SPE(efdtsteq, speundef, 0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
-
-#define GEN_SPEOP_LDST(name, opc2, sh) \
-GEN_HANDLER(name, 0x04, opc2, 0x0C, 0x00000000, PPC_SPE)
-GEN_SPEOP_LDST(evldd, 0x00, 3),
-GEN_SPEOP_LDST(evldw, 0x01, 3),
-GEN_SPEOP_LDST(evldh, 0x02, 3),
-GEN_SPEOP_LDST(evlhhesplat, 0x04, 1),
-GEN_SPEOP_LDST(evlhhousplat, 0x06, 1),
-GEN_SPEOP_LDST(evlhhossplat, 0x07, 1),
-GEN_SPEOP_LDST(evlwhe, 0x08, 2),
-GEN_SPEOP_LDST(evlwhou, 0x0A, 2),
-GEN_SPEOP_LDST(evlwhos, 0x0B, 2),
-GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2),
-GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2),
-
-GEN_SPEOP_LDST(evstdd, 0x10, 3),
-GEN_SPEOP_LDST(evstdw, 0x11, 3),
-GEN_SPEOP_LDST(evstdh, 0x12, 3),
-GEN_SPEOP_LDST(evstwhe, 0x18, 2),
-GEN_SPEOP_LDST(evstwho, 0x1A, 2),
-GEN_SPEOP_LDST(evstwwe, 0x1C, 2),
-GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
diff --git a/target-ppc/translate/vmx-impl.inc.c b/target-ppc/translate/vmx-impl.inc.c
deleted file mode 100644
index 7143eb3a39..0000000000
--- a/target-ppc/translate/vmx-impl.inc.c
+++ /dev/null
@@ -1,1113 +0,0 @@
-/*
- * translate/vmx-impl.c
- *
- * Altivec/VMX translation
- */
-
-/*** Altivec vector extension ***/
-/* Altivec registers moves */
-
-static inline TCGv_ptr gen_avr_ptr(int reg)
-{
- TCGv_ptr r = tcg_temp_new_ptr();
- tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, avr[reg]));
- return r;
-}
-
-#define GEN_VR_LDX(name, opc2, opc3) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- TCGv EA; \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_INT); \
- EA = tcg_temp_new(); \
- gen_addr_reg_index(ctx, EA); \
- tcg_gen_andi_tl(EA, EA, ~0xf); \
- /* We only need to swap high and low halves. gen_qemu_ld64_i64 does \
- necessary 64-bit byteswap already. */ \
- if (ctx->le_mode) { \
- gen_qemu_ld64_i64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \
- tcg_gen_addi_tl(EA, EA, 8); \
- gen_qemu_ld64_i64(ctx, cpu_avrh[rD(ctx->opcode)], EA); \
- } else { \
- gen_qemu_ld64_i64(ctx, cpu_avrh[rD(ctx->opcode)], EA); \
- tcg_gen_addi_tl(EA, EA, 8); \
- gen_qemu_ld64_i64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \
- } \
- tcg_temp_free(EA); \
-}
-
-#define GEN_VR_STX(name, opc2, opc3) \
-static void gen_st##name(DisasContext *ctx) \
-{ \
- TCGv EA; \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_INT); \
- EA = tcg_temp_new(); \
- gen_addr_reg_index(ctx, EA); \
- tcg_gen_andi_tl(EA, EA, ~0xf); \
- /* We only need to swap high and low halves. gen_qemu_st64_i64 does \
- necessary 64-bit byteswap already. */ \
- if (ctx->le_mode) { \
- gen_qemu_st64_i64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \
- tcg_gen_addi_tl(EA, EA, 8); \
- gen_qemu_st64_i64(ctx, cpu_avrh[rD(ctx->opcode)], EA); \
- } else { \
- gen_qemu_st64_i64(ctx, cpu_avrh[rD(ctx->opcode)], EA); \
- tcg_gen_addi_tl(EA, EA, 8); \
- gen_qemu_st64_i64(ctx, cpu_avrl[rD(ctx->opcode)], EA); \
- } \
- tcg_temp_free(EA); \
-}
-
-#define GEN_VR_LVE(name, opc2, opc3, size) \
-static void gen_lve##name(DisasContext *ctx) \
- { \
- TCGv EA; \
- TCGv_ptr rs; \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_INT); \
- EA = tcg_temp_new(); \
- gen_addr_reg_index(ctx, EA); \
- if (size > 1) { \
- tcg_gen_andi_tl(EA, EA, ~(size - 1)); \
- } \
- rs = gen_avr_ptr(rS(ctx->opcode)); \
- gen_helper_lve##name(cpu_env, rs, EA); \
- tcg_temp_free(EA); \
- tcg_temp_free_ptr(rs); \
- }
-
-#define GEN_VR_STVE(name, opc2, opc3, size) \
-static void gen_stve##name(DisasContext *ctx) \
- { \
- TCGv EA; \
- TCGv_ptr rs; \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_INT); \
- EA = tcg_temp_new(); \
- gen_addr_reg_index(ctx, EA); \
- if (size > 1) { \
- tcg_gen_andi_tl(EA, EA, ~(size - 1)); \
- } \
- rs = gen_avr_ptr(rS(ctx->opcode)); \
- gen_helper_stve##name(cpu_env, rs, EA); \
- tcg_temp_free(EA); \
- tcg_temp_free_ptr(rs); \
- }
-
-GEN_VR_LDX(lvx, 0x07, 0x03);
-/* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
-GEN_VR_LDX(lvxl, 0x07, 0x0B);
-
-GEN_VR_LVE(bx, 0x07, 0x00, 1);
-GEN_VR_LVE(hx, 0x07, 0x01, 2);
-GEN_VR_LVE(wx, 0x07, 0x02, 4);
-
-GEN_VR_STX(svx, 0x07, 0x07);
-/* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
-GEN_VR_STX(svxl, 0x07, 0x0F);
-
-GEN_VR_STVE(bx, 0x07, 0x04, 1);
-GEN_VR_STVE(hx, 0x07, 0x05, 2);
-GEN_VR_STVE(wx, 0x07, 0x06, 4);
-
-static void gen_lvsl(DisasContext *ctx)
-{
- TCGv_ptr rd;
- TCGv EA;
- if (unlikely(!ctx->altivec_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VPU);
- return;
- }
- EA = tcg_temp_new();
- gen_addr_reg_index(ctx, EA);
- rd = gen_avr_ptr(rD(ctx->opcode));
- gen_helper_lvsl(rd, EA);
- tcg_temp_free(EA);
- tcg_temp_free_ptr(rd);
-}
-
-static void gen_lvsr(DisasContext *ctx)
-{
- TCGv_ptr rd;
- TCGv EA;
- if (unlikely(!ctx->altivec_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VPU);
- return;
- }
- EA = tcg_temp_new();
- gen_addr_reg_index(ctx, EA);
- rd = gen_avr_ptr(rD(ctx->opcode));
- gen_helper_lvsr(rd, EA);
- tcg_temp_free(EA);
- tcg_temp_free_ptr(rd);
-}
-
-static void gen_mfvscr(DisasContext *ctx)
-{
- TCGv_i32 t;
- if (unlikely(!ctx->altivec_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VPU);
- return;
- }
- tcg_gen_movi_i64(cpu_avrh[rD(ctx->opcode)], 0);
- t = tcg_temp_new_i32();
- tcg_gen_ld_i32(t, cpu_env, offsetof(CPUPPCState, vscr));
- tcg_gen_extu_i32_i64(cpu_avrl[rD(ctx->opcode)], t);
- tcg_temp_free_i32(t);
-}
-
-static void gen_mtvscr(DisasContext *ctx)
-{
- TCGv_ptr p;
- if (unlikely(!ctx->altivec_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VPU);
- return;
- }
- p = gen_avr_ptr(rB(ctx->opcode));
- gen_helper_mtvscr(cpu_env, p);
- tcg_temp_free_ptr(p);
-}
-
-#define GEN_VX_VMUL10(name, add_cin, ret_carry) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- TCGv_i64 t0 = tcg_temp_new_i64(); \
- TCGv_i64 t1 = tcg_temp_new_i64(); \
- TCGv_i64 t2 = tcg_temp_new_i64(); \
- TCGv_i64 ten, z; \
- \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- \
- ten = tcg_const_i64(10); \
- z = tcg_const_i64(0); \
- \
- if (add_cin) { \
- tcg_gen_mulu2_i64(t0, t1, cpu_avrl[rA(ctx->opcode)], ten); \
- tcg_gen_andi_i64(t2, cpu_avrl[rB(ctx->opcode)], 0xF); \
- tcg_gen_add2_i64(cpu_avrl[rD(ctx->opcode)], t2, t0, t1, t2, z); \
- } else { \
- tcg_gen_mulu2_i64(cpu_avrl[rD(ctx->opcode)], t2, \
- cpu_avrl[rA(ctx->opcode)], ten); \
- } \
- \
- if (ret_carry) { \
- tcg_gen_mulu2_i64(t0, t1, cpu_avrh[rA(ctx->opcode)], ten); \
- tcg_gen_add2_i64(t0, cpu_avrl[rD(ctx->opcode)], t0, t1, t2, z); \
- tcg_gen_movi_i64(cpu_avrh[rD(ctx->opcode)], 0); \
- } else { \
- tcg_gen_mul_i64(t0, cpu_avrh[rA(ctx->opcode)], ten); \
- tcg_gen_add_i64(cpu_avrh[rD(ctx->opcode)], t0, t2); \
- } \
- \
- tcg_temp_free_i64(t0); \
- tcg_temp_free_i64(t1); \
- tcg_temp_free_i64(t2); \
- tcg_temp_free_i64(ten); \
- tcg_temp_free_i64(z); \
-} \
-
-GEN_VX_VMUL10(vmul10uq, 0, 0);
-GEN_VX_VMUL10(vmul10euq, 1, 0);
-GEN_VX_VMUL10(vmul10cuq, 0, 1);
-GEN_VX_VMUL10(vmul10ecuq, 1, 1);
-
-/* Logical operations */
-#define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- tcg_op(cpu_avrh[rD(ctx->opcode)], cpu_avrh[rA(ctx->opcode)], cpu_avrh[rB(ctx->opcode)]); \
- tcg_op(cpu_avrl[rD(ctx->opcode)], cpu_avrl[rA(ctx->opcode)], cpu_avrl[rB(ctx->opcode)]); \
-}
-
-GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16);
-GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17);
-GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18);
-GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19);
-GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20);
-GEN_VX_LOGICAL(veqv, tcg_gen_eqv_i64, 2, 26);
-GEN_VX_LOGICAL(vnand, tcg_gen_nand_i64, 2, 22);
-GEN_VX_LOGICAL(vorc, tcg_gen_orc_i64, 2, 21);
-
-#define GEN_VXFORM(name, opc2, opc3) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- TCGv_ptr ra, rb, rd; \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- ra = gen_avr_ptr(rA(ctx->opcode)); \
- rb = gen_avr_ptr(rB(ctx->opcode)); \
- rd = gen_avr_ptr(rD(ctx->opcode)); \
- gen_helper_##name (rd, ra, rb); \
- tcg_temp_free_ptr(ra); \
- tcg_temp_free_ptr(rb); \
- tcg_temp_free_ptr(rd); \
-}
-
-#define GEN_VXFORM_ENV(name, opc2, opc3) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- TCGv_ptr ra, rb, rd; \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- ra = gen_avr_ptr(rA(ctx->opcode)); \
- rb = gen_avr_ptr(rB(ctx->opcode)); \
- rd = gen_avr_ptr(rD(ctx->opcode)); \
- gen_helper_##name(cpu_env, rd, ra, rb); \
- tcg_temp_free_ptr(ra); \
- tcg_temp_free_ptr(rb); \
- tcg_temp_free_ptr(rd); \
-}
-
-#define GEN_VXFORM3(name, opc2, opc3) \
-static void glue(gen_, name)(DisasContext *ctx) \
-{ \
- TCGv_ptr ra, rb, rc, rd; \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- ra = gen_avr_ptr(rA(ctx->opcode)); \
- rb = gen_avr_ptr(rB(ctx->opcode)); \
- rc = gen_avr_ptr(rC(ctx->opcode)); \
- rd = gen_avr_ptr(rD(ctx->opcode)); \
- gen_helper_##name(rd, ra, rb, rc); \
- tcg_temp_free_ptr(ra); \
- tcg_temp_free_ptr(rb); \
- tcg_temp_free_ptr(rc); \
- tcg_temp_free_ptr(rd); \
-}
-
-/*
- * Support for Altivec instruction pairs that use bit 31 (Rc) as
- * an opcode bit. In general, these pairs come from different
- * versions of the ISA, so we must also support a pair of flags for
- * each instruction.
- */
-#define GEN_VXFORM_DUAL(name0, flg0, flg2_0, name1, flg1, flg2_1) \
-static void glue(gen_, name0##_##name1)(DisasContext *ctx) \
-{ \
- if ((Rc(ctx->opcode) == 0) && \
- ((ctx->insns_flags & flg0) || (ctx->insns_flags2 & flg2_0))) { \
- gen_##name0(ctx); \
- } else if ((Rc(ctx->opcode) == 1) && \
- ((ctx->insns_flags & flg1) || (ctx->insns_flags2 & flg2_1))) { \
- gen_##name1(ctx); \
- } else { \
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
- } \
-}
-
-/* Adds support to provide invalid mask */
-#define GEN_VXFORM_DUAL_EXT(name0, flg0, flg2_0, inval0, \
- name1, flg1, flg2_1, inval1) \
-static void glue(gen_, name0##_##name1)(DisasContext *ctx) \
-{ \
- if ((Rc(ctx->opcode) == 0) && \
- ((ctx->insns_flags & flg0) || (ctx->insns_flags2 & flg2_0)) && \
- !(ctx->opcode & inval0)) { \
- gen_##name0(ctx); \
- } else if ((Rc(ctx->opcode) == 1) && \
- ((ctx->insns_flags & flg1) || (ctx->insns_flags2 & flg2_1)) && \
- !(ctx->opcode & inval1)) { \
- gen_##name1(ctx); \
- } else { \
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
- } \
-}
-
-GEN_VXFORM(vaddubm, 0, 0);
-GEN_VXFORM_DUAL_EXT(vaddubm, PPC_ALTIVEC, PPC_NONE, 0, \
- vmul10cuq, PPC_NONE, PPC2_ISA300, 0x0000F800)
-GEN_VXFORM(vadduhm, 0, 1);
-GEN_VXFORM_DUAL(vadduhm, PPC_ALTIVEC, PPC_NONE, \
- vmul10ecuq, PPC_NONE, PPC2_ISA300)
-GEN_VXFORM(vadduwm, 0, 2);
-GEN_VXFORM(vaddudm, 0, 3);
-GEN_VXFORM(vsububm, 0, 16);
-GEN_VXFORM(vsubuhm, 0, 17);
-GEN_VXFORM(vsubuwm, 0, 18);
-GEN_VXFORM(vsubudm, 0, 19);
-GEN_VXFORM(vmaxub, 1, 0);
-GEN_VXFORM(vmaxuh, 1, 1);
-GEN_VXFORM(vmaxuw, 1, 2);
-GEN_VXFORM(vmaxud, 1, 3);
-GEN_VXFORM(vmaxsb, 1, 4);
-GEN_VXFORM(vmaxsh, 1, 5);
-GEN_VXFORM(vmaxsw, 1, 6);
-GEN_VXFORM(vmaxsd, 1, 7);
-GEN_VXFORM(vminub, 1, 8);
-GEN_VXFORM(vminuh, 1, 9);
-GEN_VXFORM(vminuw, 1, 10);
-GEN_VXFORM(vminud, 1, 11);
-GEN_VXFORM(vminsb, 1, 12);
-GEN_VXFORM(vminsh, 1, 13);
-GEN_VXFORM(vminsw, 1, 14);
-GEN_VXFORM(vminsd, 1, 15);
-GEN_VXFORM(vavgub, 1, 16);
-GEN_VXFORM(vabsdub, 1, 16);
-GEN_VXFORM_DUAL(vavgub, PPC_ALTIVEC, PPC_NONE, \
- vabsdub, PPC_NONE, PPC2_ISA300)
-GEN_VXFORM(vavguh, 1, 17);
-GEN_VXFORM(vabsduh, 1, 17);
-GEN_VXFORM_DUAL(vavguh, PPC_ALTIVEC, PPC_NONE, \
- vabsduh, PPC_NONE, PPC2_ISA300)
-GEN_VXFORM(vavguw, 1, 18);
-GEN_VXFORM(vabsduw, 1, 18);
-GEN_VXFORM_DUAL(vavguw, PPC_ALTIVEC, PPC_NONE, \
- vabsduw, PPC_NONE, PPC2_ISA300)
-GEN_VXFORM(vavgsb, 1, 20);
-GEN_VXFORM(vavgsh, 1, 21);
-GEN_VXFORM(vavgsw, 1, 22);
-GEN_VXFORM(vmrghb, 6, 0);
-GEN_VXFORM(vmrghh, 6, 1);
-GEN_VXFORM(vmrghw, 6, 2);
-GEN_VXFORM(vmrglb, 6, 4);
-GEN_VXFORM(vmrglh, 6, 5);
-GEN_VXFORM(vmrglw, 6, 6);
-
-static void gen_vmrgew(DisasContext *ctx)
-{
- TCGv_i64 tmp;
- int VT, VA, VB;
- if (unlikely(!ctx->altivec_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VPU);
- return;
- }
- VT = rD(ctx->opcode);
- VA = rA(ctx->opcode);
- VB = rB(ctx->opcode);
- tmp = tcg_temp_new_i64();
- tcg_gen_shri_i64(tmp, cpu_avrh[VB], 32);
- tcg_gen_deposit_i64(cpu_avrh[VT], cpu_avrh[VA], tmp, 0, 32);
- tcg_gen_shri_i64(tmp, cpu_avrl[VB], 32);
- tcg_gen_deposit_i64(cpu_avrl[VT], cpu_avrl[VA], tmp, 0, 32);
- tcg_temp_free_i64(tmp);
-}
-
-static void gen_vmrgow(DisasContext *ctx)
-{
- int VT, VA, VB;
- if (unlikely(!ctx->altivec_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VPU);
- return;
- }
- VT = rD(ctx->opcode);
- VA = rA(ctx->opcode);
- VB = rB(ctx->opcode);
-
- tcg_gen_deposit_i64(cpu_avrh[VT], cpu_avrh[VB], cpu_avrh[VA], 32, 32);
- tcg_gen_deposit_i64(cpu_avrl[VT], cpu_avrl[VB], cpu_avrl[VA], 32, 32);
-}
-
-GEN_VXFORM(vmuloub, 4, 0);
-GEN_VXFORM(vmulouh, 4, 1);
-GEN_VXFORM(vmulouw, 4, 2);
-GEN_VXFORM(vmuluwm, 4, 2);
-GEN_VXFORM_DUAL(vmulouw, PPC_ALTIVEC, PPC_NONE,
- vmuluwm, PPC_NONE, PPC2_ALTIVEC_207)
-GEN_VXFORM(vmulosb, 4, 4);
-GEN_VXFORM(vmulosh, 4, 5);
-GEN_VXFORM(vmulosw, 4, 6);
-GEN_VXFORM(vmuleub, 4, 8);
-GEN_VXFORM(vmuleuh, 4, 9);
-GEN_VXFORM(vmuleuw, 4, 10);
-GEN_VXFORM(vmulesb, 4, 12);
-GEN_VXFORM(vmulesh, 4, 13);
-GEN_VXFORM(vmulesw, 4, 14);
-GEN_VXFORM(vslb, 2, 4);
-GEN_VXFORM(vslh, 2, 5);
-GEN_VXFORM(vslw, 2, 6);
-GEN_VXFORM(vrlwnm, 2, 6);
-GEN_VXFORM_DUAL(vslw, PPC_ALTIVEC, PPC_NONE, \
- vrlwnm, PPC_NONE, PPC2_ISA300)
-GEN_VXFORM(vsld, 2, 23);
-GEN_VXFORM(vsrb, 2, 8);
-GEN_VXFORM(vsrh, 2, 9);
-GEN_VXFORM(vsrw, 2, 10);
-GEN_VXFORM(vsrd, 2, 27);
-GEN_VXFORM(vsrab, 2, 12);
-GEN_VXFORM(vsrah, 2, 13);
-GEN_VXFORM(vsraw, 2, 14);
-GEN_VXFORM(vsrad, 2, 15);
-GEN_VXFORM(vsrv, 2, 28);
-GEN_VXFORM(vslv, 2, 29);
-GEN_VXFORM(vslo, 6, 16);
-GEN_VXFORM(vsro, 6, 17);
-GEN_VXFORM(vaddcuw, 0, 6);
-GEN_VXFORM(vsubcuw, 0, 22);
-GEN_VXFORM_ENV(vaddubs, 0, 8);
-GEN_VXFORM_DUAL_EXT(vaddubs, PPC_ALTIVEC, PPC_NONE, 0, \
- vmul10uq, PPC_NONE, PPC2_ISA300, 0x0000F800)
-GEN_VXFORM_ENV(vadduhs, 0, 9);
-GEN_VXFORM_DUAL(vadduhs, PPC_ALTIVEC, PPC_NONE, \
- vmul10euq, PPC_NONE, PPC2_ISA300)
-GEN_VXFORM_ENV(vadduws, 0, 10);
-GEN_VXFORM_ENV(vaddsbs, 0, 12);
-GEN_VXFORM_ENV(vaddshs, 0, 13);
-GEN_VXFORM_ENV(vaddsws, 0, 14);
-GEN_VXFORM_ENV(vsububs, 0, 24);
-GEN_VXFORM_ENV(vsubuhs, 0, 25);
-GEN_VXFORM_ENV(vsubuws, 0, 26);
-GEN_VXFORM_ENV(vsubsbs, 0, 28);
-GEN_VXFORM_ENV(vsubshs, 0, 29);
-GEN_VXFORM_ENV(vsubsws, 0, 30);
-GEN_VXFORM(vadduqm, 0, 4);
-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);
-GEN_VXFORM3(vsubecuq, 31, 0);
-GEN_VXFORM_DUAL(vsubeuqm, PPC_NONE, PPC2_ALTIVEC_207, \
- vsubecuq, PPC_NONE, PPC2_ALTIVEC_207)
-GEN_VXFORM(vrlb, 2, 0);
-GEN_VXFORM(vrlh, 2, 1);
-GEN_VXFORM(vrlw, 2, 2);
-GEN_VXFORM(vrlwmi, 2, 2);
-GEN_VXFORM_DUAL(vrlw, PPC_ALTIVEC, PPC_NONE, \
- vrlwmi, PPC_NONE, PPC2_ISA300)
-GEN_VXFORM(vrld, 2, 3);
-GEN_VXFORM(vrldmi, 2, 3);
-GEN_VXFORM_DUAL(vrld, PPC_NONE, PPC2_ALTIVEC_207, \
- vrldmi, PPC_NONE, PPC2_ISA300)
-GEN_VXFORM(vsl, 2, 7);
-GEN_VXFORM(vrldnm, 2, 7);
-GEN_VXFORM_DUAL(vsl, PPC_ALTIVEC, PPC_NONE, \
- vrldnm, PPC_NONE, PPC2_ISA300)
-GEN_VXFORM(vsr, 2, 11);
-GEN_VXFORM_ENV(vpkuhum, 7, 0);
-GEN_VXFORM_ENV(vpkuwum, 7, 1);
-GEN_VXFORM_ENV(vpkudum, 7, 17);
-GEN_VXFORM_ENV(vpkuhus, 7, 2);
-GEN_VXFORM_ENV(vpkuwus, 7, 3);
-GEN_VXFORM_ENV(vpkudus, 7, 19);
-GEN_VXFORM_ENV(vpkshus, 7, 4);
-GEN_VXFORM_ENV(vpkswus, 7, 5);
-GEN_VXFORM_ENV(vpksdus, 7, 21);
-GEN_VXFORM_ENV(vpkshss, 7, 6);
-GEN_VXFORM_ENV(vpkswss, 7, 7);
-GEN_VXFORM_ENV(vpksdss, 7, 23);
-GEN_VXFORM(vpkpx, 7, 12);
-GEN_VXFORM_ENV(vsum4ubs, 4, 24);
-GEN_VXFORM_ENV(vsum4sbs, 4, 28);
-GEN_VXFORM_ENV(vsum4shs, 4, 25);
-GEN_VXFORM_ENV(vsum2sws, 4, 26);
-GEN_VXFORM_ENV(vsumsws, 4, 30);
-GEN_VXFORM_ENV(vaddfp, 5, 0);
-GEN_VXFORM_ENV(vsubfp, 5, 1);
-GEN_VXFORM_ENV(vmaxfp, 5, 16);
-GEN_VXFORM_ENV(vminfp, 5, 17);
-
-#define GEN_VXRFORM1(opname, name, str, opc2, opc3) \
-static void glue(gen_, name)(DisasContext *ctx) \
- { \
- TCGv_ptr ra, rb, rd; \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- ra = gen_avr_ptr(rA(ctx->opcode)); \
- rb = gen_avr_ptr(rB(ctx->opcode)); \
- rd = gen_avr_ptr(rD(ctx->opcode)); \
- gen_helper_##opname(cpu_env, rd, ra, rb); \
- tcg_temp_free_ptr(ra); \
- tcg_temp_free_ptr(rb); \
- tcg_temp_free_ptr(rd); \
- }
-
-#define GEN_VXRFORM(name, opc2, opc3) \
- GEN_VXRFORM1(name, name, #name, opc2, opc3) \
- GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
-
-/*
- * Support for Altivec instructions that use bit 31 (Rc) as an opcode
- * bit but also use bit 21 as an actual Rc bit. In general, thse pairs
- * come from different versions of the ISA, so we must also support a
- * pair of flags for each instruction.
- */
-#define GEN_VXRFORM_DUAL(name0, flg0, flg2_0, name1, flg1, flg2_1) \
-static void glue(gen_, name0##_##name1)(DisasContext *ctx) \
-{ \
- if ((Rc(ctx->opcode) == 0) && \
- ((ctx->insns_flags & flg0) || (ctx->insns_flags2 & flg2_0))) { \
- if (Rc21(ctx->opcode) == 0) { \
- gen_##name0(ctx); \
- } else { \
- gen_##name0##_(ctx); \
- } \
- } else if ((Rc(ctx->opcode) == 1) && \
- ((ctx->insns_flags & flg1) || (ctx->insns_flags2 & flg2_1))) { \
- if (Rc21(ctx->opcode) == 0) { \
- gen_##name1(ctx); \
- } else { \
- gen_##name1##_(ctx); \
- } \
- } else { \
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
- } \
-}
-
-GEN_VXRFORM(vcmpequb, 3, 0)
-GEN_VXRFORM(vcmpequh, 3, 1)
-GEN_VXRFORM(vcmpequw, 3, 2)
-GEN_VXRFORM(vcmpequd, 3, 3)
-GEN_VXRFORM(vcmpnezb, 3, 4)
-GEN_VXRFORM(vcmpnezh, 3, 5)
-GEN_VXRFORM(vcmpnezw, 3, 6)
-GEN_VXRFORM(vcmpgtsb, 3, 12)
-GEN_VXRFORM(vcmpgtsh, 3, 13)
-GEN_VXRFORM(vcmpgtsw, 3, 14)
-GEN_VXRFORM(vcmpgtsd, 3, 15)
-GEN_VXRFORM(vcmpgtub, 3, 8)
-GEN_VXRFORM(vcmpgtuh, 3, 9)
-GEN_VXRFORM(vcmpgtuw, 3, 10)
-GEN_VXRFORM(vcmpgtud, 3, 11)
-GEN_VXRFORM(vcmpeqfp, 3, 3)
-GEN_VXRFORM(vcmpgefp, 3, 7)
-GEN_VXRFORM(vcmpgtfp, 3, 11)
-GEN_VXRFORM(vcmpbfp, 3, 15)
-GEN_VXRFORM(vcmpneb, 3, 0)
-GEN_VXRFORM(vcmpneh, 3, 1)
-GEN_VXRFORM(vcmpnew, 3, 2)
-
-GEN_VXRFORM_DUAL(vcmpequb, PPC_ALTIVEC, PPC_NONE, \
- vcmpneb, PPC_NONE, PPC2_ISA300)
-GEN_VXRFORM_DUAL(vcmpequh, PPC_ALTIVEC, PPC_NONE, \
- vcmpneh, PPC_NONE, PPC2_ISA300)
-GEN_VXRFORM_DUAL(vcmpequw, PPC_ALTIVEC, PPC_NONE, \
- vcmpnew, PPC_NONE, PPC2_ISA300)
-GEN_VXRFORM_DUAL(vcmpeqfp, PPC_ALTIVEC, PPC_NONE, \
- vcmpequd, PPC_NONE, PPC2_ALTIVEC_207)
-GEN_VXRFORM_DUAL(vcmpbfp, PPC_ALTIVEC, PPC_NONE, \
- vcmpgtsd, PPC_NONE, PPC2_ALTIVEC_207)
-GEN_VXRFORM_DUAL(vcmpgtfp, PPC_ALTIVEC, PPC_NONE, \
- vcmpgtud, PPC_NONE, PPC2_ALTIVEC_207)
-
-#define GEN_VXFORM_SIMM(name, opc2, opc3) \
-static void glue(gen_, name)(DisasContext *ctx) \
- { \
- TCGv_ptr rd; \
- TCGv_i32 simm; \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- simm = tcg_const_i32(SIMM5(ctx->opcode)); \
- rd = gen_avr_ptr(rD(ctx->opcode)); \
- gen_helper_##name (rd, simm); \
- tcg_temp_free_i32(simm); \
- tcg_temp_free_ptr(rd); \
- }
-
-GEN_VXFORM_SIMM(vspltisb, 6, 12);
-GEN_VXFORM_SIMM(vspltish, 6, 13);
-GEN_VXFORM_SIMM(vspltisw, 6, 14);
-
-#define GEN_VXFORM_NOA(name, opc2, opc3) \
-static void glue(gen_, name)(DisasContext *ctx) \
- { \
- TCGv_ptr rb, rd; \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- rb = gen_avr_ptr(rB(ctx->opcode)); \
- rd = gen_avr_ptr(rD(ctx->opcode)); \
- gen_helper_##name (rd, rb); \
- tcg_temp_free_ptr(rb); \
- tcg_temp_free_ptr(rd); \
- }
-
-#define GEN_VXFORM_NOA_ENV(name, opc2, opc3) \
-static void glue(gen_, name)(DisasContext *ctx) \
- { \
- TCGv_ptr rb, rd; \
- \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- rb = gen_avr_ptr(rB(ctx->opcode)); \
- rd = gen_avr_ptr(rD(ctx->opcode)); \
- gen_helper_##name(cpu_env, rd, rb); \
- tcg_temp_free_ptr(rb); \
- tcg_temp_free_ptr(rd); \
- }
-
-#define GEN_VXFORM_NOA_2(name, opc2, opc3, opc4) \
-static void glue(gen_, name)(DisasContext *ctx) \
- { \
- TCGv_ptr rb, rd; \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- rb = gen_avr_ptr(rB(ctx->opcode)); \
- rd = gen_avr_ptr(rD(ctx->opcode)); \
- gen_helper_##name(rd, rb); \
- tcg_temp_free_ptr(rb); \
- tcg_temp_free_ptr(rd); \
- }
-
-#define GEN_VXFORM_NOA_3(name, opc2, opc3, opc4) \
-static void glue(gen_, name)(DisasContext *ctx) \
- { \
- TCGv_ptr rb; \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- rb = gen_avr_ptr(rB(ctx->opcode)); \
- gen_helper_##name(cpu_gpr[rD(ctx->opcode)], rb); \
- tcg_temp_free_ptr(rb); \
- }
-GEN_VXFORM_NOA(vupkhsb, 7, 8);
-GEN_VXFORM_NOA(vupkhsh, 7, 9);
-GEN_VXFORM_NOA(vupkhsw, 7, 25);
-GEN_VXFORM_NOA(vupklsb, 7, 10);
-GEN_VXFORM_NOA(vupklsh, 7, 11);
-GEN_VXFORM_NOA(vupklsw, 7, 27);
-GEN_VXFORM_NOA(vupkhpx, 7, 13);
-GEN_VXFORM_NOA(vupklpx, 7, 15);
-GEN_VXFORM_NOA_ENV(vrefp, 5, 4);
-GEN_VXFORM_NOA_ENV(vrsqrtefp, 5, 5);
-GEN_VXFORM_NOA_ENV(vexptefp, 5, 6);
-GEN_VXFORM_NOA_ENV(vlogefp, 5, 7);
-GEN_VXFORM_NOA_ENV(vrfim, 5, 11);
-GEN_VXFORM_NOA_ENV(vrfin, 5, 8);
-GEN_VXFORM_NOA_ENV(vrfip, 5, 10);
-GEN_VXFORM_NOA_ENV(vrfiz, 5, 9);
-GEN_VXFORM_NOA(vprtybw, 1, 24);
-GEN_VXFORM_NOA(vprtybd, 1, 24);
-GEN_VXFORM_NOA(vprtybq, 1, 24);
-
-#define GEN_VXFORM_SIMM(name, opc2, opc3) \
-static void glue(gen_, name)(DisasContext *ctx) \
- { \
- TCGv_ptr rd; \
- TCGv_i32 simm; \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- simm = tcg_const_i32(SIMM5(ctx->opcode)); \
- rd = gen_avr_ptr(rD(ctx->opcode)); \
- gen_helper_##name (rd, simm); \
- tcg_temp_free_i32(simm); \
- tcg_temp_free_ptr(rd); \
- }
-
-#define GEN_VXFORM_UIMM(name, opc2, opc3) \
-static void glue(gen_, name)(DisasContext *ctx) \
- { \
- TCGv_ptr rb, rd; \
- TCGv_i32 uimm; \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- uimm = tcg_const_i32(UIMM5(ctx->opcode)); \
- rb = gen_avr_ptr(rB(ctx->opcode)); \
- rd = gen_avr_ptr(rD(ctx->opcode)); \
- gen_helper_##name (rd, rb, uimm); \
- tcg_temp_free_i32(uimm); \
- tcg_temp_free_ptr(rb); \
- tcg_temp_free_ptr(rd); \
- }
-
-#define GEN_VXFORM_UIMM_ENV(name, opc2, opc3) \
-static void glue(gen_, name)(DisasContext *ctx) \
- { \
- TCGv_ptr rb, rd; \
- TCGv_i32 uimm; \
- \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- uimm = tcg_const_i32(UIMM5(ctx->opcode)); \
- rb = gen_avr_ptr(rB(ctx->opcode)); \
- rd = gen_avr_ptr(rD(ctx->opcode)); \
- gen_helper_##name(cpu_env, rd, rb, uimm); \
- tcg_temp_free_i32(uimm); \
- tcg_temp_free_ptr(rb); \
- tcg_temp_free_ptr(rd); \
- }
-
-#define GEN_VXFORM_UIMM_SPLAT(name, opc2, opc3, splat_max) \
-static void glue(gen_, name)(DisasContext *ctx) \
- { \
- TCGv_ptr rb, rd; \
- uint8_t uimm = UIMM4(ctx->opcode); \
- TCGv_i32 t0 = tcg_temp_new_i32(); \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- if (uimm > splat_max) { \
- uimm = 0; \
- } \
- tcg_gen_movi_i32(t0, uimm); \
- rb = gen_avr_ptr(rB(ctx->opcode)); \
- rd = gen_avr_ptr(rD(ctx->opcode)); \
- gen_helper_##name(rd, rb, t0); \
- tcg_temp_free_i32(t0); \
- tcg_temp_free_ptr(rb); \
- tcg_temp_free_ptr(rd); \
- }
-
-GEN_VXFORM_UIMM(vspltb, 6, 8);
-GEN_VXFORM_UIMM(vsplth, 6, 9);
-GEN_VXFORM_UIMM(vspltw, 6, 10);
-GEN_VXFORM_UIMM_SPLAT(vextractub, 6, 8, 15);
-GEN_VXFORM_UIMM_SPLAT(vextractuh, 6, 9, 14);
-GEN_VXFORM_UIMM_SPLAT(vextractuw, 6, 10, 12);
-GEN_VXFORM_UIMM_SPLAT(vextractd, 6, 11, 8);
-GEN_VXFORM_UIMM_SPLAT(vinsertb, 6, 12, 15);
-GEN_VXFORM_UIMM_SPLAT(vinserth, 6, 13, 14);
-GEN_VXFORM_UIMM_SPLAT(vinsertw, 6, 14, 12);
-GEN_VXFORM_UIMM_SPLAT(vinsertd, 6, 15, 8);
-GEN_VXFORM_UIMM_ENV(vcfux, 5, 12);
-GEN_VXFORM_UIMM_ENV(vcfsx, 5, 13);
-GEN_VXFORM_UIMM_ENV(vctuxs, 5, 14);
-GEN_VXFORM_UIMM_ENV(vctsxs, 5, 15);
-GEN_VXFORM_DUAL(vspltb, PPC_ALTIVEC, PPC_NONE,
- vextractub, PPC_NONE, PPC2_ISA300);
-GEN_VXFORM_DUAL(vsplth, PPC_ALTIVEC, PPC_NONE,
- vextractuh, PPC_NONE, PPC2_ISA300);
-GEN_VXFORM_DUAL(vspltw, PPC_ALTIVEC, PPC_NONE,
- vextractuw, PPC_NONE, PPC2_ISA300);
-GEN_VXFORM_DUAL(vspltisb, PPC_ALTIVEC, PPC_NONE,
- vinsertb, PPC_NONE, PPC2_ISA300);
-GEN_VXFORM_DUAL(vspltish, PPC_ALTIVEC, PPC_NONE,
- vinserth, PPC_NONE, PPC2_ISA300);
-GEN_VXFORM_DUAL(vspltisw, PPC_ALTIVEC, PPC_NONE,
- vinsertw, PPC_NONE, PPC2_ISA300);
-
-static void gen_vsldoi(DisasContext *ctx)
-{
- TCGv_ptr ra, rb, rd;
- TCGv_i32 sh;
- if (unlikely(!ctx->altivec_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VPU);
- return;
- }
- ra = gen_avr_ptr(rA(ctx->opcode));
- rb = gen_avr_ptr(rB(ctx->opcode));
- rd = gen_avr_ptr(rD(ctx->opcode));
- sh = tcg_const_i32(VSH(ctx->opcode));
- gen_helper_vsldoi (rd, ra, rb, sh);
- tcg_temp_free_ptr(ra);
- tcg_temp_free_ptr(rb);
- tcg_temp_free_ptr(rd);
- tcg_temp_free_i32(sh);
-}
-
-#define GEN_VAFORM_PAIRED(name0, name1, opc2) \
-static void glue(gen_, name0##_##name1)(DisasContext *ctx) \
- { \
- TCGv_ptr ra, rb, rc, rd; \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- ra = gen_avr_ptr(rA(ctx->opcode)); \
- rb = gen_avr_ptr(rB(ctx->opcode)); \
- rc = gen_avr_ptr(rC(ctx->opcode)); \
- rd = gen_avr_ptr(rD(ctx->opcode)); \
- if (Rc(ctx->opcode)) { \
- gen_helper_##name1(cpu_env, rd, ra, rb, rc); \
- } else { \
- gen_helper_##name0(cpu_env, rd, ra, rb, rc); \
- } \
- tcg_temp_free_ptr(ra); \
- tcg_temp_free_ptr(rb); \
- tcg_temp_free_ptr(rc); \
- tcg_temp_free_ptr(rd); \
- }
-
-GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16)
-
-static void gen_vmladduhm(DisasContext *ctx)
-{
- TCGv_ptr ra, rb, rc, rd;
- if (unlikely(!ctx->altivec_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VPU);
- return;
- }
- ra = gen_avr_ptr(rA(ctx->opcode));
- rb = gen_avr_ptr(rB(ctx->opcode));
- rc = gen_avr_ptr(rC(ctx->opcode));
- rd = gen_avr_ptr(rD(ctx->opcode));
- gen_helper_vmladduhm(rd, ra, rb, rc);
- tcg_temp_free_ptr(ra);
- tcg_temp_free_ptr(rb);
- tcg_temp_free_ptr(rc);
- tcg_temp_free_ptr(rd);
-}
-
-static void gen_vpermr(DisasContext *ctx)
-{
- TCGv_ptr ra, rb, rc, rd;
- if (unlikely(!ctx->altivec_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VPU);
- return;
- }
- ra = gen_avr_ptr(rA(ctx->opcode));
- rb = gen_avr_ptr(rB(ctx->opcode));
- rc = gen_avr_ptr(rC(ctx->opcode));
- rd = gen_avr_ptr(rD(ctx->opcode));
- gen_helper_vpermr(cpu_env, rd, ra, rb, rc);
- tcg_temp_free_ptr(ra);
- tcg_temp_free_ptr(rb);
- tcg_temp_free_ptr(rc);
- tcg_temp_free_ptr(rd);
-}
-
-GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18)
-GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19)
-GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20)
-GEN_VAFORM_PAIRED(vsel, vperm, 21)
-GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23)
-
-GEN_VXFORM_NOA(vclzb, 1, 28)
-GEN_VXFORM_NOA(vclzh, 1, 29)
-GEN_VXFORM_NOA(vclzw, 1, 30)
-GEN_VXFORM_NOA(vclzd, 1, 31)
-GEN_VXFORM_NOA_2(vnegw, 1, 24, 6)
-GEN_VXFORM_NOA_2(vnegd, 1, 24, 7)
-GEN_VXFORM_NOA_2(vextsb2w, 1, 24, 16)
-GEN_VXFORM_NOA_2(vextsh2w, 1, 24, 17)
-GEN_VXFORM_NOA_2(vextsb2d, 1, 24, 24)
-GEN_VXFORM_NOA_2(vextsh2d, 1, 24, 25)
-GEN_VXFORM_NOA_2(vextsw2d, 1, 24, 26)
-GEN_VXFORM_NOA_2(vctzb, 1, 24, 28)
-GEN_VXFORM_NOA_2(vctzh, 1, 24, 29)
-GEN_VXFORM_NOA_2(vctzw, 1, 24, 30)
-GEN_VXFORM_NOA_2(vctzd, 1, 24, 31)
-GEN_VXFORM_NOA_3(vclzlsbb, 1, 24, 0)
-GEN_VXFORM_NOA_3(vctzlsbb, 1, 24, 1)
-GEN_VXFORM_NOA(vpopcntb, 1, 28)
-GEN_VXFORM_NOA(vpopcnth, 1, 29)
-GEN_VXFORM_NOA(vpopcntw, 1, 30)
-GEN_VXFORM_NOA(vpopcntd, 1, 31)
-GEN_VXFORM_DUAL(vclzb, PPC_NONE, PPC2_ALTIVEC_207, \
- vpopcntb, PPC_NONE, PPC2_ALTIVEC_207)
-GEN_VXFORM_DUAL(vclzh, PPC_NONE, PPC2_ALTIVEC_207, \
- vpopcnth, PPC_NONE, PPC2_ALTIVEC_207)
-GEN_VXFORM_DUAL(vclzw, PPC_NONE, PPC2_ALTIVEC_207, \
- vpopcntw, PPC_NONE, PPC2_ALTIVEC_207)
-GEN_VXFORM_DUAL(vclzd, PPC_NONE, PPC2_ALTIVEC_207, \
- vpopcntd, PPC_NONE, PPC2_ALTIVEC_207)
-GEN_VXFORM(vbpermd, 6, 23);
-GEN_VXFORM(vbpermq, 6, 21);
-GEN_VXFORM_NOA(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) \
-{ \
- TCGv_ptr ra, rb, rd; \
- TCGv_i32 ps; \
- \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- \
- ra = gen_avr_ptr(rA(ctx->opcode)); \
- rb = gen_avr_ptr(rB(ctx->opcode)); \
- rd = gen_avr_ptr(rD(ctx->opcode)); \
- \
- ps = tcg_const_i32((ctx->opcode & 0x200) != 0); \
- \
- gen_helper_##op(cpu_crf[6], rd, ra, rb, ps); \
- \
- tcg_temp_free_ptr(ra); \
- tcg_temp_free_ptr(rb); \
- tcg_temp_free_ptr(rd); \
- tcg_temp_free_i32(ps); \
-}
-
-#define GEN_BCD2(op) \
-static void gen_##op(DisasContext *ctx) \
-{ \
- TCGv_ptr rd, rb; \
- TCGv_i32 ps; \
- \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- \
- rb = gen_avr_ptr(rB(ctx->opcode)); \
- rd = gen_avr_ptr(rD(ctx->opcode)); \
- \
- ps = tcg_const_i32((ctx->opcode & 0x200) != 0); \
- \
- gen_helper_##op(cpu_crf[6], rd, rb, ps); \
- \
- tcg_temp_free_ptr(rb); \
- tcg_temp_free_ptr(rd); \
- tcg_temp_free_i32(ps); \
-}
-
-GEN_BCD(bcdadd)
-GEN_BCD(bcdsub)
-GEN_BCD2(bcdcfn)
-GEN_BCD2(bcdctn)
-GEN_BCD2(bcdcfz)
-GEN_BCD2(bcdctz)
-
-static void gen_xpnd04_1(DisasContext *ctx)
-{
- switch (opc4(ctx->opcode)) {
- case 4:
- gen_bcdctz(ctx);
- break;
- case 5:
- gen_bcdctn(ctx);
- break;
- case 6:
- gen_bcdcfz(ctx);
- break;
- case 7:
- gen_bcdcfn(ctx);
- break;
- default:
- gen_invalid(ctx);
- break;
- }
-}
-
-static void gen_xpnd04_2(DisasContext *ctx)
-{
- switch (opc4(ctx->opcode)) {
- case 4:
- gen_bcdctz(ctx);
- break;
- case 6:
- gen_bcdcfz(ctx);
- break;
- case 7:
- gen_bcdcfn(ctx);
- break;
- default:
- gen_invalid(ctx);
- break;
- }
-}
-
-GEN_VXFORM_DUAL(vsubcuw, PPC_ALTIVEC, PPC_NONE, \
- xpnd04_1, PPC_NONE, PPC2_ISA300)
-GEN_VXFORM_DUAL(vsubsws, PPC_ALTIVEC, PPC_NONE, \
- xpnd04_2, PPC_NONE, PPC2_ISA300)
-
-GEN_VXFORM_DUAL(vsububm, PPC_ALTIVEC, PPC_NONE, \
- bcdadd, PPC_NONE, PPC2_ALTIVEC_207)
-GEN_VXFORM_DUAL(vsububs, PPC_ALTIVEC, PPC_NONE, \
- bcdadd, PPC_NONE, PPC2_ALTIVEC_207)
-GEN_VXFORM_DUAL(vsubuhm, PPC_ALTIVEC, PPC_NONE, \
- bcdsub, PPC_NONE, PPC2_ALTIVEC_207)
-GEN_VXFORM_DUAL(vsubuhs, PPC_ALTIVEC, PPC_NONE, \
- bcdsub, PPC_NONE, PPC2_ALTIVEC_207)
-
-static void gen_vsbox(DisasContext *ctx)
-{
- TCGv_ptr ra, rd;
- if (unlikely(!ctx->altivec_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VPU);
- return;
- }
- ra = gen_avr_ptr(rA(ctx->opcode));
- rd = gen_avr_ptr(rD(ctx->opcode));
- gen_helper_vsbox(rd, ra);
- tcg_temp_free_ptr(ra);
- tcg_temp_free_ptr(rd);
-}
-
-GEN_VXFORM(vcipher, 4, 20)
-GEN_VXFORM(vcipherlast, 4, 20)
-GEN_VXFORM(vncipher, 4, 21)
-GEN_VXFORM(vncipherlast, 4, 21)
-
-GEN_VXFORM_DUAL(vcipher, PPC_NONE, PPC2_ALTIVEC_207,
- vcipherlast, PPC_NONE, PPC2_ALTIVEC_207)
-GEN_VXFORM_DUAL(vncipher, PPC_NONE, PPC2_ALTIVEC_207,
- vncipherlast, PPC_NONE, PPC2_ALTIVEC_207)
-
-#define VSHASIGMA(op) \
-static void gen_##op(DisasContext *ctx) \
-{ \
- TCGv_ptr ra, rd; \
- TCGv_i32 st_six; \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- ra = gen_avr_ptr(rA(ctx->opcode)); \
- rd = gen_avr_ptr(rD(ctx->opcode)); \
- st_six = tcg_const_i32(rB(ctx->opcode)); \
- gen_helper_##op(rd, ra, st_six); \
- tcg_temp_free_ptr(ra); \
- tcg_temp_free_ptr(rd); \
- tcg_temp_free_i32(st_six); \
-}
-
-VSHASIGMA(vshasigmaw)
-VSHASIGMA(vshasigmad)
-
-GEN_VXFORM3(vpermxor, 22, 0xFF)
-GEN_VXFORM_DUAL(vsldoi, PPC_ALTIVEC, PPC_NONE,
- vpermxor, PPC_NONE, PPC2_ALTIVEC_207)
-
-#undef GEN_VR_LDX
-#undef GEN_VR_STX
-#undef GEN_VR_LVE
-#undef GEN_VR_STVE
-
-#undef GEN_VX_LOGICAL
-#undef GEN_VX_LOGICAL_207
-#undef GEN_VXFORM
-#undef GEN_VXFORM_207
-#undef GEN_VXFORM_DUAL
-#undef GEN_VXRFORM_DUAL
-#undef GEN_VXRFORM1
-#undef GEN_VXRFORM
-#undef GEN_VXFORM_SIMM
-#undef GEN_VXFORM_NOA
-#undef GEN_VXFORM_UIMM
-#undef GEN_VAFORM_PAIRED
-
-#undef GEN_BCD2
diff --git a/target-ppc/translate/vmx-ops.inc.c b/target-ppc/translate/vmx-ops.inc.c
deleted file mode 100644
index f02b3bed50..0000000000
--- a/target-ppc/translate/vmx-ops.inc.c
+++ /dev/null
@@ -1,294 +0,0 @@
-#define GEN_VR_LDX(name, opc2, opc3) \
-GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
-#define GEN_VR_STX(name, opc2, opc3) \
-GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
-#define GEN_VR_LVE(name, opc2, opc3) \
- GEN_HANDLER(lve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
-#define GEN_VR_STVE(name, opc2, opc3) \
- GEN_HANDLER(stve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
-GEN_VR_LDX(lvx, 0x07, 0x03),
-GEN_VR_LDX(lvxl, 0x07, 0x0B),
-GEN_VR_LVE(bx, 0x07, 0x00),
-GEN_VR_LVE(hx, 0x07, 0x01),
-GEN_VR_LVE(wx, 0x07, 0x02),
-GEN_VR_STX(svx, 0x07, 0x07),
-GEN_VR_STX(svxl, 0x07, 0x0F),
-GEN_VR_STVE(bx, 0x07, 0x04),
-GEN_VR_STVE(hx, 0x07, 0x05),
-GEN_VR_STVE(wx, 0x07, 0x06),
-
-#define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3) \
-GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
-
-#define GEN_VX_LOGICAL_207(name, tcg_op, opc2, opc3) \
-GEN_HANDLER_E(name, 0x04, opc2, opc3, 0x00000000, PPC_NONE, PPC2_ALTIVEC_207)
-
-GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16),
-GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17),
-GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18),
-GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19),
-GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20),
-GEN_VX_LOGICAL_207(veqv, tcg_gen_eqv_i64, 2, 26),
-GEN_VX_LOGICAL_207(vnand, tcg_gen_nand_i64, 2, 22),
-GEN_VX_LOGICAL_207(vorc, tcg_gen_orc_i64, 2, 21),
-
-#define GEN_VXFORM(name, opc2, opc3) \
-GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
-
-#define GEN_VXFORM_207(name, opc2, opc3) \
-GEN_HANDLER_E(name, 0x04, opc2, opc3, 0x00000000, PPC_NONE, PPC2_ALTIVEC_207)
-
-#define GEN_VXFORM_300(name, opc2, opc3) \
-GEN_HANDLER_E(name, 0x04, opc2, opc3, 0x00000000, PPC_NONE, PPC2_ISA300)
-
-#define GEN_VXFORM_300_EXT(name, opc2, opc3, inval) \
-GEN_HANDLER_E(name, 0x04, opc2, opc3, inval, PPC_NONE, PPC2_ISA300)
-
-#define GEN_VXFORM_300_EO(name, opc2, opc3, opc4) \
-GEN_HANDLER_E_2(name, 0x04, opc2, opc3, opc4, 0x00000000, PPC_NONE, \
- PPC2_ISA300)
-
-#define GEN_VXFORM_DUAL(name0, name1, opc2, opc3, type0, type1) \
-GEN_HANDLER_E(name0##_##name1, 0x4, opc2, opc3, 0x00000000, type0, type1)
-
-#define GEN_VXRFORM_DUAL(name0, name1, opc2, opc3, tp0, tp1) \
-GEN_HANDLER_E(name0##_##name1, 0x4, opc2, opc3, 0x00000000, tp0, tp1), \
-GEN_HANDLER_E(name0##_##name1, 0x4, opc2, (opc3 | 0x10), 0x00000000, tp0, tp1),
-
-GEN_VXFORM_DUAL(vaddubm, vmul10cuq, 0, 0, PPC_ALTIVEC, PPC_NONE),
-GEN_VXFORM_DUAL(vadduhm, vmul10ecuq, 0, 1, PPC_ALTIVEC, PPC_NONE),
-GEN_VXFORM(vadduwm, 0, 2),
-GEN_VXFORM_207(vaddudm, 0, 3),
-GEN_VXFORM_DUAL(vsububm, bcdadd, 0, 16, PPC_ALTIVEC, PPC_NONE),
-GEN_VXFORM_DUAL(vsubuhm, bcdsub, 0, 17, PPC_ALTIVEC, PPC_NONE),
-GEN_VXFORM(vsubuwm, 0, 18),
-GEN_VXFORM_207(vsubudm, 0, 19),
-GEN_VXFORM(vmaxub, 1, 0),
-GEN_VXFORM(vmaxuh, 1, 1),
-GEN_VXFORM(vmaxuw, 1, 2),
-GEN_VXFORM_207(vmaxud, 1, 3),
-GEN_VXFORM(vmaxsb, 1, 4),
-GEN_VXFORM(vmaxsh, 1, 5),
-GEN_VXFORM(vmaxsw, 1, 6),
-GEN_VXFORM_207(vmaxsd, 1, 7),
-GEN_VXFORM(vminub, 1, 8),
-GEN_VXFORM(vminuh, 1, 9),
-GEN_VXFORM(vminuw, 1, 10),
-GEN_VXFORM_207(vminud, 1, 11),
-GEN_VXFORM(vminsb, 1, 12),
-GEN_VXFORM(vminsh, 1, 13),
-GEN_VXFORM(vminsw, 1, 14),
-GEN_VXFORM_207(vminsd, 1, 15),
-GEN_VXFORM_DUAL(vavgub, vabsdub, 1, 16, PPC_ALTIVEC, PPC_NONE),
-GEN_VXFORM_DUAL(vavguh, vabsduh, 1, 17, PPC_ALTIVEC, PPC_NONE),
-GEN_VXFORM_DUAL(vavguw, vabsduw, 1, 18, PPC_ALTIVEC, PPC_NONE),
-GEN_VXFORM(vavgsb, 1, 20),
-GEN_VXFORM(vavgsh, 1, 21),
-GEN_VXFORM(vavgsw, 1, 22),
-GEN_VXFORM(vmrghb, 6, 0),
-GEN_VXFORM(vmrghh, 6, 1),
-GEN_VXFORM(vmrghw, 6, 2),
-GEN_VXFORM(vmrglb, 6, 4),
-GEN_VXFORM(vmrglh, 6, 5),
-GEN_VXFORM(vmrglw, 6, 6),
-GEN_VXFORM_207(vmrgew, 6, 30),
-GEN_VXFORM_207(vmrgow, 6, 26),
-GEN_VXFORM(vmuloub, 4, 0),
-GEN_VXFORM(vmulouh, 4, 1),
-GEN_VXFORM_DUAL(vmulouw, vmuluwm, 4, 2, PPC_ALTIVEC, PPC_NONE),
-GEN_VXFORM(vmulosb, 4, 4),
-GEN_VXFORM(vmulosh, 4, 5),
-GEN_VXFORM_207(vmulosw, 4, 6),
-GEN_VXFORM(vmuleub, 4, 8),
-GEN_VXFORM(vmuleuh, 4, 9),
-GEN_VXFORM_207(vmuleuw, 4, 10),
-GEN_VXFORM(vmulesb, 4, 12),
-GEN_VXFORM(vmulesh, 4, 13),
-GEN_VXFORM_207(vmulesw, 4, 14),
-GEN_VXFORM(vslb, 2, 4),
-GEN_VXFORM(vslh, 2, 5),
-GEN_VXFORM_DUAL(vslw, vrlwnm, 2, 6, PPC_ALTIVEC, PPC_NONE),
-GEN_VXFORM_207(vsld, 2, 23),
-GEN_VXFORM(vsrb, 2, 8),
-GEN_VXFORM(vsrh, 2, 9),
-GEN_VXFORM(vsrw, 2, 10),
-GEN_VXFORM_207(vsrd, 2, 27),
-GEN_VXFORM(vsrab, 2, 12),
-GEN_VXFORM(vsrah, 2, 13),
-GEN_VXFORM(vsraw, 2, 14),
-GEN_VXFORM_207(vsrad, 2, 15),
-GEN_VXFORM_300(vsrv, 2, 28),
-GEN_VXFORM_300(vslv, 2, 29),
-GEN_VXFORM(vslo, 6, 16),
-GEN_VXFORM(vsro, 6, 17),
-GEN_VXFORM(vaddcuw, 0, 6),
-GEN_HANDLER_E_2(vprtybw, 0x4, 0x1, 0x18, 8, 0, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E_2(vprtybd, 0x4, 0x1, 0x18, 9, 0, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E_2(vprtybq, 0x4, 0x1, 0x18, 10, 0, PPC_NONE, PPC2_ISA300),
-
-GEN_VXFORM_DUAL(vsubcuw, xpnd04_1, 0, 22, PPC_ALTIVEC, PPC_NONE),
-GEN_VXFORM_DUAL(vaddubs, vmul10uq, 0, 8, PPC_ALTIVEC, PPC_NONE),
-GEN_VXFORM_DUAL(vadduhs, vmul10euq, 0, 9, PPC_ALTIVEC, PPC_NONE),
-GEN_VXFORM(vadduws, 0, 10),
-GEN_VXFORM(vaddsbs, 0, 12),
-GEN_VXFORM(vaddshs, 0, 13),
-GEN_VXFORM(vaddsws, 0, 14),
-GEN_VXFORM_DUAL(vsububs, bcdadd, 0, 24, PPC_ALTIVEC, PPC_NONE),
-GEN_VXFORM_DUAL(vsubuhs, bcdsub, 0, 25, PPC_ALTIVEC, PPC_NONE),
-GEN_VXFORM(vsubuws, 0, 26),
-GEN_VXFORM(vsubsbs, 0, 28),
-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_207(vsubuqm, 0, 20),
-GEN_VXFORM_207(vsubcuq, 0, 21),
-GEN_VXFORM_DUAL(vsubeuqm, vsubecuq, 31, 0xFF, PPC_NONE, PPC2_ALTIVEC_207),
-GEN_VXFORM(vrlb, 2, 0),
-GEN_VXFORM(vrlh, 2, 1),
-GEN_VXFORM_DUAL(vrlw, vrlwmi, 2, 2, PPC_ALTIVEC, PPC_NONE),
-GEN_VXFORM_DUAL(vrld, vrldmi, 2, 3, PPC_NONE, PPC2_ALTIVEC_207),
-GEN_VXFORM_DUAL(vsl, vrldnm, 2, 7, PPC_ALTIVEC, PPC_NONE),
-GEN_VXFORM(vsr, 2, 11),
-GEN_VXFORM(vpkuhum, 7, 0),
-GEN_VXFORM(vpkuwum, 7, 1),
-GEN_VXFORM_207(vpkudum, 7, 17),
-GEN_VXFORM(vpkuhus, 7, 2),
-GEN_VXFORM(vpkuwus, 7, 3),
-GEN_VXFORM_207(vpkudus, 7, 19),
-GEN_VXFORM(vpkshus, 7, 4),
-GEN_VXFORM(vpkswus, 7, 5),
-GEN_VXFORM_207(vpksdus, 7, 21),
-GEN_VXFORM(vpkshss, 7, 6),
-GEN_VXFORM(vpkswss, 7, 7),
-GEN_VXFORM_207(vpksdss, 7, 23),
-GEN_VXFORM(vpkpx, 7, 12),
-GEN_VXFORM(vsum4ubs, 4, 24),
-GEN_VXFORM(vsum4sbs, 4, 28),
-GEN_VXFORM(vsum4shs, 4, 25),
-GEN_VXFORM(vsum2sws, 4, 26),
-GEN_VXFORM(vsumsws, 4, 30),
-GEN_VXFORM(vaddfp, 5, 0),
-GEN_VXFORM(vsubfp, 5, 1),
-GEN_VXFORM(vmaxfp, 5, 16),
-GEN_VXFORM(vminfp, 5, 17),
-
-#define GEN_VXRFORM1(opname, name, str, opc2, opc3) \
- GEN_HANDLER2(name, str, 0x4, opc2, opc3, 0x00000000, PPC_ALTIVEC),
-#define GEN_VXRFORM1_300(opname, name, str, opc2, opc3) \
-GEN_HANDLER2_E(name, str, 0x4, opc2, opc3, 0x00000000, PPC_NONE, PPC2_ISA300),
-#define GEN_VXRFORM(name, opc2, opc3) \
- GEN_VXRFORM1(name, name, #name, opc2, opc3) \
- GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
-#define GEN_VXRFORM_300(name, opc2, opc3) \
- GEN_VXRFORM1_300(name, name, #name, opc2, opc3) \
- GEN_VXRFORM1_300(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
-
-GEN_VXRFORM_300(vcmpnezb, 3, 4)
-GEN_VXRFORM_300(vcmpnezh, 3, 5)
-GEN_VXRFORM_300(vcmpnezw, 3, 6)
-GEN_VXRFORM(vcmpgtsb, 3, 12)
-GEN_VXRFORM(vcmpgtsh, 3, 13)
-GEN_VXRFORM(vcmpgtsw, 3, 14)
-GEN_VXRFORM(vcmpgtub, 3, 8)
-GEN_VXRFORM(vcmpgtuh, 3, 9)
-GEN_VXRFORM(vcmpgtuw, 3, 10)
-GEN_VXRFORM_DUAL(vcmpeqfp, vcmpequd, 3, 3, PPC_ALTIVEC, PPC_NONE)
-GEN_VXRFORM(vcmpgefp, 3, 7)
-GEN_VXRFORM_DUAL(vcmpgtfp, vcmpgtud, 3, 11, PPC_ALTIVEC, PPC_NONE)
-GEN_VXRFORM_DUAL(vcmpbfp, vcmpgtsd, 3, 15, PPC_ALTIVEC, PPC_NONE)
-GEN_VXRFORM_DUAL(vcmpequb, vcmpneb, 3, 0, PPC_ALTIVEC, PPC_NONE)
-GEN_VXRFORM_DUAL(vcmpequh, vcmpneh, 3, 1, PPC_ALTIVEC, PPC_NONE)
-GEN_VXRFORM_DUAL(vcmpequw, vcmpnew, 3, 2, PPC_ALTIVEC, PPC_NONE)
-
-#define GEN_VXFORM_DUAL_INV(name0, name1, opc2, opc3, inval0, inval1, type) \
-GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, \
- PPC_NONE)
-GEN_VXFORM_DUAL_INV(vspltb, vextractub, 6, 8, 0x00000000, 0x100000,
- PPC_ALTIVEC),
-GEN_VXFORM_DUAL_INV(vsplth, vextractuh, 6, 9, 0x00000000, 0x100000,
- PPC_ALTIVEC),
-GEN_VXFORM_DUAL_INV(vspltw, vextractuw, 6, 10, 0x00000000, 0x100000,
- PPC_ALTIVEC),
-GEN_VXFORM_300_EXT(vextractd, 6, 11, 0x100000),
-GEN_VXFORM_DUAL_INV(vspltisb, vinsertb, 6, 12, 0x00000000, 0x100000,
- PPC_ALTIVEC),
-GEN_VXFORM_DUAL_INV(vspltish, vinserth, 6, 13, 0x00000000, 0x100000,
- PPC_ALTIVEC),
-GEN_VXFORM_DUAL_INV(vspltisw, vinsertw, 6, 14, 0x00000000, 0x100000,
- PPC_ALTIVEC),
-GEN_VXFORM_300_EXT(vinsertd, 6, 15, 0x100000),
-GEN_VXFORM_300_EO(vnegw, 0x01, 0x18, 0x06),
-GEN_VXFORM_300_EO(vnegd, 0x01, 0x18, 0x07),
-GEN_VXFORM_300_EO(vextsb2w, 0x01, 0x18, 0x10),
-GEN_VXFORM_300_EO(vextsh2w, 0x01, 0x18, 0x11),
-GEN_VXFORM_300_EO(vextsb2d, 0x01, 0x18, 0x18),
-GEN_VXFORM_300_EO(vextsh2d, 0x01, 0x18, 0x19),
-GEN_VXFORM_300_EO(vextsw2d, 0x01, 0x18, 0x1A),
-GEN_VXFORM_300_EO(vctzb, 0x01, 0x18, 0x1C),
-GEN_VXFORM_300_EO(vctzh, 0x01, 0x18, 0x1D),
-GEN_VXFORM_300_EO(vctzw, 0x01, 0x18, 0x1E),
-GEN_VXFORM_300_EO(vctzd, 0x01, 0x18, 0x1F),
-GEN_VXFORM_300_EO(vclzlsbb, 0x01, 0x18, 0x0),
-GEN_VXFORM_300_EO(vctzlsbb, 0x01, 0x18, 0x1),
-GEN_VXFORM_300(vpermr, 0x1D, 0xFF),
-
-#define GEN_VXFORM_NOA(name, opc2, opc3) \
- GEN_HANDLER(name, 0x04, opc2, opc3, 0x001f0000, PPC_ALTIVEC)
-GEN_VXFORM_NOA(vupkhsb, 7, 8),
-GEN_VXFORM_NOA(vupkhsh, 7, 9),
-GEN_VXFORM_207(vupkhsw, 7, 25),
-GEN_VXFORM_NOA(vupklsb, 7, 10),
-GEN_VXFORM_NOA(vupklsh, 7, 11),
-GEN_VXFORM_207(vupklsw, 7, 27),
-GEN_VXFORM_NOA(vupkhpx, 7, 13),
-GEN_VXFORM_NOA(vupklpx, 7, 15),
-GEN_VXFORM_NOA(vrefp, 5, 4),
-GEN_VXFORM_NOA(vrsqrtefp, 5, 5),
-GEN_VXFORM_NOA(vexptefp, 5, 6),
-GEN_VXFORM_NOA(vlogefp, 5, 7),
-GEN_VXFORM_NOA(vrfim, 5, 11),
-GEN_VXFORM_NOA(vrfin, 5, 8),
-GEN_VXFORM_NOA(vrfip, 5, 10),
-GEN_VXFORM_NOA(vrfiz, 5, 9),
-
-#define GEN_VXFORM_UIMM(name, opc2, opc3) \
- GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
-GEN_VXFORM_UIMM(vcfux, 5, 12),
-GEN_VXFORM_UIMM(vcfsx, 5, 13),
-GEN_VXFORM_UIMM(vctuxs, 5, 14),
-GEN_VXFORM_UIMM(vctsxs, 5, 15),
-
-
-#define GEN_VAFORM_PAIRED(name0, name1, opc2) \
- GEN_HANDLER(name0##_##name1, 0x04, opc2, 0xFF, 0x00000000, PPC_ALTIVEC)
-GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16),
-GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18),
-GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19),
-GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20),
-GEN_VAFORM_PAIRED(vsel, vperm, 21),
-GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23),
-
-GEN_VXFORM_DUAL(vclzb, vpopcntb, 1, 28, PPC_NONE, PPC2_ALTIVEC_207),
-GEN_VXFORM_DUAL(vclzh, vpopcnth, 1, 29, PPC_NONE, PPC2_ALTIVEC_207),
-GEN_VXFORM_DUAL(vclzw, vpopcntw, 1, 30, PPC_NONE, PPC2_ALTIVEC_207),
-GEN_VXFORM_DUAL(vclzd, vpopcntd, 1, 31, PPC_NONE, PPC2_ALTIVEC_207),
-
-GEN_VXFORM_300(vbpermd, 6, 23),
-GEN_VXFORM_207(vbpermq, 6, 21),
-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),
-
-GEN_VXFORM_DUAL(vcipher, vcipherlast, 4, 20, PPC_NONE, PPC2_ALTIVEC_207),
-GEN_VXFORM_DUAL(vncipher, vncipherlast, 4, 21, PPC_NONE, PPC2_ALTIVEC_207),
-
-GEN_VXFORM_207(vshasigmaw, 1, 26),
-GEN_VXFORM_207(vshasigmad, 1, 27),
-
-GEN_VXFORM_DUAL(vsldoi, vpermxor, 22, 0xFF, PPC_ALTIVEC, PPC_NONE),
diff --git a/target-ppc/translate/vsx-impl.inc.c b/target-ppc/translate/vsx-impl.inc.c
deleted file mode 100644
index 5a27be4bd4..0000000000
--- a/target-ppc/translate/vsx-impl.inc.c
+++ /dev/null
@@ -1,1009 +0,0 @@
-/*** VSX extension ***/
-
-static inline TCGv_i64 cpu_vsrh(int n)
-{
- if (n < 32) {
- return cpu_fpr[n];
- } else {
- return cpu_avrh[n-32];
- }
-}
-
-static inline TCGv_i64 cpu_vsrl(int n)
-{
- if (n < 32) {
- return cpu_vsr[n];
- } else {
- return cpu_avrl[n-32];
- }
-}
-
-#define VSX_LOAD_SCALAR(name, operation) \
-static void gen_##name(DisasContext *ctx) \
-{ \
- TCGv EA; \
- if (unlikely(!ctx->vsx_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VSXU); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_INT); \
- EA = tcg_temp_new(); \
- gen_addr_reg_index(ctx, EA); \
- gen_qemu_##operation(ctx, cpu_vsrh(xT(ctx->opcode)), EA); \
- /* NOTE: cpu_vsrl is undefined */ \
- tcg_temp_free(EA); \
-}
-
-VSX_LOAD_SCALAR(lxsdx, ld64_i64)
-VSX_LOAD_SCALAR(lxsiwax, ld32s_i64)
-VSX_LOAD_SCALAR(lxsibzx, ld8u_i64)
-VSX_LOAD_SCALAR(lxsihzx, ld16u_i64)
-VSX_LOAD_SCALAR(lxsiwzx, ld32u_i64)
-VSX_LOAD_SCALAR(lxsspx, ld32fs)
-
-static void gen_lxvd2x(DisasContext *ctx)
-{
- TCGv EA;
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- gen_set_access_type(ctx, ACCESS_INT);
- EA = tcg_temp_new();
- gen_addr_reg_index(ctx, EA);
- gen_qemu_ld64_i64(ctx, cpu_vsrh(xT(ctx->opcode)), EA);
- tcg_gen_addi_tl(EA, EA, 8);
- gen_qemu_ld64_i64(ctx, cpu_vsrl(xT(ctx->opcode)), EA);
- tcg_temp_free(EA);
-}
-
-static void gen_lxvdsx(DisasContext *ctx)
-{
- TCGv EA;
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- gen_set_access_type(ctx, ACCESS_INT);
- EA = tcg_temp_new();
- gen_addr_reg_index(ctx, EA);
- gen_qemu_ld64_i64(ctx, cpu_vsrh(xT(ctx->opcode)), EA);
- tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode)));
- tcg_temp_free(EA);
-}
-
-static void gen_lxvw4x(DisasContext *ctx)
-{
- TCGv EA;
- TCGv_i64 xth = cpu_vsrh(xT(ctx->opcode));
- TCGv_i64 xtl = cpu_vsrl(xT(ctx->opcode));
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- gen_set_access_type(ctx, ACCESS_INT);
- EA = tcg_temp_new();
-
- gen_addr_reg_index(ctx, EA);
- if (ctx->le_mode) {
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
-
- tcg_gen_qemu_ld_i64(t0, EA, ctx->mem_idx, MO_LEQ);
- tcg_gen_shri_i64(t1, t0, 32);
- tcg_gen_deposit_i64(xth, t1, t0, 32, 32);
- tcg_gen_addi_tl(EA, EA, 8);
- tcg_gen_qemu_ld_i64(t0, EA, ctx->mem_idx, MO_LEQ);
- tcg_gen_shri_i64(t1, t0, 32);
- tcg_gen_deposit_i64(xtl, t1, t0, 32, 32);
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
- } else {
- tcg_gen_qemu_ld_i64(xth, EA, ctx->mem_idx, MO_BEQ);
- tcg_gen_addi_tl(EA, EA, 8);
- tcg_gen_qemu_ld_i64(xtl, EA, ctx->mem_idx, MO_BEQ);
- }
- tcg_temp_free(EA);
-}
-
-static void gen_bswap16x8(TCGv_i64 outh, TCGv_i64 outl,
- TCGv_i64 inh, TCGv_i64 inl)
-{
- TCGv_i64 mask = tcg_const_i64(0x00FF00FF00FF00FF);
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
-
- /* outh = ((inh & mask) << 8) | ((inh >> 8) & mask) */
- tcg_gen_and_i64(t0, inh, mask);
- tcg_gen_shli_i64(t0, t0, 8);
- tcg_gen_shri_i64(t1, inh, 8);
- tcg_gen_and_i64(t1, t1, mask);
- tcg_gen_or_i64(outh, t0, t1);
-
- /* outl = ((inl & mask) << 8) | ((inl >> 8) & mask) */
- tcg_gen_and_i64(t0, inl, mask);
- tcg_gen_shli_i64(t0, t0, 8);
- tcg_gen_shri_i64(t1, inl, 8);
- tcg_gen_and_i64(t1, t1, mask);
- tcg_gen_or_i64(outl, t0, t1);
-
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
- tcg_temp_free_i64(mask);
-}
-
-static void gen_bswap32x4(TCGv_i64 outh, TCGv_i64 outl,
- TCGv_i64 inh, TCGv_i64 inl)
-{
- TCGv_i64 hi = tcg_temp_new_i64();
- TCGv_i64 lo = tcg_temp_new_i64();
-
- tcg_gen_bswap64_i64(hi, inh);
- tcg_gen_bswap64_i64(lo, inl);
- tcg_gen_shri_i64(outh, hi, 32);
- tcg_gen_deposit_i64(outh, outh, hi, 32, 32);
- tcg_gen_shri_i64(outl, lo, 32);
- tcg_gen_deposit_i64(outl, outl, lo, 32, 32);
-
- tcg_temp_free_i64(hi);
- tcg_temp_free_i64(lo);
-}
-static void gen_lxvh8x(DisasContext *ctx)
-{
- TCGv EA;
- TCGv_i64 xth = cpu_vsrh(xT(ctx->opcode));
- TCGv_i64 xtl = cpu_vsrl(xT(ctx->opcode));
-
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- gen_set_access_type(ctx, ACCESS_INT);
-
- EA = tcg_temp_new();
- gen_addr_reg_index(ctx, EA);
- tcg_gen_qemu_ld_i64(xth, EA, ctx->mem_idx, MO_BEQ);
- tcg_gen_addi_tl(EA, EA, 8);
- tcg_gen_qemu_ld_i64(xtl, EA, ctx->mem_idx, MO_BEQ);
- if (ctx->le_mode) {
- gen_bswap16x8(xth, xtl, xth, xtl);
- }
- tcg_temp_free(EA);
-}
-
-static void gen_lxvb16x(DisasContext *ctx)
-{
- TCGv EA;
- TCGv_i64 xth = cpu_vsrh(xT(ctx->opcode));
- TCGv_i64 xtl = cpu_vsrl(xT(ctx->opcode));
-
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- gen_set_access_type(ctx, ACCESS_INT);
- EA = tcg_temp_new();
- gen_addr_reg_index(ctx, EA);
- tcg_gen_qemu_ld_i64(xth, EA, ctx->mem_idx, MO_BEQ);
- tcg_gen_addi_tl(EA, EA, 8);
- tcg_gen_qemu_ld_i64(xtl, EA, ctx->mem_idx, MO_BEQ);
- tcg_temp_free(EA);
-}
-
-#define VSX_STORE_SCALAR(name, operation) \
-static void gen_##name(DisasContext *ctx) \
-{ \
- TCGv EA; \
- if (unlikely(!ctx->vsx_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VSXU); \
- return; \
- } \
- gen_set_access_type(ctx, ACCESS_INT); \
- EA = tcg_temp_new(); \
- gen_addr_reg_index(ctx, EA); \
- gen_qemu_##operation(ctx, cpu_vsrh(xS(ctx->opcode)), EA); \
- tcg_temp_free(EA); \
-}
-
-VSX_STORE_SCALAR(stxsdx, st64_i64)
-
-VSX_STORE_SCALAR(stxsibx, st8_i64)
-VSX_STORE_SCALAR(stxsihx, st16_i64)
-VSX_STORE_SCALAR(stxsiwx, st32_i64)
-VSX_STORE_SCALAR(stxsspx, st32fs)
-
-static void gen_stxvd2x(DisasContext *ctx)
-{
- TCGv EA;
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- gen_set_access_type(ctx, ACCESS_INT);
- EA = tcg_temp_new();
- gen_addr_reg_index(ctx, EA);
- gen_qemu_st64_i64(ctx, cpu_vsrh(xS(ctx->opcode)), EA);
- tcg_gen_addi_tl(EA, EA, 8);
- gen_qemu_st64_i64(ctx, cpu_vsrl(xS(ctx->opcode)), EA);
- tcg_temp_free(EA);
-}
-
-static void gen_stxvw4x(DisasContext *ctx)
-{
- TCGv_i64 xsh = cpu_vsrh(xS(ctx->opcode));
- TCGv_i64 xsl = cpu_vsrl(xS(ctx->opcode));
- TCGv EA;
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- gen_set_access_type(ctx, ACCESS_INT);
- EA = tcg_temp_new();
- gen_addr_reg_index(ctx, EA);
- if (ctx->le_mode) {
- TCGv_i64 t0 = tcg_temp_new_i64();
- TCGv_i64 t1 = tcg_temp_new_i64();
-
- tcg_gen_shri_i64(t0, xsh, 32);
- tcg_gen_deposit_i64(t1, t0, xsh, 32, 32);
- tcg_gen_qemu_st_i64(t1, EA, ctx->mem_idx, MO_LEQ);
- tcg_gen_addi_tl(EA, EA, 8);
- tcg_gen_shri_i64(t0, xsl, 32);
- tcg_gen_deposit_i64(t1, t0, xsl, 32, 32);
- tcg_gen_qemu_st_i64(t1, EA, ctx->mem_idx, MO_LEQ);
- tcg_temp_free_i64(t0);
- tcg_temp_free_i64(t1);
- } else {
- tcg_gen_qemu_st_i64(xsh, EA, ctx->mem_idx, MO_BEQ);
- tcg_gen_addi_tl(EA, EA, 8);
- tcg_gen_qemu_st_i64(xsl, EA, ctx->mem_idx, MO_BEQ);
- }
- tcg_temp_free(EA);
-}
-
-static void gen_stxvh8x(DisasContext *ctx)
-{
- TCGv_i64 xsh = cpu_vsrh(xS(ctx->opcode));
- TCGv_i64 xsl = cpu_vsrl(xS(ctx->opcode));
- TCGv EA;
-
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- gen_set_access_type(ctx, ACCESS_INT);
- EA = tcg_temp_new();
- gen_addr_reg_index(ctx, EA);
- if (ctx->le_mode) {
- TCGv_i64 outh = tcg_temp_new_i64();
- TCGv_i64 outl = tcg_temp_new_i64();
-
- gen_bswap16x8(outh, outl, xsh, xsl);
- tcg_gen_qemu_st_i64(outh, EA, ctx->mem_idx, MO_BEQ);
- tcg_gen_addi_tl(EA, EA, 8);
- tcg_gen_qemu_st_i64(outl, EA, ctx->mem_idx, MO_BEQ);
- tcg_temp_free_i64(outh);
- tcg_temp_free_i64(outl);
- } else {
- tcg_gen_qemu_st_i64(xsh, EA, ctx->mem_idx, MO_BEQ);
- tcg_gen_addi_tl(EA, EA, 8);
- tcg_gen_qemu_st_i64(xsl, EA, ctx->mem_idx, MO_BEQ);
- }
- tcg_temp_free(EA);
-}
-
-static void gen_stxvb16x(DisasContext *ctx)
-{
- TCGv_i64 xsh = cpu_vsrh(xS(ctx->opcode));
- TCGv_i64 xsl = cpu_vsrl(xS(ctx->opcode));
- TCGv EA;
-
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- gen_set_access_type(ctx, ACCESS_INT);
- EA = tcg_temp_new();
- gen_addr_reg_index(ctx, EA);
- tcg_gen_qemu_st_i64(xsh, EA, ctx->mem_idx, MO_BEQ);
- tcg_gen_addi_tl(EA, EA, 8);
- tcg_gen_qemu_st_i64(xsl, EA, ctx->mem_idx, MO_BEQ);
- tcg_temp_free(EA);
-}
-
-#define MV_VSRW(name, tcgop1, tcgop2, target, source) \
-static void gen_##name(DisasContext *ctx) \
-{ \
- if (xS(ctx->opcode) < 32) { \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- } else { \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- } \
- TCGv_i64 tmp = tcg_temp_new_i64(); \
- tcg_gen_##tcgop1(tmp, source); \
- tcg_gen_##tcgop2(target, tmp); \
- tcg_temp_free_i64(tmp); \
-}
-
-
-MV_VSRW(mfvsrwz, ext32u_i64, trunc_i64_tl, cpu_gpr[rA(ctx->opcode)], \
- cpu_vsrh(xS(ctx->opcode)))
-MV_VSRW(mtvsrwa, extu_tl_i64, ext32s_i64, cpu_vsrh(xT(ctx->opcode)), \
- cpu_gpr[rA(ctx->opcode)])
-MV_VSRW(mtvsrwz, extu_tl_i64, ext32u_i64, cpu_vsrh(xT(ctx->opcode)), \
- cpu_gpr[rA(ctx->opcode)])
-
-#if defined(TARGET_PPC64)
-#define MV_VSRD(name, target, source) \
-static void gen_##name(DisasContext *ctx) \
-{ \
- if (xS(ctx->opcode) < 32) { \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- } else { \
- if (unlikely(!ctx->altivec_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VPU); \
- return; \
- } \
- } \
- tcg_gen_mov_i64(target, source); \
-}
-
-MV_VSRD(mfvsrd, cpu_gpr[rA(ctx->opcode)], cpu_vsrh(xS(ctx->opcode)))
-MV_VSRD(mtvsrd, cpu_vsrh(xT(ctx->opcode)), cpu_gpr[rA(ctx->opcode)])
-
-static void gen_mfvsrld(DisasContext *ctx)
-{
- if (xS(ctx->opcode) < 32) {
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- } else {
- if (unlikely(!ctx->altivec_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VPU);
- return;
- }
- }
-
- tcg_gen_mov_i64(cpu_gpr[rA(ctx->opcode)], cpu_vsrl(xS(ctx->opcode)));
-}
-
-static void gen_mtvsrdd(DisasContext *ctx)
-{
- if (xT(ctx->opcode) < 32) {
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- } else {
- if (unlikely(!ctx->altivec_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VPU);
- return;
- }
- }
-
- if (!rA(ctx->opcode)) {
- tcg_gen_movi_i64(cpu_vsrh(xT(ctx->opcode)), 0);
- } else {
- tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), cpu_gpr[rA(ctx->opcode)]);
- }
-
- tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_gpr[rB(ctx->opcode)]);
-}
-
-static void gen_mtvsrws(DisasContext *ctx)
-{
- if (xT(ctx->opcode) < 32) {
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- } else {
- if (unlikely(!ctx->altivec_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VPU);
- return;
- }
- }
-
- tcg_gen_deposit_i64(cpu_vsrl(xT(ctx->opcode)), cpu_gpr[rA(ctx->opcode)],
- cpu_gpr[rA(ctx->opcode)], 32, 32);
- tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), cpu_vsrl(xT(ctx->opcode)));
-}
-
-#endif
-
-static void gen_xxpermdi(DisasContext *ctx)
-{
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
-
- if (unlikely((xT(ctx->opcode) == xA(ctx->opcode)) ||
- (xT(ctx->opcode) == xB(ctx->opcode)))) {
- TCGv_i64 xh, xl;
-
- xh = tcg_temp_new_i64();
- xl = tcg_temp_new_i64();
-
- if ((DM(ctx->opcode) & 2) == 0) {
- tcg_gen_mov_i64(xh, cpu_vsrh(xA(ctx->opcode)));
- } else {
- tcg_gen_mov_i64(xh, cpu_vsrl(xA(ctx->opcode)));
- }
- if ((DM(ctx->opcode) & 1) == 0) {
- tcg_gen_mov_i64(xl, cpu_vsrh(xB(ctx->opcode)));
- } else {
- tcg_gen_mov_i64(xl, cpu_vsrl(xB(ctx->opcode)));
- }
-
- tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xh);
- tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), xl);
-
- tcg_temp_free_i64(xh);
- tcg_temp_free_i64(xl);
- } else {
- if ((DM(ctx->opcode) & 2) == 0) {
- tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), cpu_vsrh(xA(ctx->opcode)));
- } else {
- tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), cpu_vsrl(xA(ctx->opcode)));
- }
- if ((DM(ctx->opcode) & 1) == 0) {
- tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xB(ctx->opcode)));
- } else {
- tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrl(xB(ctx->opcode)));
- }
- }
-}
-
-#define OP_ABS 1
-#define OP_NABS 2
-#define OP_NEG 3
-#define OP_CPSGN 4
-#define SGN_MASK_DP 0x8000000000000000ull
-#define SGN_MASK_SP 0x8000000080000000ull
-
-#define VSX_SCALAR_MOVE(name, op, sgn_mask) \
-static void glue(gen_, name)(DisasContext * ctx) \
- { \
- TCGv_i64 xb, sgm; \
- if (unlikely(!ctx->vsx_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VSXU); \
- return; \
- } \
- xb = tcg_temp_new_i64(); \
- sgm = tcg_temp_new_i64(); \
- tcg_gen_mov_i64(xb, cpu_vsrh(xB(ctx->opcode))); \
- tcg_gen_movi_i64(sgm, sgn_mask); \
- switch (op) { \
- case OP_ABS: { \
- tcg_gen_andc_i64(xb, xb, sgm); \
- break; \
- } \
- case OP_NABS: { \
- tcg_gen_or_i64(xb, xb, sgm); \
- break; \
- } \
- case OP_NEG: { \
- tcg_gen_xor_i64(xb, xb, sgm); \
- break; \
- } \
- case OP_CPSGN: { \
- TCGv_i64 xa = tcg_temp_new_i64(); \
- tcg_gen_mov_i64(xa, cpu_vsrh(xA(ctx->opcode))); \
- tcg_gen_and_i64(xa, xa, sgm); \
- tcg_gen_andc_i64(xb, xb, sgm); \
- tcg_gen_or_i64(xb, xb, xa); \
- tcg_temp_free_i64(xa); \
- break; \
- } \
- } \
- tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xb); \
- tcg_temp_free_i64(xb); \
- tcg_temp_free_i64(sgm); \
- }
-
-VSX_SCALAR_MOVE(xsabsdp, OP_ABS, SGN_MASK_DP)
-VSX_SCALAR_MOVE(xsnabsdp, OP_NABS, SGN_MASK_DP)
-VSX_SCALAR_MOVE(xsnegdp, OP_NEG, SGN_MASK_DP)
-VSX_SCALAR_MOVE(xscpsgndp, OP_CPSGN, SGN_MASK_DP)
-
-#define VSX_VECTOR_MOVE(name, op, sgn_mask) \
-static void glue(gen_, name)(DisasContext * ctx) \
- { \
- TCGv_i64 xbh, xbl, sgm; \
- if (unlikely(!ctx->vsx_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VSXU); \
- return; \
- } \
- xbh = tcg_temp_new_i64(); \
- xbl = tcg_temp_new_i64(); \
- sgm = tcg_temp_new_i64(); \
- tcg_gen_mov_i64(xbh, cpu_vsrh(xB(ctx->opcode))); \
- tcg_gen_mov_i64(xbl, cpu_vsrl(xB(ctx->opcode))); \
- tcg_gen_movi_i64(sgm, sgn_mask); \
- switch (op) { \
- case OP_ABS: { \
- tcg_gen_andc_i64(xbh, xbh, sgm); \
- tcg_gen_andc_i64(xbl, xbl, sgm); \
- break; \
- } \
- case OP_NABS: { \
- tcg_gen_or_i64(xbh, xbh, sgm); \
- tcg_gen_or_i64(xbl, xbl, sgm); \
- break; \
- } \
- case OP_NEG: { \
- tcg_gen_xor_i64(xbh, xbh, sgm); \
- tcg_gen_xor_i64(xbl, xbl, sgm); \
- break; \
- } \
- case OP_CPSGN: { \
- TCGv_i64 xah = tcg_temp_new_i64(); \
- TCGv_i64 xal = tcg_temp_new_i64(); \
- tcg_gen_mov_i64(xah, cpu_vsrh(xA(ctx->opcode))); \
- tcg_gen_mov_i64(xal, cpu_vsrl(xA(ctx->opcode))); \
- tcg_gen_and_i64(xah, xah, sgm); \
- tcg_gen_and_i64(xal, xal, sgm); \
- tcg_gen_andc_i64(xbh, xbh, sgm); \
- tcg_gen_andc_i64(xbl, xbl, sgm); \
- tcg_gen_or_i64(xbh, xbh, xah); \
- tcg_gen_or_i64(xbl, xbl, xal); \
- tcg_temp_free_i64(xah); \
- tcg_temp_free_i64(xal); \
- break; \
- } \
- } \
- tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xbh); \
- tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), xbl); \
- tcg_temp_free_i64(xbh); \
- tcg_temp_free_i64(xbl); \
- tcg_temp_free_i64(sgm); \
- }
-
-VSX_VECTOR_MOVE(xvabsdp, OP_ABS, SGN_MASK_DP)
-VSX_VECTOR_MOVE(xvnabsdp, OP_NABS, SGN_MASK_DP)
-VSX_VECTOR_MOVE(xvnegdp, OP_NEG, SGN_MASK_DP)
-VSX_VECTOR_MOVE(xvcpsgndp, OP_CPSGN, SGN_MASK_DP)
-VSX_VECTOR_MOVE(xvabssp, OP_ABS, SGN_MASK_SP)
-VSX_VECTOR_MOVE(xvnabssp, OP_NABS, SGN_MASK_SP)
-VSX_VECTOR_MOVE(xvnegsp, OP_NEG, SGN_MASK_SP)
-VSX_VECTOR_MOVE(xvcpsgnsp, OP_CPSGN, SGN_MASK_SP)
-
-#define GEN_VSX_HELPER_2(name, op1, op2, inval, type) \
-static void gen_##name(DisasContext * ctx) \
-{ \
- TCGv_i32 opc; \
- if (unlikely(!ctx->vsx_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VSXU); \
- return; \
- } \
- opc = tcg_const_i32(ctx->opcode); \
- gen_helper_##name(cpu_env, opc); \
- tcg_temp_free_i32(opc); \
-}
-
-#define GEN_VSX_HELPER_XT_XB_ENV(name, op1, op2, inval, type) \
-static void gen_##name(DisasContext * ctx) \
-{ \
- if (unlikely(!ctx->vsx_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VSXU); \
- return; \
- } \
- gen_helper_##name(cpu_vsrh(xT(ctx->opcode)), cpu_env, \
- cpu_vsrh(xB(ctx->opcode))); \
-}
-
-GEN_VSX_HELPER_2(xsadddp, 0x00, 0x04, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xssubdp, 0x00, 0x05, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsmuldp, 0x00, 0x06, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsdivdp, 0x00, 0x07, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsredp, 0x14, 0x05, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xssqrtdp, 0x16, 0x04, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsrsqrtedp, 0x14, 0x04, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xstdivdp, 0x14, 0x07, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xstsqrtdp, 0x14, 0x06, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsmaddadp, 0x04, 0x04, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsmaddmdp, 0x04, 0x05, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsmsubadp, 0x04, 0x06, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsmsubmdp, 0x04, 0x07, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsnmaddadp, 0x04, 0x14, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsnmaddmdp, 0x04, 0x15, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsnmsubadp, 0x04, 0x16, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsnmsubmdp, 0x04, 0x17, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscmpeqdp, 0x0C, 0x00, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscmpgtdp, 0x0C, 0x01, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscmpgedp, 0x0C, 0x02, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscmpnedp, 0x0C, 0x03, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xscmpodp, 0x0C, 0x05, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscmpudp, 0x0C, 0x04, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsmaxdp, 0x00, 0x14, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsmindp, 0x00, 0x15, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscvdpsp, 0x12, 0x10, 0, PPC2_VSX)
-GEN_VSX_HELPER_XT_XB_ENV(xscvdpspn, 0x16, 0x10, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xscvspdp, 0x12, 0x14, 0, PPC2_VSX)
-GEN_VSX_HELPER_XT_XB_ENV(xscvspdpn, 0x16, 0x14, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xscvdpsxds, 0x10, 0x15, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscvdpsxws, 0x10, 0x05, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscvdpuxds, 0x10, 0x14, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscvdpuxws, 0x10, 0x04, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscvsxddp, 0x10, 0x17, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xscvuxddp, 0x10, 0x16, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsrdpi, 0x12, 0x04, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsrdpic, 0x16, 0x06, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsrdpim, 0x12, 0x07, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsrdpip, 0x12, 0x06, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xsrdpiz, 0x12, 0x05, 0, PPC2_VSX)
-GEN_VSX_HELPER_XT_XB_ENV(xsrsp, 0x12, 0x11, 0, PPC2_VSX207)
-
-GEN_VSX_HELPER_2(xsaddsp, 0x00, 0x00, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xssubsp, 0x00, 0x01, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsmulsp, 0x00, 0x02, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsdivsp, 0x00, 0x03, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsresp, 0x14, 0x01, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xssqrtsp, 0x16, 0x00, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsrsqrtesp, 0x14, 0x00, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsmaddasp, 0x04, 0x00, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsmaddmsp, 0x04, 0x01, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsmsubasp, 0x04, 0x02, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsmsubmsp, 0x04, 0x03, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsnmaddasp, 0x04, 0x10, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsnmaddmsp, 0x04, 0x11, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsnmsubasp, 0x04, 0x12, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xsnmsubmsp, 0x04, 0x13, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xscvsxdsp, 0x10, 0x13, 0, PPC2_VSX207)
-GEN_VSX_HELPER_2(xscvuxdsp, 0x10, 0x12, 0, PPC2_VSX207)
-
-GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmuldp, 0x00, 0x0E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvdivdp, 0x00, 0x0F, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvredp, 0x14, 0x0D, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvsqrtdp, 0x16, 0x0C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrsqrtedp, 0x14, 0x0C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvtdivdp, 0x14, 0x0F, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvtsqrtdp, 0x14, 0x0E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmaddadp, 0x04, 0x0C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmaddmdp, 0x04, 0x0D, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmsubadp, 0x04, 0x0E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmsubmdp, 0x04, 0x0F, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvnmaddadp, 0x04, 0x1C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvnmaddmdp, 0x04, 0x1D, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvnmsubadp, 0x04, 0x1E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvnmsubmdp, 0x04, 0x1F, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmaxdp, 0x00, 0x1C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmindp, 0x00, 0x1D, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcmpeqdp, 0x0C, 0x0C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcmpgtdp, 0x0C, 0x0D, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcmpgedp, 0x0C, 0x0E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcmpnedp, 0x0C, 0x0F, 0, PPC2_ISA300)
-GEN_VSX_HELPER_2(xvcvdpsp, 0x12, 0x18, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvdpsxds, 0x10, 0x1D, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvdpsxws, 0x10, 0x0D, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvdpuxds, 0x10, 0x1C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvdpuxws, 0x10, 0x0C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvsxddp, 0x10, 0x1F, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvuxddp, 0x10, 0x1E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvsxwdp, 0x10, 0x0F, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvuxwdp, 0x10, 0x0E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrdpi, 0x12, 0x0C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrdpic, 0x16, 0x0E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrdpim, 0x12, 0x0F, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrdpip, 0x12, 0x0E, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrdpiz, 0x12, 0x0D, 0, PPC2_VSX)
-
-GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmulsp, 0x00, 0x0A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvdivsp, 0x00, 0x0B, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvresp, 0x14, 0x09, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvsqrtsp, 0x16, 0x08, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrsqrtesp, 0x14, 0x08, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvtdivsp, 0x14, 0x0B, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvtsqrtsp, 0x14, 0x0A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmaddasp, 0x04, 0x08, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmaddmsp, 0x04, 0x09, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmsubasp, 0x04, 0x0A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmsubmsp, 0x04, 0x0B, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvnmaddasp, 0x04, 0x18, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvnmaddmsp, 0x04, 0x19, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvnmsubasp, 0x04, 0x1A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvnmsubmsp, 0x04, 0x1B, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvmaxsp, 0x00, 0x18, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvminsp, 0x00, 0x19, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcmpeqsp, 0x0C, 0x08, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcmpgtsp, 0x0C, 0x09, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcmpgesp, 0x0C, 0x0A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcmpnesp, 0x0C, 0x0B, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvspdp, 0x12, 0x1C, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvspsxds, 0x10, 0x19, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvspsxws, 0x10, 0x09, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvspuxds, 0x10, 0x18, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvspuxws, 0x10, 0x08, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvsxdsp, 0x10, 0x1B, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvuxdsp, 0x10, 0x1A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvsxwsp, 0x10, 0x0B, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvcvuxwsp, 0x10, 0x0A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrspi, 0x12, 0x08, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrspic, 0x16, 0x0A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrspim, 0x12, 0x0B, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrspip, 0x12, 0x0A, 0, PPC2_VSX)
-GEN_VSX_HELPER_2(xvrspiz, 0x12, 0x09, 0, PPC2_VSX)
-
-static void gen_xxbrd(DisasContext *ctx)
-{
- TCGv_i64 xth = cpu_vsrh(xT(ctx->opcode));
- TCGv_i64 xtl = cpu_vsrl(xT(ctx->opcode));
- TCGv_i64 xbh = cpu_vsrh(xB(ctx->opcode));
- TCGv_i64 xbl = cpu_vsrl(xB(ctx->opcode));
-
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- tcg_gen_bswap64_i64(xth, xbh);
- tcg_gen_bswap64_i64(xtl, xbl);
-}
-
-static void gen_xxbrh(DisasContext *ctx)
-{
- TCGv_i64 xth = cpu_vsrh(xT(ctx->opcode));
- TCGv_i64 xtl = cpu_vsrl(xT(ctx->opcode));
- TCGv_i64 xbh = cpu_vsrh(xB(ctx->opcode));
- TCGv_i64 xbl = cpu_vsrl(xB(ctx->opcode));
-
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- gen_bswap16x8(xth, xtl, xbh, xbl);
-}
-
-static void gen_xxbrq(DisasContext *ctx)
-{
- TCGv_i64 xth = cpu_vsrh(xT(ctx->opcode));
- TCGv_i64 xtl = cpu_vsrl(xT(ctx->opcode));
- TCGv_i64 xbh = cpu_vsrh(xB(ctx->opcode));
- TCGv_i64 xbl = cpu_vsrl(xB(ctx->opcode));
- TCGv_i64 t0 = tcg_temp_new_i64();
-
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- tcg_gen_bswap64_i64(t0, xbl);
- tcg_gen_bswap64_i64(xtl, xbh);
- tcg_gen_mov_i64(xth, t0);
- tcg_temp_free_i64(t0);
-}
-
-static void gen_xxbrw(DisasContext *ctx)
-{
- TCGv_i64 xth = cpu_vsrh(xT(ctx->opcode));
- TCGv_i64 xtl = cpu_vsrl(xT(ctx->opcode));
- TCGv_i64 xbh = cpu_vsrh(xB(ctx->opcode));
- TCGv_i64 xbl = cpu_vsrl(xB(ctx->opcode));
-
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- gen_bswap32x4(xth, xtl, xbh, xbl);
-}
-
-#define VSX_LOGICAL(name, tcg_op) \
-static void glue(gen_, name)(DisasContext * ctx) \
- { \
- if (unlikely(!ctx->vsx_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VSXU); \
- return; \
- } \
- tcg_op(cpu_vsrh(xT(ctx->opcode)), cpu_vsrh(xA(ctx->opcode)), \
- cpu_vsrh(xB(ctx->opcode))); \
- tcg_op(cpu_vsrl(xT(ctx->opcode)), cpu_vsrl(xA(ctx->opcode)), \
- cpu_vsrl(xB(ctx->opcode))); \
- }
-
-VSX_LOGICAL(xxland, tcg_gen_and_i64)
-VSX_LOGICAL(xxlandc, tcg_gen_andc_i64)
-VSX_LOGICAL(xxlor, tcg_gen_or_i64)
-VSX_LOGICAL(xxlxor, tcg_gen_xor_i64)
-VSX_LOGICAL(xxlnor, tcg_gen_nor_i64)
-VSX_LOGICAL(xxleqv, tcg_gen_eqv_i64)
-VSX_LOGICAL(xxlnand, tcg_gen_nand_i64)
-VSX_LOGICAL(xxlorc, tcg_gen_orc_i64)
-
-#define VSX_XXMRG(name, high) \
-static void glue(gen_, name)(DisasContext * ctx) \
- { \
- TCGv_i64 a0, a1, b0, b1; \
- if (unlikely(!ctx->vsx_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_VSXU); \
- return; \
- } \
- a0 = tcg_temp_new_i64(); \
- a1 = tcg_temp_new_i64(); \
- b0 = tcg_temp_new_i64(); \
- b1 = tcg_temp_new_i64(); \
- if (high) { \
- tcg_gen_mov_i64(a0, cpu_vsrh(xA(ctx->opcode))); \
- tcg_gen_mov_i64(a1, cpu_vsrh(xA(ctx->opcode))); \
- tcg_gen_mov_i64(b0, cpu_vsrh(xB(ctx->opcode))); \
- tcg_gen_mov_i64(b1, cpu_vsrh(xB(ctx->opcode))); \
- } else { \
- tcg_gen_mov_i64(a0, cpu_vsrl(xA(ctx->opcode))); \
- tcg_gen_mov_i64(a1, cpu_vsrl(xA(ctx->opcode))); \
- tcg_gen_mov_i64(b0, cpu_vsrl(xB(ctx->opcode))); \
- tcg_gen_mov_i64(b1, cpu_vsrl(xB(ctx->opcode))); \
- } \
- tcg_gen_shri_i64(a0, a0, 32); \
- tcg_gen_shri_i64(b0, b0, 32); \
- tcg_gen_deposit_i64(cpu_vsrh(xT(ctx->opcode)), \
- b0, a0, 32, 32); \
- tcg_gen_deposit_i64(cpu_vsrl(xT(ctx->opcode)), \
- b1, a1, 32, 32); \
- tcg_temp_free_i64(a0); \
- tcg_temp_free_i64(a1); \
- tcg_temp_free_i64(b0); \
- tcg_temp_free_i64(b1); \
- }
-
-VSX_XXMRG(xxmrghw, 1)
-VSX_XXMRG(xxmrglw, 0)
-
-static void gen_xxsel(DisasContext * ctx)
-{
- TCGv_i64 a, b, c;
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- a = tcg_temp_new_i64();
- b = tcg_temp_new_i64();
- c = tcg_temp_new_i64();
-
- tcg_gen_mov_i64(a, cpu_vsrh(xA(ctx->opcode)));
- tcg_gen_mov_i64(b, cpu_vsrh(xB(ctx->opcode)));
- tcg_gen_mov_i64(c, cpu_vsrh(xC(ctx->opcode)));
-
- tcg_gen_and_i64(b, b, c);
- tcg_gen_andc_i64(a, a, c);
- tcg_gen_or_i64(cpu_vsrh(xT(ctx->opcode)), a, b);
-
- tcg_gen_mov_i64(a, cpu_vsrl(xA(ctx->opcode)));
- tcg_gen_mov_i64(b, cpu_vsrl(xB(ctx->opcode)));
- tcg_gen_mov_i64(c, cpu_vsrl(xC(ctx->opcode)));
-
- tcg_gen_and_i64(b, b, c);
- tcg_gen_andc_i64(a, a, c);
- tcg_gen_or_i64(cpu_vsrl(xT(ctx->opcode)), a, b);
-
- tcg_temp_free_i64(a);
- tcg_temp_free_i64(b);
- tcg_temp_free_i64(c);
-}
-
-static void gen_xxspltw(DisasContext *ctx)
-{
- TCGv_i64 b, b2;
- TCGv_i64 vsr = (UIM(ctx->opcode) & 2) ?
- cpu_vsrl(xB(ctx->opcode)) :
- cpu_vsrh(xB(ctx->opcode));
-
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
-
- b = tcg_temp_new_i64();
- b2 = tcg_temp_new_i64();
-
- if (UIM(ctx->opcode) & 1) {
- tcg_gen_ext32u_i64(b, vsr);
- } else {
- tcg_gen_shri_i64(b, vsr, 32);
- }
-
- tcg_gen_shli_i64(b2, b, 32);
- tcg_gen_or_i64(cpu_vsrh(xT(ctx->opcode)), b, b2);
- tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), cpu_vsrh(xT(ctx->opcode)));
-
- tcg_temp_free_i64(b);
- tcg_temp_free_i64(b2);
-}
-
-#define pattern(x) (((x) & 0xff) * (~(uint64_t)0 / 0xff))
-
-static void gen_xxspltib(DisasContext *ctx)
-{
- unsigned char uim8 = IMM8(ctx->opcode);
- if (xS(ctx->opcode) < 32) {
- if (unlikely(!ctx->altivec_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VPU);
- return;
- }
- } else {
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- }
- tcg_gen_movi_i64(cpu_vsrh(xT(ctx->opcode)), pattern(uim8));
- tcg_gen_movi_i64(cpu_vsrl(xT(ctx->opcode)), pattern(uim8));
-}
-
-static void gen_xxsldwi(DisasContext *ctx)
-{
- TCGv_i64 xth, xtl;
- if (unlikely(!ctx->vsx_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_VSXU);
- return;
- }
- xth = tcg_temp_new_i64();
- xtl = tcg_temp_new_i64();
-
- switch (SHW(ctx->opcode)) {
- case 0: {
- tcg_gen_mov_i64(xth, cpu_vsrh(xA(ctx->opcode)));
- tcg_gen_mov_i64(xtl, cpu_vsrl(xA(ctx->opcode)));
- break;
- }
- case 1: {
- TCGv_i64 t0 = tcg_temp_new_i64();
- tcg_gen_mov_i64(xth, cpu_vsrh(xA(ctx->opcode)));
- tcg_gen_shli_i64(xth, xth, 32);
- tcg_gen_mov_i64(t0, cpu_vsrl(xA(ctx->opcode)));
- tcg_gen_shri_i64(t0, t0, 32);
- tcg_gen_or_i64(xth, xth, t0);
- tcg_gen_mov_i64(xtl, cpu_vsrl(xA(ctx->opcode)));
- tcg_gen_shli_i64(xtl, xtl, 32);
- tcg_gen_mov_i64(t0, cpu_vsrh(xB(ctx->opcode)));
- tcg_gen_shri_i64(t0, t0, 32);
- tcg_gen_or_i64(xtl, xtl, t0);
- tcg_temp_free_i64(t0);
- break;
- }
- case 2: {
- tcg_gen_mov_i64(xth, cpu_vsrl(xA(ctx->opcode)));
- tcg_gen_mov_i64(xtl, cpu_vsrh(xB(ctx->opcode)));
- break;
- }
- case 3: {
- TCGv_i64 t0 = tcg_temp_new_i64();
- tcg_gen_mov_i64(xth, cpu_vsrl(xA(ctx->opcode)));
- tcg_gen_shli_i64(xth, xth, 32);
- tcg_gen_mov_i64(t0, cpu_vsrh(xB(ctx->opcode)));
- tcg_gen_shri_i64(t0, t0, 32);
- tcg_gen_or_i64(xth, xth, t0);
- tcg_gen_mov_i64(xtl, cpu_vsrh(xB(ctx->opcode)));
- tcg_gen_shli_i64(xtl, xtl, 32);
- tcg_gen_mov_i64(t0, cpu_vsrl(xB(ctx->opcode)));
- tcg_gen_shri_i64(t0, t0, 32);
- tcg_gen_or_i64(xtl, xtl, t0);
- tcg_temp_free_i64(t0);
- break;
- }
- }
-
- tcg_gen_mov_i64(cpu_vsrh(xT(ctx->opcode)), xth);
- tcg_gen_mov_i64(cpu_vsrl(xT(ctx->opcode)), xtl);
-
- tcg_temp_free_i64(xth);
- tcg_temp_free_i64(xtl);
-}
-
-#undef GEN_XX2FORM
-#undef GEN_XX3FORM
-#undef GEN_XX2IFORM
-#undef GEN_XX3_RC_FORM
-#undef GEN_XX3FORM_DM
-#undef VSX_LOGICAL
diff --git a/target-ppc/translate/vsx-ops.inc.c b/target-ppc/translate/vsx-ops.inc.c
deleted file mode 100644
index 3d9104155a..0000000000
--- a/target-ppc/translate/vsx-ops.inc.c
+++ /dev/null
@@ -1,300 +0,0 @@
-GEN_HANDLER_E(lxsdx, 0x1F, 0x0C, 0x12, 0, PPC_NONE, PPC2_VSX),
-GEN_HANDLER_E(lxsiwax, 0x1F, 0x0C, 0x02, 0, PPC_NONE, PPC2_VSX207),
-GEN_HANDLER_E(lxsiwzx, 0x1F, 0x0C, 0x00, 0, PPC_NONE, PPC2_VSX207),
-GEN_HANDLER_E(lxsibzx, 0x1F, 0x0D, 0x18, 0, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E(lxsihzx, 0x1F, 0x0D, 0x19, 0, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E(lxsspx, 0x1F, 0x0C, 0x10, 0, PPC_NONE, PPC2_VSX207),
-GEN_HANDLER_E(lxvd2x, 0x1F, 0x0C, 0x1A, 0, PPC_NONE, PPC2_VSX),
-GEN_HANDLER_E(lxvdsx, 0x1F, 0x0C, 0x0A, 0, PPC_NONE, PPC2_VSX),
-GEN_HANDLER_E(lxvw4x, 0x1F, 0x0C, 0x18, 0, PPC_NONE, PPC2_VSX),
-GEN_HANDLER_E(lxvh8x, 0x1F, 0x0C, 0x19, 0, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E(lxvb16x, 0x1F, 0x0C, 0x1B, 0, PPC_NONE, PPC2_ISA300),
-
-GEN_HANDLER_E(stxsdx, 0x1F, 0xC, 0x16, 0, PPC_NONE, PPC2_VSX),
-GEN_HANDLER_E(stxsibx, 0x1F, 0xD, 0x1C, 0, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E(stxsihx, 0x1F, 0xD, 0x1D, 0, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E(stxsiwx, 0x1F, 0xC, 0x04, 0, PPC_NONE, PPC2_VSX207),
-GEN_HANDLER_E(stxsspx, 0x1F, 0xC, 0x14, 0, PPC_NONE, PPC2_VSX207),
-GEN_HANDLER_E(stxvd2x, 0x1F, 0xC, 0x1E, 0, PPC_NONE, PPC2_VSX),
-GEN_HANDLER_E(stxvw4x, 0x1F, 0xC, 0x1C, 0, PPC_NONE, PPC2_VSX),
-GEN_HANDLER_E(stxvh8x, 0x1F, 0x0C, 0x1D, 0, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E(stxvb16x, 0x1F, 0x0C, 0x1F, 0, PPC_NONE, PPC2_ISA300),
-
-GEN_HANDLER_E(mfvsrwz, 0x1F, 0x13, 0x03, 0x0000F800, PPC_NONE, PPC2_VSX207),
-GEN_HANDLER_E(mtvsrwa, 0x1F, 0x13, 0x06, 0x0000F800, PPC_NONE, PPC2_VSX207),
-GEN_HANDLER_E(mtvsrwz, 0x1F, 0x13, 0x07, 0x0000F800, PPC_NONE, PPC2_VSX207),
-#if defined(TARGET_PPC64)
-GEN_HANDLER_E(mfvsrd, 0x1F, 0x13, 0x01, 0x0000F800, PPC_NONE, PPC2_VSX207),
-GEN_HANDLER_E(mtvsrd, 0x1F, 0x13, 0x05, 0x0000F800, PPC_NONE, PPC2_VSX207),
-GEN_HANDLER_E(mfvsrld, 0X1F, 0x13, 0x09, 0x0000F800, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E(mtvsrdd, 0X1F, 0x13, 0x0D, 0x0, PPC_NONE, PPC2_ISA300),
-GEN_HANDLER_E(mtvsrws, 0x1F, 0x13, 0x0C, 0x0000F800, PPC_NONE, PPC2_ISA300),
-#endif
-
-#define GEN_XX1FORM(name, opc2, opc3, fl2) \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0, opc3, 0, PPC_NONE, fl2), \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 0, PPC_NONE, fl2)
-
-#define GEN_XX2FORM(name, opc2, opc3, fl2) \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0, opc3, 0, PPC_NONE, fl2), \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 0, PPC_NONE, fl2)
-
-#define GEN_XX2FORM_EO(name, opc2, opc3, opc4, fl2) \
-GEN_HANDLER2_E_2(name, #name, 0x3C, opc2 | 0, opc3, opc4, 0, PPC_NONE, fl2), \
-GEN_HANDLER2_E_2(name, #name, 0x3C, opc2 | 1, opc3, opc4, 0, PPC_NONE, fl2)
-
-#define GEN_XX3FORM(name, opc2, opc3, fl2) \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0, opc3, 0, PPC_NONE, fl2), \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 0, PPC_NONE, fl2), \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 2, opc3, 0, PPC_NONE, fl2), \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 3, opc3, 0, PPC_NONE, fl2)
-
-#define GEN_XX2IFORM(name, opc2, opc3, fl2) \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0, opc3, 1, PPC_NONE, fl2), \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 1, opc3, 1, PPC_NONE, fl2), \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 2, opc3, 1, PPC_NONE, fl2), \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 3, opc3, 1, PPC_NONE, fl2)
-
-#define GEN_XX3_RC_FORM(name, opc2, opc3, fl2) \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x00, opc3 | 0x00, 0, PPC_NONE, fl2), \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x01, opc3 | 0x00, 0, PPC_NONE, fl2), \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x02, opc3 | 0x00, 0, PPC_NONE, fl2), \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x03, opc3 | 0x00, 0, PPC_NONE, fl2), \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x00, opc3 | 0x10, 0, PPC_NONE, fl2), \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x01, opc3 | 0x10, 0, PPC_NONE, fl2), \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x02, opc3 | 0x10, 0, PPC_NONE, fl2), \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2 | 0x03, opc3 | 0x10, 0, PPC_NONE, fl2)
-
-#define GEN_XX3FORM_DM(name, opc2, opc3) \
-GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
-GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x01, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
-GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x02, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
-GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x03, opc3|0x00, 0, PPC_NONE, PPC2_VSX),\
-GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x04, 0, PPC_NONE, PPC2_VSX),\
-GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x01, opc3|0x04, 0, PPC_NONE, PPC2_VSX),\
-GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x02, opc3|0x04, 0, PPC_NONE, PPC2_VSX),\
-GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x03, opc3|0x04, 0, PPC_NONE, PPC2_VSX),\
-GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x08, 0, PPC_NONE, PPC2_VSX),\
-GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x01, opc3|0x08, 0, PPC_NONE, PPC2_VSX),\
-GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x02, opc3|0x08, 0, PPC_NONE, PPC2_VSX),\
-GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x03, opc3|0x08, 0, PPC_NONE, PPC2_VSX),\
-GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x00, opc3|0x0C, 0, PPC_NONE, PPC2_VSX),\
-GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x01, opc3|0x0C, 0, PPC_NONE, PPC2_VSX),\
-GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x02, opc3|0x0C, 0, PPC_NONE, PPC2_VSX),\
-GEN_HANDLER2_E(name, #name, 0x3C, opc2|0x03, opc3|0x0C, 0, PPC_NONE, PPC2_VSX)
-
-GEN_XX2FORM(xsabsdp, 0x12, 0x15, PPC2_VSX),
-GEN_XX2FORM(xsnabsdp, 0x12, 0x16, PPC2_VSX),
-GEN_XX2FORM(xsnegdp, 0x12, 0x17, PPC2_VSX),
-GEN_XX3FORM(xscpsgndp, 0x00, 0x16, PPC2_VSX),
-
-GEN_XX2FORM(xvabsdp, 0x12, 0x1D, PPC2_VSX),
-GEN_XX2FORM(xvnabsdp, 0x12, 0x1E, PPC2_VSX),
-GEN_XX2FORM(xvnegdp, 0x12, 0x1F, PPC2_VSX),
-GEN_XX3FORM(xvcpsgndp, 0x00, 0x1E, PPC2_VSX),
-GEN_XX2FORM(xvabssp, 0x12, 0x19, PPC2_VSX),
-GEN_XX2FORM(xvnabssp, 0x12, 0x1A, PPC2_VSX),
-GEN_XX2FORM(xvnegsp, 0x12, 0x1B, PPC2_VSX),
-GEN_XX3FORM(xvcpsgnsp, 0x00, 0x1A, PPC2_VSX),
-
-GEN_XX3FORM(xsadddp, 0x00, 0x04, PPC2_VSX),
-GEN_XX3FORM(xssubdp, 0x00, 0x05, PPC2_VSX),
-GEN_XX3FORM(xsmuldp, 0x00, 0x06, PPC2_VSX),
-GEN_XX3FORM(xsdivdp, 0x00, 0x07, PPC2_VSX),
-GEN_XX2FORM(xsredp, 0x14, 0x05, PPC2_VSX),
-GEN_XX2FORM(xssqrtdp, 0x16, 0x04, PPC2_VSX),
-GEN_XX2FORM(xsrsqrtedp, 0x14, 0x04, PPC2_VSX),
-GEN_XX3FORM(xstdivdp, 0x14, 0x07, PPC2_VSX),
-GEN_XX2FORM(xstsqrtdp, 0x14, 0x06, PPC2_VSX),
-GEN_XX3FORM(xsmaddadp, 0x04, 0x04, PPC2_VSX),
-GEN_XX3FORM(xsmaddmdp, 0x04, 0x05, PPC2_VSX),
-GEN_XX3FORM(xsmsubadp, 0x04, 0x06, PPC2_VSX),
-GEN_XX3FORM(xsmsubmdp, 0x04, 0x07, PPC2_VSX),
-GEN_XX3FORM(xsnmaddadp, 0x04, 0x14, PPC2_VSX),
-GEN_XX3FORM(xsnmaddmdp, 0x04, 0x15, PPC2_VSX),
-GEN_XX3FORM(xsnmsubadp, 0x04, 0x16, PPC2_VSX),
-GEN_XX3FORM(xsnmsubmdp, 0x04, 0x17, PPC2_VSX),
-GEN_XX3FORM(xscmpeqdp, 0x0C, 0x00, PPC2_ISA300),
-GEN_XX3FORM(xscmpgtdp, 0x0C, 0x01, PPC2_ISA300),
-GEN_XX3FORM(xscmpgedp, 0x0C, 0x02, PPC2_ISA300),
-GEN_XX3FORM(xscmpnedp, 0x0C, 0x03, PPC2_ISA300),
-GEN_XX2IFORM(xscmpodp, 0x0C, 0x05, PPC2_VSX),
-GEN_XX2IFORM(xscmpudp, 0x0C, 0x04, PPC2_VSX),
-GEN_XX3FORM(xsmaxdp, 0x00, 0x14, PPC2_VSX),
-GEN_XX3FORM(xsmindp, 0x00, 0x15, PPC2_VSX),
-GEN_XX2FORM(xscvdpsp, 0x12, 0x10, PPC2_VSX),
-GEN_XX2FORM(xscvdpspn, 0x16, 0x10, PPC2_VSX207),
-GEN_XX2FORM(xscvspdp, 0x12, 0x14, PPC2_VSX),
-GEN_XX2FORM(xscvspdpn, 0x16, 0x14, PPC2_VSX207),
-GEN_XX2FORM(xscvdpsxds, 0x10, 0x15, PPC2_VSX),
-GEN_XX2FORM(xscvdpsxws, 0x10, 0x05, PPC2_VSX),
-GEN_XX2FORM(xscvdpuxds, 0x10, 0x14, PPC2_VSX),
-GEN_XX2FORM(xscvdpuxws, 0x10, 0x04, PPC2_VSX),
-GEN_XX2FORM(xscvsxddp, 0x10, 0x17, PPC2_VSX),
-GEN_XX2FORM(xscvuxddp, 0x10, 0x16, PPC2_VSX),
-GEN_XX2FORM(xsrdpi, 0x12, 0x04, PPC2_VSX),
-GEN_XX2FORM(xsrdpic, 0x16, 0x06, PPC2_VSX),
-GEN_XX2FORM(xsrdpim, 0x12, 0x07, PPC2_VSX),
-GEN_XX2FORM(xsrdpip, 0x12, 0x06, PPC2_VSX),
-GEN_XX2FORM(xsrdpiz, 0x12, 0x05, PPC2_VSX),
-
-GEN_XX3FORM(xsaddsp, 0x00, 0x00, PPC2_VSX207),
-GEN_XX3FORM(xssubsp, 0x00, 0x01, PPC2_VSX207),
-GEN_XX3FORM(xsmulsp, 0x00, 0x02, PPC2_VSX207),
-GEN_XX3FORM(xsdivsp, 0x00, 0x03, PPC2_VSX207),
-GEN_XX2FORM(xsresp, 0x14, 0x01, PPC2_VSX207),
-GEN_XX2FORM(xsrsp, 0x12, 0x11, PPC2_VSX207),
-GEN_XX2FORM(xssqrtsp, 0x16, 0x00, PPC2_VSX207),
-GEN_XX2FORM(xsrsqrtesp, 0x14, 0x00, PPC2_VSX207),
-GEN_XX3FORM(xsmaddasp, 0x04, 0x00, PPC2_VSX207),
-GEN_XX3FORM(xsmaddmsp, 0x04, 0x01, PPC2_VSX207),
-GEN_XX3FORM(xsmsubasp, 0x04, 0x02, PPC2_VSX207),
-GEN_XX3FORM(xsmsubmsp, 0x04, 0x03, PPC2_VSX207),
-GEN_XX3FORM(xsnmaddasp, 0x04, 0x10, PPC2_VSX207),
-GEN_XX3FORM(xsnmaddmsp, 0x04, 0x11, PPC2_VSX207),
-GEN_XX3FORM(xsnmsubasp, 0x04, 0x12, PPC2_VSX207),
-GEN_XX3FORM(xsnmsubmsp, 0x04, 0x13, PPC2_VSX207),
-GEN_XX2FORM(xscvsxdsp, 0x10, 0x13, PPC2_VSX207),
-GEN_XX2FORM(xscvuxdsp, 0x10, 0x12, PPC2_VSX207),
-
-GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
-GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
-GEN_XX3FORM(xvmuldp, 0x00, 0x0E, PPC2_VSX),
-GEN_XX3FORM(xvdivdp, 0x00, 0x0F, PPC2_VSX),
-GEN_XX2FORM(xvredp, 0x14, 0x0D, PPC2_VSX),
-GEN_XX2FORM(xvsqrtdp, 0x16, 0x0C, PPC2_VSX),
-GEN_XX2FORM(xvrsqrtedp, 0x14, 0x0C, PPC2_VSX),
-GEN_XX3FORM(xvtdivdp, 0x14, 0x0F, PPC2_VSX),
-GEN_XX2FORM(xvtsqrtdp, 0x14, 0x0E, PPC2_VSX),
-GEN_XX3FORM(xvmaddadp, 0x04, 0x0C, PPC2_VSX),
-GEN_XX3FORM(xvmaddmdp, 0x04, 0x0D, PPC2_VSX),
-GEN_XX3FORM(xvmsubadp, 0x04, 0x0E, PPC2_VSX),
-GEN_XX3FORM(xvmsubmdp, 0x04, 0x0F, PPC2_VSX),
-GEN_XX3FORM(xvnmaddadp, 0x04, 0x1C, PPC2_VSX),
-GEN_XX3FORM(xvnmaddmdp, 0x04, 0x1D, PPC2_VSX),
-GEN_XX3FORM(xvnmsubadp, 0x04, 0x1E, PPC2_VSX),
-GEN_XX3FORM(xvnmsubmdp, 0x04, 0x1F, PPC2_VSX),
-GEN_XX3FORM(xvmaxdp, 0x00, 0x1C, PPC2_VSX),
-GEN_XX3FORM(xvmindp, 0x00, 0x1D, PPC2_VSX),
-GEN_XX3_RC_FORM(xvcmpeqdp, 0x0C, 0x0C, PPC2_VSX),
-GEN_XX3_RC_FORM(xvcmpgtdp, 0x0C, 0x0D, PPC2_VSX),
-GEN_XX3_RC_FORM(xvcmpgedp, 0x0C, 0x0E, PPC2_VSX),
-GEN_XX3_RC_FORM(xvcmpnedp, 0x0C, 0x0F, PPC2_ISA300),
-GEN_XX2FORM(xvcvdpsp, 0x12, 0x18, PPC2_VSX),
-GEN_XX2FORM(xvcvdpsxds, 0x10, 0x1D, PPC2_VSX),
-GEN_XX2FORM(xvcvdpsxws, 0x10, 0x0D, PPC2_VSX),
-GEN_XX2FORM(xvcvdpuxds, 0x10, 0x1C, PPC2_VSX),
-GEN_XX2FORM(xvcvdpuxws, 0x10, 0x0C, PPC2_VSX),
-GEN_XX2FORM(xvcvsxddp, 0x10, 0x1F, PPC2_VSX),
-GEN_XX2FORM(xvcvuxddp, 0x10, 0x1E, PPC2_VSX),
-GEN_XX2FORM(xvcvsxwdp, 0x10, 0x0F, PPC2_VSX),
-GEN_XX2FORM(xvcvuxwdp, 0x10, 0x0E, PPC2_VSX),
-GEN_XX2FORM(xvrdpi, 0x12, 0x0C, PPC2_VSX),
-GEN_XX2FORM(xvrdpic, 0x16, 0x0E, PPC2_VSX),
-GEN_XX2FORM(xvrdpim, 0x12, 0x0F, PPC2_VSX),
-GEN_XX2FORM(xvrdpip, 0x12, 0x0E, PPC2_VSX),
-GEN_XX2FORM(xvrdpiz, 0x12, 0x0D, PPC2_VSX),
-
-GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
-GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
-GEN_XX3FORM(xvmulsp, 0x00, 0x0A, PPC2_VSX),
-GEN_XX3FORM(xvdivsp, 0x00, 0x0B, PPC2_VSX),
-GEN_XX2FORM(xvresp, 0x14, 0x09, PPC2_VSX),
-GEN_XX2FORM(xvsqrtsp, 0x16, 0x08, PPC2_VSX),
-GEN_XX2FORM(xvrsqrtesp, 0x14, 0x08, PPC2_VSX),
-GEN_XX3FORM(xvtdivsp, 0x14, 0x0B, PPC2_VSX),
-GEN_XX2FORM(xvtsqrtsp, 0x14, 0x0A, PPC2_VSX),
-GEN_XX3FORM(xvmaddasp, 0x04, 0x08, PPC2_VSX),
-GEN_XX3FORM(xvmaddmsp, 0x04, 0x09, PPC2_VSX),
-GEN_XX3FORM(xvmsubasp, 0x04, 0x0A, PPC2_VSX),
-GEN_XX3FORM(xvmsubmsp, 0x04, 0x0B, PPC2_VSX),
-GEN_XX3FORM(xvnmaddasp, 0x04, 0x18, PPC2_VSX),
-GEN_XX3FORM(xvnmaddmsp, 0x04, 0x19, PPC2_VSX),
-GEN_XX3FORM(xvnmsubasp, 0x04, 0x1A, PPC2_VSX),
-GEN_XX3FORM(xvnmsubmsp, 0x04, 0x1B, PPC2_VSX),
-GEN_XX3FORM(xvmaxsp, 0x00, 0x18, PPC2_VSX),
-GEN_XX3FORM(xvminsp, 0x00, 0x19, PPC2_VSX),
-GEN_XX3_RC_FORM(xvcmpeqsp, 0x0C, 0x08, PPC2_VSX),
-GEN_XX3_RC_FORM(xvcmpgtsp, 0x0C, 0x09, PPC2_VSX),
-GEN_XX3_RC_FORM(xvcmpgesp, 0x0C, 0x0A, PPC2_VSX),
-GEN_XX3_RC_FORM(xvcmpnesp, 0x0C, 0x0B, PPC2_ISA300),
-GEN_XX2FORM(xvcvspdp, 0x12, 0x1C, PPC2_VSX),
-GEN_XX2FORM(xvcvspsxds, 0x10, 0x19, PPC2_VSX),
-GEN_XX2FORM(xvcvspsxws, 0x10, 0x09, PPC2_VSX),
-GEN_XX2FORM(xvcvspuxds, 0x10, 0x18, PPC2_VSX),
-GEN_XX2FORM(xvcvspuxws, 0x10, 0x08, PPC2_VSX),
-GEN_XX2FORM(xvcvsxdsp, 0x10, 0x1B, PPC2_VSX),
-GEN_XX2FORM(xvcvuxdsp, 0x10, 0x1A, PPC2_VSX),
-GEN_XX2FORM(xvcvsxwsp, 0x10, 0x0B, PPC2_VSX),
-GEN_XX2FORM(xvcvuxwsp, 0x10, 0x0A, PPC2_VSX),
-GEN_XX2FORM(xvrspi, 0x12, 0x08, PPC2_VSX),
-GEN_XX2FORM(xvrspic, 0x16, 0x0A, PPC2_VSX),
-GEN_XX2FORM(xvrspim, 0x12, 0x0B, PPC2_VSX),
-GEN_XX2FORM(xvrspip, 0x12, 0x0A, PPC2_VSX),
-GEN_XX2FORM(xvrspiz, 0x12, 0x09, PPC2_VSX),
-GEN_XX2FORM_EO(xxbrh, 0x16, 0x1D, 0x07, PPC2_ISA300),
-GEN_XX2FORM_EO(xxbrw, 0x16, 0x1D, 0x0F, PPC2_ISA300),
-GEN_XX2FORM_EO(xxbrd, 0x16, 0x1D, 0x17, PPC2_ISA300),
-GEN_XX2FORM_EO(xxbrq, 0x16, 0x1D, 0x1F, PPC2_ISA300),
-
-#define VSX_LOGICAL(name, opc2, opc3, fl2) \
-GEN_XX3FORM(name, opc2, opc3, fl2)
-
-VSX_LOGICAL(xxland, 0x8, 0x10, PPC2_VSX),
-VSX_LOGICAL(xxlandc, 0x8, 0x11, PPC2_VSX),
-VSX_LOGICAL(xxlor, 0x8, 0x12, PPC2_VSX),
-VSX_LOGICAL(xxlxor, 0x8, 0x13, PPC2_VSX),
-VSX_LOGICAL(xxlnor, 0x8, 0x14, PPC2_VSX),
-VSX_LOGICAL(xxleqv, 0x8, 0x17, PPC2_VSX207),
-VSX_LOGICAL(xxlnand, 0x8, 0x16, PPC2_VSX207),
-VSX_LOGICAL(xxlorc, 0x8, 0x15, PPC2_VSX207),
-GEN_XX3FORM(xxmrghw, 0x08, 0x02, PPC2_VSX),
-GEN_XX3FORM(xxmrglw, 0x08, 0x06, PPC2_VSX),
-GEN_XX2FORM(xxspltw, 0x08, 0x0A, PPC2_VSX),
-GEN_XX1FORM(xxspltib, 0x08, 0x0B, PPC2_ISA300),
-GEN_XX3FORM_DM(xxsldwi, 0x08, 0x00),
-
-#define GEN_XXSEL_ROW(opc3) \
-GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x18, opc3, 0, PPC_NONE, PPC2_VSX), \
-GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x19, opc3, 0, PPC_NONE, PPC2_VSX), \
-GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1A, opc3, 0, PPC_NONE, PPC2_VSX), \
-GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1B, opc3, 0, PPC_NONE, PPC2_VSX), \
-GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1C, opc3, 0, PPC_NONE, PPC2_VSX), \
-GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1D, opc3, 0, PPC_NONE, PPC2_VSX), \
-GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1E, opc3, 0, PPC_NONE, PPC2_VSX), \
-GEN_HANDLER2_E(xxsel, "xxsel", 0x3C, 0x1F, opc3, 0, PPC_NONE, PPC2_VSX), \
-
-GEN_XXSEL_ROW(0x00)
-GEN_XXSEL_ROW(0x01)
-GEN_XXSEL_ROW(0x02)
-GEN_XXSEL_ROW(0x03)
-GEN_XXSEL_ROW(0x04)
-GEN_XXSEL_ROW(0x05)
-GEN_XXSEL_ROW(0x06)
-GEN_XXSEL_ROW(0x07)
-GEN_XXSEL_ROW(0x08)
-GEN_XXSEL_ROW(0x09)
-GEN_XXSEL_ROW(0x0A)
-GEN_XXSEL_ROW(0x0B)
-GEN_XXSEL_ROW(0x0C)
-GEN_XXSEL_ROW(0x0D)
-GEN_XXSEL_ROW(0x0E)
-GEN_XXSEL_ROW(0x0F)
-GEN_XXSEL_ROW(0x10)
-GEN_XXSEL_ROW(0x11)
-GEN_XXSEL_ROW(0x12)
-GEN_XXSEL_ROW(0x13)
-GEN_XXSEL_ROW(0x14)
-GEN_XXSEL_ROW(0x15)
-GEN_XXSEL_ROW(0x16)
-GEN_XXSEL_ROW(0x17)
-GEN_XXSEL_ROW(0x18)
-GEN_XXSEL_ROW(0x19)
-GEN_XXSEL_ROW(0x1A)
-GEN_XXSEL_ROW(0x1B)
-GEN_XXSEL_ROW(0x1C)
-GEN_XXSEL_ROW(0x1D)
-GEN_XXSEL_ROW(0x1E)
-GEN_XXSEL_ROW(0x1F)
-
-GEN_XX3FORM_DM(xxpermdi, 0x08, 0x01),
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
deleted file mode 100644
index 626e03186c..0000000000
--- a/target-ppc/translate_init.c
+++ /dev/null
@@ -1,10601 +0,0 @@
-/*
- * PowerPC CPU initialization for qemu.
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- * Copyright 2011 Freescale Semiconductor, Inc.
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "disas/bfd.h"
-#include "exec/gdbstub.h"
-#include "sysemu/kvm.h"
-#include "kvm_ppc.h"
-#include "sysemu/arch_init.h"
-#include "sysemu/cpus.h"
-#include "cpu-models.h"
-#include "mmu-hash32.h"
-#include "mmu-hash64.h"
-#include "qemu/error-report.h"
-#include "qapi/visitor.h"
-#include "hw/qdev-properties.h"
-#include "hw/ppc/ppc.h"
-
-//#define PPC_DUMP_CPU
-//#define PPC_DEBUG_SPR
-//#define PPC_DUMP_SPR_ACCESSES
-/* #define USE_APPLE_GDB */
-
-/* Generic callbacks:
- * do nothing but store/retrieve spr value
- */
-static void spr_load_dump_spr(int sprn)
-{
-#ifdef PPC_DUMP_SPR_ACCESSES
- TCGv_i32 t0 = tcg_const_i32(sprn);
- gen_helper_load_dump_spr(cpu_env, t0);
- tcg_temp_free_i32(t0);
-#endif
-}
-
-static void spr_read_generic (DisasContext *ctx, int gprn, int sprn)
-{
- gen_load_spr(cpu_gpr[gprn], sprn);
- spr_load_dump_spr(sprn);
-}
-
-static void spr_store_dump_spr(int sprn)
-{
-#ifdef PPC_DUMP_SPR_ACCESSES
- TCGv_i32 t0 = tcg_const_i32(sprn);
- gen_helper_store_dump_spr(cpu_env, t0);
- tcg_temp_free_i32(t0);
-#endif
-}
-
-static void spr_write_generic (DisasContext *ctx, int sprn, int gprn)
-{
- gen_store_spr(sprn, cpu_gpr[gprn]);
- spr_store_dump_spr(sprn);
-}
-
-#if !defined(CONFIG_USER_ONLY)
-static void spr_write_generic32(DisasContext *ctx, int sprn, int gprn)
-{
-#ifdef TARGET_PPC64
- TCGv t0 = tcg_temp_new();
- tcg_gen_ext32u_tl(t0, cpu_gpr[gprn]);
- gen_store_spr(sprn, t0);
- tcg_temp_free(t0);
- spr_store_dump_spr(sprn);
-#else
- spr_write_generic(ctx, sprn, gprn);
-#endif
-}
-
-static void spr_write_clear (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- gen_load_spr(t0, sprn);
- tcg_gen_neg_tl(t1, cpu_gpr[gprn]);
- tcg_gen_and_tl(t0, t0, t1);
- gen_store_spr(sprn, t0);
- tcg_temp_free(t0);
- tcg_temp_free(t1);
-}
-
-static void spr_access_nop(DisasContext *ctx, int sprn, int gprn)
-{
-}
-
-#endif
-
-/* SPR common to all PowerPC */
-/* XER */
-static void spr_read_xer (DisasContext *ctx, int gprn, int sprn)
-{
- gen_read_xer(cpu_gpr[gprn]);
-}
-
-static void spr_write_xer (DisasContext *ctx, int sprn, int gprn)
-{
- gen_write_xer(cpu_gpr[gprn]);
-}
-
-/* LR */
-static void spr_read_lr (DisasContext *ctx, int gprn, int sprn)
-{
- tcg_gen_mov_tl(cpu_gpr[gprn], cpu_lr);
-}
-
-static void spr_write_lr (DisasContext *ctx, int sprn, int gprn)
-{
- tcg_gen_mov_tl(cpu_lr, cpu_gpr[gprn]);
-}
-
-/* CFAR */
-#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
-static void spr_read_cfar (DisasContext *ctx, int gprn, int sprn)
-{
- tcg_gen_mov_tl(cpu_gpr[gprn], cpu_cfar);
-}
-
-static void spr_write_cfar (DisasContext *ctx, int sprn, int gprn)
-{
- tcg_gen_mov_tl(cpu_cfar, cpu_gpr[gprn]);
-}
-#endif /* defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) */
-
-/* CTR */
-static void spr_read_ctr (DisasContext *ctx, int gprn, int sprn)
-{
- tcg_gen_mov_tl(cpu_gpr[gprn], cpu_ctr);
-}
-
-static void spr_write_ctr (DisasContext *ctx, int sprn, int gprn)
-{
- tcg_gen_mov_tl(cpu_ctr, cpu_gpr[gprn]);
-}
-
-/* User read access to SPR */
-/* USPRx */
-/* UMMCRx */
-/* UPMCx */
-/* USIA */
-/* UDECR */
-static void spr_read_ureg (DisasContext *ctx, int gprn, int sprn)
-{
- gen_load_spr(cpu_gpr[gprn], sprn + 0x10);
-}
-
-#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
-static void spr_write_ureg(DisasContext *ctx, int sprn, int gprn)
-{
- gen_store_spr(sprn + 0x10, cpu_gpr[gprn]);
-}
-#endif
-
-/* SPR common to all non-embedded PowerPC */
-/* DECR */
-#if !defined(CONFIG_USER_ONLY)
-static void spr_read_decr (DisasContext *ctx, int gprn, int sprn)
-{
- if (ctx->tb->cflags & CF_USE_ICOUNT) {
- gen_io_start();
- }
- gen_helper_load_decr(cpu_gpr[gprn], cpu_env);
- if (ctx->tb->cflags & CF_USE_ICOUNT) {
- gen_io_end();
- gen_stop_exception(ctx);
- }
-}
-
-static void spr_write_decr (DisasContext *ctx, int sprn, int gprn)
-{
- if (ctx->tb->cflags & CF_USE_ICOUNT) {
- gen_io_start();
- }
- gen_helper_store_decr(cpu_env, cpu_gpr[gprn]);
- if (ctx->tb->cflags & CF_USE_ICOUNT) {
- gen_io_end();
- gen_stop_exception(ctx);
- }
-}
-#endif
-
-/* SPR common to all non-embedded PowerPC, except 601 */
-/* Time base */
-static void spr_read_tbl (DisasContext *ctx, int gprn, int sprn)
-{
- if (ctx->tb->cflags & CF_USE_ICOUNT) {
- gen_io_start();
- }
- gen_helper_load_tbl(cpu_gpr[gprn], cpu_env);
- if (ctx->tb->cflags & CF_USE_ICOUNT) {
- gen_io_end();
- gen_stop_exception(ctx);
- }
-}
-
-static void spr_read_tbu (DisasContext *ctx, int gprn, int sprn)
-{
- if (ctx->tb->cflags & CF_USE_ICOUNT) {
- gen_io_start();
- }
- gen_helper_load_tbu(cpu_gpr[gprn], cpu_env);
- if (ctx->tb->cflags & CF_USE_ICOUNT) {
- gen_io_end();
- gen_stop_exception(ctx);
- }
-}
-
-__attribute__ (( unused ))
-static void spr_read_atbl (DisasContext *ctx, int gprn, int sprn)
-{
- gen_helper_load_atbl(cpu_gpr[gprn], cpu_env);
-}
-
-__attribute__ (( unused ))
-static void spr_read_atbu (DisasContext *ctx, int gprn, int sprn)
-{
- gen_helper_load_atbu(cpu_gpr[gprn], cpu_env);
-}
-
-#if !defined(CONFIG_USER_ONLY)
-static void spr_write_tbl (DisasContext *ctx, int sprn, int gprn)
-{
- if (ctx->tb->cflags & CF_USE_ICOUNT) {
- gen_io_start();
- }
- gen_helper_store_tbl(cpu_env, cpu_gpr[gprn]);
- if (ctx->tb->cflags & CF_USE_ICOUNT) {
- gen_io_end();
- gen_stop_exception(ctx);
- }
-}
-
-static void spr_write_tbu (DisasContext *ctx, int sprn, int gprn)
-{
- if (ctx->tb->cflags & CF_USE_ICOUNT) {
- gen_io_start();
- }
- gen_helper_store_tbu(cpu_env, cpu_gpr[gprn]);
- if (ctx->tb->cflags & CF_USE_ICOUNT) {
- gen_io_end();
- gen_stop_exception(ctx);
- }
-}
-
-__attribute__ (( unused ))
-static void spr_write_atbl (DisasContext *ctx, int sprn, int gprn)
-{
- gen_helper_store_atbl(cpu_env, cpu_gpr[gprn]);
-}
-
-__attribute__ (( unused ))
-static void spr_write_atbu (DisasContext *ctx, int sprn, int gprn)
-{
- gen_helper_store_atbu(cpu_env, cpu_gpr[gprn]);
-}
-
-#if defined(TARGET_PPC64)
-__attribute__ (( unused ))
-static void spr_read_purr (DisasContext *ctx, int gprn, int sprn)
-{
- gen_helper_load_purr(cpu_gpr[gprn], cpu_env);
-}
-
-/* HDECR */
-static void spr_read_hdecr(DisasContext *ctx, int gprn, int sprn)
-{
- if (ctx->tb->cflags & CF_USE_ICOUNT) {
- gen_io_start();
- }
- gen_helper_load_hdecr(cpu_gpr[gprn], cpu_env);
- if (ctx->tb->cflags & CF_USE_ICOUNT) {
- gen_io_end();
- gen_stop_exception(ctx);
- }
-}
-
-static void spr_write_hdecr(DisasContext *ctx, int sprn, int gprn)
-{
- if (ctx->tb->cflags & CF_USE_ICOUNT) {
- gen_io_start();
- }
- gen_helper_store_hdecr(cpu_env, cpu_gpr[gprn]);
- if (ctx->tb->cflags & CF_USE_ICOUNT) {
- gen_io_end();
- gen_stop_exception(ctx);
- }
-}
-
-#endif
-#endif
-
-#if !defined(CONFIG_USER_ONLY)
-/* IBAT0U...IBAT0U */
-/* IBAT0L...IBAT7L */
-static void spr_read_ibat (DisasContext *ctx, int gprn, int sprn)
-{
- tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
-}
-
-static void spr_read_ibat_h (DisasContext *ctx, int gprn, int sprn)
-{
- tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, IBAT[sprn & 1][((sprn - SPR_IBAT4U) / 2) + 4]));
-}
-
-static void spr_write_ibatu (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
- gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]);
- tcg_temp_free_i32(t0);
-}
-
-static void spr_write_ibatu_h (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4U) / 2) + 4);
- gen_helper_store_ibatu(cpu_env, t0, cpu_gpr[gprn]);
- tcg_temp_free_i32(t0);
-}
-
-static void spr_write_ibatl (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0L) / 2);
- gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]);
- tcg_temp_free_i32(t0);
-}
-
-static void spr_write_ibatl_h (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_IBAT4L) / 2) + 4);
- gen_helper_store_ibatl(cpu_env, t0, cpu_gpr[gprn]);
- tcg_temp_free_i32(t0);
-}
-
-/* DBAT0U...DBAT7U */
-/* DBAT0L...DBAT7L */
-static void spr_read_dbat (DisasContext *ctx, int gprn, int sprn)
-{
- tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, DBAT[sprn & 1][(sprn - SPR_DBAT0U) / 2]));
-}
-
-static void spr_read_dbat_h (DisasContext *ctx, int gprn, int sprn)
-{
- tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, DBAT[sprn & 1][((sprn - SPR_DBAT4U) / 2) + 4]));
-}
-
-static void spr_write_dbatu (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0U) / 2);
- gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]);
- tcg_temp_free_i32(t0);
-}
-
-static void spr_write_dbatu_h (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4U) / 2) + 4);
- gen_helper_store_dbatu(cpu_env, t0, cpu_gpr[gprn]);
- tcg_temp_free_i32(t0);
-}
-
-static void spr_write_dbatl (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv_i32 t0 = tcg_const_i32((sprn - SPR_DBAT0L) / 2);
- gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]);
- tcg_temp_free_i32(t0);
-}
-
-static void spr_write_dbatl_h (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv_i32 t0 = tcg_const_i32(((sprn - SPR_DBAT4L) / 2) + 4);
- gen_helper_store_dbatl(cpu_env, t0, cpu_gpr[gprn]);
- tcg_temp_free_i32(t0);
-}
-
-/* SDR1 */
-static void spr_write_sdr1 (DisasContext *ctx, int sprn, int gprn)
-{
- gen_helper_store_sdr1(cpu_env, cpu_gpr[gprn]);
-}
-
-/* 64 bits PowerPC specific SPRs */
-#if defined(TARGET_PPC64)
-static void spr_read_hior (DisasContext *ctx, int gprn, int sprn)
-{
- tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, excp_prefix));
-}
-
-static void spr_write_hior (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv t0 = tcg_temp_new();
- tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0x3FFFFF00000ULL);
- tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_prefix));
- tcg_temp_free(t0);
-}
-#endif
-#endif
-
-/* PowerPC 601 specific registers */
-/* RTC */
-static void spr_read_601_rtcl (DisasContext *ctx, int gprn, int sprn)
-{
- gen_helper_load_601_rtcl(cpu_gpr[gprn], cpu_env);
-}
-
-static void spr_read_601_rtcu (DisasContext *ctx, int gprn, int sprn)
-{
- gen_helper_load_601_rtcu(cpu_gpr[gprn], cpu_env);
-}
-
-#if !defined(CONFIG_USER_ONLY)
-static void spr_write_601_rtcu (DisasContext *ctx, int sprn, int gprn)
-{
- gen_helper_store_601_rtcu(cpu_env, cpu_gpr[gprn]);
-}
-
-static void spr_write_601_rtcl (DisasContext *ctx, int sprn, int gprn)
-{
- gen_helper_store_601_rtcl(cpu_env, cpu_gpr[gprn]);
-}
-
-static void spr_write_hid0_601 (DisasContext *ctx, int sprn, int gprn)
-{
- gen_helper_store_hid0_601(cpu_env, cpu_gpr[gprn]);
- /* Must stop the translation as endianness may have changed */
- gen_stop_exception(ctx);
-}
-#endif
-
-/* Unified bats */
-#if !defined(CONFIG_USER_ONLY)
-static void spr_read_601_ubat (DisasContext *ctx, int gprn, int sprn)
-{
- tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, IBAT[sprn & 1][(sprn - SPR_IBAT0U) / 2]));
-}
-
-static void spr_write_601_ubatu (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
- gen_helper_store_601_batl(cpu_env, t0, cpu_gpr[gprn]);
- tcg_temp_free_i32(t0);
-}
-
-static void spr_write_601_ubatl (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv_i32 t0 = tcg_const_i32((sprn - SPR_IBAT0U) / 2);
- gen_helper_store_601_batu(cpu_env, t0, cpu_gpr[gprn]);
- tcg_temp_free_i32(t0);
-}
-#endif
-
-/* PowerPC 40x specific registers */
-#if !defined(CONFIG_USER_ONLY)
-static void spr_read_40x_pit (DisasContext *ctx, int gprn, int sprn)
-{
- gen_helper_load_40x_pit(cpu_gpr[gprn], cpu_env);
-}
-
-static void spr_write_40x_pit (DisasContext *ctx, int sprn, int gprn)
-{
- gen_helper_store_40x_pit(cpu_env, cpu_gpr[gprn]);
-}
-
-static void spr_write_40x_dbcr0 (DisasContext *ctx, int sprn, int gprn)
-{
- gen_helper_store_40x_dbcr0(cpu_env, cpu_gpr[gprn]);
- /* We must stop translation as we may have rebooted */
- gen_stop_exception(ctx);
-}
-
-static void spr_write_40x_sler (DisasContext *ctx, int sprn, int gprn)
-{
- gen_helper_store_40x_sler(cpu_env, cpu_gpr[gprn]);
-}
-
-static void spr_write_booke_tcr (DisasContext *ctx, int sprn, int gprn)
-{
- gen_helper_store_booke_tcr(cpu_env, cpu_gpr[gprn]);
-}
-
-static void spr_write_booke_tsr (DisasContext *ctx, int sprn, int gprn)
-{
- gen_helper_store_booke_tsr(cpu_env, cpu_gpr[gprn]);
-}
-#endif
-
-/* PowerPC 403 specific registers */
-/* PBL1 / PBU1 / PBL2 / PBU2 */
-#if !defined(CONFIG_USER_ONLY)
-static void spr_read_403_pbr (DisasContext *ctx, int gprn, int sprn)
-{
- tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUPPCState, pb[sprn - SPR_403_PBL1]));
-}
-
-static void spr_write_403_pbr (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv_i32 t0 = tcg_const_i32(sprn - SPR_403_PBL1);
- gen_helper_store_403_pbr(cpu_env, t0, cpu_gpr[gprn]);
- tcg_temp_free_i32(t0);
-}
-
-static void spr_write_pir (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv t0 = tcg_temp_new();
- tcg_gen_andi_tl(t0, cpu_gpr[gprn], 0xF);
- gen_store_spr(SPR_PIR, t0);
- tcg_temp_free(t0);
-}
-#endif
-
-/* SPE specific registers */
-static void spr_read_spefscr (DisasContext *ctx, int gprn, int sprn)
-{
- TCGv_i32 t0 = tcg_temp_new_i32();
- tcg_gen_ld_i32(t0, cpu_env, offsetof(CPUPPCState, spe_fscr));
- tcg_gen_extu_i32_tl(cpu_gpr[gprn], t0);
- tcg_temp_free_i32(t0);
-}
-
-static void spr_write_spefscr (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv_i32 t0 = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(t0, cpu_gpr[gprn]);
- tcg_gen_st_i32(t0, cpu_env, offsetof(CPUPPCState, spe_fscr));
- tcg_temp_free_i32(t0);
-}
-
-#if !defined(CONFIG_USER_ONLY)
-/* Callback used to write the exception vector base */
-static void spr_write_excp_prefix (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv t0 = tcg_temp_new();
- tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivpr_mask));
- tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
- tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_prefix));
- gen_store_spr(sprn, t0);
- tcg_temp_free(t0);
-}
-
-static void spr_write_excp_vector (DisasContext *ctx, int sprn, int gprn)
-{
- int sprn_offs;
-
- if (sprn >= SPR_BOOKE_IVOR0 && sprn <= SPR_BOOKE_IVOR15) {
- sprn_offs = sprn - SPR_BOOKE_IVOR0;
- } else if (sprn >= SPR_BOOKE_IVOR32 && sprn <= SPR_BOOKE_IVOR37) {
- sprn_offs = sprn - SPR_BOOKE_IVOR32 + 32;
- } else if (sprn >= SPR_BOOKE_IVOR38 && sprn <= SPR_BOOKE_IVOR42) {
- sprn_offs = sprn - SPR_BOOKE_IVOR38 + 38;
- } else {
- printf("Trying to write an unknown exception vector %d %03x\n",
- sprn, sprn);
- gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
- return;
- }
-
- TCGv t0 = tcg_temp_new();
- tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivor_mask));
- tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]);
- tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, excp_vectors[sprn_offs]));
- gen_store_spr(sprn, t0);
- tcg_temp_free(t0);
-}
-#endif
-
-static inline void vscr_init (CPUPPCState *env, uint32_t val)
-{
- env->vscr = val;
- /* Altivec always uses round-to-nearest */
- set_float_rounding_mode(float_round_nearest_even, &env->vec_status);
- set_flush_to_zero(vscr_nj, &env->vec_status);
-}
-
-#ifdef CONFIG_USER_ONLY
-#define spr_register_kvm(env, num, name, uea_read, uea_write, \
- oea_read, oea_write, one_reg_id, initial_value) \
- _spr_register(env, num, name, uea_read, uea_write, initial_value)
-#define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
- oea_read, oea_write, hea_read, hea_write, \
- one_reg_id, initial_value) \
- _spr_register(env, num, name, uea_read, uea_write, initial_value)
-#else
-#if !defined(CONFIG_KVM)
-#define spr_register_kvm(env, num, name, uea_read, uea_write, \
- oea_read, oea_write, one_reg_id, initial_value) \
- _spr_register(env, num, name, uea_read, uea_write, \
- oea_read, oea_write, oea_read, oea_write, initial_value)
-#define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
- oea_read, oea_write, hea_read, hea_write, \
- one_reg_id, initial_value) \
- _spr_register(env, num, name, uea_read, uea_write, \
- oea_read, oea_write, hea_read, hea_write, initial_value)
-#else
-#define spr_register_kvm(env, num, name, uea_read, uea_write, \
- oea_read, oea_write, one_reg_id, initial_value) \
- _spr_register(env, num, name, uea_read, uea_write, \
- oea_read, oea_write, oea_read, oea_write, \
- one_reg_id, initial_value)
-#define spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
- oea_read, oea_write, hea_read, hea_write, \
- one_reg_id, initial_value) \
- _spr_register(env, num, name, uea_read, uea_write, \
- oea_read, oea_write, hea_read, hea_write, \
- one_reg_id, initial_value)
-#endif
-#endif
-
-#define spr_register(env, num, name, uea_read, uea_write, \
- oea_read, oea_write, initial_value) \
- spr_register_kvm(env, num, name, uea_read, uea_write, \
- oea_read, oea_write, 0, initial_value)
-
-#define spr_register_hv(env, num, name, uea_read, uea_write, \
- oea_read, oea_write, hea_read, hea_write, \
- initial_value) \
- spr_register_kvm_hv(env, num, name, uea_read, uea_write, \
- oea_read, oea_write, hea_read, hea_write, \
- 0, initial_value)
-
-static inline void _spr_register(CPUPPCState *env, int num,
- const char *name,
- void (*uea_read)(DisasContext *ctx, int gprn, int sprn),
- void (*uea_write)(DisasContext *ctx, int sprn, int gprn),
-#if !defined(CONFIG_USER_ONLY)
-
- void (*oea_read)(DisasContext *ctx, int gprn, int sprn),
- void (*oea_write)(DisasContext *ctx, int sprn, int gprn),
- void (*hea_read)(DisasContext *opaque, int gprn, int sprn),
- void (*hea_write)(DisasContext *opaque, int sprn, int gprn),
-#endif
-#if defined(CONFIG_KVM)
- uint64_t one_reg_id,
-#endif
- target_ulong initial_value)
-{
- ppc_spr_t *spr;
-
- spr = &env->spr_cb[num];
- if (spr->name != NULL ||env-> spr[num] != 0x00000000 ||
-#if !defined(CONFIG_USER_ONLY)
- spr->oea_read != NULL || spr->oea_write != NULL ||
-#endif
- spr->uea_read != NULL || spr->uea_write != NULL) {
- printf("Error: Trying to register SPR %d (%03x) twice !\n", num, num);
- exit(1);
- }
-#if defined(PPC_DEBUG_SPR)
- printf("*** register spr %d (%03x) %s val " TARGET_FMT_lx "\n", num, num,
- name, initial_value);
-#endif
- spr->name = name;
- spr->uea_read = uea_read;
- spr->uea_write = uea_write;
-#if !defined(CONFIG_USER_ONLY)
- spr->oea_read = oea_read;
- spr->oea_write = oea_write;
- spr->hea_read = hea_read;
- spr->hea_write = hea_write;
-#endif
-#if defined(CONFIG_KVM)
- spr->one_reg_id = one_reg_id,
-#endif
- env->spr[num] = spr->default_value = initial_value;
-}
-
-/* Generic PowerPC SPRs */
-static void gen_spr_generic (CPUPPCState *env)
-{
- /* Integer processing */
- spr_register(env, SPR_XER, "XER",
- &spr_read_xer, &spr_write_xer,
- &spr_read_xer, &spr_write_xer,
- 0x00000000);
- /* Branch contol */
- spr_register(env, SPR_LR, "LR",
- &spr_read_lr, &spr_write_lr,
- &spr_read_lr, &spr_write_lr,
- 0x00000000);
- spr_register(env, SPR_CTR, "CTR",
- &spr_read_ctr, &spr_write_ctr,
- &spr_read_ctr, &spr_write_ctr,
- 0x00000000);
- /* Interrupt processing */
- spr_register(env, SPR_SRR0, "SRR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_SRR1, "SRR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Processor control */
- spr_register(env, SPR_SPRG0, "SPRG0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_SPRG1, "SPRG1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_SPRG2, "SPRG2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_SPRG3, "SPRG3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-/* SPR common to all non-embedded PowerPC, including 601 */
-static void gen_spr_ne_601 (CPUPPCState *env)
-{
- /* Exception processing */
- spr_register_kvm(env, SPR_DSISR, "DSISR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_DSISR, 0x00000000);
- spr_register_kvm(env, SPR_DAR, "DAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_DAR, 0x00000000);
- /* Timer */
- spr_register(env, SPR_DECR, "DECR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_decr, &spr_write_decr,
- 0x00000000);
- /* Memory management */
- spr_register(env, SPR_SDR1, "SDR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_sdr1,
- 0x00000000);
-}
-
-/* BATs 0-3 */
-static void gen_low_BATs (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- spr_register(env, SPR_IBAT0U, "IBAT0U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_ibat, &spr_write_ibatu,
- 0x00000000);
- spr_register(env, SPR_IBAT0L, "IBAT0L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_ibat, &spr_write_ibatl,
- 0x00000000);
- spr_register(env, SPR_IBAT1U, "IBAT1U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_ibat, &spr_write_ibatu,
- 0x00000000);
- spr_register(env, SPR_IBAT1L, "IBAT1L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_ibat, &spr_write_ibatl,
- 0x00000000);
- spr_register(env, SPR_IBAT2U, "IBAT2U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_ibat, &spr_write_ibatu,
- 0x00000000);
- spr_register(env, SPR_IBAT2L, "IBAT2L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_ibat, &spr_write_ibatl,
- 0x00000000);
- spr_register(env, SPR_IBAT3U, "IBAT3U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_ibat, &spr_write_ibatu,
- 0x00000000);
- spr_register(env, SPR_IBAT3L, "IBAT3L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_ibat, &spr_write_ibatl,
- 0x00000000);
- spr_register(env, SPR_DBAT0U, "DBAT0U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_dbat, &spr_write_dbatu,
- 0x00000000);
- spr_register(env, SPR_DBAT0L, "DBAT0L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_dbat, &spr_write_dbatl,
- 0x00000000);
- spr_register(env, SPR_DBAT1U, "DBAT1U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_dbat, &spr_write_dbatu,
- 0x00000000);
- spr_register(env, SPR_DBAT1L, "DBAT1L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_dbat, &spr_write_dbatl,
- 0x00000000);
- spr_register(env, SPR_DBAT2U, "DBAT2U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_dbat, &spr_write_dbatu,
- 0x00000000);
- spr_register(env, SPR_DBAT2L, "DBAT2L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_dbat, &spr_write_dbatl,
- 0x00000000);
- spr_register(env, SPR_DBAT3U, "DBAT3U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_dbat, &spr_write_dbatu,
- 0x00000000);
- spr_register(env, SPR_DBAT3L, "DBAT3L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_dbat, &spr_write_dbatl,
- 0x00000000);
- env->nb_BATs += 4;
-#endif
-}
-
-/* BATs 4-7 */
-static void gen_high_BATs (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- spr_register(env, SPR_IBAT4U, "IBAT4U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_ibat_h, &spr_write_ibatu_h,
- 0x00000000);
- spr_register(env, SPR_IBAT4L, "IBAT4L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_ibat_h, &spr_write_ibatl_h,
- 0x00000000);
- spr_register(env, SPR_IBAT5U, "IBAT5U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_ibat_h, &spr_write_ibatu_h,
- 0x00000000);
- spr_register(env, SPR_IBAT5L, "IBAT5L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_ibat_h, &spr_write_ibatl_h,
- 0x00000000);
- spr_register(env, SPR_IBAT6U, "IBAT6U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_ibat_h, &spr_write_ibatu_h,
- 0x00000000);
- spr_register(env, SPR_IBAT6L, "IBAT6L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_ibat_h, &spr_write_ibatl_h,
- 0x00000000);
- spr_register(env, SPR_IBAT7U, "IBAT7U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_ibat_h, &spr_write_ibatu_h,
- 0x00000000);
- spr_register(env, SPR_IBAT7L, "IBAT7L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_ibat_h, &spr_write_ibatl_h,
- 0x00000000);
- spr_register(env, SPR_DBAT4U, "DBAT4U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_dbat_h, &spr_write_dbatu_h,
- 0x00000000);
- spr_register(env, SPR_DBAT4L, "DBAT4L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_dbat_h, &spr_write_dbatl_h,
- 0x00000000);
- spr_register(env, SPR_DBAT5U, "DBAT5U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_dbat_h, &spr_write_dbatu_h,
- 0x00000000);
- spr_register(env, SPR_DBAT5L, "DBAT5L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_dbat_h, &spr_write_dbatl_h,
- 0x00000000);
- spr_register(env, SPR_DBAT6U, "DBAT6U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_dbat_h, &spr_write_dbatu_h,
- 0x00000000);
- spr_register(env, SPR_DBAT6L, "DBAT6L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_dbat_h, &spr_write_dbatl_h,
- 0x00000000);
- spr_register(env, SPR_DBAT7U, "DBAT7U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_dbat_h, &spr_write_dbatu_h,
- 0x00000000);
- spr_register(env, SPR_DBAT7L, "DBAT7L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_dbat_h, &spr_write_dbatl_h,
- 0x00000000);
- env->nb_BATs += 4;
-#endif
-}
-
-/* Generic PowerPC time base */
-static void gen_tbl (CPUPPCState *env)
-{
- spr_register(env, SPR_VTBL, "TBL",
- &spr_read_tbl, SPR_NOACCESS,
- &spr_read_tbl, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_TBL, "TBL",
- &spr_read_tbl, SPR_NOACCESS,
- &spr_read_tbl, &spr_write_tbl,
- 0x00000000);
- spr_register(env, SPR_VTBU, "TBU",
- &spr_read_tbu, SPR_NOACCESS,
- &spr_read_tbu, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_TBU, "TBU",
- &spr_read_tbu, SPR_NOACCESS,
- &spr_read_tbu, &spr_write_tbu,
- 0x00000000);
-}
-
-/* Softare table search registers */
-static void gen_6xx_7xx_soft_tlb (CPUPPCState *env, int nb_tlbs, int nb_ways)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = nb_tlbs;
- env->nb_ways = nb_ways;
- env->id_tlbs = 1;
- env->tlb_type = TLB_6XX;
- spr_register(env, SPR_DMISS, "DMISS",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_DCMP, "DCMP",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_HASH1, "HASH1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_HASH2, "HASH2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_IMISS, "IMISS",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_ICMP, "ICMP",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_RPA, "RPA",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-#endif
-}
-
-/* SPR common to MPC755 and G2 */
-static void gen_spr_G2_755 (CPUPPCState *env)
-{
- /* SGPRs */
- spr_register(env, SPR_SPRG4, "SPRG4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_SPRG5, "SPRG5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_SPRG6, "SPRG6",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_SPRG7, "SPRG7",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-/* SPR common to all 7xx PowerPC implementations */
-static void gen_spr_7xx (CPUPPCState *env)
-{
- /* Breakpoints */
- /* XXX : not implemented */
- spr_register_kvm(env, SPR_DABR, "DABR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_DABR, 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_IABR, "IABR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Cache management */
- /* XXX : not implemented */
- spr_register(env, SPR_ICTC, "ICTC",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Performance monitors */
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_MMCR0, "MMCR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_MMCR1, "MMCR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC1, "PMC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC2, "PMC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC3, "PMC3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC4, "PMC4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_SIAR, "SIAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UMMCR0, "UMMCR0",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UMMCR1, "UMMCR1",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UPMC1, "UPMC1",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UPMC2, "UPMC2",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UPMC3, "UPMC3",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UPMC4, "UPMC4",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_USIAR, "USIAR",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* External access control */
- /* XXX : not implemented */
- spr_register(env, SPR_EAR, "EAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-#ifdef TARGET_PPC64
-#ifndef CONFIG_USER_ONLY
-static void spr_write_amr(DisasContext *ctx, int sprn, int gprn)
-{
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- TCGv t2 = tcg_temp_new();
-
- /* Note, the HV=1 PR=0 case is handled earlier by simply using
- * spr_write_generic for HV mode in the SPR table
- */
-
- /* Build insertion mask into t1 based on context */
- if (ctx->pr) {
- gen_load_spr(t1, SPR_UAMOR);
- } else {
- gen_load_spr(t1, SPR_AMOR);
- }
-
- /* Mask new bits into t2 */
- tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
-
- /* Load AMR and clear new bits in t0 */
- gen_load_spr(t0, SPR_AMR);
- tcg_gen_andc_tl(t0, t0, t1);
-
- /* Or'in new bits and write it out */
- tcg_gen_or_tl(t0, t0, t2);
- gen_store_spr(SPR_AMR, t0);
- spr_store_dump_spr(SPR_AMR);
-
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- tcg_temp_free(t2);
-}
-
-static void spr_write_uamor(DisasContext *ctx, int sprn, int gprn)
-{
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- TCGv t2 = tcg_temp_new();
-
- /* Note, the HV=1 case is handled earlier by simply using
- * spr_write_generic for HV mode in the SPR table
- */
-
- /* Build insertion mask into t1 based on context */
- gen_load_spr(t1, SPR_AMOR);
-
- /* Mask new bits into t2 */
- tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
-
- /* Load AMR and clear new bits in t0 */
- gen_load_spr(t0, SPR_UAMOR);
- tcg_gen_andc_tl(t0, t0, t1);
-
- /* Or'in new bits and write it out */
- tcg_gen_or_tl(t0, t0, t2);
- gen_store_spr(SPR_UAMOR, t0);
- spr_store_dump_spr(SPR_UAMOR);
-
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- tcg_temp_free(t2);
-}
-
-static void spr_write_iamr(DisasContext *ctx, int sprn, int gprn)
-{
- TCGv t0 = tcg_temp_new();
- TCGv t1 = tcg_temp_new();
- TCGv t2 = tcg_temp_new();
-
- /* Note, the HV=1 case is handled earlier by simply using
- * spr_write_generic for HV mode in the SPR table
- */
-
- /* Build insertion mask into t1 based on context */
- gen_load_spr(t1, SPR_AMOR);
-
- /* Mask new bits into t2 */
- tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]);
-
- /* Load AMR and clear new bits in t0 */
- gen_load_spr(t0, SPR_IAMR);
- tcg_gen_andc_tl(t0, t0, t1);
-
- /* Or'in new bits and write it out */
- tcg_gen_or_tl(t0, t0, t2);
- gen_store_spr(SPR_IAMR, t0);
- spr_store_dump_spr(SPR_IAMR);
-
- tcg_temp_free(t0);
- tcg_temp_free(t1);
- tcg_temp_free(t2);
-}
-#endif /* CONFIG_USER_ONLY */
-
-static void gen_spr_amr(CPUPPCState *env, bool has_iamr)
-{
-#ifndef CONFIG_USER_ONLY
- /* Virtual Page Class Key protection */
- /* The AMR is accessible either via SPR 13 or SPR 29. 13 is
- * userspace accessible, 29 is privileged. So we only need to set
- * the kvm ONE_REG id on one of them, we use 29 */
- spr_register(env, SPR_UAMR, "UAMR",
- &spr_read_generic, &spr_write_amr,
- &spr_read_generic, &spr_write_amr,
- 0);
- spr_register_kvm_hv(env, SPR_AMR, "AMR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_amr,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_AMR, 0);
- spr_register_kvm_hv(env, SPR_UAMOR, "UAMOR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_uamor,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_UAMOR, 0);
- spr_register_hv(env, SPR_AMOR, "AMOR",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0);
- if (has_iamr) {
- spr_register_kvm_hv(env, SPR_IAMR, "IAMR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_iamr,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_IAMR, 0);
- }
-#endif /* !CONFIG_USER_ONLY */
-}
-#endif /* TARGET_PPC64 */
-
-#ifndef CONFIG_USER_ONLY
-static void spr_read_thrm(DisasContext *ctx, int gprn, int sprn)
-{
- gen_helper_fixup_thrm(cpu_env);
- gen_load_spr(cpu_gpr[gprn], sprn);
- spr_load_dump_spr(sprn);
-}
-#endif /* !CONFIG_USER_ONLY */
-
-static void gen_spr_thrm (CPUPPCState *env)
-{
- /* Thermal management */
- /* XXX : not implemented */
- spr_register(env, SPR_THRM1, "THRM1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_thrm, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_THRM2, "THRM2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_thrm, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_THRM3, "THRM3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_thrm, &spr_write_generic,
- 0x00000000);
-}
-
-/* SPR specific to PowerPC 604 implementation */
-static void gen_spr_604 (CPUPPCState *env)
-{
- /* Processor identification */
- spr_register(env, SPR_PIR, "PIR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_pir,
- 0x00000000);
- /* Breakpoints */
- /* XXX : not implemented */
- spr_register(env, SPR_IABR, "IABR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register_kvm(env, SPR_DABR, "DABR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_DABR, 0x00000000);
- /* Performance counters */
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_MMCR0, "MMCR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC1, "PMC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC2, "PMC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_SIAR, "SIAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_SDA, "SDA",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- /* External access control */
- /* XXX : not implemented */
- spr_register(env, SPR_EAR, "EAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-/* SPR specific to PowerPC 603 implementation */
-static void gen_spr_603 (CPUPPCState *env)
-{
- /* External access control */
- /* XXX : not implemented */
- spr_register(env, SPR_EAR, "EAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Breakpoints */
- /* XXX : not implemented */
- spr_register(env, SPR_IABR, "IABR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-
-}
-
-/* SPR specific to PowerPC G2 implementation */
-static void gen_spr_G2 (CPUPPCState *env)
-{
- /* Memory base address */
- /* MBAR */
- /* XXX : not implemented */
- spr_register(env, SPR_MBAR, "MBAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Exception processing */
- spr_register(env, SPR_BOOKE_CSRR0, "CSRR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BOOKE_CSRR1, "CSRR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Breakpoints */
- /* XXX : not implemented */
- spr_register(env, SPR_DABR, "DABR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_DABR2, "DABR2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_IABR, "IABR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_IABR2, "IABR2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_IBCR, "IBCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_DBCR, "DBCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-/* SPR specific to PowerPC 602 implementation */
-static void gen_spr_602 (CPUPPCState *env)
-{
- /* ESA registers */
- /* XXX : not implemented */
- spr_register(env, SPR_SER, "SER",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_SEBR, "SEBR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_ESASRR, "ESASRR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Floating point status */
- /* XXX : not implemented */
- spr_register(env, SPR_SP, "SP",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_LT, "LT",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Watchdog timer */
- /* XXX : not implemented */
- spr_register(env, SPR_TCR, "TCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Interrupt base */
- spr_register(env, SPR_IBR, "IBR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_IABR, "IABR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-/* SPR specific to PowerPC 601 implementation */
-static void gen_spr_601 (CPUPPCState *env)
-{
- /* Multiplication/division register */
- /* MQ */
- spr_register(env, SPR_MQ, "MQ",
- &spr_read_generic, &spr_write_generic,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* RTC registers */
- spr_register(env, SPR_601_RTCU, "RTCU",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, &spr_write_601_rtcu,
- 0x00000000);
- spr_register(env, SPR_601_VRTCU, "RTCU",
- &spr_read_601_rtcu, SPR_NOACCESS,
- &spr_read_601_rtcu, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_601_RTCL, "RTCL",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, &spr_write_601_rtcl,
- 0x00000000);
- spr_register(env, SPR_601_VRTCL, "RTCL",
- &spr_read_601_rtcl, SPR_NOACCESS,
- &spr_read_601_rtcl, SPR_NOACCESS,
- 0x00000000);
- /* Timer */
-#if 0 /* ? */
- spr_register(env, SPR_601_UDECR, "UDECR",
- &spr_read_decr, SPR_NOACCESS,
- &spr_read_decr, SPR_NOACCESS,
- 0x00000000);
-#endif
- /* External access control */
- /* XXX : not implemented */
- spr_register(env, SPR_EAR, "EAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- spr_register(env, SPR_IBAT0U, "IBAT0U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_601_ubat, &spr_write_601_ubatu,
- 0x00000000);
- spr_register(env, SPR_IBAT0L, "IBAT0L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_601_ubat, &spr_write_601_ubatl,
- 0x00000000);
- spr_register(env, SPR_IBAT1U, "IBAT1U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_601_ubat, &spr_write_601_ubatu,
- 0x00000000);
- spr_register(env, SPR_IBAT1L, "IBAT1L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_601_ubat, &spr_write_601_ubatl,
- 0x00000000);
- spr_register(env, SPR_IBAT2U, "IBAT2U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_601_ubat, &spr_write_601_ubatu,
- 0x00000000);
- spr_register(env, SPR_IBAT2L, "IBAT2L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_601_ubat, &spr_write_601_ubatl,
- 0x00000000);
- spr_register(env, SPR_IBAT3U, "IBAT3U",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_601_ubat, &spr_write_601_ubatu,
- 0x00000000);
- spr_register(env, SPR_IBAT3L, "IBAT3L",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_601_ubat, &spr_write_601_ubatl,
- 0x00000000);
- env->nb_BATs = 4;
-#endif
-}
-
-static void gen_spr_74xx (CPUPPCState *env)
-{
- /* Processor identification */
- spr_register(env, SPR_PIR, "PIR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_pir,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_74XX_MMCR2, "MMCR2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_74XX_UMMCR2, "UMMCR2",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* XXX: not implemented */
- spr_register(env, SPR_BAMR, "BAMR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MSSCR0, "MSSCR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Altivec */
- spr_register(env, SPR_VRSAVE, "VRSAVE",
- &spr_read_generic, &spr_write_generic,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_L2CR, "L2CR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, spr_access_nop,
- 0x00000000);
- /* Not strictly an SPR */
- vscr_init(env, 0x00010000);
-}
-
-static void gen_l3_ctrl (CPUPPCState *env)
-{
- /* L3CR */
- /* XXX : not implemented */
- spr_register(env, SPR_L3CR, "L3CR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* L3ITCR0 */
- /* XXX : not implemented */
- spr_register(env, SPR_L3ITCR0, "L3ITCR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* L3PM */
- /* XXX : not implemented */
- spr_register(env, SPR_L3PM, "L3PM",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-static void gen_74xx_soft_tlb (CPUPPCState *env, int nb_tlbs, int nb_ways)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = nb_tlbs;
- env->nb_ways = nb_ways;
- env->id_tlbs = 1;
- env->tlb_type = TLB_6XX;
- /* XXX : not implemented */
- spr_register(env, SPR_PTEHI, "PTEHI",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_PTELO, "PTELO",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_TLBMISS, "TLBMISS",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-#endif
-}
-
-#if !defined(CONFIG_USER_ONLY)
-static void spr_write_e500_l1csr0 (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv t0 = tcg_temp_new();
-
- tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR0_DCE | L1CSR0_CPE);
- gen_store_spr(sprn, t0);
- tcg_temp_free(t0);
-}
-
-static void spr_write_e500_l1csr1(DisasContext *ctx, int sprn, int gprn)
-{
- TCGv t0 = tcg_temp_new();
-
- tcg_gen_andi_tl(t0, cpu_gpr[gprn], L1CSR1_ICE | L1CSR1_CPE);
- gen_store_spr(sprn, t0);
- tcg_temp_free(t0);
-}
-
-static void spr_write_booke206_mmucsr0 (DisasContext *ctx, int sprn, int gprn)
-{
- gen_helper_booke206_tlbflush(cpu_env, cpu_gpr[gprn]);
-}
-
-static void spr_write_booke_pid (DisasContext *ctx, int sprn, int gprn)
-{
- TCGv_i32 t0 = tcg_const_i32(sprn);
- gen_helper_booke_setpid(cpu_env, t0, cpu_gpr[gprn]);
- tcg_temp_free_i32(t0);
-}
-#endif
-
-static void gen_spr_usprgh (CPUPPCState *env)
-{
- spr_register(env, SPR_USPRG4, "USPRG4",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_USPRG5, "USPRG5",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_USPRG6, "USPRG6",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_USPRG7, "USPRG7",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
-}
-
-/* PowerPC BookE SPR */
-static void gen_spr_BookE (CPUPPCState *env, uint64_t ivor_mask)
-{
- const char *ivor_names[64] = {
- "IVOR0", "IVOR1", "IVOR2", "IVOR3",
- "IVOR4", "IVOR5", "IVOR6", "IVOR7",
- "IVOR8", "IVOR9", "IVOR10", "IVOR11",
- "IVOR12", "IVOR13", "IVOR14", "IVOR15",
- "IVOR16", "IVOR17", "IVOR18", "IVOR19",
- "IVOR20", "IVOR21", "IVOR22", "IVOR23",
- "IVOR24", "IVOR25", "IVOR26", "IVOR27",
- "IVOR28", "IVOR29", "IVOR30", "IVOR31",
- "IVOR32", "IVOR33", "IVOR34", "IVOR35",
- "IVOR36", "IVOR37", "IVOR38", "IVOR39",
- "IVOR40", "IVOR41", "IVOR42", "IVOR43",
- "IVOR44", "IVOR45", "IVOR46", "IVOR47",
- "IVOR48", "IVOR49", "IVOR50", "IVOR51",
- "IVOR52", "IVOR53", "IVOR54", "IVOR55",
- "IVOR56", "IVOR57", "IVOR58", "IVOR59",
- "IVOR60", "IVOR61", "IVOR62", "IVOR63",
- };
-#define SPR_BOOKE_IVORxx (-1)
- int ivor_sprn[64] = {
- SPR_BOOKE_IVOR0, SPR_BOOKE_IVOR1, SPR_BOOKE_IVOR2, SPR_BOOKE_IVOR3,
- SPR_BOOKE_IVOR4, SPR_BOOKE_IVOR5, SPR_BOOKE_IVOR6, SPR_BOOKE_IVOR7,
- SPR_BOOKE_IVOR8, SPR_BOOKE_IVOR9, SPR_BOOKE_IVOR10, SPR_BOOKE_IVOR11,
- SPR_BOOKE_IVOR12, SPR_BOOKE_IVOR13, SPR_BOOKE_IVOR14, SPR_BOOKE_IVOR15,
- SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
- SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
- SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
- SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
- SPR_BOOKE_IVOR32, SPR_BOOKE_IVOR33, SPR_BOOKE_IVOR34, SPR_BOOKE_IVOR35,
- SPR_BOOKE_IVOR36, SPR_BOOKE_IVOR37, SPR_BOOKE_IVOR38, SPR_BOOKE_IVOR39,
- SPR_BOOKE_IVOR40, SPR_BOOKE_IVOR41, SPR_BOOKE_IVOR42, SPR_BOOKE_IVORxx,
- SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
- SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
- SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
- SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
- SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx, SPR_BOOKE_IVORxx,
- };
- int i;
-
- /* Interrupt processing */
- spr_register(env, SPR_BOOKE_CSRR0, "CSRR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BOOKE_CSRR1, "CSRR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Debug */
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_IAC1, "IAC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_IAC2, "IAC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DAC1, "DAC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DAC2, "DAC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DBCR0, "DBCR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_40x_dbcr0,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DBCR1, "DBCR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DBCR2, "DBCR2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DBSR, "DBSR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_clear,
- 0x00000000);
- spr_register(env, SPR_BOOKE_DEAR, "DEAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BOOKE_ESR, "ESR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BOOKE_IVPR, "IVPR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_excp_prefix,
- 0x00000000);
- /* Exception vectors */
- for (i = 0; i < 64; i++) {
- if (ivor_mask & (1ULL << i)) {
- if (ivor_sprn[i] == SPR_BOOKE_IVORxx) {
- fprintf(stderr, "ERROR: IVOR %d SPR is not defined\n", i);
- exit(1);
- }
- spr_register(env, ivor_sprn[i], ivor_names[i],
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_excp_vector,
- 0x00000000);
- }
- }
- spr_register(env, SPR_BOOKE_PID, "PID",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_booke_pid,
- 0x00000000);
- spr_register(env, SPR_BOOKE_TCR, "TCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_booke_tcr,
- 0x00000000);
- spr_register(env, SPR_BOOKE_TSR, "TSR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_booke_tsr,
- 0x00000000);
- /* Timer */
- spr_register(env, SPR_DECR, "DECR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_decr, &spr_write_decr,
- 0x00000000);
- spr_register(env, SPR_BOOKE_DECAR, "DECAR",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, &spr_write_generic,
- 0x00000000);
- /* SPRGs */
- spr_register(env, SPR_USPRG0, "USPRG0",
- &spr_read_generic, &spr_write_generic,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_SPRG4, "SPRG4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_SPRG5, "SPRG5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_SPRG6, "SPRG6",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_SPRG7, "SPRG7",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-static inline uint32_t gen_tlbncfg(uint32_t assoc, uint32_t minsize,
- uint32_t maxsize, uint32_t flags,
- uint32_t nentries)
-{
- return (assoc << TLBnCFG_ASSOC_SHIFT) |
- (minsize << TLBnCFG_MINSIZE_SHIFT) |
- (maxsize << TLBnCFG_MAXSIZE_SHIFT) |
- flags | nentries;
-}
-
-/* BookE 2.06 storage control registers */
-static void gen_spr_BookE206(CPUPPCState *env, uint32_t mas_mask,
- uint32_t *tlbncfg)
-{
-#if !defined(CONFIG_USER_ONLY)
- const char *mas_names[8] = {
- "MAS0", "MAS1", "MAS2", "MAS3", "MAS4", "MAS5", "MAS6", "MAS7",
- };
- int mas_sprn[8] = {
- SPR_BOOKE_MAS0, SPR_BOOKE_MAS1, SPR_BOOKE_MAS2, SPR_BOOKE_MAS3,
- SPR_BOOKE_MAS4, SPR_BOOKE_MAS5, SPR_BOOKE_MAS6, SPR_BOOKE_MAS7,
- };
- int i;
-
- /* TLB assist registers */
- /* XXX : not implemented */
- for (i = 0; i < 8; i++) {
- void (*uea_write)(DisasContext *ctx, int sprn, int gprn) = &spr_write_generic32;
- if (i == 2 && (mas_mask & (1 << i)) && (env->insns_flags & PPC_64B)) {
- uea_write = &spr_write_generic;
- }
- if (mas_mask & (1 << i)) {
- spr_register(env, mas_sprn[i], mas_names[i],
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, uea_write,
- 0x00000000);
- }
- }
- if (env->nb_pids > 1) {
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_PID1, "PID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_booke_pid,
- 0x00000000);
- }
- if (env->nb_pids > 2) {
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_PID2, "PID2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_booke_pid,
- 0x00000000);
- }
- /* XXX : not implemented */
- spr_register(env, SPR_MMUCFG, "MMUCFG",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000); /* TOFIX */
- switch (env->nb_ways) {
- case 4:
- spr_register(env, SPR_BOOKE_TLB3CFG, "TLB3CFG",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- tlbncfg[3]);
- /* Fallthru */
- case 3:
- spr_register(env, SPR_BOOKE_TLB2CFG, "TLB2CFG",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- tlbncfg[2]);
- /* Fallthru */
- case 2:
- spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- tlbncfg[1]);
- /* Fallthru */
- case 1:
- spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- tlbncfg[0]);
- /* Fallthru */
- case 0:
- default:
- break;
- }
-#endif
-
- gen_spr_usprgh(env);
-}
-
-/* SPR specific to PowerPC 440 implementation */
-static void gen_spr_440 (CPUPPCState *env)
-{
- /* Cache control */
- /* XXX : not implemented */
- spr_register(env, SPR_440_DNV0, "DNV0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_DNV1, "DNV1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_DNV2, "DNV2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_DNV3, "DNV3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_DTV0, "DTV0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_DTV1, "DTV1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_DTV2, "DTV2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_DTV3, "DTV3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_DVLIM, "DVLIM",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_INV0, "INV0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_INV1, "INV1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_INV2, "INV2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_INV3, "INV3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_ITV0, "ITV0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_ITV1, "ITV1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_ITV2, "ITV2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_ITV3, "ITV3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_IVLIM, "IVLIM",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Cache debug */
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DCDBTRH, "DCDBTRH",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DCDBTRL, "DCDBTRL",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_ICDBTRH, "ICDBTRH",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_ICDBTRL, "ICDBTRL",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_DBDR, "DBDR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Processor control */
- spr_register(env, SPR_4xx_CCR0, "CCR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_440_RSTCFG, "RSTCFG",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- /* Storage control */
- spr_register(env, SPR_440_MMUCR, "MMUCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-/* SPR shared between PowerPC 40x implementations */
-static void gen_spr_40x (CPUPPCState *env)
-{
- /* Cache */
- /* not emulated, as QEMU do not emulate caches */
- spr_register(env, SPR_40x_DCCR, "DCCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* not emulated, as QEMU do not emulate caches */
- spr_register(env, SPR_40x_ICCR, "ICCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* not emulated, as QEMU do not emulate caches */
- spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- /* Exception */
- spr_register(env, SPR_40x_DEAR, "DEAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_40x_ESR, "ESR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_40x_EVPR, "EVPR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_excp_prefix,
- 0x00000000);
- spr_register(env, SPR_40x_SRR2, "SRR2",
- &spr_read_generic, &spr_write_generic,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_40x_SRR3, "SRR3",
- &spr_read_generic, &spr_write_generic,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Timers */
- spr_register(env, SPR_40x_PIT, "PIT",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_40x_pit, &spr_write_40x_pit,
- 0x00000000);
- spr_register(env, SPR_40x_TCR, "TCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_booke_tcr,
- 0x00000000);
- spr_register(env, SPR_40x_TSR, "TSR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_booke_tsr,
- 0x00000000);
-}
-
-/* SPR specific to PowerPC 405 implementation */
-static void gen_spr_405 (CPUPPCState *env)
-{
- /* MMU */
- spr_register(env, SPR_40x_PID, "PID",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_4xx_CCR0, "CCR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00700000);
- /* Debug interface */
- /* XXX : not implemented */
- spr_register(env, SPR_40x_DBCR0, "DBCR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_40x_dbcr0,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_405_DBCR1, "DBCR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_40x_DBSR, "DBSR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_clear,
- /* Last reset was system reset */
- 0x00000300);
- /* XXX : not implemented */
- spr_register(env, SPR_40x_DAC1, "DAC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_40x_DAC2, "DAC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_405_DVC1, "DVC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_405_DVC2, "DVC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_40x_IAC1, "IAC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_40x_IAC2, "IAC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_405_IAC3, "IAC3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_405_IAC4, "IAC4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Storage control */
- /* XXX: TODO: not implemented */
- spr_register(env, SPR_405_SLER, "SLER",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_40x_sler,
- 0x00000000);
- spr_register(env, SPR_40x_ZPR, "ZPR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_405_SU0R, "SU0R",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* SPRG */
- spr_register(env, SPR_USPRG0, "USPRG0",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_SPRG4, "SPRG4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_SPRG5, "SPRG5",
- SPR_NOACCESS, SPR_NOACCESS,
- spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_SPRG6, "SPRG6",
- SPR_NOACCESS, SPR_NOACCESS,
- spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_SPRG7, "SPRG7",
- SPR_NOACCESS, SPR_NOACCESS,
- spr_read_generic, &spr_write_generic,
- 0x00000000);
- gen_spr_usprgh(env);
-}
-
-/* SPR shared between PowerPC 401 & 403 implementations */
-static void gen_spr_401_403 (CPUPPCState *env)
-{
- /* Time base */
- spr_register(env, SPR_403_VTBL, "TBL",
- &spr_read_tbl, SPR_NOACCESS,
- &spr_read_tbl, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_403_TBL, "TBL",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, &spr_write_tbl,
- 0x00000000);
- spr_register(env, SPR_403_VTBU, "TBU",
- &spr_read_tbu, SPR_NOACCESS,
- &spr_read_tbu, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_403_TBU, "TBU",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, &spr_write_tbu,
- 0x00000000);
- /* Debug */
- /* not emulated, as QEMU do not emulate caches */
- spr_register(env, SPR_403_CDBCR, "CDBCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-/* SPR specific to PowerPC 401 implementation */
-static void gen_spr_401 (CPUPPCState *env)
-{
- /* Debug interface */
- /* XXX : not implemented */
- spr_register(env, SPR_40x_DBCR0, "DBCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_40x_dbcr0,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_40x_DBSR, "DBSR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_clear,
- /* Last reset was system reset */
- 0x00000300);
- /* XXX : not implemented */
- spr_register(env, SPR_40x_DAC1, "DAC",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_40x_IAC1, "IAC",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Storage control */
- /* XXX: TODO: not implemented */
- spr_register(env, SPR_405_SLER, "SLER",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_40x_sler,
- 0x00000000);
- /* not emulated, as QEMU never does speculative access */
- spr_register(env, SPR_40x_SGR, "SGR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0xFFFFFFFF);
- /* not emulated, as QEMU do not emulate caches */
- spr_register(env, SPR_40x_DCWR, "DCWR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-static void gen_spr_401x2 (CPUPPCState *env)
-{
- gen_spr_401(env);
- spr_register(env, SPR_40x_PID, "PID",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_40x_ZPR, "ZPR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-/* SPR specific to PowerPC 403 implementation */
-static void gen_spr_403 (CPUPPCState *env)
-{
- /* Debug interface */
- /* XXX : not implemented */
- spr_register(env, SPR_40x_DBCR0, "DBCR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_40x_dbcr0,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_40x_DBSR, "DBSR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_clear,
- /* Last reset was system reset */
- 0x00000300);
- /* XXX : not implemented */
- spr_register(env, SPR_40x_DAC1, "DAC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_40x_DAC2, "DAC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_40x_IAC1, "IAC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_40x_IAC2, "IAC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-static void gen_spr_403_real (CPUPPCState *env)
-{
- spr_register(env, SPR_403_PBL1, "PBL1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_403_pbr, &spr_write_403_pbr,
- 0x00000000);
- spr_register(env, SPR_403_PBU1, "PBU1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_403_pbr, &spr_write_403_pbr,
- 0x00000000);
- spr_register(env, SPR_403_PBL2, "PBL2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_403_pbr, &spr_write_403_pbr,
- 0x00000000);
- spr_register(env, SPR_403_PBU2, "PBU2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_403_pbr, &spr_write_403_pbr,
- 0x00000000);
-}
-
-static void gen_spr_403_mmu (CPUPPCState *env)
-{
- /* MMU */
- spr_register(env, SPR_40x_PID, "PID",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_40x_ZPR, "ZPR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-/* SPR specific to PowerPC compression coprocessor extension */
-static void gen_spr_compress (CPUPPCState *env)
-{
- /* XXX : not implemented */
- spr_register(env, SPR_401_SKR, "SKR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-static void gen_spr_5xx_8xx (CPUPPCState *env)
-{
- /* Exception processing */
- spr_register_kvm(env, SPR_DSISR, "DSISR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_DSISR, 0x00000000);
- spr_register_kvm(env, SPR_DAR, "DAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_DAR, 0x00000000);
- /* Timer */
- spr_register(env, SPR_DECR, "DECR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_decr, &spr_write_decr,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_EIE, "EIE",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_EID, "EID",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_NRI, "NRI",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_CMPA, "CMPA",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_CMPB, "CMPB",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_CMPC, "CMPC",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_CMPD, "CMPD",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_ECR, "ECR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_DER, "DER",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_COUNTA, "COUNTA",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_COUNTB, "COUNTB",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_CMPE, "CMPE",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_CMPF, "CMPF",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_CMPG, "CMPG",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_CMPH, "CMPH",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_LCTRL1, "LCTRL1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_LCTRL2, "LCTRL2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_BAR, "BAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_DPDR, "DPDR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_IMMR, "IMMR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-static void gen_spr_5xx (CPUPPCState *env)
-{
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_MI_GRA, "MI_GRA",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_L2U_GRA, "L2U_GRA",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RPCU_BBCMCR, "L2U_BBCMCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_L2U_MCR, "L2U_MCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_MI_RBA0, "MI_RBA0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_MI_RBA1, "MI_RBA1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_MI_RBA2, "MI_RBA2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_MI_RBA3, "MI_RBA3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_L2U_RBA0, "L2U_RBA0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_L2U_RBA1, "L2U_RBA1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_L2U_RBA2, "L2U_RBA2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_L2U_RBA3, "L2U_RBA3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_MI_RA0, "MI_RA0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_MI_RA1, "MI_RA1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_MI_RA2, "MI_RA2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_MI_RA3, "MI_RA3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_L2U_RA0, "L2U_RA0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_L2U_RA1, "L2U_RA1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_L2U_RA2, "L2U_RA2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_L2U_RA3, "L2U_RA3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_RCPU_FPECR, "FPECR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-static void gen_spr_8xx (CPUPPCState *env)
-{
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_IC_CST, "IC_CST",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_IC_ADR, "IC_ADR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_IC_DAT, "IC_DAT",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_DC_CST, "DC_CST",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_DC_ADR, "DC_ADR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_DC_DAT, "DC_DAT",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MI_CTR, "MI_CTR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MI_AP, "MI_AP",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MI_EPN, "MI_EPN",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MI_TWC, "MI_TWC",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MI_RPN, "MI_RPN",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MI_DBCAM, "MI_DBCAM",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MI_DBRAM0, "MI_DBRAM0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MI_DBRAM1, "MI_DBRAM1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MD_CTR, "MD_CTR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MD_CASID, "MD_CASID",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MD_AP, "MD_AP",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MD_EPN, "MD_EPN",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MD_TWB, "MD_TWB",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MD_TWC, "MD_TWC",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MD_RPN, "MD_RPN",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MD_TW, "MD_TW",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MD_DBCAM, "MD_DBCAM",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MD_DBRAM0, "MD_DBRAM0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MPC_MD_DBRAM1, "MD_DBRAM1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-// XXX: TODO
-/*
- * AMR => SPR 29 (Power 2.04)
- * CTRL => SPR 136 (Power 2.04)
- * CTRL => SPR 152 (Power 2.04)
- * SCOMC => SPR 276 (64 bits ?)
- * SCOMD => SPR 277 (64 bits ?)
- * TBU40 => SPR 286 (Power 2.04 hypv)
- * HSPRG0 => SPR 304 (Power 2.04 hypv)
- * HSPRG1 => SPR 305 (Power 2.04 hypv)
- * HDSISR => SPR 306 (Power 2.04 hypv)
- * HDAR => SPR 307 (Power 2.04 hypv)
- * PURR => SPR 309 (Power 2.04 hypv)
- * HDEC => SPR 310 (Power 2.04 hypv)
- * HIOR => SPR 311 (hypv)
- * RMOR => SPR 312 (970)
- * HRMOR => SPR 313 (Power 2.04 hypv)
- * HSRR0 => SPR 314 (Power 2.04 hypv)
- * HSRR1 => SPR 315 (Power 2.04 hypv)
- * LPIDR => SPR 317 (970)
- * EPR => SPR 702 (Power 2.04 emb)
- * perf => 768-783 (Power 2.04)
- * perf => 784-799 (Power 2.04)
- * PPR => SPR 896 (Power 2.04)
- * EPLC => SPR 947 (Power 2.04 emb)
- * EPSC => SPR 948 (Power 2.04 emb)
- * DABRX => 1015 (Power 2.04 hypv)
- * FPECR => SPR 1022 (?)
- * ... and more (thermal management, performance counters, ...)
- */
-
-/*****************************************************************************/
-/* Exception vectors models */
-static void init_excp_4xx_real (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000;
- env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
- env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
- env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
- env->ivor_mask = 0x0000FFF0UL;
- env->ivpr_mask = 0xFFFF0000UL;
- /* Hardware reset vector */
- env->hreset_vector = 0xFFFFFFFCUL;
-#endif
-}
-
-static void init_excp_4xx_softmmu (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_PIT] = 0x00001000;
- env->excp_vectors[POWERPC_EXCP_FIT] = 0x00001010;
- env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001020;
- env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001100;
- env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001200;
- env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00002000;
- env->ivor_mask = 0x0000FFF0UL;
- env->ivpr_mask = 0xFFFF0000UL;
- /* Hardware reset vector */
- env->hreset_vector = 0xFFFFFFFCUL;
-#endif
-}
-
-static void init_excp_MPC5xx (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
- env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00;
- env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000;
- env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00;
- env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00;
- env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00;
- env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00;
- env->ivor_mask = 0x0000FFF0UL;
- env->ivpr_mask = 0xFFFF0000UL;
- /* Hardware reset vector */
- env->hreset_vector = 0x00000100UL;
-#endif
-}
-
-static void init_excp_MPC8xx (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
- env->excp_vectors[POWERPC_EXCP_FPA] = 0x00000E00;
- env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001000;
- env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00001100;
- env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00001200;
- env->excp_vectors[POWERPC_EXCP_ITLBE] = 0x00001300;
- env->excp_vectors[POWERPC_EXCP_DTLBE] = 0x00001400;
- env->excp_vectors[POWERPC_EXCP_DABR] = 0x00001C00;
- env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001C00;
- env->excp_vectors[POWERPC_EXCP_MEXTBR] = 0x00001E00;
- env->excp_vectors[POWERPC_EXCP_NMEXTBR] = 0x00001F00;
- env->ivor_mask = 0x0000FFF0UL;
- env->ivpr_mask = 0xFFFF0000UL;
- /* Hardware reset vector */
- env->hreset_vector = 0x00000100UL;
-#endif
-}
-
-static void init_excp_G2 (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000A00;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
- env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
- env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
- env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
- env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
- env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
- /* Hardware reset vector */
- env->hreset_vector = 0x00000100UL;
-#endif
-}
-
-static void init_excp_e200(CPUPPCState *env, target_ulong ivpr_mask)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000FFC;
- env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_SPEU] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_EFPDI] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_EFPRI] = 0x00000000;
- env->ivor_mask = 0x0000FFF7UL;
- env->ivpr_mask = ivpr_mask;
- /* Hardware reset vector */
- env->hreset_vector = 0xFFFFFFFCUL;
-#endif
-}
-
-static void init_excp_BookE (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_APU] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_DTLB] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_ITLB] = 0x00000000;
- env->excp_vectors[POWERPC_EXCP_DEBUG] = 0x00000000;
- env->ivor_mask = 0x0000FFF0UL;
- env->ivpr_mask = 0xFFFF0000UL;
- /* Hardware reset vector */
- env->hreset_vector = 0xFFFFFFFCUL;
-#endif
-}
-
-static void init_excp_601 (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_IO] = 0x00000A00;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_RUNM] = 0x00002000;
- /* Hardware reset vector */
- env->hreset_vector = 0x00000100UL;
-#endif
-}
-
-static void init_excp_602 (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- /* XXX: exception prefix has a special behavior on 602 */
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
- env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
- env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
- env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
- env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
- env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
- env->excp_vectors[POWERPC_EXCP_WDT] = 0x00001500;
- env->excp_vectors[POWERPC_EXCP_EMUL] = 0x00001600;
- /* Hardware reset vector */
- env->hreset_vector = 0x00000100UL;
-#endif
-}
-
-static void init_excp_603 (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
- env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
- env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
- env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
- env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
- env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
- /* Hardware reset vector */
- env->hreset_vector = 0x00000100UL;
-#endif
-}
-
-static void init_excp_604 (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
- env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
- env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
- env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
- /* Hardware reset vector */
- env->hreset_vector = 0x00000100UL;
-#endif
-}
-
-static void init_excp_7x0 (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
- env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
- env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
- env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
- env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
- /* Hardware reset vector */
- env->hreset_vector = 0x00000100UL;
-#endif
-}
-
-static void init_excp_750cl (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
- env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
- env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
- env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
- /* Hardware reset vector */
- env->hreset_vector = 0x00000100UL;
-#endif
-}
-
-static void init_excp_750cx (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
- env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
- env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
- env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
- /* Hardware reset vector */
- env->hreset_vector = 0x00000100UL;
-#endif
-}
-
-/* XXX: Check if this is correct */
-static void init_excp_7x5 (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
- env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
- env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
- env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
- env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
- env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
- env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
- env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
- /* Hardware reset vector */
- env->hreset_vector = 0x00000100UL;
-#endif
-}
-
-static void init_excp_7400 (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
- env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
- env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
- env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
- env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
- env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
- env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001700;
- /* Hardware reset vector */
- env->hreset_vector = 0x00000100UL;
-#endif
-}
-
-static void init_excp_7450 (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
- env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
- env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
- env->excp_vectors[POWERPC_EXCP_IFTLB] = 0x00001000;
- env->excp_vectors[POWERPC_EXCP_DLTLB] = 0x00001100;
- env->excp_vectors[POWERPC_EXCP_DSTLB] = 0x00001200;
- env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
- env->excp_vectors[POWERPC_EXCP_SMI] = 0x00001400;
- env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001600;
- /* Hardware reset vector */
- env->hreset_vector = 0x00000100UL;
-#endif
-}
-
-#if defined (TARGET_PPC64)
-static void init_excp_970 (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
- env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
- env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
- env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
- env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
- env->excp_vectors[POWERPC_EXCP_IABR] = 0x00001300;
- env->excp_vectors[POWERPC_EXCP_MAINT] = 0x00001600;
- env->excp_vectors[POWERPC_EXCP_VPUA] = 0x00001700;
- env->excp_vectors[POWERPC_EXCP_THERM] = 0x00001800;
- /* Hardware reset vector */
- env->hreset_vector = 0x0000000000000100ULL;
-#endif
-}
-
-static void init_excp_POWER7 (CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000100;
- env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000200;
- env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000300;
- env->excp_vectors[POWERPC_EXCP_DSEG] = 0x00000380;
- env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000400;
- env->excp_vectors[POWERPC_EXCP_ISEG] = 0x00000480;
- env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;
- env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x00000600;
- env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x00000700;
- env->excp_vectors[POWERPC_EXCP_FPU] = 0x00000800;
- env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000900;
- env->excp_vectors[POWERPC_EXCP_HDECR] = 0x00000980;
- env->excp_vectors[POWERPC_EXCP_SYSCALL] = 0x00000C00;
- env->excp_vectors[POWERPC_EXCP_TRACE] = 0x00000D00;
- env->excp_vectors[POWERPC_EXCP_HDSI] = 0x00000E00;
- env->excp_vectors[POWERPC_EXCP_HISI] = 0x00000E20;
- env->excp_vectors[POWERPC_EXCP_HV_EMU] = 0x00000E40;
- env->excp_vectors[POWERPC_EXCP_HV_MAINT] = 0x00000E60;
- env->excp_vectors[POWERPC_EXCP_PERFM] = 0x00000F00;
- env->excp_vectors[POWERPC_EXCP_VPU] = 0x00000F20;
- env->excp_vectors[POWERPC_EXCP_VSXU] = 0x00000F40;
- /* Hardware reset vector */
- env->hreset_vector = 0x0000000000000100ULL;
-#endif
-}
-
-static void init_excp_POWER8(CPUPPCState *env)
-{
- init_excp_POWER7(env);
-
-#if !defined(CONFIG_USER_ONLY)
- env->excp_vectors[POWERPC_EXCP_SDOOR] = 0x00000A00;
- env->excp_vectors[POWERPC_EXCP_FU] = 0x00000F60;
- env->excp_vectors[POWERPC_EXCP_HV_FU] = 0x00000F80;
- env->excp_vectors[POWERPC_EXCP_SDOOR_HV] = 0x00000E80;
-#endif
-}
-
-#endif
-
-/*****************************************************************************/
-/* Power management enable checks */
-static int check_pow_none (CPUPPCState *env)
-{
- return 0;
-}
-
-static int check_pow_nocheck (CPUPPCState *env)
-{
- return 1;
-}
-
-static int check_pow_hid0 (CPUPPCState *env)
-{
- if (env->spr[SPR_HID0] & 0x00E00000)
- return 1;
-
- return 0;
-}
-
-static int check_pow_hid0_74xx (CPUPPCState *env)
-{
- if (env->spr[SPR_HID0] & 0x00600000)
- return 1;
-
- return 0;
-}
-
-static bool ppc_cpu_interrupts_big_endian_always(PowerPCCPU *cpu)
-{
- return true;
-}
-
-#ifdef TARGET_PPC64
-static bool ppc_cpu_interrupts_big_endian_lpcr(PowerPCCPU *cpu)
-{
- return !(cpu->env.spr[SPR_LPCR] & LPCR_ILE);
-}
-#endif
-
-/*****************************************************************************/
-/* PowerPC implementations definitions */
-
-#define POWERPC_FAMILY(_name) \
- static void \
- glue(glue(ppc_, _name), _cpu_family_class_init)(ObjectClass *, void *); \
- \
- static const TypeInfo \
- glue(glue(ppc_, _name), _cpu_family_type_info) = { \
- .name = stringify(_name) "-family-" TYPE_POWERPC_CPU, \
- .parent = TYPE_POWERPC_CPU, \
- .abstract = true, \
- .class_init = glue(glue(ppc_, _name), _cpu_family_class_init), \
- }; \
- \
- static void glue(glue(ppc_, _name), _cpu_family_register_types)(void) \
- { \
- type_register_static( \
- &glue(glue(ppc_, _name), _cpu_family_type_info)); \
- } \
- \
- type_init(glue(glue(ppc_, _name), _cpu_family_register_types)) \
- \
- static void glue(glue(ppc_, _name), _cpu_family_class_init)
-
-static void init_proc_401 (CPUPPCState *env)
-{
- gen_spr_40x(env);
- gen_spr_401_403(env);
- gen_spr_401(env);
- init_excp_4xx_real(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc40x_irq_init(ppc_env_get_cpu(env));
-
- SET_FIT_PERIOD(12, 16, 20, 24);
- SET_WDT_PERIOD(16, 20, 24, 28);
-}
-
-POWERPC_FAMILY(401)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 401";
- pcc->init_proc = init_proc_401;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
- PPC_WRTEE | PPC_DCR |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
- PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_4xx_COMMON | PPC_40x_EXCP;
- pcc->msr_mask = (1ull << MSR_KEY) |
- (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_ME) |
- (1ull << MSR_DE) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_REAL;
- pcc->excp_model = POWERPC_EXCP_40x;
- pcc->bus_model = PPC_FLAGS_INPUT_401;
- pcc->bfd_mach = bfd_mach_ppc_403;
- pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_401x2 (CPUPPCState *env)
-{
- gen_spr_40x(env);
- gen_spr_401_403(env);
- gen_spr_401x2(env);
- gen_spr_compress(env);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->id_tlbs = 0;
- env->tlb_type = TLB_EMB;
-#endif
- init_excp_4xx_softmmu(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc40x_irq_init(ppc_env_get_cpu(env));
-
- SET_FIT_PERIOD(12, 16, 20, 24);
- SET_WDT_PERIOD(16, 20, 24, 28);
-}
-
-POWERPC_FAMILY(401x2)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 401x2";
- pcc->init_proc = init_proc_401x2;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_DCR | PPC_WRTEE |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
- PPC_4xx_COMMON | PPC_40x_EXCP;
- pcc->msr_mask = (1ull << 20) |
- (1ull << MSR_KEY) |
- (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_ME) |
- (1ull << MSR_DE) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
- pcc->excp_model = POWERPC_EXCP_40x;
- pcc->bus_model = PPC_FLAGS_INPUT_401;
- pcc->bfd_mach = bfd_mach_ppc_403;
- pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_401x3 (CPUPPCState *env)
-{
- gen_spr_40x(env);
- gen_spr_401_403(env);
- gen_spr_401(env);
- gen_spr_401x2(env);
- gen_spr_compress(env);
- init_excp_4xx_softmmu(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc40x_irq_init(ppc_env_get_cpu(env));
-
- SET_FIT_PERIOD(12, 16, 20, 24);
- SET_WDT_PERIOD(16, 20, 24, 28);
-}
-
-POWERPC_FAMILY(401x3)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 401x3";
- pcc->init_proc = init_proc_401x3;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_DCR | PPC_WRTEE |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
- PPC_4xx_COMMON | PPC_40x_EXCP;
- pcc->msr_mask = (1ull << 20) |
- (1ull << MSR_KEY) |
- (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_ME) |
- (1ull << MSR_DWE) |
- (1ull << MSR_DE) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
- pcc->excp_model = POWERPC_EXCP_40x;
- pcc->bus_model = PPC_FLAGS_INPUT_401;
- pcc->bfd_mach = bfd_mach_ppc_403;
- pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_IOP480 (CPUPPCState *env)
-{
- gen_spr_40x(env);
- gen_spr_401_403(env);
- gen_spr_401x2(env);
- gen_spr_compress(env);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->id_tlbs = 0;
- env->tlb_type = TLB_EMB;
-#endif
- init_excp_4xx_softmmu(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc40x_irq_init(ppc_env_get_cpu(env));
-
- SET_FIT_PERIOD(8, 12, 16, 20);
- SET_WDT_PERIOD(16, 20, 24, 28);
-}
-
-POWERPC_FAMILY(IOP480)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "IOP480";
- pcc->init_proc = init_proc_IOP480;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
- PPC_DCR | PPC_WRTEE |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
- PPC_4xx_COMMON | PPC_40x_EXCP;
- pcc->msr_mask = (1ull << 20) |
- (1ull << MSR_KEY) |
- (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_ME) |
- (1ull << MSR_DE) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
- pcc->excp_model = POWERPC_EXCP_40x;
- pcc->bus_model = PPC_FLAGS_INPUT_401;
- pcc->bfd_mach = bfd_mach_ppc_403;
- pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_403 (CPUPPCState *env)
-{
- gen_spr_40x(env);
- gen_spr_401_403(env);
- gen_spr_403(env);
- gen_spr_403_real(env);
- init_excp_4xx_real(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc40x_irq_init(ppc_env_get_cpu(env));
-
- SET_FIT_PERIOD(8, 12, 16, 20);
- SET_WDT_PERIOD(16, 20, 24, 28);
-}
-
-POWERPC_FAMILY(403)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 403";
- pcc->init_proc = init_proc_403;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
- PPC_DCR | PPC_WRTEE |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
- PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_4xx_COMMON | PPC_40x_EXCP;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_ME) |
- (1ull << MSR_PE) |
- (1ull << MSR_PX) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_REAL;
- pcc->excp_model = POWERPC_EXCP_40x;
- pcc->bus_model = PPC_FLAGS_INPUT_401;
- pcc->bfd_mach = bfd_mach_ppc_403;
- pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_403GCX (CPUPPCState *env)
-{
- gen_spr_40x(env);
- gen_spr_401_403(env);
- gen_spr_403(env);
- gen_spr_403_real(env);
- gen_spr_403_mmu(env);
- /* Bus access control */
- /* not emulated, as QEMU never does speculative access */
- spr_register(env, SPR_40x_SGR, "SGR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0xFFFFFFFF);
- /* not emulated, as QEMU do not emulate caches */
- spr_register(env, SPR_40x_DCWR, "DCWR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->id_tlbs = 0;
- env->tlb_type = TLB_EMB;
-#endif
- init_excp_4xx_softmmu(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc40x_irq_init(ppc_env_get_cpu(env));
-
- SET_FIT_PERIOD(8, 12, 16, 20);
- SET_WDT_PERIOD(16, 20, 24, 28);
-}
-
-POWERPC_FAMILY(403GCX)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 403 GCX";
- pcc->init_proc = init_proc_403GCX;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
- PPC_DCR | PPC_WRTEE |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
- PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
- PPC_4xx_COMMON | PPC_40x_EXCP;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_ME) |
- (1ull << MSR_PE) |
- (1ull << MSR_PX) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z;
- pcc->excp_model = POWERPC_EXCP_40x;
- pcc->bus_model = PPC_FLAGS_INPUT_401;
- pcc->bfd_mach = bfd_mach_ppc_403;
- pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_405 (CPUPPCState *env)
-{
- /* Time base */
- gen_tbl(env);
- gen_spr_40x(env);
- gen_spr_405(env);
- /* Bus access control */
- /* not emulated, as QEMU never does speculative access */
- spr_register(env, SPR_40x_SGR, "SGR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0xFFFFFFFF);
- /* not emulated, as QEMU do not emulate caches */
- spr_register(env, SPR_40x_DCWR, "DCWR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->id_tlbs = 0;
- env->tlb_type = TLB_EMB;
-#endif
- init_excp_4xx_softmmu(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc40x_irq_init(ppc_env_get_cpu(env));
-
- SET_FIT_PERIOD(8, 12, 16, 20);
- SET_WDT_PERIOD(16, 20, 24, 28);
-}
-
-POWERPC_FAMILY(405)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 405";
- pcc->init_proc = init_proc_405;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_DCR | PPC_WRTEE |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_40x_ICBT |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |
- PPC_4xx_COMMON | PPC_405_MAC | PPC_40x_EXCP;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_DWE) |
- (1ull << MSR_DE) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR);
- pcc->mmu_model = POWERPC_MMU_SOFT_4xx;
- pcc->excp_model = POWERPC_EXCP_40x;
- pcc->bus_model = PPC_FLAGS_INPUT_405;
- pcc->bfd_mach = bfd_mach_ppc_403;
- pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
- POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_440EP (CPUPPCState *env)
-{
- /* Time base */
- gen_tbl(env);
- gen_spr_BookE(env, 0x000000000000FFFFULL);
- gen_spr_440(env);
- gen_spr_usprgh(env);
- /* Processor identification */
- spr_register(env, SPR_BOOKE_PIR, "PIR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_pir,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_IAC3, "IAC3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_IAC4, "IAC4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DVC1, "DVC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DVC2, "DVC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_MCSR, "MCSR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_CCR1, "CCR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->id_tlbs = 0;
- env->tlb_type = TLB_EMB;
-#endif
- init_excp_BookE(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- ppc40x_irq_init(ppc_env_get_cpu(env));
-
- SET_FIT_PERIOD(12, 16, 20, 24);
- SET_WDT_PERIOD(20, 24, 28, 32);
-}
-
-POWERPC_FAMILY(440EP)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 440 EP";
- pcc->init_proc = init_proc_440EP;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
- PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
- PPC_FLOAT_STFIWX |
- PPC_DCR | PPC_WRTEE | PPC_RFMCI |
- PPC_CACHE | PPC_CACHE_ICBI |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_MEM_TLBSYNC | PPC_MFTB |
- PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
- PPC_440_SPEC;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_DWE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR);
- pcc->mmu_model = POWERPC_MMU_BOOKE;
- pcc->excp_model = POWERPC_EXCP_BOOKE;
- pcc->bus_model = PPC_FLAGS_INPUT_BookE;
- pcc->bfd_mach = bfd_mach_ppc_403;
- pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
- POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_440GP (CPUPPCState *env)
-{
- /* Time base */
- gen_tbl(env);
- gen_spr_BookE(env, 0x000000000000FFFFULL);
- gen_spr_440(env);
- gen_spr_usprgh(env);
- /* Processor identification */
- spr_register(env, SPR_BOOKE_PIR, "PIR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_pir,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_IAC3, "IAC3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_IAC4, "IAC4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DVC1, "DVC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DVC2, "DVC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->id_tlbs = 0;
- env->tlb_type = TLB_EMB;
-#endif
- init_excp_BookE(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* XXX: TODO: allocate internal IRQ controller */
-
- SET_FIT_PERIOD(12, 16, 20, 24);
- SET_WDT_PERIOD(20, 24, 28, 32);
-}
-
-POWERPC_FAMILY(440GP)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 440 GP";
- pcc->init_proc = init_proc_440GP;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
- PPC_DCR | PPC_DCRX | PPC_WRTEE | PPC_MFAPIDI |
- PPC_CACHE | PPC_CACHE_ICBI |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_MEM_TLBSYNC | PPC_TLBIVA | PPC_MFTB |
- PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
- PPC_440_SPEC;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_DWE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR);
- pcc->mmu_model = POWERPC_MMU_BOOKE;
- pcc->excp_model = POWERPC_EXCP_BOOKE;
- pcc->bus_model = PPC_FLAGS_INPUT_BookE;
- pcc->bfd_mach = bfd_mach_ppc_403;
- pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
- POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_440x4 (CPUPPCState *env)
-{
- /* Time base */
- gen_tbl(env);
- gen_spr_BookE(env, 0x000000000000FFFFULL);
- gen_spr_440(env);
- gen_spr_usprgh(env);
- /* Processor identification */
- spr_register(env, SPR_BOOKE_PIR, "PIR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_pir,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_IAC3, "IAC3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_IAC4, "IAC4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DVC1, "DVC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DVC2, "DVC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->id_tlbs = 0;
- env->tlb_type = TLB_EMB;
-#endif
- init_excp_BookE(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* XXX: TODO: allocate internal IRQ controller */
-
- SET_FIT_PERIOD(12, 16, 20, 24);
- SET_WDT_PERIOD(20, 24, 28, 32);
-}
-
-POWERPC_FAMILY(440x4)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 440x4";
- pcc->init_proc = init_proc_440x4;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
- PPC_DCR | PPC_WRTEE |
- PPC_CACHE | PPC_CACHE_ICBI |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_MEM_TLBSYNC | PPC_MFTB |
- PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
- PPC_440_SPEC;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_DWE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR);
- pcc->mmu_model = POWERPC_MMU_BOOKE;
- pcc->excp_model = POWERPC_EXCP_BOOKE;
- pcc->bus_model = PPC_FLAGS_INPUT_BookE;
- pcc->bfd_mach = bfd_mach_ppc_403;
- pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
- POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_440x5 (CPUPPCState *env)
-{
- /* Time base */
- gen_tbl(env);
- gen_spr_BookE(env, 0x000000000000FFFFULL);
- gen_spr_440(env);
- gen_spr_usprgh(env);
- /* Processor identification */
- spr_register(env, SPR_BOOKE_PIR, "PIR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_pir,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_IAC3, "IAC3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_IAC4, "IAC4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DVC1, "DVC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DVC2, "DVC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_MCSR, "MCSR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_CCR1, "CCR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->id_tlbs = 0;
- env->tlb_type = TLB_EMB;
-#endif
- init_excp_BookE(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- ppc40x_irq_init(ppc_env_get_cpu(env));
-
- SET_FIT_PERIOD(12, 16, 20, 24);
- SET_WDT_PERIOD(20, 24, 28, 32);
-}
-
-POWERPC_FAMILY(440x5)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 440x5";
- pcc->init_proc = init_proc_440x5;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
- PPC_DCR | PPC_WRTEE | PPC_RFMCI |
- PPC_CACHE | PPC_CACHE_ICBI |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_MEM_TLBSYNC | PPC_MFTB |
- PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
- PPC_440_SPEC;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_DWE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR);
- pcc->mmu_model = POWERPC_MMU_BOOKE;
- pcc->excp_model = POWERPC_EXCP_BOOKE;
- pcc->bus_model = PPC_FLAGS_INPUT_BookE;
- pcc->bfd_mach = bfd_mach_ppc_403;
- pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
- POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
-}
-
-POWERPC_FAMILY(440x5wDFPU)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 440x5 with double precision FPU";
- pcc->init_proc = init_proc_440x5;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
- PPC_FLOAT | PPC_FLOAT_FSQRT |
- PPC_FLOAT_STFIWX |
- PPC_DCR | PPC_WRTEE | PPC_RFMCI |
- PPC_CACHE | PPC_CACHE_ICBI |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_MEM_TLBSYNC | PPC_MFTB |
- PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
- PPC_440_SPEC;
- pcc->insns_flags2 = PPC2_FP_CVT_S64;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_DWE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR);
- pcc->mmu_model = POWERPC_MMU_BOOKE;
- pcc->excp_model = POWERPC_EXCP_BOOKE;
- pcc->bus_model = PPC_FLAGS_INPUT_BookE;
- pcc->bfd_mach = bfd_mach_ppc_403;
- pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
- POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_460 (CPUPPCState *env)
-{
- /* Time base */
- gen_tbl(env);
- gen_spr_BookE(env, 0x000000000000FFFFULL);
- gen_spr_440(env);
- gen_spr_usprgh(env);
- /* Processor identification */
- spr_register(env, SPR_BOOKE_PIR, "PIR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_pir,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_IAC3, "IAC3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_IAC4, "IAC4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DVC1, "DVC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DVC2, "DVC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_MCSR, "MCSR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_CCR1, "CCR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_DCRIPR, "SPR_DCRIPR",
- &spr_read_generic, &spr_write_generic,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->id_tlbs = 0;
- env->tlb_type = TLB_EMB;
-#endif
- init_excp_BookE(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* XXX: TODO: allocate internal IRQ controller */
-
- SET_FIT_PERIOD(12, 16, 20, 24);
- SET_WDT_PERIOD(20, 24, 28, 32);
-}
-
-POWERPC_FAMILY(460)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 460 (guessed)";
- pcc->init_proc = init_proc_460;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
- PPC_DCR | PPC_DCRX | PPC_DCRUX |
- PPC_WRTEE | PPC_MFAPIDI | PPC_MFTB |
- PPC_CACHE | PPC_CACHE_ICBI |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_MEM_TLBSYNC | PPC_TLBIVA |
- PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
- PPC_440_SPEC;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_DWE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR);
- pcc->mmu_model = POWERPC_MMU_BOOKE;
- pcc->excp_model = POWERPC_EXCP_BOOKE;
- pcc->bus_model = PPC_FLAGS_INPUT_BookE;
- pcc->bfd_mach = bfd_mach_ppc_403;
- pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
- POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_460F (CPUPPCState *env)
-{
- /* Time base */
- gen_tbl(env);
- gen_spr_BookE(env, 0x000000000000FFFFULL);
- gen_spr_440(env);
- gen_spr_usprgh(env);
- /* Processor identification */
- spr_register(env, SPR_BOOKE_PIR, "PIR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_pir,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_IAC3, "IAC3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_IAC4, "IAC4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DVC1, "DVC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_DVC2, "DVC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_MCSR, "MCSR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_440_CCR1, "CCR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_DCRIPR, "SPR_DCRIPR",
- &spr_read_generic, &spr_write_generic,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->id_tlbs = 0;
- env->tlb_type = TLB_EMB;
-#endif
- init_excp_BookE(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* XXX: TODO: allocate internal IRQ controller */
-
- SET_FIT_PERIOD(12, 16, 20, 24);
- SET_WDT_PERIOD(20, 24, 28, 32);
-}
-
-POWERPC_FAMILY(460F)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 460F (guessed)";
- pcc->init_proc = init_proc_460F;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
- PPC_FLOAT | PPC_FLOAT_FRES | PPC_FLOAT_FSEL |
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
- PPC_FLOAT_STFIWX | PPC_MFTB |
- PPC_DCR | PPC_DCRX | PPC_DCRUX |
- PPC_WRTEE | PPC_MFAPIDI |
- PPC_CACHE | PPC_CACHE_ICBI |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_MEM_TLBSYNC | PPC_TLBIVA |
- PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |
- PPC_440_SPEC;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_DWE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR);
- pcc->mmu_model = POWERPC_MMU_BOOKE;
- pcc->excp_model = POWERPC_EXCP_BOOKE;
- pcc->bus_model = PPC_FLAGS_INPUT_BookE;
- pcc->bfd_mach = bfd_mach_ppc_403;
- pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE |
- POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_MPC5xx (CPUPPCState *env)
-{
- /* Time base */
- gen_tbl(env);
- gen_spr_5xx_8xx(env);
- gen_spr_5xx(env);
- init_excp_MPC5xx(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* XXX: TODO: allocate internal IRQ controller */
-}
-
-POWERPC_FAMILY(MPC5xx)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "Freescale 5xx cores (aka RCPU)";
- pcc->init_proc = init_proc_MPC5xx;
- pcc->check_pow = check_pow_none;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
- PPC_MEM_EIEIO | PPC_MEM_SYNC |
- PPC_CACHE_ICBI | PPC_FLOAT | PPC_FLOAT_STFIWX |
- PPC_MFTB;
- pcc->msr_mask = (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_REAL;
- pcc->excp_model = POWERPC_EXCP_603;
- pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
- pcc->bfd_mach = bfd_mach_ppc_505;
- pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_MPC8xx (CPUPPCState *env)
-{
- /* Time base */
- gen_tbl(env);
- gen_spr_5xx_8xx(env);
- gen_spr_8xx(env);
- init_excp_MPC8xx(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* XXX: TODO: allocate internal IRQ controller */
-}
-
-POWERPC_FAMILY(MPC8xx)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "Freescale 8xx cores (aka PowerQUICC)";
- pcc->init_proc = init_proc_MPC8xx;
- pcc->check_pow = check_pow_none;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING |
- PPC_MEM_EIEIO | PPC_MEM_SYNC |
- PPC_CACHE_ICBI | PPC_MFTB;
- pcc->msr_mask = (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_MPC8xx;
- pcc->excp_model = POWERPC_EXCP_603;
- pcc->bus_model = PPC_FLAGS_INPUT_RCPU;
- pcc->bfd_mach = bfd_mach_ppc_860;
- pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
- POWERPC_FLAG_BUS_CLK;
-}
-
-/* Freescale 82xx cores (aka PowerQUICC-II) */
-
-static void init_proc_G2 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_G2_755(env);
- gen_spr_G2(env);
- /* Time base */
- gen_tbl(env);
- /* External access control */
- /* XXX : not implemented */
- spr_register(env, SPR_EAR, "EAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Hardware implementation register */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID2, "HID2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- gen_high_BATs(env);
- gen_6xx_7xx_soft_tlb(env, 64, 2);
- init_excp_G2(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(G2)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC G2";
- pcc->init_proc = init_proc_G2;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_TGPR) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_AL) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_RI);
- pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
- pcc->excp_model = POWERPC_EXCP_G2;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_ec603e;
- pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_G2LE (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_G2_755(env);
- gen_spr_G2(env);
- /* Time base */
- gen_tbl(env);
- /* External access control */
- /* XXX : not implemented */
- spr_register(env, SPR_EAR, "EAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Hardware implementation register */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID2, "HID2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-
- /* Memory management */
- gen_low_BATs(env);
- gen_high_BATs(env);
- gen_6xx_7xx_soft_tlb(env, 64, 2);
- init_excp_G2(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(G2LE)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC G2LE";
- pcc->init_proc = init_proc_G2LE;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_TGPR) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_AL) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
- pcc->excp_model = POWERPC_EXCP_G2;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_ec603e;
- pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_e200 (CPUPPCState *env)
-{
- /* Time base */
- gen_tbl(env);
- gen_spr_BookE(env, 0x000000070000FFFFULL);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
- &spr_read_spefscr, &spr_write_spefscr,
- &spr_read_spefscr, &spr_write_spefscr,
- 0x00000000);
- /* Memory management */
- gen_spr_BookE206(env, 0x0000005D, NULL);
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_Exxx_ALTCTXCR, "ALTCTXCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_Exxx_CTXCR, "CTXCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_Exxx_DBCNT, "DBCNT",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_Exxx_DBCR3, "DBCR3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
- &spr_read_generic, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_Exxx_L1FINV0, "L1FINV0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_TLB0CFG, "TLB0CFG",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_TLB1CFG, "TLB1CFG",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_IAC3, "IAC3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_IAC4, "IAC4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MMUCSR0, "MMUCSR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000); /* TOFIX */
- spr_register(env, SPR_BOOKE_DSRR0, "DSRR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BOOKE_DSRR1, "DSRR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->id_tlbs = 0;
- env->tlb_type = TLB_EMB;
-#endif
- init_excp_e200(env, 0xFFFF0000UL);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* XXX: TODO: allocate internal IRQ controller */
-}
-
-POWERPC_FAMILY(e200)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "e200 core";
- pcc->init_proc = init_proc_e200;
- pcc->check_pow = check_pow_hid0;
- /* XXX: unimplemented instructions:
- * dcblc
- * dcbtlst
- * dcbtstls
- * icblc
- * icbtls
- * tlbivax
- * all SPE multiply-accumulate instructions
- */
- pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
- PPC_SPE | PPC_SPE_SINGLE |
- PPC_WRTEE | PPC_RFDI |
- PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_MEM_TLBSYNC | PPC_TLBIVAX |
- PPC_BOOKE;
- pcc->msr_mask = (1ull << MSR_UCLE) |
- (1ull << MSR_SPE) |
- (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_DWE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR);
- pcc->mmu_model = POWERPC_MMU_BOOKE206;
- pcc->excp_model = POWERPC_EXCP_BOOKE;
- pcc->bus_model = PPC_FLAGS_INPUT_BookE;
- pcc->bfd_mach = bfd_mach_ppc_860;
- pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
- POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_e300 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_603(env);
- /* Time base */
- gen_tbl(env);
- /* hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID2, "HID2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Breakpoints */
- /* XXX : not implemented */
- spr_register(env, SPR_DABR, "DABR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_DABR2, "DABR2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_IABR2, "IABR2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_IBCR, "IBCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_DBCR, "DBCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- gen_high_BATs(env);
- gen_6xx_7xx_soft_tlb(env, 64, 2);
- init_excp_603(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(e300)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "e300 core";
- pcc->init_proc = init_proc_e300;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_TGPR) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_AL) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
- pcc->excp_model = POWERPC_EXCP_603;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_603;
- pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
-}
-
-#if !defined(CONFIG_USER_ONLY)
-static void spr_write_mas73(DisasContext *ctx, int sprn, int gprn)
-{
- TCGv val = tcg_temp_new();
- tcg_gen_ext32u_tl(val, cpu_gpr[gprn]);
- gen_store_spr(SPR_BOOKE_MAS3, val);
- tcg_gen_shri_tl(val, cpu_gpr[gprn], 32);
- gen_store_spr(SPR_BOOKE_MAS7, val);
- tcg_temp_free(val);
-}
-
-static void spr_read_mas73(DisasContext *ctx, int gprn, int sprn)
-{
- TCGv mas7 = tcg_temp_new();
- TCGv mas3 = tcg_temp_new();
- gen_load_spr(mas7, SPR_BOOKE_MAS7);
- tcg_gen_shli_tl(mas7, mas7, 32);
- gen_load_spr(mas3, SPR_BOOKE_MAS3);
- tcg_gen_or_tl(cpu_gpr[gprn], mas3, mas7);
- tcg_temp_free(mas3);
- tcg_temp_free(mas7);
-}
-
-#endif
-
-enum fsl_e500_version {
- fsl_e500v1,
- fsl_e500v2,
- fsl_e500mc,
- fsl_e5500,
-};
-
-static void init_proc_e500 (CPUPPCState *env, int version)
-{
- PowerPCCPU *cpu = ppc_env_get_cpu(env);
- uint32_t tlbncfg[2];
- uint64_t ivor_mask;
- uint64_t ivpr_mask = 0xFFFF0000ULL;
- uint32_t l1cfg0 = 0x3800 /* 8 ways */
- | 0x0020; /* 32 kb */
- uint32_t l1cfg1 = 0x3800 /* 8 ways */
- | 0x0020; /* 32 kb */
-#if !defined(CONFIG_USER_ONLY)
- int i;
-#endif
-
- /* Time base */
- gen_tbl(env);
- /*
- * XXX The e500 doesn't implement IVOR7 and IVOR9, but doesn't
- * complain when accessing them.
- * gen_spr_BookE(env, 0x0000000F0000FD7FULL);
- */
- switch (version) {
- case fsl_e500v1:
- case fsl_e500v2:
- default:
- ivor_mask = 0x0000000F0000FFFFULL;
- break;
- case fsl_e500mc:
- case fsl_e5500:
- ivor_mask = 0x000003FE0000FFFFULL;
- break;
- }
- gen_spr_BookE(env, ivor_mask);
- /* Processor identification */
- spr_register(env, SPR_BOOKE_PIR, "PIR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_pir,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_SPEFSCR, "SPEFSCR",
- &spr_read_spefscr, &spr_write_spefscr,
- &spr_read_spefscr, &spr_write_spefscr,
- 0x00000000);
-#if !defined(CONFIG_USER_ONLY)
- /* Memory management */
- env->nb_pids = 3;
- env->nb_ways = 2;
- env->id_tlbs = 0;
- switch (version) {
- case fsl_e500v1:
- tlbncfg[0] = gen_tlbncfg(2, 1, 1, 0, 256);
- tlbncfg[1] = gen_tlbncfg(16, 1, 9, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
- break;
- case fsl_e500v2:
- tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
- tlbncfg[1] = gen_tlbncfg(16, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 16);
- break;
- case fsl_e500mc:
- case fsl_e5500:
- tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
- tlbncfg[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 64);
- break;
- default:
- cpu_abort(CPU(cpu), "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]);
- }
-#endif
- /* Cache sizes */
- switch (version) {
- case fsl_e500v1:
- case fsl_e500v2:
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- break;
- case fsl_e500mc:
- case fsl_e5500:
- env->dcache_line_size = 64;
- env->icache_line_size = 64;
- l1cfg0 |= 0x1000000; /* 64 byte cache block size */
- l1cfg1 |= 0x1000000; /* 64 byte cache block size */
- break;
- default:
- cpu_abort(CPU(cpu), "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]);
- }
- gen_spr_BookE206(env, 0x000000DF, tlbncfg);
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_Exxx_BBEAR, "BBEAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_Exxx_BBTAR, "BBTAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_Exxx_MCAR, "MCAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_BOOKE_MCSR, "MCSR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_Exxx_NPIDR, "NPIDR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_Exxx_BUCSR, "BUCSR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_Exxx_L1CFG0, "L1CFG0",
- &spr_read_generic, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- l1cfg0);
- spr_register(env, SPR_Exxx_L1CFG1, "L1CFG1",
- &spr_read_generic, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- l1cfg1);
- spr_register(env, SPR_Exxx_L1CSR0, "L1CSR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_e500_l1csr0,
- 0x00000000);
- spr_register(env, SPR_Exxx_L1CSR1, "L1CSR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_e500_l1csr1,
- 0x00000000);
- spr_register(env, SPR_BOOKE_MCSRR0, "MCSRR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BOOKE_MCSRR1, "MCSRR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_MMUCSR0, "MMUCSR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_booke206_mmucsr0,
- 0x00000000);
- spr_register(env, SPR_BOOKE_EPR, "EPR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
- /* XXX better abstract into Emb.xxx features */
- if (version == fsl_e5500) {
- spr_register(env, SPR_BOOKE_EPCR, "EPCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BOOKE_MAS7_MAS3, "MAS7_MAS3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_mas73, &spr_write_mas73,
- 0x00000000);
- ivpr_mask = (target_ulong)~0xFFFFULL;
- }
-
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 0;
- env->tlb_type = TLB_MAS;
- for (i = 0; i < BOOKE206_MAX_TLBN; i++) {
- env->nb_tlb += booke206_tlb_size(env, i);
- }
-#endif
-
- init_excp_e200(env, ivpr_mask);
- /* Allocate hardware IRQ controller */
- ppce500_irq_init(ppc_env_get_cpu(env));
-}
-
-static void init_proc_e500v1(CPUPPCState *env)
-{
- init_proc_e500(env, fsl_e500v1);
-}
-
-POWERPC_FAMILY(e500v1)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "e500v1 core";
- pcc->init_proc = init_proc_e500v1;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
- PPC_SPE | PPC_SPE_SINGLE |
- PPC_WRTEE | PPC_RFDI |
- PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
- pcc->insns_flags2 = PPC2_BOOKE206;
- pcc->msr_mask = (1ull << MSR_UCLE) |
- (1ull << MSR_SPE) |
- (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_DWE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR);
- pcc->mmu_model = POWERPC_MMU_BOOKE206;
- pcc->excp_model = POWERPC_EXCP_BOOKE;
- pcc->bus_model = PPC_FLAGS_INPUT_BookE;
- pcc->bfd_mach = bfd_mach_ppc_860;
- pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
- POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_e500v2(CPUPPCState *env)
-{
- init_proc_e500(env, fsl_e500v2);
-}
-
-POWERPC_FAMILY(e500v2)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "e500v2 core";
- pcc->init_proc = init_proc_e500v2;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL |
- PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE |
- PPC_WRTEE | PPC_RFDI |
- PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
- pcc->insns_flags2 = PPC2_BOOKE206;
- pcc->msr_mask = (1ull << MSR_UCLE) |
- (1ull << MSR_SPE) |
- (1ull << MSR_POW) |
- (1ull << MSR_CE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_DWE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR);
- pcc->mmu_model = POWERPC_MMU_BOOKE206;
- pcc->excp_model = POWERPC_EXCP_BOOKE;
- pcc->bus_model = PPC_FLAGS_INPUT_BookE;
- pcc->bfd_mach = bfd_mach_ppc_860;
- pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE |
- POWERPC_FLAG_UBLE | POWERPC_FLAG_DE |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_e500mc(CPUPPCState *env)
-{
- init_proc_e500(env, fsl_e500mc);
-}
-
-POWERPC_FAMILY(e500mc)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "e500mc core";
- pcc->init_proc = init_proc_e500mc;
- pcc->check_pow = check_pow_none;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
- PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
- PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_FLOAT | PPC_FLOAT_FRES |
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
- PPC_FLOAT_STFIWX | PPC_WAIT |
- PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC;
- pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL;
- pcc->msr_mask = (1ull << MSR_GS) |
- (1ull << MSR_UCLE) |
- (1ull << MSR_CE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PX) |
- (1ull << MSR_RI);
- pcc->mmu_model = POWERPC_MMU_BOOKE206;
- pcc->excp_model = POWERPC_EXCP_BOOKE;
- pcc->bus_model = PPC_FLAGS_INPUT_BookE;
- /* FIXME: figure out the correct flag for e500mc */
- pcc->bfd_mach = bfd_mach_ppc_e500;
- pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
-}
-
-#ifdef TARGET_PPC64
-static void init_proc_e5500(CPUPPCState *env)
-{
- init_proc_e500(env, fsl_e5500);
-}
-
-POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "e5500 core";
- pcc->init_proc = init_proc_e5500;
- pcc->check_pow = check_pow_none;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
- PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
- PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
- PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
- PPC_FLOAT | PPC_FLOAT_FRES |
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
- PPC_FLOAT_STFIWX | PPC_WAIT |
- PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
- PPC_64B | PPC_POPCNTB | PPC_POPCNTWD;
- pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 | \
- PPC2_FP_CVT_S64;
- pcc->msr_mask = (1ull << MSR_CM) |
- (1ull << MSR_GS) |
- (1ull << MSR_UCLE) |
- (1ull << MSR_CE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PX) |
- (1ull << MSR_RI);
- pcc->mmu_model = POWERPC_MMU_BOOKE206;
- pcc->excp_model = POWERPC_EXCP_BOOKE;
- pcc->bus_model = PPC_FLAGS_INPUT_BookE;
- /* FIXME: figure out the correct flag for e5500 */
- pcc->bfd_mach = bfd_mach_ppc_e500;
- pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
-}
-#endif
-
-/* Non-embedded PowerPC */
-
-/* POWER : same as 601, without mfmsr, mfsr */
-POWERPC_FAMILY(POWER)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "POWER";
- /* pcc->insns_flags = XXX_TODO; */
- /* POWER RSC (from RAD6000) */
- pcc->msr_mask = (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_AL) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR);
-}
-
-#define POWERPC_MSRR_601 (0x0000000000001040ULL)
-
-static void init_proc_601 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_601(env);
- /* Hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_hid0_601,
- 0x80010080);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_601_HID2, "HID2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_601_HID5, "HID5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- init_excp_601(env);
- /* XXX: beware that dcache line size is 64
- * but dcbz uses 32 bytes "sectors"
- * XXX: this breaks clcs instruction !
- */
- env->dcache_line_size = 32;
- env->icache_line_size = 64;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(601)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 601";
- pcc->init_proc = init_proc_601;
- pcc->check_pow = check_pow_none;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
- PPC_FLOAT |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR);
- pcc->mmu_model = POWERPC_MMU_601;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
-#endif
- pcc->excp_model = POWERPC_EXCP_601;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_601;
- pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
-}
-
-#define POWERPC_MSRR_601v (0x0000000000001040ULL)
-
-static void init_proc_601v (CPUPPCState *env)
-{
- init_proc_601(env);
- /* XXX : not implemented */
- spr_register(env, SPR_601_HID15, "HID15",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-POWERPC_FAMILY(601v)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 601v";
- pcc->init_proc = init_proc_601v;
- pcc->check_pow = check_pow_none;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_POWER_BR |
- PPC_FLOAT |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR);
- pcc->mmu_model = POWERPC_MMU_601;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
-#endif
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_601;
- pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK;
-}
-
-static void init_proc_602 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_602(env);
- /* Time base */
- gen_tbl(env);
- /* hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- gen_6xx_7xx_soft_tlb(env, 64, 2);
- init_excp_602(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(602)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 602";
- pcc->init_proc = init_proc_602;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_6xx_TLB | PPC_MEM_TLBSYNC |
- PPC_SEGMENT | PPC_602_SPEC;
- pcc->msr_mask = (1ull << MSR_VSX) |
- (1ull << MSR_SA) |
- (1ull << MSR_POW) |
- (1ull << MSR_TGPR) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- /* XXX: 602 MMU is quite specific. Should add a special case */
- pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
- pcc->excp_model = POWERPC_EXCP_602;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_602;
- pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_603 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_603(env);
- /* Time base */
- gen_tbl(env);
- /* hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- gen_6xx_7xx_soft_tlb(env, 64, 2);
- init_excp_603(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(603)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 603";
- pcc->init_proc = init_proc_603;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_TGPR) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
- pcc->excp_model = POWERPC_EXCP_603;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_603;
- pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_603E (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_603(env);
- /* Time base */
- gen_tbl(env);
- /* hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- gen_6xx_7xx_soft_tlb(env, 64, 2);
- init_excp_603(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(603E)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 603e";
- pcc->init_proc = init_proc_603E;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_TGPR) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
- pcc->excp_model = POWERPC_EXCP_603E;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_ec603e;
- pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_604 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_604(env);
- /* Time base */
- gen_tbl(env);
- /* Hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- init_excp_604(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(604)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 604";
- pcc->init_proc = init_proc_604;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_32B;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
-#endif
- pcc->excp_model = POWERPC_EXCP_604;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_604;
- pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_604E (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_604(env);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_MMCR1, "MMCR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC3, "PMC3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC4, "PMC4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Time base */
- gen_tbl(env);
- /* Hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- init_excp_604(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(604E)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 604E";
- pcc->init_proc = init_proc_604E;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_32B;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
-#endif
- pcc->excp_model = POWERPC_EXCP_604;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_604;
- pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_740 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_7xx(env);
- /* Time base */
- gen_tbl(env);
- /* Thermal management */
- gen_spr_thrm(env);
- /* Hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- init_excp_7x0(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(740)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 740";
- pcc->init_proc = init_proc_740;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_32B;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
-#endif
- pcc->excp_model = POWERPC_EXCP_7x0;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_750;
- pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_750 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_7xx(env);
- /* XXX : not implemented */
- spr_register(env, SPR_L2CR, "L2CR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, spr_access_nop,
- 0x00000000);
- /* Time base */
- gen_tbl(env);
- /* Thermal management */
- gen_spr_thrm(env);
- /* Hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- /* XXX: high BATs are also present but are known to be bugged on
- * die version 1.x
- */
- init_excp_7x0(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(750)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 750";
- pcc->init_proc = init_proc_750;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_32B;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
-#endif
- pcc->excp_model = POWERPC_EXCP_7x0;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_750;
- pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_750cl (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_7xx(env);
- /* XXX : not implemented */
- spr_register(env, SPR_L2CR, "L2CR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, spr_access_nop,
- 0x00000000);
- /* Time base */
- gen_tbl(env);
- /* Thermal management */
- /* Those registers are fake on 750CL */
- spr_register(env, SPR_THRM1, "THRM1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_THRM2, "THRM2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_THRM3, "THRM3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX: not implemented */
- spr_register(env, SPR_750_TDCL, "TDCL",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_750_TDCH, "TDCH",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* DMA */
- /* XXX : not implemented */
- spr_register(env, SPR_750_WPAR, "WPAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_750_DMAL, "DMAL",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_750_DMAU, "DMAU",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_750CL_HID2, "HID2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_750CL_HID4, "HID4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Quantization registers */
- /* XXX : not implemented */
- spr_register(env, SPR_750_GQR0, "GQR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_750_GQR1, "GQR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_750_GQR2, "GQR2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_750_GQR3, "GQR3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_750_GQR4, "GQR4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_750_GQR5, "GQR5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_750_GQR6, "GQR6",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_750_GQR7, "GQR7",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- /* PowerPC 750cl has 8 DBATs and 8 IBATs */
- gen_high_BATs(env);
- init_excp_750cl(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(750cl)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 750 CL";
- pcc->init_proc = init_proc_750cl;
- pcc->check_pow = check_pow_hid0;
- /* XXX: not implemented:
- * cache lock instructions:
- * dcbz_l
- * floating point paired instructions
- * psq_lux
- * psq_lx
- * psq_stux
- * psq_stx
- * ps_abs
- * ps_add
- * ps_cmpo0
- * ps_cmpo1
- * ps_cmpu0
- * ps_cmpu1
- * ps_div
- * ps_madd
- * ps_madds0
- * ps_madds1
- * ps_merge00
- * ps_merge01
- * ps_merge10
- * ps_merge11
- * ps_mr
- * ps_msub
- * ps_mul
- * ps_muls0
- * ps_muls1
- * ps_nabs
- * ps_neg
- * ps_nmadd
- * ps_nmsub
- * ps_res
- * ps_rsqrte
- * ps_sel
- * ps_sub
- * ps_sum0
- * ps_sum1
- */
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_32B;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
-#endif
- pcc->excp_model = POWERPC_EXCP_7x0;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_750;
- pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_750cx (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_7xx(env);
- /* XXX : not implemented */
- spr_register(env, SPR_L2CR, "L2CR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, spr_access_nop,
- 0x00000000);
- /* Time base */
- gen_tbl(env);
- /* Thermal management */
- gen_spr_thrm(env);
- /* This register is not implemented but is present for compatibility */
- spr_register(env, SPR_SDA, "SDA",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- /* PowerPC 750cx has 8 DBATs and 8 IBATs */
- gen_high_BATs(env);
- init_excp_750cx(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(750cx)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 750CX";
- pcc->init_proc = init_proc_750cx;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_32B;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
-#endif
- pcc->excp_model = POWERPC_EXCP_7x0;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_750;
- pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_750fx (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_7xx(env);
- /* XXX : not implemented */
- spr_register(env, SPR_L2CR, "L2CR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, spr_access_nop,
- 0x00000000);
- /* Time base */
- gen_tbl(env);
- /* Thermal management */
- gen_spr_thrm(env);
- /* XXX : not implemented */
- spr_register(env, SPR_750_THRM4, "THRM4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_750FX_HID2, "HID2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
- gen_high_BATs(env);
- init_excp_7x0(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(750fx)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 750FX";
- pcc->init_proc = init_proc_750fx;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_32B;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
-#endif
- pcc->excp_model = POWERPC_EXCP_7x0;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_750;
- pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_750gx (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_7xx(env);
- /* XXX : not implemented (XXX: different from 750fx) */
- spr_register(env, SPR_L2CR, "L2CR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, spr_access_nop,
- 0x00000000);
- /* Time base */
- gen_tbl(env);
- /* Thermal management */
- gen_spr_thrm(env);
- /* XXX : not implemented */
- spr_register(env, SPR_750_THRM4, "THRM4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Hardware implementation registers */
- /* XXX : not implemented (XXX: different from 750fx) */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented (XXX: different from 750fx) */
- spr_register(env, SPR_750FX_HID2, "HID2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
- gen_high_BATs(env);
- init_excp_7x0(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(750gx)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 750GX";
- pcc->init_proc = init_proc_750gx;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_32B;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
-#endif
- pcc->excp_model = POWERPC_EXCP_7x0;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_750;
- pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_745 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_7xx(env);
- gen_spr_G2_755(env);
- /* Time base */
- gen_tbl(env);
- /* Thermal management */
- gen_spr_thrm(env);
- /* Hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID2, "HID2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- gen_high_BATs(env);
- gen_6xx_7xx_soft_tlb(env, 64, 2);
- init_excp_7x5(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(745)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 745";
- pcc->init_proc = init_proc_745;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
- pcc->excp_model = POWERPC_EXCP_7x5;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_750;
- pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_755 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_7xx(env);
- gen_spr_G2_755(env);
- /* Time base */
- gen_tbl(env);
- /* L2 cache control */
- /* XXX : not implemented */
- spr_register(env, SPR_L2CR, "L2CR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, spr_access_nop,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_L2PMCR, "L2PMCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Thermal management */
- gen_spr_thrm(env);
- /* Hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_HID2, "HID2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- gen_high_BATs(env);
- gen_6xx_7xx_soft_tlb(env, 64, 2);
- init_excp_7x5(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(755)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 755";
- pcc->init_proc = init_proc_755;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_6xx_TLB |
- PPC_SEGMENT | PPC_EXTERN;
- pcc->msr_mask = (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_SOFT_6xx;
- pcc->excp_model = POWERPC_EXCP_7x5;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_750;
- pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE |
- POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_7400 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_7xx(env);
- /* Time base */
- gen_tbl(env);
- /* 74xx specific SPR */
- gen_spr_74xx(env);
- /* XXX : not implemented */
- spr_register(env, SPR_UBAMR, "UBAMR",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* XXX: this seems not implemented on all revisions. */
- /* XXX : not implemented */
- spr_register(env, SPR_MSSCR1, "MSSCR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Thermal management */
- gen_spr_thrm(env);
- /* Memory management */
- gen_low_BATs(env);
- init_excp_7400(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(7400)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 7400 (aka G4)";
- pcc->init_proc = init_proc_7400;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
- PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI |
- PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_MEM_TLBIA |
- PPC_SEGMENT | PPC_EXTERN |
- PPC_ALTIVEC;
- pcc->msr_mask = (1ull << MSR_VR) |
- (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_32B;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
-#endif
- pcc->excp_model = POWERPC_EXCP_74xx;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_7400;
- pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_7410 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_7xx(env);
- /* Time base */
- gen_tbl(env);
- /* 74xx specific SPR */
- gen_spr_74xx(env);
- /* XXX : not implemented */
- spr_register(env, SPR_UBAMR, "UBAMR",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* Thermal management */
- gen_spr_thrm(env);
- /* L2PMCR */
- /* XXX : not implemented */
- spr_register(env, SPR_L2PMCR, "L2PMCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* LDSTDB */
- /* XXX : not implemented */
- spr_register(env, SPR_LDSTDB, "LDSTDB",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- init_excp_7400(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(7410)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 7410 (aka G4)";
- pcc->init_proc = init_proc_7410;
- pcc->check_pow = check_pow_hid0;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
- PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI |
- PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_MEM_TLBIA |
- PPC_SEGMENT | PPC_EXTERN |
- PPC_ALTIVEC;
- pcc->msr_mask = (1ull << MSR_VR) |
- (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_32B;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
-#endif
- pcc->excp_model = POWERPC_EXCP_74xx;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_7400;
- pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_7440 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_7xx(env);
- /* Time base */
- gen_tbl(env);
- /* 74xx specific SPR */
- gen_spr_74xx(env);
- /* XXX : not implemented */
- spr_register(env, SPR_UBAMR, "UBAMR",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* LDSTCR */
- /* XXX : not implemented */
- spr_register(env, SPR_LDSTCR, "LDSTCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* ICTRL */
- /* XXX : not implemented */
- spr_register(env, SPR_ICTRL, "ICTRL",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* MSSSR0 */
- /* XXX : not implemented */
- spr_register(env, SPR_MSSSR0, "MSSSR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* PMC */
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC5, "PMC5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UPMC5, "UPMC5",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC6, "PMC6",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UPMC6, "UPMC6",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- gen_74xx_soft_tlb(env, 128, 2);
- init_excp_7450(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(7440)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 7440 (aka G4)";
- pcc->init_proc = init_proc_7440;
- pcc->check_pow = check_pow_hid0_74xx;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
- PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI |
- PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_MEM_TLBIA | PPC_74xx_TLB |
- PPC_SEGMENT | PPC_EXTERN |
- PPC_ALTIVEC;
- pcc->msr_mask = (1ull << MSR_VR) |
- (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
- pcc->excp_model = POWERPC_EXCP_74xx;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_7400;
- pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_7450 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_7xx(env);
- /* Time base */
- gen_tbl(env);
- /* 74xx specific SPR */
- gen_spr_74xx(env);
- /* Level 3 cache control */
- gen_l3_ctrl(env);
- /* L3ITCR1 */
- /* XXX : not implemented */
- spr_register(env, SPR_L3ITCR1, "L3ITCR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* L3ITCR2 */
- /* XXX : not implemented */
- spr_register(env, SPR_L3ITCR2, "L3ITCR2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* L3ITCR3 */
- /* XXX : not implemented */
- spr_register(env, SPR_L3ITCR3, "L3ITCR3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* L3OHCR */
- /* XXX : not implemented */
- spr_register(env, SPR_L3OHCR, "L3OHCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_UBAMR, "UBAMR",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* LDSTCR */
- /* XXX : not implemented */
- spr_register(env, SPR_LDSTCR, "LDSTCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* ICTRL */
- /* XXX : not implemented */
- spr_register(env, SPR_ICTRL, "ICTRL",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* MSSSR0 */
- /* XXX : not implemented */
- spr_register(env, SPR_MSSSR0, "MSSSR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* PMC */
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC5, "PMC5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UPMC5, "UPMC5",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC6, "PMC6",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UPMC6, "UPMC6",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- gen_74xx_soft_tlb(env, 128, 2);
- init_excp_7450(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(7450)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 7450 (aka G4)";
- pcc->init_proc = init_proc_7450;
- pcc->check_pow = check_pow_hid0_74xx;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
- PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI |
- PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_MEM_TLBIA | PPC_74xx_TLB |
- PPC_SEGMENT | PPC_EXTERN |
- PPC_ALTIVEC;
- pcc->msr_mask = (1ull << MSR_VR) |
- (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
- pcc->excp_model = POWERPC_EXCP_74xx;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_7400;
- pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_7445 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_7xx(env);
- /* Time base */
- gen_tbl(env);
- /* 74xx specific SPR */
- gen_spr_74xx(env);
- /* LDSTCR */
- /* XXX : not implemented */
- spr_register(env, SPR_LDSTCR, "LDSTCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* ICTRL */
- /* XXX : not implemented */
- spr_register(env, SPR_ICTRL, "ICTRL",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* MSSSR0 */
- /* XXX : not implemented */
- spr_register(env, SPR_MSSSR0, "MSSSR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* PMC */
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC5, "PMC5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UPMC5, "UPMC5",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC6, "PMC6",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UPMC6, "UPMC6",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* SPRGs */
- spr_register(env, SPR_SPRG4, "SPRG4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_USPRG4, "USPRG4",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_SPRG5, "SPRG5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_USPRG5, "USPRG5",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_SPRG6, "SPRG6",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_USPRG6, "USPRG6",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_SPRG7, "SPRG7",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_USPRG7, "USPRG7",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- gen_high_BATs(env);
- gen_74xx_soft_tlb(env, 128, 2);
- init_excp_7450(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(7445)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 7445 (aka G4)";
- pcc->init_proc = init_proc_7445;
- pcc->check_pow = check_pow_hid0_74xx;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
- PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI |
- PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_MEM_TLBIA | PPC_74xx_TLB |
- PPC_SEGMENT | PPC_EXTERN |
- PPC_ALTIVEC;
- pcc->msr_mask = (1ull << MSR_VR) |
- (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
- pcc->excp_model = POWERPC_EXCP_74xx;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_7400;
- pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_7455 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_7xx(env);
- /* Time base */
- gen_tbl(env);
- /* 74xx specific SPR */
- gen_spr_74xx(env);
- /* Level 3 cache control */
- gen_l3_ctrl(env);
- /* LDSTCR */
- /* XXX : not implemented */
- spr_register(env, SPR_LDSTCR, "LDSTCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* ICTRL */
- /* XXX : not implemented */
- spr_register(env, SPR_ICTRL, "ICTRL",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* MSSSR0 */
- /* XXX : not implemented */
- spr_register(env, SPR_MSSSR0, "MSSSR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* PMC */
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC5, "PMC5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UPMC5, "UPMC5",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC6, "PMC6",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UPMC6, "UPMC6",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* SPRGs */
- spr_register(env, SPR_SPRG4, "SPRG4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_USPRG4, "USPRG4",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_SPRG5, "SPRG5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_USPRG5, "USPRG5",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_SPRG6, "SPRG6",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_USPRG6, "USPRG6",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_SPRG7, "SPRG7",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_USPRG7, "USPRG7",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- gen_high_BATs(env);
- gen_74xx_soft_tlb(env, 128, 2);
- init_excp_7450(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(7455)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 7455 (aka G4)";
- pcc->init_proc = init_proc_7455;
- pcc->check_pow = check_pow_hid0_74xx;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
- PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI |
- PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_MEM_TLBIA | PPC_74xx_TLB |
- PPC_SEGMENT | PPC_EXTERN |
- PPC_ALTIVEC;
- pcc->msr_mask = (1ull << MSR_VR) |
- (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
- pcc->excp_model = POWERPC_EXCP_74xx;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_7400;
- pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_7457 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_7xx(env);
- /* Time base */
- gen_tbl(env);
- /* 74xx specific SPR */
- gen_spr_74xx(env);
- /* Level 3 cache control */
- gen_l3_ctrl(env);
- /* L3ITCR1 */
- /* XXX : not implemented */
- spr_register(env, SPR_L3ITCR1, "L3ITCR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* L3ITCR2 */
- /* XXX : not implemented */
- spr_register(env, SPR_L3ITCR2, "L3ITCR2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* L3ITCR3 */
- /* XXX : not implemented */
- spr_register(env, SPR_L3ITCR3, "L3ITCR3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* L3OHCR */
- /* XXX : not implemented */
- spr_register(env, SPR_L3OHCR, "L3OHCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* LDSTCR */
- /* XXX : not implemented */
- spr_register(env, SPR_LDSTCR, "LDSTCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* ICTRL */
- /* XXX : not implemented */
- spr_register(env, SPR_ICTRL, "ICTRL",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* MSSSR0 */
- /* XXX : not implemented */
- spr_register(env, SPR_MSSSR0, "MSSSR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* PMC */
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC5, "PMC5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UPMC5, "UPMC5",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC6, "PMC6",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UPMC6, "UPMC6",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* SPRGs */
- spr_register(env, SPR_SPRG4, "SPRG4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_USPRG4, "USPRG4",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_SPRG5, "SPRG5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_USPRG5, "USPRG5",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_SPRG6, "SPRG6",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_USPRG6, "USPRG6",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_SPRG7, "SPRG7",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_USPRG7, "USPRG7",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- gen_high_BATs(env);
- gen_74xx_soft_tlb(env, 128, 2);
- init_excp_7450(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(7457)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 7457 (aka G4)";
- pcc->init_proc = init_proc_7457;
- pcc->check_pow = check_pow_hid0_74xx;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
- PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI |
- PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_MEM_TLBIA | PPC_74xx_TLB |
- PPC_SEGMENT | PPC_EXTERN |
- PPC_ALTIVEC;
- pcc->msr_mask = (1ull << MSR_VR) |
- (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_SOFT_74xx;
- pcc->excp_model = POWERPC_EXCP_74xx;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_7400;
- pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
- POWERPC_FLAG_BUS_CLK;
-}
-
-static void init_proc_e600 (CPUPPCState *env)
-{
- gen_spr_ne_601(env);
- gen_spr_7xx(env);
- /* Time base */
- gen_tbl(env);
- /* 74xx specific SPR */
- gen_spr_74xx(env);
- /* XXX : not implemented */
- spr_register(env, SPR_UBAMR, "UBAMR",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_LDSTCR, "LDSTCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_ICTRL, "ICTRL",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_MSSSR0, "MSSSR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC5, "PMC5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UPMC5, "UPMC5",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_PMC6, "PMC6",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- /* XXX : not implemented */
- spr_register(env, SPR_7XX_UPMC6, "UPMC6",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* SPRGs */
- spr_register(env, SPR_SPRG4, "SPRG4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_USPRG4, "USPRG4",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_SPRG5, "SPRG5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_USPRG5, "USPRG5",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_SPRG6, "SPRG6",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_USPRG6, "USPRG6",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- spr_register(env, SPR_SPRG7, "SPRG7",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_USPRG7, "USPRG7",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
- /* Memory management */
- gen_low_BATs(env);
- gen_high_BATs(env);
- gen_74xx_soft_tlb(env, 128, 2);
- init_excp_7450(env);
- env->dcache_line_size = 32;
- env->icache_line_size = 32;
- /* Allocate hardware IRQ controller */
- ppc6xx_irq_init(ppc_env_get_cpu(env));
-}
-
-POWERPC_FAMILY(e600)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC e600";
- pcc->init_proc = init_proc_e600;
- pcc->check_pow = check_pow_hid0_74xx;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
- PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI |
- PPC_CACHE_DCBA | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_MEM_TLBIA | PPC_74xx_TLB |
- PPC_SEGMENT | PPC_EXTERN |
- PPC_ALTIVEC;
- pcc->insns_flags2 = PPC_NONE;
- pcc->msr_mask = (1ull << MSR_VR) |
- (1ull << MSR_POW) |
- (1ull << MSR_ILE) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_EP) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_32B;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault;
-#endif
- pcc->excp_model = POWERPC_EXCP_74xx;
- pcc->bus_model = PPC_FLAGS_INPUT_6xx;
- pcc->bfd_mach = bfd_mach_ppc_7400;
- pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
- POWERPC_FLAG_BUS_CLK;
-}
-
-#if defined (TARGET_PPC64)
-#if defined(CONFIG_USER_ONLY)
-#define POWERPC970_HID5_INIT 0x00000080
-#else
-#define POWERPC970_HID5_INIT 0x00000000
-#endif
-
-enum BOOK3S_CPU_TYPE {
- BOOK3S_CPU_970,
- BOOK3S_CPU_POWER5PLUS,
- BOOK3S_CPU_POWER6,
- BOOK3S_CPU_POWER7,
- BOOK3S_CPU_POWER8,
- BOOK3S_CPU_POWER9
-};
-
-static void gen_fscr_facility_check(DisasContext *ctx, int facility_sprn,
- int bit, int sprn, int cause)
-{
- TCGv_i32 t1 = tcg_const_i32(bit);
- TCGv_i32 t2 = tcg_const_i32(sprn);
- TCGv_i32 t3 = tcg_const_i32(cause);
-
- gen_helper_fscr_facility_check(cpu_env, t1, t2, t3);
-
- tcg_temp_free_i32(t3);
- tcg_temp_free_i32(t2);
- tcg_temp_free_i32(t1);
-}
-
-static void gen_msr_facility_check(DisasContext *ctx, int facility_sprn,
- int bit, int sprn, int cause)
-{
- TCGv_i32 t1 = tcg_const_i32(bit);
- TCGv_i32 t2 = tcg_const_i32(sprn);
- TCGv_i32 t3 = tcg_const_i32(cause);
-
- gen_helper_msr_facility_check(cpu_env, t1, t2, t3);
-
- tcg_temp_free_i32(t3);
- tcg_temp_free_i32(t2);
- tcg_temp_free_i32(t1);
-}
-
-static void spr_read_prev_upper32(DisasContext *ctx, int gprn, int sprn)
-{
- TCGv spr_up = tcg_temp_new();
- TCGv spr = tcg_temp_new();
-
- gen_load_spr(spr, sprn - 1);
- tcg_gen_shri_tl(spr_up, spr, 32);
- tcg_gen_ext32u_tl(cpu_gpr[gprn], spr_up);
-
- tcg_temp_free(spr);
- tcg_temp_free(spr_up);
-}
-
-static void spr_write_prev_upper32(DisasContext *ctx, int sprn, int gprn)
-{
- TCGv spr = tcg_temp_new();
-
- gen_load_spr(spr, sprn - 1);
- tcg_gen_deposit_tl(spr, spr, cpu_gpr[gprn], 32, 32);
- gen_store_spr(sprn - 1, spr);
-
- tcg_temp_free(spr);
-}
-
-static int check_pow_970 (CPUPPCState *env)
-{
- if (env->spr[SPR_HID0] & (HID0_DEEPNAP | HID0_DOZE | HID0_NAP)) {
- return 1;
- }
-
- return 0;
-}
-
-static void gen_spr_970_hid(CPUPPCState *env)
-{
- /* Hardware implementation registers */
- /* XXX : not implemented */
- spr_register(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_clear,
- 0x60000000);
- spr_register(env, SPR_HID1, "HID1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_970_HID5, "HID5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- POWERPC970_HID5_INIT);
-}
-
-static void gen_spr_970_hior(CPUPPCState *env)
-{
- spr_register(env, SPR_HIOR, "SPR_HIOR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_hior, &spr_write_hior,
- 0x00000000);
-}
-
-static void gen_spr_book3s_common(CPUPPCState *env)
-{
- spr_register(env, SPR_CTRL, "SPR_CTRL",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_UCTRL, "SPR_UCTRL",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, SPR_NOACCESS,
- 0x00000000);
-}
-
-static void gen_spr_book3s_altivec(CPUPPCState *env)
-{
- if (!(env->insns_flags & PPC_ALTIVEC)) {
- return;
- }
-
- spr_register_kvm(env, SPR_VRSAVE, "VRSAVE",
- &spr_read_generic, &spr_write_generic,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_VRSAVE, 0x00000000);
-
- /* Can't find information on what this should be on reset. This
- * value is the one used by 74xx processors. */
- vscr_init(env, 0x00010000);
-}
-
-static void gen_spr_book3s_dbg(CPUPPCState *env)
-{
- /*
- * TODO: different specs define different scopes for these,
- * will have to address this:
- * 970: super/write and super/read
- * powerisa 2.03..2.04: hypv/write and super/read.
- * powerisa 2.05 and newer: hypv/write and hypv/read.
- */
- spr_register_kvm(env, SPR_DABR, "DABR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_DABR, 0x00000000);
- spr_register_kvm(env, SPR_DABRX, "DABRX",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_DABRX, 0x00000000);
-}
-
-static void gen_spr_book3s_207_dbg(CPUPPCState *env)
-{
- spr_register_kvm_hv(env, SPR_DAWR, "DAWR",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_DAWR, 0x00000000);
- spr_register_kvm_hv(env, SPR_DAWRX, "DAWRX",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_DAWRX, 0x00000000);
- spr_register_kvm_hv(env, SPR_CIABR, "CIABR",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_CIABR, 0x00000000);
-}
-
-static void gen_spr_970_dbg(CPUPPCState *env)
-{
- /* Breakpoints */
- spr_register(env, SPR_IABR, "IABR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-static void gen_spr_book3s_pmu_sup(CPUPPCState *env)
-{
- spr_register_kvm(env, SPR_POWER_MMCR0, "MMCR0",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_MMCR0, 0x00000000);
- spr_register_kvm(env, SPR_POWER_MMCR1, "MMCR1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_MMCR1, 0x00000000);
- spr_register_kvm(env, SPR_POWER_MMCRA, "MMCRA",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_MMCRA, 0x00000000);
- spr_register_kvm(env, SPR_POWER_PMC1, "PMC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_PMC1, 0x00000000);
- spr_register_kvm(env, SPR_POWER_PMC2, "PMC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_PMC2, 0x00000000);
- spr_register_kvm(env, SPR_POWER_PMC3, "PMC3",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_PMC3, 0x00000000);
- spr_register_kvm(env, SPR_POWER_PMC4, "PMC4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_PMC4, 0x00000000);
- spr_register_kvm(env, SPR_POWER_PMC5, "PMC5",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_PMC5, 0x00000000);
- spr_register_kvm(env, SPR_POWER_PMC6, "PMC6",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_PMC6, 0x00000000);
- spr_register_kvm(env, SPR_POWER_SIAR, "SIAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_SIAR, 0x00000000);
- spr_register_kvm(env, SPR_POWER_SDAR, "SDAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_SDAR, 0x00000000);
-}
-
-static void gen_spr_book3s_pmu_user(CPUPPCState *env)
-{
- spr_register(env, SPR_POWER_UMMCR0, "UMMCR0",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, &spr_write_ureg,
- 0x00000000);
- spr_register(env, SPR_POWER_UMMCR1, "UMMCR1",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, &spr_write_ureg,
- 0x00000000);
- spr_register(env, SPR_POWER_UMMCRA, "UMMCRA",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, &spr_write_ureg,
- 0x00000000);
- spr_register(env, SPR_POWER_UPMC1, "UPMC1",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, &spr_write_ureg,
- 0x00000000);
- spr_register(env, SPR_POWER_UPMC2, "UPMC2",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, &spr_write_ureg,
- 0x00000000);
- spr_register(env, SPR_POWER_UPMC3, "UPMC3",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, &spr_write_ureg,
- 0x00000000);
- spr_register(env, SPR_POWER_UPMC4, "UPMC4",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, &spr_write_ureg,
- 0x00000000);
- spr_register(env, SPR_POWER_UPMC5, "UPMC5",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, &spr_write_ureg,
- 0x00000000);
- spr_register(env, SPR_POWER_UPMC6, "UPMC6",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, &spr_write_ureg,
- 0x00000000);
- spr_register(env, SPR_POWER_USIAR, "USIAR",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, &spr_write_ureg,
- 0x00000000);
- spr_register(env, SPR_POWER_USDAR, "USDAR",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, &spr_write_ureg,
- 0x00000000);
-}
-
-static void gen_spr_970_pmu_sup(CPUPPCState *env)
-{
- spr_register_kvm(env, SPR_970_PMC7, "PMC7",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_PMC7, 0x00000000);
- spr_register_kvm(env, SPR_970_PMC8, "PMC8",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_PMC8, 0x00000000);
-}
-
-static void gen_spr_970_pmu_user(CPUPPCState *env)
-{
- spr_register(env, SPR_970_UPMC7, "UPMC7",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, &spr_write_ureg,
- 0x00000000);
- spr_register(env, SPR_970_UPMC8, "UPMC8",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, &spr_write_ureg,
- 0x00000000);
-}
-
-static void gen_spr_power8_pmu_sup(CPUPPCState *env)
-{
- spr_register_kvm(env, SPR_POWER_MMCR2, "MMCR2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_MMCR2, 0x00000000);
- spr_register_kvm(env, SPR_POWER_MMCRS, "MMCRS",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_MMCRS, 0x00000000);
- spr_register_kvm(env, SPR_POWER_SIER, "SIER",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_SIER, 0x00000000);
- spr_register_kvm(env, SPR_POWER_SPMC1, "SPMC1",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_SPMC1, 0x00000000);
- spr_register_kvm(env, SPR_POWER_SPMC2, "SPMC2",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_SPMC2, 0x00000000);
- spr_register_kvm(env, SPR_TACR, "TACR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_TACR, 0x00000000);
- spr_register_kvm(env, SPR_TCSCR, "TCSCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_TCSCR, 0x00000000);
- spr_register_kvm(env, SPR_CSIGR, "CSIGR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_CSIGR, 0x00000000);
-}
-
-static void gen_spr_power8_pmu_user(CPUPPCState *env)
-{
- spr_register(env, SPR_POWER_UMMCR2, "UMMCR2",
- &spr_read_ureg, SPR_NOACCESS,
- &spr_read_ureg, &spr_write_ureg,
- 0x00000000);
- spr_register(env, SPR_POWER_USIER, "USIER",
- &spr_read_generic, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-static void gen_spr_power5p_ear(CPUPPCState *env)
-{
- /* External access control */
- spr_register(env, SPR_EAR, "EAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-#if !defined(CONFIG_USER_ONLY)
-static void spr_write_hmer(DisasContext *ctx, int sprn, int gprn)
-{
- TCGv hmer = tcg_temp_new();
-
- gen_load_spr(hmer, sprn);
- tcg_gen_and_tl(hmer, cpu_gpr[gprn], hmer);
- gen_store_spr(sprn, hmer);
- spr_store_dump_spr(sprn);
- tcg_temp_free(hmer);
-}
-
-static void spr_write_lpcr(DisasContext *ctx, int sprn, int gprn)
-{
- gen_helper_store_lpcr(cpu_env, cpu_gpr[gprn]);
-}
-
-static void spr_write_970_hid4(DisasContext *ctx, int sprn, int gprn)
-{
-#if defined(TARGET_PPC64)
- spr_write_generic(ctx, sprn, gprn);
- gen_helper_store_lpcr(cpu_env, cpu_gpr[gprn]);
-#endif
-}
-
-#endif /* !defined(CONFIG_USER_ONLY) */
-
-static void gen_spr_970_lpar(CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- /* Logical partitionning */
- /* PPC970: HID4 is effectively the LPCR */
- spr_register(env, SPR_970_HID4, "HID4",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_970_hid4,
- 0x00000000);
-#endif
-}
-
-static void gen_spr_power5p_lpar(CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- /* Logical partitionning */
- spr_register_kvm_hv(env, SPR_LPCR, "LPCR",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_lpcr,
- KVM_REG_PPC_LPCR, LPCR_LPES0 | LPCR_LPES1);
- spr_register_hv(env, SPR_HDEC, "HDEC",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_hdecr, &spr_write_hdecr, 0);
-#endif
-}
-
-static void gen_spr_book3s_ids(CPUPPCState *env)
-{
- /* FIXME: Will need to deal with thread vs core only SPRs */
-
- /* Processor identification */
- spr_register_hv(env, SPR_PIR, "PIR",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, NULL,
- 0x00000000);
- spr_register_hv(env, SPR_HID0, "HID0",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register_hv(env, SPR_TSCR, "TSCR",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register_hv(env, SPR_HMER, "HMER",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_hmer,
- 0x00000000);
- spr_register_hv(env, SPR_HMEER, "HMEER",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register_hv(env, SPR_TFMR, "TFMR",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register_hv(env, SPR_LPIDR, "LPIDR",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register_hv(env, SPR_HFSCR, "HFSCR",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register_hv(env, SPR_MMCRC, "MMCRC",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register_hv(env, SPR_MMCRH, "MMCRH",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register_hv(env, SPR_HSPRG0, "HSPRG0",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register_hv(env, SPR_HSPRG1, "HSPRG1",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register_hv(env, SPR_HSRR0, "HSRR0",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register_hv(env, SPR_HSRR1, "HSRR1",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register_hv(env, SPR_HDAR, "HDAR",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register_hv(env, SPR_HDSISR, "HDSISR",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register_hv(env, SPR_RMOR, "RMOR",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register_hv(env, SPR_HRMOR, "HRMOR",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
-}
-
-static void gen_spr_power8_ids(CPUPPCState *env)
-{
- /* Thread identification */
- spr_register(env, SPR_TIR, "TIR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- 0x00000000);
-}
-
-static void gen_spr_book3s_purr(CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- /* PURR & SPURR: Hack - treat these as aliases for the TB for now */
- spr_register_kvm(env, SPR_PURR, "PURR",
- &spr_read_purr, SPR_NOACCESS,
- &spr_read_purr, SPR_NOACCESS,
- KVM_REG_PPC_PURR, 0x00000000);
- spr_register_kvm(env, SPR_SPURR, "SPURR",
- &spr_read_purr, SPR_NOACCESS,
- &spr_read_purr, SPR_NOACCESS,
- KVM_REG_PPC_SPURR, 0x00000000);
-#endif
-}
-
-static void gen_spr_power6_dbg(CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- spr_register(env, SPR_CFAR, "SPR_CFAR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_cfar, &spr_write_cfar,
- 0x00000000);
-#endif
-}
-
-static void gen_spr_power5p_common(CPUPPCState *env)
-{
- spr_register_kvm(env, SPR_PPR, "PPR",
- &spr_read_generic, &spr_write_generic,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_PPR, 0x00000000);
-}
-
-static void gen_spr_power6_common(CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- spr_register_kvm(env, SPR_DSCR, "SPR_DSCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_DSCR, 0x00000000);
-#endif
- /*
- * Register PCR to report POWERPC_EXCP_PRIV_REG instead of
- * POWERPC_EXCP_INVAL_SPR.
- */
- spr_register(env, SPR_PCR, "PCR",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- 0x00000000);
-}
-
-static void spr_read_tar(DisasContext *ctx, int gprn, int sprn)
-{
- gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
- spr_read_generic(ctx, gprn, sprn);
-}
-
-static void spr_write_tar(DisasContext *ctx, int sprn, int gprn)
-{
- gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_TAR, sprn, FSCR_IC_TAR);
- spr_write_generic(ctx, sprn, gprn);
-}
-
-static void gen_spr_power8_tce_address_control(CPUPPCState *env)
-{
- spr_register_kvm(env, SPR_TAR, "TAR",
- &spr_read_tar, &spr_write_tar,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_TAR, 0x00000000);
-}
-
-static void spr_read_tm(DisasContext *ctx, int gprn, int sprn)
-{
- gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
- spr_read_generic(ctx, gprn, sprn);
-}
-
-static void spr_write_tm(DisasContext *ctx, int sprn, int gprn)
-{
- gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
- spr_write_generic(ctx, sprn, gprn);
-}
-
-static void spr_read_tm_upper32(DisasContext *ctx, int gprn, int sprn)
-{
- gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
- spr_read_prev_upper32(ctx, gprn, sprn);
-}
-
-static void spr_write_tm_upper32(DisasContext *ctx, int sprn, int gprn)
-{
- gen_msr_facility_check(ctx, SPR_FSCR, MSR_TM, sprn, FSCR_IC_TM);
- spr_write_prev_upper32(ctx, sprn, gprn);
-}
-
-static void gen_spr_power8_tm(CPUPPCState *env)
-{
- spr_register_kvm(env, SPR_TFHAR, "TFHAR",
- &spr_read_tm, &spr_write_tm,
- &spr_read_tm, &spr_write_tm,
- KVM_REG_PPC_TFHAR, 0x00000000);
- spr_register_kvm(env, SPR_TFIAR, "TFIAR",
- &spr_read_tm, &spr_write_tm,
- &spr_read_tm, &spr_write_tm,
- KVM_REG_PPC_TFIAR, 0x00000000);
- spr_register_kvm(env, SPR_TEXASR, "TEXASR",
- &spr_read_tm, &spr_write_tm,
- &spr_read_tm, &spr_write_tm,
- KVM_REG_PPC_TEXASR, 0x00000000);
- spr_register(env, SPR_TEXASRU, "TEXASRU",
- &spr_read_tm_upper32, &spr_write_tm_upper32,
- &spr_read_tm_upper32, &spr_write_tm_upper32,
- 0x00000000);
-}
-
-static void spr_read_ebb(DisasContext *ctx, int gprn, int sprn)
-{
- gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
- spr_read_generic(ctx, gprn, sprn);
-}
-
-static void spr_write_ebb(DisasContext *ctx, int sprn, int gprn)
-{
- gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
- spr_write_generic(ctx, sprn, gprn);
-}
-
-static void spr_read_ebb_upper32(DisasContext *ctx, int gprn, int sprn)
-{
- gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
- spr_read_prev_upper32(ctx, gprn, sprn);
-}
-
-static void spr_write_ebb_upper32(DisasContext *ctx, int sprn, int gprn)
-{
- gen_fscr_facility_check(ctx, SPR_FSCR, FSCR_EBB, sprn, FSCR_IC_EBB);
- spr_write_prev_upper32(ctx, sprn, gprn);
-}
-
-static void gen_spr_power8_ebb(CPUPPCState *env)
-{
- spr_register(env, SPR_BESCRS, "BESCRS",
- &spr_read_ebb, &spr_write_ebb,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BESCRSU, "BESCRSU",
- &spr_read_ebb_upper32, &spr_write_ebb_upper32,
- &spr_read_prev_upper32, &spr_write_prev_upper32,
- 0x00000000);
- spr_register(env, SPR_BESCRR, "BESCRR",
- &spr_read_ebb, &spr_write_ebb,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BESCRRU, "BESCRRU",
- &spr_read_ebb_upper32, &spr_write_ebb_upper32,
- &spr_read_prev_upper32, &spr_write_prev_upper32,
- 0x00000000);
- spr_register_kvm(env, SPR_EBBHR, "EBBHR",
- &spr_read_ebb, &spr_write_ebb,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_EBBHR, 0x00000000);
- spr_register_kvm(env, SPR_EBBRR, "EBBRR",
- &spr_read_ebb, &spr_write_ebb,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_EBBRR, 0x00000000);
- spr_register_kvm(env, SPR_BESCR, "BESCR",
- &spr_read_ebb, &spr_write_ebb,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_BESCR, 0x00000000);
-}
-
-/* Virtual Time Base */
-static void gen_spr_vtb(CPUPPCState *env)
-{
- spr_register(env, SPR_VTB, "VTB",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_tbl, SPR_NOACCESS,
- 0x00000000);
-}
-
-static void gen_spr_power8_fscr(CPUPPCState *env)
-{
-#if defined(CONFIG_USER_ONLY)
- target_ulong initval = 1ULL << FSCR_TAR;
-#else
- target_ulong initval = 0;
-#endif
- spr_register_kvm(env, SPR_FSCR, "FSCR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_FSCR, initval);
-}
-
-static void gen_spr_power8_pspb(CPUPPCState *env)
-{
- spr_register_kvm(env, SPR_PSPB, "PSPB",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic32,
- KVM_REG_PPC_PSPB, 0);
-}
-
-static void gen_spr_power8_ic(CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- spr_register_hv(env, SPR_IC, "IC",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0);
-#endif
-}
-
-static void gen_spr_power8_book4(CPUPPCState *env)
-{
- /* Add a number of P8 book4 registers */
-#if !defined(CONFIG_USER_ONLY)
- spr_register_kvm(env, SPR_ACOP, "ACOP",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_ACOP, 0);
- spr_register_kvm(env, SPR_BOOKS_PID, "PID",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_PID, 0);
- spr_register_kvm(env, SPR_WORT, "WORT",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_WORT, 0);
-#endif
-}
-
-static void gen_spr_power7_book4(CPUPPCState *env)
-{
- /* Add a number of P7 book4 registers */
-#if !defined(CONFIG_USER_ONLY)
- spr_register_kvm(env, SPR_ACOP, "ACOP",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_ACOP, 0);
- spr_register_kvm(env, SPR_BOOKS_PID, "PID",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- KVM_REG_PPC_PID, 0);
-#endif
-}
-
-static void gen_spr_power8_rpr(CPUPPCState *env)
-{
-#if !defined(CONFIG_USER_ONLY)
- spr_register_hv(env, SPR_RPR, "RPR",
- SPR_NOACCESS, SPR_NOACCESS,
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000103070F1F3F);
-#endif
-}
-
-static void init_proc_book3s_64(CPUPPCState *env, int version)
-{
- gen_spr_ne_601(env);
- gen_tbl(env);
- gen_spr_book3s_altivec(env);
- gen_spr_book3s_pmu_sup(env);
- gen_spr_book3s_pmu_user(env);
- gen_spr_book3s_common(env);
-
- switch (version) {
- case BOOK3S_CPU_970:
- case BOOK3S_CPU_POWER5PLUS:
- gen_spr_970_hid(env);
- gen_spr_970_hior(env);
- gen_low_BATs(env);
- gen_spr_970_pmu_sup(env);
- gen_spr_970_pmu_user(env);
- break;
- case BOOK3S_CPU_POWER7:
- case BOOK3S_CPU_POWER8:
- case BOOK3S_CPU_POWER9:
- gen_spr_book3s_ids(env);
- gen_spr_amr(env, version >= BOOK3S_CPU_POWER8);
- gen_spr_book3s_purr(env);
- env->ci_large_pages = true;
- break;
- default:
- g_assert_not_reached();
- }
- if (version >= BOOK3S_CPU_POWER5PLUS) {
- gen_spr_power5p_common(env);
- gen_spr_power5p_lpar(env);
- gen_spr_power5p_ear(env);
- } else {
- gen_spr_970_lpar(env);
- }
- if (version == BOOK3S_CPU_970) {
- gen_spr_970_dbg(env);
- }
- if (version >= BOOK3S_CPU_POWER6) {
- gen_spr_power6_common(env);
- gen_spr_power6_dbg(env);
- }
- if (version == BOOK3S_CPU_POWER7) {
- gen_spr_power7_book4(env);
- }
- if (version >= BOOK3S_CPU_POWER8) {
- gen_spr_power8_tce_address_control(env);
- gen_spr_power8_ids(env);
- gen_spr_power8_ebb(env);
- gen_spr_power8_fscr(env);
- gen_spr_power8_pmu_sup(env);
- gen_spr_power8_pmu_user(env);
- gen_spr_power8_tm(env);
- gen_spr_power8_pspb(env);
- gen_spr_vtb(env);
- gen_spr_power8_ic(env);
- gen_spr_power8_book4(env);
- gen_spr_power8_rpr(env);
- }
- if (version < BOOK3S_CPU_POWER8) {
- gen_spr_book3s_dbg(env);
- } else {
- gen_spr_book3s_207_dbg(env);
- }
-#if !defined(CONFIG_USER_ONLY)
- switch (version) {
- case BOOK3S_CPU_970:
- case BOOK3S_CPU_POWER5PLUS:
- env->slb_nr = 64;
- break;
- case BOOK3S_CPU_POWER7:
- case BOOK3S_CPU_POWER8:
- case BOOK3S_CPU_POWER9:
- default:
- env->slb_nr = 32;
- break;
- }
-#endif
- /* Allocate hardware IRQ controller */
- switch (version) {
- case BOOK3S_CPU_970:
- case BOOK3S_CPU_POWER5PLUS:
- init_excp_970(env);
- ppc970_irq_init(ppc_env_get_cpu(env));
- break;
- case BOOK3S_CPU_POWER7:
- init_excp_POWER7(env);
- ppcPOWER7_irq_init(ppc_env_get_cpu(env));
- break;
- case BOOK3S_CPU_POWER8:
- case BOOK3S_CPU_POWER9:
- init_excp_POWER8(env);
- ppcPOWER7_irq_init(ppc_env_get_cpu(env));
- break;
- default:
- g_assert_not_reached();
- }
-
- env->dcache_line_size = 128;
- env->icache_line_size = 128;
-}
-
-static void init_proc_970(CPUPPCState *env)
-{
- init_proc_book3s_64(env, BOOK3S_CPU_970);
-}
-
-POWERPC_FAMILY(970)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->desc = "PowerPC 970";
- pcc->init_proc = init_proc_970;
- pcc->check_pow = check_pow_970;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
- PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_64B | PPC_ALTIVEC |
- PPC_SEGMENT_64B | PPC_SLBI;
- pcc->insns_flags2 = PPC2_FP_CVT_S64;
- pcc->msr_mask = (1ull << MSR_SF) |
- (1ull << MSR_VR) |
- (1ull << MSR_POW) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI);
- pcc->mmu_model = POWERPC_MMU_64B;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
-#endif
- pcc->excp_model = POWERPC_EXCP_970;
- pcc->bus_model = PPC_FLAGS_INPUT_970;
- pcc->bfd_mach = bfd_mach_ppc64;
- pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
- POWERPC_FLAG_BUS_CLK;
- pcc->l1_dcache_size = 0x8000;
- pcc->l1_icache_size = 0x10000;
-}
-
-static void init_proc_power5plus(CPUPPCState *env)
-{
- init_proc_book3s_64(env, BOOK3S_CPU_POWER5PLUS);
-}
-
-POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->fw_name = "PowerPC,POWER5";
- dc->desc = "POWER5+";
- pcc->init_proc = init_proc_power5plus;
- pcc->check_pow = check_pow_970;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
- PPC_FLOAT_STFIWX |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_64B |
- PPC_SEGMENT_64B | PPC_SLBI;
- pcc->insns_flags2 = PPC2_FP_CVT_S64;
- pcc->msr_mask = (1ull << MSR_SF) |
- (1ull << MSR_VR) |
- (1ull << MSR_POW) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI);
- pcc->mmu_model = POWERPC_MMU_2_03;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
-#endif
- pcc->excp_model = POWERPC_EXCP_970;
- pcc->bus_model = PPC_FLAGS_INPUT_970;
- pcc->bfd_mach = bfd_mach_ppc64;
- pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
- POWERPC_FLAG_BUS_CLK;
- pcc->l1_dcache_size = 0x8000;
- pcc->l1_icache_size = 0x10000;
-}
-
-static void powerpc_get_compat(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
-{
- char *value = (char *)"";
- Property *prop = opaque;
- uint32_t *max_compat = qdev_get_prop_ptr(DEVICE(obj), prop);
-
- switch (*max_compat) {
- case CPU_POWERPC_LOGICAL_2_05:
- value = (char *)"power6";
- break;
- case CPU_POWERPC_LOGICAL_2_06:
- value = (char *)"power7";
- break;
- case CPU_POWERPC_LOGICAL_2_07:
- value = (char *)"power8";
- break;
- case 0:
- break;
- default:
- error_report("Internal error: compat is set to %x", *max_compat);
- abort();
- break;
- }
-
- visit_type_str(v, name, &value, errp);
-}
-
-static void powerpc_set_compat(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
-{
- Error *error = NULL;
- char *value = NULL;
- Property *prop = opaque;
- uint32_t *max_compat = qdev_get_prop_ptr(DEVICE(obj), prop);
-
- visit_type_str(v, name, &value, &error);
- if (error) {
- error_propagate(errp, error);
- return;
- }
-
- if (strcmp(value, "power6") == 0) {
- *max_compat = CPU_POWERPC_LOGICAL_2_05;
- } else if (strcmp(value, "power7") == 0) {
- *max_compat = CPU_POWERPC_LOGICAL_2_06;
- } else if (strcmp(value, "power8") == 0) {
- *max_compat = CPU_POWERPC_LOGICAL_2_07;
- } else {
- error_setg(errp, "Invalid compatibility mode \"%s\"", value);
- }
-
- g_free(value);
-}
-
-static PropertyInfo powerpc_compat_propinfo = {
- .name = "str",
- .description = "compatibility mode, power6/power7/power8",
- .get = powerpc_get_compat,
- .set = powerpc_set_compat,
-};
-
-#define DEFINE_PROP_POWERPC_COMPAT(_n, _s, _f) \
- DEFINE_PROP(_n, _s, _f, powerpc_compat_propinfo, uint32_t)
-
-static Property powerpc_servercpu_properties[] = {
- DEFINE_PROP_POWERPC_COMPAT("compat", PowerPCCPU, max_compat),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-#ifdef CONFIG_SOFTMMU
-static const struct ppc_segment_page_sizes POWER7_POWER8_sps = {
- .sps = {
- {
- .page_shift = 12, /* 4K */
- .slb_enc = 0,
- .enc = { { .page_shift = 12, .pte_enc = 0 },
- { .page_shift = 16, .pte_enc = 0x7 },
- { .page_shift = 24, .pte_enc = 0x38 }, },
- },
- {
- .page_shift = 16, /* 64K */
- .slb_enc = SLB_VSID_64K,
- .enc = { { .page_shift = 16, .pte_enc = 0x1 },
- { .page_shift = 24, .pte_enc = 0x8 }, },
- },
- {
- .page_shift = 24, /* 16M */
- .slb_enc = SLB_VSID_16M,
- .enc = { { .page_shift = 24, .pte_enc = 0 }, },
- },
- {
- .page_shift = 34, /* 16G */
- .slb_enc = SLB_VSID_16G,
- .enc = { { .page_shift = 34, .pte_enc = 0x3 }, },
- },
- }
-};
-#endif /* CONFIG_SOFTMMU */
-
-static void init_proc_POWER7 (CPUPPCState *env)
-{
- init_proc_book3s_64(env, BOOK3S_CPU_POWER7);
-}
-
-static bool ppc_pvr_match_power7(PowerPCCPUClass *pcc, uint32_t pvr)
-{
- if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7P_BASE) {
- return true;
- }
- if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER7_BASE) {
- return true;
- }
- return false;
-}
-
-static bool cpu_has_work_POWER7(CPUState *cs)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
-
- if (cs->halted) {
- if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
- return false;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
- (env->spr[SPR_LPCR] & LPCR_P7_PECE0)) {
- return true;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
- (env->spr[SPR_LPCR] & LPCR_P7_PECE1)) {
- return true;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
- (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
- return true;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
- (env->spr[SPR_LPCR] & LPCR_P7_PECE2)) {
- return true;
- }
- if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
- return true;
- }
- return false;
- } else {
- return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
- }
-}
-
-POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
- CPUClass *cc = CPU_CLASS(oc);
-
- dc->fw_name = "PowerPC,POWER7";
- dc->desc = "POWER7";
- dc->props = powerpc_servercpu_properties;
- pcc->pvr_match = ppc_pvr_match_power7;
- pcc->pcr_mask = PCR_VEC_DIS | PCR_VSX_DIS | PCR_COMPAT_2_05;
- pcc->pcr_supported = PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
- pcc->init_proc = init_proc_POWER7;
- pcc->check_pow = check_pow_nocheck;
- cc->has_work = cpu_has_work_POWER7;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
- PPC_FLOAT_FRSQRTES |
- PPC_FLOAT_STFIWX |
- PPC_FLOAT_EXT |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
- PPC_SEGMENT_64B | PPC_SLBI |
- PPC_POPCNTB | PPC_POPCNTWD |
- PPC_CILDST;
- pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |
- PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
- PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
- PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64 |
- PPC2_PM_ISA206;
- pcc->msr_mask = (1ull << MSR_SF) |
- (1ull << MSR_VR) |
- (1ull << MSR_VSX) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_2_06;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
- pcc->sps = &POWER7_POWER8_sps;
-#endif
- pcc->excp_model = POWERPC_EXCP_POWER7;
- pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
- pcc->bfd_mach = bfd_mach_ppc64;
- pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
- POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
- POWERPC_FLAG_VSX;
- pcc->l1_dcache_size = 0x8000;
- pcc->l1_icache_size = 0x8000;
- pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
-}
-
-static void init_proc_POWER8(CPUPPCState *env)
-{
- init_proc_book3s_64(env, BOOK3S_CPU_POWER8);
-}
-
-static bool ppc_pvr_match_power8(PowerPCCPUClass *pcc, uint32_t pvr)
-{
- if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8NVL_BASE) {
- return true;
- }
- if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8E_BASE) {
- return true;
- }
- if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER8_BASE) {
- return true;
- }
- return false;
-}
-
-static bool cpu_has_work_POWER8(CPUState *cs)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
-
- if (cs->halted) {
- if (!(cs->interrupt_request & CPU_INTERRUPT_HARD)) {
- return false;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_EXT)) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE2)) {
- return true;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DECR)) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE3)) {
- return true;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_MCK)) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
- return true;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HMI)) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE4)) {
- return true;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_DOORBELL)) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE0)) {
- return true;
- }
- if ((env->pending_interrupts & (1u << PPC_INTERRUPT_HDOORBELL)) &&
- (env->spr[SPR_LPCR] & LPCR_P8_PECE1)) {
- return true;
- }
- if (env->pending_interrupts & (1u << PPC_INTERRUPT_RESET)) {
- return true;
- }
- return false;
- } else {
- return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
- }
-}
-
-POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
- CPUClass *cc = CPU_CLASS(oc);
-
- dc->fw_name = "PowerPC,POWER8";
- dc->desc = "POWER8";
- dc->props = powerpc_servercpu_properties;
- pcc->pvr_match = ppc_pvr_match_power8;
- pcc->pcr_mask = PCR_TM_DIS | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
- pcc->pcr_supported = PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
- pcc->init_proc = init_proc_POWER8;
- pcc->check_pow = check_pow_nocheck;
- cc->has_work = cpu_has_work_POWER8;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
- PPC_FLOAT_FRSQRTES |
- PPC_FLOAT_STFIWX |
- PPC_FLOAT_EXT |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |
- PPC_SEGMENT_64B | PPC_SLBI |
- PPC_POPCNTB | PPC_POPCNTWD |
- PPC_CILDST;
- pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
- PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
- PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
- 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;
- pcc->msr_mask = (1ull << MSR_SF) |
- (1ull << MSR_SHV) |
- (1ull << MSR_TM) |
- (1ull << MSR_VR) |
- (1ull << MSR_VSX) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- pcc->mmu_model = POWERPC_MMU_2_07;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
- pcc->sps = &POWER7_POWER8_sps;
-#endif
- pcc->excp_model = POWERPC_EXCP_POWER8;
- pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
- pcc->bfd_mach = bfd_mach_ppc64;
- pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
- POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
- POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
- pcc->l1_dcache_size = 0x8000;
- pcc->l1_icache_size = 0x8000;
- pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
-}
-static void init_proc_POWER9(CPUPPCState *env)
-{
- init_proc_book3s_64(env, BOOK3S_CPU_POWER9);
-}
-
-static bool ppc_pvr_match_power9(PowerPCCPUClass *pcc, uint32_t pvr)
-{
- if ((pvr & CPU_POWERPC_POWER_SERVER_MASK) == CPU_POWERPC_POWER9_BASE) {
- return true;
- }
- return false;
-}
-
-POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(oc);
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- dc->fw_name = "PowerPC,POWER9";
- dc->desc = "POWER9";
- dc->props = powerpc_servercpu_properties;
- pcc->pvr_match = ppc_pvr_match_power9;
- pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07;
- pcc->init_proc = init_proc_POWER9;
- pcc->check_pow = check_pow_nocheck;
- pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |
- PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
- PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
- PPC_FLOAT_FRSQRTES |
- PPC_FLOAT_STFIWX |
- PPC_FLOAT_EXT |
- PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
- PPC_MEM_SYNC | PPC_MEM_EIEIO |
- PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
- PPC_64B | PPC_64BX | PPC_ALTIVEC |
- PPC_SEGMENT_64B | PPC_SLBI |
- PPC_POPCNTB | PPC_POPCNTWD |
- PPC_CILDST;
- pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |
- PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |
- PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |
- 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_ISA300;
- pcc->msr_mask = (1ull << MSR_SF) |
- (1ull << MSR_TM) |
- (1ull << MSR_VR) |
- (1ull << MSR_VSX) |
- (1ull << MSR_EE) |
- (1ull << MSR_PR) |
- (1ull << MSR_FP) |
- (1ull << MSR_ME) |
- (1ull << MSR_FE0) |
- (1ull << MSR_SE) |
- (1ull << MSR_DE) |
- (1ull << MSR_FE1) |
- (1ull << MSR_IR) |
- (1ull << MSR_DR) |
- (1ull << MSR_PMM) |
- (1ull << MSR_RI) |
- (1ull << MSR_LE);
- /* Using 2.07 defines until new radix model is added. */
- pcc->mmu_model = POWERPC_MMU_2_07;
-#if defined(CONFIG_SOFTMMU)
- pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
- /* segment page size remain the same */
- pcc->sps = &POWER7_POWER8_sps;
-#endif
- pcc->excp_model = POWERPC_EXCP_POWER8;
- pcc->bus_model = PPC_FLAGS_INPUT_POWER7;
- pcc->bfd_mach = bfd_mach_ppc64;
- pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
- POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
- POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |
- POWERPC_FLAG_VSX | POWERPC_FLAG_TM;
- pcc->l1_dcache_size = 0x8000;
- pcc->l1_icache_size = 0x8000;
- pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;
-}
-
-#if !defined(CONFIG_USER_ONLY)
-
-void cpu_ppc_set_papr(PowerPCCPU *cpu)
-{
- CPUPPCState *env = &cpu->env;
- ppc_spr_t *lpcr = &env->spr_cb[SPR_LPCR];
- ppc_spr_t *amor = &env->spr_cb[SPR_AMOR];
-
- /* PAPR always has exception vectors in RAM not ROM. To ensure this,
- * MSR[IP] should never be set.
- *
- * We also disallow setting of MSR_HV
- */
- env->msr_mask &= ~((1ull << MSR_EP) | MSR_HVB);
-
- /* Set emulated LPCR to not send interrupts to hypervisor. Note that
- * under KVM, the actual HW LPCR will be set differently by KVM itself,
- * the settings below ensure proper operations with TCG in absence of
- * a real hypervisor.
- *
- * Clearing VPM0 will also cause us to use RMOR in mmu-hash64.c for
- * real mode accesses, which thankfully defaults to 0 and isn't
- * accessible in guest mode.
- */
- lpcr->default_value &= ~(LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV);
- lpcr->default_value |= LPCR_LPES0 | LPCR_LPES1;
-
- /* Set RMLS to the max (ie, 16G) */
- lpcr->default_value &= ~LPCR_RMLS;
- lpcr->default_value |= 1ull << LPCR_RMLS_SHIFT;
-
- /* P7 and P8 has slightly different PECE bits, mostly because P8 adds
- * bit 47 and 48 which are reserved on P7. Here we set them all, which
- * will work as expected for both implementations
- */
- lpcr->default_value |= LPCR_P8_PECE0 | LPCR_P8_PECE1 | LPCR_P8_PECE2 |
- LPCR_P8_PECE3 | LPCR_P8_PECE4;
-
- /* We should be followed by a CPU reset but update the active value
- * just in case...
- */
- env->spr[SPR_LPCR] = lpcr->default_value;
-
- /* Set a full AMOR so guest can use the AMR as it sees fit */
- env->spr[SPR_AMOR] = amor->default_value = 0xffffffffffffffffull;
-
- /* Update some env bits based on new LPCR value */
- ppc_hash64_update_rmls(env);
- ppc_hash64_update_vrma(env);
-
- /* Tell KVM that we're in PAPR mode */
- if (kvm_enabled()) {
- kvmppc_set_papr(cpu);
- }
-}
-
-#endif /* !defined(CONFIG_USER_ONLY) */
-
-#endif /* defined (TARGET_PPC64) */
-
-/*****************************************************************************/
-/* Generic CPU instantiation routine */
-static void init_ppc_proc(PowerPCCPU *cpu)
-{
- PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
- CPUPPCState *env = &cpu->env;
-#if !defined(CONFIG_USER_ONLY)
- int i;
-
- env->irq_inputs = NULL;
- /* Set all exception vectors to an invalid address */
- for (i = 0; i < POWERPC_EXCP_NB; i++)
- env->excp_vectors[i] = (target_ulong)(-1ULL);
- env->ivor_mask = 0x00000000;
- env->ivpr_mask = 0x00000000;
- /* Default MMU definitions */
- env->nb_BATs = 0;
- env->nb_tlb = 0;
- env->nb_ways = 0;
- env->tlb_type = TLB_NONE;
-#endif
- /* Register SPR common to all PowerPC implementations */
- gen_spr_generic(env);
- spr_register(env, SPR_PVR, "PVR",
- /* Linux permits userspace to read PVR */
-#if defined(CONFIG_LINUX_USER)
- &spr_read_generic,
-#else
- SPR_NOACCESS,
-#endif
- SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- pcc->pvr);
- /* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
- if (pcc->svr != POWERPC_SVR_NONE) {
- if (pcc->svr & POWERPC_SVR_E500) {
- spr_register(env, SPR_E500_SVR, "SVR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- pcc->svr & ~POWERPC_SVR_E500);
- } else {
- spr_register(env, SPR_SVR, "SVR",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- pcc->svr);
- }
- }
- /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
- (*pcc->init_proc)(env);
-
- /* MSR bits & flags consistency checks */
- if (env->msr_mask & (1 << 25)) {
- switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
- case POWERPC_FLAG_SPE:
- case POWERPC_FLAG_VRE:
- break;
- default:
- fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
- exit(1);
- }
- } else if (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
- fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
- exit(1);
- }
- if (env->msr_mask & (1 << 17)) {
- switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
- case POWERPC_FLAG_TGPR:
- case POWERPC_FLAG_CE:
- break;
- default:
- fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
- exit(1);
- }
- } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
- fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
- exit(1);
- }
- if (env->msr_mask & (1 << 10)) {
- switch (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
- POWERPC_FLAG_UBLE)) {
- case POWERPC_FLAG_SE:
- case POWERPC_FLAG_DWE:
- case POWERPC_FLAG_UBLE:
- break;
- default:
- fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
- "POWERPC_FLAG_UBLE\n");
- exit(1);
- }
- } else if (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
- POWERPC_FLAG_UBLE)) {
- fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
- "POWERPC_FLAG_UBLE\n");
- exit(1);
- }
- if (env->msr_mask & (1 << 9)) {
- switch (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
- case POWERPC_FLAG_BE:
- case POWERPC_FLAG_DE:
- break;
- default:
- fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should define POWERPC_FLAG_BE or POWERPC_FLAG_DE\n");
- exit(1);
- }
- } else if (env->flags & (POWERPC_FLAG_BE | POWERPC_FLAG_DE)) {
- fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should not define POWERPC_FLAG_BE nor POWERPC_FLAG_DE\n");
- exit(1);
- }
- if (env->msr_mask & (1 << 2)) {
- switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
- case POWERPC_FLAG_PX:
- case POWERPC_FLAG_PMM:
- break;
- default:
- fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
- exit(1);
- }
- } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
- fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
- exit(1);
- }
- if ((env->flags & (POWERPC_FLAG_RTC_CLK | POWERPC_FLAG_BUS_CLK)) == 0) {
- fprintf(stderr, "PowerPC flags inconsistency\n"
- "Should define the time-base and decrementer clock source\n");
- exit(1);
- }
- /* Allocate TLBs buffer when needed */
-#if !defined(CONFIG_USER_ONLY)
- if (env->nb_tlb != 0) {
- int nb_tlb = env->nb_tlb;
- if (env->id_tlbs != 0)
- nb_tlb *= 2;
- switch (env->tlb_type) {
- case TLB_6XX:
- env->tlb.tlb6 = g_malloc0(nb_tlb * sizeof(ppc6xx_tlb_t));
- break;
- case TLB_EMB:
- env->tlb.tlbe = g_malloc0(nb_tlb * sizeof(ppcemb_tlb_t));
- break;
- case TLB_MAS:
- env->tlb.tlbm = g_malloc0(nb_tlb * sizeof(ppcmas_tlb_t));
- break;
- }
- /* Pre-compute some useful values */
- env->tlb_per_way = env->nb_tlb / env->nb_ways;
- }
- if (env->irq_inputs == NULL) {
- fprintf(stderr, "WARNING: no internal IRQ controller registered.\n"
- " Attempt QEMU to crash very soon !\n");
- }
-#endif
- if (env->check_pow == NULL) {
- fprintf(stderr, "WARNING: no power management check handler "
- "registered.\n"
- " Attempt QEMU to crash very soon !\n");
- }
-}
-
-#if defined(PPC_DUMP_CPU)
-static void dump_ppc_sprs (CPUPPCState *env)
-{
- ppc_spr_t *spr;
-#if !defined(CONFIG_USER_ONLY)
- uint32_t sr, sw;
-#endif
- uint32_t ur, uw;
- int i, j, n;
-
- printf("Special purpose registers:\n");
- for (i = 0; i < 32; i++) {
- for (j = 0; j < 32; j++) {
- n = (i << 5) | j;
- spr = &env->spr_cb[n];
- uw = spr->uea_write != NULL && spr->uea_write != SPR_NOACCESS;
- ur = spr->uea_read != NULL && spr->uea_read != SPR_NOACCESS;
-#if !defined(CONFIG_USER_ONLY)
- sw = spr->oea_write != NULL && spr->oea_write != SPR_NOACCESS;
- sr = spr->oea_read != NULL && spr->oea_read != SPR_NOACCESS;
- if (sw || sr || uw || ur) {
- printf("SPR: %4d (%03x) %-8s s%c%c u%c%c\n",
- (i << 5) | j, (i << 5) | j, spr->name,
- sw ? 'w' : '-', sr ? 'r' : '-',
- uw ? 'w' : '-', ur ? 'r' : '-');
- }
-#else
- if (uw || ur) {
- printf("SPR: %4d (%03x) %-8s u%c%c\n",
- (i << 5) | j, (i << 5) | j, spr->name,
- uw ? 'w' : '-', ur ? 'r' : '-');
- }
-#endif
- }
- }
- fflush(stdout);
- fflush(stderr);
-}
-#endif
-
-/*****************************************************************************/
-
-/* Opcode types */
-enum {
- PPC_DIRECT = 0, /* Opcode routine */
- PPC_INDIRECT = 1, /* Indirect opcode table */
-};
-
-#define PPC_OPCODE_MASK 0x3
-
-static inline int is_indirect_opcode (void *handler)
-{
- return ((uintptr_t)handler & PPC_OPCODE_MASK) == PPC_INDIRECT;
-}
-
-static inline opc_handler_t **ind_table(void *handler)
-{
- return (opc_handler_t **)((uintptr_t)handler & ~PPC_OPCODE_MASK);
-}
-
-/* Instruction table creation */
-/* Opcodes tables creation */
-static void fill_new_table (opc_handler_t **table, int len)
-{
- int i;
-
- for (i = 0; i < len; i++)
- table[i] = &invalid_handler;
-}
-
-static int create_new_table (opc_handler_t **table, unsigned char idx)
-{
- opc_handler_t **tmp;
-
- tmp = g_new(opc_handler_t *, PPC_CPU_INDIRECT_OPCODES_LEN);
- fill_new_table(tmp, PPC_CPU_INDIRECT_OPCODES_LEN);
- table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT);
-
- return 0;
-}
-
-static int insert_in_table (opc_handler_t **table, unsigned char idx,
- opc_handler_t *handler)
-{
- if (table[idx] != &invalid_handler)
- return -1;
- table[idx] = handler;
-
- return 0;
-}
-
-static int register_direct_insn (opc_handler_t **ppc_opcodes,
- unsigned char idx, opc_handler_t *handler)
-{
- if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
- printf("*** ERROR: opcode %02x already assigned in main "
- "opcode table\n", idx);
-#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
- printf(" Registered handler '%s' - new handler '%s'\n",
- ppc_opcodes[idx]->oname, handler->oname);
-#endif
- return -1;
- }
-
- return 0;
-}
-
-static int register_ind_in_table (opc_handler_t **table,
- unsigned char idx1, unsigned char idx2,
- opc_handler_t *handler)
-{
- if (table[idx1] == &invalid_handler) {
- if (create_new_table(table, idx1) < 0) {
- printf("*** ERROR: unable to create indirect table "
- "idx=%02x\n", idx1);
- return -1;
- }
- } else {
- if (!is_indirect_opcode(table[idx1])) {
- printf("*** ERROR: idx %02x already assigned to a direct "
- "opcode\n", idx1);
-#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
- printf(" Registered handler '%s' - new handler '%s'\n",
- ind_table(table[idx1])[idx2]->oname, handler->oname);
-#endif
- return -1;
- }
- }
- if (handler != NULL &&
- insert_in_table(ind_table(table[idx1]), idx2, handler) < 0) {
- printf("*** ERROR: opcode %02x already assigned in "
- "opcode table %02x\n", idx2, idx1);
-#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
- printf(" Registered handler '%s' - new handler '%s'\n",
- ind_table(table[idx1])[idx2]->oname, handler->oname);
-#endif
- return -1;
- }
-
- return 0;
-}
-
-static int register_ind_insn (opc_handler_t **ppc_opcodes,
- unsigned char idx1, unsigned char idx2,
- opc_handler_t *handler)
-{
- return register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
-}
-
-static int register_dblind_insn (opc_handler_t **ppc_opcodes,
- unsigned char idx1, unsigned char idx2,
- unsigned char idx3, opc_handler_t *handler)
-{
- if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
- printf("*** ERROR: unable to join indirect table idx "
- "[%02x-%02x]\n", idx1, idx2);
- return -1;
- }
- if (register_ind_in_table(ind_table(ppc_opcodes[idx1]), idx2, idx3,
- handler) < 0) {
- printf("*** ERROR: unable to insert opcode "
- "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
- return -1;
- }
-
- return 0;
-}
-
-static int register_trplind_insn(opc_handler_t **ppc_opcodes,
- unsigned char idx1, unsigned char idx2,
- unsigned char idx3, unsigned char idx4,
- opc_handler_t *handler)
-{
- opc_handler_t **table;
-
- if (register_ind_in_table(ppc_opcodes, idx1, idx2, NULL) < 0) {
- printf("*** ERROR: unable to join indirect table idx "
- "[%02x-%02x]\n", idx1, idx2);
- return -1;
- }
- table = ind_table(ppc_opcodes[idx1]);
- if (register_ind_in_table(table, idx2, idx3, NULL) < 0) {
- printf("*** ERROR: unable to join 2nd-level indirect table idx "
- "[%02x-%02x-%02x]\n", idx1, idx2, idx3);
- return -1;
- }
- table = ind_table(table[idx2]);
- if (register_ind_in_table(table, idx3, idx4, handler) < 0) {
- printf("*** ERROR: unable to insert opcode "
- "[%02x-%02x-%02x-%02x]\n", idx1, idx2, idx3, idx4);
- return -1;
- }
- return 0;
-}
-static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn)
-{
- if (insn->opc2 != 0xFF) {
- if (insn->opc3 != 0xFF) {
- if (insn->opc4 != 0xFF) {
- if (register_trplind_insn(ppc_opcodes, insn->opc1, insn->opc2,
- insn->opc3, insn->opc4,
- &insn->handler) < 0) {
- return -1;
- }
- } else {
- if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,
- insn->opc3, &insn->handler) < 0)
- return -1;
- }
- } else {
- if (register_ind_insn(ppc_opcodes, insn->opc1,
- insn->opc2, &insn->handler) < 0)
- return -1;
- }
- } else {
- if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0)
- return -1;
- }
-
- return 0;
-}
-
-static int test_opcode_table (opc_handler_t **table, int len)
-{
- int i, count, tmp;
-
- for (i = 0, count = 0; i < len; i++) {
- /* Consistency fixup */
- if (table[i] == NULL)
- table[i] = &invalid_handler;
- if (table[i] != &invalid_handler) {
- if (is_indirect_opcode(table[i])) {
- tmp = test_opcode_table(ind_table(table[i]),
- PPC_CPU_INDIRECT_OPCODES_LEN);
- if (tmp == 0) {
- free(table[i]);
- table[i] = &invalid_handler;
- } else {
- count++;
- }
- } else {
- count++;
- }
- }
- }
-
- return count;
-}
-
-static void fix_opcode_tables (opc_handler_t **ppc_opcodes)
-{
- if (test_opcode_table(ppc_opcodes, PPC_CPU_OPCODES_LEN) == 0)
- printf("*** WARNING: no opcode defined !\n");
-}
-
-/*****************************************************************************/
-static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp)
-{
- PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
- CPUPPCState *env = &cpu->env;
- opcode_t *opc;
-
- fill_new_table(env->opcodes, PPC_CPU_OPCODES_LEN);
- for (opc = opcodes; opc < &opcodes[ARRAY_SIZE(opcodes)]; opc++) {
- if (((opc->handler.type & pcc->insns_flags) != 0) ||
- ((opc->handler.type2 & pcc->insns_flags2) != 0)) {
- if (register_insn(env->opcodes, opc) < 0) {
- error_setg(errp, "ERROR initializing PowerPC instruction "
- "0x%02x 0x%02x 0x%02x", opc->opc1, opc->opc2,
- opc->opc3);
- return;
- }
- }
- }
- fix_opcode_tables(env->opcodes);
- fflush(stdout);
- fflush(stderr);
-}
-
-#if defined(PPC_DUMP_CPU)
-static void dump_ppc_insns (CPUPPCState *env)
-{
- opc_handler_t **table, *handler;
- const char *p, *q;
- uint8_t opc1, opc2, opc3, opc4;
-
- printf("Instructions set:\n");
- /* opc1 is 6 bits long */
- for (opc1 = 0x00; opc1 < PPC_CPU_OPCODES_LEN; opc1++) {
- table = env->opcodes;
- handler = table[opc1];
- if (is_indirect_opcode(handler)) {
- /* opc2 is 5 bits long */
- for (opc2 = 0; opc2 < PPC_CPU_INDIRECT_OPCODES_LEN; opc2++) {
- table = env->opcodes;
- handler = env->opcodes[opc1];
- table = ind_table(handler);
- handler = table[opc2];
- if (is_indirect_opcode(handler)) {
- table = ind_table(handler);
- /* opc3 is 5 bits long */
- for (opc3 = 0; opc3 < PPC_CPU_INDIRECT_OPCODES_LEN;
- opc3++) {
- handler = table[opc3];
- if (is_indirect_opcode(handler)) {
- table = ind_table(handler);
- /* opc4 is 5 bits long */
- for (opc4 = 0; opc4 < PPC_CPU_INDIRECT_OPCODES_LEN;
- opc4++) {
- handler = table[opc4];
- if (handler->handler != &gen_invalid) {
- printf("INSN: %02x %02x %02x %02x -- "
- "(%02d %04d %02d) : %s\n",
- opc1, opc2, opc3, opc4,
- opc1, (opc3 << 5) | opc2, opc4,
- handler->oname);
- }
- }
- } else {
- if (handler->handler != &gen_invalid) {
- /* Special hack to properly dump SPE insns */
- p = strchr(handler->oname, '_');
- if (p == NULL) {
- printf("INSN: %02x %02x %02x (%02d %04d) : "
- "%s\n",
- opc1, opc2, opc3, opc1,
- (opc3 << 5) | opc2,
- handler->oname);
- } else {
- q = "speundef";
- if ((p - handler->oname) != strlen(q)
- || (memcmp(handler->oname, q, strlen(q))
- != 0)) {
- /* First instruction */
- printf("INSN: %02x %02x %02x"
- "(%02d %04d) : %.*s\n",
- opc1, opc2 << 1, opc3, opc1,
- (opc3 << 6) | (opc2 << 1),
- (int)(p - handler->oname),
- handler->oname);
- }
- if (strcmp(p + 1, q) != 0) {
- /* Second instruction */
- printf("INSN: %02x %02x %02x "
- "(%02d %04d) : %s\n", opc1,
- (opc2 << 1) | 1, opc3, opc1,
- (opc3 << 6) | (opc2 << 1) | 1,
- p + 1);
- }
- }
- }
- }
- }
- } else {
- if (handler->handler != &gen_invalid) {
- printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
- opc1, opc2, opc1, opc2, handler->oname);
- }
- }
- }
- } else {
- if (handler->handler != &gen_invalid) {
- printf("INSN: %02x -- -- (%02d ----) : %s\n",
- opc1, opc1, handler->oname);
- }
- }
- }
-}
-#endif
-
-static bool avr_need_swap(CPUPPCState *env)
-{
-#ifdef HOST_WORDS_BIGENDIAN
- return msr_le;
-#else
- return !msr_le;
-#endif
-}
-
-static int gdb_get_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
- if (n < 32) {
- stfq_p(mem_buf, env->fpr[n]);
- ppc_maybe_bswap_register(env, mem_buf, 8);
- return 8;
- }
- if (n == 32) {
- stl_p(mem_buf, env->fpscr);
- ppc_maybe_bswap_register(env, mem_buf, 4);
- return 4;
- }
- return 0;
-}
-
-static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
- if (n < 32) {
- ppc_maybe_bswap_register(env, mem_buf, 8);
- env->fpr[n] = ldfq_p(mem_buf);
- return 8;
- }
- if (n == 32) {
- ppc_maybe_bswap_register(env, mem_buf, 4);
- helper_store_fpscr(env, ldl_p(mem_buf), 0xffffffff);
- return 4;
- }
- return 0;
-}
-
-static int gdb_get_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
- if (n < 32) {
- if (!avr_need_swap(env)) {
- stq_p(mem_buf, env->avr[n].u64[0]);
- stq_p(mem_buf+8, env->avr[n].u64[1]);
- } else {
- stq_p(mem_buf, env->avr[n].u64[1]);
- stq_p(mem_buf+8, env->avr[n].u64[0]);
- }
- ppc_maybe_bswap_register(env, mem_buf, 8);
- ppc_maybe_bswap_register(env, mem_buf + 8, 8);
- return 16;
- }
- if (n == 32) {
- stl_p(mem_buf, env->vscr);
- ppc_maybe_bswap_register(env, mem_buf, 4);
- return 4;
- }
- if (n == 33) {
- stl_p(mem_buf, (uint32_t)env->spr[SPR_VRSAVE]);
- ppc_maybe_bswap_register(env, mem_buf, 4);
- return 4;
- }
- return 0;
-}
-
-static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
- if (n < 32) {
- ppc_maybe_bswap_register(env, mem_buf, 8);
- ppc_maybe_bswap_register(env, mem_buf + 8, 8);
- if (!avr_need_swap(env)) {
- env->avr[n].u64[0] = ldq_p(mem_buf);
- env->avr[n].u64[1] = ldq_p(mem_buf+8);
- } else {
- env->avr[n].u64[1] = ldq_p(mem_buf);
- env->avr[n].u64[0] = ldq_p(mem_buf+8);
- }
- return 16;
- }
- if (n == 32) {
- ppc_maybe_bswap_register(env, mem_buf, 4);
- env->vscr = ldl_p(mem_buf);
- return 4;
- }
- if (n == 33) {
- ppc_maybe_bswap_register(env, mem_buf, 4);
- env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf);
- return 4;
- }
- return 0;
-}
-
-static int gdb_get_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
- if (n < 32) {
-#if defined(TARGET_PPC64)
- stl_p(mem_buf, env->gpr[n] >> 32);
- ppc_maybe_bswap_register(env, mem_buf, 4);
-#else
- stl_p(mem_buf, env->gprh[n]);
-#endif
- return 4;
- }
- if (n == 32) {
- stq_p(mem_buf, env->spe_acc);
- ppc_maybe_bswap_register(env, mem_buf, 8);
- return 8;
- }
- if (n == 33) {
- stl_p(mem_buf, env->spe_fscr);
- ppc_maybe_bswap_register(env, mem_buf, 4);
- return 4;
- }
- return 0;
-}
-
-static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
- if (n < 32) {
-#if defined(TARGET_PPC64)
- target_ulong lo = (uint32_t)env->gpr[n];
- target_ulong hi;
-
- ppc_maybe_bswap_register(env, mem_buf, 4);
-
- hi = (target_ulong)ldl_p(mem_buf) << 32;
- env->gpr[n] = lo | hi;
-#else
- env->gprh[n] = ldl_p(mem_buf);
-#endif
- return 4;
- }
- if (n == 32) {
- ppc_maybe_bswap_register(env, mem_buf, 8);
- env->spe_acc = ldq_p(mem_buf);
- return 8;
- }
- if (n == 33) {
- ppc_maybe_bswap_register(env, mem_buf, 4);
- env->spe_fscr = ldl_p(mem_buf);
- return 4;
- }
- return 0;
-}
-
-static int gdb_get_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
- if (n < 32) {
- stq_p(mem_buf, env->vsr[n]);
- ppc_maybe_bswap_register(env, mem_buf, 8);
- return 8;
- }
- return 0;
-}
-
-static int gdb_set_vsx_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
-{
- if (n < 32) {
- ppc_maybe_bswap_register(env, mem_buf, 8);
- env->vsr[n] = ldq_p(mem_buf);
- return 8;
- }
- return 0;
-}
-
-static int ppc_fixup_cpu(PowerPCCPU *cpu)
-{
- CPUPPCState *env = &cpu->env;
-
- /* TCG doesn't (yet) emulate some groups of instructions that
- * are implemented on some otherwise supported CPUs (e.g. VSX
- * and decimal floating point instructions on POWER7). We
- * remove unsupported instruction groups from the cpu state's
- * instruction masks and hope the guest can cope. For at
- * least the pseries machine, the unavailability of these
- * instructions can be advertised to the guest via the device
- * tree. */
- if ((env->insns_flags & ~PPC_TCG_INSNS)
- || (env->insns_flags2 & ~PPC_TCG_INSNS2)) {
- fprintf(stderr, "Warning: Disabling some instructions which are not "
- "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")\n",
- env->insns_flags & ~PPC_TCG_INSNS,
- env->insns_flags2 & ~PPC_TCG_INSNS2);
- }
- env->insns_flags &= PPC_TCG_INSNS;
- env->insns_flags2 &= PPC_TCG_INSNS2;
- return 0;
-}
-
-static inline bool ppc_cpu_is_valid(PowerPCCPUClass *pcc)
-{
-#ifdef TARGET_PPCEMB
- return pcc->mmu_model == POWERPC_MMU_BOOKE ||
- pcc->mmu_model == POWERPC_MMU_SOFT_4xx ||
- pcc->mmu_model == POWERPC_MMU_SOFT_4xx_Z;
-#else
- return true;
-#endif
-}
-
-static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
-{
- CPUState *cs = CPU(dev);
- PowerPCCPU *cpu = POWERPC_CPU(dev);
- PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
- Error *local_err = NULL;
-#if !defined(CONFIG_USER_ONLY)
- int max_smt = kvmppc_smt_threads();
-#endif
-
-#if !defined(CONFIG_USER_ONLY)
- if (smp_threads > max_smt) {
- error_setg(errp, "Cannot support more than %d threads on PPC with %s",
- max_smt, kvm_enabled() ? "KVM" : "TCG");
- return;
- }
- if (!is_power_of_2(smp_threads)) {
- error_setg(errp, "Cannot support %d threads on PPC with %s, "
- "threads count must be a power of 2.",
- smp_threads, kvm_enabled() ? "KVM" : "TCG");
- return;
- }
-#endif
-
- cpu_exec_realizefn(cs, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
-
-#if !defined(CONFIG_USER_ONLY)
- cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt
- + (cs->cpu_index % smp_threads);
-
- if (kvm_enabled() && !kvm_vcpu_id_is_valid(cpu->cpu_dt_id)) {
- error_setg(errp, "Can't create CPU with id %d in KVM", cpu->cpu_dt_id);
- error_append_hint(errp, "Adjust the number of cpus to %d "
- "or try to raise the number of threads per core\n",
- cpu->cpu_dt_id * smp_threads / max_smt);
- return;
- }
-#endif
-
- if (tcg_enabled()) {
- if (ppc_fixup_cpu(cpu) != 0) {
- error_setg(errp, "Unable to emulate selected CPU with TCG");
- return;
- }
- }
-
-#if defined(TARGET_PPCEMB)
- if (!ppc_cpu_is_valid(pcc)) {
- error_setg(errp, "CPU does not possess a BookE or 4xx MMU. "
- "Please use qemu-system-ppc or qemu-system-ppc64 instead "
- "or choose another CPU model.");
- return;
- }
-#endif
-
- create_ppc_opcodes(cpu, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
- init_ppc_proc(cpu);
-
- if (pcc->insns_flags & PPC_FLOAT) {
- gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
- 33, "power-fpu.xml", 0);
- }
- if (pcc->insns_flags & PPC_ALTIVEC) {
- gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
- 34, "power-altivec.xml", 0);
- }
- if (pcc->insns_flags & PPC_SPE) {
- gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
- 34, "power-spe.xml", 0);
- }
- if (pcc->insns_flags2 & PPC2_VSX) {
- gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
- 32, "power-vsx.xml", 0);
- }
-
- qemu_init_vcpu(cs);
-
- pcc->parent_realize(dev, errp);
-
-#if defined(PPC_DUMP_CPU)
- {
- CPUPPCState *env = &cpu->env;
- const char *mmu_model, *excp_model, *bus_model;
- switch (env->mmu_model) {
- case POWERPC_MMU_32B:
- mmu_model = "PowerPC 32";
- break;
- case POWERPC_MMU_SOFT_6xx:
- mmu_model = "PowerPC 6xx/7xx with software driven TLBs";
- break;
- case POWERPC_MMU_SOFT_74xx:
- mmu_model = "PowerPC 74xx with software driven TLBs";
- break;
- case POWERPC_MMU_SOFT_4xx:
- mmu_model = "PowerPC 4xx with software driven TLBs";
- break;
- case POWERPC_MMU_SOFT_4xx_Z:
- mmu_model = "PowerPC 4xx with software driven TLBs "
- "and zones protections";
- break;
- case POWERPC_MMU_REAL:
- mmu_model = "PowerPC real mode only";
- break;
- case POWERPC_MMU_MPC8xx:
- mmu_model = "PowerPC MPC8xx";
- break;
- case POWERPC_MMU_BOOKE:
- mmu_model = "PowerPC BookE";
- break;
- case POWERPC_MMU_BOOKE206:
- mmu_model = "PowerPC BookE 2.06";
- break;
- case POWERPC_MMU_601:
- mmu_model = "PowerPC 601";
- break;
-#if defined (TARGET_PPC64)
- case POWERPC_MMU_64B:
- mmu_model = "PowerPC 64";
- break;
-#endif
- default:
- mmu_model = "Unknown or invalid";
- break;
- }
- switch (env->excp_model) {
- case POWERPC_EXCP_STD:
- excp_model = "PowerPC";
- break;
- case POWERPC_EXCP_40x:
- excp_model = "PowerPC 40x";
- break;
- case POWERPC_EXCP_601:
- excp_model = "PowerPC 601";
- break;
- case POWERPC_EXCP_602:
- excp_model = "PowerPC 602";
- break;
- case POWERPC_EXCP_603:
- excp_model = "PowerPC 603";
- break;
- case POWERPC_EXCP_603E:
- excp_model = "PowerPC 603e";
- break;
- case POWERPC_EXCP_604:
- excp_model = "PowerPC 604";
- break;
- case POWERPC_EXCP_7x0:
- excp_model = "PowerPC 740/750";
- break;
- case POWERPC_EXCP_7x5:
- excp_model = "PowerPC 745/755";
- break;
- case POWERPC_EXCP_74xx:
- excp_model = "PowerPC 74xx";
- break;
- case POWERPC_EXCP_BOOKE:
- excp_model = "PowerPC BookE";
- break;
-#if defined (TARGET_PPC64)
- case POWERPC_EXCP_970:
- excp_model = "PowerPC 970";
- break;
-#endif
- default:
- excp_model = "Unknown or invalid";
- break;
- }
- switch (env->bus_model) {
- case PPC_FLAGS_INPUT_6xx:
- bus_model = "PowerPC 6xx";
- break;
- case PPC_FLAGS_INPUT_BookE:
- bus_model = "PowerPC BookE";
- break;
- case PPC_FLAGS_INPUT_405:
- bus_model = "PowerPC 405";
- break;
- case PPC_FLAGS_INPUT_401:
- bus_model = "PowerPC 401/403";
- break;
- case PPC_FLAGS_INPUT_RCPU:
- bus_model = "RCPU / MPC8xx";
- break;
-#if defined (TARGET_PPC64)
- case PPC_FLAGS_INPUT_970:
- bus_model = "PowerPC 970";
- break;
-#endif
- default:
- bus_model = "Unknown or invalid";
- break;
- }
- printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
- " MMU model : %s\n",
- object_class_get_name(OBJECT_CLASS(pcc)),
- pcc->pvr, pcc->msr_mask, mmu_model);
-#if !defined(CONFIG_USER_ONLY)
- if (env->tlb.tlb6) {
- printf(" %d %s TLB in %d ways\n",
- env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
- env->nb_ways);
- }
-#endif
- printf(" Exceptions model : %s\n"
- " Bus model : %s\n",
- excp_model, bus_model);
- printf(" MSR features :\n");
- if (env->flags & POWERPC_FLAG_SPE)
- printf(" signal processing engine enable"
- "\n");
- else if (env->flags & POWERPC_FLAG_VRE)
- printf(" vector processor enable\n");
- if (env->flags & POWERPC_FLAG_TGPR)
- printf(" temporary GPRs\n");
- else if (env->flags & POWERPC_FLAG_CE)
- printf(" critical input enable\n");
- if (env->flags & POWERPC_FLAG_SE)
- printf(" single-step trace mode\n");
- else if (env->flags & POWERPC_FLAG_DWE)
- printf(" debug wait enable\n");
- else if (env->flags & POWERPC_FLAG_UBLE)
- printf(" user BTB lock enable\n");
- if (env->flags & POWERPC_FLAG_BE)
- printf(" branch-step trace mode\n");
- else if (env->flags & POWERPC_FLAG_DE)
- printf(" debug interrupt enable\n");
- if (env->flags & POWERPC_FLAG_PX)
- printf(" inclusive protection\n");
- else if (env->flags & POWERPC_FLAG_PMM)
- printf(" performance monitor mark\n");
- if (env->flags == POWERPC_FLAG_NONE)
- printf(" none\n");
- printf(" Time-base/decrementer clock source: %s\n",
- env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
- dump_ppc_insns(env);
- dump_ppc_sprs(env);
- fflush(stdout);
- }
-#endif
-}
-
-static void ppc_cpu_unrealizefn(DeviceState *dev, Error **errp)
-{
- PowerPCCPU *cpu = POWERPC_CPU(dev);
- PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
- CPUPPCState *env = &cpu->env;
- Error *local_err = NULL;
- opc_handler_t **table, **table_2;
- int i, j, k;
-
- pcc->parent_unrealize(dev, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
-
- for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) {
- if (env->opcodes[i] == &invalid_handler) {
- continue;
- }
- if (is_indirect_opcode(env->opcodes[i])) {
- table = ind_table(env->opcodes[i]);
- for (j = 0; j < PPC_CPU_INDIRECT_OPCODES_LEN; j++) {
- if (table[j] == &invalid_handler) {
- continue;
- }
- if (is_indirect_opcode(table[j])) {
- table_2 = ind_table(table[j]);
- for (k = 0; k < PPC_CPU_INDIRECT_OPCODES_LEN; k++) {
- if (table_2[k] != &invalid_handler &&
- is_indirect_opcode(table_2[k])) {
- g_free((opc_handler_t *)((uintptr_t)table_2[k] &
- ~PPC_INDIRECT));
- }
- }
- g_free((opc_handler_t *)((uintptr_t)table[j] &
- ~PPC_INDIRECT));
- }
- }
- g_free((opc_handler_t *)((uintptr_t)env->opcodes[i] &
- ~PPC_INDIRECT));
- }
- }
-}
-
-int ppc_get_compat_smt_threads(PowerPCCPU *cpu)
-{
- CPUState *cs = CPU(cpu);
- int ret = MIN(cs->nr_threads, kvmppc_smt_threads());
-
- switch (cpu->cpu_version) {
- case CPU_POWERPC_LOGICAL_2_05:
- ret = MIN(ret, 2);
- break;
- case CPU_POWERPC_LOGICAL_2_06:
- ret = MIN(ret, 4);
- break;
- case CPU_POWERPC_LOGICAL_2_07:
- ret = MIN(ret, 8);
- break;
- }
-
- return ret;
-}
-
-#ifdef TARGET_PPC64
-void ppc_set_compat(PowerPCCPU *cpu, uint32_t cpu_version, Error **errp)
-{
- int ret = 0;
- CPUPPCState *env = &cpu->env;
- PowerPCCPUClass *host_pcc;
-
- cpu->cpu_version = cpu_version;
-
- switch (cpu_version) {
- case CPU_POWERPC_LOGICAL_2_05:
- env->spr[SPR_PCR] = PCR_TM_DIS | PCR_VSX_DIS | PCR_COMPAT_2_07 |
- PCR_COMPAT_2_06 | PCR_COMPAT_2_05;
- break;
- case CPU_POWERPC_LOGICAL_2_06:
- case CPU_POWERPC_LOGICAL_2_06_PLUS:
- env->spr[SPR_PCR] = PCR_TM_DIS | PCR_COMPAT_2_07 | PCR_COMPAT_2_06;
- break;
- case CPU_POWERPC_LOGICAL_2_07:
- env->spr[SPR_PCR] = PCR_COMPAT_2_07;
- break;
- default:
- env->spr[SPR_PCR] = 0;
- break;
- }
-
- host_pcc = kvm_ppc_get_host_cpu_class();
- if (host_pcc) {
- env->spr[SPR_PCR] &= host_pcc->pcr_mask;
- }
-
- if (kvm_enabled()) {
- ret = kvmppc_set_compat(cpu, cpu->cpu_version);
- if (ret < 0) {
- error_setg_errno(errp, -ret,
- "Unable to set CPU compatibility mode in KVM");
- }
- }
-}
-#endif
-
-static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b)
-{
- ObjectClass *oc = (ObjectClass *)a;
- uint32_t pvr = *(uint32_t *)b;
- PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
-
- /* -cpu host does a PVR lookup during construction */
- if (unlikely(strcmp(object_class_get_name(oc),
- TYPE_HOST_POWERPC_CPU) == 0)) {
- return -1;
- }
-
- if (!ppc_cpu_is_valid(pcc)) {
- return -1;
- }
-
- return pcc->pvr == pvr ? 0 : -1;
-}
-
-PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr)
-{
- GSList *list, *item;
- PowerPCCPUClass *pcc = NULL;
-
- list = object_class_get_list(TYPE_POWERPC_CPU, false);
- item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr);
- if (item != NULL) {
- pcc = POWERPC_CPU_CLASS(item->data);
- }
- g_slist_free(list);
-
- return pcc;
-}
-
-static gint ppc_cpu_compare_class_pvr_mask(gconstpointer a, gconstpointer b)
-{
- ObjectClass *oc = (ObjectClass *)a;
- uint32_t pvr = *(uint32_t *)b;
- PowerPCCPUClass *pcc = (PowerPCCPUClass *)a;
-
- /* -cpu host does a PVR lookup during construction */
- if (unlikely(strcmp(object_class_get_name(oc),
- TYPE_HOST_POWERPC_CPU) == 0)) {
- return -1;
- }
-
- if (!ppc_cpu_is_valid(pcc)) {
- return -1;
- }
-
- if (pcc->pvr_match(pcc, pvr)) {
- return 0;
- }
-
- return -1;
-}
-
-PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr)
-{
- GSList *list, *item;
- PowerPCCPUClass *pcc = NULL;
-
- list = object_class_get_list(TYPE_POWERPC_CPU, true);
- item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr_mask);
- if (item != NULL) {
- pcc = POWERPC_CPU_CLASS(item->data);
- }
- g_slist_free(list);
-
- return pcc;
-}
-
-static gint ppc_cpu_compare_class_name(gconstpointer a, gconstpointer b)
-{
- ObjectClass *oc = (ObjectClass *)a;
- const char *name = b;
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- if (strncasecmp(name, object_class_get_name(oc), strlen(name)) == 0 &&
- ppc_cpu_is_valid(pcc) &&
- strcmp(object_class_get_name(oc) + strlen(name),
- "-" TYPE_POWERPC_CPU) == 0) {
- return 0;
- }
- return -1;
-}
-
-
-static ObjectClass *ppc_cpu_class_by_name(const char *name);
-
-static ObjectClass *ppc_cpu_class_by_alias(PowerPCCPUAlias *alias)
-{
- ObjectClass *invalid_class = (void*)ppc_cpu_class_by_alias;
-
- /* Cache target class lookups in the alias table */
- if (!alias->oc) {
- alias->oc = ppc_cpu_class_by_name(alias->model);
- if (!alias->oc) {
- /* Fast check for non-existing aliases */
- alias->oc = invalid_class;
- }
- }
-
- if (alias->oc == invalid_class) {
- return NULL;
- } else {
- return alias->oc;
- }
-}
-
-static ObjectClass *ppc_cpu_class_by_name(const char *name)
-{
- GSList *list, *item;
- ObjectClass *ret = NULL;
- const char *p;
- int i, len;
-
- /* Check if the given name is a PVR */
- len = strlen(name);
- if (len == 10 && name[0] == '0' && name[1] == 'x') {
- p = name + 2;
- goto check_pvr;
- } else if (len == 8) {
- p = name;
- check_pvr:
- for (i = 0; i < 8; i++) {
- if (!qemu_isxdigit(*p++))
- break;
- }
- if (i == 8) {
- return OBJECT_CLASS(ppc_cpu_class_by_pvr(strtoul(name, NULL, 16)));
- }
- }
-
- list = object_class_get_list(TYPE_POWERPC_CPU, false);
- item = g_slist_find_custom(list, name, ppc_cpu_compare_class_name);
- if (item != NULL) {
- ret = OBJECT_CLASS(item->data);
- }
- g_slist_free(list);
-
- if (ret) {
- return ret;
- }
-
- for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
- if (strcmp(ppc_cpu_aliases[i].alias, name) == 0) {
- return ppc_cpu_class_by_alias(&ppc_cpu_aliases[i]);
- }
- }
-
- return NULL;
-}
-
-const char *ppc_cpu_lookup_alias(const char *alias)
-{
- int ai;
-
- for (ai = 0; ppc_cpu_aliases[ai].alias != NULL; ai++) {
- if (strcmp(ppc_cpu_aliases[ai].alias, alias) == 0) {
- return ppc_cpu_aliases[ai].model;
- }
- }
-
- return NULL;
-}
-
-PowerPCCPU *cpu_ppc_init(const char *cpu_model)
-{
- return POWERPC_CPU(cpu_generic_init(TYPE_POWERPC_CPU, cpu_model));
-}
-
-/* Sort by PVR, ordering special case "host" last. */
-static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b)
-{
- ObjectClass *oc_a = (ObjectClass *)a;
- ObjectClass *oc_b = (ObjectClass *)b;
- PowerPCCPUClass *pcc_a = POWERPC_CPU_CLASS(oc_a);
- PowerPCCPUClass *pcc_b = POWERPC_CPU_CLASS(oc_b);
- const char *name_a = object_class_get_name(oc_a);
- const char *name_b = object_class_get_name(oc_b);
-
- if (strcmp(name_a, TYPE_HOST_POWERPC_CPU) == 0) {
- return 1;
- } else if (strcmp(name_b, TYPE_HOST_POWERPC_CPU) == 0) {
- return -1;
- } else {
- /* Avoid an integer overflow during subtraction */
- if (pcc_a->pvr < pcc_b->pvr) {
- return -1;
- } else if (pcc_a->pvr > pcc_b->pvr) {
- return 1;
- } else {
- return 0;
- }
- }
-}
-
-static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
-{
- ObjectClass *oc = data;
- CPUListState *s = user_data;
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
- const char *typename = object_class_get_name(oc);
- char *name;
- int i;
-
- if (!ppc_cpu_is_valid(pcc)) {
- return;
- }
- if (unlikely(strcmp(typename, TYPE_HOST_POWERPC_CPU) == 0)) {
- return;
- }
-
- name = g_strndup(typename,
- strlen(typename) - strlen("-" TYPE_POWERPC_CPU));
- (*s->cpu_fprintf)(s->file, "PowerPC %-16s PVR %08x\n",
- name, pcc->pvr);
- for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
- PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
- ObjectClass *alias_oc = ppc_cpu_class_by_alias(alias);
-
- if (alias_oc != oc) {
- continue;
- }
- (*s->cpu_fprintf)(s->file, "PowerPC %-16s (alias for %s)\n",
- alias->alias, name);
- }
- g_free(name);
-}
-
-void ppc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
-{
- CPUListState s = {
- .file = f,
- .cpu_fprintf = cpu_fprintf,
- };
- GSList *list;
-
- list = object_class_get_list(TYPE_POWERPC_CPU, false);
- list = g_slist_sort(list, ppc_cpu_list_compare);
- g_slist_foreach(list, ppc_cpu_list_entry, &s);
- g_slist_free(list);
-
-#ifdef CONFIG_KVM
- cpu_fprintf(f, "\n");
- cpu_fprintf(f, "PowerPC %-16s\n", "host");
-#endif
-}
-
-static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
-{
- ObjectClass *oc = data;
- CpuDefinitionInfoList **first = user_data;
- const char *typename;
- CpuDefinitionInfoList *entry;
- CpuDefinitionInfo *info;
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
- if (!ppc_cpu_is_valid(pcc)) {
- return;
- }
-
- typename = object_class_get_name(oc);
- info = g_malloc0(sizeof(*info));
- info->name = g_strndup(typename,
- strlen(typename) - strlen("-" TYPE_POWERPC_CPU));
-
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = *first;
- *first = entry;
-}
-
-CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
-{
- CpuDefinitionInfoList *cpu_list = NULL;
- GSList *list;
- int i;
-
- list = object_class_get_list(TYPE_POWERPC_CPU, false);
- g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list);
- g_slist_free(list);
-
- for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
- PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
- ObjectClass *oc;
- CpuDefinitionInfoList *entry;
- CpuDefinitionInfo *info;
-
- oc = ppc_cpu_class_by_alias(alias);
- if (oc == NULL) {
- continue;
- }
-
- info = g_malloc0(sizeof(*info));
- info->name = g_strdup(alias->alias);
-
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = cpu_list;
- cpu_list = entry;
- }
-
- return cpu_list;
-}
-
-static void ppc_cpu_set_pc(CPUState *cs, vaddr value)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
-
- cpu->env.nip = value;
-}
-
-static bool ppc_cpu_has_work(CPUState *cs)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
-
- return msr_ee && (cs->interrupt_request & CPU_INTERRUPT_HARD);
-}
-
-static void ppc_cpu_exec_enter(CPUState *cs)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
-
- env->reserve_addr = -1;
-}
-
-/* CPUClass::reset() */
-static void ppc_cpu_reset(CPUState *s)
-{
- PowerPCCPU *cpu = POWERPC_CPU(s);
- PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
- CPUPPCState *env = &cpu->env;
- target_ulong msr;
- int i;
-
- pcc->parent_reset(s);
-
- msr = (target_ulong)0;
- msr |= (target_ulong)MSR_HVB;
- msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
- msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
- msr |= (target_ulong)1 << MSR_EP;
-#if defined(DO_SINGLE_STEP) && 0
- /* Single step trace mode */
- msr |= (target_ulong)1 << MSR_SE;
- msr |= (target_ulong)1 << MSR_BE;
-#endif
-#if defined(CONFIG_USER_ONLY)
- msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
- msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
- msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
- msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
- msr |= (target_ulong)1 << MSR_PR;
-#if defined(TARGET_PPC64)
- msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
-#endif
-#if !defined(TARGET_WORDS_BIGENDIAN)
- msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
- if (!((env->msr_mask >> MSR_LE) & 1)) {
- fprintf(stderr, "Selected CPU does not support little-endian.\n");
- exit(1);
- }
-#endif
-#endif
-
-#if defined(TARGET_PPC64)
- if (env->mmu_model & POWERPC_MMU_64) {
- msr |= (1ULL << MSR_SF);
- }
-#endif
-
- hreg_store_msr(env, msr, 1);
-
-#if !defined(CONFIG_USER_ONLY)
- env->nip = env->hreset_vector | env->excp_prefix;
- if (env->mmu_model != POWERPC_MMU_REAL) {
- ppc_tlb_invalidate_all(env);
- }
-#endif
-
- hreg_compute_hflags(env);
- env->reserve_addr = (target_ulong)-1ULL;
- /* Be sure no exception or interrupt is pending */
- env->pending_interrupts = 0;
- s->exception_index = POWERPC_EXCP_NONE;
- env->error_code = 0;
-
-#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
- env->vpa_addr = 0;
- env->slb_shadow_addr = 0;
- env->slb_shadow_size = 0;
- env->dtl_addr = 0;
- env->dtl_size = 0;
-#endif /* TARGET_PPC64 */
-
- for (i = 0; i < ARRAY_SIZE(env->spr_cb); i++) {
- ppc_spr_t *spr = &env->spr_cb[i];
-
- if (!spr->name) {
- continue;
- }
- env->spr[i] = spr->default_value;
- }
-
- /* Flush all TLBs */
- tlb_flush(s, 1);
-}
-
-#ifndef CONFIG_USER_ONLY
-static bool ppc_cpu_is_big_endian(CPUState *cs)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
-
- cpu_synchronize_state(cs);
-
- return !msr_le;
-}
-#endif
-
-static void ppc_cpu_initfn(Object *obj)
-{
- CPUState *cs = CPU(obj);
- PowerPCCPU *cpu = POWERPC_CPU(obj);
- PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
- CPUPPCState *env = &cpu->env;
-
- cs->env_ptr = env;
-
- env->msr_mask = pcc->msr_mask;
- env->mmu_model = pcc->mmu_model;
- env->excp_model = pcc->excp_model;
- env->bus_model = pcc->bus_model;
- env->insns_flags = pcc->insns_flags;
- env->insns_flags2 = pcc->insns_flags2;
- env->flags = pcc->flags;
- env->bfd_mach = pcc->bfd_mach;
- env->check_pow = pcc->check_pow;
-
- /* Mark HV mode as supported if the CPU has an MSR_HV bit
- * in the msr_mask. The mask can later be cleared by PAPR
- * mode but the hv mode support will remain, thus enforcing
- * that we cannot use priv. instructions in guest in PAPR
- * mode. For 970 we currently simply don't set HV in msr_mask
- * thus simulating an "Apple mode" 970. If we ever want to
- * support 970 HV mode, we'll have to add a processor attribute
- * of some sort.
- */
-#if !defined(CONFIG_USER_ONLY)
- env->has_hv_mode = !!(env->msr_mask & MSR_HVB);
-#endif
-
-#if defined(TARGET_PPC64)
- if (pcc->sps) {
- env->sps = *pcc->sps;
- } else if (env->mmu_model & POWERPC_MMU_64) {
- /* Use default sets of page sizes. We don't support MPSS */
- static const struct ppc_segment_page_sizes defsps_4k = {
- .sps = {
- { .page_shift = 12, /* 4K */
- .slb_enc = 0,
- .enc = { { .page_shift = 12, .pte_enc = 0 } }
- },
- { .page_shift = 24, /* 16M */
- .slb_enc = 0x100,
- .enc = { { .page_shift = 24, .pte_enc = 0 } }
- },
- },
- };
- static const struct ppc_segment_page_sizes defsps_64k = {
- .sps = {
- { .page_shift = 12, /* 4K */
- .slb_enc = 0,
- .enc = { { .page_shift = 12, .pte_enc = 0 } }
- },
- { .page_shift = 16, /* 64K */
- .slb_enc = 0x110,
- .enc = { { .page_shift = 16, .pte_enc = 1 } }
- },
- { .page_shift = 24, /* 16M */
- .slb_enc = 0x100,
- .enc = { { .page_shift = 24, .pte_enc = 0 } }
- },
- },
- };
- env->sps = (env->mmu_model & POWERPC_MMU_64K) ? defsps_64k : defsps_4k;
- }
-#endif /* defined(TARGET_PPC64) */
-
- if (tcg_enabled()) {
- ppc_translate_init();
- }
-}
-
-static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr)
-{
- return pcc->pvr == pvr;
-}
-
-static gchar *ppc_gdb_arch_name(CPUState *cs)
-{
-#if defined(TARGET_PPC64)
- return g_strdup("powerpc:common64");
-#else
- return g_strdup("powerpc:common");
-#endif
-}
-
-static Property ppc_cpu_properties[] = {
- DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU, pre_2_8_migration, false),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void ppc_cpu_class_init(ObjectClass *oc, void *data)
-{
- PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
- CPUClass *cc = CPU_CLASS(oc);
- DeviceClass *dc = DEVICE_CLASS(oc);
-
- pcc->parent_realize = dc->realize;
- pcc->parent_unrealize = dc->unrealize;
- pcc->pvr_match = ppc_pvr_match_default;
- pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always;
- dc->realize = ppc_cpu_realizefn;
- dc->unrealize = ppc_cpu_unrealizefn;
- dc->props = ppc_cpu_properties;
-
- pcc->parent_reset = cc->reset;
- cc->reset = ppc_cpu_reset;
-
- cc->class_by_name = ppc_cpu_class_by_name;
- cc->has_work = ppc_cpu_has_work;
- cc->do_interrupt = ppc_cpu_do_interrupt;
- cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
- cc->dump_state = ppc_cpu_dump_state;
- cc->dump_statistics = ppc_cpu_dump_statistics;
- cc->set_pc = ppc_cpu_set_pc;
- cc->gdb_read_register = ppc_cpu_gdb_read_register;
- cc->gdb_write_register = ppc_cpu_gdb_write_register;
-#ifdef CONFIG_USER_ONLY
- cc->handle_mmu_fault = ppc_cpu_handle_mmu_fault;
-#else
- cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug;
- cc->vmsd = &vmstate_ppc_cpu;
-#if defined(TARGET_PPC64)
- cc->write_elf64_note = ppc64_cpu_write_elf64_note;
-#endif
-#endif
- cc->cpu_exec_enter = ppc_cpu_exec_enter;
-
- cc->gdb_num_core_regs = 71;
-
-#ifdef USE_APPLE_GDB
- cc->gdb_read_register = ppc_cpu_gdb_read_register_apple;
- cc->gdb_write_register = ppc_cpu_gdb_write_register_apple;
- cc->gdb_num_core_regs = 71 + 32;
-#endif
-
- cc->gdb_arch_name = ppc_gdb_arch_name;
-#if defined(TARGET_PPC64)
- cc->gdb_core_xml_file = "power64-core.xml";
-#else
- cc->gdb_core_xml_file = "power-core.xml";
-#endif
-#ifndef CONFIG_USER_ONLY
- cc->virtio_is_big_endian = ppc_cpu_is_big_endian;
-#endif
-
- dc->fw_name = "PowerPC,UNKNOWN";
-}
-
-static const TypeInfo ppc_cpu_type_info = {
- .name = TYPE_POWERPC_CPU,
- .parent = TYPE_CPU,
- .instance_size = sizeof(PowerPCCPU),
- .instance_init = ppc_cpu_initfn,
- .abstract = true,
- .class_size = sizeof(PowerPCCPUClass),
- .class_init = ppc_cpu_class_init,
-};
-
-static void ppc_cpu_register_types(void)
-{
- type_register_static(&ppc_cpu_type_info);
-}
-
-type_init(ppc_cpu_register_types)
diff --git a/target-ppc/user_only_helper.c b/target-ppc/user_only_helper.c
deleted file mode 100644
index 6aff34713f..0000000000
--- a/target-ppc/user_only_helper.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * PowerPC MMU stub handling for user mode emulation
- *
- * Copyright (c) 2003-2007 Jocelyn Mayer
- * Copyright (c) 2013 David Gibson, IBM Corporation.
- *
- * 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 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 <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-
-int ppc_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
- int mmu_idx)
-{
- PowerPCCPU *cpu = POWERPC_CPU(cs);
- CPUPPCState *env = &cpu->env;
- int exception, error_code;
-
- if (rw == 2) {
- exception = POWERPC_EXCP_ISI;
- error_code = 0x40000000;
- } else {
- exception = POWERPC_EXCP_DSI;
- error_code = 0x40000000;
- if (rw) {
- error_code |= 0x02000000;
- }
- env->spr[SPR_DAR] = address;
- env->spr[SPR_DSISR] = error_code;
- }
- cs->exception_index = exception;
- env->error_code = error_code;
-
- return 1;
-}