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

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