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

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

unix.superglobalmegacorp.com

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