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

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.1.11  root        5:  *  Copyright (C) 2011 Freescale Semiconductor, Inc.
1.1       root        6:  *
                      7:  * This library is free software; you can redistribute it and/or
                      8:  * modify it under the terms of the GNU Lesser General Public
                      9:  * License as published by the Free Software Foundation; either
                     10:  * version 2 of the License, or (at your option) any later version.
                     11:  *
                     12:  * This library is distributed in the hope that it will be useful,
                     13:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     15:  * Lesser General Public License for more details.
                     16:  *
                     17:  * You should have received a copy of the GNU Lesser General Public
1.1.1.7   root       18:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1.1       root       19:  */
                     20: 
                     21: #include "cpu.h"
                     22: #include "disas.h"
1.1.1.6   root       23: #include "tcg-op.h"
                     24: #include "host-utils.h"
                     25: 
                     26: #include "helper.h"
                     27: #define GEN_HELPER 1
                     28: #include "helper.h"
                     29: 
                     30: #define CPU_SINGLE_STEP 0x1
                     31: #define CPU_BRANCH_STEP 0x2
                     32: #define GDBSTUB_SINGLE_STEP 0x4
1.1       root       33: 
1.1.1.5   root       34: /* Include definitions for instructions classes and implementations flags */
1.1       root       35: //#define PPC_DEBUG_DISAS
1.1.1.5   root       36: //#define DO_PPC_STATISTICS
1.1       root       37: 
1.1.1.6   root       38: #ifdef PPC_DEBUG_DISAS
                     39: #  define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
1.1.1.2   root       40: #else
1.1.1.6   root       41: #  define LOG_DISAS(...) do { } while (0)
1.1.1.2   root       42: #endif
1.1.1.6   root       43: /*****************************************************************************/
                     44: /* Code translation helpers                                                  */
1.1.1.2   root       45: 
1.1.1.6   root       46: /* global register indexes */
                     47: static TCGv_ptr cpu_env;
                     48: static char cpu_reg_names[10*3 + 22*4 /* GPR */
                     49: #if !defined(TARGET_PPC64)
                     50:     + 10*4 + 22*5 /* SPE GPRh */
1.1.1.5   root       51: #endif
1.1.1.6   root       52:     + 10*4 + 22*5 /* FPR */
                     53:     + 2*(10*6 + 22*7) /* AVRh, AVRl */
                     54:     + 8*5 /* CRF */];
                     55: static TCGv cpu_gpr[32];
                     56: #if !defined(TARGET_PPC64)
                     57: static TCGv cpu_gprh[32];
                     58: #endif
                     59: static TCGv_i64 cpu_fpr[32];
                     60: static TCGv_i64 cpu_avrh[32], cpu_avrl[32];
                     61: static TCGv_i32 cpu_crf[8];
                     62: static TCGv cpu_nip;
                     63: static TCGv cpu_msr;
                     64: static TCGv cpu_ctr;
                     65: static TCGv cpu_lr;
1.1.1.12  root       66: #if defined(TARGET_PPC64)
                     67: static TCGv cpu_cfar;
                     68: #endif
1.1.1.6   root       69: static TCGv cpu_xer;
                     70: static TCGv cpu_reserve;
                     71: static TCGv_i32 cpu_fpscr;
                     72: static TCGv_i32 cpu_access_type;
1.1       root       73: 
1.1.1.6   root       74: #include "gen-icount.h"
1.1       root       75: 
1.1.1.6   root       76: void ppc_translate_init(void)
1.1.1.5   root       77: {
1.1.1.6   root       78:     int i;
                     79:     char* p;
1.1.1.7   root       80:     size_t cpu_reg_names_size;
1.1.1.6   root       81:     static int done_init = 0;
                     82: 
                     83:     if (done_init)
                     84:         return;
                     85: 
                     86:     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
                     87: 
                     88:     p = cpu_reg_names;
1.1.1.7   root       89:     cpu_reg_names_size = sizeof(cpu_reg_names);
1.1.1.6   root       90: 
                     91:     for (i = 0; i < 8; i++) {
1.1.1.7   root       92:         snprintf(p, cpu_reg_names_size, "crf%d", i);
1.1.1.6   root       93:         cpu_crf[i] = tcg_global_mem_new_i32(TCG_AREG0,
1.1.1.13! root       94:                                             offsetof(CPUPPCState, crf[i]), p);
1.1.1.6   root       95:         p += 5;
1.1.1.7   root       96:         cpu_reg_names_size -= 5;
1.1.1.6   root       97:     }
                     98: 
                     99:     for (i = 0; i < 32; i++) {
1.1.1.7   root      100:         snprintf(p, cpu_reg_names_size, "r%d", i);
1.1.1.6   root      101:         cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
1.1.1.13! root      102:                                         offsetof(CPUPPCState, gpr[i]), p);
1.1.1.6   root      103:         p += (i < 10) ? 3 : 4;
1.1.1.7   root      104:         cpu_reg_names_size -= (i < 10) ? 3 : 4;
1.1.1.6   root      105: #if !defined(TARGET_PPC64)
1.1.1.7   root      106:         snprintf(p, cpu_reg_names_size, "r%dH", i);
1.1.1.6   root      107:         cpu_gprh[i] = tcg_global_mem_new_i32(TCG_AREG0,
1.1.1.13! root      108:                                              offsetof(CPUPPCState, gprh[i]), p);
1.1.1.6   root      109:         p += (i < 10) ? 4 : 5;
1.1.1.7   root      110:         cpu_reg_names_size -= (i < 10) ? 4 : 5;
1.1.1.5   root      111: #endif
                    112: 
1.1.1.7   root      113:         snprintf(p, cpu_reg_names_size, "fp%d", i);
1.1.1.6   root      114:         cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0,
1.1.1.13! root      115:                                             offsetof(CPUPPCState, fpr[i]), p);
1.1.1.6   root      116:         p += (i < 10) ? 4 : 5;
1.1.1.7   root      117:         cpu_reg_names_size -= (i < 10) ? 4 : 5;
1.1.1.6   root      118: 
1.1.1.7   root      119:         snprintf(p, cpu_reg_names_size, "avr%dH", i);
1.1.1.8   root      120: #ifdef HOST_WORDS_BIGENDIAN
1.1.1.6   root      121:         cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
1.1.1.13! root      122:                                              offsetof(CPUPPCState, avr[i].u64[0]), p);
1.1.1.6   root      123: #else
                    124:         cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
1.1.1.13! root      125:                                              offsetof(CPUPPCState, avr[i].u64[1]), p);
1.1.1.5   root      126: #endif
1.1.1.6   root      127:         p += (i < 10) ? 6 : 7;
1.1.1.7   root      128:         cpu_reg_names_size -= (i < 10) ? 6 : 7;
1.1.1.5   root      129: 
1.1.1.7   root      130:         snprintf(p, cpu_reg_names_size, "avr%dL", i);
1.1.1.8   root      131: #ifdef HOST_WORDS_BIGENDIAN
1.1.1.6   root      132:         cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
1.1.1.13! root      133:                                              offsetof(CPUPPCState, avr[i].u64[1]), p);
1.1.1.6   root      134: #else
                    135:         cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
1.1.1.13! root      136:                                              offsetof(CPUPPCState, avr[i].u64[0]), p);
1.1.1.5   root      137: #endif
1.1.1.6   root      138:         p += (i < 10) ? 6 : 7;
1.1.1.7   root      139:         cpu_reg_names_size -= (i < 10) ? 6 : 7;
1.1.1.6   root      140:     }
                    141: 
                    142:     cpu_nip = tcg_global_mem_new(TCG_AREG0,
1.1.1.13! root      143:                                  offsetof(CPUPPCState, nip), "nip");
1.1.1.6   root      144: 
                    145:     cpu_msr = tcg_global_mem_new(TCG_AREG0,
1.1.1.13! root      146:                                  offsetof(CPUPPCState, msr), "msr");
1.1.1.6   root      147: 
                    148:     cpu_ctr = tcg_global_mem_new(TCG_AREG0,
1.1.1.13! root      149:                                  offsetof(CPUPPCState, ctr), "ctr");
1.1.1.6   root      150: 
                    151:     cpu_lr = tcg_global_mem_new(TCG_AREG0,
1.1.1.13! root      152:                                 offsetof(CPUPPCState, lr), "lr");
1.1.1.6   root      153: 
1.1.1.12  root      154: #if defined(TARGET_PPC64)
                    155:     cpu_cfar = tcg_global_mem_new(TCG_AREG0,
1.1.1.13! root      156:                                   offsetof(CPUPPCState, cfar), "cfar");
1.1.1.12  root      157: #endif
                    158: 
1.1.1.6   root      159:     cpu_xer = tcg_global_mem_new(TCG_AREG0,
1.1.1.13! root      160:                                  offsetof(CPUPPCState, xer), "xer");
1.1.1.6   root      161: 
                    162:     cpu_reserve = tcg_global_mem_new(TCG_AREG0,
1.1.1.13! root      163:                                      offsetof(CPUPPCState, reserve_addr),
1.1.1.8   root      164:                                      "reserve_addr");
1.1.1.6   root      165: 
                    166:     cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0,
1.1.1.13! root      167:                                        offsetof(CPUPPCState, fpscr), "fpscr");
1.1.1.6   root      168: 
                    169:     cpu_access_type = tcg_global_mem_new_i32(TCG_AREG0,
1.1.1.13! root      170:                                              offsetof(CPUPPCState, access_type), "access_type");
1.1.1.6   root      171: 
                    172:     /* register helpers */
                    173: #define GEN_HELPER 2
                    174: #include "helper.h"
                    175: 
                    176:     done_init = 1;
                    177: }
1.1       root      178: 
                    179: /* internal defines */
                    180: typedef struct DisasContext {
                    181:     struct TranslationBlock *tb;
                    182:     target_ulong nip;
                    183:     uint32_t opcode;
                    184:     uint32_t exception;
                    185:     /* Routine used to access memory */
                    186:     int mem_idx;
1.1.1.6   root      187:     int access_type;
1.1       root      188:     /* Translation flags */
1.1.1.6   root      189:     int le_mode;
1.1.1.5   root      190: #if defined(TARGET_PPC64)
                    191:     int sf_mode;
1.1.1.12  root      192:     int has_cfar;
1.1.1.5   root      193: #endif
1.1       root      194:     int fpu_enabled;
1.1.1.5   root      195:     int altivec_enabled;
                    196:     int spe_enabled;
1.1       root      197:     ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
1.1.1.3   root      198:     int singlestep_enabled;
1.1       root      199: } DisasContext;
                    200: 
                    201: struct opc_handler_t {
1.1.1.12  root      202:     /* invalid bits for instruction 1 (Rc(opcode) == 0) */
                    203:     uint32_t inval1;
                    204:     /* invalid bits for instruction 2 (Rc(opcode) == 1) */
                    205:     uint32_t inval2;
1.1       root      206:     /* instruction type */
1.1.1.5   root      207:     uint64_t type;
1.1.1.11  root      208:     /* extended instruction type */
                    209:     uint64_t type2;
1.1       root      210:     /* handler */
                    211:     void (*handler)(DisasContext *ctx);
1.1.1.5   root      212: #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
1.1.1.6   root      213:     const char *oname;
1.1.1.5   root      214: #endif
                    215: #if defined(DO_PPC_STATISTICS)
                    216:     uint64_t count;
                    217: #endif
1.1       root      218: };
                    219: 
1.1.1.8   root      220: static inline void gen_reset_fpstatus(void)
1.1.1.5   root      221: {
1.1.1.6   root      222:     gen_helper_reset_fpstatus();
1.1.1.5   root      223: }
                    224: 
1.1.1.8   root      225: static inline void gen_compute_fprf(TCGv_i64 arg, int set_fprf, int set_rc)
1.1.1.5   root      226: {
1.1.1.6   root      227:     TCGv_i32 t0 = tcg_temp_new_i32();
                    228: 
1.1.1.5   root      229:     if (set_fprf != 0) {
                    230:         /* This case might be optimized later */
1.1.1.6   root      231:         tcg_gen_movi_i32(t0, 1);
                    232:         gen_helper_compute_fprf(t0, arg, t0);
                    233:         if (unlikely(set_rc)) {
                    234:             tcg_gen_mov_i32(cpu_crf[1], t0);
                    235:         }
                    236:         gen_helper_float_check_status();
1.1.1.5   root      237:     } else if (unlikely(set_rc)) {
                    238:         /* We always need to compute fpcc */
1.1.1.6   root      239:         tcg_gen_movi_i32(t0, 0);
                    240:         gen_helper_compute_fprf(t0, arg, t0);
                    241:         tcg_gen_mov_i32(cpu_crf[1], t0);
1.1.1.5   root      242:     }
1.1.1.6   root      243: 
                    244:     tcg_temp_free_i32(t0);
1.1.1.5   root      245: }
                    246: 
1.1.1.8   root      247: static inline void gen_set_access_type(DisasContext *ctx, int access_type)
1.1.1.5   root      248: {
1.1.1.6   root      249:     if (ctx->access_type != access_type) {
                    250:         tcg_gen_movi_i32(cpu_access_type, access_type);
                    251:         ctx->access_type = access_type;
                    252:     }
1.1.1.5   root      253: }
                    254: 
1.1.1.8   root      255: static inline void gen_update_nip(DisasContext *ctx, target_ulong nip)
1.1.1.5   root      256: {
                    257: #if defined(TARGET_PPC64)
                    258:     if (ctx->sf_mode)
1.1.1.6   root      259:         tcg_gen_movi_tl(cpu_nip, nip);
1.1.1.5   root      260:     else
                    261: #endif
1.1.1.6   root      262:         tcg_gen_movi_tl(cpu_nip, (uint32_t)nip);
1.1.1.5   root      263: }
                    264: 
1.1.1.8   root      265: static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
1.1.1.6   root      266: {
                    267:     TCGv_i32 t0, t1;
                    268:     if (ctx->exception == POWERPC_EXCP_NONE) {
                    269:         gen_update_nip(ctx, ctx->nip);
                    270:     }
                    271:     t0 = tcg_const_i32(excp);
                    272:     t1 = tcg_const_i32(error);
                    273:     gen_helper_raise_exception_err(t0, t1);
                    274:     tcg_temp_free_i32(t0);
                    275:     tcg_temp_free_i32(t1);
                    276:     ctx->exception = (excp);
                    277: }
1.1.1.5   root      278: 
1.1.1.8   root      279: static inline void gen_exception(DisasContext *ctx, uint32_t excp)
1.1.1.6   root      280: {
                    281:     TCGv_i32 t0;
                    282:     if (ctx->exception == POWERPC_EXCP_NONE) {
                    283:         gen_update_nip(ctx, ctx->nip);
                    284:     }
                    285:     t0 = tcg_const_i32(excp);
                    286:     gen_helper_raise_exception(t0);
                    287:     tcg_temp_free_i32(t0);
                    288:     ctx->exception = (excp);
                    289: }
1.1.1.5   root      290: 
1.1.1.8   root      291: static inline void gen_debug_exception(DisasContext *ctx)
1.1.1.6   root      292: {
                    293:     TCGv_i32 t0;
1.1       root      294: 
1.1.1.12  root      295:     if ((ctx->exception != POWERPC_EXCP_BRANCH) &&
                    296:         (ctx->exception != POWERPC_EXCP_SYNC)) {
1.1.1.6   root      297:         gen_update_nip(ctx, ctx->nip);
1.1.1.12  root      298:     }
1.1.1.6   root      299:     t0 = tcg_const_i32(EXCP_DEBUG);
                    300:     gen_helper_raise_exception(t0);
                    301:     tcg_temp_free_i32(t0);
                    302: }
1.1       root      303: 
1.1.1.8   root      304: static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
1.1.1.6   root      305: {
                    306:     gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | error);
                    307: }
1.1       root      308: 
1.1.1.2   root      309: /* Stop translation */
1.1.1.8   root      310: static inline void gen_stop_exception(DisasContext *ctx)
1.1       root      311: {
1.1.1.5   root      312:     gen_update_nip(ctx, ctx->nip);
                    313:     ctx->exception = POWERPC_EXCP_STOP;
1.1       root      314: }
                    315: 
1.1.1.2   root      316: /* No need to update nip here, as execution flow will change */
1.1.1.8   root      317: static inline void gen_sync_exception(DisasContext *ctx)
1.1       root      318: {
1.1.1.5   root      319:     ctx->exception = POWERPC_EXCP_SYNC;
1.1       root      320: }
                    321: 
                    322: #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
1.1.1.11  root      323: GEN_OPCODE(name, opc1, opc2, opc3, inval, type, PPC_NONE)
                    324: 
                    325: #define GEN_HANDLER_E(name, opc1, opc2, opc3, inval, type, type2)             \
                    326: GEN_OPCODE(name, opc1, opc2, opc3, inval, type, type2)
1.1       root      327: 
1.1.1.5   root      328: #define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
1.1.1.11  root      329: GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, PPC_NONE)
                    330: 
                    331: #define GEN_HANDLER2_E(name, onam, opc1, opc2, opc3, inval, type, type2)      \
                    332: GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, type2)
1.1.1.5   root      333: 
1.1       root      334: typedef struct opcode_t {
                    335:     unsigned char opc1, opc2, opc3;
1.1.1.6   root      336: #if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
1.1       root      337:     unsigned char pad[5];
                    338: #else
                    339:     unsigned char pad[1];
                    340: #endif
                    341:     opc_handler_t handler;
1.1.1.6   root      342:     const char *oname;
1.1       root      343: } opcode_t;
                    344: 
1.1.1.5   root      345: /*****************************************************************************/
1.1       root      346: /***                           Instruction decoding                        ***/
                    347: #define EXTRACT_HELPER(name, shift, nb)                                       \
1.1.1.8   root      348: static inline uint32_t name(uint32_t opcode)                                  \
1.1       root      349: {                                                                             \
                    350:     return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
                    351: }
                    352: 
                    353: #define EXTRACT_SHELPER(name, shift, nb)                                      \
1.1.1.8   root      354: static inline int32_t name(uint32_t opcode)                                   \
1.1       root      355: {                                                                             \
                    356:     return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
                    357: }
                    358: 
                    359: /* Opcode part 1 */
                    360: EXTRACT_HELPER(opc1, 26, 6);
                    361: /* Opcode part 2 */
                    362: EXTRACT_HELPER(opc2, 1, 5);
                    363: /* Opcode part 3 */
                    364: EXTRACT_HELPER(opc3, 6, 5);
                    365: /* Update Cr0 flags */
                    366: EXTRACT_HELPER(Rc, 0, 1);
                    367: /* Destination */
                    368: EXTRACT_HELPER(rD, 21, 5);
                    369: /* Source */
                    370: EXTRACT_HELPER(rS, 21, 5);
                    371: /* First operand */
                    372: EXTRACT_HELPER(rA, 16, 5);
                    373: /* Second operand */
                    374: EXTRACT_HELPER(rB, 11, 5);
                    375: /* Third operand */
                    376: EXTRACT_HELPER(rC, 6, 5);
                    377: /***                               Get CRn                                 ***/
                    378: EXTRACT_HELPER(crfD, 23, 3);
                    379: EXTRACT_HELPER(crfS, 18, 3);
                    380: EXTRACT_HELPER(crbD, 21, 5);
                    381: EXTRACT_HELPER(crbA, 16, 5);
                    382: EXTRACT_HELPER(crbB, 11, 5);
                    383: /* SPR / TBL */
                    384: EXTRACT_HELPER(_SPR, 11, 10);
1.1.1.8   root      385: static inline uint32_t SPR(uint32_t opcode)
1.1       root      386: {
                    387:     uint32_t sprn = _SPR(opcode);
                    388: 
                    389:     return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
                    390: }
                    391: /***                              Get constants                            ***/
                    392: EXTRACT_HELPER(IMM, 12, 8);
                    393: /* 16 bits signed immediate value */
                    394: EXTRACT_SHELPER(SIMM, 0, 16);
                    395: /* 16 bits unsigned immediate value */
                    396: EXTRACT_HELPER(UIMM, 0, 16);
1.1.1.6   root      397: /* 5 bits signed immediate value */
                    398: EXTRACT_HELPER(SIMM5, 16, 5);
                    399: /* 5 bits signed immediate value */
                    400: EXTRACT_HELPER(UIMM5, 16, 5);
1.1       root      401: /* Bit count */
                    402: EXTRACT_HELPER(NB, 11, 5);
                    403: /* Shift count */
                    404: EXTRACT_HELPER(SH, 11, 5);
1.1.1.6   root      405: /* Vector shift count */
                    406: EXTRACT_HELPER(VSH, 6, 4);
1.1       root      407: /* Mask start */
                    408: EXTRACT_HELPER(MB, 6, 5);
                    409: /* Mask end */
                    410: EXTRACT_HELPER(ME, 1, 5);
                    411: /* Trap operand */
                    412: EXTRACT_HELPER(TO, 21, 5);
                    413: 
                    414: EXTRACT_HELPER(CRM, 12, 8);
                    415: EXTRACT_HELPER(FM, 17, 8);
                    416: EXTRACT_HELPER(SR, 16, 4);
1.1.1.6   root      417: EXTRACT_HELPER(FPIMM, 12, 4);
1.1       root      418: 
                    419: /***                            Jump target decoding                       ***/
                    420: /* Displacement */
                    421: EXTRACT_SHELPER(d, 0, 16);
                    422: /* Immediate address */
1.1.1.8   root      423: static inline target_ulong LI(uint32_t opcode)
1.1       root      424: {
                    425:     return (opcode >> 0) & 0x03FFFFFC;
                    426: }
                    427: 
1.1.1.8   root      428: static inline uint32_t BD(uint32_t opcode)
1.1       root      429: {
                    430:     return (opcode >> 0) & 0xFFFC;
                    431: }
                    432: 
                    433: EXTRACT_HELPER(BO, 21, 5);
                    434: EXTRACT_HELPER(BI, 16, 5);
                    435: /* Absolute/relative address */
                    436: EXTRACT_HELPER(AA, 1, 1);
                    437: /* Link */
                    438: EXTRACT_HELPER(LK, 0, 1);
                    439: 
                    440: /* Create a mask between <start> and <end> bits */
1.1.1.8   root      441: static inline target_ulong MASK(uint32_t start, uint32_t end)
1.1       root      442: {
1.1.1.5   root      443:     target_ulong ret;
1.1       root      444: 
1.1.1.5   root      445: #if defined(TARGET_PPC64)
                    446:     if (likely(start == 0)) {
                    447:         ret = UINT64_MAX << (63 - end);
                    448:     } else if (likely(end == 63)) {
                    449:         ret = UINT64_MAX >> start;
                    450:     }
                    451: #else
                    452:     if (likely(start == 0)) {
                    453:         ret = UINT32_MAX << (31  - end);
                    454:     } else if (likely(end == 31)) {
                    455:         ret = UINT32_MAX >> start;
                    456:     }
                    457: #endif
                    458:     else {
                    459:         ret = (((target_ulong)(-1ULL)) >> (start)) ^
                    460:             (((target_ulong)(-1ULL) >> (end)) >> 1);
                    461:         if (unlikely(start > end))
                    462:             return ~ret;
                    463:     }
1.1       root      464: 
                    465:     return ret;
                    466: }
                    467: 
1.1.1.5   root      468: /*****************************************************************************/
                    469: /* PowerPC instructions table                                                */
1.1       root      470: 
1.1.1.5   root      471: #if defined(DO_PPC_STATISTICS)
1.1.1.11  root      472: #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)                    \
1.1.1.7   root      473: {                                                                             \
1.1.1.5   root      474:     .opc1 = op1,                                                              \
                    475:     .opc2 = op2,                                                              \
                    476:     .opc3 = op3,                                                              \
                    477:     .pad  = { 0, },                                                           \
                    478:     .handler = {                                                              \
1.1.1.12  root      479:         .inval1  = invl,                                                      \
                    480:         .type = _typ,                                                         \
                    481:         .type2 = _typ2,                                                       \
                    482:         .handler = &gen_##name,                                               \
                    483:         .oname = stringify(name),                                             \
                    484:     },                                                                        \
                    485:     .oname = stringify(name),                                                 \
                    486: }
                    487: #define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2)       \
                    488: {                                                                             \
                    489:     .opc1 = op1,                                                              \
                    490:     .opc2 = op2,                                                              \
                    491:     .opc3 = op3,                                                              \
                    492:     .pad  = { 0, },                                                           \
                    493:     .handler = {                                                              \
                    494:         .inval1  = invl1,                                                     \
                    495:         .inval2  = invl2,                                                     \
1.1.1.5   root      496:         .type = _typ,                                                         \
1.1.1.11  root      497:         .type2 = _typ2,                                                       \
1.1.1.5   root      498:         .handler = &gen_##name,                                               \
                    499:         .oname = stringify(name),                                             \
                    500:     },                                                                        \
                    501:     .oname = stringify(name),                                                 \
                    502: }
1.1.1.11  root      503: #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2)             \
1.1.1.7   root      504: {                                                                             \
1.1.1.5   root      505:     .opc1 = op1,                                                              \
                    506:     .opc2 = op2,                                                              \
                    507:     .opc3 = op3,                                                              \
                    508:     .pad  = { 0, },                                                           \
                    509:     .handler = {                                                              \
1.1.1.12  root      510:         .inval1  = invl,                                                      \
1.1.1.5   root      511:         .type = _typ,                                                         \
1.1.1.11  root      512:         .type2 = _typ2,                                                       \
1.1.1.5   root      513:         .handler = &gen_##name,                                               \
                    514:         .oname = onam,                                                        \
                    515:     },                                                                        \
                    516:     .oname = onam,                                                            \
                    517: }
                    518: #else
1.1.1.11  root      519: #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)                    \
1.1.1.7   root      520: {                                                                             \
1.1       root      521:     .opc1 = op1,                                                              \
                    522:     .opc2 = op2,                                                              \
                    523:     .opc3 = op3,                                                              \
                    524:     .pad  = { 0, },                                                           \
                    525:     .handler = {                                                              \
1.1.1.12  root      526:         .inval1  = invl,                                                      \
                    527:         .type = _typ,                                                         \
                    528:         .type2 = _typ2,                                                       \
                    529:         .handler = &gen_##name,                                               \
                    530:     },                                                                        \
                    531:     .oname = stringify(name),                                                 \
                    532: }
                    533: #define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2)       \
                    534: {                                                                             \
                    535:     .opc1 = op1,                                                              \
                    536:     .opc2 = op2,                                                              \
                    537:     .opc3 = op3,                                                              \
                    538:     .pad  = { 0, },                                                           \
                    539:     .handler = {                                                              \
                    540:         .inval1  = invl1,                                                     \
                    541:         .inval2  = invl2,                                                     \
1.1       root      542:         .type = _typ,                                                         \
1.1.1.11  root      543:         .type2 = _typ2,                                                       \
1.1       root      544:         .handler = &gen_##name,                                               \
                    545:     },                                                                        \
                    546:     .oname = stringify(name),                                                 \
                    547: }
1.1.1.11  root      548: #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2)             \
1.1.1.7   root      549: {                                                                             \
1.1.1.5   root      550:     .opc1 = op1,                                                              \
                    551:     .opc2 = op2,                                                              \
                    552:     .opc3 = op3,                                                              \
                    553:     .pad  = { 0, },                                                           \
                    554:     .handler = {                                                              \
1.1.1.12  root      555:         .inval1  = invl,                                                      \
1.1.1.5   root      556:         .type = _typ,                                                         \
1.1.1.11  root      557:         .type2 = _typ2,                                                       \
1.1.1.5   root      558:         .handler = &gen_##name,                                               \
                    559:     },                                                                        \
                    560:     .oname = onam,                                                            \
                    561: }
                    562: #endif
1.1       root      563: 
1.1.1.6   root      564: /* SPR load/store helpers */
1.1.1.8   root      565: static inline void gen_load_spr(TCGv t, int reg)
1.1.1.6   root      566: {
1.1.1.13! root      567:     tcg_gen_ld_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg]));
1.1.1.6   root      568: }
                    569: 
1.1.1.8   root      570: static inline void gen_store_spr(int reg, TCGv t)
1.1.1.6   root      571: {
1.1.1.13! root      572:     tcg_gen_st_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg]));
1.1.1.6   root      573: }
                    574: 
1.1       root      575: /* Invalid instruction */
1.1.1.7   root      576: static void gen_invalid(DisasContext *ctx)
1.1       root      577: {
1.1.1.6   root      578:     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1       root      579: }
                    580: 
                    581: static opc_handler_t invalid_handler = {
1.1.1.12  root      582:     .inval1  = 0xFFFFFFFF,
                    583:     .inval2  = 0xFFFFFFFF,
1.1       root      584:     .type    = PPC_NONE,
1.1.1.11  root      585:     .type2   = PPC_NONE,
1.1       root      586:     .handler = gen_invalid,
                    587: };
                    588: 
1.1.1.6   root      589: /***                           Integer comparison                          ***/
1.1       root      590: 
1.1.1.8   root      591: static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
1.1.1.6   root      592: {
                    593:     int l1, l2, l3;
1.1       root      594: 
1.1.1.6   root      595:     tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_xer);
                    596:     tcg_gen_shri_i32(cpu_crf[crf], cpu_crf[crf], XER_SO);
                    597:     tcg_gen_andi_i32(cpu_crf[crf], cpu_crf[crf], 1);
                    598: 
                    599:     l1 = gen_new_label();
                    600:     l2 = gen_new_label();
                    601:     l3 = gen_new_label();
                    602:     if (s) {
                    603:         tcg_gen_brcond_tl(TCG_COND_LT, arg0, arg1, l1);
                    604:         tcg_gen_brcond_tl(TCG_COND_GT, arg0, arg1, l2);
                    605:     } else {
                    606:         tcg_gen_brcond_tl(TCG_COND_LTU, arg0, arg1, l1);
                    607:         tcg_gen_brcond_tl(TCG_COND_GTU, arg0, arg1, l2);
                    608:     }
                    609:     tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_EQ);
                    610:     tcg_gen_br(l3);
                    611:     gen_set_label(l1);
                    612:     tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_LT);
                    613:     tcg_gen_br(l3);
                    614:     gen_set_label(l2);
                    615:     tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_GT);
                    616:     gen_set_label(l3);
1.1.1.5   root      617: }
                    618: 
1.1.1.8   root      619: static inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
1.1.1.6   root      620: {
                    621:     TCGv t0 = tcg_const_local_tl(arg1);
                    622:     gen_op_cmp(arg0, t0, s, crf);
                    623:     tcg_temp_free(t0);
1.1.1.5   root      624: }
                    625: 
1.1.1.6   root      626: #if defined(TARGET_PPC64)
1.1.1.8   root      627: static inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
1.1.1.6   root      628: {
                    629:     TCGv t0, t1;
                    630:     t0 = tcg_temp_local_new();
                    631:     t1 = tcg_temp_local_new();
                    632:     if (s) {
                    633:         tcg_gen_ext32s_tl(t0, arg0);
                    634:         tcg_gen_ext32s_tl(t1, arg1);
                    635:     } else {
                    636:         tcg_gen_ext32u_tl(t0, arg0);
                    637:         tcg_gen_ext32u_tl(t1, arg1);
                    638:     }
                    639:     gen_op_cmp(t0, t1, s, crf);
                    640:     tcg_temp_free(t1);
                    641:     tcg_temp_free(t0);
1.1.1.5   root      642: }
                    643: 
1.1.1.8   root      644: static inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf)
1.1.1.6   root      645: {
                    646:     TCGv t0 = tcg_const_local_tl(arg1);
                    647:     gen_op_cmp32(arg0, t0, s, crf);
                    648:     tcg_temp_free(t0);
1.1       root      649: }
1.1.1.5   root      650: #endif
1.1       root      651: 
1.1.1.8   root      652: static inline void gen_set_Rc0(DisasContext *ctx, TCGv reg)
1.1.1.5   root      653: {
                    654: #if defined(TARGET_PPC64)
1.1.1.6   root      655:     if (!(ctx->sf_mode))
                    656:         gen_op_cmpi32(reg, 0, 1, 0);
                    657:     else
1.1.1.5   root      658: #endif
1.1.1.6   root      659:         gen_op_cmpi(reg, 0, 1, 0);
1.1.1.5   root      660: }
1.1.1.6   root      661: 
                    662: /* cmp */
1.1.1.7   root      663: static void gen_cmp(DisasContext *ctx)
1.1.1.5   root      664: {
                    665: #if defined(TARGET_PPC64)
1.1.1.6   root      666:     if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
                    667:         gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
                    668:                      1, crfD(ctx->opcode));
                    669:     else
1.1.1.5   root      670: #endif
1.1.1.6   root      671:         gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
                    672:                    1, crfD(ctx->opcode));
1.1.1.5   root      673: }
1.1.1.6   root      674: 
                    675: /* cmpi */
1.1.1.7   root      676: static void gen_cmpi(DisasContext *ctx)
1.1.1.5   root      677: {
1.1.1.6   root      678: #if defined(TARGET_PPC64)
                    679:     if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
                    680:         gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
                    681:                       1, crfD(ctx->opcode));
                    682:     else
1.1.1.5   root      683: #endif
1.1.1.6   root      684:         gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
                    685:                     1, crfD(ctx->opcode));
1.1.1.5   root      686: }
1.1.1.6   root      687: 
                    688: /* cmpl */
1.1.1.7   root      689: static void gen_cmpl(DisasContext *ctx)
1.1.1.5   root      690: {
1.1.1.6   root      691: #if defined(TARGET_PPC64)
                    692:     if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
                    693:         gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
                    694:                      0, crfD(ctx->opcode));
                    695:     else
1.1.1.5   root      696: #endif
1.1.1.6   root      697:         gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
                    698:                    0, crfD(ctx->opcode));
1.1.1.5   root      699: }
1.1.1.6   root      700: 
                    701: /* cmpli */
1.1.1.7   root      702: static void gen_cmpli(DisasContext *ctx)
1.1.1.5   root      703: {
                    704: #if defined(TARGET_PPC64)
1.1.1.6   root      705:     if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
                    706:         gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
                    707:                       0, crfD(ctx->opcode));
                    708:     else
                    709: #endif
                    710:         gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
                    711:                     0, crfD(ctx->opcode));
1.1.1.5   root      712: }
1.1.1.6   root      713: 
                    714: /* isel (PowerPC 2.03 specification) */
1.1.1.7   root      715: static void gen_isel(DisasContext *ctx)
1.1.1.5   root      716: {
1.1.1.6   root      717:     int l1, l2;
                    718:     uint32_t bi = rC(ctx->opcode);
                    719:     uint32_t mask;
                    720:     TCGv_i32 t0;
                    721: 
                    722:     l1 = gen_new_label();
                    723:     l2 = gen_new_label();
                    724: 
                    725:     mask = 1 << (3 - (bi & 0x03));
                    726:     t0 = tcg_temp_new_i32();
                    727:     tcg_gen_andi_i32(t0, cpu_crf[bi >> 2], mask);
                    728:     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
                    729:     if (rA(ctx->opcode) == 0)
                    730:         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
                    731:     else
                    732:         tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                    733:     tcg_gen_br(l2);
                    734:     gen_set_label(l1);
                    735:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                    736:     gen_set_label(l2);
                    737:     tcg_temp_free_i32(t0);
1.1.1.5   root      738: }
1.1.1.6   root      739: 
                    740: /***                           Integer arithmetic                          ***/
                    741: 
1.1.1.8   root      742: static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0,
                    743:                                            TCGv arg1, TCGv arg2, int sub)
1.1.1.5   root      744: {
1.1.1.6   root      745:     int l1;
                    746:     TCGv t0;
                    747: 
                    748:     l1 = gen_new_label();
                    749:     /* Start with XER OV disabled, the most likely case */
                    750:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                    751:     t0 = tcg_temp_local_new();
                    752:     tcg_gen_xor_tl(t0, arg0, arg1);
1.1.1.5   root      753: #if defined(TARGET_PPC64)
1.1.1.6   root      754:     if (!ctx->sf_mode)
                    755:         tcg_gen_ext32s_tl(t0, t0);
1.1.1.5   root      756: #endif
1.1.1.6   root      757:     if (sub)
                    758:         tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
                    759:     else
                    760:         tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
                    761:     tcg_gen_xor_tl(t0, arg1, arg2);
                    762: #if defined(TARGET_PPC64)
                    763:     if (!ctx->sf_mode)
                    764:         tcg_gen_ext32s_tl(t0, t0);
                    765: #endif
                    766:     if (sub)
                    767:         tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
                    768:     else
                    769:         tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
                    770:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                    771:     gen_set_label(l1);
                    772:     tcg_temp_free(t0);
1.1.1.5   root      773: }
1.1.1.6   root      774: 
1.1.1.8   root      775: static inline void gen_op_arith_compute_ca(DisasContext *ctx, TCGv arg1,
                    776:                                            TCGv arg2, int sub)
1.1.1.5   root      777: {
1.1.1.6   root      778:     int l1 = gen_new_label();
                    779: 
1.1.1.5   root      780: #if defined(TARGET_PPC64)
1.1.1.6   root      781:     if (!(ctx->sf_mode)) {
                    782:         TCGv t0, t1;
                    783:         t0 = tcg_temp_new();
                    784:         t1 = tcg_temp_new();
                    785: 
                    786:         tcg_gen_ext32u_tl(t0, arg1);
                    787:         tcg_gen_ext32u_tl(t1, arg2);
                    788:         if (sub) {
                    789:             tcg_gen_brcond_tl(TCG_COND_GTU, t0, t1, l1);
                    790:         } else {
                    791:             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
                    792:         }
                    793:         tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
                    794:         gen_set_label(l1);
                    795:         tcg_temp_free(t0);
                    796:         tcg_temp_free(t1);
                    797:     } else
                    798: #endif
                    799:     {
                    800:         if (sub) {
                    801:             tcg_gen_brcond_tl(TCG_COND_GTU, arg1, arg2, l1);
                    802:         } else {
                    803:             tcg_gen_brcond_tl(TCG_COND_GEU, arg1, arg2, l1);
                    804:         }
                    805:         tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
                    806:         gen_set_label(l1);
                    807:     }
1.1.1.5   root      808: }
1.1.1.6   root      809: 
                    810: /* Common add function */
1.1.1.8   root      811: static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1,
                    812:                                     TCGv arg2, int add_ca, int compute_ca,
                    813:                                     int compute_ov)
1.1.1.6   root      814: {
                    815:     TCGv t0, t1;
                    816: 
                    817:     if ((!compute_ca && !compute_ov) ||
                    818:         (!TCGV_EQUAL(ret,arg1) && !TCGV_EQUAL(ret, arg2)))  {
                    819:         t0 = ret;
                    820:     } else {
                    821:         t0 = tcg_temp_local_new();
                    822:     }
                    823: 
                    824:     if (add_ca) {
                    825:         t1 = tcg_temp_local_new();
                    826:         tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
                    827:         tcg_gen_shri_tl(t1, t1, XER_CA);
1.1.1.7   root      828:     } else {
                    829:         TCGV_UNUSED(t1);
1.1.1.6   root      830:     }
                    831: 
                    832:     if (compute_ca && compute_ov) {
                    833:         /* Start with XER CA and OV disabled, the most likely case */
                    834:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
                    835:     } else if (compute_ca) {
                    836:         /* Start with XER CA disabled, the most likely case */
                    837:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
                    838:     } else if (compute_ov) {
                    839:         /* Start with XER OV disabled, the most likely case */
                    840:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                    841:     }
                    842: 
                    843:     tcg_gen_add_tl(t0, arg1, arg2);
                    844: 
                    845:     if (compute_ca) {
                    846:         gen_op_arith_compute_ca(ctx, t0, arg1, 0);
                    847:     }
                    848:     if (add_ca) {
                    849:         tcg_gen_add_tl(t0, t0, t1);
                    850:         gen_op_arith_compute_ca(ctx, t0, t1, 0);
                    851:         tcg_temp_free(t1);
                    852:     }
                    853:     if (compute_ov) {
                    854:         gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0);
                    855:     }
                    856: 
                    857:     if (unlikely(Rc(ctx->opcode) != 0))
                    858:         gen_set_Rc0(ctx, t0);
                    859: 
                    860:     if (!TCGV_EQUAL(t0, ret)) {
                    861:         tcg_gen_mov_tl(ret, t0);
                    862:         tcg_temp_free(t0);
                    863:     }
1.1.1.5   root      864: }
1.1.1.6   root      865: /* Add functions with two operands */
                    866: #define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
1.1.1.7   root      867: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.6   root      868: {                                                                             \
                    869:     gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
                    870:                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
                    871:                      add_ca, compute_ca, compute_ov);                         \
1.1.1.5   root      872: }
1.1.1.6   root      873: /* Add functions with one operand and one immediate */
                    874: #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
                    875:                                 add_ca, compute_ca, compute_ov)               \
1.1.1.7   root      876: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.6   root      877: {                                                                             \
                    878:     TCGv t0 = tcg_const_local_tl(const_val);                                  \
                    879:     gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
                    880:                      cpu_gpr[rA(ctx->opcode)], t0,                            \
                    881:                      add_ca, compute_ca, compute_ov);                         \
                    882:     tcg_temp_free(t0);                                                        \
1.1.1.5   root      883: }
1.1.1.6   root      884: 
                    885: /* add  add.  addo  addo. */
                    886: GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
                    887: GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
                    888: /* addc  addc.  addco  addco. */
                    889: GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
                    890: GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
                    891: /* adde  adde.  addeo  addeo. */
                    892: GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
                    893: GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
                    894: /* addme  addme.  addmeo  addmeo.  */
                    895: GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
                    896: GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
                    897: /* addze  addze.  addzeo  addzeo.*/
                    898: GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
                    899: GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
1.1       root      900: /* addi */
1.1.1.7   root      901: static void gen_addi(DisasContext *ctx)
1.1       root      902: {
1.1.1.5   root      903:     target_long simm = SIMM(ctx->opcode);
1.1       root      904: 
                    905:     if (rA(ctx->opcode) == 0) {
1.1.1.5   root      906:         /* li case */
1.1.1.6   root      907:         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm);
1.1       root      908:     } else {
1.1.1.6   root      909:         tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], simm);
1.1       root      910:     }
                    911: }
1.1.1.6   root      912: /* addic  addic.*/
1.1.1.8   root      913: static inline void gen_op_addic(DisasContext *ctx, TCGv ret, TCGv arg1,
                    914:                                 int compute_Rc0)
1.1       root      915: {
1.1.1.5   root      916:     target_long simm = SIMM(ctx->opcode);
                    917: 
1.1.1.6   root      918:     /* Start with XER CA and OV disabled, the most likely case */
                    919:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
                    920: 
1.1.1.5   root      921:     if (likely(simm != 0)) {
1.1.1.6   root      922:         TCGv t0 = tcg_temp_local_new();
                    923:         tcg_gen_addi_tl(t0, arg1, simm);
                    924:         gen_op_arith_compute_ca(ctx, t0, arg1, 0);
                    925:         tcg_gen_mov_tl(ret, t0);
                    926:         tcg_temp_free(t0);
1.1.1.5   root      927:     } else {
1.1.1.6   root      928:         tcg_gen_mov_tl(ret, arg1);
                    929:     }
                    930:     if (compute_Rc0) {
                    931:         gen_set_Rc0(ctx, ret);
1.1.1.5   root      932:     }
1.1       root      933: }
1.1.1.7   root      934: 
                    935: static void gen_addic(DisasContext *ctx)
1.1.1.6   root      936: {
                    937:     gen_op_addic(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
                    938: }
1.1.1.7   root      939: 
                    940: static void gen_addic_(DisasContext *ctx)
1.1       root      941: {
1.1.1.6   root      942:     gen_op_addic(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
1.1       root      943: }
1.1.1.7   root      944: 
1.1       root      945: /* addis */
1.1.1.7   root      946: static void gen_addis(DisasContext *ctx)
1.1       root      947: {
1.1.1.5   root      948:     target_long simm = SIMM(ctx->opcode);
1.1       root      949: 
                    950:     if (rA(ctx->opcode) == 0) {
1.1.1.5   root      951:         /* lis case */
1.1.1.6   root      952:         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm << 16);
1.1       root      953:     } else {
1.1.1.6   root      954:         tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], simm << 16);
1.1       root      955:     }
                    956: }
                    957: 
1.1.1.8   root      958: static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, TCGv arg1,
                    959:                                      TCGv arg2, int sign, int compute_ov)
1.1.1.6   root      960: {
                    961:     int l1 = gen_new_label();
                    962:     int l2 = gen_new_label();
                    963:     TCGv_i32 t0 = tcg_temp_local_new_i32();
                    964:     TCGv_i32 t1 = tcg_temp_local_new_i32();
                    965: 
                    966:     tcg_gen_trunc_tl_i32(t0, arg1);
                    967:     tcg_gen_trunc_tl_i32(t1, arg2);
                    968:     tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l1);
                    969:     if (sign) {
                    970:         int l3 = gen_new_label();
                    971:         tcg_gen_brcondi_i32(TCG_COND_NE, t1, -1, l3);
                    972:         tcg_gen_brcondi_i32(TCG_COND_EQ, t0, INT32_MIN, l1);
                    973:         gen_set_label(l3);
                    974:         tcg_gen_div_i32(t0, t0, t1);
                    975:     } else {
                    976:         tcg_gen_divu_i32(t0, t0, t1);
                    977:     }
                    978:     if (compute_ov) {
                    979:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                    980:     }
                    981:     tcg_gen_br(l2);
                    982:     gen_set_label(l1);
                    983:     if (sign) {
                    984:         tcg_gen_sari_i32(t0, t0, 31);
                    985:     } else {
                    986:         tcg_gen_movi_i32(t0, 0);
                    987:     }
                    988:     if (compute_ov) {
                    989:         tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                    990:     }
                    991:     gen_set_label(l2);
                    992:     tcg_gen_extu_i32_tl(ret, t0);
                    993:     tcg_temp_free_i32(t0);
                    994:     tcg_temp_free_i32(t1);
                    995:     if (unlikely(Rc(ctx->opcode) != 0))
                    996:         gen_set_Rc0(ctx, ret);
                    997: }
                    998: /* Div functions */
                    999: #define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
1.1.1.7   root     1000: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.6   root     1001: {                                                                             \
                   1002:     gen_op_arith_divw(ctx, cpu_gpr[rD(ctx->opcode)],                          \
                   1003:                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
                   1004:                      sign, compute_ov);                                       \
                   1005: }
                   1006: /* divwu  divwu.  divwuo  divwuo.   */
                   1007: GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0);
                   1008: GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1);
                   1009: /* divw  divw.  divwo  divwo.   */
                   1010: GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0);
                   1011: GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1);
                   1012: #if defined(TARGET_PPC64)
1.1.1.8   root     1013: static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1,
                   1014:                                      TCGv arg2, int sign, int compute_ov)
1.1.1.6   root     1015: {
                   1016:     int l1 = gen_new_label();
                   1017:     int l2 = gen_new_label();
                   1018: 
                   1019:     tcg_gen_brcondi_i64(TCG_COND_EQ, arg2, 0, l1);
                   1020:     if (sign) {
                   1021:         int l3 = gen_new_label();
                   1022:         tcg_gen_brcondi_i64(TCG_COND_NE, arg2, -1, l3);
                   1023:         tcg_gen_brcondi_i64(TCG_COND_EQ, arg1, INT64_MIN, l1);
                   1024:         gen_set_label(l3);
                   1025:         tcg_gen_div_i64(ret, arg1, arg2);
                   1026:     } else {
                   1027:         tcg_gen_divu_i64(ret, arg1, arg2);
                   1028:     }
                   1029:     if (compute_ov) {
                   1030:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                   1031:     }
                   1032:     tcg_gen_br(l2);
                   1033:     gen_set_label(l1);
                   1034:     if (sign) {
                   1035:         tcg_gen_sari_i64(ret, arg1, 63);
                   1036:     } else {
                   1037:         tcg_gen_movi_i64(ret, 0);
                   1038:     }
                   1039:     if (compute_ov) {
                   1040:         tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                   1041:     }
                   1042:     gen_set_label(l2);
                   1043:     if (unlikely(Rc(ctx->opcode) != 0))
                   1044:         gen_set_Rc0(ctx, ret);
1.1.1.5   root     1045: }
1.1.1.6   root     1046: #define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
1.1.1.7   root     1047: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1       root     1048: {                                                                             \
1.1.1.6   root     1049:     gen_op_arith_divd(ctx, cpu_gpr[rD(ctx->opcode)],                          \
                   1050:                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
                   1051:                       sign, compute_ov);                                      \
1.1       root     1052: }
1.1.1.6   root     1053: /* divwu  divwu.  divwuo  divwuo.   */
                   1054: GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0);
                   1055: GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1);
                   1056: /* divw  divw.  divwo  divwo.   */
                   1057: GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0);
                   1058: GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
1.1.1.5   root     1059: #endif
1.1       root     1060: 
1.1.1.6   root     1061: /* mulhw  mulhw. */
1.1.1.7   root     1062: static void gen_mulhw(DisasContext *ctx)
1.1       root     1063: {
1.1.1.6   root     1064:     TCGv_i64 t0, t1;
                   1065: 
                   1066:     t0 = tcg_temp_new_i64();
                   1067:     t1 = tcg_temp_new_i64();
1.1.1.5   root     1068: #if defined(TARGET_PPC64)
1.1.1.6   root     1069:     tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
                   1070:     tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
                   1071:     tcg_gen_mul_i64(t0, t0, t1);
                   1072:     tcg_gen_shri_i64(cpu_gpr[rD(ctx->opcode)], t0, 32);
                   1073: #else
                   1074:     tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   1075:     tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   1076:     tcg_gen_mul_i64(t0, t0, t1);
                   1077:     tcg_gen_shri_i64(t0, t0, 32);
                   1078:     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
1.1.1.5   root     1079: #endif
1.1.1.6   root     1080:     tcg_temp_free_i64(t0);
                   1081:     tcg_temp_free_i64(t1);
                   1082:     if (unlikely(Rc(ctx->opcode) != 0))
                   1083:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1       root     1084: }
1.1.1.7   root     1085: 
1.1.1.6   root     1086: /* mulhwu  mulhwu.  */
1.1.1.7   root     1087: static void gen_mulhwu(DisasContext *ctx)
1.1       root     1088: {
1.1.1.6   root     1089:     TCGv_i64 t0, t1;
                   1090: 
                   1091:     t0 = tcg_temp_new_i64();
                   1092:     t1 = tcg_temp_new_i64();
1.1.1.5   root     1093: #if defined(TARGET_PPC64)
1.1.1.6   root     1094:     tcg_gen_ext32u_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   1095:     tcg_gen_ext32u_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   1096:     tcg_gen_mul_i64(t0, t0, t1);
                   1097:     tcg_gen_shri_i64(cpu_gpr[rD(ctx->opcode)], t0, 32);
                   1098: #else
                   1099:     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   1100:     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   1101:     tcg_gen_mul_i64(t0, t0, t1);
                   1102:     tcg_gen_shri_i64(t0, t0, 32);
                   1103:     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
1.1.1.5   root     1104: #endif
1.1.1.6   root     1105:     tcg_temp_free_i64(t0);
                   1106:     tcg_temp_free_i64(t1);
                   1107:     if (unlikely(Rc(ctx->opcode) != 0))
                   1108:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
                   1109: }
1.1.1.7   root     1110: 
1.1.1.6   root     1111: /* mullw  mullw. */
1.1.1.7   root     1112: static void gen_mullw(DisasContext *ctx)
1.1.1.6   root     1113: {
                   1114:     tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
                   1115:                    cpu_gpr[rB(ctx->opcode)]);
                   1116:     tcg_gen_ext32s_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)]);
                   1117:     if (unlikely(Rc(ctx->opcode) != 0))
                   1118:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1       root     1119: }
1.1.1.7   root     1120: 
1.1.1.6   root     1121: /* mullwo  mullwo. */
1.1.1.7   root     1122: static void gen_mullwo(DisasContext *ctx)
1.1.1.6   root     1123: {
                   1124:     int l1;
                   1125:     TCGv_i64 t0, t1;
1.1       root     1126: 
1.1.1.6   root     1127:     t0 = tcg_temp_new_i64();
                   1128:     t1 = tcg_temp_new_i64();
                   1129:     l1 = gen_new_label();
                   1130:     /* Start with XER OV disabled, the most likely case */
                   1131:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                   1132: #if defined(TARGET_PPC64)
                   1133:     tcg_gen_ext32s_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   1134:     tcg_gen_ext32s_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   1135: #else
                   1136:     tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   1137:     tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   1138: #endif
                   1139:     tcg_gen_mul_i64(t0, t0, t1);
                   1140: #if defined(TARGET_PPC64)
                   1141:     tcg_gen_ext32s_i64(cpu_gpr[rD(ctx->opcode)], t0);
                   1142:     tcg_gen_brcond_i64(TCG_COND_EQ, t0, cpu_gpr[rD(ctx->opcode)], l1);
                   1143: #else
                   1144:     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   1145:     tcg_gen_ext32s_i64(t1, t0);
                   1146:     tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
                   1147: #endif
                   1148:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                   1149:     gen_set_label(l1);
                   1150:     tcg_temp_free_i64(t0);
                   1151:     tcg_temp_free_i64(t1);
                   1152:     if (unlikely(Rc(ctx->opcode) != 0))
                   1153:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
                   1154: }
1.1.1.7   root     1155: 
1.1.1.6   root     1156: /* mulli */
1.1.1.7   root     1157: static void gen_mulli(DisasContext *ctx)
1.1.1.5   root     1158: {
1.1.1.6   root     1159:     tcg_gen_muli_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
                   1160:                     SIMM(ctx->opcode));
                   1161: }
                   1162: #if defined(TARGET_PPC64)
                   1163: #define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
1.1.1.7   root     1164: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.6   root     1165: {                                                                             \
                   1166:     gen_helper_##name (cpu_gpr[rD(ctx->opcode)],                              \
                   1167:                        cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);   \
                   1168:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
                   1169:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);                           \
                   1170: }
                   1171: /* mulhd  mulhd. */
                   1172: GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00);
                   1173: /* mulhdu  mulhdu. */
                   1174: GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02);
1.1.1.7   root     1175: 
1.1.1.6   root     1176: /* mulld  mulld. */
1.1.1.7   root     1177: static void gen_mulld(DisasContext *ctx)
1.1.1.6   root     1178: {
                   1179:     tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
                   1180:                    cpu_gpr[rB(ctx->opcode)]);
                   1181:     if (unlikely(Rc(ctx->opcode) != 0))
                   1182:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
                   1183: }
                   1184: /* mulldo  mulldo. */
                   1185: GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17);
                   1186: #endif
1.1.1.5   root     1187: 
1.1.1.6   root     1188: /* neg neg. nego nego. */
1.1.1.8   root     1189: static inline void gen_op_arith_neg(DisasContext *ctx, TCGv ret, TCGv arg1,
                   1190:                                     int ov_check)
1.1.1.6   root     1191: {
                   1192:     int l1 = gen_new_label();
                   1193:     int l2 = gen_new_label();
                   1194:     TCGv t0 = tcg_temp_local_new();
                   1195: #if defined(TARGET_PPC64)
                   1196:     if (ctx->sf_mode) {
                   1197:         tcg_gen_mov_tl(t0, arg1);
                   1198:         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT64_MIN, l1);
                   1199:     } else
                   1200: #endif
                   1201:     {
                   1202:         tcg_gen_ext32s_tl(t0, arg1);
                   1203:         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT32_MIN, l1);
                   1204:     }
                   1205:     tcg_gen_neg_tl(ret, arg1);
                   1206:     if (ov_check) {
                   1207:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                   1208:     }
                   1209:     tcg_gen_br(l2);
                   1210:     gen_set_label(l1);
                   1211:     tcg_gen_mov_tl(ret, t0);
                   1212:     if (ov_check) {
                   1213:         tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                   1214:     }
                   1215:     gen_set_label(l2);
                   1216:     tcg_temp_free(t0);
                   1217:     if (unlikely(Rc(ctx->opcode) != 0))
                   1218:         gen_set_Rc0(ctx, ret);
                   1219: }
1.1.1.7   root     1220: 
                   1221: static void gen_neg(DisasContext *ctx)
1.1.1.6   root     1222: {
                   1223:     gen_op_arith_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
                   1224: }
1.1.1.7   root     1225: 
                   1226: static void gen_nego(DisasContext *ctx)
1.1.1.6   root     1227: {
                   1228:     gen_op_arith_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
                   1229: }
                   1230: 
                   1231: /* Common subf function */
1.1.1.8   root     1232: static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,
                   1233:                                      TCGv arg2, int add_ca, int compute_ca,
                   1234:                                      int compute_ov)
1.1.1.6   root     1235: {
                   1236:     TCGv t0, t1;
                   1237: 
                   1238:     if ((!compute_ca && !compute_ov) ||
                   1239:         (!TCGV_EQUAL(ret, arg1) && !TCGV_EQUAL(ret, arg2)))  {
                   1240:         t0 = ret;
1.1.1.5   root     1241:     } else {
1.1.1.6   root     1242:         t0 = tcg_temp_local_new();
1.1.1.5   root     1243:     }
1.1.1.6   root     1244: 
                   1245:     if (add_ca) {
                   1246:         t1 = tcg_temp_local_new();
                   1247:         tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
                   1248:         tcg_gen_shri_tl(t1, t1, XER_CA);
1.1.1.7   root     1249:     } else {
                   1250:         TCGV_UNUSED(t1);
1.1.1.6   root     1251:     }
                   1252: 
                   1253:     if (compute_ca && compute_ov) {
                   1254:         /* Start with XER CA and OV disabled, the most likely case */
                   1255:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
                   1256:     } else if (compute_ca) {
                   1257:         /* Start with XER CA disabled, the most likely case */
                   1258:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
                   1259:     } else if (compute_ov) {
                   1260:         /* Start with XER OV disabled, the most likely case */
                   1261:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                   1262:     }
                   1263: 
                   1264:     if (add_ca) {
                   1265:         tcg_gen_not_tl(t0, arg1);
                   1266:         tcg_gen_add_tl(t0, t0, arg2);
                   1267:         gen_op_arith_compute_ca(ctx, t0, arg2, 0);
                   1268:         tcg_gen_add_tl(t0, t0, t1);
                   1269:         gen_op_arith_compute_ca(ctx, t0, t1, 0);
                   1270:         tcg_temp_free(t1);
                   1271:     } else {
                   1272:         tcg_gen_sub_tl(t0, arg2, arg1);
                   1273:         if (compute_ca) {
                   1274:             gen_op_arith_compute_ca(ctx, t0, arg2, 1);
                   1275:         }
                   1276:     }
                   1277:     if (compute_ov) {
                   1278:         gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1);
                   1279:     }
                   1280: 
                   1281:     if (unlikely(Rc(ctx->opcode) != 0))
                   1282:         gen_set_Rc0(ctx, t0);
                   1283: 
                   1284:     if (!TCGV_EQUAL(t0, ret)) {
                   1285:         tcg_gen_mov_tl(ret, t0);
                   1286:         tcg_temp_free(t0);
                   1287:     }
                   1288: }
                   1289: /* Sub functions with Two operands functions */
                   1290: #define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
1.1.1.7   root     1291: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.6   root     1292: {                                                                             \
                   1293:     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
                   1294:                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
                   1295:                       add_ca, compute_ca, compute_ov);                        \
                   1296: }
                   1297: /* Sub functions with one operand and one immediate */
                   1298: #define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
                   1299:                                 add_ca, compute_ca, compute_ov)               \
1.1.1.7   root     1300: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.6   root     1301: {                                                                             \
                   1302:     TCGv t0 = tcg_const_local_tl(const_val);                                  \
                   1303:     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
                   1304:                       cpu_gpr[rA(ctx->opcode)], t0,                           \
                   1305:                       add_ca, compute_ca, compute_ov);                        \
                   1306:     tcg_temp_free(t0);                                                        \
                   1307: }
                   1308: /* subf  subf.  subfo  subfo. */
                   1309: GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
                   1310: GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
                   1311: /* subfc  subfc.  subfco  subfco. */
                   1312: GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
                   1313: GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
                   1314: /* subfe  subfe.  subfeo  subfo. */
                   1315: GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
                   1316: GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
                   1317: /* subfme  subfme.  subfmeo  subfmeo.  */
                   1318: GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
                   1319: GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
                   1320: /* subfze  subfze.  subfzeo  subfzeo.*/
                   1321: GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
                   1322: GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
1.1.1.7   root     1323: 
1.1.1.6   root     1324: /* subfic */
1.1.1.7   root     1325: static void gen_subfic(DisasContext *ctx)
1.1.1.6   root     1326: {
                   1327:     /* Start with XER CA and OV disabled, the most likely case */
                   1328:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
                   1329:     TCGv t0 = tcg_temp_local_new();
                   1330:     TCGv t1 = tcg_const_local_tl(SIMM(ctx->opcode));
                   1331:     tcg_gen_sub_tl(t0, t1, cpu_gpr[rA(ctx->opcode)]);
                   1332:     gen_op_arith_compute_ca(ctx, t0, t1, 1);
                   1333:     tcg_temp_free(t1);
                   1334:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   1335:     tcg_temp_free(t0);
1.1.1.5   root     1336: }
                   1337: 
1.1       root     1338: /***                            Integer logical                            ***/
1.1.1.6   root     1339: #define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
1.1.1.7   root     1340: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1       root     1341: {                                                                             \
1.1.1.6   root     1342:     tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],                \
                   1343:        cpu_gpr[rB(ctx->opcode)]);                                             \
1.1.1.5   root     1344:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1.1.1.6   root     1345:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1.1       root     1346: }
                   1347: 
1.1.1.6   root     1348: #define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
1.1.1.7   root     1349: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1       root     1350: {                                                                             \
1.1.1.6   root     1351:     tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);               \
1.1.1.5   root     1352:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1.1.1.6   root     1353:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1.1       root     1354: }
                   1355: 
                   1356: /* and & and. */
1.1.1.6   root     1357: GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
1.1       root     1358: /* andc & andc. */
1.1.1.6   root     1359: GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
1.1.1.7   root     1360: 
1.1       root     1361: /* andi. */
1.1.1.7   root     1362: static void gen_andi_(DisasContext *ctx)
1.1       root     1363: {
1.1.1.6   root     1364:     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode));
                   1365:     gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1366: }
1.1.1.7   root     1367: 
1.1       root     1368: /* andis. */
1.1.1.7   root     1369: static void gen_andis_(DisasContext *ctx)
1.1       root     1370: {
1.1.1.6   root     1371:     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode) << 16);
                   1372:     gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1373: }
1.1.1.7   root     1374: 
1.1       root     1375: /* cntlzw */
1.1.1.7   root     1376: static void gen_cntlzw(DisasContext *ctx)
1.1.1.6   root     1377: {
                   1378:     gen_helper_cntlzw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1379:     if (unlikely(Rc(ctx->opcode) != 0))
                   1380:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
                   1381: }
1.1       root     1382: /* eqv & eqv. */
1.1.1.6   root     1383: GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
1.1       root     1384: /* extsb & extsb. */
1.1.1.6   root     1385: GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
1.1       root     1386: /* extsh & extsh. */
1.1.1.6   root     1387: GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
1.1       root     1388: /* nand & nand. */
1.1.1.6   root     1389: GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
1.1       root     1390: /* nor & nor. */
1.1.1.6   root     1391: GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
1.1.1.7   root     1392: 
1.1       root     1393: /* or & or. */
1.1.1.7   root     1394: static void gen_or(DisasContext *ctx)
1.1       root     1395: {
1.1.1.5   root     1396:     int rs, ra, rb;
                   1397: 
                   1398:     rs = rS(ctx->opcode);
                   1399:     ra = rA(ctx->opcode);
                   1400:     rb = rB(ctx->opcode);
                   1401:     /* Optimisation for mr. ri case */
                   1402:     if (rs != ra || rs != rb) {
1.1.1.6   root     1403:         if (rs != rb)
                   1404:             tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]);
                   1405:         else
                   1406:             tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]);
1.1.1.5   root     1407:         if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1408:             gen_set_Rc0(ctx, cpu_gpr[ra]);
1.1.1.5   root     1409:     } else if (unlikely(Rc(ctx->opcode) != 0)) {
1.1.1.6   root     1410:         gen_set_Rc0(ctx, cpu_gpr[rs]);
1.1.1.5   root     1411: #if defined(TARGET_PPC64)
                   1412:     } else {
1.1.1.6   root     1413:         int prio = 0;
                   1414: 
1.1.1.5   root     1415:         switch (rs) {
                   1416:         case 1:
                   1417:             /* Set process priority to low */
1.1.1.6   root     1418:             prio = 2;
1.1.1.5   root     1419:             break;
                   1420:         case 6:
                   1421:             /* Set process priority to medium-low */
1.1.1.6   root     1422:             prio = 3;
1.1.1.5   root     1423:             break;
                   1424:         case 2:
                   1425:             /* Set process priority to normal */
1.1.1.6   root     1426:             prio = 4;
1.1.1.5   root     1427:             break;
                   1428: #if !defined(CONFIG_USER_ONLY)
                   1429:         case 31:
1.1.1.6   root     1430:             if (ctx->mem_idx > 0) {
1.1.1.5   root     1431:                 /* Set process priority to very low */
1.1.1.6   root     1432:                 prio = 1;
1.1.1.5   root     1433:             }
                   1434:             break;
                   1435:         case 5:
1.1.1.6   root     1436:             if (ctx->mem_idx > 0) {
1.1.1.5   root     1437:                 /* Set process priority to medium-hight */
1.1.1.6   root     1438:                 prio = 5;
1.1.1.5   root     1439:             }
                   1440:             break;
                   1441:         case 3:
1.1.1.6   root     1442:             if (ctx->mem_idx > 0) {
1.1.1.5   root     1443:                 /* Set process priority to high */
1.1.1.6   root     1444:                 prio = 6;
1.1.1.5   root     1445:             }
                   1446:             break;
                   1447:         case 7:
1.1.1.6   root     1448:             if (ctx->mem_idx > 1) {
1.1.1.5   root     1449:                 /* Set process priority to very high */
1.1.1.6   root     1450:                 prio = 7;
1.1.1.5   root     1451:             }
                   1452:             break;
                   1453: #endif
                   1454:         default:
                   1455:             /* nop */
                   1456:             break;
                   1457:         }
1.1.1.6   root     1458:         if (prio) {
                   1459:             TCGv t0 = tcg_temp_new();
                   1460:             gen_load_spr(t0, SPR_PPR);
                   1461:             tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
                   1462:             tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
                   1463:             gen_store_spr(SPR_PPR, t0);
                   1464:             tcg_temp_free(t0);
                   1465:         }
1.1.1.5   root     1466: #endif
1.1       root     1467:     }
                   1468: }
                   1469: /* orc & orc. */
1.1.1.6   root     1470: GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
1.1.1.7   root     1471: 
1.1       root     1472: /* xor & xor. */
1.1.1.7   root     1473: static void gen_xor(DisasContext *ctx)
1.1       root     1474: {
                   1475:     /* Optimisation for "set to zero" case */
1.1.1.6   root     1476:     if (rS(ctx->opcode) != rB(ctx->opcode))
                   1477:         tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   1478:     else
                   1479:         tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1.1.1.5   root     1480:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1481:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1482: }
1.1.1.7   root     1483: 
1.1       root     1484: /* ori */
1.1.1.7   root     1485: static void gen_ori(DisasContext *ctx)
1.1       root     1486: {
1.1.1.5   root     1487:     target_ulong uimm = UIMM(ctx->opcode);
1.1       root     1488: 
                   1489:     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
                   1490:         /* NOP */
1.1.1.5   root     1491:         /* XXX: should handle special NOPs for POWER series */
1.1       root     1492:         return;
1.1.1.5   root     1493:     }
1.1.1.6   root     1494:     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1.1       root     1495: }
1.1.1.7   root     1496: 
1.1       root     1497: /* oris */
1.1.1.7   root     1498: static void gen_oris(DisasContext *ctx)
1.1       root     1499: {
1.1.1.5   root     1500:     target_ulong uimm = UIMM(ctx->opcode);
1.1       root     1501: 
                   1502:     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
                   1503:         /* NOP */
                   1504:         return;
1.1.1.5   root     1505:     }
1.1.1.6   root     1506:     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1.1       root     1507: }
1.1.1.7   root     1508: 
1.1       root     1509: /* xori */
1.1.1.7   root     1510: static void gen_xori(DisasContext *ctx)
1.1       root     1511: {
1.1.1.5   root     1512:     target_ulong uimm = UIMM(ctx->opcode);
1.1       root     1513: 
                   1514:     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
                   1515:         /* NOP */
                   1516:         return;
                   1517:     }
1.1.1.6   root     1518:     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1.1       root     1519: }
1.1.1.7   root     1520: 
1.1       root     1521: /* xoris */
1.1.1.7   root     1522: static void gen_xoris(DisasContext *ctx)
1.1       root     1523: {
1.1.1.5   root     1524:     target_ulong uimm = UIMM(ctx->opcode);
1.1       root     1525: 
                   1526:     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
                   1527:         /* NOP */
                   1528:         return;
                   1529:     }
1.1.1.6   root     1530:     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1.1.1.5   root     1531: }
1.1.1.7   root     1532: 
1.1.1.5   root     1533: /* popcntb : PowerPC 2.03 specification */
1.1.1.7   root     1534: static void gen_popcntb(DisasContext *ctx)
1.1.1.5   root     1535: {
1.1.1.11  root     1536:     gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1537: }
                   1538: 
                   1539: static void gen_popcntw(DisasContext *ctx)
                   1540: {
                   1541:     gen_helper_popcntw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1542: }
                   1543: 
1.1.1.5   root     1544: #if defined(TARGET_PPC64)
1.1.1.11  root     1545: /* popcntd: PowerPC 2.06 specification */
                   1546: static void gen_popcntd(DisasContext *ctx)
                   1547: {
                   1548:     gen_helper_popcntd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1.1       root     1549: }
1.1.1.11  root     1550: #endif
1.1       root     1551: 
1.1.1.5   root     1552: #if defined(TARGET_PPC64)
                   1553: /* extsw & extsw. */
1.1.1.6   root     1554: GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
1.1.1.7   root     1555: 
1.1.1.5   root     1556: /* cntlzd */
1.1.1.7   root     1557: static void gen_cntlzd(DisasContext *ctx)
1.1.1.6   root     1558: {
                   1559:     gen_helper_cntlzd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1560:     if (unlikely(Rc(ctx->opcode) != 0))
                   1561:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
                   1562: }
1.1.1.5   root     1563: #endif
                   1564: 
1.1       root     1565: /***                             Integer rotate                            ***/
1.1.1.7   root     1566: 
1.1       root     1567: /* rlwimi & rlwimi. */
1.1.1.7   root     1568: static void gen_rlwimi(DisasContext *ctx)
1.1       root     1569: {
1.1.1.5   root     1570:     uint32_t mb, me, sh;
1.1       root     1571: 
                   1572:     mb = MB(ctx->opcode);
                   1573:     me = ME(ctx->opcode);
1.1.1.5   root     1574:     sh = SH(ctx->opcode);
1.1.1.6   root     1575:     if (likely(sh == 0 && mb == 0 && me == 31)) {
                   1576:         tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1577:     } else {
                   1578:         target_ulong mask;
                   1579:         TCGv t1;
                   1580:         TCGv t0 = tcg_temp_new();
                   1581: #if defined(TARGET_PPC64)
                   1582:         TCGv_i32 t2 = tcg_temp_new_i32();
                   1583:         tcg_gen_trunc_i64_i32(t2, cpu_gpr[rS(ctx->opcode)]);
                   1584:         tcg_gen_rotli_i32(t2, t2, sh);
                   1585:         tcg_gen_extu_i32_i64(t0, t2);
                   1586:         tcg_temp_free_i32(t2);
                   1587: #else
                   1588:         tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   1589: #endif
                   1590: #if defined(TARGET_PPC64)
                   1591:         mb += 32;
                   1592:         me += 32;
                   1593: #endif
                   1594:         mask = MASK(mb, me);
                   1595:         t1 = tcg_temp_new();
                   1596:         tcg_gen_andi_tl(t0, t0, mask);
                   1597:         tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
                   1598:         tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   1599:         tcg_temp_free(t0);
                   1600:         tcg_temp_free(t1);
                   1601:     }
1.1.1.5   root     1602:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1603:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1604: }
1.1.1.7   root     1605: 
1.1       root     1606: /* rlwinm & rlwinm. */
1.1.1.7   root     1607: static void gen_rlwinm(DisasContext *ctx)
1.1       root     1608: {
                   1609:     uint32_t mb, me, sh;
1.1.1.5   root     1610: 
1.1       root     1611:     sh = SH(ctx->opcode);
                   1612:     mb = MB(ctx->opcode);
                   1613:     me = ME(ctx->opcode);
1.1.1.6   root     1614: 
                   1615:     if (likely(mb == 0 && me == (31 - sh))) {
                   1616:         if (likely(sh == 0)) {
                   1617:             tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1618:         } else {
                   1619:             TCGv t0 = tcg_temp_new();
                   1620:             tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
                   1621:             tcg_gen_shli_tl(t0, t0, sh);
                   1622:             tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   1623:             tcg_temp_free(t0);
1.1       root     1624:         }
1.1.1.6   root     1625:     } else if (likely(sh != 0 && me == 31 && sh == (32 - mb))) {
                   1626:         TCGv t0 = tcg_temp_new();
                   1627:         tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
                   1628:         tcg_gen_shri_tl(t0, t0, mb);
                   1629:         tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   1630:         tcg_temp_free(t0);
                   1631:     } else {
                   1632:         TCGv t0 = tcg_temp_new();
                   1633: #if defined(TARGET_PPC64)
                   1634:         TCGv_i32 t1 = tcg_temp_new_i32();
                   1635:         tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
                   1636:         tcg_gen_rotli_i32(t1, t1, sh);
                   1637:         tcg_gen_extu_i32_i64(t0, t1);
                   1638:         tcg_temp_free_i32(t1);
                   1639: #else
                   1640:         tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   1641: #endif
1.1.1.5   root     1642: #if defined(TARGET_PPC64)
1.1.1.6   root     1643:         mb += 32;
                   1644:         me += 32;
1.1.1.5   root     1645: #endif
1.1.1.6   root     1646:         tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
                   1647:         tcg_temp_free(t0);
                   1648:     }
1.1.1.5   root     1649:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1650:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1651: }
1.1.1.7   root     1652: 
1.1       root     1653: /* rlwnm & rlwnm. */
1.1.1.7   root     1654: static void gen_rlwnm(DisasContext *ctx)
1.1       root     1655: {
                   1656:     uint32_t mb, me;
1.1.1.6   root     1657:     TCGv t0;
                   1658: #if defined(TARGET_PPC64)
                   1659:     TCGv_i32 t1, t2;
                   1660: #endif
1.1       root     1661: 
                   1662:     mb = MB(ctx->opcode);
                   1663:     me = ME(ctx->opcode);
1.1.1.6   root     1664:     t0 = tcg_temp_new();
                   1665:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1f);
                   1666: #if defined(TARGET_PPC64)
                   1667:     t1 = tcg_temp_new_i32();
                   1668:     t2 = tcg_temp_new_i32();
                   1669:     tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
                   1670:     tcg_gen_trunc_i64_i32(t2, t0);
                   1671:     tcg_gen_rotl_i32(t1, t1, t2);
                   1672:     tcg_gen_extu_i32_i64(t0, t1);
                   1673:     tcg_temp_free_i32(t1);
                   1674:     tcg_temp_free_i32(t2);
                   1675: #else
                   1676:     tcg_gen_rotl_i32(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   1677: #endif
1.1.1.5   root     1678:     if (unlikely(mb != 0 || me != 31)) {
                   1679: #if defined(TARGET_PPC64)
                   1680:         mb += 32;
                   1681:         me += 32;
                   1682: #endif
1.1.1.6   root     1683:         tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
                   1684:     } else {
                   1685:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1.1       root     1686:     }
1.1.1.6   root     1687:     tcg_temp_free(t0);
1.1.1.5   root     1688:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1689:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     1690: }
                   1691: 
                   1692: #if defined(TARGET_PPC64)
                   1693: #define GEN_PPC64_R2(name, opc1, opc2)                                        \
1.1.1.7   root     1694: static void glue(gen_, name##0)(DisasContext *ctx)                            \
1.1.1.5   root     1695: {                                                                             \
                   1696:     gen_##name(ctx, 0);                                                       \
                   1697: }                                                                             \
1.1.1.7   root     1698:                                                                               \
                   1699: static void glue(gen_, name##1)(DisasContext *ctx)                            \
1.1.1.5   root     1700: {                                                                             \
                   1701:     gen_##name(ctx, 1);                                                       \
                   1702: }
                   1703: #define GEN_PPC64_R4(name, opc1, opc2)                                        \
1.1.1.7   root     1704: static void glue(gen_, name##0)(DisasContext *ctx)                            \
1.1.1.5   root     1705: {                                                                             \
                   1706:     gen_##name(ctx, 0, 0);                                                    \
                   1707: }                                                                             \
1.1.1.7   root     1708:                                                                               \
                   1709: static void glue(gen_, name##1)(DisasContext *ctx)                            \
1.1.1.5   root     1710: {                                                                             \
                   1711:     gen_##name(ctx, 0, 1);                                                    \
                   1712: }                                                                             \
1.1.1.7   root     1713:                                                                               \
                   1714: static void glue(gen_, name##2)(DisasContext *ctx)                            \
1.1.1.5   root     1715: {                                                                             \
                   1716:     gen_##name(ctx, 1, 0);                                                    \
                   1717: }                                                                             \
1.1.1.7   root     1718:                                                                               \
                   1719: static void glue(gen_, name##3)(DisasContext *ctx)                            \
1.1.1.5   root     1720: {                                                                             \
                   1721:     gen_##name(ctx, 1, 1);                                                    \
                   1722: }
                   1723: 
1.1.1.8   root     1724: static inline void gen_rldinm(DisasContext *ctx, uint32_t mb, uint32_t me,
                   1725:                               uint32_t sh)
1.1.1.5   root     1726: {
1.1.1.6   root     1727:     if (likely(sh != 0 && mb == 0 && me == (63 - sh))) {
                   1728:         tcg_gen_shli_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
                   1729:     } else if (likely(sh != 0 && me == 63 && sh == (64 - mb))) {
                   1730:         tcg_gen_shri_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], mb);
                   1731:     } else {
                   1732:         TCGv t0 = tcg_temp_new();
                   1733:         tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   1734:         if (likely(mb == 0 && me == 63)) {
                   1735:             tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   1736:         } else {
                   1737:             tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1.1.1.5   root     1738:         }
1.1.1.6   root     1739:         tcg_temp_free(t0);
1.1.1.5   root     1740:     }
                   1741:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1742:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     1743: }
                   1744: /* rldicl - rldicl. */
1.1.1.8   root     1745: static inline void gen_rldicl(DisasContext *ctx, int mbn, int shn)
1.1.1.5   root     1746: {
                   1747:     uint32_t sh, mb;
                   1748: 
                   1749:     sh = SH(ctx->opcode) | (shn << 5);
                   1750:     mb = MB(ctx->opcode) | (mbn << 5);
                   1751:     gen_rldinm(ctx, mb, 63, sh);
                   1752: }
                   1753: GEN_PPC64_R4(rldicl, 0x1E, 0x00);
                   1754: /* rldicr - rldicr. */
1.1.1.8   root     1755: static inline void gen_rldicr(DisasContext *ctx, int men, int shn)
1.1.1.5   root     1756: {
                   1757:     uint32_t sh, me;
                   1758: 
                   1759:     sh = SH(ctx->opcode) | (shn << 5);
                   1760:     me = MB(ctx->opcode) | (men << 5);
                   1761:     gen_rldinm(ctx, 0, me, sh);
                   1762: }
                   1763: GEN_PPC64_R4(rldicr, 0x1E, 0x02);
                   1764: /* rldic - rldic. */
1.1.1.8   root     1765: static inline void gen_rldic(DisasContext *ctx, int mbn, int shn)
1.1.1.5   root     1766: {
                   1767:     uint32_t sh, mb;
                   1768: 
                   1769:     sh = SH(ctx->opcode) | (shn << 5);
                   1770:     mb = MB(ctx->opcode) | (mbn << 5);
                   1771:     gen_rldinm(ctx, mb, 63 - sh, sh);
                   1772: }
                   1773: GEN_PPC64_R4(rldic, 0x1E, 0x04);
                   1774: 
1.1.1.8   root     1775: static inline void gen_rldnm(DisasContext *ctx, uint32_t mb, uint32_t me)
1.1.1.5   root     1776: {
1.1.1.6   root     1777:     TCGv t0;
                   1778: 
                   1779:     mb = MB(ctx->opcode);
                   1780:     me = ME(ctx->opcode);
                   1781:     t0 = tcg_temp_new();
                   1782:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
                   1783:     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1.1.1.5   root     1784:     if (unlikely(mb != 0 || me != 63)) {
1.1.1.6   root     1785:         tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
                   1786:     } else {
                   1787:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1.1.1.5   root     1788:     }
1.1.1.6   root     1789:     tcg_temp_free(t0);
1.1.1.5   root     1790:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1791:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     1792: }
                   1793: 
                   1794: /* rldcl - rldcl. */
1.1.1.8   root     1795: static inline void gen_rldcl(DisasContext *ctx, int mbn)
1.1.1.5   root     1796: {
                   1797:     uint32_t mb;
                   1798: 
                   1799:     mb = MB(ctx->opcode) | (mbn << 5);
                   1800:     gen_rldnm(ctx, mb, 63);
                   1801: }
                   1802: GEN_PPC64_R2(rldcl, 0x1E, 0x08);
                   1803: /* rldcr - rldcr. */
1.1.1.8   root     1804: static inline void gen_rldcr(DisasContext *ctx, int men)
1.1.1.5   root     1805: {
                   1806:     uint32_t me;
                   1807: 
                   1808:     me = MB(ctx->opcode) | (men << 5);
                   1809:     gen_rldnm(ctx, 0, me);
                   1810: }
                   1811: GEN_PPC64_R2(rldcr, 0x1E, 0x09);
                   1812: /* rldimi - rldimi. */
1.1.1.8   root     1813: static inline void gen_rldimi(DisasContext *ctx, int mbn, int shn)
1.1.1.5   root     1814: {
                   1815:     uint32_t sh, mb, me;
                   1816: 
                   1817:     sh = SH(ctx->opcode) | (shn << 5);
                   1818:     mb = MB(ctx->opcode) | (mbn << 5);
                   1819:     me = 63 - sh;
1.1.1.6   root     1820:     if (unlikely(sh == 0 && mb == 0)) {
                   1821:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1822:     } else {
                   1823:         TCGv t0, t1;
                   1824:         target_ulong mask;
                   1825: 
                   1826:         t0 = tcg_temp_new();
                   1827:         tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   1828:         t1 = tcg_temp_new();
                   1829:         mask = MASK(mb, me);
                   1830:         tcg_gen_andi_tl(t0, t0, mask);
                   1831:         tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
                   1832:         tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   1833:         tcg_temp_free(t0);
                   1834:         tcg_temp_free(t1);
                   1835:     }
1.1.1.5   root     1836:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1837:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1838: }
1.1.1.5   root     1839: GEN_PPC64_R4(rldimi, 0x1E, 0x06);
                   1840: #endif
1.1       root     1841: 
                   1842: /***                             Integer shift                             ***/
1.1.1.7   root     1843: 
1.1       root     1844: /* slw & slw. */
1.1.1.7   root     1845: static void gen_slw(DisasContext *ctx)
1.1.1.6   root     1846: {
1.1.1.8   root     1847:     TCGv t0, t1;
1.1.1.6   root     1848: 
1.1.1.8   root     1849:     t0 = tcg_temp_new();
                   1850:     /* AND rS with a mask that is 0 when rB >= 0x20 */
                   1851: #if defined(TARGET_PPC64)
                   1852:     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
                   1853:     tcg_gen_sari_tl(t0, t0, 0x3f);
                   1854: #else
                   1855:     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
                   1856:     tcg_gen_sari_tl(t0, t0, 0x1f);
                   1857: #endif
                   1858:     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   1859:     t1 = tcg_temp_new();
                   1860:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
                   1861:     tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   1862:     tcg_temp_free(t1);
1.1.1.6   root     1863:     tcg_temp_free(t0);
1.1.1.8   root     1864:     tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.6   root     1865:     if (unlikely(Rc(ctx->opcode) != 0))
                   1866:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
                   1867: }
1.1.1.7   root     1868: 
1.1       root     1869: /* sraw & sraw. */
1.1.1.7   root     1870: static void gen_sraw(DisasContext *ctx)
1.1.1.6   root     1871: {
                   1872:     gen_helper_sraw(cpu_gpr[rA(ctx->opcode)],
                   1873:                     cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   1874:     if (unlikely(Rc(ctx->opcode) != 0))
                   1875:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
                   1876: }
1.1.1.7   root     1877: 
1.1       root     1878: /* srawi & srawi. */
1.1.1.7   root     1879: static void gen_srawi(DisasContext *ctx)
1.1       root     1880: {
1.1.1.6   root     1881:     int sh = SH(ctx->opcode);
                   1882:     if (sh != 0) {
                   1883:         int l1, l2;
                   1884:         TCGv t0;
                   1885:         l1 = gen_new_label();
                   1886:         l2 = gen_new_label();
                   1887:         t0 = tcg_temp_local_new();
                   1888:         tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
                   1889:         tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
                   1890:         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
                   1891:         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
                   1892:         tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
                   1893:         tcg_gen_br(l2);
                   1894:         gen_set_label(l1);
                   1895:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
                   1896:         gen_set_label(l2);
                   1897:         tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
                   1898:         tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], t0, sh);
                   1899:         tcg_temp_free(t0);
                   1900:     } else {
                   1901:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1902:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1.1.1.5   root     1903:     }
                   1904:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1905:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1906: }
1.1.1.7   root     1907: 
1.1       root     1908: /* srw & srw. */
1.1.1.7   root     1909: static void gen_srw(DisasContext *ctx)
1.1.1.6   root     1910: {
                   1911:     TCGv t0, t1;
                   1912: 
1.1.1.8   root     1913:     t0 = tcg_temp_new();
                   1914:     /* AND rS with a mask that is 0 when rB >= 0x20 */
                   1915: #if defined(TARGET_PPC64)
                   1916:     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
                   1917:     tcg_gen_sari_tl(t0, t0, 0x3f);
                   1918: #else
                   1919:     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
                   1920:     tcg_gen_sari_tl(t0, t0, 0x1f);
                   1921: #endif
                   1922:     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   1923:     tcg_gen_ext32u_tl(t0, t0);
1.1.1.6   root     1924:     t1 = tcg_temp_new();
1.1.1.8   root     1925:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
                   1926:     tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1.1.1.6   root     1927:     tcg_temp_free(t1);
                   1928:     tcg_temp_free(t0);
                   1929:     if (unlikely(Rc(ctx->opcode) != 0))
                   1930:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
                   1931: }
1.1.1.7   root     1932: 
1.1.1.5   root     1933: #if defined(TARGET_PPC64)
                   1934: /* sld & sld. */
1.1.1.7   root     1935: static void gen_sld(DisasContext *ctx)
1.1.1.6   root     1936: {
1.1.1.8   root     1937:     TCGv t0, t1;
1.1.1.6   root     1938: 
1.1.1.8   root     1939:     t0 = tcg_temp_new();
                   1940:     /* AND rS with a mask that is 0 when rB >= 0x40 */
                   1941:     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
                   1942:     tcg_gen_sari_tl(t0, t0, 0x3f);
                   1943:     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   1944:     t1 = tcg_temp_new();
                   1945:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
                   1946:     tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   1947:     tcg_temp_free(t1);
1.1.1.6   root     1948:     tcg_temp_free(t0);
                   1949:     if (unlikely(Rc(ctx->opcode) != 0))
                   1950:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
                   1951: }
1.1.1.7   root     1952: 
1.1.1.5   root     1953: /* srad & srad. */
1.1.1.7   root     1954: static void gen_srad(DisasContext *ctx)
1.1.1.6   root     1955: {
                   1956:     gen_helper_srad(cpu_gpr[rA(ctx->opcode)],
                   1957:                     cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   1958:     if (unlikely(Rc(ctx->opcode) != 0))
                   1959:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
                   1960: }
1.1.1.5   root     1961: /* sradi & sradi. */
1.1.1.8   root     1962: static inline void gen_sradi(DisasContext *ctx, int n)
1.1.1.5   root     1963: {
1.1.1.6   root     1964:     int sh = SH(ctx->opcode) + (n << 5);
1.1.1.5   root     1965:     if (sh != 0) {
1.1.1.6   root     1966:         int l1, l2;
                   1967:         TCGv t0;
                   1968:         l1 = gen_new_label();
                   1969:         l2 = gen_new_label();
                   1970:         t0 = tcg_temp_local_new();
                   1971:         tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
                   1972:         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
                   1973:         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
                   1974:         tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
                   1975:         tcg_gen_br(l2);
                   1976:         gen_set_label(l1);
                   1977:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
                   1978:         gen_set_label(l2);
                   1979:         tcg_temp_free(t0);
                   1980:         tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
                   1981:     } else {
                   1982:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1983:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1.1.1.5   root     1984:     }
                   1985:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1986:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     1987: }
1.1.1.7   root     1988: 
                   1989: static void gen_sradi0(DisasContext *ctx)
1.1.1.5   root     1990: {
                   1991:     gen_sradi(ctx, 0);
                   1992: }
1.1.1.7   root     1993: 
                   1994: static void gen_sradi1(DisasContext *ctx)
1.1.1.5   root     1995: {
                   1996:     gen_sradi(ctx, 1);
                   1997: }
1.1.1.7   root     1998: 
1.1.1.5   root     1999: /* srd & srd. */
1.1.1.7   root     2000: static void gen_srd(DisasContext *ctx)
1.1.1.6   root     2001: {
1.1.1.8   root     2002:     TCGv t0, t1;
1.1.1.6   root     2003: 
1.1.1.8   root     2004:     t0 = tcg_temp_new();
                   2005:     /* AND rS with a mask that is 0 when rB >= 0x40 */
                   2006:     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
                   2007:     tcg_gen_sari_tl(t0, t0, 0x3f);
                   2008:     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   2009:     t1 = tcg_temp_new();
                   2010:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
                   2011:     tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   2012:     tcg_temp_free(t1);
1.1.1.6   root     2013:     tcg_temp_free(t0);
                   2014:     if (unlikely(Rc(ctx->opcode) != 0))
                   2015:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
                   2016: }
1.1.1.5   root     2017: #endif
1.1       root     2018: 
                   2019: /***                       Floating-Point arithmetic                       ***/
1.1.1.5   root     2020: #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
1.1.1.7   root     2021: static void gen_f##name(DisasContext *ctx)                                    \
1.1       root     2022: {                                                                             \
1.1.1.5   root     2023:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     2024:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     2025:         return;                                                               \
                   2026:     }                                                                         \
1.1.1.6   root     2027:     /* NIP cannot be restored if the memory exception comes from an helper */ \
                   2028:     gen_update_nip(ctx, ctx->nip - 4);                                        \
1.1.1.5   root     2029:     gen_reset_fpstatus();                                                     \
1.1.1.6   root     2030:     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
                   2031:                      cpu_fpr[rC(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);     \
1.1       root     2032:     if (isfloat) {                                                            \
1.1.1.6   root     2033:         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
1.1       root     2034:     }                                                                         \
1.1.1.6   root     2035:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], set_fprf,                      \
                   2036:                      Rc(ctx->opcode) != 0);                                   \
1.1       root     2037: }
                   2038: 
1.1.1.5   root     2039: #define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
                   2040: _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
                   2041: _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
1.1       root     2042: 
1.1.1.5   root     2043: #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1.1.1.7   root     2044: static void gen_f##name(DisasContext *ctx)                                    \
1.1       root     2045: {                                                                             \
1.1.1.5   root     2046:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     2047:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     2048:         return;                                                               \
                   2049:     }                                                                         \
1.1.1.6   root     2050:     /* NIP cannot be restored if the memory exception comes from an helper */ \
                   2051:     gen_update_nip(ctx, ctx->nip - 4);                                        \
1.1.1.5   root     2052:     gen_reset_fpstatus();                                                     \
1.1.1.6   root     2053:     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
                   2054:                      cpu_fpr[rB(ctx->opcode)]);                               \
1.1       root     2055:     if (isfloat) {                                                            \
1.1.1.6   root     2056:         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
1.1       root     2057:     }                                                                         \
1.1.1.6   root     2058:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
                   2059:                      set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     2060: }
1.1.1.5   root     2061: #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
                   2062: _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
                   2063: _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1.1       root     2064: 
1.1.1.5   root     2065: #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1.1.1.7   root     2066: static void gen_f##name(DisasContext *ctx)                                    \
1.1       root     2067: {                                                                             \
1.1.1.5   root     2068:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     2069:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     2070:         return;                                                               \
                   2071:     }                                                                         \
1.1.1.6   root     2072:     /* NIP cannot be restored if the memory exception comes from an helper */ \
                   2073:     gen_update_nip(ctx, ctx->nip - 4);                                        \
1.1.1.5   root     2074:     gen_reset_fpstatus();                                                     \
1.1.1.6   root     2075:     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
                   2076:                        cpu_fpr[rC(ctx->opcode)]);                             \
1.1       root     2077:     if (isfloat) {                                                            \
1.1.1.6   root     2078:         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
1.1       root     2079:     }                                                                         \
1.1.1.6   root     2080:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
                   2081:                      set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     2082: }
1.1.1.5   root     2083: #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
                   2084: _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
                   2085: _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1.1       root     2086: 
1.1.1.5   root     2087: #define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
1.1.1.7   root     2088: static void gen_f##name(DisasContext *ctx)                                    \
1.1       root     2089: {                                                                             \
1.1.1.5   root     2090:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     2091:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     2092:         return;                                                               \
                   2093:     }                                                                         \
1.1.1.6   root     2094:     /* NIP cannot be restored if the memory exception comes from an helper */ \
                   2095:     gen_update_nip(ctx, ctx->nip - 4);                                        \
1.1.1.5   root     2096:     gen_reset_fpstatus();                                                     \
1.1.1.6   root     2097:     gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);   \
                   2098:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
                   2099:                      set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     2100: }
                   2101: 
1.1.1.5   root     2102: #define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
1.1.1.7   root     2103: static void gen_f##name(DisasContext *ctx)                                    \
1.1       root     2104: {                                                                             \
1.1.1.5   root     2105:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     2106:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     2107:         return;                                                               \
                   2108:     }                                                                         \
1.1.1.6   root     2109:     /* NIP cannot be restored if the memory exception comes from an helper */ \
                   2110:     gen_update_nip(ctx, ctx->nip - 4);                                        \
1.1.1.5   root     2111:     gen_reset_fpstatus();                                                     \
1.1.1.6   root     2112:     gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);   \
                   2113:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
                   2114:                      set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     2115: }
                   2116: 
                   2117: /* fadd - fadds */
1.1.1.5   root     2118: GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
1.1       root     2119: /* fdiv - fdivs */
1.1.1.5   root     2120: GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
1.1       root     2121: /* fmul - fmuls */
1.1.1.5   root     2122: GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
                   2123: 
                   2124: /* fre */
                   2125: GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
1.1       root     2126: 
                   2127: /* fres */
1.1.1.5   root     2128: GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
1.1       root     2129: 
                   2130: /* frsqrte */
1.1.1.5   root     2131: GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
                   2132: 
                   2133: /* frsqrtes */
1.1.1.7   root     2134: static void gen_frsqrtes(DisasContext *ctx)
1.1.1.5   root     2135: {
1.1.1.6   root     2136:     if (unlikely(!ctx->fpu_enabled)) {
                   2137:         gen_exception(ctx, POWERPC_EXCP_FPU);
                   2138:         return;
                   2139:     }
                   2140:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2141:     gen_update_nip(ctx, ctx->nip - 4);
                   2142:     gen_reset_fpstatus();
                   2143:     gen_helper_frsqrte(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
                   2144:     gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);
                   2145:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
1.1.1.5   root     2146: }
1.1       root     2147: 
                   2148: /* fsel */
1.1.1.5   root     2149: _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
1.1       root     2150: /* fsub - fsubs */
1.1.1.5   root     2151: GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
1.1       root     2152: /* Optional: */
1.1.1.7   root     2153: 
1.1       root     2154: /* fsqrt */
1.1.1.7   root     2155: static void gen_fsqrt(DisasContext *ctx)
1.1       root     2156: {
1.1.1.5   root     2157:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2158:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2159:         return;
                   2160:     }
1.1.1.6   root     2161:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2162:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2163:     gen_reset_fpstatus();
1.1.1.6   root     2164:     gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
                   2165:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
1.1       root     2166: }
                   2167: 
1.1.1.7   root     2168: static void gen_fsqrts(DisasContext *ctx)
1.1       root     2169: {
1.1.1.5   root     2170:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2171:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2172:         return;
                   2173:     }
1.1.1.6   root     2174:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2175:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2176:     gen_reset_fpstatus();
1.1.1.6   root     2177:     gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
                   2178:     gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);
                   2179:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
1.1       root     2180: }
                   2181: 
                   2182: /***                     Floating-Point multiply-and-add                   ***/
                   2183: /* fmadd - fmadds */
1.1.1.5   root     2184: GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
1.1       root     2185: /* fmsub - fmsubs */
1.1.1.5   root     2186: GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
1.1       root     2187: /* fnmadd - fnmadds */
1.1.1.5   root     2188: GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
1.1       root     2189: /* fnmsub - fnmsubs */
1.1.1.5   root     2190: GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
1.1       root     2191: 
                   2192: /***                     Floating-Point round & convert                    ***/
                   2193: /* fctiw */
1.1.1.5   root     2194: GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
1.1       root     2195: /* fctiwz */
1.1.1.5   root     2196: GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
1.1       root     2197: /* frsp */
1.1.1.5   root     2198: GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
                   2199: #if defined(TARGET_PPC64)
                   2200: /* fcfid */
                   2201: GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
                   2202: /* fctid */
                   2203: GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
                   2204: /* fctidz */
                   2205: GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
                   2206: #endif
                   2207: 
                   2208: /* frin */
                   2209: GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
                   2210: /* friz */
                   2211: GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
                   2212: /* frip */
                   2213: GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
                   2214: /* frim */
                   2215: GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
1.1       root     2216: 
                   2217: /***                         Floating-Point compare                        ***/
1.1.1.7   root     2218: 
1.1       root     2219: /* fcmpo */
1.1.1.7   root     2220: static void gen_fcmpo(DisasContext *ctx)
1.1       root     2221: {
1.1.1.6   root     2222:     TCGv_i32 crf;
1.1.1.5   root     2223:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2224:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2225:         return;
                   2226:     }
1.1.1.6   root     2227:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2228:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2229:     gen_reset_fpstatus();
1.1.1.6   root     2230:     crf = tcg_const_i32(crfD(ctx->opcode));
                   2231:     gen_helper_fcmpo(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf);
                   2232:     tcg_temp_free_i32(crf);
                   2233:     gen_helper_float_check_status();
1.1       root     2234: }
                   2235: 
                   2236: /* fcmpu */
1.1.1.7   root     2237: static void gen_fcmpu(DisasContext *ctx)
1.1       root     2238: {
1.1.1.6   root     2239:     TCGv_i32 crf;
1.1.1.5   root     2240:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2241:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2242:         return;
                   2243:     }
1.1.1.6   root     2244:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2245:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2246:     gen_reset_fpstatus();
1.1.1.6   root     2247:     crf = tcg_const_i32(crfD(ctx->opcode));
                   2248:     gen_helper_fcmpu(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf);
                   2249:     tcg_temp_free_i32(crf);
                   2250:     gen_helper_float_check_status();
1.1       root     2251: }
                   2252: 
                   2253: /***                         Floating-point move                           ***/
                   2254: /* fabs */
1.1.1.5   root     2255: /* XXX: beware that fabs never checks for NaNs nor update FPSCR */
                   2256: GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
1.1       root     2257: 
                   2258: /* fmr  - fmr. */
1.1.1.5   root     2259: /* XXX: beware that fmr never checks for NaNs nor update FPSCR */
1.1.1.7   root     2260: static void gen_fmr(DisasContext *ctx)
1.1       root     2261: {
1.1.1.5   root     2262:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2263:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2264:         return;
                   2265:     }
1.1.1.6   root     2266:     tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
                   2267:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
1.1       root     2268: }
                   2269: 
                   2270: /* fnabs */
1.1.1.5   root     2271: /* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
                   2272: GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
1.1       root     2273: /* fneg */
1.1.1.5   root     2274: /* XXX: beware that fneg never checks for NaNs nor update FPSCR */
                   2275: GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
1.1       root     2276: 
                   2277: /***                  Floating-Point status & ctrl register                ***/
1.1.1.7   root     2278: 
1.1       root     2279: /* mcrfs */
1.1.1.7   root     2280: static void gen_mcrfs(DisasContext *ctx)
1.1       root     2281: {
1.1.1.5   root     2282:     int bfa;
                   2283: 
                   2284:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2285:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2286:         return;
                   2287:     }
1.1.1.5   root     2288:     bfa = 4 * (7 - crfS(ctx->opcode));
1.1.1.6   root     2289:     tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_fpscr, bfa);
                   2290:     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf);
                   2291:     tcg_gen_andi_i32(cpu_fpscr, cpu_fpscr, ~(0xF << bfa));
1.1       root     2292: }
                   2293: 
                   2294: /* mffs */
1.1.1.7   root     2295: static void gen_mffs(DisasContext *ctx)
1.1       root     2296: {
1.1.1.5   root     2297:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2298:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2299:         return;
                   2300:     }
1.1.1.5   root     2301:     gen_reset_fpstatus();
1.1.1.6   root     2302:     tcg_gen_extu_i32_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpscr);
                   2303:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
1.1       root     2304: }
                   2305: 
                   2306: /* mtfsb0 */
1.1.1.7   root     2307: static void gen_mtfsb0(DisasContext *ctx)
1.1       root     2308: {
                   2309:     uint8_t crb;
1.1.1.5   root     2310: 
                   2311:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2312:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2313:         return;
                   2314:     }
1.1.1.6   root     2315:     crb = 31 - crbD(ctx->opcode);
1.1.1.5   root     2316:     gen_reset_fpstatus();
1.1.1.6   root     2317:     if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) {
                   2318:         TCGv_i32 t0;
                   2319:         /* NIP cannot be restored if the memory exception comes from an helper */
                   2320:         gen_update_nip(ctx, ctx->nip - 4);
                   2321:         t0 = tcg_const_i32(crb);
                   2322:         gen_helper_fpscr_clrbit(t0);
                   2323:         tcg_temp_free_i32(t0);
                   2324:     }
1.1.1.5   root     2325:     if (unlikely(Rc(ctx->opcode) != 0)) {
1.1.1.6   root     2326:         tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
1.1.1.5   root     2327:     }
1.1       root     2328: }
                   2329: 
                   2330: /* mtfsb1 */
1.1.1.7   root     2331: static void gen_mtfsb1(DisasContext *ctx)
1.1       root     2332: {
                   2333:     uint8_t crb;
1.1.1.5   root     2334: 
                   2335:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2336:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2337:         return;
                   2338:     }
1.1.1.6   root     2339:     crb = 31 - crbD(ctx->opcode);
1.1.1.5   root     2340:     gen_reset_fpstatus();
                   2341:     /* XXX: we pretend we can only do IEEE floating-point computations */
1.1.1.6   root     2342:     if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) {
                   2343:         TCGv_i32 t0;
                   2344:         /* NIP cannot be restored if the memory exception comes from an helper */
                   2345:         gen_update_nip(ctx, ctx->nip - 4);
                   2346:         t0 = tcg_const_i32(crb);
                   2347:         gen_helper_fpscr_setbit(t0);
                   2348:         tcg_temp_free_i32(t0);
                   2349:     }
1.1.1.5   root     2350:     if (unlikely(Rc(ctx->opcode) != 0)) {
1.1.1.6   root     2351:         tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
1.1.1.5   root     2352:     }
                   2353:     /* We can raise a differed exception */
1.1.1.6   root     2354:     gen_helper_float_check_status();
1.1       root     2355: }
                   2356: 
                   2357: /* mtfsf */
1.1.1.7   root     2358: static void gen_mtfsf(DisasContext *ctx)
1.1       root     2359: {
1.1.1.6   root     2360:     TCGv_i32 t0;
1.1.1.7   root     2361:     int L = ctx->opcode & 0x02000000;
1.1.1.6   root     2362: 
1.1.1.5   root     2363:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2364:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2365:         return;
                   2366:     }
1.1.1.6   root     2367:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2368:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2369:     gen_reset_fpstatus();
1.1.1.7   root     2370:     if (L)
                   2371:         t0 = tcg_const_i32(0xff);
                   2372:     else
                   2373:         t0 = tcg_const_i32(FM(ctx->opcode));
1.1.1.6   root     2374:     gen_helper_store_fpscr(cpu_fpr[rB(ctx->opcode)], t0);
                   2375:     tcg_temp_free_i32(t0);
1.1.1.5   root     2376:     if (unlikely(Rc(ctx->opcode) != 0)) {
1.1.1.6   root     2377:         tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
1.1.1.5   root     2378:     }
                   2379:     /* We can raise a differed exception */
1.1.1.6   root     2380:     gen_helper_float_check_status();
1.1       root     2381: }
                   2382: 
                   2383: /* mtfsfi */
1.1.1.7   root     2384: static void gen_mtfsfi(DisasContext *ctx)
1.1       root     2385: {
1.1.1.5   root     2386:     int bf, sh;
1.1.1.6   root     2387:     TCGv_i64 t0;
                   2388:     TCGv_i32 t1;
1.1.1.5   root     2389: 
                   2390:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2391:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2392:         return;
                   2393:     }
1.1.1.5   root     2394:     bf = crbD(ctx->opcode) >> 2;
                   2395:     sh = 7 - bf;
1.1.1.6   root     2396:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2397:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2398:     gen_reset_fpstatus();
1.1.1.6   root     2399:     t0 = tcg_const_i64(FPIMM(ctx->opcode) << (4 * sh));
                   2400:     t1 = tcg_const_i32(1 << sh);
                   2401:     gen_helper_store_fpscr(t0, t1);
                   2402:     tcg_temp_free_i64(t0);
                   2403:     tcg_temp_free_i32(t1);
1.1.1.5   root     2404:     if (unlikely(Rc(ctx->opcode) != 0)) {
1.1.1.6   root     2405:         tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
1.1.1.5   root     2406:     }
                   2407:     /* We can raise a differed exception */
1.1.1.6   root     2408:     gen_helper_float_check_status();
1.1       root     2409: }
                   2410: 
1.1.1.5   root     2411: /***                           Addressing modes                            ***/
                   2412: /* Register indirect with immediate index : EA = (rA|0) + SIMM */
1.1.1.8   root     2413: static inline void gen_addr_imm_index(DisasContext *ctx, TCGv EA,
                   2414:                                       target_long maskl)
1.1.1.5   root     2415: {
                   2416:     target_long simm = SIMM(ctx->opcode);
                   2417: 
                   2418:     simm &= ~maskl;
                   2419:     if (rA(ctx->opcode) == 0) {
1.1.1.6   root     2420: #if defined(TARGET_PPC64)
                   2421:         if (!ctx->sf_mode) {
                   2422:             tcg_gen_movi_tl(EA, (uint32_t)simm);
                   2423:         } else
                   2424: #endif
                   2425:         tcg_gen_movi_tl(EA, simm);
                   2426:     } else if (likely(simm != 0)) {
                   2427:         tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
                   2428: #if defined(TARGET_PPC64)
                   2429:         if (!ctx->sf_mode) {
                   2430:             tcg_gen_ext32u_tl(EA, EA);
                   2431:         }
                   2432: #endif
1.1.1.5   root     2433:     } else {
1.1.1.6   root     2434: #if defined(TARGET_PPC64)
                   2435:         if (!ctx->sf_mode) {
                   2436:             tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
                   2437:         } else
1.1.1.5   root     2438: #endif
1.1.1.6   root     2439:         tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
                   2440:     }
1.1.1.5   root     2441: }
                   2442: 
1.1.1.8   root     2443: static inline void gen_addr_reg_index(DisasContext *ctx, TCGv EA)
1.1.1.5   root     2444: {
                   2445:     if (rA(ctx->opcode) == 0) {
1.1.1.6   root     2446: #if defined(TARGET_PPC64)
                   2447:         if (!ctx->sf_mode) {
                   2448:             tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]);
                   2449:         } else
                   2450: #endif
                   2451:         tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     2452:     } else {
1.1.1.6   root     2453:         tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   2454: #if defined(TARGET_PPC64)
                   2455:         if (!ctx->sf_mode) {
                   2456:             tcg_gen_ext32u_tl(EA, EA);
                   2457:         }
1.1.1.5   root     2458: #endif
1.1.1.6   root     2459:     }
1.1.1.5   root     2460: }
                   2461: 
1.1.1.8   root     2462: static inline void gen_addr_register(DisasContext *ctx, TCGv EA)
1.1.1.5   root     2463: {
                   2464:     if (rA(ctx->opcode) == 0) {
1.1.1.6   root     2465:         tcg_gen_movi_tl(EA, 0);
1.1.1.5   root     2466:     } else {
1.1.1.6   root     2467: #if defined(TARGET_PPC64)
                   2468:         if (!ctx->sf_mode) {
                   2469:             tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
                   2470:         } else
                   2471: #endif
                   2472:             tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
                   2473:     }
                   2474: }
                   2475: 
1.1.1.8   root     2476: static inline void gen_addr_add(DisasContext *ctx, TCGv ret, TCGv arg1,
                   2477:                                 target_long val)
1.1.1.6   root     2478: {
                   2479:     tcg_gen_addi_tl(ret, arg1, val);
                   2480: #if defined(TARGET_PPC64)
                   2481:     if (!ctx->sf_mode) {
                   2482:         tcg_gen_ext32u_tl(ret, ret);
1.1.1.5   root     2483:     }
                   2484: #endif
                   2485: }
                   2486: 
1.1.1.8   root     2487: static inline void gen_check_align(DisasContext *ctx, TCGv EA, int mask)
1.1.1.6   root     2488: {
                   2489:     int l1 = gen_new_label();
                   2490:     TCGv t0 = tcg_temp_new();
                   2491:     TCGv_i32 t1, t2;
                   2492:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2493:     gen_update_nip(ctx, ctx->nip - 4);
                   2494:     tcg_gen_andi_tl(t0, EA, mask);
                   2495:     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
                   2496:     t1 = tcg_const_i32(POWERPC_EXCP_ALIGN);
                   2497:     t2 = tcg_const_i32(0);
                   2498:     gen_helper_raise_exception_err(t1, t2);
                   2499:     tcg_temp_free_i32(t1);
                   2500:     tcg_temp_free_i32(t2);
                   2501:     gen_set_label(l1);
                   2502:     tcg_temp_free(t0);
                   2503: }
                   2504: 
                   2505: /***                             Integer load                              ***/
1.1.1.8   root     2506: static inline void gen_qemu_ld8u(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2507: {
                   2508:     tcg_gen_qemu_ld8u(arg1, arg2, ctx->mem_idx);
                   2509: }
                   2510: 
1.1.1.8   root     2511: static inline void gen_qemu_ld8s(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2512: {
                   2513:     tcg_gen_qemu_ld8s(arg1, arg2, ctx->mem_idx);
                   2514: }
                   2515: 
1.1.1.8   root     2516: static inline void gen_qemu_ld16u(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2517: {
                   2518:     tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
                   2519:     if (unlikely(ctx->le_mode)) {
1.1.1.7   root     2520:         tcg_gen_bswap16_tl(arg1, arg1);
1.1.1.6   root     2521:     }
                   2522: }
                   2523: 
1.1.1.8   root     2524: static inline void gen_qemu_ld16s(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2525: {
                   2526:     if (unlikely(ctx->le_mode)) {
                   2527:         tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
1.1.1.7   root     2528:         tcg_gen_bswap16_tl(arg1, arg1);
1.1.1.6   root     2529:         tcg_gen_ext16s_tl(arg1, arg1);
                   2530:     } else {
                   2531:         tcg_gen_qemu_ld16s(arg1, arg2, ctx->mem_idx);
                   2532:     }
                   2533: }
                   2534: 
1.1.1.8   root     2535: static inline void gen_qemu_ld32u(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2536: {
                   2537:     tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
                   2538:     if (unlikely(ctx->le_mode)) {
1.1.1.7   root     2539:         tcg_gen_bswap32_tl(arg1, arg1);
1.1.1.6   root     2540:     }
1.1       root     2541: }
                   2542: 
1.1.1.6   root     2543: #if defined(TARGET_PPC64)
1.1.1.8   root     2544: static inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2545: {
                   2546:     if (unlikely(ctx->le_mode)) {
                   2547:         tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
1.1.1.7   root     2548:         tcg_gen_bswap32_tl(arg1, arg1);
                   2549:         tcg_gen_ext32s_tl(arg1, arg1);
1.1.1.6   root     2550:     } else
                   2551:         tcg_gen_qemu_ld32s(arg1, arg2, ctx->mem_idx);
                   2552: }
                   2553: #endif
                   2554: 
1.1.1.8   root     2555: static inline void gen_qemu_ld64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
1.1.1.6   root     2556: {
                   2557:     tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
                   2558:     if (unlikely(ctx->le_mode)) {
1.1.1.7   root     2559:         tcg_gen_bswap64_i64(arg1, arg1);
1.1.1.6   root     2560:     }
                   2561: }
                   2562: 
1.1.1.8   root     2563: static inline void gen_qemu_st8(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2564: {
                   2565:     tcg_gen_qemu_st8(arg1, arg2, ctx->mem_idx);
                   2566: }
                   2567: 
1.1.1.8   root     2568: static inline void gen_qemu_st16(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2569: {
                   2570:     if (unlikely(ctx->le_mode)) {
                   2571:         TCGv t0 = tcg_temp_new();
                   2572:         tcg_gen_ext16u_tl(t0, arg1);
1.1.1.7   root     2573:         tcg_gen_bswap16_tl(t0, t0);
1.1.1.6   root     2574:         tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
                   2575:         tcg_temp_free(t0);
                   2576:     } else {
                   2577:         tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
                   2578:     }
                   2579: }
                   2580: 
1.1.1.8   root     2581: static inline void gen_qemu_st32(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2582: {
                   2583:     if (unlikely(ctx->le_mode)) {
1.1.1.7   root     2584:         TCGv t0 = tcg_temp_new();
                   2585:         tcg_gen_ext32u_tl(t0, arg1);
                   2586:         tcg_gen_bswap32_tl(t0, t0);
1.1.1.6   root     2587:         tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
                   2588:         tcg_temp_free(t0);
                   2589:     } else {
                   2590:         tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
                   2591:     }
                   2592: }
                   2593: 
1.1.1.8   root     2594: static inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
1.1.1.6   root     2595: {
                   2596:     if (unlikely(ctx->le_mode)) {
                   2597:         TCGv_i64 t0 = tcg_temp_new_i64();
1.1.1.7   root     2598:         tcg_gen_bswap64_i64(t0, arg1);
1.1.1.6   root     2599:         tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx);
                   2600:         tcg_temp_free_i64(t0);
                   2601:     } else
                   2602:         tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx);
                   2603: }
                   2604: 
                   2605: #define GEN_LD(name, ldop, opc, type)                                         \
1.1.1.7   root     2606: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.6   root     2607: {                                                                             \
                   2608:     TCGv EA;                                                                  \
                   2609:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   2610:     EA = tcg_temp_new();                                                      \
                   2611:     gen_addr_imm_index(ctx, EA, 0);                                           \
                   2612:     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
                   2613:     tcg_temp_free(EA);                                                        \
                   2614: }
                   2615: 
                   2616: #define GEN_LDU(name, ldop, opc, type)                                        \
1.1.1.7   root     2617: static void glue(gen_, name##u)(DisasContext *ctx)                                    \
1.1       root     2618: {                                                                             \
1.1.1.6   root     2619:     TCGv EA;                                                                  \
1.1.1.5   root     2620:     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
                   2621:                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1.1.1.6   root     2622:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     2623:         return;                                                               \
                   2624:     }                                                                         \
1.1.1.6   root     2625:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   2626:     EA = tcg_temp_new();                                                      \
1.1.1.5   root     2627:     if (type == PPC_64B)                                                      \
1.1.1.6   root     2628:         gen_addr_imm_index(ctx, EA, 0x03);                                    \
1.1.1.5   root     2629:     else                                                                      \
1.1.1.6   root     2630:         gen_addr_imm_index(ctx, EA, 0);                                       \
                   2631:     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
                   2632:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
                   2633:     tcg_temp_free(EA);                                                        \
1.1       root     2634: }
                   2635: 
1.1.1.6   root     2636: #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
1.1.1.7   root     2637: static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
1.1       root     2638: {                                                                             \
1.1.1.6   root     2639:     TCGv EA;                                                                  \
1.1.1.5   root     2640:     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
                   2641:                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1.1.1.6   root     2642:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     2643:         return;                                                               \
                   2644:     }                                                                         \
1.1.1.6   root     2645:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   2646:     EA = tcg_temp_new();                                                      \
                   2647:     gen_addr_reg_index(ctx, EA);                                              \
                   2648:     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
                   2649:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
                   2650:     tcg_temp_free(EA);                                                        \
                   2651: }
                   2652: 
1.1.1.13! root     2653: #define GEN_LDX_E(name, ldop, opc2, opc3, type, type2)                        \
1.1.1.7   root     2654: static void glue(gen_, name##x)(DisasContext *ctx)                            \
1.1.1.6   root     2655: {                                                                             \
                   2656:     TCGv EA;                                                                  \
                   2657:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   2658:     EA = tcg_temp_new();                                                      \
                   2659:     gen_addr_reg_index(ctx, EA);                                              \
                   2660:     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
                   2661:     tcg_temp_free(EA);                                                        \
                   2662: }
1.1.1.13! root     2663: #define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
        !          2664:     GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE)
1.1.1.6   root     2665: 
                   2666: #define GEN_LDS(name, ldop, op, type)                                         \
                   2667: GEN_LD(name, ldop, op | 0x20, type);                                          \
                   2668: GEN_LDU(name, ldop, op | 0x21, type);                                         \
                   2669: GEN_LDUX(name, ldop, 0x17, op | 0x01, type);                                  \
                   2670: GEN_LDX(name, ldop, 0x17, op | 0x00, type)
1.1       root     2671: 
                   2672: /* lbz lbzu lbzux lbzx */
1.1.1.6   root     2673: GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER);
1.1       root     2674: /* lha lhau lhaux lhax */
1.1.1.6   root     2675: GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER);
1.1       root     2676: /* lhz lhzu lhzux lhzx */
1.1.1.6   root     2677: GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER);
1.1       root     2678: /* lwz lwzu lwzux lwzx */
1.1.1.6   root     2679: GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER);
1.1.1.5   root     2680: #if defined(TARGET_PPC64)
                   2681: /* lwaux */
1.1.1.6   root     2682: GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B);
1.1.1.5   root     2683: /* lwax */
1.1.1.6   root     2684: GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B);
1.1.1.5   root     2685: /* ldux */
1.1.1.6   root     2686: GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B);
1.1.1.5   root     2687: /* ldx */
1.1.1.6   root     2688: GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B);
1.1.1.7   root     2689: 
                   2690: static void gen_ld(DisasContext *ctx)
1.1.1.5   root     2691: {
1.1.1.6   root     2692:     TCGv EA;
1.1.1.5   root     2693:     if (Rc(ctx->opcode)) {
                   2694:         if (unlikely(rA(ctx->opcode) == 0 ||
                   2695:                      rA(ctx->opcode) == rD(ctx->opcode))) {
1.1.1.6   root     2696:             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     2697:             return;
                   2698:         }
                   2699:     }
1.1.1.6   root     2700:     gen_set_access_type(ctx, ACCESS_INT);
                   2701:     EA = tcg_temp_new();
                   2702:     gen_addr_imm_index(ctx, EA, 0x03);
1.1.1.5   root     2703:     if (ctx->opcode & 0x02) {
                   2704:         /* lwa (lwau is undefined) */
1.1.1.6   root     2705:         gen_qemu_ld32s(ctx, cpu_gpr[rD(ctx->opcode)], EA);
1.1.1.5   root     2706:     } else {
                   2707:         /* ld - ldu */
1.1.1.6   root     2708:         gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], EA);
1.1.1.5   root     2709:     }
                   2710:     if (Rc(ctx->opcode))
1.1.1.6   root     2711:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
                   2712:     tcg_temp_free(EA);
1.1.1.5   root     2713: }
1.1.1.7   root     2714: 
1.1.1.5   root     2715: /* lq */
1.1.1.7   root     2716: static void gen_lq(DisasContext *ctx)
1.1.1.5   root     2717: {
                   2718: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     2719:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     2720: #else
                   2721:     int ra, rd;
1.1.1.6   root     2722:     TCGv EA;
1.1.1.5   root     2723: 
                   2724:     /* Restore CPU state */
1.1.1.6   root     2725:     if (unlikely(ctx->mem_idx == 0)) {
                   2726:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     2727:         return;
                   2728:     }
                   2729:     ra = rA(ctx->opcode);
                   2730:     rd = rD(ctx->opcode);
                   2731:     if (unlikely((rd & 1) || rd == ra)) {
1.1.1.6   root     2732:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     2733:         return;
                   2734:     }
1.1.1.6   root     2735:     if (unlikely(ctx->le_mode)) {
1.1.1.5   root     2736:         /* Little-endian mode is not handled */
1.1.1.6   root     2737:         gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
1.1.1.5   root     2738:         return;
                   2739:     }
1.1.1.6   root     2740:     gen_set_access_type(ctx, ACCESS_INT);
                   2741:     EA = tcg_temp_new();
                   2742:     gen_addr_imm_index(ctx, EA, 0x0F);
                   2743:     gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
                   2744:     gen_addr_add(ctx, EA, EA, 8);
                   2745:     gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
                   2746:     tcg_temp_free(EA);
1.1.1.5   root     2747: #endif
                   2748: }
                   2749: #endif
1.1       root     2750: 
                   2751: /***                              Integer store                            ***/
1.1.1.6   root     2752: #define GEN_ST(name, stop, opc, type)                                         \
1.1.1.7   root     2753: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1       root     2754: {                                                                             \
1.1.1.6   root     2755:     TCGv EA;                                                                  \
                   2756:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   2757:     EA = tcg_temp_new();                                                      \
                   2758:     gen_addr_imm_index(ctx, EA, 0);                                           \
                   2759:     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
                   2760:     tcg_temp_free(EA);                                                        \
1.1       root     2761: }
                   2762: 
1.1.1.6   root     2763: #define GEN_STU(name, stop, opc, type)                                        \
1.1.1.7   root     2764: static void glue(gen_, stop##u)(DisasContext *ctx)                                    \
1.1       root     2765: {                                                                             \
1.1.1.6   root     2766:     TCGv EA;                                                                  \
1.1.1.5   root     2767:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6   root     2768:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     2769:         return;                                                               \
                   2770:     }                                                                         \
1.1.1.6   root     2771:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   2772:     EA = tcg_temp_new();                                                      \
1.1.1.5   root     2773:     if (type == PPC_64B)                                                      \
1.1.1.6   root     2774:         gen_addr_imm_index(ctx, EA, 0x03);                                    \
1.1.1.5   root     2775:     else                                                                      \
1.1.1.6   root     2776:         gen_addr_imm_index(ctx, EA, 0);                                       \
                   2777:     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
                   2778:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
                   2779:     tcg_temp_free(EA);                                                        \
1.1       root     2780: }
                   2781: 
1.1.1.6   root     2782: #define GEN_STUX(name, stop, opc2, opc3, type)                                \
1.1.1.7   root     2783: static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
1.1       root     2784: {                                                                             \
1.1.1.6   root     2785:     TCGv EA;                                                                  \
1.1.1.5   root     2786:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6   root     2787:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     2788:         return;                                                               \
                   2789:     }                                                                         \
1.1.1.6   root     2790:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   2791:     EA = tcg_temp_new();                                                      \
                   2792:     gen_addr_reg_index(ctx, EA);                                              \
                   2793:     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
                   2794:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
                   2795:     tcg_temp_free(EA);                                                        \
                   2796: }
                   2797: 
1.1.1.13! root     2798: #define GEN_STX_E(name, stop, opc2, opc3, type, type2)                        \
        !          2799: static void glue(gen_, name##x)(DisasContext *ctx)                            \
1.1.1.6   root     2800: {                                                                             \
                   2801:     TCGv EA;                                                                  \
                   2802:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   2803:     EA = tcg_temp_new();                                                      \
                   2804:     gen_addr_reg_index(ctx, EA);                                              \
                   2805:     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
                   2806:     tcg_temp_free(EA);                                                        \
                   2807: }
1.1.1.13! root     2808: #define GEN_STX(name, stop, opc2, opc3, type)                                 \
        !          2809:     GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE)
1.1.1.6   root     2810: 
                   2811: #define GEN_STS(name, stop, op, type)                                         \
                   2812: GEN_ST(name, stop, op | 0x20, type);                                          \
                   2813: GEN_STU(name, stop, op | 0x21, type);                                         \
                   2814: GEN_STUX(name, stop, 0x17, op | 0x01, type);                                  \
                   2815: GEN_STX(name, stop, 0x17, op | 0x00, type)
1.1       root     2816: 
                   2817: /* stb stbu stbux stbx */
1.1.1.6   root     2818: GEN_STS(stb, st8, 0x06, PPC_INTEGER);
1.1       root     2819: /* sth sthu sthux sthx */
1.1.1.6   root     2820: GEN_STS(sth, st16, 0x0C, PPC_INTEGER);
1.1       root     2821: /* stw stwu stwux stwx */
1.1.1.6   root     2822: GEN_STS(stw, st32, 0x04, PPC_INTEGER);
1.1.1.5   root     2823: #if defined(TARGET_PPC64)
1.1.1.6   root     2824: GEN_STUX(std, st64, 0x15, 0x05, PPC_64B);
                   2825: GEN_STX(std, st64, 0x15, 0x04, PPC_64B);
1.1.1.7   root     2826: 
                   2827: static void gen_std(DisasContext *ctx)
1.1.1.5   root     2828: {
                   2829:     int rs;
1.1.1.6   root     2830:     TCGv EA;
1.1       root     2831: 
1.1.1.5   root     2832:     rs = rS(ctx->opcode);
                   2833:     if ((ctx->opcode & 0x3) == 0x2) {
                   2834: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     2835:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     2836: #else
                   2837:         /* stq */
1.1.1.6   root     2838:         if (unlikely(ctx->mem_idx == 0)) {
                   2839:             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     2840:             return;
                   2841:         }
                   2842:         if (unlikely(rs & 1)) {
1.1.1.6   root     2843:             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     2844:             return;
                   2845:         }
1.1.1.6   root     2846:         if (unlikely(ctx->le_mode)) {
1.1.1.5   root     2847:             /* Little-endian mode is not handled */
1.1.1.6   root     2848:             gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
1.1.1.5   root     2849:             return;
                   2850:         }
1.1.1.6   root     2851:         gen_set_access_type(ctx, ACCESS_INT);
                   2852:         EA = tcg_temp_new();
                   2853:         gen_addr_imm_index(ctx, EA, 0x03);
                   2854:         gen_qemu_st64(ctx, cpu_gpr[rs], EA);
                   2855:         gen_addr_add(ctx, EA, EA, 8);
                   2856:         gen_qemu_st64(ctx, cpu_gpr[rs+1], EA);
                   2857:         tcg_temp_free(EA);
1.1.1.5   root     2858: #endif
                   2859:     } else {
                   2860:         /* std / stdu */
                   2861:         if (Rc(ctx->opcode)) {
                   2862:             if (unlikely(rA(ctx->opcode) == 0)) {
1.1.1.6   root     2863:                 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     2864:                 return;
                   2865:             }
                   2866:         }
1.1.1.6   root     2867:         gen_set_access_type(ctx, ACCESS_INT);
                   2868:         EA = tcg_temp_new();
                   2869:         gen_addr_imm_index(ctx, EA, 0x03);
                   2870:         gen_qemu_st64(ctx, cpu_gpr[rs], EA);
1.1.1.5   root     2871:         if (Rc(ctx->opcode))
1.1.1.6   root     2872:             tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
                   2873:         tcg_temp_free(EA);
1.1.1.5   root     2874:     }
                   2875: }
                   2876: #endif
1.1       root     2877: /***                Integer load and store with byte reverse               ***/
                   2878: /* lhbrx */
1.1.1.8   root     2879: static inline void gen_qemu_ld16ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2880: {
                   2881:     tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
                   2882:     if (likely(!ctx->le_mode)) {
1.1.1.7   root     2883:         tcg_gen_bswap16_tl(arg1, arg1);
1.1.1.6   root     2884:     }
                   2885: }
                   2886: GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
                   2887: 
1.1       root     2888: /* lwbrx */
1.1.1.8   root     2889: static inline void gen_qemu_ld32ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2890: {
                   2891:     tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
                   2892:     if (likely(!ctx->le_mode)) {
1.1.1.7   root     2893:         tcg_gen_bswap32_tl(arg1, arg1);
1.1.1.6   root     2894:     }
                   2895: }
                   2896: GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
                   2897: 
1.1.1.13! root     2898: #if defined(TARGET_PPC64)
        !          2899: /* ldbrx */
        !          2900: static inline void gen_qemu_ld64ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
        !          2901: {
        !          2902:     tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
        !          2903:     if (likely(!ctx->le_mode)) {
        !          2904:         tcg_gen_bswap64_tl(arg1, arg1);
        !          2905:     }
        !          2906: }
        !          2907: GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX);
        !          2908: #endif  /* TARGET_PPC64 */
        !          2909: 
1.1       root     2910: /* sthbrx */
1.1.1.8   root     2911: static inline void gen_qemu_st16r(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2912: {
                   2913:     if (likely(!ctx->le_mode)) {
                   2914:         TCGv t0 = tcg_temp_new();
                   2915:         tcg_gen_ext16u_tl(t0, arg1);
1.1.1.7   root     2916:         tcg_gen_bswap16_tl(t0, t0);
1.1.1.6   root     2917:         tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
                   2918:         tcg_temp_free(t0);
                   2919:     } else {
                   2920:         tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
                   2921:     }
                   2922: }
                   2923: GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
                   2924: 
1.1       root     2925: /* stwbrx */
1.1.1.8   root     2926: static inline void gen_qemu_st32r(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2927: {
                   2928:     if (likely(!ctx->le_mode)) {
1.1.1.7   root     2929:         TCGv t0 = tcg_temp_new();
                   2930:         tcg_gen_ext32u_tl(t0, arg1);
                   2931:         tcg_gen_bswap32_tl(t0, t0);
1.1.1.6   root     2932:         tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
                   2933:         tcg_temp_free(t0);
                   2934:     } else {
                   2935:         tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
                   2936:     }
                   2937: }
                   2938: GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
1.1       root     2939: 
1.1.1.13! root     2940: #if defined(TARGET_PPC64)
        !          2941: /* stdbrx */
        !          2942: static inline void gen_qemu_st64r(DisasContext *ctx, TCGv arg1, TCGv arg2)
        !          2943: {
        !          2944:     if (likely(!ctx->le_mode)) {
        !          2945:         TCGv t0 = tcg_temp_new();
        !          2946:         tcg_gen_bswap64_tl(t0, arg1);
        !          2947:         tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx);
        !          2948:         tcg_temp_free(t0);
        !          2949:     } else {
        !          2950:         tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx);
        !          2951:     }
        !          2952: }
        !          2953: GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX);
        !          2954: #endif  /* TARGET_PPC64 */
        !          2955: 
1.1       root     2956: /***                    Integer load and store multiple                    ***/
1.1.1.7   root     2957: 
1.1       root     2958: /* lmw */
1.1.1.7   root     2959: static void gen_lmw(DisasContext *ctx)
1.1       root     2960: {
1.1.1.6   root     2961:     TCGv t0;
                   2962:     TCGv_i32 t1;
                   2963:     gen_set_access_type(ctx, ACCESS_INT);
1.1.1.5   root     2964:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2965:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6   root     2966:     t0 = tcg_temp_new();
                   2967:     t1 = tcg_const_i32(rD(ctx->opcode));
                   2968:     gen_addr_imm_index(ctx, t0, 0);
                   2969:     gen_helper_lmw(t0, t1);
                   2970:     tcg_temp_free(t0);
                   2971:     tcg_temp_free_i32(t1);
1.1       root     2972: }
                   2973: 
                   2974: /* stmw */
1.1.1.7   root     2975: static void gen_stmw(DisasContext *ctx)
1.1       root     2976: {
1.1.1.6   root     2977:     TCGv t0;
                   2978:     TCGv_i32 t1;
                   2979:     gen_set_access_type(ctx, ACCESS_INT);
1.1.1.5   root     2980:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2981:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6   root     2982:     t0 = tcg_temp_new();
                   2983:     t1 = tcg_const_i32(rS(ctx->opcode));
                   2984:     gen_addr_imm_index(ctx, t0, 0);
                   2985:     gen_helper_stmw(t0, t1);
                   2986:     tcg_temp_free(t0);
                   2987:     tcg_temp_free_i32(t1);
1.1       root     2988: }
                   2989: 
                   2990: /***                    Integer load and store strings                     ***/
1.1.1.7   root     2991: 
1.1       root     2992: /* lswi */
                   2993: /* PowerPC32 specification says we must generate an exception if
                   2994:  * rA is in the range of registers to be loaded.
                   2995:  * In an other hand, IBM says this is valid, but rA won't be loaded.
                   2996:  * For now, I'll follow the spec...
                   2997:  */
1.1.1.7   root     2998: static void gen_lswi(DisasContext *ctx)
1.1       root     2999: {
1.1.1.6   root     3000:     TCGv t0;
                   3001:     TCGv_i32 t1, t2;
1.1       root     3002:     int nb = NB(ctx->opcode);
                   3003:     int start = rD(ctx->opcode);
                   3004:     int ra = rA(ctx->opcode);
                   3005:     int nr;
                   3006: 
                   3007:     if (nb == 0)
                   3008:         nb = 32;
                   3009:     nr = nb / 4;
1.1.1.5   root     3010:     if (unlikely(((start + nr) > 32  &&
                   3011:                   start <= ra && (start + nr - 32) > ra) ||
                   3012:                  ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
1.1.1.6   root     3013:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
1.1       root     3014:         return;
                   3015:     }
1.1.1.6   root     3016:     gen_set_access_type(ctx, ACCESS_INT);
1.1       root     3017:     /* NIP cannot be restored if the memory exception comes from an helper */
1.1.1.5   root     3018:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6   root     3019:     t0 = tcg_temp_new();
                   3020:     gen_addr_register(ctx, t0);
                   3021:     t1 = tcg_const_i32(nb);
                   3022:     t2 = tcg_const_i32(start);
                   3023:     gen_helper_lsw(t0, t1, t2);
                   3024:     tcg_temp_free(t0);
                   3025:     tcg_temp_free_i32(t1);
                   3026:     tcg_temp_free_i32(t2);
1.1       root     3027: }
                   3028: 
                   3029: /* lswx */
1.1.1.7   root     3030: static void gen_lswx(DisasContext *ctx)
1.1       root     3031: {
1.1.1.6   root     3032:     TCGv t0;
                   3033:     TCGv_i32 t1, t2, t3;
                   3034:     gen_set_access_type(ctx, ACCESS_INT);
1.1.1.5   root     3035:     /* NIP cannot be restored if the memory exception comes from an helper */
                   3036:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6   root     3037:     t0 = tcg_temp_new();
                   3038:     gen_addr_reg_index(ctx, t0);
                   3039:     t1 = tcg_const_i32(rD(ctx->opcode));
                   3040:     t2 = tcg_const_i32(rA(ctx->opcode));
                   3041:     t3 = tcg_const_i32(rB(ctx->opcode));
                   3042:     gen_helper_lswx(t0, t1, t2, t3);
                   3043:     tcg_temp_free(t0);
                   3044:     tcg_temp_free_i32(t1);
                   3045:     tcg_temp_free_i32(t2);
                   3046:     tcg_temp_free_i32(t3);
1.1       root     3047: }
                   3048: 
                   3049: /* stswi */
1.1.1.7   root     3050: static void gen_stswi(DisasContext *ctx)
1.1       root     3051: {
1.1.1.6   root     3052:     TCGv t0;
                   3053:     TCGv_i32 t1, t2;
1.1       root     3054:     int nb = NB(ctx->opcode);
1.1.1.6   root     3055:     gen_set_access_type(ctx, ACCESS_INT);
1.1.1.5   root     3056:     /* NIP cannot be restored if the memory exception comes from an helper */
                   3057:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6   root     3058:     t0 = tcg_temp_new();
                   3059:     gen_addr_register(ctx, t0);
1.1       root     3060:     if (nb == 0)
                   3061:         nb = 32;
1.1.1.6   root     3062:     t1 = tcg_const_i32(nb);
                   3063:     t2 = tcg_const_i32(rS(ctx->opcode));
                   3064:     gen_helper_stsw(t0, t1, t2);
                   3065:     tcg_temp_free(t0);
                   3066:     tcg_temp_free_i32(t1);
                   3067:     tcg_temp_free_i32(t2);
1.1       root     3068: }
                   3069: 
                   3070: /* stswx */
1.1.1.7   root     3071: static void gen_stswx(DisasContext *ctx)
1.1       root     3072: {
1.1.1.6   root     3073:     TCGv t0;
                   3074:     TCGv_i32 t1, t2;
                   3075:     gen_set_access_type(ctx, ACCESS_INT);
1.1       root     3076:     /* NIP cannot be restored if the memory exception comes from an helper */
1.1.1.5   root     3077:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6   root     3078:     t0 = tcg_temp_new();
                   3079:     gen_addr_reg_index(ctx, t0);
                   3080:     t1 = tcg_temp_new_i32();
                   3081:     tcg_gen_trunc_tl_i32(t1, cpu_xer);
                   3082:     tcg_gen_andi_i32(t1, t1, 0x7F);
                   3083:     t2 = tcg_const_i32(rS(ctx->opcode));
                   3084:     gen_helper_stsw(t0, t1, t2);
                   3085:     tcg_temp_free(t0);
                   3086:     tcg_temp_free_i32(t1);
                   3087:     tcg_temp_free_i32(t2);
1.1       root     3088: }
                   3089: 
                   3090: /***                        Memory synchronisation                         ***/
                   3091: /* eieio */
1.1.1.7   root     3092: static void gen_eieio(DisasContext *ctx)
1.1       root     3093: {
                   3094: }
                   3095: 
                   3096: /* isync */
1.1.1.7   root     3097: static void gen_isync(DisasContext *ctx)
1.1       root     3098: {
1.1.1.6   root     3099:     gen_stop_exception(ctx);
1.1       root     3100: }
                   3101: 
                   3102: /* lwarx */
1.1.1.7   root     3103: static void gen_lwarx(DisasContext *ctx)
1.1       root     3104: {
1.1.1.6   root     3105:     TCGv t0;
1.1.1.8   root     3106:     TCGv gpr = cpu_gpr[rD(ctx->opcode)];
1.1.1.6   root     3107:     gen_set_access_type(ctx, ACCESS_RES);
                   3108:     t0 = tcg_temp_local_new();
                   3109:     gen_addr_reg_index(ctx, t0);
                   3110:     gen_check_align(ctx, t0, 0x03);
1.1.1.8   root     3111:     gen_qemu_ld32u(ctx, gpr, t0);
1.1.1.6   root     3112:     tcg_gen_mov_tl(cpu_reserve, t0);
1.1.1.13! root     3113:     tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUPPCState, reserve_val));
1.1.1.6   root     3114:     tcg_temp_free(t0);
1.1       root     3115: }
                   3116: 
1.1.1.8   root     3117: #if defined(CONFIG_USER_ONLY)
                   3118: static void gen_conditional_store (DisasContext *ctx, TCGv EA,
                   3119:                                    int reg, int size)
                   3120: {
                   3121:     TCGv t0 = tcg_temp_new();
                   3122:     uint32_t save_exception = ctx->exception;
                   3123: 
1.1.1.13! root     3124:     tcg_gen_st_tl(EA, cpu_env, offsetof(CPUPPCState, reserve_ea));
1.1.1.8   root     3125:     tcg_gen_movi_tl(t0, (size << 5) | reg);
1.1.1.13! root     3126:     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, reserve_info));
1.1.1.8   root     3127:     tcg_temp_free(t0);
                   3128:     gen_update_nip(ctx, ctx->nip-4);
                   3129:     ctx->exception = POWERPC_EXCP_BRANCH;
                   3130:     gen_exception(ctx, POWERPC_EXCP_STCX);
                   3131:     ctx->exception = save_exception;
                   3132: }
                   3133: #endif
                   3134: 
1.1       root     3135: /* stwcx. */
1.1.1.7   root     3136: static void gen_stwcx_(DisasContext *ctx)
1.1       root     3137: {
1.1.1.6   root     3138:     TCGv t0;
                   3139:     gen_set_access_type(ctx, ACCESS_RES);
                   3140:     t0 = tcg_temp_local_new();
                   3141:     gen_addr_reg_index(ctx, t0);
                   3142:     gen_check_align(ctx, t0, 0x03);
1.1.1.8   root     3143: #if defined(CONFIG_USER_ONLY)
                   3144:     gen_conditional_store(ctx, t0, rS(ctx->opcode), 4);
                   3145: #else
                   3146:     {
                   3147:         int l1;
                   3148: 
                   3149:         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
                   3150:         tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
                   3151:         tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
                   3152:         l1 = gen_new_label();
                   3153:         tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
                   3154:         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
                   3155:         gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], t0);
                   3156:         gen_set_label(l1);
                   3157:         tcg_gen_movi_tl(cpu_reserve, -1);
                   3158:     }
                   3159: #endif
1.1.1.6   root     3160:     tcg_temp_free(t0);
1.1       root     3161: }
                   3162: 
1.1.1.5   root     3163: #if defined(TARGET_PPC64)
                   3164: /* ldarx */
1.1.1.7   root     3165: static void gen_ldarx(DisasContext *ctx)
1.1.1.5   root     3166: {
1.1.1.6   root     3167:     TCGv t0;
1.1.1.8   root     3168:     TCGv gpr = cpu_gpr[rD(ctx->opcode)];
1.1.1.6   root     3169:     gen_set_access_type(ctx, ACCESS_RES);
                   3170:     t0 = tcg_temp_local_new();
                   3171:     gen_addr_reg_index(ctx, t0);
                   3172:     gen_check_align(ctx, t0, 0x07);
1.1.1.8   root     3173:     gen_qemu_ld64(ctx, gpr, t0);
1.1.1.6   root     3174:     tcg_gen_mov_tl(cpu_reserve, t0);
1.1.1.13! root     3175:     tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUPPCState, reserve_val));
1.1.1.6   root     3176:     tcg_temp_free(t0);
1.1.1.5   root     3177: }
                   3178: 
                   3179: /* stdcx. */
1.1.1.7   root     3180: static void gen_stdcx_(DisasContext *ctx)
1.1.1.5   root     3181: {
1.1.1.6   root     3182:     TCGv t0;
                   3183:     gen_set_access_type(ctx, ACCESS_RES);
                   3184:     t0 = tcg_temp_local_new();
                   3185:     gen_addr_reg_index(ctx, t0);
                   3186:     gen_check_align(ctx, t0, 0x07);
1.1.1.8   root     3187: #if defined(CONFIG_USER_ONLY)
                   3188:     gen_conditional_store(ctx, t0, rS(ctx->opcode), 8);
                   3189: #else
                   3190:     {
                   3191:         int l1;
                   3192:         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
                   3193:         tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
                   3194:         tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
                   3195:         l1 = gen_new_label();
                   3196:         tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
                   3197:         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
                   3198:         gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], t0);
                   3199:         gen_set_label(l1);
                   3200:         tcg_gen_movi_tl(cpu_reserve, -1);
                   3201:     }
                   3202: #endif
1.1.1.6   root     3203:     tcg_temp_free(t0);
1.1.1.5   root     3204: }
                   3205: #endif /* defined(TARGET_PPC64) */
                   3206: 
1.1       root     3207: /* sync */
1.1.1.7   root     3208: static void gen_sync(DisasContext *ctx)
1.1       root     3209: {
                   3210: }
                   3211: 
1.1.1.5   root     3212: /* wait */
1.1.1.7   root     3213: static void gen_wait(DisasContext *ctx)
1.1.1.5   root     3214: {
1.1.1.6   root     3215:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.13! root     3216:     tcg_gen_st_i32(t0, cpu_env, offsetof(CPUPPCState, halted));
1.1.1.6   root     3217:     tcg_temp_free_i32(t0);
1.1.1.5   root     3218:     /* Stop translation, as the CPU is supposed to sleep from now */
1.1.1.6   root     3219:     gen_exception_err(ctx, EXCP_HLT, 1);
1.1.1.5   root     3220: }
                   3221: 
1.1       root     3222: /***                         Floating-point load                           ***/
1.1.1.6   root     3223: #define GEN_LDF(name, ldop, opc, type)                                        \
1.1.1.7   root     3224: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1       root     3225: {                                                                             \
1.1.1.6   root     3226:     TCGv EA;                                                                  \
1.1.1.5   root     3227:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     3228:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3229:         return;                                                               \
                   3230:     }                                                                         \
1.1.1.6   root     3231:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
                   3232:     EA = tcg_temp_new();                                                      \
                   3233:     gen_addr_imm_index(ctx, EA, 0);                                           \
                   3234:     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
                   3235:     tcg_temp_free(EA);                                                        \
1.1       root     3236: }
                   3237: 
1.1.1.6   root     3238: #define GEN_LDUF(name, ldop, opc, type)                                       \
1.1.1.7   root     3239: static void glue(gen_, name##u)(DisasContext *ctx)                                    \
1.1       root     3240: {                                                                             \
1.1.1.6   root     3241:     TCGv EA;                                                                  \
1.1.1.5   root     3242:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     3243:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3244:         return;                                                               \
                   3245:     }                                                                         \
1.1.1.5   root     3246:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6   root     3247:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     3248:         return;                                                               \
                   3249:     }                                                                         \
1.1.1.6   root     3250:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
                   3251:     EA = tcg_temp_new();                                                      \
                   3252:     gen_addr_imm_index(ctx, EA, 0);                                           \
                   3253:     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
                   3254:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
                   3255:     tcg_temp_free(EA);                                                        \
1.1       root     3256: }
                   3257: 
1.1.1.6   root     3258: #define GEN_LDUXF(name, ldop, opc, type)                                      \
1.1.1.7   root     3259: static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
1.1       root     3260: {                                                                             \
1.1.1.6   root     3261:     TCGv EA;                                                                  \
1.1.1.5   root     3262:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     3263:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3264:         return;                                                               \
                   3265:     }                                                                         \
1.1.1.5   root     3266:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6   root     3267:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     3268:         return;                                                               \
                   3269:     }                                                                         \
1.1.1.6   root     3270:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
                   3271:     EA = tcg_temp_new();                                                      \
                   3272:     gen_addr_reg_index(ctx, EA);                                              \
                   3273:     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
                   3274:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
                   3275:     tcg_temp_free(EA);                                                        \
1.1       root     3276: }
                   3277: 
1.1.1.6   root     3278: #define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
1.1.1.7   root     3279: static void glue(gen_, name##x)(DisasContext *ctx)                                    \
1.1       root     3280: {                                                                             \
1.1.1.6   root     3281:     TCGv EA;                                                                  \
1.1.1.5   root     3282:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     3283:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3284:         return;                                                               \
                   3285:     }                                                                         \
1.1.1.6   root     3286:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
                   3287:     EA = tcg_temp_new();                                                      \
                   3288:     gen_addr_reg_index(ctx, EA);                                              \
                   3289:     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
                   3290:     tcg_temp_free(EA);                                                        \
                   3291: }
                   3292: 
                   3293: #define GEN_LDFS(name, ldop, op, type)                                        \
                   3294: GEN_LDF(name, ldop, op | 0x20, type);                                         \
                   3295: GEN_LDUF(name, ldop, op | 0x21, type);                                        \
                   3296: GEN_LDUXF(name, ldop, op | 0x01, type);                                       \
                   3297: GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
                   3298: 
1.1.1.8   root     3299: static inline void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
1.1.1.6   root     3300: {
                   3301:     TCGv t0 = tcg_temp_new();
                   3302:     TCGv_i32 t1 = tcg_temp_new_i32();
                   3303:     gen_qemu_ld32u(ctx, t0, arg2);
                   3304:     tcg_gen_trunc_tl_i32(t1, t0);
                   3305:     tcg_temp_free(t0);
                   3306:     gen_helper_float32_to_float64(arg1, t1);
                   3307:     tcg_temp_free_i32(t1);
                   3308: }
                   3309: 
                   3310:  /* lfd lfdu lfdux lfdx */
                   3311: GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT);
                   3312:  /* lfs lfsu lfsux lfsx */
                   3313: GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT);
1.1       root     3314: 
                   3315: /***                         Floating-point store                          ***/
1.1.1.6   root     3316: #define GEN_STF(name, stop, opc, type)                                        \
1.1.1.7   root     3317: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1       root     3318: {                                                                             \
1.1.1.6   root     3319:     TCGv EA;                                                                  \
1.1.1.5   root     3320:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     3321:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1.1.5   root     3322:         return;                                                               \
1.1       root     3323:     }                                                                         \
1.1.1.6   root     3324:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
                   3325:     EA = tcg_temp_new();                                                      \
                   3326:     gen_addr_imm_index(ctx, EA, 0);                                           \
                   3327:     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
                   3328:     tcg_temp_free(EA);                                                        \
1.1       root     3329: }
                   3330: 
1.1.1.6   root     3331: #define GEN_STUF(name, stop, opc, type)                                       \
1.1.1.7   root     3332: static void glue(gen_, name##u)(DisasContext *ctx)                                    \
1.1       root     3333: {                                                                             \
1.1.1.6   root     3334:     TCGv EA;                                                                  \
1.1.1.5   root     3335:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     3336:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3337:         return;                                                               \
                   3338:     }                                                                         \
1.1.1.5   root     3339:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6   root     3340:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     3341:         return;                                                               \
                   3342:     }                                                                         \
1.1.1.6   root     3343:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
                   3344:     EA = tcg_temp_new();                                                      \
                   3345:     gen_addr_imm_index(ctx, EA, 0);                                           \
                   3346:     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
                   3347:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
                   3348:     tcg_temp_free(EA);                                                        \
1.1       root     3349: }
                   3350: 
1.1.1.6   root     3351: #define GEN_STUXF(name, stop, opc, type)                                      \
1.1.1.7   root     3352: static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
1.1       root     3353: {                                                                             \
1.1.1.6   root     3354:     TCGv EA;                                                                  \
1.1.1.5   root     3355:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     3356:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3357:         return;                                                               \
                   3358:     }                                                                         \
1.1.1.5   root     3359:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6   root     3360:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     3361:         return;                                                               \
                   3362:     }                                                                         \
1.1.1.6   root     3363:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
                   3364:     EA = tcg_temp_new();                                                      \
                   3365:     gen_addr_reg_index(ctx, EA);                                              \
                   3366:     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
                   3367:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
                   3368:     tcg_temp_free(EA);                                                        \
1.1       root     3369: }
                   3370: 
1.1.1.6   root     3371: #define GEN_STXF(name, stop, opc2, opc3, type)                                \
1.1.1.7   root     3372: static void glue(gen_, name##x)(DisasContext *ctx)                                    \
1.1       root     3373: {                                                                             \
1.1.1.6   root     3374:     TCGv EA;                                                                  \
1.1.1.5   root     3375:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     3376:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3377:         return;                                                               \
                   3378:     }                                                                         \
1.1.1.6   root     3379:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
                   3380:     EA = tcg_temp_new();                                                      \
                   3381:     gen_addr_reg_index(ctx, EA);                                              \
                   3382:     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
                   3383:     tcg_temp_free(EA);                                                        \
                   3384: }
                   3385: 
                   3386: #define GEN_STFS(name, stop, op, type)                                        \
                   3387: GEN_STF(name, stop, op | 0x20, type);                                         \
                   3388: GEN_STUF(name, stop, op | 0x21, type);                                        \
                   3389: GEN_STUXF(name, stop, op | 0x01, type);                                       \
                   3390: GEN_STXF(name, stop, 0x17, op | 0x00, type)
                   3391: 
1.1.1.8   root     3392: static inline void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
1.1.1.6   root     3393: {
                   3394:     TCGv_i32 t0 = tcg_temp_new_i32();
                   3395:     TCGv t1 = tcg_temp_new();
                   3396:     gen_helper_float64_to_float32(t0, arg1);
                   3397:     tcg_gen_extu_i32_tl(t1, t0);
                   3398:     tcg_temp_free_i32(t0);
                   3399:     gen_qemu_st32(ctx, t1, arg2);
                   3400:     tcg_temp_free(t1);
1.1       root     3401: }
                   3402: 
                   3403: /* stfd stfdu stfdux stfdx */
1.1.1.6   root     3404: GEN_STFS(stfd, st64, 0x16, PPC_FLOAT);
1.1       root     3405: /* stfs stfsu stfsux stfsx */
1.1.1.6   root     3406: GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT);
1.1       root     3407: 
                   3408: /* Optional: */
1.1.1.8   root     3409: static inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
1.1.1.6   root     3410: {
                   3411:     TCGv t0 = tcg_temp_new();
                   3412:     tcg_gen_trunc_i64_tl(t0, arg1),
                   3413:     gen_qemu_st32(ctx, t0, arg2);
                   3414:     tcg_temp_free(t0);
                   3415: }
1.1       root     3416: /* stfiwx */
1.1.1.6   root     3417: GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
1.1       root     3418: 
1.1.1.12  root     3419: static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip)
                   3420: {
                   3421: #if defined(TARGET_PPC64)
                   3422:     if (ctx->has_cfar)
                   3423:         tcg_gen_movi_tl(cpu_cfar, nip);
                   3424: #endif
                   3425: }
                   3426: 
1.1       root     3427: /***                                Branch                                 ***/
1.1.1.8   root     3428: static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1.1.1.2   root     3429: {
                   3430:     TranslationBlock *tb;
                   3431:     tb = ctx->tb;
1.1.1.5   root     3432: #if defined(TARGET_PPC64)
1.1.1.6   root     3433:     if (!ctx->sf_mode)
                   3434:         dest = (uint32_t) dest;
1.1.1.5   root     3435: #endif
1.1.1.6   root     3436:     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
                   3437:         likely(!ctx->singlestep_enabled)) {
                   3438:         tcg_gen_goto_tb(n);
                   3439:         tcg_gen_movi_tl(cpu_nip, dest & ~3);
1.1.1.11  root     3440:         tcg_gen_exit_tb((tcg_target_long)tb + n);
1.1.1.2   root     3441:     } else {
1.1.1.6   root     3442:         tcg_gen_movi_tl(cpu_nip, dest & ~3);
                   3443:         if (unlikely(ctx->singlestep_enabled)) {
                   3444:             if ((ctx->singlestep_enabled &
                   3445:                 (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
                   3446:                 ctx->exception == POWERPC_EXCP_BRANCH) {
                   3447:                 target_ulong tmp = ctx->nip;
                   3448:                 ctx->nip = dest;
                   3449:                 gen_exception(ctx, POWERPC_EXCP_TRACE);
                   3450:                 ctx->nip = tmp;
                   3451:             }
                   3452:             if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
                   3453:                 gen_debug_exception(ctx);
                   3454:             }
                   3455:         }
                   3456:         tcg_gen_exit_tb(0);
1.1.1.2   root     3457:     }
                   3458: }
                   3459: 
1.1.1.8   root     3460: static inline void gen_setlr(DisasContext *ctx, target_ulong nip)
1.1.1.5   root     3461: {
                   3462: #if defined(TARGET_PPC64)
1.1.1.6   root     3463:     if (ctx->sf_mode == 0)
                   3464:         tcg_gen_movi_tl(cpu_lr, (uint32_t)nip);
1.1.1.5   root     3465:     else
                   3466: #endif
1.1.1.6   root     3467:         tcg_gen_movi_tl(cpu_lr, nip);
1.1.1.5   root     3468: }
                   3469: 
1.1       root     3470: /* b ba bl bla */
1.1.1.7   root     3471: static void gen_b(DisasContext *ctx)
1.1       root     3472: {
1.1.1.5   root     3473:     target_ulong li, target;
1.1       root     3474: 
1.1.1.6   root     3475:     ctx->exception = POWERPC_EXCP_BRANCH;
1.1       root     3476:     /* sign extend LI */
1.1.1.5   root     3477: #if defined(TARGET_PPC64)
                   3478:     if (ctx->sf_mode)
                   3479:         li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
                   3480:     else
                   3481: #endif
                   3482:         li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
                   3483:     if (likely(AA(ctx->opcode) == 0))
1.1       root     3484:         target = ctx->nip + li - 4;
                   3485:     else
                   3486:         target = li;
1.1.1.5   root     3487:     if (LK(ctx->opcode))
                   3488:         gen_setlr(ctx, ctx->nip);
1.1.1.12  root     3489:     gen_update_cfar(ctx, ctx->nip);
1.1.1.2   root     3490:     gen_goto_tb(ctx, 0, target);
1.1       root     3491: }
                   3492: 
                   3493: #define BCOND_IM  0
                   3494: #define BCOND_LR  1
                   3495: #define BCOND_CTR 2
                   3496: 
1.1.1.8   root     3497: static inline void gen_bcond(DisasContext *ctx, int type)
1.1.1.5   root     3498: {
                   3499:     uint32_t bo = BO(ctx->opcode);
1.1.1.9   root     3500:     int l1;
1.1.1.6   root     3501:     TCGv target;
1.1       root     3502: 
1.1.1.6   root     3503:     ctx->exception = POWERPC_EXCP_BRANCH;
                   3504:     if (type == BCOND_LR || type == BCOND_CTR) {
                   3505:         target = tcg_temp_local_new();
                   3506:         if (type == BCOND_CTR)
                   3507:             tcg_gen_mov_tl(target, cpu_ctr);
                   3508:         else
                   3509:             tcg_gen_mov_tl(target, cpu_lr);
1.1.1.7   root     3510:     } else {
                   3511:         TCGV_UNUSED(target);
1.1       root     3512:     }
1.1.1.5   root     3513:     if (LK(ctx->opcode))
                   3514:         gen_setlr(ctx, ctx->nip);
1.1.1.6   root     3515:     l1 = gen_new_label();
                   3516:     if ((bo & 0x4) == 0) {
                   3517:         /* Decrement and test CTR */
                   3518:         TCGv temp = tcg_temp_new();
                   3519:         if (unlikely(type == BCOND_CTR)) {
                   3520:             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
                   3521:             return;
                   3522:         }
                   3523:         tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
1.1.1.5   root     3524: #if defined(TARGET_PPC64)
1.1.1.6   root     3525:         if (!ctx->sf_mode)
                   3526:             tcg_gen_ext32u_tl(temp, cpu_ctr);
                   3527:         else
1.1.1.5   root     3528: #endif
1.1.1.6   root     3529:             tcg_gen_mov_tl(temp, cpu_ctr);
                   3530:         if (bo & 0x2) {
                   3531:             tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
                   3532:         } else {
                   3533:             tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
1.1       root     3534:         }
1.1.1.6   root     3535:         tcg_temp_free(temp);
                   3536:     }
                   3537:     if ((bo & 0x10) == 0) {
                   3538:         /* Test CR */
                   3539:         uint32_t bi = BI(ctx->opcode);
                   3540:         uint32_t mask = 1 << (3 - (bi & 0x03));
                   3541:         TCGv_i32 temp = tcg_temp_new_i32();
                   3542: 
1.1.1.5   root     3543:         if (bo & 0x8) {
1.1.1.6   root     3544:             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
                   3545:             tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1);
1.1.1.5   root     3546:         } else {
1.1.1.6   root     3547:             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
                   3548:             tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);
1.1.1.5   root     3549:         }
1.1.1.6   root     3550:         tcg_temp_free_i32(temp);
1.1.1.5   root     3551:     }
1.1.1.12  root     3552:     gen_update_cfar(ctx, ctx->nip);
1.1       root     3553:     if (type == BCOND_IM) {
1.1.1.6   root     3554:         target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
                   3555:         if (likely(AA(ctx->opcode) == 0)) {
                   3556:             gen_goto_tb(ctx, 0, ctx->nip + li - 4);
                   3557:         } else {
                   3558:             gen_goto_tb(ctx, 0, li);
                   3559:         }
1.1.1.2   root     3560:         gen_set_label(l1);
                   3561:         gen_goto_tb(ctx, 1, ctx->nip);
1.1       root     3562:     } else {
1.1.1.5   root     3563: #if defined(TARGET_PPC64)
1.1.1.6   root     3564:         if (!(ctx->sf_mode))
                   3565:             tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3);
                   3566:         else
                   3567: #endif
                   3568:             tcg_gen_andi_tl(cpu_nip, target, ~3);
                   3569:         tcg_gen_exit_tb(0);
                   3570:         gen_set_label(l1);
                   3571: #if defined(TARGET_PPC64)
                   3572:         if (!(ctx->sf_mode))
                   3573:             tcg_gen_movi_tl(cpu_nip, (uint32_t)ctx->nip);
1.1.1.5   root     3574:         else
                   3575: #endif
1.1.1.6   root     3576:             tcg_gen_movi_tl(cpu_nip, ctx->nip);
                   3577:         tcg_gen_exit_tb(0);
1.1       root     3578:     }
                   3579: }
                   3580: 
1.1.1.7   root     3581: static void gen_bc(DisasContext *ctx)
1.1.1.5   root     3582: {
1.1       root     3583:     gen_bcond(ctx, BCOND_IM);
                   3584: }
                   3585: 
1.1.1.7   root     3586: static void gen_bcctr(DisasContext *ctx)
1.1.1.5   root     3587: {
1.1       root     3588:     gen_bcond(ctx, BCOND_CTR);
                   3589: }
                   3590: 
1.1.1.7   root     3591: static void gen_bclr(DisasContext *ctx)
1.1.1.5   root     3592: {
1.1       root     3593:     gen_bcond(ctx, BCOND_LR);
                   3594: }
                   3595: 
                   3596: /***                      Condition register logical                       ***/
1.1.1.6   root     3597: #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
1.1.1.7   root     3598: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1       root     3599: {                                                                             \
1.1.1.5   root     3600:     uint8_t bitmask;                                                          \
                   3601:     int sh;                                                                   \
1.1.1.6   root     3602:     TCGv_i32 t0, t1;                                                          \
1.1.1.5   root     3603:     sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
1.1.1.6   root     3604:     t0 = tcg_temp_new_i32();                                                  \
1.1.1.5   root     3605:     if (sh > 0)                                                               \
1.1.1.6   root     3606:         tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh);            \
1.1.1.5   root     3607:     else if (sh < 0)                                                          \
1.1.1.6   root     3608:         tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh);           \
                   3609:     else                                                                      \
                   3610:         tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]);                 \
                   3611:     t1 = tcg_temp_new_i32();                                                  \
1.1.1.5   root     3612:     sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
                   3613:     if (sh > 0)                                                               \
1.1.1.6   root     3614:         tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh);            \
1.1.1.5   root     3615:     else if (sh < 0)                                                          \
1.1.1.6   root     3616:         tcg_gen_shli_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], -sh);           \
                   3617:     else                                                                      \
                   3618:         tcg_gen_mov_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2]);                 \
                   3619:     tcg_op(t0, t0, t1);                                                       \
1.1.1.5   root     3620:     bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03));                          \
1.1.1.6   root     3621:     tcg_gen_andi_i32(t0, t0, bitmask);                                        \
                   3622:     tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask);          \
                   3623:     tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1);                  \
                   3624:     tcg_temp_free_i32(t0);                                                    \
                   3625:     tcg_temp_free_i32(t1);                                                    \
1.1       root     3626: }
                   3627: 
                   3628: /* crand */
1.1.1.6   root     3629: GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08);
1.1       root     3630: /* crandc */
1.1.1.6   root     3631: GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04);
1.1       root     3632: /* creqv */
1.1.1.6   root     3633: GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09);
1.1       root     3634: /* crnand */
1.1.1.6   root     3635: GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07);
1.1       root     3636: /* crnor */
1.1.1.6   root     3637: GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01);
1.1       root     3638: /* cror */
1.1.1.6   root     3639: GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E);
1.1       root     3640: /* crorc */
1.1.1.6   root     3641: GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D);
1.1       root     3642: /* crxor */
1.1.1.6   root     3643: GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06);
1.1.1.7   root     3644: 
1.1       root     3645: /* mcrf */
1.1.1.7   root     3646: static void gen_mcrf(DisasContext *ctx)
1.1       root     3647: {
1.1.1.6   root     3648:     tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]);
1.1       root     3649: }
                   3650: 
                   3651: /***                           System linkage                              ***/
1.1.1.7   root     3652: 
1.1.1.6   root     3653: /* rfi (mem_idx only) */
1.1.1.7   root     3654: static void gen_rfi(DisasContext *ctx)
1.1       root     3655: {
                   3656: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     3657:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     3658: #else
                   3659:     /* Restore CPU state */
1.1.1.6   root     3660:     if (unlikely(!ctx->mem_idx)) {
                   3661:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     3662:         return;
                   3663:     }
1.1.1.12  root     3664:     gen_update_cfar(ctx, ctx->nip);
1.1.1.6   root     3665:     gen_helper_rfi();
                   3666:     gen_sync_exception(ctx);
1.1       root     3667: #endif
                   3668: }
                   3669: 
1.1.1.5   root     3670: #if defined(TARGET_PPC64)
1.1.1.7   root     3671: static void gen_rfid(DisasContext *ctx)
1.1.1.5   root     3672: {
                   3673: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     3674:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     3675: #else
                   3676:     /* Restore CPU state */
1.1.1.6   root     3677:     if (unlikely(!ctx->mem_idx)) {
                   3678:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     3679:         return;
                   3680:     }
1.1.1.12  root     3681:     gen_update_cfar(ctx, ctx->nip);
1.1.1.6   root     3682:     gen_helper_rfid();
                   3683:     gen_sync_exception(ctx);
1.1.1.5   root     3684: #endif
                   3685: }
                   3686: 
1.1.1.7   root     3687: static void gen_hrfid(DisasContext *ctx)
1.1       root     3688: {
                   3689: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     3690:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     3691: #else
                   3692:     /* Restore CPU state */
1.1.1.6   root     3693:     if (unlikely(ctx->mem_idx <= 1)) {
                   3694:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     3695:         return;
                   3696:     }
1.1.1.6   root     3697:     gen_helper_hrfid();
                   3698:     gen_sync_exception(ctx);
1.1.1.5   root     3699: #endif
                   3700: }
                   3701: #endif
                   3702: 
                   3703: /* sc */
                   3704: #if defined(CONFIG_USER_ONLY)
                   3705: #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
1.1       root     3706: #else
1.1.1.5   root     3707: #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
1.1       root     3708: #endif
1.1.1.7   root     3709: static void gen_sc(DisasContext *ctx)
1.1.1.5   root     3710: {
                   3711:     uint32_t lev;
                   3712: 
                   3713:     lev = (ctx->opcode >> 5) & 0x7F;
1.1.1.6   root     3714:     gen_exception_err(ctx, POWERPC_SYSCALL, lev);
1.1       root     3715: }
                   3716: 
                   3717: /***                                Trap                                   ***/
1.1.1.7   root     3718: 
1.1       root     3719: /* tw */
1.1.1.7   root     3720: static void gen_tw(DisasContext *ctx)
1.1       root     3721: {
1.1.1.6   root     3722:     TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
1.1.1.4   root     3723:     /* Update the nip since this might generate a trap exception */
1.1.1.5   root     3724:     gen_update_nip(ctx, ctx->nip);
1.1.1.6   root     3725:     gen_helper_tw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
                   3726:     tcg_temp_free_i32(t0);
1.1       root     3727: }
                   3728: 
                   3729: /* twi */
1.1.1.7   root     3730: static void gen_twi(DisasContext *ctx)
1.1       root     3731: {
1.1.1.6   root     3732:     TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
                   3733:     TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
1.1.1.5   root     3734:     /* Update the nip since this might generate a trap exception */
                   3735:     gen_update_nip(ctx, ctx->nip);
1.1.1.6   root     3736:     gen_helper_tw(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   3737:     tcg_temp_free(t0);
                   3738:     tcg_temp_free_i32(t1);
1.1       root     3739: }
                   3740: 
1.1.1.5   root     3741: #if defined(TARGET_PPC64)
                   3742: /* td */
1.1.1.7   root     3743: static void gen_td(DisasContext *ctx)
1.1       root     3744: {
1.1.1.6   root     3745:     TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
1.1.1.5   root     3746:     /* Update the nip since this might generate a trap exception */
                   3747:     gen_update_nip(ctx, ctx->nip);
1.1.1.6   root     3748:     gen_helper_td(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
                   3749:     tcg_temp_free_i32(t0);
1.1.1.5   root     3750: }
1.1       root     3751: 
1.1.1.5   root     3752: /* tdi */
1.1.1.7   root     3753: static void gen_tdi(DisasContext *ctx)
1.1.1.5   root     3754: {
1.1.1.6   root     3755:     TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
                   3756:     TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
1.1.1.5   root     3757:     /* Update the nip since this might generate a trap exception */
                   3758:     gen_update_nip(ctx, ctx->nip);
1.1.1.6   root     3759:     gen_helper_td(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   3760:     tcg_temp_free(t0);
                   3761:     tcg_temp_free_i32(t1);
1.1       root     3762: }
1.1.1.5   root     3763: #endif
1.1       root     3764: 
1.1.1.5   root     3765: /***                          Processor control                            ***/
1.1.1.7   root     3766: 
1.1       root     3767: /* mcrxr */
1.1.1.7   root     3768: static void gen_mcrxr(DisasContext *ctx)
1.1       root     3769: {
1.1.1.6   root     3770:     tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], cpu_xer);
                   3771:     tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], XER_CA);
                   3772:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_SO | 1 << XER_OV | 1 << XER_CA));
1.1       root     3773: }
                   3774: 
1.1.1.6   root     3775: /* mfcr mfocrf */
1.1.1.7   root     3776: static void gen_mfcr(DisasContext *ctx)
1.1       root     3777: {
1.1.1.5   root     3778:     uint32_t crm, crn;
                   3779: 
                   3780:     if (likely(ctx->opcode & 0x00100000)) {
                   3781:         crm = CRM(ctx->opcode);
1.1.1.6   root     3782:         if (likely(crm && ((crm & (crm - 1)) == 0))) {
                   3783:             crn = ctz32 (crm);
                   3784:             tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
1.1.1.7   root     3785:             tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)],
                   3786:                             cpu_gpr[rD(ctx->opcode)], crn * 4);
1.1.1.5   root     3787:         }
                   3788:     } else {
1.1.1.7   root     3789:         TCGv_i32 t0 = tcg_temp_new_i32();
                   3790:         tcg_gen_mov_i32(t0, cpu_crf[0]);
                   3791:         tcg_gen_shli_i32(t0, t0, 4);
                   3792:         tcg_gen_or_i32(t0, t0, cpu_crf[1]);
                   3793:         tcg_gen_shli_i32(t0, t0, 4);
                   3794:         tcg_gen_or_i32(t0, t0, cpu_crf[2]);
                   3795:         tcg_gen_shli_i32(t0, t0, 4);
                   3796:         tcg_gen_or_i32(t0, t0, cpu_crf[3]);
                   3797:         tcg_gen_shli_i32(t0, t0, 4);
                   3798:         tcg_gen_or_i32(t0, t0, cpu_crf[4]);
                   3799:         tcg_gen_shli_i32(t0, t0, 4);
                   3800:         tcg_gen_or_i32(t0, t0, cpu_crf[5]);
                   3801:         tcg_gen_shli_i32(t0, t0, 4);
                   3802:         tcg_gen_or_i32(t0, t0, cpu_crf[6]);
                   3803:         tcg_gen_shli_i32(t0, t0, 4);
                   3804:         tcg_gen_or_i32(t0, t0, cpu_crf[7]);
                   3805:         tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   3806:         tcg_temp_free_i32(t0);
1.1.1.5   root     3807:     }
1.1       root     3808: }
                   3809: 
                   3810: /* mfmsr */
1.1.1.7   root     3811: static void gen_mfmsr(DisasContext *ctx)
1.1       root     3812: {
                   3813: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     3814:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     3815: #else
1.1.1.6   root     3816:     if (unlikely(!ctx->mem_idx)) {
                   3817:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     3818:         return;
                   3819:     }
1.1.1.6   root     3820:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
1.1       root     3821: #endif
                   3822: }
                   3823: 
1.1.1.9   root     3824: static void spr_noaccess(void *opaque, int gprn, int sprn)
1.1       root     3825: {
1.1.1.9   root     3826: #if 0
1.1       root     3827:     sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
                   3828:     printf("ERROR: try to access SPR %d !\n", sprn);
1.1.1.9   root     3829: #endif
1.1       root     3830: }
                   3831: #define SPR_NOACCESS (&spr_noaccess)
                   3832: 
                   3833: /* mfspr */
1.1.1.8   root     3834: static inline void gen_op_mfspr(DisasContext *ctx)
1.1       root     3835: {
1.1.1.6   root     3836:     void (*read_cb)(void *opaque, int gprn, int sprn);
1.1       root     3837:     uint32_t sprn = SPR(ctx->opcode);
                   3838: 
                   3839: #if !defined(CONFIG_USER_ONLY)
1.1.1.6   root     3840:     if (ctx->mem_idx == 2)
1.1.1.5   root     3841:         read_cb = ctx->spr_cb[sprn].hea_read;
1.1.1.6   root     3842:     else if (ctx->mem_idx)
1.1       root     3843:         read_cb = ctx->spr_cb[sprn].oea_read;
                   3844:     else
                   3845: #endif
                   3846:         read_cb = ctx->spr_cb[sprn].uea_read;
1.1.1.5   root     3847:     if (likely(read_cb != NULL)) {
                   3848:         if (likely(read_cb != SPR_NOACCESS)) {
1.1.1.6   root     3849:             (*read_cb)(ctx, rD(ctx->opcode), sprn);
1.1       root     3850:         } else {
                   3851:             /* Privilege exception */
1.1.1.5   root     3852:             /* This is a hack to avoid warnings when running Linux:
                   3853:              * this OS breaks the PowerPC virtualisation model,
                   3854:              * allowing userland application to read the PVR
                   3855:              */
                   3856:             if (sprn != SPR_PVR) {
1.1.1.6   root     3857:                 qemu_log("Trying to read privileged spr %d %03x at "
1.1.1.8   root     3858:                          TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
                   3859:                 printf("Trying to read privileged spr %d %03x at "
                   3860:                        TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
1.1.1.2   root     3861:             }
1.1.1.6   root     3862:             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     3863:         }
                   3864:     } else {
                   3865:         /* Not defined */
1.1.1.6   root     3866:         qemu_log("Trying to read invalid spr %d %03x at "
1.1.1.8   root     3867:                     TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
                   3868:         printf("Trying to read invalid spr %d %03x at " TARGET_FMT_lx "\n",
1.1.1.5   root     3869:                sprn, sprn, ctx->nip);
1.1.1.6   root     3870:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
1.1       root     3871:     }
                   3872: }
                   3873: 
1.1.1.7   root     3874: static void gen_mfspr(DisasContext *ctx)
1.1       root     3875: {
                   3876:     gen_op_mfspr(ctx);
1.1.1.5   root     3877: }
1.1       root     3878: 
                   3879: /* mftb */
1.1.1.7   root     3880: static void gen_mftb(DisasContext *ctx)
1.1       root     3881: {
                   3882:     gen_op_mfspr(ctx);
                   3883: }
                   3884: 
1.1.1.6   root     3885: /* mtcrf mtocrf*/
1.1.1.7   root     3886: static void gen_mtcrf(DisasContext *ctx)
1.1       root     3887: {
1.1.1.5   root     3888:     uint32_t crm, crn;
                   3889: 
                   3890:     crm = CRM(ctx->opcode);
1.1.1.6   root     3891:     if (likely((ctx->opcode & 0x00100000))) {
                   3892:         if (crm && ((crm & (crm - 1)) == 0)) {
                   3893:             TCGv_i32 temp = tcg_temp_new_i32();
                   3894:             crn = ctz32 (crm);
                   3895:             tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
                   3896:             tcg_gen_shri_i32(temp, temp, crn * 4);
                   3897:             tcg_gen_andi_i32(cpu_crf[7 - crn], temp, 0xf);
                   3898:             tcg_temp_free_i32(temp);
                   3899:         }
1.1.1.5   root     3900:     } else {
1.1.1.7   root     3901:         TCGv_i32 temp = tcg_temp_new_i32();
                   3902:         tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
                   3903:         for (crn = 0 ; crn < 8 ; crn++) {
                   3904:             if (crm & (1 << crn)) {
                   3905:                     tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
                   3906:                     tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
                   3907:             }
                   3908:         }
1.1.1.6   root     3909:         tcg_temp_free_i32(temp);
1.1.1.5   root     3910:     }
1.1       root     3911: }
                   3912: 
                   3913: /* mtmsr */
1.1.1.5   root     3914: #if defined(TARGET_PPC64)
1.1.1.7   root     3915: static void gen_mtmsrd(DisasContext *ctx)
1.1.1.5   root     3916: {
                   3917: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     3918:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     3919: #else
1.1.1.6   root     3920:     if (unlikely(!ctx->mem_idx)) {
                   3921:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     3922:         return;
                   3923:     }
                   3924:     if (ctx->opcode & 0x00010000) {
                   3925:         /* Special form that does not need any synchronisation */
1.1.1.6   root     3926:         TCGv t0 = tcg_temp_new();
                   3927:         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
                   3928:         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
                   3929:         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
                   3930:         tcg_temp_free(t0);
1.1.1.5   root     3931:     } else {
                   3932:         /* XXX: we need to update nip before the store
                   3933:          *      if we enter power saving mode, we will exit the loop
                   3934:          *      directly from ppc_store_msr
                   3935:          */
                   3936:         gen_update_nip(ctx, ctx->nip);
1.1.1.6   root     3937:         gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     3938:         /* Must stop the translation as machine state (may have) changed */
                   3939:         /* Note that mtmsr is not always defined as context-synchronizing */
1.1.1.6   root     3940:         gen_stop_exception(ctx);
1.1.1.5   root     3941:     }
                   3942: #endif
                   3943: }
                   3944: #endif
                   3945: 
1.1.1.7   root     3946: static void gen_mtmsr(DisasContext *ctx)
1.1       root     3947: {
                   3948: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     3949:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     3950: #else
1.1.1.6   root     3951:     if (unlikely(!ctx->mem_idx)) {
                   3952:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     3953:         return;
                   3954:     }
1.1.1.5   root     3955:     if (ctx->opcode & 0x00010000) {
                   3956:         /* Special form that does not need any synchronisation */
1.1.1.6   root     3957:         TCGv t0 = tcg_temp_new();
                   3958:         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
                   3959:         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
                   3960:         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
                   3961:         tcg_temp_free(t0);
1.1.1.5   root     3962:     } else {
1.1.1.11  root     3963:         TCGv msr = tcg_temp_new();
                   3964: 
1.1.1.5   root     3965:         /* XXX: we need to update nip before the store
                   3966:          *      if we enter power saving mode, we will exit the loop
                   3967:          *      directly from ppc_store_msr
                   3968:          */
                   3969:         gen_update_nip(ctx, ctx->nip);
                   3970: #if defined(TARGET_PPC64)
1.1.1.11  root     3971:         tcg_gen_deposit_tl(msr, cpu_msr, cpu_gpr[rS(ctx->opcode)], 0, 32);
                   3972: #else
                   3973:         tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     3974: #endif
1.1.1.11  root     3975:         gen_helper_store_msr(msr);
1.1.1.5   root     3976:         /* Must stop the translation as machine state (may have) changed */
1.1.1.6   root     3977:         /* Note that mtmsr is not always defined as context-synchronizing */
                   3978:         gen_stop_exception(ctx);
1.1.1.5   root     3979:     }
1.1       root     3980: #endif
                   3981: }
                   3982: 
                   3983: /* mtspr */
1.1.1.7   root     3984: static void gen_mtspr(DisasContext *ctx)
1.1       root     3985: {
1.1.1.6   root     3986:     void (*write_cb)(void *opaque, int sprn, int gprn);
1.1       root     3987:     uint32_t sprn = SPR(ctx->opcode);
                   3988: 
                   3989: #if !defined(CONFIG_USER_ONLY)
1.1.1.6   root     3990:     if (ctx->mem_idx == 2)
1.1.1.5   root     3991:         write_cb = ctx->spr_cb[sprn].hea_write;
1.1.1.6   root     3992:     else if (ctx->mem_idx)
1.1       root     3993:         write_cb = ctx->spr_cb[sprn].oea_write;
                   3994:     else
                   3995: #endif
                   3996:         write_cb = ctx->spr_cb[sprn].uea_write;
1.1.1.5   root     3997:     if (likely(write_cb != NULL)) {
                   3998:         if (likely(write_cb != SPR_NOACCESS)) {
1.1.1.6   root     3999:             (*write_cb)(ctx, sprn, rS(ctx->opcode));
1.1       root     4000:         } else {
                   4001:             /* Privilege exception */
1.1.1.6   root     4002:             qemu_log("Trying to write privileged spr %d %03x at "
1.1.1.8   root     4003:                      TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
                   4004:             printf("Trying to write privileged spr %d %03x at " TARGET_FMT_lx
                   4005:                    "\n", sprn, sprn, ctx->nip);
1.1.1.6   root     4006:             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4007:         }
1.1       root     4008:     } else {
                   4009:         /* Not defined */
1.1.1.6   root     4010:         qemu_log("Trying to write invalid spr %d %03x at "
1.1.1.8   root     4011:                  TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
                   4012:         printf("Trying to write invalid spr %d %03x at " TARGET_FMT_lx "\n",
1.1.1.5   root     4013:                sprn, sprn, ctx->nip);
1.1.1.6   root     4014:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
1.1       root     4015:     }
                   4016: }
                   4017: 
                   4018: /***                         Cache management                              ***/
1.1.1.7   root     4019: 
1.1       root     4020: /* dcbf */
1.1.1.7   root     4021: static void gen_dcbf(DisasContext *ctx)
1.1       root     4022: {
1.1.1.5   root     4023:     /* XXX: specification says this is treated as a load by the MMU */
1.1.1.6   root     4024:     TCGv t0;
                   4025:     gen_set_access_type(ctx, ACCESS_CACHE);
                   4026:     t0 = tcg_temp_new();
                   4027:     gen_addr_reg_index(ctx, t0);
                   4028:     gen_qemu_ld8u(ctx, t0, t0);
                   4029:     tcg_temp_free(t0);
1.1       root     4030: }
                   4031: 
                   4032: /* dcbi (Supervisor only) */
1.1.1.7   root     4033: static void gen_dcbi(DisasContext *ctx)
1.1       root     4034: {
                   4035: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4036:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     4037: #else
1.1.1.6   root     4038:     TCGv EA, val;
                   4039:     if (unlikely(!ctx->mem_idx)) {
                   4040:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     4041:         return;
                   4042:     }
1.1.1.6   root     4043:     EA = tcg_temp_new();
                   4044:     gen_set_access_type(ctx, ACCESS_CACHE);
                   4045:     gen_addr_reg_index(ctx, EA);
                   4046:     val = tcg_temp_new();
1.1.1.5   root     4047:     /* XXX: specification says this should be treated as a store by the MMU */
1.1.1.6   root     4048:     gen_qemu_ld8u(ctx, val, EA);
                   4049:     gen_qemu_st8(ctx, val, EA);
                   4050:     tcg_temp_free(val);
                   4051:     tcg_temp_free(EA);
1.1       root     4052: #endif
                   4053: }
                   4054: 
                   4055: /* dcdst */
1.1.1.7   root     4056: static void gen_dcbst(DisasContext *ctx)
1.1       root     4057: {
1.1.1.5   root     4058:     /* XXX: specification say this is treated as a load by the MMU */
1.1.1.6   root     4059:     TCGv t0;
                   4060:     gen_set_access_type(ctx, ACCESS_CACHE);
                   4061:     t0 = tcg_temp_new();
                   4062:     gen_addr_reg_index(ctx, t0);
                   4063:     gen_qemu_ld8u(ctx, t0, t0);
                   4064:     tcg_temp_free(t0);
1.1       root     4065: }
                   4066: 
                   4067: /* dcbt */
1.1.1.7   root     4068: static void gen_dcbt(DisasContext *ctx)
1.1       root     4069: {
1.1.1.5   root     4070:     /* interpreted as no-op */
                   4071:     /* XXX: specification say this is treated as a load by the MMU
                   4072:      *      but does not generate any exception
                   4073:      */
1.1       root     4074: }
                   4075: 
                   4076: /* dcbtst */
1.1.1.7   root     4077: static void gen_dcbtst(DisasContext *ctx)
1.1       root     4078: {
1.1.1.5   root     4079:     /* interpreted as no-op */
                   4080:     /* XXX: specification say this is treated as a load by the MMU
                   4081:      *      but does not generate any exception
                   4082:      */
1.1       root     4083: }
                   4084: 
                   4085: /* dcbz */
1.1.1.7   root     4086: static void gen_dcbz(DisasContext *ctx)
1.1.1.6   root     4087: {
                   4088:     TCGv t0;
                   4089:     gen_set_access_type(ctx, ACCESS_CACHE);
                   4090:     /* NIP cannot be restored if the memory exception comes from an helper */
                   4091:     gen_update_nip(ctx, ctx->nip - 4);
                   4092:     t0 = tcg_temp_new();
                   4093:     gen_addr_reg_index(ctx, t0);
                   4094:     gen_helper_dcbz(t0);
                   4095:     tcg_temp_free(t0);
                   4096: }
1.1       root     4097: 
1.1.1.7   root     4098: static void gen_dcbz_970(DisasContext *ctx)
1.1       root     4099: {
1.1.1.6   root     4100:     TCGv t0;
                   4101:     gen_set_access_type(ctx, ACCESS_CACHE);
                   4102:     /* NIP cannot be restored if the memory exception comes from an helper */
                   4103:     gen_update_nip(ctx, ctx->nip - 4);
                   4104:     t0 = tcg_temp_new();
                   4105:     gen_addr_reg_index(ctx, t0);
                   4106:     if (ctx->opcode & 0x00200000)
                   4107:         gen_helper_dcbz(t0);
                   4108:     else
                   4109:         gen_helper_dcbz_970(t0);
                   4110:     tcg_temp_free(t0);
                   4111: }
1.1.1.5   root     4112: 
1.1.1.6   root     4113: /* dst / dstt */
1.1.1.7   root     4114: static void gen_dst(DisasContext *ctx)
1.1.1.6   root     4115: {
                   4116:     if (rA(ctx->opcode) == 0) {
                   4117:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
                   4118:     } else {
                   4119:         /* interpreted as no-op */
1.1       root     4120:     }
1.1.1.5   root     4121: }
                   4122: 
1.1.1.6   root     4123: /* dstst /dststt */
1.1.1.7   root     4124: static void gen_dstst(DisasContext *ctx)
1.1.1.5   root     4125: {
1.1.1.6   root     4126:     if (rA(ctx->opcode) == 0) {
                   4127:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
                   4128:     } else {
                   4129:         /* interpreted as no-op */
                   4130:     }
                   4131: 
1.1.1.5   root     4132: }
                   4133: 
1.1.1.6   root     4134: /* dss / dssall */
1.1.1.7   root     4135: static void gen_dss(DisasContext *ctx)
1.1.1.5   root     4136: {
1.1.1.6   root     4137:     /* interpreted as no-op */
1.1       root     4138: }
                   4139: 
                   4140: /* icbi */
1.1.1.7   root     4141: static void gen_icbi(DisasContext *ctx)
1.1       root     4142: {
1.1.1.6   root     4143:     TCGv t0;
                   4144:     gen_set_access_type(ctx, ACCESS_CACHE);
1.1.1.5   root     4145:     /* NIP cannot be restored if the memory exception comes from an helper */
                   4146:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6   root     4147:     t0 = tcg_temp_new();
                   4148:     gen_addr_reg_index(ctx, t0);
                   4149:     gen_helper_icbi(t0);
                   4150:     tcg_temp_free(t0);
1.1       root     4151: }
                   4152: 
                   4153: /* Optional: */
                   4154: /* dcba */
1.1.1.7   root     4155: static void gen_dcba(DisasContext *ctx)
1.1       root     4156: {
1.1.1.5   root     4157:     /* interpreted as no-op */
                   4158:     /* XXX: specification say this is treated as a store by the MMU
                   4159:      *      but does not generate any exception
                   4160:      */
1.1       root     4161: }
                   4162: 
                   4163: /***                    Segment register manipulation                      ***/
                   4164: /* Supervisor only: */
1.1.1.7   root     4165: 
1.1       root     4166: /* mfsr */
1.1.1.7   root     4167: static void gen_mfsr(DisasContext *ctx)
1.1       root     4168: {
                   4169: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4170:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4171: #else
1.1.1.6   root     4172:     TCGv t0;
                   4173:     if (unlikely(!ctx->mem_idx)) {
                   4174:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4175:         return;
                   4176:     }
1.1.1.6   root     4177:     t0 = tcg_const_tl(SR(ctx->opcode));
                   4178:     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
                   4179:     tcg_temp_free(t0);
1.1       root     4180: #endif
                   4181: }
                   4182: 
                   4183: /* mfsrin */
1.1.1.7   root     4184: static void gen_mfsrin(DisasContext *ctx)
1.1       root     4185: {
                   4186: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4187:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4188: #else
1.1.1.6   root     4189:     TCGv t0;
                   4190:     if (unlikely(!ctx->mem_idx)) {
                   4191:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4192:         return;
                   4193:     }
1.1.1.6   root     4194:     t0 = tcg_temp_new();
                   4195:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
                   4196:     tcg_gen_andi_tl(t0, t0, 0xF);
                   4197:     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
                   4198:     tcg_temp_free(t0);
1.1       root     4199: #endif
                   4200: }
                   4201: 
                   4202: /* mtsr */
1.1.1.7   root     4203: static void gen_mtsr(DisasContext *ctx)
1.1       root     4204: {
                   4205: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4206:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4207: #else
1.1.1.6   root     4208:     TCGv t0;
                   4209:     if (unlikely(!ctx->mem_idx)) {
                   4210:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4211:         return;
                   4212:     }
1.1.1.6   root     4213:     t0 = tcg_const_tl(SR(ctx->opcode));
                   4214:     gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
                   4215:     tcg_temp_free(t0);
1.1       root     4216: #endif
                   4217: }
                   4218: 
                   4219: /* mtsrin */
1.1.1.7   root     4220: static void gen_mtsrin(DisasContext *ctx)
1.1       root     4221: {
                   4222: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4223:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4224: #else
1.1.1.6   root     4225:     TCGv t0;
                   4226:     if (unlikely(!ctx->mem_idx)) {
                   4227:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4228:         return;
                   4229:     }
1.1.1.6   root     4230:     t0 = tcg_temp_new();
                   4231:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
                   4232:     tcg_gen_andi_tl(t0, t0, 0xF);
                   4233:     gen_helper_store_sr(t0, cpu_gpr[rD(ctx->opcode)]);
                   4234:     tcg_temp_free(t0);
1.1       root     4235: #endif
                   4236: }
                   4237: 
1.1.1.5   root     4238: #if defined(TARGET_PPC64)
                   4239: /* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
1.1.1.7   root     4240: 
1.1.1.5   root     4241: /* mfsr */
1.1.1.7   root     4242: static void gen_mfsr_64b(DisasContext *ctx)
1.1       root     4243: {
                   4244: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4245:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4246: #else
1.1.1.6   root     4247:     TCGv t0;
                   4248:     if (unlikely(!ctx->mem_idx)) {
                   4249:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4250:         return;
                   4251:     }
1.1.1.6   root     4252:     t0 = tcg_const_tl(SR(ctx->opcode));
1.1.1.7   root     4253:     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
1.1.1.6   root     4254:     tcg_temp_free(t0);
1.1.1.5   root     4255: #endif
                   4256: }
                   4257: 
                   4258: /* mfsrin */
1.1.1.7   root     4259: static void gen_mfsrin_64b(DisasContext *ctx)
1.1.1.5   root     4260: {
                   4261: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4262:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4263: #else
1.1.1.6   root     4264:     TCGv t0;
                   4265:     if (unlikely(!ctx->mem_idx)) {
                   4266:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4267:         return;
                   4268:     }
1.1.1.6   root     4269:     t0 = tcg_temp_new();
                   4270:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
                   4271:     tcg_gen_andi_tl(t0, t0, 0xF);
1.1.1.7   root     4272:     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
1.1.1.6   root     4273:     tcg_temp_free(t0);
1.1.1.5   root     4274: #endif
                   4275: }
                   4276: 
                   4277: /* mtsr */
1.1.1.7   root     4278: static void gen_mtsr_64b(DisasContext *ctx)
1.1.1.5   root     4279: {
                   4280: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4281:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4282: #else
1.1.1.6   root     4283:     TCGv t0;
                   4284:     if (unlikely(!ctx->mem_idx)) {
                   4285:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4286:         return;
                   4287:     }
1.1.1.6   root     4288:     t0 = tcg_const_tl(SR(ctx->opcode));
1.1.1.7   root     4289:     gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
1.1.1.6   root     4290:     tcg_temp_free(t0);
1.1.1.5   root     4291: #endif
                   4292: }
                   4293: 
                   4294: /* mtsrin */
1.1.1.7   root     4295: static void gen_mtsrin_64b(DisasContext *ctx)
1.1.1.5   root     4296: {
                   4297: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4298:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4299: #else
1.1.1.6   root     4300:     TCGv t0;
                   4301:     if (unlikely(!ctx->mem_idx)) {
                   4302:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4303:         return;
                   4304:     }
1.1.1.6   root     4305:     t0 = tcg_temp_new();
                   4306:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
                   4307:     tcg_gen_andi_tl(t0, t0, 0xF);
1.1.1.7   root     4308:     gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
1.1.1.6   root     4309:     tcg_temp_free(t0);
1.1.1.5   root     4310: #endif
                   4311: }
1.1.1.7   root     4312: 
                   4313: /* slbmte */
                   4314: static void gen_slbmte(DisasContext *ctx)
                   4315: {
                   4316: #if defined(CONFIG_USER_ONLY)
                   4317:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
                   4318: #else
                   4319:     if (unlikely(!ctx->mem_idx)) {
                   4320:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
                   4321:         return;
                   4322:     }
                   4323:     gen_helper_store_slb(cpu_gpr[rB(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   4324: #endif
                   4325: }
                   4326: 
1.1.1.11  root     4327: static void gen_slbmfee(DisasContext *ctx)
                   4328: {
                   4329: #if defined(CONFIG_USER_ONLY)
                   4330:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
                   4331: #else
                   4332:     if (unlikely(!ctx->mem_idx)) {
                   4333:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
                   4334:         return;
                   4335:     }
                   4336:     gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)],
                   4337:                              cpu_gpr[rB(ctx->opcode)]);
                   4338: #endif
                   4339: }
                   4340: 
                   4341: static void gen_slbmfev(DisasContext *ctx)
                   4342: {
                   4343: #if defined(CONFIG_USER_ONLY)
                   4344:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
                   4345: #else
                   4346:     if (unlikely(!ctx->mem_idx)) {
                   4347:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
                   4348:         return;
                   4349:     }
                   4350:     gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)],
                   4351:                              cpu_gpr[rB(ctx->opcode)]);
                   4352: #endif
                   4353: }
1.1.1.5   root     4354: #endif /* defined(TARGET_PPC64) */
                   4355: 
                   4356: /***                      Lookaside buffer management                      ***/
1.1.1.6   root     4357: /* Optional & mem_idx only: */
1.1.1.7   root     4358: 
1.1.1.5   root     4359: /* tlbia */
1.1.1.7   root     4360: static void gen_tlbia(DisasContext *ctx)
1.1.1.5   root     4361: {
                   4362: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4363:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4364: #else
1.1.1.6   root     4365:     if (unlikely(!ctx->mem_idx)) {
                   4366:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4367:         return;
                   4368:     }
1.1.1.6   root     4369:     gen_helper_tlbia();
1.1       root     4370: #endif
                   4371: }
                   4372: 
1.1.1.7   root     4373: /* tlbiel */
                   4374: static void gen_tlbiel(DisasContext *ctx)
                   4375: {
                   4376: #if defined(CONFIG_USER_ONLY)
                   4377:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   4378: #else
                   4379:     if (unlikely(!ctx->mem_idx)) {
                   4380:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   4381:         return;
                   4382:     }
                   4383:     gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
                   4384: #endif
                   4385: }
                   4386: 
1.1       root     4387: /* tlbie */
1.1.1.7   root     4388: static void gen_tlbie(DisasContext *ctx)
1.1.1.5   root     4389: {
                   4390: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4391:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4392: #else
1.1.1.6   root     4393:     if (unlikely(!ctx->mem_idx)) {
                   4394:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4395:         return;
                   4396:     }
                   4397: #if defined(TARGET_PPC64)
1.1.1.6   root     4398:     if (!ctx->sf_mode) {
                   4399:         TCGv t0 = tcg_temp_new();
                   4400:         tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
                   4401:         gen_helper_tlbie(t0);
                   4402:         tcg_temp_free(t0);
                   4403:     } else
1.1.1.5   root     4404: #endif
1.1.1.6   root     4405:         gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4406: #endif
                   4407: }
                   4408: 
                   4409: /* tlbsync */
1.1.1.7   root     4410: static void gen_tlbsync(DisasContext *ctx)
1.1.1.5   root     4411: {
                   4412: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4413:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4414: #else
1.1.1.6   root     4415:     if (unlikely(!ctx->mem_idx)) {
                   4416:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4417:         return;
                   4418:     }
                   4419:     /* This has no effect: it should ensure that all previous
                   4420:      * tlbie have completed
                   4421:      */
1.1.1.6   root     4422:     gen_stop_exception(ctx);
1.1.1.5   root     4423: #endif
                   4424: }
                   4425: 
                   4426: #if defined(TARGET_PPC64)
                   4427: /* slbia */
1.1.1.7   root     4428: static void gen_slbia(DisasContext *ctx)
1.1.1.5   root     4429: {
                   4430: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4431:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4432: #else
1.1.1.6   root     4433:     if (unlikely(!ctx->mem_idx)) {
                   4434:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4435:         return;
                   4436:     }
1.1.1.6   root     4437:     gen_helper_slbia();
1.1.1.5   root     4438: #endif
                   4439: }
                   4440: 
                   4441: /* slbie */
1.1.1.7   root     4442: static void gen_slbie(DisasContext *ctx)
1.1.1.5   root     4443: {
                   4444: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4445:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4446: #else
1.1.1.6   root     4447:     if (unlikely(!ctx->mem_idx)) {
                   4448:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4449:         return;
                   4450:     }
1.1.1.6   root     4451:     gen_helper_slbie(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4452: #endif
                   4453: }
                   4454: #endif
                   4455: 
                   4456: /***                              External control                         ***/
                   4457: /* Optional: */
1.1.1.7   root     4458: 
1.1.1.5   root     4459: /* eciwx */
1.1.1.7   root     4460: static void gen_eciwx(DisasContext *ctx)
1.1.1.5   root     4461: {
1.1.1.6   root     4462:     TCGv t0;
                   4463:     /* Should check EAR[E] ! */
                   4464:     gen_set_access_type(ctx, ACCESS_EXT);
                   4465:     t0 = tcg_temp_new();
                   4466:     gen_addr_reg_index(ctx, t0);
                   4467:     gen_check_align(ctx, t0, 0x03);
                   4468:     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
                   4469:     tcg_temp_free(t0);
1.1.1.5   root     4470: }
                   4471: 
                   4472: /* ecowx */
1.1.1.7   root     4473: static void gen_ecowx(DisasContext *ctx)
1.1.1.5   root     4474: {
1.1.1.6   root     4475:     TCGv t0;
                   4476:     /* Should check EAR[E] ! */
                   4477:     gen_set_access_type(ctx, ACCESS_EXT);
                   4478:     t0 = tcg_temp_new();
                   4479:     gen_addr_reg_index(ctx, t0);
                   4480:     gen_check_align(ctx, t0, 0x03);
                   4481:     gen_qemu_st32(ctx, cpu_gpr[rD(ctx->opcode)], t0);
                   4482:     tcg_temp_free(t0);
1.1.1.5   root     4483: }
                   4484: 
                   4485: /* PowerPC 601 specific instructions */
1.1.1.7   root     4486: 
1.1.1.5   root     4487: /* abs - abs. */
1.1.1.7   root     4488: static void gen_abs(DisasContext *ctx)
1.1.1.5   root     4489: {
1.1.1.6   root     4490:     int l1 = gen_new_label();
                   4491:     int l2 = gen_new_label();
                   4492:     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);
                   4493:     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4494:     tcg_gen_br(l2);
                   4495:     gen_set_label(l1);
                   4496:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4497:     gen_set_label(l2);
1.1.1.5   root     4498:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4499:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4500: }
                   4501: 
                   4502: /* abso - abso. */
1.1.1.7   root     4503: static void gen_abso(DisasContext *ctx)
1.1.1.5   root     4504: {
1.1.1.6   root     4505:     int l1 = gen_new_label();
                   4506:     int l2 = gen_new_label();
                   4507:     int l3 = gen_new_label();
                   4508:     /* Start with XER OV disabled, the most likely case */
                   4509:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                   4510:     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
                   4511:     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
                   4512:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                   4513:     tcg_gen_br(l2);
                   4514:     gen_set_label(l1);
                   4515:     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4516:     tcg_gen_br(l3);
                   4517:     gen_set_label(l2);
                   4518:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4519:     gen_set_label(l3);
1.1.1.5   root     4520:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4521:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4522: }
                   4523: 
                   4524: /* clcs */
1.1.1.7   root     4525: static void gen_clcs(DisasContext *ctx)
1.1.1.5   root     4526: {
1.1.1.6   root     4527:     TCGv_i32 t0 = tcg_const_i32(rA(ctx->opcode));
                   4528:     gen_helper_clcs(cpu_gpr[rD(ctx->opcode)], t0);
                   4529:     tcg_temp_free_i32(t0);
1.1.1.5   root     4530:     /* Rc=1 sets CR0 to an undefined state */
                   4531: }
                   4532: 
                   4533: /* div - div. */
1.1.1.7   root     4534: static void gen_div(DisasContext *ctx)
1.1.1.5   root     4535: {
1.1.1.6   root     4536:     gen_helper_div(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4537:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4538:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4539: }
                   4540: 
                   4541: /* divo - divo. */
1.1.1.7   root     4542: static void gen_divo(DisasContext *ctx)
1.1.1.5   root     4543: {
1.1.1.6   root     4544:     gen_helper_divo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4545:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4546:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4547: }
                   4548: 
                   4549: /* divs - divs. */
1.1.1.7   root     4550: static void gen_divs(DisasContext *ctx)
1.1.1.5   root     4551: {
1.1.1.6   root     4552:     gen_helper_divs(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4553:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4554:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4555: }
                   4556: 
                   4557: /* divso - divso. */
1.1.1.7   root     4558: static void gen_divso(DisasContext *ctx)
1.1.1.5   root     4559: {
1.1.1.6   root     4560:     gen_helper_divso(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4561:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4562:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4563: }
                   4564: 
                   4565: /* doz - doz. */
1.1.1.7   root     4566: static void gen_doz(DisasContext *ctx)
1.1.1.5   root     4567: {
1.1.1.6   root     4568:     int l1 = gen_new_label();
                   4569:     int l2 = gen_new_label();
                   4570:     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
                   4571:     tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4572:     tcg_gen_br(l2);
                   4573:     gen_set_label(l1);
                   4574:     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
                   4575:     gen_set_label(l2);
1.1.1.5   root     4576:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4577:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4578: }
                   4579: 
                   4580: /* dozo - dozo. */
1.1.1.7   root     4581: static void gen_dozo(DisasContext *ctx)
1.1.1.5   root     4582: {
1.1.1.6   root     4583:     int l1 = gen_new_label();
                   4584:     int l2 = gen_new_label();
                   4585:     TCGv t0 = tcg_temp_new();
                   4586:     TCGv t1 = tcg_temp_new();
                   4587:     TCGv t2 = tcg_temp_new();
                   4588:     /* Start with XER OV disabled, the most likely case */
                   4589:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                   4590:     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
                   4591:     tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4592:     tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4593:     tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0);
                   4594:     tcg_gen_andc_tl(t1, t1, t2);
                   4595:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   4596:     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
                   4597:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                   4598:     tcg_gen_br(l2);
                   4599:     gen_set_label(l1);
                   4600:     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
                   4601:     gen_set_label(l2);
                   4602:     tcg_temp_free(t0);
                   4603:     tcg_temp_free(t1);
                   4604:     tcg_temp_free(t2);
1.1.1.5   root     4605:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4606:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4607: }
                   4608: 
                   4609: /* dozi */
1.1.1.7   root     4610: static void gen_dozi(DisasContext *ctx)
1.1.1.5   root     4611: {
1.1.1.6   root     4612:     target_long simm = SIMM(ctx->opcode);
                   4613:     int l1 = gen_new_label();
                   4614:     int l2 = gen_new_label();
                   4615:     tcg_gen_brcondi_tl(TCG_COND_LT, cpu_gpr[rA(ctx->opcode)], simm, l1);
                   4616:     tcg_gen_subfi_tl(cpu_gpr[rD(ctx->opcode)], simm, cpu_gpr[rA(ctx->opcode)]);
                   4617:     tcg_gen_br(l2);
                   4618:     gen_set_label(l1);
                   4619:     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
                   4620:     gen_set_label(l2);
                   4621:     if (unlikely(Rc(ctx->opcode) != 0))
                   4622:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4623: }
                   4624: 
                   4625: /* lscbx - lscbx. */
1.1.1.7   root     4626: static void gen_lscbx(DisasContext *ctx)
1.1.1.5   root     4627: {
1.1.1.6   root     4628:     TCGv t0 = tcg_temp_new();
                   4629:     TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
                   4630:     TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode));
                   4631:     TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
1.1.1.5   root     4632: 
1.1.1.6   root     4633:     gen_addr_reg_index(ctx, t0);
1.1.1.5   root     4634:     /* NIP cannot be restored if the memory exception comes from an helper */
                   4635:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6   root     4636:     gen_helper_lscbx(t0, t0, t1, t2, t3);
                   4637:     tcg_temp_free_i32(t1);
                   4638:     tcg_temp_free_i32(t2);
                   4639:     tcg_temp_free_i32(t3);
                   4640:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
                   4641:     tcg_gen_or_tl(cpu_xer, cpu_xer, t0);
1.1.1.5   root     4642:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4643:         gen_set_Rc0(ctx, t0);
                   4644:     tcg_temp_free(t0);
1.1.1.5   root     4645: }
                   4646: 
                   4647: /* maskg - maskg. */
1.1.1.7   root     4648: static void gen_maskg(DisasContext *ctx)
1.1.1.5   root     4649: {
1.1.1.6   root     4650:     int l1 = gen_new_label();
                   4651:     TCGv t0 = tcg_temp_new();
                   4652:     TCGv t1 = tcg_temp_new();
                   4653:     TCGv t2 = tcg_temp_new();
                   4654:     TCGv t3 = tcg_temp_new();
                   4655:     tcg_gen_movi_tl(t3, 0xFFFFFFFF);
                   4656:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4657:     tcg_gen_andi_tl(t1, cpu_gpr[rS(ctx->opcode)], 0x1F);
                   4658:     tcg_gen_addi_tl(t2, t0, 1);
                   4659:     tcg_gen_shr_tl(t2, t3, t2);
                   4660:     tcg_gen_shr_tl(t3, t3, t1);
                   4661:     tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], t2, t3);
                   4662:     tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
                   4663:     tcg_gen_neg_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4664:     gen_set_label(l1);
                   4665:     tcg_temp_free(t0);
                   4666:     tcg_temp_free(t1);
                   4667:     tcg_temp_free(t2);
                   4668:     tcg_temp_free(t3);
1.1.1.5   root     4669:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4670:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4671: }
                   4672: 
                   4673: /* maskir - maskir. */
1.1.1.7   root     4674: static void gen_maskir(DisasContext *ctx)
1.1.1.5   root     4675: {
1.1.1.6   root     4676:     TCGv t0 = tcg_temp_new();
                   4677:     TCGv t1 = tcg_temp_new();
                   4678:     tcg_gen_and_tl(t0, cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   4679:     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   4680:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   4681:     tcg_temp_free(t0);
                   4682:     tcg_temp_free(t1);
1.1.1.5   root     4683:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4684:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4685: }
                   4686: 
                   4687: /* mul - mul. */
1.1.1.7   root     4688: static void gen_mul(DisasContext *ctx)
1.1.1.5   root     4689: {
1.1.1.6   root     4690:     TCGv_i64 t0 = tcg_temp_new_i64();
                   4691:     TCGv_i64 t1 = tcg_temp_new_i64();
                   4692:     TCGv t2 = tcg_temp_new();
                   4693:     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   4694:     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   4695:     tcg_gen_mul_i64(t0, t0, t1);
                   4696:     tcg_gen_trunc_i64_tl(t2, t0);
                   4697:     gen_store_spr(SPR_MQ, t2);
                   4698:     tcg_gen_shri_i64(t1, t0, 32);
                   4699:     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
                   4700:     tcg_temp_free_i64(t0);
                   4701:     tcg_temp_free_i64(t1);
                   4702:     tcg_temp_free(t2);
1.1.1.5   root     4703:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4704:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4705: }
                   4706: 
                   4707: /* mulo - mulo. */
1.1.1.7   root     4708: static void gen_mulo(DisasContext *ctx)
1.1.1.5   root     4709: {
1.1.1.6   root     4710:     int l1 = gen_new_label();
                   4711:     TCGv_i64 t0 = tcg_temp_new_i64();
                   4712:     TCGv_i64 t1 = tcg_temp_new_i64();
                   4713:     TCGv t2 = tcg_temp_new();
                   4714:     /* Start with XER OV disabled, the most likely case */
                   4715:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                   4716:     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   4717:     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   4718:     tcg_gen_mul_i64(t0, t0, t1);
                   4719:     tcg_gen_trunc_i64_tl(t2, t0);
                   4720:     gen_store_spr(SPR_MQ, t2);
                   4721:     tcg_gen_shri_i64(t1, t0, 32);
                   4722:     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
                   4723:     tcg_gen_ext32s_i64(t1, t0);
                   4724:     tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
                   4725:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                   4726:     gen_set_label(l1);
                   4727:     tcg_temp_free_i64(t0);
                   4728:     tcg_temp_free_i64(t1);
                   4729:     tcg_temp_free(t2);
1.1.1.5   root     4730:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4731:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4732: }
                   4733: 
                   4734: /* nabs - nabs. */
1.1.1.7   root     4735: static void gen_nabs(DisasContext *ctx)
1.1.1.5   root     4736: {
1.1.1.6   root     4737:     int l1 = gen_new_label();
                   4738:     int l2 = gen_new_label();
                   4739:     tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
                   4740:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4741:     tcg_gen_br(l2);
                   4742:     gen_set_label(l1);
                   4743:     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4744:     gen_set_label(l2);
1.1.1.5   root     4745:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4746:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4747: }
                   4748: 
                   4749: /* nabso - nabso. */
1.1.1.7   root     4750: static void gen_nabso(DisasContext *ctx)
1.1.1.5   root     4751: {
1.1.1.6   root     4752:     int l1 = gen_new_label();
                   4753:     int l2 = gen_new_label();
                   4754:     tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
                   4755:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4756:     tcg_gen_br(l2);
                   4757:     gen_set_label(l1);
                   4758:     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4759:     gen_set_label(l2);
                   4760:     /* nabs never overflows */
                   4761:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
1.1.1.5   root     4762:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4763:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4764: }
                   4765: 
                   4766: /* rlmi - rlmi. */
1.1.1.7   root     4767: static void gen_rlmi(DisasContext *ctx)
1.1.1.5   root     4768: {
1.1.1.6   root     4769:     uint32_t mb = MB(ctx->opcode);
                   4770:     uint32_t me = ME(ctx->opcode);
                   4771:     TCGv t0 = tcg_temp_new();
                   4772:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4773:     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   4774:     tcg_gen_andi_tl(t0, t0, MASK(mb, me));
                   4775:     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~MASK(mb, me));
                   4776:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], t0);
                   4777:     tcg_temp_free(t0);
1.1.1.5   root     4778:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4779:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4780: }
                   4781: 
                   4782: /* rrib - rrib. */
1.1.1.7   root     4783: static void gen_rrib(DisasContext *ctx)
1.1.1.5   root     4784: {
1.1.1.6   root     4785:     TCGv t0 = tcg_temp_new();
                   4786:     TCGv t1 = tcg_temp_new();
                   4787:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4788:     tcg_gen_movi_tl(t1, 0x80000000);
                   4789:     tcg_gen_shr_tl(t1, t1, t0);
                   4790:     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   4791:     tcg_gen_and_tl(t0, t0, t1);
                   4792:     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], t1);
                   4793:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   4794:     tcg_temp_free(t0);
                   4795:     tcg_temp_free(t1);
1.1.1.5   root     4796:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4797:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4798: }
                   4799: 
                   4800: /* sle - sle. */
1.1.1.7   root     4801: static void gen_sle(DisasContext *ctx)
1.1.1.5   root     4802: {
1.1.1.6   root     4803:     TCGv t0 = tcg_temp_new();
                   4804:     TCGv t1 = tcg_temp_new();
                   4805:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4806:     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
                   4807:     tcg_gen_subfi_tl(t1, 32, t1);
                   4808:     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
                   4809:     tcg_gen_or_tl(t1, t0, t1);
                   4810:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   4811:     gen_store_spr(SPR_MQ, t1);
                   4812:     tcg_temp_free(t0);
                   4813:     tcg_temp_free(t1);
1.1.1.5   root     4814:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4815:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4816: }
                   4817: 
                   4818: /* sleq - sleq. */
1.1.1.7   root     4819: static void gen_sleq(DisasContext *ctx)
1.1.1.5   root     4820: {
1.1.1.6   root     4821:     TCGv t0 = tcg_temp_new();
                   4822:     TCGv t1 = tcg_temp_new();
                   4823:     TCGv t2 = tcg_temp_new();
                   4824:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4825:     tcg_gen_movi_tl(t2, 0xFFFFFFFF);
                   4826:     tcg_gen_shl_tl(t2, t2, t0);
                   4827:     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   4828:     gen_load_spr(t1, SPR_MQ);
                   4829:     gen_store_spr(SPR_MQ, t0);
                   4830:     tcg_gen_and_tl(t0, t0, t2);
                   4831:     tcg_gen_andc_tl(t1, t1, t2);
                   4832:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   4833:     tcg_temp_free(t0);
                   4834:     tcg_temp_free(t1);
                   4835:     tcg_temp_free(t2);
1.1.1.5   root     4836:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4837:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4838: }
                   4839: 
                   4840: /* sliq - sliq. */
1.1.1.7   root     4841: static void gen_sliq(DisasContext *ctx)
1.1.1.5   root     4842: {
1.1.1.6   root     4843:     int sh = SH(ctx->opcode);
                   4844:     TCGv t0 = tcg_temp_new();
                   4845:     TCGv t1 = tcg_temp_new();
                   4846:     tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   4847:     tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
                   4848:     tcg_gen_or_tl(t1, t0, t1);
                   4849:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   4850:     gen_store_spr(SPR_MQ, t1);
                   4851:     tcg_temp_free(t0);
                   4852:     tcg_temp_free(t1);
1.1.1.5   root     4853:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4854:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4855: }
                   4856: 
                   4857: /* slliq - slliq. */
1.1.1.7   root     4858: static void gen_slliq(DisasContext *ctx)
1.1.1.5   root     4859: {
1.1.1.6   root     4860:     int sh = SH(ctx->opcode);
                   4861:     TCGv t0 = tcg_temp_new();
                   4862:     TCGv t1 = tcg_temp_new();
                   4863:     tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   4864:     gen_load_spr(t1, SPR_MQ);
                   4865:     gen_store_spr(SPR_MQ, t0);
                   4866:     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU << sh));
                   4867:     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU << sh));
                   4868:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   4869:     tcg_temp_free(t0);
                   4870:     tcg_temp_free(t1);
1.1.1.5   root     4871:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4872:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4873: }
                   4874: 
                   4875: /* sllq - sllq. */
1.1.1.7   root     4876: static void gen_sllq(DisasContext *ctx)
1.1.1.5   root     4877: {
1.1.1.6   root     4878:     int l1 = gen_new_label();
                   4879:     int l2 = gen_new_label();
                   4880:     TCGv t0 = tcg_temp_local_new();
                   4881:     TCGv t1 = tcg_temp_local_new();
                   4882:     TCGv t2 = tcg_temp_local_new();
                   4883:     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4884:     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
                   4885:     tcg_gen_shl_tl(t1, t1, t2);
                   4886:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
                   4887:     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
                   4888:     gen_load_spr(t0, SPR_MQ);
                   4889:     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   4890:     tcg_gen_br(l2);
                   4891:     gen_set_label(l1);
                   4892:     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
                   4893:     gen_load_spr(t2, SPR_MQ);
                   4894:     tcg_gen_andc_tl(t1, t2, t1);
                   4895:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   4896:     gen_set_label(l2);
                   4897:     tcg_temp_free(t0);
                   4898:     tcg_temp_free(t1);
                   4899:     tcg_temp_free(t2);
1.1.1.5   root     4900:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4901:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4902: }
                   4903: 
                   4904: /* slq - slq. */
1.1.1.7   root     4905: static void gen_slq(DisasContext *ctx)
1.1.1.5   root     4906: {
1.1.1.6   root     4907:     int l1 = gen_new_label();
                   4908:     TCGv t0 = tcg_temp_new();
                   4909:     TCGv t1 = tcg_temp_new();
                   4910:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4911:     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
                   4912:     tcg_gen_subfi_tl(t1, 32, t1);
                   4913:     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
                   4914:     tcg_gen_or_tl(t1, t0, t1);
                   4915:     gen_store_spr(SPR_MQ, t1);
                   4916:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
                   4917:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   4918:     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
                   4919:     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
                   4920:     gen_set_label(l1);
                   4921:     tcg_temp_free(t0);
                   4922:     tcg_temp_free(t1);
1.1.1.5   root     4923:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4924:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4925: }
                   4926: 
                   4927: /* sraiq - sraiq. */
1.1.1.7   root     4928: static void gen_sraiq(DisasContext *ctx)
1.1.1.5   root     4929: {
1.1.1.6   root     4930:     int sh = SH(ctx->opcode);
                   4931:     int l1 = gen_new_label();
                   4932:     TCGv t0 = tcg_temp_new();
                   4933:     TCGv t1 = tcg_temp_new();
                   4934:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   4935:     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
                   4936:     tcg_gen_or_tl(t0, t0, t1);
                   4937:     gen_store_spr(SPR_MQ, t0);
                   4938:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
                   4939:     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
                   4940:     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
                   4941:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
                   4942:     gen_set_label(l1);
                   4943:     tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
                   4944:     tcg_temp_free(t0);
                   4945:     tcg_temp_free(t1);
1.1.1.5   root     4946:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4947:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4948: }
                   4949: 
                   4950: /* sraq - sraq. */
1.1.1.7   root     4951: static void gen_sraq(DisasContext *ctx)
1.1.1.5   root     4952: {
1.1.1.6   root     4953:     int l1 = gen_new_label();
                   4954:     int l2 = gen_new_label();
                   4955:     TCGv t0 = tcg_temp_new();
                   4956:     TCGv t1 = tcg_temp_local_new();
                   4957:     TCGv t2 = tcg_temp_local_new();
                   4958:     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4959:     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
                   4960:     tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2);
                   4961:     tcg_gen_subfi_tl(t2, 32, t2);
                   4962:     tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2);
                   4963:     tcg_gen_or_tl(t0, t0, t2);
                   4964:     gen_store_spr(SPR_MQ, t0);
                   4965:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
                   4966:     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1);
                   4967:     tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]);
                   4968:     tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31);
                   4969:     gen_set_label(l1);
                   4970:     tcg_temp_free(t0);
                   4971:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
                   4972:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
                   4973:     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
                   4974:     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);
                   4975:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
                   4976:     gen_set_label(l2);
                   4977:     tcg_temp_free(t1);
                   4978:     tcg_temp_free(t2);
1.1.1.5   root     4979:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4980:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4981: }
                   4982: 
                   4983: /* sre - sre. */
1.1.1.7   root     4984: static void gen_sre(DisasContext *ctx)
1.1.1.5   root     4985: {
1.1.1.6   root     4986:     TCGv t0 = tcg_temp_new();
                   4987:     TCGv t1 = tcg_temp_new();
                   4988:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4989:     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
                   4990:     tcg_gen_subfi_tl(t1, 32, t1);
                   4991:     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
                   4992:     tcg_gen_or_tl(t1, t0, t1);
                   4993:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   4994:     gen_store_spr(SPR_MQ, t1);
                   4995:     tcg_temp_free(t0);
                   4996:     tcg_temp_free(t1);
1.1.1.5   root     4997:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4998:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4999: }
                   5000: 
                   5001: /* srea - srea. */
1.1.1.7   root     5002: static void gen_srea(DisasContext *ctx)
1.1.1.5   root     5003: {
1.1.1.6   root     5004:     TCGv t0 = tcg_temp_new();
                   5005:     TCGv t1 = tcg_temp_new();
                   5006:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   5007:     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
                   5008:     gen_store_spr(SPR_MQ, t0);
                   5009:     tcg_gen_sar_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t1);
                   5010:     tcg_temp_free(t0);
                   5011:     tcg_temp_free(t1);
1.1.1.5   root     5012:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     5013:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5014: }
                   5015: 
                   5016: /* sreq */
1.1.1.7   root     5017: static void gen_sreq(DisasContext *ctx)
1.1.1.5   root     5018: {
1.1.1.6   root     5019:     TCGv t0 = tcg_temp_new();
                   5020:     TCGv t1 = tcg_temp_new();
                   5021:     TCGv t2 = tcg_temp_new();
                   5022:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   5023:     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
                   5024:     tcg_gen_shr_tl(t1, t1, t0);
                   5025:     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   5026:     gen_load_spr(t2, SPR_MQ);
                   5027:     gen_store_spr(SPR_MQ, t0);
                   5028:     tcg_gen_and_tl(t0, t0, t1);
                   5029:     tcg_gen_andc_tl(t2, t2, t1);
                   5030:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
                   5031:     tcg_temp_free(t0);
                   5032:     tcg_temp_free(t1);
                   5033:     tcg_temp_free(t2);
1.1.1.5   root     5034:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     5035:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5036: }
                   5037: 
                   5038: /* sriq */
1.1.1.7   root     5039: static void gen_sriq(DisasContext *ctx)
1.1.1.5   root     5040: {
1.1.1.6   root     5041:     int sh = SH(ctx->opcode);
                   5042:     TCGv t0 = tcg_temp_new();
                   5043:     TCGv t1 = tcg_temp_new();
                   5044:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   5045:     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
                   5046:     tcg_gen_or_tl(t1, t0, t1);
                   5047:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   5048:     gen_store_spr(SPR_MQ, t1);
                   5049:     tcg_temp_free(t0);
                   5050:     tcg_temp_free(t1);
1.1.1.5   root     5051:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     5052:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5053: }
                   5054: 
                   5055: /* srliq */
1.1.1.7   root     5056: static void gen_srliq(DisasContext *ctx)
1.1.1.5   root     5057: {
1.1.1.6   root     5058:     int sh = SH(ctx->opcode);
                   5059:     TCGv t0 = tcg_temp_new();
                   5060:     TCGv t1 = tcg_temp_new();
                   5061:     tcg_gen_rotri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   5062:     gen_load_spr(t1, SPR_MQ);
                   5063:     gen_store_spr(SPR_MQ, t0);
                   5064:     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU >> sh));
                   5065:     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU >> sh));
                   5066:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   5067:     tcg_temp_free(t0);
                   5068:     tcg_temp_free(t1);
1.1.1.5   root     5069:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     5070:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5071: }
                   5072: 
                   5073: /* srlq */
1.1.1.7   root     5074: static void gen_srlq(DisasContext *ctx)
1.1.1.5   root     5075: {
1.1.1.6   root     5076:     int l1 = gen_new_label();
                   5077:     int l2 = gen_new_label();
                   5078:     TCGv t0 = tcg_temp_local_new();
                   5079:     TCGv t1 = tcg_temp_local_new();
                   5080:     TCGv t2 = tcg_temp_local_new();
                   5081:     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   5082:     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
                   5083:     tcg_gen_shr_tl(t2, t1, t2);
                   5084:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
                   5085:     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
                   5086:     gen_load_spr(t0, SPR_MQ);
                   5087:     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
                   5088:     tcg_gen_br(l2);
                   5089:     gen_set_label(l1);
                   5090:     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
                   5091:     tcg_gen_and_tl(t0, t0, t2);
                   5092:     gen_load_spr(t1, SPR_MQ);
                   5093:     tcg_gen_andc_tl(t1, t1, t2);
                   5094:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   5095:     gen_set_label(l2);
                   5096:     tcg_temp_free(t0);
                   5097:     tcg_temp_free(t1);
                   5098:     tcg_temp_free(t2);
1.1.1.5   root     5099:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     5100:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5101: }
                   5102: 
                   5103: /* srq */
1.1.1.7   root     5104: static void gen_srq(DisasContext *ctx)
1.1.1.5   root     5105: {
1.1.1.6   root     5106:     int l1 = gen_new_label();
                   5107:     TCGv t0 = tcg_temp_new();
                   5108:     TCGv t1 = tcg_temp_new();
                   5109:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   5110:     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
                   5111:     tcg_gen_subfi_tl(t1, 32, t1);
                   5112:     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
                   5113:     tcg_gen_or_tl(t1, t0, t1);
                   5114:     gen_store_spr(SPR_MQ, t1);
                   5115:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
                   5116:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   5117:     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
                   5118:     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
                   5119:     gen_set_label(l1);
                   5120:     tcg_temp_free(t0);
                   5121:     tcg_temp_free(t1);
1.1.1.5   root     5122:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     5123:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5124: }
                   5125: 
                   5126: /* PowerPC 602 specific instructions */
1.1.1.7   root     5127: 
1.1.1.5   root     5128: /* dsa  */
1.1.1.7   root     5129: static void gen_dsa(DisasContext *ctx)
1.1.1.5   root     5130: {
                   5131:     /* XXX: TODO */
1.1.1.6   root     5132:     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5133: }
                   5134: 
                   5135: /* esa */
1.1.1.7   root     5136: static void gen_esa(DisasContext *ctx)
1.1.1.5   root     5137: {
                   5138:     /* XXX: TODO */
1.1.1.6   root     5139:     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5140: }
                   5141: 
                   5142: /* mfrom */
1.1.1.7   root     5143: static void gen_mfrom(DisasContext *ctx)
1.1.1.5   root     5144: {
                   5145: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5146:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5147: #else
1.1.1.6   root     5148:     if (unlikely(!ctx->mem_idx)) {
                   5149:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5150:         return;
                   5151:     }
1.1.1.6   root     5152:     gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5153: #endif
                   5154: }
                   5155: 
                   5156: /* 602 - 603 - G2 TLB management */
1.1.1.7   root     5157: 
1.1.1.5   root     5158: /* tlbld */
1.1.1.7   root     5159: static void gen_tlbld_6xx(DisasContext *ctx)
1.1.1.5   root     5160: {
                   5161: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5162:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5163: #else
1.1.1.6   root     5164:     if (unlikely(!ctx->mem_idx)) {
                   5165:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5166:         return;
                   5167:     }
1.1.1.6   root     5168:     gen_helper_6xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     5169: #endif
                   5170: }
                   5171: 
                   5172: /* tlbli */
1.1.1.7   root     5173: static void gen_tlbli_6xx(DisasContext *ctx)
1.1.1.5   root     5174: {
                   5175: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5176:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5177: #else
1.1.1.6   root     5178:     if (unlikely(!ctx->mem_idx)) {
                   5179:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5180:         return;
                   5181:     }
1.1.1.6   root     5182:     gen_helper_6xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     5183: #endif
                   5184: }
                   5185: 
                   5186: /* 74xx TLB management */
1.1.1.7   root     5187: 
1.1.1.5   root     5188: /* tlbld */
1.1.1.7   root     5189: static void gen_tlbld_74xx(DisasContext *ctx)
1.1.1.5   root     5190: {
                   5191: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5192:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5193: #else
1.1.1.6   root     5194:     if (unlikely(!ctx->mem_idx)) {
                   5195:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5196:         return;
                   5197:     }
1.1.1.6   root     5198:     gen_helper_74xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     5199: #endif
                   5200: }
                   5201: 
                   5202: /* tlbli */
1.1.1.7   root     5203: static void gen_tlbli_74xx(DisasContext *ctx)
1.1.1.5   root     5204: {
                   5205: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5206:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5207: #else
1.1.1.6   root     5208:     if (unlikely(!ctx->mem_idx)) {
                   5209:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5210:         return;
                   5211:     }
1.1.1.6   root     5212:     gen_helper_74xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     5213: #endif
                   5214: }
                   5215: 
                   5216: /* POWER instructions not in PowerPC 601 */
1.1.1.7   root     5217: 
1.1.1.5   root     5218: /* clf */
1.1.1.7   root     5219: static void gen_clf(DisasContext *ctx)
1.1.1.5   root     5220: {
                   5221:     /* Cache line flush: implemented as no-op */
                   5222: }
                   5223: 
                   5224: /* cli */
1.1.1.7   root     5225: static void gen_cli(DisasContext *ctx)
1.1.1.5   root     5226: {
                   5227:     /* Cache line invalidate: privileged and treated as no-op */
                   5228: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5229:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5230: #else
1.1.1.6   root     5231:     if (unlikely(!ctx->mem_idx)) {
                   5232:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5233:         return;
                   5234:     }
                   5235: #endif
                   5236: }
                   5237: 
                   5238: /* dclst */
1.1.1.7   root     5239: static void gen_dclst(DisasContext *ctx)
1.1.1.5   root     5240: {
                   5241:     /* Data cache line store: treated as no-op */
                   5242: }
                   5243: 
1.1.1.7   root     5244: static void gen_mfsri(DisasContext *ctx)
1.1.1.5   root     5245: {
                   5246: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5247:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5248: #else
                   5249:     int ra = rA(ctx->opcode);
                   5250:     int rd = rD(ctx->opcode);
1.1.1.6   root     5251:     TCGv t0;
                   5252:     if (unlikely(!ctx->mem_idx)) {
                   5253:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   5254:         return;
                   5255:     }
                   5256:     t0 = tcg_temp_new();
                   5257:     gen_addr_reg_index(ctx, t0);
                   5258:     tcg_gen_shri_tl(t0, t0, 28);
                   5259:     tcg_gen_andi_tl(t0, t0, 0xF);
                   5260:     gen_helper_load_sr(cpu_gpr[rd], t0);
                   5261:     tcg_temp_free(t0);
1.1.1.5   root     5262:     if (ra != 0 && ra != rd)
1.1.1.6   root     5263:         tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
1.1.1.5   root     5264: #endif
                   5265: }
                   5266: 
1.1.1.7   root     5267: static void gen_rac(DisasContext *ctx)
1.1.1.5   root     5268: {
                   5269: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5270:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5271: #else
1.1.1.6   root     5272:     TCGv t0;
                   5273:     if (unlikely(!ctx->mem_idx)) {
                   5274:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5275:         return;
                   5276:     }
1.1.1.6   root     5277:     t0 = tcg_temp_new();
                   5278:     gen_addr_reg_index(ctx, t0);
                   5279:     gen_helper_rac(cpu_gpr[rD(ctx->opcode)], t0);
                   5280:     tcg_temp_free(t0);
1.1.1.5   root     5281: #endif
                   5282: }
                   5283: 
1.1.1.7   root     5284: static void gen_rfsvc(DisasContext *ctx)
1.1.1.5   root     5285: {
                   5286: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5287:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5288: #else
1.1.1.6   root     5289:     if (unlikely(!ctx->mem_idx)) {
                   5290:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5291:         return;
                   5292:     }
1.1.1.6   root     5293:     gen_helper_rfsvc();
                   5294:     gen_sync_exception(ctx);
1.1.1.5   root     5295: #endif
                   5296: }
                   5297: 
                   5298: /* svc is not implemented for now */
                   5299: 
                   5300: /* POWER2 specific instructions */
                   5301: /* Quad manipulation (load/store two floats at a time) */
                   5302: 
                   5303: /* lfq */
1.1.1.7   root     5304: static void gen_lfq(DisasContext *ctx)
1.1.1.5   root     5305: {
1.1.1.6   root     5306:     int rd = rD(ctx->opcode);
                   5307:     TCGv t0;
                   5308:     gen_set_access_type(ctx, ACCESS_FLOAT);
                   5309:     t0 = tcg_temp_new();
                   5310:     gen_addr_imm_index(ctx, t0, 0);
                   5311:     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
                   5312:     gen_addr_add(ctx, t0, t0, 8);
                   5313:     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
                   5314:     tcg_temp_free(t0);
1.1.1.5   root     5315: }
                   5316: 
                   5317: /* lfqu */
1.1.1.7   root     5318: static void gen_lfqu(DisasContext *ctx)
1.1.1.5   root     5319: {
                   5320:     int ra = rA(ctx->opcode);
1.1.1.6   root     5321:     int rd = rD(ctx->opcode);
                   5322:     TCGv t0, t1;
                   5323:     gen_set_access_type(ctx, ACCESS_FLOAT);
                   5324:     t0 = tcg_temp_new();
                   5325:     t1 = tcg_temp_new();
                   5326:     gen_addr_imm_index(ctx, t0, 0);
                   5327:     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
                   5328:     gen_addr_add(ctx, t1, t0, 8);
                   5329:     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
1.1.1.5   root     5330:     if (ra != 0)
1.1.1.6   root     5331:         tcg_gen_mov_tl(cpu_gpr[ra], t0);
                   5332:     tcg_temp_free(t0);
                   5333:     tcg_temp_free(t1);
1.1.1.5   root     5334: }
                   5335: 
                   5336: /* lfqux */
1.1.1.7   root     5337: static void gen_lfqux(DisasContext *ctx)
1.1.1.5   root     5338: {
                   5339:     int ra = rA(ctx->opcode);
1.1.1.6   root     5340:     int rd = rD(ctx->opcode);
                   5341:     gen_set_access_type(ctx, ACCESS_FLOAT);
                   5342:     TCGv t0, t1;
                   5343:     t0 = tcg_temp_new();
                   5344:     gen_addr_reg_index(ctx, t0);
                   5345:     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
                   5346:     t1 = tcg_temp_new();
                   5347:     gen_addr_add(ctx, t1, t0, 8);
                   5348:     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
                   5349:     tcg_temp_free(t1);
1.1.1.5   root     5350:     if (ra != 0)
1.1.1.6   root     5351:         tcg_gen_mov_tl(cpu_gpr[ra], t0);
                   5352:     tcg_temp_free(t0);
1.1.1.5   root     5353: }
                   5354: 
                   5355: /* lfqx */
1.1.1.7   root     5356: static void gen_lfqx(DisasContext *ctx)
1.1.1.5   root     5357: {
1.1.1.6   root     5358:     int rd = rD(ctx->opcode);
                   5359:     TCGv t0;
                   5360:     gen_set_access_type(ctx, ACCESS_FLOAT);
                   5361:     t0 = tcg_temp_new();
                   5362:     gen_addr_reg_index(ctx, t0);
                   5363:     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
                   5364:     gen_addr_add(ctx, t0, t0, 8);
                   5365:     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
                   5366:     tcg_temp_free(t0);
1.1.1.5   root     5367: }
                   5368: 
                   5369: /* stfq */
1.1.1.7   root     5370: static void gen_stfq(DisasContext *ctx)
1.1.1.5   root     5371: {
1.1.1.6   root     5372:     int rd = rD(ctx->opcode);
                   5373:     TCGv t0;
                   5374:     gen_set_access_type(ctx, ACCESS_FLOAT);
                   5375:     t0 = tcg_temp_new();
                   5376:     gen_addr_imm_index(ctx, t0, 0);
                   5377:     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
                   5378:     gen_addr_add(ctx, t0, t0, 8);
                   5379:     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
                   5380:     tcg_temp_free(t0);
1.1.1.5   root     5381: }
                   5382: 
                   5383: /* stfqu */
1.1.1.7   root     5384: static void gen_stfqu(DisasContext *ctx)
1.1.1.5   root     5385: {
                   5386:     int ra = rA(ctx->opcode);
1.1.1.6   root     5387:     int rd = rD(ctx->opcode);
                   5388:     TCGv t0, t1;
                   5389:     gen_set_access_type(ctx, ACCESS_FLOAT);
                   5390:     t0 = tcg_temp_new();
                   5391:     gen_addr_imm_index(ctx, t0, 0);
                   5392:     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
                   5393:     t1 = tcg_temp_new();
                   5394:     gen_addr_add(ctx, t1, t0, 8);
                   5395:     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
                   5396:     tcg_temp_free(t1);
1.1.1.5   root     5397:     if (ra != 0)
1.1.1.6   root     5398:         tcg_gen_mov_tl(cpu_gpr[ra], t0);
                   5399:     tcg_temp_free(t0);
1.1.1.5   root     5400: }
                   5401: 
                   5402: /* stfqux */
1.1.1.7   root     5403: static void gen_stfqux(DisasContext *ctx)
1.1.1.5   root     5404: {
                   5405:     int ra = rA(ctx->opcode);
1.1.1.6   root     5406:     int rd = rD(ctx->opcode);
                   5407:     TCGv t0, t1;
                   5408:     gen_set_access_type(ctx, ACCESS_FLOAT);
                   5409:     t0 = tcg_temp_new();
                   5410:     gen_addr_reg_index(ctx, t0);
                   5411:     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
                   5412:     t1 = tcg_temp_new();
                   5413:     gen_addr_add(ctx, t1, t0, 8);
                   5414:     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
                   5415:     tcg_temp_free(t1);
1.1.1.5   root     5416:     if (ra != 0)
1.1.1.6   root     5417:         tcg_gen_mov_tl(cpu_gpr[ra], t0);
                   5418:     tcg_temp_free(t0);
1.1.1.5   root     5419: }
                   5420: 
                   5421: /* stfqx */
1.1.1.7   root     5422: static void gen_stfqx(DisasContext *ctx)
1.1.1.5   root     5423: {
1.1.1.6   root     5424:     int rd = rD(ctx->opcode);
                   5425:     TCGv t0;
                   5426:     gen_set_access_type(ctx, ACCESS_FLOAT);
                   5427:     t0 = tcg_temp_new();
                   5428:     gen_addr_reg_index(ctx, t0);
                   5429:     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
                   5430:     gen_addr_add(ctx, t0, t0, 8);
                   5431:     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
                   5432:     tcg_temp_free(t0);
1.1.1.5   root     5433: }
                   5434: 
                   5435: /* BookE specific instructions */
1.1.1.7   root     5436: 
1.1.1.5   root     5437: /* XXX: not implemented on 440 ? */
1.1.1.7   root     5438: static void gen_mfapidi(DisasContext *ctx)
1.1.1.5   root     5439: {
                   5440:     /* XXX: TODO */
1.1.1.6   root     5441:     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5442: }
                   5443: 
                   5444: /* XXX: not implemented on 440 ? */
1.1.1.7   root     5445: static void gen_tlbiva(DisasContext *ctx)
1.1.1.5   root     5446: {
                   5447: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5448:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5449: #else
1.1.1.6   root     5450:     TCGv t0;
                   5451:     if (unlikely(!ctx->mem_idx)) {
                   5452:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5453:         return;
                   5454:     }
1.1.1.6   root     5455:     t0 = tcg_temp_new();
                   5456:     gen_addr_reg_index(ctx, t0);
                   5457:     gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
                   5458:     tcg_temp_free(t0);
1.1.1.5   root     5459: #endif
                   5460: }
                   5461: 
                   5462: /* All 405 MAC instructions are translated here */
1.1.1.8   root     5463: static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
                   5464:                                         int ra, int rb, int rt, int Rc)
1.1.1.5   root     5465: {
1.1.1.6   root     5466:     TCGv t0, t1;
                   5467: 
                   5468:     t0 = tcg_temp_local_new();
                   5469:     t1 = tcg_temp_local_new();
                   5470: 
1.1.1.5   root     5471:     switch (opc3 & 0x0D) {
                   5472:     case 0x05:
                   5473:         /* macchw    - macchw.    - macchwo   - macchwo.   */
                   5474:         /* macchws   - macchws.   - macchwso  - macchwso.  */
                   5475:         /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
                   5476:         /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
                   5477:         /* mulchw - mulchw. */
1.1.1.6   root     5478:         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
                   5479:         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
                   5480:         tcg_gen_ext16s_tl(t1, t1);
1.1.1.5   root     5481:         break;
                   5482:     case 0x04:
                   5483:         /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
                   5484:         /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
                   5485:         /* mulchwu - mulchwu. */
1.1.1.6   root     5486:         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
                   5487:         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
                   5488:         tcg_gen_ext16u_tl(t1, t1);
1.1.1.5   root     5489:         break;
                   5490:     case 0x01:
                   5491:         /* machhw    - machhw.    - machhwo   - machhwo.   */
                   5492:         /* machhws   - machhws.   - machhwso  - machhwso.  */
                   5493:         /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
                   5494:         /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
                   5495:         /* mulhhw - mulhhw. */
1.1.1.6   root     5496:         tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
                   5497:         tcg_gen_ext16s_tl(t0, t0);
                   5498:         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
                   5499:         tcg_gen_ext16s_tl(t1, t1);
1.1.1.5   root     5500:         break;
                   5501:     case 0x00:
                   5502:         /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
                   5503:         /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
                   5504:         /* mulhhwu - mulhhwu. */
1.1.1.6   root     5505:         tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
                   5506:         tcg_gen_ext16u_tl(t0, t0);
                   5507:         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
                   5508:         tcg_gen_ext16u_tl(t1, t1);
1.1.1.5   root     5509:         break;
                   5510:     case 0x0D:
                   5511:         /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
                   5512:         /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
                   5513:         /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
                   5514:         /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
                   5515:         /* mullhw - mullhw. */
1.1.1.6   root     5516:         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
                   5517:         tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
1.1.1.5   root     5518:         break;
                   5519:     case 0x0C:
                   5520:         /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
                   5521:         /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
                   5522:         /* mullhwu - mullhwu. */
1.1.1.6   root     5523:         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
                   5524:         tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
1.1.1.5   root     5525:         break;
                   5526:     }
                   5527:     if (opc2 & 0x04) {
1.1.1.6   root     5528:         /* (n)multiply-and-accumulate (0x0C / 0x0E) */
                   5529:         tcg_gen_mul_tl(t1, t0, t1);
                   5530:         if (opc2 & 0x02) {
                   5531:             /* nmultiply-and-accumulate (0x0E) */
                   5532:             tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
                   5533:         } else {
                   5534:             /* multiply-and-accumulate (0x0C) */
                   5535:             tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
                   5536:         }
                   5537: 
                   5538:         if (opc3 & 0x12) {
                   5539:             /* Check overflow and/or saturate */
                   5540:             int l1 = gen_new_label();
                   5541: 
                   5542:             if (opc3 & 0x10) {
                   5543:                 /* Start with XER OV disabled, the most likely case */
                   5544:                 tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                   5545:             }
                   5546:             if (opc3 & 0x01) {
                   5547:                 /* Signed */
                   5548:                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
                   5549:                 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   5550:                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
                   5551:                 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
                   5552:                 if (opc3 & 0x02) {
                   5553:                     /* Saturate */
                   5554:                     tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
                   5555:                     tcg_gen_xori_tl(t0, t0, 0x7fffffff);
                   5556:                 }
                   5557:             } else {
                   5558:                 /* Unsigned */
                   5559:                 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
                   5560:                 if (opc3 & 0x02) {
                   5561:                     /* Saturate */
                   5562:                     tcg_gen_movi_tl(t0, UINT32_MAX);
                   5563:                 }
                   5564:             }
                   5565:             if (opc3 & 0x10) {
                   5566:                 /* Check overflow */
                   5567:                 tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                   5568:             }
                   5569:             gen_set_label(l1);
                   5570:             tcg_gen_mov_tl(cpu_gpr[rt], t0);
                   5571:         }
                   5572:     } else {
                   5573:         tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
1.1.1.5   root     5574:     }
1.1.1.6   root     5575:     tcg_temp_free(t0);
                   5576:     tcg_temp_free(t1);
1.1.1.5   root     5577:     if (unlikely(Rc) != 0) {
                   5578:         /* Update Rc0 */
1.1.1.6   root     5579:         gen_set_Rc0(ctx, cpu_gpr[rt]);
1.1.1.5   root     5580:     }
                   5581: }
                   5582: 
                   5583: #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
1.1.1.7   root     5584: static void glue(gen_, name)(DisasContext *ctx)                               \
1.1.1.5   root     5585: {                                                                             \
                   5586:     gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
                   5587:                          rD(ctx->opcode), Rc(ctx->opcode));                   \
                   5588: }
                   5589: 
                   5590: /* macchw    - macchw.    */
                   5591: GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
                   5592: /* macchwo   - macchwo.   */
                   5593: GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
                   5594: /* macchws   - macchws.   */
                   5595: GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
                   5596: /* macchwso  - macchwso.  */
                   5597: GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
                   5598: /* macchwsu  - macchwsu.  */
                   5599: GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
                   5600: /* macchwsuo - macchwsuo. */
                   5601: GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
                   5602: /* macchwu   - macchwu.   */
                   5603: GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
                   5604: /* macchwuo  - macchwuo.  */
                   5605: GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
                   5606: /* machhw    - machhw.    */
                   5607: GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
                   5608: /* machhwo   - machhwo.   */
                   5609: GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
                   5610: /* machhws   - machhws.   */
                   5611: GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
                   5612: /* machhwso  - machhwso.  */
                   5613: GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
                   5614: /* machhwsu  - machhwsu.  */
                   5615: GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
                   5616: /* machhwsuo - machhwsuo. */
                   5617: GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
                   5618: /* machhwu   - machhwu.   */
                   5619: GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
                   5620: /* machhwuo  - machhwuo.  */
                   5621: GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
                   5622: /* maclhw    - maclhw.    */
                   5623: GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
                   5624: /* maclhwo   - maclhwo.   */
                   5625: GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
                   5626: /* maclhws   - maclhws.   */
                   5627: GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
                   5628: /* maclhwso  - maclhwso.  */
                   5629: GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
                   5630: /* maclhwu   - maclhwu.   */
                   5631: GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
                   5632: /* maclhwuo  - maclhwuo.  */
                   5633: GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
                   5634: /* maclhwsu  - maclhwsu.  */
                   5635: GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
                   5636: /* maclhwsuo - maclhwsuo. */
                   5637: GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
                   5638: /* nmacchw   - nmacchw.   */
                   5639: GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
                   5640: /* nmacchwo  - nmacchwo.  */
                   5641: GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
                   5642: /* nmacchws  - nmacchws.  */
                   5643: GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
                   5644: /* nmacchwso - nmacchwso. */
                   5645: GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
                   5646: /* nmachhw   - nmachhw.   */
                   5647: GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
                   5648: /* nmachhwo  - nmachhwo.  */
                   5649: GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
                   5650: /* nmachhws  - nmachhws.  */
                   5651: GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
                   5652: /* nmachhwso - nmachhwso. */
                   5653: GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
                   5654: /* nmaclhw   - nmaclhw.   */
                   5655: GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
                   5656: /* nmaclhwo  - nmaclhwo.  */
                   5657: GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
                   5658: /* nmaclhws  - nmaclhws.  */
                   5659: GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
                   5660: /* nmaclhwso - nmaclhwso. */
                   5661: GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
                   5662: 
                   5663: /* mulchw  - mulchw.  */
                   5664: GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
                   5665: /* mulchwu - mulchwu. */
                   5666: GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
                   5667: /* mulhhw  - mulhhw.  */
                   5668: GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
                   5669: /* mulhhwu - mulhhwu. */
                   5670: GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
                   5671: /* mullhw  - mullhw.  */
                   5672: GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
                   5673: /* mullhwu - mullhwu. */
                   5674: GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
                   5675: 
                   5676: /* mfdcr */
1.1.1.7   root     5677: static void gen_mfdcr(DisasContext *ctx)
1.1.1.5   root     5678: {
                   5679: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5680:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5681: #else
1.1.1.6   root     5682:     TCGv dcrn;
                   5683:     if (unlikely(!ctx->mem_idx)) {
                   5684:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5685:         return;
                   5686:     }
1.1.1.6   root     5687:     /* NIP cannot be restored if the memory exception comes from an helper */
                   5688:     gen_update_nip(ctx, ctx->nip - 4);
                   5689:     dcrn = tcg_const_tl(SPR(ctx->opcode));
                   5690:     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], dcrn);
                   5691:     tcg_temp_free(dcrn);
1.1.1.5   root     5692: #endif
                   5693: }
                   5694: 
                   5695: /* mtdcr */
1.1.1.7   root     5696: static void gen_mtdcr(DisasContext *ctx)
1.1.1.5   root     5697: {
                   5698: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5699:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5700: #else
1.1.1.6   root     5701:     TCGv dcrn;
                   5702:     if (unlikely(!ctx->mem_idx)) {
                   5703:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5704:         return;
                   5705:     }
1.1.1.6   root     5706:     /* NIP cannot be restored if the memory exception comes from an helper */
                   5707:     gen_update_nip(ctx, ctx->nip - 4);
                   5708:     dcrn = tcg_const_tl(SPR(ctx->opcode));
                   5709:     gen_helper_store_dcr(dcrn, cpu_gpr[rS(ctx->opcode)]);
                   5710:     tcg_temp_free(dcrn);
1.1.1.5   root     5711: #endif
                   5712: }
                   5713: 
                   5714: /* mfdcrx */
                   5715: /* XXX: not implemented on 440 ? */
1.1.1.7   root     5716: static void gen_mfdcrx(DisasContext *ctx)
1.1.1.5   root     5717: {
                   5718: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5719:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5720: #else
1.1.1.6   root     5721:     if (unlikely(!ctx->mem_idx)) {
                   5722:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5723:         return;
                   5724:     }
1.1.1.6   root     5725:     /* NIP cannot be restored if the memory exception comes from an helper */
                   5726:     gen_update_nip(ctx, ctx->nip - 4);
                   5727:     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5728:     /* Note: Rc update flag set leads to undefined state of Rc0 */
                   5729: #endif
                   5730: }
                   5731: 
                   5732: /* mtdcrx */
                   5733: /* XXX: not implemented on 440 ? */
1.1.1.7   root     5734: static void gen_mtdcrx(DisasContext *ctx)
1.1.1.5   root     5735: {
                   5736: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5737:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5738: #else
1.1.1.6   root     5739:     if (unlikely(!ctx->mem_idx)) {
                   5740:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5741:         return;
                   5742:     }
1.1.1.6   root     5743:     /* NIP cannot be restored if the memory exception comes from an helper */
                   5744:     gen_update_nip(ctx, ctx->nip - 4);
                   5745:     gen_helper_store_dcr(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     5746:     /* Note: Rc update flag set leads to undefined state of Rc0 */
                   5747: #endif
                   5748: }
                   5749: 
                   5750: /* mfdcrux (PPC 460) : user-mode access to DCR */
1.1.1.7   root     5751: static void gen_mfdcrux(DisasContext *ctx)
1.1.1.5   root     5752: {
1.1.1.6   root     5753:     /* NIP cannot be restored if the memory exception comes from an helper */
                   5754:     gen_update_nip(ctx, ctx->nip - 4);
                   5755:     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5756:     /* Note: Rc update flag set leads to undefined state of Rc0 */
                   5757: }
                   5758: 
                   5759: /* mtdcrux (PPC 460) : user-mode access to DCR */
1.1.1.7   root     5760: static void gen_mtdcrux(DisasContext *ctx)
1.1.1.5   root     5761: {
1.1.1.6   root     5762:     /* NIP cannot be restored if the memory exception comes from an helper */
                   5763:     gen_update_nip(ctx, ctx->nip - 4);
                   5764:     gen_helper_store_dcr(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     5765:     /* Note: Rc update flag set leads to undefined state of Rc0 */
                   5766: }
                   5767: 
                   5768: /* dccci */
1.1.1.7   root     5769: static void gen_dccci(DisasContext *ctx)
1.1.1.5   root     5770: {
                   5771: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5772:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5773: #else
1.1.1.6   root     5774:     if (unlikely(!ctx->mem_idx)) {
                   5775:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5776:         return;
                   5777:     }
                   5778:     /* interpreted as no-op */
                   5779: #endif
                   5780: }
                   5781: 
                   5782: /* dcread */
1.1.1.7   root     5783: static void gen_dcread(DisasContext *ctx)
1.1.1.5   root     5784: {
                   5785: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5786:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5787: #else
1.1.1.6   root     5788:     TCGv EA, val;
                   5789:     if (unlikely(!ctx->mem_idx)) {
                   5790:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5791:         return;
                   5792:     }
1.1.1.6   root     5793:     gen_set_access_type(ctx, ACCESS_CACHE);
                   5794:     EA = tcg_temp_new();
                   5795:     gen_addr_reg_index(ctx, EA);
                   5796:     val = tcg_temp_new();
                   5797:     gen_qemu_ld32u(ctx, val, EA);
                   5798:     tcg_temp_free(val);
                   5799:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
                   5800:     tcg_temp_free(EA);
1.1.1.5   root     5801: #endif
                   5802: }
                   5803: 
                   5804: /* icbt */
1.1.1.7   root     5805: static void gen_icbt_40x(DisasContext *ctx)
1.1.1.5   root     5806: {
                   5807:     /* interpreted as no-op */
                   5808:     /* XXX: specification say this is treated as a load by the MMU
                   5809:      *      but does not generate any exception
                   5810:      */
                   5811: }
                   5812: 
                   5813: /* iccci */
1.1.1.7   root     5814: static void gen_iccci(DisasContext *ctx)
1.1.1.5   root     5815: {
                   5816: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5817:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5818: #else
1.1.1.6   root     5819:     if (unlikely(!ctx->mem_idx)) {
                   5820:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5821:         return;
                   5822:     }
                   5823:     /* interpreted as no-op */
                   5824: #endif
                   5825: }
                   5826: 
                   5827: /* icread */
1.1.1.7   root     5828: static void gen_icread(DisasContext *ctx)
1.1.1.5   root     5829: {
                   5830: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5831:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5832: #else
1.1.1.6   root     5833:     if (unlikely(!ctx->mem_idx)) {
                   5834:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5835:         return;
                   5836:     }
                   5837:     /* interpreted as no-op */
                   5838: #endif
                   5839: }
                   5840: 
1.1.1.6   root     5841: /* rfci (mem_idx only) */
1.1.1.7   root     5842: static void gen_rfci_40x(DisasContext *ctx)
1.1.1.5   root     5843: {
                   5844: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5845:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5846: #else
1.1.1.6   root     5847:     if (unlikely(!ctx->mem_idx)) {
                   5848:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5849:         return;
                   5850:     }
                   5851:     /* Restore CPU state */
1.1.1.6   root     5852:     gen_helper_40x_rfci();
                   5853:     gen_sync_exception(ctx);
1.1.1.5   root     5854: #endif
                   5855: }
                   5856: 
1.1.1.7   root     5857: static void gen_rfci(DisasContext *ctx)
1.1.1.5   root     5858: {
                   5859: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5860:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5861: #else
1.1.1.6   root     5862:     if (unlikely(!ctx->mem_idx)) {
                   5863:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5864:         return;
                   5865:     }
                   5866:     /* Restore CPU state */
1.1.1.6   root     5867:     gen_helper_rfci();
                   5868:     gen_sync_exception(ctx);
1.1.1.5   root     5869: #endif
                   5870: }
                   5871: 
                   5872: /* BookE specific */
1.1.1.7   root     5873: 
1.1.1.5   root     5874: /* XXX: not implemented on 440 ? */
1.1.1.7   root     5875: static void gen_rfdi(DisasContext *ctx)
1.1.1.5   root     5876: {
                   5877: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5878:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5879: #else
1.1.1.6   root     5880:     if (unlikely(!ctx->mem_idx)) {
                   5881:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5882:         return;
                   5883:     }
                   5884:     /* Restore CPU state */
1.1.1.6   root     5885:     gen_helper_rfdi();
                   5886:     gen_sync_exception(ctx);
1.1.1.5   root     5887: #endif
                   5888: }
                   5889: 
                   5890: /* XXX: not implemented on 440 ? */
1.1.1.7   root     5891: static void gen_rfmci(DisasContext *ctx)
1.1.1.5   root     5892: {
                   5893: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5894:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5895: #else
1.1.1.6   root     5896:     if (unlikely(!ctx->mem_idx)) {
                   5897:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5898:         return;
                   5899:     }
                   5900:     /* Restore CPU state */
1.1.1.6   root     5901:     gen_helper_rfmci();
                   5902:     gen_sync_exception(ctx);
1.1.1.5   root     5903: #endif
                   5904: }
                   5905: 
                   5906: /* TLB management - PowerPC 405 implementation */
1.1.1.7   root     5907: 
1.1.1.5   root     5908: /* tlbre */
1.1.1.7   root     5909: static void gen_tlbre_40x(DisasContext *ctx)
1.1.1.5   root     5910: {
                   5911: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5912:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5913: #else
1.1.1.6   root     5914:     if (unlikely(!ctx->mem_idx)) {
                   5915:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5916:         return;
                   5917:     }
                   5918:     switch (rB(ctx->opcode)) {
                   5919:     case 0:
1.1.1.6   root     5920:         gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5921:         break;
                   5922:     case 1:
1.1.1.6   root     5923:         gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5924:         break;
                   5925:     default:
1.1.1.6   root     5926:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5927:         break;
                   5928:     }
                   5929: #endif
                   5930: }
                   5931: 
                   5932: /* tlbsx - tlbsx. */
1.1.1.7   root     5933: static void gen_tlbsx_40x(DisasContext *ctx)
1.1.1.5   root     5934: {
                   5935: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5936:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5937: #else
1.1.1.6   root     5938:     TCGv t0;
                   5939:     if (unlikely(!ctx->mem_idx)) {
                   5940:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5941:         return;
                   5942:     }
1.1.1.6   root     5943:     t0 = tcg_temp_new();
                   5944:     gen_addr_reg_index(ctx, t0);
                   5945:     gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
                   5946:     tcg_temp_free(t0);
                   5947:     if (Rc(ctx->opcode)) {
                   5948:         int l1 = gen_new_label();
                   5949:         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
                   5950:         tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
                   5951:         tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
                   5952:         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
                   5953:         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
                   5954:         gen_set_label(l1);
                   5955:     }
1.1.1.5   root     5956: #endif
                   5957: }
                   5958: 
                   5959: /* tlbwe */
1.1.1.7   root     5960: static void gen_tlbwe_40x(DisasContext *ctx)
1.1.1.5   root     5961: {
                   5962: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5963:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5964: #else
1.1.1.6   root     5965:     if (unlikely(!ctx->mem_idx)) {
                   5966:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5967:         return;
                   5968:     }
                   5969:     switch (rB(ctx->opcode)) {
                   5970:     case 0:
1.1.1.6   root     5971:         gen_helper_4xx_tlbwe_hi(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     5972:         break;
                   5973:     case 1:
1.1.1.6   root     5974:         gen_helper_4xx_tlbwe_lo(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     5975:         break;
                   5976:     default:
1.1.1.6   root     5977:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5978:         break;
                   5979:     }
                   5980: #endif
                   5981: }
                   5982: 
                   5983: /* TLB management - PowerPC 440 implementation */
1.1.1.7   root     5984: 
1.1.1.5   root     5985: /* tlbre */
1.1.1.7   root     5986: static void gen_tlbre_440(DisasContext *ctx)
1.1.1.5   root     5987: {
                   5988: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5989:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5990: #else
1.1.1.6   root     5991:     if (unlikely(!ctx->mem_idx)) {
                   5992:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5993:         return;
                   5994:     }
                   5995:     switch (rB(ctx->opcode)) {
                   5996:     case 0:
                   5997:     case 1:
                   5998:     case 2:
1.1.1.6   root     5999:         {
                   6000:             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
1.1.1.10  root     6001:             gen_helper_440_tlbre(cpu_gpr[rD(ctx->opcode)], t0, cpu_gpr[rA(ctx->opcode)]);
1.1.1.6   root     6002:             tcg_temp_free_i32(t0);
                   6003:         }
1.1.1.5   root     6004:         break;
                   6005:     default:
1.1.1.6   root     6006:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     6007:         break;
                   6008:     }
                   6009: #endif
                   6010: }
                   6011: 
                   6012: /* tlbsx - tlbsx. */
1.1.1.7   root     6013: static void gen_tlbsx_440(DisasContext *ctx)
1.1       root     6014: {
                   6015: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     6016:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     6017: #else
1.1.1.6   root     6018:     TCGv t0;
                   6019:     if (unlikely(!ctx->mem_idx)) {
                   6020:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     6021:         return;
                   6022:     }
1.1.1.6   root     6023:     t0 = tcg_temp_new();
                   6024:     gen_addr_reg_index(ctx, t0);
                   6025:     gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
                   6026:     tcg_temp_free(t0);
                   6027:     if (Rc(ctx->opcode)) {
                   6028:         int l1 = gen_new_label();
                   6029:         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
                   6030:         tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
                   6031:         tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
                   6032:         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
                   6033:         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
                   6034:         gen_set_label(l1);
                   6035:     }
1.1       root     6036: #endif
                   6037: }
                   6038: 
1.1.1.5   root     6039: /* tlbwe */
1.1.1.7   root     6040: static void gen_tlbwe_440(DisasContext *ctx)
1.1       root     6041: {
                   6042: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     6043:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     6044: #else
1.1.1.6   root     6045:     if (unlikely(!ctx->mem_idx)) {
                   6046:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     6047:         return;
                   6048:     }
1.1.1.5   root     6049:     switch (rB(ctx->opcode)) {
                   6050:     case 0:
                   6051:     case 1:
                   6052:     case 2:
1.1.1.6   root     6053:         {
                   6054:             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
                   6055:             gen_helper_440_tlbwe(t0, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   6056:             tcg_temp_free_i32(t0);
                   6057:         }
1.1.1.5   root     6058:         break;
                   6059:     default:
1.1.1.6   root     6060:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     6061:         break;
                   6062:     }
                   6063: #endif
                   6064: }
                   6065: 
1.1.1.11  root     6066: /* TLB management - PowerPC BookE 2.06 implementation */
                   6067: 
                   6068: /* tlbre */
                   6069: static void gen_tlbre_booke206(DisasContext *ctx)
                   6070: {
                   6071: #if defined(CONFIG_USER_ONLY)
                   6072:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   6073: #else
                   6074:     if (unlikely(!ctx->mem_idx)) {
                   6075:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   6076:         return;
                   6077:     }
                   6078: 
                   6079:     gen_helper_booke206_tlbre();
                   6080: #endif
                   6081: }
                   6082: 
                   6083: /* tlbsx - tlbsx. */
                   6084: static void gen_tlbsx_booke206(DisasContext *ctx)
                   6085: {
                   6086: #if defined(CONFIG_USER_ONLY)
                   6087:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   6088: #else
                   6089:     TCGv t0;
                   6090:     if (unlikely(!ctx->mem_idx)) {
                   6091:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   6092:         return;
                   6093:     }
                   6094: 
                   6095:     if (rA(ctx->opcode)) {
                   6096:         t0 = tcg_temp_new();
                   6097:         tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]);
                   6098:     } else {
                   6099:         t0 = tcg_const_tl(0);
                   6100:     }
                   6101: 
                   6102:     tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]);
                   6103:     gen_helper_booke206_tlbsx(t0);
                   6104: #endif
                   6105: }
                   6106: 
                   6107: /* tlbwe */
                   6108: static void gen_tlbwe_booke206(DisasContext *ctx)
                   6109: {
                   6110: #if defined(CONFIG_USER_ONLY)
                   6111:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   6112: #else
                   6113:     if (unlikely(!ctx->mem_idx)) {
                   6114:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   6115:         return;
                   6116:     }
1.1.1.13! root     6117:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.11  root     6118:     gen_helper_booke206_tlbwe();
                   6119: #endif
                   6120: }
                   6121: 
                   6122: static void gen_tlbivax_booke206(DisasContext *ctx)
                   6123: {
                   6124: #if defined(CONFIG_USER_ONLY)
                   6125:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   6126: #else
                   6127:     TCGv t0;
                   6128:     if (unlikely(!ctx->mem_idx)) {
                   6129:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   6130:         return;
                   6131:     }
                   6132: 
                   6133:     t0 = tcg_temp_new();
                   6134:     gen_addr_reg_index(ctx, t0);
                   6135: 
                   6136:     gen_helper_booke206_tlbivax(t0);
                   6137: #endif
                   6138: }
                   6139: 
1.1.1.13! root     6140: static void gen_tlbilx_booke206(DisasContext *ctx)
        !          6141: {
        !          6142: #if defined(CONFIG_USER_ONLY)
        !          6143:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
        !          6144: #else
        !          6145:     TCGv t0;
        !          6146:     if (unlikely(!ctx->mem_idx)) {
        !          6147:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
        !          6148:         return;
        !          6149:     }
        !          6150: 
        !          6151:     t0 = tcg_temp_new();
        !          6152:     gen_addr_reg_index(ctx, t0);
        !          6153: 
        !          6154:     switch((ctx->opcode >> 21) & 0x3) {
        !          6155:     case 0:
        !          6156:         gen_helper_booke206_tlbilx0(t0);
        !          6157:         break;
        !          6158:     case 1:
        !          6159:         gen_helper_booke206_tlbilx1(t0);
        !          6160:         break;
        !          6161:     case 3:
        !          6162:         gen_helper_booke206_tlbilx3(t0);
        !          6163:         break;
        !          6164:     default:
        !          6165:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
        !          6166:         break;
        !          6167:     }
        !          6168: 
        !          6169:     tcg_temp_free(t0);
        !          6170: #endif
        !          6171: }
        !          6172: 
1.1.1.11  root     6173: 
1.1.1.5   root     6174: /* wrtee */
1.1.1.7   root     6175: static void gen_wrtee(DisasContext *ctx)
1.1.1.5   root     6176: {
                   6177: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     6178:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     6179: #else
1.1.1.6   root     6180:     TCGv t0;
                   6181:     if (unlikely(!ctx->mem_idx)) {
                   6182:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     6183:         return;
                   6184:     }
1.1.1.6   root     6185:     t0 = tcg_temp_new();
                   6186:     tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
                   6187:     tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
                   6188:     tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
                   6189:     tcg_temp_free(t0);
1.1.1.5   root     6190:     /* Stop translation to have a chance to raise an exception
                   6191:      * if we just set msr_ee to 1
1.1       root     6192:      */
1.1.1.6   root     6193:     gen_stop_exception(ctx);
1.1       root     6194: #endif
                   6195: }
                   6196: 
1.1.1.5   root     6197: /* wrteei */
1.1.1.7   root     6198: static void gen_wrteei(DisasContext *ctx)
1.1.1.5   root     6199: {
1.1       root     6200: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     6201:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     6202: #else
1.1.1.6   root     6203:     if (unlikely(!ctx->mem_idx)) {
                   6204:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     6205:         return;
                   6206:     }
1.1.1.7   root     6207:     if (ctx->opcode & 0x00008000) {
1.1.1.6   root     6208:         tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
                   6209:         /* Stop translation to have a chance to raise an exception */
                   6210:         gen_stop_exception(ctx);
                   6211:     } else {
                   6212:         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
                   6213:     }
1.1.1.5   root     6214: #endif
                   6215: }
                   6216: 
                   6217: /* PowerPC 440 specific instructions */
1.1.1.7   root     6218: 
1.1.1.5   root     6219: /* dlmzb */
1.1.1.7   root     6220: static void gen_dlmzb(DisasContext *ctx)
1.1.1.5   root     6221: {
1.1.1.6   root     6222:     TCGv_i32 t0 = tcg_const_i32(Rc(ctx->opcode));
                   6223:     gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
                   6224:                      cpu_gpr[rB(ctx->opcode)], t0);
                   6225:     tcg_temp_free_i32(t0);
1.1.1.5   root     6226: }
                   6227: 
                   6228: /* mbar replaces eieio on 440 */
1.1.1.7   root     6229: static void gen_mbar(DisasContext *ctx)
1.1.1.5   root     6230: {
                   6231:     /* interpreted as no-op */
                   6232: }
                   6233: 
                   6234: /* msync replaces sync on 440 */
1.1.1.13! root     6235: static void gen_msync_4xx(DisasContext *ctx)
1.1.1.5   root     6236: {
                   6237:     /* interpreted as no-op */
                   6238: }
                   6239: 
                   6240: /* icbt */
1.1.1.7   root     6241: static void gen_icbt_440(DisasContext *ctx)
1.1.1.5   root     6242: {
                   6243:     /* interpreted as no-op */
                   6244:     /* XXX: specification say this is treated as a load by the MMU
                   6245:      *      but does not generate any exception
                   6246:      */
                   6247: }
                   6248: 
1.1.1.13! root     6249: /* Embedded.Processor Control */
        !          6250: 
        !          6251: static void gen_msgclr(DisasContext *ctx)
        !          6252: {
        !          6253: #if defined(CONFIG_USER_ONLY)
        !          6254:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
        !          6255: #else
        !          6256:     if (unlikely(ctx->mem_idx == 0)) {
        !          6257:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
        !          6258:         return;
        !          6259:     }
        !          6260: 
        !          6261:     gen_helper_msgclr(cpu_gpr[rB(ctx->opcode)]);
        !          6262: #endif
        !          6263: }
        !          6264: 
        !          6265: static void gen_msgsnd(DisasContext *ctx)
        !          6266: {
        !          6267: #if defined(CONFIG_USER_ONLY)
        !          6268:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
        !          6269: #else
        !          6270:     if (unlikely(ctx->mem_idx == 0)) {
        !          6271:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
        !          6272:         return;
        !          6273:     }
        !          6274: 
        !          6275:     gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
        !          6276: #endif
        !          6277: }
        !          6278: 
1.1.1.5   root     6279: /***                      Altivec vector extension                         ***/
                   6280: /* Altivec registers moves */
                   6281: 
1.1.1.8   root     6282: static inline TCGv_ptr gen_avr_ptr(int reg)
1.1.1.6   root     6283: {
                   6284:     TCGv_ptr r = tcg_temp_new_ptr();
                   6285:     tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, avr[reg]));
                   6286:     return r;
                   6287: }
1.1.1.5   root     6288: 
                   6289: #define GEN_VR_LDX(name, opc2, opc3)                                          \
1.1.1.7   root     6290: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.5   root     6291: {                                                                             \
1.1.1.6   root     6292:     TCGv EA;                                                                  \
1.1.1.5   root     6293:     if (unlikely(!ctx->altivec_enabled)) {                                    \
1.1.1.6   root     6294:         gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
1.1.1.5   root     6295:         return;                                                               \
                   6296:     }                                                                         \
1.1.1.6   root     6297:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   6298:     EA = tcg_temp_new();                                                      \
                   6299:     gen_addr_reg_index(ctx, EA);                                              \
                   6300:     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
                   6301:     if (ctx->le_mode) {                                                       \
                   6302:         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
                   6303:         tcg_gen_addi_tl(EA, EA, 8);                                           \
                   6304:         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
                   6305:     } else {                                                                  \
                   6306:         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
                   6307:         tcg_gen_addi_tl(EA, EA, 8);                                           \
                   6308:         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
                   6309:     }                                                                         \
                   6310:     tcg_temp_free(EA);                                                        \
1.1.1.5   root     6311: }
                   6312: 
                   6313: #define GEN_VR_STX(name, opc2, opc3)                                          \
1.1.1.7   root     6314: static void gen_st##name(DisasContext *ctx)                                   \
1.1.1.5   root     6315: {                                                                             \
1.1.1.6   root     6316:     TCGv EA;                                                                  \
1.1.1.5   root     6317:     if (unlikely(!ctx->altivec_enabled)) {                                    \
1.1.1.6   root     6318:         gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
1.1.1.5   root     6319:         return;                                                               \
                   6320:     }                                                                         \
1.1.1.6   root     6321:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   6322:     EA = tcg_temp_new();                                                      \
                   6323:     gen_addr_reg_index(ctx, EA);                                              \
                   6324:     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
                   6325:     if (ctx->le_mode) {                                                       \
                   6326:         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
                   6327:         tcg_gen_addi_tl(EA, EA, 8);                                           \
                   6328:         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
                   6329:     } else {                                                                  \
                   6330:         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
                   6331:         tcg_gen_addi_tl(EA, EA, 8);                                           \
                   6332:         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
                   6333:     }                                                                         \
                   6334:     tcg_temp_free(EA);                                                        \
1.1.1.5   root     6335: }
                   6336: 
1.1.1.6   root     6337: #define GEN_VR_LVE(name, opc2, opc3)                                    \
1.1.1.7   root     6338: static void gen_lve##name(DisasContext *ctx)                            \
1.1.1.6   root     6339:     {                                                                   \
                   6340:         TCGv EA;                                                        \
                   6341:         TCGv_ptr rs;                                                    \
                   6342:         if (unlikely(!ctx->altivec_enabled)) {                          \
                   6343:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
                   6344:             return;                                                     \
                   6345:         }                                                               \
                   6346:         gen_set_access_type(ctx, ACCESS_INT);                           \
                   6347:         EA = tcg_temp_new();                                            \
                   6348:         gen_addr_reg_index(ctx, EA);                                    \
                   6349:         rs = gen_avr_ptr(rS(ctx->opcode));                              \
                   6350:         gen_helper_lve##name (rs, EA);                                  \
                   6351:         tcg_temp_free(EA);                                              \
                   6352:         tcg_temp_free_ptr(rs);                                          \
                   6353:     }
                   6354: 
                   6355: #define GEN_VR_STVE(name, opc2, opc3)                                   \
1.1.1.7   root     6356: static void gen_stve##name(DisasContext *ctx)                           \
1.1.1.6   root     6357:     {                                                                   \
                   6358:         TCGv EA;                                                        \
                   6359:         TCGv_ptr rs;                                                    \
                   6360:         if (unlikely(!ctx->altivec_enabled)) {                          \
                   6361:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
                   6362:             return;                                                     \
                   6363:         }                                                               \
                   6364:         gen_set_access_type(ctx, ACCESS_INT);                           \
                   6365:         EA = tcg_temp_new();                                            \
                   6366:         gen_addr_reg_index(ctx, EA);                                    \
                   6367:         rs = gen_avr_ptr(rS(ctx->opcode));                              \
                   6368:         gen_helper_stve##name (rs, EA);                                 \
                   6369:         tcg_temp_free(EA);                                              \
                   6370:         tcg_temp_free_ptr(rs);                                          \
                   6371:     }
                   6372: 
                   6373: GEN_VR_LDX(lvx, 0x07, 0x03);
1.1.1.5   root     6374: /* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
1.1.1.6   root     6375: GEN_VR_LDX(lvxl, 0x07, 0x0B);
1.1.1.5   root     6376: 
1.1.1.6   root     6377: GEN_VR_LVE(bx, 0x07, 0x00);
                   6378: GEN_VR_LVE(hx, 0x07, 0x01);
                   6379: GEN_VR_LVE(wx, 0x07, 0x02);
                   6380: 
                   6381: GEN_VR_STX(svx, 0x07, 0x07);
1.1.1.5   root     6382: /* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
1.1.1.6   root     6383: GEN_VR_STX(svxl, 0x07, 0x0F);
                   6384: 
                   6385: GEN_VR_STVE(bx, 0x07, 0x04);
                   6386: GEN_VR_STVE(hx, 0x07, 0x05);
                   6387: GEN_VR_STVE(wx, 0x07, 0x06);
                   6388: 
1.1.1.7   root     6389: static void gen_lvsl(DisasContext *ctx)
1.1.1.6   root     6390: {
                   6391:     TCGv_ptr rd;
                   6392:     TCGv EA;
                   6393:     if (unlikely(!ctx->altivec_enabled)) {
                   6394:         gen_exception(ctx, POWERPC_EXCP_VPU);
                   6395:         return;
                   6396:     }
                   6397:     EA = tcg_temp_new();
                   6398:     gen_addr_reg_index(ctx, EA);
                   6399:     rd = gen_avr_ptr(rD(ctx->opcode));
                   6400:     gen_helper_lvsl(rd, EA);
                   6401:     tcg_temp_free(EA);
                   6402:     tcg_temp_free_ptr(rd);
                   6403: }
                   6404: 
1.1.1.7   root     6405: static void gen_lvsr(DisasContext *ctx)
1.1.1.6   root     6406: {
                   6407:     TCGv_ptr rd;
                   6408:     TCGv EA;
                   6409:     if (unlikely(!ctx->altivec_enabled)) {
                   6410:         gen_exception(ctx, POWERPC_EXCP_VPU);
                   6411:         return;
                   6412:     }
                   6413:     EA = tcg_temp_new();
                   6414:     gen_addr_reg_index(ctx, EA);
                   6415:     rd = gen_avr_ptr(rD(ctx->opcode));
                   6416:     gen_helper_lvsr(rd, EA);
                   6417:     tcg_temp_free(EA);
                   6418:     tcg_temp_free_ptr(rd);
                   6419: }
                   6420: 
1.1.1.7   root     6421: static void gen_mfvscr(DisasContext *ctx)
1.1.1.6   root     6422: {
                   6423:     TCGv_i32 t;
                   6424:     if (unlikely(!ctx->altivec_enabled)) {
                   6425:         gen_exception(ctx, POWERPC_EXCP_VPU);
                   6426:         return;
                   6427:     }
                   6428:     tcg_gen_movi_i64(cpu_avrh[rD(ctx->opcode)], 0);
                   6429:     t = tcg_temp_new_i32();
1.1.1.13! root     6430:     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUPPCState, vscr));
1.1.1.6   root     6431:     tcg_gen_extu_i32_i64(cpu_avrl[rD(ctx->opcode)], t);
                   6432:     tcg_temp_free_i32(t);
                   6433: }
                   6434: 
1.1.1.7   root     6435: static void gen_mtvscr(DisasContext *ctx)
1.1.1.6   root     6436: {
                   6437:     TCGv_ptr p;
                   6438:     if (unlikely(!ctx->altivec_enabled)) {
                   6439:         gen_exception(ctx, POWERPC_EXCP_VPU);
                   6440:         return;
                   6441:     }
                   6442:     p = gen_avr_ptr(rD(ctx->opcode));
                   6443:     gen_helper_mtvscr(p);
                   6444:     tcg_temp_free_ptr(p);
                   6445: }
                   6446: 
                   6447: /* Logical operations */
                   6448: #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
1.1.1.7   root     6449: static void glue(gen_, name)(DisasContext *ctx)                                 \
1.1.1.6   root     6450: {                                                                       \
                   6451:     if (unlikely(!ctx->altivec_enabled)) {                              \
                   6452:         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
                   6453:         return;                                                         \
                   6454:     }                                                                   \
                   6455:     tcg_op(cpu_avrh[rD(ctx->opcode)], cpu_avrh[rA(ctx->opcode)], cpu_avrh[rB(ctx->opcode)]); \
                   6456:     tcg_op(cpu_avrl[rD(ctx->opcode)], cpu_avrl[rA(ctx->opcode)], cpu_avrl[rB(ctx->opcode)]); \
                   6457: }
                   6458: 
                   6459: GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16);
                   6460: GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17);
                   6461: GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18);
                   6462: GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19);
                   6463: GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20);
                   6464: 
                   6465: #define GEN_VXFORM(name, opc2, opc3)                                    \
1.1.1.7   root     6466: static void glue(gen_, name)(DisasContext *ctx)                                 \
1.1.1.6   root     6467: {                                                                       \
                   6468:     TCGv_ptr ra, rb, rd;                                                \
                   6469:     if (unlikely(!ctx->altivec_enabled)) {                              \
                   6470:         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
                   6471:         return;                                                         \
                   6472:     }                                                                   \
                   6473:     ra = gen_avr_ptr(rA(ctx->opcode));                                  \
                   6474:     rb = gen_avr_ptr(rB(ctx->opcode));                                  \
                   6475:     rd = gen_avr_ptr(rD(ctx->opcode));                                  \
                   6476:     gen_helper_##name (rd, ra, rb);                                     \
                   6477:     tcg_temp_free_ptr(ra);                                              \
                   6478:     tcg_temp_free_ptr(rb);                                              \
                   6479:     tcg_temp_free_ptr(rd);                                              \
                   6480: }
                   6481: 
                   6482: GEN_VXFORM(vaddubm, 0, 0);
                   6483: GEN_VXFORM(vadduhm, 0, 1);
                   6484: GEN_VXFORM(vadduwm, 0, 2);
                   6485: GEN_VXFORM(vsububm, 0, 16);
                   6486: GEN_VXFORM(vsubuhm, 0, 17);
                   6487: GEN_VXFORM(vsubuwm, 0, 18);
                   6488: GEN_VXFORM(vmaxub, 1, 0);
                   6489: GEN_VXFORM(vmaxuh, 1, 1);
                   6490: GEN_VXFORM(vmaxuw, 1, 2);
                   6491: GEN_VXFORM(vmaxsb, 1, 4);
                   6492: GEN_VXFORM(vmaxsh, 1, 5);
                   6493: GEN_VXFORM(vmaxsw, 1, 6);
                   6494: GEN_VXFORM(vminub, 1, 8);
                   6495: GEN_VXFORM(vminuh, 1, 9);
                   6496: GEN_VXFORM(vminuw, 1, 10);
                   6497: GEN_VXFORM(vminsb, 1, 12);
                   6498: GEN_VXFORM(vminsh, 1, 13);
                   6499: GEN_VXFORM(vminsw, 1, 14);
                   6500: GEN_VXFORM(vavgub, 1, 16);
                   6501: GEN_VXFORM(vavguh, 1, 17);
                   6502: GEN_VXFORM(vavguw, 1, 18);
                   6503: GEN_VXFORM(vavgsb, 1, 20);
                   6504: GEN_VXFORM(vavgsh, 1, 21);
                   6505: GEN_VXFORM(vavgsw, 1, 22);
                   6506: GEN_VXFORM(vmrghb, 6, 0);
                   6507: GEN_VXFORM(vmrghh, 6, 1);
                   6508: GEN_VXFORM(vmrghw, 6, 2);
                   6509: GEN_VXFORM(vmrglb, 6, 4);
                   6510: GEN_VXFORM(vmrglh, 6, 5);
                   6511: GEN_VXFORM(vmrglw, 6, 6);
                   6512: GEN_VXFORM(vmuloub, 4, 0);
                   6513: GEN_VXFORM(vmulouh, 4, 1);
                   6514: GEN_VXFORM(vmulosb, 4, 4);
                   6515: GEN_VXFORM(vmulosh, 4, 5);
                   6516: GEN_VXFORM(vmuleub, 4, 8);
                   6517: GEN_VXFORM(vmuleuh, 4, 9);
                   6518: GEN_VXFORM(vmulesb, 4, 12);
                   6519: GEN_VXFORM(vmulesh, 4, 13);
                   6520: GEN_VXFORM(vslb, 2, 4);
                   6521: GEN_VXFORM(vslh, 2, 5);
                   6522: GEN_VXFORM(vslw, 2, 6);
                   6523: GEN_VXFORM(vsrb, 2, 8);
                   6524: GEN_VXFORM(vsrh, 2, 9);
                   6525: GEN_VXFORM(vsrw, 2, 10);
                   6526: GEN_VXFORM(vsrab, 2, 12);
                   6527: GEN_VXFORM(vsrah, 2, 13);
                   6528: GEN_VXFORM(vsraw, 2, 14);
                   6529: GEN_VXFORM(vslo, 6, 16);
                   6530: GEN_VXFORM(vsro, 6, 17);
                   6531: GEN_VXFORM(vaddcuw, 0, 6);
                   6532: GEN_VXFORM(vsubcuw, 0, 22);
                   6533: GEN_VXFORM(vaddubs, 0, 8);
                   6534: GEN_VXFORM(vadduhs, 0, 9);
                   6535: GEN_VXFORM(vadduws, 0, 10);
                   6536: GEN_VXFORM(vaddsbs, 0, 12);
                   6537: GEN_VXFORM(vaddshs, 0, 13);
                   6538: GEN_VXFORM(vaddsws, 0, 14);
                   6539: GEN_VXFORM(vsububs, 0, 24);
                   6540: GEN_VXFORM(vsubuhs, 0, 25);
                   6541: GEN_VXFORM(vsubuws, 0, 26);
                   6542: GEN_VXFORM(vsubsbs, 0, 28);
                   6543: GEN_VXFORM(vsubshs, 0, 29);
                   6544: GEN_VXFORM(vsubsws, 0, 30);
                   6545: GEN_VXFORM(vrlb, 2, 0);
                   6546: GEN_VXFORM(vrlh, 2, 1);
                   6547: GEN_VXFORM(vrlw, 2, 2);
                   6548: GEN_VXFORM(vsl, 2, 7);
                   6549: GEN_VXFORM(vsr, 2, 11);
                   6550: GEN_VXFORM(vpkuhum, 7, 0);
                   6551: GEN_VXFORM(vpkuwum, 7, 1);
                   6552: GEN_VXFORM(vpkuhus, 7, 2);
                   6553: GEN_VXFORM(vpkuwus, 7, 3);
                   6554: GEN_VXFORM(vpkshus, 7, 4);
                   6555: GEN_VXFORM(vpkswus, 7, 5);
                   6556: GEN_VXFORM(vpkshss, 7, 6);
                   6557: GEN_VXFORM(vpkswss, 7, 7);
                   6558: GEN_VXFORM(vpkpx, 7, 12);
                   6559: GEN_VXFORM(vsum4ubs, 4, 24);
                   6560: GEN_VXFORM(vsum4sbs, 4, 28);
                   6561: GEN_VXFORM(vsum4shs, 4, 25);
                   6562: GEN_VXFORM(vsum2sws, 4, 26);
                   6563: GEN_VXFORM(vsumsws, 4, 30);
                   6564: GEN_VXFORM(vaddfp, 5, 0);
                   6565: GEN_VXFORM(vsubfp, 5, 1);
                   6566: GEN_VXFORM(vmaxfp, 5, 16);
                   6567: GEN_VXFORM(vminfp, 5, 17);
                   6568: 
                   6569: #define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
1.1.1.7   root     6570: static void glue(gen_, name)(DisasContext *ctx)                         \
1.1.1.6   root     6571:     {                                                                   \
                   6572:         TCGv_ptr ra, rb, rd;                                            \
                   6573:         if (unlikely(!ctx->altivec_enabled)) {                          \
                   6574:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
                   6575:             return;                                                     \
                   6576:         }                                                               \
                   6577:         ra = gen_avr_ptr(rA(ctx->opcode));                              \
                   6578:         rb = gen_avr_ptr(rB(ctx->opcode));                              \
                   6579:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
                   6580:         gen_helper_##opname (rd, ra, rb);                               \
                   6581:         tcg_temp_free_ptr(ra);                                          \
                   6582:         tcg_temp_free_ptr(rb);                                          \
                   6583:         tcg_temp_free_ptr(rd);                                          \
                   6584:     }
                   6585: 
                   6586: #define GEN_VXRFORM(name, opc2, opc3)                                \
                   6587:     GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
                   6588:     GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
                   6589: 
                   6590: GEN_VXRFORM(vcmpequb, 3, 0)
                   6591: GEN_VXRFORM(vcmpequh, 3, 1)
                   6592: GEN_VXRFORM(vcmpequw, 3, 2)
                   6593: GEN_VXRFORM(vcmpgtsb, 3, 12)
                   6594: GEN_VXRFORM(vcmpgtsh, 3, 13)
                   6595: GEN_VXRFORM(vcmpgtsw, 3, 14)
                   6596: GEN_VXRFORM(vcmpgtub, 3, 8)
                   6597: GEN_VXRFORM(vcmpgtuh, 3, 9)
                   6598: GEN_VXRFORM(vcmpgtuw, 3, 10)
                   6599: GEN_VXRFORM(vcmpeqfp, 3, 3)
                   6600: GEN_VXRFORM(vcmpgefp, 3, 7)
                   6601: GEN_VXRFORM(vcmpgtfp, 3, 11)
                   6602: GEN_VXRFORM(vcmpbfp, 3, 15)
                   6603: 
                   6604: #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
1.1.1.7   root     6605: static void glue(gen_, name)(DisasContext *ctx)                         \
1.1.1.6   root     6606:     {                                                                   \
                   6607:         TCGv_ptr rd;                                                    \
                   6608:         TCGv_i32 simm;                                                  \
                   6609:         if (unlikely(!ctx->altivec_enabled)) {                          \
                   6610:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
                   6611:             return;                                                     \
                   6612:         }                                                               \
                   6613:         simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
                   6614:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
                   6615:         gen_helper_##name (rd, simm);                                   \
                   6616:         tcg_temp_free_i32(simm);                                        \
                   6617:         tcg_temp_free_ptr(rd);                                          \
                   6618:     }
                   6619: 
                   6620: GEN_VXFORM_SIMM(vspltisb, 6, 12);
                   6621: GEN_VXFORM_SIMM(vspltish, 6, 13);
                   6622: GEN_VXFORM_SIMM(vspltisw, 6, 14);
                   6623: 
                   6624: #define GEN_VXFORM_NOA(name, opc2, opc3)                                \
1.1.1.7   root     6625: static void glue(gen_, name)(DisasContext *ctx)                                 \
1.1.1.6   root     6626:     {                                                                   \
                   6627:         TCGv_ptr rb, rd;                                                \
                   6628:         if (unlikely(!ctx->altivec_enabled)) {                          \
                   6629:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
                   6630:             return;                                                     \
                   6631:         }                                                               \
                   6632:         rb = gen_avr_ptr(rB(ctx->opcode));                              \
                   6633:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
                   6634:         gen_helper_##name (rd, rb);                                     \
                   6635:         tcg_temp_free_ptr(rb);                                          \
                   6636:         tcg_temp_free_ptr(rd);                                         \
                   6637:     }
                   6638: 
                   6639: GEN_VXFORM_NOA(vupkhsb, 7, 8);
                   6640: GEN_VXFORM_NOA(vupkhsh, 7, 9);
                   6641: GEN_VXFORM_NOA(vupklsb, 7, 10);
                   6642: GEN_VXFORM_NOA(vupklsh, 7, 11);
                   6643: GEN_VXFORM_NOA(vupkhpx, 7, 13);
                   6644: GEN_VXFORM_NOA(vupklpx, 7, 15);
                   6645: GEN_VXFORM_NOA(vrefp, 5, 4);
                   6646: GEN_VXFORM_NOA(vrsqrtefp, 5, 5);
1.1.1.9   root     6647: GEN_VXFORM_NOA(vexptefp, 5, 6);
1.1.1.6   root     6648: GEN_VXFORM_NOA(vlogefp, 5, 7);
                   6649: GEN_VXFORM_NOA(vrfim, 5, 8);
                   6650: GEN_VXFORM_NOA(vrfin, 5, 9);
                   6651: GEN_VXFORM_NOA(vrfip, 5, 10);
                   6652: GEN_VXFORM_NOA(vrfiz, 5, 11);
                   6653: 
                   6654: #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
1.1.1.7   root     6655: static void glue(gen_, name)(DisasContext *ctx)                                 \
1.1.1.6   root     6656:     {                                                                   \
                   6657:         TCGv_ptr rd;                                                    \
                   6658:         TCGv_i32 simm;                                                  \
                   6659:         if (unlikely(!ctx->altivec_enabled)) {                          \
                   6660:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
                   6661:             return;                                                     \
                   6662:         }                                                               \
                   6663:         simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
                   6664:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
                   6665:         gen_helper_##name (rd, simm);                                   \
                   6666:         tcg_temp_free_i32(simm);                                        \
                   6667:         tcg_temp_free_ptr(rd);                                          \
                   6668:     }
                   6669: 
                   6670: #define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
1.1.1.7   root     6671: static void glue(gen_, name)(DisasContext *ctx)                                 \
1.1.1.6   root     6672:     {                                                                   \
                   6673:         TCGv_ptr rb, rd;                                                \
                   6674:         TCGv_i32 uimm;                                                  \
                   6675:         if (unlikely(!ctx->altivec_enabled)) {                          \
                   6676:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
                   6677:             return;                                                     \
                   6678:         }                                                               \
                   6679:         uimm = tcg_const_i32(UIMM5(ctx->opcode));                       \
                   6680:         rb = gen_avr_ptr(rB(ctx->opcode));                              \
                   6681:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
                   6682:         gen_helper_##name (rd, rb, uimm);                               \
                   6683:         tcg_temp_free_i32(uimm);                                        \
                   6684:         tcg_temp_free_ptr(rb);                                          \
                   6685:         tcg_temp_free_ptr(rd);                                          \
                   6686:     }
                   6687: 
                   6688: GEN_VXFORM_UIMM(vspltb, 6, 8);
                   6689: GEN_VXFORM_UIMM(vsplth, 6, 9);
                   6690: GEN_VXFORM_UIMM(vspltw, 6, 10);
                   6691: GEN_VXFORM_UIMM(vcfux, 5, 12);
                   6692: GEN_VXFORM_UIMM(vcfsx, 5, 13);
                   6693: GEN_VXFORM_UIMM(vctuxs, 5, 14);
                   6694: GEN_VXFORM_UIMM(vctsxs, 5, 15);
                   6695: 
1.1.1.7   root     6696: static void gen_vsldoi(DisasContext *ctx)
1.1.1.6   root     6697: {
                   6698:     TCGv_ptr ra, rb, rd;
                   6699:     TCGv_i32 sh;
                   6700:     if (unlikely(!ctx->altivec_enabled)) {
                   6701:         gen_exception(ctx, POWERPC_EXCP_VPU);
                   6702:         return;
                   6703:     }
                   6704:     ra = gen_avr_ptr(rA(ctx->opcode));
                   6705:     rb = gen_avr_ptr(rB(ctx->opcode));
                   6706:     rd = gen_avr_ptr(rD(ctx->opcode));
                   6707:     sh = tcg_const_i32(VSH(ctx->opcode));
                   6708:     gen_helper_vsldoi (rd, ra, rb, sh);
                   6709:     tcg_temp_free_ptr(ra);
                   6710:     tcg_temp_free_ptr(rb);
                   6711:     tcg_temp_free_ptr(rd);
                   6712:     tcg_temp_free_i32(sh);
                   6713: }
                   6714: 
                   6715: #define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
1.1.1.7   root     6716: static void glue(gen_, name0##_##name1)(DisasContext *ctx)                      \
1.1.1.6   root     6717:     {                                                                   \
                   6718:         TCGv_ptr ra, rb, rc, rd;                                        \
                   6719:         if (unlikely(!ctx->altivec_enabled)) {                          \
                   6720:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
                   6721:             return;                                                     \
                   6722:         }                                                               \
                   6723:         ra = gen_avr_ptr(rA(ctx->opcode));                              \
                   6724:         rb = gen_avr_ptr(rB(ctx->opcode));                              \
                   6725:         rc = gen_avr_ptr(rC(ctx->opcode));                              \
                   6726:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
                   6727:         if (Rc(ctx->opcode)) {                                          \
                   6728:             gen_helper_##name1 (rd, ra, rb, rc);                        \
                   6729:         } else {                                                        \
                   6730:             gen_helper_##name0 (rd, ra, rb, rc);                        \
                   6731:         }                                                               \
                   6732:         tcg_temp_free_ptr(ra);                                          \
                   6733:         tcg_temp_free_ptr(rb);                                          \
                   6734:         tcg_temp_free_ptr(rc);                                          \
                   6735:         tcg_temp_free_ptr(rd);                                          \
                   6736:     }
                   6737: 
                   6738: GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16)
                   6739: 
1.1.1.7   root     6740: static void gen_vmladduhm(DisasContext *ctx)
1.1.1.6   root     6741: {
                   6742:     TCGv_ptr ra, rb, rc, rd;
                   6743:     if (unlikely(!ctx->altivec_enabled)) {
                   6744:         gen_exception(ctx, POWERPC_EXCP_VPU);
                   6745:         return;
                   6746:     }
                   6747:     ra = gen_avr_ptr(rA(ctx->opcode));
                   6748:     rb = gen_avr_ptr(rB(ctx->opcode));
                   6749:     rc = gen_avr_ptr(rC(ctx->opcode));
                   6750:     rd = gen_avr_ptr(rD(ctx->opcode));
                   6751:     gen_helper_vmladduhm(rd, ra, rb, rc);
                   6752:     tcg_temp_free_ptr(ra);
                   6753:     tcg_temp_free_ptr(rb);
                   6754:     tcg_temp_free_ptr(rc);
                   6755:     tcg_temp_free_ptr(rd);
                   6756: }
                   6757: 
                   6758: GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18)
                   6759: GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19)
                   6760: GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20)
                   6761: GEN_VAFORM_PAIRED(vsel, vperm, 21)
                   6762: GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23)
1.1.1.5   root     6763: 
                   6764: /***                           SPE extension                               ***/
                   6765: /* Register moves */
                   6766: 
1.1.1.11  root     6767: 
                   6768: static inline void gen_evmra(DisasContext *ctx)
                   6769: {
                   6770: 
                   6771:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     6772:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.11  root     6773:         return;
                   6774:     }
                   6775: 
                   6776: #if defined(TARGET_PPC64)
                   6777:     /* rD := rA */
                   6778:     tcg_gen_mov_i64(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   6779: 
                   6780:     /* spe_acc := rA */
                   6781:     tcg_gen_st_i64(cpu_gpr[rA(ctx->opcode)],
                   6782:                    cpu_env,
1.1.1.13! root     6783:                    offsetof(CPUPPCState, spe_acc));
1.1.1.11  root     6784: #else
                   6785:     TCGv_i64 tmp = tcg_temp_new_i64();
                   6786: 
                   6787:     /* tmp := rA_lo + rA_hi << 32 */
                   6788:     tcg_gen_concat_i32_i64(tmp, cpu_gpr[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
                   6789: 
                   6790:     /* spe_acc := tmp */
1.1.1.13! root     6791:     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
1.1.1.11  root     6792:     tcg_temp_free_i64(tmp);
                   6793: 
                   6794:     /* rD := rA */
                   6795:     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   6796:     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
                   6797: #endif
                   6798: }
                   6799: 
1.1.1.8   root     6800: static inline void gen_load_gpr64(TCGv_i64 t, int reg)
                   6801: {
1.1.1.6   root     6802: #if defined(TARGET_PPC64)
                   6803:     tcg_gen_mov_i64(t, cpu_gpr[reg]);
                   6804: #else
                   6805:     tcg_gen_concat_i32_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
1.1.1.5   root     6806: #endif
1.1.1.6   root     6807: }
1.1.1.5   root     6808: 
1.1.1.8   root     6809: static inline void gen_store_gpr64(int reg, TCGv_i64 t)
                   6810: {
1.1.1.6   root     6811: #if defined(TARGET_PPC64)
                   6812:     tcg_gen_mov_i64(cpu_gpr[reg], t);
                   6813: #else
                   6814:     TCGv_i64 tmp = tcg_temp_new_i64();
                   6815:     tcg_gen_trunc_i64_i32(cpu_gpr[reg], t);
                   6816:     tcg_gen_shri_i64(tmp, t, 32);
                   6817:     tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp);
                   6818:     tcg_temp_free_i64(tmp);
1.1.1.5   root     6819: #endif
1.1.1.6   root     6820: }
1.1.1.5   root     6821: 
1.1.1.12  root     6822: #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type)         \
1.1.1.7   root     6823: static void glue(gen_, name0##_##name1)(DisasContext *ctx)                    \
1.1.1.5   root     6824: {                                                                             \
                   6825:     if (Rc(ctx->opcode))                                                      \
                   6826:         gen_##name1(ctx);                                                     \
                   6827:     else                                                                      \
                   6828:         gen_##name0(ctx);                                                     \
                   6829: }
                   6830: 
                   6831: /* Handler for undefined SPE opcodes */
1.1.1.8   root     6832: static inline void gen_speundef(DisasContext *ctx)
1.1       root     6833: {
1.1.1.6   root     6834:     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     6835: }
                   6836: 
1.1.1.6   root     6837: /* SPE logic */
                   6838: #if defined(TARGET_PPC64)
                   6839: #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
1.1.1.8   root     6840: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     6841: {                                                                             \
                   6842:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     6843:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     6844:         return;                                                               \
                   6845:     }                                                                         \
                   6846:     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
                   6847:            cpu_gpr[rB(ctx->opcode)]);                                         \
                   6848: }
                   6849: #else
                   6850: #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
1.1.1.8   root     6851: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     6852: {                                                                             \
                   6853:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     6854:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     6855:         return;                                                               \
                   6856:     }                                                                         \
                   6857:     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
                   6858:            cpu_gpr[rB(ctx->opcode)]);                                         \
                   6859:     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
                   6860:            cpu_gprh[rB(ctx->opcode)]);                                        \
1.1.1.5   root     6861: }
1.1.1.6   root     6862: #endif
1.1.1.5   root     6863: 
1.1.1.6   root     6864: GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl);
                   6865: GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl);
                   6866: GEN_SPEOP_LOGIC2(evxor, tcg_gen_xor_tl);
                   6867: GEN_SPEOP_LOGIC2(evor, tcg_gen_or_tl);
                   6868: GEN_SPEOP_LOGIC2(evnor, tcg_gen_nor_tl);
                   6869: GEN_SPEOP_LOGIC2(eveqv, tcg_gen_eqv_tl);
                   6870: GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl);
                   6871: GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
1.1.1.5   root     6872: 
1.1.1.6   root     6873: /* SPE logic immediate */
                   6874: #if defined(TARGET_PPC64)
                   6875: #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
1.1.1.8   root     6876: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     6877: {                                                                             \
                   6878:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     6879:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     6880:         return;                                                               \
                   6881:     }                                                                         \
1.1.1.6   root     6882:     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
                   6883:     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
                   6884:     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
                   6885:     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
                   6886:     tcg_opi(t0, t0, rB(ctx->opcode));                                         \
                   6887:     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
                   6888:     tcg_gen_trunc_i64_i32(t1, t2);                                            \
                   6889:     tcg_temp_free_i64(t2);                                                    \
                   6890:     tcg_opi(t1, t1, rB(ctx->opcode));                                         \
                   6891:     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
                   6892:     tcg_temp_free_i32(t0);                                                    \
                   6893:     tcg_temp_free_i32(t1);                                                    \
1.1.1.5   root     6894: }
1.1.1.6   root     6895: #else
                   6896: #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
1.1.1.8   root     6897: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     6898: {                                                                             \
                   6899:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     6900:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     6901:         return;                                                               \
                   6902:     }                                                                         \
1.1.1.6   root     6903:     tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],               \
                   6904:             rB(ctx->opcode));                                                 \
                   6905:     tcg_opi(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],             \
                   6906:             rB(ctx->opcode));                                                 \
1.1.1.5   root     6907: }
1.1.1.6   root     6908: #endif
                   6909: GEN_SPEOP_TCG_LOGIC_IMM2(evslwi, tcg_gen_shli_i32);
                   6910: GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu, tcg_gen_shri_i32);
                   6911: GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis, tcg_gen_sari_i32);
                   6912: GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32);
1.1.1.5   root     6913: 
1.1.1.6   root     6914: /* SPE arithmetic */
                   6915: #if defined(TARGET_PPC64)
                   6916: #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
1.1.1.8   root     6917: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     6918: {                                                                             \
                   6919:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     6920:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     6921:         return;                                                               \
                   6922:     }                                                                         \
1.1.1.6   root     6923:     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
                   6924:     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
                   6925:     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
                   6926:     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
                   6927:     tcg_op(t0, t0);                                                           \
                   6928:     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
                   6929:     tcg_gen_trunc_i64_i32(t1, t2);                                            \
                   6930:     tcg_temp_free_i64(t2);                                                    \
                   6931:     tcg_op(t1, t1);                                                           \
                   6932:     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
                   6933:     tcg_temp_free_i32(t0);                                                    \
                   6934:     tcg_temp_free_i32(t1);                                                    \
1.1.1.5   root     6935: }
1.1.1.6   root     6936: #else
                   6937: #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
1.1.1.8   root     6938: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     6939: {                                                                             \
                   6940:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     6941:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     6942:         return;                                                               \
                   6943:     }                                                                         \
1.1.1.6   root     6944:     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);               \
                   6945:     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);             \
1.1.1.5   root     6946: }
1.1.1.6   root     6947: #endif
1.1.1.5   root     6948: 
1.1.1.8   root     6949: static inline void gen_op_evabs(TCGv_i32 ret, TCGv_i32 arg1)
1.1.1.6   root     6950: {
                   6951:     int l1 = gen_new_label();
                   6952:     int l2 = gen_new_label();
1.1.1.5   root     6953: 
1.1.1.6   root     6954:     tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
                   6955:     tcg_gen_neg_i32(ret, arg1);
                   6956:     tcg_gen_br(l2);
                   6957:     gen_set_label(l1);
                   6958:     tcg_gen_mov_i32(ret, arg1);
                   6959:     gen_set_label(l2);
                   6960: }
                   6961: GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
                   6962: GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
                   6963: GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
                   6964: GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
1.1.1.8   root     6965: static inline void gen_op_evrndw(TCGv_i32 ret, TCGv_i32 arg1)
1.1.1.6   root     6966: {
                   6967:     tcg_gen_addi_i32(ret, arg1, 0x8000);
                   6968:     tcg_gen_ext16u_i32(ret, ret);
                   6969: }
                   6970: GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw);
                   6971: GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32);
                   6972: GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
1.1.1.5   root     6973: 
1.1.1.6   root     6974: #if defined(TARGET_PPC64)
                   6975: #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
1.1.1.8   root     6976: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     6977: {                                                                             \
                   6978:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     6979:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     6980:         return;                                                               \
                   6981:     }                                                                         \
1.1.1.6   root     6982:     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
                   6983:     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
                   6984:     TCGv_i32 t2 = tcg_temp_local_new_i32();                                   \
                   6985:     TCGv_i64 t3 = tcg_temp_local_new_i64();                                   \
                   6986:     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
                   6987:     tcg_gen_trunc_i64_i32(t2, cpu_gpr[rB(ctx->opcode)]);                      \
                   6988:     tcg_op(t0, t0, t2);                                                       \
                   6989:     tcg_gen_shri_i64(t3, cpu_gpr[rA(ctx->opcode)], 32);                       \
                   6990:     tcg_gen_trunc_i64_i32(t1, t3);                                            \
                   6991:     tcg_gen_shri_i64(t3, cpu_gpr[rB(ctx->opcode)], 32);                       \
                   6992:     tcg_gen_trunc_i64_i32(t2, t3);                                            \
                   6993:     tcg_temp_free_i64(t3);                                                    \
                   6994:     tcg_op(t1, t1, t2);                                                       \
                   6995:     tcg_temp_free_i32(t2);                                                    \
                   6996:     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
                   6997:     tcg_temp_free_i32(t0);                                                    \
                   6998:     tcg_temp_free_i32(t1);                                                    \
1.1.1.5   root     6999: }
1.1.1.6   root     7000: #else
                   7001: #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
1.1.1.8   root     7002: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     7003: {                                                                             \
                   7004:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     7005:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     7006:         return;                                                               \
                   7007:     }                                                                         \
1.1.1.6   root     7008:     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
                   7009:            cpu_gpr[rB(ctx->opcode)]);                                         \
                   7010:     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
                   7011:            cpu_gprh[rB(ctx->opcode)]);                                        \
                   7012: }
                   7013: #endif
                   7014: 
1.1.1.8   root     7015: static inline void gen_op_evsrwu(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1.1.1.6   root     7016: {
                   7017:     TCGv_i32 t0;
                   7018:     int l1, l2;
                   7019: 
                   7020:     l1 = gen_new_label();
                   7021:     l2 = gen_new_label();
                   7022:     t0 = tcg_temp_local_new_i32();
                   7023:     /* No error here: 6 bits are used */
                   7024:     tcg_gen_andi_i32(t0, arg2, 0x3F);
                   7025:     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
                   7026:     tcg_gen_shr_i32(ret, arg1, t0);
                   7027:     tcg_gen_br(l2);
                   7028:     gen_set_label(l1);
                   7029:     tcg_gen_movi_i32(ret, 0);
1.1.1.9   root     7030:     gen_set_label(l2);
1.1.1.6   root     7031:     tcg_temp_free_i32(t0);
                   7032: }
                   7033: GEN_SPEOP_ARITH2(evsrwu, gen_op_evsrwu);
1.1.1.8   root     7034: static inline void gen_op_evsrws(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1.1.1.6   root     7035: {
                   7036:     TCGv_i32 t0;
                   7037:     int l1, l2;
                   7038: 
                   7039:     l1 = gen_new_label();
                   7040:     l2 = gen_new_label();
                   7041:     t0 = tcg_temp_local_new_i32();
                   7042:     /* No error here: 6 bits are used */
                   7043:     tcg_gen_andi_i32(t0, arg2, 0x3F);
                   7044:     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
                   7045:     tcg_gen_sar_i32(ret, arg1, t0);
                   7046:     tcg_gen_br(l2);
                   7047:     gen_set_label(l1);
                   7048:     tcg_gen_movi_i32(ret, 0);
1.1.1.9   root     7049:     gen_set_label(l2);
1.1.1.6   root     7050:     tcg_temp_free_i32(t0);
                   7051: }
                   7052: GEN_SPEOP_ARITH2(evsrws, gen_op_evsrws);
1.1.1.8   root     7053: static inline void gen_op_evslw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1.1.1.6   root     7054: {
                   7055:     TCGv_i32 t0;
                   7056:     int l1, l2;
                   7057: 
                   7058:     l1 = gen_new_label();
                   7059:     l2 = gen_new_label();
                   7060:     t0 = tcg_temp_local_new_i32();
                   7061:     /* No error here: 6 bits are used */
                   7062:     tcg_gen_andi_i32(t0, arg2, 0x3F);
                   7063:     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
                   7064:     tcg_gen_shl_i32(ret, arg1, t0);
                   7065:     tcg_gen_br(l2);
                   7066:     gen_set_label(l1);
                   7067:     tcg_gen_movi_i32(ret, 0);
1.1.1.9   root     7068:     gen_set_label(l2);
1.1.1.6   root     7069:     tcg_temp_free_i32(t0);
                   7070: }
                   7071: GEN_SPEOP_ARITH2(evslw, gen_op_evslw);
1.1.1.8   root     7072: static inline void gen_op_evrlw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1.1.1.6   root     7073: {
                   7074:     TCGv_i32 t0 = tcg_temp_new_i32();
                   7075:     tcg_gen_andi_i32(t0, arg2, 0x1F);
                   7076:     tcg_gen_rotl_i32(ret, arg1, t0);
                   7077:     tcg_temp_free_i32(t0);
                   7078: }
                   7079: GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
1.1.1.8   root     7080: static inline void gen_evmergehi(DisasContext *ctx)
1.1.1.6   root     7081: {
                   7082:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     7083:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     7084:         return;
                   7085:     }
                   7086: #if defined(TARGET_PPC64)
                   7087:     TCGv t0 = tcg_temp_new();
                   7088:     TCGv t1 = tcg_temp_new();
                   7089:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
                   7090:     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
                   7091:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
                   7092:     tcg_temp_free(t0);
                   7093:     tcg_temp_free(t1);
                   7094: #else
                   7095:     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
                   7096:     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
                   7097: #endif
                   7098: }
                   7099: GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32);
1.1.1.8   root     7100: static inline void gen_op_evsubf(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1.1.1.6   root     7101: {
                   7102:     tcg_gen_sub_i32(ret, arg2, arg1);
1.1.1.5   root     7103: }
1.1.1.6   root     7104: GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
1.1.1.5   root     7105: 
1.1.1.6   root     7106: /* SPE arithmetic immediate */
                   7107: #if defined(TARGET_PPC64)
                   7108: #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
1.1.1.8   root     7109: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     7110: {                                                                             \
                   7111:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     7112:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     7113:         return;                                                               \
                   7114:     }                                                                         \
1.1.1.6   root     7115:     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
                   7116:     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
                   7117:     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
                   7118:     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rB(ctx->opcode)]);                      \
                   7119:     tcg_op(t0, t0, rA(ctx->opcode));                                          \
                   7120:     tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
                   7121:     tcg_gen_trunc_i64_i32(t1, t2);                                            \
                   7122:     tcg_temp_free_i64(t2);                                                    \
                   7123:     tcg_op(t1, t1, rA(ctx->opcode));                                          \
                   7124:     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
                   7125:     tcg_temp_free_i32(t0);                                                    \
                   7126:     tcg_temp_free_i32(t1);                                                    \
1.1       root     7127: }
1.1.1.6   root     7128: #else
                   7129: #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
1.1.1.8   root     7130: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     7131: {                                                                             \
                   7132:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     7133:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     7134:         return;                                                               \
                   7135:     }                                                                         \
1.1.1.6   root     7136:     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],                \
                   7137:            rA(ctx->opcode));                                                  \
                   7138:     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)],              \
                   7139:            rA(ctx->opcode));                                                  \
1.1.1.5   root     7140: }
1.1.1.6   root     7141: #endif
                   7142: GEN_SPEOP_ARITH_IMM2(evaddiw, tcg_gen_addi_i32);
                   7143: GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32);
1.1.1.5   root     7144: 
1.1.1.6   root     7145: /* SPE comparison */
                   7146: #if defined(TARGET_PPC64)
                   7147: #define GEN_SPEOP_COMP(name, tcg_cond)                                        \
1.1.1.8   root     7148: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     7149: {                                                                             \
                   7150:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     7151:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     7152:         return;                                                               \
                   7153:     }                                                                         \
                   7154:     int l1 = gen_new_label();                                                 \
                   7155:     int l2 = gen_new_label();                                                 \
                   7156:     int l3 = gen_new_label();                                                 \
                   7157:     int l4 = gen_new_label();                                                 \
                   7158:     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
                   7159:     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
                   7160:     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
                   7161:     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
                   7162:     tcg_gen_trunc_i64_i32(t1, cpu_gpr[rB(ctx->opcode)]);                      \
                   7163:     tcg_gen_brcond_i32(tcg_cond, t0, t1, l1);                                 \
                   7164:     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0);                          \
                   7165:     tcg_gen_br(l2);                                                           \
                   7166:     gen_set_label(l1);                                                        \
                   7167:     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
                   7168:                      CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
                   7169:     gen_set_label(l2);                                                        \
                   7170:     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
                   7171:     tcg_gen_trunc_i64_i32(t0, t2);                                            \
                   7172:     tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
                   7173:     tcg_gen_trunc_i64_i32(t1, t2);                                            \
                   7174:     tcg_temp_free_i64(t2);                                                    \
                   7175:     tcg_gen_brcond_i32(tcg_cond, t0, t1, l3);                                 \
                   7176:     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
                   7177:                      ~(CRF_CH | CRF_CH_AND_CL));                              \
                   7178:     tcg_gen_br(l4);                                                           \
                   7179:     gen_set_label(l3);                                                        \
                   7180:     tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
                   7181:                     CRF_CH | CRF_CH_OR_CL);                                   \
                   7182:     gen_set_label(l4);                                                        \
                   7183:     tcg_temp_free_i32(t0);                                                    \
                   7184:     tcg_temp_free_i32(t1);                                                    \
                   7185: }
                   7186: #else
                   7187: #define GEN_SPEOP_COMP(name, tcg_cond)                                        \
1.1.1.8   root     7188: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     7189: {                                                                             \
                   7190:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     7191:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     7192:         return;                                                               \
                   7193:     }                                                                         \
1.1.1.6   root     7194:     int l1 = gen_new_label();                                                 \
                   7195:     int l2 = gen_new_label();                                                 \
                   7196:     int l3 = gen_new_label();                                                 \
                   7197:     int l4 = gen_new_label();                                                 \
                   7198:                                                                               \
                   7199:     tcg_gen_brcond_i32(tcg_cond, cpu_gpr[rA(ctx->opcode)],                    \
                   7200:                        cpu_gpr[rB(ctx->opcode)], l1);                         \
                   7201:     tcg_gen_movi_tl(cpu_crf[crfD(ctx->opcode)], 0);                           \
                   7202:     tcg_gen_br(l2);                                                           \
                   7203:     gen_set_label(l1);                                                        \
                   7204:     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
                   7205:                      CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
                   7206:     gen_set_label(l2);                                                        \
                   7207:     tcg_gen_brcond_i32(tcg_cond, cpu_gprh[rA(ctx->opcode)],                   \
                   7208:                        cpu_gprh[rB(ctx->opcode)], l3);                        \
                   7209:     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
                   7210:                      ~(CRF_CH | CRF_CH_AND_CL));                              \
                   7211:     tcg_gen_br(l4);                                                           \
                   7212:     gen_set_label(l3);                                                        \
                   7213:     tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
                   7214:                     CRF_CH | CRF_CH_OR_CL);                                   \
                   7215:     gen_set_label(l4);                                                        \
                   7216: }
                   7217: #endif
                   7218: GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU);
                   7219: GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT);
                   7220: GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU);
                   7221: GEN_SPEOP_COMP(evcmplts, TCG_COND_LT);
                   7222: GEN_SPEOP_COMP(evcmpeq, TCG_COND_EQ);
1.1.1.5   root     7223: 
1.1.1.6   root     7224: /* SPE misc */
1.1.1.8   root     7225: static inline void gen_brinc(DisasContext *ctx)
1.1.1.6   root     7226: {
                   7227:     /* Note: brinc is usable even if SPE is disabled */
                   7228:     gen_helper_brinc(cpu_gpr[rD(ctx->opcode)],
                   7229:                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   7230: }
1.1.1.8   root     7231: static inline void gen_evmergelo(DisasContext *ctx)
1.1.1.6   root     7232: {
                   7233:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     7234:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     7235:         return;
                   7236:     }
                   7237: #if defined(TARGET_PPC64)
                   7238:     TCGv t0 = tcg_temp_new();
                   7239:     TCGv t1 = tcg_temp_new();
1.1.1.11  root     7240:     tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
1.1.1.6   root     7241:     tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
                   7242:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
                   7243:     tcg_temp_free(t0);
                   7244:     tcg_temp_free(t1);
                   7245: #else
                   7246:     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.7   root     7247:     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1.1.1.6   root     7248: #endif
                   7249: }
1.1.1.8   root     7250: static inline void gen_evmergehilo(DisasContext *ctx)
1.1.1.6   root     7251: {
                   7252:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     7253:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     7254:         return;
                   7255:     }
                   7256: #if defined(TARGET_PPC64)
                   7257:     TCGv t0 = tcg_temp_new();
                   7258:     TCGv t1 = tcg_temp_new();
1.1.1.11  root     7259:     tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
1.1.1.6   root     7260:     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
                   7261:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
                   7262:     tcg_temp_free(t0);
                   7263:     tcg_temp_free(t1);
                   7264: #else
                   7265:     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   7266:     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
                   7267: #endif
                   7268: }
1.1.1.8   root     7269: static inline void gen_evmergelohi(DisasContext *ctx)
1.1.1.6   root     7270: {
                   7271:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     7272:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     7273:         return;
                   7274:     }
                   7275: #if defined(TARGET_PPC64)
                   7276:     TCGv t0 = tcg_temp_new();
                   7277:     TCGv t1 = tcg_temp_new();
                   7278:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
                   7279:     tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
                   7280:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
                   7281:     tcg_temp_free(t0);
                   7282:     tcg_temp_free(t1);
                   7283: #else
1.1.1.7   root     7284:     if (rD(ctx->opcode) == rA(ctx->opcode)) {
                   7285:         TCGv_i32 tmp = tcg_temp_new_i32();
                   7286:         tcg_gen_mov_i32(tmp, cpu_gpr[rA(ctx->opcode)]);
                   7287:         tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
                   7288:         tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], tmp);
                   7289:         tcg_temp_free_i32(tmp);
                   7290:     } else {
                   7291:         tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
                   7292:         tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   7293:     }
1.1.1.6   root     7294: #endif
                   7295: }
1.1.1.8   root     7296: static inline void gen_evsplati(DisasContext *ctx)
1.1.1.5   root     7297: {
1.1.1.9   root     7298:     uint64_t imm = ((int32_t)(rA(ctx->opcode) << 27)) >> 27;
1.1.1.5   root     7299: 
1.1.1.6   root     7300: #if defined(TARGET_PPC64)
                   7301:     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
                   7302: #else
                   7303:     tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
                   7304:     tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
                   7305: #endif
1.1.1.5   root     7306: }
1.1.1.8   root     7307: static inline void gen_evsplatfi(DisasContext *ctx)
1.1.1.5   root     7308: {
1.1.1.9   root     7309:     uint64_t imm = rA(ctx->opcode) << 27;
1.1.1.5   root     7310: 
1.1.1.6   root     7311: #if defined(TARGET_PPC64)
                   7312:     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
                   7313: #else
                   7314:     tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
                   7315:     tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
                   7316: #endif
1.1.1.5   root     7317: }
                   7318: 
1.1.1.8   root     7319: static inline void gen_evsel(DisasContext *ctx)
1.1.1.6   root     7320: {
                   7321:     int l1 = gen_new_label();
                   7322:     int l2 = gen_new_label();
                   7323:     int l3 = gen_new_label();
                   7324:     int l4 = gen_new_label();
                   7325:     TCGv_i32 t0 = tcg_temp_local_new_i32();
                   7326: #if defined(TARGET_PPC64)
                   7327:     TCGv t1 = tcg_temp_local_new();
                   7328:     TCGv t2 = tcg_temp_local_new();
                   7329: #endif
                   7330:     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);
                   7331:     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
                   7332: #if defined(TARGET_PPC64)
                   7333:     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF00000000ULL);
                   7334: #else
                   7335:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
                   7336: #endif
                   7337:     tcg_gen_br(l2);
                   7338:     gen_set_label(l1);
                   7339: #if defined(TARGET_PPC64)
                   7340:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0xFFFFFFFF00000000ULL);
                   7341: #else
                   7342:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
                   7343: #endif
                   7344:     gen_set_label(l2);
                   7345:     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2);
                   7346:     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3);
                   7347: #if defined(TARGET_PPC64)
1.1.1.11  root     7348:     tcg_gen_ext32u_tl(t2, cpu_gpr[rA(ctx->opcode)]);
1.1.1.6   root     7349: #else
                   7350:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   7351: #endif
                   7352:     tcg_gen_br(l4);
                   7353:     gen_set_label(l3);
                   7354: #if defined(TARGET_PPC64)
1.1.1.11  root     7355:     tcg_gen_ext32u_tl(t2, cpu_gpr[rB(ctx->opcode)]);
1.1.1.6   root     7356: #else
                   7357:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   7358: #endif
                   7359:     gen_set_label(l4);
                   7360:     tcg_temp_free_i32(t0);
                   7361: #if defined(TARGET_PPC64)
                   7362:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t1, t2);
                   7363:     tcg_temp_free(t1);
                   7364:     tcg_temp_free(t2);
                   7365: #endif
                   7366: }
1.1.1.7   root     7367: 
                   7368: static void gen_evsel0(DisasContext *ctx)
1.1.1.6   root     7369: {
                   7370:     gen_evsel(ctx);
                   7371: }
1.1.1.7   root     7372: 
                   7373: static void gen_evsel1(DisasContext *ctx)
1.1.1.6   root     7374: {
                   7375:     gen_evsel(ctx);
                   7376: }
1.1.1.7   root     7377: 
                   7378: static void gen_evsel2(DisasContext *ctx)
1.1.1.6   root     7379: {
                   7380:     gen_evsel(ctx);
                   7381: }
1.1.1.7   root     7382: 
                   7383: static void gen_evsel3(DisasContext *ctx)
1.1.1.6   root     7384: {
                   7385:     gen_evsel(ctx);
                   7386: }
1.1.1.5   root     7387: 
1.1.1.11  root     7388: /* Multiply */
                   7389: 
                   7390: static inline void gen_evmwumi(DisasContext *ctx)
                   7391: {
                   7392:     TCGv_i64 t0, t1;
                   7393: 
                   7394:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     7395:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.11  root     7396:         return;
                   7397:     }
                   7398: 
                   7399:     t0 = tcg_temp_new_i64();
                   7400:     t1 = tcg_temp_new_i64();
                   7401: 
                   7402:     /* t0 := rA; t1 := rB */
                   7403: #if defined(TARGET_PPC64)
                   7404:     tcg_gen_ext32u_tl(t0, cpu_gpr[rA(ctx->opcode)]);
                   7405:     tcg_gen_ext32u_tl(t1, cpu_gpr[rB(ctx->opcode)]);
                   7406: #else
                   7407:     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   7408:     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   7409: #endif
                   7410: 
                   7411:     tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */
                   7412: 
                   7413:     gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */
                   7414: 
                   7415:     tcg_temp_free_i64(t0);
                   7416:     tcg_temp_free_i64(t1);
                   7417: }
                   7418: 
                   7419: static inline void gen_evmwumia(DisasContext *ctx)
                   7420: {
                   7421:     TCGv_i64 tmp;
                   7422: 
                   7423:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     7424:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.11  root     7425:         return;
                   7426:     }
                   7427: 
                   7428:     gen_evmwumi(ctx);            /* rD := rA * rB */
                   7429: 
                   7430:     tmp = tcg_temp_new_i64();
                   7431: 
                   7432:     /* acc := rD */
                   7433:     gen_load_gpr64(tmp, rD(ctx->opcode));
1.1.1.13! root     7434:     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
1.1.1.11  root     7435:     tcg_temp_free_i64(tmp);
                   7436: }
                   7437: 
                   7438: static inline void gen_evmwumiaa(DisasContext *ctx)
                   7439: {
                   7440:     TCGv_i64 acc;
                   7441:     TCGv_i64 tmp;
                   7442: 
                   7443:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     7444:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.11  root     7445:         return;
                   7446:     }
                   7447: 
                   7448:     gen_evmwumi(ctx);           /* rD := rA * rB */
                   7449: 
                   7450:     acc = tcg_temp_new_i64();
                   7451:     tmp = tcg_temp_new_i64();
                   7452: 
                   7453:     /* tmp := rD */
                   7454:     gen_load_gpr64(tmp, rD(ctx->opcode));
                   7455: 
                   7456:     /* Load acc */
1.1.1.13! root     7457:     tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
1.1.1.11  root     7458: 
                   7459:     /* acc := tmp + acc */
                   7460:     tcg_gen_add_i64(acc, acc, tmp);
                   7461: 
                   7462:     /* Store acc */
1.1.1.13! root     7463:     tcg_gen_st_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
1.1.1.11  root     7464: 
                   7465:     /* rD := acc */
                   7466:     gen_store_gpr64(rD(ctx->opcode), acc);
                   7467: 
                   7468:     tcg_temp_free_i64(acc);
                   7469:     tcg_temp_free_i64(tmp);
                   7470: }
                   7471: 
                   7472: static inline void gen_evmwsmi(DisasContext *ctx)
                   7473: {
                   7474:     TCGv_i64 t0, t1;
                   7475: 
                   7476:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     7477:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.11  root     7478:         return;
                   7479:     }
                   7480: 
                   7481:     t0 = tcg_temp_new_i64();
                   7482:     t1 = tcg_temp_new_i64();
                   7483: 
                   7484:     /* t0 := rA; t1 := rB */
                   7485: #if defined(TARGET_PPC64)
                   7486:     tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
                   7487:     tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
                   7488: #else
                   7489:     tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   7490:     tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   7491: #endif
                   7492: 
                   7493:     tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */
                   7494: 
                   7495:     gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */
                   7496: 
                   7497:     tcg_temp_free_i64(t0);
                   7498:     tcg_temp_free_i64(t1);
                   7499: }
                   7500: 
                   7501: static inline void gen_evmwsmia(DisasContext *ctx)
                   7502: {
                   7503:     TCGv_i64 tmp;
                   7504: 
                   7505:     gen_evmwsmi(ctx);            /* rD := rA * rB */
                   7506: 
                   7507:     tmp = tcg_temp_new_i64();
                   7508: 
                   7509:     /* acc := rD */
                   7510:     gen_load_gpr64(tmp, rD(ctx->opcode));
1.1.1.13! root     7511:     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
1.1.1.11  root     7512: 
                   7513:     tcg_temp_free_i64(tmp);
                   7514: }
                   7515: 
                   7516: static inline void gen_evmwsmiaa(DisasContext *ctx)
                   7517: {
                   7518:     TCGv_i64 acc = tcg_temp_new_i64();
                   7519:     TCGv_i64 tmp = tcg_temp_new_i64();
                   7520: 
                   7521:     gen_evmwsmi(ctx);           /* rD := rA * rB */
                   7522: 
                   7523:     acc = tcg_temp_new_i64();
                   7524:     tmp = tcg_temp_new_i64();
                   7525: 
                   7526:     /* tmp := rD */
                   7527:     gen_load_gpr64(tmp, rD(ctx->opcode));
                   7528: 
                   7529:     /* Load acc */
1.1.1.13! root     7530:     tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
1.1.1.11  root     7531: 
                   7532:     /* acc := tmp + acc */
                   7533:     tcg_gen_add_i64(acc, acc, tmp);
                   7534: 
                   7535:     /* Store acc */
1.1.1.13! root     7536:     tcg_gen_st_i64(acc, cpu_env, offsetof(CPUPPCState, spe_acc));
1.1.1.11  root     7537: 
                   7538:     /* rD := acc */
                   7539:     gen_store_gpr64(rD(ctx->opcode), acc);
                   7540: 
                   7541:     tcg_temp_free_i64(acc);
                   7542:     tcg_temp_free_i64(tmp);
                   7543: }
                   7544: 
1.1.1.12  root     7545: GEN_SPE(evaddw,      speundef,    0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
                   7546: GEN_SPE(evaddiw,     speundef,    0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
                   7547: GEN_SPE(evsubfw,     speundef,    0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
                   7548: GEN_SPE(evsubifw,    speundef,    0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
                   7549: GEN_SPE(evabs,       evneg,       0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
                   7550: GEN_SPE(evextsb,     evextsh,     0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
                   7551: GEN_SPE(evrndw,      evcntlzw,    0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
                   7552: GEN_SPE(evcntlsw,    brinc,       0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE); //
                   7553: GEN_SPE(evmra,       speundef,    0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE);
                   7554: GEN_SPE(speundef,    evand,       0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE); ////
                   7555: GEN_SPE(evandc,      speundef,    0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
                   7556: GEN_SPE(evxor,       evor,        0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
                   7557: GEN_SPE(evnor,       eveqv,       0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
                   7558: GEN_SPE(evmwumi,     evmwsmi,     0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE);
                   7559: GEN_SPE(evmwumia,    evmwsmia,    0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE);
                   7560: GEN_SPE(evmwumiaa,   evmwsmiaa,   0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE);
                   7561: GEN_SPE(speundef,    evorc,       0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE); ////
                   7562: GEN_SPE(evnand,      speundef,    0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
                   7563: GEN_SPE(evsrwu,      evsrws,      0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
                   7564: GEN_SPE(evsrwiu,     evsrwis,     0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE);
                   7565: GEN_SPE(evslw,       speundef,    0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
                   7566: GEN_SPE(evslwi,      speundef,    0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
                   7567: GEN_SPE(evrlw,       evsplati,    0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE); //
                   7568: GEN_SPE(evrlwi,      evsplatfi,   0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE);
                   7569: GEN_SPE(evmergehi,   evmergelo,   0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
                   7570: GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
                   7571: GEN_SPE(evcmpgtu,    evcmpgts,    0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE); ////
                   7572: GEN_SPE(evcmpltu,    evcmplts,    0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE); ////
                   7573: GEN_SPE(evcmpeq,     speundef,    0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE); ////
1.1.1.5   root     7574: 
1.1.1.6   root     7575: /* SPE load and stores */
1.1.1.8   root     7576: static inline void gen_addr_spe_imm_index(DisasContext *ctx, TCGv EA, int sh)
1.1       root     7577: {
1.1.1.6   root     7578:     target_ulong uimm = rB(ctx->opcode);
                   7579: 
                   7580:     if (rA(ctx->opcode) == 0) {
                   7581:         tcg_gen_movi_tl(EA, uimm << sh);
                   7582:     } else {
                   7583:         tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], uimm << sh);
                   7584: #if defined(TARGET_PPC64)
                   7585:         if (!ctx->sf_mode) {
                   7586:             tcg_gen_ext32u_tl(EA, EA);
                   7587:         }
                   7588: #endif
1.1       root     7589:     }
1.1.1.5   root     7590: }
                   7591: 
1.1.1.8   root     7592: static inline void gen_op_evldd(DisasContext *ctx, TCGv addr)
1.1.1.5   root     7593: {
1.1.1.6   root     7594: #if defined(TARGET_PPC64)
                   7595:     gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], addr);
                   7596: #else
                   7597:     TCGv_i64 t0 = tcg_temp_new_i64();
                   7598:     gen_qemu_ld64(ctx, t0, addr);
                   7599:     tcg_gen_trunc_i64_i32(cpu_gpr[rD(ctx->opcode)], t0);
                   7600:     tcg_gen_shri_i64(t0, t0, 32);
                   7601:     tcg_gen_trunc_i64_i32(cpu_gprh[rD(ctx->opcode)], t0);
                   7602:     tcg_temp_free_i64(t0);
                   7603: #endif
1.1.1.5   root     7604: }
1.1.1.6   root     7605: 
1.1.1.8   root     7606: static inline void gen_op_evldw(DisasContext *ctx, TCGv addr)
1.1.1.5   root     7607: {
1.1.1.6   root     7608: #if defined(TARGET_PPC64)
                   7609:     TCGv t0 = tcg_temp_new();
                   7610:     gen_qemu_ld32u(ctx, t0, addr);
                   7611:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
                   7612:     gen_addr_add(ctx, addr, addr, 4);
                   7613:     gen_qemu_ld32u(ctx, t0, addr);
                   7614:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7615:     tcg_temp_free(t0);
                   7616: #else
                   7617:     gen_qemu_ld32u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
                   7618:     gen_addr_add(ctx, addr, addr, 4);
                   7619:     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
                   7620: #endif
1.1.1.5   root     7621: }
1.1.1.6   root     7622: 
1.1.1.8   root     7623: static inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
1.1.1.5   root     7624: {
1.1.1.6   root     7625:     TCGv t0 = tcg_temp_new();
                   7626: #if defined(TARGET_PPC64)
                   7627:     gen_qemu_ld16u(ctx, t0, addr);
                   7628:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
                   7629:     gen_addr_add(ctx, addr, addr, 2);
                   7630:     gen_qemu_ld16u(ctx, t0, addr);
                   7631:     tcg_gen_shli_tl(t0, t0, 32);
                   7632:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7633:     gen_addr_add(ctx, addr, addr, 2);
                   7634:     gen_qemu_ld16u(ctx, t0, addr);
                   7635:     tcg_gen_shli_tl(t0, t0, 16);
                   7636:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7637:     gen_addr_add(ctx, addr, addr, 2);
                   7638:     gen_qemu_ld16u(ctx, t0, addr);
                   7639:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7640: #else
                   7641:     gen_qemu_ld16u(ctx, t0, addr);
                   7642:     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
                   7643:     gen_addr_add(ctx, addr, addr, 2);
                   7644:     gen_qemu_ld16u(ctx, t0, addr);
                   7645:     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
                   7646:     gen_addr_add(ctx, addr, addr, 2);
                   7647:     gen_qemu_ld16u(ctx, t0, addr);
                   7648:     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
                   7649:     gen_addr_add(ctx, addr, addr, 2);
                   7650:     gen_qemu_ld16u(ctx, t0, addr);
                   7651:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7652: #endif
                   7653:     tcg_temp_free(t0);
1.1.1.5   root     7654: }
1.1.1.6   root     7655: 
1.1.1.8   root     7656: static inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr)
1.1.1.5   root     7657: {
1.1.1.6   root     7658:     TCGv t0 = tcg_temp_new();
                   7659:     gen_qemu_ld16u(ctx, t0, addr);
                   7660: #if defined(TARGET_PPC64)
                   7661:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
                   7662:     tcg_gen_shli_tl(t0, t0, 16);
                   7663:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7664: #else
                   7665:     tcg_gen_shli_tl(t0, t0, 16);
                   7666:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
                   7667:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   7668: #endif
                   7669:     tcg_temp_free(t0);
1.1.1.5   root     7670: }
                   7671: 
1.1.1.8   root     7672: static inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7673: {
                   7674:     TCGv t0 = tcg_temp_new();
                   7675:     gen_qemu_ld16u(ctx, t0, addr);
1.1.1.5   root     7676: #if defined(TARGET_PPC64)
1.1.1.6   root     7677:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
                   7678:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7679: #else
                   7680:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
                   7681:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   7682: #endif
                   7683:     tcg_temp_free(t0);
                   7684: }
                   7685: 
1.1.1.8   root     7686: static inline void gen_op_evlhhossplat(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7687: {
                   7688:     TCGv t0 = tcg_temp_new();
                   7689:     gen_qemu_ld16s(ctx, t0, addr);
                   7690: #if defined(TARGET_PPC64)
                   7691:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
                   7692:     tcg_gen_ext32u_tl(t0, t0);
                   7693:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7694: #else
                   7695:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
                   7696:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   7697: #endif
                   7698:     tcg_temp_free(t0);
                   7699: }
                   7700: 
1.1.1.8   root     7701: static inline void gen_op_evlwhe(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7702: {
                   7703:     TCGv t0 = tcg_temp_new();
                   7704: #if defined(TARGET_PPC64)
                   7705:     gen_qemu_ld16u(ctx, t0, addr);
                   7706:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
                   7707:     gen_addr_add(ctx, addr, addr, 2);
                   7708:     gen_qemu_ld16u(ctx, t0, addr);
                   7709:     tcg_gen_shli_tl(t0, t0, 16);
                   7710:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7711: #else
                   7712:     gen_qemu_ld16u(ctx, t0, addr);
                   7713:     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
                   7714:     gen_addr_add(ctx, addr, addr, 2);
                   7715:     gen_qemu_ld16u(ctx, t0, addr);
                   7716:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
                   7717: #endif
                   7718:     tcg_temp_free(t0);
                   7719: }
                   7720: 
1.1.1.8   root     7721: static inline void gen_op_evlwhou(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7722: {
                   7723: #if defined(TARGET_PPC64)
                   7724:     TCGv t0 = tcg_temp_new();
                   7725:     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
                   7726:     gen_addr_add(ctx, addr, addr, 2);
                   7727:     gen_qemu_ld16u(ctx, t0, addr);
                   7728:     tcg_gen_shli_tl(t0, t0, 32);
                   7729:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7730:     tcg_temp_free(t0);
                   7731: #else
                   7732:     gen_qemu_ld16u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
                   7733:     gen_addr_add(ctx, addr, addr, 2);
                   7734:     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
                   7735: #endif
                   7736: }
                   7737: 
1.1.1.8   root     7738: static inline void gen_op_evlwhos(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7739: {
                   7740: #if defined(TARGET_PPC64)
                   7741:     TCGv t0 = tcg_temp_new();
                   7742:     gen_qemu_ld16s(ctx, t0, addr);
                   7743:     tcg_gen_ext32u_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   7744:     gen_addr_add(ctx, addr, addr, 2);
                   7745:     gen_qemu_ld16s(ctx, t0, addr);
                   7746:     tcg_gen_shli_tl(t0, t0, 32);
                   7747:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7748:     tcg_temp_free(t0);
                   7749: #else
                   7750:     gen_qemu_ld16s(ctx, cpu_gprh[rD(ctx->opcode)], addr);
                   7751:     gen_addr_add(ctx, addr, addr, 2);
                   7752:     gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], addr);
                   7753: #endif
                   7754: }
                   7755: 
1.1.1.8   root     7756: static inline void gen_op_evlwwsplat(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7757: {
                   7758:     TCGv t0 = tcg_temp_new();
                   7759:     gen_qemu_ld32u(ctx, t0, addr);
                   7760: #if defined(TARGET_PPC64)
                   7761:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
                   7762:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7763: #else
                   7764:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
                   7765:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   7766: #endif
                   7767:     tcg_temp_free(t0);
                   7768: }
                   7769: 
1.1.1.8   root     7770: static inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7771: {
                   7772:     TCGv t0 = tcg_temp_new();
                   7773: #if defined(TARGET_PPC64)
                   7774:     gen_qemu_ld16u(ctx, t0, addr);
                   7775:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
                   7776:     tcg_gen_shli_tl(t0, t0, 32);
                   7777:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7778:     gen_addr_add(ctx, addr, addr, 2);
                   7779:     gen_qemu_ld16u(ctx, t0, addr);
                   7780:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7781:     tcg_gen_shli_tl(t0, t0, 16);
                   7782:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7783: #else
                   7784:     gen_qemu_ld16u(ctx, t0, addr);
                   7785:     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
                   7786:     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
                   7787:     gen_addr_add(ctx, addr, addr, 2);
                   7788:     gen_qemu_ld16u(ctx, t0, addr);
                   7789:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
                   7790:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
                   7791: #endif
                   7792:     tcg_temp_free(t0);
                   7793: }
                   7794: 
1.1.1.8   root     7795: static inline void gen_op_evstdd(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7796: {
                   7797: #if defined(TARGET_PPC64)
                   7798:     gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], addr);
                   7799: #else
                   7800:     TCGv_i64 t0 = tcg_temp_new_i64();
                   7801:     tcg_gen_concat_i32_i64(t0, cpu_gpr[rS(ctx->opcode)], cpu_gprh[rS(ctx->opcode)]);
                   7802:     gen_qemu_st64(ctx, t0, addr);
                   7803:     tcg_temp_free_i64(t0);
                   7804: #endif
                   7805: }
                   7806: 
1.1.1.8   root     7807: static inline void gen_op_evstdw(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7808: {
                   7809: #if defined(TARGET_PPC64)
                   7810:     TCGv t0 = tcg_temp_new();
                   7811:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
                   7812:     gen_qemu_st32(ctx, t0, addr);
                   7813:     tcg_temp_free(t0);
                   7814: #else
                   7815:     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
                   7816: #endif
                   7817:     gen_addr_add(ctx, addr, addr, 4);
                   7818:     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
1.1.1.5   root     7819: }
1.1.1.6   root     7820: 
1.1.1.8   root     7821: static inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7822: {
                   7823:     TCGv t0 = tcg_temp_new();
                   7824: #if defined(TARGET_PPC64)
                   7825:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
1.1.1.5   root     7826: #else
1.1.1.6   root     7827:     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
                   7828: #endif
                   7829:     gen_qemu_st16(ctx, t0, addr);
                   7830:     gen_addr_add(ctx, addr, addr, 2);
                   7831: #if defined(TARGET_PPC64)
                   7832:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
                   7833:     gen_qemu_st16(ctx, t0, addr);
                   7834: #else
                   7835:     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
                   7836: #endif
                   7837:     gen_addr_add(ctx, addr, addr, 2);
                   7838:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
                   7839:     gen_qemu_st16(ctx, t0, addr);
                   7840:     tcg_temp_free(t0);
                   7841:     gen_addr_add(ctx, addr, addr, 2);
                   7842:     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
                   7843: }
                   7844: 
1.1.1.8   root     7845: static inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7846: {
                   7847:     TCGv t0 = tcg_temp_new();
                   7848: #if defined(TARGET_PPC64)
                   7849:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
                   7850: #else
                   7851:     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
                   7852: #endif
                   7853:     gen_qemu_st16(ctx, t0, addr);
                   7854:     gen_addr_add(ctx, addr, addr, 2);
                   7855:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
                   7856:     gen_qemu_st16(ctx, t0, addr);
                   7857:     tcg_temp_free(t0);
                   7858: }
                   7859: 
1.1.1.8   root     7860: static inline void gen_op_evstwho(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7861: {
                   7862: #if defined(TARGET_PPC64)
                   7863:     TCGv t0 = tcg_temp_new();
                   7864:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
                   7865:     gen_qemu_st16(ctx, t0, addr);
                   7866:     tcg_temp_free(t0);
                   7867: #else
                   7868:     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
                   7869: #endif
                   7870:     gen_addr_add(ctx, addr, addr, 2);
                   7871:     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
                   7872: }
                   7873: 
1.1.1.8   root     7874: static inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7875: {
                   7876: #if defined(TARGET_PPC64)
                   7877:     TCGv t0 = tcg_temp_new();
                   7878:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
                   7879:     gen_qemu_st32(ctx, t0, addr);
                   7880:     tcg_temp_free(t0);
                   7881: #else
                   7882:     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
                   7883: #endif
                   7884: }
                   7885: 
1.1.1.8   root     7886: static inline void gen_op_evstwwo(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7887: {
                   7888:     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
                   7889: }
                   7890: 
                   7891: #define GEN_SPEOP_LDST(name, opc2, sh)                                        \
1.1.1.7   root     7892: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.6   root     7893: {                                                                             \
                   7894:     TCGv t0;                                                                  \
                   7895:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     7896:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     7897:         return;                                                               \
                   7898:     }                                                                         \
                   7899:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   7900:     t0 = tcg_temp_new();                                                      \
                   7901:     if (Rc(ctx->opcode)) {                                                    \
                   7902:         gen_addr_spe_imm_index(ctx, t0, sh);                                  \
                   7903:     } else {                                                                  \
                   7904:         gen_addr_reg_index(ctx, t0);                                          \
                   7905:     }                                                                         \
                   7906:     gen_op_##name(ctx, t0);                                                   \
                   7907:     tcg_temp_free(t0);                                                        \
                   7908: }
                   7909: 
                   7910: GEN_SPEOP_LDST(evldd, 0x00, 3);
                   7911: GEN_SPEOP_LDST(evldw, 0x01, 3);
                   7912: GEN_SPEOP_LDST(evldh, 0x02, 3);
                   7913: GEN_SPEOP_LDST(evlhhesplat, 0x04, 1);
                   7914: GEN_SPEOP_LDST(evlhhousplat, 0x06, 1);
                   7915: GEN_SPEOP_LDST(evlhhossplat, 0x07, 1);
                   7916: GEN_SPEOP_LDST(evlwhe, 0x08, 2);
                   7917: GEN_SPEOP_LDST(evlwhou, 0x0A, 2);
                   7918: GEN_SPEOP_LDST(evlwhos, 0x0B, 2);
                   7919: GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2);
                   7920: GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2);
                   7921: 
                   7922: GEN_SPEOP_LDST(evstdd, 0x10, 3);
                   7923: GEN_SPEOP_LDST(evstdw, 0x11, 3);
                   7924: GEN_SPEOP_LDST(evstdh, 0x12, 3);
                   7925: GEN_SPEOP_LDST(evstwhe, 0x18, 2);
                   7926: GEN_SPEOP_LDST(evstwho, 0x1A, 2);
                   7927: GEN_SPEOP_LDST(evstwwe, 0x1C, 2);
                   7928: GEN_SPEOP_LDST(evstwwo, 0x1E, 2);
1.1.1.5   root     7929: 
                   7930: /* Multiply and add - TODO */
                   7931: #if 0
1.1.1.12  root     7932: GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);//
                   7933: GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7934: GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, 0x00000000, PPC_SPE);
                   7935: GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7936: GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, 0x00000000, PPC_SPE);
                   7937: GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7938: GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7939: GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7940: GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, 0x00000000, PPC_SPE);
                   7941: GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7942: GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, 0x00000000, PPC_SPE);
                   7943: GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7944: 
                   7945: GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7946: GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
                   7947: GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, 0x00000000, PPC_SPE);
                   7948: GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7949: GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7950: GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7951: GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7952: GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
                   7953: GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, 0x00000000, PPC_SPE);
                   7954: GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7955: GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7956: GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7957: 
                   7958: GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
                   7959: GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
                   7960: GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
                   7961: GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
                   7962: GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, 0x00000000, PPC_SPE);
                   7963: 
                   7964: GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, 0x00000000, PPC_SPE);
                   7965: GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7966: GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, 0x00000000, PPC_SPE);
                   7967: GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7968: GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, 0x00000000, PPC_SPE);
                   7969: GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7970: GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, 0x00000000, PPC_SPE);
                   7971: GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7972: GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, 0x00000000, PPC_SPE);
                   7973: GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7974: GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, 0x00000000, PPC_SPE);
                   7975: GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7976: 
                   7977: GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, 0x00000000, PPC_SPE);
                   7978: GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, 0x00000000, PPC_SPE);
                   7979: GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7980: GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7981: 
                   7982: GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, 0x00000000, PPC_SPE);
                   7983: GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7984: GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, 0x00000000, PPC_SPE);
                   7985: GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7986: GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, 0x00000000, PPC_SPE);
                   7987: GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7988: GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, 0x00000000, PPC_SPE);
                   7989: GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7990: GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, 0x00000000, PPC_SPE);
                   7991: GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7992: GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, 0x00000000, PPC_SPE);
                   7993: GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7994: 
                   7995: GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, 0x00000000, PPC_SPE);
                   7996: GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, 0x00000000, PPC_SPE);
                   7997: GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
                   7998: GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, 0x00000000, PPC_SPE);
                   7999: GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
1.1.1.5   root     8000: #endif
                   8001: 
                   8002: /***                      SPE floating-point extension                     ***/
1.1.1.6   root     8003: #if defined(TARGET_PPC64)
                   8004: #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
1.1.1.8   root     8005: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8006: {                                                                             \
                   8007:     TCGv_i32 t0;                                                              \
                   8008:     TCGv t1;                                                                  \
                   8009:     t0 = tcg_temp_new_i32();                                                  \
                   8010:     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
                   8011:     gen_helper_##name(t0, t0);                                                \
                   8012:     t1 = tcg_temp_new();                                                      \
                   8013:     tcg_gen_extu_i32_tl(t1, t0);                                              \
                   8014:     tcg_temp_free_i32(t0);                                                    \
                   8015:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
                   8016:                     0xFFFFFFFF00000000ULL);                                   \
                   8017:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
                   8018:     tcg_temp_free(t1);                                                        \
                   8019: }
                   8020: #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
1.1.1.8   root     8021: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8022: {                                                                             \
                   8023:     TCGv_i32 t0;                                                              \
                   8024:     TCGv t1;                                                                  \
                   8025:     t0 = tcg_temp_new_i32();                                                  \
                   8026:     gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
                   8027:     t1 = tcg_temp_new();                                                      \
                   8028:     tcg_gen_extu_i32_tl(t1, t0);                                              \
                   8029:     tcg_temp_free_i32(t0);                                                    \
                   8030:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
                   8031:                     0xFFFFFFFF00000000ULL);                                   \
                   8032:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
                   8033:     tcg_temp_free(t1);                                                        \
                   8034: }
                   8035: #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
1.1.1.8   root     8036: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8037: {                                                                             \
                   8038:     TCGv_i32 t0 = tcg_temp_new_i32();                                         \
                   8039:     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
                   8040:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
                   8041:     tcg_temp_free_i32(t0);                                                    \
                   8042: }
                   8043: #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
1.1.1.8   root     8044: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8045: {                                                                             \
                   8046:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
                   8047: }
                   8048: #define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
1.1.1.8   root     8049: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8050: {                                                                             \
                   8051:     TCGv_i32 t0, t1;                                                          \
                   8052:     TCGv_i64 t2;                                                              \
                   8053:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     8054:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     8055:         return;                                                               \
                   8056:     }                                                                         \
                   8057:     t0 = tcg_temp_new_i32();                                                  \
                   8058:     t1 = tcg_temp_new_i32();                                                  \
                   8059:     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
                   8060:     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
                   8061:     gen_helper_##name(t0, t0, t1);                                            \
                   8062:     tcg_temp_free_i32(t1);                                                    \
                   8063:     t2 = tcg_temp_new();                                                      \
                   8064:     tcg_gen_extu_i32_tl(t2, t0);                                              \
                   8065:     tcg_temp_free_i32(t0);                                                    \
                   8066:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
                   8067:                     0xFFFFFFFF00000000ULL);                                   \
                   8068:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t2);    \
                   8069:     tcg_temp_free(t2);                                                        \
                   8070: }
                   8071: #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
1.1.1.8   root     8072: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     8073: {                                                                             \
1.1.1.6   root     8074:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     8075:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     8076:         return;                                                               \
                   8077:     }                                                                         \
                   8078:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],     \
                   8079:                       cpu_gpr[rB(ctx->opcode)]);                              \
1.1       root     8080: }
1.1.1.6   root     8081: #define GEN_SPEFPUOP_COMP_32(name)                                            \
1.1.1.8   root     8082: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8083: {                                                                             \
                   8084:     TCGv_i32 t0, t1;                                                          \
                   8085:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     8086:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     8087:         return;                                                               \
                   8088:     }                                                                         \
                   8089:     t0 = tcg_temp_new_i32();                                                  \
                   8090:     t1 = tcg_temp_new_i32();                                                  \
                   8091:     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
                   8092:     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
                   8093:     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
                   8094:     tcg_temp_free_i32(t0);                                                    \
                   8095:     tcg_temp_free_i32(t1);                                                    \
                   8096: }
                   8097: #define GEN_SPEFPUOP_COMP_64(name)                                            \
1.1.1.8   root     8098: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8099: {                                                                             \
                   8100:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     8101:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     8102:         return;                                                               \
                   8103:     }                                                                         \
                   8104:     gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
                   8105:                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
                   8106: }
                   8107: #else
                   8108: #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
1.1.1.8   root     8109: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8110: {                                                                             \
                   8111:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
                   8112: }
                   8113: #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
1.1.1.8   root     8114: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8115: {                                                                             \
                   8116:     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
                   8117:     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
                   8118:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
                   8119:     tcg_temp_free_i64(t0);                                                    \
                   8120: }
                   8121: #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
1.1.1.8   root     8122: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8123: {                                                                             \
                   8124:     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
                   8125:     gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
                   8126:     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
                   8127:     tcg_temp_free_i64(t0);                                                    \
                   8128: }
                   8129: #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
1.1.1.8   root     8130: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8131: {                                                                             \
                   8132:     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
                   8133:     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
                   8134:     gen_helper_##name(t0, t0);                                                \
                   8135:     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
                   8136:     tcg_temp_free_i64(t0);                                                    \
                   8137: }
                   8138: #define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
1.1.1.8   root     8139: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8140: {                                                                             \
                   8141:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     8142:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     8143:         return;                                                               \
                   8144:     }                                                                         \
                   8145:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)],                               \
                   8146:                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
                   8147: }
                   8148: #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
1.1.1.8   root     8149: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8150: {                                                                             \
                   8151:     TCGv_i64 t0, t1;                                                          \
                   8152:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     8153:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     8154:         return;                                                               \
                   8155:     }                                                                         \
                   8156:     t0 = tcg_temp_new_i64();                                                  \
                   8157:     t1 = tcg_temp_new_i64();                                                  \
                   8158:     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
                   8159:     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
                   8160:     gen_helper_##name(t0, t0, t1);                                            \
                   8161:     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
                   8162:     tcg_temp_free_i64(t0);                                                    \
                   8163:     tcg_temp_free_i64(t1);                                                    \
                   8164: }
                   8165: #define GEN_SPEFPUOP_COMP_32(name)                                            \
1.1.1.8   root     8166: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8167: {                                                                             \
                   8168:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     8169:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     8170:         return;                                                               \
                   8171:     }                                                                         \
                   8172:     gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
                   8173:                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
                   8174: }
                   8175: #define GEN_SPEFPUOP_COMP_64(name)                                            \
1.1.1.8   root     8176: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8177: {                                                                             \
                   8178:     TCGv_i64 t0, t1;                                                          \
                   8179:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12  root     8180:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     8181:         return;                                                               \
                   8182:     }                                                                         \
                   8183:     t0 = tcg_temp_new_i64();                                                  \
                   8184:     t1 = tcg_temp_new_i64();                                                  \
                   8185:     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
                   8186:     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
                   8187:     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
                   8188:     tcg_temp_free_i64(t0);                                                    \
                   8189:     tcg_temp_free_i64(t1);                                                    \
                   8190: }
                   8191: #endif
1.1       root     8192: 
1.1.1.5   root     8193: /* Single precision floating-point vectors operations */
                   8194: /* Arithmetic */
1.1.1.6   root     8195: GEN_SPEFPUOP_ARITH2_64_64(evfsadd);
                   8196: GEN_SPEFPUOP_ARITH2_64_64(evfssub);
                   8197: GEN_SPEFPUOP_ARITH2_64_64(evfsmul);
                   8198: GEN_SPEFPUOP_ARITH2_64_64(evfsdiv);
1.1.1.8   root     8199: static inline void gen_evfsabs(DisasContext *ctx)
1.1.1.6   root     8200: {
                   8201:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     8202:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8203:         return;
                   8204:     }
                   8205: #if defined(TARGET_PPC64)
1.1.1.10  root     8206:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000080000000LL);
1.1.1.6   root     8207: #else
1.1.1.10  root     8208:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x80000000);
                   8209:     tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
1.1.1.6   root     8210: #endif
                   8211: }
1.1.1.8   root     8212: static inline void gen_evfsnabs(DisasContext *ctx)
1.1.1.6   root     8213: {
                   8214:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     8215:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8216:         return;
                   8217:     }
                   8218: #if defined(TARGET_PPC64)
1.1.1.10  root     8219:     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
1.1.1.6   root     8220: #else
1.1.1.10  root     8221:     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
                   8222:     tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
1.1.1.6   root     8223: #endif
                   8224: }
1.1.1.8   root     8225: static inline void gen_evfsneg(DisasContext *ctx)
1.1.1.6   root     8226: {
                   8227:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     8228:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8229:         return;
                   8230:     }
                   8231: #if defined(TARGET_PPC64)
1.1.1.10  root     8232:     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
1.1.1.6   root     8233: #else
1.1.1.10  root     8234:     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
                   8235:     tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
1.1.1.6   root     8236: #endif
                   8237: }
                   8238: 
1.1.1.5   root     8239: /* Conversion */
1.1.1.6   root     8240: GEN_SPEFPUOP_CONV_64_64(evfscfui);
                   8241: GEN_SPEFPUOP_CONV_64_64(evfscfsi);
                   8242: GEN_SPEFPUOP_CONV_64_64(evfscfuf);
                   8243: GEN_SPEFPUOP_CONV_64_64(evfscfsf);
                   8244: GEN_SPEFPUOP_CONV_64_64(evfsctui);
                   8245: GEN_SPEFPUOP_CONV_64_64(evfsctsi);
                   8246: GEN_SPEFPUOP_CONV_64_64(evfsctuf);
                   8247: GEN_SPEFPUOP_CONV_64_64(evfsctsf);
                   8248: GEN_SPEFPUOP_CONV_64_64(evfsctuiz);
                   8249: GEN_SPEFPUOP_CONV_64_64(evfsctsiz);
                   8250: 
1.1.1.5   root     8251: /* Comparison */
1.1.1.6   root     8252: GEN_SPEFPUOP_COMP_64(evfscmpgt);
                   8253: GEN_SPEFPUOP_COMP_64(evfscmplt);
                   8254: GEN_SPEFPUOP_COMP_64(evfscmpeq);
                   8255: GEN_SPEFPUOP_COMP_64(evfststgt);
                   8256: GEN_SPEFPUOP_COMP_64(evfststlt);
                   8257: GEN_SPEFPUOP_COMP_64(evfststeq);
1.1.1.5   root     8258: 
                   8259: /* Opcodes definitions */
1.1.1.12  root     8260: GEN_SPE(evfsadd,   evfssub,   0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
                   8261: GEN_SPE(evfsabs,   evfsnabs,  0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); //
                   8262: GEN_SPE(evfsneg,   speundef,  0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); //
                   8263: GEN_SPE(evfsmul,   evfsdiv,   0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
                   8264: GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
                   8265: GEN_SPE(evfscmpeq, speundef,  0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
                   8266: GEN_SPE(evfscfui,  evfscfsi,  0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
                   8267: GEN_SPE(evfscfuf,  evfscfsf,  0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
                   8268: GEN_SPE(evfsctui,  evfsctsi,  0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
                   8269: GEN_SPE(evfsctuf,  evfsctsf,  0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
                   8270: GEN_SPE(evfsctuiz, speundef,  0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
                   8271: GEN_SPE(evfsctsiz, speundef,  0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
                   8272: GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
                   8273: GEN_SPE(evfststeq, speundef,  0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
1.1.1.5   root     8274: 
                   8275: /* Single precision floating-point operations */
                   8276: /* Arithmetic */
1.1.1.6   root     8277: GEN_SPEFPUOP_ARITH2_32_32(efsadd);
                   8278: GEN_SPEFPUOP_ARITH2_32_32(efssub);
                   8279: GEN_SPEFPUOP_ARITH2_32_32(efsmul);
                   8280: GEN_SPEFPUOP_ARITH2_32_32(efsdiv);
1.1.1.8   root     8281: static inline void gen_efsabs(DisasContext *ctx)
1.1.1.6   root     8282: {
                   8283:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     8284:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8285:         return;
                   8286:     }
1.1.1.10  root     8287:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL);
1.1.1.6   root     8288: }
1.1.1.8   root     8289: static inline void gen_efsnabs(DisasContext *ctx)
1.1.1.6   root     8290: {
                   8291:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     8292:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8293:         return;
                   8294:     }
1.1.1.10  root     8295:     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
1.1.1.6   root     8296: }
1.1.1.8   root     8297: static inline void gen_efsneg(DisasContext *ctx)
1.1.1.6   root     8298: {
                   8299:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     8300:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8301:         return;
                   8302:     }
1.1.1.10  root     8303:     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
1.1.1.6   root     8304: }
                   8305: 
1.1.1.5   root     8306: /* Conversion */
1.1.1.6   root     8307: GEN_SPEFPUOP_CONV_32_32(efscfui);
                   8308: GEN_SPEFPUOP_CONV_32_32(efscfsi);
                   8309: GEN_SPEFPUOP_CONV_32_32(efscfuf);
                   8310: GEN_SPEFPUOP_CONV_32_32(efscfsf);
                   8311: GEN_SPEFPUOP_CONV_32_32(efsctui);
                   8312: GEN_SPEFPUOP_CONV_32_32(efsctsi);
                   8313: GEN_SPEFPUOP_CONV_32_32(efsctuf);
                   8314: GEN_SPEFPUOP_CONV_32_32(efsctsf);
                   8315: GEN_SPEFPUOP_CONV_32_32(efsctuiz);
                   8316: GEN_SPEFPUOP_CONV_32_32(efsctsiz);
                   8317: GEN_SPEFPUOP_CONV_32_64(efscfd);
                   8318: 
1.1.1.5   root     8319: /* Comparison */
1.1.1.6   root     8320: GEN_SPEFPUOP_COMP_32(efscmpgt);
                   8321: GEN_SPEFPUOP_COMP_32(efscmplt);
                   8322: GEN_SPEFPUOP_COMP_32(efscmpeq);
                   8323: GEN_SPEFPUOP_COMP_32(efststgt);
                   8324: GEN_SPEFPUOP_COMP_32(efststlt);
                   8325: GEN_SPEFPUOP_COMP_32(efststeq);
1.1.1.5   root     8326: 
                   8327: /* Opcodes definitions */
1.1.1.12  root     8328: GEN_SPE(efsadd,   efssub,   0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
                   8329: GEN_SPE(efsabs,   efsnabs,  0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); //
                   8330: GEN_SPE(efsneg,   speundef, 0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); //
                   8331: GEN_SPE(efsmul,   efsdiv,   0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
                   8332: GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
                   8333: GEN_SPE(efscmpeq, efscfd,   0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE); //
                   8334: GEN_SPE(efscfui,  efscfsi,  0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
                   8335: GEN_SPE(efscfuf,  efscfsf,  0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
                   8336: GEN_SPE(efsctui,  efsctsi,  0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
                   8337: GEN_SPE(efsctuf,  efsctsf,  0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
                   8338: GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
                   8339: GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
                   8340: GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
                   8341: GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
1.1.1.5   root     8342: 
                   8343: /* Double precision floating-point operations */
                   8344: /* Arithmetic */
1.1.1.6   root     8345: GEN_SPEFPUOP_ARITH2_64_64(efdadd);
                   8346: GEN_SPEFPUOP_ARITH2_64_64(efdsub);
                   8347: GEN_SPEFPUOP_ARITH2_64_64(efdmul);
                   8348: GEN_SPEFPUOP_ARITH2_64_64(efddiv);
1.1.1.8   root     8349: static inline void gen_efdabs(DisasContext *ctx)
1.1.1.6   root     8350: {
                   8351:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     8352:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8353:         return;
                   8354:     }
                   8355: #if defined(TARGET_PPC64)
1.1.1.10  root     8356:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000000000000LL);
1.1.1.6   root     8357: #else
1.1.1.10  root     8358:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   8359:     tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
1.1.1.6   root     8360: #endif
                   8361: }
1.1.1.8   root     8362: static inline void gen_efdnabs(DisasContext *ctx)
1.1.1.6   root     8363: {
                   8364:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     8365:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8366:         return;
                   8367:     }
                   8368: #if defined(TARGET_PPC64)
1.1.1.10  root     8369:     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
1.1.1.6   root     8370: #else
1.1.1.10  root     8371:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   8372:     tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
1.1.1.6   root     8373: #endif
                   8374: }
1.1.1.8   root     8375: static inline void gen_efdneg(DisasContext *ctx)
1.1.1.6   root     8376: {
                   8377:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12  root     8378:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8379:         return;
                   8380:     }
                   8381: #if defined(TARGET_PPC64)
1.1.1.10  root     8382:     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
1.1.1.6   root     8383: #else
1.1.1.10  root     8384:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   8385:     tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
1.1.1.6   root     8386: #endif
                   8387: }
                   8388: 
1.1.1.5   root     8389: /* Conversion */
1.1.1.6   root     8390: GEN_SPEFPUOP_CONV_64_32(efdcfui);
                   8391: GEN_SPEFPUOP_CONV_64_32(efdcfsi);
                   8392: GEN_SPEFPUOP_CONV_64_32(efdcfuf);
                   8393: GEN_SPEFPUOP_CONV_64_32(efdcfsf);
                   8394: GEN_SPEFPUOP_CONV_32_64(efdctui);
                   8395: GEN_SPEFPUOP_CONV_32_64(efdctsi);
                   8396: GEN_SPEFPUOP_CONV_32_64(efdctuf);
                   8397: GEN_SPEFPUOP_CONV_32_64(efdctsf);
                   8398: GEN_SPEFPUOP_CONV_32_64(efdctuiz);
                   8399: GEN_SPEFPUOP_CONV_32_64(efdctsiz);
                   8400: GEN_SPEFPUOP_CONV_64_32(efdcfs);
                   8401: GEN_SPEFPUOP_CONV_64_64(efdcfuid);
                   8402: GEN_SPEFPUOP_CONV_64_64(efdcfsid);
                   8403: GEN_SPEFPUOP_CONV_64_64(efdctuidz);
                   8404: GEN_SPEFPUOP_CONV_64_64(efdctsidz);
1.1.1.5   root     8405: 
                   8406: /* Comparison */
1.1.1.6   root     8407: GEN_SPEFPUOP_COMP_64(efdcmpgt);
                   8408: GEN_SPEFPUOP_COMP_64(efdcmplt);
                   8409: GEN_SPEFPUOP_COMP_64(efdcmpeq);
                   8410: GEN_SPEFPUOP_COMP_64(efdtstgt);
                   8411: GEN_SPEFPUOP_COMP_64(efdtstlt);
                   8412: GEN_SPEFPUOP_COMP_64(efdtsteq);
1.1.1.5   root     8413: 
                   8414: /* Opcodes definitions */
1.1.1.12  root     8415: GEN_SPE(efdadd,    efdsub,    0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); //
                   8416: GEN_SPE(efdcfuid,  efdcfsid,  0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
                   8417: GEN_SPE(efdabs,    efdnabs,   0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE); //
                   8418: GEN_SPE(efdneg,    speundef,  0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
                   8419: GEN_SPE(efdmul,    efddiv,    0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); //
                   8420: GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
                   8421: GEN_SPE(efdcmpgt,  efdcmplt,  0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
                   8422: GEN_SPE(efdcmpeq,  efdcfs,    0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE); //
                   8423: GEN_SPE(efdcfui,   efdcfsi,   0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
                   8424: GEN_SPE(efdcfuf,   efdcfsf,   0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
                   8425: GEN_SPE(efdctui,   efdctsi,   0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
                   8426: GEN_SPE(efdctuf,   efdctsf,   0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
                   8427: GEN_SPE(efdctuiz,  speundef,  0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
                   8428: GEN_SPE(efdctsiz,  speundef,  0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
                   8429: GEN_SPE(efdtstgt,  efdtstlt,  0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
                   8430: GEN_SPE(efdtsteq,  speundef,  0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
1.1.1.5   root     8431: 
1.1.1.7   root     8432: static opcode_t opcodes[] = {
                   8433: GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
                   8434: GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
                   8435: GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
                   8436: GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400000, PPC_INTEGER),
                   8437: GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
                   8438: GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
                   8439: GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8440: GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8441: GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8442: GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8443: GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER),
                   8444: GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER),
                   8445: GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER),
                   8446: GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER),
                   8447: GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8448: #if defined(TARGET_PPC64)
                   8449: GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B),
                   8450: #endif
                   8451: GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER),
                   8452: GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER),
                   8453: GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8454: GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8455: GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8456: GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
                   8457: GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
                   8458: GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
                   8459: GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8460: GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8461: GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8462: GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8463: GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB),
1.1.1.11  root     8464: GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD),
1.1.1.7   root     8465: #if defined(TARGET_PPC64)
1.1.1.11  root     8466: GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD),
1.1.1.7   root     8467: GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
                   8468: #endif
                   8469: GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8470: GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8471: GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8472: GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER),
                   8473: GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER),
                   8474: GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER),
                   8475: GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER),
                   8476: #if defined(TARGET_PPC64)
                   8477: GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B),
                   8478: GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B),
                   8479: GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B),
                   8480: GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B),
                   8481: GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B),
                   8482: #endif
                   8483: GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES),
                   8484: GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
                   8485: GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
                   8486: GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT),
                   8487: GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT),
                   8488: GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT),
                   8489: GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
                   8490: GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT),
                   8491: GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
                   8492: GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
                   8493: GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00010000, PPC_FLOAT),
                   8494: GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT),
                   8495: #if defined(TARGET_PPC64)
                   8496: GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
                   8497: GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
                   8498: GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
                   8499: #endif
                   8500: GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8501: GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8502: GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING),
                   8503: GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING),
                   8504: GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
                   8505: GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
                   8506: GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO),
                   8507: GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
1.1.1.10  root     8508: GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES),
1.1.1.7   root     8509: GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
                   8510: #if defined(TARGET_PPC64)
1.1.1.10  root     8511: GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B),
1.1.1.7   root     8512: GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
                   8513: #endif
                   8514: GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC),
                   8515: GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT),
                   8516: GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
                   8517: GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
                   8518: GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW),
                   8519: GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW),
                   8520: GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
                   8521: GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
                   8522: #if defined(TARGET_PPC64)
                   8523: GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
                   8524: GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
                   8525: #endif
                   8526: GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
                   8527: GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
                   8528: GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
                   8529: #if defined(TARGET_PPC64)
                   8530: GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B),
                   8531: GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B),
                   8532: #endif
                   8533: GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
                   8534: GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC),
                   8535: GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC),
                   8536: GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
                   8537: GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
                   8538: GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
                   8539: #if defined(TARGET_PPC64)
                   8540: GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
                   8541: #endif
                   8542: GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC),
                   8543: GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC),
                   8544: GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
                   8545: GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
                   8546: GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
                   8547: GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE),
                   8548: GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE),
                   8549: GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ),
                   8550: GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT),
                   8551: GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
                   8552: GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC),
                   8553: GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
                   8554: GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI),
                   8555: GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA),
                   8556: GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
                   8557: GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
                   8558: GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT),
                   8559: GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT),
                   8560: #if defined(TARGET_PPC64)
                   8561: GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B),
                   8562: GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
                   8563:              PPC_SEGMENT_64B),
                   8564: GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
                   8565: GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
                   8566:              PPC_SEGMENT_64B),
1.1.1.11  root     8567: GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B),
                   8568: GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B),
                   8569: GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B),
1.1.1.7   root     8570: #endif
                   8571: GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
                   8572: GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE),
                   8573: GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE),
                   8574: GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
                   8575: #if defined(TARGET_PPC64)
                   8576: GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI),
                   8577: GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI),
                   8578: #endif
                   8579: GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN),
                   8580: GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN),
                   8581: GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR),
                   8582: GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR),
                   8583: GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR),
                   8584: GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR),
                   8585: GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR),
                   8586: GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR),
                   8587: GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR),
                   8588: GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR),
                   8589: GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR),
                   8590: GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
                   8591: GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR),
                   8592: GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR),
                   8593: GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR),
                   8594: GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR),
                   8595: GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR),
                   8596: GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR),
                   8597: GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR),
                   8598: GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
                   8599: GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR),
                   8600: GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR),
                   8601: GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR),
                   8602: GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR),
                   8603: GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR),
                   8604: GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR),
                   8605: GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR),
                   8606: GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR),
                   8607: GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR),
                   8608: GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR),
                   8609: GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR),
                   8610: GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR),
                   8611: GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR),
                   8612: GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR),
                   8613: GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR),
                   8614: GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR),
                   8615: GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC),
                   8616: GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC),
                   8617: GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC),
                   8618: GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB),
                   8619: GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB),
                   8620: GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB),
                   8621: GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB),
                   8622: GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER),
                   8623: GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER),
                   8624: GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER),
                   8625: GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER),
                   8626: GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER),
                   8627: GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER),
                   8628: GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
                   8629: GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
                   8630: GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2),
                   8631: GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2),
                   8632: GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
                   8633: GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
                   8634: GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2),
                   8635: GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2),
                   8636: GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI),
                   8637: GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA),
                   8638: GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR),
                   8639: GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR),
                   8640: GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX),
                   8641: GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX),
                   8642: GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX),
                   8643: GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX),
                   8644: GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON),
                   8645: GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON),
                   8646: GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT),
                   8647: GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON),
                   8648: GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON),
                   8649: GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP),
1.1.1.11  root     8650: GEN_HANDLER_E(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE, PPC2_BOOKE206),
1.1.1.7   root     8651: GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI),
                   8652: GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI),
                   8653: GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB),
                   8654: GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB),
                   8655: GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB),
                   8656: GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE),
                   8657: GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE),
                   8658: GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE),
1.1.1.11  root     8659: GEN_HANDLER2_E(tlbre_booke206, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001,
                   8660:                PPC_NONE, PPC2_BOOKE206),
                   8661: GEN_HANDLER2_E(tlbsx_booke206, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000,
                   8662:                PPC_NONE, PPC2_BOOKE206),
                   8663: GEN_HANDLER2_E(tlbwe_booke206, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001,
                   8664:                PPC_NONE, PPC2_BOOKE206),
                   8665: GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001,
                   8666:                PPC_NONE, PPC2_BOOKE206),
1.1.1.13! root     8667: GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001,
        !          8668:                PPC_NONE, PPC2_BOOKE206),
        !          8669: GEN_HANDLER2_E(msgsnd, "msgsnd", 0x1F, 0x0E, 0x06, 0x03ff0001,
        !          8670:                PPC_NONE, PPC2_PRCNTL),
        !          8671: GEN_HANDLER2_E(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001,
        !          8672:                PPC_NONE, PPC2_PRCNTL),
1.1.1.7   root     8673: GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
                   8674: GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
                   8675: GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
1.1.1.11  root     8676: GEN_HANDLER_E(mbar, 0x1F, 0x16, 0x1a, 0x001FF801,
                   8677:               PPC_BOOKE, PPC2_BOOKE206),
1.1.1.13! root     8678: GEN_HANDLER(msync_4xx, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE),
1.1.1.11  root     8679: GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001,
                   8680:                PPC_BOOKE, PPC2_BOOKE206),
1.1.1.7   root     8681: GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC),
                   8682: GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC),
                   8683: GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
                   8684: GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
                   8685: GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC),
                   8686: GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC),
                   8687: GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE),
                   8688: GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE),
                   8689: GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE),
                   8690: GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE),
                   8691: 
                   8692: #undef GEN_INT_ARITH_ADD
                   8693: #undef GEN_INT_ARITH_ADD_CONST
                   8694: #define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
                   8695: GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER),
                   8696: #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
                   8697:                                 add_ca, compute_ca, compute_ov)               \
                   8698: GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER),
                   8699: GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
                   8700: GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
                   8701: GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
                   8702: GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
                   8703: GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
                   8704: GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
                   8705: GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
                   8706: GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
                   8707: GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
                   8708: GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
                   8709: 
                   8710: #undef GEN_INT_ARITH_DIVW
                   8711: #define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
                   8712: GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)
                   8713: GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0),
                   8714: GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1),
                   8715: GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0),
                   8716: GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1),
                   8717: 
                   8718: #if defined(TARGET_PPC64)
                   8719: #undef GEN_INT_ARITH_DIVD
                   8720: #define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
                   8721: GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
                   8722: GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0),
                   8723: GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1),
                   8724: GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0),
                   8725: GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
                   8726: 
                   8727: #undef GEN_INT_ARITH_MUL_HELPER
                   8728: #define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
                   8729: GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
                   8730: GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00),
                   8731: GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02),
                   8732: GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17),
                   8733: #endif
                   8734: 
                   8735: #undef GEN_INT_ARITH_SUBF
                   8736: #undef GEN_INT_ARITH_SUBF_CONST
                   8737: #define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
                   8738: GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER),
                   8739: #define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
                   8740:                                 add_ca, compute_ca, compute_ov)               \
                   8741: GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER),
                   8742: GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
                   8743: GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
                   8744: GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
                   8745: GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
                   8746: GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
                   8747: GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
                   8748: GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
                   8749: GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
                   8750: GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
                   8751: GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
                   8752: 
                   8753: #undef GEN_LOGICAL1
                   8754: #undef GEN_LOGICAL2
                   8755: #define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
                   8756: GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)
                   8757: #define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
                   8758: GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)
                   8759: GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER),
                   8760: GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER),
                   8761: GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER),
                   8762: GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER),
                   8763: GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER),
                   8764: GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER),
                   8765: GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER),
                   8766: GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER),
                   8767: #if defined(TARGET_PPC64)
                   8768: GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B),
                   8769: #endif
                   8770: 
                   8771: #if defined(TARGET_PPC64)
                   8772: #undef GEN_PPC64_R2
                   8773: #undef GEN_PPC64_R4
                   8774: #define GEN_PPC64_R2(name, opc1, opc2)                                        \
                   8775: GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
                   8776: GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
                   8777:              PPC_64B)
                   8778: #define GEN_PPC64_R4(name, opc1, opc2)                                        \
                   8779: GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
                   8780: GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
                   8781:              PPC_64B),                                                        \
                   8782: GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
                   8783:              PPC_64B),                                                        \
                   8784: GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
                   8785:              PPC_64B)
                   8786: GEN_PPC64_R4(rldicl, 0x1E, 0x00),
                   8787: GEN_PPC64_R4(rldicr, 0x1E, 0x02),
                   8788: GEN_PPC64_R4(rldic, 0x1E, 0x04),
                   8789: GEN_PPC64_R2(rldcl, 0x1E, 0x08),
                   8790: GEN_PPC64_R2(rldcr, 0x1E, 0x09),
                   8791: GEN_PPC64_R4(rldimi, 0x1E, 0x06),
                   8792: #endif
                   8793: 
                   8794: #undef _GEN_FLOAT_ACB
                   8795: #undef GEN_FLOAT_ACB
                   8796: #undef _GEN_FLOAT_AB
                   8797: #undef GEN_FLOAT_AB
                   8798: #undef _GEN_FLOAT_AC
                   8799: #undef GEN_FLOAT_AC
                   8800: #undef GEN_FLOAT_B
                   8801: #undef GEN_FLOAT_BS
                   8802: #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
                   8803: GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)
                   8804: #define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
                   8805: _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type),                     \
                   8806: _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type)
                   8807: #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
                   8808: GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
                   8809: #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
                   8810: _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
                   8811: _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
                   8812: #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
                   8813: GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
                   8814: #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
                   8815: _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
                   8816: _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
                   8817: #define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
                   8818: GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)
                   8819: #define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
                   8820: GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)
                   8821: 
                   8822: GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT),
                   8823: GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT),
                   8824: GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT),
                   8825: GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT),
                   8826: GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES),
                   8827: GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE),
                   8828: _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL),
                   8829: GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT),
                   8830: GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT),
                   8831: GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT),
                   8832: GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT),
                   8833: GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT),
                   8834: GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT),
                   8835: GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT),
                   8836: GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT),
                   8837: #if defined(TARGET_PPC64)
                   8838: GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B),
                   8839: GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B),
                   8840: GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B),
                   8841: #endif
                   8842: GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT),
                   8843: GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT),
                   8844: GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT),
                   8845: GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT),
                   8846: GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT),
                   8847: GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT),
                   8848: GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT),
                   8849: 
                   8850: #undef GEN_LD
                   8851: #undef GEN_LDU
                   8852: #undef GEN_LDUX
1.1.1.13! root     8853: #undef GEN_LDX_E
1.1.1.7   root     8854: #undef GEN_LDS
                   8855: #define GEN_LD(name, ldop, opc, type)                                         \
                   8856: GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
                   8857: #define GEN_LDU(name, ldop, opc, type)                                        \
                   8858: GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
                   8859: #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
                   8860: GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
1.1.1.13! root     8861: #define GEN_LDX_E(name, ldop, opc2, opc3, type, type2)                        \
        !          8862: GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
1.1.1.7   root     8863: #define GEN_LDS(name, ldop, op, type)                                         \
                   8864: GEN_LD(name, ldop, op | 0x20, type)                                           \
                   8865: GEN_LDU(name, ldop, op | 0x21, type)                                          \
                   8866: GEN_LDUX(name, ldop, 0x17, op | 0x01, type)                                   \
                   8867: GEN_LDX(name, ldop, 0x17, op | 0x00, type)
                   8868: 
                   8869: GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER)
                   8870: GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER)
                   8871: GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER)
                   8872: GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER)
                   8873: #if defined(TARGET_PPC64)
                   8874: GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
                   8875: GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
                   8876: GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
                   8877: GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
1.1.1.13! root     8878: GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX)
1.1.1.7   root     8879: #endif
                   8880: GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
                   8881: GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
                   8882: 
                   8883: #undef GEN_ST
                   8884: #undef GEN_STU
                   8885: #undef GEN_STUX
1.1.1.13! root     8886: #undef GEN_STX_E
1.1.1.7   root     8887: #undef GEN_STS
                   8888: #define GEN_ST(name, stop, opc, type)                                         \
                   8889: GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
                   8890: #define GEN_STU(name, stop, opc, type)                                        \
                   8891: GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
                   8892: #define GEN_STUX(name, stop, opc2, opc3, type)                                \
                   8893: GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
1.1.1.13! root     8894: #define GEN_STX_E(name, stop, opc2, opc3, type, type2)                        \
        !          8895: GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
1.1.1.7   root     8896: #define GEN_STS(name, stop, op, type)                                         \
                   8897: GEN_ST(name, stop, op | 0x20, type)                                           \
                   8898: GEN_STU(name, stop, op | 0x21, type)                                          \
                   8899: GEN_STUX(name, stop, 0x17, op | 0x01, type)                                   \
                   8900: GEN_STX(name, stop, 0x17, op | 0x00, type)
                   8901: 
                   8902: GEN_STS(stb, st8, 0x06, PPC_INTEGER)
                   8903: GEN_STS(sth, st16, 0x0C, PPC_INTEGER)
                   8904: GEN_STS(stw, st32, 0x04, PPC_INTEGER)
                   8905: #if defined(TARGET_PPC64)
                   8906: GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
                   8907: GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
1.1.1.13! root     8908: GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX)
1.1.1.7   root     8909: #endif
                   8910: GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
                   8911: GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
                   8912: 
                   8913: #undef GEN_LDF
                   8914: #undef GEN_LDUF
                   8915: #undef GEN_LDUXF
                   8916: #undef GEN_LDXF
                   8917: #undef GEN_LDFS
                   8918: #define GEN_LDF(name, ldop, opc, type)                                        \
                   8919: GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
                   8920: #define GEN_LDUF(name, ldop, opc, type)                                       \
                   8921: GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
                   8922: #define GEN_LDUXF(name, ldop, opc, type)                                      \
                   8923: GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
                   8924: #define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
                   8925: GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
                   8926: #define GEN_LDFS(name, ldop, op, type)                                        \
                   8927: GEN_LDF(name, ldop, op | 0x20, type)                                          \
                   8928: GEN_LDUF(name, ldop, op | 0x21, type)                                         \
                   8929: GEN_LDUXF(name, ldop, op | 0x01, type)                                        \
                   8930: GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
                   8931: 
                   8932: GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT)
                   8933: GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT)
                   8934: 
                   8935: #undef GEN_STF
                   8936: #undef GEN_STUF
                   8937: #undef GEN_STUXF
                   8938: #undef GEN_STXF
                   8939: #undef GEN_STFS
                   8940: #define GEN_STF(name, stop, opc, type)                                        \
                   8941: GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
                   8942: #define GEN_STUF(name, stop, opc, type)                                       \
                   8943: GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
                   8944: #define GEN_STUXF(name, stop, opc, type)                                      \
                   8945: GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
                   8946: #define GEN_STXF(name, stop, opc2, opc3, type)                                \
                   8947: GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
                   8948: #define GEN_STFS(name, stop, op, type)                                        \
                   8949: GEN_STF(name, stop, op | 0x20, type)                                          \
                   8950: GEN_STUF(name, stop, op | 0x21, type)                                         \
                   8951: GEN_STUXF(name, stop, op | 0x01, type)                                        \
                   8952: GEN_STXF(name, stop, 0x17, op | 0x00, type)
                   8953: 
                   8954: GEN_STFS(stfd, st64, 0x16, PPC_FLOAT)
                   8955: GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT)
                   8956: GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
                   8957: 
                   8958: #undef GEN_CRLOGIC
                   8959: #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
                   8960: GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)
                   8961: GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08),
                   8962: GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04),
                   8963: GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09),
                   8964: GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07),
                   8965: GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01),
                   8966: GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E),
                   8967: GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D),
                   8968: GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06),
                   8969: 
                   8970: #undef GEN_MAC_HANDLER
                   8971: #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
                   8972: GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)
                   8973: GEN_MAC_HANDLER(macchw, 0x0C, 0x05),
                   8974: GEN_MAC_HANDLER(macchwo, 0x0C, 0x15),
                   8975: GEN_MAC_HANDLER(macchws, 0x0C, 0x07),
                   8976: GEN_MAC_HANDLER(macchwso, 0x0C, 0x17),
                   8977: GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06),
                   8978: GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16),
                   8979: GEN_MAC_HANDLER(macchwu, 0x0C, 0x04),
                   8980: GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14),
                   8981: GEN_MAC_HANDLER(machhw, 0x0C, 0x01),
                   8982: GEN_MAC_HANDLER(machhwo, 0x0C, 0x11),
                   8983: GEN_MAC_HANDLER(machhws, 0x0C, 0x03),
                   8984: GEN_MAC_HANDLER(machhwso, 0x0C, 0x13),
                   8985: GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02),
                   8986: GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12),
                   8987: GEN_MAC_HANDLER(machhwu, 0x0C, 0x00),
                   8988: GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10),
                   8989: GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D),
                   8990: GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D),
                   8991: GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F),
                   8992: GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F),
                   8993: GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C),
                   8994: GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C),
                   8995: GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E),
                   8996: GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E),
                   8997: GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05),
                   8998: GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15),
                   8999: GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07),
                   9000: GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17),
                   9001: GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01),
                   9002: GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11),
                   9003: GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03),
                   9004: GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13),
                   9005: GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D),
                   9006: GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D),
                   9007: GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F),
                   9008: GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F),
                   9009: GEN_MAC_HANDLER(mulchw, 0x08, 0x05),
                   9010: GEN_MAC_HANDLER(mulchwu, 0x08, 0x04),
                   9011: GEN_MAC_HANDLER(mulhhw, 0x08, 0x01),
                   9012: GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00),
                   9013: GEN_MAC_HANDLER(mullhw, 0x08, 0x0D),
                   9014: GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C),
                   9015: 
                   9016: #undef GEN_VR_LDX
                   9017: #undef GEN_VR_STX
                   9018: #undef GEN_VR_LVE
                   9019: #undef GEN_VR_STVE
                   9020: #define GEN_VR_LDX(name, opc2, opc3)                                          \
                   9021: GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
                   9022: #define GEN_VR_STX(name, opc2, opc3)                                          \
                   9023: GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
                   9024: #define GEN_VR_LVE(name, opc2, opc3)                                    \
                   9025:     GEN_HANDLER(lve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
                   9026: #define GEN_VR_STVE(name, opc2, opc3)                                   \
                   9027:     GEN_HANDLER(stve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
                   9028: GEN_VR_LDX(lvx, 0x07, 0x03),
                   9029: GEN_VR_LDX(lvxl, 0x07, 0x0B),
                   9030: GEN_VR_LVE(bx, 0x07, 0x00),
                   9031: GEN_VR_LVE(hx, 0x07, 0x01),
                   9032: GEN_VR_LVE(wx, 0x07, 0x02),
                   9033: GEN_VR_STX(svx, 0x07, 0x07),
                   9034: GEN_VR_STX(svxl, 0x07, 0x0F),
                   9035: GEN_VR_STVE(bx, 0x07, 0x04),
                   9036: GEN_VR_STVE(hx, 0x07, 0x05),
                   9037: GEN_VR_STVE(wx, 0x07, 0x06),
                   9038: 
                   9039: #undef GEN_VX_LOGICAL
                   9040: #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
                   9041: GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
                   9042: GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16),
                   9043: GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17),
                   9044: GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18),
                   9045: GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19),
                   9046: GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20),
                   9047: 
                   9048: #undef GEN_VXFORM
                   9049: #define GEN_VXFORM(name, opc2, opc3)                                    \
                   9050: GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
                   9051: GEN_VXFORM(vaddubm, 0, 0),
                   9052: GEN_VXFORM(vadduhm, 0, 1),
                   9053: GEN_VXFORM(vadduwm, 0, 2),
                   9054: GEN_VXFORM(vsububm, 0, 16),
                   9055: GEN_VXFORM(vsubuhm, 0, 17),
                   9056: GEN_VXFORM(vsubuwm, 0, 18),
                   9057: GEN_VXFORM(vmaxub, 1, 0),
                   9058: GEN_VXFORM(vmaxuh, 1, 1),
                   9059: GEN_VXFORM(vmaxuw, 1, 2),
                   9060: GEN_VXFORM(vmaxsb, 1, 4),
                   9061: GEN_VXFORM(vmaxsh, 1, 5),
                   9062: GEN_VXFORM(vmaxsw, 1, 6),
                   9063: GEN_VXFORM(vminub, 1, 8),
                   9064: GEN_VXFORM(vminuh, 1, 9),
                   9065: GEN_VXFORM(vminuw, 1, 10),
                   9066: GEN_VXFORM(vminsb, 1, 12),
                   9067: GEN_VXFORM(vminsh, 1, 13),
                   9068: GEN_VXFORM(vminsw, 1, 14),
                   9069: GEN_VXFORM(vavgub, 1, 16),
                   9070: GEN_VXFORM(vavguh, 1, 17),
                   9071: GEN_VXFORM(vavguw, 1, 18),
                   9072: GEN_VXFORM(vavgsb, 1, 20),
                   9073: GEN_VXFORM(vavgsh, 1, 21),
                   9074: GEN_VXFORM(vavgsw, 1, 22),
                   9075: GEN_VXFORM(vmrghb, 6, 0),
                   9076: GEN_VXFORM(vmrghh, 6, 1),
                   9077: GEN_VXFORM(vmrghw, 6, 2),
                   9078: GEN_VXFORM(vmrglb, 6, 4),
                   9079: GEN_VXFORM(vmrglh, 6, 5),
                   9080: GEN_VXFORM(vmrglw, 6, 6),
                   9081: GEN_VXFORM(vmuloub, 4, 0),
                   9082: GEN_VXFORM(vmulouh, 4, 1),
                   9083: GEN_VXFORM(vmulosb, 4, 4),
                   9084: GEN_VXFORM(vmulosh, 4, 5),
                   9085: GEN_VXFORM(vmuleub, 4, 8),
                   9086: GEN_VXFORM(vmuleuh, 4, 9),
                   9087: GEN_VXFORM(vmulesb, 4, 12),
                   9088: GEN_VXFORM(vmulesh, 4, 13),
                   9089: GEN_VXFORM(vslb, 2, 4),
                   9090: GEN_VXFORM(vslh, 2, 5),
                   9091: GEN_VXFORM(vslw, 2, 6),
                   9092: GEN_VXFORM(vsrb, 2, 8),
                   9093: GEN_VXFORM(vsrh, 2, 9),
                   9094: GEN_VXFORM(vsrw, 2, 10),
                   9095: GEN_VXFORM(vsrab, 2, 12),
                   9096: GEN_VXFORM(vsrah, 2, 13),
                   9097: GEN_VXFORM(vsraw, 2, 14),
                   9098: GEN_VXFORM(vslo, 6, 16),
                   9099: GEN_VXFORM(vsro, 6, 17),
                   9100: GEN_VXFORM(vaddcuw, 0, 6),
                   9101: GEN_VXFORM(vsubcuw, 0, 22),
                   9102: GEN_VXFORM(vaddubs, 0, 8),
                   9103: GEN_VXFORM(vadduhs, 0, 9),
                   9104: GEN_VXFORM(vadduws, 0, 10),
                   9105: GEN_VXFORM(vaddsbs, 0, 12),
                   9106: GEN_VXFORM(vaddshs, 0, 13),
                   9107: GEN_VXFORM(vaddsws, 0, 14),
                   9108: GEN_VXFORM(vsububs, 0, 24),
                   9109: GEN_VXFORM(vsubuhs, 0, 25),
                   9110: GEN_VXFORM(vsubuws, 0, 26),
                   9111: GEN_VXFORM(vsubsbs, 0, 28),
                   9112: GEN_VXFORM(vsubshs, 0, 29),
                   9113: GEN_VXFORM(vsubsws, 0, 30),
                   9114: GEN_VXFORM(vrlb, 2, 0),
                   9115: GEN_VXFORM(vrlh, 2, 1),
                   9116: GEN_VXFORM(vrlw, 2, 2),
                   9117: GEN_VXFORM(vsl, 2, 7),
                   9118: GEN_VXFORM(vsr, 2, 11),
                   9119: GEN_VXFORM(vpkuhum, 7, 0),
                   9120: GEN_VXFORM(vpkuwum, 7, 1),
                   9121: GEN_VXFORM(vpkuhus, 7, 2),
                   9122: GEN_VXFORM(vpkuwus, 7, 3),
                   9123: GEN_VXFORM(vpkshus, 7, 4),
                   9124: GEN_VXFORM(vpkswus, 7, 5),
                   9125: GEN_VXFORM(vpkshss, 7, 6),
                   9126: GEN_VXFORM(vpkswss, 7, 7),
                   9127: GEN_VXFORM(vpkpx, 7, 12),
                   9128: GEN_VXFORM(vsum4ubs, 4, 24),
                   9129: GEN_VXFORM(vsum4sbs, 4, 28),
                   9130: GEN_VXFORM(vsum4shs, 4, 25),
                   9131: GEN_VXFORM(vsum2sws, 4, 26),
                   9132: GEN_VXFORM(vsumsws, 4, 30),
                   9133: GEN_VXFORM(vaddfp, 5, 0),
                   9134: GEN_VXFORM(vsubfp, 5, 1),
                   9135: GEN_VXFORM(vmaxfp, 5, 16),
                   9136: GEN_VXFORM(vminfp, 5, 17),
                   9137: 
                   9138: #undef GEN_VXRFORM1
                   9139: #undef GEN_VXRFORM
                   9140: #define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
                   9141:     GEN_HANDLER2(name, str, 0x4, opc2, opc3, 0x00000000, PPC_ALTIVEC),
                   9142: #define GEN_VXRFORM(name, opc2, opc3)                                \
                   9143:     GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
                   9144:     GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
                   9145: GEN_VXRFORM(vcmpequb, 3, 0)
                   9146: GEN_VXRFORM(vcmpequh, 3, 1)
                   9147: GEN_VXRFORM(vcmpequw, 3, 2)
                   9148: GEN_VXRFORM(vcmpgtsb, 3, 12)
                   9149: GEN_VXRFORM(vcmpgtsh, 3, 13)
                   9150: GEN_VXRFORM(vcmpgtsw, 3, 14)
                   9151: GEN_VXRFORM(vcmpgtub, 3, 8)
                   9152: GEN_VXRFORM(vcmpgtuh, 3, 9)
                   9153: GEN_VXRFORM(vcmpgtuw, 3, 10)
                   9154: GEN_VXRFORM(vcmpeqfp, 3, 3)
                   9155: GEN_VXRFORM(vcmpgefp, 3, 7)
                   9156: GEN_VXRFORM(vcmpgtfp, 3, 11)
                   9157: GEN_VXRFORM(vcmpbfp, 3, 15)
                   9158: 
                   9159: #undef GEN_VXFORM_SIMM
                   9160: #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
                   9161:     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
                   9162: GEN_VXFORM_SIMM(vspltisb, 6, 12),
                   9163: GEN_VXFORM_SIMM(vspltish, 6, 13),
                   9164: GEN_VXFORM_SIMM(vspltisw, 6, 14),
                   9165: 
                   9166: #undef GEN_VXFORM_NOA
                   9167: #define GEN_VXFORM_NOA(name, opc2, opc3)                                \
                   9168:     GEN_HANDLER(name, 0x04, opc2, opc3, 0x001f0000, PPC_ALTIVEC)
                   9169: GEN_VXFORM_NOA(vupkhsb, 7, 8),
                   9170: GEN_VXFORM_NOA(vupkhsh, 7, 9),
                   9171: GEN_VXFORM_NOA(vupklsb, 7, 10),
                   9172: GEN_VXFORM_NOA(vupklsh, 7, 11),
                   9173: GEN_VXFORM_NOA(vupkhpx, 7, 13),
                   9174: GEN_VXFORM_NOA(vupklpx, 7, 15),
                   9175: GEN_VXFORM_NOA(vrefp, 5, 4),
                   9176: GEN_VXFORM_NOA(vrsqrtefp, 5, 5),
1.1.1.9   root     9177: GEN_VXFORM_NOA(vexptefp, 5, 6),
1.1.1.7   root     9178: GEN_VXFORM_NOA(vlogefp, 5, 7),
                   9179: GEN_VXFORM_NOA(vrfim, 5, 8),
                   9180: GEN_VXFORM_NOA(vrfin, 5, 9),
                   9181: GEN_VXFORM_NOA(vrfip, 5, 10),
                   9182: GEN_VXFORM_NOA(vrfiz, 5, 11),
                   9183: 
                   9184: #undef GEN_VXFORM_UIMM
                   9185: #define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
                   9186:     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
                   9187: GEN_VXFORM_UIMM(vspltb, 6, 8),
                   9188: GEN_VXFORM_UIMM(vsplth, 6, 9),
                   9189: GEN_VXFORM_UIMM(vspltw, 6, 10),
                   9190: GEN_VXFORM_UIMM(vcfux, 5, 12),
                   9191: GEN_VXFORM_UIMM(vcfsx, 5, 13),
                   9192: GEN_VXFORM_UIMM(vctuxs, 5, 14),
                   9193: GEN_VXFORM_UIMM(vctsxs, 5, 15),
                   9194: 
                   9195: #undef GEN_VAFORM_PAIRED
                   9196: #define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
                   9197:     GEN_HANDLER(name0##_##name1, 0x04, opc2, 0xFF, 0x00000000, PPC_ALTIVEC)
                   9198: GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16),
                   9199: GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18),
                   9200: GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19),
                   9201: GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20),
                   9202: GEN_VAFORM_PAIRED(vsel, vperm, 21),
                   9203: GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23),
                   9204: 
                   9205: #undef GEN_SPE
1.1.1.12  root     9206: #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \
                   9207:     GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE)
                   9208: GEN_SPE(evaddw,      speundef,    0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
                   9209: GEN_SPE(evaddiw,     speundef,    0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
                   9210: GEN_SPE(evsubfw,     speundef,    0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
                   9211: GEN_SPE(evsubifw,    speundef,    0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
                   9212: GEN_SPE(evabs,       evneg,       0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
                   9213: GEN_SPE(evextsb,     evextsh,     0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
                   9214: GEN_SPE(evrndw,      evcntlzw,    0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
                   9215: GEN_SPE(evcntlsw,    brinc,       0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE),
                   9216: GEN_SPE(evmra,       speundef,    0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE),
                   9217: GEN_SPE(speundef,    evand,       0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
                   9218: GEN_SPE(evandc,      speundef,    0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
                   9219: GEN_SPE(evxor,       evor,        0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE),
                   9220: GEN_SPE(evnor,       eveqv,       0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE),
                   9221: GEN_SPE(evmwumi,     evmwsmi,     0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
                   9222: GEN_SPE(evmwumia,    evmwsmia,    0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
                   9223: GEN_SPE(evmwumiaa,   evmwsmiaa,   0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE),
                   9224: GEN_SPE(speundef,    evorc,       0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
                   9225: GEN_SPE(evnand,      speundef,    0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
                   9226: GEN_SPE(evsrwu,      evsrws,      0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE),
                   9227: GEN_SPE(evsrwiu,     evsrwis,     0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE),
                   9228: GEN_SPE(evslw,       speundef,    0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
                   9229: GEN_SPE(evslwi,      speundef,    0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
                   9230: GEN_SPE(evrlw,       evsplati,    0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
                   9231: GEN_SPE(evrlwi,      evsplatfi,   0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
                   9232: GEN_SPE(evmergehi,   evmergelo,   0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE),
                   9233: GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE),
                   9234: GEN_SPE(evcmpgtu,    evcmpgts,    0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE),
                   9235: GEN_SPE(evcmpltu,    evcmplts,    0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE),
                   9236: GEN_SPE(evcmpeq,     speundef,    0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE),
                   9237: 
                   9238: GEN_SPE(evfsadd,     evfssub,     0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
                   9239: GEN_SPE(evfsabs,     evfsnabs,    0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
                   9240: GEN_SPE(evfsneg,     speundef,    0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
                   9241: GEN_SPE(evfsmul,     evfsdiv,     0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
                   9242: GEN_SPE(evfscmpgt,   evfscmplt,   0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
                   9243: GEN_SPE(evfscmpeq,   speundef,    0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
                   9244: GEN_SPE(evfscfui,    evfscfsi,    0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
                   9245: GEN_SPE(evfscfuf,    evfscfsf,    0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
                   9246: GEN_SPE(evfsctui,    evfsctsi,    0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
                   9247: GEN_SPE(evfsctuf,    evfsctsf,    0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
                   9248: GEN_SPE(evfsctuiz,   speundef,    0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
                   9249: GEN_SPE(evfsctsiz,   speundef,    0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
                   9250: GEN_SPE(evfststgt,   evfststlt,   0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
                   9251: GEN_SPE(evfststeq,   speundef,    0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
                   9252: 
                   9253: GEN_SPE(efsadd,      efssub,      0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
                   9254: GEN_SPE(efsabs,      efsnabs,     0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
                   9255: GEN_SPE(efsneg,      speundef,    0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
                   9256: GEN_SPE(efsmul,      efsdiv,      0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
                   9257: GEN_SPE(efscmpgt,    efscmplt,    0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
                   9258: GEN_SPE(efscmpeq,    efscfd,      0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE),
                   9259: GEN_SPE(efscfui,     efscfsi,     0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
                   9260: GEN_SPE(efscfuf,     efscfsf,     0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
                   9261: GEN_SPE(efsctui,     efsctsi,     0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
                   9262: GEN_SPE(efsctuf,     efsctsf,     0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
                   9263: GEN_SPE(efsctuiz,    speundef,    0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
                   9264: GEN_SPE(efsctsiz,    speundef,    0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
                   9265: GEN_SPE(efststgt,    efststlt,    0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
                   9266: GEN_SPE(efststeq,    speundef,    0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
                   9267: 
                   9268: GEN_SPE(efdadd,      efdsub,      0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
                   9269: GEN_SPE(efdcfuid,    efdcfsid,    0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
                   9270: GEN_SPE(efdabs,      efdnabs,     0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE),
                   9271: GEN_SPE(efdneg,      speundef,    0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE),
                   9272: GEN_SPE(efdmul,      efddiv,      0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
                   9273: GEN_SPE(efdctuidz,   efdctsidz,   0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
                   9274: GEN_SPE(efdcmpgt,    efdcmplt,    0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
                   9275: GEN_SPE(efdcmpeq,    efdcfs,      0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE),
                   9276: GEN_SPE(efdcfui,     efdcfsi,     0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
                   9277: GEN_SPE(efdcfuf,     efdcfsf,     0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
                   9278: GEN_SPE(efdctui,     efdctsi,     0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
                   9279: GEN_SPE(efdctuf,     efdctsf,     0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
                   9280: GEN_SPE(efdctuiz,    speundef,    0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
                   9281: GEN_SPE(efdctsiz,    speundef,    0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
                   9282: GEN_SPE(efdtstgt,    efdtstlt,    0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
                   9283: GEN_SPE(efdtsteq,    speundef,    0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
1.1.1.7   root     9284: 
                   9285: #undef GEN_SPEOP_LDST
                   9286: #define GEN_SPEOP_LDST(name, opc2, sh)                                        \
                   9287: GEN_HANDLER(name, 0x04, opc2, 0x0C, 0x00000000, PPC_SPE)
                   9288: GEN_SPEOP_LDST(evldd, 0x00, 3),
                   9289: GEN_SPEOP_LDST(evldw, 0x01, 3),
                   9290: GEN_SPEOP_LDST(evldh, 0x02, 3),
                   9291: GEN_SPEOP_LDST(evlhhesplat, 0x04, 1),
                   9292: GEN_SPEOP_LDST(evlhhousplat, 0x06, 1),
                   9293: GEN_SPEOP_LDST(evlhhossplat, 0x07, 1),
                   9294: GEN_SPEOP_LDST(evlwhe, 0x08, 2),
                   9295: GEN_SPEOP_LDST(evlwhou, 0x0A, 2),
                   9296: GEN_SPEOP_LDST(evlwhos, 0x0B, 2),
                   9297: GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2),
                   9298: GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2),
                   9299: 
                   9300: GEN_SPEOP_LDST(evstdd, 0x10, 3),
                   9301: GEN_SPEOP_LDST(evstdw, 0x11, 3),
                   9302: GEN_SPEOP_LDST(evstdh, 0x12, 3),
                   9303: GEN_SPEOP_LDST(evstwhe, 0x18, 2),
                   9304: GEN_SPEOP_LDST(evstwho, 0x1A, 2),
                   9305: GEN_SPEOP_LDST(evstwwe, 0x1C, 2),
                   9306: GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
                   9307: };
1.1       root     9308: 
1.1.1.5   root     9309: #include "helper_regs.h"
1.1.1.13! root     9310: #include "translate_init.c"
1.1       root     9311: 
                   9312: /*****************************************************************************/
                   9313: /* Misc PowerPC helpers */
1.1.1.13! root     9314: void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
1.1.1.5   root     9315:                      int flags)
                   9316: {
1.1       root     9317: #define RGPL  4
                   9318: #define RFPL  4
                   9319: 
                   9320:     int i;
                   9321: 
1.1.1.13! root     9322:     cpu_synchronize_state(env);
        !          9323: 
1.1.1.8   root     9324:     cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
1.1.1.10  root     9325:                 TARGET_FMT_lx " XER " TARGET_FMT_lx "\n",
                   9326:                 env->nip, env->lr, env->ctr, env->xer);
1.1.1.8   root     9327:     cpu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx "  HF "
                   9328:                 TARGET_FMT_lx " idx %d\n", env->msr, env->spr[SPR_HID0],
                   9329:                 env->hflags, env->mmu_idx);
1.1.1.5   root     9330: #if !defined(NO_TIMER_DUMP)
1.1.1.10  root     9331:     cpu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
1.1.1.5   root     9332: #if !defined(CONFIG_USER_ONLY)
1.1.1.10  root     9333:                 " DECR %08" PRIu32
1.1.1.5   root     9334: #endif
                   9335:                 "\n",
                   9336:                 cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
                   9337: #if !defined(CONFIG_USER_ONLY)
                   9338:                 , cpu_ppc_load_decr(env)
                   9339: #endif
                   9340:                 );
                   9341: #endif
                   9342:     for (i = 0; i < 32; i++) {
1.1       root     9343:         if ((i & (RGPL - 1)) == 0)
                   9344:             cpu_fprintf(f, "GPR%02d", i);
1.1.1.8   root     9345:         cpu_fprintf(f, " %016" PRIx64, ppc_dump_gpr(env, i));
1.1       root     9346:         if ((i & (RGPL - 1)) == (RGPL - 1))
                   9347:             cpu_fprintf(f, "\n");
1.1.1.5   root     9348:     }
1.1       root     9349:     cpu_fprintf(f, "CR ");
1.1.1.5   root     9350:     for (i = 0; i < 8; i++)
1.1       root     9351:         cpu_fprintf(f, "%01x", env->crf[i]);
                   9352:     cpu_fprintf(f, "  [");
1.1.1.5   root     9353:     for (i = 0; i < 8; i++) {
                   9354:         char a = '-';
                   9355:         if (env->crf[i] & 0x08)
                   9356:             a = 'L';
                   9357:         else if (env->crf[i] & 0x04)
                   9358:             a = 'G';
                   9359:         else if (env->crf[i] & 0x02)
                   9360:             a = 'E';
1.1       root     9361:         cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
1.1.1.5   root     9362:     }
1.1.1.8   root     9363:     cpu_fprintf(f, " ]             RES " TARGET_FMT_lx "\n",
                   9364:                 env->reserve_addr);
1.1       root     9365:     for (i = 0; i < 32; i++) {
                   9366:         if ((i & (RFPL - 1)) == 0)
                   9367:             cpu_fprintf(f, "FPR%02d", i);
1.1.1.3   root     9368:         cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
1.1       root     9369:         if ((i & (RFPL - 1)) == (RFPL - 1))
                   9370:             cpu_fprintf(f, "\n");
                   9371:     }
1.1.1.6   root     9372:     cpu_fprintf(f, "FPSCR %08x\n", env->fpscr);
1.1.1.5   root     9373: #if !defined(CONFIG_USER_ONLY)
1.1.1.11  root     9374:     cpu_fprintf(f, " SRR0 " TARGET_FMT_lx "  SRR1 " TARGET_FMT_lx
                   9375:                    "    PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n",
                   9376:                 env->spr[SPR_SRR0], env->spr[SPR_SRR1],
                   9377:                 env->spr[SPR_PVR], env->spr[SPR_VRSAVE]);
                   9378: 
                   9379:     cpu_fprintf(f, "SPRG0 " TARGET_FMT_lx " SPRG1 " TARGET_FMT_lx
                   9380:                    "  SPRG2 " TARGET_FMT_lx "  SPRG3 " TARGET_FMT_lx "\n",
                   9381:                 env->spr[SPR_SPRG0], env->spr[SPR_SPRG1],
                   9382:                 env->spr[SPR_SPRG2], env->spr[SPR_SPRG3]);
                   9383: 
                   9384:     cpu_fprintf(f, "SPRG4 " TARGET_FMT_lx " SPRG5 " TARGET_FMT_lx
                   9385:                    "  SPRG6 " TARGET_FMT_lx "  SPRG7 " TARGET_FMT_lx "\n",
                   9386:                 env->spr[SPR_SPRG4], env->spr[SPR_SPRG5],
                   9387:                 env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]);
                   9388: 
                   9389:     if (env->excp_model == POWERPC_EXCP_BOOKE) {
                   9390:         cpu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx
                   9391:                        " MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n",
                   9392:                     env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
                   9393:                     env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
                   9394: 
                   9395:         cpu_fprintf(f, "  TCR " TARGET_FMT_lx "   TSR " TARGET_FMT_lx
                   9396:                        "    ESR " TARGET_FMT_lx "   DEAR " TARGET_FMT_lx "\n",
                   9397:                     env->spr[SPR_BOOKE_TCR], env->spr[SPR_BOOKE_TSR],
                   9398:                     env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
                   9399: 
                   9400:         cpu_fprintf(f, "  PIR " TARGET_FMT_lx " DECAR " TARGET_FMT_lx
                   9401:                        "   IVPR " TARGET_FMT_lx "   EPCR " TARGET_FMT_lx "\n",
                   9402:                     env->spr[SPR_BOOKE_PIR], env->spr[SPR_BOOKE_DECAR],
                   9403:                     env->spr[SPR_BOOKE_IVPR], env->spr[SPR_BOOKE_EPCR]);
                   9404: 
                   9405:         cpu_fprintf(f, " MCSR " TARGET_FMT_lx " SPRG8 " TARGET_FMT_lx
                   9406:                        "    EPR " TARGET_FMT_lx "\n",
                   9407:                     env->spr[SPR_BOOKE_MCSR], env->spr[SPR_BOOKE_SPRG8],
                   9408:                     env->spr[SPR_BOOKE_EPR]);
                   9409: 
                   9410:         /* FSL-specific */
                   9411:         cpu_fprintf(f, " MCAR " TARGET_FMT_lx "  PID1 " TARGET_FMT_lx
                   9412:                        "   PID2 " TARGET_FMT_lx "    SVR " TARGET_FMT_lx "\n",
                   9413:                     env->spr[SPR_Exxx_MCAR], env->spr[SPR_BOOKE_PID1],
                   9414:                     env->spr[SPR_BOOKE_PID2], env->spr[SPR_E500_SVR]);
                   9415: 
                   9416:         /*
                   9417:          * IVORs are left out as they are large and do not change often --
                   9418:          * they can be read with "p $ivor0", "p $ivor1", etc.
                   9419:          */
                   9420:     }
                   9421: 
1.1.1.12  root     9422: #if defined(TARGET_PPC64)
                   9423:     if (env->flags & POWERPC_FLAG_CFAR) {
                   9424:         cpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);
                   9425:     }
                   9426: #endif
                   9427: 
1.1.1.11  root     9428:     switch (env->mmu_model) {
                   9429:     case POWERPC_MMU_32B:
                   9430:     case POWERPC_MMU_601:
                   9431:     case POWERPC_MMU_SOFT_6xx:
                   9432:     case POWERPC_MMU_SOFT_74xx:
                   9433: #if defined(TARGET_PPC64)
                   9434:     case POWERPC_MMU_620:
                   9435:     case POWERPC_MMU_64B:
                   9436: #endif
                   9437:         cpu_fprintf(f, " SDR1 " TARGET_FMT_lx "\n", env->spr[SPR_SDR1]);
                   9438:         break;
                   9439:     case POWERPC_MMU_BOOKE206:
                   9440:         cpu_fprintf(f, " MAS0 " TARGET_FMT_lx "  MAS1 " TARGET_FMT_lx
                   9441:                        "   MAS2 " TARGET_FMT_lx "   MAS3 " TARGET_FMT_lx "\n",
                   9442:                     env->spr[SPR_BOOKE_MAS0], env->spr[SPR_BOOKE_MAS1],
                   9443:                     env->spr[SPR_BOOKE_MAS2], env->spr[SPR_BOOKE_MAS3]);
                   9444: 
                   9445:         cpu_fprintf(f, " MAS4 " TARGET_FMT_lx "  MAS6 " TARGET_FMT_lx
                   9446:                        "   MAS7 " TARGET_FMT_lx "    PID " TARGET_FMT_lx "\n",
                   9447:                     env->spr[SPR_BOOKE_MAS4], env->spr[SPR_BOOKE_MAS6],
                   9448:                     env->spr[SPR_BOOKE_MAS7], env->spr[SPR_BOOKE_PID]);
                   9449: 
                   9450:         cpu_fprintf(f, "MMUCFG " TARGET_FMT_lx " TLB0CFG " TARGET_FMT_lx
                   9451:                        " TLB1CFG " TARGET_FMT_lx "\n",
                   9452:                     env->spr[SPR_MMUCFG], env->spr[SPR_BOOKE_TLB0CFG],
                   9453:                     env->spr[SPR_BOOKE_TLB1CFG]);
                   9454:         break;
                   9455:     default:
                   9456:         break;
                   9457:     }
1.1.1.5   root     9458: #endif
1.1       root     9459: 
                   9460: #undef RGPL
                   9461: #undef RFPL
1.1.1.5   root     9462: }
                   9463: 
1.1.1.13! root     9464: void cpu_dump_statistics (CPUPPCState *env, FILE*f, fprintf_function cpu_fprintf,
1.1.1.5   root     9465:                           int flags)
                   9466: {
                   9467: #if defined(DO_PPC_STATISTICS)
                   9468:     opc_handler_t **t1, **t2, **t3, *handler;
                   9469:     int op1, op2, op3;
                   9470: 
                   9471:     t1 = env->opcodes;
                   9472:     for (op1 = 0; op1 < 64; op1++) {
                   9473:         handler = t1[op1];
                   9474:         if (is_indirect_opcode(handler)) {
                   9475:             t2 = ind_table(handler);
                   9476:             for (op2 = 0; op2 < 32; op2++) {
                   9477:                 handler = t2[op2];
                   9478:                 if (is_indirect_opcode(handler)) {
                   9479:                     t3 = ind_table(handler);
                   9480:                     for (op3 = 0; op3 < 32; op3++) {
                   9481:                         handler = t3[op3];
                   9482:                         if (handler->count == 0)
                   9483:                             continue;
                   9484:                         cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
1.1.1.9   root     9485:                                     "%016" PRIx64 " %" PRId64 "\n",
1.1.1.5   root     9486:                                     op1, op2, op3, op1, (op3 << 5) | op2,
                   9487:                                     handler->oname,
                   9488:                                     handler->count, handler->count);
                   9489:                     }
                   9490:                 } else {
                   9491:                     if (handler->count == 0)
                   9492:                         continue;
                   9493:                     cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
1.1.1.9   root     9494:                                 "%016" PRIx64 " %" PRId64 "\n",
1.1.1.5   root     9495:                                 op1, op2, op1, op2, handler->oname,
                   9496:                                 handler->count, handler->count);
                   9497:                 }
                   9498:             }
                   9499:         } else {
                   9500:             if (handler->count == 0)
                   9501:                 continue;
1.1.1.9   root     9502:             cpu_fprintf(f, "%02x       (%02x     ) %16s: %016" PRIx64
                   9503:                         " %" PRId64 "\n",
1.1.1.5   root     9504:                         op1, op1, handler->oname,
                   9505:                         handler->count, handler->count);
                   9506:         }
                   9507:     }
                   9508: #endif
1.1       root     9509: }
                   9510: 
                   9511: /*****************************************************************************/
1.1.1.13! root     9512: static inline void gen_intermediate_code_internal(CPUPPCState *env,
1.1.1.8   root     9513:                                                   TranslationBlock *tb,
                   9514:                                                   int search_pc)
1.1       root     9515: {
                   9516:     DisasContext ctx, *ctxp = &ctx;
                   9517:     opc_handler_t **table, *handler;
                   9518:     target_ulong pc_start;
                   9519:     uint16_t *gen_opc_end;
1.1.1.6   root     9520:     CPUBreakpoint *bp;
1.1       root     9521:     int j, lj = -1;
1.1.1.6   root     9522:     int num_insns;
                   9523:     int max_insns;
1.1       root     9524: 
                   9525:     pc_start = tb->pc;
                   9526:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
                   9527:     ctx.nip = pc_start;
                   9528:     ctx.tb = tb;
1.1.1.5   root     9529:     ctx.exception = POWERPC_EXCP_NONE;
1.1       root     9530:     ctx.spr_cb = env->spr_cb;
1.1.1.6   root     9531:     ctx.mem_idx = env->mmu_idx;
                   9532:     ctx.access_type = -1;
                   9533:     ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
1.1.1.5   root     9534: #if defined(TARGET_PPC64)
                   9535:     ctx.sf_mode = msr_sf;
1.1.1.12  root     9536:     ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
1.1       root     9537: #endif
                   9538:     ctx.fpu_enabled = msr_fp;
1.1.1.5   root     9539:     if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
                   9540:         ctx.spe_enabled = msr_spe;
                   9541:     else
                   9542:         ctx.spe_enabled = 0;
                   9543:     if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
                   9544:         ctx.altivec_enabled = msr_vr;
                   9545:     else
                   9546:         ctx.altivec_enabled = 0;
                   9547:     if ((env->flags & POWERPC_FLAG_SE) && msr_se)
1.1.1.6   root     9548:         ctx.singlestep_enabled = CPU_SINGLE_STEP;
1.1.1.5   root     9549:     else
1.1.1.6   root     9550:         ctx.singlestep_enabled = 0;
1.1.1.5   root     9551:     if ((env->flags & POWERPC_FLAG_BE) && msr_be)
1.1.1.6   root     9552:         ctx.singlestep_enabled |= CPU_BRANCH_STEP;
                   9553:     if (unlikely(env->singlestep_enabled))
                   9554:         ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
1.1       root     9555: #if defined (DO_SINGLE_STEP) && 0
                   9556:     /* Single step trace mode */
                   9557:     msr_se = 1;
                   9558: #endif
1.1.1.6   root     9559:     num_insns = 0;
                   9560:     max_insns = tb->cflags & CF_COUNT_MASK;
                   9561:     if (max_insns == 0)
                   9562:         max_insns = CF_COUNT_MASK;
                   9563: 
                   9564:     gen_icount_start();
1.1       root     9565:     /* Set env in case of segfault during code fetch */
1.1.1.5   root     9566:     while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
1.1.1.8   root     9567:         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
                   9568:             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
1.1.1.6   root     9569:                 if (bp->pc == ctx.nip) {
                   9570:                     gen_debug_exception(ctxp);
1.1.1.3   root     9571:                     break;
                   9572:                 }
                   9573:             }
                   9574:         }
1.1.1.5   root     9575:         if (unlikely(search_pc)) {
1.1       root     9576:             j = gen_opc_ptr - gen_opc_buf;
                   9577:             if (lj < j) {
                   9578:                 lj++;
                   9579:                 while (lj < j)
                   9580:                     gen_opc_instr_start[lj++] = 0;
                   9581:             }
1.1.1.7   root     9582:             gen_opc_pc[lj] = ctx.nip;
                   9583:             gen_opc_instr_start[lj] = 1;
                   9584:             gen_opc_icount[lj] = num_insns;
1.1       root     9585:         }
1.1.1.6   root     9586:         LOG_DISAS("----------------\n");
1.1.1.8   root     9587:         LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
1.1.1.6   root     9588:                   ctx.nip, ctx.mem_idx, (int)msr_ir);
                   9589:         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
                   9590:             gen_io_start();
                   9591:         if (unlikely(ctx.le_mode)) {
1.1.1.5   root     9592:             ctx.opcode = bswap32(ldl_code(ctx.nip));
                   9593:         } else {
                   9594:             ctx.opcode = ldl_code(ctx.nip);
1.1       root     9595:         }
1.1.1.6   root     9596:         LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",
1.1       root     9597:                     ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
1.1.1.5   root     9598:                     opc3(ctx.opcode), little_endian ? "little" : "big");
1.1.1.8   root     9599:         if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
                   9600:             tcg_gen_debug_insn_start(ctx.nip);
1.1       root     9601:         ctx.nip += 4;
                   9602:         table = env->opcodes;
1.1.1.6   root     9603:         num_insns++;
1.1       root     9604:         handler = table[opc1(ctx.opcode)];
                   9605:         if (is_indirect_opcode(handler)) {
                   9606:             table = ind_table(handler);
                   9607:             handler = table[opc2(ctx.opcode)];
                   9608:             if (is_indirect_opcode(handler)) {
                   9609:                 table = ind_table(handler);
                   9610:                 handler = table[opc3(ctx.opcode)];
                   9611:             }
                   9612:         }
                   9613:         /* Is opcode *REALLY* valid ? */
1.1.1.5   root     9614:         if (unlikely(handler->handler == &gen_invalid)) {
1.1.1.6   root     9615:             if (qemu_log_enabled()) {
                   9616:                 qemu_log("invalid/unsupported opcode: "
1.1.1.8   root     9617:                          "%02x - %02x - %02x (%08x) " TARGET_FMT_lx " %d\n",
                   9618:                          opc1(ctx.opcode), opc2(ctx.opcode),
                   9619:                          opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
1.1       root     9620:             }
1.1.1.5   root     9621:         } else {
1.1.1.12  root     9622:             uint32_t inval;
                   9623: 
                   9624:             if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE) && Rc(ctx.opcode))) {
                   9625:                 inval = handler->inval2;
                   9626:             } else {
                   9627:                 inval = handler->inval1;
                   9628:             }
                   9629: 
                   9630:             if (unlikely((ctx.opcode & inval) != 0)) {
1.1.1.6   root     9631:                 if (qemu_log_enabled()) {
                   9632:                     qemu_log("invalid bits: %08x for opcode: "
1.1.1.8   root     9633:                              "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n",
1.1.1.12  root     9634:                              ctx.opcode & inval, opc1(ctx.opcode),
1.1.1.8   root     9635:                              opc2(ctx.opcode), opc3(ctx.opcode),
                   9636:                              ctx.opcode, ctx.nip - 4);
1.1.1.5   root     9637:                 }
1.1.1.6   root     9638:                 gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
1.1       root     9639:                 break;
                   9640:             }
                   9641:         }
                   9642:         (*(handler->handler))(&ctx);
1.1.1.5   root     9643: #if defined(DO_PPC_STATISTICS)
                   9644:         handler->count++;
                   9645: #endif
1.1       root     9646:         /* Check trace mode exceptions */
1.1.1.6   root     9647:         if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
                   9648:                      (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
                   9649:                      ctx.exception != POWERPC_SYSCALL &&
                   9650:                      ctx.exception != POWERPC_EXCP_TRAP &&
                   9651:                      ctx.exception != POWERPC_EXCP_BRANCH)) {
                   9652:             gen_exception(ctxp, POWERPC_EXCP_TRACE);
1.1.1.5   root     9653:         } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
1.1.1.6   root     9654:                             (env->singlestep_enabled) ||
1.1.1.7   root     9655:                             singlestep ||
1.1.1.6   root     9656:                             num_insns >= max_insns)) {
1.1.1.5   root     9657:             /* if we reach a page boundary or are single stepping, stop
                   9658:              * generation
1.1       root     9659:              */
                   9660:             break;
1.1.1.5   root     9661:         }
1.1       root     9662:     }
1.1.1.6   root     9663:     if (tb->cflags & CF_LAST_IO)
                   9664:         gen_io_end();
1.1.1.5   root     9665:     if (ctx.exception == POWERPC_EXCP_NONE) {
1.1.1.2   root     9666:         gen_goto_tb(&ctx, 0, ctx.nip);
1.1.1.5   root     9667:     } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
1.1.1.6   root     9668:         if (unlikely(env->singlestep_enabled)) {
                   9669:             gen_debug_exception(ctxp);
                   9670:         }
1.1.1.5   root     9671:         /* Generate the return instruction */
1.1.1.6   root     9672:         tcg_gen_exit_tb(0);
1.1       root     9673:     }
1.1.1.6   root     9674:     gen_icount_end(tb, num_insns);
1.1       root     9675:     *gen_opc_ptr = INDEX_op_end;
1.1.1.5   root     9676:     if (unlikely(search_pc)) {
1.1       root     9677:         j = gen_opc_ptr - gen_opc_buf;
                   9678:         lj++;
                   9679:         while (lj <= j)
                   9680:             gen_opc_instr_start[lj++] = 0;
                   9681:     } else {
                   9682:         tb->size = ctx.nip - pc_start;
1.1.1.6   root     9683:         tb->icount = num_insns;
1.1       root     9684:     }
1.1.1.5   root     9685: #if defined(DEBUG_DISAS)
1.1.1.6   root     9686:     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1.1.1.5   root     9687:         int flags;
                   9688:         flags = env->bfd_mach;
1.1.1.6   root     9689:         flags |= ctx.le_mode << 16;
                   9690:         qemu_log("IN: %s\n", lookup_symbol(pc_start));
                   9691:         log_target_disas(pc_start, ctx.nip - pc_start, flags);
                   9692:         qemu_log("\n");
1.1       root     9693:     }
                   9694: #endif
                   9695: }
                   9696: 
1.1.1.13! root     9697: void gen_intermediate_code (CPUPPCState *env, struct TranslationBlock *tb)
1.1.1.6   root     9698: {
                   9699:     gen_intermediate_code_internal(env, tb, 0);
                   9700: }
                   9701: 
1.1.1.13! root     9702: void gen_intermediate_code_pc (CPUPPCState *env, struct TranslationBlock *tb)
1.1       root     9703: {
1.1.1.6   root     9704:     gen_intermediate_code_internal(env, tb, 1);
1.1       root     9705: }
                   9706: 
1.1.1.13! root     9707: void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb, int pc_pos)
1.1       root     9708: {
1.1.1.6   root     9709:     env->nip = gen_opc_pc[pc_pos];
1.1       root     9710: }

unix.superglobalmegacorp.com

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