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

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: #include <stdarg.h>
                     21: #include <stdlib.h>
                     22: #include <stdio.h>
                     23: #include <string.h>
                     24: #include <inttypes.h>
                     25: 
                     26: #include "cpu.h"
                     27: #include "disas.h"
1.1.1.6   root       28: #include "tcg-op.h"
                     29: #include "qemu-common.h"
                     30: #include "host-utils.h"
                     31: 
                     32: #include "helper.h"
                     33: #define GEN_HELPER 1
                     34: #include "helper.h"
                     35: 
                     36: #define CPU_SINGLE_STEP 0x1
                     37: #define CPU_BRANCH_STEP 0x2
                     38: #define GDBSTUB_SINGLE_STEP 0x4
1.1       root       39: 
1.1.1.5   root       40: /* Include definitions for instructions classes and implementations flags */
1.1       root       41: //#define PPC_DEBUG_DISAS
1.1.1.5   root       42: //#define DO_PPC_STATISTICS
1.1       root       43: 
1.1.1.6   root       44: #ifdef PPC_DEBUG_DISAS
                     45: #  define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
1.1.1.2   root       46: #else
1.1.1.6   root       47: #  define LOG_DISAS(...) do { } while (0)
1.1.1.2   root       48: #endif
1.1.1.6   root       49: /*****************************************************************************/
                     50: /* Code translation helpers                                                  */
1.1.1.2   root       51: 
1.1.1.6   root       52: /* global register indexes */
                     53: static TCGv_ptr cpu_env;
                     54: static char cpu_reg_names[10*3 + 22*4 /* GPR */
                     55: #if !defined(TARGET_PPC64)
                     56:     + 10*4 + 22*5 /* SPE GPRh */
1.1.1.5   root       57: #endif
1.1.1.6   root       58:     + 10*4 + 22*5 /* FPR */
                     59:     + 2*(10*6 + 22*7) /* AVRh, AVRl */
                     60:     + 8*5 /* CRF */];
                     61: static TCGv cpu_gpr[32];
                     62: #if !defined(TARGET_PPC64)
                     63: static TCGv cpu_gprh[32];
                     64: #endif
                     65: static TCGv_i64 cpu_fpr[32];
                     66: static TCGv_i64 cpu_avrh[32], cpu_avrl[32];
                     67: static TCGv_i32 cpu_crf[8];
                     68: static TCGv cpu_nip;
                     69: static TCGv cpu_msr;
                     70: static TCGv cpu_ctr;
                     71: static TCGv cpu_lr;
1.1.1.12! root       72: #if defined(TARGET_PPC64)
        !            73: static TCGv cpu_cfar;
        !            74: #endif
1.1.1.6   root       75: static TCGv cpu_xer;
                     76: static TCGv cpu_reserve;
                     77: static TCGv_i32 cpu_fpscr;
                     78: static TCGv_i32 cpu_access_type;
1.1       root       79: 
1.1.1.6   root       80: #include "gen-icount.h"
1.1       root       81: 
1.1.1.6   root       82: void ppc_translate_init(void)
1.1.1.5   root       83: {
1.1.1.6   root       84:     int i;
                     85:     char* p;
1.1.1.7   root       86:     size_t cpu_reg_names_size;
1.1.1.6   root       87:     static int done_init = 0;
                     88: 
                     89:     if (done_init)
                     90:         return;
                     91: 
                     92:     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
                     93: 
                     94:     p = cpu_reg_names;
1.1.1.7   root       95:     cpu_reg_names_size = sizeof(cpu_reg_names);
1.1.1.6   root       96: 
                     97:     for (i = 0; i < 8; i++) {
1.1.1.7   root       98:         snprintf(p, cpu_reg_names_size, "crf%d", i);
1.1.1.6   root       99:         cpu_crf[i] = tcg_global_mem_new_i32(TCG_AREG0,
                    100:                                             offsetof(CPUState, crf[i]), p);
                    101:         p += 5;
1.1.1.7   root      102:         cpu_reg_names_size -= 5;
1.1.1.6   root      103:     }
                    104: 
                    105:     for (i = 0; i < 32; i++) {
1.1.1.7   root      106:         snprintf(p, cpu_reg_names_size, "r%d", i);
1.1.1.6   root      107:         cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
                    108:                                         offsetof(CPUState, gpr[i]), p);
                    109:         p += (i < 10) ? 3 : 4;
1.1.1.7   root      110:         cpu_reg_names_size -= (i < 10) ? 3 : 4;
1.1.1.6   root      111: #if !defined(TARGET_PPC64)
1.1.1.7   root      112:         snprintf(p, cpu_reg_names_size, "r%dH", i);
1.1.1.6   root      113:         cpu_gprh[i] = tcg_global_mem_new_i32(TCG_AREG0,
                    114:                                              offsetof(CPUState, gprh[i]), p);
                    115:         p += (i < 10) ? 4 : 5;
1.1.1.7   root      116:         cpu_reg_names_size -= (i < 10) ? 4 : 5;
1.1.1.5   root      117: #endif
                    118: 
1.1.1.7   root      119:         snprintf(p, cpu_reg_names_size, "fp%d", i);
1.1.1.6   root      120:         cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0,
                    121:                                             offsetof(CPUState, fpr[i]), p);
                    122:         p += (i < 10) ? 4 : 5;
1.1.1.7   root      123:         cpu_reg_names_size -= (i < 10) ? 4 : 5;
1.1.1.6   root      124: 
1.1.1.7   root      125:         snprintf(p, cpu_reg_names_size, "avr%dH", i);
1.1.1.8   root      126: #ifdef HOST_WORDS_BIGENDIAN
1.1.1.6   root      127:         cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
                    128:                                              offsetof(CPUState, avr[i].u64[0]), p);
                    129: #else
                    130:         cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
                    131:                                              offsetof(CPUState, avr[i].u64[1]), p);
1.1.1.5   root      132: #endif
1.1.1.6   root      133:         p += (i < 10) ? 6 : 7;
1.1.1.7   root      134:         cpu_reg_names_size -= (i < 10) ? 6 : 7;
1.1.1.5   root      135: 
1.1.1.7   root      136:         snprintf(p, cpu_reg_names_size, "avr%dL", i);
1.1.1.8   root      137: #ifdef HOST_WORDS_BIGENDIAN
1.1.1.6   root      138:         cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
                    139:                                              offsetof(CPUState, avr[i].u64[1]), p);
                    140: #else
                    141:         cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
                    142:                                              offsetof(CPUState, avr[i].u64[0]), p);
1.1.1.5   root      143: #endif
1.1.1.6   root      144:         p += (i < 10) ? 6 : 7;
1.1.1.7   root      145:         cpu_reg_names_size -= (i < 10) ? 6 : 7;
1.1.1.6   root      146:     }
                    147: 
                    148:     cpu_nip = tcg_global_mem_new(TCG_AREG0,
                    149:                                  offsetof(CPUState, nip), "nip");
                    150: 
                    151:     cpu_msr = tcg_global_mem_new(TCG_AREG0,
                    152:                                  offsetof(CPUState, msr), "msr");
                    153: 
                    154:     cpu_ctr = tcg_global_mem_new(TCG_AREG0,
                    155:                                  offsetof(CPUState, ctr), "ctr");
                    156: 
                    157:     cpu_lr = tcg_global_mem_new(TCG_AREG0,
                    158:                                 offsetof(CPUState, lr), "lr");
                    159: 
1.1.1.12! root      160: #if defined(TARGET_PPC64)
        !           161:     cpu_cfar = tcg_global_mem_new(TCG_AREG0,
        !           162:                                   offsetof(CPUState, cfar), "cfar");
        !           163: #endif
        !           164: 
1.1.1.6   root      165:     cpu_xer = tcg_global_mem_new(TCG_AREG0,
                    166:                                  offsetof(CPUState, xer), "xer");
                    167: 
                    168:     cpu_reserve = tcg_global_mem_new(TCG_AREG0,
1.1.1.8   root      169:                                      offsetof(CPUState, reserve_addr),
                    170:                                      "reserve_addr");
1.1.1.6   root      171: 
                    172:     cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0,
                    173:                                        offsetof(CPUState, fpscr), "fpscr");
                    174: 
                    175:     cpu_access_type = tcg_global_mem_new_i32(TCG_AREG0,
                    176:                                              offsetof(CPUState, access_type), "access_type");
                    177: 
                    178:     /* register helpers */
                    179: #define GEN_HELPER 2
                    180: #include "helper.h"
                    181: 
                    182:     done_init = 1;
                    183: }
1.1       root      184: 
                    185: /* internal defines */
                    186: typedef struct DisasContext {
                    187:     struct TranslationBlock *tb;
                    188:     target_ulong nip;
                    189:     uint32_t opcode;
                    190:     uint32_t exception;
                    191:     /* Routine used to access memory */
                    192:     int mem_idx;
1.1.1.6   root      193:     int access_type;
1.1       root      194:     /* Translation flags */
1.1.1.6   root      195:     int le_mode;
1.1.1.5   root      196: #if defined(TARGET_PPC64)
                    197:     int sf_mode;
1.1.1.12! root      198:     int has_cfar;
1.1.1.5   root      199: #endif
1.1       root      200:     int fpu_enabled;
1.1.1.5   root      201:     int altivec_enabled;
                    202:     int spe_enabled;
1.1       root      203:     ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
1.1.1.3   root      204:     int singlestep_enabled;
1.1       root      205: } DisasContext;
                    206: 
                    207: struct opc_handler_t {
1.1.1.12! root      208:     /* invalid bits for instruction 1 (Rc(opcode) == 0) */
        !           209:     uint32_t inval1;
        !           210:     /* invalid bits for instruction 2 (Rc(opcode) == 1) */
        !           211:     uint32_t inval2;
1.1       root      212:     /* instruction type */
1.1.1.5   root      213:     uint64_t type;
1.1.1.11  root      214:     /* extended instruction type */
                    215:     uint64_t type2;
1.1       root      216:     /* handler */
                    217:     void (*handler)(DisasContext *ctx);
1.1.1.5   root      218: #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
1.1.1.6   root      219:     const char *oname;
1.1.1.5   root      220: #endif
                    221: #if defined(DO_PPC_STATISTICS)
                    222:     uint64_t count;
                    223: #endif
1.1       root      224: };
                    225: 
1.1.1.8   root      226: static inline void gen_reset_fpstatus(void)
1.1.1.5   root      227: {
1.1.1.6   root      228:     gen_helper_reset_fpstatus();
1.1.1.5   root      229: }
                    230: 
1.1.1.8   root      231: static inline void gen_compute_fprf(TCGv_i64 arg, int set_fprf, int set_rc)
1.1.1.5   root      232: {
1.1.1.6   root      233:     TCGv_i32 t0 = tcg_temp_new_i32();
                    234: 
1.1.1.5   root      235:     if (set_fprf != 0) {
                    236:         /* This case might be optimized later */
1.1.1.6   root      237:         tcg_gen_movi_i32(t0, 1);
                    238:         gen_helper_compute_fprf(t0, arg, t0);
                    239:         if (unlikely(set_rc)) {
                    240:             tcg_gen_mov_i32(cpu_crf[1], t0);
                    241:         }
                    242:         gen_helper_float_check_status();
1.1.1.5   root      243:     } else if (unlikely(set_rc)) {
                    244:         /* We always need to compute fpcc */
1.1.1.6   root      245:         tcg_gen_movi_i32(t0, 0);
                    246:         gen_helper_compute_fprf(t0, arg, t0);
                    247:         tcg_gen_mov_i32(cpu_crf[1], t0);
1.1.1.5   root      248:     }
1.1.1.6   root      249: 
                    250:     tcg_temp_free_i32(t0);
1.1.1.5   root      251: }
                    252: 
1.1.1.8   root      253: static inline void gen_set_access_type(DisasContext *ctx, int access_type)
1.1.1.5   root      254: {
1.1.1.6   root      255:     if (ctx->access_type != access_type) {
                    256:         tcg_gen_movi_i32(cpu_access_type, access_type);
                    257:         ctx->access_type = access_type;
                    258:     }
1.1.1.5   root      259: }
                    260: 
1.1.1.8   root      261: static inline void gen_update_nip(DisasContext *ctx, target_ulong nip)
1.1.1.5   root      262: {
                    263: #if defined(TARGET_PPC64)
                    264:     if (ctx->sf_mode)
1.1.1.6   root      265:         tcg_gen_movi_tl(cpu_nip, nip);
1.1.1.5   root      266:     else
                    267: #endif
1.1.1.6   root      268:         tcg_gen_movi_tl(cpu_nip, (uint32_t)nip);
1.1.1.5   root      269: }
                    270: 
1.1.1.8   root      271: static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
1.1.1.6   root      272: {
                    273:     TCGv_i32 t0, t1;
                    274:     if (ctx->exception == POWERPC_EXCP_NONE) {
                    275:         gen_update_nip(ctx, ctx->nip);
                    276:     }
                    277:     t0 = tcg_const_i32(excp);
                    278:     t1 = tcg_const_i32(error);
                    279:     gen_helper_raise_exception_err(t0, t1);
                    280:     tcg_temp_free_i32(t0);
                    281:     tcg_temp_free_i32(t1);
                    282:     ctx->exception = (excp);
                    283: }
1.1.1.5   root      284: 
1.1.1.8   root      285: static inline void gen_exception(DisasContext *ctx, uint32_t excp)
1.1.1.6   root      286: {
                    287:     TCGv_i32 t0;
                    288:     if (ctx->exception == POWERPC_EXCP_NONE) {
                    289:         gen_update_nip(ctx, ctx->nip);
                    290:     }
                    291:     t0 = tcg_const_i32(excp);
                    292:     gen_helper_raise_exception(t0);
                    293:     tcg_temp_free_i32(t0);
                    294:     ctx->exception = (excp);
                    295: }
1.1.1.5   root      296: 
1.1.1.8   root      297: static inline void gen_debug_exception(DisasContext *ctx)
1.1.1.6   root      298: {
                    299:     TCGv_i32 t0;
1.1       root      300: 
1.1.1.12! root      301:     if ((ctx->exception != POWERPC_EXCP_BRANCH) &&
        !           302:         (ctx->exception != POWERPC_EXCP_SYNC)) {
1.1.1.6   root      303:         gen_update_nip(ctx, ctx->nip);
1.1.1.12! root      304:     }
1.1.1.6   root      305:     t0 = tcg_const_i32(EXCP_DEBUG);
                    306:     gen_helper_raise_exception(t0);
                    307:     tcg_temp_free_i32(t0);
                    308: }
1.1       root      309: 
1.1.1.8   root      310: static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
1.1.1.6   root      311: {
                    312:     gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | error);
                    313: }
1.1       root      314: 
1.1.1.2   root      315: /* Stop translation */
1.1.1.8   root      316: static inline void gen_stop_exception(DisasContext *ctx)
1.1       root      317: {
1.1.1.5   root      318:     gen_update_nip(ctx, ctx->nip);
                    319:     ctx->exception = POWERPC_EXCP_STOP;
1.1       root      320: }
                    321: 
1.1.1.2   root      322: /* No need to update nip here, as execution flow will change */
1.1.1.8   root      323: static inline void gen_sync_exception(DisasContext *ctx)
1.1       root      324: {
1.1.1.5   root      325:     ctx->exception = POWERPC_EXCP_SYNC;
1.1       root      326: }
                    327: 
                    328: #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
1.1.1.11  root      329: GEN_OPCODE(name, opc1, opc2, opc3, inval, type, PPC_NONE)
                    330: 
                    331: #define GEN_HANDLER_E(name, opc1, opc2, opc3, inval, type, type2)             \
                    332: GEN_OPCODE(name, opc1, opc2, opc3, inval, type, type2)
1.1       root      333: 
1.1.1.5   root      334: #define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
1.1.1.11  root      335: GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, PPC_NONE)
                    336: 
                    337: #define GEN_HANDLER2_E(name, onam, opc1, opc2, opc3, inval, type, type2)      \
                    338: GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, type2)
1.1.1.5   root      339: 
1.1       root      340: typedef struct opcode_t {
                    341:     unsigned char opc1, opc2, opc3;
1.1.1.6   root      342: #if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
1.1       root      343:     unsigned char pad[5];
                    344: #else
                    345:     unsigned char pad[1];
                    346: #endif
                    347:     opc_handler_t handler;
1.1.1.6   root      348:     const char *oname;
1.1       root      349: } opcode_t;
                    350: 
1.1.1.5   root      351: /*****************************************************************************/
1.1       root      352: /***                           Instruction decoding                        ***/
                    353: #define EXTRACT_HELPER(name, shift, nb)                                       \
1.1.1.8   root      354: static inline uint32_t name(uint32_t opcode)                                  \
1.1       root      355: {                                                                             \
                    356:     return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
                    357: }
                    358: 
                    359: #define EXTRACT_SHELPER(name, shift, nb)                                      \
1.1.1.8   root      360: static inline int32_t name(uint32_t opcode)                                   \
1.1       root      361: {                                                                             \
                    362:     return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
                    363: }
                    364: 
                    365: /* Opcode part 1 */
                    366: EXTRACT_HELPER(opc1, 26, 6);
                    367: /* Opcode part 2 */
                    368: EXTRACT_HELPER(opc2, 1, 5);
                    369: /* Opcode part 3 */
                    370: EXTRACT_HELPER(opc3, 6, 5);
                    371: /* Update Cr0 flags */
                    372: EXTRACT_HELPER(Rc, 0, 1);
                    373: /* Destination */
                    374: EXTRACT_HELPER(rD, 21, 5);
                    375: /* Source */
                    376: EXTRACT_HELPER(rS, 21, 5);
                    377: /* First operand */
                    378: EXTRACT_HELPER(rA, 16, 5);
                    379: /* Second operand */
                    380: EXTRACT_HELPER(rB, 11, 5);
                    381: /* Third operand */
                    382: EXTRACT_HELPER(rC, 6, 5);
                    383: /***                               Get CRn                                 ***/
                    384: EXTRACT_HELPER(crfD, 23, 3);
                    385: EXTRACT_HELPER(crfS, 18, 3);
                    386: EXTRACT_HELPER(crbD, 21, 5);
                    387: EXTRACT_HELPER(crbA, 16, 5);
                    388: EXTRACT_HELPER(crbB, 11, 5);
                    389: /* SPR / TBL */
                    390: EXTRACT_HELPER(_SPR, 11, 10);
1.1.1.8   root      391: static inline uint32_t SPR(uint32_t opcode)
1.1       root      392: {
                    393:     uint32_t sprn = _SPR(opcode);
                    394: 
                    395:     return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
                    396: }
                    397: /***                              Get constants                            ***/
                    398: EXTRACT_HELPER(IMM, 12, 8);
                    399: /* 16 bits signed immediate value */
                    400: EXTRACT_SHELPER(SIMM, 0, 16);
                    401: /* 16 bits unsigned immediate value */
                    402: EXTRACT_HELPER(UIMM, 0, 16);
1.1.1.6   root      403: /* 5 bits signed immediate value */
                    404: EXTRACT_HELPER(SIMM5, 16, 5);
                    405: /* 5 bits signed immediate value */
                    406: EXTRACT_HELPER(UIMM5, 16, 5);
1.1       root      407: /* Bit count */
                    408: EXTRACT_HELPER(NB, 11, 5);
                    409: /* Shift count */
                    410: EXTRACT_HELPER(SH, 11, 5);
1.1.1.6   root      411: /* Vector shift count */
                    412: EXTRACT_HELPER(VSH, 6, 4);
1.1       root      413: /* Mask start */
                    414: EXTRACT_HELPER(MB, 6, 5);
                    415: /* Mask end */
                    416: EXTRACT_HELPER(ME, 1, 5);
                    417: /* Trap operand */
                    418: EXTRACT_HELPER(TO, 21, 5);
                    419: 
                    420: EXTRACT_HELPER(CRM, 12, 8);
                    421: EXTRACT_HELPER(FM, 17, 8);
                    422: EXTRACT_HELPER(SR, 16, 4);
1.1.1.6   root      423: EXTRACT_HELPER(FPIMM, 12, 4);
1.1       root      424: 
                    425: /***                            Jump target decoding                       ***/
                    426: /* Displacement */
                    427: EXTRACT_SHELPER(d, 0, 16);
                    428: /* Immediate address */
1.1.1.8   root      429: static inline target_ulong LI(uint32_t opcode)
1.1       root      430: {
                    431:     return (opcode >> 0) & 0x03FFFFFC;
                    432: }
                    433: 
1.1.1.8   root      434: static inline uint32_t BD(uint32_t opcode)
1.1       root      435: {
                    436:     return (opcode >> 0) & 0xFFFC;
                    437: }
                    438: 
                    439: EXTRACT_HELPER(BO, 21, 5);
                    440: EXTRACT_HELPER(BI, 16, 5);
                    441: /* Absolute/relative address */
                    442: EXTRACT_HELPER(AA, 1, 1);
                    443: /* Link */
                    444: EXTRACT_HELPER(LK, 0, 1);
                    445: 
                    446: /* Create a mask between <start> and <end> bits */
1.1.1.8   root      447: static inline target_ulong MASK(uint32_t start, uint32_t end)
1.1       root      448: {
1.1.1.5   root      449:     target_ulong ret;
1.1       root      450: 
1.1.1.5   root      451: #if defined(TARGET_PPC64)
                    452:     if (likely(start == 0)) {
                    453:         ret = UINT64_MAX << (63 - end);
                    454:     } else if (likely(end == 63)) {
                    455:         ret = UINT64_MAX >> start;
                    456:     }
                    457: #else
                    458:     if (likely(start == 0)) {
                    459:         ret = UINT32_MAX << (31  - end);
                    460:     } else if (likely(end == 31)) {
                    461:         ret = UINT32_MAX >> start;
                    462:     }
                    463: #endif
                    464:     else {
                    465:         ret = (((target_ulong)(-1ULL)) >> (start)) ^
                    466:             (((target_ulong)(-1ULL) >> (end)) >> 1);
                    467:         if (unlikely(start > end))
                    468:             return ~ret;
                    469:     }
1.1       root      470: 
                    471:     return ret;
                    472: }
                    473: 
1.1.1.5   root      474: /*****************************************************************************/
                    475: /* PowerPC instructions table                                                */
1.1       root      476: 
1.1.1.5   root      477: #if defined(DO_PPC_STATISTICS)
1.1.1.11  root      478: #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)                    \
1.1.1.7   root      479: {                                                                             \
1.1.1.5   root      480:     .opc1 = op1,                                                              \
                    481:     .opc2 = op2,                                                              \
                    482:     .opc3 = op3,                                                              \
                    483:     .pad  = { 0, },                                                           \
                    484:     .handler = {                                                              \
1.1.1.12! root      485:         .inval1  = invl,                                                      \
        !           486:         .type = _typ,                                                         \
        !           487:         .type2 = _typ2,                                                       \
        !           488:         .handler = &gen_##name,                                               \
        !           489:         .oname = stringify(name),                                             \
        !           490:     },                                                                        \
        !           491:     .oname = stringify(name),                                                 \
        !           492: }
        !           493: #define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2)       \
        !           494: {                                                                             \
        !           495:     .opc1 = op1,                                                              \
        !           496:     .opc2 = op2,                                                              \
        !           497:     .opc3 = op3,                                                              \
        !           498:     .pad  = { 0, },                                                           \
        !           499:     .handler = {                                                              \
        !           500:         .inval1  = invl1,                                                     \
        !           501:         .inval2  = invl2,                                                     \
1.1.1.5   root      502:         .type = _typ,                                                         \
1.1.1.11  root      503:         .type2 = _typ2,                                                       \
1.1.1.5   root      504:         .handler = &gen_##name,                                               \
                    505:         .oname = stringify(name),                                             \
                    506:     },                                                                        \
                    507:     .oname = stringify(name),                                                 \
                    508: }
1.1.1.11  root      509: #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2)             \
1.1.1.7   root      510: {                                                                             \
1.1.1.5   root      511:     .opc1 = op1,                                                              \
                    512:     .opc2 = op2,                                                              \
                    513:     .opc3 = op3,                                                              \
                    514:     .pad  = { 0, },                                                           \
                    515:     .handler = {                                                              \
1.1.1.12! root      516:         .inval1  = invl,                                                      \
1.1.1.5   root      517:         .type = _typ,                                                         \
1.1.1.11  root      518:         .type2 = _typ2,                                                       \
1.1.1.5   root      519:         .handler = &gen_##name,                                               \
                    520:         .oname = onam,                                                        \
                    521:     },                                                                        \
                    522:     .oname = onam,                                                            \
                    523: }
                    524: #else
1.1.1.11  root      525: #define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)                    \
1.1.1.7   root      526: {                                                                             \
1.1       root      527:     .opc1 = op1,                                                              \
                    528:     .opc2 = op2,                                                              \
                    529:     .opc3 = op3,                                                              \
                    530:     .pad  = { 0, },                                                           \
                    531:     .handler = {                                                              \
1.1.1.12! root      532:         .inval1  = invl,                                                      \
        !           533:         .type = _typ,                                                         \
        !           534:         .type2 = _typ2,                                                       \
        !           535:         .handler = &gen_##name,                                               \
        !           536:     },                                                                        \
        !           537:     .oname = stringify(name),                                                 \
        !           538: }
        !           539: #define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2)       \
        !           540: {                                                                             \
        !           541:     .opc1 = op1,                                                              \
        !           542:     .opc2 = op2,                                                              \
        !           543:     .opc3 = op3,                                                              \
        !           544:     .pad  = { 0, },                                                           \
        !           545:     .handler = {                                                              \
        !           546:         .inval1  = invl1,                                                     \
        !           547:         .inval2  = invl2,                                                     \
1.1       root      548:         .type = _typ,                                                         \
1.1.1.11  root      549:         .type2 = _typ2,                                                       \
1.1       root      550:         .handler = &gen_##name,                                               \
                    551:     },                                                                        \
                    552:     .oname = stringify(name),                                                 \
                    553: }
1.1.1.11  root      554: #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2)             \
1.1.1.7   root      555: {                                                                             \
1.1.1.5   root      556:     .opc1 = op1,                                                              \
                    557:     .opc2 = op2,                                                              \
                    558:     .opc3 = op3,                                                              \
                    559:     .pad  = { 0, },                                                           \
                    560:     .handler = {                                                              \
1.1.1.12! root      561:         .inval1  = invl,                                                      \
1.1.1.5   root      562:         .type = _typ,                                                         \
1.1.1.11  root      563:         .type2 = _typ2,                                                       \
1.1.1.5   root      564:         .handler = &gen_##name,                                               \
                    565:     },                                                                        \
                    566:     .oname = onam,                                                            \
                    567: }
                    568: #endif
1.1       root      569: 
1.1.1.6   root      570: /* SPR load/store helpers */
1.1.1.8   root      571: static inline void gen_load_spr(TCGv t, int reg)
1.1.1.6   root      572: {
                    573:     tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, spr[reg]));
                    574: }
                    575: 
1.1.1.8   root      576: static inline void gen_store_spr(int reg, TCGv t)
1.1.1.6   root      577: {
                    578:     tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, spr[reg]));
                    579: }
                    580: 
1.1       root      581: /* Invalid instruction */
1.1.1.7   root      582: static void gen_invalid(DisasContext *ctx)
1.1       root      583: {
1.1.1.6   root      584:     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1       root      585: }
                    586: 
                    587: static opc_handler_t invalid_handler = {
1.1.1.12! root      588:     .inval1  = 0xFFFFFFFF,
        !           589:     .inval2  = 0xFFFFFFFF,
1.1       root      590:     .type    = PPC_NONE,
1.1.1.11  root      591:     .type2   = PPC_NONE,
1.1       root      592:     .handler = gen_invalid,
                    593: };
                    594: 
1.1.1.6   root      595: /***                           Integer comparison                          ***/
1.1       root      596: 
1.1.1.8   root      597: static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
1.1.1.6   root      598: {
                    599:     int l1, l2, l3;
1.1       root      600: 
1.1.1.6   root      601:     tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_xer);
                    602:     tcg_gen_shri_i32(cpu_crf[crf], cpu_crf[crf], XER_SO);
                    603:     tcg_gen_andi_i32(cpu_crf[crf], cpu_crf[crf], 1);
                    604: 
                    605:     l1 = gen_new_label();
                    606:     l2 = gen_new_label();
                    607:     l3 = gen_new_label();
                    608:     if (s) {
                    609:         tcg_gen_brcond_tl(TCG_COND_LT, arg0, arg1, l1);
                    610:         tcg_gen_brcond_tl(TCG_COND_GT, arg0, arg1, l2);
                    611:     } else {
                    612:         tcg_gen_brcond_tl(TCG_COND_LTU, arg0, arg1, l1);
                    613:         tcg_gen_brcond_tl(TCG_COND_GTU, arg0, arg1, l2);
                    614:     }
                    615:     tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_EQ);
                    616:     tcg_gen_br(l3);
                    617:     gen_set_label(l1);
                    618:     tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_LT);
                    619:     tcg_gen_br(l3);
                    620:     gen_set_label(l2);
                    621:     tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_GT);
                    622:     gen_set_label(l3);
1.1.1.5   root      623: }
                    624: 
1.1.1.8   root      625: static inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
1.1.1.6   root      626: {
                    627:     TCGv t0 = tcg_const_local_tl(arg1);
                    628:     gen_op_cmp(arg0, t0, s, crf);
                    629:     tcg_temp_free(t0);
1.1.1.5   root      630: }
                    631: 
1.1.1.6   root      632: #if defined(TARGET_PPC64)
1.1.1.8   root      633: static inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
1.1.1.6   root      634: {
                    635:     TCGv t0, t1;
                    636:     t0 = tcg_temp_local_new();
                    637:     t1 = tcg_temp_local_new();
                    638:     if (s) {
                    639:         tcg_gen_ext32s_tl(t0, arg0);
                    640:         tcg_gen_ext32s_tl(t1, arg1);
                    641:     } else {
                    642:         tcg_gen_ext32u_tl(t0, arg0);
                    643:         tcg_gen_ext32u_tl(t1, arg1);
                    644:     }
                    645:     gen_op_cmp(t0, t1, s, crf);
                    646:     tcg_temp_free(t1);
                    647:     tcg_temp_free(t0);
1.1.1.5   root      648: }
                    649: 
1.1.1.8   root      650: static inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf)
1.1.1.6   root      651: {
                    652:     TCGv t0 = tcg_const_local_tl(arg1);
                    653:     gen_op_cmp32(arg0, t0, s, crf);
                    654:     tcg_temp_free(t0);
1.1       root      655: }
1.1.1.5   root      656: #endif
1.1       root      657: 
1.1.1.8   root      658: static inline void gen_set_Rc0(DisasContext *ctx, TCGv reg)
1.1.1.5   root      659: {
                    660: #if defined(TARGET_PPC64)
1.1.1.6   root      661:     if (!(ctx->sf_mode))
                    662:         gen_op_cmpi32(reg, 0, 1, 0);
                    663:     else
1.1.1.5   root      664: #endif
1.1.1.6   root      665:         gen_op_cmpi(reg, 0, 1, 0);
1.1.1.5   root      666: }
1.1.1.6   root      667: 
                    668: /* cmp */
1.1.1.7   root      669: static void gen_cmp(DisasContext *ctx)
1.1.1.5   root      670: {
                    671: #if defined(TARGET_PPC64)
1.1.1.6   root      672:     if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
                    673:         gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
                    674:                      1, crfD(ctx->opcode));
                    675:     else
1.1.1.5   root      676: #endif
1.1.1.6   root      677:         gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
                    678:                    1, crfD(ctx->opcode));
1.1.1.5   root      679: }
1.1.1.6   root      680: 
                    681: /* cmpi */
1.1.1.7   root      682: static void gen_cmpi(DisasContext *ctx)
1.1.1.5   root      683: {
1.1.1.6   root      684: #if defined(TARGET_PPC64)
                    685:     if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
                    686:         gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
                    687:                       1, crfD(ctx->opcode));
                    688:     else
1.1.1.5   root      689: #endif
1.1.1.6   root      690:         gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
                    691:                     1, crfD(ctx->opcode));
1.1.1.5   root      692: }
1.1.1.6   root      693: 
                    694: /* cmpl */
1.1.1.7   root      695: static void gen_cmpl(DisasContext *ctx)
1.1.1.5   root      696: {
1.1.1.6   root      697: #if defined(TARGET_PPC64)
                    698:     if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
                    699:         gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
                    700:                      0, crfD(ctx->opcode));
                    701:     else
1.1.1.5   root      702: #endif
1.1.1.6   root      703:         gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
                    704:                    0, crfD(ctx->opcode));
1.1.1.5   root      705: }
1.1.1.6   root      706: 
                    707: /* cmpli */
1.1.1.7   root      708: static void gen_cmpli(DisasContext *ctx)
1.1.1.5   root      709: {
                    710: #if defined(TARGET_PPC64)
1.1.1.6   root      711:     if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
                    712:         gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
                    713:                       0, crfD(ctx->opcode));
                    714:     else
                    715: #endif
                    716:         gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
                    717:                     0, crfD(ctx->opcode));
1.1.1.5   root      718: }
1.1.1.6   root      719: 
                    720: /* isel (PowerPC 2.03 specification) */
1.1.1.7   root      721: static void gen_isel(DisasContext *ctx)
1.1.1.5   root      722: {
1.1.1.6   root      723:     int l1, l2;
                    724:     uint32_t bi = rC(ctx->opcode);
                    725:     uint32_t mask;
                    726:     TCGv_i32 t0;
                    727: 
                    728:     l1 = gen_new_label();
                    729:     l2 = gen_new_label();
                    730: 
                    731:     mask = 1 << (3 - (bi & 0x03));
                    732:     t0 = tcg_temp_new_i32();
                    733:     tcg_gen_andi_i32(t0, cpu_crf[bi >> 2], mask);
                    734:     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
                    735:     if (rA(ctx->opcode) == 0)
                    736:         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
                    737:     else
                    738:         tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                    739:     tcg_gen_br(l2);
                    740:     gen_set_label(l1);
                    741:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                    742:     gen_set_label(l2);
                    743:     tcg_temp_free_i32(t0);
1.1.1.5   root      744: }
1.1.1.6   root      745: 
                    746: /***                           Integer arithmetic                          ***/
                    747: 
1.1.1.8   root      748: static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0,
                    749:                                            TCGv arg1, TCGv arg2, int sub)
1.1.1.5   root      750: {
1.1.1.6   root      751:     int l1;
                    752:     TCGv t0;
                    753: 
                    754:     l1 = gen_new_label();
                    755:     /* Start with XER OV disabled, the most likely case */
                    756:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                    757:     t0 = tcg_temp_local_new();
                    758:     tcg_gen_xor_tl(t0, arg0, arg1);
1.1.1.5   root      759: #if defined(TARGET_PPC64)
1.1.1.6   root      760:     if (!ctx->sf_mode)
                    761:         tcg_gen_ext32s_tl(t0, t0);
1.1.1.5   root      762: #endif
1.1.1.6   root      763:     if (sub)
                    764:         tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
                    765:     else
                    766:         tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
                    767:     tcg_gen_xor_tl(t0, arg1, arg2);
                    768: #if defined(TARGET_PPC64)
                    769:     if (!ctx->sf_mode)
                    770:         tcg_gen_ext32s_tl(t0, t0);
                    771: #endif
                    772:     if (sub)
                    773:         tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
                    774:     else
                    775:         tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
                    776:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                    777:     gen_set_label(l1);
                    778:     tcg_temp_free(t0);
1.1.1.5   root      779: }
1.1.1.6   root      780: 
1.1.1.8   root      781: static inline void gen_op_arith_compute_ca(DisasContext *ctx, TCGv arg1,
                    782:                                            TCGv arg2, int sub)
1.1.1.5   root      783: {
1.1.1.6   root      784:     int l1 = gen_new_label();
                    785: 
1.1.1.5   root      786: #if defined(TARGET_PPC64)
1.1.1.6   root      787:     if (!(ctx->sf_mode)) {
                    788:         TCGv t0, t1;
                    789:         t0 = tcg_temp_new();
                    790:         t1 = tcg_temp_new();
                    791: 
                    792:         tcg_gen_ext32u_tl(t0, arg1);
                    793:         tcg_gen_ext32u_tl(t1, arg2);
                    794:         if (sub) {
                    795:             tcg_gen_brcond_tl(TCG_COND_GTU, t0, t1, l1);
                    796:         } else {
                    797:             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
                    798:         }
                    799:         tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
                    800:         gen_set_label(l1);
                    801:         tcg_temp_free(t0);
                    802:         tcg_temp_free(t1);
                    803:     } else
                    804: #endif
                    805:     {
                    806:         if (sub) {
                    807:             tcg_gen_brcond_tl(TCG_COND_GTU, arg1, arg2, l1);
                    808:         } else {
                    809:             tcg_gen_brcond_tl(TCG_COND_GEU, arg1, arg2, l1);
                    810:         }
                    811:         tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
                    812:         gen_set_label(l1);
                    813:     }
1.1.1.5   root      814: }
1.1.1.6   root      815: 
                    816: /* Common add function */
1.1.1.8   root      817: static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1,
                    818:                                     TCGv arg2, int add_ca, int compute_ca,
                    819:                                     int compute_ov)
1.1.1.6   root      820: {
                    821:     TCGv t0, t1;
                    822: 
                    823:     if ((!compute_ca && !compute_ov) ||
                    824:         (!TCGV_EQUAL(ret,arg1) && !TCGV_EQUAL(ret, arg2)))  {
                    825:         t0 = ret;
                    826:     } else {
                    827:         t0 = tcg_temp_local_new();
                    828:     }
                    829: 
                    830:     if (add_ca) {
                    831:         t1 = tcg_temp_local_new();
                    832:         tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
                    833:         tcg_gen_shri_tl(t1, t1, XER_CA);
1.1.1.7   root      834:     } else {
                    835:         TCGV_UNUSED(t1);
1.1.1.6   root      836:     }
                    837: 
                    838:     if (compute_ca && compute_ov) {
                    839:         /* Start with XER CA and OV disabled, the most likely case */
                    840:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
                    841:     } else if (compute_ca) {
                    842:         /* Start with XER CA disabled, the most likely case */
                    843:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
                    844:     } else if (compute_ov) {
                    845:         /* Start with XER OV disabled, the most likely case */
                    846:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                    847:     }
                    848: 
                    849:     tcg_gen_add_tl(t0, arg1, arg2);
                    850: 
                    851:     if (compute_ca) {
                    852:         gen_op_arith_compute_ca(ctx, t0, arg1, 0);
                    853:     }
                    854:     if (add_ca) {
                    855:         tcg_gen_add_tl(t0, t0, t1);
                    856:         gen_op_arith_compute_ca(ctx, t0, t1, 0);
                    857:         tcg_temp_free(t1);
                    858:     }
                    859:     if (compute_ov) {
                    860:         gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0);
                    861:     }
                    862: 
                    863:     if (unlikely(Rc(ctx->opcode) != 0))
                    864:         gen_set_Rc0(ctx, t0);
                    865: 
                    866:     if (!TCGV_EQUAL(t0, ret)) {
                    867:         tcg_gen_mov_tl(ret, t0);
                    868:         tcg_temp_free(t0);
                    869:     }
1.1.1.5   root      870: }
1.1.1.6   root      871: /* Add functions with two operands */
                    872: #define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
1.1.1.7   root      873: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.6   root      874: {                                                                             \
                    875:     gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
                    876:                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
                    877:                      add_ca, compute_ca, compute_ov);                         \
1.1.1.5   root      878: }
1.1.1.6   root      879: /* Add functions with one operand and one immediate */
                    880: #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
                    881:                                 add_ca, compute_ca, compute_ov)               \
1.1.1.7   root      882: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.6   root      883: {                                                                             \
                    884:     TCGv t0 = tcg_const_local_tl(const_val);                                  \
                    885:     gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
                    886:                      cpu_gpr[rA(ctx->opcode)], t0,                            \
                    887:                      add_ca, compute_ca, compute_ov);                         \
                    888:     tcg_temp_free(t0);                                                        \
1.1.1.5   root      889: }
1.1.1.6   root      890: 
                    891: /* add  add.  addo  addo. */
                    892: GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
                    893: GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
                    894: /* addc  addc.  addco  addco. */
                    895: GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
                    896: GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
                    897: /* adde  adde.  addeo  addeo. */
                    898: GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
                    899: GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
                    900: /* addme  addme.  addmeo  addmeo.  */
                    901: GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
                    902: GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
                    903: /* addze  addze.  addzeo  addzeo.*/
                    904: GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
                    905: GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
1.1       root      906: /* addi */
1.1.1.7   root      907: static void gen_addi(DisasContext *ctx)
1.1       root      908: {
1.1.1.5   root      909:     target_long simm = SIMM(ctx->opcode);
1.1       root      910: 
                    911:     if (rA(ctx->opcode) == 0) {
1.1.1.5   root      912:         /* li case */
1.1.1.6   root      913:         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm);
1.1       root      914:     } else {
1.1.1.6   root      915:         tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], simm);
1.1       root      916:     }
                    917: }
1.1.1.6   root      918: /* addic  addic.*/
1.1.1.8   root      919: static inline void gen_op_addic(DisasContext *ctx, TCGv ret, TCGv arg1,
                    920:                                 int compute_Rc0)
1.1       root      921: {
1.1.1.5   root      922:     target_long simm = SIMM(ctx->opcode);
                    923: 
1.1.1.6   root      924:     /* Start with XER CA and OV disabled, the most likely case */
                    925:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
                    926: 
1.1.1.5   root      927:     if (likely(simm != 0)) {
1.1.1.6   root      928:         TCGv t0 = tcg_temp_local_new();
                    929:         tcg_gen_addi_tl(t0, arg1, simm);
                    930:         gen_op_arith_compute_ca(ctx, t0, arg1, 0);
                    931:         tcg_gen_mov_tl(ret, t0);
                    932:         tcg_temp_free(t0);
1.1.1.5   root      933:     } else {
1.1.1.6   root      934:         tcg_gen_mov_tl(ret, arg1);
                    935:     }
                    936:     if (compute_Rc0) {
                    937:         gen_set_Rc0(ctx, ret);
1.1.1.5   root      938:     }
1.1       root      939: }
1.1.1.7   root      940: 
                    941: static void gen_addic(DisasContext *ctx)
1.1.1.6   root      942: {
                    943:     gen_op_addic(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
                    944: }
1.1.1.7   root      945: 
                    946: static void gen_addic_(DisasContext *ctx)
1.1       root      947: {
1.1.1.6   root      948:     gen_op_addic(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
1.1       root      949: }
1.1.1.7   root      950: 
1.1       root      951: /* addis */
1.1.1.7   root      952: static void gen_addis(DisasContext *ctx)
1.1       root      953: {
1.1.1.5   root      954:     target_long simm = SIMM(ctx->opcode);
1.1       root      955: 
                    956:     if (rA(ctx->opcode) == 0) {
1.1.1.5   root      957:         /* lis case */
1.1.1.6   root      958:         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm << 16);
1.1       root      959:     } else {
1.1.1.6   root      960:         tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], simm << 16);
1.1       root      961:     }
                    962: }
                    963: 
1.1.1.8   root      964: static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, TCGv arg1,
                    965:                                      TCGv arg2, int sign, int compute_ov)
1.1.1.6   root      966: {
                    967:     int l1 = gen_new_label();
                    968:     int l2 = gen_new_label();
                    969:     TCGv_i32 t0 = tcg_temp_local_new_i32();
                    970:     TCGv_i32 t1 = tcg_temp_local_new_i32();
                    971: 
                    972:     tcg_gen_trunc_tl_i32(t0, arg1);
                    973:     tcg_gen_trunc_tl_i32(t1, arg2);
                    974:     tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l1);
                    975:     if (sign) {
                    976:         int l3 = gen_new_label();
                    977:         tcg_gen_brcondi_i32(TCG_COND_NE, t1, -1, l3);
                    978:         tcg_gen_brcondi_i32(TCG_COND_EQ, t0, INT32_MIN, l1);
                    979:         gen_set_label(l3);
                    980:         tcg_gen_div_i32(t0, t0, t1);
                    981:     } else {
                    982:         tcg_gen_divu_i32(t0, t0, t1);
                    983:     }
                    984:     if (compute_ov) {
                    985:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                    986:     }
                    987:     tcg_gen_br(l2);
                    988:     gen_set_label(l1);
                    989:     if (sign) {
                    990:         tcg_gen_sari_i32(t0, t0, 31);
                    991:     } else {
                    992:         tcg_gen_movi_i32(t0, 0);
                    993:     }
                    994:     if (compute_ov) {
                    995:         tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                    996:     }
                    997:     gen_set_label(l2);
                    998:     tcg_gen_extu_i32_tl(ret, t0);
                    999:     tcg_temp_free_i32(t0);
                   1000:     tcg_temp_free_i32(t1);
                   1001:     if (unlikely(Rc(ctx->opcode) != 0))
                   1002:         gen_set_Rc0(ctx, ret);
                   1003: }
                   1004: /* Div functions */
                   1005: #define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
1.1.1.7   root     1006: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.6   root     1007: {                                                                             \
                   1008:     gen_op_arith_divw(ctx, cpu_gpr[rD(ctx->opcode)],                          \
                   1009:                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
                   1010:                      sign, compute_ov);                                       \
                   1011: }
                   1012: /* divwu  divwu.  divwuo  divwuo.   */
                   1013: GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0);
                   1014: GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1);
                   1015: /* divw  divw.  divwo  divwo.   */
                   1016: GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0);
                   1017: GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1);
                   1018: #if defined(TARGET_PPC64)
1.1.1.8   root     1019: static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1,
                   1020:                                      TCGv arg2, int sign, int compute_ov)
1.1.1.6   root     1021: {
                   1022:     int l1 = gen_new_label();
                   1023:     int l2 = gen_new_label();
                   1024: 
                   1025:     tcg_gen_brcondi_i64(TCG_COND_EQ, arg2, 0, l1);
                   1026:     if (sign) {
                   1027:         int l3 = gen_new_label();
                   1028:         tcg_gen_brcondi_i64(TCG_COND_NE, arg2, -1, l3);
                   1029:         tcg_gen_brcondi_i64(TCG_COND_EQ, arg1, INT64_MIN, l1);
                   1030:         gen_set_label(l3);
                   1031:         tcg_gen_div_i64(ret, arg1, arg2);
                   1032:     } else {
                   1033:         tcg_gen_divu_i64(ret, arg1, arg2);
                   1034:     }
                   1035:     if (compute_ov) {
                   1036:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                   1037:     }
                   1038:     tcg_gen_br(l2);
                   1039:     gen_set_label(l1);
                   1040:     if (sign) {
                   1041:         tcg_gen_sari_i64(ret, arg1, 63);
                   1042:     } else {
                   1043:         tcg_gen_movi_i64(ret, 0);
                   1044:     }
                   1045:     if (compute_ov) {
                   1046:         tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                   1047:     }
                   1048:     gen_set_label(l2);
                   1049:     if (unlikely(Rc(ctx->opcode) != 0))
                   1050:         gen_set_Rc0(ctx, ret);
1.1.1.5   root     1051: }
1.1.1.6   root     1052: #define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
1.1.1.7   root     1053: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1       root     1054: {                                                                             \
1.1.1.6   root     1055:     gen_op_arith_divd(ctx, cpu_gpr[rD(ctx->opcode)],                          \
                   1056:                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
                   1057:                       sign, compute_ov);                                      \
1.1       root     1058: }
1.1.1.6   root     1059: /* divwu  divwu.  divwuo  divwuo.   */
                   1060: GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0);
                   1061: GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1);
                   1062: /* divw  divw.  divwo  divwo.   */
                   1063: GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0);
                   1064: GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
1.1.1.5   root     1065: #endif
1.1       root     1066: 
1.1.1.6   root     1067: /* mulhw  mulhw. */
1.1.1.7   root     1068: static void gen_mulhw(DisasContext *ctx)
1.1       root     1069: {
1.1.1.6   root     1070:     TCGv_i64 t0, t1;
                   1071: 
                   1072:     t0 = tcg_temp_new_i64();
                   1073:     t1 = tcg_temp_new_i64();
1.1.1.5   root     1074: #if defined(TARGET_PPC64)
1.1.1.6   root     1075:     tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
                   1076:     tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
                   1077:     tcg_gen_mul_i64(t0, t0, t1);
                   1078:     tcg_gen_shri_i64(cpu_gpr[rD(ctx->opcode)], t0, 32);
                   1079: #else
                   1080:     tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   1081:     tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   1082:     tcg_gen_mul_i64(t0, t0, t1);
                   1083:     tcg_gen_shri_i64(t0, t0, 32);
                   1084:     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
1.1.1.5   root     1085: #endif
1.1.1.6   root     1086:     tcg_temp_free_i64(t0);
                   1087:     tcg_temp_free_i64(t1);
                   1088:     if (unlikely(Rc(ctx->opcode) != 0))
                   1089:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1       root     1090: }
1.1.1.7   root     1091: 
1.1.1.6   root     1092: /* mulhwu  mulhwu.  */
1.1.1.7   root     1093: static void gen_mulhwu(DisasContext *ctx)
1.1       root     1094: {
1.1.1.6   root     1095:     TCGv_i64 t0, t1;
                   1096: 
                   1097:     t0 = tcg_temp_new_i64();
                   1098:     t1 = tcg_temp_new_i64();
1.1.1.5   root     1099: #if defined(TARGET_PPC64)
1.1.1.6   root     1100:     tcg_gen_ext32u_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   1101:     tcg_gen_ext32u_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   1102:     tcg_gen_mul_i64(t0, t0, t1);
                   1103:     tcg_gen_shri_i64(cpu_gpr[rD(ctx->opcode)], t0, 32);
                   1104: #else
                   1105:     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   1106:     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   1107:     tcg_gen_mul_i64(t0, t0, t1);
                   1108:     tcg_gen_shri_i64(t0, t0, 32);
                   1109:     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
1.1.1.5   root     1110: #endif
1.1.1.6   root     1111:     tcg_temp_free_i64(t0);
                   1112:     tcg_temp_free_i64(t1);
                   1113:     if (unlikely(Rc(ctx->opcode) != 0))
                   1114:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
                   1115: }
1.1.1.7   root     1116: 
1.1.1.6   root     1117: /* mullw  mullw. */
1.1.1.7   root     1118: static void gen_mullw(DisasContext *ctx)
1.1.1.6   root     1119: {
                   1120:     tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
                   1121:                    cpu_gpr[rB(ctx->opcode)]);
                   1122:     tcg_gen_ext32s_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)]);
                   1123:     if (unlikely(Rc(ctx->opcode) != 0))
                   1124:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1       root     1125: }
1.1.1.7   root     1126: 
1.1.1.6   root     1127: /* mullwo  mullwo. */
1.1.1.7   root     1128: static void gen_mullwo(DisasContext *ctx)
1.1.1.6   root     1129: {
                   1130:     int l1;
                   1131:     TCGv_i64 t0, t1;
1.1       root     1132: 
1.1.1.6   root     1133:     t0 = tcg_temp_new_i64();
                   1134:     t1 = tcg_temp_new_i64();
                   1135:     l1 = gen_new_label();
                   1136:     /* Start with XER OV disabled, the most likely case */
                   1137:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                   1138: #if defined(TARGET_PPC64)
                   1139:     tcg_gen_ext32s_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   1140:     tcg_gen_ext32s_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   1141: #else
                   1142:     tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   1143:     tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   1144: #endif
                   1145:     tcg_gen_mul_i64(t0, t0, t1);
                   1146: #if defined(TARGET_PPC64)
                   1147:     tcg_gen_ext32s_i64(cpu_gpr[rD(ctx->opcode)], t0);
                   1148:     tcg_gen_brcond_i64(TCG_COND_EQ, t0, cpu_gpr[rD(ctx->opcode)], l1);
                   1149: #else
                   1150:     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   1151:     tcg_gen_ext32s_i64(t1, t0);
                   1152:     tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
                   1153: #endif
                   1154:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                   1155:     gen_set_label(l1);
                   1156:     tcg_temp_free_i64(t0);
                   1157:     tcg_temp_free_i64(t1);
                   1158:     if (unlikely(Rc(ctx->opcode) != 0))
                   1159:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
                   1160: }
1.1.1.7   root     1161: 
1.1.1.6   root     1162: /* mulli */
1.1.1.7   root     1163: static void gen_mulli(DisasContext *ctx)
1.1.1.5   root     1164: {
1.1.1.6   root     1165:     tcg_gen_muli_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
                   1166:                     SIMM(ctx->opcode));
                   1167: }
                   1168: #if defined(TARGET_PPC64)
                   1169: #define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
1.1.1.7   root     1170: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.6   root     1171: {                                                                             \
                   1172:     gen_helper_##name (cpu_gpr[rD(ctx->opcode)],                              \
                   1173:                        cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);   \
                   1174:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
                   1175:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);                           \
                   1176: }
                   1177: /* mulhd  mulhd. */
                   1178: GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00);
                   1179: /* mulhdu  mulhdu. */
                   1180: GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02);
1.1.1.7   root     1181: 
1.1.1.6   root     1182: /* mulld  mulld. */
1.1.1.7   root     1183: static void gen_mulld(DisasContext *ctx)
1.1.1.6   root     1184: {
                   1185:     tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
                   1186:                    cpu_gpr[rB(ctx->opcode)]);
                   1187:     if (unlikely(Rc(ctx->opcode) != 0))
                   1188:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
                   1189: }
                   1190: /* mulldo  mulldo. */
                   1191: GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17);
                   1192: #endif
1.1.1.5   root     1193: 
1.1.1.6   root     1194: /* neg neg. nego nego. */
1.1.1.8   root     1195: static inline void gen_op_arith_neg(DisasContext *ctx, TCGv ret, TCGv arg1,
                   1196:                                     int ov_check)
1.1.1.6   root     1197: {
                   1198:     int l1 = gen_new_label();
                   1199:     int l2 = gen_new_label();
                   1200:     TCGv t0 = tcg_temp_local_new();
                   1201: #if defined(TARGET_PPC64)
                   1202:     if (ctx->sf_mode) {
                   1203:         tcg_gen_mov_tl(t0, arg1);
                   1204:         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT64_MIN, l1);
                   1205:     } else
                   1206: #endif
                   1207:     {
                   1208:         tcg_gen_ext32s_tl(t0, arg1);
                   1209:         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT32_MIN, l1);
                   1210:     }
                   1211:     tcg_gen_neg_tl(ret, arg1);
                   1212:     if (ov_check) {
                   1213:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                   1214:     }
                   1215:     tcg_gen_br(l2);
                   1216:     gen_set_label(l1);
                   1217:     tcg_gen_mov_tl(ret, t0);
                   1218:     if (ov_check) {
                   1219:         tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                   1220:     }
                   1221:     gen_set_label(l2);
                   1222:     tcg_temp_free(t0);
                   1223:     if (unlikely(Rc(ctx->opcode) != 0))
                   1224:         gen_set_Rc0(ctx, ret);
                   1225: }
1.1.1.7   root     1226: 
                   1227: static void gen_neg(DisasContext *ctx)
1.1.1.6   root     1228: {
                   1229:     gen_op_arith_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
                   1230: }
1.1.1.7   root     1231: 
                   1232: static void gen_nego(DisasContext *ctx)
1.1.1.6   root     1233: {
                   1234:     gen_op_arith_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
                   1235: }
                   1236: 
                   1237: /* Common subf function */
1.1.1.8   root     1238: static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,
                   1239:                                      TCGv arg2, int add_ca, int compute_ca,
                   1240:                                      int compute_ov)
1.1.1.6   root     1241: {
                   1242:     TCGv t0, t1;
                   1243: 
                   1244:     if ((!compute_ca && !compute_ov) ||
                   1245:         (!TCGV_EQUAL(ret, arg1) && !TCGV_EQUAL(ret, arg2)))  {
                   1246:         t0 = ret;
1.1.1.5   root     1247:     } else {
1.1.1.6   root     1248:         t0 = tcg_temp_local_new();
1.1.1.5   root     1249:     }
1.1.1.6   root     1250: 
                   1251:     if (add_ca) {
                   1252:         t1 = tcg_temp_local_new();
                   1253:         tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
                   1254:         tcg_gen_shri_tl(t1, t1, XER_CA);
1.1.1.7   root     1255:     } else {
                   1256:         TCGV_UNUSED(t1);
1.1.1.6   root     1257:     }
                   1258: 
                   1259:     if (compute_ca && compute_ov) {
                   1260:         /* Start with XER CA and OV disabled, the most likely case */
                   1261:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
                   1262:     } else if (compute_ca) {
                   1263:         /* Start with XER CA disabled, the most likely case */
                   1264:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
                   1265:     } else if (compute_ov) {
                   1266:         /* Start with XER OV disabled, the most likely case */
                   1267:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                   1268:     }
                   1269: 
                   1270:     if (add_ca) {
                   1271:         tcg_gen_not_tl(t0, arg1);
                   1272:         tcg_gen_add_tl(t0, t0, arg2);
                   1273:         gen_op_arith_compute_ca(ctx, t0, arg2, 0);
                   1274:         tcg_gen_add_tl(t0, t0, t1);
                   1275:         gen_op_arith_compute_ca(ctx, t0, t1, 0);
                   1276:         tcg_temp_free(t1);
                   1277:     } else {
                   1278:         tcg_gen_sub_tl(t0, arg2, arg1);
                   1279:         if (compute_ca) {
                   1280:             gen_op_arith_compute_ca(ctx, t0, arg2, 1);
                   1281:         }
                   1282:     }
                   1283:     if (compute_ov) {
                   1284:         gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1);
                   1285:     }
                   1286: 
                   1287:     if (unlikely(Rc(ctx->opcode) != 0))
                   1288:         gen_set_Rc0(ctx, t0);
                   1289: 
                   1290:     if (!TCGV_EQUAL(t0, ret)) {
                   1291:         tcg_gen_mov_tl(ret, t0);
                   1292:         tcg_temp_free(t0);
                   1293:     }
                   1294: }
                   1295: /* Sub functions with Two operands functions */
                   1296: #define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
1.1.1.7   root     1297: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.6   root     1298: {                                                                             \
                   1299:     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
                   1300:                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
                   1301:                       add_ca, compute_ca, compute_ov);                        \
                   1302: }
                   1303: /* Sub functions with one operand and one immediate */
                   1304: #define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
                   1305:                                 add_ca, compute_ca, compute_ov)               \
1.1.1.7   root     1306: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.6   root     1307: {                                                                             \
                   1308:     TCGv t0 = tcg_const_local_tl(const_val);                                  \
                   1309:     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
                   1310:                       cpu_gpr[rA(ctx->opcode)], t0,                           \
                   1311:                       add_ca, compute_ca, compute_ov);                        \
                   1312:     tcg_temp_free(t0);                                                        \
                   1313: }
                   1314: /* subf  subf.  subfo  subfo. */
                   1315: GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
                   1316: GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
                   1317: /* subfc  subfc.  subfco  subfco. */
                   1318: GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
                   1319: GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
                   1320: /* subfe  subfe.  subfeo  subfo. */
                   1321: GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
                   1322: GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
                   1323: /* subfme  subfme.  subfmeo  subfmeo.  */
                   1324: GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
                   1325: GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
                   1326: /* subfze  subfze.  subfzeo  subfzeo.*/
                   1327: GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
                   1328: GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
1.1.1.7   root     1329: 
1.1.1.6   root     1330: /* subfic */
1.1.1.7   root     1331: static void gen_subfic(DisasContext *ctx)
1.1.1.6   root     1332: {
                   1333:     /* Start with XER CA and OV disabled, the most likely case */
                   1334:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
                   1335:     TCGv t0 = tcg_temp_local_new();
                   1336:     TCGv t1 = tcg_const_local_tl(SIMM(ctx->opcode));
                   1337:     tcg_gen_sub_tl(t0, t1, cpu_gpr[rA(ctx->opcode)]);
                   1338:     gen_op_arith_compute_ca(ctx, t0, t1, 1);
                   1339:     tcg_temp_free(t1);
                   1340:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   1341:     tcg_temp_free(t0);
1.1.1.5   root     1342: }
                   1343: 
1.1       root     1344: /***                            Integer logical                            ***/
1.1.1.6   root     1345: #define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
1.1.1.7   root     1346: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1       root     1347: {                                                                             \
1.1.1.6   root     1348:     tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],                \
                   1349:        cpu_gpr[rB(ctx->opcode)]);                                             \
1.1.1.5   root     1350:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1.1.1.6   root     1351:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1.1       root     1352: }
                   1353: 
1.1.1.6   root     1354: #define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
1.1.1.7   root     1355: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1       root     1356: {                                                                             \
1.1.1.6   root     1357:     tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);               \
1.1.1.5   root     1358:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1.1.1.6   root     1359:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1.1       root     1360: }
                   1361: 
                   1362: /* and & and. */
1.1.1.6   root     1363: GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
1.1       root     1364: /* andc & andc. */
1.1.1.6   root     1365: GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
1.1.1.7   root     1366: 
1.1       root     1367: /* andi. */
1.1.1.7   root     1368: static void gen_andi_(DisasContext *ctx)
1.1       root     1369: {
1.1.1.6   root     1370:     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode));
                   1371:     gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1372: }
1.1.1.7   root     1373: 
1.1       root     1374: /* andis. */
1.1.1.7   root     1375: static void gen_andis_(DisasContext *ctx)
1.1       root     1376: {
1.1.1.6   root     1377:     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode) << 16);
                   1378:     gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1379: }
1.1.1.7   root     1380: 
1.1       root     1381: /* cntlzw */
1.1.1.7   root     1382: static void gen_cntlzw(DisasContext *ctx)
1.1.1.6   root     1383: {
                   1384:     gen_helper_cntlzw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1385:     if (unlikely(Rc(ctx->opcode) != 0))
                   1386:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
                   1387: }
1.1       root     1388: /* eqv & eqv. */
1.1.1.6   root     1389: GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
1.1       root     1390: /* extsb & extsb. */
1.1.1.6   root     1391: GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
1.1       root     1392: /* extsh & extsh. */
1.1.1.6   root     1393: GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
1.1       root     1394: /* nand & nand. */
1.1.1.6   root     1395: GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
1.1       root     1396: /* nor & nor. */
1.1.1.6   root     1397: GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
1.1.1.7   root     1398: 
1.1       root     1399: /* or & or. */
1.1.1.7   root     1400: static void gen_or(DisasContext *ctx)
1.1       root     1401: {
1.1.1.5   root     1402:     int rs, ra, rb;
                   1403: 
                   1404:     rs = rS(ctx->opcode);
                   1405:     ra = rA(ctx->opcode);
                   1406:     rb = rB(ctx->opcode);
                   1407:     /* Optimisation for mr. ri case */
                   1408:     if (rs != ra || rs != rb) {
1.1.1.6   root     1409:         if (rs != rb)
                   1410:             tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]);
                   1411:         else
                   1412:             tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]);
1.1.1.5   root     1413:         if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1414:             gen_set_Rc0(ctx, cpu_gpr[ra]);
1.1.1.5   root     1415:     } else if (unlikely(Rc(ctx->opcode) != 0)) {
1.1.1.6   root     1416:         gen_set_Rc0(ctx, cpu_gpr[rs]);
1.1.1.5   root     1417: #if defined(TARGET_PPC64)
                   1418:     } else {
1.1.1.6   root     1419:         int prio = 0;
                   1420: 
1.1.1.5   root     1421:         switch (rs) {
                   1422:         case 1:
                   1423:             /* Set process priority to low */
1.1.1.6   root     1424:             prio = 2;
1.1.1.5   root     1425:             break;
                   1426:         case 6:
                   1427:             /* Set process priority to medium-low */
1.1.1.6   root     1428:             prio = 3;
1.1.1.5   root     1429:             break;
                   1430:         case 2:
                   1431:             /* Set process priority to normal */
1.1.1.6   root     1432:             prio = 4;
1.1.1.5   root     1433:             break;
                   1434: #if !defined(CONFIG_USER_ONLY)
                   1435:         case 31:
1.1.1.6   root     1436:             if (ctx->mem_idx > 0) {
1.1.1.5   root     1437:                 /* Set process priority to very low */
1.1.1.6   root     1438:                 prio = 1;
1.1.1.5   root     1439:             }
                   1440:             break;
                   1441:         case 5:
1.1.1.6   root     1442:             if (ctx->mem_idx > 0) {
1.1.1.5   root     1443:                 /* Set process priority to medium-hight */
1.1.1.6   root     1444:                 prio = 5;
1.1.1.5   root     1445:             }
                   1446:             break;
                   1447:         case 3:
1.1.1.6   root     1448:             if (ctx->mem_idx > 0) {
1.1.1.5   root     1449:                 /* Set process priority to high */
1.1.1.6   root     1450:                 prio = 6;
1.1.1.5   root     1451:             }
                   1452:             break;
                   1453:         case 7:
1.1.1.6   root     1454:             if (ctx->mem_idx > 1) {
1.1.1.5   root     1455:                 /* Set process priority to very high */
1.1.1.6   root     1456:                 prio = 7;
1.1.1.5   root     1457:             }
                   1458:             break;
                   1459: #endif
                   1460:         default:
                   1461:             /* nop */
                   1462:             break;
                   1463:         }
1.1.1.6   root     1464:         if (prio) {
                   1465:             TCGv t0 = tcg_temp_new();
                   1466:             gen_load_spr(t0, SPR_PPR);
                   1467:             tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
                   1468:             tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
                   1469:             gen_store_spr(SPR_PPR, t0);
                   1470:             tcg_temp_free(t0);
                   1471:         }
1.1.1.5   root     1472: #endif
1.1       root     1473:     }
                   1474: }
                   1475: /* orc & orc. */
1.1.1.6   root     1476: GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
1.1.1.7   root     1477: 
1.1       root     1478: /* xor & xor. */
1.1.1.7   root     1479: static void gen_xor(DisasContext *ctx)
1.1       root     1480: {
                   1481:     /* Optimisation for "set to zero" case */
1.1.1.6   root     1482:     if (rS(ctx->opcode) != rB(ctx->opcode))
                   1483:         tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   1484:     else
                   1485:         tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1.1.1.5   root     1486:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1487:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1488: }
1.1.1.7   root     1489: 
1.1       root     1490: /* ori */
1.1.1.7   root     1491: static void gen_ori(DisasContext *ctx)
1.1       root     1492: {
1.1.1.5   root     1493:     target_ulong uimm = UIMM(ctx->opcode);
1.1       root     1494: 
                   1495:     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
                   1496:         /* NOP */
1.1.1.5   root     1497:         /* XXX: should handle special NOPs for POWER series */
1.1       root     1498:         return;
1.1.1.5   root     1499:     }
1.1.1.6   root     1500:     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1.1       root     1501: }
1.1.1.7   root     1502: 
1.1       root     1503: /* oris */
1.1.1.7   root     1504: static void gen_oris(DisasContext *ctx)
1.1       root     1505: {
1.1.1.5   root     1506:     target_ulong uimm = UIMM(ctx->opcode);
1.1       root     1507: 
                   1508:     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
                   1509:         /* NOP */
                   1510:         return;
1.1.1.5   root     1511:     }
1.1.1.6   root     1512:     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1.1       root     1513: }
1.1.1.7   root     1514: 
1.1       root     1515: /* xori */
1.1.1.7   root     1516: static void gen_xori(DisasContext *ctx)
1.1       root     1517: {
1.1.1.5   root     1518:     target_ulong uimm = UIMM(ctx->opcode);
1.1       root     1519: 
                   1520:     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
                   1521:         /* NOP */
                   1522:         return;
                   1523:     }
1.1.1.6   root     1524:     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1.1       root     1525: }
1.1.1.7   root     1526: 
1.1       root     1527: /* xoris */
1.1.1.7   root     1528: static void gen_xoris(DisasContext *ctx)
1.1       root     1529: {
1.1.1.5   root     1530:     target_ulong uimm = UIMM(ctx->opcode);
1.1       root     1531: 
                   1532:     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
                   1533:         /* NOP */
                   1534:         return;
                   1535:     }
1.1.1.6   root     1536:     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1.1.1.5   root     1537: }
1.1.1.7   root     1538: 
1.1.1.5   root     1539: /* popcntb : PowerPC 2.03 specification */
1.1.1.7   root     1540: static void gen_popcntb(DisasContext *ctx)
1.1.1.5   root     1541: {
1.1.1.11  root     1542:     gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1543: }
                   1544: 
                   1545: static void gen_popcntw(DisasContext *ctx)
                   1546: {
                   1547:     gen_helper_popcntw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1548: }
                   1549: 
1.1.1.5   root     1550: #if defined(TARGET_PPC64)
1.1.1.11  root     1551: /* popcntd: PowerPC 2.06 specification */
                   1552: static void gen_popcntd(DisasContext *ctx)
                   1553: {
                   1554:     gen_helper_popcntd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1.1       root     1555: }
1.1.1.11  root     1556: #endif
1.1       root     1557: 
1.1.1.5   root     1558: #if defined(TARGET_PPC64)
                   1559: /* extsw & extsw. */
1.1.1.6   root     1560: GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
1.1.1.7   root     1561: 
1.1.1.5   root     1562: /* cntlzd */
1.1.1.7   root     1563: static void gen_cntlzd(DisasContext *ctx)
1.1.1.6   root     1564: {
                   1565:     gen_helper_cntlzd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1566:     if (unlikely(Rc(ctx->opcode) != 0))
                   1567:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
                   1568: }
1.1.1.5   root     1569: #endif
                   1570: 
1.1       root     1571: /***                             Integer rotate                            ***/
1.1.1.7   root     1572: 
1.1       root     1573: /* rlwimi & rlwimi. */
1.1.1.7   root     1574: static void gen_rlwimi(DisasContext *ctx)
1.1       root     1575: {
1.1.1.5   root     1576:     uint32_t mb, me, sh;
1.1       root     1577: 
                   1578:     mb = MB(ctx->opcode);
                   1579:     me = ME(ctx->opcode);
1.1.1.5   root     1580:     sh = SH(ctx->opcode);
1.1.1.6   root     1581:     if (likely(sh == 0 && mb == 0 && me == 31)) {
                   1582:         tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1583:     } else {
                   1584:         target_ulong mask;
                   1585:         TCGv t1;
                   1586:         TCGv t0 = tcg_temp_new();
                   1587: #if defined(TARGET_PPC64)
                   1588:         TCGv_i32 t2 = tcg_temp_new_i32();
                   1589:         tcg_gen_trunc_i64_i32(t2, cpu_gpr[rS(ctx->opcode)]);
                   1590:         tcg_gen_rotli_i32(t2, t2, sh);
                   1591:         tcg_gen_extu_i32_i64(t0, t2);
                   1592:         tcg_temp_free_i32(t2);
                   1593: #else
                   1594:         tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   1595: #endif
                   1596: #if defined(TARGET_PPC64)
                   1597:         mb += 32;
                   1598:         me += 32;
                   1599: #endif
                   1600:         mask = MASK(mb, me);
                   1601:         t1 = tcg_temp_new();
                   1602:         tcg_gen_andi_tl(t0, t0, mask);
                   1603:         tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
                   1604:         tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   1605:         tcg_temp_free(t0);
                   1606:         tcg_temp_free(t1);
                   1607:     }
1.1.1.5   root     1608:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1609:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1610: }
1.1.1.7   root     1611: 
1.1       root     1612: /* rlwinm & rlwinm. */
1.1.1.7   root     1613: static void gen_rlwinm(DisasContext *ctx)
1.1       root     1614: {
                   1615:     uint32_t mb, me, sh;
1.1.1.5   root     1616: 
1.1       root     1617:     sh = SH(ctx->opcode);
                   1618:     mb = MB(ctx->opcode);
                   1619:     me = ME(ctx->opcode);
1.1.1.6   root     1620: 
                   1621:     if (likely(mb == 0 && me == (31 - sh))) {
                   1622:         if (likely(sh == 0)) {
                   1623:             tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1624:         } else {
                   1625:             TCGv t0 = tcg_temp_new();
                   1626:             tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
                   1627:             tcg_gen_shli_tl(t0, t0, sh);
                   1628:             tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   1629:             tcg_temp_free(t0);
1.1       root     1630:         }
1.1.1.6   root     1631:     } else if (likely(sh != 0 && me == 31 && sh == (32 - mb))) {
                   1632:         TCGv t0 = tcg_temp_new();
                   1633:         tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
                   1634:         tcg_gen_shri_tl(t0, t0, mb);
                   1635:         tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   1636:         tcg_temp_free(t0);
                   1637:     } else {
                   1638:         TCGv t0 = tcg_temp_new();
                   1639: #if defined(TARGET_PPC64)
                   1640:         TCGv_i32 t1 = tcg_temp_new_i32();
                   1641:         tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
                   1642:         tcg_gen_rotli_i32(t1, t1, sh);
                   1643:         tcg_gen_extu_i32_i64(t0, t1);
                   1644:         tcg_temp_free_i32(t1);
                   1645: #else
                   1646:         tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   1647: #endif
1.1.1.5   root     1648: #if defined(TARGET_PPC64)
1.1.1.6   root     1649:         mb += 32;
                   1650:         me += 32;
1.1.1.5   root     1651: #endif
1.1.1.6   root     1652:         tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
                   1653:         tcg_temp_free(t0);
                   1654:     }
1.1.1.5   root     1655:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1656:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1657: }
1.1.1.7   root     1658: 
1.1       root     1659: /* rlwnm & rlwnm. */
1.1.1.7   root     1660: static void gen_rlwnm(DisasContext *ctx)
1.1       root     1661: {
                   1662:     uint32_t mb, me;
1.1.1.6   root     1663:     TCGv t0;
                   1664: #if defined(TARGET_PPC64)
                   1665:     TCGv_i32 t1, t2;
                   1666: #endif
1.1       root     1667: 
                   1668:     mb = MB(ctx->opcode);
                   1669:     me = ME(ctx->opcode);
1.1.1.6   root     1670:     t0 = tcg_temp_new();
                   1671:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1f);
                   1672: #if defined(TARGET_PPC64)
                   1673:     t1 = tcg_temp_new_i32();
                   1674:     t2 = tcg_temp_new_i32();
                   1675:     tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
                   1676:     tcg_gen_trunc_i64_i32(t2, t0);
                   1677:     tcg_gen_rotl_i32(t1, t1, t2);
                   1678:     tcg_gen_extu_i32_i64(t0, t1);
                   1679:     tcg_temp_free_i32(t1);
                   1680:     tcg_temp_free_i32(t2);
                   1681: #else
                   1682:     tcg_gen_rotl_i32(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   1683: #endif
1.1.1.5   root     1684:     if (unlikely(mb != 0 || me != 31)) {
                   1685: #if defined(TARGET_PPC64)
                   1686:         mb += 32;
                   1687:         me += 32;
                   1688: #endif
1.1.1.6   root     1689:         tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
                   1690:     } else {
                   1691:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1.1       root     1692:     }
1.1.1.6   root     1693:     tcg_temp_free(t0);
1.1.1.5   root     1694:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1695:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     1696: }
                   1697: 
                   1698: #if defined(TARGET_PPC64)
                   1699: #define GEN_PPC64_R2(name, opc1, opc2)                                        \
1.1.1.7   root     1700: static void glue(gen_, name##0)(DisasContext *ctx)                            \
1.1.1.5   root     1701: {                                                                             \
                   1702:     gen_##name(ctx, 0);                                                       \
                   1703: }                                                                             \
1.1.1.7   root     1704:                                                                               \
                   1705: static void glue(gen_, name##1)(DisasContext *ctx)                            \
1.1.1.5   root     1706: {                                                                             \
                   1707:     gen_##name(ctx, 1);                                                       \
                   1708: }
                   1709: #define GEN_PPC64_R4(name, opc1, opc2)                                        \
1.1.1.7   root     1710: static void glue(gen_, name##0)(DisasContext *ctx)                            \
1.1.1.5   root     1711: {                                                                             \
                   1712:     gen_##name(ctx, 0, 0);                                                    \
                   1713: }                                                                             \
1.1.1.7   root     1714:                                                                               \
                   1715: static void glue(gen_, name##1)(DisasContext *ctx)                            \
1.1.1.5   root     1716: {                                                                             \
                   1717:     gen_##name(ctx, 0, 1);                                                    \
                   1718: }                                                                             \
1.1.1.7   root     1719:                                                                               \
                   1720: static void glue(gen_, name##2)(DisasContext *ctx)                            \
1.1.1.5   root     1721: {                                                                             \
                   1722:     gen_##name(ctx, 1, 0);                                                    \
                   1723: }                                                                             \
1.1.1.7   root     1724:                                                                               \
                   1725: static void glue(gen_, name##3)(DisasContext *ctx)                            \
1.1.1.5   root     1726: {                                                                             \
                   1727:     gen_##name(ctx, 1, 1);                                                    \
                   1728: }
                   1729: 
1.1.1.8   root     1730: static inline void gen_rldinm(DisasContext *ctx, uint32_t mb, uint32_t me,
                   1731:                               uint32_t sh)
1.1.1.5   root     1732: {
1.1.1.6   root     1733:     if (likely(sh != 0 && mb == 0 && me == (63 - sh))) {
                   1734:         tcg_gen_shli_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
                   1735:     } else if (likely(sh != 0 && me == 63 && sh == (64 - mb))) {
                   1736:         tcg_gen_shri_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], mb);
                   1737:     } else {
                   1738:         TCGv t0 = tcg_temp_new();
                   1739:         tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   1740:         if (likely(mb == 0 && me == 63)) {
                   1741:             tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   1742:         } else {
                   1743:             tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1.1.1.5   root     1744:         }
1.1.1.6   root     1745:         tcg_temp_free(t0);
1.1.1.5   root     1746:     }
                   1747:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1748:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     1749: }
                   1750: /* rldicl - rldicl. */
1.1.1.8   root     1751: static inline void gen_rldicl(DisasContext *ctx, int mbn, int shn)
1.1.1.5   root     1752: {
                   1753:     uint32_t sh, mb;
                   1754: 
                   1755:     sh = SH(ctx->opcode) | (shn << 5);
                   1756:     mb = MB(ctx->opcode) | (mbn << 5);
                   1757:     gen_rldinm(ctx, mb, 63, sh);
                   1758: }
                   1759: GEN_PPC64_R4(rldicl, 0x1E, 0x00);
                   1760: /* rldicr - rldicr. */
1.1.1.8   root     1761: static inline void gen_rldicr(DisasContext *ctx, int men, int shn)
1.1.1.5   root     1762: {
                   1763:     uint32_t sh, me;
                   1764: 
                   1765:     sh = SH(ctx->opcode) | (shn << 5);
                   1766:     me = MB(ctx->opcode) | (men << 5);
                   1767:     gen_rldinm(ctx, 0, me, sh);
                   1768: }
                   1769: GEN_PPC64_R4(rldicr, 0x1E, 0x02);
                   1770: /* rldic - rldic. */
1.1.1.8   root     1771: static inline void gen_rldic(DisasContext *ctx, int mbn, int shn)
1.1.1.5   root     1772: {
                   1773:     uint32_t sh, mb;
                   1774: 
                   1775:     sh = SH(ctx->opcode) | (shn << 5);
                   1776:     mb = MB(ctx->opcode) | (mbn << 5);
                   1777:     gen_rldinm(ctx, mb, 63 - sh, sh);
                   1778: }
                   1779: GEN_PPC64_R4(rldic, 0x1E, 0x04);
                   1780: 
1.1.1.8   root     1781: static inline void gen_rldnm(DisasContext *ctx, uint32_t mb, uint32_t me)
1.1.1.5   root     1782: {
1.1.1.6   root     1783:     TCGv t0;
                   1784: 
                   1785:     mb = MB(ctx->opcode);
                   1786:     me = ME(ctx->opcode);
                   1787:     t0 = tcg_temp_new();
                   1788:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
                   1789:     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1.1.1.5   root     1790:     if (unlikely(mb != 0 || me != 63)) {
1.1.1.6   root     1791:         tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
                   1792:     } else {
                   1793:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1.1.1.5   root     1794:     }
1.1.1.6   root     1795:     tcg_temp_free(t0);
1.1.1.5   root     1796:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1797:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     1798: }
                   1799: 
                   1800: /* rldcl - rldcl. */
1.1.1.8   root     1801: static inline void gen_rldcl(DisasContext *ctx, int mbn)
1.1.1.5   root     1802: {
                   1803:     uint32_t mb;
                   1804: 
                   1805:     mb = MB(ctx->opcode) | (mbn << 5);
                   1806:     gen_rldnm(ctx, mb, 63);
                   1807: }
                   1808: GEN_PPC64_R2(rldcl, 0x1E, 0x08);
                   1809: /* rldcr - rldcr. */
1.1.1.8   root     1810: static inline void gen_rldcr(DisasContext *ctx, int men)
1.1.1.5   root     1811: {
                   1812:     uint32_t me;
                   1813: 
                   1814:     me = MB(ctx->opcode) | (men << 5);
                   1815:     gen_rldnm(ctx, 0, me);
                   1816: }
                   1817: GEN_PPC64_R2(rldcr, 0x1E, 0x09);
                   1818: /* rldimi - rldimi. */
1.1.1.8   root     1819: static inline void gen_rldimi(DisasContext *ctx, int mbn, int shn)
1.1.1.5   root     1820: {
                   1821:     uint32_t sh, mb, me;
                   1822: 
                   1823:     sh = SH(ctx->opcode) | (shn << 5);
                   1824:     mb = MB(ctx->opcode) | (mbn << 5);
                   1825:     me = 63 - sh;
1.1.1.6   root     1826:     if (unlikely(sh == 0 && mb == 0)) {
                   1827:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1828:     } else {
                   1829:         TCGv t0, t1;
                   1830:         target_ulong mask;
                   1831: 
                   1832:         t0 = tcg_temp_new();
                   1833:         tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   1834:         t1 = tcg_temp_new();
                   1835:         mask = MASK(mb, me);
                   1836:         tcg_gen_andi_tl(t0, t0, mask);
                   1837:         tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
                   1838:         tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   1839:         tcg_temp_free(t0);
                   1840:         tcg_temp_free(t1);
                   1841:     }
1.1.1.5   root     1842:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1843:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1844: }
1.1.1.5   root     1845: GEN_PPC64_R4(rldimi, 0x1E, 0x06);
                   1846: #endif
1.1       root     1847: 
                   1848: /***                             Integer shift                             ***/
1.1.1.7   root     1849: 
1.1       root     1850: /* slw & slw. */
1.1.1.7   root     1851: static void gen_slw(DisasContext *ctx)
1.1.1.6   root     1852: {
1.1.1.8   root     1853:     TCGv t0, t1;
1.1.1.6   root     1854: 
1.1.1.8   root     1855:     t0 = tcg_temp_new();
                   1856:     /* AND rS with a mask that is 0 when rB >= 0x20 */
                   1857: #if defined(TARGET_PPC64)
                   1858:     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
                   1859:     tcg_gen_sari_tl(t0, t0, 0x3f);
                   1860: #else
                   1861:     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
                   1862:     tcg_gen_sari_tl(t0, t0, 0x1f);
                   1863: #endif
                   1864:     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   1865:     t1 = tcg_temp_new();
                   1866:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
                   1867:     tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   1868:     tcg_temp_free(t1);
1.1.1.6   root     1869:     tcg_temp_free(t0);
1.1.1.8   root     1870:     tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.6   root     1871:     if (unlikely(Rc(ctx->opcode) != 0))
                   1872:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
                   1873: }
1.1.1.7   root     1874: 
1.1       root     1875: /* sraw & sraw. */
1.1.1.7   root     1876: static void gen_sraw(DisasContext *ctx)
1.1.1.6   root     1877: {
                   1878:     gen_helper_sraw(cpu_gpr[rA(ctx->opcode)],
                   1879:                     cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   1880:     if (unlikely(Rc(ctx->opcode) != 0))
                   1881:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
                   1882: }
1.1.1.7   root     1883: 
1.1       root     1884: /* srawi & srawi. */
1.1.1.7   root     1885: static void gen_srawi(DisasContext *ctx)
1.1       root     1886: {
1.1.1.6   root     1887:     int sh = SH(ctx->opcode);
                   1888:     if (sh != 0) {
                   1889:         int l1, l2;
                   1890:         TCGv t0;
                   1891:         l1 = gen_new_label();
                   1892:         l2 = gen_new_label();
                   1893:         t0 = tcg_temp_local_new();
                   1894:         tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
                   1895:         tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
                   1896:         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
                   1897:         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
                   1898:         tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
                   1899:         tcg_gen_br(l2);
                   1900:         gen_set_label(l1);
                   1901:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
                   1902:         gen_set_label(l2);
                   1903:         tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
                   1904:         tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], t0, sh);
                   1905:         tcg_temp_free(t0);
                   1906:     } else {
                   1907:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1908:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1.1.1.5   root     1909:     }
                   1910:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1911:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1912: }
1.1.1.7   root     1913: 
1.1       root     1914: /* srw & srw. */
1.1.1.7   root     1915: static void gen_srw(DisasContext *ctx)
1.1.1.6   root     1916: {
                   1917:     TCGv t0, t1;
                   1918: 
1.1.1.8   root     1919:     t0 = tcg_temp_new();
                   1920:     /* AND rS with a mask that is 0 when rB >= 0x20 */
                   1921: #if defined(TARGET_PPC64)
                   1922:     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
                   1923:     tcg_gen_sari_tl(t0, t0, 0x3f);
                   1924: #else
                   1925:     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
                   1926:     tcg_gen_sari_tl(t0, t0, 0x1f);
                   1927: #endif
                   1928:     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   1929:     tcg_gen_ext32u_tl(t0, t0);
1.1.1.6   root     1930:     t1 = tcg_temp_new();
1.1.1.8   root     1931:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
                   1932:     tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
1.1.1.6   root     1933:     tcg_temp_free(t1);
                   1934:     tcg_temp_free(t0);
                   1935:     if (unlikely(Rc(ctx->opcode) != 0))
                   1936:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
                   1937: }
1.1.1.7   root     1938: 
1.1.1.5   root     1939: #if defined(TARGET_PPC64)
                   1940: /* sld & sld. */
1.1.1.7   root     1941: static void gen_sld(DisasContext *ctx)
1.1.1.6   root     1942: {
1.1.1.8   root     1943:     TCGv t0, t1;
1.1.1.6   root     1944: 
1.1.1.8   root     1945:     t0 = tcg_temp_new();
                   1946:     /* AND rS with a mask that is 0 when rB >= 0x40 */
                   1947:     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
                   1948:     tcg_gen_sari_tl(t0, t0, 0x3f);
                   1949:     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   1950:     t1 = tcg_temp_new();
                   1951:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
                   1952:     tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   1953:     tcg_temp_free(t1);
1.1.1.6   root     1954:     tcg_temp_free(t0);
                   1955:     if (unlikely(Rc(ctx->opcode) != 0))
                   1956:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
                   1957: }
1.1.1.7   root     1958: 
1.1.1.5   root     1959: /* srad & srad. */
1.1.1.7   root     1960: static void gen_srad(DisasContext *ctx)
1.1.1.6   root     1961: {
                   1962:     gen_helper_srad(cpu_gpr[rA(ctx->opcode)],
                   1963:                     cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   1964:     if (unlikely(Rc(ctx->opcode) != 0))
                   1965:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
                   1966: }
1.1.1.5   root     1967: /* sradi & sradi. */
1.1.1.8   root     1968: static inline void gen_sradi(DisasContext *ctx, int n)
1.1.1.5   root     1969: {
1.1.1.6   root     1970:     int sh = SH(ctx->opcode) + (n << 5);
1.1.1.5   root     1971:     if (sh != 0) {
1.1.1.6   root     1972:         int l1, l2;
                   1973:         TCGv t0;
                   1974:         l1 = gen_new_label();
                   1975:         l2 = gen_new_label();
                   1976:         t0 = tcg_temp_local_new();
                   1977:         tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
                   1978:         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
                   1979:         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
                   1980:         tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
                   1981:         tcg_gen_br(l2);
                   1982:         gen_set_label(l1);
                   1983:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
                   1984:         gen_set_label(l2);
                   1985:         tcg_temp_free(t0);
                   1986:         tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
                   1987:     } else {
                   1988:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   1989:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1.1.1.5   root     1990:     }
                   1991:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     1992:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     1993: }
1.1.1.7   root     1994: 
                   1995: static void gen_sradi0(DisasContext *ctx)
1.1.1.5   root     1996: {
                   1997:     gen_sradi(ctx, 0);
                   1998: }
1.1.1.7   root     1999: 
                   2000: static void gen_sradi1(DisasContext *ctx)
1.1.1.5   root     2001: {
                   2002:     gen_sradi(ctx, 1);
                   2003: }
1.1.1.7   root     2004: 
1.1.1.5   root     2005: /* srd & srd. */
1.1.1.7   root     2006: static void gen_srd(DisasContext *ctx)
1.1.1.6   root     2007: {
1.1.1.8   root     2008:     TCGv t0, t1;
1.1.1.6   root     2009: 
1.1.1.8   root     2010:     t0 = tcg_temp_new();
                   2011:     /* AND rS with a mask that is 0 when rB >= 0x40 */
                   2012:     tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
                   2013:     tcg_gen_sari_tl(t0, t0, 0x3f);
                   2014:     tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   2015:     t1 = tcg_temp_new();
                   2016:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
                   2017:     tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   2018:     tcg_temp_free(t1);
1.1.1.6   root     2019:     tcg_temp_free(t0);
                   2020:     if (unlikely(Rc(ctx->opcode) != 0))
                   2021:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
                   2022: }
1.1.1.5   root     2023: #endif
1.1       root     2024: 
                   2025: /***                       Floating-Point arithmetic                       ***/
1.1.1.5   root     2026: #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
1.1.1.7   root     2027: static void gen_f##name(DisasContext *ctx)                                    \
1.1       root     2028: {                                                                             \
1.1.1.5   root     2029:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     2030:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     2031:         return;                                                               \
                   2032:     }                                                                         \
1.1.1.6   root     2033:     /* NIP cannot be restored if the memory exception comes from an helper */ \
                   2034:     gen_update_nip(ctx, ctx->nip - 4);                                        \
1.1.1.5   root     2035:     gen_reset_fpstatus();                                                     \
1.1.1.6   root     2036:     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
                   2037:                      cpu_fpr[rC(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);     \
1.1       root     2038:     if (isfloat) {                                                            \
1.1.1.6   root     2039:         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
1.1       root     2040:     }                                                                         \
1.1.1.6   root     2041:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], set_fprf,                      \
                   2042:                      Rc(ctx->opcode) != 0);                                   \
1.1       root     2043: }
                   2044: 
1.1.1.5   root     2045: #define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
                   2046: _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
                   2047: _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
1.1       root     2048: 
1.1.1.5   root     2049: #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1.1.1.7   root     2050: static void gen_f##name(DisasContext *ctx)                                    \
1.1       root     2051: {                                                                             \
1.1.1.5   root     2052:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     2053:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     2054:         return;                                                               \
                   2055:     }                                                                         \
1.1.1.6   root     2056:     /* NIP cannot be restored if the memory exception comes from an helper */ \
                   2057:     gen_update_nip(ctx, ctx->nip - 4);                                        \
1.1.1.5   root     2058:     gen_reset_fpstatus();                                                     \
1.1.1.6   root     2059:     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
                   2060:                      cpu_fpr[rB(ctx->opcode)]);                               \
1.1       root     2061:     if (isfloat) {                                                            \
1.1.1.6   root     2062:         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
1.1       root     2063:     }                                                                         \
1.1.1.6   root     2064:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
                   2065:                      set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     2066: }
1.1.1.5   root     2067: #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
                   2068: _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
                   2069: _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1.1       root     2070: 
1.1.1.5   root     2071: #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
1.1.1.7   root     2072: static void gen_f##name(DisasContext *ctx)                                    \
1.1       root     2073: {                                                                             \
1.1.1.5   root     2074:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     2075:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     2076:         return;                                                               \
                   2077:     }                                                                         \
1.1.1.6   root     2078:     /* NIP cannot be restored if the memory exception comes from an helper */ \
                   2079:     gen_update_nip(ctx, ctx->nip - 4);                                        \
1.1.1.5   root     2080:     gen_reset_fpstatus();                                                     \
1.1.1.6   root     2081:     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
                   2082:                        cpu_fpr[rC(ctx->opcode)]);                             \
1.1       root     2083:     if (isfloat) {                                                            \
1.1.1.6   root     2084:         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
1.1       root     2085:     }                                                                         \
1.1.1.6   root     2086:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
                   2087:                      set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     2088: }
1.1.1.5   root     2089: #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
                   2090: _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
                   2091: _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1.1       root     2092: 
1.1.1.5   root     2093: #define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
1.1.1.7   root     2094: static void gen_f##name(DisasContext *ctx)                                    \
1.1       root     2095: {                                                                             \
1.1.1.5   root     2096:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     2097:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     2098:         return;                                                               \
                   2099:     }                                                                         \
1.1.1.6   root     2100:     /* NIP cannot be restored if the memory exception comes from an helper */ \
                   2101:     gen_update_nip(ctx, ctx->nip - 4);                                        \
1.1.1.5   root     2102:     gen_reset_fpstatus();                                                     \
1.1.1.6   root     2103:     gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);   \
                   2104:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
                   2105:                      set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     2106: }
                   2107: 
1.1.1.5   root     2108: #define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
1.1.1.7   root     2109: static void gen_f##name(DisasContext *ctx)                                    \
1.1       root     2110: {                                                                             \
1.1.1.5   root     2111:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     2112:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     2113:         return;                                                               \
                   2114:     }                                                                         \
1.1.1.6   root     2115:     /* NIP cannot be restored if the memory exception comes from an helper */ \
                   2116:     gen_update_nip(ctx, ctx->nip - 4);                                        \
1.1.1.5   root     2117:     gen_reset_fpstatus();                                                     \
1.1.1.6   root     2118:     gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);   \
                   2119:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
                   2120:                      set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     2121: }
                   2122: 
                   2123: /* fadd - fadds */
1.1.1.5   root     2124: GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
1.1       root     2125: /* fdiv - fdivs */
1.1.1.5   root     2126: GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
1.1       root     2127: /* fmul - fmuls */
1.1.1.5   root     2128: GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
                   2129: 
                   2130: /* fre */
                   2131: GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
1.1       root     2132: 
                   2133: /* fres */
1.1.1.5   root     2134: GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
1.1       root     2135: 
                   2136: /* frsqrte */
1.1.1.5   root     2137: GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
                   2138: 
                   2139: /* frsqrtes */
1.1.1.7   root     2140: static void gen_frsqrtes(DisasContext *ctx)
1.1.1.5   root     2141: {
1.1.1.6   root     2142:     if (unlikely(!ctx->fpu_enabled)) {
                   2143:         gen_exception(ctx, POWERPC_EXCP_FPU);
                   2144:         return;
                   2145:     }
                   2146:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2147:     gen_update_nip(ctx, ctx->nip - 4);
                   2148:     gen_reset_fpstatus();
                   2149:     gen_helper_frsqrte(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
                   2150:     gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);
                   2151:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
1.1.1.5   root     2152: }
1.1       root     2153: 
                   2154: /* fsel */
1.1.1.5   root     2155: _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
1.1       root     2156: /* fsub - fsubs */
1.1.1.5   root     2157: GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
1.1       root     2158: /* Optional: */
1.1.1.7   root     2159: 
1.1       root     2160: /* fsqrt */
1.1.1.7   root     2161: static void gen_fsqrt(DisasContext *ctx)
1.1       root     2162: {
1.1.1.5   root     2163:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2164:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2165:         return;
                   2166:     }
1.1.1.6   root     2167:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2168:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2169:     gen_reset_fpstatus();
1.1.1.6   root     2170:     gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
                   2171:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
1.1       root     2172: }
                   2173: 
1.1.1.7   root     2174: static void gen_fsqrts(DisasContext *ctx)
1.1       root     2175: {
1.1.1.5   root     2176:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2177:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2178:         return;
                   2179:     }
1.1.1.6   root     2180:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2181:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2182:     gen_reset_fpstatus();
1.1.1.6   root     2183:     gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
                   2184:     gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);
                   2185:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
1.1       root     2186: }
                   2187: 
                   2188: /***                     Floating-Point multiply-and-add                   ***/
                   2189: /* fmadd - fmadds */
1.1.1.5   root     2190: GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
1.1       root     2191: /* fmsub - fmsubs */
1.1.1.5   root     2192: GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
1.1       root     2193: /* fnmadd - fnmadds */
1.1.1.5   root     2194: GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
1.1       root     2195: /* fnmsub - fnmsubs */
1.1.1.5   root     2196: GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
1.1       root     2197: 
                   2198: /***                     Floating-Point round & convert                    ***/
                   2199: /* fctiw */
1.1.1.5   root     2200: GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
1.1       root     2201: /* fctiwz */
1.1.1.5   root     2202: GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
1.1       root     2203: /* frsp */
1.1.1.5   root     2204: GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
                   2205: #if defined(TARGET_PPC64)
                   2206: /* fcfid */
                   2207: GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
                   2208: /* fctid */
                   2209: GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
                   2210: /* fctidz */
                   2211: GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
                   2212: #endif
                   2213: 
                   2214: /* frin */
                   2215: GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
                   2216: /* friz */
                   2217: GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
                   2218: /* frip */
                   2219: GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
                   2220: /* frim */
                   2221: GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
1.1       root     2222: 
                   2223: /***                         Floating-Point compare                        ***/
1.1.1.7   root     2224: 
1.1       root     2225: /* fcmpo */
1.1.1.7   root     2226: static void gen_fcmpo(DisasContext *ctx)
1.1       root     2227: {
1.1.1.6   root     2228:     TCGv_i32 crf;
1.1.1.5   root     2229:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2230:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2231:         return;
                   2232:     }
1.1.1.6   root     2233:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2234:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2235:     gen_reset_fpstatus();
1.1.1.6   root     2236:     crf = tcg_const_i32(crfD(ctx->opcode));
                   2237:     gen_helper_fcmpo(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf);
                   2238:     tcg_temp_free_i32(crf);
                   2239:     gen_helper_float_check_status();
1.1       root     2240: }
                   2241: 
                   2242: /* fcmpu */
1.1.1.7   root     2243: static void gen_fcmpu(DisasContext *ctx)
1.1       root     2244: {
1.1.1.6   root     2245:     TCGv_i32 crf;
1.1.1.5   root     2246:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2247:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2248:         return;
                   2249:     }
1.1.1.6   root     2250:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2251:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2252:     gen_reset_fpstatus();
1.1.1.6   root     2253:     crf = tcg_const_i32(crfD(ctx->opcode));
                   2254:     gen_helper_fcmpu(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf);
                   2255:     tcg_temp_free_i32(crf);
                   2256:     gen_helper_float_check_status();
1.1       root     2257: }
                   2258: 
                   2259: /***                         Floating-point move                           ***/
                   2260: /* fabs */
1.1.1.5   root     2261: /* XXX: beware that fabs never checks for NaNs nor update FPSCR */
                   2262: GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
1.1       root     2263: 
                   2264: /* fmr  - fmr. */
1.1.1.5   root     2265: /* XXX: beware that fmr never checks for NaNs nor update FPSCR */
1.1.1.7   root     2266: static void gen_fmr(DisasContext *ctx)
1.1       root     2267: {
1.1.1.5   root     2268:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2269:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2270:         return;
                   2271:     }
1.1.1.6   root     2272:     tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
                   2273:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
1.1       root     2274: }
                   2275: 
                   2276: /* fnabs */
1.1.1.5   root     2277: /* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
                   2278: GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
1.1       root     2279: /* fneg */
1.1.1.5   root     2280: /* XXX: beware that fneg never checks for NaNs nor update FPSCR */
                   2281: GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
1.1       root     2282: 
                   2283: /***                  Floating-Point status & ctrl register                ***/
1.1.1.7   root     2284: 
1.1       root     2285: /* mcrfs */
1.1.1.7   root     2286: static void gen_mcrfs(DisasContext *ctx)
1.1       root     2287: {
1.1.1.5   root     2288:     int bfa;
                   2289: 
                   2290:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2291:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2292:         return;
                   2293:     }
1.1.1.5   root     2294:     bfa = 4 * (7 - crfS(ctx->opcode));
1.1.1.6   root     2295:     tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_fpscr, bfa);
                   2296:     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf);
                   2297:     tcg_gen_andi_i32(cpu_fpscr, cpu_fpscr, ~(0xF << bfa));
1.1       root     2298: }
                   2299: 
                   2300: /* mffs */
1.1.1.7   root     2301: static void gen_mffs(DisasContext *ctx)
1.1       root     2302: {
1.1.1.5   root     2303:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2304:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2305:         return;
                   2306:     }
1.1.1.5   root     2307:     gen_reset_fpstatus();
1.1.1.6   root     2308:     tcg_gen_extu_i32_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpscr);
                   2309:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
1.1       root     2310: }
                   2311: 
                   2312: /* mtfsb0 */
1.1.1.7   root     2313: static void gen_mtfsb0(DisasContext *ctx)
1.1       root     2314: {
                   2315:     uint8_t crb;
1.1.1.5   root     2316: 
                   2317:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2318:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2319:         return;
                   2320:     }
1.1.1.6   root     2321:     crb = 31 - crbD(ctx->opcode);
1.1.1.5   root     2322:     gen_reset_fpstatus();
1.1.1.6   root     2323:     if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) {
                   2324:         TCGv_i32 t0;
                   2325:         /* NIP cannot be restored if the memory exception comes from an helper */
                   2326:         gen_update_nip(ctx, ctx->nip - 4);
                   2327:         t0 = tcg_const_i32(crb);
                   2328:         gen_helper_fpscr_clrbit(t0);
                   2329:         tcg_temp_free_i32(t0);
                   2330:     }
1.1.1.5   root     2331:     if (unlikely(Rc(ctx->opcode) != 0)) {
1.1.1.6   root     2332:         tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
1.1.1.5   root     2333:     }
1.1       root     2334: }
                   2335: 
                   2336: /* mtfsb1 */
1.1.1.7   root     2337: static void gen_mtfsb1(DisasContext *ctx)
1.1       root     2338: {
                   2339:     uint8_t crb;
1.1.1.5   root     2340: 
                   2341:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2342:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2343:         return;
                   2344:     }
1.1.1.6   root     2345:     crb = 31 - crbD(ctx->opcode);
1.1.1.5   root     2346:     gen_reset_fpstatus();
                   2347:     /* XXX: we pretend we can only do IEEE floating-point computations */
1.1.1.6   root     2348:     if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) {
                   2349:         TCGv_i32 t0;
                   2350:         /* NIP cannot be restored if the memory exception comes from an helper */
                   2351:         gen_update_nip(ctx, ctx->nip - 4);
                   2352:         t0 = tcg_const_i32(crb);
                   2353:         gen_helper_fpscr_setbit(t0);
                   2354:         tcg_temp_free_i32(t0);
                   2355:     }
1.1.1.5   root     2356:     if (unlikely(Rc(ctx->opcode) != 0)) {
1.1.1.6   root     2357:         tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
1.1.1.5   root     2358:     }
                   2359:     /* We can raise a differed exception */
1.1.1.6   root     2360:     gen_helper_float_check_status();
1.1       root     2361: }
                   2362: 
                   2363: /* mtfsf */
1.1.1.7   root     2364: static void gen_mtfsf(DisasContext *ctx)
1.1       root     2365: {
1.1.1.6   root     2366:     TCGv_i32 t0;
1.1.1.7   root     2367:     int L = ctx->opcode & 0x02000000;
1.1.1.6   root     2368: 
1.1.1.5   root     2369:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2370:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2371:         return;
                   2372:     }
1.1.1.6   root     2373:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2374:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2375:     gen_reset_fpstatus();
1.1.1.7   root     2376:     if (L)
                   2377:         t0 = tcg_const_i32(0xff);
                   2378:     else
                   2379:         t0 = tcg_const_i32(FM(ctx->opcode));
1.1.1.6   root     2380:     gen_helper_store_fpscr(cpu_fpr[rB(ctx->opcode)], t0);
                   2381:     tcg_temp_free_i32(t0);
1.1.1.5   root     2382:     if (unlikely(Rc(ctx->opcode) != 0)) {
1.1.1.6   root     2383:         tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
1.1.1.5   root     2384:     }
                   2385:     /* We can raise a differed exception */
1.1.1.6   root     2386:     gen_helper_float_check_status();
1.1       root     2387: }
                   2388: 
                   2389: /* mtfsfi */
1.1.1.7   root     2390: static void gen_mtfsfi(DisasContext *ctx)
1.1       root     2391: {
1.1.1.5   root     2392:     int bf, sh;
1.1.1.6   root     2393:     TCGv_i64 t0;
                   2394:     TCGv_i32 t1;
1.1.1.5   root     2395: 
                   2396:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6   root     2397:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2398:         return;
                   2399:     }
1.1.1.5   root     2400:     bf = crbD(ctx->opcode) >> 2;
                   2401:     sh = 7 - bf;
1.1.1.6   root     2402:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2403:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2404:     gen_reset_fpstatus();
1.1.1.6   root     2405:     t0 = tcg_const_i64(FPIMM(ctx->opcode) << (4 * sh));
                   2406:     t1 = tcg_const_i32(1 << sh);
                   2407:     gen_helper_store_fpscr(t0, t1);
                   2408:     tcg_temp_free_i64(t0);
                   2409:     tcg_temp_free_i32(t1);
1.1.1.5   root     2410:     if (unlikely(Rc(ctx->opcode) != 0)) {
1.1.1.6   root     2411:         tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
1.1.1.5   root     2412:     }
                   2413:     /* We can raise a differed exception */
1.1.1.6   root     2414:     gen_helper_float_check_status();
1.1       root     2415: }
                   2416: 
1.1.1.5   root     2417: /***                           Addressing modes                            ***/
                   2418: /* Register indirect with immediate index : EA = (rA|0) + SIMM */
1.1.1.8   root     2419: static inline void gen_addr_imm_index(DisasContext *ctx, TCGv EA,
                   2420:                                       target_long maskl)
1.1.1.5   root     2421: {
                   2422:     target_long simm = SIMM(ctx->opcode);
                   2423: 
                   2424:     simm &= ~maskl;
                   2425:     if (rA(ctx->opcode) == 0) {
1.1.1.6   root     2426: #if defined(TARGET_PPC64)
                   2427:         if (!ctx->sf_mode) {
                   2428:             tcg_gen_movi_tl(EA, (uint32_t)simm);
                   2429:         } else
                   2430: #endif
                   2431:         tcg_gen_movi_tl(EA, simm);
                   2432:     } else if (likely(simm != 0)) {
                   2433:         tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
                   2434: #if defined(TARGET_PPC64)
                   2435:         if (!ctx->sf_mode) {
                   2436:             tcg_gen_ext32u_tl(EA, EA);
                   2437:         }
                   2438: #endif
1.1.1.5   root     2439:     } else {
1.1.1.6   root     2440: #if defined(TARGET_PPC64)
                   2441:         if (!ctx->sf_mode) {
                   2442:             tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
                   2443:         } else
1.1.1.5   root     2444: #endif
1.1.1.6   root     2445:         tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
                   2446:     }
1.1.1.5   root     2447: }
                   2448: 
1.1.1.8   root     2449: static inline void gen_addr_reg_index(DisasContext *ctx, TCGv EA)
1.1.1.5   root     2450: {
                   2451:     if (rA(ctx->opcode) == 0) {
1.1.1.6   root     2452: #if defined(TARGET_PPC64)
                   2453:         if (!ctx->sf_mode) {
                   2454:             tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]);
                   2455:         } else
                   2456: #endif
                   2457:         tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     2458:     } else {
1.1.1.6   root     2459:         tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   2460: #if defined(TARGET_PPC64)
                   2461:         if (!ctx->sf_mode) {
                   2462:             tcg_gen_ext32u_tl(EA, EA);
                   2463:         }
1.1.1.5   root     2464: #endif
1.1.1.6   root     2465:     }
1.1.1.5   root     2466: }
                   2467: 
1.1.1.8   root     2468: static inline void gen_addr_register(DisasContext *ctx, TCGv EA)
1.1.1.5   root     2469: {
                   2470:     if (rA(ctx->opcode) == 0) {
1.1.1.6   root     2471:         tcg_gen_movi_tl(EA, 0);
1.1.1.5   root     2472:     } else {
1.1.1.6   root     2473: #if defined(TARGET_PPC64)
                   2474:         if (!ctx->sf_mode) {
                   2475:             tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
                   2476:         } else
                   2477: #endif
                   2478:             tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
                   2479:     }
                   2480: }
                   2481: 
1.1.1.8   root     2482: static inline void gen_addr_add(DisasContext *ctx, TCGv ret, TCGv arg1,
                   2483:                                 target_long val)
1.1.1.6   root     2484: {
                   2485:     tcg_gen_addi_tl(ret, arg1, val);
                   2486: #if defined(TARGET_PPC64)
                   2487:     if (!ctx->sf_mode) {
                   2488:         tcg_gen_ext32u_tl(ret, ret);
1.1.1.5   root     2489:     }
                   2490: #endif
                   2491: }
                   2492: 
1.1.1.8   root     2493: static inline void gen_check_align(DisasContext *ctx, TCGv EA, int mask)
1.1.1.6   root     2494: {
                   2495:     int l1 = gen_new_label();
                   2496:     TCGv t0 = tcg_temp_new();
                   2497:     TCGv_i32 t1, t2;
                   2498:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2499:     gen_update_nip(ctx, ctx->nip - 4);
                   2500:     tcg_gen_andi_tl(t0, EA, mask);
                   2501:     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
                   2502:     t1 = tcg_const_i32(POWERPC_EXCP_ALIGN);
                   2503:     t2 = tcg_const_i32(0);
                   2504:     gen_helper_raise_exception_err(t1, t2);
                   2505:     tcg_temp_free_i32(t1);
                   2506:     tcg_temp_free_i32(t2);
                   2507:     gen_set_label(l1);
                   2508:     tcg_temp_free(t0);
                   2509: }
                   2510: 
                   2511: /***                             Integer load                              ***/
1.1.1.8   root     2512: static inline void gen_qemu_ld8u(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2513: {
                   2514:     tcg_gen_qemu_ld8u(arg1, arg2, ctx->mem_idx);
                   2515: }
                   2516: 
1.1.1.8   root     2517: static inline void gen_qemu_ld8s(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2518: {
                   2519:     tcg_gen_qemu_ld8s(arg1, arg2, ctx->mem_idx);
                   2520: }
                   2521: 
1.1.1.8   root     2522: static inline void gen_qemu_ld16u(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2523: {
                   2524:     tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
                   2525:     if (unlikely(ctx->le_mode)) {
1.1.1.7   root     2526:         tcg_gen_bswap16_tl(arg1, arg1);
1.1.1.6   root     2527:     }
                   2528: }
                   2529: 
1.1.1.8   root     2530: static inline void gen_qemu_ld16s(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2531: {
                   2532:     if (unlikely(ctx->le_mode)) {
                   2533:         tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
1.1.1.7   root     2534:         tcg_gen_bswap16_tl(arg1, arg1);
1.1.1.6   root     2535:         tcg_gen_ext16s_tl(arg1, arg1);
                   2536:     } else {
                   2537:         tcg_gen_qemu_ld16s(arg1, arg2, ctx->mem_idx);
                   2538:     }
                   2539: }
                   2540: 
1.1.1.8   root     2541: static inline void gen_qemu_ld32u(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2542: {
                   2543:     tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
                   2544:     if (unlikely(ctx->le_mode)) {
1.1.1.7   root     2545:         tcg_gen_bswap32_tl(arg1, arg1);
1.1.1.6   root     2546:     }
1.1       root     2547: }
                   2548: 
1.1.1.6   root     2549: #if defined(TARGET_PPC64)
1.1.1.8   root     2550: static inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2551: {
                   2552:     if (unlikely(ctx->le_mode)) {
                   2553:         tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
1.1.1.7   root     2554:         tcg_gen_bswap32_tl(arg1, arg1);
                   2555:         tcg_gen_ext32s_tl(arg1, arg1);
1.1.1.6   root     2556:     } else
                   2557:         tcg_gen_qemu_ld32s(arg1, arg2, ctx->mem_idx);
                   2558: }
                   2559: #endif
                   2560: 
1.1.1.8   root     2561: static inline void gen_qemu_ld64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
1.1.1.6   root     2562: {
                   2563:     tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
                   2564:     if (unlikely(ctx->le_mode)) {
1.1.1.7   root     2565:         tcg_gen_bswap64_i64(arg1, arg1);
1.1.1.6   root     2566:     }
                   2567: }
                   2568: 
1.1.1.8   root     2569: static inline void gen_qemu_st8(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2570: {
                   2571:     tcg_gen_qemu_st8(arg1, arg2, ctx->mem_idx);
                   2572: }
                   2573: 
1.1.1.8   root     2574: static inline void gen_qemu_st16(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2575: {
                   2576:     if (unlikely(ctx->le_mode)) {
                   2577:         TCGv t0 = tcg_temp_new();
                   2578:         tcg_gen_ext16u_tl(t0, arg1);
1.1.1.7   root     2579:         tcg_gen_bswap16_tl(t0, t0);
1.1.1.6   root     2580:         tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
                   2581:         tcg_temp_free(t0);
                   2582:     } else {
                   2583:         tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
                   2584:     }
                   2585: }
                   2586: 
1.1.1.8   root     2587: static inline void gen_qemu_st32(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2588: {
                   2589:     if (unlikely(ctx->le_mode)) {
1.1.1.7   root     2590:         TCGv t0 = tcg_temp_new();
                   2591:         tcg_gen_ext32u_tl(t0, arg1);
                   2592:         tcg_gen_bswap32_tl(t0, t0);
1.1.1.6   root     2593:         tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
                   2594:         tcg_temp_free(t0);
                   2595:     } else {
                   2596:         tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
                   2597:     }
                   2598: }
                   2599: 
1.1.1.8   root     2600: static inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
1.1.1.6   root     2601: {
                   2602:     if (unlikely(ctx->le_mode)) {
                   2603:         TCGv_i64 t0 = tcg_temp_new_i64();
1.1.1.7   root     2604:         tcg_gen_bswap64_i64(t0, arg1);
1.1.1.6   root     2605:         tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx);
                   2606:         tcg_temp_free_i64(t0);
                   2607:     } else
                   2608:         tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx);
                   2609: }
                   2610: 
                   2611: #define GEN_LD(name, ldop, opc, type)                                         \
1.1.1.7   root     2612: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.6   root     2613: {                                                                             \
                   2614:     TCGv EA;                                                                  \
                   2615:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   2616:     EA = tcg_temp_new();                                                      \
                   2617:     gen_addr_imm_index(ctx, EA, 0);                                           \
                   2618:     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
                   2619:     tcg_temp_free(EA);                                                        \
                   2620: }
                   2621: 
                   2622: #define GEN_LDU(name, ldop, opc, type)                                        \
1.1.1.7   root     2623: static void glue(gen_, name##u)(DisasContext *ctx)                                    \
1.1       root     2624: {                                                                             \
1.1.1.6   root     2625:     TCGv EA;                                                                  \
1.1.1.5   root     2626:     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
                   2627:                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1.1.1.6   root     2628:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     2629:         return;                                                               \
                   2630:     }                                                                         \
1.1.1.6   root     2631:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   2632:     EA = tcg_temp_new();                                                      \
1.1.1.5   root     2633:     if (type == PPC_64B)                                                      \
1.1.1.6   root     2634:         gen_addr_imm_index(ctx, EA, 0x03);                                    \
1.1.1.5   root     2635:     else                                                                      \
1.1.1.6   root     2636:         gen_addr_imm_index(ctx, EA, 0);                                       \
                   2637:     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
                   2638:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
                   2639:     tcg_temp_free(EA);                                                        \
1.1       root     2640: }
                   2641: 
1.1.1.6   root     2642: #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
1.1.1.7   root     2643: static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
1.1       root     2644: {                                                                             \
1.1.1.6   root     2645:     TCGv EA;                                                                  \
1.1.1.5   root     2646:     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
                   2647:                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1.1.1.6   root     2648:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     2649:         return;                                                               \
                   2650:     }                                                                         \
1.1.1.6   root     2651:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   2652:     EA = tcg_temp_new();                                                      \
                   2653:     gen_addr_reg_index(ctx, EA);                                              \
                   2654:     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
                   2655:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
                   2656:     tcg_temp_free(EA);                                                        \
                   2657: }
                   2658: 
                   2659: #define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
1.1.1.7   root     2660: static void glue(gen_, name##x)(DisasContext *ctx)                            \
1.1.1.6   root     2661: {                                                                             \
                   2662:     TCGv EA;                                                                  \
                   2663:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   2664:     EA = tcg_temp_new();                                                      \
                   2665:     gen_addr_reg_index(ctx, EA);                                              \
                   2666:     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
                   2667:     tcg_temp_free(EA);                                                        \
                   2668: }
                   2669: 
                   2670: #define GEN_LDS(name, ldop, op, type)                                         \
                   2671: GEN_LD(name, ldop, op | 0x20, type);                                          \
                   2672: GEN_LDU(name, ldop, op | 0x21, type);                                         \
                   2673: GEN_LDUX(name, ldop, 0x17, op | 0x01, type);                                  \
                   2674: GEN_LDX(name, ldop, 0x17, op | 0x00, type)
1.1       root     2675: 
                   2676: /* lbz lbzu lbzux lbzx */
1.1.1.6   root     2677: GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER);
1.1       root     2678: /* lha lhau lhaux lhax */
1.1.1.6   root     2679: GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER);
1.1       root     2680: /* lhz lhzu lhzux lhzx */
1.1.1.6   root     2681: GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER);
1.1       root     2682: /* lwz lwzu lwzux lwzx */
1.1.1.6   root     2683: GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER);
1.1.1.5   root     2684: #if defined(TARGET_PPC64)
                   2685: /* lwaux */
1.1.1.6   root     2686: GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B);
1.1.1.5   root     2687: /* lwax */
1.1.1.6   root     2688: GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B);
1.1.1.5   root     2689: /* ldux */
1.1.1.6   root     2690: GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B);
1.1.1.5   root     2691: /* ldx */
1.1.1.6   root     2692: GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B);
1.1.1.7   root     2693: 
                   2694: static void gen_ld(DisasContext *ctx)
1.1.1.5   root     2695: {
1.1.1.6   root     2696:     TCGv EA;
1.1.1.5   root     2697:     if (Rc(ctx->opcode)) {
                   2698:         if (unlikely(rA(ctx->opcode) == 0 ||
                   2699:                      rA(ctx->opcode) == rD(ctx->opcode))) {
1.1.1.6   root     2700:             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     2701:             return;
                   2702:         }
                   2703:     }
1.1.1.6   root     2704:     gen_set_access_type(ctx, ACCESS_INT);
                   2705:     EA = tcg_temp_new();
                   2706:     gen_addr_imm_index(ctx, EA, 0x03);
1.1.1.5   root     2707:     if (ctx->opcode & 0x02) {
                   2708:         /* lwa (lwau is undefined) */
1.1.1.6   root     2709:         gen_qemu_ld32s(ctx, cpu_gpr[rD(ctx->opcode)], EA);
1.1.1.5   root     2710:     } else {
                   2711:         /* ld - ldu */
1.1.1.6   root     2712:         gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], EA);
1.1.1.5   root     2713:     }
                   2714:     if (Rc(ctx->opcode))
1.1.1.6   root     2715:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
                   2716:     tcg_temp_free(EA);
1.1.1.5   root     2717: }
1.1.1.7   root     2718: 
1.1.1.5   root     2719: /* lq */
1.1.1.7   root     2720: static void gen_lq(DisasContext *ctx)
1.1.1.5   root     2721: {
                   2722: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     2723:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     2724: #else
                   2725:     int ra, rd;
1.1.1.6   root     2726:     TCGv EA;
1.1.1.5   root     2727: 
                   2728:     /* Restore CPU state */
1.1.1.6   root     2729:     if (unlikely(ctx->mem_idx == 0)) {
                   2730:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     2731:         return;
                   2732:     }
                   2733:     ra = rA(ctx->opcode);
                   2734:     rd = rD(ctx->opcode);
                   2735:     if (unlikely((rd & 1) || rd == ra)) {
1.1.1.6   root     2736:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     2737:         return;
                   2738:     }
1.1.1.6   root     2739:     if (unlikely(ctx->le_mode)) {
1.1.1.5   root     2740:         /* Little-endian mode is not handled */
1.1.1.6   root     2741:         gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
1.1.1.5   root     2742:         return;
                   2743:     }
1.1.1.6   root     2744:     gen_set_access_type(ctx, ACCESS_INT);
                   2745:     EA = tcg_temp_new();
                   2746:     gen_addr_imm_index(ctx, EA, 0x0F);
                   2747:     gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
                   2748:     gen_addr_add(ctx, EA, EA, 8);
                   2749:     gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
                   2750:     tcg_temp_free(EA);
1.1.1.5   root     2751: #endif
                   2752: }
                   2753: #endif
1.1       root     2754: 
                   2755: /***                              Integer store                            ***/
1.1.1.6   root     2756: #define GEN_ST(name, stop, opc, type)                                         \
1.1.1.7   root     2757: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1       root     2758: {                                                                             \
1.1.1.6   root     2759:     TCGv EA;                                                                  \
                   2760:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   2761:     EA = tcg_temp_new();                                                      \
                   2762:     gen_addr_imm_index(ctx, EA, 0);                                           \
                   2763:     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
                   2764:     tcg_temp_free(EA);                                                        \
1.1       root     2765: }
                   2766: 
1.1.1.6   root     2767: #define GEN_STU(name, stop, opc, type)                                        \
1.1.1.7   root     2768: static void glue(gen_, stop##u)(DisasContext *ctx)                                    \
1.1       root     2769: {                                                                             \
1.1.1.6   root     2770:     TCGv EA;                                                                  \
1.1.1.5   root     2771:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6   root     2772:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     2773:         return;                                                               \
                   2774:     }                                                                         \
1.1.1.6   root     2775:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   2776:     EA = tcg_temp_new();                                                      \
1.1.1.5   root     2777:     if (type == PPC_64B)                                                      \
1.1.1.6   root     2778:         gen_addr_imm_index(ctx, EA, 0x03);                                    \
1.1.1.5   root     2779:     else                                                                      \
1.1.1.6   root     2780:         gen_addr_imm_index(ctx, EA, 0);                                       \
                   2781:     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
                   2782:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
                   2783:     tcg_temp_free(EA);                                                        \
1.1       root     2784: }
                   2785: 
1.1.1.6   root     2786: #define GEN_STUX(name, stop, opc2, opc3, type)                                \
1.1.1.7   root     2787: static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
1.1       root     2788: {                                                                             \
1.1.1.6   root     2789:     TCGv EA;                                                                  \
1.1.1.5   root     2790:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6   root     2791:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     2792:         return;                                                               \
                   2793:     }                                                                         \
1.1.1.6   root     2794:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   2795:     EA = tcg_temp_new();                                                      \
                   2796:     gen_addr_reg_index(ctx, EA);                                              \
                   2797:     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
                   2798:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
                   2799:     tcg_temp_free(EA);                                                        \
                   2800: }
                   2801: 
                   2802: #define GEN_STX(name, stop, opc2, opc3, type)                                 \
1.1.1.7   root     2803: static void glue(gen_, name##x)(DisasContext *ctx)                                    \
1.1.1.6   root     2804: {                                                                             \
                   2805:     TCGv EA;                                                                  \
                   2806:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   2807:     EA = tcg_temp_new();                                                      \
                   2808:     gen_addr_reg_index(ctx, EA);                                              \
                   2809:     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
                   2810:     tcg_temp_free(EA);                                                        \
                   2811: }
                   2812: 
                   2813: #define GEN_STS(name, stop, op, type)                                         \
                   2814: GEN_ST(name, stop, op | 0x20, type);                                          \
                   2815: GEN_STU(name, stop, op | 0x21, type);                                         \
                   2816: GEN_STUX(name, stop, 0x17, op | 0x01, type);                                  \
                   2817: GEN_STX(name, stop, 0x17, op | 0x00, type)
1.1       root     2818: 
                   2819: /* stb stbu stbux stbx */
1.1.1.6   root     2820: GEN_STS(stb, st8, 0x06, PPC_INTEGER);
1.1       root     2821: /* sth sthu sthux sthx */
1.1.1.6   root     2822: GEN_STS(sth, st16, 0x0C, PPC_INTEGER);
1.1       root     2823: /* stw stwu stwux stwx */
1.1.1.6   root     2824: GEN_STS(stw, st32, 0x04, PPC_INTEGER);
1.1.1.5   root     2825: #if defined(TARGET_PPC64)
1.1.1.6   root     2826: GEN_STUX(std, st64, 0x15, 0x05, PPC_64B);
                   2827: GEN_STX(std, st64, 0x15, 0x04, PPC_64B);
1.1.1.7   root     2828: 
                   2829: static void gen_std(DisasContext *ctx)
1.1.1.5   root     2830: {
                   2831:     int rs;
1.1.1.6   root     2832:     TCGv EA;
1.1       root     2833: 
1.1.1.5   root     2834:     rs = rS(ctx->opcode);
                   2835:     if ((ctx->opcode & 0x3) == 0x2) {
                   2836: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     2837:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     2838: #else
                   2839:         /* stq */
1.1.1.6   root     2840:         if (unlikely(ctx->mem_idx == 0)) {
                   2841:             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     2842:             return;
                   2843:         }
                   2844:         if (unlikely(rs & 1)) {
1.1.1.6   root     2845:             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     2846:             return;
                   2847:         }
1.1.1.6   root     2848:         if (unlikely(ctx->le_mode)) {
1.1.1.5   root     2849:             /* Little-endian mode is not handled */
1.1.1.6   root     2850:             gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
1.1.1.5   root     2851:             return;
                   2852:         }
1.1.1.6   root     2853:         gen_set_access_type(ctx, ACCESS_INT);
                   2854:         EA = tcg_temp_new();
                   2855:         gen_addr_imm_index(ctx, EA, 0x03);
                   2856:         gen_qemu_st64(ctx, cpu_gpr[rs], EA);
                   2857:         gen_addr_add(ctx, EA, EA, 8);
                   2858:         gen_qemu_st64(ctx, cpu_gpr[rs+1], EA);
                   2859:         tcg_temp_free(EA);
1.1.1.5   root     2860: #endif
                   2861:     } else {
                   2862:         /* std / stdu */
                   2863:         if (Rc(ctx->opcode)) {
                   2864:             if (unlikely(rA(ctx->opcode) == 0)) {
1.1.1.6   root     2865:                 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     2866:                 return;
                   2867:             }
                   2868:         }
1.1.1.6   root     2869:         gen_set_access_type(ctx, ACCESS_INT);
                   2870:         EA = tcg_temp_new();
                   2871:         gen_addr_imm_index(ctx, EA, 0x03);
                   2872:         gen_qemu_st64(ctx, cpu_gpr[rs], EA);
1.1.1.5   root     2873:         if (Rc(ctx->opcode))
1.1.1.6   root     2874:             tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
                   2875:         tcg_temp_free(EA);
1.1.1.5   root     2876:     }
                   2877: }
                   2878: #endif
1.1       root     2879: /***                Integer load and store with byte reverse               ***/
                   2880: /* lhbrx */
1.1.1.8   root     2881: static inline void gen_qemu_ld16ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2882: {
                   2883:     tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
                   2884:     if (likely(!ctx->le_mode)) {
1.1.1.7   root     2885:         tcg_gen_bswap16_tl(arg1, arg1);
1.1.1.6   root     2886:     }
                   2887: }
                   2888: GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
                   2889: 
1.1       root     2890: /* lwbrx */
1.1.1.8   root     2891: static inline void gen_qemu_ld32ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2892: {
                   2893:     tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
                   2894:     if (likely(!ctx->le_mode)) {
1.1.1.7   root     2895:         tcg_gen_bswap32_tl(arg1, arg1);
1.1.1.6   root     2896:     }
                   2897: }
                   2898: GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
                   2899: 
1.1       root     2900: /* sthbrx */
1.1.1.8   root     2901: static inline void gen_qemu_st16r(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2902: {
                   2903:     if (likely(!ctx->le_mode)) {
                   2904:         TCGv t0 = tcg_temp_new();
                   2905:         tcg_gen_ext16u_tl(t0, arg1);
1.1.1.7   root     2906:         tcg_gen_bswap16_tl(t0, t0);
1.1.1.6   root     2907:         tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
                   2908:         tcg_temp_free(t0);
                   2909:     } else {
                   2910:         tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
                   2911:     }
                   2912: }
                   2913: GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
                   2914: 
1.1       root     2915: /* stwbrx */
1.1.1.8   root     2916: static inline void gen_qemu_st32r(DisasContext *ctx, TCGv arg1, TCGv arg2)
1.1.1.6   root     2917: {
                   2918:     if (likely(!ctx->le_mode)) {
1.1.1.7   root     2919:         TCGv t0 = tcg_temp_new();
                   2920:         tcg_gen_ext32u_tl(t0, arg1);
                   2921:         tcg_gen_bswap32_tl(t0, t0);
1.1.1.6   root     2922:         tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
                   2923:         tcg_temp_free(t0);
                   2924:     } else {
                   2925:         tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
                   2926:     }
                   2927: }
                   2928: GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
1.1       root     2929: 
                   2930: /***                    Integer load and store multiple                    ***/
1.1.1.7   root     2931: 
1.1       root     2932: /* lmw */
1.1.1.7   root     2933: static void gen_lmw(DisasContext *ctx)
1.1       root     2934: {
1.1.1.6   root     2935:     TCGv t0;
                   2936:     TCGv_i32 t1;
                   2937:     gen_set_access_type(ctx, ACCESS_INT);
1.1.1.5   root     2938:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2939:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6   root     2940:     t0 = tcg_temp_new();
                   2941:     t1 = tcg_const_i32(rD(ctx->opcode));
                   2942:     gen_addr_imm_index(ctx, t0, 0);
                   2943:     gen_helper_lmw(t0, t1);
                   2944:     tcg_temp_free(t0);
                   2945:     tcg_temp_free_i32(t1);
1.1       root     2946: }
                   2947: 
                   2948: /* stmw */
1.1.1.7   root     2949: static void gen_stmw(DisasContext *ctx)
1.1       root     2950: {
1.1.1.6   root     2951:     TCGv t0;
                   2952:     TCGv_i32 t1;
                   2953:     gen_set_access_type(ctx, ACCESS_INT);
1.1.1.5   root     2954:     /* NIP cannot be restored if the memory exception comes from an helper */
                   2955:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6   root     2956:     t0 = tcg_temp_new();
                   2957:     t1 = tcg_const_i32(rS(ctx->opcode));
                   2958:     gen_addr_imm_index(ctx, t0, 0);
                   2959:     gen_helper_stmw(t0, t1);
                   2960:     tcg_temp_free(t0);
                   2961:     tcg_temp_free_i32(t1);
1.1       root     2962: }
                   2963: 
                   2964: /***                    Integer load and store strings                     ***/
1.1.1.7   root     2965: 
1.1       root     2966: /* lswi */
                   2967: /* PowerPC32 specification says we must generate an exception if
                   2968:  * rA is in the range of registers to be loaded.
                   2969:  * In an other hand, IBM says this is valid, but rA won't be loaded.
                   2970:  * For now, I'll follow the spec...
                   2971:  */
1.1.1.7   root     2972: static void gen_lswi(DisasContext *ctx)
1.1       root     2973: {
1.1.1.6   root     2974:     TCGv t0;
                   2975:     TCGv_i32 t1, t2;
1.1       root     2976:     int nb = NB(ctx->opcode);
                   2977:     int start = rD(ctx->opcode);
                   2978:     int ra = rA(ctx->opcode);
                   2979:     int nr;
                   2980: 
                   2981:     if (nb == 0)
                   2982:         nb = 32;
                   2983:     nr = nb / 4;
1.1.1.5   root     2984:     if (unlikely(((start + nr) > 32  &&
                   2985:                   start <= ra && (start + nr - 32) > ra) ||
                   2986:                  ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
1.1.1.6   root     2987:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
1.1       root     2988:         return;
                   2989:     }
1.1.1.6   root     2990:     gen_set_access_type(ctx, ACCESS_INT);
1.1       root     2991:     /* NIP cannot be restored if the memory exception comes from an helper */
1.1.1.5   root     2992:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6   root     2993:     t0 = tcg_temp_new();
                   2994:     gen_addr_register(ctx, t0);
                   2995:     t1 = tcg_const_i32(nb);
                   2996:     t2 = tcg_const_i32(start);
                   2997:     gen_helper_lsw(t0, t1, t2);
                   2998:     tcg_temp_free(t0);
                   2999:     tcg_temp_free_i32(t1);
                   3000:     tcg_temp_free_i32(t2);
1.1       root     3001: }
                   3002: 
                   3003: /* lswx */
1.1.1.7   root     3004: static void gen_lswx(DisasContext *ctx)
1.1       root     3005: {
1.1.1.6   root     3006:     TCGv t0;
                   3007:     TCGv_i32 t1, t2, t3;
                   3008:     gen_set_access_type(ctx, ACCESS_INT);
1.1.1.5   root     3009:     /* NIP cannot be restored if the memory exception comes from an helper */
                   3010:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6   root     3011:     t0 = tcg_temp_new();
                   3012:     gen_addr_reg_index(ctx, t0);
                   3013:     t1 = tcg_const_i32(rD(ctx->opcode));
                   3014:     t2 = tcg_const_i32(rA(ctx->opcode));
                   3015:     t3 = tcg_const_i32(rB(ctx->opcode));
                   3016:     gen_helper_lswx(t0, t1, t2, t3);
                   3017:     tcg_temp_free(t0);
                   3018:     tcg_temp_free_i32(t1);
                   3019:     tcg_temp_free_i32(t2);
                   3020:     tcg_temp_free_i32(t3);
1.1       root     3021: }
                   3022: 
                   3023: /* stswi */
1.1.1.7   root     3024: static void gen_stswi(DisasContext *ctx)
1.1       root     3025: {
1.1.1.6   root     3026:     TCGv t0;
                   3027:     TCGv_i32 t1, t2;
1.1       root     3028:     int nb = NB(ctx->opcode);
1.1.1.6   root     3029:     gen_set_access_type(ctx, ACCESS_INT);
1.1.1.5   root     3030:     /* NIP cannot be restored if the memory exception comes from an helper */
                   3031:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6   root     3032:     t0 = tcg_temp_new();
                   3033:     gen_addr_register(ctx, t0);
1.1       root     3034:     if (nb == 0)
                   3035:         nb = 32;
1.1.1.6   root     3036:     t1 = tcg_const_i32(nb);
                   3037:     t2 = tcg_const_i32(rS(ctx->opcode));
                   3038:     gen_helper_stsw(t0, t1, t2);
                   3039:     tcg_temp_free(t0);
                   3040:     tcg_temp_free_i32(t1);
                   3041:     tcg_temp_free_i32(t2);
1.1       root     3042: }
                   3043: 
                   3044: /* stswx */
1.1.1.7   root     3045: static void gen_stswx(DisasContext *ctx)
1.1       root     3046: {
1.1.1.6   root     3047:     TCGv t0;
                   3048:     TCGv_i32 t1, t2;
                   3049:     gen_set_access_type(ctx, ACCESS_INT);
1.1       root     3050:     /* NIP cannot be restored if the memory exception comes from an helper */
1.1.1.5   root     3051:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6   root     3052:     t0 = tcg_temp_new();
                   3053:     gen_addr_reg_index(ctx, t0);
                   3054:     t1 = tcg_temp_new_i32();
                   3055:     tcg_gen_trunc_tl_i32(t1, cpu_xer);
                   3056:     tcg_gen_andi_i32(t1, t1, 0x7F);
                   3057:     t2 = tcg_const_i32(rS(ctx->opcode));
                   3058:     gen_helper_stsw(t0, t1, t2);
                   3059:     tcg_temp_free(t0);
                   3060:     tcg_temp_free_i32(t1);
                   3061:     tcg_temp_free_i32(t2);
1.1       root     3062: }
                   3063: 
                   3064: /***                        Memory synchronisation                         ***/
                   3065: /* eieio */
1.1.1.7   root     3066: static void gen_eieio(DisasContext *ctx)
1.1       root     3067: {
                   3068: }
                   3069: 
                   3070: /* isync */
1.1.1.7   root     3071: static void gen_isync(DisasContext *ctx)
1.1       root     3072: {
1.1.1.6   root     3073:     gen_stop_exception(ctx);
1.1       root     3074: }
                   3075: 
                   3076: /* lwarx */
1.1.1.7   root     3077: static void gen_lwarx(DisasContext *ctx)
1.1       root     3078: {
1.1.1.6   root     3079:     TCGv t0;
1.1.1.8   root     3080:     TCGv gpr = cpu_gpr[rD(ctx->opcode)];
1.1.1.6   root     3081:     gen_set_access_type(ctx, ACCESS_RES);
                   3082:     t0 = tcg_temp_local_new();
                   3083:     gen_addr_reg_index(ctx, t0);
                   3084:     gen_check_align(ctx, t0, 0x03);
1.1.1.8   root     3085:     gen_qemu_ld32u(ctx, gpr, t0);
1.1.1.6   root     3086:     tcg_gen_mov_tl(cpu_reserve, t0);
1.1.1.8   root     3087:     tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUState, reserve_val));
1.1.1.6   root     3088:     tcg_temp_free(t0);
1.1       root     3089: }
                   3090: 
1.1.1.8   root     3091: #if defined(CONFIG_USER_ONLY)
                   3092: static void gen_conditional_store (DisasContext *ctx, TCGv EA,
                   3093:                                    int reg, int size)
                   3094: {
                   3095:     TCGv t0 = tcg_temp_new();
                   3096:     uint32_t save_exception = ctx->exception;
                   3097: 
                   3098:     tcg_gen_st_tl(EA, cpu_env, offsetof(CPUState, reserve_ea));
                   3099:     tcg_gen_movi_tl(t0, (size << 5) | reg);
                   3100:     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, reserve_info));
                   3101:     tcg_temp_free(t0);
                   3102:     gen_update_nip(ctx, ctx->nip-4);
                   3103:     ctx->exception = POWERPC_EXCP_BRANCH;
                   3104:     gen_exception(ctx, POWERPC_EXCP_STCX);
                   3105:     ctx->exception = save_exception;
                   3106: }
                   3107: #endif
                   3108: 
1.1       root     3109: /* stwcx. */
1.1.1.7   root     3110: static void gen_stwcx_(DisasContext *ctx)
1.1       root     3111: {
1.1.1.6   root     3112:     TCGv t0;
                   3113:     gen_set_access_type(ctx, ACCESS_RES);
                   3114:     t0 = tcg_temp_local_new();
                   3115:     gen_addr_reg_index(ctx, t0);
                   3116:     gen_check_align(ctx, t0, 0x03);
1.1.1.8   root     3117: #if defined(CONFIG_USER_ONLY)
                   3118:     gen_conditional_store(ctx, t0, rS(ctx->opcode), 4);
                   3119: #else
                   3120:     {
                   3121:         int l1;
                   3122: 
                   3123:         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
                   3124:         tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
                   3125:         tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
                   3126:         l1 = gen_new_label();
                   3127:         tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
                   3128:         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
                   3129:         gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], t0);
                   3130:         gen_set_label(l1);
                   3131:         tcg_gen_movi_tl(cpu_reserve, -1);
                   3132:     }
                   3133: #endif
1.1.1.6   root     3134:     tcg_temp_free(t0);
1.1       root     3135: }
                   3136: 
1.1.1.5   root     3137: #if defined(TARGET_PPC64)
                   3138: /* ldarx */
1.1.1.7   root     3139: static void gen_ldarx(DisasContext *ctx)
1.1.1.5   root     3140: {
1.1.1.6   root     3141:     TCGv t0;
1.1.1.8   root     3142:     TCGv gpr = cpu_gpr[rD(ctx->opcode)];
1.1.1.6   root     3143:     gen_set_access_type(ctx, ACCESS_RES);
                   3144:     t0 = tcg_temp_local_new();
                   3145:     gen_addr_reg_index(ctx, t0);
                   3146:     gen_check_align(ctx, t0, 0x07);
1.1.1.8   root     3147:     gen_qemu_ld64(ctx, gpr, t0);
1.1.1.6   root     3148:     tcg_gen_mov_tl(cpu_reserve, t0);
1.1.1.8   root     3149:     tcg_gen_st_tl(gpr, cpu_env, offsetof(CPUState, reserve_val));
1.1.1.6   root     3150:     tcg_temp_free(t0);
1.1.1.5   root     3151: }
                   3152: 
                   3153: /* stdcx. */
1.1.1.7   root     3154: static void gen_stdcx_(DisasContext *ctx)
1.1.1.5   root     3155: {
1.1.1.6   root     3156:     TCGv t0;
                   3157:     gen_set_access_type(ctx, ACCESS_RES);
                   3158:     t0 = tcg_temp_local_new();
                   3159:     gen_addr_reg_index(ctx, t0);
                   3160:     gen_check_align(ctx, t0, 0x07);
1.1.1.8   root     3161: #if defined(CONFIG_USER_ONLY)
                   3162:     gen_conditional_store(ctx, t0, rS(ctx->opcode), 8);
                   3163: #else
                   3164:     {
                   3165:         int l1;
                   3166:         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
                   3167:         tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
                   3168:         tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
                   3169:         l1 = gen_new_label();
                   3170:         tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
                   3171:         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
                   3172:         gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], t0);
                   3173:         gen_set_label(l1);
                   3174:         tcg_gen_movi_tl(cpu_reserve, -1);
                   3175:     }
                   3176: #endif
1.1.1.6   root     3177:     tcg_temp_free(t0);
1.1.1.5   root     3178: }
                   3179: #endif /* defined(TARGET_PPC64) */
                   3180: 
1.1       root     3181: /* sync */
1.1.1.7   root     3182: static void gen_sync(DisasContext *ctx)
1.1       root     3183: {
                   3184: }
                   3185: 
1.1.1.5   root     3186: /* wait */
1.1.1.7   root     3187: static void gen_wait(DisasContext *ctx)
1.1.1.5   root     3188: {
1.1.1.6   root     3189:     TCGv_i32 t0 = tcg_temp_new_i32();
                   3190:     tcg_gen_st_i32(t0, cpu_env, offsetof(CPUState, halted));
                   3191:     tcg_temp_free_i32(t0);
1.1.1.5   root     3192:     /* Stop translation, as the CPU is supposed to sleep from now */
1.1.1.6   root     3193:     gen_exception_err(ctx, EXCP_HLT, 1);
1.1.1.5   root     3194: }
                   3195: 
1.1       root     3196: /***                         Floating-point load                           ***/
1.1.1.6   root     3197: #define GEN_LDF(name, ldop, opc, type)                                        \
1.1.1.7   root     3198: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1       root     3199: {                                                                             \
1.1.1.6   root     3200:     TCGv EA;                                                                  \
1.1.1.5   root     3201:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     3202:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3203:         return;                                                               \
                   3204:     }                                                                         \
1.1.1.6   root     3205:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
                   3206:     EA = tcg_temp_new();                                                      \
                   3207:     gen_addr_imm_index(ctx, EA, 0);                                           \
                   3208:     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
                   3209:     tcg_temp_free(EA);                                                        \
1.1       root     3210: }
                   3211: 
1.1.1.6   root     3212: #define GEN_LDUF(name, ldop, opc, type)                                       \
1.1.1.7   root     3213: static void glue(gen_, name##u)(DisasContext *ctx)                                    \
1.1       root     3214: {                                                                             \
1.1.1.6   root     3215:     TCGv EA;                                                                  \
1.1.1.5   root     3216:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     3217:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3218:         return;                                                               \
                   3219:     }                                                                         \
1.1.1.5   root     3220:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6   root     3221:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     3222:         return;                                                               \
                   3223:     }                                                                         \
1.1.1.6   root     3224:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
                   3225:     EA = tcg_temp_new();                                                      \
                   3226:     gen_addr_imm_index(ctx, EA, 0);                                           \
                   3227:     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
                   3228:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
                   3229:     tcg_temp_free(EA);                                                        \
1.1       root     3230: }
                   3231: 
1.1.1.6   root     3232: #define GEN_LDUXF(name, ldop, opc, type)                                      \
1.1.1.7   root     3233: static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
1.1       root     3234: {                                                                             \
1.1.1.6   root     3235:     TCGv EA;                                                                  \
1.1.1.5   root     3236:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     3237:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3238:         return;                                                               \
                   3239:     }                                                                         \
1.1.1.5   root     3240:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6   root     3241:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     3242:         return;                                                               \
                   3243:     }                                                                         \
1.1.1.6   root     3244:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
                   3245:     EA = tcg_temp_new();                                                      \
                   3246:     gen_addr_reg_index(ctx, EA);                                              \
                   3247:     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
                   3248:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
                   3249:     tcg_temp_free(EA);                                                        \
1.1       root     3250: }
                   3251: 
1.1.1.6   root     3252: #define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
1.1.1.7   root     3253: static void glue(gen_, name##x)(DisasContext *ctx)                                    \
1.1       root     3254: {                                                                             \
1.1.1.6   root     3255:     TCGv EA;                                                                  \
1.1.1.5   root     3256:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     3257:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3258:         return;                                                               \
                   3259:     }                                                                         \
1.1.1.6   root     3260:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
                   3261:     EA = tcg_temp_new();                                                      \
                   3262:     gen_addr_reg_index(ctx, EA);                                              \
                   3263:     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
                   3264:     tcg_temp_free(EA);                                                        \
                   3265: }
                   3266: 
                   3267: #define GEN_LDFS(name, ldop, op, type)                                        \
                   3268: GEN_LDF(name, ldop, op | 0x20, type);                                         \
                   3269: GEN_LDUF(name, ldop, op | 0x21, type);                                        \
                   3270: GEN_LDUXF(name, ldop, op | 0x01, type);                                       \
                   3271: GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
                   3272: 
1.1.1.8   root     3273: static inline void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
1.1.1.6   root     3274: {
                   3275:     TCGv t0 = tcg_temp_new();
                   3276:     TCGv_i32 t1 = tcg_temp_new_i32();
                   3277:     gen_qemu_ld32u(ctx, t0, arg2);
                   3278:     tcg_gen_trunc_tl_i32(t1, t0);
                   3279:     tcg_temp_free(t0);
                   3280:     gen_helper_float32_to_float64(arg1, t1);
                   3281:     tcg_temp_free_i32(t1);
                   3282: }
                   3283: 
                   3284:  /* lfd lfdu lfdux lfdx */
                   3285: GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT);
                   3286:  /* lfs lfsu lfsux lfsx */
                   3287: GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT);
1.1       root     3288: 
                   3289: /***                         Floating-point store                          ***/
1.1.1.6   root     3290: #define GEN_STF(name, stop, opc, type)                                        \
1.1.1.7   root     3291: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1       root     3292: {                                                                             \
1.1.1.6   root     3293:     TCGv EA;                                                                  \
1.1.1.5   root     3294:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     3295:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1.1.5   root     3296:         return;                                                               \
1.1       root     3297:     }                                                                         \
1.1.1.6   root     3298:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
                   3299:     EA = tcg_temp_new();                                                      \
                   3300:     gen_addr_imm_index(ctx, EA, 0);                                           \
                   3301:     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
                   3302:     tcg_temp_free(EA);                                                        \
1.1       root     3303: }
                   3304: 
1.1.1.6   root     3305: #define GEN_STUF(name, stop, opc, type)                                       \
1.1.1.7   root     3306: static void glue(gen_, name##u)(DisasContext *ctx)                                    \
1.1       root     3307: {                                                                             \
1.1.1.6   root     3308:     TCGv EA;                                                                  \
1.1.1.5   root     3309:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     3310:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3311:         return;                                                               \
                   3312:     }                                                                         \
1.1.1.5   root     3313:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6   root     3314:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     3315:         return;                                                               \
                   3316:     }                                                                         \
1.1.1.6   root     3317:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
                   3318:     EA = tcg_temp_new();                                                      \
                   3319:     gen_addr_imm_index(ctx, EA, 0);                                           \
                   3320:     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
                   3321:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
                   3322:     tcg_temp_free(EA);                                                        \
1.1       root     3323: }
                   3324: 
1.1.1.6   root     3325: #define GEN_STUXF(name, stop, opc, type)                                      \
1.1.1.7   root     3326: static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
1.1       root     3327: {                                                                             \
1.1.1.6   root     3328:     TCGv EA;                                                                  \
1.1.1.5   root     3329:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     3330:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3331:         return;                                                               \
                   3332:     }                                                                         \
1.1.1.5   root     3333:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6   root     3334:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     3335:         return;                                                               \
                   3336:     }                                                                         \
1.1.1.6   root     3337:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
                   3338:     EA = tcg_temp_new();                                                      \
                   3339:     gen_addr_reg_index(ctx, EA);                                              \
                   3340:     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
                   3341:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
                   3342:     tcg_temp_free(EA);                                                        \
1.1       root     3343: }
                   3344: 
1.1.1.6   root     3345: #define GEN_STXF(name, stop, opc2, opc3, type)                                \
1.1.1.7   root     3346: static void glue(gen_, name##x)(DisasContext *ctx)                                    \
1.1       root     3347: {                                                                             \
1.1.1.6   root     3348:     TCGv EA;                                                                  \
1.1.1.5   root     3349:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6   root     3350:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3351:         return;                                                               \
                   3352:     }                                                                         \
1.1.1.6   root     3353:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
                   3354:     EA = tcg_temp_new();                                                      \
                   3355:     gen_addr_reg_index(ctx, EA);                                              \
                   3356:     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
                   3357:     tcg_temp_free(EA);                                                        \
                   3358: }
                   3359: 
                   3360: #define GEN_STFS(name, stop, op, type)                                        \
                   3361: GEN_STF(name, stop, op | 0x20, type);                                         \
                   3362: GEN_STUF(name, stop, op | 0x21, type);                                        \
                   3363: GEN_STUXF(name, stop, op | 0x01, type);                                       \
                   3364: GEN_STXF(name, stop, 0x17, op | 0x00, type)
                   3365: 
1.1.1.8   root     3366: static inline void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
1.1.1.6   root     3367: {
                   3368:     TCGv_i32 t0 = tcg_temp_new_i32();
                   3369:     TCGv t1 = tcg_temp_new();
                   3370:     gen_helper_float64_to_float32(t0, arg1);
                   3371:     tcg_gen_extu_i32_tl(t1, t0);
                   3372:     tcg_temp_free_i32(t0);
                   3373:     gen_qemu_st32(ctx, t1, arg2);
                   3374:     tcg_temp_free(t1);
1.1       root     3375: }
                   3376: 
                   3377: /* stfd stfdu stfdux stfdx */
1.1.1.6   root     3378: GEN_STFS(stfd, st64, 0x16, PPC_FLOAT);
1.1       root     3379: /* stfs stfsu stfsux stfsx */
1.1.1.6   root     3380: GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT);
1.1       root     3381: 
                   3382: /* Optional: */
1.1.1.8   root     3383: static inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
1.1.1.6   root     3384: {
                   3385:     TCGv t0 = tcg_temp_new();
                   3386:     tcg_gen_trunc_i64_tl(t0, arg1),
                   3387:     gen_qemu_st32(ctx, t0, arg2);
                   3388:     tcg_temp_free(t0);
                   3389: }
1.1       root     3390: /* stfiwx */
1.1.1.6   root     3391: GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
1.1       root     3392: 
1.1.1.12! root     3393: static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip)
        !          3394: {
        !          3395: #if defined(TARGET_PPC64)
        !          3396:     if (ctx->has_cfar)
        !          3397:         tcg_gen_movi_tl(cpu_cfar, nip);
        !          3398: #endif
        !          3399: }
        !          3400: 
1.1       root     3401: /***                                Branch                                 ***/
1.1.1.8   root     3402: static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1.1.1.2   root     3403: {
                   3404:     TranslationBlock *tb;
                   3405:     tb = ctx->tb;
1.1.1.5   root     3406: #if defined(TARGET_PPC64)
1.1.1.6   root     3407:     if (!ctx->sf_mode)
                   3408:         dest = (uint32_t) dest;
1.1.1.5   root     3409: #endif
1.1.1.6   root     3410:     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
                   3411:         likely(!ctx->singlestep_enabled)) {
                   3412:         tcg_gen_goto_tb(n);
                   3413:         tcg_gen_movi_tl(cpu_nip, dest & ~3);
1.1.1.11  root     3414:         tcg_gen_exit_tb((tcg_target_long)tb + n);
1.1.1.2   root     3415:     } else {
1.1.1.6   root     3416:         tcg_gen_movi_tl(cpu_nip, dest & ~3);
                   3417:         if (unlikely(ctx->singlestep_enabled)) {
                   3418:             if ((ctx->singlestep_enabled &
                   3419:                 (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
                   3420:                 ctx->exception == POWERPC_EXCP_BRANCH) {
                   3421:                 target_ulong tmp = ctx->nip;
                   3422:                 ctx->nip = dest;
                   3423:                 gen_exception(ctx, POWERPC_EXCP_TRACE);
                   3424:                 ctx->nip = tmp;
                   3425:             }
                   3426:             if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
                   3427:                 gen_debug_exception(ctx);
                   3428:             }
                   3429:         }
                   3430:         tcg_gen_exit_tb(0);
1.1.1.2   root     3431:     }
                   3432: }
                   3433: 
1.1.1.8   root     3434: static inline void gen_setlr(DisasContext *ctx, target_ulong nip)
1.1.1.5   root     3435: {
                   3436: #if defined(TARGET_PPC64)
1.1.1.6   root     3437:     if (ctx->sf_mode == 0)
                   3438:         tcg_gen_movi_tl(cpu_lr, (uint32_t)nip);
1.1.1.5   root     3439:     else
                   3440: #endif
1.1.1.6   root     3441:         tcg_gen_movi_tl(cpu_lr, nip);
1.1.1.5   root     3442: }
                   3443: 
1.1       root     3444: /* b ba bl bla */
1.1.1.7   root     3445: static void gen_b(DisasContext *ctx)
1.1       root     3446: {
1.1.1.5   root     3447:     target_ulong li, target;
1.1       root     3448: 
1.1.1.6   root     3449:     ctx->exception = POWERPC_EXCP_BRANCH;
1.1       root     3450:     /* sign extend LI */
1.1.1.5   root     3451: #if defined(TARGET_PPC64)
                   3452:     if (ctx->sf_mode)
                   3453:         li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
                   3454:     else
                   3455: #endif
                   3456:         li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
                   3457:     if (likely(AA(ctx->opcode) == 0))
1.1       root     3458:         target = ctx->nip + li - 4;
                   3459:     else
                   3460:         target = li;
1.1.1.5   root     3461:     if (LK(ctx->opcode))
                   3462:         gen_setlr(ctx, ctx->nip);
1.1.1.12! root     3463:     gen_update_cfar(ctx, ctx->nip);
1.1.1.2   root     3464:     gen_goto_tb(ctx, 0, target);
1.1       root     3465: }
                   3466: 
                   3467: #define BCOND_IM  0
                   3468: #define BCOND_LR  1
                   3469: #define BCOND_CTR 2
                   3470: 
1.1.1.8   root     3471: static inline void gen_bcond(DisasContext *ctx, int type)
1.1.1.5   root     3472: {
                   3473:     uint32_t bo = BO(ctx->opcode);
1.1.1.9   root     3474:     int l1;
1.1.1.6   root     3475:     TCGv target;
1.1       root     3476: 
1.1.1.6   root     3477:     ctx->exception = POWERPC_EXCP_BRANCH;
                   3478:     if (type == BCOND_LR || type == BCOND_CTR) {
                   3479:         target = tcg_temp_local_new();
                   3480:         if (type == BCOND_CTR)
                   3481:             tcg_gen_mov_tl(target, cpu_ctr);
                   3482:         else
                   3483:             tcg_gen_mov_tl(target, cpu_lr);
1.1.1.7   root     3484:     } else {
                   3485:         TCGV_UNUSED(target);
1.1       root     3486:     }
1.1.1.5   root     3487:     if (LK(ctx->opcode))
                   3488:         gen_setlr(ctx, ctx->nip);
1.1.1.6   root     3489:     l1 = gen_new_label();
                   3490:     if ((bo & 0x4) == 0) {
                   3491:         /* Decrement and test CTR */
                   3492:         TCGv temp = tcg_temp_new();
                   3493:         if (unlikely(type == BCOND_CTR)) {
                   3494:             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
                   3495:             return;
                   3496:         }
                   3497:         tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
1.1.1.5   root     3498: #if defined(TARGET_PPC64)
1.1.1.6   root     3499:         if (!ctx->sf_mode)
                   3500:             tcg_gen_ext32u_tl(temp, cpu_ctr);
                   3501:         else
1.1.1.5   root     3502: #endif
1.1.1.6   root     3503:             tcg_gen_mov_tl(temp, cpu_ctr);
                   3504:         if (bo & 0x2) {
                   3505:             tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
                   3506:         } else {
                   3507:             tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
1.1       root     3508:         }
1.1.1.6   root     3509:         tcg_temp_free(temp);
                   3510:     }
                   3511:     if ((bo & 0x10) == 0) {
                   3512:         /* Test CR */
                   3513:         uint32_t bi = BI(ctx->opcode);
                   3514:         uint32_t mask = 1 << (3 - (bi & 0x03));
                   3515:         TCGv_i32 temp = tcg_temp_new_i32();
                   3516: 
1.1.1.5   root     3517:         if (bo & 0x8) {
1.1.1.6   root     3518:             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
                   3519:             tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1);
1.1.1.5   root     3520:         } else {
1.1.1.6   root     3521:             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
                   3522:             tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);
1.1.1.5   root     3523:         }
1.1.1.6   root     3524:         tcg_temp_free_i32(temp);
1.1.1.5   root     3525:     }
1.1.1.12! root     3526:     gen_update_cfar(ctx, ctx->nip);
1.1       root     3527:     if (type == BCOND_IM) {
1.1.1.6   root     3528:         target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
                   3529:         if (likely(AA(ctx->opcode) == 0)) {
                   3530:             gen_goto_tb(ctx, 0, ctx->nip + li - 4);
                   3531:         } else {
                   3532:             gen_goto_tb(ctx, 0, li);
                   3533:         }
1.1.1.2   root     3534:         gen_set_label(l1);
                   3535:         gen_goto_tb(ctx, 1, ctx->nip);
1.1       root     3536:     } else {
1.1.1.5   root     3537: #if defined(TARGET_PPC64)
1.1.1.6   root     3538:         if (!(ctx->sf_mode))
                   3539:             tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3);
                   3540:         else
                   3541: #endif
                   3542:             tcg_gen_andi_tl(cpu_nip, target, ~3);
                   3543:         tcg_gen_exit_tb(0);
                   3544:         gen_set_label(l1);
                   3545: #if defined(TARGET_PPC64)
                   3546:         if (!(ctx->sf_mode))
                   3547:             tcg_gen_movi_tl(cpu_nip, (uint32_t)ctx->nip);
1.1.1.5   root     3548:         else
                   3549: #endif
1.1.1.6   root     3550:             tcg_gen_movi_tl(cpu_nip, ctx->nip);
                   3551:         tcg_gen_exit_tb(0);
1.1       root     3552:     }
                   3553: }
                   3554: 
1.1.1.7   root     3555: static void gen_bc(DisasContext *ctx)
1.1.1.5   root     3556: {
1.1       root     3557:     gen_bcond(ctx, BCOND_IM);
                   3558: }
                   3559: 
1.1.1.7   root     3560: static void gen_bcctr(DisasContext *ctx)
1.1.1.5   root     3561: {
1.1       root     3562:     gen_bcond(ctx, BCOND_CTR);
                   3563: }
                   3564: 
1.1.1.7   root     3565: static void gen_bclr(DisasContext *ctx)
1.1.1.5   root     3566: {
1.1       root     3567:     gen_bcond(ctx, BCOND_LR);
                   3568: }
                   3569: 
                   3570: /***                      Condition register logical                       ***/
1.1.1.6   root     3571: #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
1.1.1.7   root     3572: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1       root     3573: {                                                                             \
1.1.1.5   root     3574:     uint8_t bitmask;                                                          \
                   3575:     int sh;                                                                   \
1.1.1.6   root     3576:     TCGv_i32 t0, t1;                                                          \
1.1.1.5   root     3577:     sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
1.1.1.6   root     3578:     t0 = tcg_temp_new_i32();                                                  \
1.1.1.5   root     3579:     if (sh > 0)                                                               \
1.1.1.6   root     3580:         tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh);            \
1.1.1.5   root     3581:     else if (sh < 0)                                                          \
1.1.1.6   root     3582:         tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh);           \
                   3583:     else                                                                      \
                   3584:         tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]);                 \
                   3585:     t1 = tcg_temp_new_i32();                                                  \
1.1.1.5   root     3586:     sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
                   3587:     if (sh > 0)                                                               \
1.1.1.6   root     3588:         tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh);            \
1.1.1.5   root     3589:     else if (sh < 0)                                                          \
1.1.1.6   root     3590:         tcg_gen_shli_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], -sh);           \
                   3591:     else                                                                      \
                   3592:         tcg_gen_mov_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2]);                 \
                   3593:     tcg_op(t0, t0, t1);                                                       \
1.1.1.5   root     3594:     bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03));                          \
1.1.1.6   root     3595:     tcg_gen_andi_i32(t0, t0, bitmask);                                        \
                   3596:     tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask);          \
                   3597:     tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1);                  \
                   3598:     tcg_temp_free_i32(t0);                                                    \
                   3599:     tcg_temp_free_i32(t1);                                                    \
1.1       root     3600: }
                   3601: 
                   3602: /* crand */
1.1.1.6   root     3603: GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08);
1.1       root     3604: /* crandc */
1.1.1.6   root     3605: GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04);
1.1       root     3606: /* creqv */
1.1.1.6   root     3607: GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09);
1.1       root     3608: /* crnand */
1.1.1.6   root     3609: GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07);
1.1       root     3610: /* crnor */
1.1.1.6   root     3611: GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01);
1.1       root     3612: /* cror */
1.1.1.6   root     3613: GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E);
1.1       root     3614: /* crorc */
1.1.1.6   root     3615: GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D);
1.1       root     3616: /* crxor */
1.1.1.6   root     3617: GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06);
1.1.1.7   root     3618: 
1.1       root     3619: /* mcrf */
1.1.1.7   root     3620: static void gen_mcrf(DisasContext *ctx)
1.1       root     3621: {
1.1.1.6   root     3622:     tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]);
1.1       root     3623: }
                   3624: 
                   3625: /***                           System linkage                              ***/
1.1.1.7   root     3626: 
1.1.1.6   root     3627: /* rfi (mem_idx only) */
1.1.1.7   root     3628: static void gen_rfi(DisasContext *ctx)
1.1       root     3629: {
                   3630: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     3631:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     3632: #else
                   3633:     /* Restore CPU state */
1.1.1.6   root     3634:     if (unlikely(!ctx->mem_idx)) {
                   3635:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     3636:         return;
                   3637:     }
1.1.1.12! root     3638:     gen_update_cfar(ctx, ctx->nip);
1.1.1.6   root     3639:     gen_helper_rfi();
                   3640:     gen_sync_exception(ctx);
1.1       root     3641: #endif
                   3642: }
                   3643: 
1.1.1.5   root     3644: #if defined(TARGET_PPC64)
1.1.1.7   root     3645: static void gen_rfid(DisasContext *ctx)
1.1.1.5   root     3646: {
                   3647: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     3648:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     3649: #else
                   3650:     /* Restore CPU state */
1.1.1.6   root     3651:     if (unlikely(!ctx->mem_idx)) {
                   3652:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     3653:         return;
                   3654:     }
1.1.1.12! root     3655:     gen_update_cfar(ctx, ctx->nip);
1.1.1.6   root     3656:     gen_helper_rfid();
                   3657:     gen_sync_exception(ctx);
1.1.1.5   root     3658: #endif
                   3659: }
                   3660: 
1.1.1.7   root     3661: static void gen_hrfid(DisasContext *ctx)
1.1       root     3662: {
                   3663: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     3664:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     3665: #else
                   3666:     /* Restore CPU state */
1.1.1.6   root     3667:     if (unlikely(ctx->mem_idx <= 1)) {
                   3668:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     3669:         return;
                   3670:     }
1.1.1.6   root     3671:     gen_helper_hrfid();
                   3672:     gen_sync_exception(ctx);
1.1.1.5   root     3673: #endif
                   3674: }
                   3675: #endif
                   3676: 
                   3677: /* sc */
                   3678: #if defined(CONFIG_USER_ONLY)
                   3679: #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
1.1       root     3680: #else
1.1.1.5   root     3681: #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
1.1       root     3682: #endif
1.1.1.7   root     3683: static void gen_sc(DisasContext *ctx)
1.1.1.5   root     3684: {
                   3685:     uint32_t lev;
                   3686: 
                   3687:     lev = (ctx->opcode >> 5) & 0x7F;
1.1.1.6   root     3688:     gen_exception_err(ctx, POWERPC_SYSCALL, lev);
1.1       root     3689: }
                   3690: 
                   3691: /***                                Trap                                   ***/
1.1.1.7   root     3692: 
1.1       root     3693: /* tw */
1.1.1.7   root     3694: static void gen_tw(DisasContext *ctx)
1.1       root     3695: {
1.1.1.6   root     3696:     TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
1.1.1.4   root     3697:     /* Update the nip since this might generate a trap exception */
1.1.1.5   root     3698:     gen_update_nip(ctx, ctx->nip);
1.1.1.6   root     3699:     gen_helper_tw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
                   3700:     tcg_temp_free_i32(t0);
1.1       root     3701: }
                   3702: 
                   3703: /* twi */
1.1.1.7   root     3704: static void gen_twi(DisasContext *ctx)
1.1       root     3705: {
1.1.1.6   root     3706:     TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
                   3707:     TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
1.1.1.5   root     3708:     /* Update the nip since this might generate a trap exception */
                   3709:     gen_update_nip(ctx, ctx->nip);
1.1.1.6   root     3710:     gen_helper_tw(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   3711:     tcg_temp_free(t0);
                   3712:     tcg_temp_free_i32(t1);
1.1       root     3713: }
                   3714: 
1.1.1.5   root     3715: #if defined(TARGET_PPC64)
                   3716: /* td */
1.1.1.7   root     3717: static void gen_td(DisasContext *ctx)
1.1       root     3718: {
1.1.1.6   root     3719:     TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
1.1.1.5   root     3720:     /* Update the nip since this might generate a trap exception */
                   3721:     gen_update_nip(ctx, ctx->nip);
1.1.1.6   root     3722:     gen_helper_td(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
                   3723:     tcg_temp_free_i32(t0);
1.1.1.5   root     3724: }
1.1       root     3725: 
1.1.1.5   root     3726: /* tdi */
1.1.1.7   root     3727: static void gen_tdi(DisasContext *ctx)
1.1.1.5   root     3728: {
1.1.1.6   root     3729:     TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
                   3730:     TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
1.1.1.5   root     3731:     /* Update the nip since this might generate a trap exception */
                   3732:     gen_update_nip(ctx, ctx->nip);
1.1.1.6   root     3733:     gen_helper_td(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   3734:     tcg_temp_free(t0);
                   3735:     tcg_temp_free_i32(t1);
1.1       root     3736: }
1.1.1.5   root     3737: #endif
1.1       root     3738: 
1.1.1.5   root     3739: /***                          Processor control                            ***/
1.1.1.7   root     3740: 
1.1       root     3741: /* mcrxr */
1.1.1.7   root     3742: static void gen_mcrxr(DisasContext *ctx)
1.1       root     3743: {
1.1.1.6   root     3744:     tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], cpu_xer);
                   3745:     tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], XER_CA);
                   3746:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_SO | 1 << XER_OV | 1 << XER_CA));
1.1       root     3747: }
                   3748: 
1.1.1.6   root     3749: /* mfcr mfocrf */
1.1.1.7   root     3750: static void gen_mfcr(DisasContext *ctx)
1.1       root     3751: {
1.1.1.5   root     3752:     uint32_t crm, crn;
                   3753: 
                   3754:     if (likely(ctx->opcode & 0x00100000)) {
                   3755:         crm = CRM(ctx->opcode);
1.1.1.6   root     3756:         if (likely(crm && ((crm & (crm - 1)) == 0))) {
                   3757:             crn = ctz32 (crm);
                   3758:             tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
1.1.1.7   root     3759:             tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)],
                   3760:                             cpu_gpr[rD(ctx->opcode)], crn * 4);
1.1.1.5   root     3761:         }
                   3762:     } else {
1.1.1.7   root     3763:         TCGv_i32 t0 = tcg_temp_new_i32();
                   3764:         tcg_gen_mov_i32(t0, cpu_crf[0]);
                   3765:         tcg_gen_shli_i32(t0, t0, 4);
                   3766:         tcg_gen_or_i32(t0, t0, cpu_crf[1]);
                   3767:         tcg_gen_shli_i32(t0, t0, 4);
                   3768:         tcg_gen_or_i32(t0, t0, cpu_crf[2]);
                   3769:         tcg_gen_shli_i32(t0, t0, 4);
                   3770:         tcg_gen_or_i32(t0, t0, cpu_crf[3]);
                   3771:         tcg_gen_shli_i32(t0, t0, 4);
                   3772:         tcg_gen_or_i32(t0, t0, cpu_crf[4]);
                   3773:         tcg_gen_shli_i32(t0, t0, 4);
                   3774:         tcg_gen_or_i32(t0, t0, cpu_crf[5]);
                   3775:         tcg_gen_shli_i32(t0, t0, 4);
                   3776:         tcg_gen_or_i32(t0, t0, cpu_crf[6]);
                   3777:         tcg_gen_shli_i32(t0, t0, 4);
                   3778:         tcg_gen_or_i32(t0, t0, cpu_crf[7]);
                   3779:         tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   3780:         tcg_temp_free_i32(t0);
1.1.1.5   root     3781:     }
1.1       root     3782: }
                   3783: 
                   3784: /* mfmsr */
1.1.1.7   root     3785: static void gen_mfmsr(DisasContext *ctx)
1.1       root     3786: {
                   3787: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     3788:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     3789: #else
1.1.1.6   root     3790:     if (unlikely(!ctx->mem_idx)) {
                   3791:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     3792:         return;
                   3793:     }
1.1.1.6   root     3794:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
1.1       root     3795: #endif
                   3796: }
                   3797: 
1.1.1.9   root     3798: static void spr_noaccess(void *opaque, int gprn, int sprn)
1.1       root     3799: {
1.1.1.9   root     3800: #if 0
1.1       root     3801:     sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
                   3802:     printf("ERROR: try to access SPR %d !\n", sprn);
1.1.1.9   root     3803: #endif
1.1       root     3804: }
                   3805: #define SPR_NOACCESS (&spr_noaccess)
                   3806: 
                   3807: /* mfspr */
1.1.1.8   root     3808: static inline void gen_op_mfspr(DisasContext *ctx)
1.1       root     3809: {
1.1.1.6   root     3810:     void (*read_cb)(void *opaque, int gprn, int sprn);
1.1       root     3811:     uint32_t sprn = SPR(ctx->opcode);
                   3812: 
                   3813: #if !defined(CONFIG_USER_ONLY)
1.1.1.6   root     3814:     if (ctx->mem_idx == 2)
1.1.1.5   root     3815:         read_cb = ctx->spr_cb[sprn].hea_read;
1.1.1.6   root     3816:     else if (ctx->mem_idx)
1.1       root     3817:         read_cb = ctx->spr_cb[sprn].oea_read;
                   3818:     else
                   3819: #endif
                   3820:         read_cb = ctx->spr_cb[sprn].uea_read;
1.1.1.5   root     3821:     if (likely(read_cb != NULL)) {
                   3822:         if (likely(read_cb != SPR_NOACCESS)) {
1.1.1.6   root     3823:             (*read_cb)(ctx, rD(ctx->opcode), sprn);
1.1       root     3824:         } else {
                   3825:             /* Privilege exception */
1.1.1.5   root     3826:             /* This is a hack to avoid warnings when running Linux:
                   3827:              * this OS breaks the PowerPC virtualisation model,
                   3828:              * allowing userland application to read the PVR
                   3829:              */
                   3830:             if (sprn != SPR_PVR) {
1.1.1.6   root     3831:                 qemu_log("Trying to read privileged spr %d %03x at "
1.1.1.8   root     3832:                          TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
                   3833:                 printf("Trying to read privileged spr %d %03x at "
                   3834:                        TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
1.1.1.2   root     3835:             }
1.1.1.6   root     3836:             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     3837:         }
                   3838:     } else {
                   3839:         /* Not defined */
1.1.1.6   root     3840:         qemu_log("Trying to read invalid spr %d %03x at "
1.1.1.8   root     3841:                     TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
                   3842:         printf("Trying to read invalid spr %d %03x at " TARGET_FMT_lx "\n",
1.1.1.5   root     3843:                sprn, sprn, ctx->nip);
1.1.1.6   root     3844:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
1.1       root     3845:     }
                   3846: }
                   3847: 
1.1.1.7   root     3848: static void gen_mfspr(DisasContext *ctx)
1.1       root     3849: {
                   3850:     gen_op_mfspr(ctx);
1.1.1.5   root     3851: }
1.1       root     3852: 
                   3853: /* mftb */
1.1.1.7   root     3854: static void gen_mftb(DisasContext *ctx)
1.1       root     3855: {
                   3856:     gen_op_mfspr(ctx);
                   3857: }
                   3858: 
1.1.1.6   root     3859: /* mtcrf mtocrf*/
1.1.1.7   root     3860: static void gen_mtcrf(DisasContext *ctx)
1.1       root     3861: {
1.1.1.5   root     3862:     uint32_t crm, crn;
                   3863: 
                   3864:     crm = CRM(ctx->opcode);
1.1.1.6   root     3865:     if (likely((ctx->opcode & 0x00100000))) {
                   3866:         if (crm && ((crm & (crm - 1)) == 0)) {
                   3867:             TCGv_i32 temp = tcg_temp_new_i32();
                   3868:             crn = ctz32 (crm);
                   3869:             tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
                   3870:             tcg_gen_shri_i32(temp, temp, crn * 4);
                   3871:             tcg_gen_andi_i32(cpu_crf[7 - crn], temp, 0xf);
                   3872:             tcg_temp_free_i32(temp);
                   3873:         }
1.1.1.5   root     3874:     } else {
1.1.1.7   root     3875:         TCGv_i32 temp = tcg_temp_new_i32();
                   3876:         tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
                   3877:         for (crn = 0 ; crn < 8 ; crn++) {
                   3878:             if (crm & (1 << crn)) {
                   3879:                     tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
                   3880:                     tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
                   3881:             }
                   3882:         }
1.1.1.6   root     3883:         tcg_temp_free_i32(temp);
1.1.1.5   root     3884:     }
1.1       root     3885: }
                   3886: 
                   3887: /* mtmsr */
1.1.1.5   root     3888: #if defined(TARGET_PPC64)
1.1.1.7   root     3889: static void gen_mtmsrd(DisasContext *ctx)
1.1.1.5   root     3890: {
                   3891: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     3892:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     3893: #else
1.1.1.6   root     3894:     if (unlikely(!ctx->mem_idx)) {
                   3895:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     3896:         return;
                   3897:     }
                   3898:     if (ctx->opcode & 0x00010000) {
                   3899:         /* Special form that does not need any synchronisation */
1.1.1.6   root     3900:         TCGv t0 = tcg_temp_new();
                   3901:         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
                   3902:         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
                   3903:         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
                   3904:         tcg_temp_free(t0);
1.1.1.5   root     3905:     } else {
                   3906:         /* XXX: we need to update nip before the store
                   3907:          *      if we enter power saving mode, we will exit the loop
                   3908:          *      directly from ppc_store_msr
                   3909:          */
                   3910:         gen_update_nip(ctx, ctx->nip);
1.1.1.6   root     3911:         gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     3912:         /* Must stop the translation as machine state (may have) changed */
                   3913:         /* Note that mtmsr is not always defined as context-synchronizing */
1.1.1.6   root     3914:         gen_stop_exception(ctx);
1.1.1.5   root     3915:     }
                   3916: #endif
                   3917: }
                   3918: #endif
                   3919: 
1.1.1.7   root     3920: static void gen_mtmsr(DisasContext *ctx)
1.1       root     3921: {
                   3922: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     3923:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     3924: #else
1.1.1.6   root     3925:     if (unlikely(!ctx->mem_idx)) {
                   3926:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     3927:         return;
                   3928:     }
1.1.1.5   root     3929:     if (ctx->opcode & 0x00010000) {
                   3930:         /* Special form that does not need any synchronisation */
1.1.1.6   root     3931:         TCGv t0 = tcg_temp_new();
                   3932:         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
                   3933:         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
                   3934:         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
                   3935:         tcg_temp_free(t0);
1.1.1.5   root     3936:     } else {
1.1.1.11  root     3937:         TCGv msr = tcg_temp_new();
                   3938: 
1.1.1.5   root     3939:         /* XXX: we need to update nip before the store
                   3940:          *      if we enter power saving mode, we will exit the loop
                   3941:          *      directly from ppc_store_msr
                   3942:          */
                   3943:         gen_update_nip(ctx, ctx->nip);
                   3944: #if defined(TARGET_PPC64)
1.1.1.11  root     3945:         tcg_gen_deposit_tl(msr, cpu_msr, cpu_gpr[rS(ctx->opcode)], 0, 32);
                   3946: #else
                   3947:         tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     3948: #endif
1.1.1.11  root     3949:         gen_helper_store_msr(msr);
1.1.1.5   root     3950:         /* Must stop the translation as machine state (may have) changed */
1.1.1.6   root     3951:         /* Note that mtmsr is not always defined as context-synchronizing */
                   3952:         gen_stop_exception(ctx);
1.1.1.5   root     3953:     }
1.1       root     3954: #endif
                   3955: }
                   3956: 
                   3957: /* mtspr */
1.1.1.7   root     3958: static void gen_mtspr(DisasContext *ctx)
1.1       root     3959: {
1.1.1.6   root     3960:     void (*write_cb)(void *opaque, int sprn, int gprn);
1.1       root     3961:     uint32_t sprn = SPR(ctx->opcode);
                   3962: 
                   3963: #if !defined(CONFIG_USER_ONLY)
1.1.1.6   root     3964:     if (ctx->mem_idx == 2)
1.1.1.5   root     3965:         write_cb = ctx->spr_cb[sprn].hea_write;
1.1.1.6   root     3966:     else if (ctx->mem_idx)
1.1       root     3967:         write_cb = ctx->spr_cb[sprn].oea_write;
                   3968:     else
                   3969: #endif
                   3970:         write_cb = ctx->spr_cb[sprn].uea_write;
1.1.1.5   root     3971:     if (likely(write_cb != NULL)) {
                   3972:         if (likely(write_cb != SPR_NOACCESS)) {
1.1.1.6   root     3973:             (*write_cb)(ctx, sprn, rS(ctx->opcode));
1.1       root     3974:         } else {
                   3975:             /* Privilege exception */
1.1.1.6   root     3976:             qemu_log("Trying to write privileged spr %d %03x at "
1.1.1.8   root     3977:                      TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
                   3978:             printf("Trying to write privileged spr %d %03x at " TARGET_FMT_lx
                   3979:                    "\n", sprn, sprn, ctx->nip);
1.1.1.6   root     3980:             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     3981:         }
1.1       root     3982:     } else {
                   3983:         /* Not defined */
1.1.1.6   root     3984:         qemu_log("Trying to write invalid spr %d %03x at "
1.1.1.8   root     3985:                  TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
                   3986:         printf("Trying to write invalid spr %d %03x at " TARGET_FMT_lx "\n",
1.1.1.5   root     3987:                sprn, sprn, ctx->nip);
1.1.1.6   root     3988:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
1.1       root     3989:     }
                   3990: }
                   3991: 
                   3992: /***                         Cache management                              ***/
1.1.1.7   root     3993: 
1.1       root     3994: /* dcbf */
1.1.1.7   root     3995: static void gen_dcbf(DisasContext *ctx)
1.1       root     3996: {
1.1.1.5   root     3997:     /* XXX: specification says this is treated as a load by the MMU */
1.1.1.6   root     3998:     TCGv t0;
                   3999:     gen_set_access_type(ctx, ACCESS_CACHE);
                   4000:     t0 = tcg_temp_new();
                   4001:     gen_addr_reg_index(ctx, t0);
                   4002:     gen_qemu_ld8u(ctx, t0, t0);
                   4003:     tcg_temp_free(t0);
1.1       root     4004: }
                   4005: 
                   4006: /* dcbi (Supervisor only) */
1.1.1.7   root     4007: static void gen_dcbi(DisasContext *ctx)
1.1       root     4008: {
                   4009: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4010:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     4011: #else
1.1.1.6   root     4012:     TCGv EA, val;
                   4013:     if (unlikely(!ctx->mem_idx)) {
                   4014:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     4015:         return;
                   4016:     }
1.1.1.6   root     4017:     EA = tcg_temp_new();
                   4018:     gen_set_access_type(ctx, ACCESS_CACHE);
                   4019:     gen_addr_reg_index(ctx, EA);
                   4020:     val = tcg_temp_new();
1.1.1.5   root     4021:     /* XXX: specification says this should be treated as a store by the MMU */
1.1.1.6   root     4022:     gen_qemu_ld8u(ctx, val, EA);
                   4023:     gen_qemu_st8(ctx, val, EA);
                   4024:     tcg_temp_free(val);
                   4025:     tcg_temp_free(EA);
1.1       root     4026: #endif
                   4027: }
                   4028: 
                   4029: /* dcdst */
1.1.1.7   root     4030: static void gen_dcbst(DisasContext *ctx)
1.1       root     4031: {
1.1.1.5   root     4032:     /* XXX: specification say this is treated as a load by the MMU */
1.1.1.6   root     4033:     TCGv t0;
                   4034:     gen_set_access_type(ctx, ACCESS_CACHE);
                   4035:     t0 = tcg_temp_new();
                   4036:     gen_addr_reg_index(ctx, t0);
                   4037:     gen_qemu_ld8u(ctx, t0, t0);
                   4038:     tcg_temp_free(t0);
1.1       root     4039: }
                   4040: 
                   4041: /* dcbt */
1.1.1.7   root     4042: static void gen_dcbt(DisasContext *ctx)
1.1       root     4043: {
1.1.1.5   root     4044:     /* interpreted as no-op */
                   4045:     /* XXX: specification say this is treated as a load by the MMU
                   4046:      *      but does not generate any exception
                   4047:      */
1.1       root     4048: }
                   4049: 
                   4050: /* dcbtst */
1.1.1.7   root     4051: static void gen_dcbtst(DisasContext *ctx)
1.1       root     4052: {
1.1.1.5   root     4053:     /* interpreted as no-op */
                   4054:     /* XXX: specification say this is treated as a load by the MMU
                   4055:      *      but does not generate any exception
                   4056:      */
1.1       root     4057: }
                   4058: 
                   4059: /* dcbz */
1.1.1.7   root     4060: static void gen_dcbz(DisasContext *ctx)
1.1.1.6   root     4061: {
                   4062:     TCGv t0;
                   4063:     gen_set_access_type(ctx, ACCESS_CACHE);
                   4064:     /* NIP cannot be restored if the memory exception comes from an helper */
                   4065:     gen_update_nip(ctx, ctx->nip - 4);
                   4066:     t0 = tcg_temp_new();
                   4067:     gen_addr_reg_index(ctx, t0);
                   4068:     gen_helper_dcbz(t0);
                   4069:     tcg_temp_free(t0);
                   4070: }
1.1       root     4071: 
1.1.1.7   root     4072: static void gen_dcbz_970(DisasContext *ctx)
1.1       root     4073: {
1.1.1.6   root     4074:     TCGv t0;
                   4075:     gen_set_access_type(ctx, ACCESS_CACHE);
                   4076:     /* NIP cannot be restored if the memory exception comes from an helper */
                   4077:     gen_update_nip(ctx, ctx->nip - 4);
                   4078:     t0 = tcg_temp_new();
                   4079:     gen_addr_reg_index(ctx, t0);
                   4080:     if (ctx->opcode & 0x00200000)
                   4081:         gen_helper_dcbz(t0);
                   4082:     else
                   4083:         gen_helper_dcbz_970(t0);
                   4084:     tcg_temp_free(t0);
                   4085: }
1.1.1.5   root     4086: 
1.1.1.6   root     4087: /* dst / dstt */
1.1.1.7   root     4088: static void gen_dst(DisasContext *ctx)
1.1.1.6   root     4089: {
                   4090:     if (rA(ctx->opcode) == 0) {
                   4091:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
                   4092:     } else {
                   4093:         /* interpreted as no-op */
1.1       root     4094:     }
1.1.1.5   root     4095: }
                   4096: 
1.1.1.6   root     4097: /* dstst /dststt */
1.1.1.7   root     4098: static void gen_dstst(DisasContext *ctx)
1.1.1.5   root     4099: {
1.1.1.6   root     4100:     if (rA(ctx->opcode) == 0) {
                   4101:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
                   4102:     } else {
                   4103:         /* interpreted as no-op */
                   4104:     }
                   4105: 
1.1.1.5   root     4106: }
                   4107: 
1.1.1.6   root     4108: /* dss / dssall */
1.1.1.7   root     4109: static void gen_dss(DisasContext *ctx)
1.1.1.5   root     4110: {
1.1.1.6   root     4111:     /* interpreted as no-op */
1.1       root     4112: }
                   4113: 
                   4114: /* icbi */
1.1.1.7   root     4115: static void gen_icbi(DisasContext *ctx)
1.1       root     4116: {
1.1.1.6   root     4117:     TCGv t0;
                   4118:     gen_set_access_type(ctx, ACCESS_CACHE);
1.1.1.5   root     4119:     /* NIP cannot be restored if the memory exception comes from an helper */
                   4120:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6   root     4121:     t0 = tcg_temp_new();
                   4122:     gen_addr_reg_index(ctx, t0);
                   4123:     gen_helper_icbi(t0);
                   4124:     tcg_temp_free(t0);
1.1       root     4125: }
                   4126: 
                   4127: /* Optional: */
                   4128: /* dcba */
1.1.1.7   root     4129: static void gen_dcba(DisasContext *ctx)
1.1       root     4130: {
1.1.1.5   root     4131:     /* interpreted as no-op */
                   4132:     /* XXX: specification say this is treated as a store by the MMU
                   4133:      *      but does not generate any exception
                   4134:      */
1.1       root     4135: }
                   4136: 
                   4137: /***                    Segment register manipulation                      ***/
                   4138: /* Supervisor only: */
1.1.1.7   root     4139: 
1.1       root     4140: /* mfsr */
1.1.1.7   root     4141: static void gen_mfsr(DisasContext *ctx)
1.1       root     4142: {
                   4143: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4144:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4145: #else
1.1.1.6   root     4146:     TCGv t0;
                   4147:     if (unlikely(!ctx->mem_idx)) {
                   4148:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4149:         return;
                   4150:     }
1.1.1.6   root     4151:     t0 = tcg_const_tl(SR(ctx->opcode));
                   4152:     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
                   4153:     tcg_temp_free(t0);
1.1       root     4154: #endif
                   4155: }
                   4156: 
                   4157: /* mfsrin */
1.1.1.7   root     4158: static void gen_mfsrin(DisasContext *ctx)
1.1       root     4159: {
                   4160: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4161:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4162: #else
1.1.1.6   root     4163:     TCGv t0;
                   4164:     if (unlikely(!ctx->mem_idx)) {
                   4165:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4166:         return;
                   4167:     }
1.1.1.6   root     4168:     t0 = tcg_temp_new();
                   4169:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
                   4170:     tcg_gen_andi_tl(t0, t0, 0xF);
                   4171:     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
                   4172:     tcg_temp_free(t0);
1.1       root     4173: #endif
                   4174: }
                   4175: 
                   4176: /* mtsr */
1.1.1.7   root     4177: static void gen_mtsr(DisasContext *ctx)
1.1       root     4178: {
                   4179: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4180:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4181: #else
1.1.1.6   root     4182:     TCGv t0;
                   4183:     if (unlikely(!ctx->mem_idx)) {
                   4184:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4185:         return;
                   4186:     }
1.1.1.6   root     4187:     t0 = tcg_const_tl(SR(ctx->opcode));
                   4188:     gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
                   4189:     tcg_temp_free(t0);
1.1       root     4190: #endif
                   4191: }
                   4192: 
                   4193: /* mtsrin */
1.1.1.7   root     4194: static void gen_mtsrin(DisasContext *ctx)
1.1       root     4195: {
                   4196: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4197:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4198: #else
1.1.1.6   root     4199:     TCGv t0;
                   4200:     if (unlikely(!ctx->mem_idx)) {
                   4201:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4202:         return;
                   4203:     }
1.1.1.6   root     4204:     t0 = tcg_temp_new();
                   4205:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
                   4206:     tcg_gen_andi_tl(t0, t0, 0xF);
                   4207:     gen_helper_store_sr(t0, cpu_gpr[rD(ctx->opcode)]);
                   4208:     tcg_temp_free(t0);
1.1       root     4209: #endif
                   4210: }
                   4211: 
1.1.1.5   root     4212: #if defined(TARGET_PPC64)
                   4213: /* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
1.1.1.7   root     4214: 
1.1.1.5   root     4215: /* mfsr */
1.1.1.7   root     4216: static void gen_mfsr_64b(DisasContext *ctx)
1.1       root     4217: {
                   4218: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4219:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4220: #else
1.1.1.6   root     4221:     TCGv t0;
                   4222:     if (unlikely(!ctx->mem_idx)) {
                   4223:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4224:         return;
                   4225:     }
1.1.1.6   root     4226:     t0 = tcg_const_tl(SR(ctx->opcode));
1.1.1.7   root     4227:     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
1.1.1.6   root     4228:     tcg_temp_free(t0);
1.1.1.5   root     4229: #endif
                   4230: }
                   4231: 
                   4232: /* mfsrin */
1.1.1.7   root     4233: static void gen_mfsrin_64b(DisasContext *ctx)
1.1.1.5   root     4234: {
                   4235: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4236:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4237: #else
1.1.1.6   root     4238:     TCGv t0;
                   4239:     if (unlikely(!ctx->mem_idx)) {
                   4240:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4241:         return;
                   4242:     }
1.1.1.6   root     4243:     t0 = tcg_temp_new();
                   4244:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
                   4245:     tcg_gen_andi_tl(t0, t0, 0xF);
1.1.1.7   root     4246:     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
1.1.1.6   root     4247:     tcg_temp_free(t0);
1.1.1.5   root     4248: #endif
                   4249: }
                   4250: 
                   4251: /* mtsr */
1.1.1.7   root     4252: static void gen_mtsr_64b(DisasContext *ctx)
1.1.1.5   root     4253: {
                   4254: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4255:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4256: #else
1.1.1.6   root     4257:     TCGv t0;
                   4258:     if (unlikely(!ctx->mem_idx)) {
                   4259:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4260:         return;
                   4261:     }
1.1.1.6   root     4262:     t0 = tcg_const_tl(SR(ctx->opcode));
1.1.1.7   root     4263:     gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
1.1.1.6   root     4264:     tcg_temp_free(t0);
1.1.1.5   root     4265: #endif
                   4266: }
                   4267: 
                   4268: /* mtsrin */
1.1.1.7   root     4269: static void gen_mtsrin_64b(DisasContext *ctx)
1.1.1.5   root     4270: {
                   4271: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4272:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4273: #else
1.1.1.6   root     4274:     TCGv t0;
                   4275:     if (unlikely(!ctx->mem_idx)) {
                   4276:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4277:         return;
                   4278:     }
1.1.1.6   root     4279:     t0 = tcg_temp_new();
                   4280:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
                   4281:     tcg_gen_andi_tl(t0, t0, 0xF);
1.1.1.7   root     4282:     gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
1.1.1.6   root     4283:     tcg_temp_free(t0);
1.1.1.5   root     4284: #endif
                   4285: }
1.1.1.7   root     4286: 
                   4287: /* slbmte */
                   4288: static void gen_slbmte(DisasContext *ctx)
                   4289: {
                   4290: #if defined(CONFIG_USER_ONLY)
                   4291:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
                   4292: #else
                   4293:     if (unlikely(!ctx->mem_idx)) {
                   4294:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
                   4295:         return;
                   4296:     }
                   4297:     gen_helper_store_slb(cpu_gpr[rB(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   4298: #endif
                   4299: }
                   4300: 
1.1.1.11  root     4301: static void gen_slbmfee(DisasContext *ctx)
                   4302: {
                   4303: #if defined(CONFIG_USER_ONLY)
                   4304:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
                   4305: #else
                   4306:     if (unlikely(!ctx->mem_idx)) {
                   4307:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
                   4308:         return;
                   4309:     }
                   4310:     gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)],
                   4311:                              cpu_gpr[rB(ctx->opcode)]);
                   4312: #endif
                   4313: }
                   4314: 
                   4315: static void gen_slbmfev(DisasContext *ctx)
                   4316: {
                   4317: #if defined(CONFIG_USER_ONLY)
                   4318:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
                   4319: #else
                   4320:     if (unlikely(!ctx->mem_idx)) {
                   4321:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
                   4322:         return;
                   4323:     }
                   4324:     gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)],
                   4325:                              cpu_gpr[rB(ctx->opcode)]);
                   4326: #endif
                   4327: }
1.1.1.5   root     4328: #endif /* defined(TARGET_PPC64) */
                   4329: 
                   4330: /***                      Lookaside buffer management                      ***/
1.1.1.6   root     4331: /* Optional & mem_idx only: */
1.1.1.7   root     4332: 
1.1.1.5   root     4333: /* tlbia */
1.1.1.7   root     4334: static void gen_tlbia(DisasContext *ctx)
1.1.1.5   root     4335: {
                   4336: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4337:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4338: #else
1.1.1.6   root     4339:     if (unlikely(!ctx->mem_idx)) {
                   4340:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4341:         return;
                   4342:     }
1.1.1.6   root     4343:     gen_helper_tlbia();
1.1       root     4344: #endif
                   4345: }
                   4346: 
1.1.1.7   root     4347: /* tlbiel */
                   4348: static void gen_tlbiel(DisasContext *ctx)
                   4349: {
                   4350: #if defined(CONFIG_USER_ONLY)
                   4351:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   4352: #else
                   4353:     if (unlikely(!ctx->mem_idx)) {
                   4354:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   4355:         return;
                   4356:     }
                   4357:     gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
                   4358: #endif
                   4359: }
                   4360: 
1.1       root     4361: /* tlbie */
1.1.1.7   root     4362: static void gen_tlbie(DisasContext *ctx)
1.1.1.5   root     4363: {
                   4364: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4365:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4366: #else
1.1.1.6   root     4367:     if (unlikely(!ctx->mem_idx)) {
                   4368:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4369:         return;
                   4370:     }
                   4371: #if defined(TARGET_PPC64)
1.1.1.6   root     4372:     if (!ctx->sf_mode) {
                   4373:         TCGv t0 = tcg_temp_new();
                   4374:         tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
                   4375:         gen_helper_tlbie(t0);
                   4376:         tcg_temp_free(t0);
                   4377:     } else
1.1.1.5   root     4378: #endif
1.1.1.6   root     4379:         gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4380: #endif
                   4381: }
                   4382: 
                   4383: /* tlbsync */
1.1.1.7   root     4384: static void gen_tlbsync(DisasContext *ctx)
1.1.1.5   root     4385: {
                   4386: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4387:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4388: #else
1.1.1.6   root     4389:     if (unlikely(!ctx->mem_idx)) {
                   4390:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4391:         return;
                   4392:     }
                   4393:     /* This has no effect: it should ensure that all previous
                   4394:      * tlbie have completed
                   4395:      */
1.1.1.6   root     4396:     gen_stop_exception(ctx);
1.1.1.5   root     4397: #endif
                   4398: }
                   4399: 
                   4400: #if defined(TARGET_PPC64)
                   4401: /* slbia */
1.1.1.7   root     4402: static void gen_slbia(DisasContext *ctx)
1.1.1.5   root     4403: {
                   4404: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4405:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4406: #else
1.1.1.6   root     4407:     if (unlikely(!ctx->mem_idx)) {
                   4408:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4409:         return;
                   4410:     }
1.1.1.6   root     4411:     gen_helper_slbia();
1.1.1.5   root     4412: #endif
                   4413: }
                   4414: 
                   4415: /* slbie */
1.1.1.7   root     4416: static void gen_slbie(DisasContext *ctx)
1.1.1.5   root     4417: {
                   4418: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     4419:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4420: #else
1.1.1.6   root     4421:     if (unlikely(!ctx->mem_idx)) {
                   4422:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4423:         return;
                   4424:     }
1.1.1.6   root     4425:     gen_helper_slbie(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4426: #endif
                   4427: }
                   4428: #endif
                   4429: 
                   4430: /***                              External control                         ***/
                   4431: /* Optional: */
1.1.1.7   root     4432: 
1.1.1.5   root     4433: /* eciwx */
1.1.1.7   root     4434: static void gen_eciwx(DisasContext *ctx)
1.1.1.5   root     4435: {
1.1.1.6   root     4436:     TCGv t0;
                   4437:     /* Should check EAR[E] ! */
                   4438:     gen_set_access_type(ctx, ACCESS_EXT);
                   4439:     t0 = tcg_temp_new();
                   4440:     gen_addr_reg_index(ctx, t0);
                   4441:     gen_check_align(ctx, t0, 0x03);
                   4442:     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
                   4443:     tcg_temp_free(t0);
1.1.1.5   root     4444: }
                   4445: 
                   4446: /* ecowx */
1.1.1.7   root     4447: static void gen_ecowx(DisasContext *ctx)
1.1.1.5   root     4448: {
1.1.1.6   root     4449:     TCGv t0;
                   4450:     /* Should check EAR[E] ! */
                   4451:     gen_set_access_type(ctx, ACCESS_EXT);
                   4452:     t0 = tcg_temp_new();
                   4453:     gen_addr_reg_index(ctx, t0);
                   4454:     gen_check_align(ctx, t0, 0x03);
                   4455:     gen_qemu_st32(ctx, cpu_gpr[rD(ctx->opcode)], t0);
                   4456:     tcg_temp_free(t0);
1.1.1.5   root     4457: }
                   4458: 
                   4459: /* PowerPC 601 specific instructions */
1.1.1.7   root     4460: 
1.1.1.5   root     4461: /* abs - abs. */
1.1.1.7   root     4462: static void gen_abs(DisasContext *ctx)
1.1.1.5   root     4463: {
1.1.1.6   root     4464:     int l1 = gen_new_label();
                   4465:     int l2 = gen_new_label();
                   4466:     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);
                   4467:     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4468:     tcg_gen_br(l2);
                   4469:     gen_set_label(l1);
                   4470:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4471:     gen_set_label(l2);
1.1.1.5   root     4472:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4473:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4474: }
                   4475: 
                   4476: /* abso - abso. */
1.1.1.7   root     4477: static void gen_abso(DisasContext *ctx)
1.1.1.5   root     4478: {
1.1.1.6   root     4479:     int l1 = gen_new_label();
                   4480:     int l2 = gen_new_label();
                   4481:     int l3 = gen_new_label();
                   4482:     /* Start with XER OV disabled, the most likely case */
                   4483:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                   4484:     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
                   4485:     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
                   4486:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                   4487:     tcg_gen_br(l2);
                   4488:     gen_set_label(l1);
                   4489:     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4490:     tcg_gen_br(l3);
                   4491:     gen_set_label(l2);
                   4492:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4493:     gen_set_label(l3);
1.1.1.5   root     4494:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4495:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4496: }
                   4497: 
                   4498: /* clcs */
1.1.1.7   root     4499: static void gen_clcs(DisasContext *ctx)
1.1.1.5   root     4500: {
1.1.1.6   root     4501:     TCGv_i32 t0 = tcg_const_i32(rA(ctx->opcode));
                   4502:     gen_helper_clcs(cpu_gpr[rD(ctx->opcode)], t0);
                   4503:     tcg_temp_free_i32(t0);
1.1.1.5   root     4504:     /* Rc=1 sets CR0 to an undefined state */
                   4505: }
                   4506: 
                   4507: /* div - div. */
1.1.1.7   root     4508: static void gen_div(DisasContext *ctx)
1.1.1.5   root     4509: {
1.1.1.6   root     4510:     gen_helper_div(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4511:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4512:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4513: }
                   4514: 
                   4515: /* divo - divo. */
1.1.1.7   root     4516: static void gen_divo(DisasContext *ctx)
1.1.1.5   root     4517: {
1.1.1.6   root     4518:     gen_helper_divo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4519:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4520:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4521: }
                   4522: 
                   4523: /* divs - divs. */
1.1.1.7   root     4524: static void gen_divs(DisasContext *ctx)
1.1.1.5   root     4525: {
1.1.1.6   root     4526:     gen_helper_divs(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4527:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4528:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4529: }
                   4530: 
                   4531: /* divso - divso. */
1.1.1.7   root     4532: static void gen_divso(DisasContext *ctx)
1.1.1.5   root     4533: {
1.1.1.6   root     4534:     gen_helper_divso(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4535:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4536:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4537: }
                   4538: 
                   4539: /* doz - doz. */
1.1.1.7   root     4540: static void gen_doz(DisasContext *ctx)
1.1.1.5   root     4541: {
1.1.1.6   root     4542:     int l1 = gen_new_label();
                   4543:     int l2 = gen_new_label();
                   4544:     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
                   4545:     tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4546:     tcg_gen_br(l2);
                   4547:     gen_set_label(l1);
                   4548:     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
                   4549:     gen_set_label(l2);
1.1.1.5   root     4550:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4551:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4552: }
                   4553: 
                   4554: /* dozo - dozo. */
1.1.1.7   root     4555: static void gen_dozo(DisasContext *ctx)
1.1.1.5   root     4556: {
1.1.1.6   root     4557:     int l1 = gen_new_label();
                   4558:     int l2 = gen_new_label();
                   4559:     TCGv t0 = tcg_temp_new();
                   4560:     TCGv t1 = tcg_temp_new();
                   4561:     TCGv t2 = tcg_temp_new();
                   4562:     /* Start with XER OV disabled, the most likely case */
                   4563:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                   4564:     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
                   4565:     tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4566:     tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4567:     tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0);
                   4568:     tcg_gen_andc_tl(t1, t1, t2);
                   4569:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   4570:     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
                   4571:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                   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);
                   4576:     tcg_temp_free(t0);
                   4577:     tcg_temp_free(t1);
                   4578:     tcg_temp_free(t2);
1.1.1.5   root     4579:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4580:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4581: }
                   4582: 
                   4583: /* dozi */
1.1.1.7   root     4584: static void gen_dozi(DisasContext *ctx)
1.1.1.5   root     4585: {
1.1.1.6   root     4586:     target_long simm = SIMM(ctx->opcode);
                   4587:     int l1 = gen_new_label();
                   4588:     int l2 = gen_new_label();
                   4589:     tcg_gen_brcondi_tl(TCG_COND_LT, cpu_gpr[rA(ctx->opcode)], simm, l1);
                   4590:     tcg_gen_subfi_tl(cpu_gpr[rD(ctx->opcode)], simm, cpu_gpr[rA(ctx->opcode)]);
                   4591:     tcg_gen_br(l2);
                   4592:     gen_set_label(l1);
                   4593:     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
                   4594:     gen_set_label(l2);
                   4595:     if (unlikely(Rc(ctx->opcode) != 0))
                   4596:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4597: }
                   4598: 
                   4599: /* lscbx - lscbx. */
1.1.1.7   root     4600: static void gen_lscbx(DisasContext *ctx)
1.1.1.5   root     4601: {
1.1.1.6   root     4602:     TCGv t0 = tcg_temp_new();
                   4603:     TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
                   4604:     TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode));
                   4605:     TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
1.1.1.5   root     4606: 
1.1.1.6   root     4607:     gen_addr_reg_index(ctx, t0);
1.1.1.5   root     4608:     /* NIP cannot be restored if the memory exception comes from an helper */
                   4609:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6   root     4610:     gen_helper_lscbx(t0, t0, t1, t2, t3);
                   4611:     tcg_temp_free_i32(t1);
                   4612:     tcg_temp_free_i32(t2);
                   4613:     tcg_temp_free_i32(t3);
                   4614:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
                   4615:     tcg_gen_or_tl(cpu_xer, cpu_xer, t0);
1.1.1.5   root     4616:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4617:         gen_set_Rc0(ctx, t0);
                   4618:     tcg_temp_free(t0);
1.1.1.5   root     4619: }
                   4620: 
                   4621: /* maskg - maskg. */
1.1.1.7   root     4622: static void gen_maskg(DisasContext *ctx)
1.1.1.5   root     4623: {
1.1.1.6   root     4624:     int l1 = gen_new_label();
                   4625:     TCGv t0 = tcg_temp_new();
                   4626:     TCGv t1 = tcg_temp_new();
                   4627:     TCGv t2 = tcg_temp_new();
                   4628:     TCGv t3 = tcg_temp_new();
                   4629:     tcg_gen_movi_tl(t3, 0xFFFFFFFF);
                   4630:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4631:     tcg_gen_andi_tl(t1, cpu_gpr[rS(ctx->opcode)], 0x1F);
                   4632:     tcg_gen_addi_tl(t2, t0, 1);
                   4633:     tcg_gen_shr_tl(t2, t3, t2);
                   4634:     tcg_gen_shr_tl(t3, t3, t1);
                   4635:     tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], t2, t3);
                   4636:     tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
                   4637:     tcg_gen_neg_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4638:     gen_set_label(l1);
                   4639:     tcg_temp_free(t0);
                   4640:     tcg_temp_free(t1);
                   4641:     tcg_temp_free(t2);
                   4642:     tcg_temp_free(t3);
1.1.1.5   root     4643:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4644:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4645: }
                   4646: 
                   4647: /* maskir - maskir. */
1.1.1.7   root     4648: static void gen_maskir(DisasContext *ctx)
1.1.1.5   root     4649: {
1.1.1.6   root     4650:     TCGv t0 = tcg_temp_new();
                   4651:     TCGv t1 = tcg_temp_new();
                   4652:     tcg_gen_and_tl(t0, cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   4653:     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   4654:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   4655:     tcg_temp_free(t0);
                   4656:     tcg_temp_free(t1);
1.1.1.5   root     4657:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4658:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4659: }
                   4660: 
                   4661: /* mul - mul. */
1.1.1.7   root     4662: static void gen_mul(DisasContext *ctx)
1.1.1.5   root     4663: {
1.1.1.6   root     4664:     TCGv_i64 t0 = tcg_temp_new_i64();
                   4665:     TCGv_i64 t1 = tcg_temp_new_i64();
                   4666:     TCGv t2 = tcg_temp_new();
                   4667:     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   4668:     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   4669:     tcg_gen_mul_i64(t0, t0, t1);
                   4670:     tcg_gen_trunc_i64_tl(t2, t0);
                   4671:     gen_store_spr(SPR_MQ, t2);
                   4672:     tcg_gen_shri_i64(t1, t0, 32);
                   4673:     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
                   4674:     tcg_temp_free_i64(t0);
                   4675:     tcg_temp_free_i64(t1);
                   4676:     tcg_temp_free(t2);
1.1.1.5   root     4677:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4678:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4679: }
                   4680: 
                   4681: /* mulo - mulo. */
1.1.1.7   root     4682: static void gen_mulo(DisasContext *ctx)
1.1.1.5   root     4683: {
1.1.1.6   root     4684:     int l1 = gen_new_label();
                   4685:     TCGv_i64 t0 = tcg_temp_new_i64();
                   4686:     TCGv_i64 t1 = tcg_temp_new_i64();
                   4687:     TCGv t2 = tcg_temp_new();
                   4688:     /* Start with XER OV disabled, the most likely case */
                   4689:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                   4690:     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   4691:     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   4692:     tcg_gen_mul_i64(t0, t0, t1);
                   4693:     tcg_gen_trunc_i64_tl(t2, t0);
                   4694:     gen_store_spr(SPR_MQ, t2);
                   4695:     tcg_gen_shri_i64(t1, t0, 32);
                   4696:     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
                   4697:     tcg_gen_ext32s_i64(t1, t0);
                   4698:     tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
                   4699:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                   4700:     gen_set_label(l1);
                   4701:     tcg_temp_free_i64(t0);
                   4702:     tcg_temp_free_i64(t1);
                   4703:     tcg_temp_free(t2);
1.1.1.5   root     4704:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4705:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4706: }
                   4707: 
                   4708: /* nabs - nabs. */
1.1.1.7   root     4709: static void gen_nabs(DisasContext *ctx)
1.1.1.5   root     4710: {
1.1.1.6   root     4711:     int l1 = gen_new_label();
                   4712:     int l2 = gen_new_label();
                   4713:     tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
                   4714:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4715:     tcg_gen_br(l2);
                   4716:     gen_set_label(l1);
                   4717:     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4718:     gen_set_label(l2);
1.1.1.5   root     4719:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4720:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4721: }
                   4722: 
                   4723: /* nabso - nabso. */
1.1.1.7   root     4724: static void gen_nabso(DisasContext *ctx)
1.1.1.5   root     4725: {
1.1.1.6   root     4726:     int l1 = gen_new_label();
                   4727:     int l2 = gen_new_label();
                   4728:     tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
                   4729:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4730:     tcg_gen_br(l2);
                   4731:     gen_set_label(l1);
                   4732:     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   4733:     gen_set_label(l2);
                   4734:     /* nabs never overflows */
                   4735:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
1.1.1.5   root     4736:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4737:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4738: }
                   4739: 
                   4740: /* rlmi - rlmi. */
1.1.1.7   root     4741: static void gen_rlmi(DisasContext *ctx)
1.1.1.5   root     4742: {
1.1.1.6   root     4743:     uint32_t mb = MB(ctx->opcode);
                   4744:     uint32_t me = ME(ctx->opcode);
                   4745:     TCGv t0 = tcg_temp_new();
                   4746:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4747:     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   4748:     tcg_gen_andi_tl(t0, t0, MASK(mb, me));
                   4749:     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~MASK(mb, me));
                   4750:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], t0);
                   4751:     tcg_temp_free(t0);
1.1.1.5   root     4752:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4753:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4754: }
                   4755: 
                   4756: /* rrib - rrib. */
1.1.1.7   root     4757: static void gen_rrib(DisasContext *ctx)
1.1.1.5   root     4758: {
1.1.1.6   root     4759:     TCGv t0 = tcg_temp_new();
                   4760:     TCGv t1 = tcg_temp_new();
                   4761:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4762:     tcg_gen_movi_tl(t1, 0x80000000);
                   4763:     tcg_gen_shr_tl(t1, t1, t0);
                   4764:     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   4765:     tcg_gen_and_tl(t0, t0, t1);
                   4766:     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], t1);
                   4767:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   4768:     tcg_temp_free(t0);
                   4769:     tcg_temp_free(t1);
1.1.1.5   root     4770:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4771:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4772: }
                   4773: 
                   4774: /* sle - sle. */
1.1.1.7   root     4775: static void gen_sle(DisasContext *ctx)
1.1.1.5   root     4776: {
1.1.1.6   root     4777:     TCGv t0 = tcg_temp_new();
                   4778:     TCGv t1 = tcg_temp_new();
                   4779:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4780:     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
                   4781:     tcg_gen_subfi_tl(t1, 32, t1);
                   4782:     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
                   4783:     tcg_gen_or_tl(t1, t0, t1);
                   4784:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   4785:     gen_store_spr(SPR_MQ, t1);
                   4786:     tcg_temp_free(t0);
                   4787:     tcg_temp_free(t1);
1.1.1.5   root     4788:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4789:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4790: }
                   4791: 
                   4792: /* sleq - sleq. */
1.1.1.7   root     4793: static void gen_sleq(DisasContext *ctx)
1.1.1.5   root     4794: {
1.1.1.6   root     4795:     TCGv t0 = tcg_temp_new();
                   4796:     TCGv t1 = tcg_temp_new();
                   4797:     TCGv t2 = tcg_temp_new();
                   4798:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4799:     tcg_gen_movi_tl(t2, 0xFFFFFFFF);
                   4800:     tcg_gen_shl_tl(t2, t2, t0);
                   4801:     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   4802:     gen_load_spr(t1, SPR_MQ);
                   4803:     gen_store_spr(SPR_MQ, t0);
                   4804:     tcg_gen_and_tl(t0, t0, t2);
                   4805:     tcg_gen_andc_tl(t1, t1, t2);
                   4806:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   4807:     tcg_temp_free(t0);
                   4808:     tcg_temp_free(t1);
                   4809:     tcg_temp_free(t2);
1.1.1.5   root     4810:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4811:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4812: }
                   4813: 
                   4814: /* sliq - sliq. */
1.1.1.7   root     4815: static void gen_sliq(DisasContext *ctx)
1.1.1.5   root     4816: {
1.1.1.6   root     4817:     int sh = SH(ctx->opcode);
                   4818:     TCGv t0 = tcg_temp_new();
                   4819:     TCGv t1 = tcg_temp_new();
                   4820:     tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   4821:     tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
                   4822:     tcg_gen_or_tl(t1, t0, t1);
                   4823:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   4824:     gen_store_spr(SPR_MQ, t1);
                   4825:     tcg_temp_free(t0);
                   4826:     tcg_temp_free(t1);
1.1.1.5   root     4827:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4828:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4829: }
                   4830: 
                   4831: /* slliq - slliq. */
1.1.1.7   root     4832: static void gen_slliq(DisasContext *ctx)
1.1.1.5   root     4833: {
1.1.1.6   root     4834:     int sh = SH(ctx->opcode);
                   4835:     TCGv t0 = tcg_temp_new();
                   4836:     TCGv t1 = tcg_temp_new();
                   4837:     tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   4838:     gen_load_spr(t1, SPR_MQ);
                   4839:     gen_store_spr(SPR_MQ, t0);
                   4840:     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU << sh));
                   4841:     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU << sh));
                   4842:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   4843:     tcg_temp_free(t0);
                   4844:     tcg_temp_free(t1);
1.1.1.5   root     4845:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4846:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4847: }
                   4848: 
                   4849: /* sllq - sllq. */
1.1.1.7   root     4850: static void gen_sllq(DisasContext *ctx)
1.1.1.5   root     4851: {
1.1.1.6   root     4852:     int l1 = gen_new_label();
                   4853:     int l2 = gen_new_label();
                   4854:     TCGv t0 = tcg_temp_local_new();
                   4855:     TCGv t1 = tcg_temp_local_new();
                   4856:     TCGv t2 = tcg_temp_local_new();
                   4857:     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4858:     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
                   4859:     tcg_gen_shl_tl(t1, t1, t2);
                   4860:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
                   4861:     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
                   4862:     gen_load_spr(t0, SPR_MQ);
                   4863:     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   4864:     tcg_gen_br(l2);
                   4865:     gen_set_label(l1);
                   4866:     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
                   4867:     gen_load_spr(t2, SPR_MQ);
                   4868:     tcg_gen_andc_tl(t1, t2, t1);
                   4869:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   4870:     gen_set_label(l2);
                   4871:     tcg_temp_free(t0);
                   4872:     tcg_temp_free(t1);
                   4873:     tcg_temp_free(t2);
1.1.1.5   root     4874:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4875:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4876: }
                   4877: 
                   4878: /* slq - slq. */
1.1.1.7   root     4879: static void gen_slq(DisasContext *ctx)
1.1.1.5   root     4880: {
1.1.1.6   root     4881:     int l1 = gen_new_label();
                   4882:     TCGv t0 = tcg_temp_new();
                   4883:     TCGv t1 = tcg_temp_new();
                   4884:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4885:     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
                   4886:     tcg_gen_subfi_tl(t1, 32, t1);
                   4887:     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
                   4888:     tcg_gen_or_tl(t1, t0, t1);
                   4889:     gen_store_spr(SPR_MQ, t1);
                   4890:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
                   4891:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   4892:     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
                   4893:     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
                   4894:     gen_set_label(l1);
                   4895:     tcg_temp_free(t0);
                   4896:     tcg_temp_free(t1);
1.1.1.5   root     4897:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4898:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4899: }
                   4900: 
                   4901: /* sraiq - sraiq. */
1.1.1.7   root     4902: static void gen_sraiq(DisasContext *ctx)
1.1.1.5   root     4903: {
1.1.1.6   root     4904:     int sh = SH(ctx->opcode);
                   4905:     int l1 = gen_new_label();
                   4906:     TCGv t0 = tcg_temp_new();
                   4907:     TCGv t1 = tcg_temp_new();
                   4908:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   4909:     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
                   4910:     tcg_gen_or_tl(t0, t0, t1);
                   4911:     gen_store_spr(SPR_MQ, t0);
                   4912:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
                   4913:     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
                   4914:     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
                   4915:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
                   4916:     gen_set_label(l1);
                   4917:     tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
                   4918:     tcg_temp_free(t0);
                   4919:     tcg_temp_free(t1);
1.1.1.5   root     4920:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4921:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4922: }
                   4923: 
                   4924: /* sraq - sraq. */
1.1.1.7   root     4925: static void gen_sraq(DisasContext *ctx)
1.1.1.5   root     4926: {
1.1.1.6   root     4927:     int l1 = gen_new_label();
                   4928:     int l2 = gen_new_label();
                   4929:     TCGv t0 = tcg_temp_new();
                   4930:     TCGv t1 = tcg_temp_local_new();
                   4931:     TCGv t2 = tcg_temp_local_new();
                   4932:     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4933:     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
                   4934:     tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2);
                   4935:     tcg_gen_subfi_tl(t2, 32, t2);
                   4936:     tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2);
                   4937:     tcg_gen_or_tl(t0, t0, t2);
                   4938:     gen_store_spr(SPR_MQ, t0);
                   4939:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
                   4940:     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1);
                   4941:     tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]);
                   4942:     tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31);
                   4943:     gen_set_label(l1);
                   4944:     tcg_temp_free(t0);
                   4945:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
                   4946:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
                   4947:     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
                   4948:     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);
                   4949:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
                   4950:     gen_set_label(l2);
                   4951:     tcg_temp_free(t1);
                   4952:     tcg_temp_free(t2);
1.1.1.5   root     4953:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4954:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4955: }
                   4956: 
                   4957: /* sre - sre. */
1.1.1.7   root     4958: static void gen_sre(DisasContext *ctx)
1.1.1.5   root     4959: {
1.1.1.6   root     4960:     TCGv t0 = tcg_temp_new();
                   4961:     TCGv t1 = tcg_temp_new();
                   4962:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4963:     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
                   4964:     tcg_gen_subfi_tl(t1, 32, t1);
                   4965:     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
                   4966:     tcg_gen_or_tl(t1, t0, t1);
                   4967:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   4968:     gen_store_spr(SPR_MQ, t1);
                   4969:     tcg_temp_free(t0);
                   4970:     tcg_temp_free(t1);
1.1.1.5   root     4971:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4972:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4973: }
                   4974: 
                   4975: /* srea - srea. */
1.1.1.7   root     4976: static void gen_srea(DisasContext *ctx)
1.1.1.5   root     4977: {
1.1.1.6   root     4978:     TCGv t0 = tcg_temp_new();
                   4979:     TCGv t1 = tcg_temp_new();
                   4980:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4981:     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
                   4982:     gen_store_spr(SPR_MQ, t0);
                   4983:     tcg_gen_sar_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t1);
                   4984:     tcg_temp_free(t0);
                   4985:     tcg_temp_free(t1);
1.1.1.5   root     4986:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     4987:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4988: }
                   4989: 
                   4990: /* sreq */
1.1.1.7   root     4991: static void gen_sreq(DisasContext *ctx)
1.1.1.5   root     4992: {
1.1.1.6   root     4993:     TCGv t0 = tcg_temp_new();
                   4994:     TCGv t1 = tcg_temp_new();
                   4995:     TCGv t2 = tcg_temp_new();
                   4996:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   4997:     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
                   4998:     tcg_gen_shr_tl(t1, t1, t0);
                   4999:     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
                   5000:     gen_load_spr(t2, SPR_MQ);
                   5001:     gen_store_spr(SPR_MQ, t0);
                   5002:     tcg_gen_and_tl(t0, t0, t1);
                   5003:     tcg_gen_andc_tl(t2, t2, t1);
                   5004:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
                   5005:     tcg_temp_free(t0);
                   5006:     tcg_temp_free(t1);
                   5007:     tcg_temp_free(t2);
1.1.1.5   root     5008:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     5009:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5010: }
                   5011: 
                   5012: /* sriq */
1.1.1.7   root     5013: static void gen_sriq(DisasContext *ctx)
1.1.1.5   root     5014: {
1.1.1.6   root     5015:     int sh = SH(ctx->opcode);
                   5016:     TCGv t0 = tcg_temp_new();
                   5017:     TCGv t1 = tcg_temp_new();
                   5018:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   5019:     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
                   5020:     tcg_gen_or_tl(t1, t0, t1);
                   5021:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   5022:     gen_store_spr(SPR_MQ, t1);
                   5023:     tcg_temp_free(t0);
                   5024:     tcg_temp_free(t1);
1.1.1.5   root     5025:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     5026:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5027: }
                   5028: 
                   5029: /* srliq */
1.1.1.7   root     5030: static void gen_srliq(DisasContext *ctx)
1.1.1.5   root     5031: {
1.1.1.6   root     5032:     int sh = SH(ctx->opcode);
                   5033:     TCGv t0 = tcg_temp_new();
                   5034:     TCGv t1 = tcg_temp_new();
                   5035:     tcg_gen_rotri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
                   5036:     gen_load_spr(t1, SPR_MQ);
                   5037:     gen_store_spr(SPR_MQ, t0);
                   5038:     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU >> sh));
                   5039:     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU >> sh));
                   5040:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   5041:     tcg_temp_free(t0);
                   5042:     tcg_temp_free(t1);
1.1.1.5   root     5043:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     5044:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5045: }
                   5046: 
                   5047: /* srlq */
1.1.1.7   root     5048: static void gen_srlq(DisasContext *ctx)
1.1.1.5   root     5049: {
1.1.1.6   root     5050:     int l1 = gen_new_label();
                   5051:     int l2 = gen_new_label();
                   5052:     TCGv t0 = tcg_temp_local_new();
                   5053:     TCGv t1 = tcg_temp_local_new();
                   5054:     TCGv t2 = tcg_temp_local_new();
                   5055:     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   5056:     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
                   5057:     tcg_gen_shr_tl(t2, t1, t2);
                   5058:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
                   5059:     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
                   5060:     gen_load_spr(t0, SPR_MQ);
                   5061:     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
                   5062:     tcg_gen_br(l2);
                   5063:     gen_set_label(l1);
                   5064:     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
                   5065:     tcg_gen_and_tl(t0, t0, t2);
                   5066:     gen_load_spr(t1, SPR_MQ);
                   5067:     tcg_gen_andc_tl(t1, t1, t2);
                   5068:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
                   5069:     gen_set_label(l2);
                   5070:     tcg_temp_free(t0);
                   5071:     tcg_temp_free(t1);
                   5072:     tcg_temp_free(t2);
1.1.1.5   root     5073:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     5074:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5075: }
                   5076: 
                   5077: /* srq */
1.1.1.7   root     5078: static void gen_srq(DisasContext *ctx)
1.1.1.5   root     5079: {
1.1.1.6   root     5080:     int l1 = gen_new_label();
                   5081:     TCGv t0 = tcg_temp_new();
                   5082:     TCGv t1 = tcg_temp_new();
                   5083:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
                   5084:     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
                   5085:     tcg_gen_subfi_tl(t1, 32, t1);
                   5086:     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
                   5087:     tcg_gen_or_tl(t1, t0, t1);
                   5088:     gen_store_spr(SPR_MQ, t1);
                   5089:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
                   5090:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
                   5091:     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
                   5092:     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
                   5093:     gen_set_label(l1);
                   5094:     tcg_temp_free(t0);
                   5095:     tcg_temp_free(t1);
1.1.1.5   root     5096:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6   root     5097:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5098: }
                   5099: 
                   5100: /* PowerPC 602 specific instructions */
1.1.1.7   root     5101: 
1.1.1.5   root     5102: /* dsa  */
1.1.1.7   root     5103: static void gen_dsa(DisasContext *ctx)
1.1.1.5   root     5104: {
                   5105:     /* XXX: TODO */
1.1.1.6   root     5106:     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5107: }
                   5108: 
                   5109: /* esa */
1.1.1.7   root     5110: static void gen_esa(DisasContext *ctx)
1.1.1.5   root     5111: {
                   5112:     /* XXX: TODO */
1.1.1.6   root     5113:     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5114: }
                   5115: 
                   5116: /* mfrom */
1.1.1.7   root     5117: static void gen_mfrom(DisasContext *ctx)
1.1.1.5   root     5118: {
                   5119: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5120:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5121: #else
1.1.1.6   root     5122:     if (unlikely(!ctx->mem_idx)) {
                   5123:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5124:         return;
                   5125:     }
1.1.1.6   root     5126:     gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5127: #endif
                   5128: }
                   5129: 
                   5130: /* 602 - 603 - G2 TLB management */
1.1.1.7   root     5131: 
1.1.1.5   root     5132: /* tlbld */
1.1.1.7   root     5133: static void gen_tlbld_6xx(DisasContext *ctx)
1.1.1.5   root     5134: {
                   5135: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5136:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5137: #else
1.1.1.6   root     5138:     if (unlikely(!ctx->mem_idx)) {
                   5139:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5140:         return;
                   5141:     }
1.1.1.6   root     5142:     gen_helper_6xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     5143: #endif
                   5144: }
                   5145: 
                   5146: /* tlbli */
1.1.1.7   root     5147: static void gen_tlbli_6xx(DisasContext *ctx)
1.1.1.5   root     5148: {
                   5149: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5150:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5151: #else
1.1.1.6   root     5152:     if (unlikely(!ctx->mem_idx)) {
                   5153:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5154:         return;
                   5155:     }
1.1.1.6   root     5156:     gen_helper_6xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     5157: #endif
                   5158: }
                   5159: 
                   5160: /* 74xx TLB management */
1.1.1.7   root     5161: 
1.1.1.5   root     5162: /* tlbld */
1.1.1.7   root     5163: static void gen_tlbld_74xx(DisasContext *ctx)
1.1.1.5   root     5164: {
                   5165: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5166:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5167: #else
1.1.1.6   root     5168:     if (unlikely(!ctx->mem_idx)) {
                   5169:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5170:         return;
                   5171:     }
1.1.1.6   root     5172:     gen_helper_74xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     5173: #endif
                   5174: }
                   5175: 
                   5176: /* tlbli */
1.1.1.7   root     5177: static void gen_tlbli_74xx(DisasContext *ctx)
1.1.1.5   root     5178: {
                   5179: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5180:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5181: #else
1.1.1.6   root     5182:     if (unlikely(!ctx->mem_idx)) {
                   5183:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5184:         return;
                   5185:     }
1.1.1.6   root     5186:     gen_helper_74xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     5187: #endif
                   5188: }
                   5189: 
                   5190: /* POWER instructions not in PowerPC 601 */
1.1.1.7   root     5191: 
1.1.1.5   root     5192: /* clf */
1.1.1.7   root     5193: static void gen_clf(DisasContext *ctx)
1.1.1.5   root     5194: {
                   5195:     /* Cache line flush: implemented as no-op */
                   5196: }
                   5197: 
                   5198: /* cli */
1.1.1.7   root     5199: static void gen_cli(DisasContext *ctx)
1.1.1.5   root     5200: {
                   5201:     /* Cache line invalidate: privileged and treated as no-op */
                   5202: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5203:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5204: #else
1.1.1.6   root     5205:     if (unlikely(!ctx->mem_idx)) {
                   5206:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5207:         return;
                   5208:     }
                   5209: #endif
                   5210: }
                   5211: 
                   5212: /* dclst */
1.1.1.7   root     5213: static void gen_dclst(DisasContext *ctx)
1.1.1.5   root     5214: {
                   5215:     /* Data cache line store: treated as no-op */
                   5216: }
                   5217: 
1.1.1.7   root     5218: static void gen_mfsri(DisasContext *ctx)
1.1.1.5   root     5219: {
                   5220: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5221:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5222: #else
                   5223:     int ra = rA(ctx->opcode);
                   5224:     int rd = rD(ctx->opcode);
1.1.1.6   root     5225:     TCGv t0;
                   5226:     if (unlikely(!ctx->mem_idx)) {
                   5227:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   5228:         return;
                   5229:     }
                   5230:     t0 = tcg_temp_new();
                   5231:     gen_addr_reg_index(ctx, t0);
                   5232:     tcg_gen_shri_tl(t0, t0, 28);
                   5233:     tcg_gen_andi_tl(t0, t0, 0xF);
                   5234:     gen_helper_load_sr(cpu_gpr[rd], t0);
                   5235:     tcg_temp_free(t0);
1.1.1.5   root     5236:     if (ra != 0 && ra != rd)
1.1.1.6   root     5237:         tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
1.1.1.5   root     5238: #endif
                   5239: }
                   5240: 
1.1.1.7   root     5241: static void gen_rac(DisasContext *ctx)
1.1.1.5   root     5242: {
                   5243: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5244:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5245: #else
1.1.1.6   root     5246:     TCGv t0;
                   5247:     if (unlikely(!ctx->mem_idx)) {
                   5248:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5249:         return;
                   5250:     }
1.1.1.6   root     5251:     t0 = tcg_temp_new();
                   5252:     gen_addr_reg_index(ctx, t0);
                   5253:     gen_helper_rac(cpu_gpr[rD(ctx->opcode)], t0);
                   5254:     tcg_temp_free(t0);
1.1.1.5   root     5255: #endif
                   5256: }
                   5257: 
1.1.1.7   root     5258: static void gen_rfsvc(DisasContext *ctx)
1.1.1.5   root     5259: {
                   5260: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5261:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5262: #else
1.1.1.6   root     5263:     if (unlikely(!ctx->mem_idx)) {
                   5264:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5265:         return;
                   5266:     }
1.1.1.6   root     5267:     gen_helper_rfsvc();
                   5268:     gen_sync_exception(ctx);
1.1.1.5   root     5269: #endif
                   5270: }
                   5271: 
                   5272: /* svc is not implemented for now */
                   5273: 
                   5274: /* POWER2 specific instructions */
                   5275: /* Quad manipulation (load/store two floats at a time) */
                   5276: 
                   5277: /* lfq */
1.1.1.7   root     5278: static void gen_lfq(DisasContext *ctx)
1.1.1.5   root     5279: {
1.1.1.6   root     5280:     int rd = rD(ctx->opcode);
                   5281:     TCGv t0;
                   5282:     gen_set_access_type(ctx, ACCESS_FLOAT);
                   5283:     t0 = tcg_temp_new();
                   5284:     gen_addr_imm_index(ctx, t0, 0);
                   5285:     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
                   5286:     gen_addr_add(ctx, t0, t0, 8);
                   5287:     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
                   5288:     tcg_temp_free(t0);
1.1.1.5   root     5289: }
                   5290: 
                   5291: /* lfqu */
1.1.1.7   root     5292: static void gen_lfqu(DisasContext *ctx)
1.1.1.5   root     5293: {
                   5294:     int ra = rA(ctx->opcode);
1.1.1.6   root     5295:     int rd = rD(ctx->opcode);
                   5296:     TCGv t0, t1;
                   5297:     gen_set_access_type(ctx, ACCESS_FLOAT);
                   5298:     t0 = tcg_temp_new();
                   5299:     t1 = tcg_temp_new();
                   5300:     gen_addr_imm_index(ctx, t0, 0);
                   5301:     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
                   5302:     gen_addr_add(ctx, t1, t0, 8);
                   5303:     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
1.1.1.5   root     5304:     if (ra != 0)
1.1.1.6   root     5305:         tcg_gen_mov_tl(cpu_gpr[ra], t0);
                   5306:     tcg_temp_free(t0);
                   5307:     tcg_temp_free(t1);
1.1.1.5   root     5308: }
                   5309: 
                   5310: /* lfqux */
1.1.1.7   root     5311: static void gen_lfqux(DisasContext *ctx)
1.1.1.5   root     5312: {
                   5313:     int ra = rA(ctx->opcode);
1.1.1.6   root     5314:     int rd = rD(ctx->opcode);
                   5315:     gen_set_access_type(ctx, ACCESS_FLOAT);
                   5316:     TCGv t0, t1;
                   5317:     t0 = tcg_temp_new();
                   5318:     gen_addr_reg_index(ctx, t0);
                   5319:     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
                   5320:     t1 = tcg_temp_new();
                   5321:     gen_addr_add(ctx, t1, t0, 8);
                   5322:     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
                   5323:     tcg_temp_free(t1);
1.1.1.5   root     5324:     if (ra != 0)
1.1.1.6   root     5325:         tcg_gen_mov_tl(cpu_gpr[ra], t0);
                   5326:     tcg_temp_free(t0);
1.1.1.5   root     5327: }
                   5328: 
                   5329: /* lfqx */
1.1.1.7   root     5330: static void gen_lfqx(DisasContext *ctx)
1.1.1.5   root     5331: {
1.1.1.6   root     5332:     int rd = rD(ctx->opcode);
                   5333:     TCGv t0;
                   5334:     gen_set_access_type(ctx, ACCESS_FLOAT);
                   5335:     t0 = tcg_temp_new();
                   5336:     gen_addr_reg_index(ctx, t0);
                   5337:     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
                   5338:     gen_addr_add(ctx, t0, t0, 8);
                   5339:     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
                   5340:     tcg_temp_free(t0);
1.1.1.5   root     5341: }
                   5342: 
                   5343: /* stfq */
1.1.1.7   root     5344: static void gen_stfq(DisasContext *ctx)
1.1.1.5   root     5345: {
1.1.1.6   root     5346:     int rd = rD(ctx->opcode);
                   5347:     TCGv t0;
                   5348:     gen_set_access_type(ctx, ACCESS_FLOAT);
                   5349:     t0 = tcg_temp_new();
                   5350:     gen_addr_imm_index(ctx, t0, 0);
                   5351:     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
                   5352:     gen_addr_add(ctx, t0, t0, 8);
                   5353:     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
                   5354:     tcg_temp_free(t0);
1.1.1.5   root     5355: }
                   5356: 
                   5357: /* stfqu */
1.1.1.7   root     5358: static void gen_stfqu(DisasContext *ctx)
1.1.1.5   root     5359: {
                   5360:     int ra = rA(ctx->opcode);
1.1.1.6   root     5361:     int rd = rD(ctx->opcode);
                   5362:     TCGv t0, t1;
                   5363:     gen_set_access_type(ctx, ACCESS_FLOAT);
                   5364:     t0 = tcg_temp_new();
                   5365:     gen_addr_imm_index(ctx, t0, 0);
                   5366:     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
                   5367:     t1 = tcg_temp_new();
                   5368:     gen_addr_add(ctx, t1, t0, 8);
                   5369:     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
                   5370:     tcg_temp_free(t1);
1.1.1.5   root     5371:     if (ra != 0)
1.1.1.6   root     5372:         tcg_gen_mov_tl(cpu_gpr[ra], t0);
                   5373:     tcg_temp_free(t0);
1.1.1.5   root     5374: }
                   5375: 
                   5376: /* stfqux */
1.1.1.7   root     5377: static void gen_stfqux(DisasContext *ctx)
1.1.1.5   root     5378: {
                   5379:     int ra = rA(ctx->opcode);
1.1.1.6   root     5380:     int rd = rD(ctx->opcode);
                   5381:     TCGv t0, t1;
                   5382:     gen_set_access_type(ctx, ACCESS_FLOAT);
                   5383:     t0 = tcg_temp_new();
                   5384:     gen_addr_reg_index(ctx, t0);
                   5385:     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
                   5386:     t1 = tcg_temp_new();
                   5387:     gen_addr_add(ctx, t1, t0, 8);
                   5388:     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
                   5389:     tcg_temp_free(t1);
1.1.1.5   root     5390:     if (ra != 0)
1.1.1.6   root     5391:         tcg_gen_mov_tl(cpu_gpr[ra], t0);
                   5392:     tcg_temp_free(t0);
1.1.1.5   root     5393: }
                   5394: 
                   5395: /* stfqx */
1.1.1.7   root     5396: static void gen_stfqx(DisasContext *ctx)
1.1.1.5   root     5397: {
1.1.1.6   root     5398:     int rd = rD(ctx->opcode);
                   5399:     TCGv t0;
                   5400:     gen_set_access_type(ctx, ACCESS_FLOAT);
                   5401:     t0 = tcg_temp_new();
                   5402:     gen_addr_reg_index(ctx, t0);
                   5403:     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
                   5404:     gen_addr_add(ctx, t0, t0, 8);
                   5405:     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
                   5406:     tcg_temp_free(t0);
1.1.1.5   root     5407: }
                   5408: 
                   5409: /* BookE specific instructions */
1.1.1.7   root     5410: 
1.1.1.5   root     5411: /* XXX: not implemented on 440 ? */
1.1.1.7   root     5412: static void gen_mfapidi(DisasContext *ctx)
1.1.1.5   root     5413: {
                   5414:     /* XXX: TODO */
1.1.1.6   root     5415:     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5416: }
                   5417: 
                   5418: /* XXX: not implemented on 440 ? */
1.1.1.7   root     5419: static void gen_tlbiva(DisasContext *ctx)
1.1.1.5   root     5420: {
                   5421: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5422:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5423: #else
1.1.1.6   root     5424:     TCGv t0;
                   5425:     if (unlikely(!ctx->mem_idx)) {
                   5426:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5427:         return;
                   5428:     }
1.1.1.6   root     5429:     t0 = tcg_temp_new();
                   5430:     gen_addr_reg_index(ctx, t0);
                   5431:     gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
                   5432:     tcg_temp_free(t0);
1.1.1.5   root     5433: #endif
                   5434: }
                   5435: 
                   5436: /* All 405 MAC instructions are translated here */
1.1.1.8   root     5437: static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
                   5438:                                         int ra, int rb, int rt, int Rc)
1.1.1.5   root     5439: {
1.1.1.6   root     5440:     TCGv t0, t1;
                   5441: 
                   5442:     t0 = tcg_temp_local_new();
                   5443:     t1 = tcg_temp_local_new();
                   5444: 
1.1.1.5   root     5445:     switch (opc3 & 0x0D) {
                   5446:     case 0x05:
                   5447:         /* macchw    - macchw.    - macchwo   - macchwo.   */
                   5448:         /* macchws   - macchws.   - macchwso  - macchwso.  */
                   5449:         /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
                   5450:         /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
                   5451:         /* mulchw - mulchw. */
1.1.1.6   root     5452:         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
                   5453:         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
                   5454:         tcg_gen_ext16s_tl(t1, t1);
1.1.1.5   root     5455:         break;
                   5456:     case 0x04:
                   5457:         /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
                   5458:         /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
                   5459:         /* mulchwu - mulchwu. */
1.1.1.6   root     5460:         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
                   5461:         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
                   5462:         tcg_gen_ext16u_tl(t1, t1);
1.1.1.5   root     5463:         break;
                   5464:     case 0x01:
                   5465:         /* machhw    - machhw.    - machhwo   - machhwo.   */
                   5466:         /* machhws   - machhws.   - machhwso  - machhwso.  */
                   5467:         /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
                   5468:         /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
                   5469:         /* mulhhw - mulhhw. */
1.1.1.6   root     5470:         tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
                   5471:         tcg_gen_ext16s_tl(t0, t0);
                   5472:         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
                   5473:         tcg_gen_ext16s_tl(t1, t1);
1.1.1.5   root     5474:         break;
                   5475:     case 0x00:
                   5476:         /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
                   5477:         /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
                   5478:         /* mulhhwu - mulhhwu. */
1.1.1.6   root     5479:         tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
                   5480:         tcg_gen_ext16u_tl(t0, t0);
                   5481:         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
                   5482:         tcg_gen_ext16u_tl(t1, t1);
1.1.1.5   root     5483:         break;
                   5484:     case 0x0D:
                   5485:         /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
                   5486:         /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
                   5487:         /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
                   5488:         /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
                   5489:         /* mullhw - mullhw. */
1.1.1.6   root     5490:         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
                   5491:         tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
1.1.1.5   root     5492:         break;
                   5493:     case 0x0C:
                   5494:         /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
                   5495:         /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
                   5496:         /* mullhwu - mullhwu. */
1.1.1.6   root     5497:         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
                   5498:         tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
1.1.1.5   root     5499:         break;
                   5500:     }
                   5501:     if (opc2 & 0x04) {
1.1.1.6   root     5502:         /* (n)multiply-and-accumulate (0x0C / 0x0E) */
                   5503:         tcg_gen_mul_tl(t1, t0, t1);
                   5504:         if (opc2 & 0x02) {
                   5505:             /* nmultiply-and-accumulate (0x0E) */
                   5506:             tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
                   5507:         } else {
                   5508:             /* multiply-and-accumulate (0x0C) */
                   5509:             tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
                   5510:         }
                   5511: 
                   5512:         if (opc3 & 0x12) {
                   5513:             /* Check overflow and/or saturate */
                   5514:             int l1 = gen_new_label();
                   5515: 
                   5516:             if (opc3 & 0x10) {
                   5517:                 /* Start with XER OV disabled, the most likely case */
                   5518:                 tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
                   5519:             }
                   5520:             if (opc3 & 0x01) {
                   5521:                 /* Signed */
                   5522:                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
                   5523:                 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   5524:                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
                   5525:                 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
                   5526:                 if (opc3 & 0x02) {
                   5527:                     /* Saturate */
                   5528:                     tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
                   5529:                     tcg_gen_xori_tl(t0, t0, 0x7fffffff);
                   5530:                 }
                   5531:             } else {
                   5532:                 /* Unsigned */
                   5533:                 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
                   5534:                 if (opc3 & 0x02) {
                   5535:                     /* Saturate */
                   5536:                     tcg_gen_movi_tl(t0, UINT32_MAX);
                   5537:                 }
                   5538:             }
                   5539:             if (opc3 & 0x10) {
                   5540:                 /* Check overflow */
                   5541:                 tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
                   5542:             }
                   5543:             gen_set_label(l1);
                   5544:             tcg_gen_mov_tl(cpu_gpr[rt], t0);
                   5545:         }
                   5546:     } else {
                   5547:         tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
1.1.1.5   root     5548:     }
1.1.1.6   root     5549:     tcg_temp_free(t0);
                   5550:     tcg_temp_free(t1);
1.1.1.5   root     5551:     if (unlikely(Rc) != 0) {
                   5552:         /* Update Rc0 */
1.1.1.6   root     5553:         gen_set_Rc0(ctx, cpu_gpr[rt]);
1.1.1.5   root     5554:     }
                   5555: }
                   5556: 
                   5557: #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
1.1.1.7   root     5558: static void glue(gen_, name)(DisasContext *ctx)                               \
1.1.1.5   root     5559: {                                                                             \
                   5560:     gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
                   5561:                          rD(ctx->opcode), Rc(ctx->opcode));                   \
                   5562: }
                   5563: 
                   5564: /* macchw    - macchw.    */
                   5565: GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
                   5566: /* macchwo   - macchwo.   */
                   5567: GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
                   5568: /* macchws   - macchws.   */
                   5569: GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
                   5570: /* macchwso  - macchwso.  */
                   5571: GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
                   5572: /* macchwsu  - macchwsu.  */
                   5573: GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
                   5574: /* macchwsuo - macchwsuo. */
                   5575: GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
                   5576: /* macchwu   - macchwu.   */
                   5577: GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
                   5578: /* macchwuo  - macchwuo.  */
                   5579: GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
                   5580: /* machhw    - machhw.    */
                   5581: GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
                   5582: /* machhwo   - machhwo.   */
                   5583: GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
                   5584: /* machhws   - machhws.   */
                   5585: GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
                   5586: /* machhwso  - machhwso.  */
                   5587: GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
                   5588: /* machhwsu  - machhwsu.  */
                   5589: GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
                   5590: /* machhwsuo - machhwsuo. */
                   5591: GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
                   5592: /* machhwu   - machhwu.   */
                   5593: GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
                   5594: /* machhwuo  - machhwuo.  */
                   5595: GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
                   5596: /* maclhw    - maclhw.    */
                   5597: GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
                   5598: /* maclhwo   - maclhwo.   */
                   5599: GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
                   5600: /* maclhws   - maclhws.   */
                   5601: GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
                   5602: /* maclhwso  - maclhwso.  */
                   5603: GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
                   5604: /* maclhwu   - maclhwu.   */
                   5605: GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
                   5606: /* maclhwuo  - maclhwuo.  */
                   5607: GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
                   5608: /* maclhwsu  - maclhwsu.  */
                   5609: GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
                   5610: /* maclhwsuo - maclhwsuo. */
                   5611: GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
                   5612: /* nmacchw   - nmacchw.   */
                   5613: GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
                   5614: /* nmacchwo  - nmacchwo.  */
                   5615: GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
                   5616: /* nmacchws  - nmacchws.  */
                   5617: GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
                   5618: /* nmacchwso - nmacchwso. */
                   5619: GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
                   5620: /* nmachhw   - nmachhw.   */
                   5621: GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
                   5622: /* nmachhwo  - nmachhwo.  */
                   5623: GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
                   5624: /* nmachhws  - nmachhws.  */
                   5625: GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
                   5626: /* nmachhwso - nmachhwso. */
                   5627: GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
                   5628: /* nmaclhw   - nmaclhw.   */
                   5629: GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
                   5630: /* nmaclhwo  - nmaclhwo.  */
                   5631: GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
                   5632: /* nmaclhws  - nmaclhws.  */
                   5633: GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
                   5634: /* nmaclhwso - nmaclhwso. */
                   5635: GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
                   5636: 
                   5637: /* mulchw  - mulchw.  */
                   5638: GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
                   5639: /* mulchwu - mulchwu. */
                   5640: GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
                   5641: /* mulhhw  - mulhhw.  */
                   5642: GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
                   5643: /* mulhhwu - mulhhwu. */
                   5644: GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
                   5645: /* mullhw  - mullhw.  */
                   5646: GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
                   5647: /* mullhwu - mullhwu. */
                   5648: GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
                   5649: 
                   5650: /* mfdcr */
1.1.1.7   root     5651: static void gen_mfdcr(DisasContext *ctx)
1.1.1.5   root     5652: {
                   5653: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5654:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5655: #else
1.1.1.6   root     5656:     TCGv dcrn;
                   5657:     if (unlikely(!ctx->mem_idx)) {
                   5658:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5659:         return;
                   5660:     }
1.1.1.6   root     5661:     /* NIP cannot be restored if the memory exception comes from an helper */
                   5662:     gen_update_nip(ctx, ctx->nip - 4);
                   5663:     dcrn = tcg_const_tl(SPR(ctx->opcode));
                   5664:     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], dcrn);
                   5665:     tcg_temp_free(dcrn);
1.1.1.5   root     5666: #endif
                   5667: }
                   5668: 
                   5669: /* mtdcr */
1.1.1.7   root     5670: static void gen_mtdcr(DisasContext *ctx)
1.1.1.5   root     5671: {
                   5672: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5673:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5674: #else
1.1.1.6   root     5675:     TCGv dcrn;
                   5676:     if (unlikely(!ctx->mem_idx)) {
                   5677:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5678:         return;
                   5679:     }
1.1.1.6   root     5680:     /* NIP cannot be restored if the memory exception comes from an helper */
                   5681:     gen_update_nip(ctx, ctx->nip - 4);
                   5682:     dcrn = tcg_const_tl(SPR(ctx->opcode));
                   5683:     gen_helper_store_dcr(dcrn, cpu_gpr[rS(ctx->opcode)]);
                   5684:     tcg_temp_free(dcrn);
1.1.1.5   root     5685: #endif
                   5686: }
                   5687: 
                   5688: /* mfdcrx */
                   5689: /* XXX: not implemented on 440 ? */
1.1.1.7   root     5690: static void gen_mfdcrx(DisasContext *ctx)
1.1.1.5   root     5691: {
                   5692: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5693:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5694: #else
1.1.1.6   root     5695:     if (unlikely(!ctx->mem_idx)) {
                   5696:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5697:         return;
                   5698:     }
1.1.1.6   root     5699:     /* NIP cannot be restored if the memory exception comes from an helper */
                   5700:     gen_update_nip(ctx, ctx->nip - 4);
                   5701:     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5702:     /* Note: Rc update flag set leads to undefined state of Rc0 */
                   5703: #endif
                   5704: }
                   5705: 
                   5706: /* mtdcrx */
                   5707: /* XXX: not implemented on 440 ? */
1.1.1.7   root     5708: static void gen_mtdcrx(DisasContext *ctx)
1.1.1.5   root     5709: {
                   5710: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5711:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5712: #else
1.1.1.6   root     5713:     if (unlikely(!ctx->mem_idx)) {
                   5714:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5715:         return;
                   5716:     }
1.1.1.6   root     5717:     /* NIP cannot be restored if the memory exception comes from an helper */
                   5718:     gen_update_nip(ctx, ctx->nip - 4);
                   5719:     gen_helper_store_dcr(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     5720:     /* Note: Rc update flag set leads to undefined state of Rc0 */
                   5721: #endif
                   5722: }
                   5723: 
                   5724: /* mfdcrux (PPC 460) : user-mode access to DCR */
1.1.1.7   root     5725: static void gen_mfdcrux(DisasContext *ctx)
1.1.1.5   root     5726: {
1.1.1.6   root     5727:     /* NIP cannot be restored if the memory exception comes from an helper */
                   5728:     gen_update_nip(ctx, ctx->nip - 4);
                   5729:     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5730:     /* Note: Rc update flag set leads to undefined state of Rc0 */
                   5731: }
                   5732: 
                   5733: /* mtdcrux (PPC 460) : user-mode access to DCR */
1.1.1.7   root     5734: static void gen_mtdcrux(DisasContext *ctx)
1.1.1.5   root     5735: {
1.1.1.6   root     5736:     /* NIP cannot be restored if the memory exception comes from an helper */
                   5737:     gen_update_nip(ctx, ctx->nip - 4);
                   5738:     gen_helper_store_dcr(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     5739:     /* Note: Rc update flag set leads to undefined state of Rc0 */
                   5740: }
                   5741: 
                   5742: /* dccci */
1.1.1.7   root     5743: static void gen_dccci(DisasContext *ctx)
1.1.1.5   root     5744: {
                   5745: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5746:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5747: #else
1.1.1.6   root     5748:     if (unlikely(!ctx->mem_idx)) {
                   5749:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5750:         return;
                   5751:     }
                   5752:     /* interpreted as no-op */
                   5753: #endif
                   5754: }
                   5755: 
                   5756: /* dcread */
1.1.1.7   root     5757: static void gen_dcread(DisasContext *ctx)
1.1.1.5   root     5758: {
                   5759: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5760:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5761: #else
1.1.1.6   root     5762:     TCGv EA, val;
                   5763:     if (unlikely(!ctx->mem_idx)) {
                   5764:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5765:         return;
                   5766:     }
1.1.1.6   root     5767:     gen_set_access_type(ctx, ACCESS_CACHE);
                   5768:     EA = tcg_temp_new();
                   5769:     gen_addr_reg_index(ctx, EA);
                   5770:     val = tcg_temp_new();
                   5771:     gen_qemu_ld32u(ctx, val, EA);
                   5772:     tcg_temp_free(val);
                   5773:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
                   5774:     tcg_temp_free(EA);
1.1.1.5   root     5775: #endif
                   5776: }
                   5777: 
                   5778: /* icbt */
1.1.1.7   root     5779: static void gen_icbt_40x(DisasContext *ctx)
1.1.1.5   root     5780: {
                   5781:     /* interpreted as no-op */
                   5782:     /* XXX: specification say this is treated as a load by the MMU
                   5783:      *      but does not generate any exception
                   5784:      */
                   5785: }
                   5786: 
                   5787: /* iccci */
1.1.1.7   root     5788: static void gen_iccci(DisasContext *ctx)
1.1.1.5   root     5789: {
                   5790: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5791:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5792: #else
1.1.1.6   root     5793:     if (unlikely(!ctx->mem_idx)) {
                   5794:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5795:         return;
                   5796:     }
                   5797:     /* interpreted as no-op */
                   5798: #endif
                   5799: }
                   5800: 
                   5801: /* icread */
1.1.1.7   root     5802: static void gen_icread(DisasContext *ctx)
1.1.1.5   root     5803: {
                   5804: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5805:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5806: #else
1.1.1.6   root     5807:     if (unlikely(!ctx->mem_idx)) {
                   5808:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5809:         return;
                   5810:     }
                   5811:     /* interpreted as no-op */
                   5812: #endif
                   5813: }
                   5814: 
1.1.1.6   root     5815: /* rfci (mem_idx only) */
1.1.1.7   root     5816: static void gen_rfci_40x(DisasContext *ctx)
1.1.1.5   root     5817: {
                   5818: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5819:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5820: #else
1.1.1.6   root     5821:     if (unlikely(!ctx->mem_idx)) {
                   5822:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5823:         return;
                   5824:     }
                   5825:     /* Restore CPU state */
1.1.1.6   root     5826:     gen_helper_40x_rfci();
                   5827:     gen_sync_exception(ctx);
1.1.1.5   root     5828: #endif
                   5829: }
                   5830: 
1.1.1.7   root     5831: static void gen_rfci(DisasContext *ctx)
1.1.1.5   root     5832: {
                   5833: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5834:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5835: #else
1.1.1.6   root     5836:     if (unlikely(!ctx->mem_idx)) {
                   5837:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5838:         return;
                   5839:     }
                   5840:     /* Restore CPU state */
1.1.1.6   root     5841:     gen_helper_rfci();
                   5842:     gen_sync_exception(ctx);
1.1.1.5   root     5843: #endif
                   5844: }
                   5845: 
                   5846: /* BookE specific */
1.1.1.7   root     5847: 
1.1.1.5   root     5848: /* XXX: not implemented on 440 ? */
1.1.1.7   root     5849: static void gen_rfdi(DisasContext *ctx)
1.1.1.5   root     5850: {
                   5851: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5852:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5853: #else
1.1.1.6   root     5854:     if (unlikely(!ctx->mem_idx)) {
                   5855:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5856:         return;
                   5857:     }
                   5858:     /* Restore CPU state */
1.1.1.6   root     5859:     gen_helper_rfdi();
                   5860:     gen_sync_exception(ctx);
1.1.1.5   root     5861: #endif
                   5862: }
                   5863: 
                   5864: /* XXX: not implemented on 440 ? */
1.1.1.7   root     5865: static void gen_rfmci(DisasContext *ctx)
1.1.1.5   root     5866: {
                   5867: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5868:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5869: #else
1.1.1.6   root     5870:     if (unlikely(!ctx->mem_idx)) {
                   5871:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5872:         return;
                   5873:     }
                   5874:     /* Restore CPU state */
1.1.1.6   root     5875:     gen_helper_rfmci();
                   5876:     gen_sync_exception(ctx);
1.1.1.5   root     5877: #endif
                   5878: }
                   5879: 
                   5880: /* TLB management - PowerPC 405 implementation */
1.1.1.7   root     5881: 
1.1.1.5   root     5882: /* tlbre */
1.1.1.7   root     5883: static void gen_tlbre_40x(DisasContext *ctx)
1.1.1.5   root     5884: {
                   5885: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5886:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5887: #else
1.1.1.6   root     5888:     if (unlikely(!ctx->mem_idx)) {
                   5889:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5890:         return;
                   5891:     }
                   5892:     switch (rB(ctx->opcode)) {
                   5893:     case 0:
1.1.1.6   root     5894:         gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5895:         break;
                   5896:     case 1:
1.1.1.6   root     5897:         gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5898:         break;
                   5899:     default:
1.1.1.6   root     5900:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5901:         break;
                   5902:     }
                   5903: #endif
                   5904: }
                   5905: 
                   5906: /* tlbsx - tlbsx. */
1.1.1.7   root     5907: static void gen_tlbsx_40x(DisasContext *ctx)
1.1.1.5   root     5908: {
                   5909: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5910:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5911: #else
1.1.1.6   root     5912:     TCGv t0;
                   5913:     if (unlikely(!ctx->mem_idx)) {
                   5914:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5915:         return;
                   5916:     }
1.1.1.6   root     5917:     t0 = tcg_temp_new();
                   5918:     gen_addr_reg_index(ctx, t0);
                   5919:     gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
                   5920:     tcg_temp_free(t0);
                   5921:     if (Rc(ctx->opcode)) {
                   5922:         int l1 = gen_new_label();
                   5923:         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
                   5924:         tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
                   5925:         tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
                   5926:         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
                   5927:         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
                   5928:         gen_set_label(l1);
                   5929:     }
1.1.1.5   root     5930: #endif
                   5931: }
                   5932: 
                   5933: /* tlbwe */
1.1.1.7   root     5934: static void gen_tlbwe_40x(DisasContext *ctx)
1.1.1.5   root     5935: {
                   5936: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5937:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5938: #else
1.1.1.6   root     5939:     if (unlikely(!ctx->mem_idx)) {
                   5940:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5941:         return;
                   5942:     }
                   5943:     switch (rB(ctx->opcode)) {
                   5944:     case 0:
1.1.1.6   root     5945:         gen_helper_4xx_tlbwe_hi(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     5946:         break;
                   5947:     case 1:
1.1.1.6   root     5948:         gen_helper_4xx_tlbwe_lo(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     5949:         break;
                   5950:     default:
1.1.1.6   root     5951:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5952:         break;
                   5953:     }
                   5954: #endif
                   5955: }
                   5956: 
                   5957: /* TLB management - PowerPC 440 implementation */
1.1.1.7   root     5958: 
1.1.1.5   root     5959: /* tlbre */
1.1.1.7   root     5960: static void gen_tlbre_440(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:
                   5971:     case 1:
                   5972:     case 2:
1.1.1.6   root     5973:         {
                   5974:             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
1.1.1.10  root     5975:             gen_helper_440_tlbre(cpu_gpr[rD(ctx->opcode)], t0, cpu_gpr[rA(ctx->opcode)]);
1.1.1.6   root     5976:             tcg_temp_free_i32(t0);
                   5977:         }
1.1.1.5   root     5978:         break;
                   5979:     default:
1.1.1.6   root     5980:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5981:         break;
                   5982:     }
                   5983: #endif
                   5984: }
                   5985: 
                   5986: /* tlbsx - tlbsx. */
1.1.1.7   root     5987: static void gen_tlbsx_440(DisasContext *ctx)
1.1       root     5988: {
                   5989: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     5990:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     5991: #else
1.1.1.6   root     5992:     TCGv t0;
                   5993:     if (unlikely(!ctx->mem_idx)) {
                   5994:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     5995:         return;
                   5996:     }
1.1.1.6   root     5997:     t0 = tcg_temp_new();
                   5998:     gen_addr_reg_index(ctx, t0);
                   5999:     gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
                   6000:     tcg_temp_free(t0);
                   6001:     if (Rc(ctx->opcode)) {
                   6002:         int l1 = gen_new_label();
                   6003:         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
                   6004:         tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
                   6005:         tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
                   6006:         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
                   6007:         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
                   6008:         gen_set_label(l1);
                   6009:     }
1.1       root     6010: #endif
                   6011: }
                   6012: 
1.1.1.5   root     6013: /* tlbwe */
1.1.1.7   root     6014: static void gen_tlbwe_440(DisasContext *ctx)
1.1       root     6015: {
                   6016: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     6017:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     6018: #else
1.1.1.6   root     6019:     if (unlikely(!ctx->mem_idx)) {
                   6020:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     6021:         return;
                   6022:     }
1.1.1.5   root     6023:     switch (rB(ctx->opcode)) {
                   6024:     case 0:
                   6025:     case 1:
                   6026:     case 2:
1.1.1.6   root     6027:         {
                   6028:             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
                   6029:             gen_helper_440_tlbwe(t0, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
                   6030:             tcg_temp_free_i32(t0);
                   6031:         }
1.1.1.5   root     6032:         break;
                   6033:     default:
1.1.1.6   root     6034:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     6035:         break;
                   6036:     }
                   6037: #endif
                   6038: }
                   6039: 
1.1.1.11  root     6040: /* TLB management - PowerPC BookE 2.06 implementation */
                   6041: 
                   6042: /* tlbre */
                   6043: static void gen_tlbre_booke206(DisasContext *ctx)
                   6044: {
                   6045: #if defined(CONFIG_USER_ONLY)
                   6046:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   6047: #else
                   6048:     if (unlikely(!ctx->mem_idx)) {
                   6049:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   6050:         return;
                   6051:     }
                   6052: 
                   6053:     gen_helper_booke206_tlbre();
                   6054: #endif
                   6055: }
                   6056: 
                   6057: /* tlbsx - tlbsx. */
                   6058: static void gen_tlbsx_booke206(DisasContext *ctx)
                   6059: {
                   6060: #if defined(CONFIG_USER_ONLY)
                   6061:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   6062: #else
                   6063:     TCGv t0;
                   6064:     if (unlikely(!ctx->mem_idx)) {
                   6065:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   6066:         return;
                   6067:     }
                   6068: 
                   6069:     if (rA(ctx->opcode)) {
                   6070:         t0 = tcg_temp_new();
                   6071:         tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]);
                   6072:     } else {
                   6073:         t0 = tcg_const_tl(0);
                   6074:     }
                   6075: 
                   6076:     tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]);
                   6077:     gen_helper_booke206_tlbsx(t0);
                   6078: #endif
                   6079: }
                   6080: 
                   6081: /* tlbwe */
                   6082: static void gen_tlbwe_booke206(DisasContext *ctx)
                   6083: {
                   6084: #if defined(CONFIG_USER_ONLY)
                   6085:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   6086: #else
                   6087:     if (unlikely(!ctx->mem_idx)) {
                   6088:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   6089:         return;
                   6090:     }
                   6091:     gen_helper_booke206_tlbwe();
                   6092: #endif
                   6093: }
                   6094: 
                   6095: static void gen_tlbivax_booke206(DisasContext *ctx)
                   6096: {
                   6097: #if defined(CONFIG_USER_ONLY)
                   6098:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   6099: #else
                   6100:     TCGv t0;
                   6101:     if (unlikely(!ctx->mem_idx)) {
                   6102:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
                   6103:         return;
                   6104:     }
                   6105: 
                   6106:     t0 = tcg_temp_new();
                   6107:     gen_addr_reg_index(ctx, t0);
                   6108: 
                   6109:     gen_helper_booke206_tlbivax(t0);
                   6110: #endif
                   6111: }
                   6112: 
                   6113: 
1.1.1.5   root     6114: /* wrtee */
1.1.1.7   root     6115: static void gen_wrtee(DisasContext *ctx)
1.1.1.5   root     6116: {
                   6117: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     6118:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     6119: #else
1.1.1.6   root     6120:     TCGv t0;
                   6121:     if (unlikely(!ctx->mem_idx)) {
                   6122:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     6123:         return;
                   6124:     }
1.1.1.6   root     6125:     t0 = tcg_temp_new();
                   6126:     tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
                   6127:     tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
                   6128:     tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
                   6129:     tcg_temp_free(t0);
1.1.1.5   root     6130:     /* Stop translation to have a chance to raise an exception
                   6131:      * if we just set msr_ee to 1
1.1       root     6132:      */
1.1.1.6   root     6133:     gen_stop_exception(ctx);
1.1       root     6134: #endif
                   6135: }
                   6136: 
1.1.1.5   root     6137: /* wrteei */
1.1.1.7   root     6138: static void gen_wrteei(DisasContext *ctx)
1.1.1.5   root     6139: {
1.1       root     6140: #if defined(CONFIG_USER_ONLY)
1.1.1.6   root     6141:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     6142: #else
1.1.1.6   root     6143:     if (unlikely(!ctx->mem_idx)) {
                   6144:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     6145:         return;
                   6146:     }
1.1.1.7   root     6147:     if (ctx->opcode & 0x00008000) {
1.1.1.6   root     6148:         tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
                   6149:         /* Stop translation to have a chance to raise an exception */
                   6150:         gen_stop_exception(ctx);
                   6151:     } else {
                   6152:         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
                   6153:     }
1.1.1.5   root     6154: #endif
                   6155: }
                   6156: 
                   6157: /* PowerPC 440 specific instructions */
1.1.1.7   root     6158: 
1.1.1.5   root     6159: /* dlmzb */
1.1.1.7   root     6160: static void gen_dlmzb(DisasContext *ctx)
1.1.1.5   root     6161: {
1.1.1.6   root     6162:     TCGv_i32 t0 = tcg_const_i32(Rc(ctx->opcode));
                   6163:     gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
                   6164:                      cpu_gpr[rB(ctx->opcode)], t0);
                   6165:     tcg_temp_free_i32(t0);
1.1.1.5   root     6166: }
                   6167: 
                   6168: /* mbar replaces eieio on 440 */
1.1.1.7   root     6169: static void gen_mbar(DisasContext *ctx)
1.1.1.5   root     6170: {
                   6171:     /* interpreted as no-op */
                   6172: }
                   6173: 
                   6174: /* msync replaces sync on 440 */
1.1.1.7   root     6175: static void gen_msync(DisasContext *ctx)
1.1.1.5   root     6176: {
                   6177:     /* interpreted as no-op */
                   6178: }
                   6179: 
                   6180: /* icbt */
1.1.1.7   root     6181: static void gen_icbt_440(DisasContext *ctx)
1.1.1.5   root     6182: {
                   6183:     /* interpreted as no-op */
                   6184:     /* XXX: specification say this is treated as a load by the MMU
                   6185:      *      but does not generate any exception
                   6186:      */
                   6187: }
                   6188: 
                   6189: /***                      Altivec vector extension                         ***/
                   6190: /* Altivec registers moves */
                   6191: 
1.1.1.8   root     6192: static inline TCGv_ptr gen_avr_ptr(int reg)
1.1.1.6   root     6193: {
                   6194:     TCGv_ptr r = tcg_temp_new_ptr();
                   6195:     tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, avr[reg]));
                   6196:     return r;
                   6197: }
1.1.1.5   root     6198: 
                   6199: #define GEN_VR_LDX(name, opc2, opc3)                                          \
1.1.1.7   root     6200: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.5   root     6201: {                                                                             \
1.1.1.6   root     6202:     TCGv EA;                                                                  \
1.1.1.5   root     6203:     if (unlikely(!ctx->altivec_enabled)) {                                    \
1.1.1.6   root     6204:         gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
1.1.1.5   root     6205:         return;                                                               \
                   6206:     }                                                                         \
1.1.1.6   root     6207:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   6208:     EA = tcg_temp_new();                                                      \
                   6209:     gen_addr_reg_index(ctx, EA);                                              \
                   6210:     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
                   6211:     if (ctx->le_mode) {                                                       \
                   6212:         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
                   6213:         tcg_gen_addi_tl(EA, EA, 8);                                           \
                   6214:         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
                   6215:     } else {                                                                  \
                   6216:         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
                   6217:         tcg_gen_addi_tl(EA, EA, 8);                                           \
                   6218:         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
                   6219:     }                                                                         \
                   6220:     tcg_temp_free(EA);                                                        \
1.1.1.5   root     6221: }
                   6222: 
                   6223: #define GEN_VR_STX(name, opc2, opc3)                                          \
1.1.1.7   root     6224: static void gen_st##name(DisasContext *ctx)                                   \
1.1.1.5   root     6225: {                                                                             \
1.1.1.6   root     6226:     TCGv EA;                                                                  \
1.1.1.5   root     6227:     if (unlikely(!ctx->altivec_enabled)) {                                    \
1.1.1.6   root     6228:         gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
1.1.1.5   root     6229:         return;                                                               \
                   6230:     }                                                                         \
1.1.1.6   root     6231:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   6232:     EA = tcg_temp_new();                                                      \
                   6233:     gen_addr_reg_index(ctx, EA);                                              \
                   6234:     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
                   6235:     if (ctx->le_mode) {                                                       \
                   6236:         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
                   6237:         tcg_gen_addi_tl(EA, EA, 8);                                           \
                   6238:         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
                   6239:     } else {                                                                  \
                   6240:         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
                   6241:         tcg_gen_addi_tl(EA, EA, 8);                                           \
                   6242:         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
                   6243:     }                                                                         \
                   6244:     tcg_temp_free(EA);                                                        \
1.1.1.5   root     6245: }
                   6246: 
1.1.1.6   root     6247: #define GEN_VR_LVE(name, opc2, opc3)                                    \
1.1.1.7   root     6248: static void gen_lve##name(DisasContext *ctx)                            \
1.1.1.6   root     6249:     {                                                                   \
                   6250:         TCGv EA;                                                        \
                   6251:         TCGv_ptr rs;                                                    \
                   6252:         if (unlikely(!ctx->altivec_enabled)) {                          \
                   6253:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
                   6254:             return;                                                     \
                   6255:         }                                                               \
                   6256:         gen_set_access_type(ctx, ACCESS_INT);                           \
                   6257:         EA = tcg_temp_new();                                            \
                   6258:         gen_addr_reg_index(ctx, EA);                                    \
                   6259:         rs = gen_avr_ptr(rS(ctx->opcode));                              \
                   6260:         gen_helper_lve##name (rs, EA);                                  \
                   6261:         tcg_temp_free(EA);                                              \
                   6262:         tcg_temp_free_ptr(rs);                                          \
                   6263:     }
                   6264: 
                   6265: #define GEN_VR_STVE(name, opc2, opc3)                                   \
1.1.1.7   root     6266: static void gen_stve##name(DisasContext *ctx)                           \
1.1.1.6   root     6267:     {                                                                   \
                   6268:         TCGv EA;                                                        \
                   6269:         TCGv_ptr rs;                                                    \
                   6270:         if (unlikely(!ctx->altivec_enabled)) {                          \
                   6271:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
                   6272:             return;                                                     \
                   6273:         }                                                               \
                   6274:         gen_set_access_type(ctx, ACCESS_INT);                           \
                   6275:         EA = tcg_temp_new();                                            \
                   6276:         gen_addr_reg_index(ctx, EA);                                    \
                   6277:         rs = gen_avr_ptr(rS(ctx->opcode));                              \
                   6278:         gen_helper_stve##name (rs, EA);                                 \
                   6279:         tcg_temp_free(EA);                                              \
                   6280:         tcg_temp_free_ptr(rs);                                          \
                   6281:     }
                   6282: 
                   6283: GEN_VR_LDX(lvx, 0x07, 0x03);
1.1.1.5   root     6284: /* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
1.1.1.6   root     6285: GEN_VR_LDX(lvxl, 0x07, 0x0B);
1.1.1.5   root     6286: 
1.1.1.6   root     6287: GEN_VR_LVE(bx, 0x07, 0x00);
                   6288: GEN_VR_LVE(hx, 0x07, 0x01);
                   6289: GEN_VR_LVE(wx, 0x07, 0x02);
                   6290: 
                   6291: GEN_VR_STX(svx, 0x07, 0x07);
1.1.1.5   root     6292: /* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
1.1.1.6   root     6293: GEN_VR_STX(svxl, 0x07, 0x0F);
                   6294: 
                   6295: GEN_VR_STVE(bx, 0x07, 0x04);
                   6296: GEN_VR_STVE(hx, 0x07, 0x05);
                   6297: GEN_VR_STVE(wx, 0x07, 0x06);
                   6298: 
1.1.1.7   root     6299: static void gen_lvsl(DisasContext *ctx)
1.1.1.6   root     6300: {
                   6301:     TCGv_ptr rd;
                   6302:     TCGv EA;
                   6303:     if (unlikely(!ctx->altivec_enabled)) {
                   6304:         gen_exception(ctx, POWERPC_EXCP_VPU);
                   6305:         return;
                   6306:     }
                   6307:     EA = tcg_temp_new();
                   6308:     gen_addr_reg_index(ctx, EA);
                   6309:     rd = gen_avr_ptr(rD(ctx->opcode));
                   6310:     gen_helper_lvsl(rd, EA);
                   6311:     tcg_temp_free(EA);
                   6312:     tcg_temp_free_ptr(rd);
                   6313: }
                   6314: 
1.1.1.7   root     6315: static void gen_lvsr(DisasContext *ctx)
1.1.1.6   root     6316: {
                   6317:     TCGv_ptr rd;
                   6318:     TCGv EA;
                   6319:     if (unlikely(!ctx->altivec_enabled)) {
                   6320:         gen_exception(ctx, POWERPC_EXCP_VPU);
                   6321:         return;
                   6322:     }
                   6323:     EA = tcg_temp_new();
                   6324:     gen_addr_reg_index(ctx, EA);
                   6325:     rd = gen_avr_ptr(rD(ctx->opcode));
                   6326:     gen_helper_lvsr(rd, EA);
                   6327:     tcg_temp_free(EA);
                   6328:     tcg_temp_free_ptr(rd);
                   6329: }
                   6330: 
1.1.1.7   root     6331: static void gen_mfvscr(DisasContext *ctx)
1.1.1.6   root     6332: {
                   6333:     TCGv_i32 t;
                   6334:     if (unlikely(!ctx->altivec_enabled)) {
                   6335:         gen_exception(ctx, POWERPC_EXCP_VPU);
                   6336:         return;
                   6337:     }
                   6338:     tcg_gen_movi_i64(cpu_avrh[rD(ctx->opcode)], 0);
                   6339:     t = tcg_temp_new_i32();
                   6340:     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, vscr));
                   6341:     tcg_gen_extu_i32_i64(cpu_avrl[rD(ctx->opcode)], t);
                   6342:     tcg_temp_free_i32(t);
                   6343: }
                   6344: 
1.1.1.7   root     6345: static void gen_mtvscr(DisasContext *ctx)
1.1.1.6   root     6346: {
                   6347:     TCGv_ptr p;
                   6348:     if (unlikely(!ctx->altivec_enabled)) {
                   6349:         gen_exception(ctx, POWERPC_EXCP_VPU);
                   6350:         return;
                   6351:     }
                   6352:     p = gen_avr_ptr(rD(ctx->opcode));
                   6353:     gen_helper_mtvscr(p);
                   6354:     tcg_temp_free_ptr(p);
                   6355: }
                   6356: 
                   6357: /* Logical operations */
                   6358: #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
1.1.1.7   root     6359: static void glue(gen_, name)(DisasContext *ctx)                                 \
1.1.1.6   root     6360: {                                                                       \
                   6361:     if (unlikely(!ctx->altivec_enabled)) {                              \
                   6362:         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
                   6363:         return;                                                         \
                   6364:     }                                                                   \
                   6365:     tcg_op(cpu_avrh[rD(ctx->opcode)], cpu_avrh[rA(ctx->opcode)], cpu_avrh[rB(ctx->opcode)]); \
                   6366:     tcg_op(cpu_avrl[rD(ctx->opcode)], cpu_avrl[rA(ctx->opcode)], cpu_avrl[rB(ctx->opcode)]); \
                   6367: }
                   6368: 
                   6369: GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16);
                   6370: GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17);
                   6371: GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18);
                   6372: GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19);
                   6373: GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20);
                   6374: 
                   6375: #define GEN_VXFORM(name, opc2, opc3)                                    \
1.1.1.7   root     6376: static void glue(gen_, name)(DisasContext *ctx)                                 \
1.1.1.6   root     6377: {                                                                       \
                   6378:     TCGv_ptr ra, rb, rd;                                                \
                   6379:     if (unlikely(!ctx->altivec_enabled)) {                              \
                   6380:         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
                   6381:         return;                                                         \
                   6382:     }                                                                   \
                   6383:     ra = gen_avr_ptr(rA(ctx->opcode));                                  \
                   6384:     rb = gen_avr_ptr(rB(ctx->opcode));                                  \
                   6385:     rd = gen_avr_ptr(rD(ctx->opcode));                                  \
                   6386:     gen_helper_##name (rd, ra, rb);                                     \
                   6387:     tcg_temp_free_ptr(ra);                                              \
                   6388:     tcg_temp_free_ptr(rb);                                              \
                   6389:     tcg_temp_free_ptr(rd);                                              \
                   6390: }
                   6391: 
                   6392: GEN_VXFORM(vaddubm, 0, 0);
                   6393: GEN_VXFORM(vadduhm, 0, 1);
                   6394: GEN_VXFORM(vadduwm, 0, 2);
                   6395: GEN_VXFORM(vsububm, 0, 16);
                   6396: GEN_VXFORM(vsubuhm, 0, 17);
                   6397: GEN_VXFORM(vsubuwm, 0, 18);
                   6398: GEN_VXFORM(vmaxub, 1, 0);
                   6399: GEN_VXFORM(vmaxuh, 1, 1);
                   6400: GEN_VXFORM(vmaxuw, 1, 2);
                   6401: GEN_VXFORM(vmaxsb, 1, 4);
                   6402: GEN_VXFORM(vmaxsh, 1, 5);
                   6403: GEN_VXFORM(vmaxsw, 1, 6);
                   6404: GEN_VXFORM(vminub, 1, 8);
                   6405: GEN_VXFORM(vminuh, 1, 9);
                   6406: GEN_VXFORM(vminuw, 1, 10);
                   6407: GEN_VXFORM(vminsb, 1, 12);
                   6408: GEN_VXFORM(vminsh, 1, 13);
                   6409: GEN_VXFORM(vminsw, 1, 14);
                   6410: GEN_VXFORM(vavgub, 1, 16);
                   6411: GEN_VXFORM(vavguh, 1, 17);
                   6412: GEN_VXFORM(vavguw, 1, 18);
                   6413: GEN_VXFORM(vavgsb, 1, 20);
                   6414: GEN_VXFORM(vavgsh, 1, 21);
                   6415: GEN_VXFORM(vavgsw, 1, 22);
                   6416: GEN_VXFORM(vmrghb, 6, 0);
                   6417: GEN_VXFORM(vmrghh, 6, 1);
                   6418: GEN_VXFORM(vmrghw, 6, 2);
                   6419: GEN_VXFORM(vmrglb, 6, 4);
                   6420: GEN_VXFORM(vmrglh, 6, 5);
                   6421: GEN_VXFORM(vmrglw, 6, 6);
                   6422: GEN_VXFORM(vmuloub, 4, 0);
                   6423: GEN_VXFORM(vmulouh, 4, 1);
                   6424: GEN_VXFORM(vmulosb, 4, 4);
                   6425: GEN_VXFORM(vmulosh, 4, 5);
                   6426: GEN_VXFORM(vmuleub, 4, 8);
                   6427: GEN_VXFORM(vmuleuh, 4, 9);
                   6428: GEN_VXFORM(vmulesb, 4, 12);
                   6429: GEN_VXFORM(vmulesh, 4, 13);
                   6430: GEN_VXFORM(vslb, 2, 4);
                   6431: GEN_VXFORM(vslh, 2, 5);
                   6432: GEN_VXFORM(vslw, 2, 6);
                   6433: GEN_VXFORM(vsrb, 2, 8);
                   6434: GEN_VXFORM(vsrh, 2, 9);
                   6435: GEN_VXFORM(vsrw, 2, 10);
                   6436: GEN_VXFORM(vsrab, 2, 12);
                   6437: GEN_VXFORM(vsrah, 2, 13);
                   6438: GEN_VXFORM(vsraw, 2, 14);
                   6439: GEN_VXFORM(vslo, 6, 16);
                   6440: GEN_VXFORM(vsro, 6, 17);
                   6441: GEN_VXFORM(vaddcuw, 0, 6);
                   6442: GEN_VXFORM(vsubcuw, 0, 22);
                   6443: GEN_VXFORM(vaddubs, 0, 8);
                   6444: GEN_VXFORM(vadduhs, 0, 9);
                   6445: GEN_VXFORM(vadduws, 0, 10);
                   6446: GEN_VXFORM(vaddsbs, 0, 12);
                   6447: GEN_VXFORM(vaddshs, 0, 13);
                   6448: GEN_VXFORM(vaddsws, 0, 14);
                   6449: GEN_VXFORM(vsububs, 0, 24);
                   6450: GEN_VXFORM(vsubuhs, 0, 25);
                   6451: GEN_VXFORM(vsubuws, 0, 26);
                   6452: GEN_VXFORM(vsubsbs, 0, 28);
                   6453: GEN_VXFORM(vsubshs, 0, 29);
                   6454: GEN_VXFORM(vsubsws, 0, 30);
                   6455: GEN_VXFORM(vrlb, 2, 0);
                   6456: GEN_VXFORM(vrlh, 2, 1);
                   6457: GEN_VXFORM(vrlw, 2, 2);
                   6458: GEN_VXFORM(vsl, 2, 7);
                   6459: GEN_VXFORM(vsr, 2, 11);
                   6460: GEN_VXFORM(vpkuhum, 7, 0);
                   6461: GEN_VXFORM(vpkuwum, 7, 1);
                   6462: GEN_VXFORM(vpkuhus, 7, 2);
                   6463: GEN_VXFORM(vpkuwus, 7, 3);
                   6464: GEN_VXFORM(vpkshus, 7, 4);
                   6465: GEN_VXFORM(vpkswus, 7, 5);
                   6466: GEN_VXFORM(vpkshss, 7, 6);
                   6467: GEN_VXFORM(vpkswss, 7, 7);
                   6468: GEN_VXFORM(vpkpx, 7, 12);
                   6469: GEN_VXFORM(vsum4ubs, 4, 24);
                   6470: GEN_VXFORM(vsum4sbs, 4, 28);
                   6471: GEN_VXFORM(vsum4shs, 4, 25);
                   6472: GEN_VXFORM(vsum2sws, 4, 26);
                   6473: GEN_VXFORM(vsumsws, 4, 30);
                   6474: GEN_VXFORM(vaddfp, 5, 0);
                   6475: GEN_VXFORM(vsubfp, 5, 1);
                   6476: GEN_VXFORM(vmaxfp, 5, 16);
                   6477: GEN_VXFORM(vminfp, 5, 17);
                   6478: 
                   6479: #define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
1.1.1.7   root     6480: static void glue(gen_, name)(DisasContext *ctx)                         \
1.1.1.6   root     6481:     {                                                                   \
                   6482:         TCGv_ptr ra, rb, rd;                                            \
                   6483:         if (unlikely(!ctx->altivec_enabled)) {                          \
                   6484:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
                   6485:             return;                                                     \
                   6486:         }                                                               \
                   6487:         ra = gen_avr_ptr(rA(ctx->opcode));                              \
                   6488:         rb = gen_avr_ptr(rB(ctx->opcode));                              \
                   6489:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
                   6490:         gen_helper_##opname (rd, ra, rb);                               \
                   6491:         tcg_temp_free_ptr(ra);                                          \
                   6492:         tcg_temp_free_ptr(rb);                                          \
                   6493:         tcg_temp_free_ptr(rd);                                          \
                   6494:     }
                   6495: 
                   6496: #define GEN_VXRFORM(name, opc2, opc3)                                \
                   6497:     GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
                   6498:     GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
                   6499: 
                   6500: GEN_VXRFORM(vcmpequb, 3, 0)
                   6501: GEN_VXRFORM(vcmpequh, 3, 1)
                   6502: GEN_VXRFORM(vcmpequw, 3, 2)
                   6503: GEN_VXRFORM(vcmpgtsb, 3, 12)
                   6504: GEN_VXRFORM(vcmpgtsh, 3, 13)
                   6505: GEN_VXRFORM(vcmpgtsw, 3, 14)
                   6506: GEN_VXRFORM(vcmpgtub, 3, 8)
                   6507: GEN_VXRFORM(vcmpgtuh, 3, 9)
                   6508: GEN_VXRFORM(vcmpgtuw, 3, 10)
                   6509: GEN_VXRFORM(vcmpeqfp, 3, 3)
                   6510: GEN_VXRFORM(vcmpgefp, 3, 7)
                   6511: GEN_VXRFORM(vcmpgtfp, 3, 11)
                   6512: GEN_VXRFORM(vcmpbfp, 3, 15)
                   6513: 
                   6514: #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
1.1.1.7   root     6515: static void glue(gen_, name)(DisasContext *ctx)                         \
1.1.1.6   root     6516:     {                                                                   \
                   6517:         TCGv_ptr rd;                                                    \
                   6518:         TCGv_i32 simm;                                                  \
                   6519:         if (unlikely(!ctx->altivec_enabled)) {                          \
                   6520:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
                   6521:             return;                                                     \
                   6522:         }                                                               \
                   6523:         simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
                   6524:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
                   6525:         gen_helper_##name (rd, simm);                                   \
                   6526:         tcg_temp_free_i32(simm);                                        \
                   6527:         tcg_temp_free_ptr(rd);                                          \
                   6528:     }
                   6529: 
                   6530: GEN_VXFORM_SIMM(vspltisb, 6, 12);
                   6531: GEN_VXFORM_SIMM(vspltish, 6, 13);
                   6532: GEN_VXFORM_SIMM(vspltisw, 6, 14);
                   6533: 
                   6534: #define GEN_VXFORM_NOA(name, opc2, opc3)                                \
1.1.1.7   root     6535: static void glue(gen_, name)(DisasContext *ctx)                                 \
1.1.1.6   root     6536:     {                                                                   \
                   6537:         TCGv_ptr rb, rd;                                                \
                   6538:         if (unlikely(!ctx->altivec_enabled)) {                          \
                   6539:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
                   6540:             return;                                                     \
                   6541:         }                                                               \
                   6542:         rb = gen_avr_ptr(rB(ctx->opcode));                              \
                   6543:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
                   6544:         gen_helper_##name (rd, rb);                                     \
                   6545:         tcg_temp_free_ptr(rb);                                          \
                   6546:         tcg_temp_free_ptr(rd);                                         \
                   6547:     }
                   6548: 
                   6549: GEN_VXFORM_NOA(vupkhsb, 7, 8);
                   6550: GEN_VXFORM_NOA(vupkhsh, 7, 9);
                   6551: GEN_VXFORM_NOA(vupklsb, 7, 10);
                   6552: GEN_VXFORM_NOA(vupklsh, 7, 11);
                   6553: GEN_VXFORM_NOA(vupkhpx, 7, 13);
                   6554: GEN_VXFORM_NOA(vupklpx, 7, 15);
                   6555: GEN_VXFORM_NOA(vrefp, 5, 4);
                   6556: GEN_VXFORM_NOA(vrsqrtefp, 5, 5);
1.1.1.9   root     6557: GEN_VXFORM_NOA(vexptefp, 5, 6);
1.1.1.6   root     6558: GEN_VXFORM_NOA(vlogefp, 5, 7);
                   6559: GEN_VXFORM_NOA(vrfim, 5, 8);
                   6560: GEN_VXFORM_NOA(vrfin, 5, 9);
                   6561: GEN_VXFORM_NOA(vrfip, 5, 10);
                   6562: GEN_VXFORM_NOA(vrfiz, 5, 11);
                   6563: 
                   6564: #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
1.1.1.7   root     6565: static void glue(gen_, name)(DisasContext *ctx)                                 \
1.1.1.6   root     6566:     {                                                                   \
                   6567:         TCGv_ptr rd;                                                    \
                   6568:         TCGv_i32 simm;                                                  \
                   6569:         if (unlikely(!ctx->altivec_enabled)) {                          \
                   6570:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
                   6571:             return;                                                     \
                   6572:         }                                                               \
                   6573:         simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
                   6574:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
                   6575:         gen_helper_##name (rd, simm);                                   \
                   6576:         tcg_temp_free_i32(simm);                                        \
                   6577:         tcg_temp_free_ptr(rd);                                          \
                   6578:     }
                   6579: 
                   6580: #define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
1.1.1.7   root     6581: static void glue(gen_, name)(DisasContext *ctx)                                 \
1.1.1.6   root     6582:     {                                                                   \
                   6583:         TCGv_ptr rb, rd;                                                \
                   6584:         TCGv_i32 uimm;                                                  \
                   6585:         if (unlikely(!ctx->altivec_enabled)) {                          \
                   6586:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
                   6587:             return;                                                     \
                   6588:         }                                                               \
                   6589:         uimm = tcg_const_i32(UIMM5(ctx->opcode));                       \
                   6590:         rb = gen_avr_ptr(rB(ctx->opcode));                              \
                   6591:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
                   6592:         gen_helper_##name (rd, rb, uimm);                               \
                   6593:         tcg_temp_free_i32(uimm);                                        \
                   6594:         tcg_temp_free_ptr(rb);                                          \
                   6595:         tcg_temp_free_ptr(rd);                                          \
                   6596:     }
                   6597: 
                   6598: GEN_VXFORM_UIMM(vspltb, 6, 8);
                   6599: GEN_VXFORM_UIMM(vsplth, 6, 9);
                   6600: GEN_VXFORM_UIMM(vspltw, 6, 10);
                   6601: GEN_VXFORM_UIMM(vcfux, 5, 12);
                   6602: GEN_VXFORM_UIMM(vcfsx, 5, 13);
                   6603: GEN_VXFORM_UIMM(vctuxs, 5, 14);
                   6604: GEN_VXFORM_UIMM(vctsxs, 5, 15);
                   6605: 
1.1.1.7   root     6606: static void gen_vsldoi(DisasContext *ctx)
1.1.1.6   root     6607: {
                   6608:     TCGv_ptr ra, rb, rd;
                   6609:     TCGv_i32 sh;
                   6610:     if (unlikely(!ctx->altivec_enabled)) {
                   6611:         gen_exception(ctx, POWERPC_EXCP_VPU);
                   6612:         return;
                   6613:     }
                   6614:     ra = gen_avr_ptr(rA(ctx->opcode));
                   6615:     rb = gen_avr_ptr(rB(ctx->opcode));
                   6616:     rd = gen_avr_ptr(rD(ctx->opcode));
                   6617:     sh = tcg_const_i32(VSH(ctx->opcode));
                   6618:     gen_helper_vsldoi (rd, ra, rb, sh);
                   6619:     tcg_temp_free_ptr(ra);
                   6620:     tcg_temp_free_ptr(rb);
                   6621:     tcg_temp_free_ptr(rd);
                   6622:     tcg_temp_free_i32(sh);
                   6623: }
                   6624: 
                   6625: #define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
1.1.1.7   root     6626: static void glue(gen_, name0##_##name1)(DisasContext *ctx)                      \
1.1.1.6   root     6627:     {                                                                   \
                   6628:         TCGv_ptr ra, rb, rc, rd;                                        \
                   6629:         if (unlikely(!ctx->altivec_enabled)) {                          \
                   6630:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
                   6631:             return;                                                     \
                   6632:         }                                                               \
                   6633:         ra = gen_avr_ptr(rA(ctx->opcode));                              \
                   6634:         rb = gen_avr_ptr(rB(ctx->opcode));                              \
                   6635:         rc = gen_avr_ptr(rC(ctx->opcode));                              \
                   6636:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
                   6637:         if (Rc(ctx->opcode)) {                                          \
                   6638:             gen_helper_##name1 (rd, ra, rb, rc);                        \
                   6639:         } else {                                                        \
                   6640:             gen_helper_##name0 (rd, ra, rb, rc);                        \
                   6641:         }                                                               \
                   6642:         tcg_temp_free_ptr(ra);                                          \
                   6643:         tcg_temp_free_ptr(rb);                                          \
                   6644:         tcg_temp_free_ptr(rc);                                          \
                   6645:         tcg_temp_free_ptr(rd);                                          \
                   6646:     }
                   6647: 
                   6648: GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16)
                   6649: 
1.1.1.7   root     6650: static void gen_vmladduhm(DisasContext *ctx)
1.1.1.6   root     6651: {
                   6652:     TCGv_ptr ra, rb, rc, rd;
                   6653:     if (unlikely(!ctx->altivec_enabled)) {
                   6654:         gen_exception(ctx, POWERPC_EXCP_VPU);
                   6655:         return;
                   6656:     }
                   6657:     ra = gen_avr_ptr(rA(ctx->opcode));
                   6658:     rb = gen_avr_ptr(rB(ctx->opcode));
                   6659:     rc = gen_avr_ptr(rC(ctx->opcode));
                   6660:     rd = gen_avr_ptr(rD(ctx->opcode));
                   6661:     gen_helper_vmladduhm(rd, ra, rb, rc);
                   6662:     tcg_temp_free_ptr(ra);
                   6663:     tcg_temp_free_ptr(rb);
                   6664:     tcg_temp_free_ptr(rc);
                   6665:     tcg_temp_free_ptr(rd);
                   6666: }
                   6667: 
                   6668: GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18)
                   6669: GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19)
                   6670: GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20)
                   6671: GEN_VAFORM_PAIRED(vsel, vperm, 21)
                   6672: GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23)
1.1.1.5   root     6673: 
                   6674: /***                           SPE extension                               ***/
                   6675: /* Register moves */
                   6676: 
1.1.1.11  root     6677: 
                   6678: static inline void gen_evmra(DisasContext *ctx)
                   6679: {
                   6680: 
                   6681:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     6682:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.11  root     6683:         return;
                   6684:     }
                   6685: 
                   6686: #if defined(TARGET_PPC64)
                   6687:     /* rD := rA */
                   6688:     tcg_gen_mov_i64(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   6689: 
                   6690:     /* spe_acc := rA */
                   6691:     tcg_gen_st_i64(cpu_gpr[rA(ctx->opcode)],
                   6692:                    cpu_env,
                   6693:                    offsetof(CPUState, spe_acc));
                   6694: #else
                   6695:     TCGv_i64 tmp = tcg_temp_new_i64();
                   6696: 
                   6697:     /* tmp := rA_lo + rA_hi << 32 */
                   6698:     tcg_gen_concat_i32_i64(tmp, cpu_gpr[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
                   6699: 
                   6700:     /* spe_acc := tmp */
                   6701:     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc));
                   6702:     tcg_temp_free_i64(tmp);
                   6703: 
                   6704:     /* rD := rA */
                   6705:     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   6706:     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
                   6707: #endif
                   6708: }
                   6709: 
1.1.1.8   root     6710: static inline void gen_load_gpr64(TCGv_i64 t, int reg)
                   6711: {
1.1.1.6   root     6712: #if defined(TARGET_PPC64)
                   6713:     tcg_gen_mov_i64(t, cpu_gpr[reg]);
                   6714: #else
                   6715:     tcg_gen_concat_i32_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
1.1.1.5   root     6716: #endif
1.1.1.6   root     6717: }
1.1.1.5   root     6718: 
1.1.1.8   root     6719: static inline void gen_store_gpr64(int reg, TCGv_i64 t)
                   6720: {
1.1.1.6   root     6721: #if defined(TARGET_PPC64)
                   6722:     tcg_gen_mov_i64(cpu_gpr[reg], t);
                   6723: #else
                   6724:     TCGv_i64 tmp = tcg_temp_new_i64();
                   6725:     tcg_gen_trunc_i64_i32(cpu_gpr[reg], t);
                   6726:     tcg_gen_shri_i64(tmp, t, 32);
                   6727:     tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp);
                   6728:     tcg_temp_free_i64(tmp);
1.1.1.5   root     6729: #endif
1.1.1.6   root     6730: }
1.1.1.5   root     6731: 
1.1.1.12! root     6732: #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type)         \
1.1.1.7   root     6733: static void glue(gen_, name0##_##name1)(DisasContext *ctx)                    \
1.1.1.5   root     6734: {                                                                             \
                   6735:     if (Rc(ctx->opcode))                                                      \
                   6736:         gen_##name1(ctx);                                                     \
                   6737:     else                                                                      \
                   6738:         gen_##name0(ctx);                                                     \
                   6739: }
                   6740: 
                   6741: /* Handler for undefined SPE opcodes */
1.1.1.8   root     6742: static inline void gen_speundef(DisasContext *ctx)
1.1       root     6743: {
1.1.1.6   root     6744:     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     6745: }
                   6746: 
1.1.1.6   root     6747: /* SPE logic */
                   6748: #if defined(TARGET_PPC64)
                   6749: #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
1.1.1.8   root     6750: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     6751: {                                                                             \
                   6752:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     6753:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     6754:         return;                                                               \
                   6755:     }                                                                         \
                   6756:     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
                   6757:            cpu_gpr[rB(ctx->opcode)]);                                         \
                   6758: }
                   6759: #else
                   6760: #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
1.1.1.8   root     6761: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     6762: {                                                                             \
                   6763:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     6764:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     6765:         return;                                                               \
                   6766:     }                                                                         \
                   6767:     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
                   6768:            cpu_gpr[rB(ctx->opcode)]);                                         \
                   6769:     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
                   6770:            cpu_gprh[rB(ctx->opcode)]);                                        \
1.1.1.5   root     6771: }
1.1.1.6   root     6772: #endif
1.1.1.5   root     6773: 
1.1.1.6   root     6774: GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl);
                   6775: GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl);
                   6776: GEN_SPEOP_LOGIC2(evxor, tcg_gen_xor_tl);
                   6777: GEN_SPEOP_LOGIC2(evor, tcg_gen_or_tl);
                   6778: GEN_SPEOP_LOGIC2(evnor, tcg_gen_nor_tl);
                   6779: GEN_SPEOP_LOGIC2(eveqv, tcg_gen_eqv_tl);
                   6780: GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl);
                   6781: GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
1.1.1.5   root     6782: 
1.1.1.6   root     6783: /* SPE logic immediate */
                   6784: #if defined(TARGET_PPC64)
                   6785: #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
1.1.1.8   root     6786: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     6787: {                                                                             \
                   6788:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     6789:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     6790:         return;                                                               \
                   6791:     }                                                                         \
1.1.1.6   root     6792:     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
                   6793:     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
                   6794:     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
                   6795:     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
                   6796:     tcg_opi(t0, t0, rB(ctx->opcode));                                         \
                   6797:     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
                   6798:     tcg_gen_trunc_i64_i32(t1, t2);                                            \
                   6799:     tcg_temp_free_i64(t2);                                                    \
                   6800:     tcg_opi(t1, t1, rB(ctx->opcode));                                         \
                   6801:     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
                   6802:     tcg_temp_free_i32(t0);                                                    \
                   6803:     tcg_temp_free_i32(t1);                                                    \
1.1.1.5   root     6804: }
1.1.1.6   root     6805: #else
                   6806: #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
1.1.1.8   root     6807: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     6808: {                                                                             \
                   6809:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     6810:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     6811:         return;                                                               \
                   6812:     }                                                                         \
1.1.1.6   root     6813:     tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],               \
                   6814:             rB(ctx->opcode));                                                 \
                   6815:     tcg_opi(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],             \
                   6816:             rB(ctx->opcode));                                                 \
1.1.1.5   root     6817: }
1.1.1.6   root     6818: #endif
                   6819: GEN_SPEOP_TCG_LOGIC_IMM2(evslwi, tcg_gen_shli_i32);
                   6820: GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu, tcg_gen_shri_i32);
                   6821: GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis, tcg_gen_sari_i32);
                   6822: GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32);
1.1.1.5   root     6823: 
1.1.1.6   root     6824: /* SPE arithmetic */
                   6825: #if defined(TARGET_PPC64)
                   6826: #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
1.1.1.8   root     6827: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     6828: {                                                                             \
                   6829:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     6830:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     6831:         return;                                                               \
                   6832:     }                                                                         \
1.1.1.6   root     6833:     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
                   6834:     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
                   6835:     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
                   6836:     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
                   6837:     tcg_op(t0, t0);                                                           \
                   6838:     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
                   6839:     tcg_gen_trunc_i64_i32(t1, t2);                                            \
                   6840:     tcg_temp_free_i64(t2);                                                    \
                   6841:     tcg_op(t1, t1);                                                           \
                   6842:     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
                   6843:     tcg_temp_free_i32(t0);                                                    \
                   6844:     tcg_temp_free_i32(t1);                                                    \
1.1.1.5   root     6845: }
1.1.1.6   root     6846: #else
                   6847: #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
1.1.1.8   root     6848: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     6849: {                                                                             \
                   6850:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     6851:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     6852:         return;                                                               \
                   6853:     }                                                                         \
1.1.1.6   root     6854:     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);               \
                   6855:     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);             \
1.1.1.5   root     6856: }
1.1.1.6   root     6857: #endif
1.1.1.5   root     6858: 
1.1.1.8   root     6859: static inline void gen_op_evabs(TCGv_i32 ret, TCGv_i32 arg1)
1.1.1.6   root     6860: {
                   6861:     int l1 = gen_new_label();
                   6862:     int l2 = gen_new_label();
1.1.1.5   root     6863: 
1.1.1.6   root     6864:     tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
                   6865:     tcg_gen_neg_i32(ret, arg1);
                   6866:     tcg_gen_br(l2);
                   6867:     gen_set_label(l1);
                   6868:     tcg_gen_mov_i32(ret, arg1);
                   6869:     gen_set_label(l2);
                   6870: }
                   6871: GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
                   6872: GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
                   6873: GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
                   6874: GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
1.1.1.8   root     6875: static inline void gen_op_evrndw(TCGv_i32 ret, TCGv_i32 arg1)
1.1.1.6   root     6876: {
                   6877:     tcg_gen_addi_i32(ret, arg1, 0x8000);
                   6878:     tcg_gen_ext16u_i32(ret, ret);
                   6879: }
                   6880: GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw);
                   6881: GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32);
                   6882: GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
1.1.1.5   root     6883: 
1.1.1.6   root     6884: #if defined(TARGET_PPC64)
                   6885: #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
1.1.1.8   root     6886: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     6887: {                                                                             \
                   6888:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     6889:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     6890:         return;                                                               \
                   6891:     }                                                                         \
1.1.1.6   root     6892:     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
                   6893:     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
                   6894:     TCGv_i32 t2 = tcg_temp_local_new_i32();                                   \
                   6895:     TCGv_i64 t3 = tcg_temp_local_new_i64();                                   \
                   6896:     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
                   6897:     tcg_gen_trunc_i64_i32(t2, cpu_gpr[rB(ctx->opcode)]);                      \
                   6898:     tcg_op(t0, t0, t2);                                                       \
                   6899:     tcg_gen_shri_i64(t3, cpu_gpr[rA(ctx->opcode)], 32);                       \
                   6900:     tcg_gen_trunc_i64_i32(t1, t3);                                            \
                   6901:     tcg_gen_shri_i64(t3, cpu_gpr[rB(ctx->opcode)], 32);                       \
                   6902:     tcg_gen_trunc_i64_i32(t2, t3);                                            \
                   6903:     tcg_temp_free_i64(t3);                                                    \
                   6904:     tcg_op(t1, t1, t2);                                                       \
                   6905:     tcg_temp_free_i32(t2);                                                    \
                   6906:     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
                   6907:     tcg_temp_free_i32(t0);                                                    \
                   6908:     tcg_temp_free_i32(t1);                                                    \
1.1.1.5   root     6909: }
1.1.1.6   root     6910: #else
                   6911: #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
1.1.1.8   root     6912: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     6913: {                                                                             \
                   6914:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     6915:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     6916:         return;                                                               \
                   6917:     }                                                                         \
1.1.1.6   root     6918:     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
                   6919:            cpu_gpr[rB(ctx->opcode)]);                                         \
                   6920:     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
                   6921:            cpu_gprh[rB(ctx->opcode)]);                                        \
                   6922: }
                   6923: #endif
                   6924: 
1.1.1.8   root     6925: static inline void gen_op_evsrwu(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1.1.1.6   root     6926: {
                   6927:     TCGv_i32 t0;
                   6928:     int l1, l2;
                   6929: 
                   6930:     l1 = gen_new_label();
                   6931:     l2 = gen_new_label();
                   6932:     t0 = tcg_temp_local_new_i32();
                   6933:     /* No error here: 6 bits are used */
                   6934:     tcg_gen_andi_i32(t0, arg2, 0x3F);
                   6935:     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
                   6936:     tcg_gen_shr_i32(ret, arg1, t0);
                   6937:     tcg_gen_br(l2);
                   6938:     gen_set_label(l1);
                   6939:     tcg_gen_movi_i32(ret, 0);
1.1.1.9   root     6940:     gen_set_label(l2);
1.1.1.6   root     6941:     tcg_temp_free_i32(t0);
                   6942: }
                   6943: GEN_SPEOP_ARITH2(evsrwu, gen_op_evsrwu);
1.1.1.8   root     6944: static inline void gen_op_evsrws(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1.1.1.6   root     6945: {
                   6946:     TCGv_i32 t0;
                   6947:     int l1, l2;
                   6948: 
                   6949:     l1 = gen_new_label();
                   6950:     l2 = gen_new_label();
                   6951:     t0 = tcg_temp_local_new_i32();
                   6952:     /* No error here: 6 bits are used */
                   6953:     tcg_gen_andi_i32(t0, arg2, 0x3F);
                   6954:     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
                   6955:     tcg_gen_sar_i32(ret, arg1, t0);
                   6956:     tcg_gen_br(l2);
                   6957:     gen_set_label(l1);
                   6958:     tcg_gen_movi_i32(ret, 0);
1.1.1.9   root     6959:     gen_set_label(l2);
1.1.1.6   root     6960:     tcg_temp_free_i32(t0);
                   6961: }
                   6962: GEN_SPEOP_ARITH2(evsrws, gen_op_evsrws);
1.1.1.8   root     6963: static inline void gen_op_evslw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1.1.1.6   root     6964: {
                   6965:     TCGv_i32 t0;
                   6966:     int l1, l2;
                   6967: 
                   6968:     l1 = gen_new_label();
                   6969:     l2 = gen_new_label();
                   6970:     t0 = tcg_temp_local_new_i32();
                   6971:     /* No error here: 6 bits are used */
                   6972:     tcg_gen_andi_i32(t0, arg2, 0x3F);
                   6973:     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
                   6974:     tcg_gen_shl_i32(ret, arg1, t0);
                   6975:     tcg_gen_br(l2);
                   6976:     gen_set_label(l1);
                   6977:     tcg_gen_movi_i32(ret, 0);
1.1.1.9   root     6978:     gen_set_label(l2);
1.1.1.6   root     6979:     tcg_temp_free_i32(t0);
                   6980: }
                   6981: GEN_SPEOP_ARITH2(evslw, gen_op_evslw);
1.1.1.8   root     6982: static inline void gen_op_evrlw(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1.1.1.6   root     6983: {
                   6984:     TCGv_i32 t0 = tcg_temp_new_i32();
                   6985:     tcg_gen_andi_i32(t0, arg2, 0x1F);
                   6986:     tcg_gen_rotl_i32(ret, arg1, t0);
                   6987:     tcg_temp_free_i32(t0);
                   6988: }
                   6989: GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
1.1.1.8   root     6990: static inline void gen_evmergehi(DisasContext *ctx)
1.1.1.6   root     6991: {
                   6992:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     6993:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     6994:         return;
                   6995:     }
                   6996: #if defined(TARGET_PPC64)
                   6997:     TCGv t0 = tcg_temp_new();
                   6998:     TCGv t1 = tcg_temp_new();
                   6999:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
                   7000:     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
                   7001:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
                   7002:     tcg_temp_free(t0);
                   7003:     tcg_temp_free(t1);
                   7004: #else
                   7005:     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
                   7006:     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
                   7007: #endif
                   7008: }
                   7009: GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32);
1.1.1.8   root     7010: static inline void gen_op_evsubf(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
1.1.1.6   root     7011: {
                   7012:     tcg_gen_sub_i32(ret, arg2, arg1);
1.1.1.5   root     7013: }
1.1.1.6   root     7014: GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
1.1.1.5   root     7015: 
1.1.1.6   root     7016: /* SPE arithmetic immediate */
                   7017: #if defined(TARGET_PPC64)
                   7018: #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
1.1.1.8   root     7019: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     7020: {                                                                             \
                   7021:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     7022:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     7023:         return;                                                               \
                   7024:     }                                                                         \
1.1.1.6   root     7025:     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
                   7026:     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
                   7027:     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
                   7028:     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rB(ctx->opcode)]);                      \
                   7029:     tcg_op(t0, t0, rA(ctx->opcode));                                          \
                   7030:     tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
                   7031:     tcg_gen_trunc_i64_i32(t1, t2);                                            \
                   7032:     tcg_temp_free_i64(t2);                                                    \
                   7033:     tcg_op(t1, t1, rA(ctx->opcode));                                          \
                   7034:     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
                   7035:     tcg_temp_free_i32(t0);                                                    \
                   7036:     tcg_temp_free_i32(t1);                                                    \
1.1       root     7037: }
1.1.1.6   root     7038: #else
                   7039: #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
1.1.1.8   root     7040: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     7041: {                                                                             \
                   7042:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     7043:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     7044:         return;                                                               \
                   7045:     }                                                                         \
1.1.1.6   root     7046:     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],                \
                   7047:            rA(ctx->opcode));                                                  \
                   7048:     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)],              \
                   7049:            rA(ctx->opcode));                                                  \
1.1.1.5   root     7050: }
1.1.1.6   root     7051: #endif
                   7052: GEN_SPEOP_ARITH_IMM2(evaddiw, tcg_gen_addi_i32);
                   7053: GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32);
1.1.1.5   root     7054: 
1.1.1.6   root     7055: /* SPE comparison */
                   7056: #if defined(TARGET_PPC64)
                   7057: #define GEN_SPEOP_COMP(name, tcg_cond)                                        \
1.1.1.8   root     7058: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     7059: {                                                                             \
                   7060:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     7061:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     7062:         return;                                                               \
                   7063:     }                                                                         \
                   7064:     int l1 = gen_new_label();                                                 \
                   7065:     int l2 = gen_new_label();                                                 \
                   7066:     int l3 = gen_new_label();                                                 \
                   7067:     int l4 = gen_new_label();                                                 \
                   7068:     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
                   7069:     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
                   7070:     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
                   7071:     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
                   7072:     tcg_gen_trunc_i64_i32(t1, cpu_gpr[rB(ctx->opcode)]);                      \
                   7073:     tcg_gen_brcond_i32(tcg_cond, t0, t1, l1);                                 \
                   7074:     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0);                          \
                   7075:     tcg_gen_br(l2);                                                           \
                   7076:     gen_set_label(l1);                                                        \
                   7077:     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
                   7078:                      CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
                   7079:     gen_set_label(l2);                                                        \
                   7080:     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
                   7081:     tcg_gen_trunc_i64_i32(t0, t2);                                            \
                   7082:     tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
                   7083:     tcg_gen_trunc_i64_i32(t1, t2);                                            \
                   7084:     tcg_temp_free_i64(t2);                                                    \
                   7085:     tcg_gen_brcond_i32(tcg_cond, t0, t1, l3);                                 \
                   7086:     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
                   7087:                      ~(CRF_CH | CRF_CH_AND_CL));                              \
                   7088:     tcg_gen_br(l4);                                                           \
                   7089:     gen_set_label(l3);                                                        \
                   7090:     tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
                   7091:                     CRF_CH | CRF_CH_OR_CL);                                   \
                   7092:     gen_set_label(l4);                                                        \
                   7093:     tcg_temp_free_i32(t0);                                                    \
                   7094:     tcg_temp_free_i32(t1);                                                    \
                   7095: }
                   7096: #else
                   7097: #define GEN_SPEOP_COMP(name, tcg_cond)                                        \
1.1.1.8   root     7098: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     7099: {                                                                             \
                   7100:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     7101:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.5   root     7102:         return;                                                               \
                   7103:     }                                                                         \
1.1.1.6   root     7104:     int l1 = gen_new_label();                                                 \
                   7105:     int l2 = gen_new_label();                                                 \
                   7106:     int l3 = gen_new_label();                                                 \
                   7107:     int l4 = gen_new_label();                                                 \
                   7108:                                                                               \
                   7109:     tcg_gen_brcond_i32(tcg_cond, cpu_gpr[rA(ctx->opcode)],                    \
                   7110:                        cpu_gpr[rB(ctx->opcode)], l1);                         \
                   7111:     tcg_gen_movi_tl(cpu_crf[crfD(ctx->opcode)], 0);                           \
                   7112:     tcg_gen_br(l2);                                                           \
                   7113:     gen_set_label(l1);                                                        \
                   7114:     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
                   7115:                      CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
                   7116:     gen_set_label(l2);                                                        \
                   7117:     tcg_gen_brcond_i32(tcg_cond, cpu_gprh[rA(ctx->opcode)],                   \
                   7118:                        cpu_gprh[rB(ctx->opcode)], l3);                        \
                   7119:     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
                   7120:                      ~(CRF_CH | CRF_CH_AND_CL));                              \
                   7121:     tcg_gen_br(l4);                                                           \
                   7122:     gen_set_label(l3);                                                        \
                   7123:     tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
                   7124:                     CRF_CH | CRF_CH_OR_CL);                                   \
                   7125:     gen_set_label(l4);                                                        \
                   7126: }
                   7127: #endif
                   7128: GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU);
                   7129: GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT);
                   7130: GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU);
                   7131: GEN_SPEOP_COMP(evcmplts, TCG_COND_LT);
                   7132: GEN_SPEOP_COMP(evcmpeq, TCG_COND_EQ);
1.1.1.5   root     7133: 
1.1.1.6   root     7134: /* SPE misc */
1.1.1.8   root     7135: static inline void gen_brinc(DisasContext *ctx)
1.1.1.6   root     7136: {
                   7137:     /* Note: brinc is usable even if SPE is disabled */
                   7138:     gen_helper_brinc(cpu_gpr[rD(ctx->opcode)],
                   7139:                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   7140: }
1.1.1.8   root     7141: static inline void gen_evmergelo(DisasContext *ctx)
1.1.1.6   root     7142: {
                   7143:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     7144:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     7145:         return;
                   7146:     }
                   7147: #if defined(TARGET_PPC64)
                   7148:     TCGv t0 = tcg_temp_new();
                   7149:     TCGv t1 = tcg_temp_new();
1.1.1.11  root     7150:     tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
1.1.1.6   root     7151:     tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
                   7152:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
                   7153:     tcg_temp_free(t0);
                   7154:     tcg_temp_free(t1);
                   7155: #else
                   7156:     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.7   root     7157:     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1.1.1.6   root     7158: #endif
                   7159: }
1.1.1.8   root     7160: static inline void gen_evmergehilo(DisasContext *ctx)
1.1.1.6   root     7161: {
                   7162:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     7163:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     7164:         return;
                   7165:     }
                   7166: #if defined(TARGET_PPC64)
                   7167:     TCGv t0 = tcg_temp_new();
                   7168:     TCGv t1 = tcg_temp_new();
1.1.1.11  root     7169:     tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
1.1.1.6   root     7170:     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
                   7171:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
                   7172:     tcg_temp_free(t0);
                   7173:     tcg_temp_free(t1);
                   7174: #else
                   7175:     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   7176:     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
                   7177: #endif
                   7178: }
1.1.1.8   root     7179: static inline void gen_evmergelohi(DisasContext *ctx)
1.1.1.6   root     7180: {
                   7181:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     7182:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     7183:         return;
                   7184:     }
                   7185: #if defined(TARGET_PPC64)
                   7186:     TCGv t0 = tcg_temp_new();
                   7187:     TCGv t1 = tcg_temp_new();
                   7188:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
                   7189:     tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
                   7190:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
                   7191:     tcg_temp_free(t0);
                   7192:     tcg_temp_free(t1);
                   7193: #else
1.1.1.7   root     7194:     if (rD(ctx->opcode) == rA(ctx->opcode)) {
                   7195:         TCGv_i32 tmp = tcg_temp_new_i32();
                   7196:         tcg_gen_mov_i32(tmp, cpu_gpr[rA(ctx->opcode)]);
                   7197:         tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
                   7198:         tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], tmp);
                   7199:         tcg_temp_free_i32(tmp);
                   7200:     } else {
                   7201:         tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
                   7202:         tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   7203:     }
1.1.1.6   root     7204: #endif
                   7205: }
1.1.1.8   root     7206: static inline void gen_evsplati(DisasContext *ctx)
1.1.1.5   root     7207: {
1.1.1.9   root     7208:     uint64_t imm = ((int32_t)(rA(ctx->opcode) << 27)) >> 27;
1.1.1.5   root     7209: 
1.1.1.6   root     7210: #if defined(TARGET_PPC64)
                   7211:     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
                   7212: #else
                   7213:     tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
                   7214:     tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
                   7215: #endif
1.1.1.5   root     7216: }
1.1.1.8   root     7217: static inline void gen_evsplatfi(DisasContext *ctx)
1.1.1.5   root     7218: {
1.1.1.9   root     7219:     uint64_t imm = rA(ctx->opcode) << 27;
1.1.1.5   root     7220: 
1.1.1.6   root     7221: #if defined(TARGET_PPC64)
                   7222:     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
                   7223: #else
                   7224:     tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
                   7225:     tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
                   7226: #endif
1.1.1.5   root     7227: }
                   7228: 
1.1.1.8   root     7229: static inline void gen_evsel(DisasContext *ctx)
1.1.1.6   root     7230: {
                   7231:     int l1 = gen_new_label();
                   7232:     int l2 = gen_new_label();
                   7233:     int l3 = gen_new_label();
                   7234:     int l4 = gen_new_label();
                   7235:     TCGv_i32 t0 = tcg_temp_local_new_i32();
                   7236: #if defined(TARGET_PPC64)
                   7237:     TCGv t1 = tcg_temp_local_new();
                   7238:     TCGv t2 = tcg_temp_local_new();
                   7239: #endif
                   7240:     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);
                   7241:     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
                   7242: #if defined(TARGET_PPC64)
                   7243:     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF00000000ULL);
                   7244: #else
                   7245:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
                   7246: #endif
                   7247:     tcg_gen_br(l2);
                   7248:     gen_set_label(l1);
                   7249: #if defined(TARGET_PPC64)
                   7250:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0xFFFFFFFF00000000ULL);
                   7251: #else
                   7252:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
                   7253: #endif
                   7254:     gen_set_label(l2);
                   7255:     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2);
                   7256:     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3);
                   7257: #if defined(TARGET_PPC64)
1.1.1.11  root     7258:     tcg_gen_ext32u_tl(t2, cpu_gpr[rA(ctx->opcode)]);
1.1.1.6   root     7259: #else
                   7260:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   7261: #endif
                   7262:     tcg_gen_br(l4);
                   7263:     gen_set_label(l3);
                   7264: #if defined(TARGET_PPC64)
1.1.1.11  root     7265:     tcg_gen_ext32u_tl(t2, cpu_gpr[rB(ctx->opcode)]);
1.1.1.6   root     7266: #else
                   7267:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
                   7268: #endif
                   7269:     gen_set_label(l4);
                   7270:     tcg_temp_free_i32(t0);
                   7271: #if defined(TARGET_PPC64)
                   7272:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t1, t2);
                   7273:     tcg_temp_free(t1);
                   7274:     tcg_temp_free(t2);
                   7275: #endif
                   7276: }
1.1.1.7   root     7277: 
                   7278: static void gen_evsel0(DisasContext *ctx)
1.1.1.6   root     7279: {
                   7280:     gen_evsel(ctx);
                   7281: }
1.1.1.7   root     7282: 
                   7283: static void gen_evsel1(DisasContext *ctx)
1.1.1.6   root     7284: {
                   7285:     gen_evsel(ctx);
                   7286: }
1.1.1.7   root     7287: 
                   7288: static void gen_evsel2(DisasContext *ctx)
1.1.1.6   root     7289: {
                   7290:     gen_evsel(ctx);
                   7291: }
1.1.1.7   root     7292: 
                   7293: static void gen_evsel3(DisasContext *ctx)
1.1.1.6   root     7294: {
                   7295:     gen_evsel(ctx);
                   7296: }
1.1.1.5   root     7297: 
1.1.1.11  root     7298: /* Multiply */
                   7299: 
                   7300: static inline void gen_evmwumi(DisasContext *ctx)
                   7301: {
                   7302:     TCGv_i64 t0, t1;
                   7303: 
                   7304:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     7305:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.11  root     7306:         return;
                   7307:     }
                   7308: 
                   7309:     t0 = tcg_temp_new_i64();
                   7310:     t1 = tcg_temp_new_i64();
                   7311: 
                   7312:     /* t0 := rA; t1 := rB */
                   7313: #if defined(TARGET_PPC64)
                   7314:     tcg_gen_ext32u_tl(t0, cpu_gpr[rA(ctx->opcode)]);
                   7315:     tcg_gen_ext32u_tl(t1, cpu_gpr[rB(ctx->opcode)]);
                   7316: #else
                   7317:     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   7318:     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   7319: #endif
                   7320: 
                   7321:     tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */
                   7322: 
                   7323:     gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */
                   7324: 
                   7325:     tcg_temp_free_i64(t0);
                   7326:     tcg_temp_free_i64(t1);
                   7327: }
                   7328: 
                   7329: static inline void gen_evmwumia(DisasContext *ctx)
                   7330: {
                   7331:     TCGv_i64 tmp;
                   7332: 
                   7333:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     7334:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.11  root     7335:         return;
                   7336:     }
                   7337: 
                   7338:     gen_evmwumi(ctx);            /* rD := rA * rB */
                   7339: 
                   7340:     tmp = tcg_temp_new_i64();
                   7341: 
                   7342:     /* acc := rD */
                   7343:     gen_load_gpr64(tmp, rD(ctx->opcode));
                   7344:     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc));
                   7345:     tcg_temp_free_i64(tmp);
                   7346: }
                   7347: 
                   7348: static inline void gen_evmwumiaa(DisasContext *ctx)
                   7349: {
                   7350:     TCGv_i64 acc;
                   7351:     TCGv_i64 tmp;
                   7352: 
                   7353:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     7354:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.11  root     7355:         return;
                   7356:     }
                   7357: 
                   7358:     gen_evmwumi(ctx);           /* rD := rA * rB */
                   7359: 
                   7360:     acc = tcg_temp_new_i64();
                   7361:     tmp = tcg_temp_new_i64();
                   7362: 
                   7363:     /* tmp := rD */
                   7364:     gen_load_gpr64(tmp, rD(ctx->opcode));
                   7365: 
                   7366:     /* Load acc */
                   7367:     tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUState, spe_acc));
                   7368: 
                   7369:     /* acc := tmp + acc */
                   7370:     tcg_gen_add_i64(acc, acc, tmp);
                   7371: 
                   7372:     /* Store acc */
                   7373:     tcg_gen_st_i64(acc, cpu_env, offsetof(CPUState, spe_acc));
                   7374: 
                   7375:     /* rD := acc */
                   7376:     gen_store_gpr64(rD(ctx->opcode), acc);
                   7377: 
                   7378:     tcg_temp_free_i64(acc);
                   7379:     tcg_temp_free_i64(tmp);
                   7380: }
                   7381: 
                   7382: static inline void gen_evmwsmi(DisasContext *ctx)
                   7383: {
                   7384:     TCGv_i64 t0, t1;
                   7385: 
                   7386:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     7387:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.11  root     7388:         return;
                   7389:     }
                   7390: 
                   7391:     t0 = tcg_temp_new_i64();
                   7392:     t1 = tcg_temp_new_i64();
                   7393: 
                   7394:     /* t0 := rA; t1 := rB */
                   7395: #if defined(TARGET_PPC64)
                   7396:     tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
                   7397:     tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
                   7398: #else
                   7399:     tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
                   7400:     tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
                   7401: #endif
                   7402: 
                   7403:     tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */
                   7404: 
                   7405:     gen_store_gpr64(rD(ctx->opcode), t0); /* rD := t0 */
                   7406: 
                   7407:     tcg_temp_free_i64(t0);
                   7408:     tcg_temp_free_i64(t1);
                   7409: }
                   7410: 
                   7411: static inline void gen_evmwsmia(DisasContext *ctx)
                   7412: {
                   7413:     TCGv_i64 tmp;
                   7414: 
                   7415:     gen_evmwsmi(ctx);            /* rD := rA * rB */
                   7416: 
                   7417:     tmp = tcg_temp_new_i64();
                   7418: 
                   7419:     /* acc := rD */
                   7420:     gen_load_gpr64(tmp, rD(ctx->opcode));
                   7421:     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUState, spe_acc));
                   7422: 
                   7423:     tcg_temp_free_i64(tmp);
                   7424: }
                   7425: 
                   7426: static inline void gen_evmwsmiaa(DisasContext *ctx)
                   7427: {
                   7428:     TCGv_i64 acc = tcg_temp_new_i64();
                   7429:     TCGv_i64 tmp = tcg_temp_new_i64();
                   7430: 
                   7431:     gen_evmwsmi(ctx);           /* rD := rA * rB */
                   7432: 
                   7433:     acc = tcg_temp_new_i64();
                   7434:     tmp = tcg_temp_new_i64();
                   7435: 
                   7436:     /* tmp := rD */
                   7437:     gen_load_gpr64(tmp, rD(ctx->opcode));
                   7438: 
                   7439:     /* Load acc */
                   7440:     tcg_gen_ld_i64(acc, cpu_env, offsetof(CPUState, spe_acc));
                   7441: 
                   7442:     /* acc := tmp + acc */
                   7443:     tcg_gen_add_i64(acc, acc, tmp);
                   7444: 
                   7445:     /* Store acc */
                   7446:     tcg_gen_st_i64(acc, cpu_env, offsetof(CPUState, spe_acc));
                   7447: 
                   7448:     /* rD := acc */
                   7449:     gen_store_gpr64(rD(ctx->opcode), acc);
                   7450: 
                   7451:     tcg_temp_free_i64(acc);
                   7452:     tcg_temp_free_i64(tmp);
                   7453: }
                   7454: 
1.1.1.12! root     7455: GEN_SPE(evaddw,      speundef,    0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
        !          7456: GEN_SPE(evaddiw,     speundef,    0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
        !          7457: GEN_SPE(evsubfw,     speundef,    0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
        !          7458: GEN_SPE(evsubifw,    speundef,    0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
        !          7459: GEN_SPE(evabs,       evneg,       0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
        !          7460: GEN_SPE(evextsb,     evextsh,     0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
        !          7461: GEN_SPE(evrndw,      evcntlzw,    0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE); ////
        !          7462: GEN_SPE(evcntlsw,    brinc,       0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE); //
        !          7463: GEN_SPE(evmra,       speundef,    0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE);
        !          7464: GEN_SPE(speundef,    evand,       0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE); ////
        !          7465: GEN_SPE(evandc,      speundef,    0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
        !          7466: GEN_SPE(evxor,       evor,        0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
        !          7467: GEN_SPE(evnor,       eveqv,       0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
        !          7468: GEN_SPE(evmwumi,     evmwsmi,     0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE);
        !          7469: GEN_SPE(evmwumia,    evmwsmia,    0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE);
        !          7470: GEN_SPE(evmwumiaa,   evmwsmiaa,   0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE);
        !          7471: GEN_SPE(speundef,    evorc,       0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE); ////
        !          7472: GEN_SPE(evnand,      speundef,    0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
        !          7473: GEN_SPE(evsrwu,      evsrws,      0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
        !          7474: GEN_SPE(evsrwiu,     evsrwis,     0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE);
        !          7475: GEN_SPE(evslw,       speundef,    0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE); ////
        !          7476: GEN_SPE(evslwi,      speundef,    0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE);
        !          7477: GEN_SPE(evrlw,       evsplati,    0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE); //
        !          7478: GEN_SPE(evrlwi,      evsplatfi,   0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE);
        !          7479: GEN_SPE(evmergehi,   evmergelo,   0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
        !          7480: GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE); ////
        !          7481: GEN_SPE(evcmpgtu,    evcmpgts,    0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE); ////
        !          7482: GEN_SPE(evcmpltu,    evcmplts,    0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE); ////
        !          7483: GEN_SPE(evcmpeq,     speundef,    0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE); ////
1.1.1.5   root     7484: 
1.1.1.6   root     7485: /* SPE load and stores */
1.1.1.8   root     7486: static inline void gen_addr_spe_imm_index(DisasContext *ctx, TCGv EA, int sh)
1.1       root     7487: {
1.1.1.6   root     7488:     target_ulong uimm = rB(ctx->opcode);
                   7489: 
                   7490:     if (rA(ctx->opcode) == 0) {
                   7491:         tcg_gen_movi_tl(EA, uimm << sh);
                   7492:     } else {
                   7493:         tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], uimm << sh);
                   7494: #if defined(TARGET_PPC64)
                   7495:         if (!ctx->sf_mode) {
                   7496:             tcg_gen_ext32u_tl(EA, EA);
                   7497:         }
                   7498: #endif
1.1       root     7499:     }
1.1.1.5   root     7500: }
                   7501: 
1.1.1.8   root     7502: static inline void gen_op_evldd(DisasContext *ctx, TCGv addr)
1.1.1.5   root     7503: {
1.1.1.6   root     7504: #if defined(TARGET_PPC64)
                   7505:     gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], addr);
                   7506: #else
                   7507:     TCGv_i64 t0 = tcg_temp_new_i64();
                   7508:     gen_qemu_ld64(ctx, t0, addr);
                   7509:     tcg_gen_trunc_i64_i32(cpu_gpr[rD(ctx->opcode)], t0);
                   7510:     tcg_gen_shri_i64(t0, t0, 32);
                   7511:     tcg_gen_trunc_i64_i32(cpu_gprh[rD(ctx->opcode)], t0);
                   7512:     tcg_temp_free_i64(t0);
                   7513: #endif
1.1.1.5   root     7514: }
1.1.1.6   root     7515: 
1.1.1.8   root     7516: static inline void gen_op_evldw(DisasContext *ctx, TCGv addr)
1.1.1.5   root     7517: {
1.1.1.6   root     7518: #if defined(TARGET_PPC64)
                   7519:     TCGv t0 = tcg_temp_new();
                   7520:     gen_qemu_ld32u(ctx, t0, addr);
                   7521:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
                   7522:     gen_addr_add(ctx, addr, addr, 4);
                   7523:     gen_qemu_ld32u(ctx, t0, addr);
                   7524:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7525:     tcg_temp_free(t0);
                   7526: #else
                   7527:     gen_qemu_ld32u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
                   7528:     gen_addr_add(ctx, addr, addr, 4);
                   7529:     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
                   7530: #endif
1.1.1.5   root     7531: }
1.1.1.6   root     7532: 
1.1.1.8   root     7533: static inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
1.1.1.5   root     7534: {
1.1.1.6   root     7535:     TCGv t0 = tcg_temp_new();
                   7536: #if defined(TARGET_PPC64)
                   7537:     gen_qemu_ld16u(ctx, t0, addr);
                   7538:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
                   7539:     gen_addr_add(ctx, addr, addr, 2);
                   7540:     gen_qemu_ld16u(ctx, t0, addr);
                   7541:     tcg_gen_shli_tl(t0, t0, 32);
                   7542:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7543:     gen_addr_add(ctx, addr, addr, 2);
                   7544:     gen_qemu_ld16u(ctx, t0, addr);
                   7545:     tcg_gen_shli_tl(t0, t0, 16);
                   7546:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7547:     gen_addr_add(ctx, addr, addr, 2);
                   7548:     gen_qemu_ld16u(ctx, t0, addr);
                   7549:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7550: #else
                   7551:     gen_qemu_ld16u(ctx, t0, addr);
                   7552:     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
                   7553:     gen_addr_add(ctx, addr, addr, 2);
                   7554:     gen_qemu_ld16u(ctx, t0, addr);
                   7555:     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
                   7556:     gen_addr_add(ctx, addr, addr, 2);
                   7557:     gen_qemu_ld16u(ctx, t0, addr);
                   7558:     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
                   7559:     gen_addr_add(ctx, addr, addr, 2);
                   7560:     gen_qemu_ld16u(ctx, t0, addr);
                   7561:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7562: #endif
                   7563:     tcg_temp_free(t0);
1.1.1.5   root     7564: }
1.1.1.6   root     7565: 
1.1.1.8   root     7566: static inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr)
1.1.1.5   root     7567: {
1.1.1.6   root     7568:     TCGv t0 = tcg_temp_new();
                   7569:     gen_qemu_ld16u(ctx, t0, addr);
                   7570: #if defined(TARGET_PPC64)
                   7571:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
                   7572:     tcg_gen_shli_tl(t0, t0, 16);
                   7573:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7574: #else
                   7575:     tcg_gen_shli_tl(t0, t0, 16);
                   7576:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
                   7577:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   7578: #endif
                   7579:     tcg_temp_free(t0);
1.1.1.5   root     7580: }
                   7581: 
1.1.1.8   root     7582: static inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7583: {
                   7584:     TCGv t0 = tcg_temp_new();
                   7585:     gen_qemu_ld16u(ctx, t0, addr);
1.1.1.5   root     7586: #if defined(TARGET_PPC64)
1.1.1.6   root     7587:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
                   7588:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7589: #else
                   7590:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
                   7591:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   7592: #endif
                   7593:     tcg_temp_free(t0);
                   7594: }
                   7595: 
1.1.1.8   root     7596: static inline void gen_op_evlhhossplat(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7597: {
                   7598:     TCGv t0 = tcg_temp_new();
                   7599:     gen_qemu_ld16s(ctx, t0, addr);
                   7600: #if defined(TARGET_PPC64)
                   7601:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
                   7602:     tcg_gen_ext32u_tl(t0, t0);
                   7603:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7604: #else
                   7605:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
                   7606:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   7607: #endif
                   7608:     tcg_temp_free(t0);
                   7609: }
                   7610: 
1.1.1.8   root     7611: static inline void gen_op_evlwhe(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7612: {
                   7613:     TCGv t0 = tcg_temp_new();
                   7614: #if defined(TARGET_PPC64)
                   7615:     gen_qemu_ld16u(ctx, t0, addr);
                   7616:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
                   7617:     gen_addr_add(ctx, addr, addr, 2);
                   7618:     gen_qemu_ld16u(ctx, t0, addr);
                   7619:     tcg_gen_shli_tl(t0, t0, 16);
                   7620:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7621: #else
                   7622:     gen_qemu_ld16u(ctx, t0, addr);
                   7623:     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
                   7624:     gen_addr_add(ctx, addr, addr, 2);
                   7625:     gen_qemu_ld16u(ctx, t0, addr);
                   7626:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
                   7627: #endif
                   7628:     tcg_temp_free(t0);
                   7629: }
                   7630: 
1.1.1.8   root     7631: static inline void gen_op_evlwhou(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7632: {
                   7633: #if defined(TARGET_PPC64)
                   7634:     TCGv t0 = tcg_temp_new();
                   7635:     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
                   7636:     gen_addr_add(ctx, addr, addr, 2);
                   7637:     gen_qemu_ld16u(ctx, t0, addr);
                   7638:     tcg_gen_shli_tl(t0, t0, 32);
                   7639:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7640:     tcg_temp_free(t0);
                   7641: #else
                   7642:     gen_qemu_ld16u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
                   7643:     gen_addr_add(ctx, addr, addr, 2);
                   7644:     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
                   7645: #endif
                   7646: }
                   7647: 
1.1.1.8   root     7648: static inline void gen_op_evlwhos(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7649: {
                   7650: #if defined(TARGET_PPC64)
                   7651:     TCGv t0 = tcg_temp_new();
                   7652:     gen_qemu_ld16s(ctx, t0, addr);
                   7653:     tcg_gen_ext32u_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   7654:     gen_addr_add(ctx, addr, addr, 2);
                   7655:     gen_qemu_ld16s(ctx, t0, addr);
                   7656:     tcg_gen_shli_tl(t0, t0, 32);
                   7657:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7658:     tcg_temp_free(t0);
                   7659: #else
                   7660:     gen_qemu_ld16s(ctx, cpu_gprh[rD(ctx->opcode)], addr);
                   7661:     gen_addr_add(ctx, addr, addr, 2);
                   7662:     gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], addr);
                   7663: #endif
                   7664: }
                   7665: 
1.1.1.8   root     7666: static inline void gen_op_evlwwsplat(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7667: {
                   7668:     TCGv t0 = tcg_temp_new();
                   7669:     gen_qemu_ld32u(ctx, t0, addr);
                   7670: #if defined(TARGET_PPC64)
                   7671:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
                   7672:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7673: #else
                   7674:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
                   7675:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
                   7676: #endif
                   7677:     tcg_temp_free(t0);
                   7678: }
                   7679: 
1.1.1.8   root     7680: static inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7681: {
                   7682:     TCGv t0 = tcg_temp_new();
                   7683: #if defined(TARGET_PPC64)
                   7684:     gen_qemu_ld16u(ctx, t0, addr);
                   7685:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
                   7686:     tcg_gen_shli_tl(t0, t0, 32);
                   7687:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7688:     gen_addr_add(ctx, addr, addr, 2);
                   7689:     gen_qemu_ld16u(ctx, t0, addr);
                   7690:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7691:     tcg_gen_shli_tl(t0, t0, 16);
                   7692:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
                   7693: #else
                   7694:     gen_qemu_ld16u(ctx, t0, addr);
                   7695:     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
                   7696:     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
                   7697:     gen_addr_add(ctx, addr, addr, 2);
                   7698:     gen_qemu_ld16u(ctx, t0, addr);
                   7699:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
                   7700:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
                   7701: #endif
                   7702:     tcg_temp_free(t0);
                   7703: }
                   7704: 
1.1.1.8   root     7705: static inline void gen_op_evstdd(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7706: {
                   7707: #if defined(TARGET_PPC64)
                   7708:     gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], addr);
                   7709: #else
                   7710:     TCGv_i64 t0 = tcg_temp_new_i64();
                   7711:     tcg_gen_concat_i32_i64(t0, cpu_gpr[rS(ctx->opcode)], cpu_gprh[rS(ctx->opcode)]);
                   7712:     gen_qemu_st64(ctx, t0, addr);
                   7713:     tcg_temp_free_i64(t0);
                   7714: #endif
                   7715: }
                   7716: 
1.1.1.8   root     7717: static inline void gen_op_evstdw(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7718: {
                   7719: #if defined(TARGET_PPC64)
                   7720:     TCGv t0 = tcg_temp_new();
                   7721:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
                   7722:     gen_qemu_st32(ctx, t0, addr);
                   7723:     tcg_temp_free(t0);
                   7724: #else
                   7725:     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
                   7726: #endif
                   7727:     gen_addr_add(ctx, addr, addr, 4);
                   7728:     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
1.1.1.5   root     7729: }
1.1.1.6   root     7730: 
1.1.1.8   root     7731: static inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7732: {
                   7733:     TCGv t0 = tcg_temp_new();
                   7734: #if defined(TARGET_PPC64)
                   7735:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
1.1.1.5   root     7736: #else
1.1.1.6   root     7737:     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
                   7738: #endif
                   7739:     gen_qemu_st16(ctx, t0, addr);
                   7740:     gen_addr_add(ctx, addr, addr, 2);
                   7741: #if defined(TARGET_PPC64)
                   7742:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
                   7743:     gen_qemu_st16(ctx, t0, addr);
                   7744: #else
                   7745:     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
                   7746: #endif
                   7747:     gen_addr_add(ctx, addr, addr, 2);
                   7748:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
                   7749:     gen_qemu_st16(ctx, t0, addr);
                   7750:     tcg_temp_free(t0);
                   7751:     gen_addr_add(ctx, addr, addr, 2);
                   7752:     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
                   7753: }
                   7754: 
1.1.1.8   root     7755: static inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7756: {
                   7757:     TCGv t0 = tcg_temp_new();
                   7758: #if defined(TARGET_PPC64)
                   7759:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
                   7760: #else
                   7761:     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
                   7762: #endif
                   7763:     gen_qemu_st16(ctx, t0, addr);
                   7764:     gen_addr_add(ctx, addr, addr, 2);
                   7765:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
                   7766:     gen_qemu_st16(ctx, t0, addr);
                   7767:     tcg_temp_free(t0);
                   7768: }
                   7769: 
1.1.1.8   root     7770: static inline void gen_op_evstwho(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7771: {
                   7772: #if defined(TARGET_PPC64)
                   7773:     TCGv t0 = tcg_temp_new();
                   7774:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
                   7775:     gen_qemu_st16(ctx, t0, addr);
                   7776:     tcg_temp_free(t0);
                   7777: #else
                   7778:     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
                   7779: #endif
                   7780:     gen_addr_add(ctx, addr, addr, 2);
                   7781:     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
                   7782: }
                   7783: 
1.1.1.8   root     7784: static inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7785: {
                   7786: #if defined(TARGET_PPC64)
                   7787:     TCGv t0 = tcg_temp_new();
                   7788:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
                   7789:     gen_qemu_st32(ctx, t0, addr);
                   7790:     tcg_temp_free(t0);
                   7791: #else
                   7792:     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
                   7793: #endif
                   7794: }
                   7795: 
1.1.1.8   root     7796: static inline void gen_op_evstwwo(DisasContext *ctx, TCGv addr)
1.1.1.6   root     7797: {
                   7798:     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
                   7799: }
                   7800: 
                   7801: #define GEN_SPEOP_LDST(name, opc2, sh)                                        \
1.1.1.7   root     7802: static void glue(gen_, name)(DisasContext *ctx)                                       \
1.1.1.6   root     7803: {                                                                             \
                   7804:     TCGv t0;                                                                  \
                   7805:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     7806:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     7807:         return;                                                               \
                   7808:     }                                                                         \
                   7809:     gen_set_access_type(ctx, ACCESS_INT);                                     \
                   7810:     t0 = tcg_temp_new();                                                      \
                   7811:     if (Rc(ctx->opcode)) {                                                    \
                   7812:         gen_addr_spe_imm_index(ctx, t0, sh);                                  \
                   7813:     } else {                                                                  \
                   7814:         gen_addr_reg_index(ctx, t0);                                          \
                   7815:     }                                                                         \
                   7816:     gen_op_##name(ctx, t0);                                                   \
                   7817:     tcg_temp_free(t0);                                                        \
                   7818: }
                   7819: 
                   7820: GEN_SPEOP_LDST(evldd, 0x00, 3);
                   7821: GEN_SPEOP_LDST(evldw, 0x01, 3);
                   7822: GEN_SPEOP_LDST(evldh, 0x02, 3);
                   7823: GEN_SPEOP_LDST(evlhhesplat, 0x04, 1);
                   7824: GEN_SPEOP_LDST(evlhhousplat, 0x06, 1);
                   7825: GEN_SPEOP_LDST(evlhhossplat, 0x07, 1);
                   7826: GEN_SPEOP_LDST(evlwhe, 0x08, 2);
                   7827: GEN_SPEOP_LDST(evlwhou, 0x0A, 2);
                   7828: GEN_SPEOP_LDST(evlwhos, 0x0B, 2);
                   7829: GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2);
                   7830: GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2);
                   7831: 
                   7832: GEN_SPEOP_LDST(evstdd, 0x10, 3);
                   7833: GEN_SPEOP_LDST(evstdw, 0x11, 3);
                   7834: GEN_SPEOP_LDST(evstdh, 0x12, 3);
                   7835: GEN_SPEOP_LDST(evstwhe, 0x18, 2);
                   7836: GEN_SPEOP_LDST(evstwho, 0x1A, 2);
                   7837: GEN_SPEOP_LDST(evstwwe, 0x1C, 2);
                   7838: GEN_SPEOP_LDST(evstwwo, 0x1E, 2);
1.1.1.5   root     7839: 
                   7840: /* Multiply and add - TODO */
                   7841: #if 0
1.1.1.12! root     7842: GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);//
        !          7843: GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7844: GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, 0x00000000, PPC_SPE);
        !          7845: GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7846: GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, 0x00000000, PPC_SPE);
        !          7847: GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7848: GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7849: GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7850: GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, 0x00000000, PPC_SPE);
        !          7851: GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7852: GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, 0x00000000, PPC_SPE);
        !          7853: GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7854: 
        !          7855: GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7856: GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
        !          7857: GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, 0x00000000, PPC_SPE);
        !          7858: GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7859: GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7860: GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7861: GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7862: GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, 0xFFFFFFFF, PPC_SPE);
        !          7863: GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, 0x00000000, PPC_SPE);
        !          7864: GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7865: GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7866: GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7867: 
        !          7868: GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
        !          7869: GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
        !          7870: GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
        !          7871: GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, 0x0000F800, PPC_SPE);
        !          7872: GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, 0x00000000, PPC_SPE);
        !          7873: 
        !          7874: GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, 0x00000000, PPC_SPE);
        !          7875: GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7876: GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, 0x00000000, PPC_SPE);
        !          7877: GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7878: GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, 0x00000000, PPC_SPE);
        !          7879: GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7880: GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, 0x00000000, PPC_SPE);
        !          7881: GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7882: GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, 0x00000000, PPC_SPE);
        !          7883: GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7884: GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, 0x00000000, PPC_SPE);
        !          7885: GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7886: 
        !          7887: GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, 0x00000000, PPC_SPE);
        !          7888: GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, 0x00000000, PPC_SPE);
        !          7889: GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7890: GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7891: 
        !          7892: GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, 0x00000000, PPC_SPE);
        !          7893: GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7894: GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, 0x00000000, PPC_SPE);
        !          7895: GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7896: GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, 0x00000000, PPC_SPE);
        !          7897: GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7898: GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, 0x00000000, PPC_SPE);
        !          7899: GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7900: GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, 0x00000000, PPC_SPE);
        !          7901: GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7902: GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, 0x00000000, PPC_SPE);
        !          7903: GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7904: 
        !          7905: GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, 0x00000000, PPC_SPE);
        !          7906: GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, 0x00000000, PPC_SPE);
        !          7907: GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
        !          7908: GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, 0x00000000, PPC_SPE);
        !          7909: GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0xFFFFFFFF, 0x00000000, PPC_SPE);
1.1.1.5   root     7910: #endif
                   7911: 
                   7912: /***                      SPE floating-point extension                     ***/
1.1.1.6   root     7913: #if defined(TARGET_PPC64)
                   7914: #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
1.1.1.8   root     7915: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     7916: {                                                                             \
                   7917:     TCGv_i32 t0;                                                              \
                   7918:     TCGv t1;                                                                  \
                   7919:     t0 = tcg_temp_new_i32();                                                  \
                   7920:     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
                   7921:     gen_helper_##name(t0, t0);                                                \
                   7922:     t1 = tcg_temp_new();                                                      \
                   7923:     tcg_gen_extu_i32_tl(t1, t0);                                              \
                   7924:     tcg_temp_free_i32(t0);                                                    \
                   7925:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
                   7926:                     0xFFFFFFFF00000000ULL);                                   \
                   7927:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
                   7928:     tcg_temp_free(t1);                                                        \
                   7929: }
                   7930: #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
1.1.1.8   root     7931: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     7932: {                                                                             \
                   7933:     TCGv_i32 t0;                                                              \
                   7934:     TCGv t1;                                                                  \
                   7935:     t0 = tcg_temp_new_i32();                                                  \
                   7936:     gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
                   7937:     t1 = tcg_temp_new();                                                      \
                   7938:     tcg_gen_extu_i32_tl(t1, t0);                                              \
                   7939:     tcg_temp_free_i32(t0);                                                    \
                   7940:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
                   7941:                     0xFFFFFFFF00000000ULL);                                   \
                   7942:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
                   7943:     tcg_temp_free(t1);                                                        \
                   7944: }
                   7945: #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
1.1.1.8   root     7946: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     7947: {                                                                             \
                   7948:     TCGv_i32 t0 = tcg_temp_new_i32();                                         \
                   7949:     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
                   7950:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
                   7951:     tcg_temp_free_i32(t0);                                                    \
                   7952: }
                   7953: #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
1.1.1.8   root     7954: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     7955: {                                                                             \
                   7956:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
                   7957: }
                   7958: #define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
1.1.1.8   root     7959: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     7960: {                                                                             \
                   7961:     TCGv_i32 t0, t1;                                                          \
                   7962:     TCGv_i64 t2;                                                              \
                   7963:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     7964:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     7965:         return;                                                               \
                   7966:     }                                                                         \
                   7967:     t0 = tcg_temp_new_i32();                                                  \
                   7968:     t1 = tcg_temp_new_i32();                                                  \
                   7969:     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
                   7970:     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
                   7971:     gen_helper_##name(t0, t0, t1);                                            \
                   7972:     tcg_temp_free_i32(t1);                                                    \
                   7973:     t2 = tcg_temp_new();                                                      \
                   7974:     tcg_gen_extu_i32_tl(t2, t0);                                              \
                   7975:     tcg_temp_free_i32(t0);                                                    \
                   7976:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
                   7977:                     0xFFFFFFFF00000000ULL);                                   \
                   7978:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t2);    \
                   7979:     tcg_temp_free(t2);                                                        \
                   7980: }
                   7981: #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
1.1.1.8   root     7982: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.5   root     7983: {                                                                             \
1.1.1.6   root     7984:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     7985:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     7986:         return;                                                               \
                   7987:     }                                                                         \
                   7988:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],     \
                   7989:                       cpu_gpr[rB(ctx->opcode)]);                              \
1.1       root     7990: }
1.1.1.6   root     7991: #define GEN_SPEFPUOP_COMP_32(name)                                            \
1.1.1.8   root     7992: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     7993: {                                                                             \
                   7994:     TCGv_i32 t0, t1;                                                          \
                   7995:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     7996:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     7997:         return;                                                               \
                   7998:     }                                                                         \
                   7999:     t0 = tcg_temp_new_i32();                                                  \
                   8000:     t1 = tcg_temp_new_i32();                                                  \
                   8001:     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
                   8002:     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
                   8003:     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
                   8004:     tcg_temp_free_i32(t0);                                                    \
                   8005:     tcg_temp_free_i32(t1);                                                    \
                   8006: }
                   8007: #define GEN_SPEFPUOP_COMP_64(name)                                            \
1.1.1.8   root     8008: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8009: {                                                                             \
                   8010:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     8011:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     8012:         return;                                                               \
                   8013:     }                                                                         \
                   8014:     gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
                   8015:                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
                   8016: }
                   8017: #else
                   8018: #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
1.1.1.8   root     8019: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8020: {                                                                             \
                   8021:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
                   8022: }
                   8023: #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
1.1.1.8   root     8024: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8025: {                                                                             \
                   8026:     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
                   8027:     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
                   8028:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
                   8029:     tcg_temp_free_i64(t0);                                                    \
                   8030: }
                   8031: #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
1.1.1.8   root     8032: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8033: {                                                                             \
                   8034:     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
                   8035:     gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
                   8036:     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
                   8037:     tcg_temp_free_i64(t0);                                                    \
                   8038: }
                   8039: #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
1.1.1.8   root     8040: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8041: {                                                                             \
                   8042:     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
                   8043:     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
                   8044:     gen_helper_##name(t0, t0);                                                \
                   8045:     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
                   8046:     tcg_temp_free_i64(t0);                                                    \
                   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:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     8052:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     8053:         return;                                                               \
                   8054:     }                                                                         \
                   8055:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)],                               \
                   8056:                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
                   8057: }
                   8058: #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
1.1.1.8   root     8059: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8060: {                                                                             \
                   8061:     TCGv_i64 t0, t1;                                                          \
                   8062:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     8063:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     8064:         return;                                                               \
                   8065:     }                                                                         \
                   8066:     t0 = tcg_temp_new_i64();                                                  \
                   8067:     t1 = tcg_temp_new_i64();                                                  \
                   8068:     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
                   8069:     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
                   8070:     gen_helper_##name(t0, t0, t1);                                            \
                   8071:     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
                   8072:     tcg_temp_free_i64(t0);                                                    \
                   8073:     tcg_temp_free_i64(t1);                                                    \
                   8074: }
                   8075: #define GEN_SPEFPUOP_COMP_32(name)                                            \
1.1.1.8   root     8076: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8077: {                                                                             \
                   8078:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     8079:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     8080:         return;                                                               \
                   8081:     }                                                                         \
                   8082:     gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
                   8083:                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
                   8084: }
                   8085: #define GEN_SPEFPUOP_COMP_64(name)                                            \
1.1.1.8   root     8086: static inline void gen_##name(DisasContext *ctx)                              \
1.1.1.6   root     8087: {                                                                             \
                   8088:     TCGv_i64 t0, t1;                                                          \
                   8089:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.12! root     8090:         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
1.1.1.6   root     8091:         return;                                                               \
                   8092:     }                                                                         \
                   8093:     t0 = tcg_temp_new_i64();                                                  \
                   8094:     t1 = tcg_temp_new_i64();                                                  \
                   8095:     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
                   8096:     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
                   8097:     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
                   8098:     tcg_temp_free_i64(t0);                                                    \
                   8099:     tcg_temp_free_i64(t1);                                                    \
                   8100: }
                   8101: #endif
1.1       root     8102: 
1.1.1.5   root     8103: /* Single precision floating-point vectors operations */
                   8104: /* Arithmetic */
1.1.1.6   root     8105: GEN_SPEFPUOP_ARITH2_64_64(evfsadd);
                   8106: GEN_SPEFPUOP_ARITH2_64_64(evfssub);
                   8107: GEN_SPEFPUOP_ARITH2_64_64(evfsmul);
                   8108: GEN_SPEFPUOP_ARITH2_64_64(evfsdiv);
1.1.1.8   root     8109: static inline void gen_evfsabs(DisasContext *ctx)
1.1.1.6   root     8110: {
                   8111:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     8112:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8113:         return;
                   8114:     }
                   8115: #if defined(TARGET_PPC64)
1.1.1.10  root     8116:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000080000000LL);
1.1.1.6   root     8117: #else
1.1.1.10  root     8118:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x80000000);
                   8119:     tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
1.1.1.6   root     8120: #endif
                   8121: }
1.1.1.8   root     8122: static inline void gen_evfsnabs(DisasContext *ctx)
1.1.1.6   root     8123: {
                   8124:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     8125:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8126:         return;
                   8127:     }
                   8128: #if defined(TARGET_PPC64)
1.1.1.10  root     8129:     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
1.1.1.6   root     8130: #else
1.1.1.10  root     8131:     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
                   8132:     tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
1.1.1.6   root     8133: #endif
                   8134: }
1.1.1.8   root     8135: static inline void gen_evfsneg(DisasContext *ctx)
1.1.1.6   root     8136: {
                   8137:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     8138:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8139:         return;
                   8140:     }
                   8141: #if defined(TARGET_PPC64)
1.1.1.10  root     8142:     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
1.1.1.6   root     8143: #else
1.1.1.10  root     8144:     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
                   8145:     tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
1.1.1.6   root     8146: #endif
                   8147: }
                   8148: 
1.1.1.5   root     8149: /* Conversion */
1.1.1.6   root     8150: GEN_SPEFPUOP_CONV_64_64(evfscfui);
                   8151: GEN_SPEFPUOP_CONV_64_64(evfscfsi);
                   8152: GEN_SPEFPUOP_CONV_64_64(evfscfuf);
                   8153: GEN_SPEFPUOP_CONV_64_64(evfscfsf);
                   8154: GEN_SPEFPUOP_CONV_64_64(evfsctui);
                   8155: GEN_SPEFPUOP_CONV_64_64(evfsctsi);
                   8156: GEN_SPEFPUOP_CONV_64_64(evfsctuf);
                   8157: GEN_SPEFPUOP_CONV_64_64(evfsctsf);
                   8158: GEN_SPEFPUOP_CONV_64_64(evfsctuiz);
                   8159: GEN_SPEFPUOP_CONV_64_64(evfsctsiz);
                   8160: 
1.1.1.5   root     8161: /* Comparison */
1.1.1.6   root     8162: GEN_SPEFPUOP_COMP_64(evfscmpgt);
                   8163: GEN_SPEFPUOP_COMP_64(evfscmplt);
                   8164: GEN_SPEFPUOP_COMP_64(evfscmpeq);
                   8165: GEN_SPEFPUOP_COMP_64(evfststgt);
                   8166: GEN_SPEFPUOP_COMP_64(evfststlt);
                   8167: GEN_SPEFPUOP_COMP_64(evfststeq);
1.1.1.5   root     8168: 
                   8169: /* Opcodes definitions */
1.1.1.12! root     8170: GEN_SPE(evfsadd,   evfssub,   0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
        !          8171: GEN_SPE(evfsabs,   evfsnabs,  0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); //
        !          8172: GEN_SPE(evfsneg,   speundef,  0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); //
        !          8173: GEN_SPE(evfsmul,   evfsdiv,   0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
        !          8174: GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
        !          8175: GEN_SPE(evfscmpeq, speundef,  0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
        !          8176: GEN_SPE(evfscfui,  evfscfsi,  0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
        !          8177: GEN_SPE(evfscfuf,  evfscfsf,  0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
        !          8178: GEN_SPE(evfsctui,  evfsctsi,  0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
        !          8179: GEN_SPE(evfsctuf,  evfsctsf,  0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
        !          8180: GEN_SPE(evfsctuiz, speundef,  0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
        !          8181: GEN_SPE(evfsctsiz, speundef,  0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
        !          8182: GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
        !          8183: GEN_SPE(evfststeq, speundef,  0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
1.1.1.5   root     8184: 
                   8185: /* Single precision floating-point operations */
                   8186: /* Arithmetic */
1.1.1.6   root     8187: GEN_SPEFPUOP_ARITH2_32_32(efsadd);
                   8188: GEN_SPEFPUOP_ARITH2_32_32(efssub);
                   8189: GEN_SPEFPUOP_ARITH2_32_32(efsmul);
                   8190: GEN_SPEFPUOP_ARITH2_32_32(efsdiv);
1.1.1.8   root     8191: static inline void gen_efsabs(DisasContext *ctx)
1.1.1.6   root     8192: {
                   8193:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     8194:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8195:         return;
                   8196:     }
1.1.1.10  root     8197:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL);
1.1.1.6   root     8198: }
1.1.1.8   root     8199: static inline void gen_efsnabs(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:     }
1.1.1.10  root     8205:     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
1.1.1.6   root     8206: }
1.1.1.8   root     8207: static inline void gen_efsneg(DisasContext *ctx)
1.1.1.6   root     8208: {
                   8209:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     8210:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8211:         return;
                   8212:     }
1.1.1.10  root     8213:     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
1.1.1.6   root     8214: }
                   8215: 
1.1.1.5   root     8216: /* Conversion */
1.1.1.6   root     8217: GEN_SPEFPUOP_CONV_32_32(efscfui);
                   8218: GEN_SPEFPUOP_CONV_32_32(efscfsi);
                   8219: GEN_SPEFPUOP_CONV_32_32(efscfuf);
                   8220: GEN_SPEFPUOP_CONV_32_32(efscfsf);
                   8221: GEN_SPEFPUOP_CONV_32_32(efsctui);
                   8222: GEN_SPEFPUOP_CONV_32_32(efsctsi);
                   8223: GEN_SPEFPUOP_CONV_32_32(efsctuf);
                   8224: GEN_SPEFPUOP_CONV_32_32(efsctsf);
                   8225: GEN_SPEFPUOP_CONV_32_32(efsctuiz);
                   8226: GEN_SPEFPUOP_CONV_32_32(efsctsiz);
                   8227: GEN_SPEFPUOP_CONV_32_64(efscfd);
                   8228: 
1.1.1.5   root     8229: /* Comparison */
1.1.1.6   root     8230: GEN_SPEFPUOP_COMP_32(efscmpgt);
                   8231: GEN_SPEFPUOP_COMP_32(efscmplt);
                   8232: GEN_SPEFPUOP_COMP_32(efscmpeq);
                   8233: GEN_SPEFPUOP_COMP_32(efststgt);
                   8234: GEN_SPEFPUOP_COMP_32(efststlt);
                   8235: GEN_SPEFPUOP_COMP_32(efststeq);
1.1.1.5   root     8236: 
                   8237: /* Opcodes definitions */
1.1.1.12! root     8238: GEN_SPE(efsadd,   efssub,   0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
        !          8239: GEN_SPE(efsabs,   efsnabs,  0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE); //
        !          8240: GEN_SPE(efsneg,   speundef, 0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE); //
        !          8241: GEN_SPE(efsmul,   efsdiv,   0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE); //
        !          8242: GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
        !          8243: GEN_SPE(efscmpeq, efscfd,   0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE); //
        !          8244: GEN_SPE(efscfui,  efscfsi,  0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
        !          8245: GEN_SPE(efscfuf,  efscfsf,  0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
        !          8246: GEN_SPE(efsctui,  efsctsi,  0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
        !          8247: GEN_SPE(efsctuf,  efsctsf,  0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE); //
        !          8248: GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
        !          8249: GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
        !          8250: GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE); //
        !          8251: GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE); //
1.1.1.5   root     8252: 
                   8253: /* Double precision floating-point operations */
                   8254: /* Arithmetic */
1.1.1.6   root     8255: GEN_SPEFPUOP_ARITH2_64_64(efdadd);
                   8256: GEN_SPEFPUOP_ARITH2_64_64(efdsub);
                   8257: GEN_SPEFPUOP_ARITH2_64_64(efdmul);
                   8258: GEN_SPEFPUOP_ARITH2_64_64(efddiv);
1.1.1.8   root     8259: static inline void gen_efdabs(DisasContext *ctx)
1.1.1.6   root     8260: {
                   8261:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     8262:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8263:         return;
                   8264:     }
                   8265: #if defined(TARGET_PPC64)
1.1.1.10  root     8266:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000000000000LL);
1.1.1.6   root     8267: #else
1.1.1.10  root     8268:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   8269:     tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
1.1.1.6   root     8270: #endif
                   8271: }
1.1.1.8   root     8272: static inline void gen_efdnabs(DisasContext *ctx)
1.1.1.6   root     8273: {
                   8274:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     8275:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8276:         return;
                   8277:     }
                   8278: #if defined(TARGET_PPC64)
1.1.1.10  root     8279:     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
1.1.1.6   root     8280: #else
1.1.1.10  root     8281:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   8282:     tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
1.1.1.6   root     8283: #endif
                   8284: }
1.1.1.8   root     8285: static inline void gen_efdneg(DisasContext *ctx)
1.1.1.6   root     8286: {
                   8287:     if (unlikely(!ctx->spe_enabled)) {
1.1.1.12! root     8288:         gen_exception(ctx, POWERPC_EXCP_SPEU);
1.1.1.6   root     8289:         return;
                   8290:     }
                   8291: #if defined(TARGET_PPC64)
1.1.1.10  root     8292:     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
1.1.1.6   root     8293: #else
1.1.1.10  root     8294:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
                   8295:     tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
1.1.1.6   root     8296: #endif
                   8297: }
                   8298: 
1.1.1.5   root     8299: /* Conversion */
1.1.1.6   root     8300: GEN_SPEFPUOP_CONV_64_32(efdcfui);
                   8301: GEN_SPEFPUOP_CONV_64_32(efdcfsi);
                   8302: GEN_SPEFPUOP_CONV_64_32(efdcfuf);
                   8303: GEN_SPEFPUOP_CONV_64_32(efdcfsf);
                   8304: GEN_SPEFPUOP_CONV_32_64(efdctui);
                   8305: GEN_SPEFPUOP_CONV_32_64(efdctsi);
                   8306: GEN_SPEFPUOP_CONV_32_64(efdctuf);
                   8307: GEN_SPEFPUOP_CONV_32_64(efdctsf);
                   8308: GEN_SPEFPUOP_CONV_32_64(efdctuiz);
                   8309: GEN_SPEFPUOP_CONV_32_64(efdctsiz);
                   8310: GEN_SPEFPUOP_CONV_64_32(efdcfs);
                   8311: GEN_SPEFPUOP_CONV_64_64(efdcfuid);
                   8312: GEN_SPEFPUOP_CONV_64_64(efdcfsid);
                   8313: GEN_SPEFPUOP_CONV_64_64(efdctuidz);
                   8314: GEN_SPEFPUOP_CONV_64_64(efdctsidz);
1.1.1.5   root     8315: 
                   8316: /* Comparison */
1.1.1.6   root     8317: GEN_SPEFPUOP_COMP_64(efdcmpgt);
                   8318: GEN_SPEFPUOP_COMP_64(efdcmplt);
                   8319: GEN_SPEFPUOP_COMP_64(efdcmpeq);
                   8320: GEN_SPEFPUOP_COMP_64(efdtstgt);
                   8321: GEN_SPEFPUOP_COMP_64(efdtstlt);
                   8322: GEN_SPEFPUOP_COMP_64(efdtsteq);
1.1.1.5   root     8323: 
                   8324: /* Opcodes definitions */
1.1.1.12! root     8325: GEN_SPE(efdadd,    efdsub,    0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); //
        !          8326: GEN_SPE(efdcfuid,  efdcfsid,  0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
        !          8327: GEN_SPE(efdabs,    efdnabs,   0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE); //
        !          8328: GEN_SPE(efdneg,    speundef,  0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
        !          8329: GEN_SPE(efdmul,    efddiv,    0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE); //
        !          8330: GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
        !          8331: GEN_SPE(efdcmpgt,  efdcmplt,  0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
        !          8332: GEN_SPE(efdcmpeq,  efdcfs,    0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE); //
        !          8333: GEN_SPE(efdcfui,   efdcfsi,   0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
        !          8334: GEN_SPE(efdcfuf,   efdcfsf,   0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
        !          8335: GEN_SPE(efdctui,   efdctsi,   0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
        !          8336: GEN_SPE(efdctuf,   efdctsf,   0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE); //
        !          8337: GEN_SPE(efdctuiz,  speundef,  0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
        !          8338: GEN_SPE(efdctsiz,  speundef,  0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
        !          8339: GEN_SPE(efdtstgt,  efdtstlt,  0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE); //
        !          8340: GEN_SPE(efdtsteq,  speundef,  0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE); //
1.1.1.5   root     8341: 
1.1.1.7   root     8342: static opcode_t opcodes[] = {
                   8343: GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
                   8344: GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
                   8345: GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
                   8346: GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400000, PPC_INTEGER),
                   8347: GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
                   8348: GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
                   8349: GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8350: GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8351: GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8352: GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8353: GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER),
                   8354: GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER),
                   8355: GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER),
                   8356: GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER),
                   8357: GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8358: #if defined(TARGET_PPC64)
                   8359: GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B),
                   8360: #endif
                   8361: GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER),
                   8362: GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER),
                   8363: GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8364: GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8365: GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8366: GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
                   8367: GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
                   8368: GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
                   8369: GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8370: GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8371: GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8372: GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8373: GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB),
1.1.1.11  root     8374: GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD),
1.1.1.7   root     8375: #if defined(TARGET_PPC64)
1.1.1.11  root     8376: GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD),
1.1.1.7   root     8377: GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
                   8378: #endif
                   8379: GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8380: GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8381: GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8382: GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER),
                   8383: GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER),
                   8384: GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER),
                   8385: GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER),
                   8386: #if defined(TARGET_PPC64)
                   8387: GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B),
                   8388: GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B),
                   8389: GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B),
                   8390: GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B),
                   8391: GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B),
                   8392: #endif
                   8393: GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES),
                   8394: GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
                   8395: GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT),
                   8396: GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT),
                   8397: GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT),
                   8398: GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT),
                   8399: GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
                   8400: GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT),
                   8401: GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
                   8402: GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
                   8403: GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00010000, PPC_FLOAT),
                   8404: GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT),
                   8405: #if defined(TARGET_PPC64)
                   8406: GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
                   8407: GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
                   8408: GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
                   8409: #endif
                   8410: GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8411: GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
                   8412: GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING),
                   8413: GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING),
                   8414: GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
                   8415: GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
                   8416: GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO),
                   8417: GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
1.1.1.10  root     8418: GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES),
1.1.1.7   root     8419: GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
                   8420: #if defined(TARGET_PPC64)
1.1.1.10  root     8421: GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B),
1.1.1.7   root     8422: GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
                   8423: #endif
                   8424: GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC),
                   8425: GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT),
                   8426: GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
                   8427: GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
                   8428: GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW),
                   8429: GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW),
                   8430: GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
                   8431: GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
                   8432: #if defined(TARGET_PPC64)
                   8433: GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
                   8434: GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
                   8435: #endif
                   8436: GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
                   8437: GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
                   8438: GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
                   8439: #if defined(TARGET_PPC64)
                   8440: GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B),
                   8441: GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B),
                   8442: #endif
                   8443: GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
                   8444: GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC),
                   8445: GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC),
                   8446: GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
                   8447: GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
                   8448: GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
                   8449: #if defined(TARGET_PPC64)
                   8450: GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
                   8451: #endif
                   8452: GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC),
                   8453: GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC),
                   8454: GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
                   8455: GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
                   8456: GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
                   8457: GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE),
                   8458: GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE),
                   8459: GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ),
                   8460: GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT),
                   8461: GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
                   8462: GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC),
                   8463: GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
                   8464: GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI),
                   8465: GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA),
                   8466: GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
                   8467: GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
                   8468: GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT),
                   8469: GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT),
                   8470: #if defined(TARGET_PPC64)
                   8471: GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B),
                   8472: GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
                   8473:              PPC_SEGMENT_64B),
                   8474: GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
                   8475: GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
                   8476:              PPC_SEGMENT_64B),
1.1.1.11  root     8477: GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B),
                   8478: GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B),
                   8479: GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B),
1.1.1.7   root     8480: #endif
                   8481: GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
                   8482: GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE),
                   8483: GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE),
                   8484: GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
                   8485: #if defined(TARGET_PPC64)
                   8486: GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI),
                   8487: GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI),
                   8488: #endif
                   8489: GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN),
                   8490: GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN),
                   8491: GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR),
                   8492: GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR),
                   8493: GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR),
                   8494: GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR),
                   8495: GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR),
                   8496: GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR),
                   8497: GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR),
                   8498: GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR),
                   8499: GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR),
                   8500: GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
                   8501: GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR),
                   8502: GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR),
                   8503: GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR),
                   8504: GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR),
                   8505: GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR),
                   8506: GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR),
                   8507: GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR),
                   8508: GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
                   8509: GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR),
                   8510: GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR),
                   8511: GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR),
                   8512: GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR),
                   8513: GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR),
                   8514: GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR),
                   8515: GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR),
                   8516: GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR),
                   8517: GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR),
                   8518: GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR),
                   8519: GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR),
                   8520: GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR),
                   8521: GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR),
                   8522: GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR),
                   8523: GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR),
                   8524: GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR),
                   8525: GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC),
                   8526: GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC),
                   8527: GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC),
                   8528: GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB),
                   8529: GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB),
                   8530: GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB),
                   8531: GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB),
                   8532: GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER),
                   8533: GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER),
                   8534: GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER),
                   8535: GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER),
                   8536: GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER),
                   8537: GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER),
                   8538: GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
                   8539: GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
                   8540: GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2),
                   8541: GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2),
                   8542: GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
                   8543: GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
                   8544: GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2),
                   8545: GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2),
                   8546: GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI),
                   8547: GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA),
                   8548: GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR),
                   8549: GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR),
                   8550: GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX),
                   8551: GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX),
                   8552: GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX),
                   8553: GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX),
                   8554: GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON),
                   8555: GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON),
                   8556: GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT),
                   8557: GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON),
                   8558: GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON),
                   8559: GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP),
1.1.1.11  root     8560: GEN_HANDLER_E(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE, PPC2_BOOKE206),
1.1.1.7   root     8561: GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI),
                   8562: GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI),
                   8563: GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB),
                   8564: GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB),
                   8565: GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB),
                   8566: GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE),
                   8567: GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE),
                   8568: GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE),
1.1.1.11  root     8569: GEN_HANDLER2_E(tlbre_booke206, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001,
                   8570:                PPC_NONE, PPC2_BOOKE206),
                   8571: GEN_HANDLER2_E(tlbsx_booke206, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000,
                   8572:                PPC_NONE, PPC2_BOOKE206),
                   8573: GEN_HANDLER2_E(tlbwe_booke206, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001,
                   8574:                PPC_NONE, PPC2_BOOKE206),
                   8575: GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001,
                   8576:                PPC_NONE, PPC2_BOOKE206),
1.1.1.7   root     8577: GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
                   8578: GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
                   8579: GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
1.1.1.11  root     8580: GEN_HANDLER_E(mbar, 0x1F, 0x16, 0x1a, 0x001FF801,
                   8581:               PPC_BOOKE, PPC2_BOOKE206),
                   8582: GEN_HANDLER_E(msync, 0x1F, 0x16, 0x12, 0x03FFF801,
                   8583:               PPC_BOOKE, PPC2_BOOKE206),
                   8584: GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001,
                   8585:                PPC_BOOKE, PPC2_BOOKE206),
1.1.1.7   root     8586: GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC),
                   8587: GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC),
                   8588: GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
                   8589: GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
                   8590: GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC),
                   8591: GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC),
                   8592: GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE),
                   8593: GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE),
                   8594: GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE),
                   8595: GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE),
                   8596: 
                   8597: #undef GEN_INT_ARITH_ADD
                   8598: #undef GEN_INT_ARITH_ADD_CONST
                   8599: #define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
                   8600: GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER),
                   8601: #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
                   8602:                                 add_ca, compute_ca, compute_ov)               \
                   8603: GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER),
                   8604: GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
                   8605: GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
                   8606: GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
                   8607: GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
                   8608: GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
                   8609: GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
                   8610: GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
                   8611: GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
                   8612: GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
                   8613: GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
                   8614: 
                   8615: #undef GEN_INT_ARITH_DIVW
                   8616: #define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
                   8617: GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)
                   8618: GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0),
                   8619: GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1),
                   8620: GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0),
                   8621: GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1),
                   8622: 
                   8623: #if defined(TARGET_PPC64)
                   8624: #undef GEN_INT_ARITH_DIVD
                   8625: #define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
                   8626: GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
                   8627: GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0),
                   8628: GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1),
                   8629: GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0),
                   8630: GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
                   8631: 
                   8632: #undef GEN_INT_ARITH_MUL_HELPER
                   8633: #define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
                   8634: GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
                   8635: GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00),
                   8636: GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02),
                   8637: GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17),
                   8638: #endif
                   8639: 
                   8640: #undef GEN_INT_ARITH_SUBF
                   8641: #undef GEN_INT_ARITH_SUBF_CONST
                   8642: #define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
                   8643: GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER),
                   8644: #define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
                   8645:                                 add_ca, compute_ca, compute_ov)               \
                   8646: GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER),
                   8647: GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
                   8648: GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
                   8649: GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
                   8650: GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
                   8651: GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
                   8652: GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
                   8653: GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
                   8654: GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
                   8655: GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
                   8656: GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
                   8657: 
                   8658: #undef GEN_LOGICAL1
                   8659: #undef GEN_LOGICAL2
                   8660: #define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
                   8661: GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)
                   8662: #define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
                   8663: GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)
                   8664: GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER),
                   8665: GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER),
                   8666: GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER),
                   8667: GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER),
                   8668: GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER),
                   8669: GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER),
                   8670: GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER),
                   8671: GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER),
                   8672: #if defined(TARGET_PPC64)
                   8673: GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B),
                   8674: #endif
                   8675: 
                   8676: #if defined(TARGET_PPC64)
                   8677: #undef GEN_PPC64_R2
                   8678: #undef GEN_PPC64_R4
                   8679: #define GEN_PPC64_R2(name, opc1, opc2)                                        \
                   8680: GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
                   8681: GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
                   8682:              PPC_64B)
                   8683: #define GEN_PPC64_R4(name, opc1, opc2)                                        \
                   8684: GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
                   8685: GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
                   8686:              PPC_64B),                                                        \
                   8687: GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
                   8688:              PPC_64B),                                                        \
                   8689: GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
                   8690:              PPC_64B)
                   8691: GEN_PPC64_R4(rldicl, 0x1E, 0x00),
                   8692: GEN_PPC64_R4(rldicr, 0x1E, 0x02),
                   8693: GEN_PPC64_R4(rldic, 0x1E, 0x04),
                   8694: GEN_PPC64_R2(rldcl, 0x1E, 0x08),
                   8695: GEN_PPC64_R2(rldcr, 0x1E, 0x09),
                   8696: GEN_PPC64_R4(rldimi, 0x1E, 0x06),
                   8697: #endif
                   8698: 
                   8699: #undef _GEN_FLOAT_ACB
                   8700: #undef GEN_FLOAT_ACB
                   8701: #undef _GEN_FLOAT_AB
                   8702: #undef GEN_FLOAT_AB
                   8703: #undef _GEN_FLOAT_AC
                   8704: #undef GEN_FLOAT_AC
                   8705: #undef GEN_FLOAT_B
                   8706: #undef GEN_FLOAT_BS
                   8707: #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
                   8708: GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)
                   8709: #define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
                   8710: _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type),                     \
                   8711: _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type)
                   8712: #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
                   8713: GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
                   8714: #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
                   8715: _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
                   8716: _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
                   8717: #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
                   8718: GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)
                   8719: #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
                   8720: _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type),               \
                   8721: _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type)
                   8722: #define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
                   8723: GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)
                   8724: #define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
                   8725: GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)
                   8726: 
                   8727: GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT),
                   8728: GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT),
                   8729: GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT),
                   8730: GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT),
                   8731: GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES),
                   8732: GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE),
                   8733: _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL),
                   8734: GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT),
                   8735: GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT),
                   8736: GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT),
                   8737: GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT),
                   8738: GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT),
                   8739: GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT),
                   8740: GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT),
                   8741: GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT),
                   8742: #if defined(TARGET_PPC64)
                   8743: GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B),
                   8744: GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B),
                   8745: GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B),
                   8746: #endif
                   8747: GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT),
                   8748: GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT),
                   8749: GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT),
                   8750: GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT),
                   8751: GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT),
                   8752: GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT),
                   8753: GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT),
                   8754: 
                   8755: #undef GEN_LD
                   8756: #undef GEN_LDU
                   8757: #undef GEN_LDUX
                   8758: #undef GEN_LDX
                   8759: #undef GEN_LDS
                   8760: #define GEN_LD(name, ldop, opc, type)                                         \
                   8761: GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
                   8762: #define GEN_LDU(name, ldop, opc, type)                                        \
                   8763: GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
                   8764: #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
                   8765: GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
                   8766: #define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
                   8767: GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
                   8768: #define GEN_LDS(name, ldop, op, type)                                         \
                   8769: GEN_LD(name, ldop, op | 0x20, type)                                           \
                   8770: GEN_LDU(name, ldop, op | 0x21, type)                                          \
                   8771: GEN_LDUX(name, ldop, 0x17, op | 0x01, type)                                   \
                   8772: GEN_LDX(name, ldop, 0x17, op | 0x00, type)
                   8773: 
                   8774: GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER)
                   8775: GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER)
                   8776: GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER)
                   8777: GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER)
                   8778: #if defined(TARGET_PPC64)
                   8779: GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
                   8780: GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
                   8781: GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B)
                   8782: GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B)
                   8783: #endif
                   8784: GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
                   8785: GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
                   8786: 
                   8787: #undef GEN_ST
                   8788: #undef GEN_STU
                   8789: #undef GEN_STUX
                   8790: #undef GEN_STX
                   8791: #undef GEN_STS
                   8792: #define GEN_ST(name, stop, opc, type)                                         \
                   8793: GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
                   8794: #define GEN_STU(name, stop, opc, type)                                        \
                   8795: GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
                   8796: #define GEN_STUX(name, stop, opc2, opc3, type)                                \
                   8797: GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
                   8798: #define GEN_STX(name, stop, opc2, opc3, type)                                 \
                   8799: GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
                   8800: #define GEN_STS(name, stop, op, type)                                         \
                   8801: GEN_ST(name, stop, op | 0x20, type)                                           \
                   8802: GEN_STU(name, stop, op | 0x21, type)                                          \
                   8803: GEN_STUX(name, stop, 0x17, op | 0x01, type)                                   \
                   8804: GEN_STX(name, stop, 0x17, op | 0x00, type)
                   8805: 
                   8806: GEN_STS(stb, st8, 0x06, PPC_INTEGER)
                   8807: GEN_STS(sth, st16, 0x0C, PPC_INTEGER)
                   8808: GEN_STS(stw, st32, 0x04, PPC_INTEGER)
                   8809: #if defined(TARGET_PPC64)
                   8810: GEN_STUX(std, st64, 0x15, 0x05, PPC_64B)
                   8811: GEN_STX(std, st64, 0x15, 0x04, PPC_64B)
                   8812: #endif
                   8813: GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
                   8814: GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
                   8815: 
                   8816: #undef GEN_LDF
                   8817: #undef GEN_LDUF
                   8818: #undef GEN_LDUXF
                   8819: #undef GEN_LDXF
                   8820: #undef GEN_LDFS
                   8821: #define GEN_LDF(name, ldop, opc, type)                                        \
                   8822: GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
                   8823: #define GEN_LDUF(name, ldop, opc, type)                                       \
                   8824: GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
                   8825: #define GEN_LDUXF(name, ldop, opc, type)                                      \
                   8826: GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
                   8827: #define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
                   8828: GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
                   8829: #define GEN_LDFS(name, ldop, op, type)                                        \
                   8830: GEN_LDF(name, ldop, op | 0x20, type)                                          \
                   8831: GEN_LDUF(name, ldop, op | 0x21, type)                                         \
                   8832: GEN_LDUXF(name, ldop, op | 0x01, type)                                        \
                   8833: GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
                   8834: 
                   8835: GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT)
                   8836: GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT)
                   8837: 
                   8838: #undef GEN_STF
                   8839: #undef GEN_STUF
                   8840: #undef GEN_STUXF
                   8841: #undef GEN_STXF
                   8842: #undef GEN_STFS
                   8843: #define GEN_STF(name, stop, opc, type)                                        \
                   8844: GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
                   8845: #define GEN_STUF(name, stop, opc, type)                                       \
                   8846: GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
                   8847: #define GEN_STUXF(name, stop, opc, type)                                      \
                   8848: GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
                   8849: #define GEN_STXF(name, stop, opc2, opc3, type)                                \
                   8850: GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
                   8851: #define GEN_STFS(name, stop, op, type)                                        \
                   8852: GEN_STF(name, stop, op | 0x20, type)                                          \
                   8853: GEN_STUF(name, stop, op | 0x21, type)                                         \
                   8854: GEN_STUXF(name, stop, op | 0x01, type)                                        \
                   8855: GEN_STXF(name, stop, 0x17, op | 0x00, type)
                   8856: 
                   8857: GEN_STFS(stfd, st64, 0x16, PPC_FLOAT)
                   8858: GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT)
                   8859: GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
                   8860: 
                   8861: #undef GEN_CRLOGIC
                   8862: #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
                   8863: GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)
                   8864: GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08),
                   8865: GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04),
                   8866: GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09),
                   8867: GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07),
                   8868: GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01),
                   8869: GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E),
                   8870: GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D),
                   8871: GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06),
                   8872: 
                   8873: #undef GEN_MAC_HANDLER
                   8874: #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
                   8875: GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)
                   8876: GEN_MAC_HANDLER(macchw, 0x0C, 0x05),
                   8877: GEN_MAC_HANDLER(macchwo, 0x0C, 0x15),
                   8878: GEN_MAC_HANDLER(macchws, 0x0C, 0x07),
                   8879: GEN_MAC_HANDLER(macchwso, 0x0C, 0x17),
                   8880: GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06),
                   8881: GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16),
                   8882: GEN_MAC_HANDLER(macchwu, 0x0C, 0x04),
                   8883: GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14),
                   8884: GEN_MAC_HANDLER(machhw, 0x0C, 0x01),
                   8885: GEN_MAC_HANDLER(machhwo, 0x0C, 0x11),
                   8886: GEN_MAC_HANDLER(machhws, 0x0C, 0x03),
                   8887: GEN_MAC_HANDLER(machhwso, 0x0C, 0x13),
                   8888: GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02),
                   8889: GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12),
                   8890: GEN_MAC_HANDLER(machhwu, 0x0C, 0x00),
                   8891: GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10),
                   8892: GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D),
                   8893: GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D),
                   8894: GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F),
                   8895: GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F),
                   8896: GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C),
                   8897: GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C),
                   8898: GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E),
                   8899: GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E),
                   8900: GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05),
                   8901: GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15),
                   8902: GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07),
                   8903: GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17),
                   8904: GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01),
                   8905: GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11),
                   8906: GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03),
                   8907: GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13),
                   8908: GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D),
                   8909: GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D),
                   8910: GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F),
                   8911: GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F),
                   8912: GEN_MAC_HANDLER(mulchw, 0x08, 0x05),
                   8913: GEN_MAC_HANDLER(mulchwu, 0x08, 0x04),
                   8914: GEN_MAC_HANDLER(mulhhw, 0x08, 0x01),
                   8915: GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00),
                   8916: GEN_MAC_HANDLER(mullhw, 0x08, 0x0D),
                   8917: GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C),
                   8918: 
                   8919: #undef GEN_VR_LDX
                   8920: #undef GEN_VR_STX
                   8921: #undef GEN_VR_LVE
                   8922: #undef GEN_VR_STVE
                   8923: #define GEN_VR_LDX(name, opc2, opc3)                                          \
                   8924: GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
                   8925: #define GEN_VR_STX(name, opc2, opc3)                                          \
                   8926: GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
                   8927: #define GEN_VR_LVE(name, opc2, opc3)                                    \
                   8928:     GEN_HANDLER(lve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
                   8929: #define GEN_VR_STVE(name, opc2, opc3)                                   \
                   8930:     GEN_HANDLER(stve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)
                   8931: GEN_VR_LDX(lvx, 0x07, 0x03),
                   8932: GEN_VR_LDX(lvxl, 0x07, 0x0B),
                   8933: GEN_VR_LVE(bx, 0x07, 0x00),
                   8934: GEN_VR_LVE(hx, 0x07, 0x01),
                   8935: GEN_VR_LVE(wx, 0x07, 0x02),
                   8936: GEN_VR_STX(svx, 0x07, 0x07),
                   8937: GEN_VR_STX(svxl, 0x07, 0x0F),
                   8938: GEN_VR_STVE(bx, 0x07, 0x04),
                   8939: GEN_VR_STVE(hx, 0x07, 0x05),
                   8940: GEN_VR_STVE(wx, 0x07, 0x06),
                   8941: 
                   8942: #undef GEN_VX_LOGICAL
                   8943: #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
                   8944: GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
                   8945: GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16),
                   8946: GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17),
                   8947: GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18),
                   8948: GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19),
                   8949: GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20),
                   8950: 
                   8951: #undef GEN_VXFORM
                   8952: #define GEN_VXFORM(name, opc2, opc3)                                    \
                   8953: GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
                   8954: GEN_VXFORM(vaddubm, 0, 0),
                   8955: GEN_VXFORM(vadduhm, 0, 1),
                   8956: GEN_VXFORM(vadduwm, 0, 2),
                   8957: GEN_VXFORM(vsububm, 0, 16),
                   8958: GEN_VXFORM(vsubuhm, 0, 17),
                   8959: GEN_VXFORM(vsubuwm, 0, 18),
                   8960: GEN_VXFORM(vmaxub, 1, 0),
                   8961: GEN_VXFORM(vmaxuh, 1, 1),
                   8962: GEN_VXFORM(vmaxuw, 1, 2),
                   8963: GEN_VXFORM(vmaxsb, 1, 4),
                   8964: GEN_VXFORM(vmaxsh, 1, 5),
                   8965: GEN_VXFORM(vmaxsw, 1, 6),
                   8966: GEN_VXFORM(vminub, 1, 8),
                   8967: GEN_VXFORM(vminuh, 1, 9),
                   8968: GEN_VXFORM(vminuw, 1, 10),
                   8969: GEN_VXFORM(vminsb, 1, 12),
                   8970: GEN_VXFORM(vminsh, 1, 13),
                   8971: GEN_VXFORM(vminsw, 1, 14),
                   8972: GEN_VXFORM(vavgub, 1, 16),
                   8973: GEN_VXFORM(vavguh, 1, 17),
                   8974: GEN_VXFORM(vavguw, 1, 18),
                   8975: GEN_VXFORM(vavgsb, 1, 20),
                   8976: GEN_VXFORM(vavgsh, 1, 21),
                   8977: GEN_VXFORM(vavgsw, 1, 22),
                   8978: GEN_VXFORM(vmrghb, 6, 0),
                   8979: GEN_VXFORM(vmrghh, 6, 1),
                   8980: GEN_VXFORM(vmrghw, 6, 2),
                   8981: GEN_VXFORM(vmrglb, 6, 4),
                   8982: GEN_VXFORM(vmrglh, 6, 5),
                   8983: GEN_VXFORM(vmrglw, 6, 6),
                   8984: GEN_VXFORM(vmuloub, 4, 0),
                   8985: GEN_VXFORM(vmulouh, 4, 1),
                   8986: GEN_VXFORM(vmulosb, 4, 4),
                   8987: GEN_VXFORM(vmulosh, 4, 5),
                   8988: GEN_VXFORM(vmuleub, 4, 8),
                   8989: GEN_VXFORM(vmuleuh, 4, 9),
                   8990: GEN_VXFORM(vmulesb, 4, 12),
                   8991: GEN_VXFORM(vmulesh, 4, 13),
                   8992: GEN_VXFORM(vslb, 2, 4),
                   8993: GEN_VXFORM(vslh, 2, 5),
                   8994: GEN_VXFORM(vslw, 2, 6),
                   8995: GEN_VXFORM(vsrb, 2, 8),
                   8996: GEN_VXFORM(vsrh, 2, 9),
                   8997: GEN_VXFORM(vsrw, 2, 10),
                   8998: GEN_VXFORM(vsrab, 2, 12),
                   8999: GEN_VXFORM(vsrah, 2, 13),
                   9000: GEN_VXFORM(vsraw, 2, 14),
                   9001: GEN_VXFORM(vslo, 6, 16),
                   9002: GEN_VXFORM(vsro, 6, 17),
                   9003: GEN_VXFORM(vaddcuw, 0, 6),
                   9004: GEN_VXFORM(vsubcuw, 0, 22),
                   9005: GEN_VXFORM(vaddubs, 0, 8),
                   9006: GEN_VXFORM(vadduhs, 0, 9),
                   9007: GEN_VXFORM(vadduws, 0, 10),
                   9008: GEN_VXFORM(vaddsbs, 0, 12),
                   9009: GEN_VXFORM(vaddshs, 0, 13),
                   9010: GEN_VXFORM(vaddsws, 0, 14),
                   9011: GEN_VXFORM(vsububs, 0, 24),
                   9012: GEN_VXFORM(vsubuhs, 0, 25),
                   9013: GEN_VXFORM(vsubuws, 0, 26),
                   9014: GEN_VXFORM(vsubsbs, 0, 28),
                   9015: GEN_VXFORM(vsubshs, 0, 29),
                   9016: GEN_VXFORM(vsubsws, 0, 30),
                   9017: GEN_VXFORM(vrlb, 2, 0),
                   9018: GEN_VXFORM(vrlh, 2, 1),
                   9019: GEN_VXFORM(vrlw, 2, 2),
                   9020: GEN_VXFORM(vsl, 2, 7),
                   9021: GEN_VXFORM(vsr, 2, 11),
                   9022: GEN_VXFORM(vpkuhum, 7, 0),
                   9023: GEN_VXFORM(vpkuwum, 7, 1),
                   9024: GEN_VXFORM(vpkuhus, 7, 2),
                   9025: GEN_VXFORM(vpkuwus, 7, 3),
                   9026: GEN_VXFORM(vpkshus, 7, 4),
                   9027: GEN_VXFORM(vpkswus, 7, 5),
                   9028: GEN_VXFORM(vpkshss, 7, 6),
                   9029: GEN_VXFORM(vpkswss, 7, 7),
                   9030: GEN_VXFORM(vpkpx, 7, 12),
                   9031: GEN_VXFORM(vsum4ubs, 4, 24),
                   9032: GEN_VXFORM(vsum4sbs, 4, 28),
                   9033: GEN_VXFORM(vsum4shs, 4, 25),
                   9034: GEN_VXFORM(vsum2sws, 4, 26),
                   9035: GEN_VXFORM(vsumsws, 4, 30),
                   9036: GEN_VXFORM(vaddfp, 5, 0),
                   9037: GEN_VXFORM(vsubfp, 5, 1),
                   9038: GEN_VXFORM(vmaxfp, 5, 16),
                   9039: GEN_VXFORM(vminfp, 5, 17),
                   9040: 
                   9041: #undef GEN_VXRFORM1
                   9042: #undef GEN_VXRFORM
                   9043: #define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
                   9044:     GEN_HANDLER2(name, str, 0x4, opc2, opc3, 0x00000000, PPC_ALTIVEC),
                   9045: #define GEN_VXRFORM(name, opc2, opc3)                                \
                   9046:     GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
                   9047:     GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
                   9048: GEN_VXRFORM(vcmpequb, 3, 0)
                   9049: GEN_VXRFORM(vcmpequh, 3, 1)
                   9050: GEN_VXRFORM(vcmpequw, 3, 2)
                   9051: GEN_VXRFORM(vcmpgtsb, 3, 12)
                   9052: GEN_VXRFORM(vcmpgtsh, 3, 13)
                   9053: GEN_VXRFORM(vcmpgtsw, 3, 14)
                   9054: GEN_VXRFORM(vcmpgtub, 3, 8)
                   9055: GEN_VXRFORM(vcmpgtuh, 3, 9)
                   9056: GEN_VXRFORM(vcmpgtuw, 3, 10)
                   9057: GEN_VXRFORM(vcmpeqfp, 3, 3)
                   9058: GEN_VXRFORM(vcmpgefp, 3, 7)
                   9059: GEN_VXRFORM(vcmpgtfp, 3, 11)
                   9060: GEN_VXRFORM(vcmpbfp, 3, 15)
                   9061: 
                   9062: #undef GEN_VXFORM_SIMM
                   9063: #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
                   9064:     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
                   9065: GEN_VXFORM_SIMM(vspltisb, 6, 12),
                   9066: GEN_VXFORM_SIMM(vspltish, 6, 13),
                   9067: GEN_VXFORM_SIMM(vspltisw, 6, 14),
                   9068: 
                   9069: #undef GEN_VXFORM_NOA
                   9070: #define GEN_VXFORM_NOA(name, opc2, opc3)                                \
                   9071:     GEN_HANDLER(name, 0x04, opc2, opc3, 0x001f0000, PPC_ALTIVEC)
                   9072: GEN_VXFORM_NOA(vupkhsb, 7, 8),
                   9073: GEN_VXFORM_NOA(vupkhsh, 7, 9),
                   9074: GEN_VXFORM_NOA(vupklsb, 7, 10),
                   9075: GEN_VXFORM_NOA(vupklsh, 7, 11),
                   9076: GEN_VXFORM_NOA(vupkhpx, 7, 13),
                   9077: GEN_VXFORM_NOA(vupklpx, 7, 15),
                   9078: GEN_VXFORM_NOA(vrefp, 5, 4),
                   9079: GEN_VXFORM_NOA(vrsqrtefp, 5, 5),
1.1.1.9   root     9080: GEN_VXFORM_NOA(vexptefp, 5, 6),
1.1.1.7   root     9081: GEN_VXFORM_NOA(vlogefp, 5, 7),
                   9082: GEN_VXFORM_NOA(vrfim, 5, 8),
                   9083: GEN_VXFORM_NOA(vrfin, 5, 9),
                   9084: GEN_VXFORM_NOA(vrfip, 5, 10),
                   9085: GEN_VXFORM_NOA(vrfiz, 5, 11),
                   9086: 
                   9087: #undef GEN_VXFORM_UIMM
                   9088: #define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
                   9089:     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)
                   9090: GEN_VXFORM_UIMM(vspltb, 6, 8),
                   9091: GEN_VXFORM_UIMM(vsplth, 6, 9),
                   9092: GEN_VXFORM_UIMM(vspltw, 6, 10),
                   9093: GEN_VXFORM_UIMM(vcfux, 5, 12),
                   9094: GEN_VXFORM_UIMM(vcfsx, 5, 13),
                   9095: GEN_VXFORM_UIMM(vctuxs, 5, 14),
                   9096: GEN_VXFORM_UIMM(vctsxs, 5, 15),
                   9097: 
                   9098: #undef GEN_VAFORM_PAIRED
                   9099: #define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
                   9100:     GEN_HANDLER(name0##_##name1, 0x04, opc2, 0xFF, 0x00000000, PPC_ALTIVEC)
                   9101: GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16),
                   9102: GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18),
                   9103: GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19),
                   9104: GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20),
                   9105: GEN_VAFORM_PAIRED(vsel, vperm, 21),
                   9106: GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23),
                   9107: 
                   9108: #undef GEN_SPE
1.1.1.12! root     9109: #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \
        !          9110:     GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE)
        !          9111: GEN_SPE(evaddw,      speundef,    0x00, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
        !          9112: GEN_SPE(evaddiw,     speundef,    0x01, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
        !          9113: GEN_SPE(evsubfw,     speundef,    0x02, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
        !          9114: GEN_SPE(evsubifw,    speundef,    0x03, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
        !          9115: GEN_SPE(evabs,       evneg,       0x04, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
        !          9116: GEN_SPE(evextsb,     evextsh,     0x05, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
        !          9117: GEN_SPE(evrndw,      evcntlzw,    0x06, 0x08, 0x0000F800, 0x0000F800, PPC_SPE),
        !          9118: GEN_SPE(evcntlsw,    brinc,       0x07, 0x08, 0x0000F800, 0x00000000, PPC_SPE),
        !          9119: GEN_SPE(evmra,       speundef,    0x02, 0x13, 0x0000F800, 0xFFFFFFFF, PPC_SPE),
        !          9120: GEN_SPE(speundef,    evand,       0x08, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
        !          9121: GEN_SPE(evandc,      speundef,    0x09, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
        !          9122: GEN_SPE(evxor,       evor,        0x0B, 0x08, 0x00000000, 0x00000000, PPC_SPE),
        !          9123: GEN_SPE(evnor,       eveqv,       0x0C, 0x08, 0x00000000, 0x00000000, PPC_SPE),
        !          9124: GEN_SPE(evmwumi,     evmwsmi,     0x0C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
        !          9125: GEN_SPE(evmwumia,    evmwsmia,    0x1C, 0x11, 0x00000000, 0x00000000, PPC_SPE),
        !          9126: GEN_SPE(evmwumiaa,   evmwsmiaa,   0x0C, 0x15, 0x00000000, 0x00000000, PPC_SPE),
        !          9127: GEN_SPE(speundef,    evorc,       0x0D, 0x08, 0xFFFFFFFF, 0x00000000, PPC_SPE),
        !          9128: GEN_SPE(evnand,      speundef,    0x0F, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
        !          9129: GEN_SPE(evsrwu,      evsrws,      0x10, 0x08, 0x00000000, 0x00000000, PPC_SPE),
        !          9130: GEN_SPE(evsrwiu,     evsrwis,     0x11, 0x08, 0x00000000, 0x00000000, PPC_SPE),
        !          9131: GEN_SPE(evslw,       speundef,    0x12, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
        !          9132: GEN_SPE(evslwi,      speundef,    0x13, 0x08, 0x00000000, 0xFFFFFFFF, PPC_SPE),
        !          9133: GEN_SPE(evrlw,       evsplati,    0x14, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
        !          9134: GEN_SPE(evrlwi,      evsplatfi,   0x15, 0x08, 0x00000000, 0x0000F800, PPC_SPE),
        !          9135: GEN_SPE(evmergehi,   evmergelo,   0x16, 0x08, 0x00000000, 0x00000000, PPC_SPE),
        !          9136: GEN_SPE(evmergehilo, evmergelohi, 0x17, 0x08, 0x00000000, 0x00000000, PPC_SPE),
        !          9137: GEN_SPE(evcmpgtu,    evcmpgts,    0x18, 0x08, 0x00600000, 0x00600000, PPC_SPE),
        !          9138: GEN_SPE(evcmpltu,    evcmplts,    0x19, 0x08, 0x00600000, 0x00600000, PPC_SPE),
        !          9139: GEN_SPE(evcmpeq,     speundef,    0x1A, 0x08, 0x00600000, 0xFFFFFFFF, PPC_SPE),
        !          9140: 
        !          9141: GEN_SPE(evfsadd,     evfssub,     0x00, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
        !          9142: GEN_SPE(evfsabs,     evfsnabs,    0x02, 0x0A, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
        !          9143: GEN_SPE(evfsneg,     speundef,    0x03, 0x0A, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
        !          9144: GEN_SPE(evfsmul,     evfsdiv,     0x04, 0x0A, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
        !          9145: GEN_SPE(evfscmpgt,   evfscmplt,   0x06, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
        !          9146: GEN_SPE(evfscmpeq,   speundef,    0x07, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
        !          9147: GEN_SPE(evfscfui,    evfscfsi,    0x08, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
        !          9148: GEN_SPE(evfscfuf,    evfscfsf,    0x09, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
        !          9149: GEN_SPE(evfsctui,    evfsctsi,    0x0A, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
        !          9150: GEN_SPE(evfsctuf,    evfsctsf,    0x0B, 0x0A, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
        !          9151: GEN_SPE(evfsctuiz,   speundef,    0x0C, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
        !          9152: GEN_SPE(evfsctsiz,   speundef,    0x0D, 0x0A, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
        !          9153: GEN_SPE(evfststgt,   evfststlt,   0x0E, 0x0A, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
        !          9154: GEN_SPE(evfststeq,   speundef,    0x0F, 0x0A, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
        !          9155: 
        !          9156: GEN_SPE(efsadd,      efssub,      0x00, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
        !          9157: GEN_SPE(efsabs,      efsnabs,     0x02, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_SINGLE),
        !          9158: GEN_SPE(efsneg,      speundef,    0x03, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_SINGLE),
        !          9159: GEN_SPE(efsmul,      efsdiv,      0x04, 0x0B, 0x00000000, 0x00000000, PPC_SPE_SINGLE),
        !          9160: GEN_SPE(efscmpgt,    efscmplt,    0x06, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
        !          9161: GEN_SPE(efscmpeq,    efscfd,      0x07, 0x0B, 0x00600000, 0x00180000, PPC_SPE_SINGLE),
        !          9162: GEN_SPE(efscfui,     efscfsi,     0x08, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
        !          9163: GEN_SPE(efscfuf,     efscfsf,     0x09, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
        !          9164: GEN_SPE(efsctui,     efsctsi,     0x0A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
        !          9165: GEN_SPE(efsctuf,     efsctsf,     0x0B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_SINGLE),
        !          9166: GEN_SPE(efsctuiz,    speundef,    0x0C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
        !          9167: GEN_SPE(efsctsiz,    speundef,    0x0D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_SINGLE),
        !          9168: GEN_SPE(efststgt,    efststlt,    0x0E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_SINGLE),
        !          9169: GEN_SPE(efststeq,    speundef,    0x0F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_SINGLE),
        !          9170: 
        !          9171: GEN_SPE(efdadd,      efdsub,      0x10, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
        !          9172: GEN_SPE(efdcfuid,    efdcfsid,    0x11, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
        !          9173: GEN_SPE(efdabs,      efdnabs,     0x12, 0x0B, 0x0000F800, 0x0000F800, PPC_SPE_DOUBLE),
        !          9174: GEN_SPE(efdneg,      speundef,    0x13, 0x0B, 0x0000F800, 0xFFFFFFFF, PPC_SPE_DOUBLE),
        !          9175: GEN_SPE(efdmul,      efddiv,      0x14, 0x0B, 0x00000000, 0x00000000, PPC_SPE_DOUBLE),
        !          9176: GEN_SPE(efdctuidz,   efdctsidz,   0x15, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
        !          9177: GEN_SPE(efdcmpgt,    efdcmplt,    0x16, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
        !          9178: GEN_SPE(efdcmpeq,    efdcfs,      0x17, 0x0B, 0x00600000, 0x00180000, PPC_SPE_DOUBLE),
        !          9179: GEN_SPE(efdcfui,     efdcfsi,     0x18, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
        !          9180: GEN_SPE(efdcfuf,     efdcfsf,     0x19, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
        !          9181: GEN_SPE(efdctui,     efdctsi,     0x1A, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
        !          9182: GEN_SPE(efdctuf,     efdctsf,     0x1B, 0x0B, 0x00180000, 0x00180000, PPC_SPE_DOUBLE),
        !          9183: GEN_SPE(efdctuiz,    speundef,    0x1C, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
        !          9184: GEN_SPE(efdctsiz,    speundef,    0x1D, 0x0B, 0x00180000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
        !          9185: GEN_SPE(efdtstgt,    efdtstlt,    0x1E, 0x0B, 0x00600000, 0x00600000, PPC_SPE_DOUBLE),
        !          9186: GEN_SPE(efdtsteq,    speundef,    0x1F, 0x0B, 0x00600000, 0xFFFFFFFF, PPC_SPE_DOUBLE),
1.1.1.7   root     9187: 
                   9188: #undef GEN_SPEOP_LDST
                   9189: #define GEN_SPEOP_LDST(name, opc2, sh)                                        \
                   9190: GEN_HANDLER(name, 0x04, opc2, 0x0C, 0x00000000, PPC_SPE)
                   9191: GEN_SPEOP_LDST(evldd, 0x00, 3),
                   9192: GEN_SPEOP_LDST(evldw, 0x01, 3),
                   9193: GEN_SPEOP_LDST(evldh, 0x02, 3),
                   9194: GEN_SPEOP_LDST(evlhhesplat, 0x04, 1),
                   9195: GEN_SPEOP_LDST(evlhhousplat, 0x06, 1),
                   9196: GEN_SPEOP_LDST(evlhhossplat, 0x07, 1),
                   9197: GEN_SPEOP_LDST(evlwhe, 0x08, 2),
                   9198: GEN_SPEOP_LDST(evlwhou, 0x0A, 2),
                   9199: GEN_SPEOP_LDST(evlwhos, 0x0B, 2),
                   9200: GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2),
                   9201: GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2),
                   9202: 
                   9203: GEN_SPEOP_LDST(evstdd, 0x10, 3),
                   9204: GEN_SPEOP_LDST(evstdw, 0x11, 3),
                   9205: GEN_SPEOP_LDST(evstdh, 0x12, 3),
                   9206: GEN_SPEOP_LDST(evstwhe, 0x18, 2),
                   9207: GEN_SPEOP_LDST(evstwho, 0x1A, 2),
                   9208: GEN_SPEOP_LDST(evstwwe, 0x1C, 2),
                   9209: GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
                   9210: };
1.1       root     9211: 
                   9212: #include "translate_init.c"
1.1.1.5   root     9213: #include "helper_regs.h"
1.1       root     9214: 
                   9215: /*****************************************************************************/
                   9216: /* Misc PowerPC helpers */
1.1.1.10  root     9217: void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
1.1.1.5   root     9218:                      int flags)
                   9219: {
1.1       root     9220: #define RGPL  4
                   9221: #define RFPL  4
                   9222: 
                   9223:     int i;
                   9224: 
1.1.1.8   root     9225:     cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
1.1.1.10  root     9226:                 TARGET_FMT_lx " XER " TARGET_FMT_lx "\n",
                   9227:                 env->nip, env->lr, env->ctr, env->xer);
1.1.1.8   root     9228:     cpu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx "  HF "
                   9229:                 TARGET_FMT_lx " idx %d\n", env->msr, env->spr[SPR_HID0],
                   9230:                 env->hflags, env->mmu_idx);
1.1.1.5   root     9231: #if !defined(NO_TIMER_DUMP)
1.1.1.10  root     9232:     cpu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
1.1.1.5   root     9233: #if !defined(CONFIG_USER_ONLY)
1.1.1.10  root     9234:                 " DECR %08" PRIu32
1.1.1.5   root     9235: #endif
                   9236:                 "\n",
                   9237:                 cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
                   9238: #if !defined(CONFIG_USER_ONLY)
                   9239:                 , cpu_ppc_load_decr(env)
                   9240: #endif
                   9241:                 );
                   9242: #endif
                   9243:     for (i = 0; i < 32; i++) {
1.1       root     9244:         if ((i & (RGPL - 1)) == 0)
                   9245:             cpu_fprintf(f, "GPR%02d", i);
1.1.1.8   root     9246:         cpu_fprintf(f, " %016" PRIx64, ppc_dump_gpr(env, i));
1.1       root     9247:         if ((i & (RGPL - 1)) == (RGPL - 1))
                   9248:             cpu_fprintf(f, "\n");
1.1.1.5   root     9249:     }
1.1       root     9250:     cpu_fprintf(f, "CR ");
1.1.1.5   root     9251:     for (i = 0; i < 8; i++)
1.1       root     9252:         cpu_fprintf(f, "%01x", env->crf[i]);
                   9253:     cpu_fprintf(f, "  [");
1.1.1.5   root     9254:     for (i = 0; i < 8; i++) {
                   9255:         char a = '-';
                   9256:         if (env->crf[i] & 0x08)
                   9257:             a = 'L';
                   9258:         else if (env->crf[i] & 0x04)
                   9259:             a = 'G';
                   9260:         else if (env->crf[i] & 0x02)
                   9261:             a = 'E';
1.1       root     9262:         cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
1.1.1.5   root     9263:     }
1.1.1.8   root     9264:     cpu_fprintf(f, " ]             RES " TARGET_FMT_lx "\n",
                   9265:                 env->reserve_addr);
1.1       root     9266:     for (i = 0; i < 32; i++) {
                   9267:         if ((i & (RFPL - 1)) == 0)
                   9268:             cpu_fprintf(f, "FPR%02d", i);
1.1.1.3   root     9269:         cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
1.1       root     9270:         if ((i & (RFPL - 1)) == (RFPL - 1))
                   9271:             cpu_fprintf(f, "\n");
                   9272:     }
1.1.1.6   root     9273:     cpu_fprintf(f, "FPSCR %08x\n", env->fpscr);
1.1.1.5   root     9274: #if !defined(CONFIG_USER_ONLY)
1.1.1.11  root     9275:     cpu_fprintf(f, " SRR0 " TARGET_FMT_lx "  SRR1 " TARGET_FMT_lx
                   9276:                    "    PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n",
                   9277:                 env->spr[SPR_SRR0], env->spr[SPR_SRR1],
                   9278:                 env->spr[SPR_PVR], env->spr[SPR_VRSAVE]);
                   9279: 
                   9280:     cpu_fprintf(f, "SPRG0 " TARGET_FMT_lx " SPRG1 " TARGET_FMT_lx
                   9281:                    "  SPRG2 " TARGET_FMT_lx "  SPRG3 " TARGET_FMT_lx "\n",
                   9282:                 env->spr[SPR_SPRG0], env->spr[SPR_SPRG1],
                   9283:                 env->spr[SPR_SPRG2], env->spr[SPR_SPRG3]);
                   9284: 
                   9285:     cpu_fprintf(f, "SPRG4 " TARGET_FMT_lx " SPRG5 " TARGET_FMT_lx
                   9286:                    "  SPRG6 " TARGET_FMT_lx "  SPRG7 " TARGET_FMT_lx "\n",
                   9287:                 env->spr[SPR_SPRG4], env->spr[SPR_SPRG5],
                   9288:                 env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]);
                   9289: 
                   9290:     if (env->excp_model == POWERPC_EXCP_BOOKE) {
                   9291:         cpu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx
                   9292:                        " MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n",
                   9293:                     env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
                   9294:                     env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
                   9295: 
                   9296:         cpu_fprintf(f, "  TCR " TARGET_FMT_lx "   TSR " TARGET_FMT_lx
                   9297:                        "    ESR " TARGET_FMT_lx "   DEAR " TARGET_FMT_lx "\n",
                   9298:                     env->spr[SPR_BOOKE_TCR], env->spr[SPR_BOOKE_TSR],
                   9299:                     env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
                   9300: 
                   9301:         cpu_fprintf(f, "  PIR " TARGET_FMT_lx " DECAR " TARGET_FMT_lx
                   9302:                        "   IVPR " TARGET_FMT_lx "   EPCR " TARGET_FMT_lx "\n",
                   9303:                     env->spr[SPR_BOOKE_PIR], env->spr[SPR_BOOKE_DECAR],
                   9304:                     env->spr[SPR_BOOKE_IVPR], env->spr[SPR_BOOKE_EPCR]);
                   9305: 
                   9306:         cpu_fprintf(f, " MCSR " TARGET_FMT_lx " SPRG8 " TARGET_FMT_lx
                   9307:                        "    EPR " TARGET_FMT_lx "\n",
                   9308:                     env->spr[SPR_BOOKE_MCSR], env->spr[SPR_BOOKE_SPRG8],
                   9309:                     env->spr[SPR_BOOKE_EPR]);
                   9310: 
                   9311:         /* FSL-specific */
                   9312:         cpu_fprintf(f, " MCAR " TARGET_FMT_lx "  PID1 " TARGET_FMT_lx
                   9313:                        "   PID2 " TARGET_FMT_lx "    SVR " TARGET_FMT_lx "\n",
                   9314:                     env->spr[SPR_Exxx_MCAR], env->spr[SPR_BOOKE_PID1],
                   9315:                     env->spr[SPR_BOOKE_PID2], env->spr[SPR_E500_SVR]);
                   9316: 
                   9317:         /*
                   9318:          * IVORs are left out as they are large and do not change often --
                   9319:          * they can be read with "p $ivor0", "p $ivor1", etc.
                   9320:          */
                   9321:     }
                   9322: 
1.1.1.12! root     9323: #if defined(TARGET_PPC64)
        !          9324:     if (env->flags & POWERPC_FLAG_CFAR) {
        !          9325:         cpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);
        !          9326:     }
        !          9327: #endif
        !          9328: 
1.1.1.11  root     9329:     switch (env->mmu_model) {
                   9330:     case POWERPC_MMU_32B:
                   9331:     case POWERPC_MMU_601:
                   9332:     case POWERPC_MMU_SOFT_6xx:
                   9333:     case POWERPC_MMU_SOFT_74xx:
                   9334: #if defined(TARGET_PPC64)
                   9335:     case POWERPC_MMU_620:
                   9336:     case POWERPC_MMU_64B:
                   9337: #endif
                   9338:         cpu_fprintf(f, " SDR1 " TARGET_FMT_lx "\n", env->spr[SPR_SDR1]);
                   9339:         break;
                   9340:     case POWERPC_MMU_BOOKE206:
                   9341:         cpu_fprintf(f, " MAS0 " TARGET_FMT_lx "  MAS1 " TARGET_FMT_lx
                   9342:                        "   MAS2 " TARGET_FMT_lx "   MAS3 " TARGET_FMT_lx "\n",
                   9343:                     env->spr[SPR_BOOKE_MAS0], env->spr[SPR_BOOKE_MAS1],
                   9344:                     env->spr[SPR_BOOKE_MAS2], env->spr[SPR_BOOKE_MAS3]);
                   9345: 
                   9346:         cpu_fprintf(f, " MAS4 " TARGET_FMT_lx "  MAS6 " TARGET_FMT_lx
                   9347:                        "   MAS7 " TARGET_FMT_lx "    PID " TARGET_FMT_lx "\n",
                   9348:                     env->spr[SPR_BOOKE_MAS4], env->spr[SPR_BOOKE_MAS6],
                   9349:                     env->spr[SPR_BOOKE_MAS7], env->spr[SPR_BOOKE_PID]);
                   9350: 
                   9351:         cpu_fprintf(f, "MMUCFG " TARGET_FMT_lx " TLB0CFG " TARGET_FMT_lx
                   9352:                        " TLB1CFG " TARGET_FMT_lx "\n",
                   9353:                     env->spr[SPR_MMUCFG], env->spr[SPR_BOOKE_TLB0CFG],
                   9354:                     env->spr[SPR_BOOKE_TLB1CFG]);
                   9355:         break;
                   9356:     default:
                   9357:         break;
                   9358:     }
1.1.1.5   root     9359: #endif
1.1       root     9360: 
                   9361: #undef RGPL
                   9362: #undef RFPL
1.1.1.5   root     9363: }
                   9364: 
1.1.1.10  root     9365: void cpu_dump_statistics (CPUState *env, FILE*f, fprintf_function cpu_fprintf,
1.1.1.5   root     9366:                           int flags)
                   9367: {
                   9368: #if defined(DO_PPC_STATISTICS)
                   9369:     opc_handler_t **t1, **t2, **t3, *handler;
                   9370:     int op1, op2, op3;
                   9371: 
                   9372:     t1 = env->opcodes;
                   9373:     for (op1 = 0; op1 < 64; op1++) {
                   9374:         handler = t1[op1];
                   9375:         if (is_indirect_opcode(handler)) {
                   9376:             t2 = ind_table(handler);
                   9377:             for (op2 = 0; op2 < 32; op2++) {
                   9378:                 handler = t2[op2];
                   9379:                 if (is_indirect_opcode(handler)) {
                   9380:                     t3 = ind_table(handler);
                   9381:                     for (op3 = 0; op3 < 32; op3++) {
                   9382:                         handler = t3[op3];
                   9383:                         if (handler->count == 0)
                   9384:                             continue;
                   9385:                         cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
1.1.1.9   root     9386:                                     "%016" PRIx64 " %" PRId64 "\n",
1.1.1.5   root     9387:                                     op1, op2, op3, op1, (op3 << 5) | op2,
                   9388:                                     handler->oname,
                   9389:                                     handler->count, handler->count);
                   9390:                     }
                   9391:                 } else {
                   9392:                     if (handler->count == 0)
                   9393:                         continue;
                   9394:                     cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
1.1.1.9   root     9395:                                 "%016" PRIx64 " %" PRId64 "\n",
1.1.1.5   root     9396:                                 op1, op2, op1, op2, handler->oname,
                   9397:                                 handler->count, handler->count);
                   9398:                 }
                   9399:             }
                   9400:         } else {
                   9401:             if (handler->count == 0)
                   9402:                 continue;
1.1.1.9   root     9403:             cpu_fprintf(f, "%02x       (%02x     ) %16s: %016" PRIx64
                   9404:                         " %" PRId64 "\n",
1.1.1.5   root     9405:                         op1, op1, handler->oname,
                   9406:                         handler->count, handler->count);
                   9407:         }
                   9408:     }
                   9409: #endif
1.1       root     9410: }
                   9411: 
                   9412: /*****************************************************************************/
1.1.1.8   root     9413: static inline void gen_intermediate_code_internal(CPUState *env,
                   9414:                                                   TranslationBlock *tb,
                   9415:                                                   int search_pc)
1.1       root     9416: {
                   9417:     DisasContext ctx, *ctxp = &ctx;
                   9418:     opc_handler_t **table, *handler;
                   9419:     target_ulong pc_start;
                   9420:     uint16_t *gen_opc_end;
1.1.1.6   root     9421:     CPUBreakpoint *bp;
1.1       root     9422:     int j, lj = -1;
1.1.1.6   root     9423:     int num_insns;
                   9424:     int max_insns;
1.1       root     9425: 
                   9426:     pc_start = tb->pc;
                   9427:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
                   9428:     ctx.nip = pc_start;
                   9429:     ctx.tb = tb;
1.1.1.5   root     9430:     ctx.exception = POWERPC_EXCP_NONE;
1.1       root     9431:     ctx.spr_cb = env->spr_cb;
1.1.1.6   root     9432:     ctx.mem_idx = env->mmu_idx;
                   9433:     ctx.access_type = -1;
                   9434:     ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
1.1.1.5   root     9435: #if defined(TARGET_PPC64)
                   9436:     ctx.sf_mode = msr_sf;
1.1.1.12! root     9437:     ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
1.1       root     9438: #endif
                   9439:     ctx.fpu_enabled = msr_fp;
1.1.1.5   root     9440:     if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
                   9441:         ctx.spe_enabled = msr_spe;
                   9442:     else
                   9443:         ctx.spe_enabled = 0;
                   9444:     if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
                   9445:         ctx.altivec_enabled = msr_vr;
                   9446:     else
                   9447:         ctx.altivec_enabled = 0;
                   9448:     if ((env->flags & POWERPC_FLAG_SE) && msr_se)
1.1.1.6   root     9449:         ctx.singlestep_enabled = CPU_SINGLE_STEP;
1.1.1.5   root     9450:     else
1.1.1.6   root     9451:         ctx.singlestep_enabled = 0;
1.1.1.5   root     9452:     if ((env->flags & POWERPC_FLAG_BE) && msr_be)
1.1.1.6   root     9453:         ctx.singlestep_enabled |= CPU_BRANCH_STEP;
                   9454:     if (unlikely(env->singlestep_enabled))
                   9455:         ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
1.1       root     9456: #if defined (DO_SINGLE_STEP) && 0
                   9457:     /* Single step trace mode */
                   9458:     msr_se = 1;
                   9459: #endif
1.1.1.6   root     9460:     num_insns = 0;
                   9461:     max_insns = tb->cflags & CF_COUNT_MASK;
                   9462:     if (max_insns == 0)
                   9463:         max_insns = CF_COUNT_MASK;
                   9464: 
                   9465:     gen_icount_start();
1.1       root     9466:     /* Set env in case of segfault during code fetch */
1.1.1.5   root     9467:     while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
1.1.1.8   root     9468:         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
                   9469:             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
1.1.1.6   root     9470:                 if (bp->pc == ctx.nip) {
                   9471:                     gen_debug_exception(ctxp);
1.1.1.3   root     9472:                     break;
                   9473:                 }
                   9474:             }
                   9475:         }
1.1.1.5   root     9476:         if (unlikely(search_pc)) {
1.1       root     9477:             j = gen_opc_ptr - gen_opc_buf;
                   9478:             if (lj < j) {
                   9479:                 lj++;
                   9480:                 while (lj < j)
                   9481:                     gen_opc_instr_start[lj++] = 0;
                   9482:             }
1.1.1.7   root     9483:             gen_opc_pc[lj] = ctx.nip;
                   9484:             gen_opc_instr_start[lj] = 1;
                   9485:             gen_opc_icount[lj] = num_insns;
1.1       root     9486:         }
1.1.1.6   root     9487:         LOG_DISAS("----------------\n");
1.1.1.8   root     9488:         LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
1.1.1.6   root     9489:                   ctx.nip, ctx.mem_idx, (int)msr_ir);
                   9490:         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
                   9491:             gen_io_start();
                   9492:         if (unlikely(ctx.le_mode)) {
1.1.1.5   root     9493:             ctx.opcode = bswap32(ldl_code(ctx.nip));
                   9494:         } else {
                   9495:             ctx.opcode = ldl_code(ctx.nip);
1.1       root     9496:         }
1.1.1.6   root     9497:         LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",
1.1       root     9498:                     ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
1.1.1.5   root     9499:                     opc3(ctx.opcode), little_endian ? "little" : "big");
1.1.1.8   root     9500:         if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
                   9501:             tcg_gen_debug_insn_start(ctx.nip);
1.1       root     9502:         ctx.nip += 4;
                   9503:         table = env->opcodes;
1.1.1.6   root     9504:         num_insns++;
1.1       root     9505:         handler = table[opc1(ctx.opcode)];
                   9506:         if (is_indirect_opcode(handler)) {
                   9507:             table = ind_table(handler);
                   9508:             handler = table[opc2(ctx.opcode)];
                   9509:             if (is_indirect_opcode(handler)) {
                   9510:                 table = ind_table(handler);
                   9511:                 handler = table[opc3(ctx.opcode)];
                   9512:             }
                   9513:         }
                   9514:         /* Is opcode *REALLY* valid ? */
1.1.1.5   root     9515:         if (unlikely(handler->handler == &gen_invalid)) {
1.1.1.6   root     9516:             if (qemu_log_enabled()) {
                   9517:                 qemu_log("invalid/unsupported opcode: "
1.1.1.8   root     9518:                          "%02x - %02x - %02x (%08x) " TARGET_FMT_lx " %d\n",
                   9519:                          opc1(ctx.opcode), opc2(ctx.opcode),
                   9520:                          opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
1.1       root     9521:             }
1.1.1.5   root     9522:         } else {
1.1.1.12! root     9523:             uint32_t inval;
        !          9524: 
        !          9525:             if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE) && Rc(ctx.opcode))) {
        !          9526:                 inval = handler->inval2;
        !          9527:             } else {
        !          9528:                 inval = handler->inval1;
        !          9529:             }
        !          9530: 
        !          9531:             if (unlikely((ctx.opcode & inval) != 0)) {
1.1.1.6   root     9532:                 if (qemu_log_enabled()) {
                   9533:                     qemu_log("invalid bits: %08x for opcode: "
1.1.1.8   root     9534:                              "%02x - %02x - %02x (%08x) " TARGET_FMT_lx "\n",
1.1.1.12! root     9535:                              ctx.opcode & inval, opc1(ctx.opcode),
1.1.1.8   root     9536:                              opc2(ctx.opcode), opc3(ctx.opcode),
                   9537:                              ctx.opcode, ctx.nip - 4);
1.1.1.5   root     9538:                 }
1.1.1.6   root     9539:                 gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
1.1       root     9540:                 break;
                   9541:             }
                   9542:         }
                   9543:         (*(handler->handler))(&ctx);
1.1.1.5   root     9544: #if defined(DO_PPC_STATISTICS)
                   9545:         handler->count++;
                   9546: #endif
1.1       root     9547:         /* Check trace mode exceptions */
1.1.1.6   root     9548:         if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
                   9549:                      (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
                   9550:                      ctx.exception != POWERPC_SYSCALL &&
                   9551:                      ctx.exception != POWERPC_EXCP_TRAP &&
                   9552:                      ctx.exception != POWERPC_EXCP_BRANCH)) {
                   9553:             gen_exception(ctxp, POWERPC_EXCP_TRACE);
1.1.1.5   root     9554:         } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
1.1.1.6   root     9555:                             (env->singlestep_enabled) ||
1.1.1.7   root     9556:                             singlestep ||
1.1.1.6   root     9557:                             num_insns >= max_insns)) {
1.1.1.5   root     9558:             /* if we reach a page boundary or are single stepping, stop
                   9559:              * generation
1.1       root     9560:              */
                   9561:             break;
1.1.1.5   root     9562:         }
1.1       root     9563:     }
1.1.1.6   root     9564:     if (tb->cflags & CF_LAST_IO)
                   9565:         gen_io_end();
1.1.1.5   root     9566:     if (ctx.exception == POWERPC_EXCP_NONE) {
1.1.1.2   root     9567:         gen_goto_tb(&ctx, 0, ctx.nip);
1.1.1.5   root     9568:     } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
1.1.1.6   root     9569:         if (unlikely(env->singlestep_enabled)) {
                   9570:             gen_debug_exception(ctxp);
                   9571:         }
1.1.1.5   root     9572:         /* Generate the return instruction */
1.1.1.6   root     9573:         tcg_gen_exit_tb(0);
1.1       root     9574:     }
1.1.1.6   root     9575:     gen_icount_end(tb, num_insns);
1.1       root     9576:     *gen_opc_ptr = INDEX_op_end;
1.1.1.5   root     9577:     if (unlikely(search_pc)) {
1.1       root     9578:         j = gen_opc_ptr - gen_opc_buf;
                   9579:         lj++;
                   9580:         while (lj <= j)
                   9581:             gen_opc_instr_start[lj++] = 0;
                   9582:     } else {
                   9583:         tb->size = ctx.nip - pc_start;
1.1.1.6   root     9584:         tb->icount = num_insns;
1.1       root     9585:     }
1.1.1.5   root     9586: #if defined(DEBUG_DISAS)
1.1.1.6   root     9587:     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1.1.1.5   root     9588:         int flags;
                   9589:         flags = env->bfd_mach;
1.1.1.6   root     9590:         flags |= ctx.le_mode << 16;
                   9591:         qemu_log("IN: %s\n", lookup_symbol(pc_start));
                   9592:         log_target_disas(pc_start, ctx.nip - pc_start, flags);
                   9593:         qemu_log("\n");
1.1       root     9594:     }
                   9595: #endif
                   9596: }
                   9597: 
1.1.1.6   root     9598: void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
                   9599: {
                   9600:     gen_intermediate_code_internal(env, tb, 0);
                   9601: }
                   9602: 
                   9603: void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
1.1       root     9604: {
1.1.1.6   root     9605:     gen_intermediate_code_internal(env, tb, 1);
1.1       root     9606: }
                   9607: 
1.1.1.11  root     9608: void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
1.1       root     9609: {
1.1.1.6   root     9610:     env->nip = gen_opc_pc[pc_pos];
1.1       root     9611: }

unix.superglobalmegacorp.com

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