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

1.1       root        1: /*
                      2:  *  PowerPC emulation for qemu: main translation routines.
1.1.1.5   root        3:  *
                      4:  *  Copyright (c) 2003-2007 Jocelyn Mayer
1.1       root        5:  *
                      6:  * This library is free software; you can redistribute it and/or
                      7:  * modify it under the terms of the GNU Lesser General Public
                      8:  * License as published by the Free Software Foundation; either
                      9:  * version 2 of the License, or (at your option) any later version.
                     10:  *
                     11:  * This library is distributed in the hope that it will be useful,
                     12:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     14:  * Lesser General Public License for more details.
                     15:  *
                     16:  * You should have received a copy of the GNU Lesser General Public
                     17:  * License along with this library; if not, write to the Free Software
1.1.1.6 ! root       18:  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
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 "exec-all.h"
                     28: #include "disas.h"
1.1.1.6 ! root       29: #include "tcg-op.h"
        !            30: #include "qemu-common.h"
        !            31: #include "host-utils.h"
        !            32: 
        !            33: #include "helper.h"
        !            34: #define GEN_HELPER 1
        !            35: #include "helper.h"
        !            36: 
        !            37: #define CPU_SINGLE_STEP 0x1
        !            38: #define CPU_BRANCH_STEP 0x2
        !            39: #define GDBSTUB_SINGLE_STEP 0x4
1.1       root       40: 
1.1.1.5   root       41: /* Include definitions for instructions classes and implementations flags */
1.1       root       42: //#define DO_SINGLE_STEP
                     43: //#define PPC_DEBUG_DISAS
1.1.1.5   root       44: //#define DO_PPC_STATISTICS
1.1       root       45: 
1.1.1.6 ! root       46: #ifdef PPC_DEBUG_DISAS
        !            47: #  define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
1.1.1.2   root       48: #else
1.1.1.6 ! root       49: #  define LOG_DISAS(...) do { } while (0)
1.1.1.2   root       50: #endif
1.1.1.6 ! root       51: /*****************************************************************************/
        !            52: /* Code translation helpers                                                  */
1.1.1.2   root       53: 
1.1.1.6 ! root       54: /* global register indexes */
        !            55: static TCGv_ptr cpu_env;
        !            56: static char cpu_reg_names[10*3 + 22*4 /* GPR */
        !            57: #if !defined(TARGET_PPC64)
        !            58:     + 10*4 + 22*5 /* SPE GPRh */
1.1.1.5   root       59: #endif
1.1.1.6 ! root       60:     + 10*4 + 22*5 /* FPR */
        !            61:     + 2*(10*6 + 22*7) /* AVRh, AVRl */
        !            62:     + 8*5 /* CRF */];
        !            63: static TCGv cpu_gpr[32];
        !            64: #if !defined(TARGET_PPC64)
        !            65: static TCGv cpu_gprh[32];
        !            66: #endif
        !            67: static TCGv_i64 cpu_fpr[32];
        !            68: static TCGv_i64 cpu_avrh[32], cpu_avrl[32];
        !            69: static TCGv_i32 cpu_crf[8];
        !            70: static TCGv cpu_nip;
        !            71: static TCGv cpu_msr;
        !            72: static TCGv cpu_ctr;
        !            73: static TCGv cpu_lr;
        !            74: static TCGv cpu_xer;
        !            75: static TCGv cpu_reserve;
        !            76: static TCGv_i32 cpu_fpscr;
        !            77: static TCGv_i32 cpu_access_type;
1.1       root       78: 
1.1.1.6 ! root       79: #include "gen-icount.h"
1.1       root       80: 
1.1.1.6 ! root       81: void ppc_translate_init(void)
1.1.1.5   root       82: {
1.1.1.6 ! root       83:     int i;
        !            84:     char* p;
        !            85:     static int done_init = 0;
        !            86: 
        !            87:     if (done_init)
        !            88:         return;
        !            89: 
        !            90:     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
        !            91: 
        !            92:     p = cpu_reg_names;
        !            93: 
        !            94:     for (i = 0; i < 8; i++) {
        !            95:         sprintf(p, "crf%d", i);
        !            96:         cpu_crf[i] = tcg_global_mem_new_i32(TCG_AREG0,
        !            97:                                             offsetof(CPUState, crf[i]), p);
        !            98:         p += 5;
        !            99:     }
        !           100: 
        !           101:     for (i = 0; i < 32; i++) {
        !           102:         sprintf(p, "r%d", i);
        !           103:         cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
        !           104:                                         offsetof(CPUState, gpr[i]), p);
        !           105:         p += (i < 10) ? 3 : 4;
        !           106: #if !defined(TARGET_PPC64)
        !           107:         sprintf(p, "r%dH", i);
        !           108:         cpu_gprh[i] = tcg_global_mem_new_i32(TCG_AREG0,
        !           109:                                              offsetof(CPUState, gprh[i]), p);
        !           110:         p += (i < 10) ? 4 : 5;
1.1.1.5   root      111: #endif
                    112: 
1.1.1.6 ! root      113:         sprintf(p, "fp%d", i);
        !           114:         cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0,
        !           115:                                             offsetof(CPUState, fpr[i]), p);
        !           116:         p += (i < 10) ? 4 : 5;
        !           117: 
        !           118:         sprintf(p, "avr%dH", i);
        !           119: #ifdef WORDS_BIGENDIAN
        !           120:         cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
        !           121:                                              offsetof(CPUState, avr[i].u64[0]), p);
        !           122: #else
        !           123:         cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
        !           124:                                              offsetof(CPUState, avr[i].u64[1]), p);
1.1.1.5   root      125: #endif
1.1.1.6 ! root      126:         p += (i < 10) ? 6 : 7;
1.1.1.5   root      127: 
1.1.1.6 ! root      128:         sprintf(p, "avr%dL", i);
        !           129: #ifdef WORDS_BIGENDIAN
        !           130:         cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
        !           131:                                              offsetof(CPUState, avr[i].u64[1]), p);
        !           132: #else
        !           133:         cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
        !           134:                                              offsetof(CPUState, avr[i].u64[0]), p);
1.1.1.5   root      135: #endif
1.1.1.6 ! root      136:         p += (i < 10) ? 6 : 7;
        !           137:     }
        !           138: 
        !           139:     cpu_nip = tcg_global_mem_new(TCG_AREG0,
        !           140:                                  offsetof(CPUState, nip), "nip");
        !           141: 
        !           142:     cpu_msr = tcg_global_mem_new(TCG_AREG0,
        !           143:                                  offsetof(CPUState, msr), "msr");
        !           144: 
        !           145:     cpu_ctr = tcg_global_mem_new(TCG_AREG0,
        !           146:                                  offsetof(CPUState, ctr), "ctr");
        !           147: 
        !           148:     cpu_lr = tcg_global_mem_new(TCG_AREG0,
        !           149:                                 offsetof(CPUState, lr), "lr");
        !           150: 
        !           151:     cpu_xer = tcg_global_mem_new(TCG_AREG0,
        !           152:                                  offsetof(CPUState, xer), "xer");
        !           153: 
        !           154:     cpu_reserve = tcg_global_mem_new(TCG_AREG0,
        !           155:                                      offsetof(CPUState, reserve), "reserve");
        !           156: 
        !           157:     cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0,
        !           158:                                        offsetof(CPUState, fpscr), "fpscr");
        !           159: 
        !           160:     cpu_access_type = tcg_global_mem_new_i32(TCG_AREG0,
        !           161:                                              offsetof(CPUState, access_type), "access_type");
        !           162: 
        !           163:     /* register helpers */
        !           164: #define GEN_HELPER 2
        !           165: #include "helper.h"
        !           166: 
        !           167:     done_init = 1;
        !           168: }
1.1       root      169: 
                    170: /* internal defines */
                    171: typedef struct DisasContext {
                    172:     struct TranslationBlock *tb;
                    173:     target_ulong nip;
                    174:     uint32_t opcode;
                    175:     uint32_t exception;
                    176:     /* Routine used to access memory */
                    177:     int mem_idx;
1.1.1.6 ! root      178:     int access_type;
1.1       root      179:     /* Translation flags */
1.1.1.6 ! root      180:     int le_mode;
1.1.1.5   root      181: #if defined(TARGET_PPC64)
                    182:     int sf_mode;
                    183: #endif
1.1       root      184:     int fpu_enabled;
1.1.1.5   root      185:     int altivec_enabled;
                    186:     int spe_enabled;
1.1       root      187:     ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
1.1.1.3   root      188:     int singlestep_enabled;
1.1       root      189: } DisasContext;
                    190: 
                    191: struct opc_handler_t {
                    192:     /* invalid bits */
                    193:     uint32_t inval;
                    194:     /* instruction type */
1.1.1.5   root      195:     uint64_t type;
1.1       root      196:     /* handler */
                    197:     void (*handler)(DisasContext *ctx);
1.1.1.5   root      198: #if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
1.1.1.6 ! root      199:     const char *oname;
1.1.1.5   root      200: #endif
                    201: #if defined(DO_PPC_STATISTICS)
                    202:     uint64_t count;
                    203: #endif
1.1       root      204: };
                    205: 
1.1.1.5   root      206: static always_inline void gen_reset_fpstatus (void)
                    207: {
                    208: #ifdef CONFIG_SOFTFLOAT
1.1.1.6 ! root      209:     gen_helper_reset_fpstatus();
1.1.1.5   root      210: #endif
                    211: }
                    212: 
1.1.1.6 ! root      213: static always_inline void gen_compute_fprf (TCGv_i64 arg, int set_fprf, int set_rc)
1.1.1.5   root      214: {
1.1.1.6 ! root      215:     TCGv_i32 t0 = tcg_temp_new_i32();
        !           216: 
1.1.1.5   root      217:     if (set_fprf != 0) {
                    218:         /* This case might be optimized later */
1.1.1.6 ! root      219:         tcg_gen_movi_i32(t0, 1);
        !           220:         gen_helper_compute_fprf(t0, arg, t0);
        !           221:         if (unlikely(set_rc)) {
        !           222:             tcg_gen_mov_i32(cpu_crf[1], t0);
        !           223:         }
        !           224:         gen_helper_float_check_status();
1.1.1.5   root      225:     } else if (unlikely(set_rc)) {
                    226:         /* We always need to compute fpcc */
1.1.1.6 ! root      227:         tcg_gen_movi_i32(t0, 0);
        !           228:         gen_helper_compute_fprf(t0, arg, t0);
        !           229:         tcg_gen_mov_i32(cpu_crf[1], t0);
1.1.1.5   root      230:     }
1.1.1.6 ! root      231: 
        !           232:     tcg_temp_free_i32(t0);
1.1.1.5   root      233: }
                    234: 
1.1.1.6 ! root      235: static always_inline void gen_set_access_type (DisasContext *ctx, int access_type)
1.1.1.5   root      236: {
1.1.1.6 ! root      237:     if (ctx->access_type != access_type) {
        !           238:         tcg_gen_movi_i32(cpu_access_type, access_type);
        !           239:         ctx->access_type = access_type;
        !           240:     }
1.1.1.5   root      241: }
                    242: 
                    243: static always_inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
                    244: {
                    245: #if defined(TARGET_PPC64)
                    246:     if (ctx->sf_mode)
1.1.1.6 ! root      247:         tcg_gen_movi_tl(cpu_nip, nip);
1.1.1.5   root      248:     else
                    249: #endif
1.1.1.6 ! root      250:         tcg_gen_movi_tl(cpu_nip, (uint32_t)nip);
1.1.1.5   root      251: }
                    252: 
1.1.1.6 ! root      253: static always_inline void gen_exception_err (DisasContext *ctx, uint32_t excp, uint32_t error)
        !           254: {
        !           255:     TCGv_i32 t0, t1;
        !           256:     if (ctx->exception == POWERPC_EXCP_NONE) {
        !           257:         gen_update_nip(ctx, ctx->nip);
        !           258:     }
        !           259:     t0 = tcg_const_i32(excp);
        !           260:     t1 = tcg_const_i32(error);
        !           261:     gen_helper_raise_exception_err(t0, t1);
        !           262:     tcg_temp_free_i32(t0);
        !           263:     tcg_temp_free_i32(t1);
        !           264:     ctx->exception = (excp);
        !           265: }
1.1.1.5   root      266: 
1.1.1.6 ! root      267: static always_inline void gen_exception (DisasContext *ctx, uint32_t excp)
        !           268: {
        !           269:     TCGv_i32 t0;
        !           270:     if (ctx->exception == POWERPC_EXCP_NONE) {
        !           271:         gen_update_nip(ctx, ctx->nip);
        !           272:     }
        !           273:     t0 = tcg_const_i32(excp);
        !           274:     gen_helper_raise_exception(t0);
        !           275:     tcg_temp_free_i32(t0);
        !           276:     ctx->exception = (excp);
        !           277: }
1.1.1.5   root      278: 
1.1.1.6 ! root      279: static always_inline void gen_debug_exception (DisasContext *ctx)
        !           280: {
        !           281:     TCGv_i32 t0;
1.1       root      282: 
1.1.1.6 ! root      283:     if (ctx->exception != POWERPC_EXCP_BRANCH)
        !           284:         gen_update_nip(ctx, ctx->nip);
        !           285:     t0 = tcg_const_i32(EXCP_DEBUG);
        !           286:     gen_helper_raise_exception(t0);
        !           287:     tcg_temp_free_i32(t0);
        !           288: }
1.1       root      289: 
1.1.1.6 ! root      290: static always_inline void gen_inval_exception (DisasContext *ctx, uint32_t error)
        !           291: {
        !           292:     gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | error);
        !           293: }
1.1       root      294: 
1.1.1.2   root      295: /* Stop translation */
1.1.1.6 ! root      296: static always_inline void gen_stop_exception (DisasContext *ctx)
1.1       root      297: {
1.1.1.5   root      298:     gen_update_nip(ctx, ctx->nip);
                    299:     ctx->exception = POWERPC_EXCP_STOP;
1.1       root      300: }
                    301: 
1.1.1.2   root      302: /* No need to update nip here, as execution flow will change */
1.1.1.6 ! root      303: static always_inline void gen_sync_exception (DisasContext *ctx)
1.1       root      304: {
1.1.1.5   root      305:     ctx->exception = POWERPC_EXCP_SYNC;
1.1       root      306: }
                    307: 
                    308: #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
                    309: static void gen_##name (DisasContext *ctx);                                   \
                    310: GEN_OPCODE(name, opc1, opc2, opc3, inval, type);                              \
                    311: static void gen_##name (DisasContext *ctx)
                    312: 
1.1.1.5   root      313: #define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
                    314: static void gen_##name (DisasContext *ctx);                                   \
                    315: GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type);                       \
                    316: static void gen_##name (DisasContext *ctx)
                    317: 
1.1       root      318: typedef struct opcode_t {
                    319:     unsigned char opc1, opc2, opc3;
1.1.1.6 ! root      320: #if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
1.1       root      321:     unsigned char pad[5];
                    322: #else
                    323:     unsigned char pad[1];
                    324: #endif
                    325:     opc_handler_t handler;
1.1.1.6 ! root      326:     const char *oname;
1.1       root      327: } opcode_t;
                    328: 
1.1.1.5   root      329: /*****************************************************************************/
1.1       root      330: /***                           Instruction decoding                        ***/
                    331: #define EXTRACT_HELPER(name, shift, nb)                                       \
1.1.1.5   root      332: static always_inline uint32_t name (uint32_t opcode)                          \
1.1       root      333: {                                                                             \
                    334:     return (opcode >> (shift)) & ((1 << (nb)) - 1);                           \
                    335: }
                    336: 
                    337: #define EXTRACT_SHELPER(name, shift, nb)                                      \
1.1.1.5   root      338: static always_inline int32_t name (uint32_t opcode)                           \
1.1       root      339: {                                                                             \
                    340:     return (int16_t)((opcode >> (shift)) & ((1 << (nb)) - 1));                \
                    341: }
                    342: 
                    343: /* Opcode part 1 */
                    344: EXTRACT_HELPER(opc1, 26, 6);
                    345: /* Opcode part 2 */
                    346: EXTRACT_HELPER(opc2, 1, 5);
                    347: /* Opcode part 3 */
                    348: EXTRACT_HELPER(opc3, 6, 5);
                    349: /* Update Cr0 flags */
                    350: EXTRACT_HELPER(Rc, 0, 1);
                    351: /* Destination */
                    352: EXTRACT_HELPER(rD, 21, 5);
                    353: /* Source */
                    354: EXTRACT_HELPER(rS, 21, 5);
                    355: /* First operand */
                    356: EXTRACT_HELPER(rA, 16, 5);
                    357: /* Second operand */
                    358: EXTRACT_HELPER(rB, 11, 5);
                    359: /* Third operand */
                    360: EXTRACT_HELPER(rC, 6, 5);
                    361: /***                               Get CRn                                 ***/
                    362: EXTRACT_HELPER(crfD, 23, 3);
                    363: EXTRACT_HELPER(crfS, 18, 3);
                    364: EXTRACT_HELPER(crbD, 21, 5);
                    365: EXTRACT_HELPER(crbA, 16, 5);
                    366: EXTRACT_HELPER(crbB, 11, 5);
                    367: /* SPR / TBL */
                    368: EXTRACT_HELPER(_SPR, 11, 10);
1.1.1.5   root      369: static always_inline uint32_t SPR (uint32_t opcode)
1.1       root      370: {
                    371:     uint32_t sprn = _SPR(opcode);
                    372: 
                    373:     return ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
                    374: }
                    375: /***                              Get constants                            ***/
                    376: EXTRACT_HELPER(IMM, 12, 8);
                    377: /* 16 bits signed immediate value */
                    378: EXTRACT_SHELPER(SIMM, 0, 16);
                    379: /* 16 bits unsigned immediate value */
                    380: EXTRACT_HELPER(UIMM, 0, 16);
1.1.1.6 ! root      381: /* 5 bits signed immediate value */
        !           382: EXTRACT_HELPER(SIMM5, 16, 5);
        !           383: /* 5 bits signed immediate value */
        !           384: EXTRACT_HELPER(UIMM5, 16, 5);
1.1       root      385: /* Bit count */
                    386: EXTRACT_HELPER(NB, 11, 5);
                    387: /* Shift count */
                    388: EXTRACT_HELPER(SH, 11, 5);
1.1.1.6 ! root      389: /* Vector shift count */
        !           390: EXTRACT_HELPER(VSH, 6, 4);
1.1       root      391: /* Mask start */
                    392: EXTRACT_HELPER(MB, 6, 5);
                    393: /* Mask end */
                    394: EXTRACT_HELPER(ME, 1, 5);
                    395: /* Trap operand */
                    396: EXTRACT_HELPER(TO, 21, 5);
                    397: 
                    398: EXTRACT_HELPER(CRM, 12, 8);
                    399: EXTRACT_HELPER(FM, 17, 8);
                    400: EXTRACT_HELPER(SR, 16, 4);
1.1.1.6 ! root      401: EXTRACT_HELPER(FPIMM, 12, 4);
1.1       root      402: 
                    403: /***                            Jump target decoding                       ***/
                    404: /* Displacement */
                    405: EXTRACT_SHELPER(d, 0, 16);
                    406: /* Immediate address */
1.1.1.5   root      407: static always_inline target_ulong LI (uint32_t opcode)
1.1       root      408: {
                    409:     return (opcode >> 0) & 0x03FFFFFC;
                    410: }
                    411: 
1.1.1.5   root      412: static always_inline uint32_t BD (uint32_t opcode)
1.1       root      413: {
                    414:     return (opcode >> 0) & 0xFFFC;
                    415: }
                    416: 
                    417: EXTRACT_HELPER(BO, 21, 5);
                    418: EXTRACT_HELPER(BI, 16, 5);
                    419: /* Absolute/relative address */
                    420: EXTRACT_HELPER(AA, 1, 1);
                    421: /* Link */
                    422: EXTRACT_HELPER(LK, 0, 1);
                    423: 
                    424: /* Create a mask between <start> and <end> bits */
1.1.1.5   root      425: static always_inline target_ulong MASK (uint32_t start, uint32_t end)
1.1       root      426: {
1.1.1.5   root      427:     target_ulong ret;
1.1       root      428: 
1.1.1.5   root      429: #if defined(TARGET_PPC64)
                    430:     if (likely(start == 0)) {
                    431:         ret = UINT64_MAX << (63 - end);
                    432:     } else if (likely(end == 63)) {
                    433:         ret = UINT64_MAX >> start;
                    434:     }
                    435: #else
                    436:     if (likely(start == 0)) {
                    437:         ret = UINT32_MAX << (31  - end);
                    438:     } else if (likely(end == 31)) {
                    439:         ret = UINT32_MAX >> start;
                    440:     }
                    441: #endif
                    442:     else {
                    443:         ret = (((target_ulong)(-1ULL)) >> (start)) ^
                    444:             (((target_ulong)(-1ULL) >> (end)) >> 1);
                    445:         if (unlikely(start > end))
                    446:             return ~ret;
                    447:     }
1.1       root      448: 
                    449:     return ret;
                    450: }
                    451: 
1.1.1.5   root      452: /*****************************************************************************/
                    453: /* PowerPC Instructions types definitions                                    */
                    454: enum {
                    455:     PPC_NONE           = 0x0000000000000000ULL,
                    456:     /* PowerPC base instructions set                                         */
                    457:     PPC_INSNS_BASE     = 0x0000000000000001ULL,
                    458:     /*   integer operations instructions                                     */
                    459: #define PPC_INTEGER PPC_INSNS_BASE
                    460:     /*   flow control instructions                                           */
                    461: #define PPC_FLOW    PPC_INSNS_BASE
                    462:     /*   virtual memory instructions                                         */
                    463: #define PPC_MEM     PPC_INSNS_BASE
                    464:     /*   ld/st with reservation instructions                                 */
                    465: #define PPC_RES     PPC_INSNS_BASE
                    466:     /*   spr/msr access instructions                                         */
                    467: #define PPC_MISC    PPC_INSNS_BASE
                    468:     /* Deprecated instruction sets                                           */
                    469:     /*   Original POWER instruction set                                      */
                    470:     PPC_POWER          = 0x0000000000000002ULL,
                    471:     /*   POWER2 instruction set extension                                    */
                    472:     PPC_POWER2         = 0x0000000000000004ULL,
                    473:     /*   Power RTC support                                                   */
                    474:     PPC_POWER_RTC      = 0x0000000000000008ULL,
                    475:     /*   Power-to-PowerPC bridge (601)                                       */
                    476:     PPC_POWER_BR       = 0x0000000000000010ULL,
                    477:     /* 64 bits PowerPC instruction set                                       */
                    478:     PPC_64B            = 0x0000000000000020ULL,
                    479:     /*   New 64 bits extensions (PowerPC 2.0x)                               */
                    480:     PPC_64BX           = 0x0000000000000040ULL,
                    481:     /*   64 bits hypervisor extensions                                       */
                    482:     PPC_64H            = 0x0000000000000080ULL,
                    483:     /*   New wait instruction (PowerPC 2.0x)                                 */
                    484:     PPC_WAIT           = 0x0000000000000100ULL,
                    485:     /*   Time base mftb instruction                                          */
                    486:     PPC_MFTB           = 0x0000000000000200ULL,
                    487: 
                    488:     /* Fixed-point unit extensions                                           */
                    489:     /*   PowerPC 602 specific                                                */
                    490:     PPC_602_SPEC       = 0x0000000000000400ULL,
                    491:     /*   isel instruction                                                    */
                    492:     PPC_ISEL           = 0x0000000000000800ULL,
                    493:     /*   popcntb instruction                                                 */
                    494:     PPC_POPCNTB        = 0x0000000000001000ULL,
                    495:     /*   string load / store                                                 */
                    496:     PPC_STRING         = 0x0000000000002000ULL,
                    497: 
                    498:     /* Floating-point unit extensions                                        */
                    499:     /*   Optional floating point instructions                                */
                    500:     PPC_FLOAT          = 0x0000000000010000ULL,
                    501:     /* New floating-point extensions (PowerPC 2.0x)                          */
                    502:     PPC_FLOAT_EXT      = 0x0000000000020000ULL,
                    503:     PPC_FLOAT_FSQRT    = 0x0000000000040000ULL,
                    504:     PPC_FLOAT_FRES     = 0x0000000000080000ULL,
                    505:     PPC_FLOAT_FRSQRTE  = 0x0000000000100000ULL,
                    506:     PPC_FLOAT_FRSQRTES = 0x0000000000200000ULL,
                    507:     PPC_FLOAT_FSEL     = 0x0000000000400000ULL,
                    508:     PPC_FLOAT_STFIWX   = 0x0000000000800000ULL,
                    509: 
                    510:     /* Vector/SIMD extensions                                                */
                    511:     /*   Altivec support                                                     */
                    512:     PPC_ALTIVEC        = 0x0000000001000000ULL,
                    513:     /*   PowerPC 2.03 SPE extension                                          */
                    514:     PPC_SPE            = 0x0000000002000000ULL,
1.1.1.6 ! root      515:     /*   PowerPC 2.03 SPE single-precision floating-point extension          */
        !           516:     PPC_SPE_SINGLE     = 0x0000000004000000ULL,
        !           517:     /*   PowerPC 2.03 SPE double-precision floating-point extension          */
        !           518:     PPC_SPE_DOUBLE     = 0x0000000008000000ULL,
1.1.1.5   root      519: 
                    520:     /* Optional memory control instructions                                  */
                    521:     PPC_MEM_TLBIA      = 0x0000000010000000ULL,
                    522:     PPC_MEM_TLBIE      = 0x0000000020000000ULL,
                    523:     PPC_MEM_TLBSYNC    = 0x0000000040000000ULL,
                    524:     /*   sync instruction                                                    */
                    525:     PPC_MEM_SYNC       = 0x0000000080000000ULL,
                    526:     /*   eieio instruction                                                   */
                    527:     PPC_MEM_EIEIO      = 0x0000000100000000ULL,
                    528: 
                    529:     /* Cache control instructions                                            */
                    530:     PPC_CACHE          = 0x0000000200000000ULL,
                    531:     /*   icbi instruction                                                    */
                    532:     PPC_CACHE_ICBI     = 0x0000000400000000ULL,
                    533:     /*   dcbz instruction with fixed cache line size                         */
                    534:     PPC_CACHE_DCBZ     = 0x0000000800000000ULL,
                    535:     /*   dcbz instruction with tunable cache line size                       */
                    536:     PPC_CACHE_DCBZT    = 0x0000001000000000ULL,
                    537:     /*   dcba instruction                                                    */
                    538:     PPC_CACHE_DCBA     = 0x0000002000000000ULL,
                    539:     /*   Freescale cache locking instructions                                */
                    540:     PPC_CACHE_LOCK     = 0x0000004000000000ULL,
                    541: 
                    542:     /* MMU related extensions                                                */
                    543:     /*   external control instructions                                       */
                    544:     PPC_EXTERN         = 0x0000010000000000ULL,
                    545:     /*   segment register access instructions                                */
                    546:     PPC_SEGMENT        = 0x0000020000000000ULL,
                    547:     /*   PowerPC 6xx TLB management instructions                             */
                    548:     PPC_6xx_TLB        = 0x0000040000000000ULL,
                    549:     /* PowerPC 74xx TLB management instructions                              */
                    550:     PPC_74xx_TLB       = 0x0000080000000000ULL,
                    551:     /*   PowerPC 40x TLB management instructions                             */
                    552:     PPC_40x_TLB        = 0x0000100000000000ULL,
                    553:     /*   segment register access instructions for PowerPC 64 "bridge"        */
                    554:     PPC_SEGMENT_64B    = 0x0000200000000000ULL,
                    555:     /*   SLB management                                                      */
                    556:     PPC_SLBI           = 0x0000400000000000ULL,
                    557: 
                    558:     /* Embedded PowerPC dedicated instructions                               */
                    559:     PPC_WRTEE          = 0x0001000000000000ULL,
                    560:     /* PowerPC 40x exception model                                           */
                    561:     PPC_40x_EXCP       = 0x0002000000000000ULL,
                    562:     /* PowerPC 405 Mac instructions                                          */
                    563:     PPC_405_MAC        = 0x0004000000000000ULL,
                    564:     /* PowerPC 440 specific instructions                                     */
                    565:     PPC_440_SPEC       = 0x0008000000000000ULL,
                    566:     /* BookE (embedded) PowerPC specification                                */
                    567:     PPC_BOOKE          = 0x0010000000000000ULL,
                    568:     /* mfapidi instruction                                                   */
                    569:     PPC_MFAPIDI        = 0x0020000000000000ULL,
                    570:     /* tlbiva instruction                                                    */
                    571:     PPC_TLBIVA         = 0x0040000000000000ULL,
                    572:     /* tlbivax instruction                                                   */
                    573:     PPC_TLBIVAX        = 0x0080000000000000ULL,
                    574:     /* PowerPC 4xx dedicated instructions                                    */
                    575:     PPC_4xx_COMMON     = 0x0100000000000000ULL,
                    576:     /* PowerPC 40x ibct instructions                                         */
                    577:     PPC_40x_ICBT       = 0x0200000000000000ULL,
                    578:     /* rfmci is not implemented in all BookE PowerPC                         */
                    579:     PPC_RFMCI          = 0x0400000000000000ULL,
                    580:     /* rfdi instruction                                                      */
                    581:     PPC_RFDI           = 0x0800000000000000ULL,
                    582:     /* DCR accesses                                                          */
                    583:     PPC_DCR            = 0x1000000000000000ULL,
                    584:     /* DCR extended accesse                                                  */
                    585:     PPC_DCRX           = 0x2000000000000000ULL,
                    586:     /* user-mode DCR access, implemented in PowerPC 460                      */
                    587:     PPC_DCRUX          = 0x4000000000000000ULL,
                    588: };
                    589: 
                    590: /*****************************************************************************/
                    591: /* PowerPC instructions table                                                */
1.1       root      592: #if HOST_LONG_BITS == 64
                    593: #define OPC_ALIGN 8
                    594: #else
                    595: #define OPC_ALIGN 4
                    596: #endif
                    597: #if defined(__APPLE__)
1.1.1.5   root      598: #define OPCODES_SECTION                                                       \
1.1       root      599:     __attribute__ ((section("__TEXT,__opcodes"), unused, aligned (OPC_ALIGN) ))
                    600: #else
1.1.1.5   root      601: #define OPCODES_SECTION                                                       \
1.1       root      602:     __attribute__ ((section(".opcodes"), unused, aligned (OPC_ALIGN) ))
                    603: #endif
                    604: 
1.1.1.5   root      605: #if defined(DO_PPC_STATISTICS)
                    606: #define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
                    607: OPCODES_SECTION opcode_t opc_##name = {                                       \
                    608:     .opc1 = op1,                                                              \
                    609:     .opc2 = op2,                                                              \
                    610:     .opc3 = op3,                                                              \
                    611:     .pad  = { 0, },                                                           \
                    612:     .handler = {                                                              \
                    613:         .inval   = invl,                                                      \
                    614:         .type = _typ,                                                         \
                    615:         .handler = &gen_##name,                                               \
                    616:         .oname = stringify(name),                                             \
                    617:     },                                                                        \
                    618:     .oname = stringify(name),                                                 \
                    619: }
                    620: #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
                    621: OPCODES_SECTION opcode_t opc_##name = {                                       \
                    622:     .opc1 = op1,                                                              \
                    623:     .opc2 = op2,                                                              \
                    624:     .opc3 = op3,                                                              \
                    625:     .pad  = { 0, },                                                           \
                    626:     .handler = {                                                              \
                    627:         .inval   = invl,                                                      \
                    628:         .type = _typ,                                                         \
                    629:         .handler = &gen_##name,                                               \
                    630:         .oname = onam,                                                        \
                    631:     },                                                                        \
                    632:     .oname = onam,                                                            \
                    633: }
                    634: #else
1.1       root      635: #define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
                    636: OPCODES_SECTION opcode_t opc_##name = {                                       \
                    637:     .opc1 = op1,                                                              \
                    638:     .opc2 = op2,                                                              \
                    639:     .opc3 = op3,                                                              \
                    640:     .pad  = { 0, },                                                           \
                    641:     .handler = {                                                              \
                    642:         .inval   = invl,                                                      \
                    643:         .type = _typ,                                                         \
                    644:         .handler = &gen_##name,                                               \
                    645:     },                                                                        \
                    646:     .oname = stringify(name),                                                 \
                    647: }
1.1.1.5   root      648: #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
                    649: OPCODES_SECTION opcode_t opc_##name = {                                       \
                    650:     .opc1 = op1,                                                              \
                    651:     .opc2 = op2,                                                              \
                    652:     .opc3 = op3,                                                              \
                    653:     .pad  = { 0, },                                                           \
                    654:     .handler = {                                                              \
                    655:         .inval   = invl,                                                      \
                    656:         .type = _typ,                                                         \
                    657:         .handler = &gen_##name,                                               \
                    658:     },                                                                        \
                    659:     .oname = onam,                                                            \
                    660: }
                    661: #endif
1.1       root      662: 
                    663: #define GEN_OPCODE_MARK(name)                                                 \
                    664: OPCODES_SECTION opcode_t opc_##name = {                                       \
                    665:     .opc1 = 0xFF,                                                             \
                    666:     .opc2 = 0xFF,                                                             \
                    667:     .opc3 = 0xFF,                                                             \
                    668:     .pad  = { 0, },                                                           \
                    669:     .handler = {                                                              \
                    670:         .inval   = 0x00000000,                                                \
                    671:         .type = 0x00,                                                         \
                    672:         .handler = NULL,                                                      \
                    673:     },                                                                        \
                    674:     .oname = stringify(name),                                                 \
                    675: }
                    676: 
1.1.1.6 ! root      677: /* SPR load/store helpers */
        !           678: static always_inline void gen_load_spr(TCGv t, int reg)
        !           679: {
        !           680:     tcg_gen_ld_tl(t, cpu_env, offsetof(CPUState, spr[reg]));
        !           681: }
        !           682: 
        !           683: static always_inline void gen_store_spr(int reg, TCGv t)
        !           684: {
        !           685:     tcg_gen_st_tl(t, cpu_env, offsetof(CPUState, spr[reg]));
        !           686: }
        !           687: 
1.1       root      688: /* Start opcode list */
                    689: GEN_OPCODE_MARK(start);
                    690: 
                    691: /* Invalid instruction */
                    692: GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
                    693: {
1.1.1.6 ! root      694:     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1       root      695: }
                    696: 
                    697: static opc_handler_t invalid_handler = {
                    698:     .inval   = 0xFFFFFFFF,
                    699:     .type    = PPC_NONE,
                    700:     .handler = gen_invalid,
                    701: };
                    702: 
1.1.1.6 ! root      703: /***                           Integer comparison                          ***/
1.1       root      704: 
1.1.1.6 ! root      705: static always_inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
        !           706: {
        !           707:     int l1, l2, l3;
1.1       root      708: 
1.1.1.6 ! root      709:     tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_xer);
        !           710:     tcg_gen_shri_i32(cpu_crf[crf], cpu_crf[crf], XER_SO);
        !           711:     tcg_gen_andi_i32(cpu_crf[crf], cpu_crf[crf], 1);
        !           712: 
        !           713:     l1 = gen_new_label();
        !           714:     l2 = gen_new_label();
        !           715:     l3 = gen_new_label();
        !           716:     if (s) {
        !           717:         tcg_gen_brcond_tl(TCG_COND_LT, arg0, arg1, l1);
        !           718:         tcg_gen_brcond_tl(TCG_COND_GT, arg0, arg1, l2);
        !           719:     } else {
        !           720:         tcg_gen_brcond_tl(TCG_COND_LTU, arg0, arg1, l1);
        !           721:         tcg_gen_brcond_tl(TCG_COND_GTU, arg0, arg1, l2);
        !           722:     }
        !           723:     tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_EQ);
        !           724:     tcg_gen_br(l3);
        !           725:     gen_set_label(l1);
        !           726:     tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_LT);
        !           727:     tcg_gen_br(l3);
        !           728:     gen_set_label(l2);
        !           729:     tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1 << CRF_GT);
        !           730:     gen_set_label(l3);
1.1.1.5   root      731: }
                    732: 
1.1.1.6 ! root      733: static always_inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
        !           734: {
        !           735:     TCGv t0 = tcg_const_local_tl(arg1);
        !           736:     gen_op_cmp(arg0, t0, s, crf);
        !           737:     tcg_temp_free(t0);
1.1.1.5   root      738: }
                    739: 
1.1.1.6 ! root      740: #if defined(TARGET_PPC64)
        !           741: static always_inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
        !           742: {
        !           743:     TCGv t0, t1;
        !           744:     t0 = tcg_temp_local_new();
        !           745:     t1 = tcg_temp_local_new();
        !           746:     if (s) {
        !           747:         tcg_gen_ext32s_tl(t0, arg0);
        !           748:         tcg_gen_ext32s_tl(t1, arg1);
        !           749:     } else {
        !           750:         tcg_gen_ext32u_tl(t0, arg0);
        !           751:         tcg_gen_ext32u_tl(t1, arg1);
        !           752:     }
        !           753:     gen_op_cmp(t0, t1, s, crf);
        !           754:     tcg_temp_free(t1);
        !           755:     tcg_temp_free(t0);
1.1.1.5   root      756: }
                    757: 
1.1.1.6 ! root      758: static always_inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf)
        !           759: {
        !           760:     TCGv t0 = tcg_const_local_tl(arg1);
        !           761:     gen_op_cmp32(arg0, t0, s, crf);
        !           762:     tcg_temp_free(t0);
1.1       root      763: }
1.1.1.5   root      764: #endif
1.1       root      765: 
1.1.1.6 ! root      766: static always_inline void gen_set_Rc0 (DisasContext *ctx, TCGv reg)
1.1.1.5   root      767: {
                    768: #if defined(TARGET_PPC64)
1.1.1.6 ! root      769:     if (!(ctx->sf_mode))
        !           770:         gen_op_cmpi32(reg, 0, 1, 0);
        !           771:     else
1.1.1.5   root      772: #endif
1.1.1.6 ! root      773:         gen_op_cmpi(reg, 0, 1, 0);
1.1.1.5   root      774: }
1.1.1.6 ! root      775: 
        !           776: /* cmp */
        !           777: GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER)
1.1.1.5   root      778: {
                    779: #if defined(TARGET_PPC64)
1.1.1.6 ! root      780:     if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
        !           781:         gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
        !           782:                      1, crfD(ctx->opcode));
        !           783:     else
1.1.1.5   root      784: #endif
1.1.1.6 ! root      785:         gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
        !           786:                    1, crfD(ctx->opcode));
1.1.1.5   root      787: }
1.1.1.6 ! root      788: 
        !           789: /* cmpi */
        !           790: GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1.1.1.5   root      791: {
1.1.1.6 ! root      792: #if defined(TARGET_PPC64)
        !           793:     if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
        !           794:         gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
        !           795:                       1, crfD(ctx->opcode));
        !           796:     else
1.1.1.5   root      797: #endif
1.1.1.6 ! root      798:         gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
        !           799:                     1, crfD(ctx->opcode));
1.1.1.5   root      800: }
1.1.1.6 ! root      801: 
        !           802: /* cmpl */
        !           803: GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400000, PPC_INTEGER)
1.1.1.5   root      804: {
1.1.1.6 ! root      805: #if defined(TARGET_PPC64)
        !           806:     if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
        !           807:         gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
        !           808:                      0, crfD(ctx->opcode));
        !           809:     else
1.1.1.5   root      810: #endif
1.1.1.6 ! root      811:         gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
        !           812:                    0, crfD(ctx->opcode));
1.1.1.5   root      813: }
1.1.1.6 ! root      814: 
        !           815: /* cmpli */
        !           816: GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER)
1.1.1.5   root      817: {
                    818: #if defined(TARGET_PPC64)
1.1.1.6 ! root      819:     if (!(ctx->sf_mode && (ctx->opcode & 0x00200000)))
        !           820:         gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
        !           821:                       0, crfD(ctx->opcode));
        !           822:     else
        !           823: #endif
        !           824:         gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
        !           825:                     0, crfD(ctx->opcode));
1.1.1.5   root      826: }
1.1.1.6 ! root      827: 
        !           828: /* isel (PowerPC 2.03 specification) */
        !           829: GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL)
1.1.1.5   root      830: {
1.1.1.6 ! root      831:     int l1, l2;
        !           832:     uint32_t bi = rC(ctx->opcode);
        !           833:     uint32_t mask;
        !           834:     TCGv_i32 t0;
        !           835: 
        !           836:     l1 = gen_new_label();
        !           837:     l2 = gen_new_label();
        !           838: 
        !           839:     mask = 1 << (3 - (bi & 0x03));
        !           840:     t0 = tcg_temp_new_i32();
        !           841:     tcg_gen_andi_i32(t0, cpu_crf[bi >> 2], mask);
        !           842:     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
        !           843:     if (rA(ctx->opcode) == 0)
        !           844:         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
        !           845:     else
        !           846:         tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
        !           847:     tcg_gen_br(l2);
        !           848:     gen_set_label(l1);
        !           849:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
        !           850:     gen_set_label(l2);
        !           851:     tcg_temp_free_i32(t0);
1.1.1.5   root      852: }
1.1.1.6 ! root      853: 
        !           854: /***                           Integer arithmetic                          ***/
        !           855: 
        !           856: static always_inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0, TCGv arg1, TCGv arg2, int sub)
1.1.1.5   root      857: {
1.1.1.6 ! root      858:     int l1;
        !           859:     TCGv t0;
        !           860: 
        !           861:     l1 = gen_new_label();
        !           862:     /* Start with XER OV disabled, the most likely case */
        !           863:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
        !           864:     t0 = tcg_temp_local_new();
        !           865:     tcg_gen_xor_tl(t0, arg0, arg1);
1.1.1.5   root      866: #if defined(TARGET_PPC64)
1.1.1.6 ! root      867:     if (!ctx->sf_mode)
        !           868:         tcg_gen_ext32s_tl(t0, t0);
1.1.1.5   root      869: #endif
1.1.1.6 ! root      870:     if (sub)
        !           871:         tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
        !           872:     else
        !           873:         tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
        !           874:     tcg_gen_xor_tl(t0, arg1, arg2);
        !           875: #if defined(TARGET_PPC64)
        !           876:     if (!ctx->sf_mode)
        !           877:         tcg_gen_ext32s_tl(t0, t0);
        !           878: #endif
        !           879:     if (sub)
        !           880:         tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
        !           881:     else
        !           882:         tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
        !           883:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
        !           884:     gen_set_label(l1);
        !           885:     tcg_temp_free(t0);
1.1.1.5   root      886: }
1.1.1.6 ! root      887: 
        !           888: static always_inline void gen_op_arith_compute_ca(DisasContext *ctx, TCGv arg1, TCGv arg2, int sub)
1.1.1.5   root      889: {
1.1.1.6 ! root      890:     int l1 = gen_new_label();
        !           891: 
1.1.1.5   root      892: #if defined(TARGET_PPC64)
1.1.1.6 ! root      893:     if (!(ctx->sf_mode)) {
        !           894:         TCGv t0, t1;
        !           895:         t0 = tcg_temp_new();
        !           896:         t1 = tcg_temp_new();
        !           897: 
        !           898:         tcg_gen_ext32u_tl(t0, arg1);
        !           899:         tcg_gen_ext32u_tl(t1, arg2);
        !           900:         if (sub) {
        !           901:             tcg_gen_brcond_tl(TCG_COND_GTU, t0, t1, l1);
        !           902:         } else {
        !           903:             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
        !           904:         }
        !           905:         tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
        !           906:         gen_set_label(l1);
        !           907:         tcg_temp_free(t0);
        !           908:         tcg_temp_free(t1);
        !           909:     } else
        !           910: #endif
        !           911:     {
        !           912:         if (sub) {
        !           913:             tcg_gen_brcond_tl(TCG_COND_GTU, arg1, arg2, l1);
        !           914:         } else {
        !           915:             tcg_gen_brcond_tl(TCG_COND_GEU, arg1, arg2, l1);
        !           916:         }
        !           917:         tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
        !           918:         gen_set_label(l1);
        !           919:     }
1.1.1.5   root      920: }
1.1.1.6 ! root      921: 
        !           922: /* Common add function */
        !           923: static always_inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
        !           924:                                            int add_ca, int compute_ca, int compute_ov)
        !           925: {
        !           926:     TCGv t0, t1;
        !           927: 
        !           928:     if ((!compute_ca && !compute_ov) ||
        !           929:         (!TCGV_EQUAL(ret,arg1) && !TCGV_EQUAL(ret, arg2)))  {
        !           930:         t0 = ret;
        !           931:     } else {
        !           932:         t0 = tcg_temp_local_new();
        !           933:     }
        !           934: 
        !           935:     if (add_ca) {
        !           936:         t1 = tcg_temp_local_new();
        !           937:         tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
        !           938:         tcg_gen_shri_tl(t1, t1, XER_CA);
        !           939:     }
        !           940: 
        !           941:     if (compute_ca && compute_ov) {
        !           942:         /* Start with XER CA and OV disabled, the most likely case */
        !           943:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
        !           944:     } else if (compute_ca) {
        !           945:         /* Start with XER CA disabled, the most likely case */
        !           946:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
        !           947:     } else if (compute_ov) {
        !           948:         /* Start with XER OV disabled, the most likely case */
        !           949:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
        !           950:     }
        !           951: 
        !           952:     tcg_gen_add_tl(t0, arg1, arg2);
        !           953: 
        !           954:     if (compute_ca) {
        !           955:         gen_op_arith_compute_ca(ctx, t0, arg1, 0);
        !           956:     }
        !           957:     if (add_ca) {
        !           958:         tcg_gen_add_tl(t0, t0, t1);
        !           959:         gen_op_arith_compute_ca(ctx, t0, t1, 0);
        !           960:         tcg_temp_free(t1);
        !           961:     }
        !           962:     if (compute_ov) {
        !           963:         gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0);
        !           964:     }
        !           965: 
        !           966:     if (unlikely(Rc(ctx->opcode) != 0))
        !           967:         gen_set_Rc0(ctx, t0);
        !           968: 
        !           969:     if (!TCGV_EQUAL(t0, ret)) {
        !           970:         tcg_gen_mov_tl(ret, t0);
        !           971:         tcg_temp_free(t0);
        !           972:     }
1.1.1.5   root      973: }
1.1.1.6 ! root      974: /* Add functions with two operands */
        !           975: #define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
        !           976: GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER)                  \
        !           977: {                                                                             \
        !           978:     gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
        !           979:                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
        !           980:                      add_ca, compute_ca, compute_ov);                         \
1.1.1.5   root      981: }
1.1.1.6 ! root      982: /* Add functions with one operand and one immediate */
        !           983: #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
        !           984:                                 add_ca, compute_ca, compute_ov)               \
        !           985: GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER)                  \
        !           986: {                                                                             \
        !           987:     TCGv t0 = tcg_const_local_tl(const_val);                                  \
        !           988:     gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
        !           989:                      cpu_gpr[rA(ctx->opcode)], t0,                            \
        !           990:                      add_ca, compute_ca, compute_ov);                         \
        !           991:     tcg_temp_free(t0);                                                        \
1.1.1.5   root      992: }
1.1.1.6 ! root      993: 
        !           994: /* add  add.  addo  addo. */
        !           995: GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
        !           996: GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
        !           997: /* addc  addc.  addco  addco. */
        !           998: GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
        !           999: GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
        !          1000: /* adde  adde.  addeo  addeo. */
        !          1001: GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
        !          1002: GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
        !          1003: /* addme  addme.  addmeo  addmeo.  */
        !          1004: GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
        !          1005: GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
        !          1006: /* addze  addze.  addzeo  addzeo.*/
        !          1007: GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
        !          1008: GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
1.1       root     1009: /* addi */
                   1010: GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1011: {
1.1.1.5   root     1012:     target_long simm = SIMM(ctx->opcode);
1.1       root     1013: 
                   1014:     if (rA(ctx->opcode) == 0) {
1.1.1.5   root     1015:         /* li case */
1.1.1.6 ! root     1016:         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm);
1.1       root     1017:     } else {
1.1.1.6 ! root     1018:         tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], simm);
1.1       root     1019:     }
                   1020: }
1.1.1.6 ! root     1021: /* addic  addic.*/
        !          1022: static always_inline void gen_op_addic (DisasContext *ctx, TCGv ret, TCGv arg1,
        !          1023:                                         int compute_Rc0)
1.1       root     1024: {
1.1.1.5   root     1025:     target_long simm = SIMM(ctx->opcode);
                   1026: 
1.1.1.6 ! root     1027:     /* Start with XER CA and OV disabled, the most likely case */
        !          1028:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
        !          1029: 
1.1.1.5   root     1030:     if (likely(simm != 0)) {
1.1.1.6 ! root     1031:         TCGv t0 = tcg_temp_local_new();
        !          1032:         tcg_gen_addi_tl(t0, arg1, simm);
        !          1033:         gen_op_arith_compute_ca(ctx, t0, arg1, 0);
        !          1034:         tcg_gen_mov_tl(ret, t0);
        !          1035:         tcg_temp_free(t0);
1.1.1.5   root     1036:     } else {
1.1.1.6 ! root     1037:         tcg_gen_mov_tl(ret, arg1);
        !          1038:     }
        !          1039:     if (compute_Rc0) {
        !          1040:         gen_set_Rc0(ctx, ret);
1.1.1.5   root     1041:     }
1.1       root     1042: }
1.1.1.6 ! root     1043: GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
        !          1044: {
        !          1045:     gen_op_addic(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
        !          1046: }
1.1.1.5   root     1047: GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1.1       root     1048: {
1.1.1.6 ! root     1049:     gen_op_addic(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
1.1       root     1050: }
                   1051: /* addis */
                   1052: GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1053: {
1.1.1.5   root     1054:     target_long simm = SIMM(ctx->opcode);
1.1       root     1055: 
                   1056:     if (rA(ctx->opcode) == 0) {
1.1.1.5   root     1057:         /* lis case */
1.1.1.6 ! root     1058:         tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm << 16);
1.1       root     1059:     } else {
1.1.1.6 ! root     1060:         tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], simm << 16);
1.1       root     1061:     }
                   1062: }
                   1063: 
1.1.1.6 ! root     1064: static always_inline void gen_op_arith_divw (DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
        !          1065:                                              int sign, int compute_ov)
        !          1066: {
        !          1067:     int l1 = gen_new_label();
        !          1068:     int l2 = gen_new_label();
        !          1069:     TCGv_i32 t0 = tcg_temp_local_new_i32();
        !          1070:     TCGv_i32 t1 = tcg_temp_local_new_i32();
        !          1071: 
        !          1072:     tcg_gen_trunc_tl_i32(t0, arg1);
        !          1073:     tcg_gen_trunc_tl_i32(t1, arg2);
        !          1074:     tcg_gen_brcondi_i32(TCG_COND_EQ, t1, 0, l1);
        !          1075:     if (sign) {
        !          1076:         int l3 = gen_new_label();
        !          1077:         tcg_gen_brcondi_i32(TCG_COND_NE, t1, -1, l3);
        !          1078:         tcg_gen_brcondi_i32(TCG_COND_EQ, t0, INT32_MIN, l1);
        !          1079:         gen_set_label(l3);
        !          1080:         tcg_gen_div_i32(t0, t0, t1);
        !          1081:     } else {
        !          1082:         tcg_gen_divu_i32(t0, t0, t1);
        !          1083:     }
        !          1084:     if (compute_ov) {
        !          1085:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
        !          1086:     }
        !          1087:     tcg_gen_br(l2);
        !          1088:     gen_set_label(l1);
        !          1089:     if (sign) {
        !          1090:         tcg_gen_sari_i32(t0, t0, 31);
        !          1091:     } else {
        !          1092:         tcg_gen_movi_i32(t0, 0);
        !          1093:     }
        !          1094:     if (compute_ov) {
        !          1095:         tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
        !          1096:     }
        !          1097:     gen_set_label(l2);
        !          1098:     tcg_gen_extu_i32_tl(ret, t0);
        !          1099:     tcg_temp_free_i32(t0);
        !          1100:     tcg_temp_free_i32(t1);
        !          1101:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1102:         gen_set_Rc0(ctx, ret);
        !          1103: }
        !          1104: /* Div functions */
        !          1105: #define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
        !          1106: GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)                  \
        !          1107: {                                                                             \
        !          1108:     gen_op_arith_divw(ctx, cpu_gpr[rD(ctx->opcode)],                          \
        !          1109:                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
        !          1110:                      sign, compute_ov);                                       \
        !          1111: }
        !          1112: /* divwu  divwu.  divwuo  divwuo.   */
        !          1113: GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0);
        !          1114: GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1);
        !          1115: /* divw  divw.  divwo  divwo.   */
        !          1116: GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0);
        !          1117: GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1);
        !          1118: #if defined(TARGET_PPC64)
        !          1119: static always_inline void gen_op_arith_divd (DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
        !          1120:                                              int sign, int compute_ov)
        !          1121: {
        !          1122:     int l1 = gen_new_label();
        !          1123:     int l2 = gen_new_label();
        !          1124: 
        !          1125:     tcg_gen_brcondi_i64(TCG_COND_EQ, arg2, 0, l1);
        !          1126:     if (sign) {
        !          1127:         int l3 = gen_new_label();
        !          1128:         tcg_gen_brcondi_i64(TCG_COND_NE, arg2, -1, l3);
        !          1129:         tcg_gen_brcondi_i64(TCG_COND_EQ, arg1, INT64_MIN, l1);
        !          1130:         gen_set_label(l3);
        !          1131:         tcg_gen_div_i64(ret, arg1, arg2);
        !          1132:     } else {
        !          1133:         tcg_gen_divu_i64(ret, arg1, arg2);
        !          1134:     }
        !          1135:     if (compute_ov) {
        !          1136:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
        !          1137:     }
        !          1138:     tcg_gen_br(l2);
        !          1139:     gen_set_label(l1);
        !          1140:     if (sign) {
        !          1141:         tcg_gen_sari_i64(ret, arg1, 63);
        !          1142:     } else {
        !          1143:         tcg_gen_movi_i64(ret, 0);
        !          1144:     }
        !          1145:     if (compute_ov) {
        !          1146:         tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
        !          1147:     }
        !          1148:     gen_set_label(l2);
        !          1149:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1150:         gen_set_Rc0(ctx, ret);
1.1.1.5   root     1151: }
1.1.1.6 ! root     1152: #define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
        !          1153: GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)                      \
1.1       root     1154: {                                                                             \
1.1.1.6 ! root     1155:     gen_op_arith_divd(ctx, cpu_gpr[rD(ctx->opcode)],                          \
        !          1156:                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
        !          1157:                       sign, compute_ov);                                      \
1.1       root     1158: }
1.1.1.6 ! root     1159: /* divwu  divwu.  divwuo  divwuo.   */
        !          1160: GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0);
        !          1161: GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1);
        !          1162: /* divw  divw.  divwo  divwo.   */
        !          1163: GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0);
        !          1164: GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
1.1.1.5   root     1165: #endif
1.1       root     1166: 
1.1.1.6 ! root     1167: /* mulhw  mulhw. */
        !          1168: GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER)
1.1       root     1169: {
1.1.1.6 ! root     1170:     TCGv_i64 t0, t1;
        !          1171: 
        !          1172:     t0 = tcg_temp_new_i64();
        !          1173:     t1 = tcg_temp_new_i64();
1.1.1.5   root     1174: #if defined(TARGET_PPC64)
1.1.1.6 ! root     1175:     tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
        !          1176:     tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
        !          1177:     tcg_gen_mul_i64(t0, t0, t1);
        !          1178:     tcg_gen_shri_i64(cpu_gpr[rD(ctx->opcode)], t0, 32);
        !          1179: #else
        !          1180:     tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
        !          1181:     tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
        !          1182:     tcg_gen_mul_i64(t0, t0, t1);
        !          1183:     tcg_gen_shri_i64(t0, t0, 32);
        !          1184:     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
1.1.1.5   root     1185: #endif
1.1.1.6 ! root     1186:     tcg_temp_free_i64(t0);
        !          1187:     tcg_temp_free_i64(t1);
        !          1188:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1189:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1       root     1190: }
1.1.1.6 ! root     1191: /* mulhwu  mulhwu.  */
        !          1192: GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER)
1.1       root     1193: {
1.1.1.6 ! root     1194:     TCGv_i64 t0, t1;
        !          1195: 
        !          1196:     t0 = tcg_temp_new_i64();
        !          1197:     t1 = tcg_temp_new_i64();
1.1.1.5   root     1198: #if defined(TARGET_PPC64)
1.1.1.6 ! root     1199:     tcg_gen_ext32u_i64(t0, cpu_gpr[rA(ctx->opcode)]);
        !          1200:     tcg_gen_ext32u_i64(t1, cpu_gpr[rB(ctx->opcode)]);
        !          1201:     tcg_gen_mul_i64(t0, t0, t1);
        !          1202:     tcg_gen_shri_i64(cpu_gpr[rD(ctx->opcode)], t0, 32);
        !          1203: #else
        !          1204:     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
        !          1205:     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
        !          1206:     tcg_gen_mul_i64(t0, t0, t1);
        !          1207:     tcg_gen_shri_i64(t0, t0, 32);
        !          1208:     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
1.1.1.5   root     1209: #endif
1.1.1.6 ! root     1210:     tcg_temp_free_i64(t0);
        !          1211:     tcg_temp_free_i64(t1);
        !          1212:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1213:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
        !          1214: }
        !          1215: /* mullw  mullw. */
        !          1216: GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER)
        !          1217: {
        !          1218:     tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
        !          1219:                    cpu_gpr[rB(ctx->opcode)]);
        !          1220:     tcg_gen_ext32s_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)]);
        !          1221:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1222:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1       root     1223: }
1.1.1.6 ! root     1224: /* mullwo  mullwo. */
        !          1225: GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER)
        !          1226: {
        !          1227:     int l1;
        !          1228:     TCGv_i64 t0, t1;
1.1       root     1229: 
1.1.1.6 ! root     1230:     t0 = tcg_temp_new_i64();
        !          1231:     t1 = tcg_temp_new_i64();
        !          1232:     l1 = gen_new_label();
        !          1233:     /* Start with XER OV disabled, the most likely case */
        !          1234:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
        !          1235: #if defined(TARGET_PPC64)
        !          1236:     tcg_gen_ext32s_i64(t0, cpu_gpr[rA(ctx->opcode)]);
        !          1237:     tcg_gen_ext32s_i64(t1, cpu_gpr[rB(ctx->opcode)]);
        !          1238: #else
        !          1239:     tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
        !          1240:     tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
        !          1241: #endif
        !          1242:     tcg_gen_mul_i64(t0, t0, t1);
        !          1243: #if defined(TARGET_PPC64)
        !          1244:     tcg_gen_ext32s_i64(cpu_gpr[rD(ctx->opcode)], t0);
        !          1245:     tcg_gen_brcond_i64(TCG_COND_EQ, t0, cpu_gpr[rD(ctx->opcode)], l1);
        !          1246: #else
        !          1247:     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
        !          1248:     tcg_gen_ext32s_i64(t1, t0);
        !          1249:     tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
        !          1250: #endif
        !          1251:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
        !          1252:     gen_set_label(l1);
        !          1253:     tcg_temp_free_i64(t0);
        !          1254:     tcg_temp_free_i64(t1);
        !          1255:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1256:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
        !          1257: }
        !          1258: /* mulli */
        !          1259: GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1.1.1.5   root     1260: {
1.1.1.6 ! root     1261:     tcg_gen_muli_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
        !          1262:                     SIMM(ctx->opcode));
        !          1263: }
        !          1264: #if defined(TARGET_PPC64)
        !          1265: #define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
        !          1266: GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)                      \
        !          1267: {                                                                             \
        !          1268:     gen_helper_##name (cpu_gpr[rD(ctx->opcode)],                              \
        !          1269:                        cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);   \
        !          1270:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
        !          1271:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);                           \
        !          1272: }
        !          1273: /* mulhd  mulhd. */
        !          1274: GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00);
        !          1275: /* mulhdu  mulhdu. */
        !          1276: GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02);
        !          1277: /* mulld  mulld. */
        !          1278: GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B)
        !          1279: {
        !          1280:     tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
        !          1281:                    cpu_gpr[rB(ctx->opcode)]);
        !          1282:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1283:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
        !          1284: }
        !          1285: /* mulldo  mulldo. */
        !          1286: GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17);
        !          1287: #endif
1.1.1.5   root     1288: 
1.1.1.6 ! root     1289: /* neg neg. nego nego. */
        !          1290: static always_inline void gen_op_arith_neg (DisasContext *ctx, TCGv ret, TCGv arg1, int ov_check)
        !          1291: {
        !          1292:     int l1 = gen_new_label();
        !          1293:     int l2 = gen_new_label();
        !          1294:     TCGv t0 = tcg_temp_local_new();
        !          1295: #if defined(TARGET_PPC64)
        !          1296:     if (ctx->sf_mode) {
        !          1297:         tcg_gen_mov_tl(t0, arg1);
        !          1298:         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT64_MIN, l1);
        !          1299:     } else
        !          1300: #endif
        !          1301:     {
        !          1302:         tcg_gen_ext32s_tl(t0, arg1);
        !          1303:         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT32_MIN, l1);
        !          1304:     }
        !          1305:     tcg_gen_neg_tl(ret, arg1);
        !          1306:     if (ov_check) {
        !          1307:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
        !          1308:     }
        !          1309:     tcg_gen_br(l2);
        !          1310:     gen_set_label(l1);
        !          1311:     tcg_gen_mov_tl(ret, t0);
        !          1312:     if (ov_check) {
        !          1313:         tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
        !          1314:     }
        !          1315:     gen_set_label(l2);
        !          1316:     tcg_temp_free(t0);
        !          1317:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1318:         gen_set_Rc0(ctx, ret);
        !          1319: }
        !          1320: GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER)
        !          1321: {
        !          1322:     gen_op_arith_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0);
        !          1323: }
        !          1324: GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER)
        !          1325: {
        !          1326:     gen_op_arith_neg(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 1);
        !          1327: }
        !          1328: 
        !          1329: /* Common subf function */
        !          1330: static always_inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2,
        !          1331:                                             int add_ca, int compute_ca, int compute_ov)
        !          1332: {
        !          1333:     TCGv t0, t1;
        !          1334: 
        !          1335:     if ((!compute_ca && !compute_ov) ||
        !          1336:         (!TCGV_EQUAL(ret, arg1) && !TCGV_EQUAL(ret, arg2)))  {
        !          1337:         t0 = ret;
1.1.1.5   root     1338:     } else {
1.1.1.6 ! root     1339:         t0 = tcg_temp_local_new();
1.1.1.5   root     1340:     }
1.1.1.6 ! root     1341: 
        !          1342:     if (add_ca) {
        !          1343:         t1 = tcg_temp_local_new();
        !          1344:         tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
        !          1345:         tcg_gen_shri_tl(t1, t1, XER_CA);
        !          1346:     }
        !          1347: 
        !          1348:     if (compute_ca && compute_ov) {
        !          1349:         /* Start with XER CA and OV disabled, the most likely case */
        !          1350:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV)));
        !          1351:     } else if (compute_ca) {
        !          1352:         /* Start with XER CA disabled, the most likely case */
        !          1353:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
        !          1354:     } else if (compute_ov) {
        !          1355:         /* Start with XER OV disabled, the most likely case */
        !          1356:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
        !          1357:     }
        !          1358: 
        !          1359:     if (add_ca) {
        !          1360:         tcg_gen_not_tl(t0, arg1);
        !          1361:         tcg_gen_add_tl(t0, t0, arg2);
        !          1362:         gen_op_arith_compute_ca(ctx, t0, arg2, 0);
        !          1363:         tcg_gen_add_tl(t0, t0, t1);
        !          1364:         gen_op_arith_compute_ca(ctx, t0, t1, 0);
        !          1365:         tcg_temp_free(t1);
        !          1366:     } else {
        !          1367:         tcg_gen_sub_tl(t0, arg2, arg1);
        !          1368:         if (compute_ca) {
        !          1369:             gen_op_arith_compute_ca(ctx, t0, arg2, 1);
        !          1370:         }
        !          1371:     }
        !          1372:     if (compute_ov) {
        !          1373:         gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1);
        !          1374:     }
        !          1375: 
        !          1376:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1377:         gen_set_Rc0(ctx, t0);
        !          1378: 
        !          1379:     if (!TCGV_EQUAL(t0, ret)) {
        !          1380:         tcg_gen_mov_tl(ret, t0);
        !          1381:         tcg_temp_free(t0);
        !          1382:     }
        !          1383: }
        !          1384: /* Sub functions with Two operands functions */
        !          1385: #define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
        !          1386: GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER)                  \
        !          1387: {                                                                             \
        !          1388:     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
        !          1389:                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
        !          1390:                       add_ca, compute_ca, compute_ov);                        \
        !          1391: }
        !          1392: /* Sub functions with one operand and one immediate */
        !          1393: #define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
        !          1394:                                 add_ca, compute_ca, compute_ov)               \
        !          1395: GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER)                  \
        !          1396: {                                                                             \
        !          1397:     TCGv t0 = tcg_const_local_tl(const_val);                                  \
        !          1398:     gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
        !          1399:                       cpu_gpr[rA(ctx->opcode)], t0,                           \
        !          1400:                       add_ca, compute_ca, compute_ov);                        \
        !          1401:     tcg_temp_free(t0);                                                        \
        !          1402: }
        !          1403: /* subf  subf.  subfo  subfo. */
        !          1404: GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
        !          1405: GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
        !          1406: /* subfc  subfc.  subfco  subfco. */
        !          1407: GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
        !          1408: GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
        !          1409: /* subfe  subfe.  subfeo  subfo. */
        !          1410: GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
        !          1411: GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
        !          1412: /* subfme  subfme.  subfmeo  subfmeo.  */
        !          1413: GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
        !          1414: GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
        !          1415: /* subfze  subfze.  subfzeo  subfzeo.*/
        !          1416: GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
        !          1417: GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
        !          1418: /* subfic */
        !          1419: GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
        !          1420: {
        !          1421:     /* Start with XER CA and OV disabled, the most likely case */
        !          1422:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
        !          1423:     TCGv t0 = tcg_temp_local_new();
        !          1424:     TCGv t1 = tcg_const_local_tl(SIMM(ctx->opcode));
        !          1425:     tcg_gen_sub_tl(t0, t1, cpu_gpr[rA(ctx->opcode)]);
        !          1426:     gen_op_arith_compute_ca(ctx, t0, t1, 1);
        !          1427:     tcg_temp_free(t1);
        !          1428:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
        !          1429:     tcg_temp_free(t0);
1.1.1.5   root     1430: }
                   1431: 
1.1       root     1432: /***                            Integer logical                            ***/
1.1.1.6 ! root     1433: #define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
        !          1434: GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)                          \
1.1       root     1435: {                                                                             \
1.1.1.6 ! root     1436:     tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],                \
        !          1437:        cpu_gpr[rB(ctx->opcode)]);                                             \
1.1.1.5   root     1438:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1.1.1.6 ! root     1439:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1.1       root     1440: }
                   1441: 
1.1.1.6 ! root     1442: #define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
1.1.1.5   root     1443: GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)                          \
1.1       root     1444: {                                                                             \
1.1.1.6 ! root     1445:     tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);               \
1.1.1.5   root     1446:     if (unlikely(Rc(ctx->opcode) != 0))                                       \
1.1.1.6 ! root     1447:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1.1       root     1448: }
                   1449: 
                   1450: /* and & and. */
1.1.1.6 ! root     1451: GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
1.1       root     1452: /* andc & andc. */
1.1.1.6 ! root     1453: GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
1.1       root     1454: /* andi. */
1.1.1.5   root     1455: GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1.1       root     1456: {
1.1.1.6 ! root     1457:     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode));
        !          1458:     gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1459: }
                   1460: /* andis. */
1.1.1.5   root     1461: GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1.1       root     1462: {
1.1.1.6 ! root     1463:     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode) << 16);
        !          1464:     gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1465: }
                   1466: /* cntlzw */
1.1.1.6 ! root     1467: GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER)
        !          1468: {
        !          1469:     gen_helper_cntlzw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
        !          1470:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1471:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
        !          1472: }
1.1       root     1473: /* eqv & eqv. */
1.1.1.6 ! root     1474: GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
1.1       root     1475: /* extsb & extsb. */
1.1.1.6 ! root     1476: GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
1.1       root     1477: /* extsh & extsh. */
1.1.1.6 ! root     1478: GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
1.1       root     1479: /* nand & nand. */
1.1.1.6 ! root     1480: GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
1.1       root     1481: /* nor & nor. */
1.1.1.6 ! root     1482: GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
1.1       root     1483: /* or & or. */
                   1484: GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
                   1485: {
1.1.1.5   root     1486:     int rs, ra, rb;
                   1487: 
                   1488:     rs = rS(ctx->opcode);
                   1489:     ra = rA(ctx->opcode);
                   1490:     rb = rB(ctx->opcode);
                   1491:     /* Optimisation for mr. ri case */
                   1492:     if (rs != ra || rs != rb) {
1.1.1.6 ! root     1493:         if (rs != rb)
        !          1494:             tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]);
        !          1495:         else
        !          1496:             tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]);
1.1.1.5   root     1497:         if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     1498:             gen_set_Rc0(ctx, cpu_gpr[ra]);
1.1.1.5   root     1499:     } else if (unlikely(Rc(ctx->opcode) != 0)) {
1.1.1.6 ! root     1500:         gen_set_Rc0(ctx, cpu_gpr[rs]);
1.1.1.5   root     1501: #if defined(TARGET_PPC64)
                   1502:     } else {
1.1.1.6 ! root     1503:         int prio = 0;
        !          1504: 
1.1.1.5   root     1505:         switch (rs) {
                   1506:         case 1:
                   1507:             /* Set process priority to low */
1.1.1.6 ! root     1508:             prio = 2;
1.1.1.5   root     1509:             break;
                   1510:         case 6:
                   1511:             /* Set process priority to medium-low */
1.1.1.6 ! root     1512:             prio = 3;
1.1.1.5   root     1513:             break;
                   1514:         case 2:
                   1515:             /* Set process priority to normal */
1.1.1.6 ! root     1516:             prio = 4;
1.1.1.5   root     1517:             break;
                   1518: #if !defined(CONFIG_USER_ONLY)
                   1519:         case 31:
1.1.1.6 ! root     1520:             if (ctx->mem_idx > 0) {
1.1.1.5   root     1521:                 /* Set process priority to very low */
1.1.1.6 ! root     1522:                 prio = 1;
1.1.1.5   root     1523:             }
                   1524:             break;
                   1525:         case 5:
1.1.1.6 ! root     1526:             if (ctx->mem_idx > 0) {
1.1.1.5   root     1527:                 /* Set process priority to medium-hight */
1.1.1.6 ! root     1528:                 prio = 5;
1.1.1.5   root     1529:             }
                   1530:             break;
                   1531:         case 3:
1.1.1.6 ! root     1532:             if (ctx->mem_idx > 0) {
1.1.1.5   root     1533:                 /* Set process priority to high */
1.1.1.6 ! root     1534:                 prio = 6;
1.1.1.5   root     1535:             }
                   1536:             break;
                   1537:         case 7:
1.1.1.6 ! root     1538:             if (ctx->mem_idx > 1) {
1.1.1.5   root     1539:                 /* Set process priority to very high */
1.1.1.6 ! root     1540:                 prio = 7;
1.1.1.5   root     1541:             }
                   1542:             break;
                   1543: #endif
                   1544:         default:
                   1545:             /* nop */
                   1546:             break;
                   1547:         }
1.1.1.6 ! root     1548:         if (prio) {
        !          1549:             TCGv t0 = tcg_temp_new();
        !          1550:             gen_load_spr(t0, SPR_PPR);
        !          1551:             tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
        !          1552:             tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
        !          1553:             gen_store_spr(SPR_PPR, t0);
        !          1554:             tcg_temp_free(t0);
        !          1555:         }
1.1.1.5   root     1556: #endif
1.1       root     1557:     }
                   1558: }
                   1559: /* orc & orc. */
1.1.1.6 ! root     1560: GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
1.1       root     1561: /* xor & xor. */
                   1562: GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER)
                   1563: {
                   1564:     /* Optimisation for "set to zero" case */
1.1.1.6 ! root     1565:     if (rS(ctx->opcode) != rB(ctx->opcode))
        !          1566:         tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
        !          1567:     else
        !          1568:         tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1.1.1.5   root     1569:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     1570:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1571: }
                   1572: /* ori */
                   1573: GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1574: {
1.1.1.5   root     1575:     target_ulong uimm = UIMM(ctx->opcode);
1.1       root     1576: 
                   1577:     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
                   1578:         /* NOP */
1.1.1.5   root     1579:         /* XXX: should handle special NOPs for POWER series */
1.1       root     1580:         return;
1.1.1.5   root     1581:     }
1.1.1.6 ! root     1582:     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1.1       root     1583: }
                   1584: /* oris */
                   1585: GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1586: {
1.1.1.5   root     1587:     target_ulong uimm = UIMM(ctx->opcode);
1.1       root     1588: 
                   1589:     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
                   1590:         /* NOP */
                   1591:         return;
1.1.1.5   root     1592:     }
1.1.1.6 ! root     1593:     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1.1       root     1594: }
                   1595: /* xori */
                   1596: GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1597: {
1.1.1.5   root     1598:     target_ulong uimm = UIMM(ctx->opcode);
1.1       root     1599: 
                   1600:     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
                   1601:         /* NOP */
                   1602:         return;
                   1603:     }
1.1.1.6 ! root     1604:     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1.1       root     1605: }
                   1606: /* xoris */
                   1607: GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1608: {
1.1.1.5   root     1609:     target_ulong uimm = UIMM(ctx->opcode);
1.1       root     1610: 
                   1611:     if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
                   1612:         /* NOP */
                   1613:         return;
                   1614:     }
1.1.1.6 ! root     1615:     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1.1.1.5   root     1616: }
                   1617: /* popcntb : PowerPC 2.03 specification */
                   1618: GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB)
                   1619: {
                   1620: #if defined(TARGET_PPC64)
                   1621:     if (ctx->sf_mode)
1.1.1.6 ! root     1622:         gen_helper_popcntb_64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     1623:     else
                   1624: #endif
1.1.1.6 ! root     1625:         gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1.1       root     1626: }
                   1627: 
1.1.1.5   root     1628: #if defined(TARGET_PPC64)
                   1629: /* extsw & extsw. */
1.1.1.6 ! root     1630: GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
1.1.1.5   root     1631: /* cntlzd */
1.1.1.6 ! root     1632: GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B)
        !          1633: {
        !          1634:     gen_helper_cntlzd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
        !          1635:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1636:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
        !          1637: }
1.1.1.5   root     1638: #endif
                   1639: 
1.1       root     1640: /***                             Integer rotate                            ***/
                   1641: /* rlwimi & rlwimi. */
                   1642: GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1643: {
1.1.1.5   root     1644:     uint32_t mb, me, sh;
1.1       root     1645: 
                   1646:     mb = MB(ctx->opcode);
                   1647:     me = ME(ctx->opcode);
1.1.1.5   root     1648:     sh = SH(ctx->opcode);
1.1.1.6 ! root     1649:     if (likely(sh == 0 && mb == 0 && me == 31)) {
        !          1650:         tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
        !          1651:     } else {
        !          1652:         target_ulong mask;
        !          1653:         TCGv t1;
        !          1654:         TCGv t0 = tcg_temp_new();
        !          1655: #if defined(TARGET_PPC64)
        !          1656:         TCGv_i32 t2 = tcg_temp_new_i32();
        !          1657:         tcg_gen_trunc_i64_i32(t2, cpu_gpr[rS(ctx->opcode)]);
        !          1658:         tcg_gen_rotli_i32(t2, t2, sh);
        !          1659:         tcg_gen_extu_i32_i64(t0, t2);
        !          1660:         tcg_temp_free_i32(t2);
        !          1661: #else
        !          1662:         tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
        !          1663: #endif
        !          1664: #if defined(TARGET_PPC64)
        !          1665:         mb += 32;
        !          1666:         me += 32;
        !          1667: #endif
        !          1668:         mask = MASK(mb, me);
        !          1669:         t1 = tcg_temp_new();
        !          1670:         tcg_gen_andi_tl(t0, t0, mask);
        !          1671:         tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
        !          1672:         tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
        !          1673:         tcg_temp_free(t0);
        !          1674:         tcg_temp_free(t1);
        !          1675:     }
1.1.1.5   root     1676:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     1677:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1678: }
                   1679: /* rlwinm & rlwinm. */
                   1680: GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1681: {
                   1682:     uint32_t mb, me, sh;
1.1.1.5   root     1683: 
1.1       root     1684:     sh = SH(ctx->opcode);
                   1685:     mb = MB(ctx->opcode);
                   1686:     me = ME(ctx->opcode);
1.1.1.6 ! root     1687: 
        !          1688:     if (likely(mb == 0 && me == (31 - sh))) {
        !          1689:         if (likely(sh == 0)) {
        !          1690:             tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
        !          1691:         } else {
        !          1692:             TCGv t0 = tcg_temp_new();
        !          1693:             tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
        !          1694:             tcg_gen_shli_tl(t0, t0, sh);
        !          1695:             tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
        !          1696:             tcg_temp_free(t0);
1.1       root     1697:         }
1.1.1.6 ! root     1698:     } else if (likely(sh != 0 && me == 31 && sh == (32 - mb))) {
        !          1699:         TCGv t0 = tcg_temp_new();
        !          1700:         tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
        !          1701:         tcg_gen_shri_tl(t0, t0, mb);
        !          1702:         tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
        !          1703:         tcg_temp_free(t0);
        !          1704:     } else {
        !          1705:         TCGv t0 = tcg_temp_new();
        !          1706: #if defined(TARGET_PPC64)
        !          1707:         TCGv_i32 t1 = tcg_temp_new_i32();
        !          1708:         tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
        !          1709:         tcg_gen_rotli_i32(t1, t1, sh);
        !          1710:         tcg_gen_extu_i32_i64(t0, t1);
        !          1711:         tcg_temp_free_i32(t1);
        !          1712: #else
        !          1713:         tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
        !          1714: #endif
1.1.1.5   root     1715: #if defined(TARGET_PPC64)
1.1.1.6 ! root     1716:         mb += 32;
        !          1717:         me += 32;
1.1.1.5   root     1718: #endif
1.1.1.6 ! root     1719:         tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
        !          1720:         tcg_temp_free(t0);
        !          1721:     }
1.1.1.5   root     1722:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     1723:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1724: }
                   1725: /* rlwnm & rlwnm. */
                   1726: GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   1727: {
                   1728:     uint32_t mb, me;
1.1.1.6 ! root     1729:     TCGv t0;
        !          1730: #if defined(TARGET_PPC64)
        !          1731:     TCGv_i32 t1, t2;
        !          1732: #endif
1.1       root     1733: 
                   1734:     mb = MB(ctx->opcode);
                   1735:     me = ME(ctx->opcode);
1.1.1.6 ! root     1736:     t0 = tcg_temp_new();
        !          1737:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1f);
        !          1738: #if defined(TARGET_PPC64)
        !          1739:     t1 = tcg_temp_new_i32();
        !          1740:     t2 = tcg_temp_new_i32();
        !          1741:     tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
        !          1742:     tcg_gen_trunc_i64_i32(t2, t0);
        !          1743:     tcg_gen_rotl_i32(t1, t1, t2);
        !          1744:     tcg_gen_extu_i32_i64(t0, t1);
        !          1745:     tcg_temp_free_i32(t1);
        !          1746:     tcg_temp_free_i32(t2);
        !          1747: #else
        !          1748:     tcg_gen_rotl_i32(t0, cpu_gpr[rS(ctx->opcode)], t0);
        !          1749: #endif
1.1.1.5   root     1750:     if (unlikely(mb != 0 || me != 31)) {
                   1751: #if defined(TARGET_PPC64)
                   1752:         mb += 32;
                   1753:         me += 32;
                   1754: #endif
1.1.1.6 ! root     1755:         tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
        !          1756:     } else {
        !          1757:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1.1       root     1758:     }
1.1.1.6 ! root     1759:     tcg_temp_free(t0);
1.1.1.5   root     1760:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     1761:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     1762: }
                   1763: 
                   1764: #if defined(TARGET_PPC64)
                   1765: #define GEN_PPC64_R2(name, opc1, opc2)                                        \
                   1766: GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
                   1767: {                                                                             \
                   1768:     gen_##name(ctx, 0);                                                       \
                   1769: }                                                                             \
                   1770: GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
                   1771:              PPC_64B)                                                         \
                   1772: {                                                                             \
                   1773:     gen_##name(ctx, 1);                                                       \
                   1774: }
                   1775: #define GEN_PPC64_R4(name, opc1, opc2)                                        \
                   1776: GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B) \
                   1777: {                                                                             \
                   1778:     gen_##name(ctx, 0, 0);                                                    \
                   1779: }                                                                             \
                   1780: GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
                   1781:              PPC_64B)                                                         \
                   1782: {                                                                             \
                   1783:     gen_##name(ctx, 0, 1);                                                    \
                   1784: }                                                                             \
                   1785: GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
                   1786:              PPC_64B)                                                         \
                   1787: {                                                                             \
                   1788:     gen_##name(ctx, 1, 0);                                                    \
                   1789: }                                                                             \
                   1790: GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
                   1791:              PPC_64B)                                                         \
                   1792: {                                                                             \
                   1793:     gen_##name(ctx, 1, 1);                                                    \
                   1794: }
                   1795: 
                   1796: static always_inline void gen_rldinm (DisasContext *ctx, uint32_t mb,
                   1797:                                       uint32_t me, uint32_t sh)
                   1798: {
1.1.1.6 ! root     1799:     if (likely(sh != 0 && mb == 0 && me == (63 - sh))) {
        !          1800:         tcg_gen_shli_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
        !          1801:     } else if (likely(sh != 0 && me == 63 && sh == (64 - mb))) {
        !          1802:         tcg_gen_shri_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], mb);
        !          1803:     } else {
        !          1804:         TCGv t0 = tcg_temp_new();
        !          1805:         tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
        !          1806:         if (likely(mb == 0 && me == 63)) {
        !          1807:             tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
        !          1808:         } else {
        !          1809:             tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
1.1.1.5   root     1810:         }
1.1.1.6 ! root     1811:         tcg_temp_free(t0);
1.1.1.5   root     1812:     }
                   1813:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     1814:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     1815: }
                   1816: /* rldicl - rldicl. */
                   1817: static always_inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
                   1818: {
                   1819:     uint32_t sh, mb;
                   1820: 
                   1821:     sh = SH(ctx->opcode) | (shn << 5);
                   1822:     mb = MB(ctx->opcode) | (mbn << 5);
                   1823:     gen_rldinm(ctx, mb, 63, sh);
                   1824: }
                   1825: GEN_PPC64_R4(rldicl, 0x1E, 0x00);
                   1826: /* rldicr - rldicr. */
                   1827: static always_inline void gen_rldicr (DisasContext *ctx, int men, int shn)
                   1828: {
                   1829:     uint32_t sh, me;
                   1830: 
                   1831:     sh = SH(ctx->opcode) | (shn << 5);
                   1832:     me = MB(ctx->opcode) | (men << 5);
                   1833:     gen_rldinm(ctx, 0, me, sh);
                   1834: }
                   1835: GEN_PPC64_R4(rldicr, 0x1E, 0x02);
                   1836: /* rldic - rldic. */
                   1837: static always_inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
                   1838: {
                   1839:     uint32_t sh, mb;
                   1840: 
                   1841:     sh = SH(ctx->opcode) | (shn << 5);
                   1842:     mb = MB(ctx->opcode) | (mbn << 5);
                   1843:     gen_rldinm(ctx, mb, 63 - sh, sh);
                   1844: }
                   1845: GEN_PPC64_R4(rldic, 0x1E, 0x04);
                   1846: 
                   1847: static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb,
                   1848:                                      uint32_t me)
                   1849: {
1.1.1.6 ! root     1850:     TCGv t0;
        !          1851: 
        !          1852:     mb = MB(ctx->opcode);
        !          1853:     me = ME(ctx->opcode);
        !          1854:     t0 = tcg_temp_new();
        !          1855:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
        !          1856:     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
1.1.1.5   root     1857:     if (unlikely(mb != 0 || me != 63)) {
1.1.1.6 ! root     1858:         tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me));
        !          1859:     } else {
        !          1860:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
1.1.1.5   root     1861:     }
1.1.1.6 ! root     1862:     tcg_temp_free(t0);
1.1.1.5   root     1863:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     1864:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     1865: }
                   1866: 
                   1867: /* rldcl - rldcl. */
                   1868: static always_inline void gen_rldcl (DisasContext *ctx, int mbn)
                   1869: {
                   1870:     uint32_t mb;
                   1871: 
                   1872:     mb = MB(ctx->opcode) | (mbn << 5);
                   1873:     gen_rldnm(ctx, mb, 63);
                   1874: }
                   1875: GEN_PPC64_R2(rldcl, 0x1E, 0x08);
                   1876: /* rldcr - rldcr. */
                   1877: static always_inline void gen_rldcr (DisasContext *ctx, int men)
                   1878: {
                   1879:     uint32_t me;
                   1880: 
                   1881:     me = MB(ctx->opcode) | (men << 5);
                   1882:     gen_rldnm(ctx, 0, me);
                   1883: }
                   1884: GEN_PPC64_R2(rldcr, 0x1E, 0x09);
                   1885: /* rldimi - rldimi. */
                   1886: static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
                   1887: {
                   1888:     uint32_t sh, mb, me;
                   1889: 
                   1890:     sh = SH(ctx->opcode) | (shn << 5);
                   1891:     mb = MB(ctx->opcode) | (mbn << 5);
                   1892:     me = 63 - sh;
1.1.1.6 ! root     1893:     if (unlikely(sh == 0 && mb == 0)) {
        !          1894:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
        !          1895:     } else {
        !          1896:         TCGv t0, t1;
        !          1897:         target_ulong mask;
        !          1898: 
        !          1899:         t0 = tcg_temp_new();
        !          1900:         tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
        !          1901:         t1 = tcg_temp_new();
        !          1902:         mask = MASK(mb, me);
        !          1903:         tcg_gen_andi_tl(t0, t0, mask);
        !          1904:         tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
        !          1905:         tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
        !          1906:         tcg_temp_free(t0);
        !          1907:         tcg_temp_free(t1);
        !          1908:     }
1.1.1.5   root     1909:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     1910:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1911: }
1.1.1.5   root     1912: GEN_PPC64_R4(rldimi, 0x1E, 0x06);
                   1913: #endif
1.1       root     1914: 
                   1915: /***                             Integer shift                             ***/
                   1916: /* slw & slw. */
1.1.1.6 ! root     1917: GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER)
        !          1918: {
        !          1919:     TCGv t0;
        !          1920:     int l1, l2;
        !          1921:     l1 = gen_new_label();
        !          1922:     l2 = gen_new_label();
        !          1923: 
        !          1924:     t0 = tcg_temp_local_new();
        !          1925:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
        !          1926:     tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x20, l1);
        !          1927:     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
        !          1928:     tcg_gen_br(l2);
        !          1929:     gen_set_label(l1);
        !          1930:     tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t0);
        !          1931:     tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
        !          1932:     gen_set_label(l2);
        !          1933:     tcg_temp_free(t0);
        !          1934:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1935:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
        !          1936: }
1.1       root     1937: /* sraw & sraw. */
1.1.1.6 ! root     1938: GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER)
        !          1939: {
        !          1940:     gen_helper_sraw(cpu_gpr[rA(ctx->opcode)],
        !          1941:                     cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
        !          1942:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1943:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
        !          1944: }
1.1       root     1945: /* srawi & srawi. */
                   1946: GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
                   1947: {
1.1.1.6 ! root     1948:     int sh = SH(ctx->opcode);
        !          1949:     if (sh != 0) {
        !          1950:         int l1, l2;
        !          1951:         TCGv t0;
        !          1952:         l1 = gen_new_label();
        !          1953:         l2 = gen_new_label();
        !          1954:         t0 = tcg_temp_local_new();
        !          1955:         tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
        !          1956:         tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
        !          1957:         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
        !          1958:         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
        !          1959:         tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
        !          1960:         tcg_gen_br(l2);
        !          1961:         gen_set_label(l1);
        !          1962:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
        !          1963:         gen_set_label(l2);
        !          1964:         tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
        !          1965:         tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], t0, sh);
        !          1966:         tcg_temp_free(t0);
        !          1967:     } else {
        !          1968:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
        !          1969:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1.1.1.5   root     1970:     }
                   1971:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     1972:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1       root     1973: }
                   1974: /* srw & srw. */
1.1.1.6 ! root     1975: GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER)
        !          1976: {
        !          1977:     TCGv t0, t1;
        !          1978:     int l1, l2;
        !          1979:     l1 = gen_new_label();
        !          1980:     l2 = gen_new_label();
        !          1981: 
        !          1982:     t0 = tcg_temp_local_new();
        !          1983:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
        !          1984:     tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x20, l1);
        !          1985:     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
        !          1986:     tcg_gen_br(l2);
        !          1987:     gen_set_label(l1);
        !          1988:     t1 = tcg_temp_new();
        !          1989:     tcg_gen_ext32u_tl(t1, cpu_gpr[rS(ctx->opcode)]);
        !          1990:     tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t1, t0);
        !          1991:     tcg_temp_free(t1);
        !          1992:     gen_set_label(l2);
        !          1993:     tcg_temp_free(t0);
        !          1994:     if (unlikely(Rc(ctx->opcode) != 0))
        !          1995:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
        !          1996: }
1.1.1.5   root     1997: #if defined(TARGET_PPC64)
                   1998: /* sld & sld. */
1.1.1.6 ! root     1999: GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B)
        !          2000: {
        !          2001:     TCGv t0;
        !          2002:     int l1, l2;
        !          2003:     l1 = gen_new_label();
        !          2004:     l2 = gen_new_label();
        !          2005: 
        !          2006:     t0 = tcg_temp_local_new();
        !          2007:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x7f);
        !          2008:     tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x40, l1);
        !          2009:     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
        !          2010:     tcg_gen_br(l2);
        !          2011:     gen_set_label(l1);
        !          2012:     tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t0);
        !          2013:     gen_set_label(l2);
        !          2014:     tcg_temp_free(t0);
        !          2015:     if (unlikely(Rc(ctx->opcode) != 0))
        !          2016:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
        !          2017: }
1.1.1.5   root     2018: /* srad & srad. */
1.1.1.6 ! root     2019: GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B)
        !          2020: {
        !          2021:     gen_helper_srad(cpu_gpr[rA(ctx->opcode)],
        !          2022:                     cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
        !          2023:     if (unlikely(Rc(ctx->opcode) != 0))
        !          2024:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
        !          2025: }
1.1.1.5   root     2026: /* sradi & sradi. */
                   2027: static always_inline void gen_sradi (DisasContext *ctx, int n)
                   2028: {
1.1.1.6 ! root     2029:     int sh = SH(ctx->opcode) + (n << 5);
1.1.1.5   root     2030:     if (sh != 0) {
1.1.1.6 ! root     2031:         int l1, l2;
        !          2032:         TCGv t0;
        !          2033:         l1 = gen_new_label();
        !          2034:         l2 = gen_new_label();
        !          2035:         t0 = tcg_temp_local_new();
        !          2036:         tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
        !          2037:         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
        !          2038:         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
        !          2039:         tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
        !          2040:         tcg_gen_br(l2);
        !          2041:         gen_set_label(l1);
        !          2042:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
        !          2043:         gen_set_label(l2);
        !          2044:         tcg_temp_free(t0);
        !          2045:         tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
        !          2046:     } else {
        !          2047:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
        !          2048:         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
1.1.1.5   root     2049:     }
                   2050:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     2051:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     2052: }
                   2053: GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B)
                   2054: {
                   2055:     gen_sradi(ctx, 0);
                   2056: }
                   2057: GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B)
                   2058: {
                   2059:     gen_sradi(ctx, 1);
                   2060: }
                   2061: /* srd & srd. */
1.1.1.6 ! root     2062: GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B)
        !          2063: {
        !          2064:     TCGv t0;
        !          2065:     int l1, l2;
        !          2066:     l1 = gen_new_label();
        !          2067:     l2 = gen_new_label();
        !          2068: 
        !          2069:     t0 = tcg_temp_local_new();
        !          2070:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x7f);
        !          2071:     tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x40, l1);
        !          2072:     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
        !          2073:     tcg_gen_br(l2);
        !          2074:     gen_set_label(l1);
        !          2075:     tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t0);
        !          2076:     gen_set_label(l2);
        !          2077:     tcg_temp_free(t0);
        !          2078:     if (unlikely(Rc(ctx->opcode) != 0))
        !          2079:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
        !          2080: }
1.1.1.5   root     2081: #endif
1.1       root     2082: 
                   2083: /***                       Floating-Point arithmetic                       ***/
1.1.1.5   root     2084: #define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
                   2085: GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type)                        \
1.1       root     2086: {                                                                             \
1.1.1.5   root     2087:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6 ! root     2088:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     2089:         return;                                                               \
                   2090:     }                                                                         \
1.1.1.6 ! root     2091:     /* NIP cannot be restored if the memory exception comes from an helper */ \
        !          2092:     gen_update_nip(ctx, ctx->nip - 4);                                        \
1.1.1.5   root     2093:     gen_reset_fpstatus();                                                     \
1.1.1.6 ! root     2094:     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
        !          2095:                      cpu_fpr[rC(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);     \
1.1       root     2096:     if (isfloat) {                                                            \
1.1.1.6 ! root     2097:         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
1.1       root     2098:     }                                                                         \
1.1.1.6 ! root     2099:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], set_fprf,                      \
        !          2100:                      Rc(ctx->opcode) != 0);                                   \
1.1       root     2101: }
                   2102: 
1.1.1.5   root     2103: #define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
                   2104: _GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
                   2105: _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
1.1       root     2106: 
1.1.1.5   root     2107: #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
                   2108: GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1.1       root     2109: {                                                                             \
1.1.1.5   root     2110:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6 ! root     2111:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     2112:         return;                                                               \
                   2113:     }                                                                         \
1.1.1.6 ! root     2114:     /* NIP cannot be restored if the memory exception comes from an helper */ \
        !          2115:     gen_update_nip(ctx, ctx->nip - 4);                                        \
1.1.1.5   root     2116:     gen_reset_fpstatus();                                                     \
1.1.1.6 ! root     2117:     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
        !          2118:                      cpu_fpr[rB(ctx->opcode)]);                               \
1.1       root     2119:     if (isfloat) {                                                            \
1.1.1.6 ! root     2120:         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
1.1       root     2121:     }                                                                         \
1.1.1.6 ! root     2122:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
        !          2123:                      set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     2124: }
1.1.1.5   root     2125: #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
                   2126: _GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
                   2127: _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1.1       root     2128: 
1.1.1.5   root     2129: #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
                   2130: GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type)                             \
1.1       root     2131: {                                                                             \
1.1.1.5   root     2132:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6 ! root     2133:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     2134:         return;                                                               \
                   2135:     }                                                                         \
1.1.1.6 ! root     2136:     /* NIP cannot be restored if the memory exception comes from an helper */ \
        !          2137:     gen_update_nip(ctx, ctx->nip - 4);                                        \
1.1.1.5   root     2138:     gen_reset_fpstatus();                                                     \
1.1.1.6 ! root     2139:     gen_helper_f##op(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rA(ctx->opcode)],      \
        !          2140:                        cpu_fpr[rC(ctx->opcode)]);                             \
1.1       root     2141:     if (isfloat) {                                                            \
1.1.1.6 ! root     2142:         gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);  \
1.1       root     2143:     }                                                                         \
1.1.1.6 ! root     2144:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
        !          2145:                      set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     2146: }
1.1.1.5   root     2147: #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
                   2148: _GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
                   2149: _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
1.1       root     2150: 
1.1.1.5   root     2151: #define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
                   2152: GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)                        \
1.1       root     2153: {                                                                             \
1.1.1.5   root     2154:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6 ! root     2155:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     2156:         return;                                                               \
                   2157:     }                                                                         \
1.1.1.6 ! root     2158:     /* NIP cannot be restored if the memory exception comes from an helper */ \
        !          2159:     gen_update_nip(ctx, ctx->nip - 4);                                        \
1.1.1.5   root     2160:     gen_reset_fpstatus();                                                     \
1.1.1.6 ! root     2161:     gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);   \
        !          2162:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
        !          2163:                      set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     2164: }
                   2165: 
1.1.1.5   root     2166: #define GEN_FLOAT_BS(name, op1, op2, set_fprf, type)                          \
                   2167: GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type)                        \
1.1       root     2168: {                                                                             \
1.1.1.5   root     2169:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6 ! root     2170:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     2171:         return;                                                               \
                   2172:     }                                                                         \
1.1.1.6 ! root     2173:     /* NIP cannot be restored if the memory exception comes from an helper */ \
        !          2174:     gen_update_nip(ctx, ctx->nip - 4);                                        \
1.1.1.5   root     2175:     gen_reset_fpstatus();                                                     \
1.1.1.6 ! root     2176:     gen_helper_f##name(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);   \
        !          2177:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)],                                \
        !          2178:                      set_fprf, Rc(ctx->opcode) != 0);                         \
1.1       root     2179: }
                   2180: 
                   2181: /* fadd - fadds */
1.1.1.5   root     2182: GEN_FLOAT_AB(add, 0x15, 0x000007C0, 1, PPC_FLOAT);
1.1       root     2183: /* fdiv - fdivs */
1.1.1.5   root     2184: GEN_FLOAT_AB(div, 0x12, 0x000007C0, 1, PPC_FLOAT);
1.1       root     2185: /* fmul - fmuls */
1.1.1.5   root     2186: GEN_FLOAT_AC(mul, 0x19, 0x0000F800, 1, PPC_FLOAT);
                   2187: 
                   2188: /* fre */
                   2189: GEN_FLOAT_BS(re, 0x3F, 0x18, 1, PPC_FLOAT_EXT);
1.1       root     2190: 
                   2191: /* fres */
1.1.1.5   root     2192: GEN_FLOAT_BS(res, 0x3B, 0x18, 1, PPC_FLOAT_FRES);
1.1       root     2193: 
                   2194: /* frsqrte */
1.1.1.5   root     2195: GEN_FLOAT_BS(rsqrte, 0x3F, 0x1A, 1, PPC_FLOAT_FRSQRTE);
                   2196: 
                   2197: /* frsqrtes */
1.1.1.6 ! root     2198: GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES)
1.1.1.5   root     2199: {
1.1.1.6 ! root     2200:     if (unlikely(!ctx->fpu_enabled)) {
        !          2201:         gen_exception(ctx, POWERPC_EXCP_FPU);
        !          2202:         return;
        !          2203:     }
        !          2204:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          2205:     gen_update_nip(ctx, ctx->nip - 4);
        !          2206:     gen_reset_fpstatus();
        !          2207:     gen_helper_frsqrte(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
        !          2208:     gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);
        !          2209:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
1.1.1.5   root     2210: }
1.1       root     2211: 
                   2212: /* fsel */
1.1.1.5   root     2213: _GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
1.1       root     2214: /* fsub - fsubs */
1.1.1.5   root     2215: GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
1.1       root     2216: /* Optional: */
                   2217: /* fsqrt */
1.1.1.5   root     2218: GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1.1       root     2219: {
1.1.1.5   root     2220:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6 ! root     2221:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2222:         return;
                   2223:     }
1.1.1.6 ! root     2224:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          2225:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2226:     gen_reset_fpstatus();
1.1.1.6 ! root     2227:     gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
        !          2228:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
1.1       root     2229: }
                   2230: 
1.1.1.5   root     2231: GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1.1       root     2232: {
1.1.1.5   root     2233:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6 ! root     2234:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2235:         return;
                   2236:     }
1.1.1.6 ! root     2237:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          2238:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2239:     gen_reset_fpstatus();
1.1.1.6 ! root     2240:     gen_helper_fsqrt(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
        !          2241:     gen_helper_frsp(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rD(ctx->opcode)]);
        !          2242:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 1, Rc(ctx->opcode) != 0);
1.1       root     2243: }
                   2244: 
                   2245: /***                     Floating-Point multiply-and-add                   ***/
                   2246: /* fmadd - fmadds */
1.1.1.5   root     2247: GEN_FLOAT_ACB(madd, 0x1D, 1, PPC_FLOAT);
1.1       root     2248: /* fmsub - fmsubs */
1.1.1.5   root     2249: GEN_FLOAT_ACB(msub, 0x1C, 1, PPC_FLOAT);
1.1       root     2250: /* fnmadd - fnmadds */
1.1.1.5   root     2251: GEN_FLOAT_ACB(nmadd, 0x1F, 1, PPC_FLOAT);
1.1       root     2252: /* fnmsub - fnmsubs */
1.1.1.5   root     2253: GEN_FLOAT_ACB(nmsub, 0x1E, 1, PPC_FLOAT);
1.1       root     2254: 
                   2255: /***                     Floating-Point round & convert                    ***/
                   2256: /* fctiw */
1.1.1.5   root     2257: GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
1.1       root     2258: /* fctiwz */
1.1.1.5   root     2259: GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
1.1       root     2260: /* frsp */
1.1.1.5   root     2261: GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
                   2262: #if defined(TARGET_PPC64)
                   2263: /* fcfid */
                   2264: GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC_64B);
                   2265: /* fctid */
                   2266: GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC_64B);
                   2267: /* fctidz */
                   2268: GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC_64B);
                   2269: #endif
                   2270: 
                   2271: /* frin */
                   2272: GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
                   2273: /* friz */
                   2274: GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
                   2275: /* frip */
                   2276: GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
                   2277: /* frim */
                   2278: GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
1.1       root     2279: 
                   2280: /***                         Floating-Point compare                        ***/
                   2281: /* fcmpo */
1.1.1.5   root     2282: GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1.1       root     2283: {
1.1.1.6 ! root     2284:     TCGv_i32 crf;
1.1.1.5   root     2285:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6 ! root     2286:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2287:         return;
                   2288:     }
1.1.1.6 ! root     2289:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          2290:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2291:     gen_reset_fpstatus();
1.1.1.6 ! root     2292:     crf = tcg_const_i32(crfD(ctx->opcode));
        !          2293:     gen_helper_fcmpo(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf);
        !          2294:     tcg_temp_free_i32(crf);
        !          2295:     gen_helper_float_check_status();
1.1       root     2296: }
                   2297: 
                   2298: /* fcmpu */
1.1.1.5   root     2299: GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1.1       root     2300: {
1.1.1.6 ! root     2301:     TCGv_i32 crf;
1.1.1.5   root     2302:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6 ! root     2303:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2304:         return;
                   2305:     }
1.1.1.6 ! root     2306:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          2307:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2308:     gen_reset_fpstatus();
1.1.1.6 ! root     2309:     crf = tcg_const_i32(crfD(ctx->opcode));
        !          2310:     gen_helper_fcmpu(cpu_fpr[rA(ctx->opcode)], cpu_fpr[rB(ctx->opcode)], crf);
        !          2311:     tcg_temp_free_i32(crf);
        !          2312:     gen_helper_float_check_status();
1.1       root     2313: }
                   2314: 
                   2315: /***                         Floating-point move                           ***/
                   2316: /* fabs */
1.1.1.5   root     2317: /* XXX: beware that fabs never checks for NaNs nor update FPSCR */
                   2318: GEN_FLOAT_B(abs, 0x08, 0x08, 0, PPC_FLOAT);
1.1       root     2319: 
                   2320: /* fmr  - fmr. */
1.1.1.5   root     2321: /* XXX: beware that fmr never checks for NaNs nor update FPSCR */
1.1       root     2322: GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
                   2323: {
1.1.1.5   root     2324:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6 ! root     2325:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2326:         return;
                   2327:     }
1.1.1.6 ! root     2328:     tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]);
        !          2329:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
1.1       root     2330: }
                   2331: 
                   2332: /* fnabs */
1.1.1.5   root     2333: /* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
                   2334: GEN_FLOAT_B(nabs, 0x08, 0x04, 0, PPC_FLOAT);
1.1       root     2335: /* fneg */
1.1.1.5   root     2336: /* XXX: beware that fneg never checks for NaNs nor update FPSCR */
                   2337: GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
1.1       root     2338: 
                   2339: /***                  Floating-Point status & ctrl register                ***/
                   2340: /* mcrfs */
                   2341: GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
                   2342: {
1.1.1.5   root     2343:     int bfa;
                   2344: 
                   2345:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6 ! root     2346:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2347:         return;
                   2348:     }
1.1.1.5   root     2349:     bfa = 4 * (7 - crfS(ctx->opcode));
1.1.1.6 ! root     2350:     tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_fpscr, bfa);
        !          2351:     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf);
        !          2352:     tcg_gen_andi_i32(cpu_fpscr, cpu_fpscr, ~(0xF << bfa));
1.1       root     2353: }
                   2354: 
                   2355: /* mffs */
                   2356: GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
                   2357: {
1.1.1.5   root     2358:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6 ! root     2359:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2360:         return;
                   2361:     }
1.1.1.5   root     2362:     gen_reset_fpstatus();
1.1.1.6 ! root     2363:     tcg_gen_extu_i32_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpscr);
        !          2364:     gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
1.1       root     2365: }
                   2366: 
                   2367: /* mtfsb0 */
                   2368: GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
                   2369: {
                   2370:     uint8_t crb;
1.1.1.5   root     2371: 
                   2372:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6 ! root     2373:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2374:         return;
                   2375:     }
1.1.1.6 ! root     2376:     crb = 31 - crbD(ctx->opcode);
1.1.1.5   root     2377:     gen_reset_fpstatus();
1.1.1.6 ! root     2378:     if (likely(crb != FPSCR_FEX && crb != FPSCR_VX)) {
        !          2379:         TCGv_i32 t0;
        !          2380:         /* NIP cannot be restored if the memory exception comes from an helper */
        !          2381:         gen_update_nip(ctx, ctx->nip - 4);
        !          2382:         t0 = tcg_const_i32(crb);
        !          2383:         gen_helper_fpscr_clrbit(t0);
        !          2384:         tcg_temp_free_i32(t0);
        !          2385:     }
1.1.1.5   root     2386:     if (unlikely(Rc(ctx->opcode) != 0)) {
1.1.1.6 ! root     2387:         tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
1.1.1.5   root     2388:     }
1.1       root     2389: }
                   2390: 
                   2391: /* mtfsb1 */
                   2392: GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
                   2393: {
                   2394:     uint8_t crb;
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.6 ! root     2400:     crb = 31 - crbD(ctx->opcode);
1.1.1.5   root     2401:     gen_reset_fpstatus();
                   2402:     /* XXX: we pretend we can only do IEEE floating-point computations */
1.1.1.6 ! root     2403:     if (likely(crb != FPSCR_FEX && crb != FPSCR_VX && crb != FPSCR_NI)) {
        !          2404:         TCGv_i32 t0;
        !          2405:         /* NIP cannot be restored if the memory exception comes from an helper */
        !          2406:         gen_update_nip(ctx, ctx->nip - 4);
        !          2407:         t0 = tcg_const_i32(crb);
        !          2408:         gen_helper_fpscr_setbit(t0);
        !          2409:         tcg_temp_free_i32(t0);
        !          2410:     }
1.1.1.5   root     2411:     if (unlikely(Rc(ctx->opcode) != 0)) {
1.1.1.6 ! root     2412:         tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
1.1.1.5   root     2413:     }
                   2414:     /* We can raise a differed exception */
1.1.1.6 ! root     2415:     gen_helper_float_check_status();
1.1       root     2416: }
                   2417: 
                   2418: /* mtfsf */
                   2419: GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
                   2420: {
1.1.1.6 ! root     2421:     TCGv_i32 t0;
        !          2422: 
1.1.1.5   root     2423:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6 ! root     2424:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2425:         return;
                   2426:     }
1.1.1.6 ! root     2427:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          2428:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2429:     gen_reset_fpstatus();
1.1.1.6 ! root     2430:     t0 = tcg_const_i32(FM(ctx->opcode));
        !          2431:     gen_helper_store_fpscr(cpu_fpr[rB(ctx->opcode)], t0);
        !          2432:     tcg_temp_free_i32(t0);
1.1.1.5   root     2433:     if (unlikely(Rc(ctx->opcode) != 0)) {
1.1.1.6 ! root     2434:         tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
1.1.1.5   root     2435:     }
                   2436:     /* We can raise a differed exception */
1.1.1.6 ! root     2437:     gen_helper_float_check_status();
1.1       root     2438: }
                   2439: 
                   2440: /* mtfsfi */
                   2441: GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
                   2442: {
1.1.1.5   root     2443:     int bf, sh;
1.1.1.6 ! root     2444:     TCGv_i64 t0;
        !          2445:     TCGv_i32 t1;
1.1.1.5   root     2446: 
                   2447:     if (unlikely(!ctx->fpu_enabled)) {
1.1.1.6 ! root     2448:         gen_exception(ctx, POWERPC_EXCP_FPU);
1.1       root     2449:         return;
                   2450:     }
1.1.1.5   root     2451:     bf = crbD(ctx->opcode) >> 2;
                   2452:     sh = 7 - bf;
1.1.1.6 ! root     2453:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          2454:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.5   root     2455:     gen_reset_fpstatus();
1.1.1.6 ! root     2456:     t0 = tcg_const_i64(FPIMM(ctx->opcode) << (4 * sh));
        !          2457:     t1 = tcg_const_i32(1 << sh);
        !          2458:     gen_helper_store_fpscr(t0, t1);
        !          2459:     tcg_temp_free_i64(t0);
        !          2460:     tcg_temp_free_i32(t1);
1.1.1.5   root     2461:     if (unlikely(Rc(ctx->opcode) != 0)) {
1.1.1.6 ! root     2462:         tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX);
1.1.1.5   root     2463:     }
                   2464:     /* We can raise a differed exception */
1.1.1.6 ! root     2465:     gen_helper_float_check_status();
1.1       root     2466: }
                   2467: 
1.1.1.5   root     2468: /***                           Addressing modes                            ***/
                   2469: /* Register indirect with immediate index : EA = (rA|0) + SIMM */
1.1.1.6 ! root     2470: static always_inline void gen_addr_imm_index (DisasContext *ctx, TCGv EA, target_long maskl)
1.1.1.5   root     2471: {
                   2472:     target_long simm = SIMM(ctx->opcode);
                   2473: 
                   2474:     simm &= ~maskl;
                   2475:     if (rA(ctx->opcode) == 0) {
1.1.1.6 ! root     2476: #if defined(TARGET_PPC64)
        !          2477:         if (!ctx->sf_mode) {
        !          2478:             tcg_gen_movi_tl(EA, (uint32_t)simm);
        !          2479:         } else
        !          2480: #endif
        !          2481:         tcg_gen_movi_tl(EA, simm);
        !          2482:     } else if (likely(simm != 0)) {
        !          2483:         tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
        !          2484: #if defined(TARGET_PPC64)
        !          2485:         if (!ctx->sf_mode) {
        !          2486:             tcg_gen_ext32u_tl(EA, EA);
        !          2487:         }
        !          2488: #endif
1.1.1.5   root     2489:     } else {
1.1.1.6 ! root     2490: #if defined(TARGET_PPC64)
        !          2491:         if (!ctx->sf_mode) {
        !          2492:             tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
        !          2493:         } else
1.1.1.5   root     2494: #endif
1.1.1.6 ! root     2495:         tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
        !          2496:     }
1.1.1.5   root     2497: }
                   2498: 
1.1.1.6 ! root     2499: static always_inline void gen_addr_reg_index (DisasContext *ctx, TCGv EA)
1.1.1.5   root     2500: {
                   2501:     if (rA(ctx->opcode) == 0) {
1.1.1.6 ! root     2502: #if defined(TARGET_PPC64)
        !          2503:         if (!ctx->sf_mode) {
        !          2504:             tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]);
        !          2505:         } else
        !          2506: #endif
        !          2507:         tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     2508:     } else {
1.1.1.6 ! root     2509:         tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
        !          2510: #if defined(TARGET_PPC64)
        !          2511:         if (!ctx->sf_mode) {
        !          2512:             tcg_gen_ext32u_tl(EA, EA);
        !          2513:         }
1.1.1.5   root     2514: #endif
1.1.1.6 ! root     2515:     }
1.1.1.5   root     2516: }
                   2517: 
1.1.1.6 ! root     2518: static always_inline void gen_addr_register (DisasContext *ctx, TCGv EA)
1.1.1.5   root     2519: {
                   2520:     if (rA(ctx->opcode) == 0) {
1.1.1.6 ! root     2521:         tcg_gen_movi_tl(EA, 0);
1.1.1.5   root     2522:     } else {
1.1.1.6 ! root     2523: #if defined(TARGET_PPC64)
        !          2524:         if (!ctx->sf_mode) {
        !          2525:             tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
        !          2526:         } else
        !          2527: #endif
        !          2528:             tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
        !          2529:     }
        !          2530: }
        !          2531: 
        !          2532: static always_inline void gen_addr_add (DisasContext *ctx, TCGv ret, TCGv arg1, target_long val)
        !          2533: {
        !          2534:     tcg_gen_addi_tl(ret, arg1, val);
        !          2535: #if defined(TARGET_PPC64)
        !          2536:     if (!ctx->sf_mode) {
        !          2537:         tcg_gen_ext32u_tl(ret, ret);
1.1.1.5   root     2538:     }
                   2539: #endif
                   2540: }
                   2541: 
1.1.1.6 ! root     2542: static always_inline void gen_check_align (DisasContext *ctx, TCGv EA, int mask)
        !          2543: {
        !          2544:     int l1 = gen_new_label();
        !          2545:     TCGv t0 = tcg_temp_new();
        !          2546:     TCGv_i32 t1, t2;
        !          2547:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          2548:     gen_update_nip(ctx, ctx->nip - 4);
        !          2549:     tcg_gen_andi_tl(t0, EA, mask);
        !          2550:     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
        !          2551:     t1 = tcg_const_i32(POWERPC_EXCP_ALIGN);
        !          2552:     t2 = tcg_const_i32(0);
        !          2553:     gen_helper_raise_exception_err(t1, t2);
        !          2554:     tcg_temp_free_i32(t1);
        !          2555:     tcg_temp_free_i32(t2);
        !          2556:     gen_set_label(l1);
        !          2557:     tcg_temp_free(t0);
        !          2558: }
        !          2559: 
        !          2560: /***                             Integer load                              ***/
        !          2561: static always_inline void gen_qemu_ld8u(DisasContext *ctx, TCGv arg1, TCGv arg2)
        !          2562: {
        !          2563:     tcg_gen_qemu_ld8u(arg1, arg2, ctx->mem_idx);
        !          2564: }
        !          2565: 
        !          2566: static always_inline void gen_qemu_ld8s(DisasContext *ctx, TCGv arg1, TCGv arg2)
        !          2567: {
        !          2568:     tcg_gen_qemu_ld8s(arg1, arg2, ctx->mem_idx);
        !          2569: }
        !          2570: 
        !          2571: static always_inline void gen_qemu_ld16u(DisasContext *ctx, TCGv arg1, TCGv arg2)
        !          2572: {
        !          2573:     tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
        !          2574:     if (unlikely(ctx->le_mode)) {
1.1.1.5   root     2575: #if defined(TARGET_PPC64)
1.1.1.6 ! root     2576:         TCGv_i32 t0 = tcg_temp_new_i32();
        !          2577:         tcg_gen_trunc_tl_i32(t0, arg1);
        !          2578:         tcg_gen_bswap16_i32(t0, t0);
        !          2579:         tcg_gen_extu_i32_tl(arg1, t0);
        !          2580:         tcg_temp_free_i32(t0);
1.1.1.5   root     2581: #else
1.1.1.6 ! root     2582:         tcg_gen_bswap16_i32(arg1, arg1);
1.1.1.5   root     2583: #endif
1.1.1.6 ! root     2584:     }
        !          2585: }
        !          2586: 
        !          2587: static always_inline void gen_qemu_ld16s(DisasContext *ctx, TCGv arg1, TCGv arg2)
        !          2588: {
        !          2589:     if (unlikely(ctx->le_mode)) {
1.1.1.5   root     2590: #if defined(TARGET_PPC64)
1.1.1.6 ! root     2591:         TCGv_i32 t0;
        !          2592:         tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
        !          2593:         t0 = tcg_temp_new_i32();
        !          2594:         tcg_gen_trunc_tl_i32(t0, arg1);
        !          2595:         tcg_gen_bswap16_i32(t0, t0);
        !          2596:         tcg_gen_extu_i32_tl(arg1, t0);
        !          2597:         tcg_gen_ext16s_tl(arg1, arg1);
        !          2598:         tcg_temp_free_i32(t0);
1.1.1.5   root     2599: #else
1.1.1.6 ! root     2600:         tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
        !          2601:         tcg_gen_bswap16_i32(arg1, arg1);
        !          2602:         tcg_gen_ext16s_i32(arg1, arg1);
1.1.1.5   root     2603: #endif
1.1.1.6 ! root     2604:     } else {
        !          2605:         tcg_gen_qemu_ld16s(arg1, arg2, ctx->mem_idx);
        !          2606:     }
        !          2607: }
        !          2608: 
        !          2609: static always_inline void gen_qemu_ld32u(DisasContext *ctx, TCGv arg1, TCGv arg2)
        !          2610: {
        !          2611:     tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
        !          2612:     if (unlikely(ctx->le_mode)) {
1.1.1.5   root     2613: #if defined(TARGET_PPC64)
1.1.1.6 ! root     2614:         TCGv_i32 t0 = tcg_temp_new_i32();
        !          2615:         tcg_gen_trunc_tl_i32(t0, arg1);
        !          2616:         tcg_gen_bswap_i32(t0, t0);
        !          2617:         tcg_gen_extu_i32_tl(arg1, t0);
        !          2618:         tcg_temp_free_i32(t0);
1.1.1.5   root     2619: #else
1.1.1.6 ! root     2620:         tcg_gen_bswap_i32(arg1, arg1);
1.1.1.5   root     2621: #endif
1.1.1.6 ! root     2622:     }
1.1       root     2623: }
                   2624: 
1.1.1.6 ! root     2625: #if defined(TARGET_PPC64)
        !          2626: static always_inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
        !          2627: {
        !          2628:     if (unlikely(ctx->le_mode)) {
        !          2629:         TCGv_i32 t0;
        !          2630:         tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
        !          2631:         t0 = tcg_temp_new_i32();
        !          2632:         tcg_gen_trunc_tl_i32(t0, arg1);
        !          2633:         tcg_gen_bswap_i32(t0, t0);
        !          2634:         tcg_gen_ext_i32_tl(arg1, t0);
        !          2635:         tcg_temp_free_i32(t0);
        !          2636:     } else
        !          2637:         tcg_gen_qemu_ld32s(arg1, arg2, ctx->mem_idx);
        !          2638: }
        !          2639: #endif
        !          2640: 
        !          2641: static always_inline void gen_qemu_ld64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
        !          2642: {
        !          2643:     tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
        !          2644:     if (unlikely(ctx->le_mode)) {
        !          2645:         tcg_gen_bswap_i64(arg1, arg1);
        !          2646:     }
        !          2647: }
        !          2648: 
        !          2649: static always_inline void gen_qemu_st8(DisasContext *ctx, TCGv arg1, TCGv arg2)
        !          2650: {
        !          2651:     tcg_gen_qemu_st8(arg1, arg2, ctx->mem_idx);
        !          2652: }
        !          2653: 
        !          2654: static always_inline void gen_qemu_st16(DisasContext *ctx, TCGv arg1, TCGv arg2)
        !          2655: {
        !          2656:     if (unlikely(ctx->le_mode)) {
        !          2657: #if defined(TARGET_PPC64)
        !          2658:         TCGv_i32 t0;
        !          2659:         TCGv t1;
        !          2660:         t0 = tcg_temp_new_i32();
        !          2661:         tcg_gen_trunc_tl_i32(t0, arg1);
        !          2662:         tcg_gen_ext16u_i32(t0, t0);
        !          2663:         tcg_gen_bswap16_i32(t0, t0);
        !          2664:         t1 = tcg_temp_new();
        !          2665:         tcg_gen_extu_i32_tl(t1, t0);
        !          2666:         tcg_temp_free_i32(t0);
        !          2667:         tcg_gen_qemu_st16(t1, arg2, ctx->mem_idx);
        !          2668:         tcg_temp_free(t1);
        !          2669: #else
        !          2670:         TCGv t0 = tcg_temp_new();
        !          2671:         tcg_gen_ext16u_tl(t0, arg1);
        !          2672:         tcg_gen_bswap16_i32(t0, t0);
        !          2673:         tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
        !          2674:         tcg_temp_free(t0);
        !          2675: #endif
        !          2676:     } else {
        !          2677:         tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
        !          2678:     }
        !          2679: }
        !          2680: 
        !          2681: static always_inline void gen_qemu_st32(DisasContext *ctx, TCGv arg1, TCGv arg2)
        !          2682: {
        !          2683:     if (unlikely(ctx->le_mode)) {
        !          2684: #if defined(TARGET_PPC64)
        !          2685:         TCGv_i32 t0;
        !          2686:         TCGv t1;
        !          2687:         t0 = tcg_temp_new_i32();
        !          2688:         tcg_gen_trunc_tl_i32(t0, arg1);
        !          2689:         tcg_gen_bswap_i32(t0, t0);
        !          2690:         t1 = tcg_temp_new();
        !          2691:         tcg_gen_extu_i32_tl(t1, t0);
        !          2692:         tcg_temp_free_i32(t0);
        !          2693:         tcg_gen_qemu_st32(t1, arg2, ctx->mem_idx);
        !          2694:         tcg_temp_free(t1);
        !          2695: #else
        !          2696:         TCGv t0 = tcg_temp_new_i32();
        !          2697:         tcg_gen_bswap_i32(t0, arg1);
        !          2698:         tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
        !          2699:         tcg_temp_free(t0);
        !          2700: #endif
        !          2701:     } else {
        !          2702:         tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
        !          2703:     }
        !          2704: }
        !          2705: 
        !          2706: static always_inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
        !          2707: {
        !          2708:     if (unlikely(ctx->le_mode)) {
        !          2709:         TCGv_i64 t0 = tcg_temp_new_i64();
        !          2710:         tcg_gen_bswap_i64(t0, arg1);
        !          2711:         tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx);
        !          2712:         tcg_temp_free_i64(t0);
        !          2713:     } else
        !          2714:         tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx);
        !          2715: }
        !          2716: 
        !          2717: #define GEN_LD(name, ldop, opc, type)                                         \
        !          2718: GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type)                          \
        !          2719: {                                                                             \
        !          2720:     TCGv EA;                                                                  \
        !          2721:     gen_set_access_type(ctx, ACCESS_INT);                                     \
        !          2722:     EA = tcg_temp_new();                                                      \
        !          2723:     gen_addr_imm_index(ctx, EA, 0);                                           \
        !          2724:     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
        !          2725:     tcg_temp_free(EA);                                                        \
        !          2726: }
        !          2727: 
        !          2728: #define GEN_LDU(name, ldop, opc, type)                                        \
        !          2729: GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type)                       \
1.1       root     2730: {                                                                             \
1.1.1.6 ! root     2731:     TCGv EA;                                                                  \
1.1.1.5   root     2732:     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
                   2733:                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1.1.1.6 ! root     2734:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     2735:         return;                                                               \
                   2736:     }                                                                         \
1.1.1.6 ! root     2737:     gen_set_access_type(ctx, ACCESS_INT);                                     \
        !          2738:     EA = tcg_temp_new();                                                      \
1.1.1.5   root     2739:     if (type == PPC_64B)                                                      \
1.1.1.6 ! root     2740:         gen_addr_imm_index(ctx, EA, 0x03);                                    \
1.1.1.5   root     2741:     else                                                                      \
1.1.1.6 ! root     2742:         gen_addr_imm_index(ctx, EA, 0);                                       \
        !          2743:     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
        !          2744:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
        !          2745:     tcg_temp_free(EA);                                                        \
1.1       root     2746: }
                   2747: 
1.1.1.6 ! root     2748: #define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
        !          2749: GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type)                     \
1.1       root     2750: {                                                                             \
1.1.1.6 ! root     2751:     TCGv EA;                                                                  \
1.1.1.5   root     2752:     if (unlikely(rA(ctx->opcode) == 0 ||                                      \
                   2753:                  rA(ctx->opcode) == rD(ctx->opcode))) {                       \
1.1.1.6 ! root     2754:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     2755:         return;                                                               \
                   2756:     }                                                                         \
1.1.1.6 ! root     2757:     gen_set_access_type(ctx, ACCESS_INT);                                     \
        !          2758:     EA = tcg_temp_new();                                                      \
        !          2759:     gen_addr_reg_index(ctx, EA);                                              \
        !          2760:     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
        !          2761:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
        !          2762:     tcg_temp_free(EA);                                                        \
        !          2763: }
        !          2764: 
        !          2765: #define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
        !          2766: GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type)                      \
        !          2767: {                                                                             \
        !          2768:     TCGv EA;                                                                  \
        !          2769:     gen_set_access_type(ctx, ACCESS_INT);                                     \
        !          2770:     EA = tcg_temp_new();                                                      \
        !          2771:     gen_addr_reg_index(ctx, EA);                                              \
        !          2772:     gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
        !          2773:     tcg_temp_free(EA);                                                        \
        !          2774: }
        !          2775: 
        !          2776: #define GEN_LDS(name, ldop, op, type)                                         \
        !          2777: GEN_LD(name, ldop, op | 0x20, type);                                          \
        !          2778: GEN_LDU(name, ldop, op | 0x21, type);                                         \
        !          2779: GEN_LDUX(name, ldop, 0x17, op | 0x01, type);                                  \
        !          2780: GEN_LDX(name, ldop, 0x17, op | 0x00, type)
1.1       root     2781: 
                   2782: /* lbz lbzu lbzux lbzx */
1.1.1.6 ! root     2783: GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER);
1.1       root     2784: /* lha lhau lhaux lhax */
1.1.1.6 ! root     2785: GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER);
1.1       root     2786: /* lhz lhzu lhzux lhzx */
1.1.1.6 ! root     2787: GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER);
1.1       root     2788: /* lwz lwzu lwzux lwzx */
1.1.1.6 ! root     2789: GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER);
1.1.1.5   root     2790: #if defined(TARGET_PPC64)
                   2791: /* lwaux */
1.1.1.6 ! root     2792: GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B);
1.1.1.5   root     2793: /* lwax */
1.1.1.6 ! root     2794: GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B);
1.1.1.5   root     2795: /* ldux */
1.1.1.6 ! root     2796: GEN_LDUX(ld, ld64, 0x15, 0x01, PPC_64B);
1.1.1.5   root     2797: /* ldx */
1.1.1.6 ! root     2798: GEN_LDX(ld, ld64, 0x15, 0x00, PPC_64B);
1.1.1.5   root     2799: GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
                   2800: {
1.1.1.6 ! root     2801:     TCGv EA;
1.1.1.5   root     2802:     if (Rc(ctx->opcode)) {
                   2803:         if (unlikely(rA(ctx->opcode) == 0 ||
                   2804:                      rA(ctx->opcode) == rD(ctx->opcode))) {
1.1.1.6 ! root     2805:             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     2806:             return;
                   2807:         }
                   2808:     }
1.1.1.6 ! root     2809:     gen_set_access_type(ctx, ACCESS_INT);
        !          2810:     EA = tcg_temp_new();
        !          2811:     gen_addr_imm_index(ctx, EA, 0x03);
1.1.1.5   root     2812:     if (ctx->opcode & 0x02) {
                   2813:         /* lwa (lwau is undefined) */
1.1.1.6 ! root     2814:         gen_qemu_ld32s(ctx, cpu_gpr[rD(ctx->opcode)], EA);
1.1.1.5   root     2815:     } else {
                   2816:         /* ld - ldu */
1.1.1.6 ! root     2817:         gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], EA);
1.1.1.5   root     2818:     }
                   2819:     if (Rc(ctx->opcode))
1.1.1.6 ! root     2820:         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
        !          2821:     tcg_temp_free(EA);
1.1.1.5   root     2822: }
                   2823: /* lq */
                   2824: GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX)
                   2825: {
                   2826: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     2827:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     2828: #else
                   2829:     int ra, rd;
1.1.1.6 ! root     2830:     TCGv EA;
1.1.1.5   root     2831: 
                   2832:     /* Restore CPU state */
1.1.1.6 ! root     2833:     if (unlikely(ctx->mem_idx == 0)) {
        !          2834:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     2835:         return;
                   2836:     }
                   2837:     ra = rA(ctx->opcode);
                   2838:     rd = rD(ctx->opcode);
                   2839:     if (unlikely((rd & 1) || rd == ra)) {
1.1.1.6 ! root     2840:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     2841:         return;
                   2842:     }
1.1.1.6 ! root     2843:     if (unlikely(ctx->le_mode)) {
1.1.1.5   root     2844:         /* Little-endian mode is not handled */
1.1.1.6 ! root     2845:         gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
1.1.1.5   root     2846:         return;
                   2847:     }
1.1.1.6 ! root     2848:     gen_set_access_type(ctx, ACCESS_INT);
        !          2849:     EA = tcg_temp_new();
        !          2850:     gen_addr_imm_index(ctx, EA, 0x0F);
        !          2851:     gen_qemu_ld64(ctx, cpu_gpr[rd], EA);
        !          2852:     gen_addr_add(ctx, EA, EA, 8);
        !          2853:     gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
        !          2854:     tcg_temp_free(EA);
1.1.1.5   root     2855: #endif
                   2856: }
                   2857: #endif
1.1       root     2858: 
                   2859: /***                              Integer store                            ***/
1.1.1.6 ! root     2860: #define GEN_ST(name, stop, opc, type)                                         \
        !          2861: GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type)                          \
1.1       root     2862: {                                                                             \
1.1.1.6 ! root     2863:     TCGv EA;                                                                  \
        !          2864:     gen_set_access_type(ctx, ACCESS_INT);                                     \
        !          2865:     EA = tcg_temp_new();                                                      \
        !          2866:     gen_addr_imm_index(ctx, EA, 0);                                           \
        !          2867:     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
        !          2868:     tcg_temp_free(EA);                                                        \
1.1       root     2869: }
                   2870: 
1.1.1.6 ! root     2871: #define GEN_STU(name, stop, opc, type)                                        \
        !          2872: GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type)                       \
1.1       root     2873: {                                                                             \
1.1.1.6 ! root     2874:     TCGv EA;                                                                  \
1.1.1.5   root     2875:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6 ! root     2876:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     2877:         return;                                                               \
                   2878:     }                                                                         \
1.1.1.6 ! root     2879:     gen_set_access_type(ctx, ACCESS_INT);                                     \
        !          2880:     EA = tcg_temp_new();                                                      \
1.1.1.5   root     2881:     if (type == PPC_64B)                                                      \
1.1.1.6 ! root     2882:         gen_addr_imm_index(ctx, EA, 0x03);                                    \
1.1.1.5   root     2883:     else                                                                      \
1.1.1.6 ! root     2884:         gen_addr_imm_index(ctx, EA, 0);                                       \
        !          2885:     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
        !          2886:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
        !          2887:     tcg_temp_free(EA);                                                        \
1.1       root     2888: }
                   2889: 
1.1.1.6 ! root     2890: #define GEN_STUX(name, stop, opc2, opc3, type)                                \
        !          2891: GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type)                     \
1.1       root     2892: {                                                                             \
1.1.1.6 ! root     2893:     TCGv EA;                                                                  \
1.1.1.5   root     2894:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6 ! root     2895:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     2896:         return;                                                               \
                   2897:     }                                                                         \
1.1.1.6 ! root     2898:     gen_set_access_type(ctx, ACCESS_INT);                                     \
        !          2899:     EA = tcg_temp_new();                                                      \
        !          2900:     gen_addr_reg_index(ctx, EA);                                              \
        !          2901:     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
        !          2902:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
        !          2903:     tcg_temp_free(EA);                                                        \
        !          2904: }
        !          2905: 
        !          2906: #define GEN_STX(name, stop, opc2, opc3, type)                                 \
        !          2907: GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type)                      \
        !          2908: {                                                                             \
        !          2909:     TCGv EA;                                                                  \
        !          2910:     gen_set_access_type(ctx, ACCESS_INT);                                     \
        !          2911:     EA = tcg_temp_new();                                                      \
        !          2912:     gen_addr_reg_index(ctx, EA);                                              \
        !          2913:     gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
        !          2914:     tcg_temp_free(EA);                                                        \
        !          2915: }
        !          2916: 
        !          2917: #define GEN_STS(name, stop, op, type)                                         \
        !          2918: GEN_ST(name, stop, op | 0x20, type);                                          \
        !          2919: GEN_STU(name, stop, op | 0x21, type);                                         \
        !          2920: GEN_STUX(name, stop, 0x17, op | 0x01, type);                                  \
        !          2921: GEN_STX(name, stop, 0x17, op | 0x00, type)
1.1       root     2922: 
                   2923: /* stb stbu stbux stbx */
1.1.1.6 ! root     2924: GEN_STS(stb, st8, 0x06, PPC_INTEGER);
1.1       root     2925: /* sth sthu sthux sthx */
1.1.1.6 ! root     2926: GEN_STS(sth, st16, 0x0C, PPC_INTEGER);
1.1       root     2927: /* stw stwu stwux stwx */
1.1.1.6 ! root     2928: GEN_STS(stw, st32, 0x04, PPC_INTEGER);
1.1.1.5   root     2929: #if defined(TARGET_PPC64)
1.1.1.6 ! root     2930: GEN_STUX(std, st64, 0x15, 0x05, PPC_64B);
        !          2931: GEN_STX(std, st64, 0x15, 0x04, PPC_64B);
1.1.1.5   root     2932: GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
                   2933: {
                   2934:     int rs;
1.1.1.6 ! root     2935:     TCGv EA;
1.1       root     2936: 
1.1.1.5   root     2937:     rs = rS(ctx->opcode);
                   2938:     if ((ctx->opcode & 0x3) == 0x2) {
                   2939: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     2940:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     2941: #else
                   2942:         /* stq */
1.1.1.6 ! root     2943:         if (unlikely(ctx->mem_idx == 0)) {
        !          2944:             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     2945:             return;
                   2946:         }
                   2947:         if (unlikely(rs & 1)) {
1.1.1.6 ! root     2948:             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     2949:             return;
                   2950:         }
1.1.1.6 ! root     2951:         if (unlikely(ctx->le_mode)) {
1.1.1.5   root     2952:             /* Little-endian mode is not handled */
1.1.1.6 ! root     2953:             gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
1.1.1.5   root     2954:             return;
                   2955:         }
1.1.1.6 ! root     2956:         gen_set_access_type(ctx, ACCESS_INT);
        !          2957:         EA = tcg_temp_new();
        !          2958:         gen_addr_imm_index(ctx, EA, 0x03);
        !          2959:         gen_qemu_st64(ctx, cpu_gpr[rs], EA);
        !          2960:         gen_addr_add(ctx, EA, EA, 8);
        !          2961:         gen_qemu_st64(ctx, cpu_gpr[rs+1], EA);
        !          2962:         tcg_temp_free(EA);
1.1.1.5   root     2963: #endif
                   2964:     } else {
                   2965:         /* std / stdu */
                   2966:         if (Rc(ctx->opcode)) {
                   2967:             if (unlikely(rA(ctx->opcode) == 0)) {
1.1.1.6 ! root     2968:                 gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     2969:                 return;
                   2970:             }
                   2971:         }
1.1.1.6 ! root     2972:         gen_set_access_type(ctx, ACCESS_INT);
        !          2973:         EA = tcg_temp_new();
        !          2974:         gen_addr_imm_index(ctx, EA, 0x03);
        !          2975:         gen_qemu_st64(ctx, cpu_gpr[rs], EA);
1.1.1.5   root     2976:         if (Rc(ctx->opcode))
1.1.1.6 ! root     2977:             tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
        !          2978:         tcg_temp_free(EA);
1.1.1.5   root     2979:     }
                   2980: }
                   2981: #endif
1.1       root     2982: /***                Integer load and store with byte reverse               ***/
                   2983: /* lhbrx */
1.1.1.6 ! root     2984: static void always_inline gen_qemu_ld16ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
        !          2985: {
        !          2986:     tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
        !          2987:     if (likely(!ctx->le_mode)) {
        !          2988: #if defined(TARGET_PPC64)
        !          2989:         TCGv_i32 t0 = tcg_temp_new_i32();
        !          2990:         tcg_gen_trunc_tl_i32(t0, arg1);
        !          2991:         tcg_gen_bswap16_i32(t0, t0);
        !          2992:         tcg_gen_extu_i32_tl(arg1, t0);
        !          2993:         tcg_temp_free_i32(t0);
        !          2994: #else
        !          2995:         tcg_gen_bswap16_i32(arg1, arg1);
        !          2996: #endif
        !          2997:     }
        !          2998: }
        !          2999: GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
        !          3000: 
1.1       root     3001: /* lwbrx */
1.1.1.6 ! root     3002: static void always_inline gen_qemu_ld32ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
        !          3003: {
        !          3004:     tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
        !          3005:     if (likely(!ctx->le_mode)) {
        !          3006: #if defined(TARGET_PPC64)
        !          3007:         TCGv_i32 t0 = tcg_temp_new_i32();
        !          3008:         tcg_gen_trunc_tl_i32(t0, arg1);
        !          3009:         tcg_gen_bswap_i32(t0, t0);
        !          3010:         tcg_gen_extu_i32_tl(arg1, t0);
        !          3011:         tcg_temp_free_i32(t0);
        !          3012: #else
        !          3013:         tcg_gen_bswap_i32(arg1, arg1);
        !          3014: #endif
        !          3015:     }
        !          3016: }
        !          3017: GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
        !          3018: 
1.1       root     3019: /* sthbrx */
1.1.1.6 ! root     3020: static void always_inline gen_qemu_st16r(DisasContext *ctx, TCGv arg1, TCGv arg2)
        !          3021: {
        !          3022:     if (likely(!ctx->le_mode)) {
        !          3023: #if defined(TARGET_PPC64)
        !          3024:         TCGv_i32 t0;
        !          3025:         TCGv t1;
        !          3026:         t0 = tcg_temp_new_i32();
        !          3027:         tcg_gen_trunc_tl_i32(t0, arg1);
        !          3028:         tcg_gen_ext16u_i32(t0, t0);
        !          3029:         tcg_gen_bswap16_i32(t0, t0);
        !          3030:         t1 = tcg_temp_new();
        !          3031:         tcg_gen_extu_i32_tl(t1, t0);
        !          3032:         tcg_temp_free_i32(t0);
        !          3033:         tcg_gen_qemu_st16(t1, arg2, ctx->mem_idx);
        !          3034:         tcg_temp_free(t1);
        !          3035: #else
        !          3036:         TCGv t0 = tcg_temp_new();
        !          3037:         tcg_gen_ext16u_tl(t0, arg1);
        !          3038:         tcg_gen_bswap16_i32(t0, t0);
        !          3039:         tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
        !          3040:         tcg_temp_free(t0);
        !          3041: #endif
        !          3042:     } else {
        !          3043:         tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
        !          3044:     }
        !          3045: }
        !          3046: GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
        !          3047: 
1.1       root     3048: /* stwbrx */
1.1.1.6 ! root     3049: static void always_inline gen_qemu_st32r(DisasContext *ctx, TCGv arg1, TCGv arg2)
        !          3050: {
        !          3051:     if (likely(!ctx->le_mode)) {
        !          3052: #if defined(TARGET_PPC64)
        !          3053:         TCGv_i32 t0;
        !          3054:         TCGv t1;
        !          3055:         t0 = tcg_temp_new_i32();
        !          3056:         tcg_gen_trunc_tl_i32(t0, arg1);
        !          3057:         tcg_gen_bswap_i32(t0, t0);
        !          3058:         t1 = tcg_temp_new();
        !          3059:         tcg_gen_extu_i32_tl(t1, t0);
        !          3060:         tcg_temp_free_i32(t0);
        !          3061:         tcg_gen_qemu_st32(t1, arg2, ctx->mem_idx);
        !          3062:         tcg_temp_free(t1);
        !          3063: #else
        !          3064:         TCGv t0 = tcg_temp_new_i32();
        !          3065:         tcg_gen_bswap_i32(t0, arg1);
        !          3066:         tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
        !          3067:         tcg_temp_free(t0);
        !          3068: #endif
        !          3069:     } else {
        !          3070:         tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
        !          3071:     }
        !          3072: }
        !          3073: GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
1.1       root     3074: 
                   3075: /***                    Integer load and store multiple                    ***/
                   3076: /* lmw */
                   3077: GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   3078: {
1.1.1.6 ! root     3079:     TCGv t0;
        !          3080:     TCGv_i32 t1;
        !          3081:     gen_set_access_type(ctx, ACCESS_INT);
1.1.1.5   root     3082:     /* NIP cannot be restored if the memory exception comes from an helper */
                   3083:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6 ! root     3084:     t0 = tcg_temp_new();
        !          3085:     t1 = tcg_const_i32(rD(ctx->opcode));
        !          3086:     gen_addr_imm_index(ctx, t0, 0);
        !          3087:     gen_helper_lmw(t0, t1);
        !          3088:     tcg_temp_free(t0);
        !          3089:     tcg_temp_free_i32(t1);
1.1       root     3090: }
                   3091: 
                   3092: /* stmw */
                   3093: GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
                   3094: {
1.1.1.6 ! root     3095:     TCGv t0;
        !          3096:     TCGv_i32 t1;
        !          3097:     gen_set_access_type(ctx, ACCESS_INT);
1.1.1.5   root     3098:     /* NIP cannot be restored if the memory exception comes from an helper */
                   3099:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6 ! root     3100:     t0 = tcg_temp_new();
        !          3101:     t1 = tcg_const_i32(rS(ctx->opcode));
        !          3102:     gen_addr_imm_index(ctx, t0, 0);
        !          3103:     gen_helper_stmw(t0, t1);
        !          3104:     tcg_temp_free(t0);
        !          3105:     tcg_temp_free_i32(t1);
1.1       root     3106: }
                   3107: 
                   3108: /***                    Integer load and store strings                     ***/
                   3109: /* lswi */
                   3110: /* PowerPC32 specification says we must generate an exception if
                   3111:  * rA is in the range of registers to be loaded.
                   3112:  * In an other hand, IBM says this is valid, but rA won't be loaded.
                   3113:  * For now, I'll follow the spec...
                   3114:  */
1.1.1.5   root     3115: GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING)
1.1       root     3116: {
1.1.1.6 ! root     3117:     TCGv t0;
        !          3118:     TCGv_i32 t1, t2;
1.1       root     3119:     int nb = NB(ctx->opcode);
                   3120:     int start = rD(ctx->opcode);
                   3121:     int ra = rA(ctx->opcode);
                   3122:     int nr;
                   3123: 
                   3124:     if (nb == 0)
                   3125:         nb = 32;
                   3126:     nr = nb / 4;
1.1.1.5   root     3127:     if (unlikely(((start + nr) > 32  &&
                   3128:                   start <= ra && (start + nr - 32) > ra) ||
                   3129:                  ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
1.1.1.6 ! root     3130:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
1.1       root     3131:         return;
                   3132:     }
1.1.1.6 ! root     3133:     gen_set_access_type(ctx, ACCESS_INT);
1.1       root     3134:     /* NIP cannot be restored if the memory exception comes from an helper */
1.1.1.5   root     3135:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6 ! root     3136:     t0 = tcg_temp_new();
        !          3137:     gen_addr_register(ctx, t0);
        !          3138:     t1 = tcg_const_i32(nb);
        !          3139:     t2 = tcg_const_i32(start);
        !          3140:     gen_helper_lsw(t0, t1, t2);
        !          3141:     tcg_temp_free(t0);
        !          3142:     tcg_temp_free_i32(t1);
        !          3143:     tcg_temp_free_i32(t2);
1.1       root     3144: }
                   3145: 
                   3146: /* lswx */
1.1.1.5   root     3147: GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING)
1.1       root     3148: {
1.1.1.6 ! root     3149:     TCGv t0;
        !          3150:     TCGv_i32 t1, t2, t3;
        !          3151:     gen_set_access_type(ctx, ACCESS_INT);
1.1.1.5   root     3152:     /* NIP cannot be restored if the memory exception comes from an helper */
                   3153:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6 ! root     3154:     t0 = tcg_temp_new();
        !          3155:     gen_addr_reg_index(ctx, t0);
        !          3156:     t1 = tcg_const_i32(rD(ctx->opcode));
        !          3157:     t2 = tcg_const_i32(rA(ctx->opcode));
        !          3158:     t3 = tcg_const_i32(rB(ctx->opcode));
        !          3159:     gen_helper_lswx(t0, t1, t2, t3);
        !          3160:     tcg_temp_free(t0);
        !          3161:     tcg_temp_free_i32(t1);
        !          3162:     tcg_temp_free_i32(t2);
        !          3163:     tcg_temp_free_i32(t3);
1.1       root     3164: }
                   3165: 
                   3166: /* stswi */
1.1.1.5   root     3167: GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING)
1.1       root     3168: {
1.1.1.6 ! root     3169:     TCGv t0;
        !          3170:     TCGv_i32 t1, t2;
1.1       root     3171:     int nb = NB(ctx->opcode);
1.1.1.6 ! root     3172:     gen_set_access_type(ctx, ACCESS_INT);
1.1.1.5   root     3173:     /* NIP cannot be restored if the memory exception comes from an helper */
                   3174:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6 ! root     3175:     t0 = tcg_temp_new();
        !          3176:     gen_addr_register(ctx, t0);
1.1       root     3177:     if (nb == 0)
                   3178:         nb = 32;
1.1.1.6 ! root     3179:     t1 = tcg_const_i32(nb);
        !          3180:     t2 = tcg_const_i32(rS(ctx->opcode));
        !          3181:     gen_helper_stsw(t0, t1, t2);
        !          3182:     tcg_temp_free(t0);
        !          3183:     tcg_temp_free_i32(t1);
        !          3184:     tcg_temp_free_i32(t2);
1.1       root     3185: }
                   3186: 
                   3187: /* stswx */
1.1.1.5   root     3188: GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING)
1.1       root     3189: {
1.1.1.6 ! root     3190:     TCGv t0;
        !          3191:     TCGv_i32 t1, t2;
        !          3192:     gen_set_access_type(ctx, ACCESS_INT);
1.1       root     3193:     /* NIP cannot be restored if the memory exception comes from an helper */
1.1.1.5   root     3194:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6 ! root     3195:     t0 = tcg_temp_new();
        !          3196:     gen_addr_reg_index(ctx, t0);
        !          3197:     t1 = tcg_temp_new_i32();
        !          3198:     tcg_gen_trunc_tl_i32(t1, cpu_xer);
        !          3199:     tcg_gen_andi_i32(t1, t1, 0x7F);
        !          3200:     t2 = tcg_const_i32(rS(ctx->opcode));
        !          3201:     gen_helper_stsw(t0, t1, t2);
        !          3202:     tcg_temp_free(t0);
        !          3203:     tcg_temp_free_i32(t1);
        !          3204:     tcg_temp_free_i32(t2);
1.1       root     3205: }
                   3206: 
                   3207: /***                        Memory synchronisation                         ***/
                   3208: /* eieio */
1.1.1.5   root     3209: GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO)
1.1       root     3210: {
                   3211: }
                   3212: 
                   3213: /* isync */
1.1.1.5   root     3214: GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM)
1.1       root     3215: {
1.1.1.6 ! root     3216:     gen_stop_exception(ctx);
1.1       root     3217: }
                   3218: 
                   3219: /* lwarx */
1.1.1.5   root     3220: GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000001, PPC_RES)
1.1       root     3221: {
1.1.1.6 ! root     3222:     TCGv t0;
        !          3223:     gen_set_access_type(ctx, ACCESS_RES);
        !          3224:     t0 = tcg_temp_local_new();
        !          3225:     gen_addr_reg_index(ctx, t0);
        !          3226:     gen_check_align(ctx, t0, 0x03);
        !          3227:     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
        !          3228:     tcg_gen_mov_tl(cpu_reserve, t0);
        !          3229:     tcg_temp_free(t0);
1.1       root     3230: }
                   3231: 
                   3232: /* stwcx. */
1.1.1.5   root     3233: GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES)
1.1       root     3234: {
1.1.1.6 ! root     3235:     int l1;
        !          3236:     TCGv t0;
        !          3237:     gen_set_access_type(ctx, ACCESS_RES);
        !          3238:     t0 = tcg_temp_local_new();
        !          3239:     gen_addr_reg_index(ctx, t0);
        !          3240:     gen_check_align(ctx, t0, 0x03);
        !          3241:     tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
        !          3242:     tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
        !          3243:     tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
        !          3244:     l1 = gen_new_label();
        !          3245:     tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
        !          3246:     tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
        !          3247:     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], t0);
        !          3248:     gen_set_label(l1);
        !          3249:     tcg_gen_movi_tl(cpu_reserve, -1);
        !          3250:     tcg_temp_free(t0);
1.1       root     3251: }
                   3252: 
1.1.1.5   root     3253: #if defined(TARGET_PPC64)
                   3254: /* ldarx */
                   3255: GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_64B)
                   3256: {
1.1.1.6 ! root     3257:     TCGv t0;
        !          3258:     gen_set_access_type(ctx, ACCESS_RES);
        !          3259:     t0 = tcg_temp_local_new();
        !          3260:     gen_addr_reg_index(ctx, t0);
        !          3261:     gen_check_align(ctx, t0, 0x07);
        !          3262:     gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], t0);
        !          3263:     tcg_gen_mov_tl(cpu_reserve, t0);
        !          3264:     tcg_temp_free(t0);
1.1.1.5   root     3265: }
                   3266: 
                   3267: /* stdcx. */
                   3268: GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B)
                   3269: {
1.1.1.6 ! root     3270:     int l1;
        !          3271:     TCGv t0;
        !          3272:     gen_set_access_type(ctx, ACCESS_RES);
        !          3273:     t0 = tcg_temp_local_new();
        !          3274:     gen_addr_reg_index(ctx, t0);
        !          3275:     gen_check_align(ctx, t0, 0x07);
        !          3276:     tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
        !          3277:     tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
        !          3278:     tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
        !          3279:     l1 = gen_new_label();
        !          3280:     tcg_gen_brcond_tl(TCG_COND_NE, t0, cpu_reserve, l1);
        !          3281:     tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);
        !          3282:     gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], t0);
        !          3283:     gen_set_label(l1);
        !          3284:     tcg_gen_movi_tl(cpu_reserve, -1);
        !          3285:     tcg_temp_free(t0);
1.1.1.5   root     3286: }
                   3287: #endif /* defined(TARGET_PPC64) */
                   3288: 
1.1       root     3289: /* sync */
1.1.1.5   root     3290: GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC)
1.1       root     3291: {
                   3292: }
                   3293: 
1.1.1.5   root     3294: /* wait */
                   3295: GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT)
                   3296: {
1.1.1.6 ! root     3297:     TCGv_i32 t0 = tcg_temp_new_i32();
        !          3298:     tcg_gen_st_i32(t0, cpu_env, offsetof(CPUState, halted));
        !          3299:     tcg_temp_free_i32(t0);
1.1.1.5   root     3300:     /* Stop translation, as the CPU is supposed to sleep from now */
1.1.1.6 ! root     3301:     gen_exception_err(ctx, EXCP_HLT, 1);
1.1.1.5   root     3302: }
                   3303: 
1.1       root     3304: /***                         Floating-point load                           ***/
1.1.1.6 ! root     3305: #define GEN_LDF(name, ldop, opc, type)                                        \
        !          3306: GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type)                          \
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.6 ! root     3313:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
        !          3314:     EA = tcg_temp_new();                                                      \
        !          3315:     gen_addr_imm_index(ctx, EA, 0);                                           \
        !          3316:     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
        !          3317:     tcg_temp_free(EA);                                                        \
1.1       root     3318: }
                   3319: 
1.1.1.6 ! root     3320: #define GEN_LDUF(name, ldop, opc, type)                                       \
        !          3321: GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type)                       \
1.1       root     3322: {                                                                             \
1.1.1.6 ! root     3323:     TCGv EA;                                                                  \
1.1.1.5   root     3324:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6 ! root     3325:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3326:         return;                                                               \
                   3327:     }                                                                         \
1.1.1.5   root     3328:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6 ! root     3329:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     3330:         return;                                                               \
                   3331:     }                                                                         \
1.1.1.6 ! root     3332:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
        !          3333:     EA = tcg_temp_new();                                                      \
        !          3334:     gen_addr_imm_index(ctx, EA, 0);                                           \
        !          3335:     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
        !          3336:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
        !          3337:     tcg_temp_free(EA);                                                        \
1.1       root     3338: }
                   3339: 
1.1.1.6 ! root     3340: #define GEN_LDUXF(name, ldop, opc, type)                                      \
        !          3341: GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type)                      \
1.1       root     3342: {                                                                             \
1.1.1.6 ! root     3343:     TCGv EA;                                                                  \
1.1.1.5   root     3344:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6 ! root     3345:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3346:         return;                                                               \
                   3347:     }                                                                         \
1.1.1.5   root     3348:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6 ! root     3349:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     3350:         return;                                                               \
                   3351:     }                                                                         \
1.1.1.6 ! root     3352:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
        !          3353:     EA = tcg_temp_new();                                                      \
        !          3354:     gen_addr_reg_index(ctx, EA);                                              \
        !          3355:     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
        !          3356:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
        !          3357:     tcg_temp_free(EA);                                                        \
1.1       root     3358: }
                   3359: 
1.1.1.6 ! root     3360: #define GEN_LDXF(name, ldop, opc2, opc3, type)                                \
        !          3361: GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type)                      \
1.1       root     3362: {                                                                             \
1.1.1.6 ! root     3363:     TCGv EA;                                                                  \
1.1.1.5   root     3364:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6 ! root     3365:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3366:         return;                                                               \
                   3367:     }                                                                         \
1.1.1.6 ! root     3368:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
        !          3369:     EA = tcg_temp_new();                                                      \
        !          3370:     gen_addr_reg_index(ctx, EA);                                              \
        !          3371:     gen_qemu_##ldop(ctx, cpu_fpr[rD(ctx->opcode)], EA);                       \
        !          3372:     tcg_temp_free(EA);                                                        \
        !          3373: }
        !          3374: 
        !          3375: #define GEN_LDFS(name, ldop, op, type)                                        \
        !          3376: GEN_LDF(name, ldop, op | 0x20, type);                                         \
        !          3377: GEN_LDUF(name, ldop, op | 0x21, type);                                        \
        !          3378: GEN_LDUXF(name, ldop, op | 0x01, type);                                       \
        !          3379: GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
        !          3380: 
        !          3381: static always_inline void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
        !          3382: {
        !          3383:     TCGv t0 = tcg_temp_new();
        !          3384:     TCGv_i32 t1 = tcg_temp_new_i32();
        !          3385:     gen_qemu_ld32u(ctx, t0, arg2);
        !          3386:     tcg_gen_trunc_tl_i32(t1, t0);
        !          3387:     tcg_temp_free(t0);
        !          3388:     gen_helper_float32_to_float64(arg1, t1);
        !          3389:     tcg_temp_free_i32(t1);
        !          3390: }
        !          3391: 
        !          3392:  /* lfd lfdu lfdux lfdx */
        !          3393: GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT);
        !          3394:  /* lfs lfsu lfsux lfsx */
        !          3395: GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT);
1.1       root     3396: 
                   3397: /***                         Floating-point store                          ***/
1.1.1.6 ! root     3398: #define GEN_STF(name, stop, opc, type)                                        \
        !          3399: GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type)                          \
1.1       root     3400: {                                                                             \
1.1.1.6 ! root     3401:     TCGv EA;                                                                  \
1.1.1.5   root     3402:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6 ! root     3403:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1.1.5   root     3404:         return;                                                               \
1.1       root     3405:     }                                                                         \
1.1.1.6 ! root     3406:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
        !          3407:     EA = tcg_temp_new();                                                      \
        !          3408:     gen_addr_imm_index(ctx, EA, 0);                                           \
        !          3409:     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
        !          3410:     tcg_temp_free(EA);                                                        \
1.1       root     3411: }
                   3412: 
1.1.1.6 ! root     3413: #define GEN_STUF(name, stop, opc, type)                                       \
        !          3414: GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type)                       \
1.1       root     3415: {                                                                             \
1.1.1.6 ! root     3416:     TCGv EA;                                                                  \
1.1.1.5   root     3417:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6 ! root     3418:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3419:         return;                                                               \
                   3420:     }                                                                         \
1.1.1.5   root     3421:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6 ! root     3422:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     3423:         return;                                                               \
                   3424:     }                                                                         \
1.1.1.6 ! root     3425:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
        !          3426:     EA = tcg_temp_new();                                                      \
        !          3427:     gen_addr_imm_index(ctx, EA, 0);                                           \
        !          3428:     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
        !          3429:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
        !          3430:     tcg_temp_free(EA);                                                        \
1.1       root     3431: }
                   3432: 
1.1.1.6 ! root     3433: #define GEN_STUXF(name, stop, opc, type)                                      \
        !          3434: GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type)                      \
1.1       root     3435: {                                                                             \
1.1.1.6 ! root     3436:     TCGv EA;                                                                  \
1.1.1.5   root     3437:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6 ! root     3438:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3439:         return;                                                               \
                   3440:     }                                                                         \
1.1.1.5   root     3441:     if (unlikely(rA(ctx->opcode) == 0)) {                                     \
1.1.1.6 ! root     3442:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
1.1       root     3443:         return;                                                               \
                   3444:     }                                                                         \
1.1.1.6 ! root     3445:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
        !          3446:     EA = tcg_temp_new();                                                      \
        !          3447:     gen_addr_reg_index(ctx, EA);                                              \
        !          3448:     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
        !          3449:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
        !          3450:     tcg_temp_free(EA);                                                        \
1.1       root     3451: }
                   3452: 
1.1.1.6 ! root     3453: #define GEN_STXF(name, stop, opc2, opc3, type)                                \
        !          3454: GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type)                      \
1.1       root     3455: {                                                                             \
1.1.1.6 ! root     3456:     TCGv EA;                                                                  \
1.1.1.5   root     3457:     if (unlikely(!ctx->fpu_enabled)) {                                        \
1.1.1.6 ! root     3458:         gen_exception(ctx, POWERPC_EXCP_FPU);                                 \
1.1       root     3459:         return;                                                               \
                   3460:     }                                                                         \
1.1.1.6 ! root     3461:     gen_set_access_type(ctx, ACCESS_FLOAT);                                   \
        !          3462:     EA = tcg_temp_new();                                                      \
        !          3463:     gen_addr_reg_index(ctx, EA);                                              \
        !          3464:     gen_qemu_##stop(ctx, cpu_fpr[rS(ctx->opcode)], EA);                       \
        !          3465:     tcg_temp_free(EA);                                                        \
        !          3466: }
        !          3467: 
        !          3468: #define GEN_STFS(name, stop, op, type)                                        \
        !          3469: GEN_STF(name, stop, op | 0x20, type);                                         \
        !          3470: GEN_STUF(name, stop, op | 0x21, type);                                        \
        !          3471: GEN_STUXF(name, stop, op | 0x01, type);                                       \
        !          3472: GEN_STXF(name, stop, 0x17, op | 0x00, type)
        !          3473: 
        !          3474: static always_inline void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
        !          3475: {
        !          3476:     TCGv_i32 t0 = tcg_temp_new_i32();
        !          3477:     TCGv t1 = tcg_temp_new();
        !          3478:     gen_helper_float64_to_float32(t0, arg1);
        !          3479:     tcg_gen_extu_i32_tl(t1, t0);
        !          3480:     tcg_temp_free_i32(t0);
        !          3481:     gen_qemu_st32(ctx, t1, arg2);
        !          3482:     tcg_temp_free(t1);
1.1       root     3483: }
                   3484: 
                   3485: /* stfd stfdu stfdux stfdx */
1.1.1.6 ! root     3486: GEN_STFS(stfd, st64, 0x16, PPC_FLOAT);
1.1       root     3487: /* stfs stfsu stfsux stfsx */
1.1.1.6 ! root     3488: GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT);
1.1       root     3489: 
                   3490: /* Optional: */
1.1.1.6 ! root     3491: static always_inline void gen_qemu_st32fiw(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
        !          3492: {
        !          3493:     TCGv t0 = tcg_temp_new();
        !          3494:     tcg_gen_trunc_i64_tl(t0, arg1),
        !          3495:     gen_qemu_st32(ctx, t0, arg2);
        !          3496:     tcg_temp_free(t0);
        !          3497: }
1.1       root     3498: /* stfiwx */
1.1.1.6 ! root     3499: GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX);
1.1       root     3500: 
                   3501: /***                                Branch                                 ***/
1.1.1.5   root     3502: static always_inline void gen_goto_tb (DisasContext *ctx, int n,
                   3503:                                        target_ulong dest)
1.1.1.2   root     3504: {
                   3505:     TranslationBlock *tb;
                   3506:     tb = ctx->tb;
1.1.1.5   root     3507: #if defined(TARGET_PPC64)
1.1.1.6 ! root     3508:     if (!ctx->sf_mode)
        !          3509:         dest = (uint32_t) dest;
1.1.1.5   root     3510: #endif
1.1.1.6 ! root     3511:     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
        !          3512:         likely(!ctx->singlestep_enabled)) {
        !          3513:         tcg_gen_goto_tb(n);
        !          3514:         tcg_gen_movi_tl(cpu_nip, dest & ~3);
        !          3515:         tcg_gen_exit_tb((long)tb + n);
1.1.1.2   root     3516:     } else {
1.1.1.6 ! root     3517:         tcg_gen_movi_tl(cpu_nip, dest & ~3);
        !          3518:         if (unlikely(ctx->singlestep_enabled)) {
        !          3519:             if ((ctx->singlestep_enabled &
        !          3520:                 (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
        !          3521:                 ctx->exception == POWERPC_EXCP_BRANCH) {
        !          3522:                 target_ulong tmp = ctx->nip;
        !          3523:                 ctx->nip = dest;
        !          3524:                 gen_exception(ctx, POWERPC_EXCP_TRACE);
        !          3525:                 ctx->nip = tmp;
        !          3526:             }
        !          3527:             if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
        !          3528:                 gen_debug_exception(ctx);
        !          3529:             }
        !          3530:         }
        !          3531:         tcg_gen_exit_tb(0);
1.1.1.2   root     3532:     }
                   3533: }
                   3534: 
1.1.1.5   root     3535: static always_inline void gen_setlr (DisasContext *ctx, target_ulong nip)
                   3536: {
                   3537: #if defined(TARGET_PPC64)
1.1.1.6 ! root     3538:     if (ctx->sf_mode == 0)
        !          3539:         tcg_gen_movi_tl(cpu_lr, (uint32_t)nip);
1.1.1.5   root     3540:     else
                   3541: #endif
1.1.1.6 ! root     3542:         tcg_gen_movi_tl(cpu_lr, nip);
1.1.1.5   root     3543: }
                   3544: 
1.1       root     3545: /* b ba bl bla */
                   3546: GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
                   3547: {
1.1.1.5   root     3548:     target_ulong li, target;
1.1       root     3549: 
1.1.1.6 ! root     3550:     ctx->exception = POWERPC_EXCP_BRANCH;
1.1       root     3551:     /* sign extend LI */
1.1.1.5   root     3552: #if defined(TARGET_PPC64)
                   3553:     if (ctx->sf_mode)
                   3554:         li = ((int64_t)LI(ctx->opcode) << 38) >> 38;
                   3555:     else
                   3556: #endif
                   3557:         li = ((int32_t)LI(ctx->opcode) << 6) >> 6;
                   3558:     if (likely(AA(ctx->opcode) == 0))
1.1       root     3559:         target = ctx->nip + li - 4;
                   3560:     else
                   3561:         target = li;
1.1.1.5   root     3562:     if (LK(ctx->opcode))
                   3563:         gen_setlr(ctx, ctx->nip);
1.1.1.2   root     3564:     gen_goto_tb(ctx, 0, target);
1.1       root     3565: }
                   3566: 
                   3567: #define BCOND_IM  0
                   3568: #define BCOND_LR  1
                   3569: #define BCOND_CTR 2
                   3570: 
1.1.1.5   root     3571: static always_inline void gen_bcond (DisasContext *ctx, int type)
                   3572: {
                   3573:     uint32_t bo = BO(ctx->opcode);
1.1.1.6 ! root     3574:     int l1 = gen_new_label();
        !          3575:     TCGv target;
1.1       root     3576: 
1.1.1.6 ! root     3577:     ctx->exception = POWERPC_EXCP_BRANCH;
        !          3578:     if (type == BCOND_LR || type == BCOND_CTR) {
        !          3579:         target = tcg_temp_local_new();
        !          3580:         if (type == BCOND_CTR)
        !          3581:             tcg_gen_mov_tl(target, cpu_ctr);
        !          3582:         else
        !          3583:             tcg_gen_mov_tl(target, cpu_lr);
1.1       root     3584:     }
1.1.1.5   root     3585:     if (LK(ctx->opcode))
                   3586:         gen_setlr(ctx, ctx->nip);
1.1.1.6 ! root     3587:     l1 = gen_new_label();
        !          3588:     if ((bo & 0x4) == 0) {
        !          3589:         /* Decrement and test CTR */
        !          3590:         TCGv temp = tcg_temp_new();
        !          3591:         if (unlikely(type == BCOND_CTR)) {
        !          3592:             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
        !          3593:             return;
        !          3594:         }
        !          3595:         tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
1.1.1.5   root     3596: #if defined(TARGET_PPC64)
1.1.1.6 ! root     3597:         if (!ctx->sf_mode)
        !          3598:             tcg_gen_ext32u_tl(temp, cpu_ctr);
        !          3599:         else
1.1.1.5   root     3600: #endif
1.1.1.6 ! root     3601:             tcg_gen_mov_tl(temp, cpu_ctr);
        !          3602:         if (bo & 0x2) {
        !          3603:             tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
        !          3604:         } else {
        !          3605:             tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
1.1       root     3606:         }
1.1.1.6 ! root     3607:         tcg_temp_free(temp);
        !          3608:     }
        !          3609:     if ((bo & 0x10) == 0) {
        !          3610:         /* Test CR */
        !          3611:         uint32_t bi = BI(ctx->opcode);
        !          3612:         uint32_t mask = 1 << (3 - (bi & 0x03));
        !          3613:         TCGv_i32 temp = tcg_temp_new_i32();
        !          3614: 
1.1.1.5   root     3615:         if (bo & 0x8) {
1.1.1.6 ! root     3616:             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
        !          3617:             tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1);
1.1.1.5   root     3618:         } else {
1.1.1.6 ! root     3619:             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
        !          3620:             tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);
1.1.1.5   root     3621:         }
1.1.1.6 ! root     3622:         tcg_temp_free_i32(temp);
1.1.1.5   root     3623:     }
1.1       root     3624:     if (type == BCOND_IM) {
1.1.1.6 ! root     3625:         target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
        !          3626:         if (likely(AA(ctx->opcode) == 0)) {
        !          3627:             gen_goto_tb(ctx, 0, ctx->nip + li - 4);
        !          3628:         } else {
        !          3629:             gen_goto_tb(ctx, 0, li);
        !          3630:         }
1.1.1.2   root     3631:         gen_set_label(l1);
                   3632:         gen_goto_tb(ctx, 1, ctx->nip);
1.1       root     3633:     } else {
1.1.1.5   root     3634: #if defined(TARGET_PPC64)
1.1.1.6 ! root     3635:         if (!(ctx->sf_mode))
        !          3636:             tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3);
        !          3637:         else
        !          3638: #endif
        !          3639:             tcg_gen_andi_tl(cpu_nip, target, ~3);
        !          3640:         tcg_gen_exit_tb(0);
        !          3641:         gen_set_label(l1);
        !          3642: #if defined(TARGET_PPC64)
        !          3643:         if (!(ctx->sf_mode))
        !          3644:             tcg_gen_movi_tl(cpu_nip, (uint32_t)ctx->nip);
1.1.1.5   root     3645:         else
                   3646: #endif
1.1.1.6 ! root     3647:             tcg_gen_movi_tl(cpu_nip, ctx->nip);
        !          3648:         tcg_gen_exit_tb(0);
1.1       root     3649:     }
                   3650: }
                   3651: 
                   3652: GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1.1.1.5   root     3653: {
1.1       root     3654:     gen_bcond(ctx, BCOND_IM);
                   3655: }
                   3656: 
                   3657: GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
1.1.1.5   root     3658: {
1.1       root     3659:     gen_bcond(ctx, BCOND_CTR);
                   3660: }
                   3661: 
                   3662: GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
1.1.1.5   root     3663: {
1.1       root     3664:     gen_bcond(ctx, BCOND_LR);
                   3665: }
                   3666: 
                   3667: /***                      Condition register logical                       ***/
1.1.1.6 ! root     3668: #define GEN_CRLOGIC(name, tcg_op, opc)                                        \
        !          3669: GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                   \
1.1       root     3670: {                                                                             \
1.1.1.5   root     3671:     uint8_t bitmask;                                                          \
                   3672:     int sh;                                                                   \
1.1.1.6 ! root     3673:     TCGv_i32 t0, t1;                                                          \
1.1.1.5   root     3674:     sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
1.1.1.6 ! root     3675:     t0 = tcg_temp_new_i32();                                                  \
1.1.1.5   root     3676:     if (sh > 0)                                                               \
1.1.1.6 ! root     3677:         tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh);            \
1.1.1.5   root     3678:     else if (sh < 0)                                                          \
1.1.1.6 ! root     3679:         tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh);           \
        !          3680:     else                                                                      \
        !          3681:         tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]);                 \
        !          3682:     t1 = tcg_temp_new_i32();                                                  \
1.1.1.5   root     3683:     sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
                   3684:     if (sh > 0)                                                               \
1.1.1.6 ! root     3685:         tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh);            \
1.1.1.5   root     3686:     else if (sh < 0)                                                          \
1.1.1.6 ! root     3687:         tcg_gen_shli_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], -sh);           \
        !          3688:     else                                                                      \
        !          3689:         tcg_gen_mov_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2]);                 \
        !          3690:     tcg_op(t0, t0, t1);                                                       \
1.1.1.5   root     3691:     bitmask = 1 << (3 - (crbD(ctx->opcode) & 0x03));                          \
1.1.1.6 ! root     3692:     tcg_gen_andi_i32(t0, t0, bitmask);                                        \
        !          3693:     tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask);          \
        !          3694:     tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1);                  \
        !          3695:     tcg_temp_free_i32(t0);                                                    \
        !          3696:     tcg_temp_free_i32(t1);                                                    \
1.1       root     3697: }
                   3698: 
                   3699: /* crand */
1.1.1.6 ! root     3700: GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08);
1.1       root     3701: /* crandc */
1.1.1.6 ! root     3702: GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04);
1.1       root     3703: /* creqv */
1.1.1.6 ! root     3704: GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09);
1.1       root     3705: /* crnand */
1.1.1.6 ! root     3706: GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07);
1.1       root     3707: /* crnor */
1.1.1.6 ! root     3708: GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01);
1.1       root     3709: /* cror */
1.1.1.6 ! root     3710: GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E);
1.1       root     3711: /* crorc */
1.1.1.6 ! root     3712: GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D);
1.1       root     3713: /* crxor */
1.1.1.6 ! root     3714: GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06);
1.1       root     3715: /* mcrf */
                   3716: GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
                   3717: {
1.1.1.6 ! root     3718:     tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]);
1.1       root     3719: }
                   3720: 
                   3721: /***                           System linkage                              ***/
1.1.1.6 ! root     3722: /* rfi (mem_idx only) */
1.1.1.5   root     3723: GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
1.1       root     3724: {
                   3725: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     3726:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     3727: #else
                   3728:     /* Restore CPU state */
1.1.1.6 ! root     3729:     if (unlikely(!ctx->mem_idx)) {
        !          3730:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     3731:         return;
                   3732:     }
1.1.1.6 ! root     3733:     gen_helper_rfi();
        !          3734:     gen_sync_exception(ctx);
1.1       root     3735: #endif
                   3736: }
                   3737: 
1.1.1.5   root     3738: #if defined(TARGET_PPC64)
                   3739: GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
                   3740: {
                   3741: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     3742:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     3743: #else
                   3744:     /* Restore CPU state */
1.1.1.6 ! root     3745:     if (unlikely(!ctx->mem_idx)) {
        !          3746:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     3747:         return;
                   3748:     }
1.1.1.6 ! root     3749:     gen_helper_rfid();
        !          3750:     gen_sync_exception(ctx);
1.1.1.5   root     3751: #endif
                   3752: }
                   3753: 
                   3754: GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H)
1.1       root     3755: {
                   3756: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     3757:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     3758: #else
                   3759:     /* Restore CPU state */
1.1.1.6 ! root     3760:     if (unlikely(ctx->mem_idx <= 1)) {
        !          3761:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     3762:         return;
                   3763:     }
1.1.1.6 ! root     3764:     gen_helper_hrfid();
        !          3765:     gen_sync_exception(ctx);
1.1.1.5   root     3766: #endif
                   3767: }
                   3768: #endif
                   3769: 
                   3770: /* sc */
                   3771: #if defined(CONFIG_USER_ONLY)
                   3772: #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
1.1       root     3773: #else
1.1.1.5   root     3774: #define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
1.1       root     3775: #endif
1.1.1.5   root     3776: GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
                   3777: {
                   3778:     uint32_t lev;
                   3779: 
                   3780:     lev = (ctx->opcode >> 5) & 0x7F;
1.1.1.6 ! root     3781:     gen_exception_err(ctx, POWERPC_SYSCALL, lev);
1.1       root     3782: }
                   3783: 
                   3784: /***                                Trap                                   ***/
                   3785: /* tw */
1.1.1.5   root     3786: GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW)
1.1       root     3787: {
1.1.1.6 ! root     3788:     TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
1.1.1.4   root     3789:     /* Update the nip since this might generate a trap exception */
1.1.1.5   root     3790:     gen_update_nip(ctx, ctx->nip);
1.1.1.6 ! root     3791:     gen_helper_tw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
        !          3792:     tcg_temp_free_i32(t0);
1.1       root     3793: }
                   3794: 
                   3795: /* twi */
                   3796: GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
                   3797: {
1.1.1.6 ! root     3798:     TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
        !          3799:     TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
1.1.1.5   root     3800:     /* Update the nip since this might generate a trap exception */
                   3801:     gen_update_nip(ctx, ctx->nip);
1.1.1.6 ! root     3802:     gen_helper_tw(cpu_gpr[rA(ctx->opcode)], t0, t1);
        !          3803:     tcg_temp_free(t0);
        !          3804:     tcg_temp_free_i32(t1);
1.1       root     3805: }
                   3806: 
1.1.1.5   root     3807: #if defined(TARGET_PPC64)
                   3808: /* td */
                   3809: GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B)
1.1       root     3810: {
1.1.1.6 ! root     3811:     TCGv_i32 t0 = tcg_const_i32(TO(ctx->opcode));
1.1.1.5   root     3812:     /* Update the nip since this might generate a trap exception */
                   3813:     gen_update_nip(ctx, ctx->nip);
1.1.1.6 ! root     3814:     gen_helper_td(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
        !          3815:     tcg_temp_free_i32(t0);
1.1.1.5   root     3816: }
1.1       root     3817: 
1.1.1.5   root     3818: /* tdi */
                   3819: GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B)
                   3820: {
1.1.1.6 ! root     3821:     TCGv t0 = tcg_const_tl(SIMM(ctx->opcode));
        !          3822:     TCGv_i32 t1 = tcg_const_i32(TO(ctx->opcode));
1.1.1.5   root     3823:     /* Update the nip since this might generate a trap exception */
                   3824:     gen_update_nip(ctx, ctx->nip);
1.1.1.6 ! root     3825:     gen_helper_td(cpu_gpr[rA(ctx->opcode)], t0, t1);
        !          3826:     tcg_temp_free(t0);
        !          3827:     tcg_temp_free_i32(t1);
1.1       root     3828: }
1.1.1.5   root     3829: #endif
1.1       root     3830: 
1.1.1.5   root     3831: /***                          Processor control                            ***/
1.1       root     3832: /* mcrxr */
                   3833: GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
                   3834: {
1.1.1.6 ! root     3835:     tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], cpu_xer);
        !          3836:     tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], XER_CA);
        !          3837:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_SO | 1 << XER_OV | 1 << XER_CA));
1.1       root     3838: }
                   3839: 
1.1.1.6 ! root     3840: /* mfcr mfocrf */
1.1.1.5   root     3841: GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
1.1       root     3842: {
1.1.1.5   root     3843:     uint32_t crm, crn;
                   3844: 
                   3845:     if (likely(ctx->opcode & 0x00100000)) {
                   3846:         crm = CRM(ctx->opcode);
1.1.1.6 ! root     3847:         if (likely(crm && ((crm & (crm - 1)) == 0))) {
        !          3848:             crn = ctz32 (crm);
        !          3849:             tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
        !          3850:             tcg_gen_shli_i32(cpu_gpr[rD(ctx->opcode)],
        !          3851:                              cpu_gpr[rD(ctx->opcode)], crn * 4);
1.1.1.5   root     3852:         }
                   3853:     } else {
1.1.1.6 ! root     3854:         gen_helper_load_cr(cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     3855:     }
1.1       root     3856: }
                   3857: 
                   3858: /* mfmsr */
                   3859: GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
                   3860: {
                   3861: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     3862:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     3863: #else
1.1.1.6 ! root     3864:     if (unlikely(!ctx->mem_idx)) {
        !          3865:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     3866:         return;
                   3867:     }
1.1.1.6 ! root     3868:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
1.1       root     3869: #endif
                   3870: }
                   3871: 
1.1.1.5   root     3872: #if 1
                   3873: #define SPR_NOACCESS ((void *)(-1UL))
1.1       root     3874: #else
                   3875: static void spr_noaccess (void *opaque, int sprn)
                   3876: {
                   3877:     sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
                   3878:     printf("ERROR: try to access SPR %d !\n", sprn);
                   3879: }
                   3880: #define SPR_NOACCESS (&spr_noaccess)
                   3881: #endif
                   3882: 
                   3883: /* mfspr */
1.1.1.5   root     3884: static always_inline void gen_op_mfspr (DisasContext *ctx)
1.1       root     3885: {
1.1.1.6 ! root     3886:     void (*read_cb)(void *opaque, int gprn, int sprn);
1.1       root     3887:     uint32_t sprn = SPR(ctx->opcode);
                   3888: 
                   3889: #if !defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     3890:     if (ctx->mem_idx == 2)
1.1.1.5   root     3891:         read_cb = ctx->spr_cb[sprn].hea_read;
1.1.1.6 ! root     3892:     else if (ctx->mem_idx)
1.1       root     3893:         read_cb = ctx->spr_cb[sprn].oea_read;
                   3894:     else
                   3895: #endif
                   3896:         read_cb = ctx->spr_cb[sprn].uea_read;
1.1.1.5   root     3897:     if (likely(read_cb != NULL)) {
                   3898:         if (likely(read_cb != SPR_NOACCESS)) {
1.1.1.6 ! root     3899:             (*read_cb)(ctx, rD(ctx->opcode), sprn);
1.1       root     3900:         } else {
                   3901:             /* Privilege exception */
1.1.1.5   root     3902:             /* This is a hack to avoid warnings when running Linux:
                   3903:              * this OS breaks the PowerPC virtualisation model,
                   3904:              * allowing userland application to read the PVR
                   3905:              */
                   3906:             if (sprn != SPR_PVR) {
1.1.1.6 ! root     3907:                 qemu_log("Trying to read privileged spr %d %03x at "
1.1.1.5   root     3908:                             ADDRX "\n", sprn, sprn, ctx->nip);
                   3909:                 printf("Trying to read privileged spr %d %03x at " ADDRX "\n",
                   3910:                        sprn, sprn, ctx->nip);
1.1.1.2   root     3911:             }
1.1.1.6 ! root     3912:             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     3913:         }
                   3914:     } else {
                   3915:         /* Not defined */
1.1.1.6 ! root     3916:         qemu_log("Trying to read invalid spr %d %03x at "
1.1.1.5   root     3917:                     ADDRX "\n", sprn, sprn, ctx->nip);
                   3918:         printf("Trying to read invalid spr %d %03x at " ADDRX "\n",
                   3919:                sprn, sprn, ctx->nip);
1.1.1.6 ! root     3920:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
1.1       root     3921:     }
                   3922: }
                   3923: 
                   3924: GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC)
                   3925: {
                   3926:     gen_op_mfspr(ctx);
1.1.1.5   root     3927: }
1.1       root     3928: 
                   3929: /* mftb */
1.1.1.5   root     3930: GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
1.1       root     3931: {
                   3932:     gen_op_mfspr(ctx);
                   3933: }
                   3934: 
1.1.1.6 ! root     3935: /* mtcrf mtocrf*/
1.1       root     3936: GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
                   3937: {
1.1.1.5   root     3938:     uint32_t crm, crn;
                   3939: 
                   3940:     crm = CRM(ctx->opcode);
1.1.1.6 ! root     3941:     if (likely((ctx->opcode & 0x00100000))) {
        !          3942:         if (crm && ((crm & (crm - 1)) == 0)) {
        !          3943:             TCGv_i32 temp = tcg_temp_new_i32();
        !          3944:             crn = ctz32 (crm);
        !          3945:             tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
        !          3946:             tcg_gen_shri_i32(temp, temp, crn * 4);
        !          3947:             tcg_gen_andi_i32(cpu_crf[7 - crn], temp, 0xf);
        !          3948:             tcg_temp_free_i32(temp);
        !          3949:         }
1.1.1.5   root     3950:     } else {
1.1.1.6 ! root     3951:         TCGv_i32 temp = tcg_const_i32(crm);
        !          3952:         gen_helper_store_cr(cpu_gpr[rS(ctx->opcode)], temp);
        !          3953:         tcg_temp_free_i32(temp);
1.1.1.5   root     3954:     }
1.1       root     3955: }
                   3956: 
                   3957: /* mtmsr */
1.1.1.5   root     3958: #if defined(TARGET_PPC64)
                   3959: GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B)
                   3960: {
                   3961: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     3962:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     3963: #else
1.1.1.6 ! root     3964:     if (unlikely(!ctx->mem_idx)) {
        !          3965:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     3966:         return;
                   3967:     }
                   3968:     if (ctx->opcode & 0x00010000) {
                   3969:         /* Special form that does not need any synchronisation */
1.1.1.6 ! root     3970:         TCGv t0 = tcg_temp_new();
        !          3971:         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
        !          3972:         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
        !          3973:         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
        !          3974:         tcg_temp_free(t0);
1.1.1.5   root     3975:     } else {
                   3976:         /* XXX: we need to update nip before the store
                   3977:          *      if we enter power saving mode, we will exit the loop
                   3978:          *      directly from ppc_store_msr
                   3979:          */
                   3980:         gen_update_nip(ctx, ctx->nip);
1.1.1.6 ! root     3981:         gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     3982:         /* Must stop the translation as machine state (may have) changed */
                   3983:         /* Note that mtmsr is not always defined as context-synchronizing */
1.1.1.6 ! root     3984:         gen_stop_exception(ctx);
1.1.1.5   root     3985:     }
                   3986: #endif
                   3987: }
                   3988: #endif
                   3989: 
1.1       root     3990: GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
                   3991: {
                   3992: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     3993:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     3994: #else
1.1.1.6 ! root     3995:     if (unlikely(!ctx->mem_idx)) {
        !          3996:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     3997:         return;
                   3998:     }
1.1.1.5   root     3999:     if (ctx->opcode & 0x00010000) {
                   4000:         /* Special form that does not need any synchronisation */
1.1.1.6 ! root     4001:         TCGv t0 = tcg_temp_new();
        !          4002:         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
        !          4003:         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~((1 << MSR_RI) | (1 << MSR_EE)));
        !          4004:         tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
        !          4005:         tcg_temp_free(t0);
1.1.1.5   root     4006:     } else {
                   4007:         /* XXX: we need to update nip before the store
                   4008:          *      if we enter power saving mode, we will exit the loop
                   4009:          *      directly from ppc_store_msr
                   4010:          */
                   4011:         gen_update_nip(ctx, ctx->nip);
                   4012: #if defined(TARGET_PPC64)
1.1.1.6 ! root     4013:         if (!ctx->sf_mode) {
        !          4014:             TCGv t0 = tcg_temp_new();
        !          4015:             TCGv t1 = tcg_temp_new();
        !          4016:             tcg_gen_andi_tl(t0, cpu_msr, 0xFFFFFFFF00000000ULL);
        !          4017:             tcg_gen_ext32u_tl(t1, cpu_gpr[rS(ctx->opcode)]);
        !          4018:             tcg_gen_or_tl(t0, t0, t1);
        !          4019:             tcg_temp_free(t1);
        !          4020:             gen_helper_store_msr(t0);
        !          4021:             tcg_temp_free(t0);
        !          4022:         } else
1.1.1.5   root     4023: #endif
1.1.1.6 ! root     4024:             gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     4025:         /* Must stop the translation as machine state (may have) changed */
1.1.1.6 ! root     4026:         /* Note that mtmsr is not always defined as context-synchronizing */
        !          4027:         gen_stop_exception(ctx);
1.1.1.5   root     4028:     }
1.1       root     4029: #endif
                   4030: }
                   4031: 
                   4032: /* mtspr */
                   4033: GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
                   4034: {
1.1.1.6 ! root     4035:     void (*write_cb)(void *opaque, int sprn, int gprn);
1.1       root     4036:     uint32_t sprn = SPR(ctx->opcode);
                   4037: 
                   4038: #if !defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     4039:     if (ctx->mem_idx == 2)
1.1.1.5   root     4040:         write_cb = ctx->spr_cb[sprn].hea_write;
1.1.1.6 ! root     4041:     else if (ctx->mem_idx)
1.1       root     4042:         write_cb = ctx->spr_cb[sprn].oea_write;
                   4043:     else
                   4044: #endif
                   4045:         write_cb = ctx->spr_cb[sprn].uea_write;
1.1.1.5   root     4046:     if (likely(write_cb != NULL)) {
                   4047:         if (likely(write_cb != SPR_NOACCESS)) {
1.1.1.6 ! root     4048:             (*write_cb)(ctx, sprn, rS(ctx->opcode));
1.1       root     4049:         } else {
                   4050:             /* Privilege exception */
1.1.1.6 ! root     4051:             qemu_log("Trying to write privileged spr %d %03x at "
1.1.1.5   root     4052:                         ADDRX "\n", sprn, sprn, ctx->nip);
                   4053:             printf("Trying to write privileged spr %d %03x at " ADDRX "\n",
                   4054:                    sprn, sprn, ctx->nip);
1.1.1.6 ! root     4055:             gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4056:         }
1.1       root     4057:     } else {
                   4058:         /* Not defined */
1.1.1.6 ! root     4059:         qemu_log("Trying to write invalid spr %d %03x at "
1.1.1.5   root     4060:                     ADDRX "\n", sprn, sprn, ctx->nip);
                   4061:         printf("Trying to write invalid spr %d %03x at " ADDRX "\n",
                   4062:                sprn, sprn, ctx->nip);
1.1.1.6 ! root     4063:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
1.1       root     4064:     }
                   4065: }
                   4066: 
                   4067: /***                         Cache management                              ***/
                   4068: /* dcbf */
1.1.1.5   root     4069: GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
1.1       root     4070: {
1.1.1.5   root     4071:     /* XXX: specification says this is treated as a load by the MMU */
1.1.1.6 ! root     4072:     TCGv t0;
        !          4073:     gen_set_access_type(ctx, ACCESS_CACHE);
        !          4074:     t0 = tcg_temp_new();
        !          4075:     gen_addr_reg_index(ctx, t0);
        !          4076:     gen_qemu_ld8u(ctx, t0, t0);
        !          4077:     tcg_temp_free(t0);
1.1       root     4078: }
                   4079: 
                   4080: /* dcbi (Supervisor only) */
                   4081: GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
                   4082: {
                   4083: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     4084:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     4085: #else
1.1.1.6 ! root     4086:     TCGv EA, val;
        !          4087:     if (unlikely(!ctx->mem_idx)) {
        !          4088:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     4089:         return;
                   4090:     }
1.1.1.6 ! root     4091:     EA = tcg_temp_new();
        !          4092:     gen_set_access_type(ctx, ACCESS_CACHE);
        !          4093:     gen_addr_reg_index(ctx, EA);
        !          4094:     val = tcg_temp_new();
1.1.1.5   root     4095:     /* XXX: specification says this should be treated as a store by the MMU */
1.1.1.6 ! root     4096:     gen_qemu_ld8u(ctx, val, EA);
        !          4097:     gen_qemu_st8(ctx, val, EA);
        !          4098:     tcg_temp_free(val);
        !          4099:     tcg_temp_free(EA);
1.1       root     4100: #endif
                   4101: }
                   4102: 
                   4103: /* dcdst */
                   4104: GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
                   4105: {
1.1.1.5   root     4106:     /* XXX: specification say this is treated as a load by the MMU */
1.1.1.6 ! root     4107:     TCGv t0;
        !          4108:     gen_set_access_type(ctx, ACCESS_CACHE);
        !          4109:     t0 = tcg_temp_new();
        !          4110:     gen_addr_reg_index(ctx, t0);
        !          4111:     gen_qemu_ld8u(ctx, t0, t0);
        !          4112:     tcg_temp_free(t0);
1.1       root     4113: }
                   4114: 
                   4115: /* dcbt */
1.1.1.5   root     4116: GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x02000001, PPC_CACHE)
1.1       root     4117: {
1.1.1.5   root     4118:     /* interpreted as no-op */
                   4119:     /* XXX: specification say this is treated as a load by the MMU
                   4120:      *      but does not generate any exception
                   4121:      */
1.1       root     4122: }
                   4123: 
                   4124: /* dcbtst */
1.1.1.5   root     4125: GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x02000001, PPC_CACHE)
1.1       root     4126: {
1.1.1.5   root     4127:     /* interpreted as no-op */
                   4128:     /* XXX: specification say this is treated as a load by the MMU
                   4129:      *      but does not generate any exception
                   4130:      */
1.1       root     4131: }
                   4132: 
                   4133: /* dcbz */
1.1.1.6 ! root     4134: GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E00001, PPC_CACHE_DCBZ)
        !          4135: {
        !          4136:     TCGv t0;
        !          4137:     gen_set_access_type(ctx, ACCESS_CACHE);
        !          4138:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          4139:     gen_update_nip(ctx, ctx->nip - 4);
        !          4140:     t0 = tcg_temp_new();
        !          4141:     gen_addr_reg_index(ctx, t0);
        !          4142:     gen_helper_dcbz(t0);
        !          4143:     tcg_temp_free(t0);
        !          4144: }
1.1       root     4145: 
1.1.1.6 ! root     4146: GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZT)
1.1       root     4147: {
1.1.1.6 ! root     4148:     TCGv t0;
        !          4149:     gen_set_access_type(ctx, ACCESS_CACHE);
        !          4150:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          4151:     gen_update_nip(ctx, ctx->nip - 4);
        !          4152:     t0 = tcg_temp_new();
        !          4153:     gen_addr_reg_index(ctx, t0);
        !          4154:     if (ctx->opcode & 0x00200000)
        !          4155:         gen_helper_dcbz(t0);
        !          4156:     else
        !          4157:         gen_helper_dcbz_970(t0);
        !          4158:     tcg_temp_free(t0);
        !          4159: }
1.1.1.5   root     4160: 
1.1.1.6 ! root     4161: /* dst / dstt */
        !          4162: GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC)
        !          4163: {
        !          4164:     if (rA(ctx->opcode) == 0) {
        !          4165:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
        !          4166:     } else {
        !          4167:         /* interpreted as no-op */
1.1       root     4168:     }
1.1.1.5   root     4169: }
                   4170: 
1.1.1.6 ! root     4171: /* dstst /dststt */
        !          4172: GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC)
1.1.1.5   root     4173: {
1.1.1.6 ! root     4174:     if (rA(ctx->opcode) == 0) {
        !          4175:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
        !          4176:     } else {
        !          4177:         /* interpreted as no-op */
        !          4178:     }
        !          4179: 
1.1.1.5   root     4180: }
                   4181: 
1.1.1.6 ! root     4182: /* dss / dssall */
        !          4183: GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC)
1.1.1.5   root     4184: {
1.1.1.6 ! root     4185:     /* interpreted as no-op */
1.1       root     4186: }
                   4187: 
                   4188: /* icbi */
1.1.1.5   root     4189: GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI)
1.1       root     4190: {
1.1.1.6 ! root     4191:     TCGv t0;
        !          4192:     gen_set_access_type(ctx, ACCESS_CACHE);
1.1.1.5   root     4193:     /* NIP cannot be restored if the memory exception comes from an helper */
                   4194:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6 ! root     4195:     t0 = tcg_temp_new();
        !          4196:     gen_addr_reg_index(ctx, t0);
        !          4197:     gen_helper_icbi(t0);
        !          4198:     tcg_temp_free(t0);
1.1       root     4199: }
                   4200: 
                   4201: /* Optional: */
                   4202: /* dcba */
1.1.1.5   root     4203: GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
1.1       root     4204: {
1.1.1.5   root     4205:     /* interpreted as no-op */
                   4206:     /* XXX: specification say this is treated as a store by the MMU
                   4207:      *      but does not generate any exception
                   4208:      */
1.1       root     4209: }
                   4210: 
                   4211: /***                    Segment register manipulation                      ***/
                   4212: /* Supervisor only: */
                   4213: /* mfsr */
                   4214: GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
                   4215: {
                   4216: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     4217:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4218: #else
1.1.1.6 ! root     4219:     TCGv t0;
        !          4220:     if (unlikely(!ctx->mem_idx)) {
        !          4221:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4222:         return;
                   4223:     }
1.1.1.6 ! root     4224:     t0 = tcg_const_tl(SR(ctx->opcode));
        !          4225:     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
        !          4226:     tcg_temp_free(t0);
1.1       root     4227: #endif
                   4228: }
                   4229: 
                   4230: /* mfsrin */
                   4231: GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
                   4232: {
                   4233: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     4234:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4235: #else
1.1.1.6 ! root     4236:     TCGv t0;
        !          4237:     if (unlikely(!ctx->mem_idx)) {
        !          4238:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4239:         return;
                   4240:     }
1.1.1.6 ! root     4241:     t0 = tcg_temp_new();
        !          4242:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
        !          4243:     tcg_gen_andi_tl(t0, t0, 0xF);
        !          4244:     gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
        !          4245:     tcg_temp_free(t0);
1.1       root     4246: #endif
                   4247: }
                   4248: 
                   4249: /* mtsr */
                   4250: GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
                   4251: {
                   4252: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     4253:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4254: #else
1.1.1.6 ! root     4255:     TCGv t0;
        !          4256:     if (unlikely(!ctx->mem_idx)) {
        !          4257:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4258:         return;
                   4259:     }
1.1.1.6 ! root     4260:     t0 = tcg_const_tl(SR(ctx->opcode));
        !          4261:     gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
        !          4262:     tcg_temp_free(t0);
1.1       root     4263: #endif
                   4264: }
                   4265: 
                   4266: /* mtsrin */
                   4267: GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
                   4268: {
                   4269: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     4270:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4271: #else
1.1.1.6 ! root     4272:     TCGv t0;
        !          4273:     if (unlikely(!ctx->mem_idx)) {
        !          4274:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4275:         return;
                   4276:     }
1.1.1.6 ! root     4277:     t0 = tcg_temp_new();
        !          4278:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
        !          4279:     tcg_gen_andi_tl(t0, t0, 0xF);
        !          4280:     gen_helper_store_sr(t0, cpu_gpr[rD(ctx->opcode)]);
        !          4281:     tcg_temp_free(t0);
1.1       root     4282: #endif
                   4283: }
                   4284: 
1.1.1.5   root     4285: #if defined(TARGET_PPC64)
                   4286: /* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
                   4287: /* mfsr */
                   4288: GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
1.1       root     4289: {
                   4290: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     4291:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4292: #else
1.1.1.6 ! root     4293:     TCGv t0;
        !          4294:     if (unlikely(!ctx->mem_idx)) {
        !          4295:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1       root     4296:         return;
                   4297:     }
1.1.1.6 ! root     4298:     t0 = tcg_const_tl(SR(ctx->opcode));
        !          4299:     gen_helper_load_slb(cpu_gpr[rD(ctx->opcode)], t0);
        !          4300:     tcg_temp_free(t0);
1.1.1.5   root     4301: #endif
                   4302: }
                   4303: 
                   4304: /* mfsrin */
                   4305: GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
                   4306:              PPC_SEGMENT_64B)
                   4307: {
                   4308: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     4309:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4310: #else
1.1.1.6 ! root     4311:     TCGv t0;
        !          4312:     if (unlikely(!ctx->mem_idx)) {
        !          4313:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4314:         return;
                   4315:     }
1.1.1.6 ! root     4316:     t0 = tcg_temp_new();
        !          4317:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
        !          4318:     tcg_gen_andi_tl(t0, t0, 0xF);
        !          4319:     gen_helper_load_slb(cpu_gpr[rD(ctx->opcode)], t0);
        !          4320:     tcg_temp_free(t0);
1.1.1.5   root     4321: #endif
                   4322: }
                   4323: 
                   4324: /* mtsr */
                   4325: GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
                   4326: {
                   4327: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     4328:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4329: #else
1.1.1.6 ! root     4330:     TCGv t0;
        !          4331:     if (unlikely(!ctx->mem_idx)) {
        !          4332:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4333:         return;
                   4334:     }
1.1.1.6 ! root     4335:     t0 = tcg_const_tl(SR(ctx->opcode));
        !          4336:     gen_helper_store_slb(t0, cpu_gpr[rS(ctx->opcode)]);
        !          4337:     tcg_temp_free(t0);
1.1.1.5   root     4338: #endif
                   4339: }
                   4340: 
                   4341: /* mtsrin */
                   4342: GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
                   4343:              PPC_SEGMENT_64B)
                   4344: {
                   4345: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     4346:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4347: #else
1.1.1.6 ! root     4348:     TCGv t0;
        !          4349:     if (unlikely(!ctx->mem_idx)) {
        !          4350:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     4351:         return;
                   4352:     }
1.1.1.6 ! root     4353:     t0 = tcg_temp_new();
        !          4354:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
        !          4355:     tcg_gen_andi_tl(t0, t0, 0xF);
        !          4356:     gen_helper_store_slb(t0, cpu_gpr[rS(ctx->opcode)]);
        !          4357:     tcg_temp_free(t0);
1.1.1.5   root     4358: #endif
                   4359: }
                   4360: #endif /* defined(TARGET_PPC64) */
                   4361: 
                   4362: /***                      Lookaside buffer management                      ***/
1.1.1.6 ! root     4363: /* Optional & mem_idx only: */
1.1.1.5   root     4364: /* tlbia */
                   4365: GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
                   4366: {
                   4367: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     4368:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4369: #else
1.1.1.6 ! root     4370:     if (unlikely(!ctx->mem_idx)) {
        !          4371:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4372:         return;
                   4373:     }
1.1.1.6 ! root     4374:     gen_helper_tlbia();
1.1       root     4375: #endif
                   4376: }
                   4377: 
                   4378: /* tlbie */
1.1.1.5   root     4379: GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
                   4380: {
                   4381: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     4382:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4383: #else
1.1.1.6 ! root     4384:     if (unlikely(!ctx->mem_idx)) {
        !          4385:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4386:         return;
                   4387:     }
                   4388: #if defined(TARGET_PPC64)
1.1.1.6 ! root     4389:     if (!ctx->sf_mode) {
        !          4390:         TCGv t0 = tcg_temp_new();
        !          4391:         tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
        !          4392:         gen_helper_tlbie(t0);
        !          4393:         tcg_temp_free(t0);
        !          4394:     } else
1.1.1.5   root     4395: #endif
1.1.1.6 ! root     4396:         gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4397: #endif
                   4398: }
                   4399: 
                   4400: /* tlbsync */
                   4401: GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
                   4402: {
                   4403: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     4404:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4405: #else
1.1.1.6 ! root     4406:     if (unlikely(!ctx->mem_idx)) {
        !          4407:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4408:         return;
                   4409:     }
                   4410:     /* This has no effect: it should ensure that all previous
                   4411:      * tlbie have completed
                   4412:      */
1.1.1.6 ! root     4413:     gen_stop_exception(ctx);
1.1.1.5   root     4414: #endif
                   4415: }
                   4416: 
                   4417: #if defined(TARGET_PPC64)
                   4418: /* slbia */
                   4419: GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
                   4420: {
                   4421: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     4422:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4423: #else
1.1.1.6 ! root     4424:     if (unlikely(!ctx->mem_idx)) {
        !          4425:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4426:         return;
                   4427:     }
1.1.1.6 ! root     4428:     gen_helper_slbia();
1.1.1.5   root     4429: #endif
                   4430: }
                   4431: 
                   4432: /* slbie */
                   4433: GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
                   4434: {
                   4435: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     4436:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4437: #else
1.1.1.6 ! root     4438:     if (unlikely(!ctx->mem_idx)) {
        !          4439:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     4440:         return;
                   4441:     }
1.1.1.6 ! root     4442:     gen_helper_slbie(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4443: #endif
                   4444: }
                   4445: #endif
                   4446: 
                   4447: /***                              External control                         ***/
                   4448: /* Optional: */
                   4449: /* eciwx */
                   4450: GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN)
                   4451: {
1.1.1.6 ! root     4452:     TCGv t0;
        !          4453:     /* Should check EAR[E] ! */
        !          4454:     gen_set_access_type(ctx, ACCESS_EXT);
        !          4455:     t0 = tcg_temp_new();
        !          4456:     gen_addr_reg_index(ctx, t0);
        !          4457:     gen_check_align(ctx, t0, 0x03);
        !          4458:     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
        !          4459:     tcg_temp_free(t0);
1.1.1.5   root     4460: }
                   4461: 
                   4462: /* ecowx */
                   4463: GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN)
                   4464: {
1.1.1.6 ! root     4465:     TCGv t0;
        !          4466:     /* Should check EAR[E] ! */
        !          4467:     gen_set_access_type(ctx, ACCESS_EXT);
        !          4468:     t0 = tcg_temp_new();
        !          4469:     gen_addr_reg_index(ctx, t0);
        !          4470:     gen_check_align(ctx, t0, 0x03);
        !          4471:     gen_qemu_st32(ctx, cpu_gpr[rD(ctx->opcode)], t0);
        !          4472:     tcg_temp_free(t0);
1.1.1.5   root     4473: }
                   4474: 
                   4475: /* PowerPC 601 specific instructions */
                   4476: /* abs - abs. */
                   4477: GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR)
                   4478: {
1.1.1.6 ! root     4479:     int l1 = gen_new_label();
        !          4480:     int l2 = gen_new_label();
        !          4481:     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);
        !          4482:     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
        !          4483:     tcg_gen_br(l2);
        !          4484:     gen_set_label(l1);
        !          4485:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
        !          4486:     gen_set_label(l2);
1.1.1.5   root     4487:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4488:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4489: }
                   4490: 
                   4491: /* abso - abso. */
                   4492: GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR)
                   4493: {
1.1.1.6 ! root     4494:     int l1 = gen_new_label();
        !          4495:     int l2 = gen_new_label();
        !          4496:     int l3 = gen_new_label();
        !          4497:     /* Start with XER OV disabled, the most likely case */
        !          4498:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
        !          4499:     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
        !          4500:     tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
        !          4501:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
        !          4502:     tcg_gen_br(l2);
        !          4503:     gen_set_label(l1);
        !          4504:     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
        !          4505:     tcg_gen_br(l3);
        !          4506:     gen_set_label(l2);
        !          4507:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
        !          4508:     gen_set_label(l3);
1.1.1.5   root     4509:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4510:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4511: }
                   4512: 
                   4513: /* clcs */
                   4514: GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR)
                   4515: {
1.1.1.6 ! root     4516:     TCGv_i32 t0 = tcg_const_i32(rA(ctx->opcode));
        !          4517:     gen_helper_clcs(cpu_gpr[rD(ctx->opcode)], t0);
        !          4518:     tcg_temp_free_i32(t0);
1.1.1.5   root     4519:     /* Rc=1 sets CR0 to an undefined state */
                   4520: }
                   4521: 
                   4522: /* div - div. */
                   4523: GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR)
                   4524: {
1.1.1.6 ! root     4525:     gen_helper_div(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4526:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4527:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4528: }
                   4529: 
                   4530: /* divo - divo. */
                   4531: GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR)
                   4532: {
1.1.1.6 ! root     4533:     gen_helper_divo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4534:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4535:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4536: }
                   4537: 
                   4538: /* divs - divs. */
                   4539: GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR)
                   4540: {
1.1.1.6 ! root     4541:     gen_helper_divs(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     4542:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4543:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4544: }
                   4545: 
                   4546: /* divso - divso. */
                   4547: GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR)
                   4548: {
1.1.1.6 ! root     4549:     gen_helper_divso(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
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: /* doz - doz. */
                   4555: GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR)
                   4556: {
1.1.1.6 ! root     4557:     int l1 = gen_new_label();
        !          4558:     int l2 = gen_new_label();
        !          4559:     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
        !          4560:     tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
        !          4561:     tcg_gen_br(l2);
        !          4562:     gen_set_label(l1);
        !          4563:     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
        !          4564:     gen_set_label(l2);
1.1.1.5   root     4565:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4566:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4567: }
                   4568: 
                   4569: /* dozo - dozo. */
                   4570: GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR)
                   4571: {
1.1.1.6 ! root     4572:     int l1 = gen_new_label();
        !          4573:     int l2 = gen_new_label();
        !          4574:     TCGv t0 = tcg_temp_new();
        !          4575:     TCGv t1 = tcg_temp_new();
        !          4576:     TCGv t2 = tcg_temp_new();
        !          4577:     /* Start with XER OV disabled, the most likely case */
        !          4578:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
        !          4579:     tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
        !          4580:     tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
        !          4581:     tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
        !          4582:     tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0);
        !          4583:     tcg_gen_andc_tl(t1, t1, t2);
        !          4584:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
        !          4585:     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
        !          4586:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
        !          4587:     tcg_gen_br(l2);
        !          4588:     gen_set_label(l1);
        !          4589:     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
        !          4590:     gen_set_label(l2);
        !          4591:     tcg_temp_free(t0);
        !          4592:     tcg_temp_free(t1);
        !          4593:     tcg_temp_free(t2);
1.1.1.5   root     4594:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4595:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4596: }
                   4597: 
                   4598: /* dozi */
                   4599: GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
                   4600: {
1.1.1.6 ! root     4601:     target_long simm = SIMM(ctx->opcode);
        !          4602:     int l1 = gen_new_label();
        !          4603:     int l2 = gen_new_label();
        !          4604:     tcg_gen_brcondi_tl(TCG_COND_LT, cpu_gpr[rA(ctx->opcode)], simm, l1);
        !          4605:     tcg_gen_subfi_tl(cpu_gpr[rD(ctx->opcode)], simm, cpu_gpr[rA(ctx->opcode)]);
        !          4606:     tcg_gen_br(l2);
        !          4607:     gen_set_label(l1);
        !          4608:     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
        !          4609:     gen_set_label(l2);
        !          4610:     if (unlikely(Rc(ctx->opcode) != 0))
        !          4611:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4612: }
                   4613: 
                   4614: /* lscbx - lscbx. */
                   4615: GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR)
                   4616: {
1.1.1.6 ! root     4617:     TCGv t0 = tcg_temp_new();
        !          4618:     TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
        !          4619:     TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode));
        !          4620:     TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
1.1.1.5   root     4621: 
1.1.1.6 ! root     4622:     gen_addr_reg_index(ctx, t0);
1.1.1.5   root     4623:     /* NIP cannot be restored if the memory exception comes from an helper */
                   4624:     gen_update_nip(ctx, ctx->nip - 4);
1.1.1.6 ! root     4625:     gen_helper_lscbx(t0, t0, t1, t2, t3);
        !          4626:     tcg_temp_free_i32(t1);
        !          4627:     tcg_temp_free_i32(t2);
        !          4628:     tcg_temp_free_i32(t3);
        !          4629:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
        !          4630:     tcg_gen_or_tl(cpu_xer, cpu_xer, t0);
1.1.1.5   root     4631:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4632:         gen_set_Rc0(ctx, t0);
        !          4633:     tcg_temp_free(t0);
1.1.1.5   root     4634: }
                   4635: 
                   4636: /* maskg - maskg. */
                   4637: GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR)
                   4638: {
1.1.1.6 ! root     4639:     int l1 = gen_new_label();
        !          4640:     TCGv t0 = tcg_temp_new();
        !          4641:     TCGv t1 = tcg_temp_new();
        !          4642:     TCGv t2 = tcg_temp_new();
        !          4643:     TCGv t3 = tcg_temp_new();
        !          4644:     tcg_gen_movi_tl(t3, 0xFFFFFFFF);
        !          4645:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
        !          4646:     tcg_gen_andi_tl(t1, cpu_gpr[rS(ctx->opcode)], 0x1F);
        !          4647:     tcg_gen_addi_tl(t2, t0, 1);
        !          4648:     tcg_gen_shr_tl(t2, t3, t2);
        !          4649:     tcg_gen_shr_tl(t3, t3, t1);
        !          4650:     tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], t2, t3);
        !          4651:     tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
        !          4652:     tcg_gen_neg_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
        !          4653:     gen_set_label(l1);
        !          4654:     tcg_temp_free(t0);
        !          4655:     tcg_temp_free(t1);
        !          4656:     tcg_temp_free(t2);
        !          4657:     tcg_temp_free(t3);
1.1.1.5   root     4658:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4659:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4660: }
                   4661: 
                   4662: /* maskir - maskir. */
                   4663: GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR)
                   4664: {
1.1.1.6 ! root     4665:     TCGv t0 = tcg_temp_new();
        !          4666:     TCGv t1 = tcg_temp_new();
        !          4667:     tcg_gen_and_tl(t0, cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
        !          4668:     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
        !          4669:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
        !          4670:     tcg_temp_free(t0);
        !          4671:     tcg_temp_free(t1);
1.1.1.5   root     4672:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4673:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4674: }
                   4675: 
                   4676: /* mul - mul. */
                   4677: GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR)
                   4678: {
1.1.1.6 ! root     4679:     TCGv_i64 t0 = tcg_temp_new_i64();
        !          4680:     TCGv_i64 t1 = tcg_temp_new_i64();
        !          4681:     TCGv t2 = tcg_temp_new();
        !          4682:     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
        !          4683:     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
        !          4684:     tcg_gen_mul_i64(t0, t0, t1);
        !          4685:     tcg_gen_trunc_i64_tl(t2, t0);
        !          4686:     gen_store_spr(SPR_MQ, t2);
        !          4687:     tcg_gen_shri_i64(t1, t0, 32);
        !          4688:     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
        !          4689:     tcg_temp_free_i64(t0);
        !          4690:     tcg_temp_free_i64(t1);
        !          4691:     tcg_temp_free(t2);
1.1.1.5   root     4692:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4693:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4694: }
                   4695: 
                   4696: /* mulo - mulo. */
                   4697: GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR)
                   4698: {
1.1.1.6 ! root     4699:     int l1 = gen_new_label();
        !          4700:     TCGv_i64 t0 = tcg_temp_new_i64();
        !          4701:     TCGv_i64 t1 = tcg_temp_new_i64();
        !          4702:     TCGv t2 = tcg_temp_new();
        !          4703:     /* Start with XER OV disabled, the most likely case */
        !          4704:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
        !          4705:     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
        !          4706:     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
        !          4707:     tcg_gen_mul_i64(t0, t0, t1);
        !          4708:     tcg_gen_trunc_i64_tl(t2, t0);
        !          4709:     gen_store_spr(SPR_MQ, t2);
        !          4710:     tcg_gen_shri_i64(t1, t0, 32);
        !          4711:     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
        !          4712:     tcg_gen_ext32s_i64(t1, t0);
        !          4713:     tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
        !          4714:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
        !          4715:     gen_set_label(l1);
        !          4716:     tcg_temp_free_i64(t0);
        !          4717:     tcg_temp_free_i64(t1);
        !          4718:     tcg_temp_free(t2);
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: /* nabs - nabs. */
                   4724: GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR)
                   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);
1.1.1.5   root     4734:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4735:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4736: }
                   4737: 
                   4738: /* nabso - nabso. */
                   4739: GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR)
                   4740: {
1.1.1.6 ! root     4741:     int l1 = gen_new_label();
        !          4742:     int l2 = gen_new_label();
        !          4743:     tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
        !          4744:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
        !          4745:     tcg_gen_br(l2);
        !          4746:     gen_set_label(l1);
        !          4747:     tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
        !          4748:     gen_set_label(l2);
        !          4749:     /* nabs never overflows */
        !          4750:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
1.1.1.5   root     4751:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4752:         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1.1.1.5   root     4753: }
                   4754: 
                   4755: /* rlmi - rlmi. */
                   4756: GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR)
                   4757: {
1.1.1.6 ! root     4758:     uint32_t mb = MB(ctx->opcode);
        !          4759:     uint32_t me = ME(ctx->opcode);
        !          4760:     TCGv t0 = tcg_temp_new();
        !          4761:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
        !          4762:     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
        !          4763:     tcg_gen_andi_tl(t0, t0, MASK(mb, me));
        !          4764:     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~MASK(mb, me));
        !          4765:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], t0);
        !          4766:     tcg_temp_free(t0);
1.1.1.5   root     4767:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4768:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4769: }
                   4770: 
                   4771: /* rrib - rrib. */
                   4772: GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR)
                   4773: {
1.1.1.6 ! root     4774:     TCGv t0 = tcg_temp_new();
        !          4775:     TCGv t1 = tcg_temp_new();
        !          4776:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
        !          4777:     tcg_gen_movi_tl(t1, 0x80000000);
        !          4778:     tcg_gen_shr_tl(t1, t1, t0);
        !          4779:     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
        !          4780:     tcg_gen_and_tl(t0, t0, t1);
        !          4781:     tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], t1);
        !          4782:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
        !          4783:     tcg_temp_free(t0);
        !          4784:     tcg_temp_free(t1);
1.1.1.5   root     4785:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4786:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4787: }
                   4788: 
                   4789: /* sle - sle. */
                   4790: GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR)
                   4791: {
1.1.1.6 ! root     4792:     TCGv t0 = tcg_temp_new();
        !          4793:     TCGv t1 = tcg_temp_new();
        !          4794:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
        !          4795:     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
        !          4796:     tcg_gen_subfi_tl(t1, 32, t1);
        !          4797:     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
        !          4798:     tcg_gen_or_tl(t1, t0, t1);
        !          4799:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
        !          4800:     gen_store_spr(SPR_MQ, t1);
        !          4801:     tcg_temp_free(t0);
        !          4802:     tcg_temp_free(t1);
1.1.1.5   root     4803:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4804:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4805: }
                   4806: 
                   4807: /* sleq - sleq. */
                   4808: GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR)
                   4809: {
1.1.1.6 ! root     4810:     TCGv t0 = tcg_temp_new();
        !          4811:     TCGv t1 = tcg_temp_new();
        !          4812:     TCGv t2 = tcg_temp_new();
        !          4813:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
        !          4814:     tcg_gen_movi_tl(t2, 0xFFFFFFFF);
        !          4815:     tcg_gen_shl_tl(t2, t2, t0);
        !          4816:     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
        !          4817:     gen_load_spr(t1, SPR_MQ);
        !          4818:     gen_store_spr(SPR_MQ, t0);
        !          4819:     tcg_gen_and_tl(t0, t0, t2);
        !          4820:     tcg_gen_andc_tl(t1, t1, t2);
        !          4821:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
        !          4822:     tcg_temp_free(t0);
        !          4823:     tcg_temp_free(t1);
        !          4824:     tcg_temp_free(t2);
1.1.1.5   root     4825:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4826:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4827: }
                   4828: 
                   4829: /* sliq - sliq. */
                   4830: GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR)
                   4831: {
1.1.1.6 ! root     4832:     int sh = SH(ctx->opcode);
        !          4833:     TCGv t0 = tcg_temp_new();
        !          4834:     TCGv t1 = tcg_temp_new();
        !          4835:     tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
        !          4836:     tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
        !          4837:     tcg_gen_or_tl(t1, t0, t1);
        !          4838:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
        !          4839:     gen_store_spr(SPR_MQ, t1);
        !          4840:     tcg_temp_free(t0);
        !          4841:     tcg_temp_free(t1);
1.1.1.5   root     4842:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4843:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4844: }
                   4845: 
                   4846: /* slliq - slliq. */
                   4847: GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR)
                   4848: {
1.1.1.6 ! root     4849:     int sh = SH(ctx->opcode);
        !          4850:     TCGv t0 = tcg_temp_new();
        !          4851:     TCGv t1 = tcg_temp_new();
        !          4852:     tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
        !          4853:     gen_load_spr(t1, SPR_MQ);
        !          4854:     gen_store_spr(SPR_MQ, t0);
        !          4855:     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU << sh));
        !          4856:     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU << sh));
        !          4857:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
        !          4858:     tcg_temp_free(t0);
        !          4859:     tcg_temp_free(t1);
1.1.1.5   root     4860:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4861:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4862: }
                   4863: 
                   4864: /* sllq - sllq. */
                   4865: GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR)
                   4866: {
1.1.1.6 ! root     4867:     int l1 = gen_new_label();
        !          4868:     int l2 = gen_new_label();
        !          4869:     TCGv t0 = tcg_temp_local_new();
        !          4870:     TCGv t1 = tcg_temp_local_new();
        !          4871:     TCGv t2 = tcg_temp_local_new();
        !          4872:     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
        !          4873:     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
        !          4874:     tcg_gen_shl_tl(t1, t1, t2);
        !          4875:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
        !          4876:     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
        !          4877:     gen_load_spr(t0, SPR_MQ);
        !          4878:     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
        !          4879:     tcg_gen_br(l2);
        !          4880:     gen_set_label(l1);
        !          4881:     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
        !          4882:     gen_load_spr(t2, SPR_MQ);
        !          4883:     tcg_gen_andc_tl(t1, t2, t1);
        !          4884:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
        !          4885:     gen_set_label(l2);
        !          4886:     tcg_temp_free(t0);
        !          4887:     tcg_temp_free(t1);
        !          4888:     tcg_temp_free(t2);
1.1.1.5   root     4889:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4890:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4891: }
                   4892: 
                   4893: /* slq - slq. */
                   4894: GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR)
                   4895: {
1.1.1.6 ! root     4896:     int l1 = gen_new_label();
        !          4897:     TCGv t0 = tcg_temp_new();
        !          4898:     TCGv t1 = tcg_temp_new();
        !          4899:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
        !          4900:     tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
        !          4901:     tcg_gen_subfi_tl(t1, 32, t1);
        !          4902:     tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
        !          4903:     tcg_gen_or_tl(t1, t0, t1);
        !          4904:     gen_store_spr(SPR_MQ, t1);
        !          4905:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
        !          4906:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
        !          4907:     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
        !          4908:     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
        !          4909:     gen_set_label(l1);
        !          4910:     tcg_temp_free(t0);
        !          4911:     tcg_temp_free(t1);
1.1.1.5   root     4912:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4913:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4914: }
                   4915: 
                   4916: /* sraiq - sraiq. */
                   4917: GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR)
                   4918: {
1.1.1.6 ! root     4919:     int sh = SH(ctx->opcode);
        !          4920:     int l1 = gen_new_label();
        !          4921:     TCGv t0 = tcg_temp_new();
        !          4922:     TCGv t1 = tcg_temp_new();
        !          4923:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
        !          4924:     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
        !          4925:     tcg_gen_or_tl(t0, t0, t1);
        !          4926:     gen_store_spr(SPR_MQ, t0);
        !          4927:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
        !          4928:     tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
        !          4929:     tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
        !          4930:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
        !          4931:     gen_set_label(l1);
        !          4932:     tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
        !          4933:     tcg_temp_free(t0);
        !          4934:     tcg_temp_free(t1);
1.1.1.5   root     4935:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4936:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4937: }
                   4938: 
                   4939: /* sraq - sraq. */
                   4940: GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR)
                   4941: {
1.1.1.6 ! root     4942:     int l1 = gen_new_label();
        !          4943:     int l2 = gen_new_label();
        !          4944:     TCGv t0 = tcg_temp_new();
        !          4945:     TCGv t1 = tcg_temp_local_new();
        !          4946:     TCGv t2 = tcg_temp_local_new();
        !          4947:     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
        !          4948:     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
        !          4949:     tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2);
        !          4950:     tcg_gen_subfi_tl(t2, 32, t2);
        !          4951:     tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2);
        !          4952:     tcg_gen_or_tl(t0, t0, t2);
        !          4953:     gen_store_spr(SPR_MQ, t0);
        !          4954:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
        !          4955:     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1);
        !          4956:     tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]);
        !          4957:     tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31);
        !          4958:     gen_set_label(l1);
        !          4959:     tcg_temp_free(t0);
        !          4960:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
        !          4961:     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
        !          4962:     tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
        !          4963:     tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);
        !          4964:     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_CA));
        !          4965:     gen_set_label(l2);
        !          4966:     tcg_temp_free(t1);
        !          4967:     tcg_temp_free(t2);
1.1.1.5   root     4968:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     4969:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     4970: }
                   4971: 
                   4972: /* sre - sre. */
                   4973: GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR)
                   4974: {
1.1.1.6 ! root     4975:     TCGv t0 = tcg_temp_new();
        !          4976:     TCGv t1 = tcg_temp_new();
        !          4977:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
        !          4978:     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
        !          4979:     tcg_gen_subfi_tl(t1, 32, t1);
        !          4980:     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
        !          4981:     tcg_gen_or_tl(t1, t0, t1);
        !          4982:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
        !          4983:     gen_store_spr(SPR_MQ, 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: /* srea - srea. */
                   4991: GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR)
                   4992: {
1.1.1.6 ! root     4993:     TCGv t0 = tcg_temp_new();
        !          4994:     TCGv t1 = tcg_temp_new();
        !          4995:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
        !          4996:     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
        !          4997:     gen_store_spr(SPR_MQ, t0);
        !          4998:     tcg_gen_sar_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t1);
        !          4999:     tcg_temp_free(t0);
        !          5000:     tcg_temp_free(t1);
1.1.1.5   root     5001:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     5002:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5003: }
                   5004: 
                   5005: /* sreq */
                   5006: GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR)
                   5007: {
1.1.1.6 ! root     5008:     TCGv t0 = tcg_temp_new();
        !          5009:     TCGv t1 = tcg_temp_new();
        !          5010:     TCGv t2 = tcg_temp_new();
        !          5011:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
        !          5012:     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
        !          5013:     tcg_gen_shr_tl(t1, t1, t0);
        !          5014:     tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
        !          5015:     gen_load_spr(t2, SPR_MQ);
        !          5016:     gen_store_spr(SPR_MQ, t0);
        !          5017:     tcg_gen_and_tl(t0, t0, t1);
        !          5018:     tcg_gen_andc_tl(t2, t2, t1);
        !          5019:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
        !          5020:     tcg_temp_free(t0);
        !          5021:     tcg_temp_free(t1);
        !          5022:     tcg_temp_free(t2);
1.1.1.5   root     5023:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     5024:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5025: }
                   5026: 
                   5027: /* sriq */
                   5028: GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR)
                   5029: {
1.1.1.6 ! root     5030:     int sh = SH(ctx->opcode);
        !          5031:     TCGv t0 = tcg_temp_new();
        !          5032:     TCGv t1 = tcg_temp_new();
        !          5033:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
        !          5034:     tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
        !          5035:     tcg_gen_or_tl(t1, t0, t1);
        !          5036:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
        !          5037:     gen_store_spr(SPR_MQ, t1);
        !          5038:     tcg_temp_free(t0);
        !          5039:     tcg_temp_free(t1);
1.1.1.5   root     5040:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     5041:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5042: }
                   5043: 
                   5044: /* srliq */
                   5045: GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR)
                   5046: {
1.1.1.6 ! root     5047:     int sh = SH(ctx->opcode);
        !          5048:     TCGv t0 = tcg_temp_new();
        !          5049:     TCGv t1 = tcg_temp_new();
        !          5050:     tcg_gen_rotri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
        !          5051:     gen_load_spr(t1, SPR_MQ);
        !          5052:     gen_store_spr(SPR_MQ, t0);
        !          5053:     tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU >> sh));
        !          5054:     tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU >> sh));
        !          5055:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
        !          5056:     tcg_temp_free(t0);
        !          5057:     tcg_temp_free(t1);
1.1.1.5   root     5058:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     5059:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5060: }
                   5061: 
                   5062: /* srlq */
                   5063: GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR)
                   5064: {
1.1.1.6 ! root     5065:     int l1 = gen_new_label();
        !          5066:     int l2 = gen_new_label();
        !          5067:     TCGv t0 = tcg_temp_local_new();
        !          5068:     TCGv t1 = tcg_temp_local_new();
        !          5069:     TCGv t2 = tcg_temp_local_new();
        !          5070:     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
        !          5071:     tcg_gen_movi_tl(t1, 0xFFFFFFFF);
        !          5072:     tcg_gen_shr_tl(t2, t1, t2);
        !          5073:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
        !          5074:     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
        !          5075:     gen_load_spr(t0, SPR_MQ);
        !          5076:     tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
        !          5077:     tcg_gen_br(l2);
        !          5078:     gen_set_label(l1);
        !          5079:     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
        !          5080:     tcg_gen_and_tl(t0, t0, t2);
        !          5081:     gen_load_spr(t1, SPR_MQ);
        !          5082:     tcg_gen_andc_tl(t1, t1, t2);
        !          5083:     tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
        !          5084:     gen_set_label(l2);
        !          5085:     tcg_temp_free(t0);
        !          5086:     tcg_temp_free(t1);
        !          5087:     tcg_temp_free(t2);
1.1.1.5   root     5088:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     5089:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5090: }
                   5091: 
                   5092: /* srq */
                   5093: GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
                   5094: {
1.1.1.6 ! root     5095:     int l1 = gen_new_label();
        !          5096:     TCGv t0 = tcg_temp_new();
        !          5097:     TCGv t1 = tcg_temp_new();
        !          5098:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
        !          5099:     tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
        !          5100:     tcg_gen_subfi_tl(t1, 32, t1);
        !          5101:     tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
        !          5102:     tcg_gen_or_tl(t1, t0, t1);
        !          5103:     gen_store_spr(SPR_MQ, t1);
        !          5104:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
        !          5105:     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
        !          5106:     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
        !          5107:     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
        !          5108:     gen_set_label(l1);
        !          5109:     tcg_temp_free(t0);
        !          5110:     tcg_temp_free(t1);
1.1.1.5   root     5111:     if (unlikely(Rc(ctx->opcode) != 0))
1.1.1.6 ! root     5112:         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5113: }
                   5114: 
                   5115: /* PowerPC 602 specific instructions */
                   5116: /* dsa  */
                   5117: GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
                   5118: {
                   5119:     /* XXX: TODO */
1.1.1.6 ! root     5120:     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5121: }
                   5122: 
                   5123: /* esa */
                   5124: GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
                   5125: {
                   5126:     /* XXX: TODO */
1.1.1.6 ! root     5127:     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5128: }
                   5129: 
                   5130: /* mfrom */
                   5131: GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
                   5132: {
                   5133: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5134:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5135: #else
1.1.1.6 ! root     5136:     if (unlikely(!ctx->mem_idx)) {
        !          5137:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5138:         return;
                   5139:     }
1.1.1.6 ! root     5140:     gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5141: #endif
                   5142: }
                   5143: 
                   5144: /* 602 - 603 - G2 TLB management */
                   5145: /* tlbld */
                   5146: GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
                   5147: {
                   5148: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5149:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5150: #else
1.1.1.6 ! root     5151:     if (unlikely(!ctx->mem_idx)) {
        !          5152:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5153:         return;
                   5154:     }
1.1.1.6 ! root     5155:     gen_helper_6xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     5156: #endif
                   5157: }
                   5158: 
                   5159: /* tlbli */
                   5160: GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
                   5161: {
                   5162: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5163:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5164: #else
1.1.1.6 ! root     5165:     if (unlikely(!ctx->mem_idx)) {
        !          5166:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5167:         return;
                   5168:     }
1.1.1.6 ! root     5169:     gen_helper_6xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     5170: #endif
                   5171: }
                   5172: 
                   5173: /* 74xx TLB management */
                   5174: /* tlbld */
                   5175: GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB)
                   5176: {
                   5177: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5178:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5179: #else
1.1.1.6 ! root     5180:     if (unlikely(!ctx->mem_idx)) {
        !          5181:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5182:         return;
                   5183:     }
1.1.1.6 ! root     5184:     gen_helper_74xx_tlbd(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     5185: #endif
                   5186: }
                   5187: 
                   5188: /* tlbli */
                   5189: GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB)
                   5190: {
                   5191: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5192:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5193: #else
1.1.1.6 ! root     5194:     if (unlikely(!ctx->mem_idx)) {
        !          5195:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5196:         return;
                   5197:     }
1.1.1.6 ! root     5198:     gen_helper_74xx_tlbi(cpu_gpr[rB(ctx->opcode)]);
1.1.1.5   root     5199: #endif
                   5200: }
                   5201: 
                   5202: /* POWER instructions not in PowerPC 601 */
                   5203: /* clf */
                   5204: GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER)
                   5205: {
                   5206:     /* Cache line flush: implemented as no-op */
                   5207: }
                   5208: 
                   5209: /* cli */
                   5210: GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
                   5211: {
                   5212:     /* Cache line invalidate: privileged and treated as no-op */
                   5213: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5214:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5215: #else
1.1.1.6 ! root     5216:     if (unlikely(!ctx->mem_idx)) {
        !          5217:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5218:         return;
                   5219:     }
                   5220: #endif
                   5221: }
                   5222: 
                   5223: /* dclst */
                   5224: GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
                   5225: {
                   5226:     /* Data cache line store: treated as no-op */
                   5227: }
                   5228: 
                   5229: GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
                   5230: {
                   5231: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5232:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5233: #else
                   5234:     int ra = rA(ctx->opcode);
                   5235:     int rd = rD(ctx->opcode);
1.1.1.6 ! root     5236:     TCGv t0;
        !          5237:     if (unlikely(!ctx->mem_idx)) {
        !          5238:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
        !          5239:         return;
        !          5240:     }
        !          5241:     t0 = tcg_temp_new();
        !          5242:     gen_addr_reg_index(ctx, t0);
        !          5243:     tcg_gen_shri_tl(t0, t0, 28);
        !          5244:     tcg_gen_andi_tl(t0, t0, 0xF);
        !          5245:     gen_helper_load_sr(cpu_gpr[rd], t0);
        !          5246:     tcg_temp_free(t0);
1.1.1.5   root     5247:     if (ra != 0 && ra != rd)
1.1.1.6 ! root     5248:         tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
1.1.1.5   root     5249: #endif
                   5250: }
                   5251: 
                   5252: GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
                   5253: {
                   5254: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5255:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5256: #else
1.1.1.6 ! root     5257:     TCGv t0;
        !          5258:     if (unlikely(!ctx->mem_idx)) {
        !          5259:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5260:         return;
                   5261:     }
1.1.1.6 ! root     5262:     t0 = tcg_temp_new();
        !          5263:     gen_addr_reg_index(ctx, t0);
        !          5264:     gen_helper_rac(cpu_gpr[rD(ctx->opcode)], t0);
        !          5265:     tcg_temp_free(t0);
1.1.1.5   root     5266: #endif
                   5267: }
                   5268: 
                   5269: GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
                   5270: {
                   5271: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5272:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5273: #else
1.1.1.6 ! root     5274:     if (unlikely(!ctx->mem_idx)) {
        !          5275:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5276:         return;
                   5277:     }
1.1.1.6 ! root     5278:     gen_helper_rfsvc();
        !          5279:     gen_sync_exception(ctx);
1.1.1.5   root     5280: #endif
                   5281: }
                   5282: 
                   5283: /* svc is not implemented for now */
                   5284: 
                   5285: /* POWER2 specific instructions */
                   5286: /* Quad manipulation (load/store two floats at a time) */
                   5287: 
                   5288: /* lfq */
                   5289: GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
                   5290: {
1.1.1.6 ! root     5291:     int rd = rD(ctx->opcode);
        !          5292:     TCGv t0;
        !          5293:     gen_set_access_type(ctx, ACCESS_FLOAT);
        !          5294:     t0 = tcg_temp_new();
        !          5295:     gen_addr_imm_index(ctx, t0, 0);
        !          5296:     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
        !          5297:     gen_addr_add(ctx, t0, t0, 8);
        !          5298:     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
        !          5299:     tcg_temp_free(t0);
1.1.1.5   root     5300: }
                   5301: 
                   5302: /* lfqu */
                   5303: GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
                   5304: {
                   5305:     int ra = rA(ctx->opcode);
1.1.1.6 ! root     5306:     int rd = rD(ctx->opcode);
        !          5307:     TCGv t0, t1;
        !          5308:     gen_set_access_type(ctx, ACCESS_FLOAT);
        !          5309:     t0 = tcg_temp_new();
        !          5310:     t1 = tcg_temp_new();
        !          5311:     gen_addr_imm_index(ctx, t0, 0);
        !          5312:     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
        !          5313:     gen_addr_add(ctx, t1, t0, 8);
        !          5314:     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
1.1.1.5   root     5315:     if (ra != 0)
1.1.1.6 ! root     5316:         tcg_gen_mov_tl(cpu_gpr[ra], t0);
        !          5317:     tcg_temp_free(t0);
        !          5318:     tcg_temp_free(t1);
1.1.1.5   root     5319: }
                   5320: 
                   5321: /* lfqux */
                   5322: GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2)
                   5323: {
                   5324:     int ra = rA(ctx->opcode);
1.1.1.6 ! root     5325:     int rd = rD(ctx->opcode);
        !          5326:     gen_set_access_type(ctx, ACCESS_FLOAT);
        !          5327:     TCGv t0, t1;
        !          5328:     t0 = tcg_temp_new();
        !          5329:     gen_addr_reg_index(ctx, t0);
        !          5330:     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
        !          5331:     t1 = tcg_temp_new();
        !          5332:     gen_addr_add(ctx, t1, t0, 8);
        !          5333:     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t1);
        !          5334:     tcg_temp_free(t1);
1.1.1.5   root     5335:     if (ra != 0)
1.1.1.6 ! root     5336:         tcg_gen_mov_tl(cpu_gpr[ra], t0);
        !          5337:     tcg_temp_free(t0);
1.1.1.5   root     5338: }
                   5339: 
                   5340: /* lfqx */
                   5341: GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2)
                   5342: {
1.1.1.6 ! root     5343:     int rd = rD(ctx->opcode);
        !          5344:     TCGv t0;
        !          5345:     gen_set_access_type(ctx, ACCESS_FLOAT);
        !          5346:     t0 = tcg_temp_new();
        !          5347:     gen_addr_reg_index(ctx, t0);
        !          5348:     gen_qemu_ld64(ctx, cpu_fpr[rd], t0);
        !          5349:     gen_addr_add(ctx, t0, t0, 8);
        !          5350:     gen_qemu_ld64(ctx, cpu_fpr[(rd + 1) % 32], t0);
        !          5351:     tcg_temp_free(t0);
1.1.1.5   root     5352: }
                   5353: 
                   5354: /* stfq */
                   5355: GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
                   5356: {
1.1.1.6 ! root     5357:     int rd = rD(ctx->opcode);
        !          5358:     TCGv t0;
        !          5359:     gen_set_access_type(ctx, ACCESS_FLOAT);
        !          5360:     t0 = tcg_temp_new();
        !          5361:     gen_addr_imm_index(ctx, t0, 0);
        !          5362:     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
        !          5363:     gen_addr_add(ctx, t0, t0, 8);
        !          5364:     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
        !          5365:     tcg_temp_free(t0);
1.1.1.5   root     5366: }
                   5367: 
                   5368: /* stfqu */
                   5369: GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
                   5370: {
                   5371:     int ra = rA(ctx->opcode);
1.1.1.6 ! root     5372:     int rd = rD(ctx->opcode);
        !          5373:     TCGv t0, t1;
        !          5374:     gen_set_access_type(ctx, ACCESS_FLOAT);
        !          5375:     t0 = tcg_temp_new();
        !          5376:     gen_addr_imm_index(ctx, t0, 0);
        !          5377:     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
        !          5378:     t1 = tcg_temp_new();
        !          5379:     gen_addr_add(ctx, t1, t0, 8);
        !          5380:     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
        !          5381:     tcg_temp_free(t1);
1.1.1.5   root     5382:     if (ra != 0)
1.1.1.6 ! root     5383:         tcg_gen_mov_tl(cpu_gpr[ra], t0);
        !          5384:     tcg_temp_free(t0);
1.1.1.5   root     5385: }
                   5386: 
                   5387: /* stfqux */
                   5388: GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2)
                   5389: {
                   5390:     int ra = rA(ctx->opcode);
1.1.1.6 ! root     5391:     int rd = rD(ctx->opcode);
        !          5392:     TCGv t0, t1;
        !          5393:     gen_set_access_type(ctx, ACCESS_FLOAT);
        !          5394:     t0 = tcg_temp_new();
        !          5395:     gen_addr_reg_index(ctx, t0);
        !          5396:     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
        !          5397:     t1 = tcg_temp_new();
        !          5398:     gen_addr_add(ctx, t1, t0, 8);
        !          5399:     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t1);
        !          5400:     tcg_temp_free(t1);
1.1.1.5   root     5401:     if (ra != 0)
1.1.1.6 ! root     5402:         tcg_gen_mov_tl(cpu_gpr[ra], t0);
        !          5403:     tcg_temp_free(t0);
1.1.1.5   root     5404: }
                   5405: 
                   5406: /* stfqx */
                   5407: GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
                   5408: {
1.1.1.6 ! root     5409:     int rd = rD(ctx->opcode);
        !          5410:     TCGv t0;
        !          5411:     gen_set_access_type(ctx, ACCESS_FLOAT);
        !          5412:     t0 = tcg_temp_new();
        !          5413:     gen_addr_reg_index(ctx, t0);
        !          5414:     gen_qemu_st64(ctx, cpu_fpr[rd], t0);
        !          5415:     gen_addr_add(ctx, t0, t0, 8);
        !          5416:     gen_qemu_st64(ctx, cpu_fpr[(rd + 1) % 32], t0);
        !          5417:     tcg_temp_free(t0);
1.1.1.5   root     5418: }
                   5419: 
                   5420: /* BookE specific instructions */
                   5421: /* XXX: not implemented on 440 ? */
                   5422: GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI)
                   5423: {
                   5424:     /* XXX: TODO */
1.1.1.6 ! root     5425:     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5426: }
                   5427: 
                   5428: /* XXX: not implemented on 440 ? */
                   5429: GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA)
                   5430: {
                   5431: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5432:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5433: #else
1.1.1.6 ! root     5434:     TCGv t0;
        !          5435:     if (unlikely(!ctx->mem_idx)) {
        !          5436:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5437:         return;
                   5438:     }
1.1.1.6 ! root     5439:     t0 = tcg_temp_new();
        !          5440:     gen_addr_reg_index(ctx, t0);
        !          5441:     gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
        !          5442:     tcg_temp_free(t0);
1.1.1.5   root     5443: #endif
                   5444: }
                   5445: 
                   5446: /* All 405 MAC instructions are translated here */
                   5447: static always_inline void gen_405_mulladd_insn (DisasContext *ctx,
                   5448:                                                 int opc2, int opc3,
                   5449:                                                 int ra, int rb, int rt, int Rc)
                   5450: {
1.1.1.6 ! root     5451:     TCGv t0, t1;
        !          5452: 
        !          5453:     t0 = tcg_temp_local_new();
        !          5454:     t1 = tcg_temp_local_new();
        !          5455: 
1.1.1.5   root     5456:     switch (opc3 & 0x0D) {
                   5457:     case 0x05:
                   5458:         /* macchw    - macchw.    - macchwo   - macchwo.   */
                   5459:         /* macchws   - macchws.   - macchwso  - macchwso.  */
                   5460:         /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
                   5461:         /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
                   5462:         /* mulchw - mulchw. */
1.1.1.6 ! root     5463:         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
        !          5464:         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
        !          5465:         tcg_gen_ext16s_tl(t1, t1);
1.1.1.5   root     5466:         break;
                   5467:     case 0x04:
                   5468:         /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
                   5469:         /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
                   5470:         /* mulchwu - mulchwu. */
1.1.1.6 ! root     5471:         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
        !          5472:         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
        !          5473:         tcg_gen_ext16u_tl(t1, t1);
1.1.1.5   root     5474:         break;
                   5475:     case 0x01:
                   5476:         /* machhw    - machhw.    - machhwo   - machhwo.   */
                   5477:         /* machhws   - machhws.   - machhwso  - machhwso.  */
                   5478:         /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
                   5479:         /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
                   5480:         /* mulhhw - mulhhw. */
1.1.1.6 ! root     5481:         tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
        !          5482:         tcg_gen_ext16s_tl(t0, t0);
        !          5483:         tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
        !          5484:         tcg_gen_ext16s_tl(t1, t1);
1.1.1.5   root     5485:         break;
                   5486:     case 0x00:
                   5487:         /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
                   5488:         /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
                   5489:         /* mulhhwu - mulhhwu. */
1.1.1.6 ! root     5490:         tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
        !          5491:         tcg_gen_ext16u_tl(t0, t0);
        !          5492:         tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
        !          5493:         tcg_gen_ext16u_tl(t1, t1);
1.1.1.5   root     5494:         break;
                   5495:     case 0x0D:
                   5496:         /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
                   5497:         /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
                   5498:         /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
                   5499:         /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
                   5500:         /* mullhw - mullhw. */
1.1.1.6 ! root     5501:         tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
        !          5502:         tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
1.1.1.5   root     5503:         break;
                   5504:     case 0x0C:
                   5505:         /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
                   5506:         /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
                   5507:         /* mullhwu - mullhwu. */
1.1.1.6 ! root     5508:         tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
        !          5509:         tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
1.1.1.5   root     5510:         break;
                   5511:     }
                   5512:     if (opc2 & 0x04) {
1.1.1.6 ! root     5513:         /* (n)multiply-and-accumulate (0x0C / 0x0E) */
        !          5514:         tcg_gen_mul_tl(t1, t0, t1);
        !          5515:         if (opc2 & 0x02) {
        !          5516:             /* nmultiply-and-accumulate (0x0E) */
        !          5517:             tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
        !          5518:         } else {
        !          5519:             /* multiply-and-accumulate (0x0C) */
        !          5520:             tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
        !          5521:         }
        !          5522: 
        !          5523:         if (opc3 & 0x12) {
        !          5524:             /* Check overflow and/or saturate */
        !          5525:             int l1 = gen_new_label();
        !          5526: 
        !          5527:             if (opc3 & 0x10) {
        !          5528:                 /* Start with XER OV disabled, the most likely case */
        !          5529:                 tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
        !          5530:             }
        !          5531:             if (opc3 & 0x01) {
        !          5532:                 /* Signed */
        !          5533:                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
        !          5534:                 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
        !          5535:                 tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
        !          5536:                 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
        !          5537:                 if (opc3 & 0x02) {
        !          5538:                     /* Saturate */
        !          5539:                     tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
        !          5540:                     tcg_gen_xori_tl(t0, t0, 0x7fffffff);
        !          5541:                 }
        !          5542:             } else {
        !          5543:                 /* Unsigned */
        !          5544:                 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
        !          5545:                 if (opc3 & 0x02) {
        !          5546:                     /* Saturate */
        !          5547:                     tcg_gen_movi_tl(t0, UINT32_MAX);
        !          5548:                 }
        !          5549:             }
        !          5550:             if (opc3 & 0x10) {
        !          5551:                 /* Check overflow */
        !          5552:                 tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
        !          5553:             }
        !          5554:             gen_set_label(l1);
        !          5555:             tcg_gen_mov_tl(cpu_gpr[rt], t0);
        !          5556:         }
        !          5557:     } else {
        !          5558:         tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
1.1.1.5   root     5559:     }
1.1.1.6 ! root     5560:     tcg_temp_free(t0);
        !          5561:     tcg_temp_free(t1);
1.1.1.5   root     5562:     if (unlikely(Rc) != 0) {
                   5563:         /* Update Rc0 */
1.1.1.6 ! root     5564:         gen_set_Rc0(ctx, cpu_gpr[rt]);
1.1.1.5   root     5565:     }
                   5566: }
                   5567: 
                   5568: #define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
                   5569: GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)                  \
                   5570: {                                                                             \
                   5571:     gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
                   5572:                          rD(ctx->opcode), Rc(ctx->opcode));                   \
                   5573: }
                   5574: 
                   5575: /* macchw    - macchw.    */
                   5576: GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
                   5577: /* macchwo   - macchwo.   */
                   5578: GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
                   5579: /* macchws   - macchws.   */
                   5580: GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
                   5581: /* macchwso  - macchwso.  */
                   5582: GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
                   5583: /* macchwsu  - macchwsu.  */
                   5584: GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
                   5585: /* macchwsuo - macchwsuo. */
                   5586: GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
                   5587: /* macchwu   - macchwu.   */
                   5588: GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
                   5589: /* macchwuo  - macchwuo.  */
                   5590: GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
                   5591: /* machhw    - machhw.    */
                   5592: GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
                   5593: /* machhwo   - machhwo.   */
                   5594: GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
                   5595: /* machhws   - machhws.   */
                   5596: GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
                   5597: /* machhwso  - machhwso.  */
                   5598: GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
                   5599: /* machhwsu  - machhwsu.  */
                   5600: GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
                   5601: /* machhwsuo - machhwsuo. */
                   5602: GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
                   5603: /* machhwu   - machhwu.   */
                   5604: GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
                   5605: /* machhwuo  - machhwuo.  */
                   5606: GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
                   5607: /* maclhw    - maclhw.    */
                   5608: GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
                   5609: /* maclhwo   - maclhwo.   */
                   5610: GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
                   5611: /* maclhws   - maclhws.   */
                   5612: GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
                   5613: /* maclhwso  - maclhwso.  */
                   5614: GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
                   5615: /* maclhwu   - maclhwu.   */
                   5616: GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
                   5617: /* maclhwuo  - maclhwuo.  */
                   5618: GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
                   5619: /* maclhwsu  - maclhwsu.  */
                   5620: GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
                   5621: /* maclhwsuo - maclhwsuo. */
                   5622: GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
                   5623: /* nmacchw   - nmacchw.   */
                   5624: GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
                   5625: /* nmacchwo  - nmacchwo.  */
                   5626: GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
                   5627: /* nmacchws  - nmacchws.  */
                   5628: GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
                   5629: /* nmacchwso - nmacchwso. */
                   5630: GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
                   5631: /* nmachhw   - nmachhw.   */
                   5632: GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
                   5633: /* nmachhwo  - nmachhwo.  */
                   5634: GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
                   5635: /* nmachhws  - nmachhws.  */
                   5636: GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
                   5637: /* nmachhwso - nmachhwso. */
                   5638: GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
                   5639: /* nmaclhw   - nmaclhw.   */
                   5640: GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
                   5641: /* nmaclhwo  - nmaclhwo.  */
                   5642: GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
                   5643: /* nmaclhws  - nmaclhws.  */
                   5644: GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
                   5645: /* nmaclhwso - nmaclhwso. */
                   5646: GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
                   5647: 
                   5648: /* mulchw  - mulchw.  */
                   5649: GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
                   5650: /* mulchwu - mulchwu. */
                   5651: GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
                   5652: /* mulhhw  - mulhhw.  */
                   5653: GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
                   5654: /* mulhhwu - mulhhwu. */
                   5655: GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
                   5656: /* mullhw  - mullhw.  */
                   5657: GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
                   5658: /* mullhwu - mullhwu. */
                   5659: GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
                   5660: 
                   5661: /* mfdcr */
                   5662: GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR)
                   5663: {
                   5664: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5665:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5666: #else
1.1.1.6 ! root     5667:     TCGv dcrn;
        !          5668:     if (unlikely(!ctx->mem_idx)) {
        !          5669:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5670:         return;
                   5671:     }
1.1.1.6 ! root     5672:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          5673:     gen_update_nip(ctx, ctx->nip - 4);
        !          5674:     dcrn = tcg_const_tl(SPR(ctx->opcode));
        !          5675:     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], dcrn);
        !          5676:     tcg_temp_free(dcrn);
1.1.1.5   root     5677: #endif
                   5678: }
                   5679: 
                   5680: /* mtdcr */
                   5681: GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR)
                   5682: {
                   5683: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5684:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5685: #else
1.1.1.6 ! root     5686:     TCGv dcrn;
        !          5687:     if (unlikely(!ctx->mem_idx)) {
        !          5688:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5689:         return;
                   5690:     }
1.1.1.6 ! root     5691:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          5692:     gen_update_nip(ctx, ctx->nip - 4);
        !          5693:     dcrn = tcg_const_tl(SPR(ctx->opcode));
        !          5694:     gen_helper_store_dcr(dcrn, cpu_gpr[rS(ctx->opcode)]);
        !          5695:     tcg_temp_free(dcrn);
1.1.1.5   root     5696: #endif
                   5697: }
                   5698: 
                   5699: /* mfdcrx */
                   5700: /* XXX: not implemented on 440 ? */
                   5701: GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX)
                   5702: {
                   5703: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5704:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5705: #else
1.1.1.6 ! root     5706:     if (unlikely(!ctx->mem_idx)) {
        !          5707:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5708:         return;
                   5709:     }
1.1.1.6 ! root     5710:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          5711:     gen_update_nip(ctx, ctx->nip - 4);
        !          5712:     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5713:     /* Note: Rc update flag set leads to undefined state of Rc0 */
                   5714: #endif
                   5715: }
                   5716: 
                   5717: /* mtdcrx */
                   5718: /* XXX: not implemented on 440 ? */
                   5719: GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX)
                   5720: {
                   5721: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5722:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5723: #else
1.1.1.6 ! root     5724:     if (unlikely(!ctx->mem_idx)) {
        !          5725:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
1.1.1.5   root     5726:         return;
                   5727:     }
1.1.1.6 ! root     5728:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          5729:     gen_update_nip(ctx, ctx->nip - 4);
        !          5730:     gen_helper_store_dcr(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     5731:     /* Note: Rc update flag set leads to undefined state of Rc0 */
                   5732: #endif
                   5733: }
                   5734: 
                   5735: /* mfdcrux (PPC 460) : user-mode access to DCR */
                   5736: GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX)
                   5737: {
1.1.1.6 ! root     5738:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          5739:     gen_update_nip(ctx, ctx->nip - 4);
        !          5740:     gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5741:     /* Note: Rc update flag set leads to undefined state of Rc0 */
                   5742: }
                   5743: 
                   5744: /* mtdcrux (PPC 460) : user-mode access to DCR */
                   5745: GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
                   5746: {
1.1.1.6 ! root     5747:     /* NIP cannot be restored if the memory exception comes from an helper */
        !          5748:     gen_update_nip(ctx, ctx->nip - 4);
        !          5749:     gen_helper_store_dcr(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     5750:     /* Note: Rc update flag set leads to undefined state of Rc0 */
                   5751: }
                   5752: 
                   5753: /* dccci */
                   5754: GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
                   5755: {
                   5756: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5757:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5758: #else
1.1.1.6 ! root     5759:     if (unlikely(!ctx->mem_idx)) {
        !          5760:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5761:         return;
                   5762:     }
                   5763:     /* interpreted as no-op */
                   5764: #endif
                   5765: }
                   5766: 
                   5767: /* dcread */
                   5768: GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
                   5769: {
                   5770: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5771:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5772: #else
1.1.1.6 ! root     5773:     TCGv EA, val;
        !          5774:     if (unlikely(!ctx->mem_idx)) {
        !          5775:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5776:         return;
                   5777:     }
1.1.1.6 ! root     5778:     gen_set_access_type(ctx, ACCESS_CACHE);
        !          5779:     EA = tcg_temp_new();
        !          5780:     gen_addr_reg_index(ctx, EA);
        !          5781:     val = tcg_temp_new();
        !          5782:     gen_qemu_ld32u(ctx, val, EA);
        !          5783:     tcg_temp_free(val);
        !          5784:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
        !          5785:     tcg_temp_free(EA);
1.1.1.5   root     5786: #endif
                   5787: }
                   5788: 
                   5789: /* icbt */
                   5790: GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
                   5791: {
                   5792:     /* interpreted as no-op */
                   5793:     /* XXX: specification say this is treated as a load by the MMU
                   5794:      *      but does not generate any exception
                   5795:      */
                   5796: }
                   5797: 
                   5798: /* iccci */
                   5799: GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
                   5800: {
                   5801: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5802:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5803: #else
1.1.1.6 ! root     5804:     if (unlikely(!ctx->mem_idx)) {
        !          5805:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5806:         return;
                   5807:     }
                   5808:     /* interpreted as no-op */
                   5809: #endif
                   5810: }
                   5811: 
                   5812: /* icread */
                   5813: GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
                   5814: {
                   5815: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5816:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5817: #else
1.1.1.6 ! root     5818:     if (unlikely(!ctx->mem_idx)) {
        !          5819:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5820:         return;
                   5821:     }
                   5822:     /* interpreted as no-op */
                   5823: #endif
                   5824: }
                   5825: 
1.1.1.6 ! root     5826: /* rfci (mem_idx only) */
1.1.1.5   root     5827: GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
                   5828: {
                   5829: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5830:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5831: #else
1.1.1.6 ! root     5832:     if (unlikely(!ctx->mem_idx)) {
        !          5833:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5834:         return;
                   5835:     }
                   5836:     /* Restore CPU state */
1.1.1.6 ! root     5837:     gen_helper_40x_rfci();
        !          5838:     gen_sync_exception(ctx);
1.1.1.5   root     5839: #endif
                   5840: }
                   5841: 
                   5842: GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
                   5843: {
                   5844: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5845:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5846: #else
1.1.1.6 ! root     5847:     if (unlikely(!ctx->mem_idx)) {
        !          5848:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5849:         return;
                   5850:     }
                   5851:     /* Restore CPU state */
1.1.1.6 ! root     5852:     gen_helper_rfci();
        !          5853:     gen_sync_exception(ctx);
1.1.1.5   root     5854: #endif
                   5855: }
                   5856: 
                   5857: /* BookE specific */
                   5858: /* XXX: not implemented on 440 ? */
                   5859: GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI)
                   5860: {
                   5861: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5862:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5863: #else
1.1.1.6 ! root     5864:     if (unlikely(!ctx->mem_idx)) {
        !          5865:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5866:         return;
                   5867:     }
                   5868:     /* Restore CPU state */
1.1.1.6 ! root     5869:     gen_helper_rfdi();
        !          5870:     gen_sync_exception(ctx);
1.1.1.5   root     5871: #endif
                   5872: }
                   5873: 
                   5874: /* XXX: not implemented on 440 ? */
                   5875: GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
                   5876: {
                   5877: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5878:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5879: #else
1.1.1.6 ! root     5880:     if (unlikely(!ctx->mem_idx)) {
        !          5881:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5882:         return;
                   5883:     }
                   5884:     /* Restore CPU state */
1.1.1.6 ! root     5885:     gen_helper_rfmci();
        !          5886:     gen_sync_exception(ctx);
1.1.1.5   root     5887: #endif
                   5888: }
                   5889: 
                   5890: /* TLB management - PowerPC 405 implementation */
                   5891: /* tlbre */
                   5892: GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
                   5893: {
                   5894: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5895:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5896: #else
1.1.1.6 ! root     5897:     if (unlikely(!ctx->mem_idx)) {
        !          5898:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5899:         return;
                   5900:     }
                   5901:     switch (rB(ctx->opcode)) {
                   5902:     case 0:
1.1.1.6 ! root     5903:         gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5904:         break;
                   5905:     case 1:
1.1.1.6 ! root     5906:         gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1.1.1.5   root     5907:         break;
                   5908:     default:
1.1.1.6 ! root     5909:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5910:         break;
                   5911:     }
                   5912: #endif
                   5913: }
                   5914: 
                   5915: /* tlbsx - tlbsx. */
                   5916: GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
                   5917: {
                   5918: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5919:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5920: #else
1.1.1.6 ! root     5921:     TCGv t0;
        !          5922:     if (unlikely(!ctx->mem_idx)) {
        !          5923:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5924:         return;
                   5925:     }
1.1.1.6 ! root     5926:     t0 = tcg_temp_new();
        !          5927:     gen_addr_reg_index(ctx, t0);
        !          5928:     gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
        !          5929:     tcg_temp_free(t0);
        !          5930:     if (Rc(ctx->opcode)) {
        !          5931:         int l1 = gen_new_label();
        !          5932:         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
        !          5933:         tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
        !          5934:         tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
        !          5935:         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
        !          5936:         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
        !          5937:         gen_set_label(l1);
        !          5938:     }
1.1.1.5   root     5939: #endif
                   5940: }
                   5941: 
                   5942: /* tlbwe */
                   5943: GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
                   5944: {
                   5945: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5946:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5947: #else
1.1.1.6 ! root     5948:     if (unlikely(!ctx->mem_idx)) {
        !          5949:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5950:         return;
                   5951:     }
                   5952:     switch (rB(ctx->opcode)) {
                   5953:     case 0:
1.1.1.6 ! root     5954:         gen_helper_4xx_tlbwe_hi(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     5955:         break;
                   5956:     case 1:
1.1.1.6 ! root     5957:         gen_helper_4xx_tlbwe_lo(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1.1.1.5   root     5958:         break;
                   5959:     default:
1.1.1.6 ! root     5960:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5961:         break;
                   5962:     }
                   5963: #endif
                   5964: }
                   5965: 
                   5966: /* TLB management - PowerPC 440 implementation */
                   5967: /* tlbre */
                   5968: GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
                   5969: {
                   5970: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5971:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5972: #else
1.1.1.6 ! root     5973:     if (unlikely(!ctx->mem_idx)) {
        !          5974:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     5975:         return;
                   5976:     }
                   5977:     switch (rB(ctx->opcode)) {
                   5978:     case 0:
                   5979:     case 1:
                   5980:     case 2:
1.1.1.6 ! root     5981:         {
        !          5982:             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
        !          5983:             gen_helper_440_tlbwe(t0, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
        !          5984:             tcg_temp_free_i32(t0);
        !          5985:         }
1.1.1.5   root     5986:         break;
                   5987:     default:
1.1.1.6 ! root     5988:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     5989:         break;
                   5990:     }
                   5991: #endif
                   5992: }
                   5993: 
                   5994: /* tlbsx - tlbsx. */
                   5995: GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
1.1       root     5996: {
                   5997: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     5998:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     5999: #else
1.1.1.6 ! root     6000:     TCGv t0;
        !          6001:     if (unlikely(!ctx->mem_idx)) {
        !          6002:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     6003:         return;
                   6004:     }
1.1.1.6 ! root     6005:     t0 = tcg_temp_new();
        !          6006:     gen_addr_reg_index(ctx, t0);
        !          6007:     gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], t0);
        !          6008:     tcg_temp_free(t0);
        !          6009:     if (Rc(ctx->opcode)) {
        !          6010:         int l1 = gen_new_label();
        !          6011:         tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_xer);
        !          6012:         tcg_gen_shri_i32(cpu_crf[0], cpu_crf[0], XER_SO);
        !          6013:         tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 1);
        !          6014:         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
        !          6015:         tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
        !          6016:         gen_set_label(l1);
        !          6017:     }
1.1       root     6018: #endif
                   6019: }
                   6020: 
1.1.1.5   root     6021: /* tlbwe */
                   6022: GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
1.1       root     6023: {
                   6024: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     6025:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     6026: #else
1.1.1.6 ! root     6027:     if (unlikely(!ctx->mem_idx)) {
        !          6028:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1       root     6029:         return;
                   6030:     }
1.1.1.5   root     6031:     switch (rB(ctx->opcode)) {
                   6032:     case 0:
                   6033:     case 1:
                   6034:     case 2:
1.1.1.6 ! root     6035:         {
        !          6036:             TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
        !          6037:             gen_helper_440_tlbwe(t0, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
        !          6038:             tcg_temp_free_i32(t0);
        !          6039:         }
1.1.1.5   root     6040:         break;
                   6041:     default:
1.1.1.6 ! root     6042:         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     6043:         break;
                   6044:     }
                   6045: #endif
                   6046: }
                   6047: 
                   6048: /* wrtee */
                   6049: GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE)
                   6050: {
                   6051: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     6052:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     6053: #else
1.1.1.6 ! root     6054:     TCGv t0;
        !          6055:     if (unlikely(!ctx->mem_idx)) {
        !          6056:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     6057:         return;
                   6058:     }
1.1.1.6 ! root     6059:     t0 = tcg_temp_new();
        !          6060:     tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
        !          6061:     tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
        !          6062:     tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
        !          6063:     tcg_temp_free(t0);
1.1.1.5   root     6064:     /* Stop translation to have a chance to raise an exception
                   6065:      * if we just set msr_ee to 1
1.1       root     6066:      */
1.1.1.6 ! root     6067:     gen_stop_exception(ctx);
1.1       root     6068: #endif
                   6069: }
                   6070: 
1.1.1.5   root     6071: /* wrteei */
                   6072: GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_WRTEE)
                   6073: {
1.1       root     6074: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     6075:     gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     6076: #else
1.1.1.6 ! root     6077:     if (unlikely(!ctx->mem_idx)) {
        !          6078:         gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
1.1.1.5   root     6079:         return;
                   6080:     }
1.1.1.6 ! root     6081:     if (ctx->opcode & 0x00010000) {
        !          6082:         tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
        !          6083:         /* Stop translation to have a chance to raise an exception */
        !          6084:         gen_stop_exception(ctx);
        !          6085:     } else {
        !          6086:         tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
        !          6087:     }
1.1.1.5   root     6088: #endif
                   6089: }
                   6090: 
                   6091: /* PowerPC 440 specific instructions */
                   6092: /* dlmzb */
                   6093: GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
                   6094: {
1.1.1.6 ! root     6095:     TCGv_i32 t0 = tcg_const_i32(Rc(ctx->opcode));
        !          6096:     gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
        !          6097:                      cpu_gpr[rB(ctx->opcode)], t0);
        !          6098:     tcg_temp_free_i32(t0);
1.1.1.5   root     6099: }
                   6100: 
                   6101: /* mbar replaces eieio on 440 */
1.1.1.6 ! root     6102: GEN_HANDLER(mbar, 0x1F, 0x16, 0x1a, 0x001FF801, PPC_BOOKE)
1.1.1.5   root     6103: {
                   6104:     /* interpreted as no-op */
                   6105: }
                   6106: 
                   6107: /* msync replaces sync on 440 */
                   6108: GEN_HANDLER(msync, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE)
                   6109: {
                   6110:     /* interpreted as no-op */
                   6111: }
                   6112: 
                   6113: /* icbt */
                   6114: GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE)
                   6115: {
                   6116:     /* interpreted as no-op */
                   6117:     /* XXX: specification say this is treated as a load by the MMU
                   6118:      *      but does not generate any exception
                   6119:      */
                   6120: }
                   6121: 
                   6122: /***                      Altivec vector extension                         ***/
                   6123: /* Altivec registers moves */
                   6124: 
1.1.1.6 ! root     6125: static always_inline TCGv_ptr gen_avr_ptr(int reg)
        !          6126: {
        !          6127:     TCGv_ptr r = tcg_temp_new_ptr();
        !          6128:     tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, avr[reg]));
        !          6129:     return r;
        !          6130: }
1.1.1.5   root     6131: 
                   6132: #define GEN_VR_LDX(name, opc2, opc3)                                          \
1.1.1.6 ! root     6133: GEN_HANDLER(name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)                  \
1.1.1.5   root     6134: {                                                                             \
1.1.1.6 ! root     6135:     TCGv EA;                                                                  \
1.1.1.5   root     6136:     if (unlikely(!ctx->altivec_enabled)) {                                    \
1.1.1.6 ! root     6137:         gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
1.1.1.5   root     6138:         return;                                                               \
                   6139:     }                                                                         \
1.1.1.6 ! root     6140:     gen_set_access_type(ctx, ACCESS_INT);                                     \
        !          6141:     EA = tcg_temp_new();                                                      \
        !          6142:     gen_addr_reg_index(ctx, EA);                                              \
        !          6143:     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
        !          6144:     if (ctx->le_mode) {                                                       \
        !          6145:         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
        !          6146:         tcg_gen_addi_tl(EA, EA, 8);                                           \
        !          6147:         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
        !          6148:     } else {                                                                  \
        !          6149:         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
        !          6150:         tcg_gen_addi_tl(EA, EA, 8);                                           \
        !          6151:         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
        !          6152:     }                                                                         \
        !          6153:     tcg_temp_free(EA);                                                        \
1.1.1.5   root     6154: }
                   6155: 
                   6156: #define GEN_VR_STX(name, opc2, opc3)                                          \
                   6157: GEN_HANDLER(st##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)              \
                   6158: {                                                                             \
1.1.1.6 ! root     6159:     TCGv EA;                                                                  \
1.1.1.5   root     6160:     if (unlikely(!ctx->altivec_enabled)) {                                    \
1.1.1.6 ! root     6161:         gen_exception(ctx, POWERPC_EXCP_VPU);                                 \
1.1.1.5   root     6162:         return;                                                               \
                   6163:     }                                                                         \
1.1.1.6 ! root     6164:     gen_set_access_type(ctx, ACCESS_INT);                                     \
        !          6165:     EA = tcg_temp_new();                                                      \
        !          6166:     gen_addr_reg_index(ctx, EA);                                              \
        !          6167:     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
        !          6168:     if (ctx->le_mode) {                                                       \
        !          6169:         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
        !          6170:         tcg_gen_addi_tl(EA, EA, 8);                                           \
        !          6171:         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
        !          6172:     } else {                                                                  \
        !          6173:         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
        !          6174:         tcg_gen_addi_tl(EA, EA, 8);                                           \
        !          6175:         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
        !          6176:     }                                                                         \
        !          6177:     tcg_temp_free(EA);                                                        \
1.1.1.5   root     6178: }
                   6179: 
1.1.1.6 ! root     6180: #define GEN_VR_LVE(name, opc2, opc3)                                    \
        !          6181:     GEN_HANDLER(lve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)   \
        !          6182:     {                                                                   \
        !          6183:         TCGv EA;                                                        \
        !          6184:         TCGv_ptr rs;                                                    \
        !          6185:         if (unlikely(!ctx->altivec_enabled)) {                          \
        !          6186:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
        !          6187:             return;                                                     \
        !          6188:         }                                                               \
        !          6189:         gen_set_access_type(ctx, ACCESS_INT);                           \
        !          6190:         EA = tcg_temp_new();                                            \
        !          6191:         gen_addr_reg_index(ctx, EA);                                    \
        !          6192:         rs = gen_avr_ptr(rS(ctx->opcode));                              \
        !          6193:         gen_helper_lve##name (rs, EA);                                  \
        !          6194:         tcg_temp_free(EA);                                              \
        !          6195:         tcg_temp_free_ptr(rs);                                          \
        !          6196:     }
        !          6197: 
        !          6198: #define GEN_VR_STVE(name, opc2, opc3)                                   \
        !          6199:     GEN_HANDLER(stve##name, 0x1F, opc2, opc3, 0x00000001, PPC_ALTIVEC)  \
        !          6200:     {                                                                   \
        !          6201:         TCGv EA;                                                        \
        !          6202:         TCGv_ptr rs;                                                    \
        !          6203:         if (unlikely(!ctx->altivec_enabled)) {                          \
        !          6204:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
        !          6205:             return;                                                     \
        !          6206:         }                                                               \
        !          6207:         gen_set_access_type(ctx, ACCESS_INT);                           \
        !          6208:         EA = tcg_temp_new();                                            \
        !          6209:         gen_addr_reg_index(ctx, EA);                                    \
        !          6210:         rs = gen_avr_ptr(rS(ctx->opcode));                              \
        !          6211:         gen_helper_stve##name (rs, EA);                                 \
        !          6212:         tcg_temp_free(EA);                                              \
        !          6213:         tcg_temp_free_ptr(rs);                                          \
        !          6214:     }
        !          6215: 
        !          6216: GEN_VR_LDX(lvx, 0x07, 0x03);
1.1.1.5   root     6217: /* As we don't emulate the cache, lvxl is stricly equivalent to lvx */
1.1.1.6 ! root     6218: GEN_VR_LDX(lvxl, 0x07, 0x0B);
1.1.1.5   root     6219: 
1.1.1.6 ! root     6220: GEN_VR_LVE(bx, 0x07, 0x00);
        !          6221: GEN_VR_LVE(hx, 0x07, 0x01);
        !          6222: GEN_VR_LVE(wx, 0x07, 0x02);
        !          6223: 
        !          6224: GEN_VR_STX(svx, 0x07, 0x07);
1.1.1.5   root     6225: /* As we don't emulate the cache, stvxl is stricly equivalent to stvx */
1.1.1.6 ! root     6226: GEN_VR_STX(svxl, 0x07, 0x0F);
        !          6227: 
        !          6228: GEN_VR_STVE(bx, 0x07, 0x04);
        !          6229: GEN_VR_STVE(hx, 0x07, 0x05);
        !          6230: GEN_VR_STVE(wx, 0x07, 0x06);
        !          6231: 
        !          6232: GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC)
        !          6233: {
        !          6234:     TCGv_ptr rd;
        !          6235:     TCGv EA;
        !          6236:     if (unlikely(!ctx->altivec_enabled)) {
        !          6237:         gen_exception(ctx, POWERPC_EXCP_VPU);
        !          6238:         return;
        !          6239:     }
        !          6240:     EA = tcg_temp_new();
        !          6241:     gen_addr_reg_index(ctx, EA);
        !          6242:     rd = gen_avr_ptr(rD(ctx->opcode));
        !          6243:     gen_helper_lvsl(rd, EA);
        !          6244:     tcg_temp_free(EA);
        !          6245:     tcg_temp_free_ptr(rd);
        !          6246: }
        !          6247: 
        !          6248: GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC)
        !          6249: {
        !          6250:     TCGv_ptr rd;
        !          6251:     TCGv EA;
        !          6252:     if (unlikely(!ctx->altivec_enabled)) {
        !          6253:         gen_exception(ctx, POWERPC_EXCP_VPU);
        !          6254:         return;
        !          6255:     }
        !          6256:     EA = tcg_temp_new();
        !          6257:     gen_addr_reg_index(ctx, EA);
        !          6258:     rd = gen_avr_ptr(rD(ctx->opcode));
        !          6259:     gen_helper_lvsr(rd, EA);
        !          6260:     tcg_temp_free(EA);
        !          6261:     tcg_temp_free_ptr(rd);
        !          6262: }
        !          6263: 
        !          6264: GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC)
        !          6265: {
        !          6266:     TCGv_i32 t;
        !          6267:     if (unlikely(!ctx->altivec_enabled)) {
        !          6268:         gen_exception(ctx, POWERPC_EXCP_VPU);
        !          6269:         return;
        !          6270:     }
        !          6271:     tcg_gen_movi_i64(cpu_avrh[rD(ctx->opcode)], 0);
        !          6272:     t = tcg_temp_new_i32();
        !          6273:     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, vscr));
        !          6274:     tcg_gen_extu_i32_i64(cpu_avrl[rD(ctx->opcode)], t);
        !          6275:     tcg_temp_free_i32(t);
        !          6276: }
        !          6277: 
        !          6278: GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC)
        !          6279: {
        !          6280:     TCGv_ptr p;
        !          6281:     if (unlikely(!ctx->altivec_enabled)) {
        !          6282:         gen_exception(ctx, POWERPC_EXCP_VPU);
        !          6283:         return;
        !          6284:     }
        !          6285:     p = gen_avr_ptr(rD(ctx->opcode));
        !          6286:     gen_helper_mtvscr(p);
        !          6287:     tcg_temp_free_ptr(p);
        !          6288: }
        !          6289: 
        !          6290: /* Logical operations */
        !          6291: #define GEN_VX_LOGICAL(name, tcg_op, opc2, opc3)                        \
        !          6292: GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)            \
        !          6293: {                                                                       \
        !          6294:     if (unlikely(!ctx->altivec_enabled)) {                              \
        !          6295:         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
        !          6296:         return;                                                         \
        !          6297:     }                                                                   \
        !          6298:     tcg_op(cpu_avrh[rD(ctx->opcode)], cpu_avrh[rA(ctx->opcode)], cpu_avrh[rB(ctx->opcode)]); \
        !          6299:     tcg_op(cpu_avrl[rD(ctx->opcode)], cpu_avrl[rA(ctx->opcode)], cpu_avrl[rB(ctx->opcode)]); \
        !          6300: }
        !          6301: 
        !          6302: GEN_VX_LOGICAL(vand, tcg_gen_and_i64, 2, 16);
        !          6303: GEN_VX_LOGICAL(vandc, tcg_gen_andc_i64, 2, 17);
        !          6304: GEN_VX_LOGICAL(vor, tcg_gen_or_i64, 2, 18);
        !          6305: GEN_VX_LOGICAL(vxor, tcg_gen_xor_i64, 2, 19);
        !          6306: GEN_VX_LOGICAL(vnor, tcg_gen_nor_i64, 2, 20);
        !          6307: 
        !          6308: #define GEN_VXFORM(name, opc2, opc3)                                    \
        !          6309: GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)            \
        !          6310: {                                                                       \
        !          6311:     TCGv_ptr ra, rb, rd;                                                \
        !          6312:     if (unlikely(!ctx->altivec_enabled)) {                              \
        !          6313:         gen_exception(ctx, POWERPC_EXCP_VPU);                           \
        !          6314:         return;                                                         \
        !          6315:     }                                                                   \
        !          6316:     ra = gen_avr_ptr(rA(ctx->opcode));                                  \
        !          6317:     rb = gen_avr_ptr(rB(ctx->opcode));                                  \
        !          6318:     rd = gen_avr_ptr(rD(ctx->opcode));                                  \
        !          6319:     gen_helper_##name (rd, ra, rb);                                     \
        !          6320:     tcg_temp_free_ptr(ra);                                              \
        !          6321:     tcg_temp_free_ptr(rb);                                              \
        !          6322:     tcg_temp_free_ptr(rd);                                              \
        !          6323: }
        !          6324: 
        !          6325: GEN_VXFORM(vaddubm, 0, 0);
        !          6326: GEN_VXFORM(vadduhm, 0, 1);
        !          6327: GEN_VXFORM(vadduwm, 0, 2);
        !          6328: GEN_VXFORM(vsububm, 0, 16);
        !          6329: GEN_VXFORM(vsubuhm, 0, 17);
        !          6330: GEN_VXFORM(vsubuwm, 0, 18);
        !          6331: GEN_VXFORM(vmaxub, 1, 0);
        !          6332: GEN_VXFORM(vmaxuh, 1, 1);
        !          6333: GEN_VXFORM(vmaxuw, 1, 2);
        !          6334: GEN_VXFORM(vmaxsb, 1, 4);
        !          6335: GEN_VXFORM(vmaxsh, 1, 5);
        !          6336: GEN_VXFORM(vmaxsw, 1, 6);
        !          6337: GEN_VXFORM(vminub, 1, 8);
        !          6338: GEN_VXFORM(vminuh, 1, 9);
        !          6339: GEN_VXFORM(vminuw, 1, 10);
        !          6340: GEN_VXFORM(vminsb, 1, 12);
        !          6341: GEN_VXFORM(vminsh, 1, 13);
        !          6342: GEN_VXFORM(vminsw, 1, 14);
        !          6343: GEN_VXFORM(vavgub, 1, 16);
        !          6344: GEN_VXFORM(vavguh, 1, 17);
        !          6345: GEN_VXFORM(vavguw, 1, 18);
        !          6346: GEN_VXFORM(vavgsb, 1, 20);
        !          6347: GEN_VXFORM(vavgsh, 1, 21);
        !          6348: GEN_VXFORM(vavgsw, 1, 22);
        !          6349: GEN_VXFORM(vmrghb, 6, 0);
        !          6350: GEN_VXFORM(vmrghh, 6, 1);
        !          6351: GEN_VXFORM(vmrghw, 6, 2);
        !          6352: GEN_VXFORM(vmrglb, 6, 4);
        !          6353: GEN_VXFORM(vmrglh, 6, 5);
        !          6354: GEN_VXFORM(vmrglw, 6, 6);
        !          6355: GEN_VXFORM(vmuloub, 4, 0);
        !          6356: GEN_VXFORM(vmulouh, 4, 1);
        !          6357: GEN_VXFORM(vmulosb, 4, 4);
        !          6358: GEN_VXFORM(vmulosh, 4, 5);
        !          6359: GEN_VXFORM(vmuleub, 4, 8);
        !          6360: GEN_VXFORM(vmuleuh, 4, 9);
        !          6361: GEN_VXFORM(vmulesb, 4, 12);
        !          6362: GEN_VXFORM(vmulesh, 4, 13);
        !          6363: GEN_VXFORM(vslb, 2, 4);
        !          6364: GEN_VXFORM(vslh, 2, 5);
        !          6365: GEN_VXFORM(vslw, 2, 6);
        !          6366: GEN_VXFORM(vsrb, 2, 8);
        !          6367: GEN_VXFORM(vsrh, 2, 9);
        !          6368: GEN_VXFORM(vsrw, 2, 10);
        !          6369: GEN_VXFORM(vsrab, 2, 12);
        !          6370: GEN_VXFORM(vsrah, 2, 13);
        !          6371: GEN_VXFORM(vsraw, 2, 14);
        !          6372: GEN_VXFORM(vslo, 6, 16);
        !          6373: GEN_VXFORM(vsro, 6, 17);
        !          6374: GEN_VXFORM(vaddcuw, 0, 6);
        !          6375: GEN_VXFORM(vsubcuw, 0, 22);
        !          6376: GEN_VXFORM(vaddubs, 0, 8);
        !          6377: GEN_VXFORM(vadduhs, 0, 9);
        !          6378: GEN_VXFORM(vadduws, 0, 10);
        !          6379: GEN_VXFORM(vaddsbs, 0, 12);
        !          6380: GEN_VXFORM(vaddshs, 0, 13);
        !          6381: GEN_VXFORM(vaddsws, 0, 14);
        !          6382: GEN_VXFORM(vsububs, 0, 24);
        !          6383: GEN_VXFORM(vsubuhs, 0, 25);
        !          6384: GEN_VXFORM(vsubuws, 0, 26);
        !          6385: GEN_VXFORM(vsubsbs, 0, 28);
        !          6386: GEN_VXFORM(vsubshs, 0, 29);
        !          6387: GEN_VXFORM(vsubsws, 0, 30);
        !          6388: GEN_VXFORM(vrlb, 2, 0);
        !          6389: GEN_VXFORM(vrlh, 2, 1);
        !          6390: GEN_VXFORM(vrlw, 2, 2);
        !          6391: GEN_VXFORM(vsl, 2, 7);
        !          6392: GEN_VXFORM(vsr, 2, 11);
        !          6393: GEN_VXFORM(vpkuhum, 7, 0);
        !          6394: GEN_VXFORM(vpkuwum, 7, 1);
        !          6395: GEN_VXFORM(vpkuhus, 7, 2);
        !          6396: GEN_VXFORM(vpkuwus, 7, 3);
        !          6397: GEN_VXFORM(vpkshus, 7, 4);
        !          6398: GEN_VXFORM(vpkswus, 7, 5);
        !          6399: GEN_VXFORM(vpkshss, 7, 6);
        !          6400: GEN_VXFORM(vpkswss, 7, 7);
        !          6401: GEN_VXFORM(vpkpx, 7, 12);
        !          6402: GEN_VXFORM(vsum4ubs, 4, 24);
        !          6403: GEN_VXFORM(vsum4sbs, 4, 28);
        !          6404: GEN_VXFORM(vsum4shs, 4, 25);
        !          6405: GEN_VXFORM(vsum2sws, 4, 26);
        !          6406: GEN_VXFORM(vsumsws, 4, 30);
        !          6407: GEN_VXFORM(vaddfp, 5, 0);
        !          6408: GEN_VXFORM(vsubfp, 5, 1);
        !          6409: GEN_VXFORM(vmaxfp, 5, 16);
        !          6410: GEN_VXFORM(vminfp, 5, 17);
        !          6411: 
        !          6412: #define GEN_VXRFORM1(opname, name, str, opc2, opc3)                     \
        !          6413:     GEN_HANDLER2(name, str, 0x4, opc2, opc3, 0x00000000, PPC_ALTIVEC)   \
        !          6414:     {                                                                   \
        !          6415:         TCGv_ptr ra, rb, rd;                                            \
        !          6416:         if (unlikely(!ctx->altivec_enabled)) {                          \
        !          6417:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
        !          6418:             return;                                                     \
        !          6419:         }                                                               \
        !          6420:         ra = gen_avr_ptr(rA(ctx->opcode));                              \
        !          6421:         rb = gen_avr_ptr(rB(ctx->opcode));                              \
        !          6422:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
        !          6423:         gen_helper_##opname (rd, ra, rb);                               \
        !          6424:         tcg_temp_free_ptr(ra);                                          \
        !          6425:         tcg_temp_free_ptr(rb);                                          \
        !          6426:         tcg_temp_free_ptr(rd);                                          \
        !          6427:     }
        !          6428: 
        !          6429: #define GEN_VXRFORM(name, opc2, opc3)                                \
        !          6430:     GEN_VXRFORM1(name, name, #name, opc2, opc3)                      \
        !          6431:     GEN_VXRFORM1(name##_dot, name##_, #name ".", opc2, (opc3 | (0x1 << 4)))
        !          6432: 
        !          6433: GEN_VXRFORM(vcmpequb, 3, 0)
        !          6434: GEN_VXRFORM(vcmpequh, 3, 1)
        !          6435: GEN_VXRFORM(vcmpequw, 3, 2)
        !          6436: GEN_VXRFORM(vcmpgtsb, 3, 12)
        !          6437: GEN_VXRFORM(vcmpgtsh, 3, 13)
        !          6438: GEN_VXRFORM(vcmpgtsw, 3, 14)
        !          6439: GEN_VXRFORM(vcmpgtub, 3, 8)
        !          6440: GEN_VXRFORM(vcmpgtuh, 3, 9)
        !          6441: GEN_VXRFORM(vcmpgtuw, 3, 10)
        !          6442: GEN_VXRFORM(vcmpeqfp, 3, 3)
        !          6443: GEN_VXRFORM(vcmpgefp, 3, 7)
        !          6444: GEN_VXRFORM(vcmpgtfp, 3, 11)
        !          6445: GEN_VXRFORM(vcmpbfp, 3, 15)
        !          6446: 
        !          6447: #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
        !          6448:     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)        \
        !          6449:     {                                                                   \
        !          6450:         TCGv_ptr rd;                                                    \
        !          6451:         TCGv_i32 simm;                                                  \
        !          6452:         if (unlikely(!ctx->altivec_enabled)) {                          \
        !          6453:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
        !          6454:             return;                                                     \
        !          6455:         }                                                               \
        !          6456:         simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
        !          6457:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
        !          6458:         gen_helper_##name (rd, simm);                                   \
        !          6459:         tcg_temp_free_i32(simm);                                        \
        !          6460:         tcg_temp_free_ptr(rd);                                          \
        !          6461:     }
        !          6462: 
        !          6463: GEN_VXFORM_SIMM(vspltisb, 6, 12);
        !          6464: GEN_VXFORM_SIMM(vspltish, 6, 13);
        !          6465: GEN_VXFORM_SIMM(vspltisw, 6, 14);
        !          6466: 
        !          6467: #define GEN_VXFORM_NOA(name, opc2, opc3)                                \
        !          6468:     GEN_HANDLER(name, 0x04, opc2, opc3, 0x001f0000, PPC_ALTIVEC)        \
        !          6469:     {                                                                   \
        !          6470:         TCGv_ptr rb, rd;                                                \
        !          6471:         if (unlikely(!ctx->altivec_enabled)) {                          \
        !          6472:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
        !          6473:             return;                                                     \
        !          6474:         }                                                               \
        !          6475:         rb = gen_avr_ptr(rB(ctx->opcode));                              \
        !          6476:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
        !          6477:         gen_helper_##name (rd, rb);                                     \
        !          6478:         tcg_temp_free_ptr(rb);                                          \
        !          6479:         tcg_temp_free_ptr(rd);                                         \
        !          6480:     }
        !          6481: 
        !          6482: GEN_VXFORM_NOA(vupkhsb, 7, 8);
        !          6483: GEN_VXFORM_NOA(vupkhsh, 7, 9);
        !          6484: GEN_VXFORM_NOA(vupklsb, 7, 10);
        !          6485: GEN_VXFORM_NOA(vupklsh, 7, 11);
        !          6486: GEN_VXFORM_NOA(vupkhpx, 7, 13);
        !          6487: GEN_VXFORM_NOA(vupklpx, 7, 15);
        !          6488: GEN_VXFORM_NOA(vrefp, 5, 4);
        !          6489: GEN_VXFORM_NOA(vrsqrtefp, 5, 5);
        !          6490: GEN_VXFORM_NOA(vlogefp, 5, 7);
        !          6491: GEN_VXFORM_NOA(vrfim, 5, 8);
        !          6492: GEN_VXFORM_NOA(vrfin, 5, 9);
        !          6493: GEN_VXFORM_NOA(vrfip, 5, 10);
        !          6494: GEN_VXFORM_NOA(vrfiz, 5, 11);
        !          6495: 
        !          6496: #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
        !          6497:     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)        \
        !          6498:     {                                                                   \
        !          6499:         TCGv_ptr rd;                                                    \
        !          6500:         TCGv_i32 simm;                                                  \
        !          6501:         if (unlikely(!ctx->altivec_enabled)) {                          \
        !          6502:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
        !          6503:             return;                                                     \
        !          6504:         }                                                               \
        !          6505:         simm = tcg_const_i32(SIMM5(ctx->opcode));                       \
        !          6506:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
        !          6507:         gen_helper_##name (rd, simm);                                   \
        !          6508:         tcg_temp_free_i32(simm);                                        \
        !          6509:         tcg_temp_free_ptr(rd);                                          \
        !          6510:     }
        !          6511: 
        !          6512: #define GEN_VXFORM_UIMM(name, opc2, opc3)                               \
        !          6513:     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)        \
        !          6514:     {                                                                   \
        !          6515:         TCGv_ptr rb, rd;                                                \
        !          6516:         TCGv_i32 uimm;                                                  \
        !          6517:         if (unlikely(!ctx->altivec_enabled)) {                          \
        !          6518:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
        !          6519:             return;                                                     \
        !          6520:         }                                                               \
        !          6521:         uimm = tcg_const_i32(UIMM5(ctx->opcode));                       \
        !          6522:         rb = gen_avr_ptr(rB(ctx->opcode));                              \
        !          6523:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
        !          6524:         gen_helper_##name (rd, rb, uimm);                               \
        !          6525:         tcg_temp_free_i32(uimm);                                        \
        !          6526:         tcg_temp_free_ptr(rb);                                          \
        !          6527:         tcg_temp_free_ptr(rd);                                          \
        !          6528:     }
        !          6529: 
        !          6530: GEN_VXFORM_UIMM(vspltb, 6, 8);
        !          6531: GEN_VXFORM_UIMM(vsplth, 6, 9);
        !          6532: GEN_VXFORM_UIMM(vspltw, 6, 10);
        !          6533: GEN_VXFORM_UIMM(vcfux, 5, 12);
        !          6534: GEN_VXFORM_UIMM(vcfsx, 5, 13);
        !          6535: GEN_VXFORM_UIMM(vctuxs, 5, 14);
        !          6536: GEN_VXFORM_UIMM(vctsxs, 5, 15);
        !          6537: 
        !          6538: GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC)
        !          6539: {
        !          6540:     TCGv_ptr ra, rb, rd;
        !          6541:     TCGv_i32 sh;
        !          6542:     if (unlikely(!ctx->altivec_enabled)) {
        !          6543:         gen_exception(ctx, POWERPC_EXCP_VPU);
        !          6544:         return;
        !          6545:     }
        !          6546:     ra = gen_avr_ptr(rA(ctx->opcode));
        !          6547:     rb = gen_avr_ptr(rB(ctx->opcode));
        !          6548:     rd = gen_avr_ptr(rD(ctx->opcode));
        !          6549:     sh = tcg_const_i32(VSH(ctx->opcode));
        !          6550:     gen_helper_vsldoi (rd, ra, rb, sh);
        !          6551:     tcg_temp_free_ptr(ra);
        !          6552:     tcg_temp_free_ptr(rb);
        !          6553:     tcg_temp_free_ptr(rd);
        !          6554:     tcg_temp_free_i32(sh);
        !          6555: }
        !          6556: 
        !          6557: #define GEN_VAFORM_PAIRED(name0, name1, opc2)                           \
        !          6558:     GEN_HANDLER(name0##_##name1, 0x04, opc2, 0xFF, 0x00000000, PPC_ALTIVEC) \
        !          6559:     {                                                                   \
        !          6560:         TCGv_ptr ra, rb, rc, rd;                                        \
        !          6561:         if (unlikely(!ctx->altivec_enabled)) {                          \
        !          6562:             gen_exception(ctx, POWERPC_EXCP_VPU);                       \
        !          6563:             return;                                                     \
        !          6564:         }                                                               \
        !          6565:         ra = gen_avr_ptr(rA(ctx->opcode));                              \
        !          6566:         rb = gen_avr_ptr(rB(ctx->opcode));                              \
        !          6567:         rc = gen_avr_ptr(rC(ctx->opcode));                              \
        !          6568:         rd = gen_avr_ptr(rD(ctx->opcode));                              \
        !          6569:         if (Rc(ctx->opcode)) {                                          \
        !          6570:             gen_helper_##name1 (rd, ra, rb, rc);                        \
        !          6571:         } else {                                                        \
        !          6572:             gen_helper_##name0 (rd, ra, rb, rc);                        \
        !          6573:         }                                                               \
        !          6574:         tcg_temp_free_ptr(ra);                                          \
        !          6575:         tcg_temp_free_ptr(rb);                                          \
        !          6576:         tcg_temp_free_ptr(rc);                                          \
        !          6577:         tcg_temp_free_ptr(rd);                                          \
        !          6578:     }
        !          6579: 
        !          6580: GEN_VAFORM_PAIRED(vmhaddshs, vmhraddshs, 16)
        !          6581: 
        !          6582: GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC)
        !          6583: {
        !          6584:     TCGv_ptr ra, rb, rc, rd;
        !          6585:     if (unlikely(!ctx->altivec_enabled)) {
        !          6586:         gen_exception(ctx, POWERPC_EXCP_VPU);
        !          6587:         return;
        !          6588:     }
        !          6589:     ra = gen_avr_ptr(rA(ctx->opcode));
        !          6590:     rb = gen_avr_ptr(rB(ctx->opcode));
        !          6591:     rc = gen_avr_ptr(rC(ctx->opcode));
        !          6592:     rd = gen_avr_ptr(rD(ctx->opcode));
        !          6593:     gen_helper_vmladduhm(rd, ra, rb, rc);
        !          6594:     tcg_temp_free_ptr(ra);
        !          6595:     tcg_temp_free_ptr(rb);
        !          6596:     tcg_temp_free_ptr(rc);
        !          6597:     tcg_temp_free_ptr(rd);
        !          6598: }
        !          6599: 
        !          6600: GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18)
        !          6601: GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19)
        !          6602: GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20)
        !          6603: GEN_VAFORM_PAIRED(vsel, vperm, 21)
        !          6604: GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23)
1.1.1.5   root     6605: 
                   6606: /***                           SPE extension                               ***/
                   6607: /* Register moves */
                   6608: 
1.1.1.6 ! root     6609: static always_inline void gen_load_gpr64(TCGv_i64 t, int reg) {
        !          6610: #if defined(TARGET_PPC64)
        !          6611:     tcg_gen_mov_i64(t, cpu_gpr[reg]);
        !          6612: #else
        !          6613:     tcg_gen_concat_i32_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
1.1.1.5   root     6614: #endif
1.1.1.6 ! root     6615: }
1.1.1.5   root     6616: 
1.1.1.6 ! root     6617: static always_inline void gen_store_gpr64(int reg, TCGv_i64 t) {
        !          6618: #if defined(TARGET_PPC64)
        !          6619:     tcg_gen_mov_i64(cpu_gpr[reg], t);
        !          6620: #else
        !          6621:     TCGv_i64 tmp = tcg_temp_new_i64();
        !          6622:     tcg_gen_trunc_i64_i32(cpu_gpr[reg], t);
        !          6623:     tcg_gen_shri_i64(tmp, t, 32);
        !          6624:     tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp);
        !          6625:     tcg_temp_free_i64(tmp);
1.1.1.5   root     6626: #endif
1.1.1.6 ! root     6627: }
1.1.1.5   root     6628: 
                   6629: #define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
                   6630: GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
                   6631: {                                                                             \
                   6632:     if (Rc(ctx->opcode))                                                      \
                   6633:         gen_##name1(ctx);                                                     \
                   6634:     else                                                                      \
                   6635:         gen_##name0(ctx);                                                     \
                   6636: }
                   6637: 
                   6638: /* Handler for undefined SPE opcodes */
                   6639: static always_inline void gen_speundef (DisasContext *ctx)
1.1       root     6640: {
1.1.1.6 ! root     6641:     gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
1.1.1.5   root     6642: }
                   6643: 
1.1.1.6 ! root     6644: /* SPE logic */
        !          6645: #if defined(TARGET_PPC64)
        !          6646: #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
        !          6647: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          6648: {                                                                             \
        !          6649:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          6650:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
        !          6651:         return;                                                               \
        !          6652:     }                                                                         \
        !          6653:     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
        !          6654:            cpu_gpr[rB(ctx->opcode)]);                                         \
        !          6655: }
        !          6656: #else
        !          6657: #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
        !          6658: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          6659: {                                                                             \
        !          6660:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          6661:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
        !          6662:         return;                                                               \
        !          6663:     }                                                                         \
        !          6664:     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
        !          6665:            cpu_gpr[rB(ctx->opcode)]);                                         \
        !          6666:     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
        !          6667:            cpu_gprh[rB(ctx->opcode)]);                                        \
1.1.1.5   root     6668: }
1.1.1.6 ! root     6669: #endif
1.1.1.5   root     6670: 
1.1.1.6 ! root     6671: GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl);
        !          6672: GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl);
        !          6673: GEN_SPEOP_LOGIC2(evxor, tcg_gen_xor_tl);
        !          6674: GEN_SPEOP_LOGIC2(evor, tcg_gen_or_tl);
        !          6675: GEN_SPEOP_LOGIC2(evnor, tcg_gen_nor_tl);
        !          6676: GEN_SPEOP_LOGIC2(eveqv, tcg_gen_eqv_tl);
        !          6677: GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl);
        !          6678: GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
1.1.1.5   root     6679: 
1.1.1.6 ! root     6680: /* SPE logic immediate */
        !          6681: #if defined(TARGET_PPC64)
        !          6682: #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
        !          6683: static always_inline void gen_##name (DisasContext *ctx)                      \
1.1.1.5   root     6684: {                                                                             \
                   6685:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.6 ! root     6686:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
1.1.1.5   root     6687:         return;                                                               \
                   6688:     }                                                                         \
1.1.1.6 ! root     6689:     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
        !          6690:     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
        !          6691:     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
        !          6692:     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
        !          6693:     tcg_opi(t0, t0, rB(ctx->opcode));                                         \
        !          6694:     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
        !          6695:     tcg_gen_trunc_i64_i32(t1, t2);                                            \
        !          6696:     tcg_temp_free_i64(t2);                                                    \
        !          6697:     tcg_opi(t1, t1, rB(ctx->opcode));                                         \
        !          6698:     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
        !          6699:     tcg_temp_free_i32(t0);                                                    \
        !          6700:     tcg_temp_free_i32(t1);                                                    \
1.1.1.5   root     6701: }
1.1.1.6 ! root     6702: #else
        !          6703: #define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
        !          6704: static always_inline void gen_##name (DisasContext *ctx)                      \
1.1.1.5   root     6705: {                                                                             \
                   6706:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.6 ! root     6707:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
1.1.1.5   root     6708:         return;                                                               \
                   6709:     }                                                                         \
1.1.1.6 ! root     6710:     tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],               \
        !          6711:             rB(ctx->opcode));                                                 \
        !          6712:     tcg_opi(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],             \
        !          6713:             rB(ctx->opcode));                                                 \
1.1.1.5   root     6714: }
1.1.1.6 ! root     6715: #endif
        !          6716: GEN_SPEOP_TCG_LOGIC_IMM2(evslwi, tcg_gen_shli_i32);
        !          6717: GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu, tcg_gen_shri_i32);
        !          6718: GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis, tcg_gen_sari_i32);
        !          6719: GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32);
1.1.1.5   root     6720: 
1.1.1.6 ! root     6721: /* SPE arithmetic */
        !          6722: #if defined(TARGET_PPC64)
        !          6723: #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
        !          6724: static always_inline void gen_##name (DisasContext *ctx)                      \
1.1.1.5   root     6725: {                                                                             \
                   6726:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.6 ! root     6727:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
1.1.1.5   root     6728:         return;                                                               \
                   6729:     }                                                                         \
1.1.1.6 ! root     6730:     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
        !          6731:     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
        !          6732:     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
        !          6733:     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
        !          6734:     tcg_op(t0, t0);                                                           \
        !          6735:     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
        !          6736:     tcg_gen_trunc_i64_i32(t1, t2);                                            \
        !          6737:     tcg_temp_free_i64(t2);                                                    \
        !          6738:     tcg_op(t1, t1);                                                           \
        !          6739:     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
        !          6740:     tcg_temp_free_i32(t0);                                                    \
        !          6741:     tcg_temp_free_i32(t1);                                                    \
1.1.1.5   root     6742: }
1.1.1.6 ! root     6743: #else
        !          6744: #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
        !          6745: static always_inline void gen_##name (DisasContext *ctx)                      \
1.1.1.5   root     6746: {                                                                             \
                   6747:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.6 ! root     6748:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
1.1.1.5   root     6749:         return;                                                               \
                   6750:     }                                                                         \
1.1.1.6 ! root     6751:     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);               \
        !          6752:     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);             \
1.1.1.5   root     6753: }
1.1.1.6 ! root     6754: #endif
1.1.1.5   root     6755: 
1.1.1.6 ! root     6756: static always_inline void gen_op_evabs (TCGv_i32 ret, TCGv_i32 arg1)
        !          6757: {
        !          6758:     int l1 = gen_new_label();
        !          6759:     int l2 = gen_new_label();
1.1.1.5   root     6760: 
1.1.1.6 ! root     6761:     tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
        !          6762:     tcg_gen_neg_i32(ret, arg1);
        !          6763:     tcg_gen_br(l2);
        !          6764:     gen_set_label(l1);
        !          6765:     tcg_gen_mov_i32(ret, arg1);
        !          6766:     gen_set_label(l2);
        !          6767: }
        !          6768: GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
        !          6769: GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
        !          6770: GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
        !          6771: GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
        !          6772: static always_inline void gen_op_evrndw (TCGv_i32 ret, TCGv_i32 arg1)
        !          6773: {
        !          6774:     tcg_gen_addi_i32(ret, arg1, 0x8000);
        !          6775:     tcg_gen_ext16u_i32(ret, ret);
        !          6776: }
        !          6777: GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw);
        !          6778: GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32);
        !          6779: GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
1.1.1.5   root     6780: 
1.1.1.6 ! root     6781: #if defined(TARGET_PPC64)
        !          6782: #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
1.1.1.5   root     6783: static always_inline void gen_##name (DisasContext *ctx)                      \
                   6784: {                                                                             \
                   6785:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.6 ! root     6786:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
1.1.1.5   root     6787:         return;                                                               \
                   6788:     }                                                                         \
1.1.1.6 ! root     6789:     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
        !          6790:     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
        !          6791:     TCGv_i32 t2 = tcg_temp_local_new_i32();                                   \
        !          6792:     TCGv_i64 t3 = tcg_temp_local_new_i64();                                   \
        !          6793:     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
        !          6794:     tcg_gen_trunc_i64_i32(t2, cpu_gpr[rB(ctx->opcode)]);                      \
        !          6795:     tcg_op(t0, t0, t2);                                                       \
        !          6796:     tcg_gen_shri_i64(t3, cpu_gpr[rA(ctx->opcode)], 32);                       \
        !          6797:     tcg_gen_trunc_i64_i32(t1, t3);                                            \
        !          6798:     tcg_gen_shri_i64(t3, cpu_gpr[rB(ctx->opcode)], 32);                       \
        !          6799:     tcg_gen_trunc_i64_i32(t2, t3);                                            \
        !          6800:     tcg_temp_free_i64(t3);                                                    \
        !          6801:     tcg_op(t1, t1, t2);                                                       \
        !          6802:     tcg_temp_free_i32(t2);                                                    \
        !          6803:     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
        !          6804:     tcg_temp_free_i32(t0);                                                    \
        !          6805:     tcg_temp_free_i32(t1);                                                    \
1.1.1.5   root     6806: }
1.1.1.6 ! root     6807: #else
        !          6808: #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
1.1.1.5   root     6809: static always_inline void gen_##name (DisasContext *ctx)                      \
                   6810: {                                                                             \
                   6811:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.6 ! root     6812:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
1.1.1.5   root     6813:         return;                                                               \
                   6814:     }                                                                         \
1.1.1.6 ! root     6815:     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
        !          6816:            cpu_gpr[rB(ctx->opcode)]);                                         \
        !          6817:     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
        !          6818:            cpu_gprh[rB(ctx->opcode)]);                                        \
        !          6819: }
        !          6820: #endif
        !          6821: 
        !          6822: static always_inline void gen_op_evsrwu (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
        !          6823: {
        !          6824:     TCGv_i32 t0;
        !          6825:     int l1, l2;
        !          6826: 
        !          6827:     l1 = gen_new_label();
        !          6828:     l2 = gen_new_label();
        !          6829:     t0 = tcg_temp_local_new_i32();
        !          6830:     /* No error here: 6 bits are used */
        !          6831:     tcg_gen_andi_i32(t0, arg2, 0x3F);
        !          6832:     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
        !          6833:     tcg_gen_shr_i32(ret, arg1, t0);
        !          6834:     tcg_gen_br(l2);
        !          6835:     gen_set_label(l1);
        !          6836:     tcg_gen_movi_i32(ret, 0);
        !          6837:     tcg_gen_br(l2);
        !          6838:     tcg_temp_free_i32(t0);
        !          6839: }
        !          6840: GEN_SPEOP_ARITH2(evsrwu, gen_op_evsrwu);
        !          6841: static always_inline void gen_op_evsrws (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
        !          6842: {
        !          6843:     TCGv_i32 t0;
        !          6844:     int l1, l2;
        !          6845: 
        !          6846:     l1 = gen_new_label();
        !          6847:     l2 = gen_new_label();
        !          6848:     t0 = tcg_temp_local_new_i32();
        !          6849:     /* No error here: 6 bits are used */
        !          6850:     tcg_gen_andi_i32(t0, arg2, 0x3F);
        !          6851:     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
        !          6852:     tcg_gen_sar_i32(ret, arg1, t0);
        !          6853:     tcg_gen_br(l2);
        !          6854:     gen_set_label(l1);
        !          6855:     tcg_gen_movi_i32(ret, 0);
        !          6856:     tcg_gen_br(l2);
        !          6857:     tcg_temp_free_i32(t0);
        !          6858: }
        !          6859: GEN_SPEOP_ARITH2(evsrws, gen_op_evsrws);
        !          6860: static always_inline void gen_op_evslw (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
        !          6861: {
        !          6862:     TCGv_i32 t0;
        !          6863:     int l1, l2;
        !          6864: 
        !          6865:     l1 = gen_new_label();
        !          6866:     l2 = gen_new_label();
        !          6867:     t0 = tcg_temp_local_new_i32();
        !          6868:     /* No error here: 6 bits are used */
        !          6869:     tcg_gen_andi_i32(t0, arg2, 0x3F);
        !          6870:     tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
        !          6871:     tcg_gen_shl_i32(ret, arg1, t0);
        !          6872:     tcg_gen_br(l2);
        !          6873:     gen_set_label(l1);
        !          6874:     tcg_gen_movi_i32(ret, 0);
        !          6875:     tcg_gen_br(l2);
        !          6876:     tcg_temp_free_i32(t0);
        !          6877: }
        !          6878: GEN_SPEOP_ARITH2(evslw, gen_op_evslw);
        !          6879: static always_inline void gen_op_evrlw (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
        !          6880: {
        !          6881:     TCGv_i32 t0 = tcg_temp_new_i32();
        !          6882:     tcg_gen_andi_i32(t0, arg2, 0x1F);
        !          6883:     tcg_gen_rotl_i32(ret, arg1, t0);
        !          6884:     tcg_temp_free_i32(t0);
        !          6885: }
        !          6886: GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
        !          6887: static always_inline void gen_evmergehi (DisasContext *ctx)
        !          6888: {
        !          6889:     if (unlikely(!ctx->spe_enabled)) {
        !          6890:         gen_exception(ctx, POWERPC_EXCP_APU);
        !          6891:         return;
        !          6892:     }
        !          6893: #if defined(TARGET_PPC64)
        !          6894:     TCGv t0 = tcg_temp_new();
        !          6895:     TCGv t1 = tcg_temp_new();
        !          6896:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
        !          6897:     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
        !          6898:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
        !          6899:     tcg_temp_free(t0);
        !          6900:     tcg_temp_free(t1);
        !          6901: #else
        !          6902:     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
        !          6903:     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
        !          6904: #endif
        !          6905: }
        !          6906: GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32);
        !          6907: static always_inline void gen_op_evsubf (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
        !          6908: {
        !          6909:     tcg_gen_sub_i32(ret, arg2, arg1);
1.1.1.5   root     6910: }
1.1.1.6 ! root     6911: GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
1.1.1.5   root     6912: 
1.1.1.6 ! root     6913: /* SPE arithmetic immediate */
        !          6914: #if defined(TARGET_PPC64)
        !          6915: #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
1.1.1.5   root     6916: static always_inline void gen_##name (DisasContext *ctx)                      \
                   6917: {                                                                             \
                   6918:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.6 ! root     6919:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
1.1.1.5   root     6920:         return;                                                               \
                   6921:     }                                                                         \
1.1.1.6 ! root     6922:     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
        !          6923:     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
        !          6924:     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
        !          6925:     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rB(ctx->opcode)]);                      \
        !          6926:     tcg_op(t0, t0, rA(ctx->opcode));                                          \
        !          6927:     tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
        !          6928:     tcg_gen_trunc_i64_i32(t1, t2);                                            \
        !          6929:     tcg_temp_free_i64(t2);                                                    \
        !          6930:     tcg_op(t1, t1, rA(ctx->opcode));                                          \
        !          6931:     tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
        !          6932:     tcg_temp_free_i32(t0);                                                    \
        !          6933:     tcg_temp_free_i32(t1);                                                    \
1.1       root     6934: }
1.1.1.6 ! root     6935: #else
        !          6936: #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
        !          6937: static always_inline void gen_##name (DisasContext *ctx)                      \
1.1.1.5   root     6938: {                                                                             \
                   6939:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.6 ! root     6940:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
1.1.1.5   root     6941:         return;                                                               \
                   6942:     }                                                                         \
1.1.1.6 ! root     6943:     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],                \
        !          6944:            rA(ctx->opcode));                                                  \
        !          6945:     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)],              \
        !          6946:            rA(ctx->opcode));                                                  \
1.1.1.5   root     6947: }
1.1.1.6 ! root     6948: #endif
        !          6949: GEN_SPEOP_ARITH_IMM2(evaddiw, tcg_gen_addi_i32);
        !          6950: GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32);
1.1.1.5   root     6951: 
1.1.1.6 ! root     6952: /* SPE comparison */
        !          6953: #if defined(TARGET_PPC64)
        !          6954: #define GEN_SPEOP_COMP(name, tcg_cond)                                        \
        !          6955: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          6956: {                                                                             \
        !          6957:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          6958:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
        !          6959:         return;                                                               \
        !          6960:     }                                                                         \
        !          6961:     int l1 = gen_new_label();                                                 \
        !          6962:     int l2 = gen_new_label();                                                 \
        !          6963:     int l3 = gen_new_label();                                                 \
        !          6964:     int l4 = gen_new_label();                                                 \
        !          6965:     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
        !          6966:     TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
        !          6967:     TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
        !          6968:     tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
        !          6969:     tcg_gen_trunc_i64_i32(t1, cpu_gpr[rB(ctx->opcode)]);                      \
        !          6970:     tcg_gen_brcond_i32(tcg_cond, t0, t1, l1);                                 \
        !          6971:     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0);                          \
        !          6972:     tcg_gen_br(l2);                                                           \
        !          6973:     gen_set_label(l1);                                                        \
        !          6974:     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
        !          6975:                      CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
        !          6976:     gen_set_label(l2);                                                        \
        !          6977:     tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
        !          6978:     tcg_gen_trunc_i64_i32(t0, t2);                                            \
        !          6979:     tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
        !          6980:     tcg_gen_trunc_i64_i32(t1, t2);                                            \
        !          6981:     tcg_temp_free_i64(t2);                                                    \
        !          6982:     tcg_gen_brcond_i32(tcg_cond, t0, t1, l3);                                 \
        !          6983:     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
        !          6984:                      ~(CRF_CH | CRF_CH_AND_CL));                              \
        !          6985:     tcg_gen_br(l4);                                                           \
        !          6986:     gen_set_label(l3);                                                        \
        !          6987:     tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
        !          6988:                     CRF_CH | CRF_CH_OR_CL);                                   \
        !          6989:     gen_set_label(l4);                                                        \
        !          6990:     tcg_temp_free_i32(t0);                                                    \
        !          6991:     tcg_temp_free_i32(t1);                                                    \
        !          6992: }
        !          6993: #else
        !          6994: #define GEN_SPEOP_COMP(name, tcg_cond)                                        \
        !          6995: static always_inline void gen_##name (DisasContext *ctx)                      \
1.1.1.5   root     6996: {                                                                             \
                   6997:     if (unlikely(!ctx->spe_enabled)) {                                        \
1.1.1.6 ! root     6998:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
1.1.1.5   root     6999:         return;                                                               \
                   7000:     }                                                                         \
1.1.1.6 ! root     7001:     int l1 = gen_new_label();                                                 \
        !          7002:     int l2 = gen_new_label();                                                 \
        !          7003:     int l3 = gen_new_label();                                                 \
        !          7004:     int l4 = gen_new_label();                                                 \
        !          7005:                                                                               \
        !          7006:     tcg_gen_brcond_i32(tcg_cond, cpu_gpr[rA(ctx->opcode)],                    \
        !          7007:                        cpu_gpr[rB(ctx->opcode)], l1);                         \
        !          7008:     tcg_gen_movi_tl(cpu_crf[crfD(ctx->opcode)], 0);                           \
        !          7009:     tcg_gen_br(l2);                                                           \
        !          7010:     gen_set_label(l1);                                                        \
        !          7011:     tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
        !          7012:                      CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
        !          7013:     gen_set_label(l2);                                                        \
        !          7014:     tcg_gen_brcond_i32(tcg_cond, cpu_gprh[rA(ctx->opcode)],                   \
        !          7015:                        cpu_gprh[rB(ctx->opcode)], l3);                        \
        !          7016:     tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
        !          7017:                      ~(CRF_CH | CRF_CH_AND_CL));                              \
        !          7018:     tcg_gen_br(l4);                                                           \
        !          7019:     gen_set_label(l3);                                                        \
        !          7020:     tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
        !          7021:                     CRF_CH | CRF_CH_OR_CL);                                   \
        !          7022:     gen_set_label(l4);                                                        \
        !          7023: }
        !          7024: #endif
        !          7025: GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU);
        !          7026: GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT);
        !          7027: GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU);
        !          7028: GEN_SPEOP_COMP(evcmplts, TCG_COND_LT);
        !          7029: GEN_SPEOP_COMP(evcmpeq, TCG_COND_EQ);
1.1.1.5   root     7030: 
1.1.1.6 ! root     7031: /* SPE misc */
        !          7032: static always_inline void gen_brinc (DisasContext *ctx)
        !          7033: {
        !          7034:     /* Note: brinc is usable even if SPE is disabled */
        !          7035:     gen_helper_brinc(cpu_gpr[rD(ctx->opcode)],
        !          7036:                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
        !          7037: }
        !          7038: static always_inline void gen_evmergelo (DisasContext *ctx)
        !          7039: {
        !          7040:     if (unlikely(!ctx->spe_enabled)) {
        !          7041:         gen_exception(ctx, POWERPC_EXCP_APU);
        !          7042:         return;
        !          7043:     }
        !          7044: #if defined(TARGET_PPC64)
        !          7045:     TCGv t0 = tcg_temp_new();
        !          7046:     TCGv t1 = tcg_temp_new();
        !          7047:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL);
        !          7048:     tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
        !          7049:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
        !          7050:     tcg_temp_free(t0);
        !          7051:     tcg_temp_free(t1);
        !          7052: #else
        !          7053:     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
        !          7054:     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
        !          7055: #endif
        !          7056: }
        !          7057: static always_inline void gen_evmergehilo (DisasContext *ctx)
        !          7058: {
        !          7059:     if (unlikely(!ctx->spe_enabled)) {
        !          7060:         gen_exception(ctx, POWERPC_EXCP_APU);
        !          7061:         return;
        !          7062:     }
        !          7063: #if defined(TARGET_PPC64)
        !          7064:     TCGv t0 = tcg_temp_new();
        !          7065:     TCGv t1 = tcg_temp_new();
        !          7066:     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL);
        !          7067:     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
        !          7068:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
        !          7069:     tcg_temp_free(t0);
        !          7070:     tcg_temp_free(t1);
        !          7071: #else
        !          7072:     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
        !          7073:     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
        !          7074: #endif
        !          7075: }
        !          7076: static always_inline void gen_evmergelohi (DisasContext *ctx)
        !          7077: {
        !          7078:     if (unlikely(!ctx->spe_enabled)) {
        !          7079:         gen_exception(ctx, POWERPC_EXCP_APU);
        !          7080:         return;
        !          7081:     }
        !          7082: #if defined(TARGET_PPC64)
        !          7083:     TCGv t0 = tcg_temp_new();
        !          7084:     TCGv t1 = tcg_temp_new();
        !          7085:     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
        !          7086:     tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
        !          7087:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
        !          7088:     tcg_temp_free(t0);
        !          7089:     tcg_temp_free(t1);
        !          7090: #else
        !          7091:     tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
        !          7092:     tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
        !          7093: #endif
        !          7094: }
1.1.1.5   root     7095: static always_inline void gen_evsplati (DisasContext *ctx)
                   7096: {
1.1.1.6 ! root     7097:     uint64_t imm = ((int32_t)(rA(ctx->opcode) << 11)) >> 27;
1.1.1.5   root     7098: 
1.1.1.6 ! root     7099: #if defined(TARGET_PPC64)
        !          7100:     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
        !          7101: #else
        !          7102:     tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
        !          7103:     tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
        !          7104: #endif
1.1.1.5   root     7105: }
                   7106: static always_inline void gen_evsplatfi (DisasContext *ctx)
                   7107: {
1.1.1.6 ! root     7108:     uint64_t imm = rA(ctx->opcode) << 11;
1.1.1.5   root     7109: 
1.1.1.6 ! root     7110: #if defined(TARGET_PPC64)
        !          7111:     tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
        !          7112: #else
        !          7113:     tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
        !          7114:     tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
        !          7115: #endif
1.1.1.5   root     7116: }
                   7117: 
1.1.1.6 ! root     7118: static always_inline void gen_evsel (DisasContext *ctx)
        !          7119: {
        !          7120:     int l1 = gen_new_label();
        !          7121:     int l2 = gen_new_label();
        !          7122:     int l3 = gen_new_label();
        !          7123:     int l4 = gen_new_label();
        !          7124:     TCGv_i32 t0 = tcg_temp_local_new_i32();
        !          7125: #if defined(TARGET_PPC64)
        !          7126:     TCGv t1 = tcg_temp_local_new();
        !          7127:     TCGv t2 = tcg_temp_local_new();
        !          7128: #endif
        !          7129:     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);
        !          7130:     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
        !          7131: #if defined(TARGET_PPC64)
        !          7132:     tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF00000000ULL);
        !          7133: #else
        !          7134:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
        !          7135: #endif
        !          7136:     tcg_gen_br(l2);
        !          7137:     gen_set_label(l1);
        !          7138: #if defined(TARGET_PPC64)
        !          7139:     tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0xFFFFFFFF00000000ULL);
        !          7140: #else
        !          7141:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
        !          7142: #endif
        !          7143:     gen_set_label(l2);
        !          7144:     tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2);
        !          7145:     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3);
        !          7146: #if defined(TARGET_PPC64)
        !          7147:     tcg_gen_andi_tl(t2, cpu_gpr[rA(ctx->opcode)], 0x00000000FFFFFFFFULL);
        !          7148: #else
        !          7149:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
        !          7150: #endif
        !          7151:     tcg_gen_br(l4);
        !          7152:     gen_set_label(l3);
        !          7153: #if defined(TARGET_PPC64)
        !          7154:     tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFULL);
        !          7155: #else
        !          7156:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
        !          7157: #endif
        !          7158:     gen_set_label(l4);
        !          7159:     tcg_temp_free_i32(t0);
        !          7160: #if defined(TARGET_PPC64)
        !          7161:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t1, t2);
        !          7162:     tcg_temp_free(t1);
        !          7163:     tcg_temp_free(t2);
        !          7164: #endif
        !          7165: }
        !          7166: GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
        !          7167: {
        !          7168:     gen_evsel(ctx);
        !          7169: }
        !          7170: GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
        !          7171: {
        !          7172:     gen_evsel(ctx);
        !          7173: }
        !          7174: GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
        !          7175: {
        !          7176:     gen_evsel(ctx);
        !          7177: }
        !          7178: GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
        !          7179: {
        !          7180:     gen_evsel(ctx);
        !          7181: }
1.1.1.5   root     7182: 
                   7183: GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
                   7184: GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
                   7185: GEN_SPE(evsubfw,        speundef,      0x02, 0x08, 0x00000000, PPC_SPE); ////
                   7186: GEN_SPE(evsubifw,       speundef,      0x03, 0x08, 0x00000000, PPC_SPE);
                   7187: GEN_SPE(evabs,          evneg,         0x04, 0x08, 0x0000F800, PPC_SPE); ////
                   7188: GEN_SPE(evextsb,        evextsh,       0x05, 0x08, 0x0000F800, PPC_SPE); ////
                   7189: GEN_SPE(evrndw,         evcntlzw,      0x06, 0x08, 0x0000F800, PPC_SPE); ////
                   7190: GEN_SPE(evcntlsw,       brinc,         0x07, 0x08, 0x00000000, PPC_SPE); //
                   7191: GEN_SPE(speundef,       evand,         0x08, 0x08, 0x00000000, PPC_SPE); ////
                   7192: GEN_SPE(evandc,         speundef,      0x09, 0x08, 0x00000000, PPC_SPE); ////
                   7193: GEN_SPE(evxor,          evor,          0x0B, 0x08, 0x00000000, PPC_SPE); ////
                   7194: GEN_SPE(evnor,          eveqv,         0x0C, 0x08, 0x00000000, PPC_SPE); ////
                   7195: GEN_SPE(speundef,       evorc,         0x0D, 0x08, 0x00000000, PPC_SPE); ////
                   7196: GEN_SPE(evnand,         speundef,      0x0F, 0x08, 0x00000000, PPC_SPE); ////
                   7197: GEN_SPE(evsrwu,         evsrws,        0x10, 0x08, 0x00000000, PPC_SPE); ////
                   7198: GEN_SPE(evsrwiu,        evsrwis,       0x11, 0x08, 0x00000000, PPC_SPE);
                   7199: GEN_SPE(evslw,          speundef,      0x12, 0x08, 0x00000000, PPC_SPE); ////
                   7200: GEN_SPE(evslwi,         speundef,      0x13, 0x08, 0x00000000, PPC_SPE);
                   7201: GEN_SPE(evrlw,          evsplati,      0x14, 0x08, 0x00000000, PPC_SPE); //
                   7202: GEN_SPE(evrlwi,         evsplatfi,     0x15, 0x08, 0x00000000, PPC_SPE);
                   7203: GEN_SPE(evmergehi,      evmergelo,     0x16, 0x08, 0x00000000, PPC_SPE); ////
                   7204: GEN_SPE(evmergehilo,    evmergelohi,   0x17, 0x08, 0x00000000, PPC_SPE); ////
                   7205: GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
                   7206: GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
                   7207: GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
                   7208: 
1.1.1.6 ! root     7209: /* SPE load and stores */
        !          7210: static always_inline void gen_addr_spe_imm_index (DisasContext *ctx, TCGv EA, int sh)
1.1       root     7211: {
1.1.1.6 ! root     7212:     target_ulong uimm = rB(ctx->opcode);
        !          7213: 
        !          7214:     if (rA(ctx->opcode) == 0) {
        !          7215:         tcg_gen_movi_tl(EA, uimm << sh);
        !          7216:     } else {
        !          7217:         tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], uimm << sh);
        !          7218: #if defined(TARGET_PPC64)
        !          7219:         if (!ctx->sf_mode) {
        !          7220:             tcg_gen_ext32u_tl(EA, EA);
        !          7221:         }
        !          7222: #endif
1.1       root     7223:     }
1.1.1.5   root     7224: }
                   7225: 
1.1.1.6 ! root     7226: static always_inline void gen_op_evldd(DisasContext *ctx, TCGv addr)
1.1.1.5   root     7227: {
1.1.1.6 ! root     7228: #if defined(TARGET_PPC64)
        !          7229:     gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], addr);
        !          7230: #else
        !          7231:     TCGv_i64 t0 = tcg_temp_new_i64();
        !          7232:     gen_qemu_ld64(ctx, t0, addr);
        !          7233:     tcg_gen_trunc_i64_i32(cpu_gpr[rD(ctx->opcode)], t0);
        !          7234:     tcg_gen_shri_i64(t0, t0, 32);
        !          7235:     tcg_gen_trunc_i64_i32(cpu_gprh[rD(ctx->opcode)], t0);
        !          7236:     tcg_temp_free_i64(t0);
        !          7237: #endif
1.1.1.5   root     7238: }
1.1.1.6 ! root     7239: 
        !          7240: static always_inline void gen_op_evldw(DisasContext *ctx, TCGv addr)
1.1.1.5   root     7241: {
1.1.1.6 ! root     7242: #if defined(TARGET_PPC64)
        !          7243:     TCGv t0 = tcg_temp_new();
        !          7244:     gen_qemu_ld32u(ctx, t0, addr);
        !          7245:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
        !          7246:     gen_addr_add(ctx, addr, addr, 4);
        !          7247:     gen_qemu_ld32u(ctx, t0, addr);
        !          7248:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
        !          7249:     tcg_temp_free(t0);
        !          7250: #else
        !          7251:     gen_qemu_ld32u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
        !          7252:     gen_addr_add(ctx, addr, addr, 4);
        !          7253:     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
        !          7254: #endif
1.1.1.5   root     7255: }
1.1.1.6 ! root     7256: 
        !          7257: static always_inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
1.1.1.5   root     7258: {
1.1.1.6 ! root     7259:     TCGv t0 = tcg_temp_new();
        !          7260: #if defined(TARGET_PPC64)
        !          7261:     gen_qemu_ld16u(ctx, t0, addr);
        !          7262:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
        !          7263:     gen_addr_add(ctx, addr, addr, 2);
        !          7264:     gen_qemu_ld16u(ctx, t0, addr);
        !          7265:     tcg_gen_shli_tl(t0, t0, 32);
        !          7266:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
        !          7267:     gen_addr_add(ctx, addr, addr, 2);
        !          7268:     gen_qemu_ld16u(ctx, t0, addr);
        !          7269:     tcg_gen_shli_tl(t0, t0, 16);
        !          7270:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
        !          7271:     gen_addr_add(ctx, addr, addr, 2);
        !          7272:     gen_qemu_ld16u(ctx, t0, addr);
        !          7273:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
        !          7274: #else
        !          7275:     gen_qemu_ld16u(ctx, t0, addr);
        !          7276:     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
        !          7277:     gen_addr_add(ctx, addr, addr, 2);
        !          7278:     gen_qemu_ld16u(ctx, t0, addr);
        !          7279:     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
        !          7280:     gen_addr_add(ctx, addr, addr, 2);
        !          7281:     gen_qemu_ld16u(ctx, t0, addr);
        !          7282:     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
        !          7283:     gen_addr_add(ctx, addr, addr, 2);
        !          7284:     gen_qemu_ld16u(ctx, t0, addr);
        !          7285:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
        !          7286: #endif
        !          7287:     tcg_temp_free(t0);
1.1.1.5   root     7288: }
1.1.1.6 ! root     7289: 
        !          7290: static always_inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr)
1.1.1.5   root     7291: {
1.1.1.6 ! root     7292:     TCGv t0 = tcg_temp_new();
        !          7293:     gen_qemu_ld16u(ctx, t0, addr);
        !          7294: #if defined(TARGET_PPC64)
        !          7295:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
        !          7296:     tcg_gen_shli_tl(t0, t0, 16);
        !          7297:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
        !          7298: #else
        !          7299:     tcg_gen_shli_tl(t0, t0, 16);
        !          7300:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
        !          7301:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
        !          7302: #endif
        !          7303:     tcg_temp_free(t0);
1.1.1.5   root     7304: }
                   7305: 
1.1.1.6 ! root     7306: static always_inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr)
        !          7307: {
        !          7308:     TCGv t0 = tcg_temp_new();
        !          7309:     gen_qemu_ld16u(ctx, t0, addr);
1.1.1.5   root     7310: #if defined(TARGET_PPC64)
1.1.1.6 ! root     7311:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
        !          7312:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
        !          7313: #else
        !          7314:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
        !          7315:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
        !          7316: #endif
        !          7317:     tcg_temp_free(t0);
        !          7318: }
        !          7319: 
        !          7320: static always_inline void gen_op_evlhhossplat(DisasContext *ctx, TCGv addr)
        !          7321: {
        !          7322:     TCGv t0 = tcg_temp_new();
        !          7323:     gen_qemu_ld16s(ctx, t0, addr);
        !          7324: #if defined(TARGET_PPC64)
        !          7325:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
        !          7326:     tcg_gen_ext32u_tl(t0, t0);
        !          7327:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
        !          7328: #else
        !          7329:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
        !          7330:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
        !          7331: #endif
        !          7332:     tcg_temp_free(t0);
        !          7333: }
        !          7334: 
        !          7335: static always_inline void gen_op_evlwhe(DisasContext *ctx, TCGv addr)
        !          7336: {
        !          7337:     TCGv t0 = tcg_temp_new();
        !          7338: #if defined(TARGET_PPC64)
        !          7339:     gen_qemu_ld16u(ctx, t0, addr);
        !          7340:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
        !          7341:     gen_addr_add(ctx, addr, addr, 2);
        !          7342:     gen_qemu_ld16u(ctx, t0, addr);
        !          7343:     tcg_gen_shli_tl(t0, t0, 16);
        !          7344:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
        !          7345: #else
        !          7346:     gen_qemu_ld16u(ctx, t0, addr);
        !          7347:     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
        !          7348:     gen_addr_add(ctx, addr, addr, 2);
        !          7349:     gen_qemu_ld16u(ctx, t0, addr);
        !          7350:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
        !          7351: #endif
        !          7352:     tcg_temp_free(t0);
        !          7353: }
        !          7354: 
        !          7355: static always_inline void gen_op_evlwhou(DisasContext *ctx, TCGv addr)
        !          7356: {
        !          7357: #if defined(TARGET_PPC64)
        !          7358:     TCGv t0 = tcg_temp_new();
        !          7359:     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
        !          7360:     gen_addr_add(ctx, addr, addr, 2);
        !          7361:     gen_qemu_ld16u(ctx, t0, addr);
        !          7362:     tcg_gen_shli_tl(t0, t0, 32);
        !          7363:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
        !          7364:     tcg_temp_free(t0);
        !          7365: #else
        !          7366:     gen_qemu_ld16u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
        !          7367:     gen_addr_add(ctx, addr, addr, 2);
        !          7368:     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
        !          7369: #endif
        !          7370: }
        !          7371: 
        !          7372: static always_inline void gen_op_evlwhos(DisasContext *ctx, TCGv addr)
        !          7373: {
        !          7374: #if defined(TARGET_PPC64)
        !          7375:     TCGv t0 = tcg_temp_new();
        !          7376:     gen_qemu_ld16s(ctx, t0, addr);
        !          7377:     tcg_gen_ext32u_tl(cpu_gpr[rD(ctx->opcode)], t0);
        !          7378:     gen_addr_add(ctx, addr, addr, 2);
        !          7379:     gen_qemu_ld16s(ctx, t0, addr);
        !          7380:     tcg_gen_shli_tl(t0, t0, 32);
        !          7381:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
        !          7382:     tcg_temp_free(t0);
        !          7383: #else
        !          7384:     gen_qemu_ld16s(ctx, cpu_gprh[rD(ctx->opcode)], addr);
        !          7385:     gen_addr_add(ctx, addr, addr, 2);
        !          7386:     gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], addr);
        !          7387: #endif
        !          7388: }
        !          7389: 
        !          7390: static always_inline void gen_op_evlwwsplat(DisasContext *ctx, TCGv addr)
        !          7391: {
        !          7392:     TCGv t0 = tcg_temp_new();
        !          7393:     gen_qemu_ld32u(ctx, t0, addr);
        !          7394: #if defined(TARGET_PPC64)
        !          7395:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
        !          7396:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
        !          7397: #else
        !          7398:     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
        !          7399:     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
        !          7400: #endif
        !          7401:     tcg_temp_free(t0);
        !          7402: }
        !          7403: 
        !          7404: static always_inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
        !          7405: {
        !          7406:     TCGv t0 = tcg_temp_new();
        !          7407: #if defined(TARGET_PPC64)
        !          7408:     gen_qemu_ld16u(ctx, t0, addr);
        !          7409:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
        !          7410:     tcg_gen_shli_tl(t0, t0, 32);
        !          7411:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
        !          7412:     gen_addr_add(ctx, addr, addr, 2);
        !          7413:     gen_qemu_ld16u(ctx, t0, addr);
        !          7414:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
        !          7415:     tcg_gen_shli_tl(t0, t0, 16);
        !          7416:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
        !          7417: #else
        !          7418:     gen_qemu_ld16u(ctx, t0, addr);
        !          7419:     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
        !          7420:     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
        !          7421:     gen_addr_add(ctx, addr, addr, 2);
        !          7422:     gen_qemu_ld16u(ctx, t0, addr);
        !          7423:     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
        !          7424:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
        !          7425: #endif
        !          7426:     tcg_temp_free(t0);
        !          7427: }
        !          7428: 
        !          7429: static always_inline void gen_op_evstdd(DisasContext *ctx, TCGv addr)
        !          7430: {
        !          7431: #if defined(TARGET_PPC64)
        !          7432:     gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], addr);
        !          7433: #else
        !          7434:     TCGv_i64 t0 = tcg_temp_new_i64();
        !          7435:     tcg_gen_concat_i32_i64(t0, cpu_gpr[rS(ctx->opcode)], cpu_gprh[rS(ctx->opcode)]);
        !          7436:     gen_qemu_st64(ctx, t0, addr);
        !          7437:     tcg_temp_free_i64(t0);
        !          7438: #endif
        !          7439: }
        !          7440: 
        !          7441: static always_inline void gen_op_evstdw(DisasContext *ctx, TCGv addr)
        !          7442: {
        !          7443: #if defined(TARGET_PPC64)
        !          7444:     TCGv t0 = tcg_temp_new();
        !          7445:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
        !          7446:     gen_qemu_st32(ctx, t0, addr);
        !          7447:     tcg_temp_free(t0);
        !          7448: #else
        !          7449:     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
        !          7450: #endif
        !          7451:     gen_addr_add(ctx, addr, addr, 4);
        !          7452:     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
1.1.1.5   root     7453: }
1.1.1.6 ! root     7454: 
        !          7455: static always_inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
        !          7456: {
        !          7457:     TCGv t0 = tcg_temp_new();
        !          7458: #if defined(TARGET_PPC64)
        !          7459:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
1.1.1.5   root     7460: #else
1.1.1.6 ! root     7461:     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
        !          7462: #endif
        !          7463:     gen_qemu_st16(ctx, t0, addr);
        !          7464:     gen_addr_add(ctx, addr, addr, 2);
        !          7465: #if defined(TARGET_PPC64)
        !          7466:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
        !          7467:     gen_qemu_st16(ctx, t0, addr);
        !          7468: #else
        !          7469:     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
        !          7470: #endif
        !          7471:     gen_addr_add(ctx, addr, addr, 2);
        !          7472:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
        !          7473:     gen_qemu_st16(ctx, t0, addr);
        !          7474:     tcg_temp_free(t0);
        !          7475:     gen_addr_add(ctx, addr, addr, 2);
        !          7476:     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
        !          7477: }
        !          7478: 
        !          7479: static always_inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
        !          7480: {
        !          7481:     TCGv t0 = tcg_temp_new();
        !          7482: #if defined(TARGET_PPC64)
        !          7483:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
        !          7484: #else
        !          7485:     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
        !          7486: #endif
        !          7487:     gen_qemu_st16(ctx, t0, addr);
        !          7488:     gen_addr_add(ctx, addr, addr, 2);
        !          7489:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
        !          7490:     gen_qemu_st16(ctx, t0, addr);
        !          7491:     tcg_temp_free(t0);
        !          7492: }
        !          7493: 
        !          7494: static always_inline void gen_op_evstwho(DisasContext *ctx, TCGv addr)
        !          7495: {
        !          7496: #if defined(TARGET_PPC64)
        !          7497:     TCGv t0 = tcg_temp_new();
        !          7498:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
        !          7499:     gen_qemu_st16(ctx, t0, addr);
        !          7500:     tcg_temp_free(t0);
        !          7501: #else
        !          7502:     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
        !          7503: #endif
        !          7504:     gen_addr_add(ctx, addr, addr, 2);
        !          7505:     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
        !          7506: }
        !          7507: 
        !          7508: static always_inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr)
        !          7509: {
        !          7510: #if defined(TARGET_PPC64)
        !          7511:     TCGv t0 = tcg_temp_new();
        !          7512:     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
        !          7513:     gen_qemu_st32(ctx, t0, addr);
        !          7514:     tcg_temp_free(t0);
        !          7515: #else
        !          7516:     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
        !          7517: #endif
        !          7518: }
        !          7519: 
        !          7520: static always_inline void gen_op_evstwwo(DisasContext *ctx, TCGv addr)
        !          7521: {
        !          7522:     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
        !          7523: }
        !          7524: 
        !          7525: #define GEN_SPEOP_LDST(name, opc2, sh)                                        \
        !          7526: GEN_HANDLER(name, 0x04, opc2, 0x0C, 0x00000000, PPC_SPE)                      \
        !          7527: {                                                                             \
        !          7528:     TCGv t0;                                                                  \
        !          7529:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          7530:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
        !          7531:         return;                                                               \
        !          7532:     }                                                                         \
        !          7533:     gen_set_access_type(ctx, ACCESS_INT);                                     \
        !          7534:     t0 = tcg_temp_new();                                                      \
        !          7535:     if (Rc(ctx->opcode)) {                                                    \
        !          7536:         gen_addr_spe_imm_index(ctx, t0, sh);                                  \
        !          7537:     } else {                                                                  \
        !          7538:         gen_addr_reg_index(ctx, t0);                                          \
        !          7539:     }                                                                         \
        !          7540:     gen_op_##name(ctx, t0);                                                   \
        !          7541:     tcg_temp_free(t0);                                                        \
        !          7542: }
        !          7543: 
        !          7544: GEN_SPEOP_LDST(evldd, 0x00, 3);
        !          7545: GEN_SPEOP_LDST(evldw, 0x01, 3);
        !          7546: GEN_SPEOP_LDST(evldh, 0x02, 3);
        !          7547: GEN_SPEOP_LDST(evlhhesplat, 0x04, 1);
        !          7548: GEN_SPEOP_LDST(evlhhousplat, 0x06, 1);
        !          7549: GEN_SPEOP_LDST(evlhhossplat, 0x07, 1);
        !          7550: GEN_SPEOP_LDST(evlwhe, 0x08, 2);
        !          7551: GEN_SPEOP_LDST(evlwhou, 0x0A, 2);
        !          7552: GEN_SPEOP_LDST(evlwhos, 0x0B, 2);
        !          7553: GEN_SPEOP_LDST(evlwwsplat, 0x0C, 2);
        !          7554: GEN_SPEOP_LDST(evlwhsplat, 0x0E, 2);
        !          7555: 
        !          7556: GEN_SPEOP_LDST(evstdd, 0x10, 3);
        !          7557: GEN_SPEOP_LDST(evstdw, 0x11, 3);
        !          7558: GEN_SPEOP_LDST(evstdh, 0x12, 3);
        !          7559: GEN_SPEOP_LDST(evstwhe, 0x18, 2);
        !          7560: GEN_SPEOP_LDST(evstwho, 0x1A, 2);
        !          7561: GEN_SPEOP_LDST(evstwwe, 0x1C, 2);
        !          7562: GEN_SPEOP_LDST(evstwwo, 0x1E, 2);
1.1.1.5   root     7563: 
                   7564: /* Multiply and add - TODO */
                   7565: #if 0
                   7566: GEN_SPE(speundef,       evmhessf,      0x01, 0x10, 0x00000000, PPC_SPE);
                   7567: GEN_SPE(speundef,       evmhossf,      0x03, 0x10, 0x00000000, PPC_SPE);
                   7568: GEN_SPE(evmheumi,       evmhesmi,      0x04, 0x10, 0x00000000, PPC_SPE);
                   7569: GEN_SPE(speundef,       evmhesmf,      0x05, 0x10, 0x00000000, PPC_SPE);
                   7570: GEN_SPE(evmhoumi,       evmhosmi,      0x06, 0x10, 0x00000000, PPC_SPE);
                   7571: GEN_SPE(speundef,       evmhosmf,      0x07, 0x10, 0x00000000, PPC_SPE);
                   7572: GEN_SPE(speundef,       evmhessfa,     0x11, 0x10, 0x00000000, PPC_SPE);
                   7573: GEN_SPE(speundef,       evmhossfa,     0x13, 0x10, 0x00000000, PPC_SPE);
                   7574: GEN_SPE(evmheumia,      evmhesmia,     0x14, 0x10, 0x00000000, PPC_SPE);
                   7575: GEN_SPE(speundef,       evmhesmfa,     0x15, 0x10, 0x00000000, PPC_SPE);
                   7576: GEN_SPE(evmhoumia,      evmhosmia,     0x16, 0x10, 0x00000000, PPC_SPE);
                   7577: GEN_SPE(speundef,       evmhosmfa,     0x17, 0x10, 0x00000000, PPC_SPE);
                   7578: 
                   7579: GEN_SPE(speundef,       evmwhssf,      0x03, 0x11, 0x00000000, PPC_SPE);
                   7580: GEN_SPE(evmwlumi,       speundef,      0x04, 0x11, 0x00000000, PPC_SPE);
                   7581: GEN_SPE(evmwhumi,       evmwhsmi,      0x06, 0x11, 0x00000000, PPC_SPE);
                   7582: GEN_SPE(speundef,       evmwhsmf,      0x07, 0x11, 0x00000000, PPC_SPE);
                   7583: GEN_SPE(speundef,       evmwssf,       0x09, 0x11, 0x00000000, PPC_SPE);
                   7584: GEN_SPE(evmwumi,        evmwsmi,       0x0C, 0x11, 0x00000000, PPC_SPE);
                   7585: GEN_SPE(speundef,       evmwsmf,       0x0D, 0x11, 0x00000000, PPC_SPE);
                   7586: GEN_SPE(speundef,       evmwhssfa,     0x13, 0x11, 0x00000000, PPC_SPE);
                   7587: GEN_SPE(evmwlumia,      speundef,      0x14, 0x11, 0x00000000, PPC_SPE);
                   7588: GEN_SPE(evmwhumia,      evmwhsmia,     0x16, 0x11, 0x00000000, PPC_SPE);
                   7589: GEN_SPE(speundef,       evmwhsmfa,     0x17, 0x11, 0x00000000, PPC_SPE);
                   7590: GEN_SPE(speundef,       evmwssfa,      0x19, 0x11, 0x00000000, PPC_SPE);
                   7591: GEN_SPE(evmwumia,       evmwsmia,      0x1C, 0x11, 0x00000000, PPC_SPE);
                   7592: GEN_SPE(speundef,       evmwsmfa,      0x1D, 0x11, 0x00000000, PPC_SPE);
                   7593: 
                   7594: GEN_SPE(evadduiaaw,     evaddsiaaw,    0x00, 0x13, 0x0000F800, PPC_SPE);
                   7595: GEN_SPE(evsubfusiaaw,   evsubfssiaaw,  0x01, 0x13, 0x0000F800, PPC_SPE);
                   7596: GEN_SPE(evaddumiaaw,    evaddsmiaaw,   0x04, 0x13, 0x0000F800, PPC_SPE);
                   7597: GEN_SPE(evsubfumiaaw,   evsubfsmiaaw,  0x05, 0x13, 0x0000F800, PPC_SPE);
                   7598: GEN_SPE(evdivws,        evdivwu,       0x06, 0x13, 0x00000000, PPC_SPE);
                   7599: GEN_SPE(evmra,          speundef,      0x07, 0x13, 0x0000F800, PPC_SPE);
                   7600: 
                   7601: GEN_SPE(evmheusiaaw,    evmhessiaaw,   0x00, 0x14, 0x00000000, PPC_SPE);
                   7602: GEN_SPE(speundef,       evmhessfaaw,   0x01, 0x14, 0x00000000, PPC_SPE);
                   7603: GEN_SPE(evmhousiaaw,    evmhossiaaw,   0x02, 0x14, 0x00000000, PPC_SPE);
                   7604: GEN_SPE(speundef,       evmhossfaaw,   0x03, 0x14, 0x00000000, PPC_SPE);
                   7605: GEN_SPE(evmheumiaaw,    evmhesmiaaw,   0x04, 0x14, 0x00000000, PPC_SPE);
                   7606: GEN_SPE(speundef,       evmhesmfaaw,   0x05, 0x14, 0x00000000, PPC_SPE);
                   7607: GEN_SPE(evmhoumiaaw,    evmhosmiaaw,   0x06, 0x14, 0x00000000, PPC_SPE);
                   7608: GEN_SPE(speundef,       evmhosmfaaw,   0x07, 0x14, 0x00000000, PPC_SPE);
                   7609: GEN_SPE(evmhegumiaa,    evmhegsmiaa,   0x14, 0x14, 0x00000000, PPC_SPE);
                   7610: GEN_SPE(speundef,       evmhegsmfaa,   0x15, 0x14, 0x00000000, PPC_SPE);
                   7611: GEN_SPE(evmhogumiaa,    evmhogsmiaa,   0x16, 0x14, 0x00000000, PPC_SPE);
                   7612: GEN_SPE(speundef,       evmhogsmfaa,   0x17, 0x14, 0x00000000, PPC_SPE);
                   7613: 
                   7614: GEN_SPE(evmwlusiaaw,    evmwlssiaaw,   0x00, 0x15, 0x00000000, PPC_SPE);
                   7615: GEN_SPE(evmwlumiaaw,    evmwlsmiaaw,   0x04, 0x15, 0x00000000, PPC_SPE);
                   7616: GEN_SPE(speundef,       evmwssfaa,     0x09, 0x15, 0x00000000, PPC_SPE);
                   7617: GEN_SPE(evmwumiaa,      evmwsmiaa,     0x0C, 0x15, 0x00000000, PPC_SPE);
                   7618: GEN_SPE(speundef,       evmwsmfaa,     0x0D, 0x15, 0x00000000, PPC_SPE);
                   7619: 
                   7620: GEN_SPE(evmheusianw,    evmhessianw,   0x00, 0x16, 0x00000000, PPC_SPE);
                   7621: GEN_SPE(speundef,       evmhessfanw,   0x01, 0x16, 0x00000000, PPC_SPE);
                   7622: GEN_SPE(evmhousianw,    evmhossianw,   0x02, 0x16, 0x00000000, PPC_SPE);
                   7623: GEN_SPE(speundef,       evmhossfanw,   0x03, 0x16, 0x00000000, PPC_SPE);
                   7624: GEN_SPE(evmheumianw,    evmhesmianw,   0x04, 0x16, 0x00000000, PPC_SPE);
                   7625: GEN_SPE(speundef,       evmhesmfanw,   0x05, 0x16, 0x00000000, PPC_SPE);
                   7626: GEN_SPE(evmhoumianw,    evmhosmianw,   0x06, 0x16, 0x00000000, PPC_SPE);
                   7627: GEN_SPE(speundef,       evmhosmfanw,   0x07, 0x16, 0x00000000, PPC_SPE);
                   7628: GEN_SPE(evmhegumian,    evmhegsmian,   0x14, 0x16, 0x00000000, PPC_SPE);
                   7629: GEN_SPE(speundef,       evmhegsmfan,   0x15, 0x16, 0x00000000, PPC_SPE);
                   7630: GEN_SPE(evmhigumian,    evmhigsmian,   0x16, 0x16, 0x00000000, PPC_SPE);
                   7631: GEN_SPE(speundef,       evmhogsmfan,   0x17, 0x16, 0x00000000, PPC_SPE);
                   7632: 
                   7633: GEN_SPE(evmwlusianw,    evmwlssianw,   0x00, 0x17, 0x00000000, PPC_SPE);
                   7634: GEN_SPE(evmwlumianw,    evmwlsmianw,   0x04, 0x17, 0x00000000, PPC_SPE);
                   7635: GEN_SPE(speundef,       evmwssfan,     0x09, 0x17, 0x00000000, PPC_SPE);
                   7636: GEN_SPE(evmwumian,      evmwsmian,     0x0C, 0x17, 0x00000000, PPC_SPE);
                   7637: GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0x00000000, PPC_SPE);
                   7638: #endif
                   7639: 
                   7640: /***                      SPE floating-point extension                     ***/
1.1.1.6 ! root     7641: #if defined(TARGET_PPC64)
        !          7642: #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
        !          7643: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          7644: {                                                                             \
        !          7645:     TCGv_i32 t0;                                                              \
        !          7646:     TCGv t1;                                                                  \
        !          7647:     t0 = tcg_temp_new_i32();                                                  \
        !          7648:     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
        !          7649:     gen_helper_##name(t0, t0);                                                \
        !          7650:     t1 = tcg_temp_new();                                                      \
        !          7651:     tcg_gen_extu_i32_tl(t1, t0);                                              \
        !          7652:     tcg_temp_free_i32(t0);                                                    \
        !          7653:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
        !          7654:                     0xFFFFFFFF00000000ULL);                                   \
        !          7655:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
        !          7656:     tcg_temp_free(t1);                                                        \
        !          7657: }
        !          7658: #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
        !          7659: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          7660: {                                                                             \
        !          7661:     TCGv_i32 t0;                                                              \
        !          7662:     TCGv t1;                                                                  \
        !          7663:     t0 = tcg_temp_new_i32();                                                  \
        !          7664:     gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
        !          7665:     t1 = tcg_temp_new();                                                      \
        !          7666:     tcg_gen_extu_i32_tl(t1, t0);                                              \
        !          7667:     tcg_temp_free_i32(t0);                                                    \
        !          7668:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
        !          7669:                     0xFFFFFFFF00000000ULL);                                   \
        !          7670:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
        !          7671:     tcg_temp_free(t1);                                                        \
        !          7672: }
        !          7673: #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
        !          7674: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          7675: {                                                                             \
        !          7676:     TCGv_i32 t0 = tcg_temp_new_i32();                                         \
        !          7677:     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
        !          7678:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
        !          7679:     tcg_temp_free_i32(t0);                                                    \
        !          7680: }
        !          7681: #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
        !          7682: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          7683: {                                                                             \
        !          7684:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
        !          7685: }
        !          7686: #define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
        !          7687: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          7688: {                                                                             \
        !          7689:     TCGv_i32 t0, t1;                                                          \
        !          7690:     TCGv_i64 t2;                                                              \
        !          7691:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          7692:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
        !          7693:         return;                                                               \
        !          7694:     }                                                                         \
        !          7695:     t0 = tcg_temp_new_i32();                                                  \
        !          7696:     t1 = tcg_temp_new_i32();                                                  \
        !          7697:     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
        !          7698:     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
        !          7699:     gen_helper_##name(t0, t0, t1);                                            \
        !          7700:     tcg_temp_free_i32(t1);                                                    \
        !          7701:     t2 = tcg_temp_new();                                                      \
        !          7702:     tcg_gen_extu_i32_tl(t2, t0);                                              \
        !          7703:     tcg_temp_free_i32(t0);                                                    \
        !          7704:     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
        !          7705:                     0xFFFFFFFF00000000ULL);                                   \
        !          7706:     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t2);    \
        !          7707:     tcg_temp_free(t2);                                                        \
        !          7708: }
        !          7709: #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
1.1.1.5   root     7710: static always_inline void gen_##name (DisasContext *ctx)                      \
                   7711: {                                                                             \
1.1.1.6 ! root     7712:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          7713:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
        !          7714:         return;                                                               \
        !          7715:     }                                                                         \
        !          7716:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],     \
        !          7717:                       cpu_gpr[rB(ctx->opcode)]);                              \
1.1       root     7718: }
1.1.1.6 ! root     7719: #define GEN_SPEFPUOP_COMP_32(name)                                            \
        !          7720: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          7721: {                                                                             \
        !          7722:     TCGv_i32 t0, t1;                                                          \
        !          7723:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          7724:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
        !          7725:         return;                                                               \
        !          7726:     }                                                                         \
        !          7727:     t0 = tcg_temp_new_i32();                                                  \
        !          7728:     t1 = tcg_temp_new_i32();                                                  \
        !          7729:     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
        !          7730:     tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
        !          7731:     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
        !          7732:     tcg_temp_free_i32(t0);                                                    \
        !          7733:     tcg_temp_free_i32(t1);                                                    \
        !          7734: }
        !          7735: #define GEN_SPEFPUOP_COMP_64(name)                                            \
        !          7736: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          7737: {                                                                             \
        !          7738:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          7739:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
        !          7740:         return;                                                               \
        !          7741:     }                                                                         \
        !          7742:     gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
        !          7743:                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
        !          7744: }
        !          7745: #else
        !          7746: #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
        !          7747: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          7748: {                                                                             \
        !          7749:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
        !          7750: }
        !          7751: #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
        !          7752: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          7753: {                                                                             \
        !          7754:     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
        !          7755:     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
        !          7756:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], t0);                          \
        !          7757:     tcg_temp_free_i64(t0);                                                    \
        !          7758: }
        !          7759: #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
        !          7760: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          7761: {                                                                             \
        !          7762:     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
        !          7763:     gen_helper_##name(t0, cpu_gpr[rB(ctx->opcode)]);                          \
        !          7764:     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
        !          7765:     tcg_temp_free_i64(t0);                                                    \
        !          7766: }
        !          7767: #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
        !          7768: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          7769: {                                                                             \
        !          7770:     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
        !          7771:     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
        !          7772:     gen_helper_##name(t0, t0);                                                \
        !          7773:     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
        !          7774:     tcg_temp_free_i64(t0);                                                    \
        !          7775: }
        !          7776: #define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
        !          7777: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          7778: {                                                                             \
        !          7779:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          7780:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
        !          7781:         return;                                                               \
        !          7782:     }                                                                         \
        !          7783:     gen_helper_##name(cpu_gpr[rD(ctx->opcode)],                               \
        !          7784:                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
        !          7785: }
        !          7786: #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
        !          7787: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          7788: {                                                                             \
        !          7789:     TCGv_i64 t0, t1;                                                          \
        !          7790:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          7791:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
        !          7792:         return;                                                               \
        !          7793:     }                                                                         \
        !          7794:     t0 = tcg_temp_new_i64();                                                  \
        !          7795:     t1 = tcg_temp_new_i64();                                                  \
        !          7796:     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
        !          7797:     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
        !          7798:     gen_helper_##name(t0, t0, t1);                                            \
        !          7799:     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
        !          7800:     tcg_temp_free_i64(t0);                                                    \
        !          7801:     tcg_temp_free_i64(t1);                                                    \
        !          7802: }
        !          7803: #define GEN_SPEFPUOP_COMP_32(name)                                            \
        !          7804: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          7805: {                                                                             \
        !          7806:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          7807:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
        !          7808:         return;                                                               \
        !          7809:     }                                                                         \
        !          7810:     gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
        !          7811:                       cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
        !          7812: }
        !          7813: #define GEN_SPEFPUOP_COMP_64(name)                                            \
        !          7814: static always_inline void gen_##name (DisasContext *ctx)                      \
        !          7815: {                                                                             \
        !          7816:     TCGv_i64 t0, t1;                                                          \
        !          7817:     if (unlikely(!ctx->spe_enabled)) {                                        \
        !          7818:         gen_exception(ctx, POWERPC_EXCP_APU);                                 \
        !          7819:         return;                                                               \
        !          7820:     }                                                                         \
        !          7821:     t0 = tcg_temp_new_i64();                                                  \
        !          7822:     t1 = tcg_temp_new_i64();                                                  \
        !          7823:     gen_load_gpr64(t0, rA(ctx->opcode));                                      \
        !          7824:     gen_load_gpr64(t1, rB(ctx->opcode));                                      \
        !          7825:     gen_helper_##name(cpu_crf[crfD(ctx->opcode)], t0, t1);                    \
        !          7826:     tcg_temp_free_i64(t0);                                                    \
        !          7827:     tcg_temp_free_i64(t1);                                                    \
        !          7828: }
        !          7829: #endif
1.1       root     7830: 
1.1.1.5   root     7831: /* Single precision floating-point vectors operations */
                   7832: /* Arithmetic */
1.1.1.6 ! root     7833: GEN_SPEFPUOP_ARITH2_64_64(evfsadd);
        !          7834: GEN_SPEFPUOP_ARITH2_64_64(evfssub);
        !          7835: GEN_SPEFPUOP_ARITH2_64_64(evfsmul);
        !          7836: GEN_SPEFPUOP_ARITH2_64_64(evfsdiv);
        !          7837: static always_inline void gen_evfsabs (DisasContext *ctx)
        !          7838: {
        !          7839:     if (unlikely(!ctx->spe_enabled)) {
        !          7840:         gen_exception(ctx, POWERPC_EXCP_APU);
        !          7841:         return;
        !          7842:     }
        !          7843: #if defined(TARGET_PPC64)
        !          7844:     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000080000000LL);
        !          7845: #else
        !          7846:     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x80000000);
        !          7847:     tcg_gen_andi_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
        !          7848: #endif
        !          7849: }
        !          7850: static always_inline void gen_evfsnabs (DisasContext *ctx)
        !          7851: {
        !          7852:     if (unlikely(!ctx->spe_enabled)) {
        !          7853:         gen_exception(ctx, POWERPC_EXCP_APU);
        !          7854:         return;
        !          7855:     }
        !          7856: #if defined(TARGET_PPC64)
        !          7857:     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
        !          7858: #else
        !          7859:     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
        !          7860:     tcg_gen_ori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
        !          7861: #endif
        !          7862: }
        !          7863: static always_inline void gen_evfsneg (DisasContext *ctx)
        !          7864: {
        !          7865:     if (unlikely(!ctx->spe_enabled)) {
        !          7866:         gen_exception(ctx, POWERPC_EXCP_APU);
        !          7867:         return;
        !          7868:     }
        !          7869: #if defined(TARGET_PPC64)
        !          7870:     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
        !          7871: #else
        !          7872:     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
        !          7873:     tcg_gen_xori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
        !          7874: #endif
        !          7875: }
        !          7876: 
1.1.1.5   root     7877: /* Conversion */
1.1.1.6 ! root     7878: GEN_SPEFPUOP_CONV_64_64(evfscfui);
        !          7879: GEN_SPEFPUOP_CONV_64_64(evfscfsi);
        !          7880: GEN_SPEFPUOP_CONV_64_64(evfscfuf);
        !          7881: GEN_SPEFPUOP_CONV_64_64(evfscfsf);
        !          7882: GEN_SPEFPUOP_CONV_64_64(evfsctui);
        !          7883: GEN_SPEFPUOP_CONV_64_64(evfsctsi);
        !          7884: GEN_SPEFPUOP_CONV_64_64(evfsctuf);
        !          7885: GEN_SPEFPUOP_CONV_64_64(evfsctsf);
        !          7886: GEN_SPEFPUOP_CONV_64_64(evfsctuiz);
        !          7887: GEN_SPEFPUOP_CONV_64_64(evfsctsiz);
        !          7888: 
1.1.1.5   root     7889: /* Comparison */
1.1.1.6 ! root     7890: GEN_SPEFPUOP_COMP_64(evfscmpgt);
        !          7891: GEN_SPEFPUOP_COMP_64(evfscmplt);
        !          7892: GEN_SPEFPUOP_COMP_64(evfscmpeq);
        !          7893: GEN_SPEFPUOP_COMP_64(evfststgt);
        !          7894: GEN_SPEFPUOP_COMP_64(evfststlt);
        !          7895: GEN_SPEFPUOP_COMP_64(evfststeq);
1.1.1.5   root     7896: 
                   7897: /* Opcodes definitions */
1.1.1.6 ! root     7898: GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPE_SINGLE); //
        !          7899: GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPE_SINGLE); //
        !          7900: GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPE_SINGLE); //
        !          7901: GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPE_SINGLE); //
        !          7902: GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
        !          7903: GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
        !          7904: GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
        !          7905: GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
        !          7906: GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
        !          7907: GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
        !          7908: GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
        !          7909: GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
        !          7910: GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
        !          7911: GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
1.1.1.5   root     7912: 
                   7913: /* Single precision floating-point operations */
                   7914: /* Arithmetic */
1.1.1.6 ! root     7915: GEN_SPEFPUOP_ARITH2_32_32(efsadd);
        !          7916: GEN_SPEFPUOP_ARITH2_32_32(efssub);
        !          7917: GEN_SPEFPUOP_ARITH2_32_32(efsmul);
        !          7918: GEN_SPEFPUOP_ARITH2_32_32(efsdiv);
        !          7919: static always_inline void gen_efsabs (DisasContext *ctx)
        !          7920: {
        !          7921:     if (unlikely(!ctx->spe_enabled)) {
        !          7922:         gen_exception(ctx, POWERPC_EXCP_APU);
        !          7923:         return;
        !          7924:     }
        !          7925:     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL);
        !          7926: }
        !          7927: static always_inline void gen_efsnabs (DisasContext *ctx)
        !          7928: {
        !          7929:     if (unlikely(!ctx->spe_enabled)) {
        !          7930:         gen_exception(ctx, POWERPC_EXCP_APU);
        !          7931:         return;
        !          7932:     }
        !          7933:     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
        !          7934: }
        !          7935: static always_inline void gen_efsneg (DisasContext *ctx)
        !          7936: {
        !          7937:     if (unlikely(!ctx->spe_enabled)) {
        !          7938:         gen_exception(ctx, POWERPC_EXCP_APU);
        !          7939:         return;
        !          7940:     }
        !          7941:     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
        !          7942: }
        !          7943: 
1.1.1.5   root     7944: /* Conversion */
1.1.1.6 ! root     7945: GEN_SPEFPUOP_CONV_32_32(efscfui);
        !          7946: GEN_SPEFPUOP_CONV_32_32(efscfsi);
        !          7947: GEN_SPEFPUOP_CONV_32_32(efscfuf);
        !          7948: GEN_SPEFPUOP_CONV_32_32(efscfsf);
        !          7949: GEN_SPEFPUOP_CONV_32_32(efsctui);
        !          7950: GEN_SPEFPUOP_CONV_32_32(efsctsi);
        !          7951: GEN_SPEFPUOP_CONV_32_32(efsctuf);
        !          7952: GEN_SPEFPUOP_CONV_32_32(efsctsf);
        !          7953: GEN_SPEFPUOP_CONV_32_32(efsctuiz);
        !          7954: GEN_SPEFPUOP_CONV_32_32(efsctsiz);
        !          7955: GEN_SPEFPUOP_CONV_32_64(efscfd);
        !          7956: 
1.1.1.5   root     7957: /* Comparison */
1.1.1.6 ! root     7958: GEN_SPEFPUOP_COMP_32(efscmpgt);
        !          7959: GEN_SPEFPUOP_COMP_32(efscmplt);
        !          7960: GEN_SPEFPUOP_COMP_32(efscmpeq);
        !          7961: GEN_SPEFPUOP_COMP_32(efststgt);
        !          7962: GEN_SPEFPUOP_COMP_32(efststlt);
        !          7963: GEN_SPEFPUOP_COMP_32(efststeq);
1.1.1.5   root     7964: 
                   7965: /* Opcodes definitions */
1.1.1.6 ! root     7966: GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPE_SINGLE); //
        !          7967: GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPE_SINGLE); //
        !          7968: GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPE_SINGLE); //
        !          7969: GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPE_SINGLE); //
        !          7970: GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
        !          7971: GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
        !          7972: GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
        !          7973: GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
        !          7974: GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
        !          7975: GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
        !          7976: GEN_SPE(efsctuiz,       speundef,      0x0C, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
        !          7977: GEN_SPE(efsctsiz,       speundef,      0x0D, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
        !          7978: GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
        !          7979: GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
1.1.1.5   root     7980: 
                   7981: /* Double precision floating-point operations */
                   7982: /* Arithmetic */
1.1.1.6 ! root     7983: GEN_SPEFPUOP_ARITH2_64_64(efdadd);
        !          7984: GEN_SPEFPUOP_ARITH2_64_64(efdsub);
        !          7985: GEN_SPEFPUOP_ARITH2_64_64(efdmul);
        !          7986: GEN_SPEFPUOP_ARITH2_64_64(efddiv);
        !          7987: static always_inline void gen_efdabs (DisasContext *ctx)
        !          7988: {
        !          7989:     if (unlikely(!ctx->spe_enabled)) {
        !          7990:         gen_exception(ctx, POWERPC_EXCP_APU);
        !          7991:         return;
        !          7992:     }
        !          7993: #if defined(TARGET_PPC64)
        !          7994:     tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000000000000LL);
        !          7995: #else
        !          7996:     tcg_gen_andi_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
        !          7997: #endif
        !          7998: }
        !          7999: static always_inline void gen_efdnabs (DisasContext *ctx)
        !          8000: {
        !          8001:     if (unlikely(!ctx->spe_enabled)) {
        !          8002:         gen_exception(ctx, POWERPC_EXCP_APU);
        !          8003:         return;
        !          8004:     }
        !          8005: #if defined(TARGET_PPC64)
        !          8006:     tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
        !          8007: #else
        !          8008:     tcg_gen_ori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
        !          8009: #endif
        !          8010: }
        !          8011: static always_inline void gen_efdneg (DisasContext *ctx)
        !          8012: {
        !          8013:     if (unlikely(!ctx->spe_enabled)) {
        !          8014:         gen_exception(ctx, POWERPC_EXCP_APU);
        !          8015:         return;
        !          8016:     }
        !          8017: #if defined(TARGET_PPC64)
        !          8018:     tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
        !          8019: #else
        !          8020:     tcg_gen_xori_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
        !          8021: #endif
        !          8022: }
        !          8023: 
1.1.1.5   root     8024: /* Conversion */
1.1.1.6 ! root     8025: GEN_SPEFPUOP_CONV_64_32(efdcfui);
        !          8026: GEN_SPEFPUOP_CONV_64_32(efdcfsi);
        !          8027: GEN_SPEFPUOP_CONV_64_32(efdcfuf);
        !          8028: GEN_SPEFPUOP_CONV_64_32(efdcfsf);
        !          8029: GEN_SPEFPUOP_CONV_32_64(efdctui);
        !          8030: GEN_SPEFPUOP_CONV_32_64(efdctsi);
        !          8031: GEN_SPEFPUOP_CONV_32_64(efdctuf);
        !          8032: GEN_SPEFPUOP_CONV_32_64(efdctsf);
        !          8033: GEN_SPEFPUOP_CONV_32_64(efdctuiz);
        !          8034: GEN_SPEFPUOP_CONV_32_64(efdctsiz);
        !          8035: GEN_SPEFPUOP_CONV_64_32(efdcfs);
        !          8036: GEN_SPEFPUOP_CONV_64_64(efdcfuid);
        !          8037: GEN_SPEFPUOP_CONV_64_64(efdcfsid);
        !          8038: GEN_SPEFPUOP_CONV_64_64(efdctuidz);
        !          8039: GEN_SPEFPUOP_CONV_64_64(efdctsidz);
1.1.1.5   root     8040: 
                   8041: /* Comparison */
1.1.1.6 ! root     8042: GEN_SPEFPUOP_COMP_64(efdcmpgt);
        !          8043: GEN_SPEFPUOP_COMP_64(efdcmplt);
        !          8044: GEN_SPEFPUOP_COMP_64(efdcmpeq);
        !          8045: GEN_SPEFPUOP_COMP_64(efdtstgt);
        !          8046: GEN_SPEFPUOP_COMP_64(efdtstlt);
        !          8047: GEN_SPEFPUOP_COMP_64(efdtsteq);
1.1.1.5   root     8048: 
                   8049: /* Opcodes definitions */
1.1.1.6 ! root     8050: GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPE_DOUBLE); //
        !          8051: GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
        !          8052: GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPE_DOUBLE); //
        !          8053: GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPE_DOUBLE); //
        !          8054: GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPE_DOUBLE); //
        !          8055: GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
        !          8056: GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
        !          8057: GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
        !          8058: GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
        !          8059: GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
        !          8060: GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
        !          8061: GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
        !          8062: GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
        !          8063: GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
        !          8064: GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
        !          8065: GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
1.1.1.5   root     8066: 
1.1       root     8067: /* End opcode list */
                   8068: GEN_OPCODE_MARK(end);
                   8069: 
                   8070: #include "translate_init.c"
1.1.1.5   root     8071: #include "helper_regs.h"
1.1       root     8072: 
                   8073: /*****************************************************************************/
                   8074: /* Misc PowerPC helpers */
1.1.1.5   root     8075: void cpu_dump_state (CPUState *env, FILE *f,
                   8076:                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                   8077:                      int flags)
                   8078: {
1.1       root     8079: #define RGPL  4
                   8080: #define RFPL  4
                   8081: 
                   8082:     int i;
                   8083: 
1.1.1.5   root     8084:     cpu_fprintf(f, "NIP " ADDRX "   LR " ADDRX " CTR " ADDRX " XER %08x\n",
1.1.1.6 ! root     8085:                 env->nip, env->lr, env->ctr, env->xer);
1.1.1.5   root     8086:     cpu_fprintf(f, "MSR " ADDRX " HID0 " ADDRX "  HF " ADDRX " idx %d\n",
                   8087:                 env->msr, env->spr[SPR_HID0], env->hflags, env->mmu_idx);
                   8088: #if !defined(NO_TIMER_DUMP)
                   8089:     cpu_fprintf(f, "TB %08x %08x "
                   8090: #if !defined(CONFIG_USER_ONLY)
                   8091:                 "DECR %08x"
                   8092: #endif
                   8093:                 "\n",
                   8094:                 cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
                   8095: #if !defined(CONFIG_USER_ONLY)
                   8096:                 , cpu_ppc_load_decr(env)
                   8097: #endif
                   8098:                 );
                   8099: #endif
                   8100:     for (i = 0; i < 32; i++) {
1.1       root     8101:         if ((i & (RGPL - 1)) == 0)
                   8102:             cpu_fprintf(f, "GPR%02d", i);
1.1.1.5   root     8103:         cpu_fprintf(f, " " REGX, ppc_dump_gpr(env, i));
1.1       root     8104:         if ((i & (RGPL - 1)) == (RGPL - 1))
                   8105:             cpu_fprintf(f, "\n");
1.1.1.5   root     8106:     }
1.1       root     8107:     cpu_fprintf(f, "CR ");
1.1.1.5   root     8108:     for (i = 0; i < 8; i++)
1.1       root     8109:         cpu_fprintf(f, "%01x", env->crf[i]);
                   8110:     cpu_fprintf(f, "  [");
1.1.1.5   root     8111:     for (i = 0; i < 8; i++) {
                   8112:         char a = '-';
                   8113:         if (env->crf[i] & 0x08)
                   8114:             a = 'L';
                   8115:         else if (env->crf[i] & 0x04)
                   8116:             a = 'G';
                   8117:         else if (env->crf[i] & 0x02)
                   8118:             a = 'E';
1.1       root     8119:         cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
1.1.1.5   root     8120:     }
                   8121:     cpu_fprintf(f, " ]             RES " ADDRX "\n", env->reserve);
1.1       root     8122:     for (i = 0; i < 32; i++) {
                   8123:         if ((i & (RFPL - 1)) == 0)
                   8124:             cpu_fprintf(f, "FPR%02d", i);
1.1.1.3   root     8125:         cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
1.1       root     8126:         if ((i & (RFPL - 1)) == (RFPL - 1))
                   8127:             cpu_fprintf(f, "\n");
                   8128:     }
1.1.1.6 ! root     8129:     cpu_fprintf(f, "FPSCR %08x\n", env->fpscr);
1.1.1.5   root     8130: #if !defined(CONFIG_USER_ONLY)
                   8131:     cpu_fprintf(f, "SRR0 " ADDRX " SRR1 " ADDRX " SDR1 " ADDRX "\n",
1.1       root     8132:                 env->spr[SPR_SRR0], env->spr[SPR_SRR1], env->sdr1);
1.1.1.5   root     8133: #endif
1.1       root     8134: 
                   8135: #undef RGPL
                   8136: #undef RFPL
1.1.1.5   root     8137: }
                   8138: 
                   8139: void cpu_dump_statistics (CPUState *env, FILE*f,
                   8140:                           int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                   8141:                           int flags)
                   8142: {
                   8143: #if defined(DO_PPC_STATISTICS)
                   8144:     opc_handler_t **t1, **t2, **t3, *handler;
                   8145:     int op1, op2, op3;
                   8146: 
                   8147:     t1 = env->opcodes;
                   8148:     for (op1 = 0; op1 < 64; op1++) {
                   8149:         handler = t1[op1];
                   8150:         if (is_indirect_opcode(handler)) {
                   8151:             t2 = ind_table(handler);
                   8152:             for (op2 = 0; op2 < 32; op2++) {
                   8153:                 handler = t2[op2];
                   8154:                 if (is_indirect_opcode(handler)) {
                   8155:                     t3 = ind_table(handler);
                   8156:                     for (op3 = 0; op3 < 32; op3++) {
                   8157:                         handler = t3[op3];
                   8158:                         if (handler->count == 0)
                   8159:                             continue;
                   8160:                         cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
                   8161:                                     "%016llx %lld\n",
                   8162:                                     op1, op2, op3, op1, (op3 << 5) | op2,
                   8163:                                     handler->oname,
                   8164:                                     handler->count, handler->count);
                   8165:                     }
                   8166:                 } else {
                   8167:                     if (handler->count == 0)
                   8168:                         continue;
                   8169:                     cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
                   8170:                                 "%016llx %lld\n",
                   8171:                                 op1, op2, op1, op2, handler->oname,
                   8172:                                 handler->count, handler->count);
                   8173:                 }
                   8174:             }
                   8175:         } else {
                   8176:             if (handler->count == 0)
                   8177:                 continue;
                   8178:             cpu_fprintf(f, "%02x       (%02x     ) %16s: %016llx %lld\n",
                   8179:                         op1, op1, handler->oname,
                   8180:                         handler->count, handler->count);
                   8181:         }
                   8182:     }
                   8183: #endif
1.1       root     8184: }
                   8185: 
                   8186: /*****************************************************************************/
1.1.1.6 ! root     8187: static always_inline void gen_intermediate_code_internal (CPUState *env,
        !          8188:                                                           TranslationBlock *tb,
        !          8189:                                                           int search_pc)
1.1       root     8190: {
                   8191:     DisasContext ctx, *ctxp = &ctx;
                   8192:     opc_handler_t **table, *handler;
                   8193:     target_ulong pc_start;
                   8194:     uint16_t *gen_opc_end;
1.1.1.6 ! root     8195:     CPUBreakpoint *bp;
1.1       root     8196:     int j, lj = -1;
1.1.1.6 ! root     8197:     int num_insns;
        !          8198:     int max_insns;
1.1       root     8199: 
                   8200:     pc_start = tb->pc;
                   8201:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
                   8202:     ctx.nip = pc_start;
                   8203:     ctx.tb = tb;
1.1.1.5   root     8204:     ctx.exception = POWERPC_EXCP_NONE;
1.1       root     8205:     ctx.spr_cb = env->spr_cb;
1.1.1.6 ! root     8206:     ctx.mem_idx = env->mmu_idx;
        !          8207:     ctx.access_type = -1;
        !          8208:     ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
1.1.1.5   root     8209: #if defined(TARGET_PPC64)
                   8210:     ctx.sf_mode = msr_sf;
1.1       root     8211: #endif
                   8212:     ctx.fpu_enabled = msr_fp;
1.1.1.5   root     8213:     if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
                   8214:         ctx.spe_enabled = msr_spe;
                   8215:     else
                   8216:         ctx.spe_enabled = 0;
                   8217:     if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
                   8218:         ctx.altivec_enabled = msr_vr;
                   8219:     else
                   8220:         ctx.altivec_enabled = 0;
                   8221:     if ((env->flags & POWERPC_FLAG_SE) && msr_se)
1.1.1.6 ! root     8222:         ctx.singlestep_enabled = CPU_SINGLE_STEP;
1.1.1.5   root     8223:     else
1.1.1.6 ! root     8224:         ctx.singlestep_enabled = 0;
1.1.1.5   root     8225:     if ((env->flags & POWERPC_FLAG_BE) && msr_be)
1.1.1.6 ! root     8226:         ctx.singlestep_enabled |= CPU_BRANCH_STEP;
        !          8227:     if (unlikely(env->singlestep_enabled))
        !          8228:         ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
1.1       root     8229: #if defined (DO_SINGLE_STEP) && 0
                   8230:     /* Single step trace mode */
                   8231:     msr_se = 1;
                   8232: #endif
1.1.1.6 ! root     8233:     num_insns = 0;
        !          8234:     max_insns = tb->cflags & CF_COUNT_MASK;
        !          8235:     if (max_insns == 0)
        !          8236:         max_insns = CF_COUNT_MASK;
        !          8237: 
        !          8238:     gen_icount_start();
1.1       root     8239:     /* Set env in case of segfault during code fetch */
1.1.1.5   root     8240:     while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
1.1.1.6 ! root     8241:         if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
        !          8242:             TAILQ_FOREACH(bp, &env->breakpoints, entry) {
        !          8243:                 if (bp->pc == ctx.nip) {
        !          8244:                     gen_debug_exception(ctxp);
1.1.1.3   root     8245:                     break;
                   8246:                 }
                   8247:             }
                   8248:         }
1.1.1.5   root     8249:         if (unlikely(search_pc)) {
1.1       root     8250:             j = gen_opc_ptr - gen_opc_buf;
                   8251:             if (lj < j) {
                   8252:                 lj++;
                   8253:                 while (lj < j)
                   8254:                     gen_opc_instr_start[lj++] = 0;
                   8255:                 gen_opc_pc[lj] = ctx.nip;
                   8256:                 gen_opc_instr_start[lj] = 1;
1.1.1.6 ! root     8257:                 gen_opc_icount[lj] = num_insns;
1.1       root     8258:             }
                   8259:         }
1.1.1.6 ! root     8260:         LOG_DISAS("----------------\n");
        !          8261:         LOG_DISAS("nip=" ADDRX " super=%d ir=%d\n",
        !          8262:                   ctx.nip, ctx.mem_idx, (int)msr_ir);
        !          8263:         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
        !          8264:             gen_io_start();
        !          8265:         if (unlikely(ctx.le_mode)) {
1.1.1.5   root     8266:             ctx.opcode = bswap32(ldl_code(ctx.nip));
                   8267:         } else {
                   8268:             ctx.opcode = ldl_code(ctx.nip);
1.1       root     8269:         }
1.1.1.6 ! root     8270:         LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",
1.1       root     8271:                     ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
1.1.1.5   root     8272:                     opc3(ctx.opcode), little_endian ? "little" : "big");
1.1       root     8273:         ctx.nip += 4;
                   8274:         table = env->opcodes;
1.1.1.6 ! root     8275:         num_insns++;
1.1       root     8276:         handler = table[opc1(ctx.opcode)];
                   8277:         if (is_indirect_opcode(handler)) {
                   8278:             table = ind_table(handler);
                   8279:             handler = table[opc2(ctx.opcode)];
                   8280:             if (is_indirect_opcode(handler)) {
                   8281:                 table = ind_table(handler);
                   8282:                 handler = table[opc3(ctx.opcode)];
                   8283:             }
                   8284:         }
                   8285:         /* Is opcode *REALLY* valid ? */
1.1.1.5   root     8286:         if (unlikely(handler->handler == &gen_invalid)) {
1.1.1.6 ! root     8287:             if (qemu_log_enabled()) {
        !          8288:                 qemu_log("invalid/unsupported opcode: "
        !          8289:                           "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
        !          8290:                           opc1(ctx.opcode), opc2(ctx.opcode),
        !          8291:                           opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
1.1       root     8292:             } else {
                   8293:                 printf("invalid/unsupported opcode: "
1.1.1.5   root     8294:                        "%02x - %02x - %02x (%08x) " ADDRX " %d\n",
1.1       root     8295:                        opc1(ctx.opcode), opc2(ctx.opcode),
1.1.1.5   root     8296:                        opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, (int)msr_ir);
1.1       root     8297:             }
1.1.1.5   root     8298:         } else {
                   8299:             if (unlikely((ctx.opcode & handler->inval) != 0)) {
1.1.1.6 ! root     8300:                 if (qemu_log_enabled()) {
        !          8301:                     qemu_log("invalid bits: %08x for opcode: "
        !          8302:                               "%02x - %02x - %02x (%08x) " ADDRX "\n",
        !          8303:                               ctx.opcode & handler->inval, opc1(ctx.opcode),
        !          8304:                               opc2(ctx.opcode), opc3(ctx.opcode),
        !          8305:                               ctx.opcode, ctx.nip - 4);
1.1       root     8306:                 } else {
                   8307:                     printf("invalid bits: %08x for opcode: "
1.1.1.5   root     8308:                            "%02x - %02x - %02x (%08x) " ADDRX "\n",
                   8309:                            ctx.opcode & handler->inval, opc1(ctx.opcode),
                   8310:                            opc2(ctx.opcode), opc3(ctx.opcode),
1.1       root     8311:                            ctx.opcode, ctx.nip - 4);
1.1.1.5   root     8312:                 }
1.1.1.6 ! root     8313:                 gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
1.1       root     8314:                 break;
                   8315:             }
                   8316:         }
                   8317:         (*(handler->handler))(&ctx);
1.1.1.5   root     8318: #if defined(DO_PPC_STATISTICS)
                   8319:         handler->count++;
                   8320: #endif
1.1       root     8321:         /* Check trace mode exceptions */
1.1.1.6 ! root     8322:         if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
        !          8323:                      (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
        !          8324:                      ctx.exception != POWERPC_SYSCALL &&
        !          8325:                      ctx.exception != POWERPC_EXCP_TRAP &&
        !          8326:                      ctx.exception != POWERPC_EXCP_BRANCH)) {
        !          8327:             gen_exception(ctxp, POWERPC_EXCP_TRACE);
1.1.1.5   root     8328:         } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
1.1.1.6 ! root     8329:                             (env->singlestep_enabled) ||
        !          8330:                             num_insns >= max_insns)) {
1.1.1.5   root     8331:             /* if we reach a page boundary or are single stepping, stop
                   8332:              * generation
1.1       root     8333:              */
                   8334:             break;
1.1.1.5   root     8335:         }
1.1       root     8336: #if defined (DO_SINGLE_STEP)
                   8337:         break;
                   8338: #endif
                   8339:     }
1.1.1.6 ! root     8340:     if (tb->cflags & CF_LAST_IO)
        !          8341:         gen_io_end();
1.1.1.5   root     8342:     if (ctx.exception == POWERPC_EXCP_NONE) {
1.1.1.2   root     8343:         gen_goto_tb(&ctx, 0, ctx.nip);
1.1.1.5   root     8344:     } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
1.1.1.6 ! root     8345:         if (unlikely(env->singlestep_enabled)) {
        !          8346:             gen_debug_exception(ctxp);
        !          8347:         }
1.1.1.5   root     8348:         /* Generate the return instruction */
1.1.1.6 ! root     8349:         tcg_gen_exit_tb(0);
1.1       root     8350:     }
1.1.1.6 ! root     8351:     gen_icount_end(tb, num_insns);
1.1       root     8352:     *gen_opc_ptr = INDEX_op_end;
1.1.1.5   root     8353:     if (unlikely(search_pc)) {
1.1       root     8354:         j = gen_opc_ptr - gen_opc_buf;
                   8355:         lj++;
                   8356:         while (lj <= j)
                   8357:             gen_opc_instr_start[lj++] = 0;
                   8358:     } else {
                   8359:         tb->size = ctx.nip - pc_start;
1.1.1.6 ! root     8360:         tb->icount = num_insns;
1.1       root     8361:     }
1.1.1.5   root     8362: #if defined(DEBUG_DISAS)
1.1.1.6 ! root     8363:     qemu_log_mask(CPU_LOG_TB_CPU, "---------------- excp: %04x\n", ctx.exception);
        !          8364:     log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
        !          8365:     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
1.1.1.5   root     8366:         int flags;
                   8367:         flags = env->bfd_mach;
1.1.1.6 ! root     8368:         flags |= ctx.le_mode << 16;
        !          8369:         qemu_log("IN: %s\n", lookup_symbol(pc_start));
        !          8370:         log_target_disas(pc_start, ctx.nip - pc_start, flags);
        !          8371:         qemu_log("\n");
1.1       root     8372:     }
                   8373: #endif
                   8374: }
                   8375: 
1.1.1.6 ! root     8376: void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
        !          8377: {
        !          8378:     gen_intermediate_code_internal(env, tb, 0);
        !          8379: }
        !          8380: 
        !          8381: void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
1.1       root     8382: {
1.1.1.6 ! root     8383:     gen_intermediate_code_internal(env, tb, 1);
1.1       root     8384: }
                   8385: 
1.1.1.6 ! root     8386: void gen_pc_load(CPUState *env, TranslationBlock *tb,
        !          8387:                 unsigned long searched_pc, int pc_pos, void *puc)
1.1       root     8388: {
1.1.1.6 ! root     8389:     env->nip = gen_opc_pc[pc_pos];
1.1       root     8390: }

unix.superglobalmegacorp.com

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