Annotation of qemu/target-ppc/translate.c, revision 1.1.1.5

1.1       root        1: /*
                      2:  *  PowerPC emulation for qemu: main translation routines.
1.1.1.5 ! root        3:  *
        !             4:  *  Copyright (c) 2003-2007 Jocelyn Mayer
1.1       root        5:  *
                      6:  * This library is free software; you can redistribute it and/or
                      7:  * modify it under the terms of the GNU Lesser General Public
                      8:  * License as published by the Free Software Foundation; either
                      9:  * version 2 of the License, or (at your option) any later version.
                     10:  *
                     11:  * This library is distributed in the hope that it will be useful,
                     12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * Lesser General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU Lesser General Public
                     17:  * License along with this library; if not, write to the Free Software
                     18:  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     19:  */
                     20: #include <stdarg.h>
                     21: #include <stdlib.h>
                     22: #include <stdio.h>
                     23: #include <string.h>
                     24: #include <inttypes.h>
                     25: 
                     26: #include "cpu.h"
                     27: #include "exec-all.h"
                     28: #include "disas.h"
                     29: 
1.1.1.5 ! root       30: /* Include definitions for instructions classes and implementations flags */
1.1       root       31: //#define DO_SINGLE_STEP
                     32: //#define PPC_DEBUG_DISAS
1.1.1.5 ! root       33: //#define DEBUG_MEMORY_ACCESSES
        !            34: //#define DO_PPC_STATISTICS
        !            35: //#define OPTIMIZE_FPRF_UPDATE
1.1       root       36: 
1.1.1.5 ! root       37: /*****************************************************************************/
        !            38: /* Code translation helpers                                                  */
        !            39: #if defined(USE_DIRECT_JUMP)
1.1.1.2   root       40: #define TBPARAM(x)
                     41: #else
                     42: #define TBPARAM(x) (long)(x)
                     43: #endif
                     44: 
1.1       root       45: enum {
                     46: #define DEF(s, n, copy_size) INDEX_op_ ## s,
                     47: #include "opc.h"
                     48: #undef DEF
                     49:     NB_OPS,
                     50: };
                     51: 
                     52: static uint16_t *gen_opc_ptr;
                     53: static uint32_t *gen_opparam_ptr;
1.1.1.5 ! root       54: #if defined(OPTIMIZE_FPRF_UPDATE)
        !            55: static uint16_t *gen_fprf_buf[OPC_BUF_SIZE];
        !            56: static uint16_t **gen_fprf_ptr;
        !            57: #endif
1.1       root       58: 
                     59: #include "gen-op.h"
                     60: 
1.1.1.5 ! root       61: static always_inline void gen_set_T0 (target_ulong val)
        !            62: {
        !            63: #if defined(TARGET_PPC64)
        !            64:     if (val >> 32)
        !            65:         gen_op_set_T0_64(val >> 32, val);
        !            66:     else
        !            67: #endif
        !            68:         gen_op_set_T0(val);
        !            69: }
        !            70: 
        !            71: static always_inline void gen_set_T1 (target_ulong val)
        !            72: {
        !            73: #if defined(TARGET_PPC64)
        !            74:     if (val >> 32)
        !            75:         gen_op_set_T1_64(val >> 32, val);
        !            76:     else
        !            77: #endif
        !            78:         gen_op_set_T1(val);
        !            79: }
        !            80: 
        !            81: #define GEN8(func, NAME)                                                      \
1.1       root       82: static GenOpFunc *NAME ## _table [8] = {                                      \
                     83: NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
                     84: NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
                     85: };                                                                            \
1.1.1.5 ! root       86: static always_inline void func (int n)                                        \
1.1       root       87: {                                                                             \
                     88:     NAME ## _table[n]();                                                      \
                     89: }
                     90: 
                     91: #define GEN16(func, NAME)                                                     \
                     92: static GenOpFunc *NAME ## _table [16] = {                                     \
                     93: NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
                     94: NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
                     95: NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
                     96: NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
                     97: };                                                                            \
1.1.1.5 ! root       98: static always_inline void func (int n)                                        \
1.1       root       99: {                                                                             \
                    100:     NAME ## _table[n]();                                                      \
                    101: }
                    102: 
1.1.1.5 ! root      103: #define GEN32(func, NAME)                                                     \
1.1       root      104: static GenOpFunc *NAME ## _table [32] = {                                     \
                    105: NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
                    106: NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
                    107: NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
                    108: NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
                    109: NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
                    110: NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
                    111: NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
                    112: NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
                    113: };                                                                            \
1.1.1.5 ! root      114: static always_inline void func (int n)                                        \
1.1       root      115: {                                                                             \
                    116:     NAME ## _table[n]();                                                      \
                    117: }
                    118: 
                    119: /* Condition register moves */
                    120: GEN8(gen_op_load_crf_T0, gen_op_load_crf_T0_crf);
                    121: GEN8(gen_op_load_crf_T1, gen_op_load_crf_T1_crf);
                    122: GEN8(gen_op_store_T0_crf, gen_op_store_T0_crf_crf);
1.1.1.5 ! root      123: #if 0 // Unused
1.1       root      124: GEN8(gen_op_store_T1_crf, gen_op_store_T1_crf_crf);
1.1.1.5 ! root      125: #endif
1.1       root      126: 
                    127: /* General purpose registers moves */
                    128: GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
                    129: GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
                    130: GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
                    131: 
                    132: GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
                    133: GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
1.1.1.5 ! root      134: #if 0 // unused
1.1       root      135: GEN32(gen_op_store_T2_gpr, gen_op_store_T2_gpr_gpr);
1.1.1.5 ! root      136: #endif
1.1       root      137: 
                    138: /* floating point registers moves */
                    139: GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fpr);
                    140: GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fpr);
                    141: GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fpr);
                    142: GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fpr);
                    143: GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fpr);
1.1.1.5 ! root      144: #if 0 // unused
1.1       root      145: GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fpr);
1.1.1.5 ! root      146: #endif
1.1       root      147: 
                    148: /* internal defines */
                    149: typedef struct DisasContext {
                    150:     struct TranslationBlock *tb;
                    151:     target_ulong nip;
                    152:     uint32_t opcode;
                    153:     uint32_t exception;
                    154:     /* Routine used to access memory */
                    155:     int mem_idx;
                    156:     /* Translation flags */
                    157: #if !defined(CONFIG_USER_ONLY)
                    158:     int supervisor;
                    159: #endif
1.1.1.5 ! root      160: #if defined(TARGET_PPC64)
        !           161:     int sf_mode;
        !           162: #endif
1.1       root      163:     int fpu_enabled;
1.1.1.5 ! root      164:     int altivec_enabled;
        !           165:     int spe_enabled;
1.1       root      166:     ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
1.1.1.3   root      167:     int singlestep_enabled;
1.1.1.5 ! root      168:     int dcache_line_size;
1.1       root      169: } DisasContext;
                    170: 
                    171: struct opc_handler_t {
                    172:     /* invalid bits */
                    173:     uint32_t inval;
                    174:     /* instruction type */
1.1.1.5 ! root      175:     uint64_t type;
1.1       root      176:     /* handler */
                    177:     void (*handler)(DisasContext *ctx);
1.1.1.5 ! root      178: #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
        !           179:     const unsigned char *oname;
        !           180: #endif
        !           181: #if defined(DO_PPC_STATISTICS)
        !           182:     uint64_t count;
        !           183: #endif
1.1       root      184: };
                    185: 
1.1.1.5 ! root      186: static always_inline void gen_set_Rc0 (DisasContext *ctx)
        !           187: {
        !           188: #if defined(TARGET_PPC64)
        !           189:     if (ctx->sf_mode)
        !           190:         gen_op_cmpi_64(0);
        !           191:     else
        !           192: #endif
        !           193:         gen_op_cmpi(0);
        !           194:     gen_op_set_Rc0();
        !           195: }
        !           196: 
        !           197: static always_inline void gen_reset_fpstatus (void)
        !           198: {
        !           199: #ifdef CONFIG_SOFTFLOAT
        !           200:     gen_op_reset_fpstatus();
        !           201: #endif
        !           202: }
        !           203: 
        !           204: static always_inline void gen_compute_fprf (int set_fprf, int set_rc)
        !           205: {
        !           206:     if (set_fprf != 0) {
        !           207:         /* This case might be optimized later */
        !           208: #if defined(OPTIMIZE_FPRF_UPDATE)
        !           209:         *gen_fprf_ptr++ = gen_opc_ptr;
        !           210: #endif
        !           211:         gen_op_compute_fprf(1);
        !           212:         if (unlikely(set_rc))
        !           213:             gen_op_store_T0_crf(1);
        !           214:         gen_op_float_check_status();
        !           215:     } else if (unlikely(set_rc)) {
        !           216:         /* We always need to compute fpcc */
        !           217:         gen_op_compute_fprf(0);
        !           218:         gen_op_store_T0_crf(1);
        !           219:         if (set_fprf)
        !           220:             gen_op_float_check_status();
        !           221:     }
        !           222: }
        !           223: 
        !           224: static always_inline void gen_optimize_fprf (void)
        !           225: {
        !           226: #if defined(OPTIMIZE_FPRF_UPDATE)
        !           227:     uint16_t **ptr;
        !           228: 
        !           229:     for (ptr = gen_fprf_buf; ptr != (gen_fprf_ptr - 1); ptr++)
        !           230:         *ptr = INDEX_op_nop1;
        !           231:     gen_fprf_ptr = gen_fprf_buf;
        !           232: #endif
        !           233: }
        !           234: 
        !           235: static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
        !           236: {
        !           237: #if defined(TARGET_PPC64)
        !           238:     if (ctx->sf_mode)
        !           239:         gen_op_update_nip_64(nip >> 32, nip);
        !           240:     else
        !           241: #endif
        !           242:         gen_op_update_nip(nip);
        !           243: }
        !           244: 
        !           245: #define GEN_EXCP(ctx, excp, error)                                            \
1.1       root      246: do {                                                                          \
1.1.1.5 ! root      247:     if ((ctx)->exception == POWERPC_EXCP_NONE) {                              \
        !           248:         gen_update_nip(ctx, (ctx)->nip);                                      \
1.1       root      249:     }                                                                         \
                    250:     gen_op_raise_exception_err((excp), (error));                              \
                    251:     ctx->exception = (excp);                                                  \
                    252: } while (0)
                    253: 
1.1.1.5 ! root      254: #define GEN_EXCP_INVAL(ctx)                                                   \
        !           255: GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
        !           256:          POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL)
        !           257: 
        !           258: #define GEN_EXCP_PRIVOPC(ctx)                                                 \
        !           259: GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
        !           260:          POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_OPC)
        !           261: 
        !           262: #define GEN_EXCP_PRIVREG(ctx)                                                 \
        !           263: GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM,                                         \
        !           264:          POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG)
        !           265: 
        !           266: #define GEN_EXCP_NO_FP(ctx)                                                   \
        !           267: GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0)
1.1       root      268: 
1.1.1.5 ! root      269: #define GEN_EXCP_NO_AP(ctx)                                                   \
        !           270: GEN_EXCP(ctx, POWERPC_EXCP_APU, 0)
1.1       root      271: 
1.1.1.5 ! root      272: #define GEN_EXCP_NO_VR(ctx)                                                   \
        !           273: GEN_EXCP(ctx, POWERPC_EXCP_VPU, 0)
1.1       root      274: 
1.1.1.2   root      275: /* Stop translation */
1.1.1.5 ! root      276: static always_inline void GEN_STOP (DisasContext *ctx)
1.1       root      277: {
1.1.1.5 ! root      278:     gen_update_nip(ctx, ctx->nip);
        !           279:     ctx->exception = POWERPC_EXCP_STOP;
1.1       root      280: }
                    281: 
1.1.1.2   root      282: /* No need to update nip here, as execution flow will change */
1.1.1.5 ! root      283: static always_inline void GEN_SYNC (DisasContext *ctx)
1.1       root      284: {
1.1.1.5 ! root      285:     ctx->exception = POWERPC_EXCP_SYNC;
1.1       root      286: }
                    287: 
                    288: #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
                    289: static void gen_##name (DisasContext *ctx);                                   \
                    290: GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
                    291: static void gen_##name (DisasContext *ctx)
                    292: 
1.1.1.5 ! root      293: #define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
        !           294: static void gen_##name (DisasContext *ctx);                                   \
        !           295: GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type);                       \
        !           296: static void gen_##name (DisasContext *ctx)
        !           297: 
1.1       root      298: typedef struct opcode_t {
                    299:     unsigned char opc1, opc2, opc3;
                    300: #if HOST_LONG_BITS == 64 /* Explicitely align to 64 bits */
                    301:     unsigned char pad[5];
                    302: #else
                    303:     unsigned char pad[1];
                    304: #endif
                    305:     opc_handler_t handler;
                    306:     const unsigned char *oname;
                    307: } opcode_t;
                    308: 
1.1.1.5 ! root      309: /*****************************************************************************/
1.1       root      310: /***                           Instruction decoding                        ***/
                    311: #define EXTRACT_HELPER(name, shift, nb)                                       \
1.1.1.5 ! root      312: static always_inline uint32_t name (uint32_t opcode)                          \
1.1       root      313: {                                                                             \
                    314:     return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
                    315: }
                    316: 
                    317: #define EXTRACT_SHELPER(name, shift, nb)                                      \
1.1.1.5 ! root      318: static always_inline int32_t name (uint32_t opcode)                           \
1.1       root      319: {                                                                             \
                    320:     return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
                    321: }
                    322: 
                    323: /* Opcode part 1 */
                    324: EXTRACT_HELPER(opc1, 26, 6);
                    325: /* Opcode part 2 */
                    326: EXTRACT_HELPER(opc2, 1, 5);
                    327: /* Opcode part 3 */
                    328: EXTRACT_HELPER(opc3, 6, 5);
                    329: /* Update Cr0 flags */
                    330: EXTRACT_HELPER(Rc, 0, 1);
                    331: /* Destination */
                    332: EXTRACT_HELPER(rD, 21, 5);
                    333: /* Source */
                    334: EXTRACT_HELPER(rS, 21, 5);
                    335: /* First operand */
                    336: EXTRACT_HELPER(rA, 16, 5);
                    337: /* Second operand */
                    338: EXTRACT_HELPER(rB, 11, 5);
                    339: /* Third operand */
                    340: EXTRACT_HELPER(rC, 6, 5);
                    341: /***                               Get CRn                                 ***/
                    342: EXTRACT_HELPER(crfD, 23, 3);
                    343: EXTRACT_HELPER(crfS, 18, 3);
                    344: EXTRACT_HELPER(crbD, 21, 5);
                    345: EXTRACT_HELPER(crbA, 16, 5);
                    346: EXTRACT_HELPER(crbB, 11, 5);
                    347: /* SPR / TBL */
                    348: EXTRACT_HELPER(_SPR, 11, 10);
1.1.1.5 ! root      349: static always_inline uint32_t SPR (uint32_t opcode)
1.1       root      350: {
                    351:     uint32_t sprn = _SPR(opcode);
                    352: 
                    353:     return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
                    354: }
                    355: /***                              Get constants                            ***/
                    356: EXTRACT_HELPER(IMM, 12, 8);
                    357: /* 16 bits signed immediate value */
                    358: EXTRACT_SHELPER(SIMM, 0, 16);
                    359: /* 16 bits unsigned immediate value */
                    360: EXTRACT_HELPER(UIMM, 0, 16);
                    361: /* Bit count */
                    362: EXTRACT_HELPER(NB, 11, 5);
                    363: /* Shift count */
                    364: EXTRACT_HELPER(SH, 11, 5);
                    365: /* Mask start */
                    366: EXTRACT_HELPER(MB, 6, 5);
                    367: /* Mask end */
                    368: EXTRACT_HELPER(ME, 1, 5);
                    369: /* Trap operand */
                    370: EXTRACT_HELPER(TO, 21, 5);
                    371: 
                    372: EXTRACT_HELPER(CRM, 12, 8);
                    373: EXTRACT_HELPER(FM, 17, 8);
                    374: EXTRACT_HELPER(SR, 16, 4);
                    375: EXTRACT_HELPER(FPIMM, 20, 4);
                    376: 
                    377: /***                            Jump target decoding                       ***/
                    378: /* Displacement */
                    379: EXTRACT_SHELPER(d, 0, 16);
                    380: /* Immediate address */
1.1.1.5 ! root      381: static always_inline target_ulong LI (uint32_t opcode)
1.1       root      382: {
                    383:     return (opcode >> 0) & 0x03FFFFFC;
                    384: }
                    385: 
1.1.1.5 ! root      386: static always_inline uint32_t BD (uint32_t opcode)
1.1       root      387: {
                    388:     return (opcode >> 0) & 0xFFFC;
                    389: }
                    390: 
                    391: EXTRACT_HELPER(BO, 21, 5);
                    392: EXTRACT_HELPER(BI, 16, 5);
                    393: /* Absolute/relative address */
                    394: EXTRACT_HELPER(AA, 1, 1);
                    395: /* Link */
                    396: EXTRACT_HELPER(LK, 0, 1);
                    397: 
                    398: /* Create a mask between <start> and <end> bits */
1.1.1.5 ! root      399: static always_inline target_ulong MASK (uint32_t start, uint32_t end)
1.1       root      400: {
1.1.1.5 ! root      401:     target_ulong ret;
1.1       root      402: 
1.1.1.5 ! root      403: #if defined(TARGET_PPC64)
        !           404:     if (likely(start == 0)) {
        !           405:         ret = UINT64_MAX << (63 - end);
        !           406:     } else if (likely(end == 63)) {
        !           407:         ret = UINT64_MAX >> start;
        !           408:     }
        !           409: #else
        !           410:     if (likely(start == 0)) {
        !           411:         ret = UINT32_MAX << (31  - end);
        !           412:     } else if (likely(end == 31)) {
        !           413:         ret = UINT32_MAX >> start;
        !           414:     }
        !           415: #endif
        !           416:     else {
        !           417:         ret = (((target_ulong)(-1ULL)) >> (start)) ^
        !           418:             (((target_ulong)(-1ULL) >> (end)) >> 1);
        !           419:         if (unlikely(start > end))
        !           420:             return ~ret;
        !           421:     }
1.1       root      422: 
                    423:     return ret;
                    424: }
                    425: 
1.1.1.5 ! root      426: /*****************************************************************************/
        !           427: /* PowerPC Instructions types definitions                                    */
        !           428: enum {
        !           429:     PPC_NONE           = 0x0000000000000000ULL,
        !           430:     /* PowerPC base instructions set                                         */
        !           431:     PPC_INSNS_BASE     = 0x0000000000000001ULL,
        !           432:     /*   integer operations instructions                                     */
        !           433: #define PPC_INTEGER PPC_INSNS_BASE
        !           434:     /*   flow control instructions                                           */
        !           435: #define PPC_FLOW    PPC_INSNS_BASE
        !           436:     /*   virtual memory instructions                                         */
        !           437: #define PPC_MEM     PPC_INSNS_BASE
        !           438:     /*   ld/st with reservation instructions                                 */
        !           439: #define PPC_RES     PPC_INSNS_BASE
        !           440:     /*   spr/msr access instructions                                         */
        !           441: #define PPC_MISC    PPC_INSNS_BASE
        !           442:     /* Deprecated instruction sets                                           */
        !           443:     /*   Original POWER instruction set                                      */
        !           444:     PPC_POWER          = 0x0000000000000002ULL,
        !           445:     /*   POWER2 instruction set extension                                    */
        !           446:     PPC_POWER2         = 0x0000000000000004ULL,
        !           447:     /*   Power RTC support                                                   */
        !           448:     PPC_POWER_RTC      = 0x0000000000000008ULL,
        !           449:     /*   Power-to-PowerPC bridge (601)                                       */
        !           450:     PPC_POWER_BR       = 0x0000000000000010ULL,
        !           451:     /* 64 bits PowerPC instruction set                                       */
        !           452:     PPC_64B            = 0x0000000000000020ULL,
        !           453:     /*   New 64 bits extensions (PowerPC 2.0x)                               */
        !           454:     PPC_64BX           = 0x0000000000000040ULL,
        !           455:     /*   64 bits hypervisor extensions                                       */
        !           456:     PPC_64H            = 0x0000000000000080ULL,
        !           457:     /*   New wait instruction (PowerPC 2.0x)                                 */
        !           458:     PPC_WAIT           = 0x0000000000000100ULL,
        !           459:     /*   Time base mftb instruction                                          */
        !           460:     PPC_MFTB           = 0x0000000000000200ULL,
        !           461: 
        !           462:     /* Fixed-point unit extensions                                           */
        !           463:     /*   PowerPC 602 specific                                                */
        !           464:     PPC_602_SPEC       = 0x0000000000000400ULL,
        !           465:     /*   isel instruction                                                    */
        !           466:     PPC_ISEL           = 0x0000000000000800ULL,
        !           467:     /*   popcntb instruction                                                 */
        !           468:     PPC_POPCNTB        = 0x0000000000001000ULL,
        !           469:     /*   string load / store                                                 */
        !           470:     PPC_STRING         = 0x0000000000002000ULL,
        !           471: 
        !           472:     /* Floating-point unit extensions                                        */
        !           473:     /*   Optional floating point instructions                                */
        !           474:     PPC_FLOAT          = 0x0000000000010000ULL,
        !           475:     /* New floating-point extensions (PowerPC 2.0x)                          */
        !           476:     PPC_FLOAT_EXT      = 0x0000000000020000ULL,
        !           477:     PPC_FLOAT_FSQRT    = 0x0000000000040000ULL,
        !           478:     PPC_FLOAT_FRES     = 0x0000000000080000ULL,
        !           479:     PPC_FLOAT_FRSQRTE  = 0x0000000000100000ULL,
        !           480:     PPC_FLOAT_FRSQRTES = 0x0000000000200000ULL,
        !           481:     PPC_FLOAT_FSEL     = 0x0000000000400000ULL,
        !           482:     PPC_FLOAT_STFIWX   = 0x0000000000800000ULL,
        !           483: 
        !           484:     /* Vector/SIMD extensions                                                */
        !           485:     /*   Altivec support                                                     */
        !           486:     PPC_ALTIVEC        = 0x0000000001000000ULL,
        !           487:     /*   PowerPC 2.03 SPE extension                                          */
        !           488:     PPC_SPE            = 0x0000000002000000ULL,
        !           489:     /*   PowerPC 2.03 SPE floating-point extension                           */
        !           490:     PPC_SPEFPU         = 0x0000000004000000ULL,
        !           491: 
        !           492:     /* Optional memory control instructions                                  */
        !           493:     PPC_MEM_TLBIA      = 0x0000000010000000ULL,
        !           494:     PPC_MEM_TLBIE      = 0x0000000020000000ULL,
        !           495:     PPC_MEM_TLBSYNC    = 0x0000000040000000ULL,
        !           496:     /*   sync instruction                                                    */
        !           497:     PPC_MEM_SYNC       = 0x0000000080000000ULL,
        !           498:     /*   eieio instruction                                                   */
        !           499:     PPC_MEM_EIEIO      = 0x0000000100000000ULL,
        !           500: 
        !           501:     /* Cache control instructions                                            */
        !           502:     PPC_CACHE          = 0x0000000200000000ULL,
        !           503:     /*   icbi instruction                                                    */
        !           504:     PPC_CACHE_ICBI     = 0x0000000400000000ULL,
        !           505:     /*   dcbz instruction with fixed cache line size                         */
        !           506:     PPC_CACHE_DCBZ     = 0x0000000800000000ULL,
        !           507:     /*   dcbz instruction with tunable cache line size                       */
        !           508:     PPC_CACHE_DCBZT    = 0x0000001000000000ULL,
        !           509:     /*   dcba instruction                                                    */
        !           510:     PPC_CACHE_DCBA     = 0x0000002000000000ULL,
        !           511:     /*   Freescale cache locking instructions                                */
        !           512:     PPC_CACHE_LOCK     = 0x0000004000000000ULL,
        !           513: 
        !           514:     /* MMU related extensions                                                */
        !           515:     /*   external control instructions                                       */
        !           516:     PPC_EXTERN         = 0x0000010000000000ULL,
        !           517:     /*   segment register access instructions                                */
        !           518:     PPC_SEGMENT        = 0x0000020000000000ULL,
        !           519:     /*   PowerPC 6xx TLB management instructions                             */
        !           520:     PPC_6xx_TLB        = 0x0000040000000000ULL,
        !           521:     /* PowerPC 74xx TLB management instructions                              */
        !           522:     PPC_74xx_TLB       = 0x0000080000000000ULL,
        !           523:     /*   PowerPC 40x TLB management instructions                             */
        !           524:     PPC_40x_TLB        = 0x0000100000000000ULL,
        !           525:     /*   segment register access instructions for PowerPC 64 "bridge"        */
        !           526:     PPC_SEGMENT_64B    = 0x0000200000000000ULL,
        !           527:     /*   SLB management                                                      */
        !           528:     PPC_SLBI           = 0x0000400000000000ULL,
        !           529: 
        !           530:     /* Embedded PowerPC dedicated instructions                               */
        !           531:     PPC_WRTEE          = 0x0001000000000000ULL,
        !           532:     /* PowerPC 40x exception model                                           */
        !           533:     PPC_40x_EXCP       = 0x0002000000000000ULL,
        !           534:     /* PowerPC 405 Mac instructions                                          */
        !           535:     PPC_405_MAC        = 0x0004000000000000ULL,
        !           536:     /* PowerPC 440 specific instructions                                     */
        !           537:     PPC_440_SPEC       = 0x0008000000000000ULL,
        !           538:     /* BookE (embedded) PowerPC specification                                */
        !           539:     PPC_BOOKE          = 0x0010000000000000ULL,
        !           540:     /* mfapidi instruction                                                   */
        !           541:     PPC_MFAPIDI        = 0x0020000000000000ULL,
        !           542:     /* tlbiva instruction                                                    */
        !           543:     PPC_TLBIVA         = 0x0040000000000000ULL,
        !           544:     /* tlbivax instruction                                                   */
        !           545:     PPC_TLBIVAX        = 0x0080000000000000ULL,
        !           546:     /* PowerPC 4xx dedicated instructions                                    */
        !           547:     PPC_4xx_COMMON     = 0x0100000000000000ULL,
        !           548:     /* PowerPC 40x ibct instructions                                         */
        !           549:     PPC_40x_ICBT       = 0x0200000000000000ULL,
        !           550:     /* rfmci is not implemented in all BookE PowerPC                         */
        !           551:     PPC_RFMCI          = 0x0400000000000000ULL,
        !           552:     /* rfdi instruction                                                      */
        !           553:     PPC_RFDI           = 0x0800000000000000ULL,
        !           554:     /* DCR accesses                                                          */
        !           555:     PPC_DCR            = 0x1000000000000000ULL,
        !           556:     /* DCR extended accesse                                                  */
        !           557:     PPC_DCRX           = 0x2000000000000000ULL,
        !           558:     /* user-mode DCR access, implemented in PowerPC 460                      */
        !           559:     PPC_DCRUX          = 0x4000000000000000ULL,
        !           560: };
        !           561: 
        !           562: /*****************************************************************************/
        !           563: /* PowerPC instructions table                                                */
1.1       root      564: #if HOST_LONG_BITS == 64
                    565: #define OPC_ALIGN 8
                    566: #else
                    567: #define OPC_ALIGN 4
                    568: #endif
                    569: #if defined(__APPLE__)
1.1.1.5 ! root      570: #define OPCODES_SECTION                                                       \
1.1       root      571:     __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
                    572: #else
1.1.1.5 ! root      573: #define OPCODES_SECTION                                                       \
1.1       root      574:     __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
                    575: #endif
                    576: 
1.1.1.5 ! root      577: #if defined(DO_PPC_STATISTICS)
        !           578: #define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
        !           579: OPCODES_SECTION opcode_t opc_##name = {                                       \
        !           580:     .opc1 = op1,                                                              \
        !           581:     .opc2 = op2,                                                              \
        !           582:     .opc3 = op3,                                                              \
        !           583:     .pad  = { 0, },                                                           \
        !           584:     .handler = {                                                              \
        !           585:         .inval   = invl,                                                      \
        !           586:         .type = _typ,                                                         \
        !           587:         .handler = &gen_##name,                                               \
        !           588:         .oname = stringify(name),                                             \
        !           589:     },                                                                        \
        !           590:     .oname = stringify(name),                                                 \
        !           591: }
        !           592: #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
        !           593: OPCODES_SECTION opcode_t opc_##name = {                                       \
        !           594:     .opc1 = op1,                                                              \
        !           595:     .opc2 = op2,                                                              \
        !           596:     .opc3 = op3,                                                              \
        !           597:     .pad  = { 0, },                                                           \
        !           598:     .handler = {                                                              \
        !           599:         .inval   = invl,                                                      \
        !           600:         .type = _typ,                                                         \
        !           601:         .handler = &gen_##name,                                               \
        !           602:         .oname = onam,                                                        \
        !           603:     },                                                                        \
        !           604:     .oname = onam,                                                            \
        !           605: }
        !           606: #else
1.1       root      607: #define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
                    608: OPCODES_SECTION opcode_t opc_##name = {                                       \
                    609:     .opc1 = op1,                                                              \
                    610:     .opc2 = op2,                                                              \
                    611:     .opc3 = op3,                                                              \
                    612:     .pad  = { 0, },                                                           \
                    613:     .handler = {                                                              \
                    614:         .inval   = invl,                                                      \
                    615:         .type = _typ,                                                         \
                    616:         .handler = &gen_##name,                                               \
                    617:     },                                                                        \
                    618:     .oname = stringify(name),                                                 \
                    619: }
1.1.1.5 ! root      620: #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
        !           621: OPCODES_SECTION opcode_t opc_##name = {                                       \
        !           622:     .opc1 = op1,                                                              \
        !           623:     .opc2 = op2,                                                              \
        !           624:     .opc3 = op3,                                                              \
        !           625:     .pad  = { 0, },                                                           \
        !           626:     .handler = {                                                              \
        !           627:         .inval   = invl,                                                      \
        !           628:         .type = _typ,                                                         \
        !           629:         .handler = &gen_##name,                                               \
        !           630:     },                                                                        \
        !           631:     .oname = onam,                                                            \
        !           632: }
        !           633: #endif
1.1       root      634: 
                    635: #define GEN_OPCODE_MARK(name)                                                 \
                    636: OPCODES_SECTION opcode_t opc_##name = {                                       \
                    637:     .opc1 = 0xFF,                                                             \
                    638:     .opc2 = 0xFF,                                                             \
                    639:     .opc3 = 0xFF,                                                             \
                    640:     .pad  = { 0, },                                                           \
                    641:     .handler = {                                                              \
                    642:         .inval   = 0x00000000,                                                \
                    643:         .type = 0x00,                                                         \
                    644:         .handler = NULL,                                                      \
                    645:     },                                                                        \
                    646:     .oname = stringify(name),                                                 \
                    647: }
                    648: 
                    649: /* Start opcode list */
                    650: GEN_OPCODE_MARK(start);
                    651: 
                    652: /* Invalid instruction */
                    653: GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
                    654: {
1.1.1.5 ! root      655:     GEN_EXCP_INVAL(ctx);
1.1       root      656: }
                    657: 
                    658: static opc_handler_t invalid_handler = {
                    659:     .inval   = 0xFFFFFFFF,
                    660:     .type    = PPC_NONE,
                    661:     .handler = gen_invalid,
                    662: };
                    663: 
                    664: /***                           Integer arithmetic                          ***/
1.1.1.5 ! root      665: #define __GEN_INT_ARITH2(name, opc1, opc2, opc3, inval, type)                 \
        !           666: GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
1.1       root      667: {                                                                             \
                    668:     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
                    669:     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
                    670:     gen_op_##name();                                                          \
                    671:     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
1.1.1.5 ! root      672:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
        !           673:         gen_set_Rc0(ctx);                                                     \
1.1       root      674: }
                    675: 
1.1.1.5 ! root      676: #define __GEN_INT_ARITH2_O(name, opc1, opc2, opc3, inval, type)               \
        !           677: GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
1.1       root      678: {                                                                             \
                    679:     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
                    680:     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
                    681:     gen_op_##name();                                                          \
                    682:     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
1.1.1.5 ! root      683:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
        !           684:         gen_set_Rc0(ctx);                                                     \
1.1       root      685: }
                    686: 
1.1.1.5 ! root      687: #define __GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                        \
        !           688: GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
1.1       root      689: {                                                                             \
                    690:     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
                    691:     gen_op_##name();                                                          \
                    692:     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
1.1.1.5 ! root      693:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
        !           694:         gen_set_Rc0(ctx);                                                     \
1.1       root      695: }
1.1.1.5 ! root      696: #define __GEN_INT_ARITH1_O(name, opc1, opc2, opc3, type)                      \
        !           697: GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
1.1       root      698: {                                                                             \
                    699:     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
                    700:     gen_op_##name();                                                          \
                    701:     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
1.1.1.5 ! root      702:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
        !           703:         gen_set_Rc0(ctx);                                                     \
        !           704: }
        !           705: 
        !           706: /* Two operands arithmetic functions */
        !           707: #define GEN_INT_ARITH2(name, opc1, opc2, opc3, type)                          \
        !           708: __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000000, type)                    \
        !           709: __GEN_INT_ARITH2_O(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
        !           710: 
        !           711: /* Two operands arithmetic functions with no overflow allowed */
        !           712: #define GEN_INT_ARITHN(name, opc1, opc2, opc3, type)                          \
        !           713: __GEN_INT_ARITH2(name, opc1, opc2, opc3, 0x00000400, type)
        !           714: 
        !           715: /* One operand arithmetic functions */
        !           716: #define GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                          \
        !           717: __GEN_INT_ARITH1(name, opc1, opc2, opc3, type)                                \
        !           718: __GEN_INT_ARITH1_O(name##o, opc1, opc2, opc3 | 0x10, type)
        !           719: 
        !           720: #if defined(TARGET_PPC64)
        !           721: #define __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, inval, type)              \
        !           722: GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
        !           723: {                                                                             \
        !           724:     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
        !           725:     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
        !           726:     if (ctx->sf_mode)                                                         \
        !           727:         gen_op_##name##_64();                                                 \
        !           728:     else                                                                      \
        !           729:         gen_op_##name();                                                      \
        !           730:     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
        !           731:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
        !           732:         gen_set_Rc0(ctx);                                                     \
        !           733: }
        !           734: 
        !           735: #define __GEN_INT_ARITH2_O_64(name, opc1, opc2, opc3, inval, type)            \
        !           736: GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                              \
        !           737: {                                                                             \
        !           738:     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
        !           739:     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
        !           740:     if (ctx->sf_mode)                                                         \
        !           741:         gen_op_##name##_64();                                                 \
        !           742:     else                                                                      \
        !           743:         gen_op_##name();                                                      \
        !           744:     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
        !           745:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
        !           746:         gen_set_Rc0(ctx);                                                     \
        !           747: }
        !           748: 
        !           749: #define __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                     \
        !           750: GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
        !           751: {                                                                             \
        !           752:     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
        !           753:     if (ctx->sf_mode)                                                         \
        !           754:         gen_op_##name##_64();                                                 \
        !           755:     else                                                                      \
        !           756:         gen_op_##name();                                                      \
        !           757:     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
        !           758:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
        !           759:         gen_set_Rc0(ctx);                                                     \
        !           760: }
        !           761: #define __GEN_INT_ARITH1_O_64(name, opc1, opc2, opc3, type)                   \
        !           762: GEN_HANDLER(name, opc1, opc2, opc3, 0x0000F800, type)                         \
        !           763: {                                                                             \
        !           764:     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
        !           765:     if (ctx->sf_mode)                                                         \
        !           766:         gen_op_##name##_64();                                                 \
        !           767:     else                                                                      \
        !           768:         gen_op_##name();                                                      \
        !           769:     gen_op_store_T0_gpr(rD(ctx->opcode));                                     \
        !           770:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
        !           771:         gen_set_Rc0(ctx);                                                     \
1.1       root      772: }
                    773: 
                    774: /* Two operands arithmetic functions */
1.1.1.5 ! root      775: #define GEN_INT_ARITH2_64(name, opc1, opc2, opc3, type)                       \
        !           776: __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000000, type)                 \
        !           777: __GEN_INT_ARITH2_O_64(name##o, opc1, opc2, opc3 | 0x10, 0x00000000, type)
1.1       root      778: 
                    779: /* Two operands arithmetic functions with no overflow allowed */
1.1.1.5 ! root      780: #define GEN_INT_ARITHN_64(name, opc1, opc2, opc3, type)                       \
        !           781: __GEN_INT_ARITH2_64(name, opc1, opc2, opc3, 0x00000400, type)
1.1       root      782: 
                    783: /* One operand arithmetic functions */
1.1.1.5 ! root      784: #define GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                       \
        !           785: __GEN_INT_ARITH1_64(name, opc1, opc2, opc3, type)                             \
        !           786: __GEN_INT_ARITH1_O_64(name##o, opc1, opc2, opc3 | 0x10, type)
        !           787: #else
        !           788: #define GEN_INT_ARITH2_64 GEN_INT_ARITH2
        !           789: #define GEN_INT_ARITHN_64 GEN_INT_ARITHN
        !           790: #define GEN_INT_ARITH1_64 GEN_INT_ARITH1
        !           791: #endif
1.1       root      792: 
                    793: /* add    add.    addo    addo.    */
1.1.1.5 ! root      794: static always_inline void gen_op_addo (void)
        !           795: {
        !           796:     gen_op_move_T2_T0();
        !           797:     gen_op_add();
        !           798:     gen_op_check_addo();
        !           799: }
        !           800: #if defined(TARGET_PPC64)
        !           801: #define gen_op_add_64 gen_op_add
        !           802: static always_inline void gen_op_addo_64 (void)
        !           803: {
        !           804:     gen_op_move_T2_T0();
        !           805:     gen_op_add();
        !           806:     gen_op_check_addo_64();
        !           807: }
        !           808: #endif
        !           809: GEN_INT_ARITH2_64 (add,    0x1F, 0x0A, 0x08, PPC_INTEGER);
1.1       root      810: /* addc   addc.   addco   addco.   */
1.1.1.5 ! root      811: static always_inline void gen_op_addc (void)
        !           812: {
        !           813:     gen_op_move_T2_T0();
        !           814:     gen_op_add();
        !           815:     gen_op_check_addc();
        !           816: }
        !           817: static always_inline void gen_op_addco (void)
        !           818: {
        !           819:     gen_op_move_T2_T0();
        !           820:     gen_op_add();
        !           821:     gen_op_check_addc();
        !           822:     gen_op_check_addo();
        !           823: }
        !           824: #if defined(TARGET_PPC64)
        !           825: static always_inline void gen_op_addc_64 (void)
        !           826: {
        !           827:     gen_op_move_T2_T0();
        !           828:     gen_op_add();
        !           829:     gen_op_check_addc_64();
        !           830: }
        !           831: static always_inline void gen_op_addco_64 (void)
        !           832: {
        !           833:     gen_op_move_T2_T0();
        !           834:     gen_op_add();
        !           835:     gen_op_check_addc_64();
        !           836:     gen_op_check_addo_64();
        !           837: }
        !           838: #endif
        !           839: GEN_INT_ARITH2_64 (addc,   0x1F, 0x0A, 0x00, PPC_INTEGER);
1.1       root      840: /* adde   adde.   addeo   addeo.   */
1.1.1.5 ! root      841: static always_inline void gen_op_addeo (void)
        !           842: {
        !           843:     gen_op_move_T2_T0();
        !           844:     gen_op_adde();
        !           845:     gen_op_check_addo();
        !           846: }
        !           847: #if defined(TARGET_PPC64)
        !           848: static always_inline void gen_op_addeo_64 (void)
        !           849: {
        !           850:     gen_op_move_T2_T0();
        !           851:     gen_op_adde_64();
        !           852:     gen_op_check_addo_64();
        !           853: }
        !           854: #endif
        !           855: GEN_INT_ARITH2_64 (adde,   0x1F, 0x0A, 0x04, PPC_INTEGER);
1.1       root      856: /* addme  addme.  addmeo  addmeo.  */
1.1.1.5 ! root      857: static always_inline void gen_op_addme (void)
        !           858: {
        !           859:     gen_op_move_T1_T0();
        !           860:     gen_op_add_me();
        !           861: }
        !           862: #if defined(TARGET_PPC64)
        !           863: static always_inline void gen_op_addme_64 (void)
        !           864: {
        !           865:     gen_op_move_T1_T0();
        !           866:     gen_op_add_me_64();
        !           867: }
        !           868: #endif
        !           869: GEN_INT_ARITH1_64 (addme,  0x1F, 0x0A, 0x07, PPC_INTEGER);
1.1       root      870: /* addze  addze.  addzeo  addzeo.  */
1.1.1.5 ! root      871: static always_inline void gen_op_addze (void)
        !           872: {
        !           873:     gen_op_move_T2_T0();
        !           874:     gen_op_add_ze();
        !           875:     gen_op_check_addc();
        !           876: }
        !           877: static always_inline void gen_op_addzeo (void)
        !           878: {
        !           879:     gen_op_move_T2_T0();
        !           880:     gen_op_add_ze();
        !           881:     gen_op_check_addc();
        !           882:     gen_op_check_addo();
        !           883: }
        !           884: #if defined(TARGET_PPC64)
        !           885: static always_inline void gen_op_addze_64 (void)
        !           886: {
        !           887:     gen_op_move_T2_T0();
        !           888:     gen_op_add_ze();
        !           889:     gen_op_check_addc_64();
        !           890: }
        !           891: static always_inline void gen_op_addzeo_64 (void)
        !           892: {
        !           893:     gen_op_move_T2_T0();
        !           894:     gen_op_add_ze();
        !           895:     gen_op_check_addc_64();
        !           896:     gen_op_check_addo_64();
        !           897: }
        !           898: #endif
        !           899: GEN_INT_ARITH1_64 (addze,  0x1F, 0x0A, 0x06, PPC_INTEGER);
1.1       root      900: /* divw   divw.   divwo   divwo.   */
1.1.1.5 ! root      901: GEN_INT_ARITH2 (divw,   0x1F, 0x0B, 0x0F, PPC_INTEGER);
1.1       root      902: /* divwu  divwu.  divwuo  divwuo.  */
1.1.1.5 ! root      903: GEN_INT_ARITH2 (divwu,  0x1F, 0x0B, 0x0E, PPC_INTEGER);
1.1       root      904: /* mulhw  mulhw.                   */
1.1.1.5 ! root      905: GEN_INT_ARITHN (mulhw,  0x1F, 0x0B, 0x02, PPC_INTEGER);
1.1       root      906: /* mulhwu mulhwu.                  */
1.1.1.5 ! root      907: GEN_INT_ARITHN (mulhwu, 0x1F, 0x0B, 0x00, PPC_INTEGER);
1.1       root      908: /* mullw  mullw.  mullwo  mullwo.  */
1.1.1.5 ! root      909: GEN_INT_ARITH2 (mullw,  0x1F, 0x0B, 0x07, PPC_INTEGER);
1.1       root      910: /* neg    neg.    nego    nego.    */
1.1.1.5 ! root      911: GEN_INT_ARITH1_64 (neg,    0x1F, 0x08, 0x03, PPC_INTEGER);
1.1       root      912: /* subf   subf.   subfo   subfo.   */
1.1.1.5 ! root      913: static always_inline void gen_op_subfo (void)
        !           914: {
        !           915:     gen_op_moven_T2_T0();
        !           916:     gen_op_subf();
        !           917:     gen_op_check_addo();
        !           918: }
        !           919: #if defined(TARGET_PPC64)
        !           920: #define gen_op_subf_64 gen_op_subf
        !           921: static always_inline void gen_op_subfo_64 (void)
        !           922: {
        !           923:     gen_op_moven_T2_T0();
        !           924:     gen_op_subf();
        !           925:     gen_op_check_addo_64();
        !           926: }
        !           927: #endif
        !           928: GEN_INT_ARITH2_64 (subf,   0x1F, 0x08, 0x01, PPC_INTEGER);
1.1       root      929: /* subfc  subfc.  subfco  subfco.  */
1.1.1.5 ! root      930: static always_inline void gen_op_subfc (void)
        !           931: {
        !           932:     gen_op_subf();
        !           933:     gen_op_check_subfc();
        !           934: }
        !           935: static always_inline void gen_op_subfco (void)
        !           936: {
        !           937:     gen_op_moven_T2_T0();
        !           938:     gen_op_subf();
        !           939:     gen_op_check_subfc();
        !           940:     gen_op_check_addo();
        !           941: }
        !           942: #if defined(TARGET_PPC64)
        !           943: static always_inline void gen_op_subfc_64 (void)
        !           944: {
        !           945:     gen_op_subf();
        !           946:     gen_op_check_subfc_64();
        !           947: }
        !           948: static always_inline void gen_op_subfco_64 (void)
        !           949: {
        !           950:     gen_op_moven_T2_T0();
        !           951:     gen_op_subf();
        !           952:     gen_op_check_subfc_64();
        !           953:     gen_op_check_addo_64();
        !           954: }
        !           955: #endif
        !           956: GEN_INT_ARITH2_64 (subfc,  0x1F, 0x08, 0x00, PPC_INTEGER);
1.1       root      957: /* subfe  subfe.  subfeo  subfeo.  */
1.1.1.5 ! root      958: static always_inline void gen_op_subfeo (void)
        !           959: {
        !           960:     gen_op_moven_T2_T0();
        !           961:     gen_op_subfe();
        !           962:     gen_op_check_addo();
        !           963: }
        !           964: #if defined(TARGET_PPC64)
        !           965: #define gen_op_subfe_64 gen_op_subfe
        !           966: static always_inline void gen_op_subfeo_64 (void)
        !           967: {
        !           968:     gen_op_moven_T2_T0();
        !           969:     gen_op_subfe_64();
        !           970:     gen_op_check_addo_64();
        !           971: }
        !           972: #endif
        !           973: GEN_INT_ARITH2_64 (subfe,  0x1F, 0x08, 0x04, PPC_INTEGER);
1.1       root      974: /* subfme subfme. subfmeo subfmeo. */
1.1.1.5 ! root      975: GEN_INT_ARITH1_64 (subfme, 0x1F, 0x08, 0x07, PPC_INTEGER);
1.1       root      976: /* subfze subfze. subfzeo subfzeo. */
1.1.1.5 ! root      977: GEN_INT_ARITH1_64 (subfze, 0x1F, 0x08, 0x06, PPC_INTEGER);
1.1       root      978: /* addi */
                    979: GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                    980: {
1.1.1.5 ! root      981:     target_long simm = SIMM(ctx->opcode);
1.1       root      982: 
                    983:     if (rA(ctx->opcode) == 0) {
1.1.1.5 ! root      984:         /* li case */
        !           985:         gen_set_T0(simm);
1.1       root      986:     } else {
                    987:         gen_op_load_gpr_T0(rA(ctx->opcode));
1.1.1.5 ! root      988:         if (likely(simm != 0))
        !           989:             gen_op_addi(simm);
1.1       root      990:     }
                    991:     gen_op_store_T0_gpr(rD(ctx->opcode));
                    992: }
                    993: /* addic */
                    994: GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                    995: {
1.1.1.5 ! root      996:     target_long simm = SIMM(ctx->opcode);
        !           997: 
1.1       root      998:     gen_op_load_gpr_T0(rA(ctx->opcode));
1.1.1.5 ! root      999:     if (likely(simm != 0)) {
        !          1000:         gen_op_move_T2_T0();
        !          1001:         gen_op_addi(simm);
        !          1002: #if defined(TARGET_PPC64)
        !          1003:         if (ctx->sf_mode)
        !          1004:             gen_op_check_addc_64();
        !          1005:         else
        !          1006: #endif
        !          1007:             gen_op_check_addc();
        !          1008:     } else {
        !          1009:         gen_op_clear_xer_ca();
        !          1010:     }
1.1       root     1011:     gen_op_store_T0_gpr(rD(ctx->opcode));
                   1012: }
                   1013: /* addic. */
1.1.1.5 ! root     1014: GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1.1       root     1015: {
1.1.1.5 ! root     1016:     target_long simm = SIMM(ctx->opcode);
        !          1017: 
1.1       root     1018:     gen_op_load_gpr_T0(rA(ctx->opcode));
1.1.1.5 ! root     1019:     if (likely(simm != 0)) {
        !          1020:         gen_op_move_T2_T0();
        !          1021:         gen_op_addi(simm);
        !          1022: #if defined(TARGET_PPC64)
        !          1023:         if (ctx->sf_mode)
        !          1024:             gen_op_check_addc_64();
        !          1025:         else
        !          1026: #endif
        !          1027:             gen_op_check_addc();
        !          1028:     } else {
        !          1029:         gen_op_clear_xer_ca();
        !          1030:     }
1.1       root     1031:     gen_op_store_T0_gpr(rD(ctx->opcode));
1.1.1.5 ! root     1032:     gen_set_Rc0(ctx);
1.1       root     1033: }
                   1034: /* addis */
                   1035: GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1036: {
1.1.1.5 ! root     1037:     target_long simm = SIMM(ctx->opcode);
1.1       root     1038: 
                   1039:     if (rA(ctx->opcode) == 0) {
1.1.1.5 ! root     1040:         /* lis case */
        !          1041:         gen_set_T0(simm << 16);
1.1       root     1042:     } else {
                   1043:         gen_op_load_gpr_T0(rA(ctx->opcode));
1.1.1.5 ! root     1044:         if (likely(simm != 0))
        !          1045:             gen_op_addi(simm << 16);
1.1       root     1046:     }
                   1047:     gen_op_store_T0_gpr(rD(ctx->opcode));
                   1048: }
                   1049: /* mulli */
                   1050: GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1051: {
                   1052:     gen_op_load_gpr_T0(rA(ctx->opcode));
                   1053:     gen_op_mulli(SIMM(ctx->opcode));
                   1054:     gen_op_store_T0_gpr(rD(ctx->opcode));
                   1055: }
                   1056: /* subfic */
                   1057: GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1058: {
                   1059:     gen_op_load_gpr_T0(rA(ctx->opcode));
1.1.1.5 ! root     1060: #if defined(TARGET_PPC64)
        !          1061:     if (ctx->sf_mode)
        !          1062:         gen_op_subfic_64(SIMM(ctx->opcode));
        !          1063:     else
        !          1064: #endif
        !          1065:         gen_op_subfic(SIMM(ctx->opcode));
1.1       root     1066:     gen_op_store_T0_gpr(rD(ctx->opcode));
                   1067: }
                   1068: 
1.1.1.5 ! root     1069: #if defined(TARGET_PPC64)
        !          1070: /* mulhd  mulhd.                   */
        !          1071: GEN_INT_ARITHN (mulhd,  0x1F, 0x09, 0x02, PPC_64B);
        !          1072: /* mulhdu mulhdu.                  */
        !          1073: GEN_INT_ARITHN (mulhdu, 0x1F, 0x09, 0x00, PPC_64B);
        !          1074: /* mulld  mulld.  mulldo  mulldo.  */
        !          1075: GEN_INT_ARITH2 (mulld,  0x1F, 0x09, 0x07, PPC_64B);
        !          1076: /* divd   divd.   divdo   divdo.   */
        !          1077: GEN_INT_ARITH2 (divd,   0x1F, 0x09, 0x0F, PPC_64B);
        !          1078: /* divdu  divdu.  divduo  divduo.  */
        !          1079: GEN_INT_ARITH2 (divdu,  0x1F, 0x09, 0x0E, PPC_64B);
        !          1080: #endif
        !          1081: 
1.1       root     1082: /***                           Integer comparison                          ***/
1.1.1.5 ! root     1083: #if defined(TARGET_PPC64)
        !          1084: #define GEN_CMP(name, opc, type)                                              \
        !          1085: GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
        !          1086: {                                                                             \
        !          1087:     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
        !          1088:     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
        !          1089:     if (ctx->sf_mode && (ctx->opcode & 0x00200000))                           \
        !          1090:         gen_op_##name##_64();                                                 \
        !          1091:     else                                                                      \
        !          1092:         gen_op_##name();                                                      \
        !          1093:     gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
        !          1094: }
        !          1095: #else
        !          1096: #define GEN_CMP(name, opc, type)                                              \
        !          1097: GEN_HANDLER(name, 0x1F, 0x00, opc, 0x00400000, type)                          \
1.1       root     1098: {                                                                             \
                   1099:     gen_op_load_gpr_T0(rA(ctx->opcode));                                      \
                   1100:     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
                   1101:     gen_op_##name();                                                          \
                   1102:     gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
                   1103: }
1.1.1.5 ! root     1104: #endif
1.1       root     1105: 
                   1106: /* cmp */
1.1.1.5 ! root     1107: GEN_CMP(cmp, 0x00, PPC_INTEGER);
1.1       root     1108: /* cmpi */
                   1109: GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
                   1110: {
                   1111:     gen_op_load_gpr_T0(rA(ctx->opcode));
1.1.1.5 ! root     1112: #if defined(TARGET_PPC64)
        !          1113:     if (ctx->sf_mode && (ctx->opcode & 0x00200000))
        !          1114:         gen_op_cmpi_64(SIMM(ctx->opcode));
        !          1115:     else
        !          1116: #endif
        !          1117:         gen_op_cmpi(SIMM(ctx->opcode));
1.1       root     1118:     gen_op_store_T0_crf(crfD(ctx->opcode));
                   1119: }
                   1120: /* cmpl */
1.1.1.5 ! root     1121: GEN_CMP(cmpl, 0x01, PPC_INTEGER);
1.1       root     1122: /* cmpli */
                   1123: GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
                   1124: {
                   1125:     gen_op_load_gpr_T0(rA(ctx->opcode));
1.1.1.5 ! root     1126: #if defined(TARGET_PPC64)
        !          1127:     if (ctx->sf_mode && (ctx->opcode & 0x00200000))
        !          1128:         gen_op_cmpli_64(UIMM(ctx->opcode));
        !          1129:     else
        !          1130: #endif
        !          1131:         gen_op_cmpli(UIMM(ctx->opcode));
1.1       root     1132:     gen_op_store_T0_crf(crfD(ctx->opcode));
                   1133: }
                   1134: 
1.1.1.5 ! root     1135: /* isel (PowerPC 2.03 specification) */
        !          1136: GEN_HANDLER(isel, 0x1F, 0x0F, 0x00, 0x00000001, PPC_ISEL)
        !          1137: {
        !          1138:     uint32_t bi = rC(ctx->opcode);
        !          1139:     uint32_t mask;
        !          1140: 
        !          1141:     if (rA(ctx->opcode) == 0) {
        !          1142:         gen_set_T0(0);
        !          1143:     } else {
        !          1144:         gen_op_load_gpr_T1(rA(ctx->opcode));
        !          1145:     }
        !          1146:     gen_op_load_gpr_T2(rB(ctx->opcode));
        !          1147:     mask = 1 << (3 - (bi & 0x03));
        !          1148:     gen_op_load_crf_T0(bi >> 2);
        !          1149:     gen_op_test_true(mask);
        !          1150:     gen_op_isel();
        !          1151:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          1152: }
        !          1153: 
1.1       root     1154: /***                            Integer logical                            ***/
1.1.1.5 ! root     1155: #define __GEN_LOGICAL2(name, opc2, opc3, type)                                \
        !          1156: GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000000, type)                         \
1.1       root     1157: {                                                                             \
                   1158:     gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
                   1159:     gen_op_load_gpr_T1(rB(ctx->opcode));                                      \
                   1160:     gen_op_##name();                                                          \
                   1161:     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1.1.1.5 ! root     1162:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
        !          1163:         gen_set_Rc0(ctx);                                                     \
1.1       root     1164: }
1.1.1.5 ! root     1165: #define GEN_LOGICAL2(name, opc, type)                                         \
        !          1166: __GEN_LOGICAL2(name, 0x1C, opc, type)
1.1       root     1167: 
1.1.1.5 ! root     1168: #define GEN_LOGICAL1(name, opc, type)                                         \
        !          1169: GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
1.1       root     1170: {                                                                             \
                   1171:     gen_op_load_gpr_T0(rS(ctx->opcode));                                      \
                   1172:     gen_op_##name();                                                          \
                   1173:     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
1.1.1.5 ! root     1174:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
        !          1175:         gen_set_Rc0(ctx);                                                     \
1.1       root     1176: }
                   1177: 
                   1178: /* and & and. */
1.1.1.5 ! root     1179: GEN_LOGICAL2(and, 0x00, PPC_INTEGER);
1.1       root     1180: /* andc & andc. */
1.1.1.5 ! root     1181: GEN_LOGICAL2(andc, 0x01, PPC_INTEGER);
1.1       root     1182: /* andi. */
1.1.1.5 ! root     1183: GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1.1       root     1184: {
                   1185:     gen_op_load_gpr_T0(rS(ctx->opcode));
1.1.1.5 ! root     1186:     gen_op_andi_T0(UIMM(ctx->opcode));
1.1       root     1187:     gen_op_store_T0_gpr(rA(ctx->opcode));
1.1.1.5 ! root     1188:     gen_set_Rc0(ctx);
1.1       root     1189: }
                   1190: /* andis. */
1.1.1.5 ! root     1191: GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1.1       root     1192: {
                   1193:     gen_op_load_gpr_T0(rS(ctx->opcode));
1.1.1.5 ! root     1194:     gen_op_andi_T0(UIMM(ctx->opcode) << 16);
1.1       root     1195:     gen_op_store_T0_gpr(rA(ctx->opcode));
1.1.1.5 ! root     1196:     gen_set_Rc0(ctx);
1.1       root     1197: }
                   1198: 
                   1199: /* cntlzw */
1.1.1.5 ! root     1200: GEN_LOGICAL1(cntlzw, 0x00, PPC_INTEGER);
1.1       root     1201: /* eqv & eqv. */
1.1.1.5 ! root     1202: GEN_LOGICAL2(eqv, 0x08, PPC_INTEGER);
1.1       root     1203: /* extsb & extsb. */
1.1.1.5 ! root     1204: GEN_LOGICAL1(extsb, 0x1D, PPC_INTEGER);
1.1       root     1205: /* extsh & extsh. */
1.1.1.5 ! root     1206: GEN_LOGICAL1(extsh, 0x1C, PPC_INTEGER);
1.1       root     1207: /* nand & nand. */
1.1.1.5 ! root     1208: GEN_LOGICAL2(nand, 0x0E, PPC_INTEGER);
1.1       root     1209: /* nor & nor. */
1.1.1.5 ! root     1210: GEN_LOGICAL2(nor, 0x03, PPC_INTEGER);
1.1       root     1211: 
                   1212: /* or & or. */
                   1213: GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
                   1214: {
1.1.1.5 ! root     1215:     int rs, ra, rb;
        !          1216: 
        !          1217:     rs = rS(ctx->opcode);
        !          1218:     ra = rA(ctx->opcode);
        !          1219:     rb = rB(ctx->opcode);
        !          1220:     /* Optimisation for mr. ri case */
        !          1221:     if (rs != ra || rs != rb) {
        !          1222:         gen_op_load_gpr_T0(rs);
        !          1223:         if (rs != rb) {
        !          1224:             gen_op_load_gpr_T1(rb);
        !          1225:             gen_op_or();
        !          1226:         }
        !          1227:         gen_op_store_T0_gpr(ra);
        !          1228:         if (unlikely(Rc(ctx->opcode) != 0))
        !          1229:             gen_set_Rc0(ctx);
        !          1230:     } else if (unlikely(Rc(ctx->opcode) != 0)) {
        !          1231:         gen_op_load_gpr_T0(rs);
        !          1232:         gen_set_Rc0(ctx);
        !          1233: #if defined(TARGET_PPC64)
        !          1234:     } else {
        !          1235:         switch (rs) {
        !          1236:         case 1:
        !          1237:             /* Set process priority to low */
        !          1238:             gen_op_store_pri(2);
        !          1239:             break;
        !          1240:         case 6:
        !          1241:             /* Set process priority to medium-low */
        !          1242:             gen_op_store_pri(3);
        !          1243:             break;
        !          1244:         case 2:
        !          1245:             /* Set process priority to normal */
        !          1246:             gen_op_store_pri(4);
        !          1247:             break;
        !          1248: #if !defined(CONFIG_USER_ONLY)
        !          1249:         case 31:
        !          1250:             if (ctx->supervisor > 0) {
        !          1251:                 /* Set process priority to very low */
        !          1252:                 gen_op_store_pri(1);
        !          1253:             }
        !          1254:             break;
        !          1255:         case 5:
        !          1256:             if (ctx->supervisor > 0) {
        !          1257:                 /* Set process priority to medium-hight */
        !          1258:                 gen_op_store_pri(5);
        !          1259:             }
        !          1260:             break;
        !          1261:         case 3:
        !          1262:             if (ctx->supervisor > 0) {
        !          1263:                 /* Set process priority to high */
        !          1264:                 gen_op_store_pri(6);
        !          1265:             }
        !          1266:             break;
        !          1267:         case 7:
        !          1268:             if (ctx->supervisor > 1) {
        !          1269:                 /* Set process priority to very high */
        !          1270:                 gen_op_store_pri(7);
        !          1271:             }
        !          1272:             break;
        !          1273: #endif
        !          1274:         default:
        !          1275:             /* nop */
        !          1276:             break;
        !          1277:         }
        !          1278: #endif
1.1       root     1279:     }
                   1280: }
                   1281: 
                   1282: /* orc & orc. */
1.1.1.5 ! root     1283: GEN_LOGICAL2(orc, 0x0C, PPC_INTEGER);
1.1       root     1284: /* xor & xor. */
                   1285: GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
                   1286: {
                   1287:     gen_op_load_gpr_T0(rS(ctx->opcode));
                   1288:     /* Optimisation for "set to zero" case */
                   1289:     if (rS(ctx->opcode) != rB(ctx->opcode)) {
                   1290:         gen_op_load_gpr_T1(rB(ctx->opcode));
                   1291:         gen_op_xor();
                   1292:     } else {
1.1.1.5 ! root     1293:         gen_op_reset_T0();
1.1       root     1294:     }
                   1295:     gen_op_store_T0_gpr(rA(ctx->opcode));
1.1.1.5 ! root     1296:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1297:         gen_set_Rc0(ctx);
1.1       root     1298: }
                   1299: /* ori */
                   1300: GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1301: {
1.1.1.5 ! root     1302:     target_ulong uimm = UIMM(ctx->opcode);
1.1       root     1303: 
                   1304:     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
                   1305:         /* NOP */
1.1.1.5 ! root     1306:         /* XXX: should handle special NOPs for POWER series */
1.1       root     1307:         return;
1.1.1.5 ! root     1308:     }
        !          1309:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          1310:     if (likely(uimm != 0))
1.1       root     1311:         gen_op_ori(uimm);
1.1.1.5 ! root     1312:     gen_op_store_T0_gpr(rA(ctx->opcode));
1.1       root     1313: }
                   1314: /* oris */
                   1315: GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1316: {
1.1.1.5 ! root     1317:     target_ulong uimm = UIMM(ctx->opcode);
1.1       root     1318: 
                   1319:     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
                   1320:         /* NOP */
                   1321:         return;
1.1.1.5 ! root     1322:     }
        !          1323:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          1324:     if (likely(uimm != 0))
1.1       root     1325:         gen_op_ori(uimm << 16);
1.1.1.5 ! root     1326:     gen_op_store_T0_gpr(rA(ctx->opcode));
1.1       root     1327: }
                   1328: /* xori */
                   1329: GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1330: {
1.1.1.5 ! root     1331:     target_ulong uimm = UIMM(ctx->opcode);
1.1       root     1332: 
                   1333:     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
                   1334:         /* NOP */
                   1335:         return;
                   1336:     }
                   1337:     gen_op_load_gpr_T0(rS(ctx->opcode));
1.1.1.5 ! root     1338:     if (likely(uimm != 0))
        !          1339:         gen_op_xori(uimm);
1.1       root     1340:     gen_op_store_T0_gpr(rA(ctx->opcode));
                   1341: }
                   1342: 
                   1343: /* xoris */
                   1344: GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1345: {
1.1.1.5 ! root     1346:     target_ulong uimm = UIMM(ctx->opcode);
1.1       root     1347: 
                   1348:     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
                   1349:         /* NOP */
                   1350:         return;
                   1351:     }
                   1352:     gen_op_load_gpr_T0(rS(ctx->opcode));
1.1.1.5 ! root     1353:     if (likely(uimm != 0))
        !          1354:         gen_op_xori(uimm << 16);
        !          1355:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          1356: }
        !          1357: 
        !          1358: /* popcntb : PowerPC 2.03 specification */
        !          1359: GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB)
        !          1360: {
        !          1361:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          1362: #if defined(TARGET_PPC64)
        !          1363:     if (ctx->sf_mode)
        !          1364:         gen_op_popcntb_64();
        !          1365:     else
        !          1366: #endif
        !          1367:         gen_op_popcntb();
1.1       root     1368:     gen_op_store_T0_gpr(rA(ctx->opcode));
                   1369: }
                   1370: 
1.1.1.5 ! root     1371: #if defined(TARGET_PPC64)
        !          1372: /* extsw & extsw. */
        !          1373: GEN_LOGICAL1(extsw, 0x1E, PPC_64B);
        !          1374: /* cntlzd */
        !          1375: GEN_LOGICAL1(cntlzd, 0x01, PPC_64B);
        !          1376: #endif
        !          1377: 
1.1       root     1378: /***                             Integer rotate                            ***/
                   1379: /* rlwimi & rlwimi. */
                   1380: GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1381: {
1.1.1.5 ! root     1382:     target_ulong mask;
        !          1383:     uint32_t mb, me, sh;
1.1       root     1384: 
                   1385:     mb = MB(ctx->opcode);
                   1386:     me = ME(ctx->opcode);
1.1.1.5 ! root     1387:     sh = SH(ctx->opcode);
        !          1388:     if (likely(sh == 0)) {
        !          1389:         if (likely(mb == 0 && me == 31)) {
        !          1390:             gen_op_load_gpr_T0(rS(ctx->opcode));
        !          1391:             goto do_store;
        !          1392:         } else if (likely(mb == 31 && me == 0)) {
        !          1393:             gen_op_load_gpr_T0(rA(ctx->opcode));
        !          1394:             goto do_store;
        !          1395:         }
        !          1396:         gen_op_load_gpr_T0(rS(ctx->opcode));
        !          1397:         gen_op_load_gpr_T1(rA(ctx->opcode));
        !          1398:         goto do_mask;
        !          1399:     }
1.1       root     1400:     gen_op_load_gpr_T0(rS(ctx->opcode));
                   1401:     gen_op_load_gpr_T1(rA(ctx->opcode));
1.1.1.5 ! root     1402:     gen_op_rotli32_T0(SH(ctx->opcode));
        !          1403:  do_mask:
        !          1404: #if defined(TARGET_PPC64)
        !          1405:     mb += 32;
        !          1406:     me += 32;
        !          1407: #endif
        !          1408:     mask = MASK(mb, me);
        !          1409:     gen_op_andi_T0(mask);
        !          1410:     gen_op_andi_T1(~mask);
        !          1411:     gen_op_or();
        !          1412:  do_store:
1.1       root     1413:     gen_op_store_T0_gpr(rA(ctx->opcode));
1.1.1.5 ! root     1414:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1415:         gen_set_Rc0(ctx);
1.1       root     1416: }
                   1417: /* rlwinm & rlwinm. */
                   1418: GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1419: {
                   1420:     uint32_t mb, me, sh;
1.1.1.5 ! root     1421: 
1.1       root     1422:     sh = SH(ctx->opcode);
                   1423:     mb = MB(ctx->opcode);
                   1424:     me = ME(ctx->opcode);
                   1425:     gen_op_load_gpr_T0(rS(ctx->opcode));
1.1.1.5 ! root     1426:     if (likely(sh == 0)) {
        !          1427:         goto do_mask;
1.1       root     1428:     }
1.1.1.5 ! root     1429:     if (likely(mb == 0)) {
        !          1430:         if (likely(me == 31)) {
        !          1431:             gen_op_rotli32_T0(sh);
        !          1432:             goto do_store;
        !          1433:         } else if (likely(me == (31 - sh))) {
        !          1434:             gen_op_sli_T0(sh);
        !          1435:             goto do_store;
1.1       root     1436:         }
1.1.1.5 ! root     1437:     } else if (likely(me == 31)) {
        !          1438:         if (likely(sh == (32 - mb))) {
        !          1439:             gen_op_srli_T0(mb);
        !          1440:             goto do_store;
1.1       root     1441:         }
                   1442:     }
1.1.1.5 ! root     1443:     gen_op_rotli32_T0(sh);
        !          1444:  do_mask:
        !          1445: #if defined(TARGET_PPC64)
        !          1446:     mb += 32;
        !          1447:     me += 32;
        !          1448: #endif
        !          1449:     gen_op_andi_T0(MASK(mb, me));
        !          1450:  do_store:
1.1       root     1451:     gen_op_store_T0_gpr(rA(ctx->opcode));
1.1.1.5 ! root     1452:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1453:         gen_set_Rc0(ctx);
1.1       root     1454: }
                   1455: /* rlwnm & rlwnm. */
                   1456: GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1457: {
                   1458:     uint32_t mb, me;
                   1459: 
                   1460:     mb = MB(ctx->opcode);
                   1461:     me = ME(ctx->opcode);
                   1462:     gen_op_load_gpr_T0(rS(ctx->opcode));
                   1463:     gen_op_load_gpr_T1(rB(ctx->opcode));
1.1.1.5 ! root     1464:     gen_op_rotl32_T0_T1();
        !          1465:     if (unlikely(mb != 0 || me != 31)) {
        !          1466: #if defined(TARGET_PPC64)
        !          1467:         mb += 32;
        !          1468:         me += 32;
        !          1469: #endif
        !          1470:         gen_op_andi_T0(MASK(mb, me));
1.1       root     1471:     }
                   1472:     gen_op_store_T0_gpr(rA(ctx->opcode));
1.1.1.5 ! root     1473:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1474:         gen_set_Rc0(ctx);
        !          1475: }
        !          1476: 
        !          1477: #if defined(TARGET_PPC64)
        !          1478: #define GEN_PPC64_R2(name, opc1, opc2)                                        \
        !          1479: GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
        !          1480: {                                                                             \
        !          1481:     gen_##name(ctx, 0);                                                       \
        !          1482: }                                                                             \
        !          1483: GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
        !          1484:              PPC_64B)                                                         \
        !          1485: {                                                                             \
        !          1486:     gen_##name(ctx, 1);                                                       \
        !          1487: }
        !          1488: #define GEN_PPC64_R4(name, opc1, opc2)                                        \
        !          1489: GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
        !          1490: {                                                                             \
        !          1491:     gen_##name(ctx, 0, 0);                                                    \
        !          1492: }                                                                             \
        !          1493: GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
        !          1494:              PPC_64B)                                                         \
        !          1495: {                                                                             \
        !          1496:     gen_##name(ctx, 0, 1);                                                    \
        !          1497: }                                                                             \
        !          1498: GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
        !          1499:              PPC_64B)                                                         \
        !          1500: {                                                                             \
        !          1501:     gen_##name(ctx, 1, 0);                                                    \
        !          1502: }                                                                             \
        !          1503: GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
        !          1504:              PPC_64B)                                                         \
        !          1505: {                                                                             \
        !          1506:     gen_##name(ctx, 1, 1);                                                    \
        !          1507: }
        !          1508: 
        !          1509: static always_inline void gen_andi_T0_64 (DisasContext *ctx, uint64_t mask)
        !          1510: {
        !          1511:     if (mask >> 32)
        !          1512:         gen_op_andi_T0_64(mask >> 32, mask & 0xFFFFFFFF);
        !          1513:     else
        !          1514:         gen_op_andi_T0(mask);
        !          1515: }
        !          1516: 
        !          1517: static always_inline void gen_andi_T1_64 (DisasContext *ctx, uint64_t mask)
        !          1518: {
        !          1519:     if (mask >> 32)
        !          1520:         gen_op_andi_T1_64(mask >> 32, mask & 0xFFFFFFFF);
        !          1521:     else
        !          1522:         gen_op_andi_T1(mask);
        !          1523: }
        !          1524: 
        !          1525: static always_inline void gen_rldinm (DisasContext *ctx, uint32_t mb,
        !          1526:                                       uint32_t me, uint32_t sh)
        !          1527: {
        !          1528:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          1529:     if (likely(sh == 0)) {
        !          1530:         goto do_mask;
        !          1531:     }
        !          1532:     if (likely(mb == 0)) {
        !          1533:         if (likely(me == 63)) {
        !          1534:             gen_op_rotli64_T0(sh);
        !          1535:             goto do_store;
        !          1536:         } else if (likely(me == (63 - sh))) {
        !          1537:             gen_op_sli_T0(sh);
        !          1538:             goto do_store;
        !          1539:         }
        !          1540:     } else if (likely(me == 63)) {
        !          1541:         if (likely(sh == (64 - mb))) {
        !          1542:             gen_op_srli_T0_64(mb);
        !          1543:             goto do_store;
        !          1544:         }
        !          1545:     }
        !          1546:     gen_op_rotli64_T0(sh);
        !          1547:  do_mask:
        !          1548:     gen_andi_T0_64(ctx, MASK(mb, me));
        !          1549:  do_store:
        !          1550:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          1551:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1552:         gen_set_Rc0(ctx);
        !          1553: }
        !          1554: /* rldicl - rldicl. */
        !          1555: static always_inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
        !          1556: {
        !          1557:     uint32_t sh, mb;
        !          1558: 
        !          1559:     sh = SH(ctx->opcode) | (shn << 5);
        !          1560:     mb = MB(ctx->opcode) | (mbn << 5);
        !          1561:     gen_rldinm(ctx, mb, 63, sh);
        !          1562: }
        !          1563: GEN_PPC64_R4(rldicl, 0x1E, 0x00);
        !          1564: /* rldicr - rldicr. */
        !          1565: static always_inline void gen_rldicr (DisasContext *ctx, int men, int shn)
        !          1566: {
        !          1567:     uint32_t sh, me;
        !          1568: 
        !          1569:     sh = SH(ctx->opcode) | (shn << 5);
        !          1570:     me = MB(ctx->opcode) | (men << 5);
        !          1571:     gen_rldinm(ctx, 0, me, sh);
        !          1572: }
        !          1573: GEN_PPC64_R4(rldicr, 0x1E, 0x02);
        !          1574: /* rldic - rldic. */
        !          1575: static always_inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
        !          1576: {
        !          1577:     uint32_t sh, mb;
        !          1578: 
        !          1579:     sh = SH(ctx->opcode) | (shn << 5);
        !          1580:     mb = MB(ctx->opcode) | (mbn << 5);
        !          1581:     gen_rldinm(ctx, mb, 63 - sh, sh);
        !          1582: }
        !          1583: GEN_PPC64_R4(rldic, 0x1E, 0x04);
        !          1584: 
        !          1585: static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb,
        !          1586:                                      uint32_t me)
        !          1587: {
        !          1588:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          1589:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          1590:     gen_op_rotl64_T0_T1();
        !          1591:     if (unlikely(mb != 0 || me != 63)) {
        !          1592:         gen_andi_T0_64(ctx, MASK(mb, me));
        !          1593:     }
        !          1594:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          1595:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1596:         gen_set_Rc0(ctx);
        !          1597: }
        !          1598: 
        !          1599: /* rldcl - rldcl. */
        !          1600: static always_inline void gen_rldcl (DisasContext *ctx, int mbn)
        !          1601: {
        !          1602:     uint32_t mb;
        !          1603: 
        !          1604:     mb = MB(ctx->opcode) | (mbn << 5);
        !          1605:     gen_rldnm(ctx, mb, 63);
        !          1606: }
        !          1607: GEN_PPC64_R2(rldcl, 0x1E, 0x08);
        !          1608: /* rldcr - rldcr. */
        !          1609: static always_inline void gen_rldcr (DisasContext *ctx, int men)
        !          1610: {
        !          1611:     uint32_t me;
        !          1612: 
        !          1613:     me = MB(ctx->opcode) | (men << 5);
        !          1614:     gen_rldnm(ctx, 0, me);
        !          1615: }
        !          1616: GEN_PPC64_R2(rldcr, 0x1E, 0x09);
        !          1617: /* rldimi - rldimi. */
        !          1618: static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
        !          1619: {
        !          1620:     uint64_t mask;
        !          1621:     uint32_t sh, mb, me;
        !          1622: 
        !          1623:     sh = SH(ctx->opcode) | (shn << 5);
        !          1624:     mb = MB(ctx->opcode) | (mbn << 5);
        !          1625:     me = 63 - sh;
        !          1626:     if (likely(sh == 0)) {
        !          1627:         if (likely(mb == 0)) {
        !          1628:             gen_op_load_gpr_T0(rS(ctx->opcode));
        !          1629:             goto do_store;
        !          1630:         }
        !          1631:         gen_op_load_gpr_T0(rS(ctx->opcode));
        !          1632:         gen_op_load_gpr_T1(rA(ctx->opcode));
        !          1633:         goto do_mask;
        !          1634:     }
        !          1635:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          1636:     gen_op_load_gpr_T1(rA(ctx->opcode));
        !          1637:     gen_op_rotli64_T0(sh);
        !          1638:  do_mask:
        !          1639:     mask = MASK(mb, me);
        !          1640:     gen_andi_T0_64(ctx, mask);
        !          1641:     gen_andi_T1_64(ctx, ~mask);
        !          1642:     gen_op_or();
        !          1643:  do_store:
        !          1644:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          1645:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1646:         gen_set_Rc0(ctx);
1.1       root     1647: }
1.1.1.5 ! root     1648: GEN_PPC64_R4(rldimi, 0x1E, 0x06);
        !          1649: #endif
1.1       root     1650: 
                   1651: /***                             Integer shift                             ***/
                   1652: /* slw & slw. */
1.1.1.5 ! root     1653: __GEN_LOGICAL2(slw, 0x18, 0x00, PPC_INTEGER);
1.1       root     1654: /* sraw & sraw. */
1.1.1.5 ! root     1655: __GEN_LOGICAL2(sraw, 0x18, 0x18, PPC_INTEGER);
1.1       root     1656: /* srawi & srawi. */
                   1657: GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
                   1658: {
1.1.1.5 ! root     1659:     int mb, me;
1.1       root     1660:     gen_op_load_gpr_T0(rS(ctx->opcode));
1.1.1.5 ! root     1661:     if (SH(ctx->opcode) != 0) {
        !          1662:         gen_op_move_T1_T0();
        !          1663:         mb = 32 - SH(ctx->opcode);
        !          1664:         me = 31;
        !          1665: #if defined(TARGET_PPC64)
        !          1666:         mb += 32;
        !          1667:         me += 32;
        !          1668: #endif
        !          1669:         gen_op_srawi(SH(ctx->opcode), MASK(mb, me));
        !          1670:     }
1.1       root     1671:     gen_op_store_T0_gpr(rA(ctx->opcode));
1.1.1.5 ! root     1672:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1673:         gen_set_Rc0(ctx);
1.1       root     1674: }
                   1675: /* srw & srw. */
1.1.1.5 ! root     1676: __GEN_LOGICAL2(srw, 0x18, 0x10, PPC_INTEGER);
        !          1677: 
        !          1678: #if defined(TARGET_PPC64)
        !          1679: /* sld & sld. */
        !          1680: __GEN_LOGICAL2(sld, 0x1B, 0x00, PPC_64B);
        !          1681: /* srad & srad. */
        !          1682: __GEN_LOGICAL2(srad, 0x1A, 0x18, PPC_64B);
        !          1683: /* sradi & sradi. */
        !          1684: static always_inline void gen_sradi (DisasContext *ctx, int n)
        !          1685: {
        !          1686:     uint64_t mask;
        !          1687:     int sh, mb, me;
        !          1688: 
        !          1689:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          1690:     sh = SH(ctx->opcode) + (n << 5);
        !          1691:     if (sh != 0) {
        !          1692:         gen_op_move_T1_T0();
        !          1693:         mb = 64 - SH(ctx->opcode);
        !          1694:         me = 63;
        !          1695:         mask = MASK(mb, me);
        !          1696:         gen_op_sradi(sh, mask >> 32, mask);
        !          1697:     }
        !          1698:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          1699:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1700:         gen_set_Rc0(ctx);
        !          1701: }
        !          1702: GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
        !          1703: {
        !          1704:     gen_sradi(ctx, 0);
        !          1705: }
        !          1706: GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
        !          1707: {
        !          1708:     gen_sradi(ctx, 1);
        !          1709: }
        !          1710: /* srd & srd. */
        !          1711: __GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
        !          1712: #endif
1.1       root     1713: 
                   1714: /***                       Floating-Point arithmetic                       ***/
1.1.1.5 ! root     1715: #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
        !          1716: GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)                        \
1.1       root     1717: {                                                                             \
1.1.1.5 ! root     1718:     if (unlikely(!ctx->fpu_enabled)) {                                        \
        !          1719:         GEN_EXCP_NO_FP(ctx);                                                  \
1.1       root     1720:         return;                                                               \
                   1721:     }                                                                         \
                   1722:     gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
                   1723:     gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
                   1724:     gen_op_load_fpr_FT2(rB(ctx->opcode));                                     \
1.1.1.5 ! root     1725:     gen_reset_fpstatus();                                                     \
1.1       root     1726:     gen_op_f##op();                                                           \
                   1727:     if (isfloat) {                                                            \
                   1728:         gen_op_frsp();                                                        \
                   1729:     }                                                                         \
                   1730:     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1.1.1.5 ! root     1731:     gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     1732: }
                   1733: 
1.1.1.5 ! root     1734: #define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
        !          1735: _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
        !          1736: _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
1.1       root     1737: 
1.1.1.5 ! root     1738: #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
        !          1739: GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1.1       root     1740: {                                                                             \
1.1.1.5 ! root     1741:     if (unlikely(!ctx->fpu_enabled)) {                                        \
        !          1742:         GEN_EXCP_NO_FP(ctx);                                                  \
1.1       root     1743:         return;                                                               \
                   1744:     }                                                                         \
                   1745:     gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
                   1746:     gen_op_load_fpr_FT1(rB(ctx->opcode));                                     \
1.1.1.5 ! root     1747:     gen_reset_fpstatus();                                                     \
1.1       root     1748:     gen_op_f##op();                                                           \
                   1749:     if (isfloat) {                                                            \
                   1750:         gen_op_frsp();                                                        \
                   1751:     }                                                                         \
                   1752:     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1.1.1.5 ! root     1753:     gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     1754: }
1.1.1.5 ! root     1755: #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
        !          1756: _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
        !          1757: _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1.1       root     1758: 
1.1.1.5 ! root     1759: #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
        !          1760: GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1.1       root     1761: {                                                                             \
1.1.1.5 ! root     1762:     if (unlikely(!ctx->fpu_enabled)) {                                        \
        !          1763:         GEN_EXCP_NO_FP(ctx);                                                  \
1.1       root     1764:         return;                                                               \
                   1765:     }                                                                         \
                   1766:     gen_op_load_fpr_FT0(rA(ctx->opcode));                                     \
                   1767:     gen_op_load_fpr_FT1(rC(ctx->opcode));                                     \
1.1.1.5 ! root     1768:     gen_reset_fpstatus();                                                     \
1.1       root     1769:     gen_op_f##op();                                                           \
                   1770:     if (isfloat) {                                                            \
                   1771:         gen_op_frsp();                                                        \
                   1772:     }                                                                         \
                   1773:     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1.1.1.5 ! root     1774:     gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     1775: }
1.1.1.5 ! root     1776: #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
        !          1777: _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
        !          1778: _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1.1       root     1779: 
1.1.1.5 ! root     1780: #define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
        !          1781: GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)                        \
1.1       root     1782: {                                                                             \
1.1.1.5 ! root     1783:     if (unlikely(!ctx->fpu_enabled)) {                                        \
        !          1784:         GEN_EXCP_NO_FP(ctx);                                                  \
1.1       root     1785:         return;                                                               \
                   1786:     }                                                                         \
                   1787:     gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1.1.1.5 ! root     1788:     gen_reset_fpstatus();                                                     \
1.1       root     1789:     gen_op_f##name();                                                         \
                   1790:     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1.1.1.5 ! root     1791:     gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     1792: }
                   1793: 
1.1.1.5 ! root     1794: #define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
        !          1795: GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
1.1       root     1796: {                                                                             \
1.1.1.5 ! root     1797:     if (unlikely(!ctx->fpu_enabled)) {                                        \
        !          1798:         GEN_EXCP_NO_FP(ctx);                                                  \
1.1       root     1799:         return;                                                               \
                   1800:     }                                                                         \
                   1801:     gen_op_load_fpr_FT0(rB(ctx->opcode));                                     \
1.1.1.5 ! root     1802:     gen_reset_fpstatus();                                                     \
1.1       root     1803:     gen_op_f##name();                                                         \
                   1804:     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1.1.1.5 ! root     1805:     gen_compute_fprf(set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     1806: }
                   1807: 
                   1808: /* fadd - fadds */
1.1.1.5 ! root     1809: GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
1.1       root     1810: /* fdiv - fdivs */
1.1.1.5 ! root     1811: GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
1.1       root     1812: /* fmul - fmuls */
1.1.1.5 ! root     1813: GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
        !          1814: 
        !          1815: /* fre */
        !          1816: GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
1.1       root     1817: 
                   1818: /* fres */
1.1.1.5 ! root     1819: GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
1.1       root     1820: 
                   1821: /* frsqrte */
1.1.1.5 ! root     1822: GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
        !          1823: 
        !          1824: /* frsqrtes */
        !          1825: static always_inline void gen_op_frsqrtes (void)
        !          1826: {
        !          1827:     gen_op_frsqrte();
        !          1828:     gen_op_frsp();
        !          1829: }
        !          1830: GEN_FLOAT_BS(rsqrtes, 0x3B, 0x1A, 1, PPC_FLOAT_FRSQRTES);
1.1       root     1831: 
                   1832: /* fsel */
1.1.1.5 ! root     1833: _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
1.1       root     1834: /* fsub - fsubs */
1.1.1.5 ! root     1835: GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
1.1       root     1836: /* Optional: */
                   1837: /* fsqrt */
1.1.1.5 ! root     1838: GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1.1       root     1839: {
1.1.1.5 ! root     1840:     if (unlikely(!ctx->fpu_enabled)) {
        !          1841:         GEN_EXCP_NO_FP(ctx);
1.1       root     1842:         return;
                   1843:     }
                   1844:     gen_op_load_fpr_FT0(rB(ctx->opcode));
1.1.1.5 ! root     1845:     gen_reset_fpstatus();
1.1       root     1846:     gen_op_fsqrt();
                   1847:     gen_op_store_FT0_fpr(rD(ctx->opcode));
1.1.1.5 ! root     1848:     gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1.1       root     1849: }
                   1850: 
1.1.1.5 ! root     1851: GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1.1       root     1852: {
1.1.1.5 ! root     1853:     if (unlikely(!ctx->fpu_enabled)) {
        !          1854:         GEN_EXCP_NO_FP(ctx);
1.1       root     1855:         return;
                   1856:     }
                   1857:     gen_op_load_fpr_FT0(rB(ctx->opcode));
1.1.1.5 ! root     1858:     gen_reset_fpstatus();
1.1       root     1859:     gen_op_fsqrt();
                   1860:     gen_op_frsp();
                   1861:     gen_op_store_FT0_fpr(rD(ctx->opcode));
1.1.1.5 ! root     1862:     gen_compute_fprf(1, Rc(ctx->opcode) != 0);
1.1       root     1863: }
                   1864: 
                   1865: /***                     Floating-Point multiply-and-add                   ***/
                   1866: /* fmadd - fmadds */
1.1.1.5 ! root     1867: GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
1.1       root     1868: /* fmsub - fmsubs */
1.1.1.5 ! root     1869: GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
1.1       root     1870: /* fnmadd - fnmadds */
1.1.1.5 ! root     1871: GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
1.1       root     1872: /* fnmsub - fnmsubs */
1.1.1.5 ! root     1873: GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
1.1       root     1874: 
                   1875: /***                     Floating-Point round & convert                    ***/
                   1876: /* fctiw */
1.1.1.5 ! root     1877: GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
1.1       root     1878: /* fctiwz */
1.1.1.5 ! root     1879: GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
1.1       root     1880: /* frsp */
1.1.1.5 ! root     1881: GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
        !          1882: #if defined(TARGET_PPC64)
        !          1883: /* fcfid */
        !          1884: GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
        !          1885: /* fctid */
        !          1886: GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
        !          1887: /* fctidz */
        !          1888: GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
        !          1889: #endif
        !          1890: 
        !          1891: /* frin */
        !          1892: GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
        !          1893: /* friz */
        !          1894: GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
        !          1895: /* frip */
        !          1896: GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
        !          1897: /* frim */
        !          1898: GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
1.1       root     1899: 
                   1900: /***                         Floating-Point compare                        ***/
                   1901: /* fcmpo */
1.1.1.5 ! root     1902: GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1.1       root     1903: {
1.1.1.5 ! root     1904:     if (unlikely(!ctx->fpu_enabled)) {
        !          1905:         GEN_EXCP_NO_FP(ctx);
1.1       root     1906:         return;
                   1907:     }
                   1908:     gen_op_load_fpr_FT0(rA(ctx->opcode));
                   1909:     gen_op_load_fpr_FT1(rB(ctx->opcode));
1.1.1.5 ! root     1910:     gen_reset_fpstatus();
1.1       root     1911:     gen_op_fcmpo();
                   1912:     gen_op_store_T0_crf(crfD(ctx->opcode));
1.1.1.5 ! root     1913:     gen_op_float_check_status();
1.1       root     1914: }
                   1915: 
                   1916: /* fcmpu */
1.1.1.5 ! root     1917: GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1.1       root     1918: {
1.1.1.5 ! root     1919:     if (unlikely(!ctx->fpu_enabled)) {
        !          1920:         GEN_EXCP_NO_FP(ctx);
1.1       root     1921:         return;
                   1922:     }
                   1923:     gen_op_load_fpr_FT0(rA(ctx->opcode));
                   1924:     gen_op_load_fpr_FT1(rB(ctx->opcode));
1.1.1.5 ! root     1925:     gen_reset_fpstatus();
1.1       root     1926:     gen_op_fcmpu();
                   1927:     gen_op_store_T0_crf(crfD(ctx->opcode));
1.1.1.5 ! root     1928:     gen_op_float_check_status();
1.1       root     1929: }
                   1930: 
                   1931: /***                         Floating-point move                           ***/
                   1932: /* fabs */
1.1.1.5 ! root     1933: /* XXX: beware that fabs never checks for NaNs nor update FPSCR */
        !          1934: GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
1.1       root     1935: 
                   1936: /* fmr  - fmr. */
1.1.1.5 ! root     1937: /* XXX: beware that fmr never checks for NaNs nor update FPSCR */
1.1       root     1938: GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
                   1939: {
1.1.1.5 ! root     1940:     if (unlikely(!ctx->fpu_enabled)) {
        !          1941:         GEN_EXCP_NO_FP(ctx);
1.1       root     1942:         return;
                   1943:     }
                   1944:     gen_op_load_fpr_FT0(rB(ctx->opcode));
                   1945:     gen_op_store_FT0_fpr(rD(ctx->opcode));
1.1.1.5 ! root     1946:     gen_compute_fprf(0, Rc(ctx->opcode) != 0);
1.1       root     1947: }
                   1948: 
                   1949: /* fnabs */
1.1.1.5 ! root     1950: /* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
        !          1951: GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
1.1       root     1952: /* fneg */
1.1.1.5 ! root     1953: /* XXX: beware that fneg never checks for NaNs nor update FPSCR */
        !          1954: GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
1.1       root     1955: 
                   1956: /***                  Floating-Point status & ctrl register                ***/
                   1957: /* mcrfs */
                   1958: GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
                   1959: {
1.1.1.5 ! root     1960:     int bfa;
        !          1961: 
        !          1962:     if (unlikely(!ctx->fpu_enabled)) {
        !          1963:         GEN_EXCP_NO_FP(ctx);
1.1       root     1964:         return;
                   1965:     }
1.1.1.5 ! root     1966:     gen_optimize_fprf();
        !          1967:     bfa = 4 * (7 - crfS(ctx->opcode));
        !          1968:     gen_op_load_fpscr_T0(bfa);
1.1       root     1969:     gen_op_store_T0_crf(crfD(ctx->opcode));
1.1.1.5 ! root     1970:     gen_op_fpscr_resetbit(~(0xF << bfa));
1.1       root     1971: }
                   1972: 
                   1973: /* mffs */
                   1974: GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
                   1975: {
1.1.1.5 ! root     1976:     if (unlikely(!ctx->fpu_enabled)) {
        !          1977:         GEN_EXCP_NO_FP(ctx);
1.1       root     1978:         return;
                   1979:     }
1.1.1.5 ! root     1980:     gen_optimize_fprf();
        !          1981:     gen_reset_fpstatus();
        !          1982:     gen_op_load_fpscr_FT0();
1.1       root     1983:     gen_op_store_FT0_fpr(rD(ctx->opcode));
1.1.1.5 ! root     1984:     gen_compute_fprf(0, Rc(ctx->opcode) != 0);
1.1       root     1985: }
                   1986: 
                   1987: /* mtfsb0 */
                   1988: GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
                   1989: {
                   1990:     uint8_t crb;
1.1.1.5 ! root     1991: 
        !          1992:     if (unlikely(!ctx->fpu_enabled)) {
        !          1993:         GEN_EXCP_NO_FP(ctx);
1.1       root     1994:         return;
                   1995:     }
1.1.1.5 ! root     1996:     crb = 32 - (crbD(ctx->opcode) >> 2);
        !          1997:     gen_optimize_fprf();
        !          1998:     gen_reset_fpstatus();
        !          1999:     if (likely(crb != 30 && crb != 29))
        !          2000:         gen_op_fpscr_resetbit(~(1 << crb));
        !          2001:     if (unlikely(Rc(ctx->opcode) != 0)) {
        !          2002:         gen_op_load_fpcc();
        !          2003:         gen_op_set_Rc0();
        !          2004:     }
1.1       root     2005: }
                   2006: 
                   2007: /* mtfsb1 */
                   2008: GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
                   2009: {
                   2010:     uint8_t crb;
1.1.1.5 ! root     2011: 
        !          2012:     if (unlikely(!ctx->fpu_enabled)) {
        !          2013:         GEN_EXCP_NO_FP(ctx);
1.1       root     2014:         return;
                   2015:     }
1.1.1.5 ! root     2016:     crb = 32 - (crbD(ctx->opcode) >> 2);
        !          2017:     gen_optimize_fprf();
        !          2018:     gen_reset_fpstatus();
        !          2019:     /* XXX: we pretend we can only do IEEE floating-point computations */
        !          2020:     if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI))
        !          2021:         gen_op_fpscr_setbit(crb);
        !          2022:     if (unlikely(Rc(ctx->opcode) != 0)) {
        !          2023:         gen_op_load_fpcc();
        !          2024:         gen_op_set_Rc0();
        !          2025:     }
        !          2026:     /* We can raise a differed exception */
        !          2027:     gen_op_float_check_status();
1.1       root     2028: }
                   2029: 
                   2030: /* mtfsf */
                   2031: GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
                   2032: {
1.1.1.5 ! root     2033:     if (unlikely(!ctx->fpu_enabled)) {
        !          2034:         GEN_EXCP_NO_FP(ctx);
1.1       root     2035:         return;
                   2036:     }
1.1.1.5 ! root     2037:     gen_optimize_fprf();
1.1       root     2038:     gen_op_load_fpr_FT0(rB(ctx->opcode));
1.1.1.5 ! root     2039:     gen_reset_fpstatus();
1.1       root     2040:     gen_op_store_fpscr(FM(ctx->opcode));
1.1.1.5 ! root     2041:     if (unlikely(Rc(ctx->opcode) != 0)) {
        !          2042:         gen_op_load_fpcc();
        !          2043:         gen_op_set_Rc0();
        !          2044:     }
        !          2045:     /* We can raise a differed exception */
        !          2046:     gen_op_float_check_status();
1.1       root     2047: }
                   2048: 
                   2049: /* mtfsfi */
                   2050: GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
                   2051: {
1.1.1.5 ! root     2052:     int bf, sh;
        !          2053: 
        !          2054:     if (unlikely(!ctx->fpu_enabled)) {
        !          2055:         GEN_EXCP_NO_FP(ctx);
1.1       root     2056:         return;
                   2057:     }
1.1.1.5 ! root     2058:     bf = crbD(ctx->opcode) >> 2;
        !          2059:     sh = 7 - bf;
        !          2060:     gen_optimize_fprf();
        !          2061:     gen_op_set_FT0(FPIMM(ctx->opcode) << (4 * sh));
        !          2062:     gen_reset_fpstatus();
        !          2063:     gen_op_store_fpscr(1 << sh);
        !          2064:     if (unlikely(Rc(ctx->opcode) != 0)) {
        !          2065:         gen_op_load_fpcc();
        !          2066:         gen_op_set_Rc0();
        !          2067:     }
        !          2068:     /* We can raise a differed exception */
        !          2069:     gen_op_float_check_status();
1.1       root     2070: }
                   2071: 
1.1.1.5 ! root     2072: /***                           Addressing modes                            ***/
        !          2073: /* Register indirect with immediate index : EA = (rA|0) + SIMM */
        !          2074: static always_inline void gen_addr_imm_index (DisasContext *ctx,
        !          2075:                                               target_long maskl)
        !          2076: {
        !          2077:     target_long simm = SIMM(ctx->opcode);
        !          2078: 
        !          2079:     simm &= ~maskl;
        !          2080:     if (rA(ctx->opcode) == 0) {
        !          2081:         gen_set_T0(simm);
        !          2082:     } else {
        !          2083:         gen_op_load_gpr_T0(rA(ctx->opcode));
        !          2084:         if (likely(simm != 0))
        !          2085:             gen_op_addi(simm);
        !          2086:     }
        !          2087: #ifdef DEBUG_MEMORY_ACCESSES
        !          2088:     gen_op_print_mem_EA();
        !          2089: #endif
        !          2090: }
        !          2091: 
        !          2092: static always_inline void gen_addr_reg_index (DisasContext *ctx)
        !          2093: {
        !          2094:     if (rA(ctx->opcode) == 0) {
        !          2095:         gen_op_load_gpr_T0(rB(ctx->opcode));
        !          2096:     } else {
        !          2097:         gen_op_load_gpr_T0(rA(ctx->opcode));
        !          2098:         gen_op_load_gpr_T1(rB(ctx->opcode));
        !          2099:         gen_op_add();
        !          2100:     }
        !          2101: #ifdef DEBUG_MEMORY_ACCESSES
        !          2102:     gen_op_print_mem_EA();
        !          2103: #endif
        !          2104: }
        !          2105: 
        !          2106: static always_inline void gen_addr_register (DisasContext *ctx)
        !          2107: {
        !          2108:     if (rA(ctx->opcode) == 0) {
        !          2109:         gen_op_reset_T0();
        !          2110:     } else {
        !          2111:         gen_op_load_gpr_T0(rA(ctx->opcode));
        !          2112:     }
        !          2113: #ifdef DEBUG_MEMORY_ACCESSES
        !          2114:     gen_op_print_mem_EA();
        !          2115: #endif
        !          2116: }
        !          2117: 
        !          2118: #if defined(TARGET_PPC64)
        !          2119: #define _GEN_MEM_FUNCS(name, mode)                                            \
        !          2120:     &gen_op_##name##_##mode,                                                  \
        !          2121:     &gen_op_##name##_le_##mode,                                               \
        !          2122:     &gen_op_##name##_64_##mode,                                               \
        !          2123:     &gen_op_##name##_le_64_##mode
        !          2124: #else
        !          2125: #define _GEN_MEM_FUNCS(name, mode)                                            \
        !          2126:     &gen_op_##name##_##mode,                                                  \
        !          2127:     &gen_op_##name##_le_##mode
        !          2128: #endif
        !          2129: #if defined(CONFIG_USER_ONLY)
        !          2130: #if defined(TARGET_PPC64)
        !          2131: #define NB_MEM_FUNCS 4
        !          2132: #else
        !          2133: #define NB_MEM_FUNCS 2
        !          2134: #endif
        !          2135: #define GEN_MEM_FUNCS(name)                                                   \
        !          2136:     _GEN_MEM_FUNCS(name, raw)
        !          2137: #else
        !          2138: #if defined(TARGET_PPC64)
        !          2139: #define NB_MEM_FUNCS 12
        !          2140: #else
        !          2141: #define NB_MEM_FUNCS 6
        !          2142: #endif
        !          2143: #define GEN_MEM_FUNCS(name)                                                   \
        !          2144:     _GEN_MEM_FUNCS(name, user),                                               \
        !          2145:     _GEN_MEM_FUNCS(name, kernel),                                             \
        !          2146:     _GEN_MEM_FUNCS(name, hypv)
        !          2147: #endif
        !          2148: 
1.1       root     2149: /***                             Integer load                              ***/
                   2150: #define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
                   2151: /* Byte access routine are endian safe */
1.1.1.5 ! root     2152: #define gen_op_lbz_le_raw       gen_op_lbz_raw
        !          2153: #define gen_op_lbz_le_user      gen_op_lbz_user
        !          2154: #define gen_op_lbz_le_kernel    gen_op_lbz_kernel
        !          2155: #define gen_op_lbz_le_hypv      gen_op_lbz_hypv
        !          2156: #define gen_op_lbz_le_64_raw    gen_op_lbz_64_raw
        !          2157: #define gen_op_lbz_le_64_user   gen_op_lbz_64_user
        !          2158: #define gen_op_lbz_le_64_kernel gen_op_lbz_64_kernel
        !          2159: #define gen_op_lbz_le_64_hypv   gen_op_lbz_64_hypv
        !          2160: #define gen_op_stb_le_raw       gen_op_stb_raw
        !          2161: #define gen_op_stb_le_user      gen_op_stb_user
        !          2162: #define gen_op_stb_le_kernel    gen_op_stb_kernel
        !          2163: #define gen_op_stb_le_hypv      gen_op_stb_hypv
        !          2164: #define gen_op_stb_le_64_raw    gen_op_stb_64_raw
        !          2165: #define gen_op_stb_le_64_user   gen_op_stb_64_user
        !          2166: #define gen_op_stb_le_64_kernel gen_op_stb_64_kernel
        !          2167: #define gen_op_stb_le_64_hypv   gen_op_stb_64_hypv
1.1       root     2168: #define OP_LD_TABLE(width)                                                    \
1.1.1.5 ! root     2169: static GenOpFunc *gen_op_l##width[NB_MEM_FUNCS] = {                           \
        !          2170:     GEN_MEM_FUNCS(l##width),                                                  \
1.1       root     2171: };
                   2172: #define OP_ST_TABLE(width)                                                    \
1.1.1.5 ! root     2173: static GenOpFunc *gen_op_st##width[NB_MEM_FUNCS] = {                          \
        !          2174:     GEN_MEM_FUNCS(st##width),                                                 \
1.1       root     2175: };
1.1.1.5 ! root     2176: 
        !          2177: #define GEN_LD(width, opc, type)                                              \
        !          2178: GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
        !          2179: {                                                                             \
        !          2180:     gen_addr_imm_index(ctx, 0);                                               \
1.1       root     2181:     op_ldst(l##width);                                                        \
                   2182:     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
                   2183: }
                   2184: 
1.1.1.5 ! root     2185: #define GEN_LDU(width, opc, type)                                             \
        !          2186: GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
1.1       root     2187: {                                                                             \
1.1.1.5 ! root     2188:     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
        !          2189:                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
        !          2190:         GEN_EXCP_INVAL(ctx);                                                  \
1.1       root     2191:         return;                                                               \
                   2192:     }                                                                         \
1.1.1.5 ! root     2193:     if (type == PPC_64B)                                                      \
        !          2194:         gen_addr_imm_index(ctx, 0x03);                                        \
        !          2195:     else                                                                      \
        !          2196:         gen_addr_imm_index(ctx, 0);                                           \
1.1       root     2197:     op_ldst(l##width);                                                        \
                   2198:     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
                   2199:     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
                   2200: }
                   2201: 
1.1.1.5 ! root     2202: #define GEN_LDUX(width, opc2, opc3, type)                                     \
        !          2203: GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
1.1       root     2204: {                                                                             \
1.1.1.5 ! root     2205:     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
        !          2206:                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
        !          2207:         GEN_EXCP_INVAL(ctx);                                                  \
1.1       root     2208:         return;                                                               \
                   2209:     }                                                                         \
1.1.1.5 ! root     2210:     gen_addr_reg_index(ctx);                                                  \
1.1       root     2211:     op_ldst(l##width);                                                        \
                   2212:     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
                   2213:     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
                   2214: }
                   2215: 
1.1.1.5 ! root     2216: #define GEN_LDX(width, opc2, opc3, type)                                      \
        !          2217: GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
1.1       root     2218: {                                                                             \
1.1.1.5 ! root     2219:     gen_addr_reg_index(ctx);                                                  \
1.1       root     2220:     op_ldst(l##width);                                                        \
                   2221:     gen_op_store_T1_gpr(rD(ctx->opcode));                                     \
                   2222: }
                   2223: 
1.1.1.5 ! root     2224: #define GEN_LDS(width, op, type)                                              \
1.1       root     2225: OP_LD_TABLE(width);                                                           \
1.1.1.5 ! root     2226: GEN_LD(width, op | 0x20, type);                                               \
        !          2227: GEN_LDU(width, op | 0x21, type);                                              \
        !          2228: GEN_LDUX(width, 0x17, op | 0x01, type);                                       \
        !          2229: GEN_LDX(width, 0x17, op | 0x00, type)
1.1       root     2230: 
                   2231: /* lbz lbzu lbzux lbzx */
1.1.1.5 ! root     2232: GEN_LDS(bz, 0x02, PPC_INTEGER);
1.1       root     2233: /* lha lhau lhaux lhax */
1.1.1.5 ! root     2234: GEN_LDS(ha, 0x0A, PPC_INTEGER);
1.1       root     2235: /* lhz lhzu lhzux lhzx */
1.1.1.5 ! root     2236: GEN_LDS(hz, 0x08, PPC_INTEGER);
1.1       root     2237: /* lwz lwzu lwzux lwzx */
1.1.1.5 ! root     2238: GEN_LDS(wz, 0x00, PPC_INTEGER);
        !          2239: #if defined(TARGET_PPC64)
        !          2240: OP_LD_TABLE(wa);
        !          2241: OP_LD_TABLE(d);
        !          2242: /* lwaux */
        !          2243: GEN_LDUX(wa, 0x15, 0x0B, PPC_64B);
        !          2244: /* lwax */
        !          2245: GEN_LDX(wa, 0x15, 0x0A, PPC_64B);
        !          2246: /* ldux */
        !          2247: GEN_LDUX(d, 0x15, 0x01, PPC_64B);
        !          2248: /* ldx */
        !          2249: GEN_LDX(d, 0x15, 0x00, PPC_64B);
        !          2250: GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
        !          2251: {
        !          2252:     if (Rc(ctx->opcode)) {
        !          2253:         if (unlikely(rA(ctx->opcode) == 0 ||
        !          2254:                      rA(ctx->opcode) == rD(ctx->opcode))) {
        !          2255:             GEN_EXCP_INVAL(ctx);
        !          2256:             return;
        !          2257:         }
        !          2258:     }
        !          2259:     gen_addr_imm_index(ctx, 0x03);
        !          2260:     if (ctx->opcode & 0x02) {
        !          2261:         /* lwa (lwau is undefined) */
        !          2262:         op_ldst(lwa);
        !          2263:     } else {
        !          2264:         /* ld - ldu */
        !          2265:         op_ldst(ld);
        !          2266:     }
        !          2267:     gen_op_store_T1_gpr(rD(ctx->opcode));
        !          2268:     if (Rc(ctx->opcode))
        !          2269:         gen_op_store_T0_gpr(rA(ctx->opcode));
        !          2270: }
        !          2271: /* lq */
        !          2272: GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX)
        !          2273: {
        !          2274: #if defined(CONFIG_USER_ONLY)
        !          2275:     GEN_EXCP_PRIVOPC(ctx);
        !          2276: #else
        !          2277:     int ra, rd;
        !          2278: 
        !          2279:     /* Restore CPU state */
        !          2280:     if (unlikely(ctx->supervisor == 0)) {
        !          2281:         GEN_EXCP_PRIVOPC(ctx);
        !          2282:         return;
        !          2283:     }
        !          2284:     ra = rA(ctx->opcode);
        !          2285:     rd = rD(ctx->opcode);
        !          2286:     if (unlikely((rd & 1) || rd == ra)) {
        !          2287:         GEN_EXCP_INVAL(ctx);
        !          2288:         return;
        !          2289:     }
        !          2290:     if (unlikely(ctx->mem_idx & 1)) {
        !          2291:         /* Little-endian mode is not handled */
        !          2292:         GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
        !          2293:         return;
        !          2294:     }
        !          2295:     gen_addr_imm_index(ctx, 0x0F);
        !          2296:     op_ldst(ld);
        !          2297:     gen_op_store_T1_gpr(rd);
        !          2298:     gen_op_addi(8);
        !          2299:     op_ldst(ld);
        !          2300:     gen_op_store_T1_gpr(rd + 1);
        !          2301: #endif
        !          2302: }
        !          2303: #endif
1.1       root     2304: 
                   2305: /***                              Integer store                            ***/
1.1.1.5 ! root     2306: #define GEN_ST(width, opc, type)                                              \
        !          2307: GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
1.1       root     2308: {                                                                             \
1.1.1.5 ! root     2309:     gen_addr_imm_index(ctx, 0);                                               \
1.1       root     2310:     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
                   2311:     op_ldst(st##width);                                                       \
                   2312: }
                   2313: 
1.1.1.5 ! root     2314: #define GEN_STU(width, opc, type)                                             \
        !          2315: GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
1.1       root     2316: {                                                                             \
1.1.1.5 ! root     2317:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
        !          2318:         GEN_EXCP_INVAL(ctx);                                                  \
1.1       root     2319:         return;                                                               \
                   2320:     }                                                                         \
1.1.1.5 ! root     2321:     if (type == PPC_64B)                                                      \
        !          2322:         gen_addr_imm_index(ctx, 0x03);                                        \
        !          2323:     else                                                                      \
        !          2324:         gen_addr_imm_index(ctx, 0);                                           \
1.1       root     2325:     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
                   2326:     op_ldst(st##width);                                                       \
                   2327:     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
                   2328: }
                   2329: 
1.1.1.5 ! root     2330: #define GEN_STUX(width, opc2, opc3, type)                                     \
        !          2331: GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
1.1       root     2332: {                                                                             \
1.1.1.5 ! root     2333:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
        !          2334:         GEN_EXCP_INVAL(ctx);                                                  \
1.1       root     2335:         return;                                                               \
                   2336:     }                                                                         \
1.1.1.5 ! root     2337:     gen_addr_reg_index(ctx);                                                  \
1.1       root     2338:     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
                   2339:     op_ldst(st##width);                                                       \
                   2340:     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
                   2341: }
                   2342: 
1.1.1.5 ! root     2343: #define GEN_STX(width, opc2, opc3, type)                                      \
        !          2344: GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
1.1       root     2345: {                                                                             \
1.1.1.5 ! root     2346:     gen_addr_reg_index(ctx);                                                  \
1.1       root     2347:     gen_op_load_gpr_T1(rS(ctx->opcode));                                      \
                   2348:     op_ldst(st##width);                                                       \
                   2349: }
                   2350: 
1.1.1.5 ! root     2351: #define GEN_STS(width, op, type)                                              \
1.1       root     2352: OP_ST_TABLE(width);                                                           \
1.1.1.5 ! root     2353: GEN_ST(width, op | 0x20, type);                                               \
        !          2354: GEN_STU(width, op | 0x21, type);                                              \
        !          2355: GEN_STUX(width, 0x17, op | 0x01, type);                                       \
        !          2356: GEN_STX(width, 0x17, op | 0x00, type)
1.1       root     2357: 
                   2358: /* stb stbu stbux stbx */
1.1.1.5 ! root     2359: GEN_STS(b, 0x06, PPC_INTEGER);
1.1       root     2360: /* sth sthu sthux sthx */
1.1.1.5 ! root     2361: GEN_STS(h, 0x0C, PPC_INTEGER);
1.1       root     2362: /* stw stwu stwux stwx */
1.1.1.5 ! root     2363: GEN_STS(w, 0x04, PPC_INTEGER);
        !          2364: #if defined(TARGET_PPC64)
        !          2365: OP_ST_TABLE(d);
        !          2366: GEN_STUX(d, 0x15, 0x05, PPC_64B);
        !          2367: GEN_STX(d, 0x15, 0x04, PPC_64B);
        !          2368: GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
        !          2369: {
        !          2370:     int rs;
1.1       root     2371: 
1.1.1.5 ! root     2372:     rs = rS(ctx->opcode);
        !          2373:     if ((ctx->opcode & 0x3) == 0x2) {
        !          2374: #if defined(CONFIG_USER_ONLY)
        !          2375:         GEN_EXCP_PRIVOPC(ctx);
        !          2376: #else
        !          2377:         /* stq */
        !          2378:         if (unlikely(ctx->supervisor == 0)) {
        !          2379:             GEN_EXCP_PRIVOPC(ctx);
        !          2380:             return;
        !          2381:         }
        !          2382:         if (unlikely(rs & 1)) {
        !          2383:             GEN_EXCP_INVAL(ctx);
        !          2384:             return;
        !          2385:         }
        !          2386:         if (unlikely(ctx->mem_idx & 1)) {
        !          2387:             /* Little-endian mode is not handled */
        !          2388:             GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
        !          2389:             return;
        !          2390:         }
        !          2391:         gen_addr_imm_index(ctx, 0x03);
        !          2392:         gen_op_load_gpr_T1(rs);
        !          2393:         op_ldst(std);
        !          2394:         gen_op_addi(8);
        !          2395:         gen_op_load_gpr_T1(rs + 1);
        !          2396:         op_ldst(std);
        !          2397: #endif
        !          2398:     } else {
        !          2399:         /* std / stdu */
        !          2400:         if (Rc(ctx->opcode)) {
        !          2401:             if (unlikely(rA(ctx->opcode) == 0)) {
        !          2402:                 GEN_EXCP_INVAL(ctx);
        !          2403:                 return;
        !          2404:             }
        !          2405:         }
        !          2406:         gen_addr_imm_index(ctx, 0x03);
        !          2407:         gen_op_load_gpr_T1(rs);
        !          2408:         op_ldst(std);
        !          2409:         if (Rc(ctx->opcode))
        !          2410:             gen_op_store_T0_gpr(rA(ctx->opcode));
        !          2411:     }
        !          2412: }
        !          2413: #endif
1.1       root     2414: /***                Integer load and store with byte reverse               ***/
                   2415: /* lhbrx */
                   2416: OP_LD_TABLE(hbr);
1.1.1.5 ! root     2417: GEN_LDX(hbr, 0x16, 0x18, PPC_INTEGER);
1.1       root     2418: /* lwbrx */
                   2419: OP_LD_TABLE(wbr);
1.1.1.5 ! root     2420: GEN_LDX(wbr, 0x16, 0x10, PPC_INTEGER);
1.1       root     2421: /* sthbrx */
                   2422: OP_ST_TABLE(hbr);
1.1.1.5 ! root     2423: GEN_STX(hbr, 0x16, 0x1C, PPC_INTEGER);
1.1       root     2424: /* stwbrx */
                   2425: OP_ST_TABLE(wbr);
1.1.1.5 ! root     2426: GEN_STX(wbr, 0x16, 0x14, PPC_INTEGER);
1.1       root     2427: 
                   2428: /***                    Integer load and store multiple                    ***/
                   2429: #define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
1.1.1.5 ! root     2430: static GenOpFunc1 *gen_op_lmw[NB_MEM_FUNCS] = {
        !          2431:     GEN_MEM_FUNCS(lmw),
        !          2432: };
        !          2433: static GenOpFunc1 *gen_op_stmw[NB_MEM_FUNCS] = {
        !          2434:     GEN_MEM_FUNCS(stmw),
1.1       root     2435: };
                   2436: 
                   2437: /* lmw */
                   2438: GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   2439: {
1.1.1.5 ! root     2440:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          2441:     gen_update_nip(ctx, ctx->nip - 4);
        !          2442:     gen_addr_imm_index(ctx, 0);
1.1       root     2443:     op_ldstm(lmw, rD(ctx->opcode));
                   2444: }
                   2445: 
                   2446: /* stmw */
                   2447: GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   2448: {
1.1.1.5 ! root     2449:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          2450:     gen_update_nip(ctx, ctx->nip - 4);
        !          2451:     gen_addr_imm_index(ctx, 0);
1.1       root     2452:     op_ldstm(stmw, rS(ctx->opcode));
                   2453: }
                   2454: 
                   2455: /***                    Integer load and store strings                     ***/
                   2456: #define op_ldsts(name, start) (*gen_op_##name[ctx->mem_idx])(start)
                   2457: #define op_ldstsx(name, rd, ra, rb) (*gen_op_##name[ctx->mem_idx])(rd, ra, rb)
1.1.1.5 ! root     2458: /* string load & stores are by definition endian-safe */
        !          2459: #define gen_op_lswi_le_raw       gen_op_lswi_raw
        !          2460: #define gen_op_lswi_le_user      gen_op_lswi_user
        !          2461: #define gen_op_lswi_le_kernel    gen_op_lswi_kernel
        !          2462: #define gen_op_lswi_le_hypv      gen_op_lswi_hypv
        !          2463: #define gen_op_lswi_le_64_raw    gen_op_lswi_raw
        !          2464: #define gen_op_lswi_le_64_user   gen_op_lswi_user
        !          2465: #define gen_op_lswi_le_64_kernel gen_op_lswi_kernel
        !          2466: #define gen_op_lswi_le_64_hypv   gen_op_lswi_hypv
        !          2467: static GenOpFunc1 *gen_op_lswi[NB_MEM_FUNCS] = {
        !          2468:     GEN_MEM_FUNCS(lswi),
        !          2469: };
        !          2470: #define gen_op_lswx_le_raw       gen_op_lswx_raw
        !          2471: #define gen_op_lswx_le_user      gen_op_lswx_user
        !          2472: #define gen_op_lswx_le_kernel    gen_op_lswx_kernel
        !          2473: #define gen_op_lswx_le_hypv      gen_op_lswx_hypv
        !          2474: #define gen_op_lswx_le_64_raw    gen_op_lswx_raw
        !          2475: #define gen_op_lswx_le_64_user   gen_op_lswx_user
        !          2476: #define gen_op_lswx_le_64_kernel gen_op_lswx_kernel
        !          2477: #define gen_op_lswx_le_64_hypv   gen_op_lswx_hypv
        !          2478: static GenOpFunc3 *gen_op_lswx[NB_MEM_FUNCS] = {
        !          2479:     GEN_MEM_FUNCS(lswx),
        !          2480: };
        !          2481: #define gen_op_stsw_le_raw       gen_op_stsw_raw
        !          2482: #define gen_op_stsw_le_user      gen_op_stsw_user
        !          2483: #define gen_op_stsw_le_kernel    gen_op_stsw_kernel
        !          2484: #define gen_op_stsw_le_hypv      gen_op_stsw_hypv
        !          2485: #define gen_op_stsw_le_64_raw    gen_op_stsw_raw
        !          2486: #define gen_op_stsw_le_64_user   gen_op_stsw_user
        !          2487: #define gen_op_stsw_le_64_kernel gen_op_stsw_kernel
        !          2488: #define gen_op_stsw_le_64_hypv   gen_op_stsw_hypv
        !          2489: static GenOpFunc1 *gen_op_stsw[NB_MEM_FUNCS] = {
        !          2490:     GEN_MEM_FUNCS(stsw),
1.1       root     2491: };
                   2492: 
                   2493: /* lswi */
                   2494: /* PowerPC32 specification says we must generate an exception if
                   2495:  * rA is in the range of registers to be loaded.
                   2496:  * In an other hand, IBM says this is valid, but rA won't be loaded.
                   2497:  * For now, I'll follow the spec...
                   2498:  */
1.1.1.5 ! root     2499: GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING)
1.1       root     2500: {
                   2501:     int nb = NB(ctx->opcode);
                   2502:     int start = rD(ctx->opcode);
                   2503:     int ra = rA(ctx->opcode);
                   2504:     int nr;
                   2505: 
                   2506:     if (nb == 0)
                   2507:         nb = 32;
                   2508:     nr = nb / 4;
1.1.1.5 ! root     2509:     if (unlikely(((start + nr) > 32  &&
        !          2510:                   start <= ra && (start + nr - 32) > ra) ||
        !          2511:                  ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
        !          2512:         GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
        !          2513:                  POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX);
1.1       root     2514:         return;
                   2515:     }
                   2516:     /* NIP cannot be restored if the memory exception comes from an helper */
1.1.1.5 ! root     2517:     gen_update_nip(ctx, ctx->nip - 4);
        !          2518:     gen_addr_register(ctx);
        !          2519:     gen_op_set_T1(nb);
1.1       root     2520:     op_ldsts(lswi, start);
                   2521: }
                   2522: 
                   2523: /* lswx */
1.1.1.5 ! root     2524: GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING)
1.1       root     2525: {
                   2526:     int ra = rA(ctx->opcode);
                   2527:     int rb = rB(ctx->opcode);
                   2528: 
1.1.1.5 ! root     2529:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          2530:     gen_update_nip(ctx, ctx->nip - 4);
        !          2531:     gen_addr_reg_index(ctx);
1.1       root     2532:     if (ra == 0) {
                   2533:         ra = rb;
                   2534:     }
                   2535:     gen_op_load_xer_bc();
                   2536:     op_ldstsx(lswx, rD(ctx->opcode), ra, rb);
                   2537: }
                   2538: 
                   2539: /* stswi */
1.1.1.5 ! root     2540: GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING)
1.1       root     2541: {
                   2542:     int nb = NB(ctx->opcode);
                   2543: 
1.1.1.5 ! root     2544:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          2545:     gen_update_nip(ctx, ctx->nip - 4);
        !          2546:     gen_addr_register(ctx);
1.1       root     2547:     if (nb == 0)
                   2548:         nb = 32;
                   2549:     gen_op_set_T1(nb);
                   2550:     op_ldsts(stsw, rS(ctx->opcode));
                   2551: }
                   2552: 
                   2553: /* stswx */
1.1.1.5 ! root     2554: GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING)
1.1       root     2555: {
                   2556:     /* NIP cannot be restored if the memory exception comes from an helper */
1.1.1.5 ! root     2557:     gen_update_nip(ctx, ctx->nip - 4);
        !          2558:     gen_addr_reg_index(ctx);
        !          2559:     gen_op_load_xer_bc();
1.1       root     2560:     op_ldsts(stsw, rS(ctx->opcode));
                   2561: }
                   2562: 
                   2563: /***                        Memory synchronisation                         ***/
                   2564: /* eieio */
1.1.1.5 ! root     2565: GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO)
1.1       root     2566: {
                   2567: }
                   2568: 
                   2569: /* isync */
1.1.1.5 ! root     2570: GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM)
1.1       root     2571: {
1.1.1.5 ! root     2572:     GEN_STOP(ctx);
1.1       root     2573: }
                   2574: 
                   2575: #define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
                   2576: #define op_stwcx() (*gen_op_stwcx[ctx->mem_idx])()
1.1.1.5 ! root     2577: static GenOpFunc *gen_op_lwarx[NB_MEM_FUNCS] = {
        !          2578:     GEN_MEM_FUNCS(lwarx),
        !          2579: };
        !          2580: static GenOpFunc *gen_op_stwcx[NB_MEM_FUNCS] = {
        !          2581:     GEN_MEM_FUNCS(stwcx),
1.1       root     2582: };
                   2583: 
                   2584: /* lwarx */
1.1.1.5 ! root     2585: GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
1.1       root     2586: {
1.1.1.5 ! root     2587:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          2588:     gen_update_nip(ctx, ctx->nip - 4);
        !          2589:     gen_addr_reg_index(ctx);
1.1       root     2590:     op_lwarx();
                   2591:     gen_op_store_T1_gpr(rD(ctx->opcode));
                   2592: }
                   2593: 
                   2594: /* stwcx. */
1.1.1.5 ! root     2595: GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
1.1       root     2596: {
1.1.1.5 ! root     2597:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          2598:     gen_update_nip(ctx, ctx->nip - 4);
        !          2599:     gen_addr_reg_index(ctx);
1.1       root     2600:     gen_op_load_gpr_T1(rS(ctx->opcode));
                   2601:     op_stwcx();
                   2602: }
                   2603: 
1.1.1.5 ! root     2604: #if defined(TARGET_PPC64)
        !          2605: #define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])()
        !          2606: #define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])()
        !          2607: static GenOpFunc *gen_op_ldarx[NB_MEM_FUNCS] = {
        !          2608:     GEN_MEM_FUNCS(ldarx),
        !          2609: };
        !          2610: static GenOpFunc *gen_op_stdcx[NB_MEM_FUNCS] = {
        !          2611:     GEN_MEM_FUNCS(stdcx),
        !          2612: };
        !          2613: 
        !          2614: /* ldarx */
        !          2615: GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
        !          2616: {
        !          2617:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          2618:     gen_update_nip(ctx, ctx->nip - 4);
        !          2619:     gen_addr_reg_index(ctx);
        !          2620:     op_ldarx();
        !          2621:     gen_op_store_T1_gpr(rD(ctx->opcode));
        !          2622: }
        !          2623: 
        !          2624: /* stdcx. */
        !          2625: GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
        !          2626: {
        !          2627:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          2628:     gen_update_nip(ctx, ctx->nip - 4);
        !          2629:     gen_addr_reg_index(ctx);
        !          2630:     gen_op_load_gpr_T1(rS(ctx->opcode));
        !          2631:     op_stdcx();
        !          2632: }
        !          2633: #endif /* defined(TARGET_PPC64) */
        !          2634: 
1.1       root     2635: /* sync */
1.1.1.5 ! root     2636: GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC)
1.1       root     2637: {
                   2638: }
                   2639: 
1.1.1.5 ! root     2640: /* wait */
        !          2641: GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
        !          2642: {
        !          2643:     /* Stop translation, as the CPU is supposed to sleep from now */
        !          2644:     gen_op_wait();
        !          2645:     GEN_EXCP(ctx, EXCP_HLT, 1);
        !          2646: }
        !          2647: 
1.1       root     2648: /***                         Floating-point load                           ***/
1.1.1.5 ! root     2649: #define GEN_LDF(width, opc, type)                                             \
        !          2650: GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
1.1       root     2651: {                                                                             \
1.1.1.5 ! root     2652:     if (unlikely(!ctx->fpu_enabled)) {                                        \
        !          2653:         GEN_EXCP_NO_FP(ctx);                                                  \
1.1       root     2654:         return;                                                               \
                   2655:     }                                                                         \
1.1.1.5 ! root     2656:     gen_addr_imm_index(ctx, 0);                                               \
1.1       root     2657:     op_ldst(l##width);                                                        \
1.1.1.5 ! root     2658:     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1.1       root     2659: }
                   2660: 
1.1.1.5 ! root     2661: #define GEN_LDUF(width, opc, type)                                            \
        !          2662: GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
1.1       root     2663: {                                                                             \
1.1.1.5 ! root     2664:     if (unlikely(!ctx->fpu_enabled)) {                                        \
        !          2665:         GEN_EXCP_NO_FP(ctx);                                                  \
1.1       root     2666:         return;                                                               \
                   2667:     }                                                                         \
1.1.1.5 ! root     2668:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
        !          2669:         GEN_EXCP_INVAL(ctx);                                                  \
1.1       root     2670:         return;                                                               \
                   2671:     }                                                                         \
1.1.1.5 ! root     2672:     gen_addr_imm_index(ctx, 0);                                               \
1.1       root     2673:     op_ldst(l##width);                                                        \
1.1.1.5 ! root     2674:     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1.1       root     2675:     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
                   2676: }
                   2677: 
1.1.1.5 ! root     2678: #define GEN_LDUXF(width, opc, type)                                           \
        !          2679: GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                  \
1.1       root     2680: {                                                                             \
1.1.1.5 ! root     2681:     if (unlikely(!ctx->fpu_enabled)) {                                        \
        !          2682:         GEN_EXCP_NO_FP(ctx);                                                  \
1.1       root     2683:         return;                                                               \
                   2684:     }                                                                         \
1.1.1.5 ! root     2685:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
        !          2686:         GEN_EXCP_INVAL(ctx);                                                  \
1.1       root     2687:         return;                                                               \
                   2688:     }                                                                         \
1.1.1.5 ! root     2689:     gen_addr_reg_index(ctx);                                                  \
1.1       root     2690:     op_ldst(l##width);                                                        \
1.1.1.5 ! root     2691:     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1.1       root     2692:     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
                   2693: }
                   2694: 
1.1.1.5 ! root     2695: #define GEN_LDXF(width, opc2, opc3, type)                                     \
        !          2696: GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
1.1       root     2697: {                                                                             \
1.1.1.5 ! root     2698:     if (unlikely(!ctx->fpu_enabled)) {                                        \
        !          2699:         GEN_EXCP_NO_FP(ctx);                                                  \
1.1       root     2700:         return;                                                               \
                   2701:     }                                                                         \
1.1.1.5 ! root     2702:     gen_addr_reg_index(ctx);                                                  \
1.1       root     2703:     op_ldst(l##width);                                                        \
1.1.1.5 ! root     2704:     gen_op_store_FT0_fpr(rD(ctx->opcode));                                    \
1.1       root     2705: }
                   2706: 
1.1.1.5 ! root     2707: #define GEN_LDFS(width, op, type)                                             \
1.1       root     2708: OP_LD_TABLE(width);                                                           \
1.1.1.5 ! root     2709: GEN_LDF(width, op | 0x20, type);                                              \
        !          2710: GEN_LDUF(width, op | 0x21, type);                                             \
        !          2711: GEN_LDUXF(width, op | 0x01, type);                                            \
        !          2712: GEN_LDXF(width, 0x17, op | 0x00, type)
1.1       root     2713: 
                   2714: /* lfd lfdu lfdux lfdx */
1.1.1.5 ! root     2715: GEN_LDFS(fd, 0x12, PPC_FLOAT);
1.1       root     2716: /* lfs lfsu lfsux lfsx */
1.1.1.5 ! root     2717: GEN_LDFS(fs, 0x10, PPC_FLOAT);
1.1       root     2718: 
                   2719: /***                         Floating-point store                          ***/
1.1.1.5 ! root     2720: #define GEN_STF(width, opc, type)                                             \
        !          2721: GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
1.1       root     2722: {                                                                             \
1.1.1.5 ! root     2723:     if (unlikely(!ctx->fpu_enabled)) {                                        \
        !          2724:         GEN_EXCP_NO_FP(ctx);                                                  \
        !          2725:         return;                                                               \
1.1       root     2726:     }                                                                         \
1.1.1.5 ! root     2727:     gen_addr_imm_index(ctx, 0);                                               \
        !          2728:     gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
1.1       root     2729:     op_ldst(st##width);                                                       \
                   2730: }
                   2731: 
1.1.1.5 ! root     2732: #define GEN_STUF(width, opc, type)                                            \
        !          2733: GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
1.1       root     2734: {                                                                             \
1.1.1.5 ! root     2735:     if (unlikely(!ctx->fpu_enabled)) {                                        \
        !          2736:         GEN_EXCP_NO_FP(ctx);                                                  \
1.1       root     2737:         return;                                                               \
                   2738:     }                                                                         \
1.1.1.5 ! root     2739:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
        !          2740:         GEN_EXCP_INVAL(ctx);                                                  \
1.1       root     2741:         return;                                                               \
                   2742:     }                                                                         \
1.1.1.5 ! root     2743:     gen_addr_imm_index(ctx, 0);                                               \
        !          2744:     gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
1.1       root     2745:     op_ldst(st##width);                                                       \
                   2746:     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
                   2747: }
                   2748: 
1.1.1.5 ! root     2749: #define GEN_STUXF(width, opc, type)                                           \
        !          2750: GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, type)                 \
1.1       root     2751: {                                                                             \
1.1.1.5 ! root     2752:     if (unlikely(!ctx->fpu_enabled)) {                                        \
        !          2753:         GEN_EXCP_NO_FP(ctx);                                                  \
1.1       root     2754:         return;                                                               \
                   2755:     }                                                                         \
1.1.1.5 ! root     2756:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
        !          2757:         GEN_EXCP_INVAL(ctx);                                                  \
1.1       root     2758:         return;                                                               \
                   2759:     }                                                                         \
1.1.1.5 ! root     2760:     gen_addr_reg_index(ctx);                                                  \
        !          2761:     gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
1.1       root     2762:     op_ldst(st##width);                                                       \
                   2763:     gen_op_store_T0_gpr(rA(ctx->opcode));                                     \
                   2764: }
                   2765: 
1.1.1.5 ! root     2766: #define GEN_STXF(width, opc2, opc3, type)                                     \
        !          2767: GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
1.1       root     2768: {                                                                             \
1.1.1.5 ! root     2769:     if (unlikely(!ctx->fpu_enabled)) {                                        \
        !          2770:         GEN_EXCP_NO_FP(ctx);                                                  \
1.1       root     2771:         return;                                                               \
                   2772:     }                                                                         \
1.1.1.5 ! root     2773:     gen_addr_reg_index(ctx);                                                  \
        !          2774:     gen_op_load_fpr_FT0(rS(ctx->opcode));                                     \
1.1       root     2775:     op_ldst(st##width);                                                       \
                   2776: }
                   2777: 
1.1.1.5 ! root     2778: #define GEN_STFS(width, op, type)                                             \
1.1       root     2779: OP_ST_TABLE(width);                                                           \
1.1.1.5 ! root     2780: GEN_STF(width, op | 0x20, type);                                              \
        !          2781: GEN_STUF(width, op | 0x21, type);                                             \
        !          2782: GEN_STUXF(width, op | 0x01, type);                                            \
        !          2783: GEN_STXF(width, 0x17, op | 0x00, type)
1.1       root     2784: 
                   2785: /* stfd stfdu stfdux stfdx */
1.1.1.5 ! root     2786: GEN_STFS(fd, 0x16, PPC_FLOAT);
1.1       root     2787: /* stfs stfsu stfsux stfsx */
1.1.1.5 ! root     2788: GEN_STFS(fs, 0x14, PPC_FLOAT);
1.1       root     2789: 
                   2790: /* Optional: */
                   2791: /* stfiwx */
1.1.1.5 ! root     2792: OP_ST_TABLE(fiw);
        !          2793: GEN_STXF(fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
1.1       root     2794: 
                   2795: /***                                Branch                                 ***/
1.1.1.5 ! root     2796: static always_inline void gen_goto_tb (DisasContext *ctx, int n,
        !          2797:                                        target_ulong dest)
1.1.1.2   root     2798: {
                   2799:     TranslationBlock *tb;
                   2800:     tb = ctx->tb;
                   2801:     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
                   2802:         if (n == 0)
                   2803:             gen_op_goto_tb0(TBPARAM(tb));
                   2804:         else
                   2805:             gen_op_goto_tb1(TBPARAM(tb));
1.1.1.5 ! root     2806:         gen_set_T1(dest);
        !          2807: #if defined(TARGET_PPC64)
        !          2808:         if (ctx->sf_mode)
        !          2809:             gen_op_b_T1_64();
        !          2810:         else
        !          2811: #endif
        !          2812:             gen_op_b_T1();
1.1.1.2   root     2813:         gen_op_set_T0((long)tb + n);
1.1.1.3   root     2814:         if (ctx->singlestep_enabled)
                   2815:             gen_op_debug();
1.1.1.2   root     2816:         gen_op_exit_tb();
                   2817:     } else {
1.1.1.5 ! root     2818:         gen_set_T1(dest);
        !          2819: #if defined(TARGET_PPC64)
        !          2820:         if (ctx->sf_mode)
        !          2821:             gen_op_b_T1_64();
        !          2822:         else
        !          2823: #endif
        !          2824:             gen_op_b_T1();
        !          2825:         gen_op_reset_T0();
1.1.1.3   root     2826:         if (ctx->singlestep_enabled)
                   2827:             gen_op_debug();
1.1.1.2   root     2828:         gen_op_exit_tb();
                   2829:     }
                   2830: }
                   2831: 
1.1.1.5 ! root     2832: static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip)
        !          2833: {
        !          2834: #if defined(TARGET_PPC64)
        !          2835:     if (ctx->sf_mode != 0 && (nip >> 32))
        !          2836:         gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
        !          2837:     else
        !          2838: #endif
        !          2839:         gen_op_setlr(ctx->nip);
        !          2840: }
        !          2841: 
1.1       root     2842: /* b ba bl bla */
                   2843: GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
                   2844: {
1.1.1.5 ! root     2845:     target_ulong li, target;
1.1       root     2846: 
                   2847:     /* sign extend LI */
1.1.1.5 ! root     2848: #if defined(TARGET_PPC64)
        !          2849:     if (ctx->sf_mode)
        !          2850:         li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
        !          2851:     else
        !          2852: #endif
        !          2853:         li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
        !          2854:     if (likely(AA(ctx->opcode) == 0))
1.1       root     2855:         target = ctx->nip + li - 4;
                   2856:     else
                   2857:         target = li;
1.1.1.5 ! root     2858: #if defined(TARGET_PPC64)
        !          2859:     if (!ctx->sf_mode)
        !          2860:         target = (uint32_t)target;
        !          2861: #endif
        !          2862:     if (LK(ctx->opcode))
        !          2863:         gen_setlr(ctx, ctx->nip);
1.1.1.2   root     2864:     gen_goto_tb(ctx, 0, target);
1.1.1.5 ! root     2865:     ctx->exception = POWERPC_EXCP_BRANCH;
1.1       root     2866: }
                   2867: 
                   2868: #define BCOND_IM  0
                   2869: #define BCOND_LR  1
                   2870: #define BCOND_CTR 2
                   2871: 
1.1.1.5 ! root     2872: static always_inline void gen_bcond (DisasContext *ctx, int type)
        !          2873: {
        !          2874:     target_ulong target = 0;
        !          2875:     target_ulong li;
        !          2876:     uint32_t bo = BO(ctx->opcode);
        !          2877:     uint32_t bi = BI(ctx->opcode);
        !          2878:     uint32_t mask;
1.1       root     2879: 
                   2880:     if ((bo & 0x4) == 0)
1.1.1.5 ! root     2881:         gen_op_dec_ctr();
1.1       root     2882:     switch(type) {
                   2883:     case BCOND_IM:
1.1.1.5 ! root     2884:         li = (target_long)((int16_t)(BD(ctx->opcode)));
        !          2885:         if (likely(AA(ctx->opcode) == 0)) {
1.1       root     2886:             target = ctx->nip + li - 4;
                   2887:         } else {
                   2888:             target = li;
                   2889:         }
1.1.1.5 ! root     2890: #if defined(TARGET_PPC64)
        !          2891:         if (!ctx->sf_mode)
        !          2892:             target = (uint32_t)target;
        !          2893: #endif
1.1       root     2894:         break;
                   2895:     case BCOND_CTR:
                   2896:         gen_op_movl_T1_ctr();
                   2897:         break;
                   2898:     default:
                   2899:     case BCOND_LR:
                   2900:         gen_op_movl_T1_lr();
                   2901:         break;
                   2902:     }
1.1.1.5 ! root     2903:     if (LK(ctx->opcode))
        !          2904:         gen_setlr(ctx, ctx->nip);
1.1       root     2905:     if (bo & 0x10) {
1.1.1.5 ! root     2906:         /* No CR condition */
        !          2907:         switch (bo & 0x6) {
        !          2908:         case 0:
        !          2909: #if defined(TARGET_PPC64)
        !          2910:             if (ctx->sf_mode)
        !          2911:                 gen_op_test_ctr_64();
        !          2912:             else
        !          2913: #endif
        !          2914:                 gen_op_test_ctr();
        !          2915:             break;
        !          2916:         case 2:
        !          2917: #if defined(TARGET_PPC64)
        !          2918:             if (ctx->sf_mode)
        !          2919:                 gen_op_test_ctrz_64();
        !          2920:             else
        !          2921: #endif
        !          2922:                 gen_op_test_ctrz();
1.1       root     2923:             break;
                   2924:         default:
1.1.1.5 ! root     2925:         case 4:
        !          2926:         case 6:
1.1       root     2927:             if (type == BCOND_IM) {
1.1.1.2   root     2928:                 gen_goto_tb(ctx, 0, target);
1.1.1.5 ! root     2929:                 goto out;
1.1       root     2930:             } else {
1.1.1.5 ! root     2931: #if defined(TARGET_PPC64)
        !          2932:                 if (ctx->sf_mode)
        !          2933:                     gen_op_b_T1_64();
        !          2934:                 else
        !          2935: #endif
        !          2936:                     gen_op_b_T1();
        !          2937:                 gen_op_reset_T0();
        !          2938:                 goto no_test;
1.1       root     2939:             }
1.1.1.5 ! root     2940:             break;
1.1       root     2941:         }
1.1.1.5 ! root     2942:     } else {
        !          2943:         mask = 1 << (3 - (bi & 0x03));
        !          2944:         gen_op_load_crf_T0(bi >> 2);
        !          2945:         if (bo & 0x8) {
        !          2946:             switch (bo & 0x6) {
        !          2947:             case 0:
        !          2948: #if defined(TARGET_PPC64)
        !          2949:                 if (ctx->sf_mode)
        !          2950:                     gen_op_test_ctr_true_64(mask);
        !          2951:                 else
        !          2952: #endif
        !          2953:                     gen_op_test_ctr_true(mask);
        !          2954:                 break;
        !          2955:             case 2:
        !          2956: #if defined(TARGET_PPC64)
        !          2957:                 if (ctx->sf_mode)
        !          2958:                     gen_op_test_ctrz_true_64(mask);
        !          2959:                 else
        !          2960: #endif
        !          2961:                     gen_op_test_ctrz_true(mask);
        !          2962:                 break;
        !          2963:             default:
        !          2964:             case 4:
        !          2965:             case 6:
1.1       root     2966:                 gen_op_test_true(mask);
1.1.1.5 ! root     2967:                 break;
        !          2968:             }
        !          2969:         } else {
        !          2970:             switch (bo & 0x6) {
        !          2971:             case 0:
        !          2972: #if defined(TARGET_PPC64)
        !          2973:                 if (ctx->sf_mode)
        !          2974:                     gen_op_test_ctr_false_64(mask);
        !          2975:                 else
        !          2976: #endif
        !          2977:                     gen_op_test_ctr_false(mask);
        !          2978:                 break;
        !          2979:             case 2:
        !          2980: #if defined(TARGET_PPC64)
        !          2981:                 if (ctx->sf_mode)
        !          2982:                     gen_op_test_ctrz_false_64(mask);
        !          2983:                 else
        !          2984: #endif
        !          2985:                     gen_op_test_ctrz_false(mask);
        !          2986:                 break;
1.1       root     2987:             default:
1.1.1.5 ! root     2988:             case 4:
        !          2989:             case 6:
1.1       root     2990:                 gen_op_test_false(mask);
1.1.1.5 ! root     2991:                 break;
        !          2992:             }
        !          2993:         }
        !          2994:     }
1.1       root     2995:     if (type == BCOND_IM) {
1.1.1.2   root     2996:         int l1 = gen_new_label();
                   2997:         gen_op_jz_T0(l1);
                   2998:         gen_goto_tb(ctx, 0, target);
                   2999:         gen_set_label(l1);
                   3000:         gen_goto_tb(ctx, 1, ctx->nip);
1.1       root     3001:     } else {
1.1.1.5 ! root     3002: #if defined(TARGET_PPC64)
        !          3003:         if (ctx->sf_mode)
        !          3004:             gen_op_btest_T1_64(ctx->nip >> 32, ctx->nip);
        !          3005:         else
        !          3006: #endif
        !          3007:             gen_op_btest_T1(ctx->nip);
        !          3008:         gen_op_reset_T0();
        !          3009:     no_test:
        !          3010:         if (ctx->singlestep_enabled)
        !          3011:             gen_op_debug();
        !          3012:         gen_op_exit_tb();
1.1       root     3013:     }
1.1.1.5 ! root     3014:  out:
        !          3015:     ctx->exception = POWERPC_EXCP_BRANCH;
1.1       root     3016: }
                   3017: 
                   3018: GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1.1.1.5 ! root     3019: {
1.1       root     3020:     gen_bcond(ctx, BCOND_IM);
                   3021: }
                   3022: 
                   3023: GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
1.1.1.5 ! root     3024: {
1.1       root     3025:     gen_bcond(ctx, BCOND_CTR);
                   3026: }
                   3027: 
                   3028: GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
1.1.1.5 ! root     3029: {
1.1       root     3030:     gen_bcond(ctx, BCOND_LR);
                   3031: }
                   3032: 
                   3033: /***                      Condition register logical                       ***/
                   3034: #define GEN_CRLOGIC(op, opc)                                                  \
                   3035: GEN_HANDLER(cr##op, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                 \
                   3036: {                                                                             \
1.1.1.5 ! root     3037:     uint8_t bitmask;                                                          \
        !          3038:     int sh;                                                                   \
1.1       root     3039:     gen_op_load_crf_T0(crbA(ctx->opcode) >> 2);                               \
1.1.1.5 ! root     3040:     sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
        !          3041:     if (sh > 0)                                                               \
        !          3042:         gen_op_srli_T0(sh);                                                   \
        !          3043:     else if (sh < 0)                                                          \
        !          3044:         gen_op_sli_T0(-sh);                                                   \
1.1       root     3045:     gen_op_load_crf_T1(crbB(ctx->opcode) >> 2);                               \
1.1.1.5 ! root     3046:     sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
        !          3047:     if (sh > 0)                                                               \
        !          3048:         gen_op_srli_T1(sh);                                                   \
        !          3049:     else if (sh < 0)                                                          \
        !          3050:         gen_op_sli_T1(-sh);                                                   \
1.1       root     3051:     gen_op_##op();                                                            \
1.1.1.5 ! root     3052:     bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03));                          \
        !          3053:     gen_op_andi_T0(bitmask);                                                  \
1.1       root     3054:     gen_op_load_crf_T1(crbD(ctx->opcode) >> 2);                               \
1.1.1.5 ! root     3055:     gen_op_andi_T1(~bitmask);                                                 \
        !          3056:     gen_op_or();                                                              \
        !          3057:     gen_op_store_T0_crf(crbD(ctx->opcode) >> 2);                              \
1.1       root     3058: }
                   3059: 
                   3060: /* crand */
1.1.1.5 ! root     3061: GEN_CRLOGIC(and, 0x08);
1.1       root     3062: /* crandc */
1.1.1.5 ! root     3063: GEN_CRLOGIC(andc, 0x04);
1.1       root     3064: /* creqv */
1.1.1.5 ! root     3065: GEN_CRLOGIC(eqv, 0x09);
1.1       root     3066: /* crnand */
1.1.1.5 ! root     3067: GEN_CRLOGIC(nand, 0x07);
1.1       root     3068: /* crnor */
1.1.1.5 ! root     3069: GEN_CRLOGIC(nor, 0x01);
1.1       root     3070: /* cror */
1.1.1.5 ! root     3071: GEN_CRLOGIC(or, 0x0E);
1.1       root     3072: /* crorc */
1.1.1.5 ! root     3073: GEN_CRLOGIC(orc, 0x0D);
1.1       root     3074: /* crxor */
1.1.1.5 ! root     3075: GEN_CRLOGIC(xor, 0x06);
1.1       root     3076: /* mcrf */
                   3077: GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
                   3078: {
                   3079:     gen_op_load_crf_T0(crfS(ctx->opcode));
                   3080:     gen_op_store_T0_crf(crfD(ctx->opcode));
                   3081: }
                   3082: 
                   3083: /***                           System linkage                              ***/
                   3084: /* rfi (supervisor only) */
1.1.1.5 ! root     3085: GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
1.1       root     3086: {
                   3087: #if defined(CONFIG_USER_ONLY)
1.1.1.5 ! root     3088:     GEN_EXCP_PRIVOPC(ctx);
1.1       root     3089: #else
                   3090:     /* Restore CPU state */
1.1.1.5 ! root     3091:     if (unlikely(!ctx->supervisor)) {
        !          3092:         GEN_EXCP_PRIVOPC(ctx);
1.1       root     3093:         return;
                   3094:     }
                   3095:     gen_op_rfi();
1.1.1.5 ! root     3096:     GEN_SYNC(ctx);
1.1       root     3097: #endif
                   3098: }
                   3099: 
1.1.1.5 ! root     3100: #if defined(TARGET_PPC64)
        !          3101: GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
        !          3102: {
        !          3103: #if defined(CONFIG_USER_ONLY)
        !          3104:     GEN_EXCP_PRIVOPC(ctx);
        !          3105: #else
        !          3106:     /* Restore CPU state */
        !          3107:     if (unlikely(!ctx->supervisor)) {
        !          3108:         GEN_EXCP_PRIVOPC(ctx);
        !          3109:         return;
        !          3110:     }
        !          3111:     gen_op_rfid();
        !          3112:     GEN_SYNC(ctx);
        !          3113: #endif
        !          3114: }
        !          3115: 
        !          3116: GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H)
1.1       root     3117: {
                   3118: #if defined(CONFIG_USER_ONLY)
1.1.1.5 ! root     3119:     GEN_EXCP_PRIVOPC(ctx);
        !          3120: #else
        !          3121:     /* Restore CPU state */
        !          3122:     if (unlikely(ctx->supervisor <= 1)) {
        !          3123:         GEN_EXCP_PRIVOPC(ctx);
        !          3124:         return;
        !          3125:     }
        !          3126:     gen_op_hrfid();
        !          3127:     GEN_SYNC(ctx);
        !          3128: #endif
        !          3129: }
        !          3130: #endif
        !          3131: 
        !          3132: /* sc */
        !          3133: #if defined(CONFIG_USER_ONLY)
        !          3134: #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
1.1       root     3135: #else
1.1.1.5 ! root     3136: #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
1.1       root     3137: #endif
1.1.1.5 ! root     3138: GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
        !          3139: {
        !          3140:     uint32_t lev;
        !          3141: 
        !          3142:     lev = (ctx->opcode >> 5) & 0x7F;
        !          3143:     GEN_EXCP(ctx, POWERPC_SYSCALL, lev);
1.1       root     3144: }
                   3145: 
                   3146: /***                                Trap                                   ***/
                   3147: /* tw */
1.1.1.5 ! root     3148: GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
1.1       root     3149: {
                   3150:     gen_op_load_gpr_T0(rA(ctx->opcode));
                   3151:     gen_op_load_gpr_T1(rB(ctx->opcode));
1.1.1.4   root     3152:     /* Update the nip since this might generate a trap exception */
1.1.1.5 ! root     3153:     gen_update_nip(ctx, ctx->nip);
1.1       root     3154:     gen_op_tw(TO(ctx->opcode));
                   3155: }
                   3156: 
                   3157: /* twi */
                   3158: GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
                   3159: {
                   3160:     gen_op_load_gpr_T0(rA(ctx->opcode));
1.1.1.5 ! root     3161:     gen_set_T1(SIMM(ctx->opcode));
        !          3162:     /* Update the nip since this might generate a trap exception */
        !          3163:     gen_update_nip(ctx, ctx->nip);
        !          3164:     gen_op_tw(TO(ctx->opcode));
1.1       root     3165: }
                   3166: 
1.1.1.5 ! root     3167: #if defined(TARGET_PPC64)
        !          3168: /* td */
        !          3169: GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
1.1       root     3170: {
1.1.1.5 ! root     3171:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          3172:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          3173:     /* Update the nip since this might generate a trap exception */
        !          3174:     gen_update_nip(ctx, ctx->nip);
        !          3175:     gen_op_td(TO(ctx->opcode));
        !          3176: }
1.1       root     3177: 
1.1.1.5 ! root     3178: /* tdi */
        !          3179: GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
        !          3180: {
        !          3181:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          3182:     gen_set_T1(SIMM(ctx->opcode));
        !          3183:     /* Update the nip since this might generate a trap exception */
        !          3184:     gen_update_nip(ctx, ctx->nip);
        !          3185:     gen_op_td(TO(ctx->opcode));
1.1       root     3186: }
1.1.1.5 ! root     3187: #endif
1.1       root     3188: 
1.1.1.5 ! root     3189: /***                          Processor control                            ***/
1.1       root     3190: /* mcrxr */
                   3191: GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
                   3192: {
                   3193:     gen_op_load_xer_cr();
                   3194:     gen_op_store_T0_crf(crfD(ctx->opcode));
1.1.1.5 ! root     3195:     gen_op_clear_xer_ov();
        !          3196:     gen_op_clear_xer_ca();
1.1       root     3197: }
                   3198: 
                   3199: /* mfcr */
1.1.1.5 ! root     3200: GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
1.1       root     3201: {
1.1.1.5 ! root     3202:     uint32_t crm, crn;
        !          3203: 
        !          3204:     if (likely(ctx->opcode & 0x00100000)) {
        !          3205:         crm = CRM(ctx->opcode);
        !          3206:         if (likely((crm ^ (crm - 1)) == 0)) {
        !          3207:             crn = ffs(crm);
        !          3208:             gen_op_load_cro(7 - crn);
        !          3209:         }
        !          3210:     } else {
        !          3211:         gen_op_load_cr();
        !          3212:     }
1.1       root     3213:     gen_op_store_T0_gpr(rD(ctx->opcode));
                   3214: }
                   3215: 
                   3216: /* mfmsr */
                   3217: GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
                   3218: {
                   3219: #if defined(CONFIG_USER_ONLY)
1.1.1.5 ! root     3220:     GEN_EXCP_PRIVREG(ctx);
1.1       root     3221: #else
1.1.1.5 ! root     3222:     if (unlikely(!ctx->supervisor)) {
        !          3223:         GEN_EXCP_PRIVREG(ctx);
1.1       root     3224:         return;
                   3225:     }
                   3226:     gen_op_load_msr();
                   3227:     gen_op_store_T0_gpr(rD(ctx->opcode));
                   3228: #endif
                   3229: }
                   3230: 
1.1.1.5 ! root     3231: #if 1
        !          3232: #define SPR_NOACCESS ((void *)(-1UL))
1.1       root     3233: #else
                   3234: static void spr_noaccess (void *opaque, int sprn)
                   3235: {
                   3236:     sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
                   3237:     printf("ERROR: try to access SPR %d !\n", sprn);
                   3238: }
                   3239: #define SPR_NOACCESS (&spr_noaccess)
                   3240: #endif
                   3241: 
                   3242: /* mfspr */
1.1.1.5 ! root     3243: static always_inline void gen_op_mfspr (DisasContext *ctx)
1.1       root     3244: {
                   3245:     void (*read_cb)(void *opaque, int sprn);
                   3246:     uint32_t sprn = SPR(ctx->opcode);
                   3247: 
                   3248: #if !defined(CONFIG_USER_ONLY)
1.1.1.5 ! root     3249:     if (ctx->supervisor == 2)
        !          3250:         read_cb = ctx->spr_cb[sprn].hea_read;
        !          3251:     else if (ctx->supervisor)
1.1       root     3252:         read_cb = ctx->spr_cb[sprn].oea_read;
                   3253:     else
                   3254: #endif
                   3255:         read_cb = ctx->spr_cb[sprn].uea_read;
1.1.1.5 ! root     3256:     if (likely(read_cb != NULL)) {
        !          3257:         if (likely(read_cb != SPR_NOACCESS)) {
1.1       root     3258:             (*read_cb)(ctx, sprn);
                   3259:             gen_op_store_T0_gpr(rD(ctx->opcode));
                   3260:         } else {
                   3261:             /* Privilege exception */
1.1.1.5 ! root     3262:             /* This is a hack to avoid warnings when running Linux:
        !          3263:              * this OS breaks the PowerPC virtualisation model,
        !          3264:              * allowing userland application to read the PVR
        !          3265:              */
        !          3266:             if (sprn != SPR_PVR) {
        !          3267:                 if (loglevel != 0) {
        !          3268:                     fprintf(logfile, "Trying to read privileged spr %d %03x at "
        !          3269:                             ADDRX "\n", sprn, sprn, ctx->nip);
        !          3270:                 }
        !          3271:                 printf("Trying to read privileged spr %d %03x at " ADDRX "\n",
        !          3272:                        sprn, sprn, ctx->nip);
1.1.1.2   root     3273:             }
1.1.1.5 ! root     3274:             GEN_EXCP_PRIVREG(ctx);
1.1       root     3275:         }
                   3276:     } else {
                   3277:         /* Not defined */
1.1.1.5 ! root     3278:         if (loglevel != 0) {
        !          3279:             fprintf(logfile, "Trying to read invalid spr %d %03x at "
        !          3280:                     ADDRX "\n", sprn, sprn, ctx->nip);
1.1.1.2   root     3281:         }
1.1.1.5 ! root     3282:         printf("Trying to read invalid spr %d %03x at " ADDRX "\n",
        !          3283:                sprn, sprn, ctx->nip);
        !          3284:         GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
        !          3285:                  POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
1.1       root     3286:     }
                   3287: }
                   3288: 
                   3289: GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
                   3290: {
                   3291:     gen_op_mfspr(ctx);
1.1.1.5 ! root     3292: }
1.1       root     3293: 
                   3294: /* mftb */
1.1.1.5 ! root     3295: GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
1.1       root     3296: {
                   3297:     gen_op_mfspr(ctx);
                   3298: }
                   3299: 
                   3300: /* mtcrf */
                   3301: GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
                   3302: {
1.1.1.5 ! root     3303:     uint32_t crm, crn;
        !          3304: 
1.1       root     3305:     gen_op_load_gpr_T0(rS(ctx->opcode));
1.1.1.5 ! root     3306:     crm = CRM(ctx->opcode);
        !          3307:     if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
        !          3308:         crn = ffs(crm);
        !          3309:         gen_op_srli_T0(crn * 4);
        !          3310:         gen_op_andi_T0(0xF);
        !          3311:         gen_op_store_cro(7 - crn);
        !          3312:     } else {
        !          3313:         gen_op_store_cr(crm);
        !          3314:     }
1.1       root     3315: }
                   3316: 
                   3317: /* mtmsr */
1.1.1.5 ! root     3318: #if defined(TARGET_PPC64)
        !          3319: GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
        !          3320: {
        !          3321: #if defined(CONFIG_USER_ONLY)
        !          3322:     GEN_EXCP_PRIVREG(ctx);
        !          3323: #else
        !          3324:     if (unlikely(!ctx->supervisor)) {
        !          3325:         GEN_EXCP_PRIVREG(ctx);
        !          3326:         return;
        !          3327:     }
        !          3328:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          3329:     if (ctx->opcode & 0x00010000) {
        !          3330:         /* Special form that does not need any synchronisation */
        !          3331:         gen_op_update_riee();
        !          3332:     } else {
        !          3333:         /* XXX: we need to update nip before the store
        !          3334:          *      if we enter power saving mode, we will exit the loop
        !          3335:          *      directly from ppc_store_msr
        !          3336:          */
        !          3337:         gen_update_nip(ctx, ctx->nip);
        !          3338:         gen_op_store_msr();
        !          3339:         /* Must stop the translation as machine state (may have) changed */
        !          3340:         /* Note that mtmsr is not always defined as context-synchronizing */
        !          3341:         ctx->exception = POWERPC_EXCP_STOP;
        !          3342:     }
        !          3343: #endif
        !          3344: }
        !          3345: #endif
        !          3346: 
1.1       root     3347: GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
                   3348: {
                   3349: #if defined(CONFIG_USER_ONLY)
1.1.1.5 ! root     3350:     GEN_EXCP_PRIVREG(ctx);
1.1       root     3351: #else
1.1.1.5 ! root     3352:     if (unlikely(!ctx->supervisor)) {
        !          3353:         GEN_EXCP_PRIVREG(ctx);
1.1       root     3354:         return;
                   3355:     }
                   3356:     gen_op_load_gpr_T0(rS(ctx->opcode));
1.1.1.5 ! root     3357:     if (ctx->opcode & 0x00010000) {
        !          3358:         /* Special form that does not need any synchronisation */
        !          3359:         gen_op_update_riee();
        !          3360:     } else {
        !          3361:         /* XXX: we need to update nip before the store
        !          3362:          *      if we enter power saving mode, we will exit the loop
        !          3363:          *      directly from ppc_store_msr
        !          3364:          */
        !          3365:         gen_update_nip(ctx, ctx->nip);
        !          3366: #if defined(TARGET_PPC64)
        !          3367:         if (!ctx->sf_mode)
        !          3368:             gen_op_store_msr_32();
        !          3369:         else
        !          3370: #endif
        !          3371:             gen_op_store_msr();
        !          3372:         /* Must stop the translation as machine state (may have) changed */
        !          3373:         /* Note that mtmsrd is not always defined as context-synchronizing */
        !          3374:         ctx->exception = POWERPC_EXCP_STOP;
        !          3375:     }
1.1       root     3376: #endif
                   3377: }
                   3378: 
                   3379: /* mtspr */
                   3380: GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
                   3381: {
                   3382:     void (*write_cb)(void *opaque, int sprn);
                   3383:     uint32_t sprn = SPR(ctx->opcode);
                   3384: 
                   3385: #if !defined(CONFIG_USER_ONLY)
1.1.1.5 ! root     3386:     if (ctx->supervisor == 2)
        !          3387:         write_cb = ctx->spr_cb[sprn].hea_write;
        !          3388:     else if (ctx->supervisor)
1.1       root     3389:         write_cb = ctx->spr_cb[sprn].oea_write;
                   3390:     else
                   3391: #endif
                   3392:         write_cb = ctx->spr_cb[sprn].uea_write;
1.1.1.5 ! root     3393:     if (likely(write_cb != NULL)) {
        !          3394:         if (likely(write_cb != SPR_NOACCESS)) {
1.1       root     3395:             gen_op_load_gpr_T0(rS(ctx->opcode));
                   3396:             (*write_cb)(ctx, sprn);
                   3397:         } else {
                   3398:             /* Privilege exception */
1.1.1.5 ! root     3399:             if (loglevel != 0) {
        !          3400:                 fprintf(logfile, "Trying to write privileged spr %d %03x at "
        !          3401:                         ADDRX "\n", sprn, sprn, ctx->nip);
1.1.1.2   root     3402:             }
1.1.1.5 ! root     3403:             printf("Trying to write privileged spr %d %03x at " ADDRX "\n",
        !          3404:                    sprn, sprn, ctx->nip);
        !          3405:             GEN_EXCP_PRIVREG(ctx);
        !          3406:         }
1.1       root     3407:     } else {
                   3408:         /* Not defined */
1.1.1.5 ! root     3409:         if (loglevel != 0) {
        !          3410:             fprintf(logfile, "Trying to write invalid spr %d %03x at "
        !          3411:                     ADDRX "\n", sprn, sprn, ctx->nip);
1.1.1.2   root     3412:         }
1.1.1.5 ! root     3413:         printf("Trying to write invalid spr %d %03x at " ADDRX "\n",
        !          3414:                sprn, sprn, ctx->nip);
        !          3415:         GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
        !          3416:                  POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
1.1       root     3417:     }
                   3418: }
                   3419: 
                   3420: /***                         Cache management                              ***/
                   3421: /* dcbf */
1.1.1.5 ! root     3422: GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
1.1       root     3423: {
1.1.1.5 ! root     3424:     /* XXX: specification says this is treated as a load by the MMU */
        !          3425:     gen_addr_reg_index(ctx);
1.1       root     3426:     op_ldst(lbz);
                   3427: }
                   3428: 
                   3429: /* dcbi (Supervisor only) */
                   3430: GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
                   3431: {
                   3432: #if defined(CONFIG_USER_ONLY)
1.1.1.5 ! root     3433:     GEN_EXCP_PRIVOPC(ctx);
1.1       root     3434: #else
1.1.1.5 ! root     3435:     if (unlikely(!ctx->supervisor)) {
        !          3436:         GEN_EXCP_PRIVOPC(ctx);
1.1       root     3437:         return;
                   3438:     }
1.1.1.5 ! root     3439:     gen_addr_reg_index(ctx);
        !          3440:     /* XXX: specification says this should be treated as a store by the MMU */
1.1       root     3441:     op_ldst(lbz);
                   3442:     op_ldst(stb);
                   3443: #endif
                   3444: }
                   3445: 
                   3446: /* dcdst */
                   3447: GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
                   3448: {
1.1.1.5 ! root     3449:     /* XXX: specification say this is treated as a load by the MMU */
        !          3450:     gen_addr_reg_index(ctx);
1.1       root     3451:     op_ldst(lbz);
                   3452: }
                   3453: 
                   3454: /* dcbt */
1.1.1.5 ! root     3455: GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE)
1.1       root     3456: {
1.1.1.5 ! root     3457:     /* interpreted as no-op */
        !          3458:     /* XXX: specification say this is treated as a load by the MMU
        !          3459:      *      but does not generate any exception
        !          3460:      */
1.1       root     3461: }
                   3462: 
                   3463: /* dcbtst */
1.1.1.5 ! root     3464: GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
1.1       root     3465: {
1.1.1.5 ! root     3466:     /* interpreted as no-op */
        !          3467:     /* XXX: specification say this is treated as a load by the MMU
        !          3468:      *      but does not generate any exception
        !          3469:      */
1.1       root     3470: }
                   3471: 
                   3472: /* dcbz */
1.1.1.5 ! root     3473: #define op_dcbz(n) (*gen_op_dcbz[n][ctx->mem_idx])()
        !          3474: static GenOpFunc *gen_op_dcbz[4][NB_MEM_FUNCS] = {
        !          3475:     /* 32 bytes cache line size */
        !          3476:     {
        !          3477: #define gen_op_dcbz_l32_le_raw        gen_op_dcbz_l32_raw
        !          3478: #define gen_op_dcbz_l32_le_user       gen_op_dcbz_l32_user
        !          3479: #define gen_op_dcbz_l32_le_kernel     gen_op_dcbz_l32_kernel
        !          3480: #define gen_op_dcbz_l32_le_hypv       gen_op_dcbz_l32_hypv
        !          3481: #define gen_op_dcbz_l32_le_64_raw     gen_op_dcbz_l32_64_raw
        !          3482: #define gen_op_dcbz_l32_le_64_user    gen_op_dcbz_l32_64_user
        !          3483: #define gen_op_dcbz_l32_le_64_kernel  gen_op_dcbz_l32_64_kernel
        !          3484: #define gen_op_dcbz_l32_le_64_hypv    gen_op_dcbz_l32_64_hypv
        !          3485:         GEN_MEM_FUNCS(dcbz_l32),
        !          3486:     },
        !          3487:     /* 64 bytes cache line size */
        !          3488:     {
        !          3489: #define gen_op_dcbz_l64_le_raw        gen_op_dcbz_l64_raw
        !          3490: #define gen_op_dcbz_l64_le_user       gen_op_dcbz_l64_user
        !          3491: #define gen_op_dcbz_l64_le_kernel     gen_op_dcbz_l64_kernel
        !          3492: #define gen_op_dcbz_l64_le_hypv       gen_op_dcbz_l64_hypv
        !          3493: #define gen_op_dcbz_l64_le_64_raw     gen_op_dcbz_l64_64_raw
        !          3494: #define gen_op_dcbz_l64_le_64_user    gen_op_dcbz_l64_64_user
        !          3495: #define gen_op_dcbz_l64_le_64_kernel  gen_op_dcbz_l64_64_kernel
        !          3496: #define gen_op_dcbz_l64_le_64_hypv    gen_op_dcbz_l64_64_hypv
        !          3497:         GEN_MEM_FUNCS(dcbz_l64),
        !          3498:     },
        !          3499:     /* 128 bytes cache line size */
        !          3500:     {
        !          3501: #define gen_op_dcbz_l128_le_raw       gen_op_dcbz_l128_raw
        !          3502: #define gen_op_dcbz_l128_le_user      gen_op_dcbz_l128_user
        !          3503: #define gen_op_dcbz_l128_le_kernel    gen_op_dcbz_l128_kernel
        !          3504: #define gen_op_dcbz_l128_le_hypv      gen_op_dcbz_l128_hypv
        !          3505: #define gen_op_dcbz_l128_le_64_raw    gen_op_dcbz_l128_64_raw
        !          3506: #define gen_op_dcbz_l128_le_64_user   gen_op_dcbz_l128_64_user
        !          3507: #define gen_op_dcbz_l128_le_64_kernel gen_op_dcbz_l128_64_kernel
        !          3508: #define gen_op_dcbz_l128_le_64_hypv   gen_op_dcbz_l128_64_hypv
        !          3509:         GEN_MEM_FUNCS(dcbz_l128),
        !          3510:     },
        !          3511:     /* tunable cache line size */
        !          3512:     {
        !          3513: #define gen_op_dcbz_le_raw            gen_op_dcbz_raw
        !          3514: #define gen_op_dcbz_le_user           gen_op_dcbz_user
        !          3515: #define gen_op_dcbz_le_kernel         gen_op_dcbz_kernel
        !          3516: #define gen_op_dcbz_le_hypv           gen_op_dcbz_hypv
        !          3517: #define gen_op_dcbz_le_64_raw         gen_op_dcbz_64_raw
        !          3518: #define gen_op_dcbz_le_64_user        gen_op_dcbz_64_user
        !          3519: #define gen_op_dcbz_le_64_kernel      gen_op_dcbz_64_kernel
        !          3520: #define gen_op_dcbz_le_64_hypv        gen_op_dcbz_64_hypv
        !          3521:         GEN_MEM_FUNCS(dcbz),
        !          3522:     },
1.1       root     3523: };
                   3524: 
1.1.1.5 ! root     3525: static always_inline void handler_dcbz (DisasContext *ctx,
        !          3526:                                         int dcache_line_size)
1.1       root     3527: {
1.1.1.5 ! root     3528:     int n;
        !          3529: 
        !          3530:     switch (dcache_line_size) {
        !          3531:     case 32:
        !          3532:         n = 0;
        !          3533:         break;
        !          3534:     case 64:
        !          3535:         n = 1;
        !          3536:         break;
        !          3537:     case 128:
        !          3538:         n = 2;
        !          3539:         break;
        !          3540:     default:
        !          3541:         n = 3;
        !          3542:         break;
1.1       root     3543:     }
1.1.1.5 ! root     3544:     op_dcbz(n);
        !          3545: }
        !          3546: 
        !          3547: GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ)
        !          3548: {
        !          3549:     gen_addr_reg_index(ctx);
        !          3550:     handler_dcbz(ctx, ctx->dcache_line_size);
        !          3551:     gen_op_check_reservation();
        !          3552: }
        !          3553: 
        !          3554: GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
        !          3555: {
        !          3556:     gen_addr_reg_index(ctx);
        !          3557:     if (ctx->opcode & 0x00200000)
        !          3558:         handler_dcbz(ctx, ctx->dcache_line_size);
        !          3559:     else
        !          3560:         handler_dcbz(ctx, -1);
1.1       root     3561:     gen_op_check_reservation();
                   3562: }
                   3563: 
                   3564: /* icbi */
1.1.1.5 ! root     3565: #define op_icbi() (*gen_op_icbi[ctx->mem_idx])()
        !          3566: #define gen_op_icbi_le_raw       gen_op_icbi_raw
        !          3567: #define gen_op_icbi_le_user      gen_op_icbi_user
        !          3568: #define gen_op_icbi_le_kernel    gen_op_icbi_kernel
        !          3569: #define gen_op_icbi_le_hypv      gen_op_icbi_hypv
        !          3570: #define gen_op_icbi_le_64_raw    gen_op_icbi_64_raw
        !          3571: #define gen_op_icbi_le_64_user   gen_op_icbi_64_user
        !          3572: #define gen_op_icbi_le_64_kernel gen_op_icbi_64_kernel
        !          3573: #define gen_op_icbi_le_64_hypv   gen_op_icbi_64_hypv
        !          3574: static GenOpFunc *gen_op_icbi[NB_MEM_FUNCS] = {
        !          3575:     GEN_MEM_FUNCS(icbi),
        !          3576: };
        !          3577: 
        !          3578: GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI)
1.1       root     3579: {
1.1.1.5 ! root     3580:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          3581:     gen_update_nip(ctx, ctx->nip - 4);
        !          3582:     gen_addr_reg_index(ctx);
        !          3583:     op_icbi();
1.1       root     3584: }
                   3585: 
                   3586: /* Optional: */
                   3587: /* dcba */
1.1.1.5 ! root     3588: GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
1.1       root     3589: {
1.1.1.5 ! root     3590:     /* interpreted as no-op */
        !          3591:     /* XXX: specification say this is treated as a store by the MMU
        !          3592:      *      but does not generate any exception
        !          3593:      */
1.1       root     3594: }
                   3595: 
                   3596: /***                    Segment register manipulation                      ***/
                   3597: /* Supervisor only: */
                   3598: /* mfsr */
                   3599: GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
                   3600: {
                   3601: #if defined(CONFIG_USER_ONLY)
1.1.1.5 ! root     3602:     GEN_EXCP_PRIVREG(ctx);
1.1       root     3603: #else
1.1.1.5 ! root     3604:     if (unlikely(!ctx->supervisor)) {
        !          3605:         GEN_EXCP_PRIVREG(ctx);
1.1       root     3606:         return;
                   3607:     }
1.1.1.5 ! root     3608:     gen_op_set_T1(SR(ctx->opcode));
        !          3609:     gen_op_load_sr();
1.1       root     3610:     gen_op_store_T0_gpr(rD(ctx->opcode));
                   3611: #endif
                   3612: }
                   3613: 
                   3614: /* mfsrin */
                   3615: GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
                   3616: {
                   3617: #if defined(CONFIG_USER_ONLY)
1.1.1.5 ! root     3618:     GEN_EXCP_PRIVREG(ctx);
1.1       root     3619: #else
1.1.1.5 ! root     3620:     if (unlikely(!ctx->supervisor)) {
        !          3621:         GEN_EXCP_PRIVREG(ctx);
1.1       root     3622:         return;
                   3623:     }
                   3624:     gen_op_load_gpr_T1(rB(ctx->opcode));
1.1.1.5 ! root     3625:     gen_op_srli_T1(28);
        !          3626:     gen_op_load_sr();
1.1       root     3627:     gen_op_store_T0_gpr(rD(ctx->opcode));
                   3628: #endif
                   3629: }
                   3630: 
                   3631: /* mtsr */
                   3632: GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
                   3633: {
                   3634: #if defined(CONFIG_USER_ONLY)
1.1.1.5 ! root     3635:     GEN_EXCP_PRIVREG(ctx);
1.1       root     3636: #else
1.1.1.5 ! root     3637:     if (unlikely(!ctx->supervisor)) {
        !          3638:         GEN_EXCP_PRIVREG(ctx);
1.1       root     3639:         return;
                   3640:     }
                   3641:     gen_op_load_gpr_T0(rS(ctx->opcode));
1.1.1.5 ! root     3642:     gen_op_set_T1(SR(ctx->opcode));
        !          3643:     gen_op_store_sr();
1.1       root     3644: #endif
                   3645: }
                   3646: 
                   3647: /* mtsrin */
                   3648: GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
                   3649: {
                   3650: #if defined(CONFIG_USER_ONLY)
1.1.1.5 ! root     3651:     GEN_EXCP_PRIVREG(ctx);
1.1       root     3652: #else
1.1.1.5 ! root     3653:     if (unlikely(!ctx->supervisor)) {
        !          3654:         GEN_EXCP_PRIVREG(ctx);
1.1       root     3655:         return;
                   3656:     }
                   3657:     gen_op_load_gpr_T0(rS(ctx->opcode));
                   3658:     gen_op_load_gpr_T1(rB(ctx->opcode));
1.1.1.5 ! root     3659:     gen_op_srli_T1(28);
        !          3660:     gen_op_store_sr();
1.1       root     3661: #endif
                   3662: }
                   3663: 
1.1.1.5 ! root     3664: #if defined(TARGET_PPC64)
        !          3665: /* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
        !          3666: /* mfsr */
        !          3667: GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
1.1       root     3668: {
                   3669: #if defined(CONFIG_USER_ONLY)
1.1.1.5 ! root     3670:     GEN_EXCP_PRIVREG(ctx);
1.1       root     3671: #else
1.1.1.5 ! root     3672:     if (unlikely(!ctx->supervisor)) {
        !          3673:         GEN_EXCP_PRIVREG(ctx);
1.1       root     3674:         return;
                   3675:     }
1.1.1.5 ! root     3676:     gen_op_set_T1(SR(ctx->opcode));
        !          3677:     gen_op_load_slb();
        !          3678:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          3679: #endif
        !          3680: }
        !          3681: 
        !          3682: /* mfsrin */
        !          3683: GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
        !          3684:              PPC_SEGMENT_64B)
        !          3685: {
        !          3686: #if defined(CONFIG_USER_ONLY)
        !          3687:     GEN_EXCP_PRIVREG(ctx);
        !          3688: #else
        !          3689:     if (unlikely(!ctx->supervisor)) {
        !          3690:         GEN_EXCP_PRIVREG(ctx);
        !          3691:         return;
        !          3692:     }
        !          3693:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          3694:     gen_op_srli_T1(28);
        !          3695:     gen_op_load_slb();
        !          3696:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          3697: #endif
        !          3698: }
        !          3699: 
        !          3700: /* mtsr */
        !          3701: GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
        !          3702: {
        !          3703: #if defined(CONFIG_USER_ONLY)
        !          3704:     GEN_EXCP_PRIVREG(ctx);
        !          3705: #else
        !          3706:     if (unlikely(!ctx->supervisor)) {
        !          3707:         GEN_EXCP_PRIVREG(ctx);
        !          3708:         return;
        !          3709:     }
        !          3710:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          3711:     gen_op_set_T1(SR(ctx->opcode));
        !          3712:     gen_op_store_slb();
        !          3713: #endif
        !          3714: }
        !          3715: 
        !          3716: /* mtsrin */
        !          3717: GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
        !          3718:              PPC_SEGMENT_64B)
        !          3719: {
        !          3720: #if defined(CONFIG_USER_ONLY)
        !          3721:     GEN_EXCP_PRIVREG(ctx);
        !          3722: #else
        !          3723:     if (unlikely(!ctx->supervisor)) {
        !          3724:         GEN_EXCP_PRIVREG(ctx);
        !          3725:         return;
        !          3726:     }
        !          3727:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          3728:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          3729:     gen_op_srli_T1(28);
        !          3730:     gen_op_store_slb();
        !          3731: #endif
        !          3732: }
        !          3733: #endif /* defined(TARGET_PPC64) */
        !          3734: 
        !          3735: /***                      Lookaside buffer management                      ***/
        !          3736: /* Optional & supervisor only: */
        !          3737: /* tlbia */
        !          3738: GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
        !          3739: {
        !          3740: #if defined(CONFIG_USER_ONLY)
        !          3741:     GEN_EXCP_PRIVOPC(ctx);
        !          3742: #else
        !          3743:     if (unlikely(!ctx->supervisor)) {
        !          3744:         GEN_EXCP_PRIVOPC(ctx);
        !          3745:         return;
        !          3746:     }
        !          3747:     gen_op_tlbia();
1.1       root     3748: #endif
                   3749: }
                   3750: 
                   3751: /* tlbie */
1.1.1.5 ! root     3752: GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
        !          3753: {
        !          3754: #if defined(CONFIG_USER_ONLY)
        !          3755:     GEN_EXCP_PRIVOPC(ctx);
        !          3756: #else
        !          3757:     if (unlikely(!ctx->supervisor)) {
        !          3758:         GEN_EXCP_PRIVOPC(ctx);
        !          3759:         return;
        !          3760:     }
        !          3761:     gen_op_load_gpr_T0(rB(ctx->opcode));
        !          3762: #if defined(TARGET_PPC64)
        !          3763:     if (ctx->sf_mode)
        !          3764:         gen_op_tlbie_64();
        !          3765:     else
        !          3766: #endif
        !          3767:         gen_op_tlbie();
        !          3768: #endif
        !          3769: }
        !          3770: 
        !          3771: /* tlbsync */
        !          3772: GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
        !          3773: {
        !          3774: #if defined(CONFIG_USER_ONLY)
        !          3775:     GEN_EXCP_PRIVOPC(ctx);
        !          3776: #else
        !          3777:     if (unlikely(!ctx->supervisor)) {
        !          3778:         GEN_EXCP_PRIVOPC(ctx);
        !          3779:         return;
        !          3780:     }
        !          3781:     /* This has no effect: it should ensure that all previous
        !          3782:      * tlbie have completed
        !          3783:      */
        !          3784:     GEN_STOP(ctx);
        !          3785: #endif
        !          3786: }
        !          3787: 
        !          3788: #if defined(TARGET_PPC64)
        !          3789: /* slbia */
        !          3790: GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
        !          3791: {
        !          3792: #if defined(CONFIG_USER_ONLY)
        !          3793:     GEN_EXCP_PRIVOPC(ctx);
        !          3794: #else
        !          3795:     if (unlikely(!ctx->supervisor)) {
        !          3796:         GEN_EXCP_PRIVOPC(ctx);
        !          3797:         return;
        !          3798:     }
        !          3799:     gen_op_slbia();
        !          3800: #endif
        !          3801: }
        !          3802: 
        !          3803: /* slbie */
        !          3804: GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
        !          3805: {
        !          3806: #if defined(CONFIG_USER_ONLY)
        !          3807:     GEN_EXCP_PRIVOPC(ctx);
        !          3808: #else
        !          3809:     if (unlikely(!ctx->supervisor)) {
        !          3810:         GEN_EXCP_PRIVOPC(ctx);
        !          3811:         return;
        !          3812:     }
        !          3813:     gen_op_load_gpr_T0(rB(ctx->opcode));
        !          3814:     gen_op_slbie();
        !          3815: #endif
        !          3816: }
        !          3817: #endif
        !          3818: 
        !          3819: /***                              External control                         ***/
        !          3820: /* Optional: */
        !          3821: #define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])()
        !          3822: #define op_ecowx() (*gen_op_ecowx[ctx->mem_idx])()
        !          3823: static GenOpFunc *gen_op_eciwx[NB_MEM_FUNCS] = {
        !          3824:     GEN_MEM_FUNCS(eciwx),
        !          3825: };
        !          3826: static GenOpFunc *gen_op_ecowx[NB_MEM_FUNCS] = {
        !          3827:     GEN_MEM_FUNCS(ecowx),
        !          3828: };
        !          3829: 
        !          3830: /* eciwx */
        !          3831: GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
        !          3832: {
        !          3833:     /* Should check EAR[E] & alignment ! */
        !          3834:     gen_addr_reg_index(ctx);
        !          3835:     op_eciwx();
        !          3836:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          3837: }
        !          3838: 
        !          3839: /* ecowx */
        !          3840: GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
        !          3841: {
        !          3842:     /* Should check EAR[E] & alignment ! */
        !          3843:     gen_addr_reg_index(ctx);
        !          3844:     gen_op_load_gpr_T1(rS(ctx->opcode));
        !          3845:     op_ecowx();
        !          3846: }
        !          3847: 
        !          3848: /* PowerPC 601 specific instructions */
        !          3849: /* abs - abs. */
        !          3850: GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
        !          3851: {
        !          3852:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          3853:     gen_op_POWER_abs();
        !          3854:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          3855:     if (unlikely(Rc(ctx->opcode) != 0))
        !          3856:         gen_set_Rc0(ctx);
        !          3857: }
        !          3858: 
        !          3859: /* abso - abso. */
        !          3860: GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
        !          3861: {
        !          3862:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          3863:     gen_op_POWER_abso();
        !          3864:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          3865:     if (unlikely(Rc(ctx->opcode) != 0))
        !          3866:         gen_set_Rc0(ctx);
        !          3867: }
        !          3868: 
        !          3869: /* clcs */
        !          3870: GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
        !          3871: {
        !          3872:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          3873:     gen_op_POWER_clcs();
        !          3874:     /* Rc=1 sets CR0 to an undefined state */
        !          3875:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          3876: }
        !          3877: 
        !          3878: /* div - div. */
        !          3879: GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
        !          3880: {
        !          3881:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          3882:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          3883:     gen_op_POWER_div();
        !          3884:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          3885:     if (unlikely(Rc(ctx->opcode) != 0))
        !          3886:         gen_set_Rc0(ctx);
        !          3887: }
        !          3888: 
        !          3889: /* divo - divo. */
        !          3890: GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
        !          3891: {
        !          3892:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          3893:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          3894:     gen_op_POWER_divo();
        !          3895:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          3896:     if (unlikely(Rc(ctx->opcode) != 0))
        !          3897:         gen_set_Rc0(ctx);
        !          3898: }
        !          3899: 
        !          3900: /* divs - divs. */
        !          3901: GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
        !          3902: {
        !          3903:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          3904:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          3905:     gen_op_POWER_divs();
        !          3906:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          3907:     if (unlikely(Rc(ctx->opcode) != 0))
        !          3908:         gen_set_Rc0(ctx);
        !          3909: }
        !          3910: 
        !          3911: /* divso - divso. */
        !          3912: GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
        !          3913: {
        !          3914:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          3915:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          3916:     gen_op_POWER_divso();
        !          3917:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          3918:     if (unlikely(Rc(ctx->opcode) != 0))
        !          3919:         gen_set_Rc0(ctx);
        !          3920: }
        !          3921: 
        !          3922: /* doz - doz. */
        !          3923: GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
        !          3924: {
        !          3925:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          3926:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          3927:     gen_op_POWER_doz();
        !          3928:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          3929:     if (unlikely(Rc(ctx->opcode) != 0))
        !          3930:         gen_set_Rc0(ctx);
        !          3931: }
        !          3932: 
        !          3933: /* dozo - dozo. */
        !          3934: GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
        !          3935: {
        !          3936:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          3937:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          3938:     gen_op_POWER_dozo();
        !          3939:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          3940:     if (unlikely(Rc(ctx->opcode) != 0))
        !          3941:         gen_set_Rc0(ctx);
        !          3942: }
        !          3943: 
        !          3944: /* dozi */
        !          3945: GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
        !          3946: {
        !          3947:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          3948:     gen_op_set_T1(SIMM(ctx->opcode));
        !          3949:     gen_op_POWER_doz();
        !          3950:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          3951: }
        !          3952: 
        !          3953: /* As lscbx load from memory byte after byte, it's always endian safe.
        !          3954:  * Original POWER is 32 bits only, define 64 bits ops as 32 bits ones
        !          3955:  */
        !          3956: #define op_POWER_lscbx(start, ra, rb)                                         \
        !          3957: (*gen_op_POWER_lscbx[ctx->mem_idx])(start, ra, rb)
        !          3958: #define gen_op_POWER_lscbx_64_raw       gen_op_POWER_lscbx_raw
        !          3959: #define gen_op_POWER_lscbx_64_user      gen_op_POWER_lscbx_user
        !          3960: #define gen_op_POWER_lscbx_64_kernel    gen_op_POWER_lscbx_kernel
        !          3961: #define gen_op_POWER_lscbx_64_hypv      gen_op_POWER_lscbx_hypv
        !          3962: #define gen_op_POWER_lscbx_le_raw       gen_op_POWER_lscbx_raw
        !          3963: #define gen_op_POWER_lscbx_le_user      gen_op_POWER_lscbx_user
        !          3964: #define gen_op_POWER_lscbx_le_kernel    gen_op_POWER_lscbx_kernel
        !          3965: #define gen_op_POWER_lscbx_le_hypv      gen_op_POWER_lscbx_hypv
        !          3966: #define gen_op_POWER_lscbx_le_64_raw    gen_op_POWER_lscbx_raw
        !          3967: #define gen_op_POWER_lscbx_le_64_user   gen_op_POWER_lscbx_user
        !          3968: #define gen_op_POWER_lscbx_le_64_kernel gen_op_POWER_lscbx_kernel
        !          3969: #define gen_op_POWER_lscbx_le_64_hypv   gen_op_POWER_lscbx_hypv
        !          3970: static GenOpFunc3 *gen_op_POWER_lscbx[NB_MEM_FUNCS] = {
        !          3971:     GEN_MEM_FUNCS(POWER_lscbx),
        !          3972: };
        !          3973: 
        !          3974: /* lscbx - lscbx. */
        !          3975: GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
        !          3976: {
        !          3977:     int ra = rA(ctx->opcode);
        !          3978:     int rb = rB(ctx->opcode);
        !          3979: 
        !          3980:     gen_addr_reg_index(ctx);
        !          3981:     if (ra == 0) {
        !          3982:         ra = rb;
        !          3983:     }
        !          3984:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          3985:     gen_update_nip(ctx, ctx->nip - 4);
        !          3986:     gen_op_load_xer_bc();
        !          3987:     gen_op_load_xer_cmp();
        !          3988:     op_POWER_lscbx(rD(ctx->opcode), ra, rb);
        !          3989:     gen_op_store_xer_bc();
        !          3990:     if (unlikely(Rc(ctx->opcode) != 0))
        !          3991:         gen_set_Rc0(ctx);
        !          3992: }
        !          3993: 
        !          3994: /* maskg - maskg. */
        !          3995: GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
        !          3996: {
        !          3997:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          3998:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          3999:     gen_op_POWER_maskg();
        !          4000:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4001:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4002:         gen_set_Rc0(ctx);
        !          4003: }
        !          4004: 
        !          4005: /* maskir - maskir. */
        !          4006: GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
        !          4007: {
        !          4008:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          4009:     gen_op_load_gpr_T1(rS(ctx->opcode));
        !          4010:     gen_op_load_gpr_T2(rB(ctx->opcode));
        !          4011:     gen_op_POWER_maskir();
        !          4012:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4013:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4014:         gen_set_Rc0(ctx);
        !          4015: }
        !          4016: 
        !          4017: /* mul - mul. */
        !          4018: GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
        !          4019: {
        !          4020:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          4021:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          4022:     gen_op_POWER_mul();
        !          4023:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          4024:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4025:         gen_set_Rc0(ctx);
        !          4026: }
        !          4027: 
        !          4028: /* mulo - mulo. */
        !          4029: GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
        !          4030: {
        !          4031:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          4032:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          4033:     gen_op_POWER_mulo();
        !          4034:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          4035:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4036:         gen_set_Rc0(ctx);
        !          4037: }
        !          4038: 
        !          4039: /* nabs - nabs. */
        !          4040: GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
        !          4041: {
        !          4042:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          4043:     gen_op_POWER_nabs();
        !          4044:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          4045:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4046:         gen_set_Rc0(ctx);
        !          4047: }
        !          4048: 
        !          4049: /* nabso - nabso. */
        !          4050: GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
        !          4051: {
        !          4052:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          4053:     gen_op_POWER_nabso();
        !          4054:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          4055:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4056:         gen_set_Rc0(ctx);
        !          4057: }
        !          4058: 
        !          4059: /* rlmi - rlmi. */
        !          4060: GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
        !          4061: {
        !          4062:     uint32_t mb, me;
        !          4063: 
        !          4064:     mb = MB(ctx->opcode);
        !          4065:     me = ME(ctx->opcode);
        !          4066:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4067:     gen_op_load_gpr_T1(rA(ctx->opcode));
        !          4068:     gen_op_load_gpr_T2(rB(ctx->opcode));
        !          4069:     gen_op_POWER_rlmi(MASK(mb, me), ~MASK(mb, me));
        !          4070:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4071:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4072:         gen_set_Rc0(ctx);
        !          4073: }
        !          4074: 
        !          4075: /* rrib - rrib. */
        !          4076: GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
        !          4077: {
        !          4078:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4079:     gen_op_load_gpr_T1(rA(ctx->opcode));
        !          4080:     gen_op_load_gpr_T2(rB(ctx->opcode));
        !          4081:     gen_op_POWER_rrib();
        !          4082:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4083:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4084:         gen_set_Rc0(ctx);
        !          4085: }
        !          4086: 
        !          4087: /* sle - sle. */
        !          4088: GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
        !          4089: {
        !          4090:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4091:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          4092:     gen_op_POWER_sle();
        !          4093:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4094:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4095:         gen_set_Rc0(ctx);
        !          4096: }
        !          4097: 
        !          4098: /* sleq - sleq. */
        !          4099: GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
        !          4100: {
        !          4101:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4102:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          4103:     gen_op_POWER_sleq();
        !          4104:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4105:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4106:         gen_set_Rc0(ctx);
        !          4107: }
        !          4108: 
        !          4109: /* sliq - sliq. */
        !          4110: GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
        !          4111: {
        !          4112:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4113:     gen_op_set_T1(SH(ctx->opcode));
        !          4114:     gen_op_POWER_sle();
        !          4115:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4116:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4117:         gen_set_Rc0(ctx);
        !          4118: }
        !          4119: 
        !          4120: /* slliq - slliq. */
        !          4121: GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
        !          4122: {
        !          4123:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4124:     gen_op_set_T1(SH(ctx->opcode));
        !          4125:     gen_op_POWER_sleq();
        !          4126:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4127:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4128:         gen_set_Rc0(ctx);
        !          4129: }
        !          4130: 
        !          4131: /* sllq - sllq. */
        !          4132: GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
        !          4133: {
        !          4134:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4135:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          4136:     gen_op_POWER_sllq();
        !          4137:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4138:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4139:         gen_set_Rc0(ctx);
        !          4140: }
        !          4141: 
        !          4142: /* slq - slq. */
        !          4143: GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
        !          4144: {
        !          4145:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4146:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          4147:     gen_op_POWER_slq();
        !          4148:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4149:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4150:         gen_set_Rc0(ctx);
        !          4151: }
        !          4152: 
        !          4153: /* sraiq - sraiq. */
        !          4154: GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
        !          4155: {
        !          4156:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4157:     gen_op_set_T1(SH(ctx->opcode));
        !          4158:     gen_op_POWER_sraq();
        !          4159:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4160:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4161:         gen_set_Rc0(ctx);
        !          4162: }
        !          4163: 
        !          4164: /* sraq - sraq. */
        !          4165: GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
        !          4166: {
        !          4167:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4168:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          4169:     gen_op_POWER_sraq();
        !          4170:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4171:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4172:         gen_set_Rc0(ctx);
        !          4173: }
        !          4174: 
        !          4175: /* sre - sre. */
        !          4176: GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
        !          4177: {
        !          4178:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4179:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          4180:     gen_op_POWER_sre();
        !          4181:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4182:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4183:         gen_set_Rc0(ctx);
        !          4184: }
        !          4185: 
        !          4186: /* srea - srea. */
        !          4187: GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
        !          4188: {
        !          4189:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4190:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          4191:     gen_op_POWER_srea();
        !          4192:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4193:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4194:         gen_set_Rc0(ctx);
        !          4195: }
        !          4196: 
        !          4197: /* sreq */
        !          4198: GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
        !          4199: {
        !          4200:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4201:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          4202:     gen_op_POWER_sreq();
        !          4203:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4204:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4205:         gen_set_Rc0(ctx);
        !          4206: }
        !          4207: 
        !          4208: /* sriq */
        !          4209: GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
        !          4210: {
        !          4211:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4212:     gen_op_set_T1(SH(ctx->opcode));
        !          4213:     gen_op_POWER_srq();
        !          4214:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4215:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4216:         gen_set_Rc0(ctx);
        !          4217: }
        !          4218: 
        !          4219: /* srliq */
        !          4220: GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
        !          4221: {
        !          4222:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4223:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          4224:     gen_op_set_T1(SH(ctx->opcode));
        !          4225:     gen_op_POWER_srlq();
        !          4226:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4227:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4228:         gen_set_Rc0(ctx);
        !          4229: }
        !          4230: 
        !          4231: /* srlq */
        !          4232: GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
        !          4233: {
        !          4234:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4235:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          4236:     gen_op_POWER_srlq();
        !          4237:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4238:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4239:         gen_set_Rc0(ctx);
        !          4240: }
        !          4241: 
        !          4242: /* srq */
        !          4243: GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
        !          4244: {
        !          4245:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          4246:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          4247:     gen_op_POWER_srq();
        !          4248:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          4249:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4250:         gen_set_Rc0(ctx);
        !          4251: }
        !          4252: 
        !          4253: /* PowerPC 602 specific instructions */
        !          4254: /* dsa  */
        !          4255: GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
        !          4256: {
        !          4257:     /* XXX: TODO */
        !          4258:     GEN_EXCP_INVAL(ctx);
        !          4259: }
        !          4260: 
        !          4261: /* esa */
        !          4262: GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
        !          4263: {
        !          4264:     /* XXX: TODO */
        !          4265:     GEN_EXCP_INVAL(ctx);
        !          4266: }
        !          4267: 
        !          4268: /* mfrom */
        !          4269: GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
        !          4270: {
        !          4271: #if defined(CONFIG_USER_ONLY)
        !          4272:     GEN_EXCP_PRIVOPC(ctx);
        !          4273: #else
        !          4274:     if (unlikely(!ctx->supervisor)) {
        !          4275:         GEN_EXCP_PRIVOPC(ctx);
        !          4276:         return;
        !          4277:     }
        !          4278:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          4279:     gen_op_602_mfrom();
        !          4280:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          4281: #endif
        !          4282: }
        !          4283: 
        !          4284: /* 602 - 603 - G2 TLB management */
        !          4285: /* tlbld */
        !          4286: GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
        !          4287: {
        !          4288: #if defined(CONFIG_USER_ONLY)
        !          4289:     GEN_EXCP_PRIVOPC(ctx);
        !          4290: #else
        !          4291:     if (unlikely(!ctx->supervisor)) {
        !          4292:         GEN_EXCP_PRIVOPC(ctx);
        !          4293:         return;
        !          4294:     }
        !          4295:     gen_op_load_gpr_T0(rB(ctx->opcode));
        !          4296:     gen_op_6xx_tlbld();
        !          4297: #endif
        !          4298: }
        !          4299: 
        !          4300: /* tlbli */
        !          4301: GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
        !          4302: {
        !          4303: #if defined(CONFIG_USER_ONLY)
        !          4304:     GEN_EXCP_PRIVOPC(ctx);
        !          4305: #else
        !          4306:     if (unlikely(!ctx->supervisor)) {
        !          4307:         GEN_EXCP_PRIVOPC(ctx);
        !          4308:         return;
        !          4309:     }
        !          4310:     gen_op_load_gpr_T0(rB(ctx->opcode));
        !          4311:     gen_op_6xx_tlbli();
        !          4312: #endif
        !          4313: }
        !          4314: 
        !          4315: /* 74xx TLB management */
        !          4316: /* tlbld */
        !          4317: GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
        !          4318: {
        !          4319: #if defined(CONFIG_USER_ONLY)
        !          4320:     GEN_EXCP_PRIVOPC(ctx);
        !          4321: #else
        !          4322:     if (unlikely(!ctx->supervisor)) {
        !          4323:         GEN_EXCP_PRIVOPC(ctx);
        !          4324:         return;
        !          4325:     }
        !          4326:     gen_op_load_gpr_T0(rB(ctx->opcode));
        !          4327:     gen_op_74xx_tlbld();
        !          4328: #endif
        !          4329: }
        !          4330: 
        !          4331: /* tlbli */
        !          4332: GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB)
        !          4333: {
        !          4334: #if defined(CONFIG_USER_ONLY)
        !          4335:     GEN_EXCP_PRIVOPC(ctx);
        !          4336: #else
        !          4337:     if (unlikely(!ctx->supervisor)) {
        !          4338:         GEN_EXCP_PRIVOPC(ctx);
        !          4339:         return;
        !          4340:     }
        !          4341:     gen_op_load_gpr_T0(rB(ctx->opcode));
        !          4342:     gen_op_74xx_tlbli();
        !          4343: #endif
        !          4344: }
        !          4345: 
        !          4346: /* POWER instructions not in PowerPC 601 */
        !          4347: /* clf */
        !          4348: GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
        !          4349: {
        !          4350:     /* Cache line flush: implemented as no-op */
        !          4351: }
        !          4352: 
        !          4353: /* cli */
        !          4354: GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
        !          4355: {
        !          4356:     /* Cache line invalidate: privileged and treated as no-op */
        !          4357: #if defined(CONFIG_USER_ONLY)
        !          4358:     GEN_EXCP_PRIVOPC(ctx);
        !          4359: #else
        !          4360:     if (unlikely(!ctx->supervisor)) {
        !          4361:         GEN_EXCP_PRIVOPC(ctx);
        !          4362:         return;
        !          4363:     }
        !          4364: #endif
        !          4365: }
        !          4366: 
        !          4367: /* dclst */
        !          4368: GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
        !          4369: {
        !          4370:     /* Data cache line store: treated as no-op */
        !          4371: }
        !          4372: 
        !          4373: GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
        !          4374: {
        !          4375: #if defined(CONFIG_USER_ONLY)
        !          4376:     GEN_EXCP_PRIVOPC(ctx);
        !          4377: #else
        !          4378:     if (unlikely(!ctx->supervisor)) {
        !          4379:         GEN_EXCP_PRIVOPC(ctx);
        !          4380:         return;
        !          4381:     }
        !          4382:     int ra = rA(ctx->opcode);
        !          4383:     int rd = rD(ctx->opcode);
        !          4384: 
        !          4385:     gen_addr_reg_index(ctx);
        !          4386:     gen_op_POWER_mfsri();
        !          4387:     gen_op_store_T0_gpr(rd);
        !          4388:     if (ra != 0 && ra != rd)
        !          4389:         gen_op_store_T1_gpr(ra);
        !          4390: #endif
        !          4391: }
        !          4392: 
        !          4393: GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
        !          4394: {
        !          4395: #if defined(CONFIG_USER_ONLY)
        !          4396:     GEN_EXCP_PRIVOPC(ctx);
        !          4397: #else
        !          4398:     if (unlikely(!ctx->supervisor)) {
        !          4399:         GEN_EXCP_PRIVOPC(ctx);
        !          4400:         return;
        !          4401:     }
        !          4402:     gen_addr_reg_index(ctx);
        !          4403:     gen_op_POWER_rac();
        !          4404:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          4405: #endif
        !          4406: }
        !          4407: 
        !          4408: GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
        !          4409: {
        !          4410: #if defined(CONFIG_USER_ONLY)
        !          4411:     GEN_EXCP_PRIVOPC(ctx);
        !          4412: #else
        !          4413:     if (unlikely(!ctx->supervisor)) {
        !          4414:         GEN_EXCP_PRIVOPC(ctx);
        !          4415:         return;
        !          4416:     }
        !          4417:     gen_op_POWER_rfsvc();
        !          4418:     GEN_SYNC(ctx);
        !          4419: #endif
        !          4420: }
        !          4421: 
        !          4422: /* svc is not implemented for now */
        !          4423: 
        !          4424: /* POWER2 specific instructions */
        !          4425: /* Quad manipulation (load/store two floats at a time) */
        !          4426: /* Original POWER2 is 32 bits only, define 64 bits ops as 32 bits ones */
        !          4427: #define op_POWER2_lfq() (*gen_op_POWER2_lfq[ctx->mem_idx])()
        !          4428: #define op_POWER2_stfq() (*gen_op_POWER2_stfq[ctx->mem_idx])()
        !          4429: #define gen_op_POWER2_lfq_64_raw        gen_op_POWER2_lfq_raw
        !          4430: #define gen_op_POWER2_lfq_64_user       gen_op_POWER2_lfq_user
        !          4431: #define gen_op_POWER2_lfq_64_kernel     gen_op_POWER2_lfq_kernel
        !          4432: #define gen_op_POWER2_lfq_64_hypv       gen_op_POWER2_lfq_hypv
        !          4433: #define gen_op_POWER2_lfq_le_64_raw     gen_op_POWER2_lfq_le_raw
        !          4434: #define gen_op_POWER2_lfq_le_64_user    gen_op_POWER2_lfq_le_user
        !          4435: #define gen_op_POWER2_lfq_le_64_kernel  gen_op_POWER2_lfq_le_kernel
        !          4436: #define gen_op_POWER2_lfq_le_64_hypv    gen_op_POWER2_lfq_le_hypv
        !          4437: #define gen_op_POWER2_stfq_64_raw       gen_op_POWER2_stfq_raw
        !          4438: #define gen_op_POWER2_stfq_64_user      gen_op_POWER2_stfq_user
        !          4439: #define gen_op_POWER2_stfq_64_kernel    gen_op_POWER2_stfq_kernel
        !          4440: #define gen_op_POWER2_stfq_64_hypv      gen_op_POWER2_stfq_hypv
        !          4441: #define gen_op_POWER2_stfq_le_64_raw    gen_op_POWER2_stfq_le_raw
        !          4442: #define gen_op_POWER2_stfq_le_64_user   gen_op_POWER2_stfq_le_user
        !          4443: #define gen_op_POWER2_stfq_le_64_kernel gen_op_POWER2_stfq_le_kernel
        !          4444: #define gen_op_POWER2_stfq_le_64_hypv   gen_op_POWER2_stfq_le_hypv
        !          4445: static GenOpFunc *gen_op_POWER2_lfq[NB_MEM_FUNCS] = {
        !          4446:     GEN_MEM_FUNCS(POWER2_lfq),
        !          4447: };
        !          4448: static GenOpFunc *gen_op_POWER2_stfq[NB_MEM_FUNCS] = {
        !          4449:     GEN_MEM_FUNCS(POWER2_stfq),
        !          4450: };
        !          4451: 
        !          4452: /* lfq */
        !          4453: GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
        !          4454: {
        !          4455:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          4456:     gen_update_nip(ctx, ctx->nip - 4);
        !          4457:     gen_addr_imm_index(ctx, 0);
        !          4458:     op_POWER2_lfq();
        !          4459:     gen_op_store_FT0_fpr(rD(ctx->opcode));
        !          4460:     gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
        !          4461: }
        !          4462: 
        !          4463: /* lfqu */
        !          4464: GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
        !          4465: {
        !          4466:     int ra = rA(ctx->opcode);
        !          4467: 
        !          4468:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          4469:     gen_update_nip(ctx, ctx->nip - 4);
        !          4470:     gen_addr_imm_index(ctx, 0);
        !          4471:     op_POWER2_lfq();
        !          4472:     gen_op_store_FT0_fpr(rD(ctx->opcode));
        !          4473:     gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
        !          4474:     if (ra != 0)
        !          4475:         gen_op_store_T0_gpr(ra);
        !          4476: }
        !          4477: 
        !          4478: /* lfqux */
        !          4479: GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
        !          4480: {
        !          4481:     int ra = rA(ctx->opcode);
        !          4482: 
        !          4483:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          4484:     gen_update_nip(ctx, ctx->nip - 4);
        !          4485:     gen_addr_reg_index(ctx);
        !          4486:     op_POWER2_lfq();
        !          4487:     gen_op_store_FT0_fpr(rD(ctx->opcode));
        !          4488:     gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
        !          4489:     if (ra != 0)
        !          4490:         gen_op_store_T0_gpr(ra);
        !          4491: }
        !          4492: 
        !          4493: /* lfqx */
        !          4494: GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
        !          4495: {
        !          4496:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          4497:     gen_update_nip(ctx, ctx->nip - 4);
        !          4498:     gen_addr_reg_index(ctx);
        !          4499:     op_POWER2_lfq();
        !          4500:     gen_op_store_FT0_fpr(rD(ctx->opcode));
        !          4501:     gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
        !          4502: }
        !          4503: 
        !          4504: /* stfq */
        !          4505: GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
        !          4506: {
        !          4507:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          4508:     gen_update_nip(ctx, ctx->nip - 4);
        !          4509:     gen_addr_imm_index(ctx, 0);
        !          4510:     gen_op_load_fpr_FT0(rS(ctx->opcode));
        !          4511:     gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
        !          4512:     op_POWER2_stfq();
        !          4513: }
        !          4514: 
        !          4515: /* stfqu */
        !          4516: GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
        !          4517: {
        !          4518:     int ra = rA(ctx->opcode);
        !          4519: 
        !          4520:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          4521:     gen_update_nip(ctx, ctx->nip - 4);
        !          4522:     gen_addr_imm_index(ctx, 0);
        !          4523:     gen_op_load_fpr_FT0(rS(ctx->opcode));
        !          4524:     gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
        !          4525:     op_POWER2_stfq();
        !          4526:     if (ra != 0)
        !          4527:         gen_op_store_T0_gpr(ra);
        !          4528: }
        !          4529: 
        !          4530: /* stfqux */
        !          4531: GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
        !          4532: {
        !          4533:     int ra = rA(ctx->opcode);
        !          4534: 
        !          4535:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          4536:     gen_update_nip(ctx, ctx->nip - 4);
        !          4537:     gen_addr_reg_index(ctx);
        !          4538:     gen_op_load_fpr_FT0(rS(ctx->opcode));
        !          4539:     gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
        !          4540:     op_POWER2_stfq();
        !          4541:     if (ra != 0)
        !          4542:         gen_op_store_T0_gpr(ra);
        !          4543: }
        !          4544: 
        !          4545: /* stfqx */
        !          4546: GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
        !          4547: {
        !          4548:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          4549:     gen_update_nip(ctx, ctx->nip - 4);
        !          4550:     gen_addr_reg_index(ctx);
        !          4551:     gen_op_load_fpr_FT0(rS(ctx->opcode));
        !          4552:     gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
        !          4553:     op_POWER2_stfq();
        !          4554: }
        !          4555: 
        !          4556: /* BookE specific instructions */
        !          4557: /* XXX: not implemented on 440 ? */
        !          4558: GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI)
        !          4559: {
        !          4560:     /* XXX: TODO */
        !          4561:     GEN_EXCP_INVAL(ctx);
        !          4562: }
        !          4563: 
        !          4564: /* XXX: not implemented on 440 ? */
        !          4565: GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA)
        !          4566: {
        !          4567: #if defined(CONFIG_USER_ONLY)
        !          4568:     GEN_EXCP_PRIVOPC(ctx);
        !          4569: #else
        !          4570:     if (unlikely(!ctx->supervisor)) {
        !          4571:         GEN_EXCP_PRIVOPC(ctx);
        !          4572:         return;
        !          4573:     }
        !          4574:     gen_addr_reg_index(ctx);
        !          4575:     /* Use the same micro-ops as for tlbie */
        !          4576: #if defined(TARGET_PPC64)
        !          4577:     if (ctx->sf_mode)
        !          4578:         gen_op_tlbie_64();
        !          4579:     else
        !          4580: #endif
        !          4581:         gen_op_tlbie();
        !          4582: #endif
        !          4583: }
        !          4584: 
        !          4585: /* All 405 MAC instructions are translated here */
        !          4586: static always_inline void gen_405_mulladd_insn (DisasContext *ctx,
        !          4587:                                                 int opc2, int opc3,
        !          4588:                                                 int ra, int rb, int rt, int Rc)
        !          4589: {
        !          4590:     gen_op_load_gpr_T0(ra);
        !          4591:     gen_op_load_gpr_T1(rb);
        !          4592:     switch (opc3 & 0x0D) {
        !          4593:     case 0x05:
        !          4594:         /* macchw    - macchw.    - macchwo   - macchwo.   */
        !          4595:         /* macchws   - macchws.   - macchwso  - macchwso.  */
        !          4596:         /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
        !          4597:         /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
        !          4598:         /* mulchw - mulchw. */
        !          4599:         gen_op_405_mulchw();
        !          4600:         break;
        !          4601:     case 0x04:
        !          4602:         /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
        !          4603:         /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
        !          4604:         /* mulchwu - mulchwu. */
        !          4605:         gen_op_405_mulchwu();
        !          4606:         break;
        !          4607:     case 0x01:
        !          4608:         /* machhw    - machhw.    - machhwo   - machhwo.   */
        !          4609:         /* machhws   - machhws.   - machhwso  - machhwso.  */
        !          4610:         /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
        !          4611:         /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
        !          4612:         /* mulhhw - mulhhw. */
        !          4613:         gen_op_405_mulhhw();
        !          4614:         break;
        !          4615:     case 0x00:
        !          4616:         /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
        !          4617:         /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
        !          4618:         /* mulhhwu - mulhhwu. */
        !          4619:         gen_op_405_mulhhwu();
        !          4620:         break;
        !          4621:     case 0x0D:
        !          4622:         /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
        !          4623:         /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
        !          4624:         /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
        !          4625:         /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
        !          4626:         /* mullhw - mullhw. */
        !          4627:         gen_op_405_mullhw();
        !          4628:         break;
        !          4629:     case 0x0C:
        !          4630:         /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
        !          4631:         /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
        !          4632:         /* mullhwu - mullhwu. */
        !          4633:         gen_op_405_mullhwu();
        !          4634:         break;
        !          4635:     }
        !          4636:     if (opc2 & 0x02) {
        !          4637:         /* nmultiply-and-accumulate (0x0E) */
        !          4638:         gen_op_neg();
        !          4639:     }
        !          4640:     if (opc2 & 0x04) {
        !          4641:         /* (n)multiply-and-accumulate (0x0C - 0x0E) */
        !          4642:         gen_op_load_gpr_T2(rt);
        !          4643:         gen_op_move_T1_T0();
        !          4644:         gen_op_405_add_T0_T2();
        !          4645:     }
        !          4646:     if (opc3 & 0x10) {
        !          4647:         /* Check overflow */
        !          4648:         if (opc3 & 0x01)
        !          4649:             gen_op_check_addo();
        !          4650:         else
        !          4651:             gen_op_405_check_ovu();
        !          4652:     }
        !          4653:     if (opc3 & 0x02) {
        !          4654:         /* Saturate */
        !          4655:         if (opc3 & 0x01)
        !          4656:             gen_op_405_check_sat();
        !          4657:         else
        !          4658:             gen_op_405_check_satu();
        !          4659:     }
        !          4660:     gen_op_store_T0_gpr(rt);
        !          4661:     if (unlikely(Rc) != 0) {
        !          4662:         /* Update Rc0 */
        !          4663:         gen_set_Rc0(ctx);
        !          4664:     }
        !          4665: }
        !          4666: 
        !          4667: #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
        !          4668: GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
        !          4669: {                                                                             \
        !          4670:     gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
        !          4671:                          rD(ctx->opcode), Rc(ctx->opcode));                   \
        !          4672: }
        !          4673: 
        !          4674: /* macchw    - macchw.    */
        !          4675: GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
        !          4676: /* macchwo   - macchwo.   */
        !          4677: GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
        !          4678: /* macchws   - macchws.   */
        !          4679: GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
        !          4680: /* macchwso  - macchwso.  */
        !          4681: GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
        !          4682: /* macchwsu  - macchwsu.  */
        !          4683: GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
        !          4684: /* macchwsuo - macchwsuo. */
        !          4685: GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
        !          4686: /* macchwu   - macchwu.   */
        !          4687: GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
        !          4688: /* macchwuo  - macchwuo.  */
        !          4689: GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
        !          4690: /* machhw    - machhw.    */
        !          4691: GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
        !          4692: /* machhwo   - machhwo.   */
        !          4693: GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
        !          4694: /* machhws   - machhws.   */
        !          4695: GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
        !          4696: /* machhwso  - machhwso.  */
        !          4697: GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
        !          4698: /* machhwsu  - machhwsu.  */
        !          4699: GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
        !          4700: /* machhwsuo - machhwsuo. */
        !          4701: GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
        !          4702: /* machhwu   - machhwu.   */
        !          4703: GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
        !          4704: /* machhwuo  - machhwuo.  */
        !          4705: GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
        !          4706: /* maclhw    - maclhw.    */
        !          4707: GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
        !          4708: /* maclhwo   - maclhwo.   */
        !          4709: GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
        !          4710: /* maclhws   - maclhws.   */
        !          4711: GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
        !          4712: /* maclhwso  - maclhwso.  */
        !          4713: GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
        !          4714: /* maclhwu   - maclhwu.   */
        !          4715: GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
        !          4716: /* maclhwuo  - maclhwuo.  */
        !          4717: GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
        !          4718: /* maclhwsu  - maclhwsu.  */
        !          4719: GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
        !          4720: /* maclhwsuo - maclhwsuo. */
        !          4721: GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
        !          4722: /* nmacchw   - nmacchw.   */
        !          4723: GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
        !          4724: /* nmacchwo  - nmacchwo.  */
        !          4725: GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
        !          4726: /* nmacchws  - nmacchws.  */
        !          4727: GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
        !          4728: /* nmacchwso - nmacchwso. */
        !          4729: GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
        !          4730: /* nmachhw   - nmachhw.   */
        !          4731: GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
        !          4732: /* nmachhwo  - nmachhwo.  */
        !          4733: GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
        !          4734: /* nmachhws  - nmachhws.  */
        !          4735: GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
        !          4736: /* nmachhwso - nmachhwso. */
        !          4737: GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
        !          4738: /* nmaclhw   - nmaclhw.   */
        !          4739: GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
        !          4740: /* nmaclhwo  - nmaclhwo.  */
        !          4741: GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
        !          4742: /* nmaclhws  - nmaclhws.  */
        !          4743: GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
        !          4744: /* nmaclhwso - nmaclhwso. */
        !          4745: GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
        !          4746: 
        !          4747: /* mulchw  - mulchw.  */
        !          4748: GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
        !          4749: /* mulchwu - mulchwu. */
        !          4750: GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
        !          4751: /* mulhhw  - mulhhw.  */
        !          4752: GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
        !          4753: /* mulhhwu - mulhhwu. */
        !          4754: GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
        !          4755: /* mullhw  - mullhw.  */
        !          4756: GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
        !          4757: /* mullhwu - mullhwu. */
        !          4758: GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
        !          4759: 
        !          4760: /* mfdcr */
        !          4761: GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR)
        !          4762: {
        !          4763: #if defined(CONFIG_USER_ONLY)
        !          4764:     GEN_EXCP_PRIVREG(ctx);
        !          4765: #else
        !          4766:     uint32_t dcrn = SPR(ctx->opcode);
        !          4767: 
        !          4768:     if (unlikely(!ctx->supervisor)) {
        !          4769:         GEN_EXCP_PRIVREG(ctx);
        !          4770:         return;
        !          4771:     }
        !          4772:     gen_op_set_T0(dcrn);
        !          4773:     gen_op_load_dcr();
        !          4774:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          4775: #endif
        !          4776: }
        !          4777: 
        !          4778: /* mtdcr */
        !          4779: GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR)
        !          4780: {
        !          4781: #if defined(CONFIG_USER_ONLY)
        !          4782:     GEN_EXCP_PRIVREG(ctx);
        !          4783: #else
        !          4784:     uint32_t dcrn = SPR(ctx->opcode);
        !          4785: 
        !          4786:     if (unlikely(!ctx->supervisor)) {
        !          4787:         GEN_EXCP_PRIVREG(ctx);
        !          4788:         return;
        !          4789:     }
        !          4790:     gen_op_set_T0(dcrn);
        !          4791:     gen_op_load_gpr_T1(rS(ctx->opcode));
        !          4792:     gen_op_store_dcr();
        !          4793: #endif
        !          4794: }
        !          4795: 
        !          4796: /* mfdcrx */
        !          4797: /* XXX: not implemented on 440 ? */
        !          4798: GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX)
        !          4799: {
        !          4800: #if defined(CONFIG_USER_ONLY)
        !          4801:     GEN_EXCP_PRIVREG(ctx);
        !          4802: #else
        !          4803:     if (unlikely(!ctx->supervisor)) {
        !          4804:         GEN_EXCP_PRIVREG(ctx);
        !          4805:         return;
        !          4806:     }
        !          4807:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          4808:     gen_op_load_dcr();
        !          4809:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          4810:     /* Note: Rc update flag set leads to undefined state of Rc0 */
        !          4811: #endif
        !          4812: }
        !          4813: 
        !          4814: /* mtdcrx */
        !          4815: /* XXX: not implemented on 440 ? */
        !          4816: GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX)
        !          4817: {
        !          4818: #if defined(CONFIG_USER_ONLY)
        !          4819:     GEN_EXCP_PRIVREG(ctx);
        !          4820: #else
        !          4821:     if (unlikely(!ctx->supervisor)) {
        !          4822:         GEN_EXCP_PRIVREG(ctx);
        !          4823:         return;
        !          4824:     }
        !          4825:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          4826:     gen_op_load_gpr_T1(rS(ctx->opcode));
        !          4827:     gen_op_store_dcr();
        !          4828:     /* Note: Rc update flag set leads to undefined state of Rc0 */
        !          4829: #endif
        !          4830: }
        !          4831: 
        !          4832: /* mfdcrux (PPC 460) : user-mode access to DCR */
        !          4833: GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
        !          4834: {
        !          4835:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          4836:     gen_op_load_dcr();
        !          4837:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          4838:     /* Note: Rc update flag set leads to undefined state of Rc0 */
        !          4839: }
        !          4840: 
        !          4841: /* mtdcrux (PPC 460) : user-mode access to DCR */
        !          4842: GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
        !          4843: {
        !          4844:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          4845:     gen_op_load_gpr_T1(rS(ctx->opcode));
        !          4846:     gen_op_store_dcr();
        !          4847:     /* Note: Rc update flag set leads to undefined state of Rc0 */
        !          4848: }
        !          4849: 
        !          4850: /* dccci */
        !          4851: GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
        !          4852: {
        !          4853: #if defined(CONFIG_USER_ONLY)
        !          4854:     GEN_EXCP_PRIVOPC(ctx);
        !          4855: #else
        !          4856:     if (unlikely(!ctx->supervisor)) {
        !          4857:         GEN_EXCP_PRIVOPC(ctx);
        !          4858:         return;
        !          4859:     }
        !          4860:     /* interpreted as no-op */
        !          4861: #endif
        !          4862: }
        !          4863: 
        !          4864: /* dcread */
        !          4865: GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
        !          4866: {
        !          4867: #if defined(CONFIG_USER_ONLY)
        !          4868:     GEN_EXCP_PRIVOPC(ctx);
        !          4869: #else
        !          4870:     if (unlikely(!ctx->supervisor)) {
        !          4871:         GEN_EXCP_PRIVOPC(ctx);
        !          4872:         return;
        !          4873:     }
        !          4874:     gen_addr_reg_index(ctx);
        !          4875:     op_ldst(lwz);
        !          4876:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          4877: #endif
        !          4878: }
        !          4879: 
        !          4880: /* icbt */
        !          4881: GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
        !          4882: {
        !          4883:     /* interpreted as no-op */
        !          4884:     /* XXX: specification say this is treated as a load by the MMU
        !          4885:      *      but does not generate any exception
        !          4886:      */
        !          4887: }
        !          4888: 
        !          4889: /* iccci */
        !          4890: GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
        !          4891: {
        !          4892: #if defined(CONFIG_USER_ONLY)
        !          4893:     GEN_EXCP_PRIVOPC(ctx);
        !          4894: #else
        !          4895:     if (unlikely(!ctx->supervisor)) {
        !          4896:         GEN_EXCP_PRIVOPC(ctx);
        !          4897:         return;
        !          4898:     }
        !          4899:     /* interpreted as no-op */
        !          4900: #endif
        !          4901: }
        !          4902: 
        !          4903: /* icread */
        !          4904: GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
        !          4905: {
        !          4906: #if defined(CONFIG_USER_ONLY)
        !          4907:     GEN_EXCP_PRIVOPC(ctx);
        !          4908: #else
        !          4909:     if (unlikely(!ctx->supervisor)) {
        !          4910:         GEN_EXCP_PRIVOPC(ctx);
        !          4911:         return;
        !          4912:     }
        !          4913:     /* interpreted as no-op */
        !          4914: #endif
        !          4915: }
        !          4916: 
        !          4917: /* rfci (supervisor only) */
        !          4918: GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
        !          4919: {
        !          4920: #if defined(CONFIG_USER_ONLY)
        !          4921:     GEN_EXCP_PRIVOPC(ctx);
        !          4922: #else
        !          4923:     if (unlikely(!ctx->supervisor)) {
        !          4924:         GEN_EXCP_PRIVOPC(ctx);
        !          4925:         return;
        !          4926:     }
        !          4927:     /* Restore CPU state */
        !          4928:     gen_op_40x_rfci();
        !          4929:     GEN_SYNC(ctx);
        !          4930: #endif
        !          4931: }
        !          4932: 
        !          4933: GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
        !          4934: {
        !          4935: #if defined(CONFIG_USER_ONLY)
        !          4936:     GEN_EXCP_PRIVOPC(ctx);
        !          4937: #else
        !          4938:     if (unlikely(!ctx->supervisor)) {
        !          4939:         GEN_EXCP_PRIVOPC(ctx);
        !          4940:         return;
        !          4941:     }
        !          4942:     /* Restore CPU state */
        !          4943:     gen_op_rfci();
        !          4944:     GEN_SYNC(ctx);
        !          4945: #endif
        !          4946: }
        !          4947: 
        !          4948: /* BookE specific */
        !          4949: /* XXX: not implemented on 440 ? */
        !          4950: GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI)
        !          4951: {
        !          4952: #if defined(CONFIG_USER_ONLY)
        !          4953:     GEN_EXCP_PRIVOPC(ctx);
        !          4954: #else
        !          4955:     if (unlikely(!ctx->supervisor)) {
        !          4956:         GEN_EXCP_PRIVOPC(ctx);
        !          4957:         return;
        !          4958:     }
        !          4959:     /* Restore CPU state */
        !          4960:     gen_op_rfdi();
        !          4961:     GEN_SYNC(ctx);
        !          4962: #endif
        !          4963: }
        !          4964: 
        !          4965: /* XXX: not implemented on 440 ? */
        !          4966: GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
        !          4967: {
        !          4968: #if defined(CONFIG_USER_ONLY)
        !          4969:     GEN_EXCP_PRIVOPC(ctx);
        !          4970: #else
        !          4971:     if (unlikely(!ctx->supervisor)) {
        !          4972:         GEN_EXCP_PRIVOPC(ctx);
        !          4973:         return;
        !          4974:     }
        !          4975:     /* Restore CPU state */
        !          4976:     gen_op_rfmci();
        !          4977:     GEN_SYNC(ctx);
        !          4978: #endif
        !          4979: }
        !          4980: 
        !          4981: /* TLB management - PowerPC 405 implementation */
        !          4982: /* tlbre */
        !          4983: GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
        !          4984: {
        !          4985: #if defined(CONFIG_USER_ONLY)
        !          4986:     GEN_EXCP_PRIVOPC(ctx);
        !          4987: #else
        !          4988:     if (unlikely(!ctx->supervisor)) {
        !          4989:         GEN_EXCP_PRIVOPC(ctx);
        !          4990:         return;
        !          4991:     }
        !          4992:     switch (rB(ctx->opcode)) {
        !          4993:     case 0:
        !          4994:         gen_op_load_gpr_T0(rA(ctx->opcode));
        !          4995:         gen_op_4xx_tlbre_hi();
        !          4996:         gen_op_store_T0_gpr(rD(ctx->opcode));
        !          4997:         break;
        !          4998:     case 1:
        !          4999:         gen_op_load_gpr_T0(rA(ctx->opcode));
        !          5000:         gen_op_4xx_tlbre_lo();
        !          5001:         gen_op_store_T0_gpr(rD(ctx->opcode));
        !          5002:         break;
        !          5003:     default:
        !          5004:         GEN_EXCP_INVAL(ctx);
        !          5005:         break;
        !          5006:     }
        !          5007: #endif
        !          5008: }
        !          5009: 
        !          5010: /* tlbsx - tlbsx. */
        !          5011: GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
        !          5012: {
        !          5013: #if defined(CONFIG_USER_ONLY)
        !          5014:     GEN_EXCP_PRIVOPC(ctx);
        !          5015: #else
        !          5016:     if (unlikely(!ctx->supervisor)) {
        !          5017:         GEN_EXCP_PRIVOPC(ctx);
        !          5018:         return;
        !          5019:     }
        !          5020:     gen_addr_reg_index(ctx);
        !          5021:     gen_op_4xx_tlbsx();
        !          5022:     if (Rc(ctx->opcode))
        !          5023:         gen_op_4xx_tlbsx_check();
        !          5024:     gen_op_store_T0_gpr(rD(ctx->opcode));
        !          5025: #endif
        !          5026: }
        !          5027: 
        !          5028: /* tlbwe */
        !          5029: GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
        !          5030: {
        !          5031: #if defined(CONFIG_USER_ONLY)
        !          5032:     GEN_EXCP_PRIVOPC(ctx);
        !          5033: #else
        !          5034:     if (unlikely(!ctx->supervisor)) {
        !          5035:         GEN_EXCP_PRIVOPC(ctx);
        !          5036:         return;
        !          5037:     }
        !          5038:     switch (rB(ctx->opcode)) {
        !          5039:     case 0:
        !          5040:         gen_op_load_gpr_T0(rA(ctx->opcode));
        !          5041:         gen_op_load_gpr_T1(rS(ctx->opcode));
        !          5042:         gen_op_4xx_tlbwe_hi();
        !          5043:         break;
        !          5044:     case 1:
        !          5045:         gen_op_load_gpr_T0(rA(ctx->opcode));
        !          5046:         gen_op_load_gpr_T1(rS(ctx->opcode));
        !          5047:         gen_op_4xx_tlbwe_lo();
        !          5048:         break;
        !          5049:     default:
        !          5050:         GEN_EXCP_INVAL(ctx);
        !          5051:         break;
        !          5052:     }
        !          5053: #endif
        !          5054: }
        !          5055: 
        !          5056: /* TLB management - PowerPC 440 implementation */
        !          5057: /* tlbre */
        !          5058: GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
        !          5059: {
        !          5060: #if defined(CONFIG_USER_ONLY)
        !          5061:     GEN_EXCP_PRIVOPC(ctx);
        !          5062: #else
        !          5063:     if (unlikely(!ctx->supervisor)) {
        !          5064:         GEN_EXCP_PRIVOPC(ctx);
        !          5065:         return;
        !          5066:     }
        !          5067:     switch (rB(ctx->opcode)) {
        !          5068:     case 0:
        !          5069:     case 1:
        !          5070:     case 2:
        !          5071:         gen_op_load_gpr_T0(rA(ctx->opcode));
        !          5072:         gen_op_440_tlbre(rB(ctx->opcode));
        !          5073:         gen_op_store_T0_gpr(rD(ctx->opcode));
        !          5074:         break;
        !          5075:     default:
        !          5076:         GEN_EXCP_INVAL(ctx);
        !          5077:         break;
        !          5078:     }
        !          5079: #endif
        !          5080: }
        !          5081: 
        !          5082: /* tlbsx - tlbsx. */
        !          5083: GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
1.1       root     5084: {
                   5085: #if defined(CONFIG_USER_ONLY)
1.1.1.5 ! root     5086:     GEN_EXCP_PRIVOPC(ctx);
1.1       root     5087: #else
1.1.1.5 ! root     5088:     if (unlikely(!ctx->supervisor)) {
        !          5089:         GEN_EXCP_PRIVOPC(ctx);
1.1       root     5090:         return;
                   5091:     }
1.1.1.5 ! root     5092:     gen_addr_reg_index(ctx);
        !          5093:     gen_op_440_tlbsx();
        !          5094:     if (Rc(ctx->opcode))
        !          5095:         gen_op_4xx_tlbsx_check();
        !          5096:     gen_op_store_T0_gpr(rD(ctx->opcode));
1.1       root     5097: #endif
                   5098: }
                   5099: 
1.1.1.5 ! root     5100: /* tlbwe */
        !          5101: GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
1.1       root     5102: {
                   5103: #if defined(CONFIG_USER_ONLY)
1.1.1.5 ! root     5104:     GEN_EXCP_PRIVOPC(ctx);
1.1       root     5105: #else
1.1.1.5 ! root     5106:     if (unlikely(!ctx->supervisor)) {
        !          5107:         GEN_EXCP_PRIVOPC(ctx);
1.1       root     5108:         return;
                   5109:     }
1.1.1.5 ! root     5110:     switch (rB(ctx->opcode)) {
        !          5111:     case 0:
        !          5112:     case 1:
        !          5113:     case 2:
        !          5114:         gen_op_load_gpr_T0(rA(ctx->opcode));
        !          5115:         gen_op_load_gpr_T1(rS(ctx->opcode));
        !          5116:         gen_op_440_tlbwe(rB(ctx->opcode));
        !          5117:         break;
        !          5118:     default:
        !          5119:         GEN_EXCP_INVAL(ctx);
        !          5120:         break;
        !          5121:     }
        !          5122: #endif
        !          5123: }
        !          5124: 
        !          5125: /* wrtee */
        !          5126: GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE)
        !          5127: {
        !          5128: #if defined(CONFIG_USER_ONLY)
        !          5129:     GEN_EXCP_PRIVOPC(ctx);
        !          5130: #else
        !          5131:     if (unlikely(!ctx->supervisor)) {
        !          5132:         GEN_EXCP_PRIVOPC(ctx);
        !          5133:         return;
        !          5134:     }
        !          5135:     gen_op_load_gpr_T0(rD(ctx->opcode));
        !          5136:     gen_op_wrte();
        !          5137:     /* Stop translation to have a chance to raise an exception
        !          5138:      * if we just set msr_ee to 1
1.1       root     5139:      */
1.1.1.5 ! root     5140:     GEN_STOP(ctx);
1.1       root     5141: #endif
                   5142: }
                   5143: 
1.1.1.5 ! root     5144: /* wrteei */
        !          5145: GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_WRTEE)
        !          5146: {
1.1       root     5147: #if defined(CONFIG_USER_ONLY)
1.1.1.5 ! root     5148:     GEN_EXCP_PRIVOPC(ctx);
        !          5149: #else
        !          5150:     if (unlikely(!ctx->supervisor)) {
        !          5151:         GEN_EXCP_PRIVOPC(ctx);
        !          5152:         return;
        !          5153:     }
        !          5154:     gen_op_set_T0(ctx->opcode & 0x00010000);
        !          5155:     gen_op_wrte();
        !          5156:     /* Stop translation to have a chance to raise an exception
        !          5157:      * if we just set msr_ee to 1
        !          5158:      */
        !          5159:     GEN_STOP(ctx);
        !          5160: #endif
        !          5161: }
        !          5162: 
        !          5163: /* PowerPC 440 specific instructions */
        !          5164: /* dlmzb */
        !          5165: GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
        !          5166: {
        !          5167:     gen_op_load_gpr_T0(rS(ctx->opcode));
        !          5168:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          5169:     gen_op_440_dlmzb();
        !          5170:     gen_op_store_T0_gpr(rA(ctx->opcode));
        !          5171:     gen_op_store_xer_bc();
        !          5172:     if (Rc(ctx->opcode)) {
        !          5173:         gen_op_440_dlmzb_update_Rc();
        !          5174:         gen_op_store_T0_crf(0);
        !          5175:     }
        !          5176: }
        !          5177: 
        !          5178: /* mbar replaces eieio on 440 */
        !          5179: GEN_HANDLER(mbar, 0x1F, 0x16, 0x13, 0x001FF801, PPC_BOOKE)
        !          5180: {
        !          5181:     /* interpreted as no-op */
        !          5182: }
        !          5183: 
        !          5184: /* msync replaces sync on 440 */
        !          5185: GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE)
        !          5186: {
        !          5187:     /* interpreted as no-op */
        !          5188: }
        !          5189: 
        !          5190: /* icbt */
        !          5191: GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
        !          5192: {
        !          5193:     /* interpreted as no-op */
        !          5194:     /* XXX: specification say this is treated as a load by the MMU
        !          5195:      *      but does not generate any exception
        !          5196:      */
        !          5197: }
        !          5198: 
        !          5199: /***                      Altivec vector extension                         ***/
        !          5200: /* Altivec registers moves */
        !          5201: GEN32(gen_op_load_avr_A0, gen_op_load_avr_A0_avr);
        !          5202: GEN32(gen_op_load_avr_A1, gen_op_load_avr_A1_avr);
        !          5203: GEN32(gen_op_load_avr_A2, gen_op_load_avr_A2_avr);
        !          5204: 
        !          5205: GEN32(gen_op_store_A0_avr, gen_op_store_A0_avr_avr);
        !          5206: GEN32(gen_op_store_A1_avr, gen_op_store_A1_avr_avr);
        !          5207: #if 0 // unused
        !          5208: GEN32(gen_op_store_A2_avr, gen_op_store_A2_avr_avr);
        !          5209: #endif
        !          5210: 
        !          5211: #define op_vr_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
        !          5212: #define OP_VR_LD_TABLE(name)                                                  \
        !          5213: static GenOpFunc *gen_op_vr_l##name[NB_MEM_FUNCS] = {                         \
        !          5214:     GEN_MEM_FUNCS(vr_l##name),                                                \
1.1       root     5215: };
1.1.1.5 ! root     5216: #define OP_VR_ST_TABLE(name)                                                  \
        !          5217: static GenOpFunc *gen_op_vr_st##name[NB_MEM_FUNCS] = {                        \
        !          5218:     GEN_MEM_FUNCS(vr_st##name),                                               \
        !          5219: };
        !          5220: 
        !          5221: #define GEN_VR_LDX(name, opc2, opc3)                                          \
        !          5222: GEN_HANDLER(l##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)               \
        !          5223: {                                                                             \
        !          5224:     if (unlikely(!ctx->altivec_enabled)) {                                    \
        !          5225:         GEN_EXCP_NO_VR(ctx);                                                  \
        !          5226:         return;                                                               \
        !          5227:     }                                                                         \
        !          5228:     gen_addr_reg_index(ctx);                                                  \
        !          5229:     op_vr_ldst(vr_l##name);                                                   \
        !          5230:     gen_op_store_A0_avr(rD(ctx->opcode));                                     \
        !          5231: }
        !          5232: 
        !          5233: #define GEN_VR_STX(name, opc2, opc3)                                          \
        !          5234: GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)              \
        !          5235: {                                                                             \
        !          5236:     if (unlikely(!ctx->altivec_enabled)) {                                    \
        !          5237:         GEN_EXCP_NO_VR(ctx);                                                  \
        !          5238:         return;                                                               \
        !          5239:     }                                                                         \
        !          5240:     gen_addr_reg_index(ctx);                                                  \
        !          5241:     gen_op_load_avr_A0(rS(ctx->opcode));                                      \
        !          5242:     op_vr_ldst(vr_st##name);                                                  \
        !          5243: }
        !          5244: 
        !          5245: OP_VR_LD_TABLE(vx);
        !          5246: GEN_VR_LDX(vx, 0x07, 0x03);
        !          5247: /* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
        !          5248: #define gen_op_vr_lvxl gen_op_vr_lvx
        !          5249: GEN_VR_LDX(vxl, 0x07, 0x0B);
        !          5250: 
        !          5251: OP_VR_ST_TABLE(vx);
        !          5252: GEN_VR_STX(vx, 0x07, 0x07);
        !          5253: /* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
        !          5254: #define gen_op_vr_stvxl gen_op_vr_stvx
        !          5255: GEN_VR_STX(vxl, 0x07, 0x0F);
        !          5256: 
        !          5257: /***                           SPE extension                               ***/
        !          5258: /* Register moves */
        !          5259: #if !defined(TARGET_PPC64)
        !          5260: 
        !          5261: GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr);
        !          5262: GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr);
        !          5263: #if 0 // unused
        !          5264: GEN32(gen_op_load_gpr64_T2, gen_op_load_gpr64_T2_gpr);
1.1       root     5265: #endif
                   5266: 
1.1.1.5 ! root     5267: GEN32(gen_op_store_T0_gpr64, gen_op_store_T0_gpr64_gpr);
        !          5268: GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr);
        !          5269: #if 0 // unused
        !          5270: GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr);
        !          5271: #endif
        !          5272: 
        !          5273: #else /* !defined(TARGET_PPC64) */
        !          5274: 
        !          5275: /* No specific load/store functions: GPRs are already 64 bits */
        !          5276: #define gen_op_load_gpr64_T0 gen_op_load_gpr_T0
        !          5277: #define gen_op_load_gpr64_T1 gen_op_load_gpr_T1
        !          5278: #if 0 // unused
        !          5279: #define gen_op_load_gpr64_T2 gen_op_load_gpr_T2
        !          5280: #endif
        !          5281: 
        !          5282: #define gen_op_store_T0_gpr64 gen_op_store_T0_gpr
        !          5283: #define gen_op_store_T1_gpr64 gen_op_store_T1_gpr
        !          5284: #if 0 // unused
        !          5285: #define gen_op_store_T2_gpr64 gen_op_store_T2_gpr
        !          5286: #endif
        !          5287: 
        !          5288: #endif /* !defined(TARGET_PPC64) */
        !          5289: 
        !          5290: #define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
        !          5291: GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
        !          5292: {                                                                             \
        !          5293:     if (Rc(ctx->opcode))                                                      \
        !          5294:         gen_##name1(ctx);                                                     \
        !          5295:     else                                                                      \
        !          5296:         gen_##name0(ctx);                                                     \
        !          5297: }
        !          5298: 
        !          5299: /* Handler for undefined SPE opcodes */
        !          5300: static always_inline void gen_speundef (DisasContext *ctx)
1.1       root     5301: {
1.1.1.5 ! root     5302:     GEN_EXCP_INVAL(ctx);
        !          5303: }
        !          5304: 
        !          5305: /* SPE load and stores */
        !          5306: static always_inline void gen_addr_spe_imm_index (DisasContext *ctx, int sh)
        !          5307: {
        !          5308:     target_long simm = rB(ctx->opcode);
        !          5309: 
1.1       root     5310:     if (rA(ctx->opcode) == 0) {
1.1.1.5 ! root     5311:         gen_set_T0(simm << sh);
1.1       root     5312:     } else {
                   5313:         gen_op_load_gpr_T0(rA(ctx->opcode));
1.1.1.5 ! root     5314:         if (likely(simm != 0))
        !          5315:             gen_op_addi(simm << sh);
1.1       root     5316:     }
1.1.1.5 ! root     5317: }
        !          5318: 
        !          5319: #define op_spe_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
        !          5320: #define OP_SPE_LD_TABLE(name)                                                 \
        !          5321: static GenOpFunc *gen_op_spe_l##name[NB_MEM_FUNCS] = {                        \
        !          5322:     GEN_MEM_FUNCS(spe_l##name),                                               \
        !          5323: };
        !          5324: #define OP_SPE_ST_TABLE(name)                                                 \
        !          5325: static GenOpFunc *gen_op_spe_st##name[NB_MEM_FUNCS] = {                       \
        !          5326:     GEN_MEM_FUNCS(spe_st##name),                                              \
        !          5327: };
        !          5328: 
        !          5329: #define GEN_SPE_LD(name, sh)                                                  \
        !          5330: static always_inline void gen_evl##name (DisasContext *ctx)                   \
        !          5331: {                                                                             \
        !          5332:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          5333:         GEN_EXCP_NO_AP(ctx);                                                  \
        !          5334:         return;                                                               \
        !          5335:     }                                                                         \
        !          5336:     gen_addr_spe_imm_index(ctx, sh);                                          \
        !          5337:     op_spe_ldst(spe_l##name);                                                 \
        !          5338:     gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
        !          5339: }
        !          5340: 
        !          5341: #define GEN_SPE_LDX(name)                                                     \
        !          5342: static always_inline void gen_evl##name##x (DisasContext *ctx)                \
        !          5343: {                                                                             \
        !          5344:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          5345:         GEN_EXCP_NO_AP(ctx);                                                  \
        !          5346:         return;                                                               \
        !          5347:     }                                                                         \
        !          5348:     gen_addr_reg_index(ctx);                                                  \
        !          5349:     op_spe_ldst(spe_l##name);                                                 \
        !          5350:     gen_op_store_T1_gpr64(rD(ctx->opcode));                                   \
        !          5351: }
        !          5352: 
        !          5353: #define GEN_SPEOP_LD(name, sh)                                                \
        !          5354: OP_SPE_LD_TABLE(name);                                                        \
        !          5355: GEN_SPE_LD(name, sh);                                                         \
        !          5356: GEN_SPE_LDX(name)
        !          5357: 
        !          5358: #define GEN_SPE_ST(name, sh)                                                  \
        !          5359: static always_inline void gen_evst##name (DisasContext *ctx)                  \
        !          5360: {                                                                             \
        !          5361:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          5362:         GEN_EXCP_NO_AP(ctx);                                                  \
        !          5363:         return;                                                               \
        !          5364:     }                                                                         \
        !          5365:     gen_addr_spe_imm_index(ctx, sh);                                          \
        !          5366:     gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
        !          5367:     op_spe_ldst(spe_st##name);                                                \
        !          5368: }
        !          5369: 
        !          5370: #define GEN_SPE_STX(name)                                                     \
        !          5371: static always_inline void gen_evst##name##x (DisasContext *ctx)               \
        !          5372: {                                                                             \
        !          5373:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          5374:         GEN_EXCP_NO_AP(ctx);                                                  \
        !          5375:         return;                                                               \
        !          5376:     }                                                                         \
        !          5377:     gen_addr_reg_index(ctx);                                                  \
        !          5378:     gen_op_load_gpr64_T1(rS(ctx->opcode));                                    \
        !          5379:     op_spe_ldst(spe_st##name);                                                \
        !          5380: }
        !          5381: 
        !          5382: #define GEN_SPEOP_ST(name, sh)                                                \
        !          5383: OP_SPE_ST_TABLE(name);                                                        \
        !          5384: GEN_SPE_ST(name, sh);                                                         \
        !          5385: GEN_SPE_STX(name)
        !          5386: 
        !          5387: #define GEN_SPEOP_LDST(name, sh)                                              \
        !          5388: GEN_SPEOP_LD(name, sh);                                                       \
        !          5389: GEN_SPEOP_ST(name, sh)
        !          5390: 
        !          5391: /* SPE arithmetic and logic */
        !          5392: #define GEN_SPEOP_ARITH2(name)                                                \
        !          5393: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          5394: {                                                                             \
        !          5395:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          5396:         GEN_EXCP_NO_AP(ctx);                                                  \
        !          5397:         return;                                                               \
        !          5398:     }                                                                         \
        !          5399:     gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
        !          5400:     gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
        !          5401:     gen_op_##name();                                                          \
        !          5402:     gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
        !          5403: }
        !          5404: 
        !          5405: #define GEN_SPEOP_ARITH1(name)                                                \
        !          5406: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          5407: {                                                                             \
        !          5408:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          5409:         GEN_EXCP_NO_AP(ctx);                                                  \
        !          5410:         return;                                                               \
        !          5411:     }                                                                         \
        !          5412:     gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
        !          5413:     gen_op_##name();                                                          \
        !          5414:     gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
        !          5415: }
        !          5416: 
        !          5417: #define GEN_SPEOP_COMP(name)                                                  \
        !          5418: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          5419: {                                                                             \
        !          5420:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          5421:         GEN_EXCP_NO_AP(ctx);                                                  \
        !          5422:         return;                                                               \
        !          5423:     }                                                                         \
        !          5424:     gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
        !          5425:     gen_op_load_gpr64_T1(rB(ctx->opcode));                                    \
        !          5426:     gen_op_##name();                                                          \
        !          5427:     gen_op_store_T0_crf(crfD(ctx->opcode));                                   \
        !          5428: }
        !          5429: 
        !          5430: /* Logical */
        !          5431: GEN_SPEOP_ARITH2(evand);
        !          5432: GEN_SPEOP_ARITH2(evandc);
        !          5433: GEN_SPEOP_ARITH2(evxor);
        !          5434: GEN_SPEOP_ARITH2(evor);
        !          5435: GEN_SPEOP_ARITH2(evnor);
        !          5436: GEN_SPEOP_ARITH2(eveqv);
        !          5437: GEN_SPEOP_ARITH2(evorc);
        !          5438: GEN_SPEOP_ARITH2(evnand);
        !          5439: GEN_SPEOP_ARITH2(evsrwu);
        !          5440: GEN_SPEOP_ARITH2(evsrws);
        !          5441: GEN_SPEOP_ARITH2(evslw);
        !          5442: GEN_SPEOP_ARITH2(evrlw);
        !          5443: GEN_SPEOP_ARITH2(evmergehi);
        !          5444: GEN_SPEOP_ARITH2(evmergelo);
        !          5445: GEN_SPEOP_ARITH2(evmergehilo);
        !          5446: GEN_SPEOP_ARITH2(evmergelohi);
        !          5447: 
        !          5448: /* Arithmetic */
        !          5449: GEN_SPEOP_ARITH2(evaddw);
        !          5450: GEN_SPEOP_ARITH2(evsubfw);
        !          5451: GEN_SPEOP_ARITH1(evabs);
        !          5452: GEN_SPEOP_ARITH1(evneg);
        !          5453: GEN_SPEOP_ARITH1(evextsb);
        !          5454: GEN_SPEOP_ARITH1(evextsh);
        !          5455: GEN_SPEOP_ARITH1(evrndw);
        !          5456: GEN_SPEOP_ARITH1(evcntlzw);
        !          5457: GEN_SPEOP_ARITH1(evcntlsw);
        !          5458: static always_inline void gen_brinc (DisasContext *ctx)
        !          5459: {
        !          5460:     /* Note: brinc is usable even if SPE is disabled */
        !          5461:     gen_op_load_gpr_T0(rA(ctx->opcode));
        !          5462:     gen_op_load_gpr_T1(rB(ctx->opcode));
        !          5463:     gen_op_brinc();
1.1       root     5464:     gen_op_store_T0_gpr(rD(ctx->opcode));
                   5465: }
                   5466: 
1.1.1.5 ! root     5467: #define GEN_SPEOP_ARITH_IMM2(name)                                            \
        !          5468: static always_inline void gen_##name##i (DisasContext *ctx)                   \
        !          5469: {                                                                             \
        !          5470:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          5471:         GEN_EXCP_NO_AP(ctx);                                                  \
        !          5472:         return;                                                               \
        !          5473:     }                                                                         \
        !          5474:     gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
        !          5475:     gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
        !          5476:     gen_op_##name();                                                          \
        !          5477:     gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
        !          5478: }
        !          5479: 
        !          5480: #define GEN_SPEOP_LOGIC_IMM2(name)                                            \
        !          5481: static always_inline void gen_##name##i (DisasContext *ctx)                   \
        !          5482: {                                                                             \
        !          5483:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          5484:         GEN_EXCP_NO_AP(ctx);                                                  \
        !          5485:         return;                                                               \
        !          5486:     }                                                                         \
        !          5487:     gen_op_load_gpr64_T0(rA(ctx->opcode));                                    \
        !          5488:     gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
        !          5489:     gen_op_##name();                                                          \
        !          5490:     gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
        !          5491: }
        !          5492: 
        !          5493: GEN_SPEOP_ARITH_IMM2(evaddw);
        !          5494: #define gen_evaddiw gen_evaddwi
        !          5495: GEN_SPEOP_ARITH_IMM2(evsubfw);
        !          5496: #define gen_evsubifw gen_evsubfwi
        !          5497: GEN_SPEOP_LOGIC_IMM2(evslw);
        !          5498: GEN_SPEOP_LOGIC_IMM2(evsrwu);
        !          5499: #define gen_evsrwis gen_evsrwsi
        !          5500: GEN_SPEOP_LOGIC_IMM2(evsrws);
        !          5501: #define gen_evsrwiu gen_evsrwui
        !          5502: GEN_SPEOP_LOGIC_IMM2(evrlw);
        !          5503: 
        !          5504: static always_inline void gen_evsplati (DisasContext *ctx)
        !          5505: {
        !          5506:     int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
        !          5507: 
        !          5508:     gen_op_splatwi_T0_64(imm);
        !          5509:     gen_op_store_T0_gpr64(rD(ctx->opcode));
        !          5510: }
        !          5511: 
        !          5512: static always_inline void gen_evsplatfi (DisasContext *ctx)
        !          5513: {
        !          5514:     uint32_t imm = rA(ctx->opcode) << 27;
        !          5515: 
        !          5516:     gen_op_splatwi_T0_64(imm);
        !          5517:     gen_op_store_T0_gpr64(rD(ctx->opcode));
        !          5518: }
        !          5519: 
        !          5520: /* Comparison */
        !          5521: GEN_SPEOP_COMP(evcmpgtu);
        !          5522: GEN_SPEOP_COMP(evcmpgts);
        !          5523: GEN_SPEOP_COMP(evcmpltu);
        !          5524: GEN_SPEOP_COMP(evcmplts);
        !          5525: GEN_SPEOP_COMP(evcmpeq);
        !          5526: 
        !          5527: GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
        !          5528: GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
        !          5529: GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
        !          5530: GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
        !          5531: GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
        !          5532: GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
        !          5533: GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
        !          5534: GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
        !          5535: GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
        !          5536: GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
        !          5537: GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
        !          5538: GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
        !          5539: GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
        !          5540: GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
        !          5541: GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
        !          5542: GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
        !          5543: GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
        !          5544: GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
        !          5545: GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
        !          5546: GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
        !          5547: GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
        !          5548: GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
        !          5549: GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
        !          5550: GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
        !          5551: GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
        !          5552: 
        !          5553: static always_inline void gen_evsel (DisasContext *ctx)
1.1       root     5554: {
1.1.1.5 ! root     5555:     if (unlikely(!ctx->spe_enabled)) {
        !          5556:         GEN_EXCP_NO_AP(ctx);
        !          5557:         return;
1.1       root     5558:     }
1.1.1.5 ! root     5559:     gen_op_load_crf_T0(ctx->opcode & 0x7);
        !          5560:     gen_op_load_gpr64_T0(rA(ctx->opcode));
        !          5561:     gen_op_load_gpr64_T1(rB(ctx->opcode));
        !          5562:     gen_op_evsel();
        !          5563:     gen_op_store_T0_gpr64(rD(ctx->opcode));
        !          5564: }
        !          5565: 
        !          5566: GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
        !          5567: {
        !          5568:     gen_evsel(ctx);
        !          5569: }
        !          5570: GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
        !          5571: {
        !          5572:     gen_evsel(ctx);
        !          5573: }
        !          5574: GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
        !          5575: {
        !          5576:     gen_evsel(ctx);
        !          5577: }
        !          5578: GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
        !          5579: {
        !          5580:     gen_evsel(ctx);
        !          5581: }
        !          5582: 
        !          5583: /* Load and stores */
        !          5584: #if defined(TARGET_PPC64)
        !          5585: /* In that case, we already have 64 bits load & stores
        !          5586:  * so, spe_ldd is equivalent to ld and spe_std is equivalent to std
        !          5587:  */
        !          5588: #define gen_op_spe_ldd_raw           gen_op_ld_raw
        !          5589: #define gen_op_spe_ldd_user          gen_op_ld_user
        !          5590: #define gen_op_spe_ldd_kernel        gen_op_ld_kernel
        !          5591: #define gen_op_spe_ldd_hypv          gen_op_ld_hypv
        !          5592: #define gen_op_spe_ldd_64_raw        gen_op_ld_64_raw
        !          5593: #define gen_op_spe_ldd_64_user       gen_op_ld_64_user
        !          5594: #define gen_op_spe_ldd_64_kernel     gen_op_ld_64_kernel
        !          5595: #define gen_op_spe_ldd_64_hypv       gen_op_ld_64_hypv
        !          5596: #define gen_op_spe_ldd_le_raw        gen_op_ld_le_raw
        !          5597: #define gen_op_spe_ldd_le_user       gen_op_ld_le_user
        !          5598: #define gen_op_spe_ldd_le_kernel     gen_op_ld_le_kernel
        !          5599: #define gen_op_spe_ldd_le_hypv       gen_op_ld_le_hypv
        !          5600: #define gen_op_spe_ldd_le_64_raw     gen_op_ld_le_64_raw
        !          5601: #define gen_op_spe_ldd_le_64_user    gen_op_ld_le_64_user
        !          5602: #define gen_op_spe_ldd_le_64_kernel  gen_op_ld_le_64_kernel
        !          5603: #define gen_op_spe_ldd_le_64_hypv    gen_op_ld_le_64_hypv
        !          5604: #define gen_op_spe_stdd_raw          gen_op_std_raw
        !          5605: #define gen_op_spe_stdd_user         gen_op_std_user
        !          5606: #define gen_op_spe_stdd_kernel       gen_op_std_kernel
        !          5607: #define gen_op_spe_stdd_hypv         gen_op_std_hypv
        !          5608: #define gen_op_spe_stdd_64_raw       gen_op_std_64_raw
        !          5609: #define gen_op_spe_stdd_64_user      gen_op_std_64_user
        !          5610: #define gen_op_spe_stdd_64_kernel    gen_op_std_64_kernel
        !          5611: #define gen_op_spe_stdd_64_hypv      gen_op_std_64_hypv
        !          5612: #define gen_op_spe_stdd_le_raw       gen_op_std_le_raw
        !          5613: #define gen_op_spe_stdd_le_user      gen_op_std_le_user
        !          5614: #define gen_op_spe_stdd_le_kernel    gen_op_std_le_kernel
        !          5615: #define gen_op_spe_stdd_le_hypv      gen_op_std_le_hypv
        !          5616: #define gen_op_spe_stdd_le_64_raw    gen_op_std_le_64_raw
        !          5617: #define gen_op_spe_stdd_le_64_user   gen_op_std_le_64_user
        !          5618: #define gen_op_spe_stdd_le_64_kernel gen_op_std_le_64_kernel
        !          5619: #define gen_op_spe_stdd_le_64_hypv   gen_op_std_le_64_hypv
        !          5620: #endif /* defined(TARGET_PPC64) */
        !          5621: GEN_SPEOP_LDST(dd, 3);
        !          5622: GEN_SPEOP_LDST(dw, 3);
        !          5623: GEN_SPEOP_LDST(dh, 3);
        !          5624: GEN_SPEOP_LDST(whe, 2);
        !          5625: GEN_SPEOP_LD(whou, 2);
        !          5626: GEN_SPEOP_LD(whos, 2);
        !          5627: GEN_SPEOP_ST(who, 2);
        !          5628: 
        !          5629: #if defined(TARGET_PPC64)
        !          5630: /* In that case, spe_stwwo is equivalent to stw */
        !          5631: #define gen_op_spe_stwwo_raw          gen_op_stw_raw
        !          5632: #define gen_op_spe_stwwo_user         gen_op_stw_user
        !          5633: #define gen_op_spe_stwwo_kernel       gen_op_stw_kernel
        !          5634: #define gen_op_spe_stwwo_hypv         gen_op_stw_hypv
        !          5635: #define gen_op_spe_stwwo_le_raw       gen_op_stw_le_raw
        !          5636: #define gen_op_spe_stwwo_le_user      gen_op_stw_le_user
        !          5637: #define gen_op_spe_stwwo_le_kernel    gen_op_stw_le_kernel
        !          5638: #define gen_op_spe_stwwo_le_hypv      gen_op_stw_le_hypv
        !          5639: #define gen_op_spe_stwwo_64_raw       gen_op_stw_64_raw
        !          5640: #define gen_op_spe_stwwo_64_user      gen_op_stw_64_user
        !          5641: #define gen_op_spe_stwwo_64_kernel    gen_op_stw_64_kernel
        !          5642: #define gen_op_spe_stwwo_64_hypv      gen_op_stw_64_hypv
        !          5643: #define gen_op_spe_stwwo_le_64_raw    gen_op_stw_le_64_raw
        !          5644: #define gen_op_spe_stwwo_le_64_user   gen_op_stw_le_64_user
        !          5645: #define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
        !          5646: #define gen_op_spe_stwwo_le_64_hypv   gen_op_stw_le_64_hypv
        !          5647: #endif
        !          5648: #define _GEN_OP_SPE_STWWE(suffix)                                             \
        !          5649: static always_inline void gen_op_spe_stwwe_##suffix (void)                    \
        !          5650: {                                                                             \
        !          5651:     gen_op_srli32_T1_64();                                                    \
        !          5652:     gen_op_spe_stwwo_##suffix();                                              \
        !          5653: }
        !          5654: #define _GEN_OP_SPE_STWWE_LE(suffix)                                          \
        !          5655: static always_inline void gen_op_spe_stwwe_le_##suffix (void)                 \
        !          5656: {                                                                             \
        !          5657:     gen_op_srli32_T1_64();                                                    \
        !          5658:     gen_op_spe_stwwo_le_##suffix();                                           \
        !          5659: }
        !          5660: #if defined(TARGET_PPC64)
        !          5661: #define GEN_OP_SPE_STWWE(suffix)                                              \
        !          5662: _GEN_OP_SPE_STWWE(suffix);                                                    \
        !          5663: _GEN_OP_SPE_STWWE_LE(suffix);                                                 \
        !          5664: static always_inline void gen_op_spe_stwwe_64_##suffix (void)                 \
        !          5665: {                                                                             \
        !          5666:     gen_op_srli32_T1_64();                                                    \
        !          5667:     gen_op_spe_stwwo_64_##suffix();                                           \
        !          5668: }                                                                             \
        !          5669: static always_inline void gen_op_spe_stwwe_le_64_##suffix (void)              \
        !          5670: {                                                                             \
        !          5671:     gen_op_srli32_T1_64();                                                    \
        !          5672:     gen_op_spe_stwwo_le_64_##suffix();                                        \
        !          5673: }
        !          5674: #else
        !          5675: #define GEN_OP_SPE_STWWE(suffix)                                              \
        !          5676: _GEN_OP_SPE_STWWE(suffix);                                                    \
        !          5677: _GEN_OP_SPE_STWWE_LE(suffix)
        !          5678: #endif
        !          5679: #if defined(CONFIG_USER_ONLY)
        !          5680: GEN_OP_SPE_STWWE(raw);
        !          5681: #else /* defined(CONFIG_USER_ONLY) */
        !          5682: GEN_OP_SPE_STWWE(user);
        !          5683: GEN_OP_SPE_STWWE(kernel);
        !          5684: GEN_OP_SPE_STWWE(hypv);
        !          5685: #endif /* defined(CONFIG_USER_ONLY) */
        !          5686: GEN_SPEOP_ST(wwe, 2);
        !          5687: GEN_SPEOP_ST(wwo, 2);
        !          5688: 
        !          5689: #define GEN_SPE_LDSPLAT(name, op, suffix)                                     \
        !          5690: static always_inline void gen_op_spe_l##name##_##suffix (void)                \
        !          5691: {                                                                             \
        !          5692:     gen_op_##op##_##suffix();                                                 \
        !          5693:     gen_op_splatw_T1_64();                                                    \
        !          5694: }
        !          5695: 
        !          5696: #define GEN_OP_SPE_LHE(suffix)                                                \
        !          5697: static always_inline void gen_op_spe_lhe_##suffix (void)                      \
        !          5698: {                                                                             \
        !          5699:     gen_op_spe_lh_##suffix();                                                 \
        !          5700:     gen_op_sli16_T1_64();                                                     \
        !          5701: }
        !          5702: 
        !          5703: #define GEN_OP_SPE_LHX(suffix)                                                \
        !          5704: static always_inline void gen_op_spe_lhx_##suffix (void)                      \
        !          5705: {                                                                             \
        !          5706:     gen_op_spe_lh_##suffix();                                                 \
        !          5707:     gen_op_extsh_T1_64();                                                     \
        !          5708: }
        !          5709: 
        !          5710: #if defined(CONFIG_USER_ONLY)
        !          5711: GEN_OP_SPE_LHE(raw);
        !          5712: GEN_SPE_LDSPLAT(hhesplat, spe_lhe, raw);
        !          5713: GEN_OP_SPE_LHE(le_raw);
        !          5714: GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_raw);
        !          5715: GEN_SPE_LDSPLAT(hhousplat, spe_lh, raw);
        !          5716: GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_raw);
        !          5717: GEN_OP_SPE_LHX(raw);
        !          5718: GEN_SPE_LDSPLAT(hhossplat, spe_lhx, raw);
        !          5719: GEN_OP_SPE_LHX(le_raw);
        !          5720: GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_raw);
        !          5721: #if defined(TARGET_PPC64)
        !          5722: GEN_OP_SPE_LHE(64_raw);
        !          5723: GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_raw);
        !          5724: GEN_OP_SPE_LHE(le_64_raw);
        !          5725: GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_raw);
        !          5726: GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_raw);
        !          5727: GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_raw);
        !          5728: GEN_OP_SPE_LHX(64_raw);
        !          5729: GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_raw);
        !          5730: GEN_OP_SPE_LHX(le_64_raw);
        !          5731: GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
        !          5732: #endif
        !          5733: #else
        !          5734: GEN_OP_SPE_LHE(user);
        !          5735: GEN_OP_SPE_LHE(kernel);
        !          5736: GEN_OP_SPE_LHE(hypv);
        !          5737: GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
        !          5738: GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
        !          5739: GEN_SPE_LDSPLAT(hhesplat, spe_lhe, hypv);
        !          5740: GEN_OP_SPE_LHE(le_user);
        !          5741: GEN_OP_SPE_LHE(le_kernel);
        !          5742: GEN_OP_SPE_LHE(le_hypv);
        !          5743: GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
        !          5744: GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
        !          5745: GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_hypv);
        !          5746: GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
        !          5747: GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
        !          5748: GEN_SPE_LDSPLAT(hhousplat, spe_lh, hypv);
        !          5749: GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
        !          5750: GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
        !          5751: GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_hypv);
        !          5752: GEN_OP_SPE_LHX(user);
        !          5753: GEN_OP_SPE_LHX(kernel);
        !          5754: GEN_OP_SPE_LHX(hypv);
        !          5755: GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
        !          5756: GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
        !          5757: GEN_SPE_LDSPLAT(hhossplat, spe_lhx, hypv);
        !          5758: GEN_OP_SPE_LHX(le_user);
        !          5759: GEN_OP_SPE_LHX(le_kernel);
        !          5760: GEN_OP_SPE_LHX(le_hypv);
        !          5761: GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
        !          5762: GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
        !          5763: GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_hypv);
        !          5764: #if defined(TARGET_PPC64)
        !          5765: GEN_OP_SPE_LHE(64_user);
        !          5766: GEN_OP_SPE_LHE(64_kernel);
        !          5767: GEN_OP_SPE_LHE(64_hypv);
        !          5768: GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
        !          5769: GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
        !          5770: GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_hypv);
        !          5771: GEN_OP_SPE_LHE(le_64_user);
        !          5772: GEN_OP_SPE_LHE(le_64_kernel);
        !          5773: GEN_OP_SPE_LHE(le_64_hypv);
        !          5774: GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
        !          5775: GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
        !          5776: GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_hypv);
        !          5777: GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
        !          5778: GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
        !          5779: GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_hypv);
        !          5780: GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
        !          5781: GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
        !          5782: GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_hypv);
        !          5783: GEN_OP_SPE_LHX(64_user);
        !          5784: GEN_OP_SPE_LHX(64_kernel);
        !          5785: GEN_OP_SPE_LHX(64_hypv);
        !          5786: GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
        !          5787: GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
        !          5788: GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_hypv);
        !          5789: GEN_OP_SPE_LHX(le_64_user);
        !          5790: GEN_OP_SPE_LHX(le_64_kernel);
        !          5791: GEN_OP_SPE_LHX(le_64_hypv);
        !          5792: GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
        !          5793: GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
        !          5794: GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_hypv);
        !          5795: #endif
        !          5796: #endif
        !          5797: GEN_SPEOP_LD(hhesplat, 1);
        !          5798: GEN_SPEOP_LD(hhousplat, 1);
        !          5799: GEN_SPEOP_LD(hhossplat, 1);
        !          5800: GEN_SPEOP_LD(wwsplat, 2);
        !          5801: GEN_SPEOP_LD(whsplat, 2);
        !          5802: 
        !          5803: GEN_SPE(evlddx,         evldd,         0x00, 0x0C, 0x00000000, PPC_SPE); //
        !          5804: GEN_SPE(evldwx,         evldw,         0x01, 0x0C, 0x00000000, PPC_SPE); //
        !          5805: GEN_SPE(evldhx,         evldh,         0x02, 0x0C, 0x00000000, PPC_SPE); //
        !          5806: GEN_SPE(evlhhesplatx,   evlhhesplat,   0x04, 0x0C, 0x00000000, PPC_SPE); //
        !          5807: GEN_SPE(evlhhousplatx,  evlhhousplat,  0x06, 0x0C, 0x00000000, PPC_SPE); //
        !          5808: GEN_SPE(evlhhossplatx,  evlhhossplat,  0x07, 0x0C, 0x00000000, PPC_SPE); //
        !          5809: GEN_SPE(evlwhex,        evlwhe,        0x08, 0x0C, 0x00000000, PPC_SPE); //
        !          5810: GEN_SPE(evlwhoux,       evlwhou,       0x0A, 0x0C, 0x00000000, PPC_SPE); //
        !          5811: GEN_SPE(evlwhosx,       evlwhos,       0x0B, 0x0C, 0x00000000, PPC_SPE); //
        !          5812: GEN_SPE(evlwwsplatx,    evlwwsplat,    0x0C, 0x0C, 0x00000000, PPC_SPE); //
        !          5813: GEN_SPE(evlwhsplatx,    evlwhsplat,    0x0E, 0x0C, 0x00000000, PPC_SPE); //
        !          5814: GEN_SPE(evstddx,        evstdd,        0x10, 0x0C, 0x00000000, PPC_SPE); //
        !          5815: GEN_SPE(evstdwx,        evstdw,        0x11, 0x0C, 0x00000000, PPC_SPE); //
        !          5816: GEN_SPE(evstdhx,        evstdh,        0x12, 0x0C, 0x00000000, PPC_SPE); //
        !          5817: GEN_SPE(evstwhex,       evstwhe,       0x18, 0x0C, 0x00000000, PPC_SPE); //
        !          5818: GEN_SPE(evstwhox,       evstwho,       0x1A, 0x0C, 0x00000000, PPC_SPE); //
        !          5819: GEN_SPE(evstwwex,       evstwwe,       0x1C, 0x0C, 0x00000000, PPC_SPE); //
        !          5820: GEN_SPE(evstwwox,       evstwwo,       0x1E, 0x0C, 0x00000000, PPC_SPE); //
        !          5821: 
        !          5822: /* Multiply and add - TODO */
        !          5823: #if 0
        !          5824: GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
        !          5825: GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
        !          5826: GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
        !          5827: GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
        !          5828: GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
        !          5829: GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
        !          5830: GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
        !          5831: GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
        !          5832: GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
        !          5833: GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
        !          5834: GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
        !          5835: GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
        !          5836: 
        !          5837: GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
        !          5838: GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
        !          5839: GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
        !          5840: GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
        !          5841: GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
        !          5842: GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
        !          5843: GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
        !          5844: GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
        !          5845: GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
        !          5846: GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
        !          5847: GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
        !          5848: GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
        !          5849: GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
        !          5850: GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
        !          5851: 
        !          5852: GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
        !          5853: GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
        !          5854: GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
        !          5855: GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
        !          5856: GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
        !          5857: GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
        !          5858: 
        !          5859: GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
        !          5860: GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
        !          5861: GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
        !          5862: GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
        !          5863: GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
        !          5864: GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
        !          5865: GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
        !          5866: GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
        !          5867: GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
        !          5868: GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
        !          5869: GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
        !          5870: GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
        !          5871: 
        !          5872: GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
        !          5873: GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
        !          5874: GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
        !          5875: GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
        !          5876: GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
        !          5877: 
        !          5878: GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
        !          5879: GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
        !          5880: GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
        !          5881: GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
        !          5882: GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
        !          5883: GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
        !          5884: GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
        !          5885: GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
        !          5886: GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
        !          5887: GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
        !          5888: GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
        !          5889: GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
        !          5890: 
        !          5891: GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
        !          5892: GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
        !          5893: GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
        !          5894: GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
        !          5895: GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
        !          5896: #endif
        !          5897: 
        !          5898: /***                      SPE floating-point extension                     ***/
        !          5899: #define GEN_SPEFPUOP_CONV(name)                                               \
        !          5900: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          5901: {                                                                             \
        !          5902:     gen_op_load_gpr64_T0(rB(ctx->opcode));                                    \
        !          5903:     gen_op_##name();                                                          \
        !          5904:     gen_op_store_T0_gpr64(rD(ctx->opcode));                                   \
1.1       root     5905: }
                   5906: 
1.1.1.5 ! root     5907: /* Single precision floating-point vectors operations */
        !          5908: /* Arithmetic */
        !          5909: GEN_SPEOP_ARITH2(evfsadd);
        !          5910: GEN_SPEOP_ARITH2(evfssub);
        !          5911: GEN_SPEOP_ARITH2(evfsmul);
        !          5912: GEN_SPEOP_ARITH2(evfsdiv);
        !          5913: GEN_SPEOP_ARITH1(evfsabs);
        !          5914: GEN_SPEOP_ARITH1(evfsnabs);
        !          5915: GEN_SPEOP_ARITH1(evfsneg);
        !          5916: /* Conversion */
        !          5917: GEN_SPEFPUOP_CONV(evfscfui);
        !          5918: GEN_SPEFPUOP_CONV(evfscfsi);
        !          5919: GEN_SPEFPUOP_CONV(evfscfuf);
        !          5920: GEN_SPEFPUOP_CONV(evfscfsf);
        !          5921: GEN_SPEFPUOP_CONV(evfsctui);
        !          5922: GEN_SPEFPUOP_CONV(evfsctsi);
        !          5923: GEN_SPEFPUOP_CONV(evfsctuf);
        !          5924: GEN_SPEFPUOP_CONV(evfsctsf);
        !          5925: GEN_SPEFPUOP_CONV(evfsctuiz);
        !          5926: GEN_SPEFPUOP_CONV(evfsctsiz);
        !          5927: /* Comparison */
        !          5928: GEN_SPEOP_COMP(evfscmpgt);
        !          5929: GEN_SPEOP_COMP(evfscmplt);
        !          5930: GEN_SPEOP_COMP(evfscmpeq);
        !          5931: GEN_SPEOP_COMP(evfststgt);
        !          5932: GEN_SPEOP_COMP(evfststlt);
        !          5933: GEN_SPEOP_COMP(evfststeq);
        !          5934: 
        !          5935: /* Opcodes definitions */
        !          5936: GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
        !          5937: GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
        !          5938: GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
        !          5939: GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
        !          5940: GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
        !          5941: GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
        !          5942: GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
        !          5943: GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
        !          5944: GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
        !          5945: GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
        !          5946: GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
        !          5947: GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
        !          5948: GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
        !          5949: GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
        !          5950: 
        !          5951: /* Single precision floating-point operations */
        !          5952: /* Arithmetic */
        !          5953: GEN_SPEOP_ARITH2(efsadd);
        !          5954: GEN_SPEOP_ARITH2(efssub);
        !          5955: GEN_SPEOP_ARITH2(efsmul);
        !          5956: GEN_SPEOP_ARITH2(efsdiv);
        !          5957: GEN_SPEOP_ARITH1(efsabs);
        !          5958: GEN_SPEOP_ARITH1(efsnabs);
        !          5959: GEN_SPEOP_ARITH1(efsneg);
        !          5960: /* Conversion */
        !          5961: GEN_SPEFPUOP_CONV(efscfui);
        !          5962: GEN_SPEFPUOP_CONV(efscfsi);
        !          5963: GEN_SPEFPUOP_CONV(efscfuf);
        !          5964: GEN_SPEFPUOP_CONV(efscfsf);
        !          5965: GEN_SPEFPUOP_CONV(efsctui);
        !          5966: GEN_SPEFPUOP_CONV(efsctsi);
        !          5967: GEN_SPEFPUOP_CONV(efsctuf);
        !          5968: GEN_SPEFPUOP_CONV(efsctsf);
        !          5969: GEN_SPEFPUOP_CONV(efsctuiz);
        !          5970: GEN_SPEFPUOP_CONV(efsctsiz);
        !          5971: GEN_SPEFPUOP_CONV(efscfd);
        !          5972: /* Comparison */
        !          5973: GEN_SPEOP_COMP(efscmpgt);
        !          5974: GEN_SPEOP_COMP(efscmplt);
        !          5975: GEN_SPEOP_COMP(efscmpeq);
        !          5976: GEN_SPEOP_COMP(efststgt);
        !          5977: GEN_SPEOP_COMP(efststlt);
        !          5978: GEN_SPEOP_COMP(efststeq);
        !          5979: 
        !          5980: /* Opcodes definitions */
        !          5981: GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPEFPU); //
        !          5982: GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
        !          5983: GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
        !          5984: GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
        !          5985: GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
        !          5986: GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
        !          5987: GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
        !          5988: GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
        !          5989: GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
        !          5990: GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
        !          5991: GEN_SPE(efsctuiz,       efsctsiz,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
        !          5992: GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
        !          5993: GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
        !          5994: 
        !          5995: /* Double precision floating-point operations */
        !          5996: /* Arithmetic */
        !          5997: GEN_SPEOP_ARITH2(efdadd);
        !          5998: GEN_SPEOP_ARITH2(efdsub);
        !          5999: GEN_SPEOP_ARITH2(efdmul);
        !          6000: GEN_SPEOP_ARITH2(efddiv);
        !          6001: GEN_SPEOP_ARITH1(efdabs);
        !          6002: GEN_SPEOP_ARITH1(efdnabs);
        !          6003: GEN_SPEOP_ARITH1(efdneg);
        !          6004: /* Conversion */
        !          6005: 
        !          6006: GEN_SPEFPUOP_CONV(efdcfui);
        !          6007: GEN_SPEFPUOP_CONV(efdcfsi);
        !          6008: GEN_SPEFPUOP_CONV(efdcfuf);
        !          6009: GEN_SPEFPUOP_CONV(efdcfsf);
        !          6010: GEN_SPEFPUOP_CONV(efdctui);
        !          6011: GEN_SPEFPUOP_CONV(efdctsi);
        !          6012: GEN_SPEFPUOP_CONV(efdctuf);
        !          6013: GEN_SPEFPUOP_CONV(efdctsf);
        !          6014: GEN_SPEFPUOP_CONV(efdctuiz);
        !          6015: GEN_SPEFPUOP_CONV(efdctsiz);
        !          6016: GEN_SPEFPUOP_CONV(efdcfs);
        !          6017: GEN_SPEFPUOP_CONV(efdcfuid);
        !          6018: GEN_SPEFPUOP_CONV(efdcfsid);
        !          6019: GEN_SPEFPUOP_CONV(efdctuidz);
        !          6020: GEN_SPEFPUOP_CONV(efdctsidz);
        !          6021: /* Comparison */
        !          6022: GEN_SPEOP_COMP(efdcmpgt);
        !          6023: GEN_SPEOP_COMP(efdcmplt);
        !          6024: GEN_SPEOP_COMP(efdcmpeq);
        !          6025: GEN_SPEOP_COMP(efdtstgt);
        !          6026: GEN_SPEOP_COMP(efdtstlt);
        !          6027: GEN_SPEOP_COMP(efdtsteq);
        !          6028: 
        !          6029: /* Opcodes definitions */
        !          6030: GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
        !          6031: GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
        !          6032: GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
        !          6033: GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
        !          6034: GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
        !          6035: GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
        !          6036: GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
        !          6037: GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
        !          6038: GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
        !          6039: GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
        !          6040: GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
        !          6041: GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
        !          6042: GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
        !          6043: GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
        !          6044: GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
        !          6045: GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
        !          6046: 
1.1       root     6047: /* End opcode list */
                   6048: GEN_OPCODE_MARK(end);
                   6049: 
                   6050: #include "translate_init.c"
1.1.1.5 ! root     6051: #include "helper_regs.h"
1.1       root     6052: 
                   6053: /*****************************************************************************/
                   6054: /* Misc PowerPC helpers */
1.1.1.5 ! root     6055: void cpu_dump_state (CPUState *env, FILE *f,
        !          6056:                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
        !          6057:                      int flags)
        !          6058: {
1.1       root     6059: #define RGPL  4
                   6060: #define RFPL  4
                   6061: 
                   6062:     int i;
                   6063: 
1.1.1.5 ! root     6064:     cpu_fprintf(f, "NIP " ADDRX "   LR " ADDRX " CTR " ADDRX " XER %08x\n",
        !          6065:                 env->nip, env->lr, env->ctr, hreg_load_xer(env));
        !          6066:     cpu_fprintf(f, "MSR " ADDRX " HID0 " ADDRX "  HF " ADDRX " idx %d\n",
        !          6067:                 env->msr, env->spr[SPR_HID0], env->hflags, env->mmu_idx);
        !          6068: #if !defined(NO_TIMER_DUMP)
        !          6069:     cpu_fprintf(f, "TB %08x %08x "
        !          6070: #if !defined(CONFIG_USER_ONLY)
        !          6071:                 "DECR %08x"
        !          6072: #endif
        !          6073:                 "\n",
        !          6074:                 cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
        !          6075: #if !defined(CONFIG_USER_ONLY)
        !          6076:                 , cpu_ppc_load_decr(env)
        !          6077: #endif
        !          6078:                 );
        !          6079: #endif
        !          6080:     for (i = 0; i < 32; i++) {
1.1       root     6081:         if ((i & (RGPL - 1)) == 0)
                   6082:             cpu_fprintf(f, "GPR%02d", i);
1.1.1.5 ! root     6083:         cpu_fprintf(f, " " REGX, ppc_dump_gpr(env, i));
1.1       root     6084:         if ((i & (RGPL - 1)) == (RGPL - 1))
                   6085:             cpu_fprintf(f, "\n");
1.1.1.5 ! root     6086:     }
1.1       root     6087:     cpu_fprintf(f, "CR ");
1.1.1.5 ! root     6088:     for (i = 0; i < 8; i++)
1.1       root     6089:         cpu_fprintf(f, "%01x", env->crf[i]);
                   6090:     cpu_fprintf(f, "  [");
1.1.1.5 ! root     6091:     for (i = 0; i < 8; i++) {
        !          6092:         char a = '-';
        !          6093:         if (env->crf[i] & 0x08)
        !          6094:             a = 'L';
        !          6095:         else if (env->crf[i] & 0x04)
        !          6096:             a = 'G';
        !          6097:         else if (env->crf[i] & 0x02)
        !          6098:             a = 'E';
1.1       root     6099:         cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
1.1.1.5 ! root     6100:     }
        !          6101:     cpu_fprintf(f, " ]             RES " ADDRX "\n", env->reserve);
1.1       root     6102:     for (i = 0; i < 32; i++) {
                   6103:         if ((i & (RFPL - 1)) == 0)
                   6104:             cpu_fprintf(f, "FPR%02d", i);
1.1.1.3   root     6105:         cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
1.1       root     6106:         if ((i & (RFPL - 1)) == (RFPL - 1))
                   6107:             cpu_fprintf(f, "\n");
                   6108:     }
1.1.1.5 ! root     6109: #if !defined(CONFIG_USER_ONLY)
        !          6110:     cpu_fprintf(f, "SRR0 " ADDRX " SRR1 " ADDRX " SDR1 " ADDRX "\n",
1.1       root     6111:                 env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
1.1.1.5 ! root     6112: #endif
1.1       root     6113: 
                   6114: #undef RGPL
                   6115: #undef RFPL
1.1.1.5 ! root     6116: }
        !          6117: 
        !          6118: void cpu_dump_statistics (CPUState *env, FILE*f,
        !          6119:                           int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
        !          6120:                           int flags)
        !          6121: {
        !          6122: #if defined(DO_PPC_STATISTICS)
        !          6123:     opc_handler_t **t1, **t2, **t3, *handler;
        !          6124:     int op1, op2, op3;
        !          6125: 
        !          6126:     t1 = env->opcodes;
        !          6127:     for (op1 = 0; op1 < 64; op1++) {
        !          6128:         handler = t1[op1];
        !          6129:         if (is_indirect_opcode(handler)) {
        !          6130:             t2 = ind_table(handler);
        !          6131:             for (op2 = 0; op2 < 32; op2++) {
        !          6132:                 handler = t2[op2];
        !          6133:                 if (is_indirect_opcode(handler)) {
        !          6134:                     t3 = ind_table(handler);
        !          6135:                     for (op3 = 0; op3 < 32; op3++) {
        !          6136:                         handler = t3[op3];
        !          6137:                         if (handler->count == 0)
        !          6138:                             continue;
        !          6139:                         cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
        !          6140:                                     "%016llx %lld\n",
        !          6141:                                     op1, op2, op3, op1, (op3 << 5) | op2,
        !          6142:                                     handler->oname,
        !          6143:                                     handler->count, handler->count);
        !          6144:                     }
        !          6145:                 } else {
        !          6146:                     if (handler->count == 0)
        !          6147:                         continue;
        !          6148:                     cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
        !          6149:                                 "%016llx %lld\n",
        !          6150:                                 op1, op2, op1, op2, handler->oname,
        !          6151:                                 handler->count, handler->count);
        !          6152:                 }
        !          6153:             }
        !          6154:         } else {
        !          6155:             if (handler->count == 0)
        !          6156:                 continue;
        !          6157:             cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
        !          6158:                         op1, op1, handler->oname,
        !          6159:                         handler->count, handler->count);
        !          6160:         }
        !          6161:     }
        !          6162: #endif
1.1       root     6163: }
                   6164: 
                   6165: /*****************************************************************************/
1.1.1.5 ! root     6166: static always_inline int gen_intermediate_code_internal (CPUState *env,
        !          6167:                                                          TranslationBlock *tb,
        !          6168:                                                          int search_pc)
1.1       root     6169: {
                   6170:     DisasContext ctx, *ctxp = &ctx;
                   6171:     opc_handler_t **table, *handler;
                   6172:     target_ulong pc_start;
                   6173:     uint16_t *gen_opc_end;
1.1.1.5 ! root     6174:     int supervisor, little_endian;
        !          6175:     int single_step, branch_step;
1.1       root     6176:     int j, lj = -1;
                   6177: 
                   6178:     pc_start = tb->pc;
                   6179:     gen_opc_ptr = gen_opc_buf;
                   6180:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
                   6181:     gen_opparam_ptr = gen_opparam_buf;
1.1.1.5 ! root     6182: #if defined(OPTIMIZE_FPRF_UPDATE)
        !          6183:     gen_fprf_ptr = gen_fprf_buf;
        !          6184: #endif
1.1.1.2   root     6185:     nb_gen_labels = 0;
1.1       root     6186:     ctx.nip = pc_start;
                   6187:     ctx.tb = tb;
1.1.1.5 ! root     6188:     ctx.exception = POWERPC_EXCP_NONE;
1.1       root     6189:     ctx.spr_cb = env->spr_cb;
1.1.1.5 ! root     6190:     supervisor = env->mmu_idx;
        !          6191: #if !defined(CONFIG_USER_ONLY)
        !          6192:     ctx.supervisor = supervisor;
        !          6193: #endif
        !          6194:     little_endian = env->hflags & (1 << MSR_LE) ? 1 : 0;
        !          6195: #if defined(TARGET_PPC64)
        !          6196:     ctx.sf_mode = msr_sf;
        !          6197:     ctx.mem_idx = (supervisor << 2) | (msr_sf << 1) | little_endian;
1.1       root     6198: #else
1.1.1.5 ! root     6199:     ctx.mem_idx = (supervisor << 1) | little_endian;
1.1       root     6200: #endif
1.1.1.5 ! root     6201:     ctx.dcache_line_size = env->dcache_line_size;
1.1       root     6202:     ctx.fpu_enabled = msr_fp;
1.1.1.5 ! root     6203:     if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
        !          6204:         ctx.spe_enabled = msr_spe;
        !          6205:     else
        !          6206:         ctx.spe_enabled = 0;
        !          6207:     if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
        !          6208:         ctx.altivec_enabled = msr_vr;
        !          6209:     else
        !          6210:         ctx.altivec_enabled = 0;
        !          6211:     if ((env->flags & POWERPC_FLAG_SE) && msr_se)
        !          6212:         single_step = 1;
        !          6213:     else
        !          6214:         single_step = 0;
        !          6215:     if ((env->flags & POWERPC_FLAG_BE) && msr_be)
        !          6216:         branch_step = 1;
        !          6217:     else
        !          6218:         branch_step = 0;
        !          6219:     ctx.singlestep_enabled = env->singlestep_enabled || single_step == 1;
1.1       root     6220: #if defined (DO_SINGLE_STEP) && 0
                   6221:     /* Single step trace mode */
                   6222:     msr_se = 1;
                   6223: #endif
                   6224:     /* Set env in case of segfault during code fetch */
1.1.1.5 ! root     6225:     while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
        !          6226:         if (unlikely(env->nb_breakpoints > 0)) {
        !          6227:             for (j = 0; j < env->nb_breakpoints; j++) {
1.1.1.3   root     6228:                 if (env->breakpoints[j] == ctx.nip) {
1.1.1.5 ! root     6229:                     gen_update_nip(&ctx, ctx.nip);
1.1.1.3   root     6230:                     gen_op_debug();
                   6231:                     break;
                   6232:                 }
                   6233:             }
                   6234:         }
1.1.1.5 ! root     6235:         if (unlikely(search_pc)) {
1.1       root     6236:             j = gen_opc_ptr - gen_opc_buf;
                   6237:             if (lj < j) {
                   6238:                 lj++;
                   6239:                 while (lj < j)
                   6240:                     gen_opc_instr_start[lj++] = 0;
                   6241:                 gen_opc_pc[lj] = ctx.nip;
                   6242:                 gen_opc_instr_start[lj] = 1;
                   6243:             }
                   6244:         }
                   6245: #if defined PPC_DEBUG_DISAS
                   6246:         if (loglevel & CPU_LOG_TB_IN_ASM) {
                   6247:             fprintf(logfile, "----------------\n");
1.1.1.5 ! root     6248:             fprintf(logfile, "nip=" ADDRX " super=%d ir=%d\n",
        !          6249:                     ctx.nip, supervisor, (int)msr_ir);
1.1       root     6250:         }
                   6251: #endif
1.1.1.5 ! root     6252:         if (unlikely(little_endian)) {
        !          6253:             ctx.opcode = bswap32(ldl_code(ctx.nip));
        !          6254:         } else {
        !          6255:             ctx.opcode = ldl_code(ctx.nip);
1.1       root     6256:         }
                   6257: #if defined PPC_DEBUG_DISAS
                   6258:         if (loglevel & CPU_LOG_TB_IN_ASM) {
                   6259:             fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
                   6260:                     ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
1.1.1.5 ! root     6261:                     opc3(ctx.opcode), little_endian ? "little" : "big");
1.1       root     6262:         }
                   6263: #endif
                   6264:         ctx.nip += 4;
                   6265:         table = env->opcodes;
                   6266:         handler = table[opc1(ctx.opcode)];
                   6267:         if (is_indirect_opcode(handler)) {
                   6268:             table = ind_table(handler);
                   6269:             handler = table[opc2(ctx.opcode)];
                   6270:             if (is_indirect_opcode(handler)) {
                   6271:                 table = ind_table(handler);
                   6272:                 handler = table[opc3(ctx.opcode)];
                   6273:             }
                   6274:         }
                   6275:         /* Is opcode *REALLY* valid ? */
1.1.1.5 ! root     6276:         if (unlikely(handler->handler == &gen_invalid)) {
        !          6277:             if (loglevel != 0) {
        !          6278:                 fprintf(logfile, "invalid/unsupported opcode: "
        !          6279:                         "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
        !          6280:                         opc1(ctx.opcode), opc2(ctx.opcode),
        !          6281:                         opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
1.1       root     6282:             } else {
                   6283:                 printf("invalid/unsupported opcode: "
1.1.1.5 ! root     6284:                        "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
1.1       root     6285:                        opc1(ctx.opcode), opc2(ctx.opcode),
1.1.1.5 ! root     6286:                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
1.1       root     6287:             }
1.1.1.5 ! root     6288:         } else {
        !          6289:             if (unlikely((ctx.opcode & handler->inval) != 0)) {
        !          6290:                 if (loglevel != 0) {
1.1       root     6291:                     fprintf(logfile, "invalid bits: %08x for opcode: "
1.1.1.5 ! root     6292:                             "%02x - %02x - %02x (%08x) " ADDRX "\n",
1.1       root     6293:                             ctx.opcode & handler->inval, opc1(ctx.opcode),
                   6294:                             opc2(ctx.opcode), opc3(ctx.opcode),
                   6295:                             ctx.opcode, ctx.nip - 4);
                   6296:                 } else {
                   6297:                     printf("invalid bits: %08x for opcode: "
1.1.1.5 ! root     6298:                            "%02x - %02x - %02x (%08x) " ADDRX "\n",
        !          6299:                            ctx.opcode & handler->inval, opc1(ctx.opcode),
        !          6300:                            opc2(ctx.opcode), opc3(ctx.opcode),
1.1       root     6301:                            ctx.opcode, ctx.nip - 4);
1.1.1.5 ! root     6302:                 }
        !          6303:                 GEN_EXCP_INVAL(ctxp);
1.1       root     6304:                 break;
                   6305:             }
                   6306:         }
                   6307:         (*(handler->handler))(&ctx);
1.1.1.5 ! root     6308: #if defined(DO_PPC_STATISTICS)
        !          6309:         handler->count++;
        !          6310: #endif
1.1       root     6311:         /* Check trace mode exceptions */
1.1.1.5 ! root     6312:         if (unlikely(branch_step != 0 &&
        !          6313:                      ctx.exception == POWERPC_EXCP_BRANCH)) {
        !          6314:             GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
        !          6315:         } else if (unlikely(single_step != 0 &&
        !          6316:                             (ctx.nip <= 0x100 || ctx.nip > 0xF00 ||
        !          6317:                              (ctx.nip & 0xFC) != 0x04) &&
        !          6318:                             ctx.exception != POWERPC_SYSCALL &&
        !          6319:                             ctx.exception != POWERPC_EXCP_TRAP)) {
        !          6320:             GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
        !          6321:         } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
        !          6322:                             (env->singlestep_enabled))) {
        !          6323:             /* if we reach a page boundary or are single stepping, stop
        !          6324:              * generation
1.1       root     6325:              */
                   6326:             break;
1.1.1.5 ! root     6327:         }
1.1       root     6328: #if defined (DO_SINGLE_STEP)
                   6329:         break;
                   6330: #endif
                   6331:     }
1.1.1.5 ! root     6332:     if (ctx.exception == POWERPC_EXCP_NONE) {
1.1.1.2   root     6333:         gen_goto_tb(&ctx, 0, ctx.nip);
1.1.1.5 ! root     6334:     } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
        !          6335:         gen_op_reset_T0();
        !          6336:         /* Generate the return instruction */
        !          6337:         gen_op_exit_tb();
1.1       root     6338:     }
                   6339:     *gen_opc_ptr = INDEX_op_end;
1.1.1.5 ! root     6340:     if (unlikely(search_pc)) {
1.1       root     6341:         j = gen_opc_ptr - gen_opc_buf;
                   6342:         lj++;
                   6343:         while (lj <= j)
                   6344:             gen_opc_instr_start[lj++] = 0;
                   6345:     } else {
                   6346:         tb->size = ctx.nip - pc_start;
                   6347:     }
1.1.1.5 ! root     6348: #if defined(DEBUG_DISAS)
1.1       root     6349:     if (loglevel & CPU_LOG_TB_CPU) {
                   6350:         fprintf(logfile, "---------------- excp: %04x\n", ctx.exception);
                   6351:         cpu_dump_state(env, logfile, fprintf, 0);
                   6352:     }
                   6353:     if (loglevel & CPU_LOG_TB_IN_ASM) {
1.1.1.5 ! root     6354:         int flags;
        !          6355:         flags = env->bfd_mach;
        !          6356:         flags |= little_endian << 16;
1.1       root     6357:         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
1.1.1.5 ! root     6358:         target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
1.1       root     6359:         fprintf(logfile, "\n");
                   6360:     }
                   6361:     if (loglevel & CPU_LOG_TB_OP) {
                   6362:         fprintf(logfile, "OP:\n");
                   6363:         dump_ops(gen_opc_buf, gen_opparam_buf);
                   6364:         fprintf(logfile, "\n");
                   6365:     }
                   6366: #endif
                   6367:     return 0;
                   6368: }
                   6369: 
                   6370: int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
                   6371: {
                   6372:     return gen_intermediate_code_internal(env, tb, 0);
                   6373: }
                   6374: 
                   6375: int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
                   6376: {
                   6377:     return gen_intermediate_code_internal(env, tb, 1);
                   6378: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.