Great rework and cleanups to ease PowerPC implementations definitions.
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 26 Sep 2007 23:54:22 +0000 (23:54 +0000)
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 26 Sep 2007 23:54:22 +0000 (23:54 +0000)
* cleanup cpu.h, removing definitions used only in translate.c/translate_init.c
* add new flags to define instructions sets more precisely
* various changes in MMU models definitions
* add definitions for PowerPC 440/460 support (insns and SPRs).
* add definitions for PowerPC 401/403 and 620 input pins model
* Fix definitions for most PowerPC 401, 403, 405, 440, 601, 602, 603 and 7x0
* Preliminary support for PowerPC 74xx (aka G4) without altivec.
* Code provision for other PowerPC support (7x5, 970, ...).
* New SPR and PVR defined, from PowerPC 2.04 specification and other sources
* Misc code bugs, error messages and styles fixes.
* Update status files for PowerPC cores support.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3244 c046a42c-6fe2-441c-8c8c-71466251a162

hw/ppc.c
linux-user/main.c
target-ppc/STATUS
target-ppc/cpu.h
target-ppc/exec.h
target-ppc/helper.c
target-ppc/op.c
target-ppc/op_helper.c
target-ppc/op_helper.h
target-ppc/translate.c
target-ppc/translate_init.c

index d0eb7a4769c93f316a0c840e67a8759e5415c9c5..b3cf71b17f2c0496221b407e81064502a40f179a 100644 (file)
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -376,11 +376,11 @@ static void ppc405_set_irq (void *opaque, int pin, int level)
             /* Level sensitive - active high */
 #if defined(PPC_DEBUG_IRQ)
             if (loglevel & CPU_LOG_INT) {
-                fprintf(logfile, "%s: set the external IRQ state to %d\n",
+                fprintf(logfile, "%s: set the debug pin state to %d\n",
                         __func__, level);
             }
 #endif
-            ppc_set_irq(env, EXCP_40x_DEBUG, level);
+            ppc_set_irq(env, PPC_INTERRUPT_DEBUG, level);
             break;
         default:
             /* Unknown pin - do nothing */
@@ -904,6 +904,9 @@ struct ppc_dcrn_t {
     void *opaque;
 };
 
+/* XXX: on 460, DCR addresses are 32 bits wide,
+ *      using DCRIPR to get the 22 upper bits of the DCR address
+ */
 #define DCRN_NB 1024
 struct ppc_dcr_t {
     ppc_dcrn_t dcrn[DCRN_NB];
index 18e0be18120db6ebba74fd3887c041b2f5c69f95..b70c070c3f50fdd734a4863072996e15ce51d649 100644 (file)
@@ -712,6 +712,17 @@ uint32_t cpu_ppc601_load_rtcl (CPUState *env)
     return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
 }
 
+/* XXX: to be fixed */
+int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp)
+{
+    return -1;
+}
+
+int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val)
+{
+    return -1;
+}
+
 void cpu_loop(CPUPPCState *env)
 {
     target_siginfo_t info;
@@ -761,7 +772,7 @@ void cpu_loop(CPUPPCState *env)
         case EXCP_MACHINE_CHECK:
             fprintf(stderr, "Machine check exeption...  Stop emulation\n");
             if (loglevel)
-                fprintf(logfile, "RESET asked... Stop emulation\n");
+                fprintf(logfile, "Machine check exception. Stop emulation\n");
             info.si_signo = TARGET_SIGBUS;
             info.si_errno = 0;
             info.si_code = TARGET_BUS_OBJERR;
@@ -914,7 +925,7 @@ void cpu_loop(CPUPPCState *env)
                     info.si_code = TARGET_ILL_ILLOPC;
                     break;
                 case EXCP_INVAL_LSWX:
-            info.si_code = TARGET_ILL_ILLOPN;
+                    info.si_code = TARGET_ILL_ILLOPN;
                     break;
                 case EXCP_INVAL_SPR:
                     info.si_code = TARGET_ILL_PRVREG;
@@ -1003,7 +1014,7 @@ void cpu_loop(CPUPPCState *env)
                 if (loglevel)
                     fprintf(logfile, "Tried to go into supervisor mode !\n");
                 abort();
-        }
+            }
             break;
         case EXCP_BRANCH:
             /* We stopped because of a jump... */
index 190186562efbb75c6ce7f58af6d6106048cff73f..b4daa97afd39adeabc527a29e0ad0ea0aa38cece 100644 (file)
@@ -4,267 +4,462 @@ The goal of this file is to provide a reference status to avoid regressions.
 ===============================================================================
 PowerPC core emulation status
 
-32 bits PowerPC
-PowerPC 601:
-INSN
-SPR
-MMU
-EXCP
-
-PowerPC 602:
-INSN
-SPR
-MMU
-EXCP
-
-PowerPC 603:
-INSN OK
-SPR  OK
-MMU  OK
-EXCP OK
-
-PowerPC 604:
-INSN OK
-SPR  OK
-MMU  OK
-EXCP OK
-
-PowerPC 740:
-INSN OK
-SPR  OK
-MMU  OK
-EXCP OK
-
-PowerPC 745:
-INSN
-SPR
-MMU
-EXCP
-
-PowerPC 750:
-INSN OK
-SPR  OK
-MMU  OK
-EXCP OK
-
-PowerPC 755:
-INSN
-SPR
-MMU
-EXCP
+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
+      ?  => uncheked
+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
 
-PowerPC 7400:
-INSN KO
-SPR  KO
-MMU  OK
-EXCP OK
+Embedded PowerPC cores
+***
+PowerPC 401:
+INSN  OK
+SPR   OK 401A1
+MSR   OK
+IRQ   KO partially implemented
+MMU   OK
+EXCP  ?
 
-PowerPC 7410:
-INSN KO
-SPR  KO
-MMU  OK
-EXCP OK
-
-PowerPC 7450:
-INSN KO
-SPR  KO
-MMU  OK
-EXCP OK
-
-PowerPC 7455:
-INSN KO
-SPR  KO
-MMU  OK
-EXCP OK
-
-PowerPC 7457:
-INSN KO
-SPR  KO
-MMU  OK
-EXCP OK
-
-PowerPC 7457A:
-INSN KO
-SPR  KO
-MMU  OK
-EXCP OK
+PowerPC 401x2:
+INSN  OK
+SPR   OK 401B2 401C2 401D2 401E2 401F2
+MSR   OK
+IRQ   KO partially implemented
+MMU   OK
+EXCP  ?
 
-64 bits PowerPC
-PowerPC 970:
-INSN KO
-SPR  KO
-MMU  KO
-EXCP KO
-
-PowerPC 620: (lack of precise informations)
-INSN KO
-SPR  KO
-MMU  KO
-EXCP KO
-
-PowerPC 630: (lack of precise informations)
-INSN KO
-SPR  KO
-MMU  KO
-EXCP KO
-
-PowerPC 631: (lack of precise informations)
-INSN KO
-SPR  KO
-MMU  KO
-EXCP KO
-
-POWER4: (lack of precise informations)
-INSN KO
-SPR  KO
-MMU  KO
-EXCP KO
-
-POWER4+: (lack of precise informations)
-INSN KO
-SPR  KO
-MMU  KO
-EXCP KO
-
-POWER5: (lack of precise informations)
-INSN KO
-SPR  KO
-MMU  KO
-EXCP KO
-
-POWER5+: (lack of precise informations)
-INSN KO
-SPR  KO
-MMU  KO
-EXCP KO
-
-POWER6: (lack of precise informations)
-INSN KO
-SPR  KO
-MMU  KO
-EXCP KO
-
-RS64: (lack of precise informations)
-INSN KO
-SPR  KO
-MMU  KO
-EXCP KO
-
-RS64-II: (lack of precise informations)
-INSN KO
-SPR  KO
-MMU  KO
-EXCP KO
-
-RS64-III: (lack of precise informations)
-INSN KO
-SPR  KO
-MMU  KO
-EXCP KO
-
-RS64-IV: (lack of precise informations)
-INSN KO
-SPR  KO
-MMU  KO
-EXCP KO
+PowerPC IOP480:
+INSN  OK
+SPR   OK IOP480
+MSR   OK
+IRQ   KO partially implemented
+MMU   OK
+EXCP  ?
 
-Embedded PowerPC cores
-PowerPC 401:
-INSN OK
-SPR  OK
-MMU  OK
-EXCP ?
+To be checked: 401G2 401B3 Cobra
 
+***
 PowerPC 403:
-INSN OK
-SPR  OK
-MMU  OK
-EXCP ?
+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:
-INSN OK
-SPR  OK
-MMU  OK
-EXCP OK
+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
+=> Linux 2.4 boots (at least 1 proprietary firmware).
+
+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 460: (lack of precise informations)
+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
 
-Freescale (to be completed) ...
+***
+PowerPC e200: (not implemented)
+INSN  KO
+SPR   KO
+MSR   KO
+IRQ   KO
+MMU   KO
+EXCP  KO
 
-Original POWER
-POWER: (lack of precise informations)
+***
+PowerPC e300: (not implemented)
 INSN  KO
 SPR   KO
+MSR   KO
+IRQ   KO
 MMU   KO
 EXCP  KO
 
-POWER2: (lack of precise informations)
+***
+PowerPC e500: (not implemented)
 INSN  KO
 SPR   KO
+MSR   KO
+IRQ   KO
 MMU   KO
 EXCP  KO
 
-PowerPC CPU known to work (ie booting at least Linux 2.4):
-* main stream PowerPC cores
-- PowerPC 603 & derivatives
-- PowerPC 604 & derivatives
-- PowerPC 740 & derivatives
-- PowerPC 750 & derivatives
-- PowerPC 405
-
-PowerPC that should work but are not supported by standard Linux kernel
-(then remain mostly untested)
-- PowerPC 745
-- PowerPC 755
-
-Work in progress:
-* embedded PowerPC cores
-- BookE PowerPC
-- e500 core (Freescale PowerQUICC)
-* main stream PowerPC cores
-- PowerPC 601
-- PowerPC 602
+***
+PowerPC e600: (not implemented)
+INSN  KO
+SPR   KO
+MSR   KO
+IRQ   KO
+MMU   KO
+EXCP  KO
 
-TODO:
-* embedded PowerPC cores
-- PowerPC 401
-- PowerPC 403
-- PowerPC 440
-- PowerPC 460
-* main stream PowerPC cores
-- PowerPC 7400 (aka G4)
-- PowerPC 7410
-- PowerPC 7450
-- PowerPC 7455
-- PowerPC 7457
-- PowerPC 7457A
-* original POWER
-- POWER
-- POWER2
-* 64 bits PowerPC cores
-- PowerPC 620
-- PowerPC 630 (aka POWER3)
-- PowerPC 631 (aka POWER3+)
-- POWER4
-- POWER4+
-- POWER5
-- POWER5+
-- PowerPC 970
-* RS64 series
-- RS64
-- RS64-II
-- RS64-III
-- RS64-IV
+***
+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 crashes when entering user-mode. But it seems it does not
+         know about this CPU. As this CPU is close to 603e, it should be OK.
+
+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
+
+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
+
+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.
+
+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.
+
+PowerPC 604:
+INSN  OK
+SPR   OK
+MSR   OK
+IRQ   OK
+MMU   OK
+EXCP  OK
+Remarks: Linux 2.4 boots and properly recognizes the CPU.
+
+PowerPC 7x0:
+INSN  OK
+SPR   OK
+MSR   OK
+IRQ   OK
+MMU   OK
+EXCP  OK
+Remarks: Linux 2.4 boots and properly recognizes the CPU.
+
+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.
+
+PowerPC 7x5:
+INSN  ?
+SPR   ?
+MSR   ?
+IRQ   OK
+MMU   ?
+EXCP  OK
+=> Linux 2.4 does not boot.
+
+PowerPC 7400:
+INSN  KO Altivec missing
+SPR   OK
+MSR   OK
+IRQ   OK
+MMU   OK
+EXCP  ?  Altivec, ...
+=> Linux 2.4 boots and properly recognize the CPU.
+
+PowerPC 7410:
+INSN  KO Altivec missing
+SPR   OK
+MSR   OK
+IRQ   OK
+MMU   OK
+EXCP  ?  Altivec, ...
+=> Linux 2.4 boots and properly recognize the CPU.
+   Note that UM says tlbld & tlbli are implemented bus this may be a mistake
+   as TLB load are managed by the hardware and it does not implement the
+   needed registers.
+
+PowerPC 7441:
+INSN  KO Altivec missing + TLB load insns missing
+SPR   OK
+MSR   OK
+IRQ   OK
+MMU   KO not implemented
+EXCP  ?  Altivec, ...
+
+PowerPC 7450/7451:
+INSN  KO Altivec missing + TLB load insns missing
+SPR   OK
+MSR   OK
+IRQ   OK
+MMU   KO not implemented
+EXCP  ?  Altivec, ...
+
+PowerPC 7445/7447:
+INSN  KO Altivec missing + TLB load insns missing
+SPR   OK
+MSR   OK
+IRQ   OK
+MMU   KO not implemented
+EXCP  ?  Altivec, ...
+
+PowerPC 7455/7457:
+INSN  KO Altivec missing + TLB load insns missing
+SPR   OK
+MSR   OK
+IRQ   OK
+MMU   KO not implemented
+EXCP  ?  Altivec, ...
+
+64 bits PowerPC
+PowerPC 620: (disabled)
+INSN  KO
+SPR   KO
+MSR   ?
+IRQ   KO
+MMU   KO
+EXCP  KO
+
+PowerPC 970: (disabled)
+INSN  KO Altivec missing and more
+SPR   KO
+MSR   ?
+IRQ   OK
+MMU   KO partially implemented
+EXCP  KO
+
+PowerPC 970FX: (disabled)
+INSN  KO Altivec missing and more
+SPR   KO
+MSR   ?
+IRQ   OK
+MMU   KO partially implemented
+EXCP  KO
+
+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
index f4c7a946781b1be035b5408d4dccf1693655ae6b..f1df741e1e50bea39ae21118f1faab56a06d8a74 100644 (file)
@@ -89,528 +89,89 @@ typedef uint32_t ppc_gpr_t;
 #define DCACHE_LINE_SIZE 32
 
 /*****************************************************************************/
-/* PVR definitions for most known PowerPC */
+/* MMU model                                                                 */
 enum {
-    /* PowerPC 401 cores */
-    CPU_PPC_401A1     = 0x00210000,
-    CPU_PPC_401B2     = 0x00220000,
-#if 0
-    CPU_PPC_401B3     = xxx,
-#endif
-    CPU_PPC_401C2     = 0x00230000,
-    CPU_PPC_401D2     = 0x00240000,
-    CPU_PPC_401E2     = 0x00250000,
-    CPU_PPC_401F2     = 0x00260000,
-    CPU_PPC_401G2     = 0x00270000,
-#if 0
-    CPU_PPC_401GF     = xxx,
-#endif
-#define CPU_PPC_401 CPU_PPC_401G2
-    CPU_PPC_IOP480    = 0x40100000, /* 401B2 ? */
-    CPU_PPC_COBRA     = 0x10100000, /* IBM Processor for Network Resources */
-    /* PowerPC 403 cores */
-    CPU_PPC_403GA     = 0x00200011,
-    CPU_PPC_403GB     = 0x00200100,
-    CPU_PPC_403GC     = 0x00200200,
-    CPU_PPC_403GCX    = 0x00201400,
-#if 0
-    CPU_PPC_403GP     = xxx,
-#endif
-#define CPU_PPC_403 CPU_PPC_403GCX
-    /* PowerPC 405 cores */
-#if 0
-    CPU_PPC_405A3     = xxx,
-#endif
-#if 0
-    CPU_PPC_405A4     = xxx,
-#endif
-#if 0
-    CPU_PPC_405B3     = xxx,
-#endif
-    CPU_PPC_405D2     = 0x20010000,
-    CPU_PPC_405D4     = 0x41810000,
-    CPU_PPC_405CR     = 0x40110145,
-#define CPU_PPC_405GP CPU_PPC_405CR
-    CPU_PPC_405EP     = 0x51210950,
-#if 0
-    CPU_PPC_405EZ     = xxx,
-#endif
-    CPU_PPC_405GPR    = 0x50910951,
-#if 0
-    CPU_PPC_405LP     = xxx,
-#endif
-#define CPU_PPC_405 CPU_PPC_405D4
-    CPU_PPC_NPE405H   = 0x414100C0,
-    CPU_PPC_NPE405H2  = 0x41410140,
-    CPU_PPC_NPE405L   = 0x416100C0,
-#if 0
-    CPU_PPC_LC77700   = xxx,
-#endif
-    /* IBM STBxxx (PowerPC 401/403/405 core based microcontrollers) */
-#if 0
-    CPU_PPC_STB01000  = xxx,
-#endif
-#if 0
-    CPU_PPC_STB01010  = xxx,
-#endif
-#if 0
-    CPU_PPC_STB0210   = xxx,
-#endif
-    CPU_PPC_STB03     = 0x40310000,
-#if 0
-    CPU_PPC_STB043    = xxx,
-#endif
-#if 0
-    CPU_PPC_STB045    = xxx,
-#endif
-    CPU_PPC_STB25     = 0x51510950,
-#if 0
-    CPU_PPC_STB130    = xxx,
-#endif
-    /* Xilinx cores */
-    CPU_PPC_X2VP4     = 0x20010820,
-#define CPU_PPC_X2VP7 CPU_PPC_X2VP4
-    CPU_PPC_X2VP20    = 0x20010860,
-#define CPU_PPC_X2VP50 CPU_PPC_X2VP20
-    /* PowerPC 440 cores */
-    CPU_PPC_440EP     = 0x422218D3,
-#define CPU_PPC_440GR CPU_PPC_440EP
-    CPU_PPC_440GP     = 0x40120481,
-#if 0
-    CPU_PPC_440GRX    = xxx,
-#endif
-    CPU_PPC_440GX     = 0x51B21850,
-    CPU_PPC_440GXc    = 0x51B21892,
-    CPU_PPC_440GXf    = 0x51B21894,
-    CPU_PPC_440SP     = 0x53221850,
-    CPU_PPC_440SP2    = 0x53221891,
-    CPU_PPC_440SPE    = 0x53421890,
-    /* PowerPC 460 cores */
-#if 0
-    CPU_PPC_464H90    = xxx,
-#endif
-#if 0
-    CPU_PPC_464H90FP  = xxx,
-#endif
-    /* PowerPC MPC 5xx cores */
-    CPU_PPC_5xx       = 0x00020020,
-    /* PowerPC MPC 8xx cores (aka PowerQUICC) */
-    CPU_PPC_8xx       = 0x00500000,
-    /* PowerPC MPC 8xxx cores (aka PowerQUICC-II) */
-    CPU_PPC_82xx_HIP3 = 0x00810101,
-    CPU_PPC_82xx_HIP4 = 0x80811014,
-    CPU_PPC_827x      = 0x80822013,
-    /* eCores */
-    CPU_PPC_e200      = 0x81120000,
-    CPU_PPC_e500v110  = 0x80200010,
-    CPU_PPC_e500v120  = 0x80200020,
-    CPU_PPC_e500v210  = 0x80210010,
-    CPU_PPC_e500v220  = 0x80210020,
-#define CPU_PPC_e500 CPU_PPC_e500v220
-    CPU_PPC_e600      = 0x80040010,
-    /* PowerPC 6xx cores */
-    CPU_PPC_601       = 0x00010001,
-    CPU_PPC_602       = 0x00050100,
-    CPU_PPC_603       = 0x00030100,
-    CPU_PPC_603E      = 0x00060101,
-    CPU_PPC_603P      = 0x00070000,
-    CPU_PPC_603E7v    = 0x00070100,
-    CPU_PPC_603E7v2   = 0x00070201,
-    CPU_PPC_603E7     = 0x00070200,
-    CPU_PPC_603R      = 0x00071201,
-    CPU_PPC_G2        = 0x00810011,
-    CPU_PPC_G2H4      = 0x80811010,
-    CPU_PPC_G2gp      = 0x80821010,
-    CPU_PPC_G2ls      = 0x90810010,
-    CPU_PPC_G2LE      = 0x80820010,
-    CPU_PPC_G2LEgp    = 0x80822010,
-    CPU_PPC_G2LEls    = 0xA0822010,
-    CPU_PPC_604       = 0x00040000,
-    CPU_PPC_604E      = 0x00090100, /* Also 2110 & 2120 */
-    CPU_PPC_604R      = 0x000a0101,
-    /* PowerPC 74x/75x cores (aka G3) */
-    CPU_PPC_74x       = 0x00080000,
-    CPU_PPC_740E      = 0x00080100,
-    CPU_PPC_74xP      = 0x10080000,
-    CPU_PPC_750E      = 0x00080200,
-    CPU_PPC_750CXE21  = 0x00082201,
-    CPU_PPC_750CXE22  = 0x00082212,
-    CPU_PPC_750CXE23  = 0x00082203,
-    CPU_PPC_750CXE24  = 0x00082214,
-    CPU_PPC_750CXE24b = 0x00083214,
-    CPU_PPC_750CXE31  = 0x00083211,
-    CPU_PPC_750CXE31b = 0x00083311,
-#define CPU_PPC_750CXE CPU_PPC_750CXE31b
-    CPU_PPC_750CXR    = 0x00083410,
-    CPU_PPC_750FX10   = 0x70000100,
-    CPU_PPC_750FX20   = 0x70000200,
-    CPU_PPC_750FX21   = 0x70000201,
-    CPU_PPC_750FX22   = 0x70000202,
-    CPU_PPC_750FX23   = 0x70000203,
-#define CPU_PPC_750FX CPU_PPC_750FX23
-    CPU_PPC_750FL     = 0x700A0203,
-    CPU_PPC_750GX10   = 0x70020100,
-    CPU_PPC_750GX11   = 0x70020101,
-    CPU_PPC_750GX12   = 0x70020102,
-#define CPU_PPC_750GX CPU_PPC_750GX12
-    CPU_PPC_750GL     = 0x70020102,
-    CPU_PPC_750L30    = 0x00088300,
-    CPU_PPC_750L32    = 0x00088302,
-#define CPU_PPC_750L CPU_PPC_750L32
-    CPU_PPC_750CL     = 0x00087200,
-    CPU_PPC_755_10    = 0x00083100,
-    CPU_PPC_755_11    = 0x00083101,
-    CPU_PPC_755_20    = 0x00083200,
-    CPU_PPC_755D      = 0x00083202,
-    CPU_PPC_755E      = 0x00083203,
-#define CPU_PPC_755 CPU_PPC_755E
-    /* PowerPC 74xx cores (aka G4) */
-    CPU_PPC_7400      = 0x000C0100,
-    CPU_PPC_7410C     = 0x800C1102,
-    CPU_PPC_7410D     = 0x800C1103,
-    CPU_PPC_7410E     = 0x800C1104,
-#define CPU_PPC_7410 CPU_PPC_7410E
-    CPU_PPC_7441      = 0x80000210,
-    CPU_PPC_7445      = 0x80010100,
-    CPU_PPC_7447      = 0x80020100,
-    CPU_PPC_7447A     = 0x80030101,
-    CPU_PPC_7448      = 0x80040100,
-    CPU_PPC_7450      = 0x80000200,
-    CPU_PPC_7450b     = 0x80000201,
-    CPU_PPC_7451      = 0x80000203,
-    CPU_PPC_7451G     = 0x80000210,
-    CPU_PPC_7455      = 0x80010201,
-    CPU_PPC_7455F     = 0x80010303,
-    CPU_PPC_7455G     = 0x80010304,
-    CPU_PPC_7457      = 0x80020101,
-    CPU_PPC_7457C     = 0x80020102,
-    CPU_PPC_7457A     = 0x80030000,
-    /* 64 bits PowerPC */
-    CPU_PPC_620       = 0x00140000,
-    CPU_PPC_630       = 0x00400000,
-    CPU_PPC_631       = 0x00410000,
-    CPU_PPC_POWER4    = 0x00350000,
-    CPU_PPC_POWER4P   = 0x00380000,
-    CPU_PPC_POWER5    = 0x003A0000,
-    CPU_PPC_POWER5P   = 0x003B0000,
-#if 0
-    CPU_PPC_POWER6    = xxx,
-#endif
-    CPU_PPC_970       = 0x00390000,
-    CPU_PPC_970FX10   = 0x00391100,
-    CPU_PPC_970FX20   = 0x003C0200,
-    CPU_PPC_970FX21   = 0x003C0201,
-    CPU_PPC_970FX30   = 0x003C0300,
-    CPU_PPC_970FX31   = 0x003C0301,
-#define CPU_PPC_970FX CPU_PPC_970FX31
-    CPU_PPC_970MP10   = 0x00440100,
-    CPU_PPC_970MP11   = 0x00440101,
-#define CPU_PPC_970MP CPU_PPC_970MP11
-    CPU_PPC_CELL10    = 0x00700100,
-    CPU_PPC_CELL20    = 0x00700400,
-    CPU_PPC_CELL30    = 0x00700500,
-    CPU_PPC_CELL31    = 0x00700501,
-#define CPU_PPC_CELL32 CPU_PPC_CELL31
-#define CPU_PPC_CELL CPU_PPC_CELL32
-    CPU_PPC_RS64      = 0x00330000,
-    CPU_PPC_RS64II    = 0x00340000,
-    CPU_PPC_RS64III   = 0x00360000,
-    CPU_PPC_RS64IV    = 0x00370000,
-    /* Original POWER */
-    /* XXX: should be POWER (RIOS), RSC3308, RSC4608,
-     * POWER2 (RIOS2) & RSC2 (P2SC) here
-     */
-#if 0
-    CPU_POWER         = xxx,
-#endif
-#if 0
-    CPU_POWER2        = xxx,
-#endif
-};
-
-/* System version register (used on MPC 8xxx) */
-enum {
-    PPC_SVR_8540      = 0x80300000,
-    PPC_SVR_8541E     = 0x807A0010,
-    PPC_SVR_8543v10   = 0x80320010,
-    PPC_SVR_8543v11   = 0x80320011,
-    PPC_SVR_8543v20   = 0x80320020,
-    PPC_SVR_8543Ev10  = 0x803A0010,
-    PPC_SVR_8543Ev11  = 0x803A0011,
-    PPC_SVR_8543Ev20  = 0x803A0020,
-    PPC_SVR_8545      = 0x80310220,
-    PPC_SVR_8545E     = 0x80390220,
-    PPC_SVR_8547E     = 0x80390120,
-    PPC_SCR_8548v10   = 0x80310010,
-    PPC_SCR_8548v11   = 0x80310011,
-    PPC_SCR_8548v20   = 0x80310020,
-    PPC_SVR_8548Ev10  = 0x80390010,
-    PPC_SVR_8548Ev11  = 0x80390011,
-    PPC_SVR_8548Ev20  = 0x80390020,
-    PPC_SVR_8555E     = 0x80790010,
-    PPC_SVR_8560v10   = 0x80700010,
-    PPC_SVR_8560v20   = 0x80700020,
+    POWERPC_MMU_UNKNOWN    = 0,
+    /* Standard 32 bits PowerPC MMU                            */
+    POWERPC_MMU_32B,
+    /* Standard 64 bits PowerPC MMU                            */
+    POWERPC_MMU_64B,
+    /* PowerPC 601 MMU                                         */
+    POWERPC_MMU_601,
+    /* PowerPC 6xx MMU with software TLB                       */
+    POWERPC_MMU_SOFT_6xx,
+    /* PowerPC 74xx MMU with software TLB                      */
+    POWERPC_MMU_SOFT_74xx,
+    /* PowerPC 4xx MMU with software TLB                       */
+    POWERPC_MMU_SOFT_4xx,
+    /* PowerPC 4xx MMU with software TLB and zones protections */
+    POWERPC_MMU_SOFT_4xx_Z,
+    /* PowerPC 4xx MMU in real mode only                       */
+    POWERPC_MMU_REAL_4xx,
+    /* BookE MMU model                                         */
+    POWERPC_MMU_BOOKE,
+    /* BookE FSL MMU model                                     */
+    POWERPC_MMU_BOOKE_FSL,
+    /* 64 bits "bridge" PowerPC MMU                            */
+    POWERPC_MMU_64BRIDGE,
 };
 
 /*****************************************************************************/
-/* Instruction types */
-enum {
-    PPC_NONE        = 0x00000000,
-    /* integer operations instructions             */
-    /* flow control instructions                   */
-    /* virtual memory instructions                 */
-    /* ld/st with reservation instructions         */
-    /* cache control instructions                  */
-    /* spr/msr access instructions                 */
-    PPC_INSNS_BASE  = 0x0000000000000001ULL,
-#define PPC_INTEGER PPC_INSNS_BASE
-#define PPC_FLOW    PPC_INSNS_BASE
-#define PPC_MEM     PPC_INSNS_BASE
-#define PPC_RES     PPC_INSNS_BASE
-#define PPC_CACHE   PPC_INSNS_BASE
-#define PPC_MISC    PPC_INSNS_BASE
-    /* floating point operations instructions      */
-    PPC_FLOAT       = 0x0000000000000002ULL,
-    /* more floating point operations instructions */
-    PPC_FLOAT_EXT   = 0x0000000000000004ULL,
-    /* external control instructions               */
-    PPC_EXTERN      = 0x0000000000000008ULL,
-    /* segment register access instructions        */
-    PPC_SEGMENT     = 0x0000000000000010ULL,
-    /* Optional cache control instructions         */
-    PPC_CACHE_OPT   = 0x0000000000000020ULL,
-    /* Optional floating point op instructions     */
-    PPC_FLOAT_OPT   = 0x0000000000000040ULL,
-    /* Optional memory control instructions        */
-    PPC_MEM_TLBIA   = 0x0000000000000080ULL,
-    PPC_MEM_TLBIE   = 0x0000000000000100ULL,
-    PPC_MEM_TLBSYNC = 0x0000000000000200ULL,
-    /* eieio & sync                                */
-    PPC_MEM_SYNC    = 0x0000000000000400ULL,
-    /* PowerPC 6xx TLB management instructions     */
-    PPC_6xx_TLB     = 0x0000000000000800ULL,
-    /* Altivec support                             */
-    PPC_ALTIVEC     = 0x0000000000001000ULL,
-    /* Time base support                           */
-    PPC_TB          = 0x0000000000002000ULL,
-    /* Embedded PowerPC dedicated instructions     */
-    PPC_EMB_COMMON  = 0x0000000000004000ULL,
-    /* PowerPC 40x exception model                 */
-    PPC_40x_EXCP    = 0x0000000000008000ULL,
-    /* PowerPC 40x specific instructions           */
-    PPC_40x_SPEC    = 0x0000000000010000ULL,
-    /* PowerPC 405 Mac instructions                */
-    PPC_405_MAC     = 0x0000000000020000ULL,
-    /* PowerPC 440 specific instructions           */
-    PPC_440_SPEC    = 0x0000000000040000ULL,
-    /* Specific extensions */
-    /* Power-to-PowerPC bridge (601)               */
-    PPC_POWER_BR    = 0x0000000000080000ULL,
-    /* PowerPC 602 specific */
-    PPC_602_SPEC    = 0x0000000000100000ULL,
-    /* Deprecated instructions                     */
-    /* Original POWER instruction set              */
-    PPC_POWER       = 0x0000000000200000ULL,
-    /* POWER2 instruction set extension            */
-    PPC_POWER2      = 0x0000000000400000ULL,
-    /* Power RTC support */
-    PPC_POWER_RTC   = 0x0000000000800000ULL,
-    /* 64 bits PowerPC instructions                */
-    /* 64 bits PowerPC instruction set             */
-    PPC_64B         = 0x0000000001000000ULL,
-    /* 64 bits hypervisor extensions               */
-    PPC_64H         = 0x0000000002000000ULL,
-    /* 64 bits PowerPC "bridge" features           */
-    PPC_64_BRIDGE   = 0x0000000004000000ULL,
-    /* BookE (embedded) PowerPC specification      */
-    PPC_BOOKE       = 0x0000000008000000ULL,
-    /* eieio                                       */
-    PPC_MEM_EIEIO   = 0x0000000010000000ULL,
-    /* e500 vector instructions                    */
-    PPC_E500_VECTOR = 0x0000000020000000ULL,
-    /* PowerPC 4xx dedicated instructions          */
-    PPC_4xx_COMMON  = 0x0000000040000000ULL,
-    /* PowerPC 2.03 specification extensions       */
-    PPC_203         = 0x0000000080000000ULL,
-    /* PowerPC 2.03 SPE extension                  */
-    PPC_SPE         = 0x0000000100000000ULL,
-    /* PowerPC 2.03 SPE floating-point extension   */
-    PPC_SPEFPU      = 0x0000000200000000ULL,
-    /* SLB management                              */
-    PPC_SLBI        = 0x0000000400000000ULL,
-    /* PowerPC 40x ibct instructions               */
-    PPC_40x_ICBT    = 0x0000000800000000ULL,
-};
-
-/* CPU run-time flags (MMU and exception model) */
+/* Exception model                                                           */
 enum {
-    /* MMU model                         */
-    PPC_FLAGS_MMU_MASK       = 0x000000FF,
-    /* Standard 32 bits PowerPC MMU      */
-    PPC_FLAGS_MMU_32B        = 0x00000000,
-    /* Standard 64 bits PowerPC MMU      */
-    PPC_FLAGS_MMU_64B        = 0x00000001,
-    /* PowerPC 601 MMU                   */
-    PPC_FLAGS_MMU_601        = 0x00000002,
-    /* PowerPC 6xx MMU with software TLB */
-    PPC_FLAGS_MMU_SOFT_6xx   = 0x00000003,
-    /* PowerPC 4xx MMU with software TLB */
-    PPC_FLAGS_MMU_SOFT_4xx   = 0x00000004,
-    /* PowerPC 403 MMU                  */
-    PPC_FLAGS_MMU_403        = 0x00000005,
-    /* BookE FSL MMU model              */
-    PPC_FLAGS_MMU_BOOKE_FSL  = 0x00000006,
-    /* BookE MMU model                  */
-    PPC_FLAGS_MMU_BOOKE      = 0x00000007,
-    /* 64 bits "bridge" PowerPC MMU     */
-    PPC_FLAGS_MMU_64BRIDGE   = 0x00000008,
-    /* PowerPC 401 MMU (real mode only) */
-    PPC_FLAGS_MMU_401        = 0x00000009,
-    /* Exception model                  */
-    PPC_FLAGS_EXCP_MASK      = 0x0000FF00,
+    POWERPC_EXCP_UNKNOWN   = 0,
     /* Standard PowerPC exception model */
-    PPC_FLAGS_EXCP_STD       = 0x00000000,
+    POWERPC_EXCP_STD,
     /* PowerPC 40x exception model      */
-    PPC_FLAGS_EXCP_40x       = 0x00000100,
+    POWERPC_EXCP_40x,
     /* PowerPC 601 exception model      */
-    PPC_FLAGS_EXCP_601       = 0x00000200,
+    POWERPC_EXCP_601,
     /* PowerPC 602 exception model      */
-    PPC_FLAGS_EXCP_602       = 0x00000300,
+    POWERPC_EXCP_602,
     /* PowerPC 603 exception model      */
-    PPC_FLAGS_EXCP_603       = 0x00000400,
+    POWERPC_EXCP_603,
+    /* PowerPC 603e exception model     */
+    POWERPC_EXCP_603E,
+    /* PowerPC G2 exception model       */
+    POWERPC_EXCP_G2,
     /* PowerPC 604 exception model      */
-    PPC_FLAGS_EXCP_604       = 0x00000500,
+    POWERPC_EXCP_604,
     /* PowerPC 7x0 exception model      */
-    PPC_FLAGS_EXCP_7x0       = 0x00000600,
+    POWERPC_EXCP_7x0,
     /* PowerPC 7x5 exception model      */
-    PPC_FLAGS_EXCP_7x5       = 0x00000700,
+    POWERPC_EXCP_7x5,
     /* PowerPC 74xx exception model     */
-    PPC_FLAGS_EXCP_74xx      = 0x00000800,
+    POWERPC_EXCP_74xx,
     /* PowerPC 970 exception model      */
-    PPC_FLAGS_EXCP_970       = 0x00000900,
+    POWERPC_EXCP_970,
     /* BookE exception model            */
-    PPC_FLAGS_EXCP_BOOKE     = 0x00000A00,
-    /* Input pins model                 */
-    PPC_FLAGS_INPUT_MASK     = 0x000F0000,
+    POWERPC_EXCP_BOOKE,
+};
+
+/*****************************************************************************/
+/* Input pins model                                                          */
+enum {
+    PPC_FLAGS_INPUT_UNKNOWN = 0,
     /* PowerPC 6xx bus                  */
-    PPC_FLAGS_INPUT_6xx      = 0x00000000,
+    PPC_FLAGS_INPUT_6xx,
     /* BookE bus                        */
-    PPC_FLAGS_INPUT_BookE    = 0x00010000,
-    /* PowerPC 4xx bus                  */
-    PPC_FLAGS_INPUT_40x      = 0x00020000,
+    PPC_FLAGS_INPUT_BookE,
+    /* PowerPC 405 bus                  */
+    PPC_FLAGS_INPUT_405,
     /* PowerPC 970 bus                  */
-    PPC_FLAGS_INPUT_970      = 0x00030000,
+    PPC_FLAGS_INPUT_970,
+    /* PowerPC 401 bus                  */
+    PPC_FLAGS_INPUT_401,
 };
 
-#define PPC_MMU(env) (env->flags & PPC_FLAGS_MMU_MASK)
-#define PPC_EXCP(env) (env->flags & PPC_FLAGS_EXCP_MASK)
-#define PPC_INPUT(env) (env->flags & PPC_FLAGS_INPUT_MASK)
+#define PPC_INPUT(env) (env->bus_model)
 
-/*****************************************************************************/
-/* Supported instruction set definitions */
-/* This generates an empty opcode table... */
-#define PPC_INSNS_TODO (PPC_NONE)
-#define PPC_FLAGS_TODO (0x00000000)
-
-/* PowerPC 40x instruction set */
-#define PPC_INSNS_EMB (PPC_INSNS_BASE | PPC_EMB_COMMON)
-/* PowerPC 401 */
-#define PPC_INSNS_401 (PPC_INSNS_EMB | PPC_MEM_SYNC | PPC_MEM_EIEIO |         \
-                       PPC_4xx_COMMON | PPC_40x_EXCP | PPC_40x_ICBT)
-#define PPC_FLAGS_401 (PPC_FLAGS_MMU_401 | PPC_FLAGS_EXCP_40x |               \
-                       PPC_FLAGS_INPUT_40x)
-/* PowerPC 403 */
-#define PPC_INSNS_403 (PPC_INSNS_EMB | PPC_MEM_SYNC | PPC_MEM_EIEIO |         \
-                       PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | PPC_4xx_COMMON |     \
-                       PPC_40x_EXCP | PPC_40x_SPEC | PPC_40x_ICBT)
-#define PPC_FLAGS_403 (PPC_FLAGS_MMU_403 | PPC_FLAGS_EXCP_40x |               \
-                       PPC_FLAGS_INPUT_40x)
-/* PowerPC 405 */
-#define PPC_INSNS_405 (PPC_INSNS_EMB | PPC_MEM_SYNC | PPC_MEM_EIEIO |         \
-                       PPC_CACHE_OPT | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC |      \
-                       PPC_TB | PPC_4xx_COMMON | PPC_40x_SPEC |               \
-                       PPC_40x_ICBT | PPC_40x_EXCP | PPC_405_MAC)
-#define PPC_FLAGS_405 (PPC_FLAGS_MMU_SOFT_4xx | PPC_FLAGS_EXCP_40x |          \
-                       PPC_FLAGS_INPUT_40x)
-/* PowerPC 440 */
-#define PPC_INSNS_440 (PPC_INSNS_EMB | PPC_CACHE_OPT | PPC_BOOKE |            \
-                       PPC_MEM_TLBSYNC | PPC_4xx_COMMON | PPC_405_MAC |       \
-                       PPC_440_SPEC)
-#define PPC_FLAGS_440 (PPC_FLAGS_MMU_BOOKE | PPC_FLAGS_EXCP_BOOKE |           \
-                       PPC_FLAGS_INPUT_BookE)
-/* Generic BookE PowerPC */
-#define PPC_INSNS_BOOKE (PPC_INSNS_EMB | PPC_MEM_TLBSYNC | PPC_BOOKE |        \
-                         PPC_MEM_EIEIO | PPC_FLOAT | PPC_FLOAT_OPT |          \
-                         PPC_CACHE_OPT)
-#define PPC_FLAGS_BOOKE (PPC_FLAGS_MMU_BOOKE | PPC_FLAGS_EXCP_BOOKE |         \
-                         PPC_FLAGS_INPUT_BookE)
-/* e500 core */
-#define PPC_INSNS_E500 (PPC_INSNS_EMB | PPC_MEM_TLBSYNC | PPC_BOOKE |         \
-                        PPC_MEM_EIEIO | PPC_CACHE_OPT | PPC_E500_VECTOR)
-#define PPC_FLAGS_E500 (PPC_FLAGS_MMU_SOFT_4xx | PPC_FLAGS_EXCP_40x |         \
-                        PPC_FLAGS_INPUT_BookE)
-/* Non-embedded PowerPC */
-#define PPC_INSNS_COMMON  (PPC_INSNS_BASE | PPC_FLOAT | PPC_MEM_SYNC |        \
-                           PPC_MEM_EIEIO | PPC_SEGMENT | PPC_MEM_TLBIE)
-/* PowerPC 601 */
-#define PPC_INSNS_601 (PPC_INSNS_COMMON | PPC_EXTERN | PPC_POWER_BR)
-#define PPC_FLAGS_601 (PPC_FLAGS_MMU_601 | PPC_FLAGS_EXCP_601 |               \
-                       PPC_FLAGS_INPUT_6xx)
-/* PowerPC 602 */
-#define PPC_INSNS_602 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_6xx_TLB |       \
-                       PPC_MEM_TLBSYNC | PPC_TB | PPC_602_SPEC)
-#define PPC_FLAGS_602 (PPC_FLAGS_MMU_SOFT_6xx | PPC_FLAGS_EXCP_602 |          \
-                       PPC_FLAGS_INPUT_6xx)
-/* PowerPC 603 */
-#define PPC_INSNS_603 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_6xx_TLB |       \
-                       PPC_MEM_TLBSYNC | PPC_EXTERN | PPC_TB)
-#define PPC_FLAGS_603 (PPC_FLAGS_MMU_SOFT_6xx | PPC_FLAGS_EXCP_603 |          \
-                       PPC_FLAGS_INPUT_6xx)
-/* PowerPC G2 */
-#define PPC_INSNS_G2 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_6xx_TLB |        \
-                      PPC_MEM_TLBSYNC | PPC_EXTERN | PPC_TB)
-#define PPC_FLAGS_G2 (PPC_FLAGS_MMU_SOFT_6xx | PPC_FLAGS_EXCP_603 |           \
-                      PPC_FLAGS_INPUT_6xx)
-/* PowerPC 604 */
-#define PPC_INSNS_604 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_EXTERN |        \
-                       PPC_MEM_TLBSYNC | PPC_TB)
-#define PPC_FLAGS_604 (PPC_FLAGS_MMU_32B | PPC_FLAGS_EXCP_604 |               \
-                       PPC_FLAGS_INPUT_6xx)
-/* PowerPC 740/750 (aka G3) */
-#define PPC_INSNS_7x0 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_EXTERN |        \
-                       PPC_MEM_TLBSYNC | PPC_TB)
-#define PPC_FLAGS_7x0 (PPC_FLAGS_MMU_32B | PPC_FLAGS_EXCP_7x0 |               \
-                       PPC_FLAGS_INPUT_6xx)
-/* PowerPC 745/755 */
-#define PPC_INSNS_7x5 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_EXTERN |        \
-                       PPC_MEM_TLBSYNC | PPC_TB | PPC_6xx_TLB)
-#define PPC_FLAGS_7x5 (PPC_FLAGS_MMU_SOFT_6xx | PPC_FLAGS_EXCP_7x5 |          \
-                       PPC_FLAGS_INPUT_6xx)
-/* PowerPC 74xx (aka G4) */
-#define PPC_INSNS_74xx (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_ALTIVEC |      \
-                        PPC_MEM_TLBSYNC | PPC_TB)
-#define PPC_FLAGS_74xx (PPC_FLAGS_MMU_32B | PPC_FLAGS_EXCP_74xx |             \
-                        PPC_FLAGS_INPUT_6xx)
-/* PowerPC 970 (aka G5) */
-#define PPC_INSNS_970  (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_FLOAT_OPT |    \
-                        PPC_ALTIVEC | PPC_MEM_TLBSYNC | PPC_TB |              \
-                        PPC_64B | PPC_64_BRIDGE | PPC_SLBI)
-#define PPC_FLAGS_970  (PPC_FLAGS_MMU_64BRIDGE | PPC_FLAGS_EXCP_970 |         \
-                        PPC_FLAGS_INPUT_970)
-
-/* Default PowerPC will be 604/970 */
-#define PPC_INSNS_PPC32 PPC_INSNS_604
-#define PPC_FLAGS_PPC32 PPC_FLAGS_604
-#define PPC_INSNS_PPC64 PPC_INSNS_970
-#define PPC_FLAGS_PPC64 PPC_FLAGS_970
-#define PPC_INSNS_DEFAULT PPC_INSNS_604
-#define PPC_FLAGS_DEFAULT PPC_FLAGS_604
 typedef struct ppc_def_t ppc_def_t;
+typedef struct opc_handler_t opc_handler_t;
 
 /*****************************************************************************/
 /* Types used to describe some PowerPC registers */
 typedef struct CPUPPCState CPUPPCState;
-typedef struct opc_handler_t opc_handler_t;
 typedef struct ppc_tb_t ppc_tb_t;
 typedef struct ppc_spr_t ppc_spr_t;
 typedef struct ppc_dcr_t ppc_dcr_t;
@@ -832,7 +393,11 @@ struct CPUPPCState {
 
     /* Those resources are used during exception processing */
     /* CPU model definition */
-    uint64_t msr_mask;
+    target_ulong msr_mask;
+    uint8_t mmu_model;
+    uint8_t excp_model;
+    uint8_t bus_model;
+    uint8_t pad;
     uint32_t flags;
 
     int exception_index;
@@ -985,7 +550,7 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
 #define SPR_LR           (0x008)
 #define SPR_CTR          (0x009)
 #define SPR_DSISR        (0x012)
-#define SPR_DAR          (0x013)
+#define SPR_DAR          (0x013) /* DAE for PowerPC 601 */
 #define SPR_601_RTCU     (0x014)
 #define SPR_601_RTCL     (0x015)
 #define SPR_DECR         (0x016)
@@ -1203,6 +768,8 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
 #define SPR_440_ITV1     (0x375)
 #define SPR_440_ITV2     (0x376)
 #define SPR_440_ITV3     (0x377)
+#define SPR_440_CCR1     (0x378)
+#define SPR_DCRIPR       (0x37B)
 #define SPR_PPR          (0x380)
 #define SPR_440_DNV0     (0x390)
 #define SPR_440_DNV1     (0x391)
@@ -1219,38 +786,63 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
 #define SPR_BOOKE_DCDBTRH (0x39D)
 #define SPR_BOOKE_ICDBTRL (0x39E)
 #define SPR_BOOKE_ICDBTRH (0x39F)
+#define SPR_UMMCR2       (0x3A0)
+#define SPR_UPMC5        (0x3A1)
+#define SPR_UPMC6        (0x3A2)
+#define SPR_UBAMR        (0x3A7)
 #define SPR_UMMCR0       (0x3A8)
 #define SPR_UPMC1        (0x3A9)
 #define SPR_UPMC2        (0x3AA)
-#define SPR_USIA         (0x3AB)
+#define SPR_USIAR        (0x3AB)
 #define SPR_UMMCR1       (0x3AC)
 #define SPR_UPMC3        (0x3AD)
 #define SPR_UPMC4        (0x3AE)
 #define SPR_USDA         (0x3AF)
 #define SPR_40x_ZPR      (0x3B0)
 #define SPR_BOOKE_MAS7   (0x3B0)
+#define SPR_620_PMR0     (0x3B0)
+#define SPR_MMCR2        (0x3B0)
+#define SPR_PMC5         (0x3B1)
 #define SPR_40x_PID      (0x3B1)
+#define SPR_620_PMR1     (0x3B1)
+#define SPR_PMC6         (0x3B2)
 #define SPR_440_MMUCR    (0x3B2)
+#define SPR_620_PMR2     (0x3B2)
 #define SPR_4xx_CCR0     (0x3B3)
 #define SPR_BOOKE_EPLC   (0x3B3)
+#define SPR_620_PMR3     (0x3B3)
 #define SPR_405_IAC3     (0x3B4)
 #define SPR_BOOKE_EPSC   (0x3B4)
+#define SPR_620_PMR4     (0x3B4)
 #define SPR_405_IAC4     (0x3B5)
+#define SPR_620_PMR5     (0x3B5)
 #define SPR_405_DVC1     (0x3B6)
+#define SPR_620_PMR6     (0x3B6)
 #define SPR_405_DVC2     (0x3B7)
+#define SPR_620_PMR7     (0x3B7)
+#define SPR_BAMR         (0x3B7)
 #define SPR_MMCR0        (0x3B8)
+#define SPR_620_PMR8     (0x3B8)
 #define SPR_PMC1         (0x3B9)
 #define SPR_40x_SGR      (0x3B9)
+#define SPR_620_PMR9     (0x3B9)
 #define SPR_PMC2         (0x3BA)
 #define SPR_40x_DCWR     (0x3BA)
-#define SPR_SIA          (0x3BB)
+#define SPR_620_PMRA     (0x3BA)
+#define SPR_SIAR         (0x3BB)
 #define SPR_405_SLER     (0x3BB)
+#define SPR_620_PMRB     (0x3BB)
 #define SPR_MMCR1        (0x3BC)
 #define SPR_405_SU0R     (0x3BC)
+#define SPR_620_PMRC     (0x3BC)
+#define SPR_401_SKR      (0x3BC)
 #define SPR_PMC3         (0x3BD)
 #define SPR_405_DBCR1    (0x3BD)
+#define SPR_620_PMRD     (0x3BD)
 #define SPR_PMC4         (0x3BE)
+#define SPR_620_PMRE     (0x3BE)
 #define SPR_SDA          (0x3BF)
+#define SPR_620_PMRF     (0x3BF)
 #define SPR_403_VTBL     (0x3CC)
 #define SPR_403_VTBU     (0x3CD)
 #define SPR_DMISS        (0x3D0)
@@ -1258,18 +850,23 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
 #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_L3OHCR       (0x3D8)
 #define SPR_TCR          (0x3D8)
 #define SPR_40x_TSR      (0x3D8)
 #define SPR_IBR          (0x3DA)
 #define SPR_40x_TCR      (0x3DA)
-#define SPR_ESASR        (0x3DB)
+#define SPR_ESASRR       (0x3DB)
 #define SPR_40x_PIT      (0x3DB)
 #define SPR_403_TBL      (0x3DC)
 #define SPR_403_TBU      (0x3DD)
@@ -1277,6 +874,10 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
 #define SPR_40x_SRR2     (0x3DE)
 #define SPR_SER          (0x3DF)
 #define SPR_40x_SRR3     (0x3DF)
+#define SPR_L3ITCR0      (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)
@@ -1284,9 +885,11 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
 #define SPR_40x_DBCR0    (0x3F2)
 #define SPR_601_HID2     (0x3F2)
 #define SPR_E500_L1CSR0  (0x3F2)
+#define SPR_ICTRL        (0x3F3)
 #define SPR_HID2         (0x3F3)
 #define SPR_E500_L1CSR1  (0x3F3)
 #define SPR_440_DBDR     (0x3F3)
+#define SPR_LDSTDB       (0x3F4)
 #define SPR_40x_IAC1     (0x3F4)
 #define SPR_BOOKE_MMUCSR0 (0x3F4)
 #define SPR_DABR         (0x3F5)
@@ -1295,12 +898,18 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
 #define SPR_40x_IAC2     (0x3F5)
 #define SPR_601_HID5     (0x3F5)
 #define SPR_40x_DAC1     (0x3F6)
+#define SPR_MSSCR0       (0x3F6)
+#define SPR_MSSSR0       (0x3F7)
 #define SPR_DABRX        (0x3F7)
 #define SPR_40x_DAC2     (0x3F7)
 #define SPR_BOOKE_MMUCFG (0x3F7)
-#define SPR_L2PM         (0x3F8)
+#define SPR_LDSTCR       (0x3F8)
+#define SPR_L2PMCR       (0x3F8)
 #define SPR_750_HID2     (0x3F8)
+#define SPR_620_HID8     (0x3F8)
 #define SPR_L2CR         (0x3F9)
+#define SPR_620_HID9     (0x3F9)
+#define SPR_L3CR         (0x3FA)
 #define SPR_IABR2        (0x3FA)
 #define SPR_40x_DCCR     (0x3FA)
 #define SPR_ICTC         (0x3FB)
@@ -1310,6 +919,7 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
 #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_FPECR        (0x3FE)
@@ -1317,6 +927,7 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
 #define SPR_PIR          (0x3FF)
 #define SPR_403_PBU2     (0x3FF)
 #define SPR_601_HID15    (0x3FF)
+#define SPR_604_HID15    (0x3FF)
 #define SPR_E500_SVR     (0x3FF)
 
 /*****************************************************************************/
@@ -1367,6 +978,11 @@ enum {
 #define EXCP_40x_DEBUG     0x2000 /* Debug exception                         */
 /* 405 specific exceptions                                                   */
 #define EXCP_405_APU       0x0F20 /* APU unavailable exception               */
+/* 440 specific exceptions                                                   */
+#define EXCP_440_CRIT      0x0100 /* Critical interrupt                      */
+#define EXCP_440_SPEU      0x1600 /* SPE unavailable exception               */
+#define EXCP_440_SPED      0x1700 /* SPE floating-point data exception       */
+#define EXCP_440_SPER      0x1800 /* SPE floating-point round exception      */
 /* TLB assist exceptions (602/603)                                           */
 #define EXCP_I_TLBMISS     0x1000 /* Instruction TLB miss                    */
 #define EXCP_DL_TLBMISS    0x1100 /* Data load TLB miss                      */
@@ -1377,7 +993,7 @@ enum {
 /* Altivec related exceptions                                                */
 #define EXCP_VPU           0x0F20 /* VPU unavailable exception               */
 /* 601 specific exceptions                                                   */
-#define EXCP_601_IO        0x0600 /* IO error exception                      */
+#define EXCP_601_IO        0x0A00 /* IO error exception                      */
 #define EXCP_601_RUNM      0x2000 /* Run mode exception                      */
 /* 602 specific exceptions                                                   */
 #define EXCP_602_WATCHDOG  0x1500 /* Watchdog exception                      */
@@ -1467,6 +1083,15 @@ enum {
     PPCBookE_INPUT_CINT       = 6,
 };
 
+enum {
+    /* PowerPC 401/403 input pins */
+    PPC401_INPUT_RESET      = 0,
+    PPC401_INPUT_CINT       = 1,
+    PPC401_INPUT_INT        = 2,
+    PPC401_INPUT_BERR       = 3,
+    PPC401_INPUT_HALT       = 4,
+};
+
 enum {
     /* PowerPC 405 input pins */
     PPC405_INPUT_RESET_CORE = 0,
@@ -1478,6 +1103,18 @@ enum {
     PPC405_INPUT_DEBUG      = 6,
 };
 
+enum {
+    /* PowerPC 620 (and probably others) input pins */
+    PPC620_INPUT_HRESET     = 0,
+    PPC620_INPUT_SRESET     = 1,
+    PPC620_INPUT_CKSTP      = 2,
+    PPC620_INPUT_TBEN       = 3,
+    PPC620_INPUT_WAKEUP     = 4,
+    PPC620_INPUT_MCP        = 5,
+    PPC620_INPUT_SMI        = 6,
+    PPC620_INPUT_INT        = 7,
+};
+
 enum {
     /* PowerPC 970 input pins */
     PPC970_INPUT_HRESET     = 0,
index 156693291938e3434ed84669d252fe82b2c1e337..10a51e93cb976672c9ade902363d7b51716534fe 100644 (file)
@@ -106,6 +106,8 @@ void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
 void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code,
                        target_ulong pte0, target_ulong pte1);
 void ppc4xx_tlb_invalidate_all (CPUState *env);
+void ppc4xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
+                                 uint32_t pid);
 
 static inline void env_to_regs (void)
 {
index 061db8760951163368fb84c54c335a5a172f3901..f27a7f50a50581ea7c8bc6aee2b1366897c3c475 100644 (file)
@@ -586,8 +586,8 @@ static int find_pte64 (mmu_ctx_t *ctx, int h, int rw)
 static inline int find_pte (CPUState *env, mmu_ctx_t *ctx, int h, int rw)
 {
 #if defined(TARGET_PPC64)
-    if (PPC_MMU(env) == PPC_FLAGS_MMU_64B ||
-        PPC_MMU(env) == PPC_FLAGS_MMU_64BRIDGE)
+    if (env->mmu_model == POWERPC_MMU_64B ||
+        env->mmu_model == POWERPC_MMU_64BRIDGE)
         return find_pte64(ctx, h, rw);
 #endif
 
@@ -669,7 +669,7 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx,
     int ret, ret2;
 
 #if defined(TARGET_PPC64)
-    if (PPC_MMU(env) == PPC_FLAGS_MMU_64B) {
+    if (env->mmu_model == POWERPC_MMU_64B) {
         ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr);
         if (ret < 0)
             return ret;
@@ -724,8 +724,8 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx,
             hash = (~hash) & vsid_mask;
             ctx->pg_addr[1] = get_pgaddr(sdr, sdr_sh, hash, mask);
 #if defined(TARGET_PPC64)
-            if (PPC_MMU(env) == PPC_FLAGS_MMU_64B ||
-                PPC_MMU(env) == PPC_FLAGS_MMU_64BRIDGE) {
+            if (env->mmu_model == POWERPC_MMU_64B ||
+                env->mmu_model == POWERPC_MMU_64BRIDGE) {
                 /* Only 5 bits of the page index are used in the AVPN */
                 ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80);
             } else
@@ -735,7 +735,7 @@ static int get_segment (CPUState *env, mmu_ctx_t *ctx,
             }
             /* Initialize real address with an invalid value */
             ctx->raddr = (target_ulong)-1;
-            if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
+            if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) {
                 /* Software TLB search */
                 ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
             } else {
@@ -865,7 +865,7 @@ int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid)
 
     /* Default return value is no match */
     ret = -1;
-    for (i = 0; i < 64; i++) {
+    for (i = 0; i < env->nb_tlb; i++) {
         tlb = &env->tlb[i].tlbe;
         if (ppcemb_tlb_check(env, tlb, &raddr, address, pid, 0, i) == 0) {
             ret = i;
@@ -876,6 +876,26 @@ int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid)
     return ret;
 }
 
+void ppc4xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
+                                 uint32_t pid)
+{
+    ppcemb_tlb_t *tlb;
+    target_phys_addr_t raddr;
+    target_ulong page, end;
+    int i;
+
+    for (i = 0; i < env->nb_tlb; i++) {
+        tlb = &env->tlb[i].tlbe;
+        if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) {
+            end = tlb->EPN + tlb->size;
+            for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
+                tlb_flush_page(env, page);
+            tlb->prot &= ~PAGE_VALID;
+            break;
+        }
+    }
+}
+
 /* Helpers specific to PowerPC 40x implementations */
 void ppc4xx_tlb_invalidate_all (CPUState *env)
 {
@@ -1069,23 +1089,23 @@ static int check_physical (CPUState *env, mmu_ctx_t *ctx,
     ctx->raddr = eaddr;
     ctx->prot = PAGE_READ;
     ret = 0;
-    switch (PPC_MMU(env)) {
-    case PPC_FLAGS_MMU_32B:
-    case PPC_FLAGS_MMU_SOFT_6xx:
-    case PPC_FLAGS_MMU_601:
-    case PPC_FLAGS_MMU_SOFT_4xx:
-    case PPC_FLAGS_MMU_401:
+    switch (env->mmu_model) {
+    case POWERPC_MMU_32B:
+    case POWERPC_MMU_SOFT_6xx:
+    case POWERPC_MMU_601:
+    case POWERPC_MMU_SOFT_4xx:
+    case POWERPC_MMU_REAL_4xx:
         ctx->prot |= PAGE_WRITE;
         break;
 #if defined(TARGET_PPC64)
-    case PPC_FLAGS_MMU_64B:
-    case PPC_FLAGS_MMU_64BRIDGE:
+    case POWERPC_MMU_64B:
+    case POWERPC_MMU_64BRIDGE:
         /* Real address are 60 bits long */
-        ctx->raddr &= 0x0FFFFFFFFFFFFFFFUL;
+        ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL;
         ctx->prot |= PAGE_WRITE;
         break;
 #endif
-    case PPC_FLAGS_MMU_403:
+    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.
@@ -1108,10 +1128,10 @@ static int check_physical (CPUState *env, mmu_ctx_t *ctx,
                 ctx->prot |= PAGE_WRITE;
             }
         }
-    case PPC_FLAGS_MMU_BOOKE:
+    case POWERPC_MMU_BOOKE:
         ctx->prot |= PAGE_WRITE;
         break;
-    case PPC_FLAGS_MMU_BOOKE_FSL:
+    case POWERPC_MMU_BOOKE_FSL:
         /* XXX: TODO */
         cpu_abort(env, "BookE FSL MMU model not implemented\n");
         break;
@@ -1138,40 +1158,40 @@ int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
         ret = check_physical(env, ctx, eaddr, rw);
     } else {
         ret = -1;
-        switch (PPC_MMU(env)) {
-        case PPC_FLAGS_MMU_32B:
-        case PPC_FLAGS_MMU_SOFT_6xx:
+        switch (env->mmu_model) {
+        case POWERPC_MMU_32B:
+        case POWERPC_MMU_SOFT_6xx:
             /* Try to find a BAT */
             if (check_BATs)
                 ret = get_bat(env, ctx, eaddr, rw, access_type);
             /* No break here */
 #if defined(TARGET_PPC64)
-        case PPC_FLAGS_MMU_64B:
-        case PPC_FLAGS_MMU_64BRIDGE:
+        case POWERPC_MMU_64B:
+        case POWERPC_MMU_64BRIDGE:
 #endif
             if (ret < 0) {
                 /* We didn't match any BAT entry or don't have BATs */
                 ret = get_segment(env, ctx, eaddr, rw, access_type);
             }
             break;
-        case PPC_FLAGS_MMU_SOFT_4xx:
-        case PPC_FLAGS_MMU_403:
+        case POWERPC_MMU_SOFT_4xx:
+        case POWERPC_MMU_SOFT_4xx_Z:
             ret = mmu40x_get_physical_address(env, ctx, eaddr,
                                               rw, access_type);
             break;
-        case PPC_FLAGS_MMU_601:
+        case POWERPC_MMU_601:
             /* XXX: TODO */
             cpu_abort(env, "601 MMU model not implemented\n");
             return -1;
-        case PPC_FLAGS_MMU_BOOKE:
+        case POWERPC_MMU_BOOKE:
             ret = mmubooke_get_physical_address(env, ctx, eaddr,
                                                 rw, access_type);
             break;
-        case PPC_FLAGS_MMU_BOOKE_FSL:
+        case POWERPC_MMU_BOOKE_FSL:
             /* XXX: TODO */
             cpu_abort(env, "BookE FSL MMU model not implemented\n");
             return -1;
-        case PPC_FLAGS_MMU_401:
+        case POWERPC_MMU_REAL_4xx:
             cpu_abort(env, "PowerPC 401 does not do any translation\n");
             return -1;
         default:
@@ -1234,46 +1254,46 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
             switch (ret) {
             case -1:
                 /* No matches in page tables or TLB */
-                switch (PPC_MMU(env)) {
-                case PPC_FLAGS_MMU_SOFT_6xx:
+                switch (env->mmu_model) {
+                case POWERPC_MMU_SOFT_6xx:
                     exception = EXCP_I_TLBMISS;
                     env->spr[SPR_IMISS] = address;
                     env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
                     error_code = 1 << 18;
                     goto tlb_miss;
-                case PPC_FLAGS_MMU_SOFT_4xx:
-                case PPC_FLAGS_MMU_403:
+                case POWERPC_MMU_SOFT_4xx:
+                case POWERPC_MMU_SOFT_4xx_Z:
                     exception = EXCP_40x_ITLBMISS;
                     error_code = 0;
                     env->spr[SPR_40x_DEAR] = address;
                     env->spr[SPR_40x_ESR] = 0x00000000;
                     break;
-                case PPC_FLAGS_MMU_32B:
+                case POWERPC_MMU_32B:
                     error_code = 0x40000000;
                     break;
 #if defined(TARGET_PPC64)
-                case PPC_FLAGS_MMU_64B:
+                case POWERPC_MMU_64B:
                     /* XXX: TODO */
                     cpu_abort(env, "MMU model not implemented\n");
                     return -1;
-                case PPC_FLAGS_MMU_64BRIDGE:
+                case POWERPC_MMU_64BRIDGE:
                     /* XXX: TODO */
                     cpu_abort(env, "MMU model not implemented\n");
                     return -1;
 #endif
-                case PPC_FLAGS_MMU_601:
+                case POWERPC_MMU_601:
                     /* XXX: TODO */
                     cpu_abort(env, "MMU model not implemented\n");
                     return -1;
-                case PPC_FLAGS_MMU_BOOKE:
+                case POWERPC_MMU_BOOKE:
                     /* XXX: TODO */
                     cpu_abort(env, "MMU model not implemented\n");
                     return -1;
-                case PPC_FLAGS_MMU_BOOKE_FSL:
+                case POWERPC_MMU_BOOKE_FSL:
                     /* XXX: TODO */
                     cpu_abort(env, "MMU model not implemented\n");
                     return -1;
-                case PPC_FLAGS_MMU_401:
+                case POWERPC_MMU_REAL_4xx:
                     cpu_abort(env, "PowerPC 401 should never raise any MMU "
                               "exceptions\n");
                     return -1;
@@ -1306,8 +1326,8 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
             switch (ret) {
             case -1:
                 /* No matches in page tables or TLB */
-                switch (PPC_MMU(env)) {
-                case PPC_FLAGS_MMU_SOFT_6xx:
+                switch (env->mmu_model) {
+                case POWERPC_MMU_SOFT_6xx:
                     if (rw == 1) {
                         exception = EXCP_DS_TLBMISS;
                         error_code = 1 << 16;
@@ -1323,8 +1343,8 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                     env->spr[SPR_HASH2] = ctx.pg_addr[1];
                     /* Do not alter DAR nor DSISR */
                     goto out;
-                case PPC_FLAGS_MMU_SOFT_4xx:
-                case PPC_FLAGS_MMU_403:
+                case POWERPC_MMU_SOFT_4xx:
+                case POWERPC_MMU_SOFT_4xx_Z:
                     exception = EXCP_40x_DTLBMISS;
                     error_code = 0;
                     env->spr[SPR_40x_DEAR] = address;
@@ -1333,32 +1353,32 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                     else
                         env->spr[SPR_40x_ESR] = 0x00000000;
                     break;
-                case PPC_FLAGS_MMU_32B:
+                case POWERPC_MMU_32B:
                     error_code = 0x40000000;
                     break;
 #if defined(TARGET_PPC64)
-                case PPC_FLAGS_MMU_64B:
+                case POWERPC_MMU_64B:
                     /* XXX: TODO */
                     cpu_abort(env, "MMU model not implemented\n");
                     return -1;
-                case PPC_FLAGS_MMU_64BRIDGE:
+                case POWERPC_MMU_64BRIDGE:
                     /* XXX: TODO */
                     cpu_abort(env, "MMU model not implemented\n");
                     return -1;
 #endif
-                case PPC_FLAGS_MMU_601:
+                case POWERPC_MMU_601:
                     /* XXX: TODO */
                     cpu_abort(env, "MMU model not implemented\n");
                     return -1;
-                case PPC_FLAGS_MMU_BOOKE:
+                case POWERPC_MMU_BOOKE:
                     /* XXX: TODO */
                     cpu_abort(env, "MMU model not implemented\n");
                     return -1;
-                case PPC_FLAGS_MMU_BOOKE_FSL:
+                case POWERPC_MMU_BOOKE_FSL:
                     /* XXX: TODO */
                     cpu_abort(env, "MMU model not implemented\n");
                     return -1;
-                case PPC_FLAGS_MMU_401:
+                case POWERPC_MMU_REAL_4xx:
                     cpu_abort(env, "PowerPC 401 should never raise any MMU "
                               "exceptions\n");
                     return -1;
@@ -1544,9 +1564,9 @@ void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value)
 /* TLB management */
 void ppc_tlb_invalidate_all (CPUPPCState *env)
 {
-    if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
+    if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) {
         ppc6xx_tlb_invalidate_all(env);
-    } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
+    } else if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_4xx)) {
         ppc4xx_tlb_invalidate_all(env);
     } else {
         tlb_flush(env, 1);
@@ -1707,9 +1727,11 @@ void do_store_msr (CPUPPCState *env, target_ulong value)
         fprintf(logfile, "%s: T0 %08lx\n", __func__, value);
     }
 #endif
-    switch (PPC_EXCP(env)) {
-    case PPC_FLAGS_EXCP_602:
-    case PPC_FLAGS_EXCP_603:
+    switch (env->excp_model) {
+    case POWERPC_EXCP_602:
+    case POWERPC_EXCP_603:
+    case POWERPC_EXCP_603E:
+    case POWERPC_EXCP_G2:
         if (((value >> MSR_TGPR) & 1) != msr_tgpr) {
             /* Swap temporary saved registers with GPRs */
             swap_gpr_tgpr(env);
@@ -1750,19 +1772,21 @@ void do_store_msr (CPUPPCState *env, target_ulong value)
     do_compute_hflags(env);
 
     enter_pm = 0;
-    switch (PPC_EXCP(env)) {
-    case PPC_FLAGS_EXCP_603:
+    switch (env->excp_model) {
+    case POWERPC_EXCP_603:
+    case POWERPC_EXCP_603E:
+    case POWERPC_EXCP_G2:
         /* Don't handle SLEEP mode: we should disable all clocks...
          * No dynamic power-management.
          */
         if (msr_pow == 1 && (env->spr[SPR_HID0] & 0x00C00000) != 0)
             enter_pm = 1;
         break;
-    case PPC_FLAGS_EXCP_604:
+    case POWERPC_EXCP_604:
         if (msr_pow == 1)
             enter_pm = 1;
         break;
-    case PPC_FLAGS_EXCP_7x0:
+    case POWERPC_EXCP_7x0:
         if (msr_pow == 1 && (env->spr[SPR_HID0] & 0x00E00000) != 0)
             enter_pm = 1;
         break;
@@ -1854,12 +1878,12 @@ void do_interrupt (CPUState *env)
     switch (excp) {
     /* Generic PowerPC exceptions */
     case EXCP_RESET: /* 0x0100 */
-        switch (PPC_EXCP(env)) {
-        case PPC_FLAGS_EXCP_40x:
+        switch (env->excp_model) {
+        case POWERPC_EXCP_40x:
             srr_0 = &env->spr[SPR_40x_SRR2];
             srr_1 = &env->spr[SPR_40x_SRR3];
             break;
-        case PPC_FLAGS_EXCP_BOOKE:
+        case POWERPC_EXCP_BOOKE:
             idx = 0;
             srr_0 = &env->spr[SPR_BOOKE_CSRR0];
             srr_1 = &env->spr[SPR_BOOKE_CSRR1];
@@ -1872,12 +1896,12 @@ void do_interrupt (CPUState *env)
         }
         goto store_next;
     case EXCP_MACHINE_CHECK: /* 0x0200 */
-        switch (PPC_EXCP(env)) {
-        case PPC_FLAGS_EXCP_40x:
+        switch (env->excp_model) {
+        case POWERPC_EXCP_40x:
             srr_0 = &env->spr[SPR_40x_SRR2];
             srr_1 = &env->spr[SPR_40x_SRR3];
             break;
-        case PPC_FLAGS_EXCP_BOOKE:
+        case POWERPC_EXCP_BOOKE:
             idx = 1;
             srr_0 = &env->spr[SPR_BOOKE_MCSRR0];
             srr_1 = &env->spr[SPR_BOOKE_MCSRR1];
@@ -1920,7 +1944,7 @@ void do_interrupt (CPUState *env)
         idx = 4;
         goto store_next;
     case EXCP_ALIGN: /* 0x0600 */
-        if (likely(PPC_EXCP(env) != PPC_FLAGS_EXCP_601)) {
+        if (likely(env->excp_model != POWERPC_EXCP_601)) {
             /* Store exception cause */
             idx = 5;
             /* Get rS/rD and rA from faulting opcode */
@@ -2028,26 +2052,27 @@ void do_interrupt (CPUState *env)
         goto store_next;
     /* Implementation specific exceptions */
     case 0x0A00:
-        if (likely(env->spr[SPR_PVR] == CPU_PPC_G2 ||
-                   env->spr[SPR_PVR] == CPU_PPC_G2LE)) {
+        switch (env->excp_model) {
+        case POWERPC_EXCP_G2:
             /* Critical interrupt on G2 */
             /* XXX: TODO */
             cpu_abort(env, "G2 critical interrupt is not implemented yet !\n");
             goto store_next;
-        } else {
+        default:
             cpu_abort(env, "Invalid exception 0x0A00 !\n");
+            break;
         }
         return;
     case 0x0F20:
         idx = 9;
-        switch (PPC_EXCP(env)) {
-        case PPC_FLAGS_EXCP_40x:
+        switch (env->excp_model) {
+        case POWERPC_EXCP_40x:
             /* APU unavailable on 405 */
             /* XXX: TODO */
             cpu_abort(env,
                       "APU unavailable exception is not implemented yet !\n");
             goto store_next;
-        case PPC_FLAGS_EXCP_74xx:
+        case POWERPC_EXCP_74xx:
             /* Altivec unavailable */
             /* XXX: TODO */
             cpu_abort(env, "Altivec unavailable exception "
@@ -2060,8 +2085,8 @@ void do_interrupt (CPUState *env)
         return;
     case 0x1000:
         idx = 10;
-        switch (PPC_EXCP(env)) {
-        case PPC_FLAGS_EXCP_40x:
+        switch (env->excp_model) {
+        case POWERPC_EXCP_40x:
             /* PIT on 4xx */
             msr &= ~0xFFFF0000;
 #if defined (DEBUG_EXCEPTIONS)
@@ -2069,11 +2094,13 @@ void do_interrupt (CPUState *env)
                 fprintf(logfile, "PIT exception\n");
 #endif
             goto store_next;
-        case PPC_FLAGS_EXCP_602:
-        case PPC_FLAGS_EXCP_603:
+        case POWERPC_EXCP_602:
+        case POWERPC_EXCP_603:
+        case POWERPC_EXCP_603E:
+        case POWERPC_EXCP_G2:
             /* ITLBMISS on 602/603 */
             goto store_gprs;
-        case PPC_FLAGS_EXCP_7x5:
+        case POWERPC_EXCP_7x5:
             /* ITLBMISS on 745/755 */
             goto tlb_miss;
         default:
@@ -2083,8 +2110,8 @@ void do_interrupt (CPUState *env)
         return;
     case 0x1010:
         idx = 11;
-        switch (PPC_EXCP(env)) {
-        case PPC_FLAGS_EXCP_40x:
+        switch (env->excp_model) {
+        case POWERPC_EXCP_40x:
             /* FIT on 4xx */
             msr &= ~0xFFFF0000;
 #if defined (DEBUG_EXCEPTIONS)
@@ -2099,8 +2126,8 @@ void do_interrupt (CPUState *env)
         return;
     case 0x1020:
         idx = 12;
-        switch (PPC_EXCP(env)) {
-        case PPC_FLAGS_EXCP_40x:
+        switch (env->excp_model) {
+        case POWERPC_EXCP_40x:
             /* Watchdog on 4xx */
             msr &= ~0xFFFF0000;
 #if defined (DEBUG_EXCEPTIONS)
@@ -2108,7 +2135,7 @@ void do_interrupt (CPUState *env)
                 fprintf(logfile, "WDT exception\n");
 #endif
             goto store_next;
-        case PPC_FLAGS_EXCP_BOOKE:
+        case POWERPC_EXCP_BOOKE:
             srr_0 = &env->spr[SPR_BOOKE_CSRR0];
             srr_1 = &env->spr[SPR_BOOKE_CSRR1];
             break;
@@ -2119,16 +2146,18 @@ void do_interrupt (CPUState *env)
         return;
     case 0x1100:
         idx = 13;
-        switch (PPC_EXCP(env)) {
-        case PPC_FLAGS_EXCP_40x:
+        switch (env->excp_model) {
+        case POWERPC_EXCP_40x:
             /* DTLBMISS on 4xx */
             msr &= ~0xFFFF0000;
             goto store_next;
-        case PPC_FLAGS_EXCP_602:
-        case PPC_FLAGS_EXCP_603:
+        case POWERPC_EXCP_602:
+        case POWERPC_EXCP_603:
+        case POWERPC_EXCP_603E:
+        case POWERPC_EXCP_G2:
             /* DLTLBMISS on 602/603 */
             goto store_gprs;
-        case PPC_FLAGS_EXCP_7x5:
+        case POWERPC_EXCP_7x5:
             /* DLTLBMISS on 745/755 */
             goto tlb_miss;
         default:
@@ -2138,13 +2167,15 @@ void do_interrupt (CPUState *env)
         return;
     case 0x1200:
         idx = 14;
-        switch (PPC_EXCP(env)) {
-        case PPC_FLAGS_EXCP_40x:
+        switch (env->excp_model) {
+        case POWERPC_EXCP_40x:
             /* ITLBMISS on 4xx */
             msr &= ~0xFFFF0000;
             goto store_next;
-        case PPC_FLAGS_EXCP_602:
-        case PPC_FLAGS_EXCP_603:
+        case POWERPC_EXCP_602:
+        case POWERPC_EXCP_603:
+        case POWERPC_EXCP_603E:
+        case POWERPC_EXCP_G2:
             /* DSTLBMISS on 602/603 */
         store_gprs:
             /* Swap temporary saved registers with GPRs */
@@ -2177,7 +2208,7 @@ void do_interrupt (CPUState *env)
             }
 #endif
             goto tlb_miss;
-        case PPC_FLAGS_EXCP_7x5:
+        case POWERPC_EXCP_7x5:
             /* DSTLBMISS on 745/755 */
         tlb_miss:
             msr &= ~0xF83F0000;
@@ -2192,13 +2223,15 @@ void do_interrupt (CPUState *env)
         }
         return;
     case 0x1300:
-        switch (PPC_EXCP(env)) {
-        case PPC_FLAGS_EXCP_601:
-        case PPC_FLAGS_EXCP_602:
-        case PPC_FLAGS_EXCP_603:
-        case PPC_FLAGS_EXCP_604:
-        case PPC_FLAGS_EXCP_7x0:
-        case PPC_FLAGS_EXCP_7x5:
+        switch (env->excp_model) {
+        case POWERPC_EXCP_601:
+        case POWERPC_EXCP_602:
+        case POWERPC_EXCP_603:
+        case POWERPC_EXCP_603E:
+        case POWERPC_EXCP_G2:
+        case POWERPC_EXCP_604:
+        case POWERPC_EXCP_7x0:
+        case POWERPC_EXCP_7x5:
             /* IABR on 6xx/7xx */
             /* XXX: TODO */
             cpu_abort(env, "IABR exception is not implemented yet !\n");
@@ -2209,13 +2242,15 @@ void do_interrupt (CPUState *env)
         }
         return;
     case 0x1400:
-        switch (PPC_EXCP(env)) {
-        case PPC_FLAGS_EXCP_601:
-        case PPC_FLAGS_EXCP_602:
-        case PPC_FLAGS_EXCP_603:
-        case PPC_FLAGS_EXCP_604:
-        case PPC_FLAGS_EXCP_7x0:
-        case PPC_FLAGS_EXCP_7x5:
+        switch (env->excp_model) {
+        case POWERPC_EXCP_601:
+        case POWERPC_EXCP_602:
+        case POWERPC_EXCP_603:
+        case POWERPC_EXCP_603E:
+        case POWERPC_EXCP_G2:
+        case POWERPC_EXCP_604:
+        case POWERPC_EXCP_7x0:
+        case POWERPC_EXCP_7x5:
             /* SMI on 6xx/7xx */
             /* XXX: TODO */
             cpu_abort(env, "SMI exception is not implemented yet !\n");
@@ -2226,20 +2261,20 @@ void do_interrupt (CPUState *env)
         }
         return;
     case 0x1500:
-        switch (PPC_EXCP(env)) {
-        case PPC_FLAGS_EXCP_602:
+        switch (env->excp_model) {
+        case POWERPC_EXCP_602:
             /* Watchdog on 602 */
             /* XXX: TODO */
             cpu_abort(env,
                       "602 watchdog exception is not implemented yet !\n");
             goto store_next;
-        case PPC_FLAGS_EXCP_970:
+        case POWERPC_EXCP_970:
             /* Soft patch exception on 970 */
             /* XXX: TODO */
             cpu_abort(env,
                       "970 soft-patch exception is not implemented yet !\n");
             goto store_next;
-        case PPC_FLAGS_EXCP_74xx:
+        case POWERPC_EXCP_74xx:
             /* VPU assist on 74xx */
             /* XXX: TODO */
             cpu_abort(env, "VPU assist exception is not implemented yet !\n");
@@ -2250,14 +2285,14 @@ void do_interrupt (CPUState *env)
         }
         return;
     case 0x1600:
-        switch (PPC_EXCP(env)) {
-        case PPC_FLAGS_EXCP_602:
+        switch (env->excp_model) {
+        case POWERPC_EXCP_602:
             /* Emulation trap on 602 */
             /* XXX: TODO */
             cpu_abort(env, "602 emulation trap exception "
                       "is not implemented yet !\n");
             goto store_next;
-        case PPC_FLAGS_EXCP_970:
+        case POWERPC_EXCP_970:
             /* Maintenance exception on 970 */
             /* XXX: TODO */
             cpu_abort(env,
@@ -2269,15 +2304,15 @@ void do_interrupt (CPUState *env)
         }
         return;
     case 0x1700:
-        switch (PPC_EXCP(env)) {
-        case PPC_FLAGS_EXCP_7x0:
-        case PPC_FLAGS_EXCP_7x5:
+        switch (env->excp_model) {
+        case POWERPC_EXCP_7x0:
+        case POWERPC_EXCP_7x5:
             /* Thermal management interrupt on G3 */
             /* XXX: TODO */
             cpu_abort(env, "G3 thermal management exception "
                       "is not implemented yet !\n");
             goto store_next;
-        case PPC_FLAGS_EXCP_970:
+        case POWERPC_EXCP_970:
             /* VPU assist on 970 */
             /* XXX: TODO */
             cpu_abort(env,
@@ -2289,8 +2324,8 @@ void do_interrupt (CPUState *env)
         }
         return;
     case 0x1800:
-        switch (PPC_EXCP(env)) {
-        case PPC_FLAGS_EXCP_970:
+        switch (env->excp_model) {
+        case POWERPC_EXCP_970:
             /* Thermal exception on 970 */
             /* XXX: TODO */
             cpu_abort(env, "970 thermal management exception "
@@ -2302,19 +2337,19 @@ void do_interrupt (CPUState *env)
         }
         return;
     case 0x2000:
-        switch (PPC_EXCP(env)) {
-        case PPC_FLAGS_EXCP_40x:
+        switch (env->excp_model) {
+        case POWERPC_EXCP_40x:
             /* DEBUG on 4xx */
             /* XXX: TODO */
             cpu_abort(env, "40x debug exception is not implemented yet !\n");
             goto store_next;
-        case PPC_FLAGS_EXCP_601:
+        case POWERPC_EXCP_601:
             /* Run mode exception on 601 */
             /* XXX: TODO */
             cpu_abort(env,
                       "601 run mode exception is not implemented yet !\n");
             goto store_next;
-        case PPC_FLAGS_EXCP_BOOKE:
+        case POWERPC_EXCP_BOOKE:
             srr_0 = &env->spr[SPR_BOOKE_CSRR0];
             srr_1 = &env->spr[SPR_BOOKE_CSRR1];
             break;
@@ -2361,7 +2396,7 @@ void do_interrupt (CPUState *env)
     msr_dr = 0;
     msr_ri = 0;
     msr_le = msr_ile;
-    if (PPC_EXCP(env) == PPC_FLAGS_EXCP_BOOKE) {
+    if (env->excp_model == POWERPC_EXCP_BOOKE) {
         msr_cm = msr_icm;
         if (idx == -1 || (idx >= 16 && idx < 32)) {
             cpu_abort(env, "Invalid exception index for excp %d %08x idx %d\n",
index 593539bbf73986f3cca478e5ec2232c31eb6fbe7..93c463e30f4c58fd5a31189b6e8de1547d1eec65 100644 (file)
@@ -2319,7 +2319,6 @@ void OPPROTO op_405_check_satu (void)
     RETURN();
 }
 
-#if !defined(CONFIG_USER_ONLY)
 void OPPROTO op_load_dcr (void)
 {
     do_load_dcr();
@@ -2332,6 +2331,7 @@ void OPPROTO op_store_dcr (void)
     RETURN();
 }
 
+#if !defined(CONFIG_USER_ONLY)
 /* Return from critical interrupt :
  * same as rfi, except nip & MSR are loaded from SRR2/3 instead of SRR0/1
  */
index 07b336b54d1c21982d1abc4408934ee3ad67b94d..df00ba19c757c1cf781a92cd895ec351483fc427 100644 (file)
@@ -1206,6 +1206,41 @@ void do_405_check_sat (void)
     }
 }
 
+/* XXX: to be improved to check access rights when in user-mode */
+void do_load_dcr (void)
+{
+    target_ulong val;
+
+    if (unlikely(env->dcr_env == NULL)) {
+        if (loglevel != 0) {
+            fprintf(logfile, "No DCR environment\n");
+        }
+        do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL);
+    } else if (unlikely(ppc_dcr_read(env->dcr_env, T0, &val) != 0)) {
+        if (loglevel != 0) {
+            fprintf(logfile, "DCR read error %d %03x\n", (int)T0, (int)T0);
+        }
+        do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG);
+    } else {
+        T0 = val;
+    }
+}
+
+void do_store_dcr (void)
+{
+    if (unlikely(env->dcr_env == NULL)) {
+        if (loglevel != 0) {
+            fprintf(logfile, "No DCR environment\n");
+        }
+        do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL);
+    } else if (unlikely(ppc_dcr_write(env->dcr_env, T0, T1) != 0)) {
+        if (loglevel != 0) {
+            fprintf(logfile, "DCR write error %d %03x\n", (int)T0, (int)T0);
+        }
+        do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG);
+    }
+}
+
 #if !defined(CONFIG_USER_ONLY)
 void do_40x_rfci (void)
 {
@@ -1268,40 +1303,6 @@ void do_rfmci (void)
     env->interrupt_request = CPU_INTERRUPT_EXITTB;
 }
 
-void do_load_dcr (void)
-{
-    target_ulong val;
-
-    if (unlikely(env->dcr_env == NULL)) {
-        if (loglevel != 0) {
-            fprintf(logfile, "No DCR environment\n");
-        }
-        do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL);
-    } else if (unlikely(ppc_dcr_read(env->dcr_env, T0, &val) != 0)) {
-        if (loglevel != 0) {
-            fprintf(logfile, "DCR read error %d %03x\n", (int)T0, (int)T0);
-        }
-        do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG);
-    } else {
-        T0 = val;
-    }
-}
-
-void do_store_dcr (void)
-{
-    if (unlikely(env->dcr_env == NULL)) {
-        if (loglevel != 0) {
-            fprintf(logfile, "No DCR environment\n");
-        }
-        do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL);
-    } else if (unlikely(ppc_dcr_write(env->dcr_env, T0, T1) != 0)) {
-        if (loglevel != 0) {
-            fprintf(logfile, "DCR write error %d %03x\n", (int)T0, (int)T0);
-        }
-        do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG);
-    }
-}
-
 void do_load_403_pb (int num)
 {
     T0 = env->pb[num];
@@ -2238,7 +2239,7 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr)
     if (unlikely(ret != 0)) {
         if (likely(retaddr)) {
             /* now we have a real cpu fault */
-            pc = (target_phys_addr_t)retaddr;
+            pc = (target_phys_addr_t)(unsigned long)retaddr;
             tb = tb_find_pc(pc);
             if (likely(tb)) {
                 /* the PC is inside the translated code. It means that we have
@@ -2261,16 +2262,14 @@ void do_tlbie (void)
 {
     T0 = (uint32_t)T0;
 #if !defined(FLUSH_ALL_TLBS)
-    if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
+    /* XXX: Remove thoses tests */
+    if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) {
         ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 0);
         if (env->id_tlbs == 1)
             ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 1);
-    } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
-        /* XXX: TODO */
-#if 0
-        ppcbooke_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK,
-                                     env->spr[SPR_BOOKE_PID]);
-#endif
+    } else if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_4xx)) {
+        ppc4xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK,
+                                   env->spr[SPR_40x_PID]);
     } else {
         /* tlbie invalidate TLBs for all segments */
         T0 &= TARGET_PAGE_MASK;
@@ -2305,11 +2304,11 @@ void do_tlbie_64 (void)
 {
     T0 = (uint64_t)T0;
 #if !defined(FLUSH_ALL_TLBS)
-    if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
+    if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) {
         ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 0);
         if (env->id_tlbs == 1)
             ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 1);
-    } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
+    } else if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_4xx)) {
         /* XXX: TODO */
 #if 0
         ppcbooke_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK,
@@ -2541,7 +2540,7 @@ void do_4xx_tlbwe_hi (void)
                   "are not supported (%d)\n",
                   tlb->size, TARGET_PAGE_SIZE, (int)((T1 >> 7) & 0x7));
     }
-    tlb->EPN = (T1 & 0xFFFFFC00) & ~(tlb->size - 1);
+    tlb->EPN = T1 & ~(tlb->size - 1);
     if (T1 & 0x40)
         tlb->prot |= PAGE_VALID;
     else
@@ -2676,14 +2675,14 @@ void do_440_tlbwe (int word)
 
 void do_440_tlbsx (void)
 {
-    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR]);
+    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
 }
 
 void do_440_tlbsx_ (void)
 {
     int tmp = xer_so;
 
-    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR]);
+    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF);
     if (T0 != -1)
         tmp |= 0x02;
     env->crf[0] = tmp;
index 47f548e7b13394e3c15f4f3797afabdd52177761..4db8ac53088fd0a623d16e40d22da467284e0a72 100644 (file)
@@ -167,9 +167,9 @@ void do_440_tlbwe (int word);
 /* PowerPC 4xx specific helpers */
 void do_405_check_ov (void);
 void do_405_check_sat (void);
-#if !defined(CONFIG_USER_ONLY)
 void do_load_dcr (void);
 void do_store_dcr (void);
+#if !defined(CONFIG_USER_ONLY)
 void do_40x_rfci (void);
 void do_rfci (void);
 void do_rfdi (void);
index 9d6bf32066cb7ac1d93a6cb28871788da8bec7de..4d98ea90be9a460c45a6a0b7954cade8e30af970 100644 (file)
 #include "exec-all.h"
 #include "disas.h"
 
+/* Include definitions for instructions classes and implementations flags */
 //#define DO_SINGLE_STEP
 //#define PPC_DEBUG_DISAS
 //#define DEBUG_MEMORY_ACCESSES
 //#define DO_PPC_STATISTICS
 
+/*****************************************************************************/
+/* Code translation helpers                                                  */
 #if defined(USE_DIRECT_JUMP)
 #define TBPARAM(x)
 #else
@@ -175,8 +178,10 @@ struct opc_handler_t {
     uint64_t type;
     /* handler */
     void (*handler)(DisasContext *ctx);
-#if defined(DO_PPC_STATISTICS)
+#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
     const unsigned char *oname;
+#endif
+#if defined(DO_PPC_STATISTICS)
     uint64_t count;
 #endif
 };
@@ -249,6 +254,7 @@ typedef struct opcode_t {
     const unsigned char *oname;
 } opcode_t;
 
+/*****************************************************************************/
 /***                           Instruction decoding                        ***/
 #define EXTRACT_HELPER(name, shift, nb)                                       \
 static inline uint32_t name (uint32_t opcode)                                 \
@@ -365,6 +371,106 @@ static inline target_ulong MASK (uint32_t start, uint32_t end)
     return ret;
 }
 
+/*****************************************************************************/
+/* PowerPC Instructions types definitions                                    */
+enum {
+    PPC_NONE          = 0x0000000000000000ULL,
+    /* integer operations instructions                  */
+    /* flow control instructions                        */
+    /* virtual memory instructions                      */
+    /* ld/st with reservation instructions              */
+    /* cache control instructions                       */
+    /* spr/msr access instructions                      */
+    PPC_INSNS_BASE    = 0x0000000000000001ULL,
+#define PPC_INTEGER PPC_INSNS_BASE
+#define PPC_FLOW    PPC_INSNS_BASE
+#define PPC_MEM     PPC_INSNS_BASE
+#define PPC_RES     PPC_INSNS_BASE
+#define PPC_CACHE   PPC_INSNS_BASE
+#define PPC_MISC    PPC_INSNS_BASE
+    /* Optional floating point instructions             */
+    PPC_FLOAT         = 0x0000000000000002ULL,
+    PPC_FLOAT_FSQRT   = 0x0000000000000004ULL,
+    PPC_FLOAT_FRES    = 0x0000000000000008ULL,
+    PPC_FLOAT_FRSQRTE = 0x0000000000000010ULL,
+    PPC_FLOAT_FSEL    = 0x0000000000000020ULL,
+    PPC_FLOAT_STFIWX  = 0x0000000000000040ULL,
+    /* external control instructions                    */
+    PPC_EXTERN        = 0x0000000000000080ULL,
+    /* segment register access instructions             */
+    PPC_SEGMENT       = 0x0000000000000100ULL,
+    /* Optional cache control instruction               */
+    PPC_CACHE_DCBA    = 0x0000000000000200ULL,
+    /* Optional memory control instructions             */
+    PPC_MEM_TLBIA     = 0x0000000000000400ULL,
+    PPC_MEM_TLBIE     = 0x0000000000000800ULL,
+    PPC_MEM_TLBSYNC   = 0x0000000000001000ULL,
+    /* eieio & sync                                     */
+    PPC_MEM_SYNC      = 0x0000000000002000ULL,
+    /* PowerPC 6xx TLB management instructions          */
+    PPC_6xx_TLB       = 0x0000000000004000ULL,
+    /* Altivec support                                  */
+    PPC_ALTIVEC       = 0x0000000000008000ULL,
+    /* Time base mftb instruction                       */
+    PPC_MFTB          = 0x0000000000010000ULL,
+    /* Embedded PowerPC dedicated instructions          */
+    PPC_EMB_COMMON    = 0x0000000000020000ULL,
+    /* PowerPC 40x exception model                      */
+    PPC_40x_EXCP      = 0x0000000000040000ULL,
+    /* PowerPC 40x TLB management instructions          */
+    PPC_40x_TLB       = 0x0000000000080000ULL,
+    /* PowerPC 405 Mac instructions                     */
+    PPC_405_MAC       = 0x0000000000100000ULL,
+    /* PowerPC 440 specific instructions                */
+    PPC_440_SPEC      = 0x0000000000200000ULL,
+    /* Power-to-PowerPC bridge (601)                    */
+    PPC_POWER_BR      = 0x0000000000400000ULL,
+    /* PowerPC 602 specific */
+    PPC_602_SPEC      = 0x0000000000800000ULL,
+    /* Deprecated instructions                          */
+    /* Original POWER instruction set                   */
+    PPC_POWER         = 0x0000000001000000ULL,
+    /* POWER2 instruction set extension                 */
+    PPC_POWER2        = 0x0000000002000000ULL,
+    /* Power RTC support */
+    PPC_POWER_RTC     = 0x0000000004000000ULL,
+    /* 64 bits PowerPC instructions                     */
+    /* 64 bits PowerPC instruction set                  */
+    PPC_64B           = 0x0000000008000000ULL,
+    /* 64 bits hypervisor extensions                    */
+    PPC_64H           = 0x0000000010000000ULL,
+    /* 64 bits PowerPC "bridge" features                */
+    PPC_64_BRIDGE     = 0x0000000020000000ULL,
+    /* BookE (embedded) PowerPC specification           */
+    PPC_BOOKE         = 0x0000000040000000ULL,
+    /* eieio                                            */
+    PPC_MEM_EIEIO     = 0x0000000080000000ULL,
+    /* e500 vector instructions                         */
+    PPC_E500_VECTOR   = 0x0000000100000000ULL,
+    /* PowerPC 4xx dedicated instructions               */
+    PPC_4xx_COMMON    = 0x0000000200000000ULL,
+    /* PowerPC 2.03 specification extensions            */
+    PPC_203           = 0x0000000400000000ULL,
+    /* PowerPC 2.03 SPE extension                       */
+    PPC_SPE           = 0x0000000800000000ULL,
+    /* PowerPC 2.03 SPE floating-point extension        */
+    PPC_SPEFPU        = 0x0000001000000000ULL,
+    /* SLB management                                   */
+    PPC_SLBI          = 0x0000002000000000ULL,
+    /* PowerPC 40x ibct instructions                    */
+    PPC_40x_ICBT      = 0x0000004000000000ULL,
+    /* PowerPC 74xx TLB management instructions         */
+    PPC_74xx_TLB      = 0x0000008000000000ULL,
+    /* More BookE (embedded) instructions...            */
+    PPC_BOOKE_EXT     = 0x0000010000000000ULL,
+    /* rfmci is not implemented in all BookE PowerPC    */
+    PPC_RFMCI         = 0x0000020000000000ULL,
+    /* user-mode DCR access, implemented in PowerPC 460 */
+    PPC_DCRUX         = 0x0000040000000000ULL,
+};
+
+/*****************************************************************************/
+/* PowerPC instructions table                                                */
 #if HOST_LONG_BITS == 64
 #define OPC_ALIGN 8
 #else
@@ -845,15 +951,15 @@ GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
 
 #if defined(TARGET_PPC64)
 /* mulhd  mulhd.                   */
-GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_INTEGER);
+GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_64B);
 /* mulhdu mulhdu.                  */
-GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_INTEGER);
+GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_64B);
 /* mulld  mulld.  mulldo  mulldo.  */
-GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_INTEGER);
+GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_64B);
 /* divd   divd.   divdo   divdo.   */
-GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_INTEGER);
+GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_64B);
 /* divdu  divdu.  divduo  divduo.  */
-GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_INTEGER);
+GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_64B);
 #endif
 
 /***                           Integer comparison                          ***/
@@ -1424,8 +1530,8 @@ __GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
 #endif
 
 /***                       Floating-Point arithmetic                       ***/
-#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat)                           \
-GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT)                   \
+#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, type)                     \
+GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)                        \
 {                                                                             \
     if (unlikely(!ctx->fpu_enabled)) {                                        \
         RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
@@ -1444,9 +1550,9 @@ GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT)                   \
         gen_op_set_Rc1();                                                     \
 }
 
-#define GEN_FLOAT_ACB(name, op2)                                              \
-_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0);                                     \
-_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1);
+#define GEN_FLOAT_ACB(name, op2, type)                                        \
+_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, type);                               \
+_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, type);
 
 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat)                     \
 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
@@ -1492,8 +1598,8 @@ GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT)                        \
 _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0);                               \
 _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
 
-#define GEN_FLOAT_B(name, op2, op3)                                           \
-GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT)                   \
+#define GEN_FLOAT_B(name, op2, op3, type)                                     \
+GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)                        \
 {                                                                             \
     if (unlikely(!ctx->fpu_enabled)) {                                        \
         RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
@@ -1507,8 +1613,8 @@ GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT)                   \
         gen_op_set_Rc1();                                                     \
 }
 
-#define GEN_FLOAT_BS(name, op1, op2)                                          \
-GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, PPC_FLOAT)                   \
+#define GEN_FLOAT_BS(name, op1, op2, type)                                    \
+GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
 {                                                                             \
     if (unlikely(!ctx->fpu_enabled)) {                                        \
         RET_EXCP(ctx, EXCP_NO_FP, 0);                                         \
@@ -1529,19 +1635,19 @@ GEN_FLOAT_AB(div, 0x12, 0x000007C0);
 /* fmul - fmuls */
 GEN_FLOAT_AC(mul, 0x19, 0x0000F800);
 
-/* fres */ /* XXX: not in 601 */
-GEN_FLOAT_BS(res, 0x3B, 0x18);
+/* fres */
+GEN_FLOAT_BS(res, 0x3B, 0x18, PPC_FLOAT_FRES);
 
-/* frsqrte */ /* XXX: not in 601 */
-GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A);
+/* frsqrte */
+GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, PPC_FLOAT_FRSQRTE);
 
-/* fsel */ /* XXX: not in 601 */
-_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0);
+/* fsel */
+_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, PPC_FLOAT_FSEL);
 /* fsub - fsubs */
 GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
 /* Optional: */
 /* fsqrt */
-GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
+GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
 {
     if (unlikely(!ctx->fpu_enabled)) {
         RET_EXCP(ctx, EXCP_NO_FP, 0);
@@ -1555,7 +1661,7 @@ GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
         gen_op_set_Rc1();
 }
 
-GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
+GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
 {
     if (unlikely(!ctx->fpu_enabled)) {
         RET_EXCP(ctx, EXCP_NO_FP, 0);
@@ -1572,28 +1678,28 @@ GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT)
 
 /***                     Floating-Point multiply-and-add                   ***/
 /* fmadd - fmadds */
-GEN_FLOAT_ACB(madd, 0x1D);
+GEN_FLOAT_ACB(madd, 0x1D, PPC_FLOAT);
 /* fmsub - fmsubs */
-GEN_FLOAT_ACB(msub, 0x1C);
+GEN_FLOAT_ACB(msub, 0x1C, PPC_FLOAT);
 /* fnmadd - fnmadds */
-GEN_FLOAT_ACB(nmadd, 0x1F);
+GEN_FLOAT_ACB(nmadd, 0x1F, PPC_FLOAT);
 /* fnmsub - fnmsubs */
-GEN_FLOAT_ACB(nmsub, 0x1E);
+GEN_FLOAT_ACB(nmsub, 0x1E, PPC_FLOAT);
 
 /***                     Floating-Point round & convert                    ***/
 /* fctiw */
-GEN_FLOAT_B(ctiw, 0x0E, 0x00);
+GEN_FLOAT_B(ctiw, 0x0E, 0x00, PPC_FLOAT);
 /* fctiwz */
-GEN_FLOAT_B(ctiwz, 0x0F, 0x00);
+GEN_FLOAT_B(ctiwz, 0x0F, 0x00, PPC_FLOAT);
 /* frsp */
-GEN_FLOAT_B(rsp, 0x0C, 0x00);
+GEN_FLOAT_B(rsp, 0x0C, 0x00, PPC_FLOAT);
 #if defined(TARGET_PPC64)
 /* fcfid */
-GEN_FLOAT_B(cfid, 0x0E, 0x1A);
+GEN_FLOAT_B(cfid, 0x0E, 0x1A, PPC_64B);
 /* fctid */
-GEN_FLOAT_B(ctid, 0x0E, 0x19);
+GEN_FLOAT_B(ctid, 0x0E, 0x19, PPC_64B);
 /* fctidz */
-GEN_FLOAT_B(ctidz, 0x0F, 0x19);
+GEN_FLOAT_B(ctidz, 0x0F, 0x19, PPC_64B);
 #endif
 
 /***                         Floating-Point compare                        ***/
@@ -1627,7 +1733,7 @@ GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
 
 /***                         Floating-point move                           ***/
 /* fabs */
-GEN_FLOAT_B(abs, 0x08, 0x08);
+GEN_FLOAT_B(abs, 0x08, 0x08, PPC_FLOAT);
 
 /* fmr  - fmr. */
 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
@@ -1644,9 +1750,9 @@ GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
 }
 
 /* fnabs */
-GEN_FLOAT_B(nabs, 0x08, 0x04);
+GEN_FLOAT_B(nabs, 0x08, 0x04, PPC_FLOAT);
 /* fneg */
-GEN_FLOAT_B(neg, 0x08, 0x01);
+GEN_FLOAT_B(neg, 0x08, 0x01, PPC_FLOAT);
 
 /***                  Floating-Point status & ctrl register                ***/
 /* mcrfs */
@@ -2426,7 +2532,7 @@ static GenOpFunc *gen_op_stdcx[] = {
 #endif
 
 /* ldarx */
-GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_RES)
+GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
 {
     gen_addr_reg_index(ctx);
     op_ldarx();
@@ -2434,7 +2540,7 @@ GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_RES)
 }
 
 /* stdcx. */
-GEN_HANDLER(stdcx_, 0x1F, 0x16, 0x06, 0x00000000, PPC_RES)
+GEN_HANDLER(stdcx_, 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
 {
     gen_addr_reg_index(ctx);
     gen_op_load_gpr_T1(rS(ctx->opcode));
@@ -2591,7 +2697,7 @@ GEN_STFS(fs, 0x14);
 
 /* Optional: */
 /* stfiwx */
-GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
+GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT_STFIWX)
 {
     if (unlikely(!ctx->fpu_enabled)) {
         RET_EXCP(ctx, EXCP_NO_FP, 0);
@@ -2886,7 +2992,7 @@ GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
 }
 
 #if defined(TARGET_PPC64)
-GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_FLOW)
+GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
 {
 #if defined(CONFIG_USER_ONLY)
     RET_PRIVOPC(ctx);
@@ -3050,7 +3156,7 @@ GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
 }
 
 /* mftb */
-GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_TB)
+GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
 {
     gen_op_mfspr(ctx);
 }
@@ -3074,7 +3180,7 @@ GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
 
 /* mtmsr */
 #if defined(TARGET_PPC64)
-GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001FF801, PPC_MISC)
+GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001FF801, PPC_64B)
 {
 #if defined(CONFIG_USER_ONLY)
     RET_PRIVREG(ctx);
@@ -3296,7 +3402,7 @@ GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
 
 /* Optional: */
 /* dcba */
-GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_OPT)
+GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
 {
 }
 
@@ -3568,7 +3674,7 @@ GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
 }
 
 /* clcs */
-GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR) /* 601 ? */
+GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
 {
     gen_op_load_gpr_T0(rA(ctx->opcode));
     gen_op_POWER_clcs();
@@ -4222,14 +4328,14 @@ GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
 
 /* BookE specific instructions */
 /* XXX: not implemented on 440 ? */
-GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE)
+GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE_EXT)
 {
     /* XXX: TODO */
     RET_INVAL(ctx);
 }
 
 /* XXX: not implemented on 440 ? */
-GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE)
+GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE_EXT)
 {
 #if defined(CONFIG_USER_ONLY)
     RET_PRIVOPC(ctx);
@@ -4331,99 +4437,98 @@ static inline void gen_405_mulladd_insn (DisasContext *ctx, int opc2, int opc3,
     }
 }
 
-#define GEN_MAC_HANDLER(name, opc2, opc3, is_440)                                     \
-GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000,                               \
-            is_440 ? PPC_440_SPEC : PPC_405_MAC)                              \
+#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
+GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
 {                                                                             \
     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, 0);
+GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
 /* macchwo   - macchwo.   */
-GEN_MAC_HANDLER(macchwo, 0x0C, 0x15, 0);
+GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
 /* macchws   - macchws.   */
-GEN_MAC_HANDLER(macchws, 0x0C, 0x07, 0);
+GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
 /* macchwso  - macchwso.  */
-GEN_MAC_HANDLER(macchwso, 0x0C, 0x17, 0);
+GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
 /* macchwsu  - macchwsu.  */
-GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06, 0);
+GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
 /* macchwsuo - macchwsuo. */
-GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16, 0);
+GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
 /* macchwu   - macchwu.   */
-GEN_MAC_HANDLER(macchwu, 0x0C, 0x04, 0);
+GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
 /* macchwuo  - macchwuo.  */
-GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14, 0);
+GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
 /* machhw    - machhw.    */
-GEN_MAC_HANDLER(machhw, 0x0C, 0x01, 0);
+GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
 /* machhwo   - machhwo.   */
-GEN_MAC_HANDLER(machhwo, 0x0C, 0x11, 0);
+GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
 /* machhws   - machhws.   */
-GEN_MAC_HANDLER(machhws, 0x0C, 0x03, 0);
+GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
 /* machhwso  - machhwso.  */
-GEN_MAC_HANDLER(machhwso, 0x0C, 0x13, 0);
+GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
 /* machhwsu  - machhwsu.  */
-GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02, 0);
+GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
 /* machhwsuo - machhwsuo. */
-GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12, 0);
+GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
 /* machhwu   - machhwu.   */
-GEN_MAC_HANDLER(machhwu, 0x0C, 0x00, 0);
+GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
 /* machhwuo  - machhwuo.  */
-GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10, 0);
+GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
 /* maclhw    - maclhw.    */
-GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D, 0);
+GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
 /* maclhwo   - maclhwo.   */
-GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D, 0);
+GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
 /* maclhws   - maclhws.   */
-GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F, 0);
+GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
 /* maclhwso  - maclhwso.  */
-GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F, 0);
+GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
 /* maclhwu   - maclhwu.   */
-GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C, 0);
+GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
 /* maclhwuo  - maclhwuo.  */
-GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C, 0);
+GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
 /* maclhwsu  - maclhwsu.  */
-GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E, 0);
+GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
 /* maclhwsuo - maclhwsuo. */
-GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E, 0);
+GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
 /* nmacchw   - nmacchw.   */
-GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05, 0);
+GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
 /* nmacchwo  - nmacchwo.  */
-GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15, 0);
+GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
 /* nmacchws  - nmacchws.  */
-GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07, 0);
+GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
 /* nmacchwso - nmacchwso. */
-GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17, 0);
+GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
 /* nmachhw   - nmachhw.   */
-GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01, 0);
+GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
 /* nmachhwo  - nmachhwo.  */
-GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11, 0);
+GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
 /* nmachhws  - nmachhws.  */
-GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03, 1);
+GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
 /* nmachhwso - nmachhwso. */
-GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13, 1);
+GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
 /* nmaclhw   - nmaclhw.   */
-GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D, 1);
+GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
 /* nmaclhwo  - nmaclhwo.  */
-GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D, 1);
+GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
 /* nmaclhws  - nmaclhws.  */
-GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F, 1);
+GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
 /* nmaclhwso - nmaclhwso. */
-GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F, 1);
+GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
 
 /* mulchw  - mulchw.  */
-GEN_MAC_HANDLER(mulchw, 0x08, 0x05, 0);
+GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
 /* mulchwu - mulchwu. */
-GEN_MAC_HANDLER(mulchwu, 0x08, 0x04, 0);
+GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
 /* mulhhw  - mulhhw.  */
-GEN_MAC_HANDLER(mulhhw, 0x08, 0x01, 0);
+GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
 /* mulhhwu - mulhhwu. */
-GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00, 0);
+GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
 /* mullhw  - mullhw.  */
-GEN_MAC_HANDLER(mullhw, 0x08, 0x0D, 0);
+GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
 /* mullhwu - mullhwu. */
-GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C, 0);
+GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
 
 /* mfdcr */
 GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON)
@@ -4463,7 +4568,7 @@ GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
 
 /* mfdcrx */
 /* XXX: not implemented on 440 ? */
-GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000001, PPC_BOOKE)
+GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_BOOKE_EXT)
 {
 #if defined(CONFIG_USER_ONLY)
     RET_PRIVREG(ctx);
@@ -4475,12 +4580,13 @@ GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000001, PPC_BOOKE)
     gen_op_load_gpr_T0(rA(ctx->opcode));
     gen_op_load_dcr();
     gen_op_store_T0_gpr(rD(ctx->opcode));
+    /* Note: Rc update flag set leads to undefined state of Rc0 */
 #endif
 }
 
 /* mtdcrx */
 /* XXX: not implemented on 440 ? */
-GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000001, PPC_BOOKE)
+GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_BOOKE_EXT)
 {
 #if defined(CONFIG_USER_ONLY)
     RET_PRIVREG(ctx);
@@ -4492,9 +4598,28 @@ GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000001, PPC_BOOKE)
     gen_op_load_gpr_T0(rA(ctx->opcode));
     gen_op_load_gpr_T1(rS(ctx->opcode));
     gen_op_store_dcr();
+    /* Note: Rc update flag set leads to undefined state of Rc0 */
 #endif
 }
 
+/* mfdcrux (PPC 460) : user-mode access to DCR */
+GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
+{
+    gen_op_load_gpr_T0(rA(ctx->opcode));
+    gen_op_load_dcr();
+    gen_op_store_T0_gpr(rD(ctx->opcode));
+    /* Note: Rc update flag set leads to undefined state of Rc0 */
+}
+
+/* mtdcrux (PPC 460) : user-mode access to DCR */
+GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
+{
+    gen_op_load_gpr_T0(rA(ctx->opcode));
+    gen_op_load_gpr_T1(rS(ctx->opcode));
+    gen_op_store_dcr();
+    /* Note: Rc update flag set leads to undefined state of Rc0 */
+}
+
 /* dccci */
 GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
 {
@@ -4595,7 +4720,7 @@ GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
 
 /* BookE specific */
 /* XXX: not implemented on 440 ? */
-GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE)
+GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE_EXT)
 {
 #if defined(CONFIG_USER_ONLY)
     RET_PRIVOPC(ctx);
@@ -4611,7 +4736,7 @@ GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE)
 }
 
 /* XXX: not implemented on 440 ? */
-GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_BOOKE)
+GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
 {
 #if defined(CONFIG_USER_ONLY)
     RET_PRIVOPC(ctx);
@@ -4628,7 +4753,7 @@ GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_BOOKE)
 
 /* TLB management - PowerPC 405 implementation */
 /* tlbre */
-GEN_HANDLER(tlbre_40x, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_SPEC)
+GEN_HANDLER(tlbre_40x, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
 {
 #if defined(CONFIG_USER_ONLY)
     RET_PRIVOPC(ctx);
@@ -4656,7 +4781,7 @@ GEN_HANDLER(tlbre_40x, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_SPEC)
 }
 
 /* tlbsx - tlbsx. */
-GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_SPEC)
+GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
 {
 #if defined(CONFIG_USER_ONLY)
     RET_PRIVOPC(ctx);
@@ -4675,7 +4800,7 @@ GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_SPEC)
 }
 
 /* tlbwe */
-GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_SPEC)
+GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
 {
 #if defined(CONFIG_USER_ONLY)
     RET_PRIVOPC(ctx);
@@ -5701,7 +5826,7 @@ void cpu_dump_state (CPUState *env, FILE *f,
     for (i = 0; i < 32; i++) {
         if ((i & (RGPL - 1)) == 0)
             cpu_fprintf(f, "GPR%02d", i);
-        cpu_fprintf(f, " " REGX, env->gpr[i]);
+        cpu_fprintf(f, " " REGX, (target_ulong)env->gpr[i]);
         if ((i & (RGPL - 1)) == (RGPL - 1))
             cpu_fprintf(f, "\n");
     }
index 82270e659e8b4d11028d6a65f6b11029da979895..c6f09aea5a05daf23a7e22247493a62cda0611c6 100644 (file)
@@ -32,20 +32,26 @@ struct ppc_def_t {
     uint32_t pvr;
     uint32_t pvr_mask;
     uint64_t insns_flags;
-    uint32_t flags;
     uint64_t msr_mask;
+    uint8_t mmu_model;
+    uint8_t excp_model;
+    uint8_t bus_model;
+    uint8_t pad;
+    void (*init_proc)(CPUPPCState *env);
 };
 
 /* For user-mode emulation, we don't emulate any IRQ controller */
 #if defined(CONFIG_USER_ONLY)
-#define PPC_IRQ_INIT_FN(name)                                         \
-static inline void glue(glue(ppc, name),_irq_init) (CPUPPCState *env) \
-{                                                                     \
+#define PPC_IRQ_INIT_FN(name)                                                 \
+static inline void glue(glue(ppc, name),_irq_init) (CPUPPCState *env)         \
+{                                                                             \
 }
 #else
-#define PPC_IRQ_INIT_FN(name)                                         \
+#define PPC_IRQ_INIT_FN(name)                                                 \
 void glue(glue(ppc, name),_irq_init) (CPUPPCState *env);
 #endif
+
+PPC_IRQ_INIT_FN(401);
 PPC_IRQ_INIT_FN(405);
 PPC_IRQ_INIT_FN(6xx);
 PPC_IRQ_INIT_FN(970);
@@ -285,7 +291,7 @@ static void spr_write_asr (void *opaque, int sprn)
     RET_STOP(ctx);
 }
 #endif
-#endif /* !defined(CONFIG_USER_ONLY) */
+#endif
 
 /* PowerPC 601 specific registers */
 /* RTC */
@@ -582,7 +588,7 @@ static void gen_low_BATs (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_dbat, &spr_write_dbatl,
                  0x00000000);
-    env->nb_BATs = 4;
+    env->nb_BATs += 4;
 }
 
 /* BATs 4-7 */
@@ -652,7 +658,7 @@ static void gen_high_BATs (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_dbat_h, &spr_write_dbatl_h,
                  0x00000000);
-    env->nb_BATs = 8;
+    env->nb_BATs += 4;
 }
 
 /* Generic PowerPC time base */
@@ -797,7 +803,7 @@ static void gen_spr_7xx (CPUPPCState *env)
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
     /* XXX : not implemented */
-    spr_register(env, SPR_SIA, "SIA",
+    spr_register(env, SPR_SIAR, "SIAR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, SPR_NOACCESS,
                  0x00000000);
@@ -825,29 +831,33 @@ static void gen_spr_7xx (CPUPPCState *env)
                  &spr_read_ureg, SPR_NOACCESS,
                  &spr_read_ureg, SPR_NOACCESS,
                  0x00000000);
-    spr_register(env, SPR_USIA, "USIA",
+    spr_register(env, SPR_USIAR, "USIAR",
                  &spr_read_ureg, SPR_NOACCESS,
                  &spr_read_ureg, SPR_NOACCESS,
                  0x00000000);
-    /* Thermal management */
+    /* External access control */
     /* XXX : not implemented */
-    spr_register(env, SPR_THRM1, "THRM1",
+    spr_register(env, SPR_EAR, "EAR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
+}
+
+static void gen_spr_thrm (CPUPPCState *env)
+{
+    /* Thermal management */
     /* XXX : not implemented */
-    spr_register(env, SPR_THRM2, "THRM2",
+    spr_register(env, SPR_THRM1, "THRM1",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
     /* XXX : not implemented */
-    spr_register(env, SPR_THRM3, "THRM3",
+    spr_register(env, SPR_THRM2, "THRM2",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
-    /* External access control */
     /* XXX : not implemented */
-    spr_register(env, SPR_EAR, "EAR",
+    spr_register(env, SPR_THRM3, "THRM3",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
@@ -904,7 +914,7 @@ static void gen_spr_604 (CPUPPCState *env)
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
     /* XXX : not implemented */
-    spr_register(env, SPR_SIA, "SIA",
+    spr_register(env, SPR_SIAR, "SIAR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, SPR_NOACCESS,
                  0x00000000);
@@ -1004,7 +1014,7 @@ static void gen_spr_602 (CPUPPCState *env)
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
     /* XXX : not implemented */
-    spr_register(env, SPR_ESASR, "ESASR",
+    spr_register(env, SPR_ESASRR, "ESASRR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
@@ -1030,6 +1040,11 @@ static void gen_spr_602 (CPUPPCState *env)
                  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 */
@@ -1104,7 +1119,116 @@ static void gen_spr_601 (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_601_ubat, &spr_write_601_ubatl,
                  0x00000000);
+    env->nb_BATs = 4;
+}
+
+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_MMCR2, "MMCR2",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_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);
+    spr_register(env, SPR_UBAMR, "UBAMR",
+                 &spr_read_ureg, SPR_NOACCESS,
+                 &spr_read_ureg, SPR_NOACCESS,
+                 0x00000000);
+    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);
+}
+
+#if defined (TODO)
+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 */
+    spr_register(env, SPR_L3ITCR0, "L3ITCR0",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* L3ITCR1 */
+    spr_register(env, SPR_L3ITCR1, "L3ITCR1",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* L3ITCR2 */
+    spr_register(env, SPR_L3ITCR2, "L3ITCR2",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* L3ITCR3 */
+    spr_register(env, SPR_L3ITCR3, "L3ITCR3",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* L3OHCR */
+    spr_register(env, SPR_L3OHCR, "L3OHCR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* L3PM */
+    spr_register(env, SPR_L3PM, "L3PM",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+}
+#endif /* TODO */
+
+#if defined (TODO)
+static void gen_74xx_soft_tlb (CPUPPCState *env)
+{
+    /* XXX: TODO */
+    spr_register(env, SPR_PTEHI, "PTEHI",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_PTELO, "PTELO",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_TLBMISS, "TLBMISS",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
 }
+#endif /* TODO */
 
 /* PowerPC BookE SPR */
 static void gen_spr_BookE (CPUPPCState *env)
@@ -1132,14 +1256,6 @@ static void gen_spr_BookE (CPUPPCState *env)
                  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);
 #endif
     /* Debug */
     /* XXX : not implemented */
@@ -1366,6 +1482,7 @@ static void gen_spr_BookE (CPUPPCState *env)
 }
 
 /* FSL storage control registers */
+#if defined(TODO)
 static void gen_spr_BookE_FSL (CPUPPCState *env)
 {
     /* TLB assist registers */
@@ -1447,6 +1564,7 @@ static void gen_spr_BookE_FSL (CPUPPCState *env)
         break;
     }
 }
+#endif
 
 /* SPR specific to PowerPC 440 implementation */
 static void gen_spr_440 (CPUPPCState *env)
@@ -1599,11 +1717,6 @@ static void gen_spr_40x (CPUPPCState *env)
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
     /* XXX : not implemented */
-    spr_register(env, SPR_40x_DCWR, "DCWR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0x00000000);
-    /* XXX : not implemented */
     spr_register(env, SPR_40x_ICCR, "ICCR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
@@ -1613,11 +1726,6 @@ static void gen_spr_40x (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, SPR_NOACCESS,
                  0x00000000);
-    /* Bus access control */
-    spr_register(env, SPR_40x_SGR, "SGR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, &spr_write_generic,
-                 0xFFFFFFFF);
     /* Exception */
     spr_register(env, SPR_40x_DEAR, "DEAR",
                  SPR_NOACCESS, SPR_NOACCESS,
@@ -1834,6 +1942,19 @@ static void gen_spr_401 (CPUPPCState *env)
                  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)
 {
@@ -1867,11 +1988,10 @@ static void gen_spr_403 (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
-    /* MMU */
-    spr_register(env, SPR_40x_PID, "PID",
-                 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,
@@ -1888,6 +2008,15 @@ static void gen_spr_403 (CPUPPCState *env)
                  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,
@@ -1895,7 +2024,6 @@ static void gen_spr_403 (CPUPPCState *env)
 }
 
 /* SPR specific to PowerPC compression coprocessor extension */
-#if defined (TODO)
 static void gen_spr_compress (CPUPPCState *env)
 {
     spr_register(env, SPR_401_SKR, "SKR",
@@ -1903,14 +2031,93 @@ static void gen_spr_compress (CPUPPCState *env)
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
 }
+
+#if defined (TARGET_PPC64)
+#if defined (TODO)
+/* SPR specific to PowerPC 620 */
+static void gen_spr_620 (CPUPPCState *env)
+{
+    spr_register(env, SPR_620_PMR0, "PMR0",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_PMR1, "PMR1",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_PMR2, "PMR2",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_PMR3, "PMR3",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_PMR4, "PMR4",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_PMR5, "PMR5",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_PMR6, "PMR6",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_PMR7, "PMR7",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_PMR8, "PMR8",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_PMR9, "PMR9",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_PMRA, "PMR10",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_PMRB, "PMR11",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_PMRC, "PMR12",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_PMRD, "PMR13",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_PMRE, "PMR14",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_PMRF, "PMR15",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_HID8, "HID8",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_620_HID9, "HID9",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+}
 #endif
+#endif /* defined (TARGET_PPC64) */
 
 // XXX: TODO
 /*
  * AMR     => SPR 29 (Power 2.04)
  * CTRL    => SPR 136 (Power 2.04)
  * CTRL    => SPR 152 (Power 2.04)
- * VRSAVE  => SPR 256 (Altivec)
  * SCOMC   => SPR 276 (64 bits ?)
  * SCOMD   => SPR 277 (64 bits ?)
  * ASR     => SPR 280 (64 bits)
@@ -1942,2397 +2149,3341 @@ static void gen_spr_compress (CPUPPCState *env)
  * ... and more (thermal management, performance counters, ...)
  */
 
-static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
-{
-    env->reserve = -1;
-    /* Default MMU definitions */
-    env->nb_BATs = -1;
-    env->nb_tlb = 0;
-    env->nb_ways = 0;
-    /* XXX: missing:
-     * 32 bits PowerPC:
-     * - MPC5xx(x)
-     * - MPC8xx(x)
-     * - RCPU (same as MPC5xx ?)
-     */
-    spr_register(env, SPR_PVR, "PVR",
-                 SPR_NOACCESS, SPR_NOACCESS,
-                 &spr_read_generic, SPR_NOACCESS,
-                 def->pvr);
-    printf("%s: PVR %08x mask %08x => %08x\n", __func__,
-           def->pvr, def->pvr_mask, def->pvr & def->pvr_mask);
-    switch (def->pvr) {
-    /* Embedded PowerPC from IBM                           */
-    case CPU_PPC_401A1:   /* 401 A1 family                 */
-    case CPU_PPC_401B2:   /* 401 B2 family                 */
-#if 0
-    case CPU_PPC_401B3:   /* 401 B3 family                 */
-#endif
-    case CPU_PPC_401C2:   /* 401 C2 family                 */
-    case CPU_PPC_401D2:   /* 401 D2 family                 */
-    case CPU_PPC_401E2:   /* 401 E2 family                 */
-    case CPU_PPC_401F2:   /* 401 F2 family                 */
-    case CPU_PPC_401G2:   /* 401 G2 family                 */
-    case CPU_PPC_IOP480:  /* IOP 480 family                */
-    case CPU_PPC_COBRA:   /* IBM Processor for Network Resources */
-        gen_spr_generic(env);
-        gen_spr_40x(env);
-        gen_spr_401_403(env);
-        gen_spr_401(env);
-#if defined (TODO)
-        /* XXX: optional ? */
-        gen_spr_compress(env);
-#endif
-        env->nb_BATs = 0;
-        env->nb_tlb = 64;
-        env->nb_ways = 1;
-        env->id_tlbs = 0;
-        /* XXX: TODO: allocate internal IRQ controller */
-        break;
-
-    case CPU_PPC_403GA:   /* 403 GA family                 */
-    case CPU_PPC_403GB:   /* 403 GB family                 */
-    case CPU_PPC_403GC:   /* 403 GC family                 */
-    case CPU_PPC_403GCX:  /* 403 GCX family                */
-        gen_spr_generic(env);
-        gen_spr_40x(env);
-        gen_spr_401_403(env);
-        gen_spr_403(env);
-        env->nb_BATs = 0;
-        env->nb_tlb = 64;
-        env->nb_ways = 1;
-        env->id_tlbs = 0;
-        /* XXX: TODO: allocate internal IRQ controller */
-        break;
-
-    case CPU_PPC_405CR:   /* 405 GP/CR family              */
-    case CPU_PPC_405EP:   /* 405 EP family                 */
-    case CPU_PPC_405GPR:  /* 405 GPR family                */
-    case CPU_PPC_405D2:   /* 405 D2 family                 */
-    case CPU_PPC_405D4:   /* 405 D4 family                 */
-        gen_spr_generic(env);
-        /* Time base */
-        gen_tbl(env);
-        gen_spr_40x(env);
-        gen_spr_405(env);
-        env->nb_BATs = 0;
-        env->nb_tlb = 64;
-        env->nb_ways = 1;
-        env->id_tlbs = 0;
-        /* Allocate hardware IRQ controller */
-        ppc405_irq_init(env);
-        break;
+/*****************************************************************************/
+/* PowerPC implementations definitions                                       */
 
-    case CPU_PPC_NPE405H: /* NPe405 H family               */
-    case CPU_PPC_NPE405H2:
-    case CPU_PPC_NPE405L: /* Npe405 L family               */
-        gen_spr_generic(env);
-        /* Time base */
-        gen_tbl(env);
-        gen_spr_40x(env);
-        gen_spr_405(env);
-        env->nb_BATs = 0;
-        env->nb_tlb = 64;
-        env->nb_ways = 1;
-        env->id_tlbs = 0;
-        /* Allocate hardware IRQ controller */
-        ppc405_irq_init(env);
-        break;
+/* PowerPC 40x instruction set                                               */
+#define POWERPC_INSNS_EMB    (PPC_INSNS_BASE | PPC_EMB_COMMON)
 
-#if defined (TODO)
-    case CPU_PPC_STB01000:
-#endif
-#if defined (TODO)
-    case CPU_PPC_STB01010:
-#endif
-#if defined (TODO)
-    case CPU_PPC_STB0210:
-#endif
-    case CPU_PPC_STB03:   /* STB03 family                  */
-#if defined (TODO)
-    case CPU_PPC_STB043:  /* STB043 family                  */
-#endif
-#if defined (TODO)
-    case CPU_PPC_STB045:  /* STB045 family                  */
-#endif
-    case CPU_PPC_STB25:   /* STB25 family                  */
-#if defined (TODO)
-    case CPU_PPC_STB130:  /* STB130 family                 */
-#endif
-        gen_spr_generic(env);
-        /* Time base */
-        gen_tbl(env);
-        gen_spr_40x(env);
-        gen_spr_405(env);
-        env->nb_BATs = 0;
-        env->nb_tlb = 64;
-        env->nb_ways = 1;
-        env->id_tlbs = 0;
-        /* Allocate hardware IRQ controller */
-        ppc405_irq_init(env);
-        break;
+/* PowerPC 401                                                               */
+#define POWERPC_INSNS_401    (POWERPC_INSNS_EMB |                             \
+                              PPC_MEM_SYNC | PPC_MEM_EIEIO |                  \
+                              PPC_4xx_COMMON | PPC_40x_EXCP | PPC_40x_ICBT)
+#define POWERPC_MSRM_401     (0x00000000000FD201ULL)
+#define POWERPC_MMU_401      (POWERPC_MMU_REAL_4xx)
+#define POWERPC_EXCP_401     (POWERPC_EXCP_40x)
+#define POWERPC_INPUT_401    (PPC_FLAGS_INPUT_401)
 
-    case CPU_PPC_440EP:   /* 440 EP family                 */
-    case CPU_PPC_440GP:   /* 440 GP family                 */
-    case CPU_PPC_440GX:   /* 440 GX family                 */
-    case CPU_PPC_440GXc:  /* 440 GXc family                */
-    case CPU_PPC_440GXf:  /* 440 GXf family                */
-    case CPU_PPC_440SP:   /* 440 SP family                 */
-    case CPU_PPC_440SP2:
-    case CPU_PPC_440SPE:  /* 440 SPE family                */
-        gen_spr_generic(env);
-        /* Time base */
-        gen_tbl(env);
-        gen_spr_BookE(env);
-        gen_spr_440(env);
-        env->nb_BATs = 0;
-        env->nb_tlb = 64;
-        env->nb_ways = 1;
-        env->id_tlbs = 0;
-        /* XXX: TODO: allocate internal IRQ controller */
-        break;
+static void init_proc_401 (CPUPPCState *env)
+{
+    gen_spr_40x(env);
+    gen_spr_401_403(env);
+    gen_spr_401(env);
+    /* Bus access control */
+    spr_register(env, SPR_40x_SGR, "SGR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0xFFFFFFFF);
+    /* XXX : not implemented */
+    spr_register(env, SPR_40x_DCWR, "DCWR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* XXX: TODO: allocate internal IRQ controller */
+}
 
-    /* Embedded PowerPC from Freescale                     */
-#if defined (TODO)
-    case CPU_PPC_5xx:
-        break;
-#endif
-#if defined (TODO)
-    case CPU_PPC_8xx:     /* MPC821 / 823 / 850 / 860      */
-        break;
-#endif
-#if defined (TODO)
-    case CPU_PPC_82xx_HIP3:    /* MPC8240 / 8260                */
-    case CPU_PPC_82xx_HIP4:    /* MPC8240 / 8260                */
-        break;
-#endif
-#if defined (TODO)
-    case CPU_PPC_827x:    /* MPC 827x / 828x               */
-        break;
-#endif
-
-    /* XXX: Use MPC8540 PVR to implement a test PowerPC BookE target */
-    case CPU_PPC_e500v110:
-    case CPU_PPC_e500v120:
-    case CPU_PPC_e500v210:
-    case CPU_PPC_e500v220:
-        gen_spr_generic(env);
-        /* Time base */
-        gen_tbl(env);
-        gen_spr_BookE(env);
-        gen_spr_BookE_FSL(env);
-        env->nb_BATs = 0;
-        env->nb_tlb = 64;
-        env->nb_ways = 1;
-        env->id_tlbs = 0;
-        /* XXX: TODO: allocate internal IRQ controller */
-        break;
-
-#if defined (TODO)
-    case CPU_PPC_e600:
-        break;
-#endif
-
-    /* 32 bits PowerPC                                     */
-    case CPU_PPC_601:     /* PowerPC 601                   */
-        gen_spr_generic(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_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_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);
-        /* XXX : not implemented */
-#if 0 /* ? */
-        spr_register(env, SPR_601_HID15, "HID15",
-                     SPR_NOACCESS, SPR_NOACCESS,
-                     &spr_read_generic, &spr_write_generic,
-                     0x00000000);
-#endif
-        env->nb_tlb = 64;
-        env->nb_ways = 2;
-        env->id_tlbs = 0;
-        env->id_tlbs = 0;
-        /* XXX: TODO: allocate internal IRQ controller */
-        break;
-
-    case CPU_PPC_602:     /* PowerPC 602                   */
-        gen_spr_generic(env);
-        gen_spr_ne_601(env);
-        /* Memory management */
-        gen_low_BATs(env);
-        /* Time base */
-        gen_tbl(env);
-        gen_6xx_7xx_soft_tlb(env, 64, 2);
-        gen_spr_602(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);
-        /* Allocate hardware IRQ controller */
-        ppc6xx_irq_init(env);
-        break;
-
-    case CPU_PPC_603:     /* PowerPC 603                   */
-    case CPU_PPC_603E:    /* PowerPC 603e                  */
-    case CPU_PPC_603E7v:
-    case CPU_PPC_603E7v2:
-    case CPU_PPC_603P:    /* PowerPC 603p                  */
-    case CPU_PPC_603R:    /* PowerPC 603r                  */
-        gen_spr_generic(env);
-        gen_spr_ne_601(env);
-        /* Memory management */
-        gen_low_BATs(env);
-        /* Time base */
-        gen_tbl(env);
-        gen_6xx_7xx_soft_tlb(env, 64, 2);
-        gen_spr_603(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);
-        /* Allocate hardware IRQ controller */
-        ppc6xx_irq_init(env);
-        break;
-
-    case CPU_PPC_G2:      /* PowerPC G2 family             */
-    case CPU_PPC_G2H4:
-    case CPU_PPC_G2gp:
-    case CPU_PPC_G2ls:
-    case CPU_PPC_G2LE:    /* PowerPC G2LE family           */
-    case CPU_PPC_G2LEgp:
-    case CPU_PPC_G2LEls:
-        gen_spr_generic(env);
-        gen_spr_ne_601(env);
-        /* Memory management */
-        gen_low_BATs(env);
-        /* Time base */
-        gen_tbl(env);
-        /* Memory management */
-        gen_high_BATs(env);
-        gen_6xx_7xx_soft_tlb(env, 64, 2);
-        gen_spr_G2_755(env);
-        gen_spr_G2(env);
-        /* 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);
-        /* Allocate hardware IRQ controller */
-        ppc6xx_irq_init(env);
-        break;
-
-    case CPU_PPC_604:     /* PowerPC 604                   */
-    case CPU_PPC_604E:    /* PowerPC 604e                  */
-    case CPU_PPC_604R:    /* PowerPC 604r                  */
-        gen_spr_generic(env);
-        gen_spr_ne_601(env);
-        /* Memory management */
-        gen_low_BATs(env);
-        /* Time base */
-        gen_tbl(env);
-        gen_spr_604(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);
-        /* Allocate hardware IRQ controller */
-        ppc6xx_irq_init(env);
-        break;
-
-    case CPU_PPC_74x:     /* PowerPC 740 / 750             */
-    case CPU_PPC_740E:
-    case CPU_PPC_750E:
-    case CPU_PPC_74xP:    /* PowerPC 740P / 750P           */
-    case CPU_PPC_750CXE21: /* IBM PowerPC 750cxe            */
-    case CPU_PPC_750CXE22:
-    case CPU_PPC_750CXE23:
-    case CPU_PPC_750CXE24:
-    case CPU_PPC_750CXE24b:
-    case CPU_PPC_750CXE31:
-    case CPU_PPC_750CXE31b:
-    case CPU_PPC_750CXR:
-        gen_spr_generic(env);
-        gen_spr_ne_601(env);
-        /* Memory management */
-        gen_low_BATs(env);
-        /* Time base */
-        gen_tbl(env);
-        gen_spr_7xx(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);
-        /* Allocate hardware IRQ controller */
-        ppc6xx_irq_init(env);
-        break;
-
-    case CPU_PPC_750FX10: /* IBM PowerPC 750 FX            */
-    case CPU_PPC_750FX20:
-    case CPU_PPC_750FX21:
-    case CPU_PPC_750FX22:
-    case CPU_PPC_750FX23:
-    case CPU_PPC_750GX10: /* IBM PowerPC 750 GX            */
-    case CPU_PPC_750GX11:
-    case CPU_PPC_750GX12:
-        gen_spr_generic(env);
-        gen_spr_ne_601(env);
-        /* Memory management */
-        gen_low_BATs(env);
-        /* PowerPC 750fx & 750gx has 8 DBATs and 8 IBATs */
-        gen_high_BATs(env);
-        /* Time base */
-        gen_tbl(env);
-        gen_spr_7xx(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_750_HID2, "HID2",
-                     SPR_NOACCESS, SPR_NOACCESS,
-                     &spr_read_generic, &spr_write_generic,
-                     0x00000000);
-        /* Allocate hardware IRQ controller */
-        ppc6xx_irq_init(env);
-        break;
-
-    case CPU_PPC_755_10:  /* PowerPC 755                   */
-    case CPU_PPC_755_11:
-    case CPU_PPC_755_20:
-    case CPU_PPC_755D:
-    case CPU_PPC_755E:
-        gen_spr_generic(env);
-        gen_spr_ne_601(env);
-        /* Memory management */
-        gen_low_BATs(env);
-        /* Time base */
-        gen_tbl(env);
-        /* Memory management */
-        gen_high_BATs(env);
-        gen_6xx_7xx_soft_tlb(env, 64, 2);
-        gen_spr_G2_755(env);
-        /* L2 cache control */
-        /* XXX : not implemented */
-        spr_register(env, SPR_ICTC, "ICTC",
-                     SPR_NOACCESS, SPR_NOACCESS,
-                     &spr_read_generic, &spr_write_generic,
-                     0x00000000);
-        /* XXX : not implemented */
-        spr_register(env, SPR_L2PM, "L2PM",
-                     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_HID2, "HID2",
-                     SPR_NOACCESS, SPR_NOACCESS,
-                     &spr_read_generic, &spr_write_generic,
-                     0x00000000);
-        /* Allocate hardware IRQ controller */
-        ppc6xx_irq_init(env);
-        break;
-
-#if defined (TODO)
-    /* G4 family */
-    case CPU_PPC_7400:    /* PowerPC 7400                  */
-    case CPU_PPC_7410C:   /* PowerPC 7410                  */
-    case CPU_PPC_7410D:
-    case CPU_PPC_7410E:
-    case CPU_PPC_7441:    /* PowerPC 7441                  */
-    case CPU_PPC_7445:    /* PowerPC 7445                  */
-    case CPU_PPC_7447:    /* PowerPC 7447                  */
-    case CPU_PPC_7447A:   /* PowerPC 7447A                 */
-    case CPU_PPC_7448:    /* PowerPC 7448                  */
-    case CPU_PPC_7450:    /* PowerPC 7450                  */
-    case CPU_PPC_7450b:
-    case CPU_PPC_7451:    /* PowerPC 7451                  */
-    case CPU_PPC_7451G:
-    case CPU_PPC_7455:    /* PowerPC 7455                  */
-    case CPU_PPC_7455F:
-    case CPU_PPC_7455G:
-    case CPU_PPC_7457:    /* PowerPC 7457                  */
-    case CPU_PPC_7457C:
-    case CPU_PPC_7457A:   /* PowerPC 7457A                 */
-        break;
-#endif
-
-    /* 64 bits PowerPC                                     */
-#if defined (TARGET_PPC64)
-#if defined (TODO)
-    case CPU_PPC_620:     /* PowerPC 620                   */
-    case CPU_PPC_630:     /* PowerPC 630 (Power 3)         */
-    case CPU_PPC_631:     /* PowerPC 631 (Power 3+)        */
-    case CPU_PPC_POWER4:  /* Power 4                       */
-    case CPU_PPC_POWER4P: /* Power 4+                      */
-    case CPU_PPC_POWER5:  /* Power 5                       */
-    case CPU_PPC_POWER5P: /* Power 5+                      */
-#endif
-        break;
-
-    case CPU_PPC_970:     /* PowerPC 970                   */
-    case CPU_PPC_970FX10: /* PowerPC 970 FX                */
-    case CPU_PPC_970FX20:
-    case CPU_PPC_970FX21:
-    case CPU_PPC_970FX30:
-    case CPU_PPC_970FX31:
-    case CPU_PPC_970MP10: /* PowerPC 970 MP                */
-    case CPU_PPC_970MP11:
-        gen_spr_generic(env);
-        gen_spr_ne_601(env);
-        /* XXX: not correct */
-        gen_low_BATs(env);
-        /* Time base */
-        gen_tbl(env);
-        gen_spr_7xx(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_750_HID2, "HID2",
-                     SPR_NOACCESS, SPR_NOACCESS,
-                     &spr_read_generic, &spr_write_generic,
-                     0x00000000);
-        /* Allocate hardware IRQ controller */
-        ppc970_irq_init(env);
-        break;
-
-#if defined (TODO)
-    case CPU_PPC_CELL10:  /* Cell family                   */
-    case CPU_PPC_CELL20:
-    case CPU_PPC_CELL30:
-    case CPU_PPC_CELL31:
-#endif
-        break;
-
-#if defined (TODO)
-    case CPU_PPC_RS64:    /* Apache (RS64/A35)             */
-    case CPU_PPC_RS64II:  /* NorthStar (RS64-II/A50)       */
-    case CPU_PPC_RS64III: /* Pulsar (RS64-III)             */
-    case CPU_PPC_RS64IV:  /* IceStar/IStar/SStar (RS64-IV) */
-#endif
-        break;
-#endif /* defined (TARGET_PPC64) */
-
-#if defined (TODO)
-    /* POWER                                               */
-    case CPU_POWER:       /* POWER                         */
-    case CPU_POWER2:      /* POWER2                        */
-        break;
-#endif
-
-    default:
-        gen_spr_generic(env);
-        /* XXX: TODO: allocate internal IRQ controller */
-        break;
-    }
-    if (env->nb_BATs == -1)
-        env->nb_BATs = 4;
-    /* Allocate TLBs buffer when needed */
-    if (env->nb_tlb != 0) {
-        int nb_tlb = env->nb_tlb;
-        if (env->id_tlbs != 0)
-            nb_tlb *= 2;
-        env->tlb = qemu_mallocz(nb_tlb * sizeof(ppc_tlb_t));
-        /* Pre-compute some useful values */
-        env->tlb_per_way = env->nb_tlb / env->nb_ways;
-    }
+/* PowerPC 401x2                                                             */
+#define POWERPC_INSNS_401x2  (POWERPC_INSNS_EMB |                             \
+                              PPC_MEM_SYNC | PPC_MEM_EIEIO |                  \
+                              PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | \
+                              PPC_CACHE_DCBA | PPC_MFTB |                     \
+                              PPC_4xx_COMMON | PPC_40x_EXCP | PPC_40x_ICBT)
+#define POWERPC_MSRM_401x2   (0x00000000001FD231ULL)
+#define POWERPC_MMU_401x2    (POWERPC_MMU_SOFT_4xx_Z)
+#define POWERPC_EXCP_401x2   (POWERPC_EXCP_40x)
+#define POWERPC_INPUT_401x2  (PPC_FLAGS_INPUT_401)
+
+static void init_proc_401x2 (CPUPPCState *env)
+{
+    gen_spr_40x(env);
+    gen_spr_401_403(env);
+    gen_spr_401x2(env);
+    gen_spr_compress(env);
+    /* Bus access control */
+    spr_register(env, SPR_40x_SGR, "SGR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0xFFFFFFFF);
+    /* XXX : not implemented */
+    spr_register(env, SPR_40x_DCWR, "DCWR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* Memory management */
+    env->nb_tlb = 64;
+    env->nb_ways = 1;
+    env->id_tlbs = 0;
+    /* XXX: TODO: allocate internal IRQ controller */
 }
 
-#if defined(PPC_DUMP_CPU)
-static void dump_sprs (CPUPPCState *env)
+/* PowerPC 401x3                                                             */
+#if defined(TODO)
+#define POWERPC_INSNS_401x3  (POWERPC_INSNS_EMB |                             \
+                              PPC_MEM_SYNC | PPC_MEM_EIEIO |                  \
+                              PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | \
+                              PPC_CACHE_DCBA | PPC_MFTB |                     \
+                              PPC_4xx_COMMON | PPC_40x_EXCP | PPC_40x_ICBT)
+#define POWERPC_MSRM_401x3   (0x00000000001FD631ULL)
+#define POWERPC_MMU_401x3    (POWERPC_MMU_SOFT_4xx_Z)
+#define POWERPC_EXCP_401x3   (POWERPC_EXCP_40x)
+#define POWERPC_INPUT_401x3  (PPC_FLAGS_INPUT_401)
+
+static void init_proc_401x2 (CPUPPCState *env)
 {
-    ppc_spr_t *spr;
-    uint32_t pvr = env->spr[SPR_PVR];
-    uint32_t sr, sw, ur, uw;
-    int i, j, n;
-
-    printf("* SPRs for PVR=%08x\n", pvr);
-    for (i = 0; i < 32; i++) {
-        for (j = 0; j < 32; j++) {
-            n = (i << 5) | j;
-            spr = &env->spr_cb[n];
-#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;
-#else
-            sw = 0;
-            sr = 0;
-#endif
-            uw = spr->uea_write != NULL && spr->uea_write != SPR_NOACCESS;
-            ur = spr->uea_read != NULL && spr->uea_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' : '-');
-            }
-        }
-    }
-    fflush(stdout);
-    fflush(stderr);
 }
-#endif
-
-/*****************************************************************************/
-#include <stdlib.h>
-#include <string.h>
-
-int fflush (FILE *stream);
-
-/* Opcode types */
-enum {
-    PPC_DIRECT   = 0, /* Opcode routine        */
-    PPC_INDIRECT = 1, /* Indirect opcode table */
-};
-
-static inline int is_indirect_opcode (void *handler)
+#endif /* TODO */
+
+/* IOP480                                                                    */
+#define POWERPC_INSNS_IOP480 (POWERPC_INSNS_EMB |                             \
+                              PPC_MEM_SYNC | PPC_MEM_EIEIO |                  \
+                              PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | \
+                              PPC_CACHE_DCBA |                                \
+                              PPC_4xx_COMMON | PPC_40x_EXCP |  PPC_40x_ICBT)
+#define POWERPC_MSRM_IOP480  (0x00000000001FD231ULL)
+#define POWERPC_MMU_IOP480   (POWERPC_MMU_SOFT_4xx_Z)
+#define POWERPC_EXCP_IOP480  (POWERPC_EXCP_40x)
+#define POWERPC_INPUT_IOP480 (PPC_FLAGS_INPUT_401)
+
+static void init_proc_IOP480 (CPUPPCState *env)
 {
-    return ((unsigned long)handler & 0x03) == PPC_INDIRECT;
+    gen_spr_40x(env);
+    gen_spr_401_403(env);
+    gen_spr_401x2(env);
+    gen_spr_compress(env);
+    /* Bus access control */
+    spr_register(env, SPR_40x_SGR, "SGR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0xFFFFFFFF);
+    /* XXX : not implemented */
+    spr_register(env, SPR_40x_DCWR, "DCWR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* Memory management */
+    env->nb_tlb = 64;
+    env->nb_ways = 1;
+    env->id_tlbs = 0;
+    /* XXX: TODO: allocate internal IRQ controller */
 }
 
-static inline opc_handler_t **ind_table(void *handler)
+/* PowerPC 403                                                               */
+#define POWERPC_INSNS_403    (POWERPC_INSNS_EMB |                             \
+                              PPC_MEM_SYNC | PPC_MEM_EIEIO |                  \
+                              PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | \
+                              PPC_4xx_COMMON | PPC_40x_EXCP | PPC_40x_ICBT)
+#define POWERPC_MSRM_403     (0x000000000007D00DULL)
+#define POWERPC_MMU_403      (POWERPC_MMU_REAL_4xx)
+#define POWERPC_EXCP_403     (POWERPC_EXCP_40x)
+#define POWERPC_INPUT_403    (PPC_FLAGS_INPUT_401)
+
+static void init_proc_403 (CPUPPCState *env)
 {
-    return (opc_handler_t **)((unsigned long)handler & ~3);
+    gen_spr_40x(env);
+    gen_spr_401_403(env);
+    gen_spr_403(env);
+    gen_spr_403_real(env);
+    /* XXX: TODO: allocate internal IRQ controller */
 }
 
-/* Instruction table creation */
-/* Opcodes tables creation */
-static void fill_new_table (opc_handler_t **table, int len)
+/* PowerPC 403 GCX                                                           */
+#define POWERPC_INSNS_403GCX (POWERPC_INSNS_EMB |                             \
+                              PPC_MEM_SYNC | PPC_MEM_EIEIO |                  \
+                              PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | \
+                              PPC_4xx_COMMON | PPC_40x_EXCP | PPC_40x_ICBT)
+#define POWERPC_MSRM_403GCX  (0x000000000007D00DULL)
+#define POWERPC_MMU_403GCX   (POWERPC_MMU_SOFT_4xx_Z)
+#define POWERPC_EXCP_403GCX  (POWERPC_EXCP_40x)
+#define POWERPC_INPUT_403GCX (PPC_FLAGS_INPUT_401)
+
+static void init_proc_403GCX (CPUPPCState *env)
 {
-    int i;
-
-    for (i = 0; i < len; i++)
-        table[i] = &invalid_handler;
+    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 */
+    spr_register(env, SPR_40x_SGR, "SGR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0xFFFFFFFF);
+    /* XXX : not implemented */
+    spr_register(env, SPR_40x_DCWR, "DCWR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* Memory management */
+    env->nb_tlb = 64;
+    env->nb_ways = 1;
+    env->id_tlbs = 0;
+    /* XXX: TODO: allocate internal IRQ controller */
 }
 
-static int create_new_table (opc_handler_t **table, unsigned char idx)
+/* PowerPC 405                                                               */
+#define POWERPC_INSNS_405    (POWERPC_INSNS_EMB | PPC_MFTB |                  \
+                              PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_CACHE_DCBA | \
+                              PPC_40x_TLB | PPC_MEM_TLBIA | PPC_MEM_TLBSYNC | \
+                              PPC_4xx_COMMON | PPC_40x_EXCP | PPC_40x_ICBT |  \
+                              PPC_405_MAC)
+#define POWERPC_MSRM_405     (0x000000000006E630ULL)
+#define POWERPC_MMU_405      (POWERPC_MMU_SOFT_4xx)
+#define POWERPC_EXCP_405     (POWERPC_EXCP_40x)
+#define POWERPC_INPUT_405    (PPC_FLAGS_INPUT_405)
+
+static void init_proc_405 (CPUPPCState *env)
 {
-    opc_handler_t **tmp;
-
-    tmp = malloc(0x20 * sizeof(opc_handler_t));
-    if (tmp == NULL)
-        return -1;
-    fill_new_table(tmp, 0x20);
-    table[idx] = (opc_handler_t *)((unsigned long)tmp | PPC_INDIRECT);
-
-    return 0;
+    /* Time base */
+    gen_tbl(env);
+    gen_spr_40x(env);
+    gen_spr_405(env);
+    /* Bus access control */
+    spr_register(env, SPR_40x_SGR, "SGR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0xFFFFFFFF);
+    /* XXX : not implemented */
+    spr_register(env, SPR_40x_DCWR, "DCWR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* Memory management */
+    env->nb_tlb = 64;
+    env->nb_ways = 1;
+    env->id_tlbs = 0;
+    /* Allocate hardware IRQ controller */
+    ppc405_irq_init(env);
 }
 
-static int insert_in_table (opc_handler_t **table, unsigned char idx,
-                            opc_handler_t *handler)
+/* PowerPC 440 EP                                                            */
+#define POWERPC_INSNS_440EP  (POWERPC_INSNS_EMB |                             \
+                              PPC_CACHE_DCBA | PPC_MEM_TLBSYNC |              \
+                              PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |      \
+                              PPC_440_SPEC | PPC_RFMCI)
+#define POWERPC_MSRM_440EP   (0x000000000006D630ULL)
+#define POWERPC_MMU_440EP    (POWERPC_MMU_BOOKE)
+#define POWERPC_EXCP_440EP   (POWERPC_EXCP_BOOKE)
+#define POWERPC_INPUT_440EP  (PPC_FLAGS_INPUT_BookE)
+
+static void init_proc_440EP (CPUPPCState *env)
 {
-    if (table[idx] != &invalid_handler)
-        return -1;
-    table[idx] = handler;
-
-    return 0;
+    /* Time base */
+    gen_tbl(env);
+    gen_spr_BookE(env);
+    gen_spr_440(env);
+    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);
+    spr_register(env, SPR_440_CCR1, "CCR1",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* Memory management */
+    env->nb_tlb = 64;
+    env->nb_ways = 1;
+    env->id_tlbs = 0;
+    /* XXX: TODO: allocate internal IRQ controller */
 }
 
-static int register_direct_insn (opc_handler_t **ppc_opcodes,
-                                 unsigned char idx, opc_handler_t *handler)
+/* PowerPC 440 GP                                                            */
+#define POWERPC_INSNS_440GP  (POWERPC_INSNS_EMB |                             \
+                              PPC_CACHE_DCBA | PPC_MEM_TLBSYNC |              \
+                              PPC_BOOKE | PPC_BOOKE_EXT | PPC_4xx_COMMON |    \
+                              PPC_405_MAC | PPC_440_SPEC)
+#define POWERPC_MSRM_440GP   (0x000000000006FF30ULL)
+#define POWERPC_MMU_440GP    (POWERPC_MMU_BOOKE)
+#define POWERPC_EXCP_440GP   (POWERPC_EXCP_BOOKE)
+#define POWERPC_INPUT_440GP  (PPC_FLAGS_INPUT_BookE)
+
+static void init_proc_440GP (CPUPPCState *env)
 {
-    if (insert_in_table(ppc_opcodes, idx, handler) < 0) {
-        printf("*** ERROR: opcode %02x already assigned in main "
-               "opcode table\n", idx);
-        return -1;
-    }
-
-    return 0;
+    /* Time base */
+    gen_tbl(env);
+    gen_spr_BookE(env);
+    gen_spr_440(env);
+    /* Memory management */
+    env->nb_tlb = 64;
+    env->nb_ways = 1;
+    env->id_tlbs = 0;
+    /* XXX: TODO: allocate internal IRQ controller */
 }
 
-static int register_ind_in_table (opc_handler_t **table,
-                                  unsigned char idx1, unsigned char idx2,
-                                  opc_handler_t *handler)
+/* PowerPC 440x4                                                             */
+#if defined(TODO)
+#define POWERPC_INSNS_440x4  (POWERPC_INSNS_EMB |                             \
+                              PPC_CACHE_DCBA | PPC_MEM_TLBSYNC |              \
+                              PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |      \
+                              PPC_440_SPEC)
+#define POWERPC_MSRM_440x4   (0x000000000006FF30ULL)
+#define POWERPC_MMU_440x4    (POWERPC_MMU_BOOKE)
+#define POWERPC_EXCP_440x4   (POWERPC_EXCP_BOOKE)
+#define POWERPC_INPUT_440x4  (PPC_FLAGS_INPUT_BookE)
+
+static void init_proc_440x4 (CPUPPCState *env)
 {
-    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);
-            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);
-        return -1;
-    }
-
-    return 0;
+    /* Time base */
+    gen_tbl(env);
+    gen_spr_BookE(env);
+    gen_spr_440(env);
+    /* Memory management */
+    env->nb_tlb = 64;
+    env->nb_ways = 1;
+    env->id_tlbs = 0;
+    /* XXX: TODO: allocate internal IRQ controller */
 }
-
-static int register_ind_insn (opc_handler_t **ppc_opcodes,
-                              unsigned char idx1, unsigned char idx2,
-                              opc_handler_t *handler)
+#endif /* TODO */
+
+/* PowerPC 440x5                                                             */
+#define POWERPC_INSNS_440x5  (POWERPC_INSNS_EMB |                             \
+                              PPC_CACHE_DCBA | PPC_MEM_TLBSYNC |              \
+                              PPC_BOOKE | PPC_4xx_COMMON | PPC_405_MAC |      \
+                              PPC_440_SPEC | PPC_RFMCI)
+#define POWERPC_MSRM_440x5   (0x000000000006FF30ULL)
+#define POWERPC_MMU_440x5    (POWERPC_MMU_BOOKE)
+#define POWERPC_EXCP_440x5   (POWERPC_EXCP_BOOKE)
+#define POWERPC_INPUT_440x5  (PPC_FLAGS_INPUT_BookE)
+
+static void init_proc_440x5 (CPUPPCState *env)
 {
-    int ret;
-
-    ret = register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
-
-    return ret;
+    /* Time base */
+    gen_tbl(env);
+    gen_spr_BookE(env);
+    gen_spr_440(env);
+    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);
+    spr_register(env, SPR_440_CCR1, "CCR1",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* Memory management */
+    env->nb_tlb = 64;
+    env->nb_ways = 1;
+    env->id_tlbs = 0;
+    /* XXX: TODO: allocate internal IRQ controller */
 }
 
-static int register_dblind_insn (opc_handler_t **ppc_opcodes,
-                                 unsigned char idx1, unsigned char idx2,
-                                 unsigned char idx3, opc_handler_t *handler)
+/* PowerPC 460 (guessed)                                                     */
+#if defined(TODO)
+#define POWERPC_INSNS_460F   (POWERPC_INSNS_EMB |                             \
+                              PPC_CACHE_DCBA | PPC_MEM_TLBSYNC |              \
+                              PPC_BOOKE | PPC_BOOKE_EXT | PPC_4xx_COMMON |    \
+                              PPC_405_MAC | PPC_440_SPEC | PPC_DCRUX)
+#define POWERPC_MSRM_460     (0x000000000006FF30ULL)
+#define POWERPC_MMU_460      (POWERPC_MMU_BOOKE)
+#define POWERPC_EXCP_460     (POWERPC_EXCP_BOOKE)
+#define POWERPC_INPUT_460    (PPC_FLAGS_INPUT_BookE)
+
+static void init_proc_460 (CPUPPCState *env)
 {
-    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_insn (opc_handler_t **ppc_opcodes, opcode_t *insn)
+#endif /* TODO */
+
+/* PowerPC 460F (guessed)                                                    */
+#if defined(TODO)
+#define POWERPC_INSNS_460F   (POWERPC_INSNS_EMB |                             \
+                              PPC_CACHE_DCBA | PPC_MEM_TLBSYNC |              \
+                              PPC_FLOAT | PPC_FLOAT_FSQRT | PPC_FLOAT_FRES |  \
+                              PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |            \
+                              PPC_FLOAT_STFIWX |                              \
+                              PPC_BOOKE | PPC_BOOKE_EXT | PPC_4xx_COMMON |    \
+                              PPC_405_MAC | PPC_440_SPEC | PPC_DCRUX)
+#define POWERPC_MSRM_460     (0x000000000006FF30ULL)
+#define POWERPC_MMU_460F     (POWERPC_MMU_BOOKE)
+#define POWERPC_EXCP_460F    (POWERPC_EXCP_BOOKE)
+#define POWERPC_INPUT_460F   (PPC_FLAGS_INPUT_BookE)
+
+static void init_proc_460 (CPUPPCState *env)
 {
-    if (insn->opc2 != 0xFF) {
-        if (insn->opc3 != 0xFF) {
-            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;
+    /* Time base */
+    gen_tbl(env);
+    gen_spr_BookE(env);
+    gen_spr_440(env);
+    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);
+    spr_register(env, SPR_440_CCR1, "CCR1",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_DCRIPR, "SPR_DCRIPR",
+                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* Memory management */
+    env->nb_tlb = 64;
+    env->nb_ways = 1;
+    env->id_tlbs = 0;
+    /* XXX: TODO: allocate internal IRQ controller */
 }
-
-static int test_opcode_table (opc_handler_t **table, int len)
+#endif /* TODO */
+
+/* Generic BookE PowerPC                                                     */
+#if defined(TODO)
+#define POWERPC_INSNS_BookE  (POWERPC_INSNS_EMB |                             \
+                              PPC_MEM_EIEIO | PPC_MEM_TLBSYNC |               \
+                              PPC_CACHE_DCBA |                                \
+                              PPC_FLOAT | PPC_FLOAT_FSQRT |                   \
+                              PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE |            \
+                              PPC_FLOAT_FSEL | PPC_FLOAT_STFIW |              \
+                              PPC_BOOKE)
+#define POWERPC_MSRM_BookE   (0x000000000006D630ULL)
+#define POWERPC_MMU_BookE    (POWERPC_MMU_BOOKE)
+#define POWERPC_EXCP_BookE   (POWERPC_EXCP_BOOKE)
+#define POWERPC_INPUT_BookE  (PPC_FLAGS_INPUT_BookE)
+
+static void init_proc_BookE (CPUPPCState *env)
 {
-    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]), 0x20);
-                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)
+#endif /* TODO */
+
+/* e200 core                                                                 */
+#if defined(TODO)
+#endif /* TODO */
+
+/* e300 core                                                                 */
+#if defined(TODO)
+#endif /* TODO */
+
+/* e500 core                                                                 */
+#if defined(TODO)
+#define POWERPC_INSNS_e500   (POWERPC_INSNS_EMB |                             \
+                              PPC_MEM_EIEIO | PPC_MEM_TLBSYNC |               \
+                              PPC_CACHE_DCBA |                                \
+                              PPC_BOOKE | PPC_E500_VECTOR)
+#define POWERPC_MMU_e500     (POWERPC_MMU_SOFT_4xx)
+#define POWERPC_EXCP_e500    (POWERPC_EXCP_40x)
+#define POWERPC_INPUT_e500   (PPC_FLAGS_INPUT_BookE)
+
+static void init_proc_e500 (CPUPPCState *env)
 {
-    if (test_opcode_table(ppc_opcodes, 0x40) == 0)
-        printf("*** WARNING: no opcode defined !\n");
+    /* Time base */
+    gen_tbl(env);
+    gen_spr_BookE(env);
+    /* Memory management */
+    gen_spr_BookE_FSL(env);
+    env->nb_tlb = 64;
+    env->nb_ways = 1;
+    env->id_tlbs = 0;
+    /* XXX: TODO: allocate internal IRQ controller */
 }
-
-/*****************************************************************************/
-static int create_ppc_opcodes (CPUPPCState *env, ppc_def_t *def)
+#endif /* TODO */
+
+/* e600 core                                                                 */
+#if defined(TODO)
+#endif /* TODO */
+
+/* Non-embedded PowerPC                                                      */
+/* Base instructions set for all 6xx/7xx/74xx/970 PowerPC                    */
+#define POWERPC_INSNS_6xx    (PPC_INSNS_BASE | PPC_FLOAT | PPC_MEM_SYNC |     \
+                              PPC_MEM_EIEIO | PPC_SEGMENT | PPC_MEM_TLBIE)
+/* Instructions common to all 6xx/7xx/74xx/970 PowerPC except 601 & 602      */
+#define POWERPC_INSNS_WORKS  (POWERPC_INSNS_6xx | PPC_FLOAT_FSQRT |           \
+                              PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE |            \
+                              PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX |             \
+                              PPC_MEM_TLBSYNC | PPC_MFTB)
+
+/* POWER : same as 601, without mfmsr, mfsr                                  */
+#if defined(TODO)
+#define POWERPC_INSNS_POWER  (XXX_TODO)
+/* POWER RSC (from RAD6000) */
+#define POWERPC_MSRM_POWER   (0x00000000FEF0ULL)
+#endif /* TODO */
+
+/* PowerPC 601                                                               */
+#define POWERPC_INSNS_601    (POWERPC_INSNS_6xx | PPC_EXTERN | PPC_POWER_BR)
+#define POWERPC_MSRM_601     (0x000000000000FE70ULL)
+//#define POWERPC_MMU_601      (POWERPC_MMU_601)
+//#define POWERPC_EXCP_601     (POWERPC_EXCP_601)
+#define POWERPC_INPUT_601    (PPC_FLAGS_INPUT_6xx)
+
+static void init_proc_601 (CPUPPCState *env)
 {
-    opcode_t *opc, *start, *end;
-
-    fill_new_table(env->opcodes, 0x40);
-#if defined(PPC_DUMP_CPU)
-    printf("* PowerPC instructions for PVR %08x: %s flags %016" PRIx64
-           " %08x\n",
-           def->pvr, def->name, def->insns_flags, def->flags);
-#endif
-    if (&opc_start < &opc_end) {
-        start = &opc_start;
-        end = &opc_end;
-    } else {
-        start = &opc_end;
-        end = &opc_start;
-    }
-    for (opc = start + 1; opc != end; opc++) {
-        if ((opc->handler.type & def->insns_flags) != 0) {
-            if (register_insn(env->opcodes, opc) < 0) {
-                printf("*** ERROR initializing PowerPC instruction "
-                       "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2,
-                       opc->opc3);
-                return -1;
-            }
-#if defined(PPC_DUMP_CPU)
-            if (opc1 != 0x00) {
-                if (opc->opc3 == 0xFF) {
-                    if (opc->opc2 == 0xFF) {
-                        printf("INSN: %02x -- -- (%02d ----) : %s\n",
-                               opc->opc1, opc->opc1, opc->oname);
-                    } else {
-                        printf("INSN: %02x %02x -- (%02d %04d) : %s\n",
-                               opc->opc1, opc->opc2, opc->opc1, opc->opc2,
-                               opc->oname);
-                    }
-                } else {
-                    printf("INSN: %02x %02x %02x (%02d %04d) : %s\n",
-                           opc->opc1, opc->opc2, opc->opc3,
-                           opc->opc1, (opc->opc3 << 5) | opc->opc2,
-                           opc->oname);
-                }
-            }
-#endif
-        }
-    }
-    fix_opcode_tables(env->opcodes);
-    fflush(stdout);
-    fflush(stderr);
-
-    return 0;
+    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_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_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);
+    /* XXX : not implemented */
+    spr_register(env, SPR_601_HID15, "HID15",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* Memory management */
+    env->nb_tlb = 64;
+    env->nb_ways = 2;
+    env->id_tlbs = 0;
+    env->id_tlbs = 0;
+    /* XXX: TODO: allocate internal IRQ controller */
 }
 
-int cpu_ppc_register (CPUPPCState *env, ppc_def_t *def)
+/* PowerPC 602                                                               */
+#define POWERPC_INSNS_602    (POWERPC_INSNS_6xx | PPC_MFTB |                  \
+                              PPC_FLOAT_FRES | PPC_FLOAT_FRSQRTE |            \
+                              PPC_FLOAT_FSEL | PPC_FLOAT_STFIWX |             \
+                              PPC_6xx_TLB | PPC_MEM_TLBSYNC | PPC_602_SPEC)
+#define POWERPC_MSRM_602     (0x000000000033FF73ULL)
+#define POWERPC_MMU_602      (POWERPC_MMU_SOFT_6xx)
+//#define POWERPC_EXCP_602     (POWERPC_EXCP_602)
+#define POWERPC_INPUT_602    (PPC_FLAGS_INPUT_6xx)
+
+static void init_proc_602 (CPUPPCState *env)
 {
-    env->msr_mask = def->msr_mask;
-    env->flags = def->flags;
-    if (create_ppc_opcodes(env, def) < 0)
-        return -1;
-    init_ppc_proc(env, def);
-#if defined(PPC_DUMP_CPU)
-    dump_sprs(env);
-    if (env->tlb != NULL) {
-        printf("%d %s TLB in %d ways\n", env->nb_tlb,
-               env->id_tlbs ? "splitted" : "merged", env->nb_ways);
-    }
-#endif
+    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);
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
+}
 
-    return 0;
+/* PowerPC 603                                                               */
+#define POWERPC_INSNS_603    (POWERPC_INSNS_WORKS | PPC_6xx_TLB | PPC_EXTERN)
+#define POWERPC_MSRM_603     (0x000000000001FF73ULL)
+#define POWERPC_MMU_603      (POWERPC_MMU_SOFT_6xx)
+//#define POWERPC_EXCP_603     (POWERPC_EXCP_603)
+#define POWERPC_INPUT_603    (PPC_FLAGS_INPUT_6xx)
+
+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);
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
 }
 
+/* PowerPC 603e                                                              */
+#define POWERPC_INSNS_603E   (POWERPC_INSNS_WORKS | PPC_6xx_TLB | PPC_EXTERN)
+#define POWERPC_MSRM_603E    (0x000000000007FF73ULL)
+#define POWERPC_MMU_603E     (POWERPC_MMU_SOFT_6xx)
+//#define POWERPC_EXCP_603E    (POWERPC_EXCP_603E)
+#define POWERPC_INPUT_603E   (PPC_FLAGS_INPUT_6xx)
+
+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);
+    /* XXX : not implemented */
+    spr_register(env, SPR_IABR, "IABR",
+                 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);
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
+}
+
+/* PowerPC G2                                                                */
+#define POWERPC_INSNS_G2     (POWERPC_INSNS_WORKS | PPC_6xx_TLB | PPC_EXTERN)
+#define POWERPC_MSRM_G2      (0x000000000006FFF2ULL)
+#define POWERPC_MMU_G2       (POWERPC_MMU_SOFT_6xx)
+//#define POWERPC_EXCP_G2      (POWERPC_EXCP_G2)
+#define POWERPC_INPUT_G2     (PPC_FLAGS_INPUT_6xx)
+
+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);
+    /* 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);
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
+}
+
+/* PowerPC G2LE                                                              */
+#define POWERPC_INSNS_G2LE   (POWERPC_INSNS_WORKS | PPC_6xx_TLB | PPC_EXTERN)
+#define POWERPC_MSRM_G2LE    (0x000000000007FFF3ULL)
+#define POWERPC_MMU_G2LE     (POWERPC_MMU_SOFT_6xx)
+#define POWERPC_EXCP_G2LE    (POWERPC_EXCP_G2)
+#define POWERPC_INPUT_G2LE   (PPC_FLAGS_INPUT_6xx)
+
+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);
+    /* 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);
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
+}
+
+/* PowerPC 604                                                               */
+#define POWERPC_INSNS_604    (POWERPC_INSNS_WORKS | PPC_EXTERN)
+#define POWERPC_MSRM_604     (0x000000000005FF77ULL)
+#define POWERPC_MMU_604      (POWERPC_MMU_32B)
+//#define POWERPC_EXCP_604     (POWERPC_EXCP_604)
+#define POWERPC_INPUT_604    (PPC_FLAGS_INPUT_6xx)
+
+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);
+    /* 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);
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
+}
+
+/* PowerPC 740/750 (aka G3)                                                  */
+#define POWERPC_INSNS_7x0    (POWERPC_INSNS_WORKS | PPC_EXTERN)
+#define POWERPC_MSRM_7x0     (0x000000000007FF77ULL)
+#define POWERPC_MMU_7x0      (POWERPC_MMU_32B)
+//#define POWERPC_EXCP_7x0     (POWERPC_EXCP_7x0)
+#define POWERPC_INPUT_7x0    (PPC_FLAGS_INPUT_6xx)
+
+static void init_proc_7x0 (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);
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
+}
+
+/* PowerPC 750FX/GX                                                          */
+#define POWERPC_INSNS_750fx  (POWERPC_INSNS_WORKS | PPC_EXTERN)
+#define POWERPC_MSRM_750fx   (0x000000000007FF77ULL)
+#define POWERPC_MMU_750fx    (POWERPC_MMU_32B)
+#define POWERPC_EXCP_750fx   (POWERPC_EXCP_7x0)
+#define POWERPC_INPUT_750fx  (PPC_FLAGS_INPUT_6xx)
+
+static void init_proc_750fx (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);
+    /* XXX : not implemented */
+    spr_register(env, SPR_750_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);
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
+}
+
+/* PowerPC 745/755                                                           */
+#define POWERPC_INSNS_7x5    (POWERPC_INSNS_WORKS | PPC_EXTERN | PPC_6xx_TLB)
+#define POWERPC_MSRM_7x5     (0x000000000007FF77ULL)
+#define POWERPC_MMU_7x5      (POWERPC_MMU_SOFT_6xx)
+//#define POWERPC_EXCP_7x5     (POWERPC_EXCP_7x5)
+#define POWERPC_INPUT_7x5    (PPC_FLAGS_INPUT_6xx)
+
+static void init_proc_7x5 (CPUPPCState *env)
+{
+    gen_spr_ne_601(env);
+    gen_spr_G2_755(env);
+    /* Time base */
+    gen_tbl(env);
+    /* L2 cache control */
+    /* XXX : not implemented */
+    spr_register(env, SPR_ICTC, "ICTC",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* XXX : not implemented */
+    spr_register(env, SPR_L2PMCR, "L2PMCR",
+                 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_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);
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
+}
+
+/* PowerPC 7400 (aka G4)                                                     */
+#define POWERPC_INSNS_7400   (POWERPC_INSNS_WORKS | PPC_CACHE_DCBA |          \
+                              PPC_EXTERN | PPC_MEM_TLBIA |                    \
+                              PPC_ALTIVEC)
+#define POWERPC_MSRM_7400    (0x000000000205FF77ULL)
+#define POWERPC_MMU_7400     (POWERPC_MMU_32B)
+#define POWERPC_EXCP_7400    (POWERPC_EXCP_74xx)
+#define POWERPC_INPUT_7400   (PPC_FLAGS_INPUT_6xx)
+
+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);
+    /* Thermal management */
+    gen_spr_thrm(env);
+    /* Memory management */
+    gen_low_BATs(env);
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
+}
+
+/* PowerPC 7410 (aka G4)                                                     */
+#define POWERPC_INSNS_7410   (POWERPC_INSNS_WORKS | PPC_CACHE_DCBA |          \
+                              PPC_EXTERN | PPC_MEM_TLBIA |                    \
+                              PPC_ALTIVEC)
+#define POWERPC_MSRM_7410    (0x000000000205FF77ULL)
+#define POWERPC_MMU_7410     (POWERPC_MMU_32B)
+#define POWERPC_EXCP_7410    (POWERPC_EXCP_74xx)
+#define POWERPC_INPUT_7410   (PPC_FLAGS_INPUT_6xx)
+
+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);
+    /* 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);
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
+}
+
+/* PowerPC 7440 (aka G4)                                                     */
+#if defined (TODO)
+#define POWERPC_INSNS_7440   (POWERPC_INSNS_WORKS | PPC_CACHE_DCBA |          \
+                              PPC_EXTERN | PPC_74xx_TLB | PPC_MEM_TLBIA |     \
+                              PPC_ALTIVEC)
+#define POWERPC_MSRM_7440    (0x000000000205FF77ULL)
+#define POWERPC_MMU_7440     (POWERPC_MMU_SOFT_74xx)
+#define POWERPC_EXCP_7440    (POWERPC_EXCP_74xx)
+#define POWERPC_INPUT_7440   (PPC_FLAGS_INPUT_6xx)
+
+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);
+    /* 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 */
+    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_PMC5, "PMC5",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_UPMC5, "UPMC5",
+                 &spr_read_ureg, SPR_NOACCESS,
+                 &spr_read_ureg, SPR_NOACCESS,
+                 0x00000000);
+    spr_register(env, SPR_PMC6, "PMC6",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_UPMC6, "UPMC6",
+                 &spr_read_ureg, SPR_NOACCESS,
+                 &spr_read_ureg, SPR_NOACCESS,
+                 0x00000000);
+    /* Memory management */
+    gen_low_BATs(env);
+    gen_74xx_soft_tlb(env);
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
+}
+#endif /* TODO */
+
+/* PowerPC 7450 (aka G4)                                                     */
+#if defined (TODO)
+#define POWERPC_INSNS_7450   (POWERPC_INSNS_WORKS | PPC_CACHE_DCBA |          \
+                              PPC_EXTERN | PPC_74xx_TLB | PPC_MEM_TLBIA |     \
+                              PPC_ALTIVEC)
+#define POWERPC_MSRM_7450    (0x000000000205FF77ULL)
+#define POWERPC_MMU_7450     (POWERPC_MMU_SOFT_74xx)
+#define POWERPC_EXCP_7450    (POWERPC_EXCP_74xx)
+#define POWERPC_INPUT_7450   (PPC_FLAGS_INPUT_6xx)
+
+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);
+    /* 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 */
+    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_PMC5, "PMC5",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_UPMC5, "UPMC5",
+                 &spr_read_ureg, SPR_NOACCESS,
+                 &spr_read_ureg, SPR_NOACCESS,
+                 0x00000000);
+    spr_register(env, SPR_PMC6, "PMC6",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_UPMC6, "UPMC6",
+                 &spr_read_ureg, SPR_NOACCESS,
+                 &spr_read_ureg, SPR_NOACCESS,
+                 0x00000000);
+    /* Memory management */
+    gen_low_BATs(env);
+    gen_74xx_soft_tlb(env);
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
+}
+#endif /* TODO */
+
+/* PowerPC 7445 (aka G4)                                                     */
+#if defined (TODO)
+#define POWERPC_INSNS_7445   (POWERPC_INSNS_WORKS | PPC_CACHE_DCBA |          \
+                              PPC_EXTERN | PPC_74xx_TLB | PPC_MEM_TLBIA |     \
+                              PPC_ALTIVEC)
+#define POWERPC_MSRM_7445    (0x000000000205FF77ULL)
+#define POWERPC_MMU_7445     (POWERPC_MMU_SOFT_74xx)
+#define POWERPC_EXCP_7445    (POWERPC_EXCP_74xx)
+#define POWERPC_INPUT_7445   (PPC_FLAGS_INPUT_6xx)
+
+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 */
+    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_PMC5, "PMC5",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_UPMC5, "UPMC5",
+                 &spr_read_ureg, SPR_NOACCESS,
+                 &spr_read_ureg, SPR_NOACCESS,
+                 0x00000000);
+    spr_register(env, SPR_PMC6, "PMC6",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_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);
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
+}
+#endif /* TODO */
+
+/* PowerPC 7455 (aka G4)                                                     */
+#if defined (TODO)
+#define POWERPC_INSNS_7455   (POWERPC_INSNS_WORKS | PPC_CACHE_DCBA |          \
+                              PPC_EXTERN | PPC_74xx_TLB | PPC_MEM_TLBIA |     \
+                              PPC_ALTIVEC)
+#define POWERPC_MSRM_7455    (0x000000000205FF77ULL)
+#define POWERPC_MMU_7455     (POWERPC_MMU_SOFT_74xx)
+#define POWERPC_EXCP_7455    (POWERPC_EXCP_74xx)
+#define POWERPC_INPUT_7455   (PPC_FLAGS_INPUT_6xx)
+
+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 */
+    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_PMC5, "PMC5",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_UPMC5, "UPMC5",
+                 &spr_read_ureg, SPR_NOACCESS,
+                 &spr_read_ureg, SPR_NOACCESS,
+                 0x00000000);
+    spr_register(env, SPR_PMC6, "PMC6",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_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);
+    /* Allocate hardware IRQ controller */
+    ppc6xx_irq_init(env);
+}
+#endif /* TODO */
+
+#if defined (TARGET_PPC64)
+/* PowerPC 970                                                               */
+#if defined (TODO)
+#define POWERPC_INSNS_970    (POWERPC_INSNS_WORKS | PPC_FLOAT_FSQRT |         \
+                              PPC_64B | PPC_ALTIVEC |                         \
+                              PPC_64_BRIDGE | PPC_SLBI)
+#define POWERPC_MSRM_970     (0x900000000204FF36ULL)
+#define POWERPC_MMU_970      (POWERPC_MMU_64BRIDGE)
+//#define POWERPC_EXCP_970     (POWERPC_EXCP_970)
+#define POWERPC_INPUT_970    (PPC_FLAGS_INPUT_970)
+
+static void init_proc_970 (CPUPPCState *env)
+{
+    gen_spr_ne_601(env);
+    gen_spr_7xx(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_750_HID2, "HID2",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* Memory management */
+    /* XXX: not correct */
+    gen_low_BATs(env);
+#if 0 // TODO
+    env->slb_nr = 32;
+#endif
+    /* Allocate hardware IRQ controller */
+    ppc970_irq_init(env);
+}
+#endif /* TODO */
+
+/* PowerPC 970FX (aka G5)                                                    */
+#if defined (TODO)
+#define POWERPC_INSNS_970FX  (POWERPC_INSNS_WORKS | PPC_FLOAT_FSQRT |         \
+                              PPC_64B | PPC_ALTIVEC |                         \
+                              PPC_64_BRIDGE | PPC_SLBI)
+#define POWERPC_MSRM_970FX   (0x800000000204FF36ULL)
+#define POWERPC_MMU_970FX    (POWERPC_MMU_64BRIDGE)
+#define POWERPC_EXCP_970FX   (POWERPC_EXCP_970)
+#define POWERPC_INPUT_970FX  (PPC_FLAGS_INPUT_970)
+
+static void init_proc_970FX (CPUPPCState *env)
+{
+    gen_spr_ne_601(env);
+    gen_spr_7xx(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_750_HID2, "HID2",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* Memory management */
+    /* XXX: not correct */
+    gen_low_BATs(env);
+#if 0 // TODO
+    env->slb_nr = 32;
+#endif
+    /* Allocate hardware IRQ controller */
+    ppc970_irq_init(env);
+}
+#endif /* TODO */
+
+/* PowerPC 970 GX                                                            */
+#if defined (TODO)
+#define POWERPC_INSNS_970GX  (POWERPC_INSNS_WORKS | PPC_FLOAT_FSQRT |         \
+                              PPC_64B | PPC_ALTIVEC |                         \
+                              PPC_64_BRIDGE | PPC_SLBI)
+#define POWERPC_MSRM_970GX   (0x800000000204FF36ULL)
+#define POWERPC_MMU_970GX    (POWERPC_MMU_64BRIDGE)
+#define POWERPC_EXCP_970GX   (POWERPC_EXCP_970)
+#define POWERPC_INPUT_970GX  (PPC_FLAGS_INPUT_970)
+
+static void init_proc_970GX (CPUPPCState *env)
+{
+    gen_spr_ne_601(env);
+    gen_spr_7xx(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_750_HID2, "HID2",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* Memory management */
+    /* XXX: not correct */
+    gen_low_BATs(env);
+#if 0 // TODO
+    env->slb_nr = 32;
+#endif
+    /* Allocate hardware IRQ controller */
+    ppc970_irq_init(env);
+}
+#endif /* TODO */
+
+/* PowerPC 620                                                               */
+#if defined (TODO)
+#define POWERPC_INSNS_620    (POWERPC_INSNS_WORKS | PPC_FLOAT_FSQRT |         \
+                              PPC_64B | PPC_SLBI)
+#define POWERPC_MSRM_620     (0x800000000005FF73ULL)
+#define POWERPC_MMU_620      (POWERPC_MMU_64B)
+#define POWERPC_EXCP_620     (POWERPC_EXCP_970)
+#define POWERPC_INPUT_620    (PPC_FLAGS_INPUT_970)
+
+static void init_proc_620 (CPUPPCState *env)
+{
+    gen_spr_ne_601(env);
+    gen_spr_620(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);
+    gen_high_BATs(env);
+    /* XXX: TODO: initialize internal interrupt controller */
+}
+#endif /* TODO */
+#endif /* defined (TARGET_PPC64) */
+
+/* Default 32 bits PowerPC target will be 604 */
+#define CPU_POWERPC_PPC32     CPU_POWERPC_604
+#define POWERPC_INSNS_PPC32   POWERPC_INSNS_604
+#define POWERPC_MSRM_PPC32    POWERPC_MSRM_604
+#define POWERPC_MMU_PPC32     POWERPC_MMU_604
+#define POWERPC_EXCP_PPC32    POWERPC_EXCP_604
+#define POWERPC_INPUT_PPC32   POWERPC_INPUT_604
+#define init_proc_PPC32       init_proc_604
+
+/* Default 64 bits PowerPC target will be 970 FX */
+#define CPU_POWERPC_PPC64     CPU_POWERPC_970FX
+#define POWERPC_INSNS_PPC64   POWERPC_INSNS_970FX
+#define POWERPC_MSRM_PPC64    POWERPC_MSRM_970FX
+#define POWERPC_MMU_PPC64     POWERPC_MMU_970FX
+#define POWERPC_EXCP_PPC64    POWERPC_EXCP_970FX
+#define POWERPC_INPUT_PPC64   POWERPC_INPUT_970FX
+#define init_proc_PPC64       init_proc_970FX
+
+/* Default PowerPC target will be PowerPC 32 */
+#if defined (TARGET_PPC64) && 0 // XXX: TODO
+#define CPU_POWERPC_PPC       CPU_POWERPC_PPC64
+#define POWERPC_INSNS_PPC     POWERPC_INSNS_PPC64
+#define POWERPC_MSRM_PPC      POWERPC_MSRM_PPC64
+#define POWERPC_MMU_PPC       POWERPC_MMU_PPC64
+#define POWERPC_EXCP_PPC      POWERPC_EXCP_PPC64
+#define POWERPC_INPUT_PPC     POWERPC_INPUT_PPC64
+#define init_proc_PPC         init_proc_PPC64
+#else
+#define CPU_POWERPC_PPC       CPU_POWERPC_PPC32
+#define POWERPC_INSNS_PPC     POWERPC_INSNS_PPC32
+#define POWERPC_MSRM_PPC      POWERPC_MSRM_PPC32
+#define POWERPC_MMU_PPC       POWERPC_MMU_PPC32
+#define POWERPC_EXCP_PPC      POWERPC_EXCP_PPC32
+#define POWERPC_INPUT_PPC     POWERPC_INPUT_PPC32
+#define init_proc_PPC         init_proc_PPC32
+#endif
+
+/*****************************************************************************/
+/* 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 */
+    /* Generic PowerPC 403 */
+#define CPU_POWERPC_403       CPU_POWERPC_403GC
+    /* 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 */
+    /* Generic PowerPC 405 */
+#define CPU_POWERPC_405       CPU_POWERPC_405D4
+    /* 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 */
+#define CPU_POWERPC_405CR     CPU_POWERPC_405CRc
+    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
+#define CPU_POWERPC_405GP     CPU_POWERPC_405GPd
+    CPU_POWERPC_405GPa      = 0x40110000,
+    CPU_POWERPC_405GPb      = 0x40110040,
+    CPU_POWERPC_405GPc      = 0x40110082,
+    CPU_POWERPC_405GPd      = 0x401100C4,
+#define CPU_POWERPC_405GPe    CPU_POWERPC_405CRc
+    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,
+#define CPU_POWERPC_X2VP7     CPU_POWERPC_X2VP4
+    CPU_POWERPC_X2VP20      = 0x20010860,
+#define CPU_POWERPC_X2VP50    CPU_POWERPC_X2VP20
+#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
+#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 */
+#define CPU_POWERPC_440EP     CPU_POWERPC_440EPb
+    CPU_POWERPC_440EPa      = 0x42221850,
+    CPU_POWERPC_440EPb      = 0x422218D3,
+#define CPU_POWERPC_440GP     CPU_POWERPC_440GPc
+    CPU_POWERPC_440GPb      = 0x40120440,
+    CPU_POWERPC_440GPc      = 0x40120481,
+#define CPU_POWERPC_440GR     CPU_POWERPC_440GRa
+#define CPU_POWERPC_440GRa    CPU_POWERPC_440EPb
+    CPU_POWERPC_440GRX      = 0x200008D0,
+#define CPU_POWERPC_440EPX    CPU_POWERPC_440GRX
+#define CPU_POWERPC_440GX     CPU_POWERPC_440GXf
+    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 */
+    /* e200 family */
+#define CPU_POWERPC_e200      CPU_POWERPC_e200z6
+#if 0
+    CPU_POWERPC_e200z0      = xxx,
+#endif
+#if 0
+    CPU_POWERPC_e200z3      = xxx,
+#endif
+    CPU_POWERPC_e200z5      = 0x81000000,
+    CPU_POWERPC_e200z6      = 0x81120000,
+    /* e300 family */
+#define CPU_POWERPC_e300      CPU_POWERPC_e300c3
+    CPU_POWERPC_e300c1      = 0x00830000,
+    CPU_POWERPC_e300c2      = 0x00840000,
+    CPU_POWERPC_e300c3      = 0x00850000,
+    /* e500 family */
+#define CPU_POWERPC_e500      CPU_POWERPC_e500_v22
+    CPU_POWERPC_e500_v11    = 0x80200010,
+    CPU_POWERPC_e500_v12    = 0x80200020,
+    CPU_POWERPC_e500_v21    = 0x80210010,
+    CPU_POWERPC_e500_v22    = 0x80210020,
+#if 0
+    CPU_POWERPC_e500mc      = xxx,
+#endif
+    /* e600 family */
+    CPU_POWERPC_e600        = 0x80040010,
+    /* PowerPC MPC 5xx cores */
+    CPU_POWERPC_5xx         = 0x00020020,
+    /* PowerPC MPC 8xx cores (aka PowerQUICC) */
+    CPU_POWERPC_8xx         = 0x00500000,
+    /* PowerPC MPC 8xxx cores (aka PowerQUICC-II) */
+    CPU_POWERPC_82xx_HIP3   = 0x00810101,
+    CPU_POWERPC_82xx_HIP4   = 0x80811014,
+    CPU_POWERPC_827x        = 0x80822013,
+    /* PowerPC 6xx cores */
+    CPU_POWERPC_601         = 0x00010001,
+    CPU_POWERPC_601a        = 0x00010002,
+    CPU_POWERPC_602         = 0x00050100,
+    CPU_POWERPC_603         = 0x00030100,
+#define CPU_POWERPC_603E      CPU_POWERPC_603E_v41
+    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,
+#define CPU_POWERPC_603R      CPU_POWERPC_603E7t
+    CPU_POWERPC_G2          = 0x00810011,
+#if 0 // Linux pretends the MSB is zero...
+    CPU_POWERPC_G2H4        = 0x80811010,
+    CPU_POWERPC_G2gp        = 0x80821010,
+    CPU_POWERPC_G2ls        = 0x90810010,
+    CPU_POWERPC_G2LE        = 0x80820010,
+    CPU_POWERPC_G2LEgp      = 0x80822010,
+    CPU_POWERPC_G2LEls      = 0xA0822010,
+#else
+    CPU_POWERPC_G2H4        = 0x00811010,
+    CPU_POWERPC_G2gp        = 0x00821010,
+    CPU_POWERPC_G2ls        = 0x10810010,
+    CPU_POWERPC_G2LE        = 0x00820010,
+    CPU_POWERPC_G2LEgp      = 0x00822010,
+    CPU_POWERPC_G2LEls      = 0x20822010,
+#endif
+    CPU_POWERPC_604         = 0x00040103,
+#define CPU_POWERPC_604E      CPU_POWERPC_604E_v24
+    CPU_POWERPC_604E_v10    = 0x00090100, /* Also 2110 & 2120 */
+    CPU_POWERPC_604E_v22    = 0x00090202,
+    CPU_POWERPC_604E_v24    = 0x00090204,
+    CPU_POWERPC_604R        = 0x000a0101, /* Also 0x00093102 */
+#if 0
+    CPU_POWERPC_604EV       = xxx,
+#endif
+    /* PowerPC 740/750 cores (aka G3) */
+    /* XXX: missing 0x00084202 */
+#define CPU_POWERPC_7x0       CPU_POWERPC_7x0_v31
+    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_7x0P        = 0x10080000,
+    /* XXX: missing 0x00087010 (CL ?) */
+    CPU_POWERPC_750CL       = 0x00087200,
+#define CPU_POWERPC_750CX     CPU_POWERPC_750CX_v22
+    CPU_POWERPC_750CX_v21   = 0x00082201,
+    CPU_POWERPC_750CX_v22   = 0x00082202,
+#define CPU_POWERPC_750CXE    CPU_POWERPC_750CXE_v31b
+    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_v31  = 0x00083211,
+    CPU_POWERPC_750CXE_v31b = 0x00083311,
+    CPU_POWERPC_750CXR      = 0x00083410,
+    CPU_POWERPC_750E        = 0x00080200,
+    CPU_POWERPC_750FL       = 0x700A0203,
+#define CPU_POWERPC_750FX     CPU_POWERPC_750FX_v23
+    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,
+#define CPU_POWERPC_750GX     CPU_POWERPC_750GX_v12
+    CPU_POWERPC_750GX_v10   = 0x70020100,
+    CPU_POWERPC_750GX_v11   = 0x70020101,
+    CPU_POWERPC_750GX_v12   = 0x70020102,
+#define CPU_POWERPC_750L      CPU_POWERPC_750L_v32 /* Aka LoneStar */
+    CPU_POWERPC_750L_v22    = 0x00088202,
+    CPU_POWERPC_750L_v30    = 0x00088300,
+    CPU_POWERPC_750L_v32    = 0x00088302,
+    /* PowerPC 745/755 cores */
+#define CPU_POWERPC_7x5       CPU_POWERPC_7x5_v28
+    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 */
+#define CPU_POWERPC_7400      CPU_POWERPC_7400_v29
+    CPU_POWERPC_7400_v10    = 0x000C0100,
+    CPU_POWERPC_7400_v11    = 0x000C0101,
+    CPU_POWERPC_7400_v20    = 0x000C0200,
+    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,
+#define CPU_POWERPC_7410      CPU_POWERPC_7410_v14
+    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 */
+#define CPU_POWERPC_7448      CPU_POWERPC_7448_v21
+    CPU_POWERPC_7448_v10    = 0x80040100,
+    CPU_POWERPC_7448_v11    = 0x80040101,
+    CPU_POWERPC_7448_v20    = 0x80040200,
+    CPU_POWERPC_7448_v21    = 0x80040201,
+#define CPU_POWERPC_7450      CPU_POWERPC_7450_v21
+    CPU_POWERPC_7450_v10    = 0x80000100,
+    CPU_POWERPC_7450_v11    = 0x80000101,
+    CPU_POWERPC_7450_v12    = 0x80000102,
+    CPU_POWERPC_7450_v20    = 0x80000200, /* aka D: 2.04 */
+    CPU_POWERPC_7450_v21    = 0x80000201, /* aka E */
+    CPU_POWERPC_74x1        = 0x80000203,
+    CPU_POWERPC_74x1G       = 0x80000210, /* aka G: 2.3 */
+    /* XXX: missing 0x80010200 */
+#define CPU_POWERPC_74x5      CPU_POWERPC_74x5_v32
+    CPU_POWERPC_74x5_v10    = 0x80010100,
+    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 */
+#define CPU_POWERPC_74x7      CPU_POWERPC_74x7_v12
+    CPU_POWERPC_74x7_v10    = 0x80020100, /* aka A: 1.0 */
+    CPU_POWERPC_74x7_v11    = 0x80030101, /* aka B: 1.1 */
+    CPU_POWERPC_74x7_v12    = 0x80020102, /* aka C: 1.2 */
+    /* 64 bits PowerPC */
+    CPU_POWERPC_620         = 0x00140000,
+    CPU_POWERPC_630         = 0x00400000,
+    CPU_POWERPC_631         = 0x00410104,
+    CPU_POWERPC_POWER4      = 0x00350000,
+    CPU_POWERPC_POWER4P     = 0x00380000,
+    CPU_POWERPC_POWER5      = 0x003A0203,
+#define CPU_POWERPC_POWER5GR  CPU_POWERPC_POWER5
+    CPU_POWERPC_POWER5P     = 0x003B0000,
+#define CPU_POWERPC_POWER5GS  CPU_POWERPC_POWER5P
+    CPU_POWERPC_POWER6      = 0x003E0000,
+    CPU_POWERPC_POWER6_5    = 0x0F000001, /* POWER6 running POWER5 mode */
+    CPU_POWERPC_POWER6A     = 0x0F000002,
+    CPU_POWERPC_970         = 0x00390202,
+#define CPU_POWERPC_970FX     CPU_POWERPC_970FX_v31
+    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_970GX       = 0x00450000,
+#define CPU_POWERPC_970MP     CPU_POWERPC_970MP_v11
+    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,
+    /* 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,
+};
+
+/* System version register (used on MPC 8xxx)                                */
+enum {
+    PPC_SVR_8540      = 0x80300000,
+    PPC_SVR_8541E     = 0x807A0010,
+    PPC_SVR_8543v10   = 0x80320010,
+    PPC_SVR_8543v11   = 0x80320011,
+    PPC_SVR_8543v20   = 0x80320020,
+    PPC_SVR_8543Ev10  = 0x803A0010,
+    PPC_SVR_8543Ev11  = 0x803A0011,
+    PPC_SVR_8543Ev20  = 0x803A0020,
+    PPC_SVR_8545      = 0x80310220,
+    PPC_SVR_8545E     = 0x80390220,
+    PPC_SVR_8547E     = 0x80390120,
+    PPC_SCR_8548v10   = 0x80310010,
+    PPC_SCR_8548v11   = 0x80310011,
+    PPC_SCR_8548v20   = 0x80310020,
+    PPC_SVR_8548Ev10  = 0x80390010,
+    PPC_SVR_8548Ev11  = 0x80390011,
+    PPC_SVR_8548Ev20  = 0x80390020,
+    PPC_SVR_8555E     = 0x80790010,
+    PPC_SVR_8560v10   = 0x80700010,
+    PPC_SVR_8560v20   = 0x80700020,
+};
+
 /*****************************************************************************/
-/* PowerPC CPU definitions */
+/* PowerPC CPU definitions                                                   */
+#define POWERPC_DEF(_name, _pvr, _pvr_mask, _type)                            \
+    {                                                                         \
+        .name        = _name,                                                 \
+        .pvr         = _pvr,                                                  \
+        .pvr_mask    = _pvr_mask,                                             \
+        .insns_flags = glue(POWERPC_INSNS_,_type),                            \
+        .msr_mask    = glue(POWERPC_MSRM_,_type),                             \
+        .mmu_model   = glue(POWERPC_MMU_,_type),                              \
+        .excp_model  = glue(POWERPC_EXCP_,_type),                             \
+        .bus_model   = glue(POWERPC_INPUT_,_type),                            \
+        .init_proc   = &glue(init_proc_,_type),                               \
+    }
+
 static ppc_def_t ppc_defs[] = {
-    /* Embedded PowerPC */
+    /* Embedded PowerPC                                                      */
+    /* PowerPC 401 family                                                    */
     /* Generic PowerPC 401 */
-    {
-        .name        = "401",
-        .pvr         = CPU_PPC_401,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_401,
-        .flags       = PPC_FLAGS_401,
-        .msr_mask    = 0x000FD201,
-    },
+    POWERPC_DEF("401",         CPU_POWERPC_401,         0xFFFF0000, 401),
+    /* PowerPC 401 cores                                                     */
     /* PowerPC 401A1 */
-    {
-        .name        = "401a1",
-        .pvr         = CPU_PPC_401A1,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_401,
-        .flags       = PPC_FLAGS_401,
-        .msr_mask    = 0x000FD201,
-    },
-    /* PowerPC 401B2 */
-    {
-        .name        = "401b2",
-        .pvr         = CPU_PPC_401B2,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_401,
-        .flags       = PPC_FLAGS_401,
-        .msr_mask    = 0x000FD201,
-    },
+    POWERPC_DEF("401A1",       CPU_POWERPC_401A1,       0xFFFFFFFF, 401),
+    /* PowerPC 401B2                                                         */
+    POWERPC_DEF("401B2",       CPU_POWERPC_401B2,       0xFFFFFFFF, 401x2),
 #if defined (TODO)
-    /* PowerPC 401B3 */
-    {
-        .name        = "401b3",
-        .pvr         = CPU_PPC_401B3,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_401,
-        .flags       = PPC_FLAGS_401,
-        .msr_mask    = 0x000FD201,
-    },
-#endif
-    /* PowerPC 401C2 */
-    {
-        .name        = "401c2",
-        .pvr         = CPU_PPC_401C2,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_401,
-        .flags       = PPC_FLAGS_401,
-        .msr_mask    = 0x000FD201,
-    },
-    /* PowerPC 401D2 */
-    {
-        .name        = "401d2",
-        .pvr         = CPU_PPC_401D2,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_401,
-        .flags       = PPC_FLAGS_401,
-        .msr_mask    = 0x000FD201,
-    },
-    /* PowerPC 401E2 */
-    {
-        .name        = "401e2",
-        .pvr         = CPU_PPC_401E2,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_401,
-        .flags       = PPC_FLAGS_401,
-        .msr_mask    = 0x000FD201,
-    },
-    /* PowerPC 401F2 */
-    {
-        .name        = "401f2",
-        .pvr         = CPU_PPC_401F2,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_401,
-        .flags       = PPC_FLAGS_401,
-        .msr_mask    = 0x000FD201,
-    },
-    /* PowerPC 401G2 */
-    {
-        .name        = "401g2",
-        .pvr         = CPU_PPC_401G2,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_401,
-        .flags       = PPC_FLAGS_401,
-        .msr_mask    = 0x000FD201,
-    },
+    /* PowerPC 401B3                                                         */
+    POWERPC_DEF("401B3",       CPU_POWERPC_401B3,       0xFFFFFFFF, 401x3),
+#endif
+    /* PowerPC 401C2                                                         */
+    POWERPC_DEF("401C2",       CPU_POWERPC_401C2,       0xFFFFFFFF, 401x2),
+    /* PowerPC 401D2                                                         */
+    POWERPC_DEF("401D2",       CPU_POWERPC_401D2,       0xFFFFFFFF, 401x2),
+    /* PowerPC 401E2                                                         */
+    POWERPC_DEF("401E2",       CPU_POWERPC_401E2,       0xFFFFFFFF, 401x2),
+    /* PowerPC 401F2                                                         */
+    POWERPC_DEF("401F2",       CPU_POWERPC_401F2,       0xFFFFFFFF, 401x2),
+    /* PowerPC 401G2                                                         */
+    /* XXX: to be checked */
+    POWERPC_DEF("401G2",       CPU_POWERPC_401G2,       0xFFFFFFFF, 401x2),
+    /* PowerPC 401 microcontrolers                                           */
 #if defined (TODO)
-    /* PowerPC 401G2 */
-    {
-        .name        = "401gf",
-        .pvr         = CPU_PPC_401GF,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_401,
-        .flags       = PPC_FLAGS_401,
-        .msr_mask    = 0x000FD201,
-    },
+    /* PowerPC 401GF                                                         */
+    POWERPC_DEF("401GF",       CPU_POWERPC_401GF,       0xFFFFFFFF, 401),
 #endif
+    /* IOP480 (401 microcontroler)                                           */
+    POWERPC_DEF("IOP480",      CPU_POWERPC_IOP480,      0xFFFFFFFF, IOP480),
+    /* IBM Processor for Network Resources                                   */
+    POWERPC_DEF("Cobra",       CPU_POWERPC_COBRA,       0xFFFFFFFF, 401),
 #if defined (TODO)
-    /* IOP480 (401 microcontroler) */
-    {
-        .name        = "iop480",
-        .pvr         = CPU_PPC_IOP480,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_401,
-        .flags       = PPC_FLAGS_401,
-        .msr_mask    = 0x000FD201,
-    },
+    POWERPC_DEF("Xipchip",     CPU_POWERPC_XIPCHIP,     0xFFFFFFFF, 401),
 #endif
+    /* PowerPC 403 family                                                    */
+    /* Generic PowerPC 403                                                   */
+    POWERPC_DEF("403",         CPU_POWERPC_403,         0xFFFF0000, 403),
+    /* PowerPC 403 microcontrolers                                           */
+    /* PowerPC 403 GA                                                        */
+    POWERPC_DEF("403GA",       CPU_POWERPC_403GA,       0xFFFFFFFF, 403),
+    /* PowerPC 403 GB                                                        */
+    POWERPC_DEF("403GB",       CPU_POWERPC_403GB,       0xFFFFFFFF, 403),
+    /* PowerPC 403 GC                                                        */
+    POWERPC_DEF("403GC",       CPU_POWERPC_403GC,       0xFFFFFFFF, 403),
+    /* PowerPC 403 GCX                                                       */
+    POWERPC_DEF("403GCX",      CPU_POWERPC_403GCX,      0xFFFFFFFF, 403GCX),
 #if defined (TODO)
-    /* IBM Processor for Network Resources */
-    {
-        .name        = "Cobra",
-        .pvr         = CPU_PPC_COBRA,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_401,
-        .flags       = PPC_FLAGS_401,
-        .msr_mask    = 0x000FD201,
-    },
+    /* PowerPC 403 GP                                                        */
+    POWERPC_DEF("403GP",       CPU_POWERPC_403GP,       0xFFFFFFFF, 403),
 #endif
-    /* Generic PowerPC 403 */
-    {
-        .name        = "403",
-        .pvr         = CPU_PPC_403,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_403,
-        .flags       = PPC_FLAGS_403,
-        .msr_mask    = 0x000000000007D23DULL,
-    },
-    /* PowerPC 403 GA */
-    {
-        .name        = "403ga",
-        .pvr         = CPU_PPC_403GA,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_403,
-        .flags       = PPC_FLAGS_403,
-        .msr_mask    = 0x000000000007D23DULL,
-    },
-    /* PowerPC 403 GB */
-    {
-        .name        = "403gb",
-        .pvr         = CPU_PPC_403GB,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_403,
-        .flags       = PPC_FLAGS_403,
-        .msr_mask    = 0x000000000007D23DULL,
-    },
-    /* PowerPC 403 GC */
-    {
-        .name        = "403gc",
-        .pvr         = CPU_PPC_403GC,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_403,
-        .flags       = PPC_FLAGS_403,
-        .msr_mask    = 0x000000000007D23DULL,
-    },
-    /* PowerPC 403 GCX */
-    {
-        .name        = "403gcx",
-        .pvr         = CPU_PPC_403GCX,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_403,
-        .flags       = PPC_FLAGS_403,
-        .msr_mask    = 0x000000000007D23DULL,
-    },
+    /* PowerPC 405 family                                                    */
+    /* Generic PowerPC 405                                                   */
+    POWERPC_DEF("405",         CPU_POWERPC_405,         0xFFFF0000, 405),
+    /* PowerPC 405 cores                                                     */
 #if defined (TODO)
-    /* PowerPC 403 GP */
-    {
-        .name        = "403gp",
-        .pvr         = CPU_PPC_403GP,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_403,
-        .flags       = PPC_FLAGS_403,
-        .msr_mask    = 0x000000000007D23DULL,
-    },
+    /* PowerPC 405 A3                                                        */
+    POWERPC_DEF("405A3",       CPU_POWERPC_405A3,       0xFFFFFFFF, 405),
 #endif
-    /* Generic PowerPC 405 */
-    {
-        .name        = "405",
-        .pvr         = CPU_PPC_405,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
 #if defined (TODO)
-    /* PowerPC 405 A3 */
-    {
-        .name        = "405a3",
-        .pvr         = CPU_PPC_405A3,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
+    /* PowerPC 405 A4                                                        */
+    POWERPC_DEF("405A4",       CPU_POWERPC_405A4,       0xFFFFFFFF, 405),
 #endif
 #if defined (TODO)
-    /* PowerPC 405 A4 */
-    {
-        .name        = "405a4",
-        .pvr         = CPU_PPC_405A4,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
+    /* PowerPC 405 B3                                                        */
+    POWERPC_DEF("405B3",       CPU_POWERPC_405B3,       0xFFFFFFFF, 405),
 #endif
 #if defined (TODO)
-    /* PowerPC 405 B3 */
-    {
-        .name        = "405b3",
-        .pvr         = CPU_PPC_405B3,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
-#endif
-    /* PowerPC 405 D2 */
-    {
-        .name        = "405d2",
-        .pvr         = CPU_PPC_405D2,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
-    /* PowerPC 405 D4 */
-    {
-        .name        = "405d4",
-        .pvr         = CPU_PPC_405D4,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
-    /* PowerPC 405 CR */
-    {
-        .name        = "405cr",
-        .pvr         = CPU_PPC_405CR,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
-    /* PowerPC 405 GP */
-    {
-        .name        = "405gp",
-        .pvr         = CPU_PPC_405GP,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
-    /* PowerPC 405 EP */
-    {
-        .name        = "405ep",
-        .pvr         = CPU_PPC_405EP,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000000ED630ULL,
-    },
+    /* PowerPC 405 B4                                                        */
+    POWERPC_DEF("405B4",       CPU_POWERPC_405B4,       0xFFFFFFFF, 405),
+#endif
+#if defined (TODO)
+    /* PowerPC 405 C3                                                        */
+    POWERPC_DEF("405C3",       CPU_POWERPC_405C3,       0xFFFFFFFF, 405),
+#endif
+#if defined (TODO)
+    /* PowerPC 405 C4                                                        */
+    POWERPC_DEF("405C4",       CPU_POWERPC_405C4,       0xFFFFFFFF, 405),
+#endif
+    /* PowerPC 405 D2                                                        */
+    POWERPC_DEF("405D2",       CPU_POWERPC_405D2,       0xFFFFFFFF, 405),
+#if defined (TODO)
+    /* PowerPC 405 D3                                                        */
+    POWERPC_DEF("405D3",       CPU_POWERPC_405D3,       0xFFFFFFFF, 405),
+#endif
+    /* PowerPC 405 D4                                                        */
+    POWERPC_DEF("405D4",       CPU_POWERPC_405D4,       0xFFFFFFFF, 405),
+#if defined (TODO)
+    /* PowerPC 405 D5                                                        */
+    POWERPC_DEF("405D5",       CPU_POWERPC_405D5,       0xFFFFFFFF, 405),
+#endif
+#if defined (TODO)
+    /* PowerPC 405 E4                                                        */
+    POWERPC_DEF("405E4",       CPU_POWERPC_405E4,       0xFFFFFFFF, 405),
+#endif
+#if defined (TODO)
+    /* PowerPC 405 F4                                                        */
+    POWERPC_DEF("405F4",       CPU_POWERPC_405F4,       0xFFFFFFFF, 405),
+#endif
+#if defined (TODO)
+    /* PowerPC 405 F5                                                        */
+    POWERPC_DEF("405F5",       CPU_POWERPC_405F5,       0xFFFFFFFF, 405),
+#endif
+#if defined (TODO)
+    /* PowerPC 405 F6                                                        */
+    POWERPC_DEF("405F6",       CPU_POWERPC_405F6,       0xFFFFFFFF, 405),
+#endif
+    /* PowerPC 405 microcontrolers                                           */
+    /* PowerPC 405 CR                                                        */
+    POWERPC_DEF("405CR",       CPU_POWERPC_405CR,       0xFFFFFFFF, 405),
+    /* PowerPC 405 CRa                                                       */
+    POWERPC_DEF("405CRa",      CPU_POWERPC_405CRa,      0xFFFFFFFF, 405),
+    /* PowerPC 405 CRb                                                       */
+    POWERPC_DEF("405CRb",      CPU_POWERPC_405CRb,      0xFFFFFFFF, 405),
+    /* PowerPC 405 CRc                                                       */
+    POWERPC_DEF("405CRc",      CPU_POWERPC_405CRc,      0xFFFFFFFF, 405),
+    /* PowerPC 405 EP                                                        */
+    POWERPC_DEF("405EP",       CPU_POWERPC_405EP,       0xFFFFFFFF, 405),
+#if defined(TODO)
+    /* PowerPC 405 EXr                                                       */
+    POWERPC_DEF("405EXr",      CPU_POWERPC_405EXr,      0xFFFFFFFF, 405),
+#endif
+    /* PowerPC 405 EZ                                                        */
+    POWERPC_DEF("405EZ",       CPU_POWERPC_405EZ,       0xFFFFFFFF, 405),
+#if defined(TODO)
+    /* PowerPC 405 FX                                                        */
+    POWERPC_DEF("405FX",       CPU_POWERPC_405FX,       0xFFFFFFFF, 405),
+#endif
+    /* PowerPC 405 GP                                                        */
+    POWERPC_DEF("405GP",       CPU_POWERPC_405GP,       0xFFFFFFFF, 405),
+    /* PowerPC 405 GPa                                                       */
+    POWERPC_DEF("405GPa",      CPU_POWERPC_405GPa,      0xFFFFFFFF, 405),
+    /* PowerPC 405 GPb                                                       */
+    POWERPC_DEF("405GPb",      CPU_POWERPC_405GPb,      0xFFFFFFFF, 405),
+    /* PowerPC 405 GPc                                                       */
+    POWERPC_DEF("405GPc",      CPU_POWERPC_405GPc,      0xFFFFFFFF, 405),
+    /* PowerPC 405 GPd                                                       */
+    POWERPC_DEF("405GPd",      CPU_POWERPC_405GPd,      0xFFFFFFFF, 405),
+    /* PowerPC 405 GPe                                                       */
+    POWERPC_DEF("405GPe",      CPU_POWERPC_405GPe,      0xFFFFFFFF, 405),
+    /* PowerPC 405 GPR                                                       */
+    POWERPC_DEF("405GPR",      CPU_POWERPC_405GPR,      0xFFFFFFFF, 405),
+#if defined(TODO)
+    /* PowerPC 405 H                                                         */
+    POWERPC_DEF("405H",        CPU_POWERPC_405H,        0xFFFFFFFF, 405),
+#endif
+#if defined(TODO)
+    /* PowerPC 405 L                                                         */
+    POWERPC_DEF("405L",        CPU_POWERPC_405L,        0xFFFFFFFF, 405),
+#endif
+    /* PowerPC 405 LP                                                        */
+    POWERPC_DEF("405LP",       CPU_POWERPC_405LP,       0xFFFFFFFF, 405),
+#if defined(TODO)
+    /* PowerPC 405 PM                                                        */
+    POWERPC_DEF("405PM",       CPU_POWERPC_405PM,       0xFFFFFFFF, 405),
+#endif
+#if defined(TODO)
+    /* PowerPC 405 PS                                                        */
+    POWERPC_DEF("405PS",       CPU_POWERPC_405PS,       0xFFFFFFFF, 405),
+#endif
+#if defined(TODO)
+    /* PowerPC 405 S                                                         */
+    POWERPC_DEF("405S",        CPU_POWERPC_405S,        0xFFFFFFFF, 405),
+#endif
+    /* Npe405 H                                                              */
+    POWERPC_DEF("Npe405H",     CPU_POWERPC_NPE405H,     0xFFFFFFFF, 405),
+    /* Npe405 H2                                                             */
+    POWERPC_DEF("Npe405H2",    CPU_POWERPC_NPE405H2,    0xFFFFFFFF, 405),
+    /* Npe405 L                                                              */
+    POWERPC_DEF("Npe405L",     CPU_POWERPC_NPE405L,     0xFFFFFFFF, 405),
+    /* Npe4GS3                                                               */
+    POWERPC_DEF("Npe4GS3",     CPU_POWERPC_NPE4GS3,     0xFFFFFFFF, 405),
+#if defined (TODO)
+    POWERPC_DEF("Npcxx1",      CPU_POWERPC_NPCxx1,      0xFFFFFFFF, 405),
+#endif
+#if defined (TODO)
+    POWERPC_DEF("Npr161",      CPU_POWERPC_NPR161,      0xFFFFFFFF, 405),
+#endif
+#if defined (TODO)
+    /* PowerPC LC77700 (Sanyo)                                               */
+    POWERPC_DEF("LC77700",     CPU_POWERPC_LC77700,     0xFFFFFFFF, 405),
+#endif
+    /* PowerPC 401/403/405 based set-top-box microcontrolers                 */
+#if defined (TODO)
+    /* STB010000                                                             */
+    POWERPC_DEF("STB01000",    CPU_POWERPC_STB01000,    0xFFFFFFFF, 401x2),
+#endif
+#if defined (TODO)
+    /* STB01010                                                              */
+    POWERPC_DEF("STB01010",    CPU_POWERPC_STB01010,    0xFFFFFFFF, 401x2),
+#endif
+#if defined (TODO)
+    /* STB0210                                                               */
+    POWERPC_DEF("STB0210",     CPU_POWERPC_STB0210,     0xFFFFFFFF, 401x3),
+#endif
+    /* STB03xx                                                               */
+    POWERPC_DEF("STB03",       CPU_POWERPC_STB03,       0xFFFFFFFF, 405),
+#if defined (TODO)
+    /* STB043x                                                               */
+    POWERPC_DEF("STB043",      CPU_POWERPC_STB043,      0xFFFFFFFF, 405),
+#endif
+#if defined (TODO)
+    /* STB045x                                                               */
+    POWERPC_DEF("STB045",      CPU_POWERPC_STB045,      0xFFFFFFFF, 405),
+#endif
+    /* STB04xx                                                               */
+    POWERPC_DEF("STB04",       CPU_POWERPC_STB04,       0xFFFF0000, 405),
+    /* STB25xx                                                               */
+    POWERPC_DEF("STB25",       CPU_POWERPC_STB25,       0xFFFFFFFF, 405),
+#if defined (TODO)
+    /* STB130                                                                */
+    POWERPC_DEF("STB130",      CPU_POWERPC_STB130,      0xFFFFFFFF, 405),
+#endif
+    /* Xilinx PowerPC 405 cores                                              */
+    POWERPC_DEF("x2vp4",       CPU_POWERPC_X2VP4,       0xFFFFFFFF, 405),
+    POWERPC_DEF("x2vp7",       CPU_POWERPC_X2VP7,       0xFFFFFFFF, 405),
+    POWERPC_DEF("x2vp20",      CPU_POWERPC_X2VP20,      0xFFFFFFFF, 405),
+    POWERPC_DEF("x2vp50",      CPU_POWERPC_X2VP50,      0xFFFFFFFF, 405),
+#if defined (TODO)
+    /* Zarlink ZL10310                                                       */
+    POWERPC_DEF("zl10310",     CPU_POWERPC_ZL10310,     0xFFFFFFFF, 405),
+#endif
+#if defined (TODO)
+    /* Zarlink ZL10311                                                       */
+    POWERPC_DEF("zl10311",     CPU_POWERPC_ZL10311,     0xFFFFFFFF, 405),
+#endif
+#if defined (TODO)
+    /* Zarlink ZL10320                                                       */
+    POWERPC_DEF("zl10320",     CPU_POWERPC_ZL10320,     0xFFFFFFFF, 405),
+#endif
+#if defined (TODO)
+    /* Zarlink ZL10321                                                       */
+    POWERPC_DEF("zl10321",     CPU_POWERPC_ZL10321,     0xFFFFFFFF, 405),
+#endif
+    /* PowerPC 440 family                                                    */
+    /* Generic PowerPC 440                                                   */
+    POWERPC_DEF("440",         CPU_POWERPC_440,         0xFFFFFFFF, 440GP),
+    /* PowerPC 440 cores                                                     */
+#if defined (TODO)
+    /* PowerPC 440 A4                                                        */
+    POWERPC_DEF("440A4",       CPU_POWERPC_440A4,       0xFFFFFFFF, 440x4),
+#endif
+#if defined (TODO)
+    /* PowerPC 440 A5                                                        */
+    POWERPC_DEF("440A5",       CPU_POWERPC_440A5,       0xFFFFFFFF, 440x5),
+#endif
+#if defined (TODO)
+    /* PowerPC 440 B4                                                        */
+    POWERPC_DEF("440B4",       CPU_POWERPC_440B4,       0xFFFFFFFF, 440x4),
+#endif
+#if defined (TODO)
+    /* PowerPC 440 G4                                                        */
+    POWERPC_DEF("440G4",       CPU_POWERPC_440G4,       0xFFFFFFFF, 440x4),
+#endif
+#if defined (TODO)
+    /* PowerPC 440 F5                                                        */
+    POWERPC_DEF("440F5",       CPU_POWERPC_440F5,       0xFFFFFFFF, 440x5),
+#endif
+#if defined (TODO)
+    /* PowerPC 440 G5                                                        */
+    POWERPC_DEF("440G5",       CPU_POWERPC_440G5,       0xFFFFFFFF, 440x5),
+#endif
+#if defined (TODO)
+    /* PowerPC 440H4                                                         */
+    POWERPC_DEF("440H4",       CPU_POWERPC_440H4,       0xFFFFFFFF, 440x4),
+#endif
+#if defined (TODO)
+    /* PowerPC 440H6                                                         */
+    POWERPC_DEF("440H6",       CPU_POWERPC_440H6,       0xFFFFFFFF, 440Gx5),
+#endif
+    /* PowerPC 440 microcontrolers                                           */
+    /* PowerPC 440 EP                                                        */
+    POWERPC_DEF("440EP",       CPU_POWERPC_440EP,       0xFFFFFFFF, 440EP),
+    /* PowerPC 440 EPa                                                       */
+    POWERPC_DEF("440EPa",      CPU_POWERPC_440EPa,      0xFFFFFFFF, 440EP),
+    /* PowerPC 440 EPb                                                       */
+    POWERPC_DEF("440EPb",      CPU_POWERPC_440EPb,      0xFFFFFFFF, 440EP),
+    /* PowerPC 440 EPX                                                       */
+    POWERPC_DEF("440EPX",      CPU_POWERPC_440EPX,      0xFFFFFFFF, 440EP),
+    /* PowerPC 440 GP                                                        */
+    POWERPC_DEF("440GP",       CPU_POWERPC_440GP,       0xFFFFFFFF, 440GP),
+    /* PowerPC 440 GPb                                                       */
+    POWERPC_DEF("440GPb",      CPU_POWERPC_440GPb,      0xFFFFFFFF, 440GP),
+    /* PowerPC 440 GPc                                                       */
+    POWERPC_DEF("440GPc",      CPU_POWERPC_440GPc,      0xFFFFFFFF, 440GP),
+    /* PowerPC 440 GR                                                        */
+    POWERPC_DEF("440GR",       CPU_POWERPC_440GR,       0xFFFFFFFF, 440x5),
+    /* PowerPC 440 GRa                                                       */
+    POWERPC_DEF("440GRa",      CPU_POWERPC_440GRa,      0xFFFFFFFF, 440x5),
+    /* PowerPC 440 GRX                                                       */
+    POWERPC_DEF("440GRX",      CPU_POWERPC_440GRX,      0xFFFFFFFF, 440x5),
+    /* PowerPC 440 GX                                                        */
+    POWERPC_DEF("440GX",       CPU_POWERPC_440GX,       0xFFFFFFFF, 440EP),
+    /* PowerPC 440 GXa                                                       */
+    POWERPC_DEF("440GXa",      CPU_POWERPC_440GXa,      0xFFFFFFFF, 440EP),
+    /* PowerPC 440 GXb                                                       */
+    POWERPC_DEF("440GXb",      CPU_POWERPC_440GXb,      0xFFFFFFFF, 440EP),
+    /* PowerPC 440 GXc                                                       */
+    POWERPC_DEF("440GXc",      CPU_POWERPC_440GXc,      0xFFFFFFFF, 440EP),
+    /* PowerPC 440 GXf                                                       */
+    POWERPC_DEF("440GXf",      CPU_POWERPC_440GXf,      0xFFFFFFFF, 440EP),
+#if defined(TODO)
+    /* PowerPC 440 S                                                         */
+    POWERPC_DEF("440S",        CPU_POWERPC_440S,        0xFFFFFFFF, 440),
+#endif
+    /* PowerPC 440 SP                                                        */
+    POWERPC_DEF("440SP",       CPU_POWERPC_440SP,       0xFFFFFFFF, 440EP),
+    /* PowerPC 440 SP2                                                       */
+    POWERPC_DEF("440SP2",      CPU_POWERPC_440SP2,      0xFFFFFFFF, 440EP),
+    /* PowerPC 440 SPE                                                       */
+    POWERPC_DEF("440SPE",      CPU_POWERPC_440SPE,      0xFFFFFFFF, 440EP),
+    /* PowerPC 460 family                                                    */
+#if defined (TODO)
+    /* Generic PowerPC 464                                                   */
+    POWERPC_DEF("464",         CPU_POWERPC_464,         0xFFFFFFFF, 460),
+#endif
+    /* PowerPC 464 microcontrolers                                           */
+#if defined (TODO)
+    /* PowerPC 464H90                                                        */
+    POWERPC_DEF("464H90",      CPU_POWERPC_464H90,      0xFFFFFFFF, 460),
+#endif
+#if defined (TODO)
+    /* PowerPC 464H90F                                                       */
+    POWERPC_DEF("464H90F",     CPU_POWERPC_464H90F,     0xFFFFFFFF, 460F),
+#endif
+    /* Freescale embedded PowerPC cores                                      */
+    /* e200 family                                                           */
+#if defined (TODO)
+    /* Generic PowerPC e200 core                                             */
+    POWERPC_DEF("e200",        CPU_POWERPC_e200,        0xFFFFFFFF, e200),
+#endif
+#if defined (TODO)
+    /* PowerPC e200z5 core                                                   */
+    POWERPC_DEF("e200z5",      CPU_POWERPC_e200z5,      0xFFFFFFFF, e200),
+#endif
+#if defined (TODO)
+    /* PowerPC e200z6 core                                                   */
+    POWERPC_DEF("e200z6",      CPU_POWERPC_e200z6,      0xFFFFFFFF, e200),
+#endif
+    /* e300 family                                                           */
+#if defined (TODO)
+    /* Generic PowerPC e300 core                                             */
+    POWERPC_DEF("e300",        CPU_POWERPC_e300,        0xFFFFFFFF, e300),
+#endif
+#if defined (TODO)
+    /* PowerPC e300c1 core                                                   */
+    POWERPC_DEF("e300c1",      CPU_POWERPC_e300c1,      0xFFFFFFFF, e300),
+#endif
+#if defined (TODO)
+    /* PowerPC e300c2 core                                                   */
+    POWERPC_DEF("e300c2",      CPU_POWERPC_e300c2,      0xFFFFFFFF, e300),
+#endif
+#if defined (TODO)
+    /* PowerPC e300c3 core                                                   */
+    POWERPC_DEF("e300c3",      CPU_POWERPC_e300c3,      0xFFFFFFFF, e300),
+#endif
+    /* e500 family                                                           */
+#if defined (TODO)
+    /* PowerPC e500 core                                                     */
+    POWERPC_DEF("e500",        CPU_POWERPC_e500,        0xFFFFFFFF, e500),
+#endif
+#if defined (TODO)
+    /* PowerPC e500 v1.1 core                                                */
+    POWERPC_DEF("e500v1.1",    CPU_POWERPC_e500_v11,    0xFFFFFFFF, e500),
+#endif
+#if defined (TODO)
+    /* PowerPC e500 v1.2 core                                                */
+    POWERPC_DEF("e500v1.2",    CPU_POWERPC_e500_v12,    0xFFFFFFFF, e500),
+#endif
+#if defined (TODO)
+    /* PowerPC e500 v2.1 core                                                */
+    POWERPC_DEF("e500v2.1",    CPU_POWERPC_e500_v21,    0xFFFFFFFF, e500),
+#endif
+#if defined (TODO)
+    /* PowerPC e500 v2.2 core                                                */
+    POWERPC_DEF("e500v2.2",    CPU_POWERPC_e500_v22,    0xFFFFFFFF, e500),
+#endif
+    /* e600 family                                                           */
+#if defined (TODO)
+    /* PowerPC e600 core                                                     */
+    POWERPC_DEF("e600",        CPU_POWERPC_e600,        0xFFFFFFFF, e600),
+#endif
+    /* PowerPC MPC 5xx cores                                                 */
+#if defined (TODO)
+    /* PowerPC MPC 5xx                                                       */
+    POWERPC_DEF("mpc5xx",      CPU_POWERPC_5xx,         0xFFFFFFFF, 5xx),
+#endif
+    /* PowerPC MPC 8xx cores                                                 */
+#if defined (TODO)
+    /* PowerPC MPC 8xx                                                       */
+    POWERPC_DEF("mpc8xx",      CPU_POWERPC_8xx,         0xFFFFFFFF, 8xx),
+#endif
+    /* PowerPC MPC 8xxx cores                                                */
+#if defined (TODO)
+    /* PowerPC MPC 82xx HIP3                                                 */
+    POWERPC_DEF("mpc82xxhip3", CPU_POWERPC_82xx_HIP3,   0xFFFFFFFF, 82xx),
+#endif
+#if defined (TODO)
+    /* PowerPC MPC 82xx HIP4                                                 */
+    POWERPC_DEF("mpc82xxhip4", CPU_POWERPC_82xx_HIP4,   0xFFFFFFFF, 82xx),
+#endif
+#if defined (TODO)
+    /* PowerPC MPC 827x                                                      */
+    POWERPC_DEF("mpc827x",     CPU_POWERPC_827x,        0xFFFFFFFF, 827x),
+#endif
+
+    /* 32 bits "classic" PowerPC                                             */
+    /* PowerPC 6xx family                                                    */
+    /* PowerPC 601                                                           */
+    POWERPC_DEF("601",         CPU_POWERPC_601,         0xFFFFFFFF, 601),
+    /* PowerPC 601v2                                                         */
+    POWERPC_DEF("601a",        CPU_POWERPC_601a,        0xFFFFFFFF, 601),
+    /* PowerPC 602                                                           */
+    POWERPC_DEF("602",         CPU_POWERPC_602,         0xFFFFFFFF, 602),
+    /* PowerPC 603                                                           */
+    POWERPC_DEF("603",         CPU_POWERPC_603,         0xFFFFFFFF, 603),
+    /* Code name for PowerPC 603                                             */
+    POWERPC_DEF("Vanilla",     CPU_POWERPC_603,         0xFFFFFFFF, 603),
+    /* PowerPC 603e                                                          */
+    POWERPC_DEF("603e",        CPU_POWERPC_603E,        0xFFFFFFFF, 603E),
+    /* Code name for PowerPC 603e                                            */
+    POWERPC_DEF("Stretch",     CPU_POWERPC_603E,        0xFFFFFFFF, 603E),
+    /* PowerPC 603e v1.1                                                     */
+    POWERPC_DEF("603e1.1",     CPU_POWERPC_603E_v11,    0xFFFFFFFF, 603E),
+    /* PowerPC 603e v1.2                                                     */
+    POWERPC_DEF("603e1.2",     CPU_POWERPC_603E_v12,    0xFFFFFFFF, 603E),
+    /* PowerPC 603e v1.3                                                     */
+    POWERPC_DEF("603e1.3",     CPU_POWERPC_603E_v13,    0xFFFFFFFF, 603E),
+    /* PowerPC 603e v1.4                                                     */
+    POWERPC_DEF("603e1.4",     CPU_POWERPC_603E_v14,    0xFFFFFFFF, 603E),
+    /* PowerPC 603e v2.2                                                     */
+    POWERPC_DEF("603e2.2",     CPU_POWERPC_603E_v22,    0xFFFFFFFF, 603E),
+    /* PowerPC 603e v3                                                       */
+    POWERPC_DEF("603e3",       CPU_POWERPC_603E_v3,     0xFFFFFFFF, 603E),
+    /* PowerPC 603e v4                                                       */
+    POWERPC_DEF("603e4",       CPU_POWERPC_603E_v4,     0xFFFFFFFF, 603E),
+    /* PowerPC 603e v4.1                                                     */
+    POWERPC_DEF("603e4.1",     CPU_POWERPC_603E_v41,    0xFFFFFFFF, 603E),
+    /* PowerPC 603e                                                          */
+    POWERPC_DEF("603e7",       CPU_POWERPC_603E7,       0xFFFFFFFF, 603E),
+    /* PowerPC 603e7t                                                        */
+    POWERPC_DEF("603e7t",      CPU_POWERPC_603E7t,      0xFFFFFFFF, 603E),
+    /* PowerPC 603e7v                                                        */
+    POWERPC_DEF("603e7v",      CPU_POWERPC_603E7v,      0xFFFFFFFF, 603E),
+    /* Code name for PowerPC 603ev                                           */
+    POWERPC_DEF("Vaillant",    CPU_POWERPC_603E7v,      0xFFFFFFFF, 603E),
+    /* PowerPC 603e7v1                                                       */
+    POWERPC_DEF("603e7v1",     CPU_POWERPC_603E7v1,     0xFFFFFFFF, 603E),
+    /* PowerPC 603e7v2                                                       */
+    POWERPC_DEF("603e7v2",     CPU_POWERPC_603E7v2,     0xFFFFFFFF, 603E),
+    /* PowerPC 603p                                                          */
+    /* to be checked */
+    POWERPC_DEF("603p",        CPU_POWERPC_603P,        0xFFFFFFFF, 603),
+    /* PowerPC 603r                                                          */
+    POWERPC_DEF("603r",        CPU_POWERPC_603R,        0xFFFFFFFF, 603E),
+    /* Code name for PowerPC 603r                                            */
+    POWERPC_DEF("Goldeneye",   CPU_POWERPC_603R,        0xFFFFFFFF, 603E),
+    /* PowerPC G2 core                                                       */
+    POWERPC_DEF("G2",          CPU_POWERPC_G2,          0xFFFFFFFF, G2),
+    /* PowerPC G2 H4                                                         */
+    POWERPC_DEF("G2H4",        CPU_POWERPC_G2H4,        0xFFFFFFFF, G2),
+    /* PowerPC G2 GP                                                         */
+    POWERPC_DEF("G2GP",        CPU_POWERPC_G2gp,        0xFFFFFFFF, G2),
+    /* PowerPC G2 LS                                                         */
+    POWERPC_DEF("G2LS",        CPU_POWERPC_G2ls,        0xFFFFFFFF, G2),
+    /* PowerPC G2LE                                                          */
+    /* Same as G2, with little-endian mode support                           */
+    POWERPC_DEF("G2le",        CPU_POWERPC_G2LE,        0xFFFFFFFF, G2LE),
+    /* PowerPC G2LE GP                                                       */
+    POWERPC_DEF("G2leGP",      CPU_POWERPC_G2LEgp,      0xFFFFFFFF, G2LE),
+    /* PowerPC G2LE LS                                                       */
+    POWERPC_DEF("G2leLS",      CPU_POWERPC_G2LEls,      0xFFFFFFFF, G2LE),
+    /* PowerPC 604                                                           */
+    POWERPC_DEF("604",         CPU_POWERPC_604,         0xFFFFFFFF, 604),
+    /* PowerPC 604e                                                          */
+    POWERPC_DEF("604e",        CPU_POWERPC_604E,        0xFFFFFFFF, 604),
+    /* PowerPC 604e v1.0                                                     */
+    POWERPC_DEF("604e1.0",     CPU_POWERPC_604E_v10,    0xFFFFFFFF, 604),
+    /* PowerPC 604e v2.2                                                     */
+    POWERPC_DEF("604e2.2",     CPU_POWERPC_604E_v22,    0xFFFFFFFF, 604),
+    /* PowerPC 604e v2.4                                                     */
+    POWERPC_DEF("604e2.4",     CPU_POWERPC_604E_v24,    0xFFFFFFFF, 604),
+    /* PowerPC 604r                                                          */
+    POWERPC_DEF("604r",        CPU_POWERPC_604R,        0xFFFFFFFF, 604),
+#if defined(TODO)
+    /* PowerPC 604ev                                                         */
+    POWERPC_DEF("604ev",       CPU_POWERPC_604EV,       0xFFFFFFFF, 604),
+#endif
+    /* PowerPC 7xx family                                                    */
+    /* Generic PowerPC 740 (G3)                                              */
+    POWERPC_DEF("740",         CPU_POWERPC_7x0,         0xFFFFFFFF, 7x0),
+    /* Generic PowerPC 750 (G3)                                              */
+    POWERPC_DEF("750",         CPU_POWERPC_7x0,         0xFFFFFFFF, 7x0),
+    /* Code name for generic PowerPC 740/750 (G3)                            */
+    POWERPC_DEF("Arthur",      CPU_POWERPC_7x0,         0xFFFFFFFF, 7x0),
+    /* PowerPC 740/750 is also known as G3                                   */
+    POWERPC_DEF("G3",          CPU_POWERPC_7x0,         0xFFFFFFFF, 7x0),
+    /* PowerPC 740 v2.0 (G3)                                                 */
+    POWERPC_DEF("740v2.0",     CPU_POWERPC_7x0_v20,     0xFFFFFFFF, 7x0),
+    /* PowerPC 750 v2.0 (G3)                                                 */
+    POWERPC_DEF("750v2.0",     CPU_POWERPC_7x0_v20,     0xFFFFFFFF, 7x0),
+    /* PowerPC 740 v2.1 (G3)                                                 */
+    POWERPC_DEF("740v2.1",     CPU_POWERPC_7x0_v21,     0xFFFFFFFF, 7x0),
+    /* PowerPC 750 v2.1 (G3)                                                 */
+    POWERPC_DEF("750v2.1",     CPU_POWERPC_7x0_v21,     0xFFFFFFFF, 7x0),
+    /* PowerPC 740 v2.2 (G3)                                                 */
+    POWERPC_DEF("740v2.2",     CPU_POWERPC_7x0_v22,     0xFFFFFFFF, 7x0),
+    /* PowerPC 750 v2.2 (G3)                                                 */
+    POWERPC_DEF("750v2.2",     CPU_POWERPC_7x0_v22,     0xFFFFFFFF, 7x0),
+    /* PowerPC 740 v3.0 (G3)                                                 */
+    POWERPC_DEF("740v3.0",     CPU_POWERPC_7x0_v30,     0xFFFFFFFF, 7x0),
+    /* PowerPC 750 v3.0 (G3)                                                 */
+    POWERPC_DEF("750v3.0",     CPU_POWERPC_7x0_v30,     0xFFFFFFFF, 7x0),
+    /* PowerPC 740 v3.1 (G3)                                                 */
+    POWERPC_DEF("740v3.1",     CPU_POWERPC_7x0_v31,     0xFFFFFFFF, 7x0),
+    /* PowerPC 750 v3.1 (G3)                                                 */
+    POWERPC_DEF("750v3.1",     CPU_POWERPC_7x0_v31,     0xFFFFFFFF, 7x0),
+    /* PowerPC 740E (G3)                                                     */
+    POWERPC_DEF("740e",        CPU_POWERPC_740E,        0xFFFFFFFF, 7x0),
+    /* PowerPC 740P (G3)                                                     */
+    POWERPC_DEF("740p",        CPU_POWERPC_7x0P,        0xFFFFFFFF, 7x0),
+    /* PowerPC 750P (G3)                                                     */
+    POWERPC_DEF("750p",        CPU_POWERPC_7x0P,        0xFFFFFFFF, 7x0),
+    /* Code name for PowerPC 740P/750P (G3)                                  */
+    POWERPC_DEF("Conan/Doyle", CPU_POWERPC_7x0P,        0xFFFFFFFF, 7x0),
+    /* PowerPC 750CL (G3 embedded)                                           */
+    POWERPC_DEF("750cl",       CPU_POWERPC_750CL,       0xFFFFFFFF, 7x0),
+    /* PowerPC 750CX (G3 embedded)                                           */
+    POWERPC_DEF("750cx",       CPU_POWERPC_750CX,       0xFFFFFFFF, 7x0),
+    /* PowerPC 750CX v2.1 (G3 embedded)                                      */
+    POWERPC_DEF("750cx2.1",    CPU_POWERPC_750CX_v21,   0xFFFFFFFF, 7x0),
+    /* PowerPC 750CX v2.2 (G3 embedded)                                      */
+    POWERPC_DEF("750cx2.2",    CPU_POWERPC_750CX_v22,   0xFFFFFFFF, 7x0),
+    /* PowerPC 750CXe (G3 embedded)                                          */
+    POWERPC_DEF("750cxe",      CPU_POWERPC_750CXE,      0xFFFFFFFF, 7x0),
+    /* PowerPC 750CXe v2.1 (G3 embedded)                                     */
+    POWERPC_DEF("750cxe21",    CPU_POWERPC_750CXE_v21,  0xFFFFFFFF, 7x0),
+    /* PowerPC 750CXe v2.2 (G3 embedded)                                     */
+    POWERPC_DEF("750cxe22",    CPU_POWERPC_750CXE_v22,  0xFFFFFFFF, 7x0),
+    /* PowerPC 750CXe v2.3 (G3 embedded)                                     */
+    POWERPC_DEF("750cxe23",    CPU_POWERPC_750CXE_v23,  0xFFFFFFFF, 7x0),
+    /* PowerPC 750CXe v2.4 (G3 embedded)                                     */
+    POWERPC_DEF("750cxe24",    CPU_POWERPC_750CXE_v24,  0xFFFFFFFF, 7x0),
+    /* PowerPC 750CXe v2.4b (G3 embedded)                                    */
+    POWERPC_DEF("750cxe24b",   CPU_POWERPC_750CXE_v24b, 0xFFFFFFFF, 7x0),
+    /* PowerPC 750CXe v3.1 (G3 embedded)                                     */
+    POWERPC_DEF("750cxe31",    CPU_POWERPC_750CXE_v31,  0xFFFFFFFF, 7x0),
+    /* PowerPC 750CXe v3.1b (G3 embedded)                                    */
+    POWERPC_DEF("750cxe3.1b",  CPU_POWERPC_750CXE_v31b, 0xFFFFFFFF, 7x0),
+    /* PowerPC 750CXr (G3 embedded)                                          */
+    POWERPC_DEF("750cxr",      CPU_POWERPC_750CXR,      0xFFFFFFFF, 7x0),
+    /* PowerPC 750E (G3)                                                     */
+    POWERPC_DEF("750e",        CPU_POWERPC_750E,        0xFFFFFFFF, 7x0),
+    /* PowerPC 750FL (G3 embedded)                                           */
+    POWERPC_DEF("750fl",       CPU_POWERPC_750FL,       0xFFFFFFFF, 7x0),
+    /* PowerPC 750FX (G3 embedded)                                           */
+    POWERPC_DEF("750fx",       CPU_POWERPC_750FX,       0xFFFFFFFF, 750fx),
+    /* PowerPC 750FX v1.0 (G3 embedded)                                      */
+    POWERPC_DEF("750fx1.0",    CPU_POWERPC_750FX_v10,   0xFFFFFFFF, 750fx),
+    /* PowerPC 750FX v2.0 (G3 embedded)                                      */
+    POWERPC_DEF("750fx2.0",    CPU_POWERPC_750FX_v20,   0xFFFFFFFF, 750fx),
+    /* PowerPC 750FX v2.1 (G3 embedded)                                      */
+    POWERPC_DEF("750fx2.1",    CPU_POWERPC_750FX_v21,   0xFFFFFFFF, 750fx),
+    /* PowerPC 750FX v2.2 (G3 embedded)                                      */
+    POWERPC_DEF("750fx2.2",    CPU_POWERPC_750FX_v22,   0xFFFFFFFF, 750fx),
+    /* PowerPC 750FX v2.3 (G3 embedded)                                      */
+    POWERPC_DEF("750fx2.3",    CPU_POWERPC_750FX_v23,   0xFFFFFFFF, 750fx),
+    /* PowerPC 750GL (G3 embedded)                                           */
+    POWERPC_DEF("750gl",       CPU_POWERPC_750GL,       0xFFFFFFFF, 7x0),
+    /* PowerPC 750GX (G3 embedded)                                           */
+    POWERPC_DEF("750gx",       CPU_POWERPC_750GX,       0xFFFFFFFF, 750fx),
+    /* PowerPC 750GX v1.0 (G3 embedded)                                      */
+    POWERPC_DEF("750gx1.0",    CPU_POWERPC_750GX_v10,   0xFFFFFFFF, 750fx),
+    /* PowerPC 750GX v1.1 (G3 embedded)                                      */
+    POWERPC_DEF("750gx1.1",    CPU_POWERPC_750GX_v11,   0xFFFFFFFF, 750fx),
+    /* PowerPC 750GX v1.2 (G3 embedded)                                      */
+    POWERPC_DEF("750gx1.2",    CPU_POWERPC_750GX_v12,   0xFFFFFFFF, 750fx),
+    /* PowerPC 750L (G3 embedded)                                            */
+    POWERPC_DEF("750l",        CPU_POWERPC_750L,        0xFFFFFFFF, 7x0),
+    /* Code name for PowerPC 750L (G3 embedded)                              */
+    POWERPC_DEF("LoneStar",    CPU_POWERPC_750L,        0xFFFFFFFF, 7x0),
+    /* PowerPC 750L v2.2 (G3 embedded)                                       */
+    POWERPC_DEF("750l2.2",     CPU_POWERPC_750L_v22,    0xFFFFFFFF, 7x0),
+    /* PowerPC 750L v3.0 (G3 embedded)                                       */
+    POWERPC_DEF("750l3.0",     CPU_POWERPC_750L_v30,    0xFFFFFFFF, 7x0),
+    /* PowerPC 750L v3.2 (G3 embedded)                                       */
+    POWERPC_DEF("750l3.2",     CPU_POWERPC_750L_v32,    0xFFFFFFFF, 7x0),
+    /* Generic PowerPC 745                                                   */
+    POWERPC_DEF("745",         CPU_POWERPC_7x5,         0xFFFFFFFF, 7x5),
+    /* Generic PowerPC 755                                                   */
+    POWERPC_DEF("755",         CPU_POWERPC_7x5,         0xFFFFFFFF, 7x5),
+    /* Code name for PowerPC 745/755                                         */
+    POWERPC_DEF("Goldfinger",  CPU_POWERPC_7x5,         0xFFFFFFFF, 7x5),
+    /* PowerPC 745 v1.0                                                      */
+    POWERPC_DEF("745v1.0",     CPU_POWERPC_7x5_v10,     0xFFFFFFFF, 7x5),
+    /* PowerPC 755 v1.0                                                      */
+    POWERPC_DEF("755v1.0",     CPU_POWERPC_7x5_v10,     0xFFFFFFFF, 7x5),
+    /* PowerPC 745 v1.1                                                      */
+    POWERPC_DEF("745v1.1",     CPU_POWERPC_7x5_v11,     0xFFFFFFFF, 7x5),
+    /* PowerPC 755 v1.1                                                      */
+    POWERPC_DEF("755v1.1",     CPU_POWERPC_7x5_v11,     0xFFFFFFFF, 7x5),
+    /* PowerPC 745 v2.0                                                      */
+    POWERPC_DEF("745v2.0",     CPU_POWERPC_7x5_v20,     0xFFFFFFFF, 7x5),
+    /* PowerPC 755 v2.0                                                      */
+    POWERPC_DEF("755v2.0",     CPU_POWERPC_7x5_v20,     0xFFFFFFFF, 7x5),
+    /* PowerPC 745 v2.1                                                      */
+    POWERPC_DEF("745v2.1",     CPU_POWERPC_7x5_v21,     0xFFFFFFFF, 7x5),
+    /* PowerPC 755 v2.1                                                      */
+    POWERPC_DEF("755v2.1",     CPU_POWERPC_7x5_v21,     0xFFFFFFFF, 7x5),
+    /* PowerPC 745 v2.2                                                      */
+    POWERPC_DEF("745v2.2",     CPU_POWERPC_7x5_v22,     0xFFFFFFFF, 7x5),
+    /* PowerPC 755 v2.2                                                      */
+    POWERPC_DEF("755v2.2",     CPU_POWERPC_7x5_v22,     0xFFFFFFFF, 7x5),
+    /* PowerPC 745 v2.3                                                      */
+    POWERPC_DEF("745v2.3",     CPU_POWERPC_7x5_v23,     0xFFFFFFFF, 7x5),
+    /* PowerPC 755 v2.3                                                      */
+    POWERPC_DEF("755v2.3",     CPU_POWERPC_7x5_v23,     0xFFFFFFFF, 7x5),
+    /* PowerPC 745 v2.4                                                      */
+    POWERPC_DEF("745v2.4",     CPU_POWERPC_7x5_v24,     0xFFFFFFFF, 7x5),
+    /* PowerPC 755 v2.4                                                      */
+    POWERPC_DEF("755v2.4",     CPU_POWERPC_7x5_v24,     0xFFFFFFFF, 7x5),
+    /* PowerPC 745 v2.5                                                      */
+    POWERPC_DEF("745v2.5",     CPU_POWERPC_7x5_v25,     0xFFFFFFFF, 7x5),
+    /* PowerPC 755 v2.5                                                      */
+    POWERPC_DEF("755v2.5",     CPU_POWERPC_7x5_v25,     0xFFFFFFFF, 7x5),
+    /* PowerPC 745 v2.6                                                      */
+    POWERPC_DEF("745v2.6",     CPU_POWERPC_7x5_v26,     0xFFFFFFFF, 7x5),
+    /* PowerPC 755 v2.6                                                      */
+    POWERPC_DEF("755v2.6",     CPU_POWERPC_7x5_v26,     0xFFFFFFFF, 7x5),
+    /* PowerPC 745 v2.7                                                      */
+    POWERPC_DEF("745v2.7",     CPU_POWERPC_7x5_v27,     0xFFFFFFFF, 7x5),
+    /* PowerPC 755 v2.7                                                      */
+    POWERPC_DEF("755v2.7",     CPU_POWERPC_7x5_v27,     0xFFFFFFFF, 7x5),
+    /* PowerPC 745 v2.8                                                      */
+    POWERPC_DEF("745v2.8",     CPU_POWERPC_7x5_v28,     0xFFFFFFFF, 7x5),
+    /* PowerPC 755 v2.8                                                      */
+    POWERPC_DEF("755v2.8",     CPU_POWERPC_7x5_v28,     0xFFFFFFFF, 7x5),
+#if defined (TODO)
+    /* PowerPC 745P (G3)                                                     */
+    POWERPC_DEF("745p",        CPU_POWERPC_7x5P,        0xFFFFFFFF, 7x5),
+    /* PowerPC 755P (G3)                                                     */
+    POWERPC_DEF("755p",        CPU_POWERPC_7x5P,        0xFFFFFFFF, 7x5),
+#endif
+    /* PowerPC 74xx family                                                   */
+    /* PowerPC 7400 (G4)                                                     */
+    POWERPC_DEF("7400",        CPU_POWERPC_7400,        0xFFFFFFFF, 7400),
+    /* Code name for PowerPC 7400                                            */
+    POWERPC_DEF("Max",         CPU_POWERPC_7400,        0xFFFFFFFF, 7400),
+    /* PowerPC 74xx is also well known as G4                                 */
+    POWERPC_DEF("G4",          CPU_POWERPC_7400,        0xFFFFFFFF, 7400),
+    /* PowerPC 7400 v1.0 (G4)                                                */
+    POWERPC_DEF("7400v1.0",    CPU_POWERPC_7400_v10,    0xFFFFFFFF, 7400),
+    /* PowerPC 7400 v1.1 (G4)                                                */
+    POWERPC_DEF("7400v1.1",    CPU_POWERPC_7400_v11,    0xFFFFFFFF, 7400),
+    /* PowerPC 7400 v2.0 (G4)                                                */
+    POWERPC_DEF("7400v2.0",    CPU_POWERPC_7400_v20,    0xFFFFFFFF, 7400),
+    /* PowerPC 7400 v2.2 (G4)                                                */
+    POWERPC_DEF("7400v2.2",    CPU_POWERPC_7400_v22,    0xFFFFFFFF, 7400),
+    /* PowerPC 7400 v2.6 (G4)                                                */
+    POWERPC_DEF("7400v2.6",    CPU_POWERPC_7400_v26,    0xFFFFFFFF, 7400),
+    /* PowerPC 7400 v2.7 (G4)                                                */
+    POWERPC_DEF("7400v2.7",    CPU_POWERPC_7400_v27,    0xFFFFFFFF, 7400),
+    /* PowerPC 7400 v2.8 (G4)                                                */
+    POWERPC_DEF("7400v2.8",    CPU_POWERPC_7400_v28,    0xFFFFFFFF, 7400),
+    /* PowerPC 7400 v2.9 (G4)                                                */
+    POWERPC_DEF("7400v2.9",    CPU_POWERPC_7400_v29,    0xFFFFFFFF, 7400),
+    /* PowerPC 7410 (G4)                                                     */
+    POWERPC_DEF("7410",        CPU_POWERPC_7410,        0xFFFFFFFF, 7410),
+    /* Code name for PowerPC 7410                                            */
+    POWERPC_DEF("Nitro",       CPU_POWERPC_7410,        0xFFFFFFFF, 7410),
+    /* PowerPC 7410 v1.0 (G4)                                                */
+    POWERPC_DEF("7410v1.0",    CPU_POWERPC_7410_v10,    0xFFFFFFFF, 7410),
+    /* PowerPC 7410 v1.1 (G4)                                                */
+    POWERPC_DEF("7410v1.1",    CPU_POWERPC_7410_v11,    0xFFFFFFFF, 7410),
+    /* PowerPC 7410 v1.2 (G4)                                                */
+    POWERPC_DEF("7410v1.2",    CPU_POWERPC_7410_v12,    0xFFFFFFFF, 7410),
+    /* PowerPC 7410 v1.3 (G4)                                                */
+    POWERPC_DEF("7410v1.3",    CPU_POWERPC_7410_v13,    0xFFFFFFFF, 7410),
+    /* PowerPC 7410 v1.4 (G4)                                                */
+    POWERPC_DEF("7410v1.4",    CPU_POWERPC_7410_v14,    0xFFFFFFFF, 7410),
+    /* PowerPC 7448 (G4)                                                     */
+    POWERPC_DEF("7448",        CPU_POWERPC_7448,        0xFFFFFFFF, 7400),
+    /* PowerPC 7448 v1.0 (G4)                                                */
+    POWERPC_DEF("7448v1.0",    CPU_POWERPC_7448_v10,    0xFFFFFFFF, 7400),
+    /* PowerPC 7448 v1.1 (G4)                                                */
+    POWERPC_DEF("7448v1.1",    CPU_POWERPC_7448_v11,    0xFFFFFFFF, 7400),
+    /* PowerPC 7448 v2.0 (G4)                                                */
+    POWERPC_DEF("7448v2.0",    CPU_POWERPC_7448_v20,    0xFFFFFFFF, 7400),
+    /* PowerPC 7448 v2.1 (G4)                                                */
+    POWERPC_DEF("7448v2.1",    CPU_POWERPC_7448_v21,    0xFFFFFFFF, 7400),
+#if defined (TODO)
+    /* PowerPC 7450 (G4)                                                     */
+    POWERPC_DEF("7450",        CPU_POWERPC_7450,        0xFFFFFFFF, 7450),
+    /* Code name for PowerPC 7450                                            */
+    POWERPC_DEF("Vger",        CPU_POWERPC_7450,        0xFFFFFFFF, 7450),
+#endif
+#if defined (TODO)
+    /* PowerPC 7450 v1.0 (G4)                                                */
+    POWERPC_DEF("7450v1.0",    CPU_POWERPC_7450_v10,    0xFFFFFFFF, 7450),
+#endif
+#if defined (TODO)
+    /* PowerPC 7450 v1.1 (G4)                                                */
+    POWERPC_DEF("7450v1.1",    CPU_POWERPC_7450_v11,    0xFFFFFFFF, 7450),
+#endif
+#if defined (TODO)
+    /* PowerPC 7450 v1.2 (G4)                                                */
+    POWERPC_DEF("7450v1.2",    CPU_POWERPC_7450_v12,    0xFFFFFFFF, 7450),
+#endif
+#if defined (TODO)
+    /* PowerPC 7450 v2.0 (G4)                                                */
+    POWERPC_DEF("7450v2.0",    CPU_POWERPC_7450_v20,    0xFFFFFFFF, 7450),
+#endif
+#if defined (TODO)
+    /* PowerPC 7450 v2.1 (G4)                                                */
+    POWERPC_DEF("7450v2.1",    CPU_POWERPC_7450_v21,    0xFFFFFFFF, 7450),
+#endif
+#if defined (TODO)
+    /* PowerPC 7441 (G4)                                                     */
+    POWERPC_DEF("7441",        CPU_POWERPC_74x1,        0xFFFFFFFF, 7440),
+    /* PowerPC 7451 (G4)                                                     */
+    POWERPC_DEF("7451",        CPU_POWERPC_74x1,        0xFFFFFFFF, 7450),
+#endif
 #if defined (TODO)
-    /* PowerPC 405 EZ */
-    {
-        .name        = "405ez",
-        .pvr         = CPU_PPC_405EZ,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
+    /* PowerPC 7441g (G4)                                                    */
+    POWERPC_DEF("7441g",       CPU_POWERPC_74x1G,       0xFFFFFFFF, 7440),
+    /* PowerPC 7451g (G4)                                                    */
+    POWERPC_DEF("7451g",       CPU_POWERPC_74x1G,       0xFFFFFFFF, 7450),
 #endif
 #if defined (TODO)
-    /* PowerPC 405 GPR */
-    {
-        .name        = "405gpr",
-        .pvr         = CPU_PPC_405GPR,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
+    /* PowerPC 7445 (G4)                                                     */
+    POWERPC_DEF("7445",        CPU_POWERPC_74x5,        0xFFFFFFFF, 7445),
+    /* PowerPC 7455 (G4)                                                     */
+    POWERPC_DEF("7455",        CPU_POWERPC_74x5,        0xFFFFFFFF, 7455),
+    /* Code name for PowerPC 7445/7455                                       */
+    POWERPC_DEF("Apollo6",     CPU_POWERPC_74x5,        0xFFFFFFFF, 7455),
 #endif
 #if defined (TODO)
-    /* PowerPC 405 LP */
-    {
-        .name        = "405lp",
-        .pvr         = CPU_PPC_405EZ,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
-#endif
-    /* Npe405 H */
-    {
-        .name        = "Npe405H",
-        .pvr         = CPU_PPC_NPE405H,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
-    /* Npe405 H2 */
-    {
-        .name        = "Npe405H2",
-        .pvr         = CPU_PPC_NPE405H2,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
-    /* Npe405 L */
-    {
-        .name        = "Npe405L",
-        .pvr         = CPU_PPC_NPE405L,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
+    /* PowerPC 7445 v1.0 (G4)                                                */
+    POWERPC_DEF("7445v1.0",    CPU_POWERPC_74x5_v10,    0xFFFFFFFF, 7445),
+    /* PowerPC 7455 v1.0 (G4)                                                */
+    POWERPC_DEF("7455v1.0",    CPU_POWERPC_74x5_v10,    0xFFFFFFFF, 7455),
+#endif
 #if defined (TODO)
-    /* PowerPC LP777000 */
-    {
-        .name        = "lp777000",
-        .pvr         = CPU_PPC_LP777000,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
+    /* PowerPC 7445 v2.1 (G4)                                                */
+    POWERPC_DEF("7445v2.1",    CPU_POWERPC_74x5_v21,    0xFFFFFFFF, 7445),
+    /* PowerPC 7455 v2.1 (G4)                                                */
+    POWERPC_DEF("7455v2.1",    CPU_POWERPC_74x5_v21,    0xFFFFFFFF, 7455),
 #endif
 #if defined (TODO)
-    /* STB010000 */
-    {
-        .name        = "STB01000",
-        .pvr         = CPU_PPC_STB01000,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
+    /* PowerPC 7445 v3.2 (G4)                                                */
+    POWERPC_DEF("7445v3.2",    CPU_POWERPC_74x5_v32,    0xFFFFFFFF, 7445),
+    /* PowerPC 7455 v3.2 (G4)                                                */
+    POWERPC_DEF("7455v3.2",    CPU_POWERPC_74x5_v32,    0xFFFFFFFF, 7455),
 #endif
 #if defined (TODO)
-    /* STB01010 */
-    {
-        .name        = "STB01010",
-        .pvr         = CPU_PPC_STB01010,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
+    /* PowerPC 7445 v3.3 (G4)                                                */
+    POWERPC_DEF("7445v3.3",    CPU_POWERPC_74x5_v33,    0xFFFFFFFF, 7445),
+    /* PowerPC 7455 v3.3 (G4)                                                */
+    POWERPC_DEF("7455v3.3",    CPU_POWERPC_74x5_v33,    0xFFFFFFFF, 7455),
 #endif
 #if defined (TODO)
-    /* STB0210 */
-    {
-        .name        = "STB0210",
-        .pvr         = CPU_PPC_STB0210,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
+    /* PowerPC 7445 v3.4 (G4)                                                */
+    POWERPC_DEF("7445v3.4",    CPU_POWERPC_74x5_v34,    0xFFFFFFFF, 7445),
+    /* PowerPC 7455 v3.4 (G4)                                                */
+    POWERPC_DEF("7455v3.4",    CPU_POWERPC_74x5_v34,    0xFFFFFFFF, 7455),
 #endif
 #if defined (TODO)
-    /* STB03xx */
-    {
-        .name        = "STB03",
-        .pvr         = CPU_PPC_STB03,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
+    /* PowerPC 7447 (G4)                                                     */
+    POWERPC_DEF("7447",        CPU_POWERPC_74x7,        0xFFFFFFFF, 7445),
+    /* PowerPC 7457 (G4)                                                     */
+    POWERPC_DEF("7457",        CPU_POWERPC_74x7,        0xFFFFFFFF, 7455),
+    /* Code name for PowerPC 7447/7457                                       */
+    POWERPC_DEF("Apollo7",     CPU_POWERPC_74x7,        0xFFFFFFFF, 7455),
 #endif
 #if defined (TODO)
-    /* STB043x */
-    {
-        .name        = "STB043",
-        .pvr         = CPU_PPC_STB043,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
+    /* PowerPC 7447 v1.0 (G4)                                                */
+    POWERPC_DEF("7447v1.0",    CPU_POWERPC_74x7_v10,    0xFFFFFFFF, 7445),
+    /* PowerPC 7457 v1.0 (G4)                                                */
+    POWERPC_DEF("7457v1.0",    CPU_POWERPC_74x7_v10,    0xFFFFFFFF, 7455),
+    /* Code name for PowerPC 7447A/7457A                                     */
+    POWERPC_DEF("Apollo7PM",   CPU_POWERPC_74x7_v10,    0xFFFFFFFF, 7455),
 #endif
 #if defined (TODO)
-    /* STB045x */
-    {
-        .name        = "STB045",
-        .pvr         = CPU_PPC_STB045,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
-#endif
-#if defined (TODO) || 1
-    /* STB25xx */
-    {
-        .name        = "STB25",
-        .pvr         = CPU_PPC_STB25,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
+    /* PowerPC 7447 v1.1 (G4)                                                */
+    POWERPC_DEF("7447v1.1",    CPU_POWERPC_74x7_v11,    0xFFFFFFFF, 7445),
+    /* PowerPC 7457 v1.1 (G4)                                                */
+    POWERPC_DEF("7457v1.1",    CPU_POWERPC_74x7_v11,    0xFFFFFFFF, 7455),
 #endif
 #if defined (TODO)
-    /* STB130 */
-    {
-        .name        = "STB130",
-        .pvr         = CPU_PPC_STB130,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
-#endif
-    /* Xilinx PowerPC 405 cores */
+    /* PowerPC 7447 v1.2 (G4)                                                */
+    POWERPC_DEF("7447v1.2",    CPU_POWERPC_74x7_v12,    0xFFFFFFFF, 7445),
+    /* PowerPC 7457 v1.2 (G4)                                                */
+    POWERPC_DEF("7457v1.2",    CPU_POWERPC_74x7_v12,    0xFFFFFFFF, 7455),
+#endif
+    /* 64 bits PowerPC                                                       */
+#if defined (TARGET_PPC64)
 #if defined (TODO)
-    {
-        .name        = "x2vp4",
-        .pvr         = CPU_PPC_X2VP4,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
-    {
-        .name        = "x2vp7",
-        .pvr         = CPU_PPC_X2VP7,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
-    {
-        .name        = "x2vp20",
-        .pvr         = CPU_PPC_X2VP20,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
-    {
-        .name        = "x2vp50",
-        .pvr         = CPU_PPC_X2VP50,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_405,
-        .flags       = PPC_FLAGS_405,
-        .msr_mask    = 0x00000000020EFF30ULL,
-    },
-#endif
-    /* PowerPC 440 EP */
-    {
-        .name        = "440ep",
-        .pvr         = CPU_PPC_440EP,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_440,
-        .flags       = PPC_FLAGS_440,
-        .msr_mask    = 0x000000000006D630ULL,
-    },
-    /* PowerPC 440 GR */
-    {
-        .name        = "440gr",
-        .pvr         = CPU_PPC_440GR,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_440,
-        .flags       = PPC_FLAGS_440,
-        .msr_mask    = 0x000000000006D630ULL,
-    },
-    /* PowerPC 440 GP */
-    {
-        .name        = "440gp",
-        .pvr         = CPU_PPC_440GP,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_440,
-        .flags       = PPC_FLAGS_440,
-        .msr_mask    = 0x000000000006D630ULL,
-    },
+    /* PowerPC 620                                                           */
+    POWERPC_DEF("620",         CPU_POWERPC_620,         0xFFFFFFFF, 620),
+#endif
 #if defined (TODO)
-    /* PowerPC 440 GRX */
-    {
-        .name        = "440grx",
-        .pvr         = CPU_PPC_440GRX,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_440,
-        .flags       = PPC_FLAGS_440,
-        .msr_mask    = 0x000000000006D630ULL,
-    },
-#endif
-    /* PowerPC 440 GX */
-    {
-        .name        = "440gx",
-        .pvr         = CPU_PPC_440GX,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_440,
-        .flags       = PPC_FLAGS_440,
-        .msr_mask    = 0x000000000006D630ULL,
-    },
-    /* PowerPC 440 GXc */
-    {
-        .name        = "440gxc",
-        .pvr         = CPU_PPC_440GXc,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_440,
-        .flags       = PPC_FLAGS_440,
-        .msr_mask    = 0x000000000006D630ULL,
-    },
-    /* PowerPC 440 GXf */
-    {
-        .name        = "440gxf",
-        .pvr         = CPU_PPC_440GXf,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_440,
-        .flags       = PPC_FLAGS_440,
-        .msr_mask    = 0x000000000006D630ULL,
-    },
-    /* PowerPC 440 SP */
-    {
-        .name        = "440sp",
-        .pvr         = CPU_PPC_440SP,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_440,
-        .flags       = PPC_FLAGS_440,
-        .msr_mask    = 0x000000000006D630ULL,
-    },
-    /* PowerPC 440 SP2 */
-    {
-        .name        = "440sp2",
-        .pvr         = CPU_PPC_440SP2,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_440,
-        .flags       = PPC_FLAGS_440,
-        .msr_mask    = 0x000000000006D630ULL,
-    },
-    /* PowerPC 440 SPE */
-    {
-        .name        = "440spe",
-        .pvr         = CPU_PPC_440SPE,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_440,
-        .flags       = PPC_FLAGS_440,
-        .msr_mask    = 0x000000000006D630ULL,
-    },
-    /* Fake generic BookE PowerPC */
-    {
-        .name        = "BookE",
-        .pvr         = CPU_PPC_e500,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_BOOKE,
-        .flags       = PPC_FLAGS_BOOKE,
-        .msr_mask    = 0x000000000006D630ULL,
-    },
-    /* PowerPC 460 cores - TODO */
-    /* PowerPC MPC 5xx cores - TODO */
-    /* PowerPC MPC 8xx cores - TODO */
-    /* PowerPC MPC 8xxx cores - TODO */
-    /* e200 cores - TODO */
-    /* e500 cores - TODO */
-    /* e600 cores - TODO */
-
-    /* 32 bits "classic" PowerPC */
+    /* PowerPC 630 (POWER3)                                                  */
+    POWERPC_DEF("630",         CPU_POWERPC_630,         0xFFFFFFFF, 630),
+    POWERPC_DEF("POWER3",      CPU_POWERPC_630,         0xFFFFFFFF, 630),
+#endif
 #if defined (TODO)
-    /* PowerPC 601 */
-    {
-        .name        = "601",
-        .pvr         = CPU_PPC_601,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_601,
-        .flags       = PPC_FLAGS_601,
-        .msr_mask    = 0x000000000000FD70ULL,
-    },
+    /* PowerPC 631 (Power 3+)                                                */
+    POWERPC_DEF("631",         CPU_POWERPC_631,         0xFFFFFFFF, 631),
+    POWERPC_DEF("POWER3+",     CPU_POWERPC_631,         0xFFFFFFFF, 631),
 #endif
 #if defined (TODO)
-    /* PowerPC 602 */
-    {
-        .name        = "602",
-        .pvr         = CPU_PPC_602,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_602,
-        .flags       = PPC_FLAGS_602,
-        .msr_mask    = 0x0000000000C7FF73ULL,
-    },
-#endif
-    /* PowerPC 603 */
-    {
-        .name        = "603",
-        .pvr         = CPU_PPC_603,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_603,
-        .flags       = PPC_FLAGS_603,
-        .msr_mask    = 0x000000000007FF73ULL,
-    },
-    /* PowerPC 603e */
-    {
-        .name        = "603e",
-        .pvr         = CPU_PPC_603E,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_603,
-        .flags       = PPC_FLAGS_603,
-        .msr_mask    = 0x000000000007FF73ULL,
-    },
-    {
-        .name        = "Stretch",
-        .pvr         = CPU_PPC_603E,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_603,
-        .flags       = PPC_FLAGS_603,
-        .msr_mask    = 0x000000000007FF73ULL,
-    },
-    /* PowerPC 603p */
-    {
-        .name        = "603p",
-        .pvr         = CPU_PPC_603P,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_603,
-        .flags       = PPC_FLAGS_603,
-        .msr_mask    = 0x000000000007FF73ULL,
-    },
-    /* PowerPC 603e7 */
-    {
-        .name        = "603e7",
-        .pvr         = CPU_PPC_603E7,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_603,
-        .flags       = PPC_FLAGS_603,
-        .msr_mask    = 0x000000000007FF73ULL,
-    },
-    /* PowerPC 603e7v */
-    {
-        .name        = "603e7v",
-        .pvr         = CPU_PPC_603E7v,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_603,
-        .flags       = PPC_FLAGS_603,
-        .msr_mask    = 0x000000000007FF73ULL,
-    },
-    /* PowerPC 603e7v2 */
-    {
-        .name        = "603e7v2",
-        .pvr         = CPU_PPC_603E7v2,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_603,
-        .flags       = PPC_FLAGS_603,
-        .msr_mask    = 0x000000000007FF73ULL,
-    },
-    /* PowerPC 603r */
-    {
-        .name        = "603r",
-        .pvr         = CPU_PPC_603R,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_603,
-        .flags       = PPC_FLAGS_603,
-        .msr_mask    = 0x000000000007FF73ULL,
-    },
-    {
-        .name        = "Goldeneye",
-        .pvr         = CPU_PPC_603R,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_603,
-        .flags       = PPC_FLAGS_603,
-        .msr_mask    = 0x000000000007FF73ULL,
-    },
+    /* POWER4                                                                */
+    POWERPC_DEF("POWER4",      CPU_POWERPC_POWER4,      0xFFFFFFFF, POWER4),
+#endif
 #if defined (TODO)
-    /* XXX: TODO: according to Motorola UM, this is a derivative to 603e */
-    {
-        .name        = "G2",
-        .pvr         = CPU_PPC_G2,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_G2,
-        .flags       = PPC_FLAGS_G2,
-        .msr_mask    = 0x000000000006FFF2ULL,
-    },
-    {
-        .name        = "G2h4",
-        .pvr         = CPU_PPC_G2H4,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_G2,
-        .flags       = PPC_FLAGS_G2,
-        .msr_mask    = 0x000000000006FFF2ULL,
-    },
-    {
-        .name        = "G2gp",
-        .pvr         = CPU_PPC_G2gp,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_G2,
-        .flags       = PPC_FLAGS_G2,
-        .msr_mask    = 0x000000000006FFF2ULL,
-    },
-    {
-        .name        = "G2ls",
-        .pvr         = CPU_PPC_G2ls,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_G2,
-        .flags       = PPC_FLAGS_G2,
-        .msr_mask    = 0x000000000006FFF2ULL,
-    },
-    { /* Same as G2, with LE mode support */
-        .name        = "G2le",
-        .pvr         = CPU_PPC_G2LE,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_G2,
-        .flags       = PPC_FLAGS_G2,
-        .msr_mask    = 0x000000000007FFF3ULL,
-    },
-    {
-        .name        = "G2legp",
-        .pvr         = CPU_PPC_G2LEgp,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_G2,
-        .flags       = PPC_FLAGS_G2,
-        .msr_mask    = 0x000000000007FFF3ULL,
-    },
-    {
-        .name        = "G2lels",
-        .pvr         = CPU_PPC_G2LEls,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_G2,
-        .flags       = PPC_FLAGS_G2,
-        .msr_mask    = 0x000000000007FFF3ULL,
-    },
-#endif
-    /* PowerPC 604 */
-    {
-        .name        = "604",
-        .pvr         = CPU_PPC_604,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_604,
-        .flags       = PPC_FLAGS_604,
-        .msr_mask    = 0x000000000005FF77ULL,
-    },
-    /* PowerPC 604e */
-    {
-        .name        = "604e",
-        .pvr         = CPU_PPC_604E,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_604,
-        .flags       = PPC_FLAGS_604,
-        .msr_mask    = 0x000000000005FF77ULL,
-    },
-    /* PowerPC 604r */
-    {
-        .name        = "604r",
-        .pvr         = CPU_PPC_604R,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_604,
-        .flags       = PPC_FLAGS_604,
-        .msr_mask    = 0x000000000005FF77ULL,
-    },
-    /* generic G3 */
-    {
-        .name        = "G3",
-        .pvr         = CPU_PPC_74x,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x0,
-        .flags       = PPC_FLAGS_7x0,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
-    /* MPC740 (G3) */
-    {
-        .name        = "740",
-        .pvr         = CPU_PPC_74x,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x0,
-        .flags       = PPC_FLAGS_7x0,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
-    {
-        .name        = "Arthur",
-        .pvr         = CPU_PPC_74x,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x0,
-        .flags       = PPC_FLAGS_7x0,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
-    /* 740E (G3) */
-    {
-        .name        = "740e",
-        .pvr         = CPU_PPC_740E,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x0,
-        .flags       = PPC_FLAGS_7x0,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
-    /* MPC740P (G3) */
-    {
-        .name        = "740p",
-        .pvr         = CPU_PPC_74xP,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x0,
-        .flags       = PPC_FLAGS_7x0,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
-    {
-        .name        = "Conan/Doyle",
-        .pvr         = CPU_PPC_74xP,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x0,
-        .flags       = PPC_FLAGS_7x0,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
+    /* POWER4p                                                               */
+    POWERPC_DEF("POWER4+",     CPU_POWERPC_POWER4P,     0xFFFFFFFF, POWER4P),
+#endif
 #if defined (TODO)
-    /* MPC745 (G3) */
-    {
-        .name        = "745",
-        .pvr         = CPU_PPC_74x,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x5,
-        .flags       = PPC_FLAGS_7x5,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
-    {
-        .name        = "Goldfinger",
-        .pvr         = CPU_PPC_74x,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x5,
-        .flags       = PPC_FLAGS_7x5,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
+    /* POWER5                                                                */
+    POWERPC_DEF("POWER5",      CPU_POWERPC_POWER5,      0xFFFFFFFF, POWER5),
+    /* POWER5GR                                                              */
+    POWERPC_DEF("POWER5gr",    CPU_POWERPC_POWER5GR,    0xFFFFFFFF, POWER5),
 #endif
 #if defined (TODO)
-    /* MPC745P (G3) */
-    {
-        .name        = "745p",
-        .pvr         = CPU_PPC_74xP,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x5,
-        .flags       = PPC_FLAGS_7x5,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
-#endif
-    /* MPC750 (G3) */
-    {
-        .name        = "750",
-        .pvr         = CPU_PPC_74x,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x0,
-        .flags       = PPC_FLAGS_7x0,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
-    /* MPC750P (G3) */
-    {
-        .name        = "750p",
-        .pvr         = CPU_PPC_74xP,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x0,
-        .flags       = PPC_FLAGS_7x0,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
-    /* 750E (G3) */
-    {
-        .name        = "750e",
-        .pvr         = CPU_PPC_750E,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x0,
-        .flags       = PPC_FLAGS_7x0,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
-    /* IBM 750CXe (G3 embedded) */
-    {
-        .name        = "750cxe",
-        .pvr         = CPU_PPC_750CXE,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x0,
-        .flags       = PPC_FLAGS_7x0,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
-    /* IBM 750CXr (G3 embedded) */
-    {
-        .name        = "750cxr",
-        .pvr         = CPU_PPC_750CXR,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x0,
-        .flags       = PPC_FLAGS_7x0,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
-    /* IBM 750FX (G3 embedded) */
-    {
-        .name        = "750fx",
-        .pvr         = CPU_PPC_750FX,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x0,
-        .flags       = PPC_FLAGS_7x0,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
-    /* IBM 750FL (G3 embedded) */
-    {
-        .name        = "750fl",
-        .pvr         = CPU_PPC_750FL,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x0,
-        .flags       = PPC_FLAGS_7x0,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
-    /* IBM 750GX (G3 embedded) */
-    {
-        .name        = "750gx",
-        .pvr         = CPU_PPC_750GX,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x0,
-        .flags       = PPC_FLAGS_7x0,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
-    /* IBM 750L (G3 embedded) */
-    {
-        .name        = "750l",
-        .pvr         = CPU_PPC_750L,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x0,
-        .flags       = PPC_FLAGS_7x0,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
-    /* IBM 750CL (G3 embedded) */
-    {
-        .name        = "750cl",
-        .pvr         = CPU_PPC_750CL,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x0,
-        .flags       = PPC_FLAGS_7x0,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
+    /* POWER5+                                                               */
+    POWERPC_DEF("POWER5+",     CPU_POWERPC_POWER5P,     0xFFFFFFFF, POWER5P),
+    /* POWER5GS                                                              */
+    POWERPC_DEF("POWER5gs",    CPU_POWERPC_POWER5GS,    0xFFFFFFFF, POWER5P),
+#endif
 #if defined (TODO)
-    /* MPC755 (G3) */
-    {
-        .name        = "755",
-        .pvr         = CPU_PPC_755,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x5,
-        .flags       = PPC_FLAGS_7x5,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
+    /* POWER6                                                                */
+    POWERPC_DEF("POWER6",      CPU_POWERPC_POWER6,      0xFFFFFFFF, POWER6),
+    /* POWER6 running in POWER5 mode                                         */
+    POWERPC_DEF("POWER6_5",    CPU_POWERPC_POWER6_5,    0xFFFFFFFF, POWER5),
+    /* POWER6A                                                               */
+    POWERPC_DEF("POWER6A",     CPU_POWERPC_POWER6A,     0xFFFFFFFF, POWER6),
 #endif
 #if defined (TODO)
-    /* MPC755D (G3) */
-    {
-        .name        = "755d",
-        .pvr         = CPU_PPC_755D,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x5,
-        .flags       = PPC_FLAGS_7x5,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
+    /* PowerPC 970                                                           */
+    POWERPC_DEF("970",         CPU_POWERPC_970,         0xFFFFFFFF, 970),
 #endif
 #if defined (TODO)
-    /* MPC755E (G3) */
-    {
-        .name        = "755e",
-        .pvr         = CPU_PPC_755E,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x5,
-        .flags       = PPC_FLAGS_7x5,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
+    /* PowerPC 970FX (G5)                                                    */
+    POWERPC_DEF("970fx",       CPU_POWERPC_970FX,       0xFFFFFFFF, 970FX),
 #endif
 #if defined (TODO)
-    /* MPC755P (G3) */
-    {
-        .name        = "755p",
-        .pvr         = CPU_PPC_74xP,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_7x5,
-        .flags       = PPC_FLAGS_7x5,
-        .msr_mask    = 0x000000000007FF77ULL,
-    },
+    /* PowerPC 970FX v1.0 (G5)                                               */
+    POWERPC_DEF("970fx1.0",    CPU_POWERPC_970FX_v10,   0xFFFFFFFF, 970FX),
 #endif
 #if defined (TODO)
-    /* generic G4 */
-    {
-        .name        = "G4",
-        .pvr         = CPU_PPC_7400,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* PowerPC 970FX v2.0 (G5)                                               */
+    POWERPC_DEF("970fx2.0",    CPU_POWERPC_970FX_v20,   0xFFFFFFFF, 970FX),
 #endif
 #if defined (TODO)
-    /* PowerPC 7400 (G4) */
-    {
-        .name        = "7400",
-        .pvr         = CPU_PPC_7400,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
-    {
-        .name        = "Max",
-        .pvr         = CPU_PPC_7400,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* PowerPC 970FX v2.1 (G5)                                               */
+    POWERPC_DEF("970fx2.1",    CPU_POWERPC_970FX_v21,   0xFFFFFFFF, 970FX),
 #endif
 #if defined (TODO)
-    /* PowerPC 7410 (G4) */
-    {
-        .name        = "7410",
-        .pvr         = CPU_PPC_7410,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
-    {
-        .name        = "Nitro",
-        .pvr         = CPU_PPC_7410,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* PowerPC 970FX v3.0 (G5)                                               */
+    POWERPC_DEF("970fx3.0",    CPU_POWERPC_970FX_v30,   0xFFFFFFFF, 970FX),
 #endif
 #if defined (TODO)
-    /* PowerPC 7441 (G4) */
-    {
-        .name        = "7441",
-        .pvr         = CPU_PPC_7441,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* PowerPC 970FX v3.1 (G5)                                               */
+    POWERPC_DEF("970fx3.1",    CPU_POWERPC_970FX_v31,   0xFFFFFFFF, 970FX),
 #endif
 #if defined (TODO)
-    /* PowerPC 7445 (G4) */
-    {
-        .name        = "7445",
-        .pvr         = CPU_PPC_7445,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* PowerPC 970GX (G5)                                                    */
+    POWERPC_DEF("970gx",       CPU_POWERPC_970GX,       0xFFFFFFFF, 970GX),
 #endif
 #if defined (TODO)
-    /* PowerPC 7447 (G4) */
-    {
-        .name        = "7447",
-        .pvr         = CPU_PPC_7447,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* PowerPC 970MP                                                         */
+    POWERPC_DEF("970mp",       CPU_POWERPC_970MP,       0xFFFFFFFF, 970),
 #endif
 #if defined (TODO)
-    /* PowerPC 7447A (G4) */
-    {
-        .name        = "7447A",
-        .pvr         = CPU_PPC_7447A,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* PowerPC 970MP v1.0                                                    */
+    POWERPC_DEF("970mp1.0",    CPU_POWERPC_970MP_v10,   0xFFFFFFFF, 970),
 #endif
 #if defined (TODO)
-    /* PowerPC 7448 (G4) */
-    {
-        .name        = "7448",
-        .pvr         = CPU_PPC_7448,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* PowerPC 970MP v1.1                                                    */
+    POWERPC_DEF("970mp1.1",    CPU_POWERPC_970MP_v11,   0xFFFFFFFF, 970),
 #endif
 #if defined (TODO)
-    /* PowerPC 7450 (G4) */
-    {
-        .name        = "7450",
-        .pvr         = CPU_PPC_7450,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
-    {
-        .name        = "Vger",
-        .pvr         = CPU_PPC_7450,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* PowerPC Cell                                                          */
+    POWERPC_DEF("Cell",        CPU_POWERPC_CELL,        0xFFFFFFFF, 970),
 #endif
 #if defined (TODO)
-    /* PowerPC 7450b (G4) */
-    {
-        .name        = "7450b",
-        .pvr         = CPU_PPC_7450B,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* PowerPC Cell v1.0                                                     */
+    POWERPC_DEF("Cell1.0",     CPU_POWERPC_CELL_v10,    0xFFFFFFFF, 970),
 #endif
 #if defined (TODO)
-    /* PowerPC 7451 (G4) */
-    {
-        .name        = "7451",
-        .pvr         = CPU_PPC_7451,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* PowerPC Cell v2.0                                                     */
+    POWERPC_DEF("Cell2.0",     CPU_POWERPC_CELL_v20,    0xFFFFFFFF, 970),
 #endif
 #if defined (TODO)
-    /* PowerPC 7451g (G4) */
-    {
-        .name        = "7451g",
-        .pvr         = CPU_PPC_7451G,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* PowerPC Cell v3.0                                                     */
+    POWERPC_DEF("Cell3.0",     CPU_POWERPC_CELL_v30,    0xFFFFFFFF, 970),
 #endif
 #if defined (TODO)
-    /* PowerPC 7455 (G4) */
-    {
-        .name        = "7455",
-        .pvr         = CPU_PPC_7455,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
-    {
-        .name        = "Apollo 6",
-        .pvr         = CPU_PPC_7455,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* PowerPC Cell v3.1                                                     */
+    POWERPC_DEF("Cell3.1",     CPU_POWERPC_CELL_v31,    0xFFFFFFFF, 970),
 #endif
 #if defined (TODO)
-    /* PowerPC 7455F (G4) */
-    {
-        .name        = "7455f",
-        .pvr         = CPU_PPC_7455F,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* PowerPC Cell v3.2                                                     */
+    POWERPC_DEF("Cell3.2",     CPU_POWERPC_CELL_v32,    0xFFFFFFFF, 970),
 #endif
 #if defined (TODO)
-    /* PowerPC 7455G (G4) */
-    {
-        .name        = "7455g",
-        .pvr         = CPU_PPC_7455G,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* RS64 (Apache/A35)                                                     */
+    /* 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,        0xFFFFFFFF, RS64),
+    POWERPC_DEF("Apache",      CPU_POWERPC_RS64,        0xFFFFFFFF, RS64),
+    POWERPC_DEF("A35",         CPU_POWERPC_RS64,        0xFFFFFFFF, RS64),
 #endif
 #if defined (TODO)
-    /* PowerPC 7457 (G4) */
-    {
-        .name        = "7457",
-        .pvr         = CPU_PPC_7457,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
-    {
-        .name        = "Apollo 7",
-        .pvr         = CPU_PPC_7457,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* RS64-II (NorthStar/A50)                                               */
+    POWERPC_DEF("RS64-II",     CPU_POWERPC_RS64II,      0xFFFFFFFF, RS64),
+    POWERPC_DEF("NorthStar",   CPU_POWERPC_RS64II,      0xFFFFFFFF, RS64),
+    POWERPC_DEF("A50",         CPU_POWERPC_RS64II,      0xFFFFFFFF, RS64),
 #endif
 #if defined (TODO)
-    /* PowerPC 7457A (G4) */
-    {
-        .name        = "7457A",
-        .pvr         = CPU_PPC_7457A,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
-    {
-        .name        = "Apollo 7 PM",
-        .pvr         = CPU_PPC_7457A,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* RS64-III (Pulsar)                                                     */
+    POWERPC_DEF("RS64-III",    CPU_POWERPC_RS64III,     0xFFFFFFFF, RS64),
+    POWERPC_DEF("Pulsar",      CPU_POWERPC_RS64III,     0xFFFFFFFF, RS64),
 #endif
 #if defined (TODO)
-    /* PowerPC 7457C (G4) */
-    {
-        .name        = "7457c",
-        .pvr         = CPU_PPC_7457C,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_74xx,
-        .flags       = PPC_FLAGS_74xx,
-        .msr_mask    = 0x000000000205FF77ULL,
-    },
+    /* RS64-IV (IceStar/IStar/SStar)                                         */
+    POWERPC_DEF("RS64-IV",     CPU_POWERPC_RS64IV,      0xFFFFFFFF, RS64),
+    POWERPC_DEF("IceStar",     CPU_POWERPC_RS64IV,      0xFFFFFFFF, RS64),
+    POWERPC_DEF("IStar",       CPU_POWERPC_RS64IV,      0xFFFFFFFF, RS64),
+    POWERPC_DEF("SStar",       CPU_POWERPC_RS64IV,      0xFFFFFFFF, RS64),
 #endif
-    /* 64 bits PowerPC */
-#if defined (TARGET_PPC64)
+#endif /* defined (TARGET_PPC64) */
+    /* POWER                                                                 */
 #if defined (TODO)
-    /* PowerPC 620 */
-    {
-        .name        = "620",
-        .pvr         = CPU_PPC_620,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_620,
-        .flags       = PPC_FLAGS_620,
-        .msr_mask    = 0x800000000005FF73ULL,
-    },
+    /* Original POWER                                                        */
+    POWERPC_DEF("POWER",       CPU_POWERPC_POWER,       0xFFFFFFFF, POWER),
+    POWERPC_DEF("RIOS",        CPU_POWERPC_POWER,       0xFFFFFFFF, POWER),
+    POWERPC_DEF("RSC",         CPU_POWERPC_POWER,       0xFFFFFFFF, POWER),
+    POWERPC_DEF("RSC3308",     CPU_POWERPC_POWER,       0xFFFFFFFF, POWER),
+    POWERPC_DEF("RSC4608",     CPU_POWERPC_POWER,       0xFFFFFFFF, POWER),
 #endif
 #if defined (TODO)
-    /* PowerPC 630 (POWER3) */
-    {
-        .name        = "630",
-        .pvr         = CPU_PPC_630,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_630,
-        .flags       = PPC_FLAGS_630,
-        .msr_mask    = xxx,
+    /* POWER2                                                                */
+    POWERPC_DEF("POWER2",      CPU_POWERPC_POWER2,      0xFFFFFFFF, POWER),
+    POWERPC_DEF("RSC2",        CPU_POWERPC_POWER2,      0xFFFFFFFF, POWER),
+    POWERPC_DEF("P2SC",        CPU_POWERPC_POWER2,      0xFFFFFFFF, POWER),
+#endif
+    /* PA semi cores                                                         */
+#if defined (TODO)
+    /* PA PA6T */
+    POWERPC_DEF("PA6T",        CPU_POWERPC_PA6T,        0xFFFFFFFF, PA6T),
+#endif
+    /* Generic PowerPCs                                                      */
+#if defined (TARGET_PPC64)
+#if defined (TODO)
+    POWERPC_DEF("ppc64",       CPU_POWERPC_PPC64,       0xFFFFFFFF, PPC64),
+#endif
+#endif
+    POWERPC_DEF("ppc32",       CPU_POWERPC_PPC32,       0xFFFFFFFF, PPC32),
+    /* Fallback                                                              */
+    POWERPC_DEF("ppc",         CPU_POWERPC_PPC,         0xFFFFFFFF, PPC),
+};
+
+/*****************************************************************************/
+/* Generic CPU instanciation routine                                         */
+static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def)
+{
+#if !defined(CONFIG_USER_ONLY)
+    env->irq_inputs = NULL;
+#endif
+    /* Default MMU definitions */
+    env->nb_BATs = 0;
+    env->nb_tlb = 0;
+    env->nb_ways = 0;
+    /* Register SPR common to all PowerPC implementations */
+    gen_spr_generic(env);
+    spr_register(env, SPR_PVR, "PVR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, SPR_NOACCESS,
+                 def->pvr);
+    /* PowerPC implementation specific initialisations (SPRs, timers, ...) */
+    (*def->init_proc)(env);
+    /* Allocate TLBs buffer when needed */
+    if (env->nb_tlb != 0) {
+        int nb_tlb = env->nb_tlb;
+        if (env->id_tlbs != 0)
+            nb_tlb *= 2;
+        env->tlb = qemu_mallocz(nb_tlb * sizeof(ppc_tlb_t));
+        /* Pre-compute some useful values */
+        env->tlb_per_way = env->nb_tlb / env->nb_ways;
+    }
+#if !defined(CONFIG_USER_ONLY)
+    if (env->irq_inputs == NULL) {
+        fprintf(stderr, "WARNING: no internal IRQ controller registered.\n"
+                " Attempt Qemu to crash very soon !\n");
+    }
+#endif
+}
+
+#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
+
+/*****************************************************************************/
+#include <stdlib.h>
+#include <string.h>
+
+int fflush (FILE *stream);
+
+/* Opcode types */
+enum {
+    PPC_DIRECT   = 0, /* Opcode routine        */
+    PPC_INDIRECT = 1, /* Indirect opcode table */
+};
+
+static inline int is_indirect_opcode (void *handler)
+{
+    return ((unsigned long)handler & 0x03) == PPC_INDIRECT;
+}
+
+static inline opc_handler_t **ind_table(void *handler)
+{
+    return (opc_handler_t **)((unsigned long)handler & ~3);
+}
+
+/* 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 = malloc(0x20 * sizeof(opc_handler_t));
+    if (tmp == NULL)
+        return -1;
+    fill_new_table(tmp, 0x20);
+    table[idx] = (opc_handler_t *)((unsigned long)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);
+        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);
+            return -1;
+        }
     }
-    {
-        .name        = "POWER3",
-        .pvr         = CPU_PPC_630,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_630,
-        .flags       = PPC_FLAGS_630,
-        .msr_mask    = xxx,
+    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);
+        return -1;
     }
+
+    return 0;
+}
+
+static int register_ind_insn (opc_handler_t **ppc_opcodes,
+                              unsigned char idx1, unsigned char idx2,
+                              opc_handler_t *handler)
+{
+    int ret;
+
+    ret = register_ind_in_table(ppc_opcodes, idx1, idx2, handler);
+
+    return ret;
+}
+
+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_insn (opc_handler_t **ppc_opcodes, opcode_t *insn)
+{
+    if (insn->opc2 != 0xFF) {
+        if (insn->opc3 != 0xFF) {
+            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]), 0x20);
+                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, 0x40) == 0)
+        printf("*** WARNING: no opcode defined !\n");
+}
+
+/*****************************************************************************/
+static int create_ppc_opcodes (CPUPPCState *env, ppc_def_t *def)
+{
+    opcode_t *opc, *start, *end;
+
+    fill_new_table(env->opcodes, 0x40);
+    if (&opc_start < &opc_end) {
+        start = &opc_start;
+        end = &opc_end;
+    } else {
+        start = &opc_end;
+        end = &opc_start;
+    }
+    for (opc = start + 1; opc != end; opc++) {
+        if ((opc->handler.type & def->insns_flags) != 0) {
+            if (register_insn(env->opcodes, opc) < 0) {
+                printf("*** ERROR initializing PowerPC instruction "
+                       "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2,
+                       opc->opc3);
+                return -1;
+            }
+        }
+    }
+    fix_opcode_tables(env->opcodes);
+    fflush(stdout);
+    fflush(stderr);
+
+    return 0;
+}
+
+#if defined(PPC_DUMP_CPU)
+static int dump_ppc_insns (CPUPPCState *env)
+{
+    opc_handler_t **table, *handler;
+    uint8_t opc1, opc2, opc3;
+
+    printf("Instructions set:\n");
+    /* opc1 is 6 bits long */
+    for (opc1 = 0x00; opc1 < 0x40; opc1++) {
+        table = env->opcodes;
+        handler = table[opc1];
+        if (is_indirect_opcode(handler)) {
+            /* opc2 is 5 bits long */
+            for (opc2 = 0; opc2 < 0x20; 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 < 0x20; opc3++) {
+                        handler = table[opc3];
+                        if (handler->handler != &gen_invalid) {
+                            printf("INSN: %02x %02x %02x (%02d %04d) : %s\n",
+                                   opc1, opc2, opc3, opc1, (opc3 << 5) | opc2,
+                                   handler->oname);
+                        }
+                    }
+                } 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
-#if defined (TODO)
-    /* PowerPC 631 (Power 3+)*/
-    {
-        .name        = "631",
-        .pvr         = CPU_PPC_631,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_631,
-        .flags       = PPC_FLAGS_631,
-        .msr_mask    = xxx,
-    },
-    {
-        .name        = "POWER3+",
-        .pvr         = CPU_PPC_631,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_631,
-        .flags       = PPC_FLAGS_631,
-        .msr_mask    = xxx,
-    },
-#endif
-#if defined (TODO)
-    /* POWER4 */
-    {
-        .name        = "POWER4",
-        .pvr         = CPU_PPC_POWER4,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_POWER4,
-        .flags       = PPC_FLAGS_POWER4,
-        .msr_mask    = xxx,
-    },
-#endif
-#if defined (TODO)
-    /* POWER4p */
-    {
-        .name        = "POWER4+",
-        .pvr         = CPU_PPC_POWER4P,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_POWER4,
-        .flags       = PPC_FLAGS_POWER4,
-        .msr_mask    = xxx,
-    },
-#endif
-#if defined (TODO)
-    /* POWER5 */
-    {
-        .name        = "POWER5",
-        .pvr         = CPU_PPC_POWER5,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_POWER5,
-        .flags       = PPC_FLAGS_POWER5,
-        .msr_mask    = xxx,
-    },
-#endif
-#if defined (TODO)
-    /* POWER5+ */
-    {
-        .name        = "POWER5+",
-        .pvr         = CPU_PPC_POWER5P,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_POWER5,
-        .flags       = PPC_FLAGS_POWER5,
-        .msr_mask    = xxx,
-    },
-#endif
-#if defined (TODO)
-    /* POWER6 */
-    {
-        .name        = "POWER6",
-        .pvr         = CPU_PPC_POWER6,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_POWER6,
-        .flags       = PPC_FLAGS_POWER6,
-        .msr_mask    = xxx,
-    },
-#endif
-#if defined (TODO)
-    /* PowerPC 970 */
-    {
-        .name        = "970",
-        .pvr         = CPU_PPC_970,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_970,
-        .flags       = PPC_FLAGS_970,
-        .msr_mask    = 0x900000000204FF36ULL,
-    },
-#endif
-#if defined (TODO)
-    /* PowerPC 970FX (G5) */
-    {
-        .name        = "970fx",
-        .pvr         = CPU_PPC_970FX,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_970FX,
-        .flags       = PPC_FLAGS_970FX,
-        .msr_mask    = 0x800000000204FF36ULL,
-    },
-#endif
-#if defined (TODO)
-    /* PowerPC 970MP */
-    {
-        .name        = "970MP",
-        .pvr         = CPU_PPC_970MP,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_970,
-        .flags       = PPC_FLAGS_970,
-        .msr_mask    = 0x900000000204FF36ULL,
-    },
-#endif
-#if defined (TODO)
-    /* PowerPC Cell */
-    {
-        .name        = "Cell",
-        .pvr         = CPU_PPC_CELL,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_970,
-        .flags       = PPC_FLAGS_970,
-        .msr_mask    = 0x900000000204FF36ULL,
-    },
-#endif
-#if defined (TODO)
-    /* RS64 (Apache/A35) */
-    /* This one seems to support the whole POWER2 instruction set
-     * and the PowerPC 64 one.
-     */
-    {
-        .name        = "RS64",
-        .pvr         = CPU_PPC_RS64,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_RS64,
-        .flags       = PPC_FLAGS_RS64,
-        .msr_mask    = xxx,
-    },
-    {
-        .name        = "Apache",
-        .pvr         = CPU_PPC_RS64,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_RS64,
-        .flags       = PPC_FLAGS_RS64,
-        .msr_mask    = xxx,
-    },
-    {
-        .name        = "A35",
-        .pvr         = CPU_PPC_RS64,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_RS64,
-        .flags       = PPC_FLAGS_RS64,
-        .msr_mask    = xxx,
-    },
-#endif
-#if defined (TODO)
-    /* RS64-II (NorthStar/A50) */
-    {
-        .name        = "RS64-II",
-        .pvr         = CPU_PPC_RS64II,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_RS64,
-        .flags       = PPC_FLAGS_RS64,
-        .msr_mask    = xxx,
-    },
-    {
-        .name        = "NortStar",
-        .pvr         = CPU_PPC_RS64II,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_RS64,
-        .flags       = PPC_FLAGS_RS64,
-        .msr_mask    = xxx,
-    },
-    {
-        .name        = "A50",
-        .pvr         = CPU_PPC_RS64II,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_RS64,
-        .flags       = PPC_FLAGS_RS64,
-        .msr_mask    = xxx,
-    },
-#endif
-#if defined (TODO)
-    /* RS64-III (Pulsar) */
-    {
-        .name        = "RS64-III",
-        .pvr         = CPU_PPC_RS64III,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_RS64,
-        .flags       = PPC_FLAGS_RS64,
-        .msr_mask    = xxx,
-    },
-    {
-        .name        = "Pulsar",
-        .pvr         = CPU_PPC_RS64III,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_RS64,
-        .flags       = PPC_FLAGS_RS64,
-        .msr_mask    = xxx,
-    },
-#endif
-#if defined (TODO)
-    /* RS64-IV (IceStar/IStar/SStar) */
-    {
-        .name        = "RS64-IV",
-        .pvr         = CPU_PPC_RS64IV,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_RS64,
-        .flags       = PPC_FLAGS_RS64,
-        .msr_mask    = xxx,
-    },
-    {
-        .name        = "IceStar",
-        .pvr         = CPU_PPC_RS64IV,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_RS64,
-        .flags       = PPC_FLAGS_RS64,
-        .msr_mask    = xxx,
-    },
-    {
-        .name        = "IStar",
-        .pvr         = CPU_PPC_RS64IV,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_RS64,
-        .flags       = PPC_FLAGS_RS64,
-        .msr_mask    = xxx,
-    },
-    {
-        .name        = "SStar",
-        .pvr         = CPU_PPC_RS64IV,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_RS64,
-        .flags       = PPC_FLAGS_RS64,
-        .msr_mask    = xxx,
-    },
-#endif
-    /* POWER */
-#if defined (TODO)
-    /* Original POWER */
-    {
-        .name        = "POWER",
-        .pvr         = CPU_POWER,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_POWER,
-        .flags       = PPC_FLAGS_POWER,
-        .msr_mask    = xxx,
-    },
-#endif
-#endif /* defined (TARGET_PPC64) */
-#if defined (TODO)
-    /* POWER2 */
-    {
-        .name        = "POWER2",
-        .pvr         = CPU_POWER2,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_POWER,
-        .flags       = PPC_FLAGS_POWER,
-        .msr_mask    = xxx,
-    },
-#endif
-    /* Generic PowerPCs */
-#if defined (TODO)
+
+int cpu_ppc_register (CPUPPCState *env, ppc_def_t *def)
+{
+    env->msr_mask = def->msr_mask;
+    env->mmu_model = def->mmu_model;
+    env->excp_model = def->excp_model;
+    env->bus_model = def->bus_model;
+    if (create_ppc_opcodes(env, def) < 0)
+        return -1;
+    init_ppc_proc(env, def);
+#if defined(PPC_DUMP_CPU)
     {
-        .name        = "ppc64",
-        .pvr         = CPU_PPC_970FX,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_PPC64,
-        .flags       = PPC_FLAGS_PPC64,
-        .msr_mask    = 0xA00000000204FF36ULL,
-    },
+        const unsigned char *mmu_model, *excp_model, *bus_model;
+        switch (env->mmu_model) {
+        case POWERPC_MMU_32B:
+            mmu_model = "PowerPC 32";
+            break;
+        case POWERPC_MMU_64B:
+            mmu_model = "PowerPC 64";
+            break;
+        case POWERPC_MMU_601:
+            mmu_model = "PowerPC 601";
+            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_4xx:
+            mmu_model = "PowerPC 4xx real mode only";
+            break;
+        case POWERPC_MMU_BOOKE:
+            mmu_model = "PowerPC BookE";
+            break;
+        case POWERPC_MMU_BOOKE_FSL:
+            mmu_model = "PowerPC BookE FSL";
+            break;
+        case POWERPC_MMU_64BRIDGE:
+            mmu_model = "PowerPC 64 bridge";
+            break;
+        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_970:
+            excp_model = "PowerPC 970";
+            break;
+        case POWERPC_EXCP_BOOKE:
+            excp_model = "PowerPC BookE";
+            break;
+        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_970:
+            bus_model = "PowerPC 970";
+            break;
+        case PPC_FLAGS_INPUT_401:
+            bus_model = "PowerPC 401/403";
+            break;
+        default:
+            bus_model = "Unknown or invalid";
+            break;
+        }
+        printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
+               "    MMU model        : %s\n",
+               def->name, def->pvr, def->msr_mask, mmu_model);
+        if (env->tlb != NULL) {
+            printf("                       %d %s TLB in %d ways\n",
+                   env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
+                   env->nb_ways);
+        }
+        printf("    Exceptions model : %s\n"
+               "    Bus model        : %s\n",
+               excp_model, bus_model);
+    }
+    dump_ppc_insns(env);
+    dump_ppc_sprs(env);
+    fflush(stdout);
 #endif
-    {
-        .name        = "ppc32",
-        .pvr         = CPU_PPC_604,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_PPC32,
-        .flags       = PPC_FLAGS_PPC32,
-        .msr_mask    = 0x000000000005FF77ULL,
-    },
-    /* Fallback */
-    {
-        .name        = "ppc",
-        .pvr         = CPU_PPC_604,
-        .pvr_mask    = 0xFFFFFFFF,
-        .insns_flags = PPC_INSNS_PPC32,
-        .flags       = PPC_FLAGS_PPC32,
-        .msr_mask    = 0x000000000005FF77ULL,
-    },
-};
+
+    return 0;
+}
 
 int ppc_find_by_name (const unsigned char *name, ppc_def_t **def)
 {
@@ -4374,9 +5525,8 @@ void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
     int i;
 
     for (i = 0; ; i++) {
-        (*cpu_fprintf)(f, "PowerPC %16s PVR %08x mask %08x\n",
-                       ppc_defs[i].name,
-                       ppc_defs[i].pvr, ppc_defs[i].pvr_mask);
+        (*cpu_fprintf)(f, "PowerPC %-16s PVR %08x\n",
+                       ppc_defs[i].name, ppc_defs[i].pvr);
         if (strcmp(ppc_defs[i].name, "ppc") == 0)
             break;
     }