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

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

unix.superglobalmegacorp.com

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