qemu/target/ppc/translate.c
<<
>>
Prefs
   1/*
   2 *  PowerPC emulation for qemu: main translation routines.
   3 *
   4 *  Copyright (c) 2003-2007 Jocelyn Mayer
   5 *  Copyright (C) 2011 Freescale Semiconductor, Inc.
   6 *
   7 * This library is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU Lesser General Public
   9 * License as published by the Free Software Foundation; either
  10 * version 2 of the License, or (at your option) any later version.
  11 *
  12 * This library is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15 * Lesser General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU Lesser General Public
  18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  19 */
  20
  21#include "qemu/osdep.h"
  22#include "cpu.h"
  23#include "internal.h"
  24#include "disas/disas.h"
  25#include "exec/exec-all.h"
  26#include "tcg-op.h"
  27#include "qemu/host-utils.h"
  28#include "exec/cpu_ldst.h"
  29
  30#include "exec/helper-proto.h"
  31#include "exec/helper-gen.h"
  32
  33#include "trace-tcg.h"
  34#include "exec/log.h"
  35
  36
  37#define CPU_SINGLE_STEP 0x1
  38#define CPU_BRANCH_STEP 0x2
  39#define GDBSTUB_SINGLE_STEP 0x4
  40
  41/* Include definitions for instructions classes and implementations flags */
  42//#define PPC_DEBUG_DISAS
  43//#define DO_PPC_STATISTICS
  44
  45#ifdef PPC_DEBUG_DISAS
  46#  define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
  47#else
  48#  define LOG_DISAS(...) do { } while (0)
  49#endif
  50/*****************************************************************************/
  51/* Code translation helpers                                                  */
  52
  53/* global register indexes */
  54static TCGv_env cpu_env;
  55static char cpu_reg_names[10*3 + 22*4 /* GPR */
  56    + 10*4 + 22*5 /* SPE GPRh */
  57    + 10*4 + 22*5 /* FPR */
  58    + 2*(10*6 + 22*7) /* AVRh, AVRl */
  59    + 10*5 + 22*6 /* VSR */
  60    + 8*5 /* CRF */];
  61static TCGv cpu_gpr[32];
  62static TCGv cpu_gprh[32];
  63static TCGv_i64 cpu_fpr[32];
  64static TCGv_i64 cpu_avrh[32], cpu_avrl[32];
  65static TCGv_i64 cpu_vsr[32];
  66static TCGv_i32 cpu_crf[8];
  67static TCGv cpu_nip;
  68static TCGv cpu_msr;
  69static TCGv cpu_ctr;
  70static TCGv cpu_lr;
  71#if defined(TARGET_PPC64)
  72static TCGv cpu_cfar;
  73#endif
  74static TCGv cpu_xer, cpu_so, cpu_ov, cpu_ca, cpu_ov32, cpu_ca32;
  75static TCGv cpu_reserve;
  76static TCGv cpu_reserve_val;
  77static TCGv cpu_fpscr;
  78static TCGv_i32 cpu_access_type;
  79
  80#include "exec/gen-icount.h"
  81
  82void ppc_translate_init(void)
  83{
  84    int i;
  85    char* p;
  86    size_t cpu_reg_names_size;
  87    static int done_init = 0;
  88
  89    if (done_init)
  90        return;
  91
  92    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
  93    tcg_ctx.tcg_env = cpu_env;
  94
  95    p = cpu_reg_names;
  96    cpu_reg_names_size = sizeof(cpu_reg_names);
  97
  98    for (i = 0; i < 8; i++) {
  99        snprintf(p, cpu_reg_names_size, "crf%d", i);
 100        cpu_crf[i] = tcg_global_mem_new_i32(cpu_env,
 101                                            offsetof(CPUPPCState, crf[i]), p);
 102        p += 5;
 103        cpu_reg_names_size -= 5;
 104    }
 105
 106    for (i = 0; i < 32; i++) {
 107        snprintf(p, cpu_reg_names_size, "r%d", i);
 108        cpu_gpr[i] = tcg_global_mem_new(cpu_env,
 109                                        offsetof(CPUPPCState, gpr[i]), p);
 110        p += (i < 10) ? 3 : 4;
 111        cpu_reg_names_size -= (i < 10) ? 3 : 4;
 112        snprintf(p, cpu_reg_names_size, "r%dH", i);
 113        cpu_gprh[i] = tcg_global_mem_new(cpu_env,
 114                                         offsetof(CPUPPCState, gprh[i]), p);
 115        p += (i < 10) ? 4 : 5;
 116        cpu_reg_names_size -= (i < 10) ? 4 : 5;
 117
 118        snprintf(p, cpu_reg_names_size, "fp%d", i);
 119        cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env,
 120                                            offsetof(CPUPPCState, fpr[i]), p);
 121        p += (i < 10) ? 4 : 5;
 122        cpu_reg_names_size -= (i < 10) ? 4 : 5;
 123
 124        snprintf(p, cpu_reg_names_size, "avr%dH", i);
 125#ifdef HOST_WORDS_BIGENDIAN
 126        cpu_avrh[i] = tcg_global_mem_new_i64(cpu_env,
 127                                             offsetof(CPUPPCState, avr[i].u64[0]), p);
 128#else
 129        cpu_avrh[i] = tcg_global_mem_new_i64(cpu_env,
 130                                             offsetof(CPUPPCState, avr[i].u64[1]), p);
 131#endif
 132        p += (i < 10) ? 6 : 7;
 133        cpu_reg_names_size -= (i < 10) ? 6 : 7;
 134
 135        snprintf(p, cpu_reg_names_size, "avr%dL", i);
 136#ifdef HOST_WORDS_BIGENDIAN
 137        cpu_avrl[i] = tcg_global_mem_new_i64(cpu_env,
 138                                             offsetof(CPUPPCState, avr[i].u64[1]), p);
 139#else
 140        cpu_avrl[i] = tcg_global_mem_new_i64(cpu_env,
 141                                             offsetof(CPUPPCState, avr[i].u64[0]), p);
 142#endif
 143        p += (i < 10) ? 6 : 7;
 144        cpu_reg_names_size -= (i < 10) ? 6 : 7;
 145        snprintf(p, cpu_reg_names_size, "vsr%d", i);
 146        cpu_vsr[i] = tcg_global_mem_new_i64(cpu_env,
 147                                            offsetof(CPUPPCState, vsr[i]), p);
 148        p += (i < 10) ? 5 : 6;
 149        cpu_reg_names_size -= (i < 10) ? 5 : 6;
 150    }
 151
 152    cpu_nip = tcg_global_mem_new(cpu_env,
 153                                 offsetof(CPUPPCState, nip), "nip");
 154
 155    cpu_msr = tcg_global_mem_new(cpu_env,
 156                                 offsetof(CPUPPCState, msr), "msr");
 157
 158    cpu_ctr = tcg_global_mem_new(cpu_env,
 159                                 offsetof(CPUPPCState, ctr), "ctr");
 160
 161    cpu_lr = tcg_global_mem_new(cpu_env,
 162                                offsetof(CPUPPCState, lr), "lr");
 163
 164#if defined(TARGET_PPC64)
 165    cpu_cfar = tcg_global_mem_new(cpu_env,
 166                                  offsetof(CPUPPCState, cfar), "cfar");
 167#endif
 168
 169    cpu_xer = tcg_global_mem_new(cpu_env,
 170                                 offsetof(CPUPPCState, xer), "xer");
 171    cpu_so = tcg_global_mem_new(cpu_env,
 172                                offsetof(CPUPPCState, so), "SO");
 173    cpu_ov = tcg_global_mem_new(cpu_env,
 174                                offsetof(CPUPPCState, ov), "OV");
 175    cpu_ca = tcg_global_mem_new(cpu_env,
 176                                offsetof(CPUPPCState, ca), "CA");
 177    cpu_ov32 = tcg_global_mem_new(cpu_env,
 178                                  offsetof(CPUPPCState, ov32), "OV32");
 179    cpu_ca32 = tcg_global_mem_new(cpu_env,
 180                                  offsetof(CPUPPCState, ca32), "CA32");
 181
 182    cpu_reserve = tcg_global_mem_new(cpu_env,
 183                                     offsetof(CPUPPCState, reserve_addr),
 184                                     "reserve_addr");
 185    cpu_reserve_val = tcg_global_mem_new(cpu_env,
 186                                     offsetof(CPUPPCState, reserve_val),
 187                                     "reserve_val");
 188
 189    cpu_fpscr = tcg_global_mem_new(cpu_env,
 190                                   offsetof(CPUPPCState, fpscr), "fpscr");
 191
 192    cpu_access_type = tcg_global_mem_new_i32(cpu_env,
 193                                             offsetof(CPUPPCState, access_type), "access_type");
 194
 195    done_init = 1;
 196}
 197
 198/* internal defines */
 199struct DisasContext {
 200    struct TranslationBlock *tb;
 201    target_ulong nip;
 202    uint32_t opcode;
 203    uint32_t exception;
 204    /* Routine used to access memory */
 205    bool pr, hv, dr, le_mode;
 206    bool lazy_tlb_flush;
 207    bool need_access_type;
 208    int mem_idx;
 209    int access_type;
 210    /* Translation flags */
 211    TCGMemOp default_tcg_memop_mask;
 212#if defined(TARGET_PPC64)
 213    bool sf_mode;
 214    bool has_cfar;
 215#endif
 216    bool fpu_enabled;
 217    bool altivec_enabled;
 218    bool vsx_enabled;
 219    bool spe_enabled;
 220    bool tm_enabled;
 221    bool gtse;
 222    ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
 223    int singlestep_enabled;
 224    uint64_t insns_flags;
 225    uint64_t insns_flags2;
 226};
 227
 228/* Return true iff byteswap is needed in a scalar memop */
 229static inline bool need_byteswap(const DisasContext *ctx)
 230{
 231#if defined(TARGET_WORDS_BIGENDIAN)
 232     return ctx->le_mode;
 233#else
 234     return !ctx->le_mode;
 235#endif
 236}
 237
 238/* True when active word size < size of target_long.  */
 239#ifdef TARGET_PPC64
 240# define NARROW_MODE(C)  (!(C)->sf_mode)
 241#else
 242# define NARROW_MODE(C)  0
 243#endif
 244
 245struct opc_handler_t {
 246    /* invalid bits for instruction 1 (Rc(opcode) == 0) */
 247    uint32_t inval1;
 248    /* invalid bits for instruction 2 (Rc(opcode) == 1) */
 249    uint32_t inval2;
 250    /* instruction type */
 251    uint64_t type;
 252    /* extended instruction type */
 253    uint64_t type2;
 254    /* handler */
 255    void (*handler)(DisasContext *ctx);
 256#if defined(DO_PPC_STATISTICS) || defined(PPC_DUMP_CPU)
 257    const char *oname;
 258#endif
 259#if defined(DO_PPC_STATISTICS)
 260    uint64_t count;
 261#endif
 262};
 263
 264static inline void gen_set_access_type(DisasContext *ctx, int access_type)
 265{
 266    if (ctx->need_access_type && ctx->access_type != access_type) {
 267        tcg_gen_movi_i32(cpu_access_type, access_type);
 268        ctx->access_type = access_type;
 269    }
 270}
 271
 272static inline void gen_update_nip(DisasContext *ctx, target_ulong nip)
 273{
 274    if (NARROW_MODE(ctx)) {
 275        nip = (uint32_t)nip;
 276    }
 277    tcg_gen_movi_tl(cpu_nip, nip);
 278}
 279
 280static void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
 281{
 282    TCGv_i32 t0, t1;
 283
 284    /* These are all synchronous exceptions, we set the PC back to
 285     * the faulting instruction
 286     */
 287    if (ctx->exception == POWERPC_EXCP_NONE) {
 288        gen_update_nip(ctx, ctx->nip - 4);
 289    }
 290    t0 = tcg_const_i32(excp);
 291    t1 = tcg_const_i32(error);
 292    gen_helper_raise_exception_err(cpu_env, t0, t1);
 293    tcg_temp_free_i32(t0);
 294    tcg_temp_free_i32(t1);
 295    ctx->exception = (excp);
 296}
 297
 298static void gen_exception(DisasContext *ctx, uint32_t excp)
 299{
 300    TCGv_i32 t0;
 301
 302    /* These are all synchronous exceptions, we set the PC back to
 303     * the faulting instruction
 304     */
 305    if (ctx->exception == POWERPC_EXCP_NONE) {
 306        gen_update_nip(ctx, ctx->nip - 4);
 307    }
 308    t0 = tcg_const_i32(excp);
 309    gen_helper_raise_exception(cpu_env, t0);
 310    tcg_temp_free_i32(t0);
 311    ctx->exception = (excp);
 312}
 313
 314static void gen_exception_nip(DisasContext *ctx, uint32_t excp,
 315                              target_ulong nip)
 316{
 317    TCGv_i32 t0;
 318
 319    gen_update_nip(ctx, nip);
 320    t0 = tcg_const_i32(excp);
 321    gen_helper_raise_exception(cpu_env, t0);
 322    tcg_temp_free_i32(t0);
 323    ctx->exception = (excp);
 324}
 325
 326static void gen_debug_exception(DisasContext *ctx)
 327{
 328    TCGv_i32 t0;
 329
 330    /* These are all synchronous exceptions, we set the PC back to
 331     * the faulting instruction
 332     */
 333    if ((ctx->exception != POWERPC_EXCP_BRANCH) &&
 334        (ctx->exception != POWERPC_EXCP_SYNC)) {
 335        gen_update_nip(ctx, ctx->nip);
 336    }
 337    t0 = tcg_const_i32(EXCP_DEBUG);
 338    gen_helper_raise_exception(cpu_env, t0);
 339    tcg_temp_free_i32(t0);
 340}
 341
 342static inline void gen_inval_exception(DisasContext *ctx, uint32_t error)
 343{
 344    /* Will be converted to program check if needed */
 345    gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_INVAL | error);
 346}
 347
 348static inline void gen_priv_exception(DisasContext *ctx, uint32_t error)
 349{
 350    gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_PRIV | error);
 351}
 352
 353static inline void gen_hvpriv_exception(DisasContext *ctx, uint32_t error)
 354{
 355    /* Will be converted to program check if needed */
 356    gen_exception_err(ctx, POWERPC_EXCP_HV_EMU, POWERPC_EXCP_PRIV | error);
 357}
 358
 359/* Stop translation */
 360static inline void gen_stop_exception(DisasContext *ctx)
 361{
 362    gen_update_nip(ctx, ctx->nip);
 363    ctx->exception = POWERPC_EXCP_STOP;
 364}
 365
 366#ifndef CONFIG_USER_ONLY
 367/* No need to update nip here, as execution flow will change */
 368static inline void gen_sync_exception(DisasContext *ctx)
 369{
 370    ctx->exception = POWERPC_EXCP_SYNC;
 371}
 372#endif
 373
 374#define GEN_HANDLER(name, opc1, opc2, opc3, inval, type)                      \
 375GEN_OPCODE(name, opc1, opc2, opc3, inval, type, PPC_NONE)
 376
 377#define GEN_HANDLER_E(name, opc1, opc2, opc3, inval, type, type2)             \
 378GEN_OPCODE(name, opc1, opc2, opc3, inval, type, type2)
 379
 380#define GEN_HANDLER2(name, onam, opc1, opc2, opc3, inval, type)               \
 381GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, PPC_NONE)
 382
 383#define GEN_HANDLER2_E(name, onam, opc1, opc2, opc3, inval, type, type2)      \
 384GEN_OPCODE2(name, onam, opc1, opc2, opc3, inval, type, type2)
 385
 386#define GEN_HANDLER_E_2(name, opc1, opc2, opc3, opc4, inval, type, type2)     \
 387GEN_OPCODE3(name, opc1, opc2, opc3, opc4, inval, type, type2)
 388
 389#define GEN_HANDLER2_E_2(name, onam, opc1, opc2, opc3, opc4, inval, typ, typ2) \
 390GEN_OPCODE4(name, onam, opc1, opc2, opc3, opc4, inval, typ, typ2)
 391
 392typedef struct opcode_t {
 393    unsigned char opc1, opc2, opc3, opc4;
 394#if HOST_LONG_BITS == 64 /* Explicitly align to 64 bits */
 395    unsigned char pad[4];
 396#endif
 397    opc_handler_t handler;
 398    const char *oname;
 399} opcode_t;
 400
 401/* Helpers for priv. check */
 402#define GEN_PRIV                                                \
 403    do {                                                        \
 404        gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; \
 405    } while (0)
 406
 407#if defined(CONFIG_USER_ONLY)
 408#define CHK_HV GEN_PRIV
 409#define CHK_SV GEN_PRIV
 410#define CHK_HVRM GEN_PRIV
 411#else
 412#define CHK_HV                                                          \
 413    do {                                                                \
 414        if (unlikely(ctx->pr || !ctx->hv)) {                            \
 415            GEN_PRIV;                                                   \
 416        }                                                               \
 417    } while (0)
 418#define CHK_SV                   \
 419    do {                         \
 420        if (unlikely(ctx->pr)) { \
 421            GEN_PRIV;            \
 422        }                        \
 423    } while (0)
 424#define CHK_HVRM                                            \
 425    do {                                                    \
 426        if (unlikely(ctx->pr || !ctx->hv || ctx->dr)) {     \
 427            GEN_PRIV;                                       \
 428        }                                                   \
 429    } while (0)
 430#endif
 431
 432#define CHK_NONE
 433
 434/*****************************************************************************/
 435/* PowerPC instructions table                                                */
 436
 437#if defined(DO_PPC_STATISTICS)
 438#define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)                    \
 439{                                                                             \
 440    .opc1 = op1,                                                              \
 441    .opc2 = op2,                                                              \
 442    .opc3 = op3,                                                              \
 443    .opc4 = 0xff,                                                             \
 444    .handler = {                                                              \
 445        .inval1  = invl,                                                      \
 446        .type = _typ,                                                         \
 447        .type2 = _typ2,                                                       \
 448        .handler = &gen_##name,                                               \
 449        .oname = stringify(name),                                             \
 450    },                                                                        \
 451    .oname = stringify(name),                                                 \
 452}
 453#define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2)       \
 454{                                                                             \
 455    .opc1 = op1,                                                              \
 456    .opc2 = op2,                                                              \
 457    .opc3 = op3,                                                              \
 458    .opc4 = 0xff,                                                             \
 459    .handler = {                                                              \
 460        .inval1  = invl1,                                                     \
 461        .inval2  = invl2,                                                     \
 462        .type = _typ,                                                         \
 463        .type2 = _typ2,                                                       \
 464        .handler = &gen_##name,                                               \
 465        .oname = stringify(name),                                             \
 466    },                                                                        \
 467    .oname = stringify(name),                                                 \
 468}
 469#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2)             \
 470{                                                                             \
 471    .opc1 = op1,                                                              \
 472    .opc2 = op2,                                                              \
 473    .opc3 = op3,                                                              \
 474    .opc4 = 0xff,                                                             \
 475    .handler = {                                                              \
 476        .inval1  = invl,                                                      \
 477        .type = _typ,                                                         \
 478        .type2 = _typ2,                                                       \
 479        .handler = &gen_##name,                                               \
 480        .oname = onam,                                                        \
 481    },                                                                        \
 482    .oname = onam,                                                            \
 483}
 484#define GEN_OPCODE3(name, op1, op2, op3, op4, invl, _typ, _typ2)              \
 485{                                                                             \
 486    .opc1 = op1,                                                              \
 487    .opc2 = op2,                                                              \
 488    .opc3 = op3,                                                              \
 489    .opc4 = op4,                                                              \
 490    .handler = {                                                              \
 491        .inval1  = invl,                                                      \
 492        .type = _typ,                                                         \
 493        .type2 = _typ2,                                                       \
 494        .handler = &gen_##name,                                               \
 495        .oname = stringify(name),                                             \
 496    },                                                                        \
 497    .oname = stringify(name),                                                 \
 498}
 499#define GEN_OPCODE4(name, onam, op1, op2, op3, op4, invl, _typ, _typ2)        \
 500{                                                                             \
 501    .opc1 = op1,                                                              \
 502    .opc2 = op2,                                                              \
 503    .opc3 = op3,                                                              \
 504    .opc4 = op4,                                                              \
 505    .handler = {                                                              \
 506        .inval1  = invl,                                                      \
 507        .type = _typ,                                                         \
 508        .type2 = _typ2,                                                       \
 509        .handler = &gen_##name,                                               \
 510        .oname = onam,                                                        \
 511    },                                                                        \
 512    .oname = onam,                                                            \
 513}
 514#else
 515#define GEN_OPCODE(name, op1, op2, op3, invl, _typ, _typ2)                    \
 516{                                                                             \
 517    .opc1 = op1,                                                              \
 518    .opc2 = op2,                                                              \
 519    .opc3 = op3,                                                              \
 520    .opc4 = 0xff,                                                             \
 521    .handler = {                                                              \
 522        .inval1  = invl,                                                      \
 523        .type = _typ,                                                         \
 524        .type2 = _typ2,                                                       \
 525        .handler = &gen_##name,                                               \
 526    },                                                                        \
 527    .oname = stringify(name),                                                 \
 528}
 529#define GEN_OPCODE_DUAL(name, op1, op2, op3, invl1, invl2, _typ, _typ2)       \
 530{                                                                             \
 531    .opc1 = op1,                                                              \
 532    .opc2 = op2,                                                              \
 533    .opc3 = op3,                                                              \
 534    .opc4 = 0xff,                                                             \
 535    .handler = {                                                              \
 536        .inval1  = invl1,                                                     \
 537        .inval2  = invl2,                                                     \
 538        .type = _typ,                                                         \
 539        .type2 = _typ2,                                                       \
 540        .handler = &gen_##name,                                               \
 541    },                                                                        \
 542    .oname = stringify(name),                                                 \
 543}
 544#define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ, _typ2)             \
 545{                                                                             \
 546    .opc1 = op1,                                                              \
 547    .opc2 = op2,                                                              \
 548    .opc3 = op3,                                                              \
 549    .opc4 = 0xff,                                                             \
 550    .handler = {                                                              \
 551        .inval1  = invl,                                                      \
 552        .type = _typ,                                                         \
 553        .type2 = _typ2,                                                       \
 554        .handler = &gen_##name,                                               \
 555    },                                                                        \
 556    .oname = onam,                                                            \
 557}
 558#define GEN_OPCODE3(name, op1, op2, op3, op4, invl, _typ, _typ2)              \
 559{                                                                             \
 560    .opc1 = op1,                                                              \
 561    .opc2 = op2,                                                              \
 562    .opc3 = op3,                                                              \
 563    .opc4 = op4,                                                              \
 564    .handler = {                                                              \
 565        .inval1  = invl,                                                      \
 566        .type = _typ,                                                         \
 567        .type2 = _typ2,                                                       \
 568        .handler = &gen_##name,                                               \
 569    },                                                                        \
 570    .oname = stringify(name),                                                 \
 571}
 572#define GEN_OPCODE4(name, onam, op1, op2, op3, op4, invl, _typ, _typ2)        \
 573{                                                                             \
 574    .opc1 = op1,                                                              \
 575    .opc2 = op2,                                                              \
 576    .opc3 = op3,                                                              \
 577    .opc4 = op4,                                                              \
 578    .handler = {                                                              \
 579        .inval1  = invl,                                                      \
 580        .type = _typ,                                                         \
 581        .type2 = _typ2,                                                       \
 582        .handler = &gen_##name,                                               \
 583    },                                                                        \
 584    .oname = onam,                                                            \
 585}
 586#endif
 587
 588/* SPR load/store helpers */
 589static inline void gen_load_spr(TCGv t, int reg)
 590{
 591    tcg_gen_ld_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg]));
 592}
 593
 594static inline void gen_store_spr(int reg, TCGv t)
 595{
 596    tcg_gen_st_tl(t, cpu_env, offsetof(CPUPPCState, spr[reg]));
 597}
 598
 599/* Invalid instruction */
 600static void gen_invalid(DisasContext *ctx)
 601{
 602    gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
 603}
 604
 605static opc_handler_t invalid_handler = {
 606    .inval1  = 0xFFFFFFFF,
 607    .inval2  = 0xFFFFFFFF,
 608    .type    = PPC_NONE,
 609    .type2   = PPC_NONE,
 610    .handler = gen_invalid,
 611};
 612
 613/***                           Integer comparison                          ***/
 614
 615static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
 616{
 617    TCGv t0 = tcg_temp_new();
 618    TCGv_i32 t1 = tcg_temp_new_i32();
 619
 620    tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_so);
 621
 622    tcg_gen_setcond_tl((s ? TCG_COND_LT: TCG_COND_LTU), t0, arg0, arg1);
 623    tcg_gen_trunc_tl_i32(t1, t0);
 624    tcg_gen_shli_i32(t1, t1, CRF_LT_BIT);
 625    tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
 626
 627    tcg_gen_setcond_tl((s ? TCG_COND_GT: TCG_COND_GTU), t0, arg0, arg1);
 628    tcg_gen_trunc_tl_i32(t1, t0);
 629    tcg_gen_shli_i32(t1, t1, CRF_GT_BIT);
 630    tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
 631
 632    tcg_gen_setcond_tl(TCG_COND_EQ, t0, arg0, arg1);
 633    tcg_gen_trunc_tl_i32(t1, t0);
 634    tcg_gen_shli_i32(t1, t1, CRF_EQ_BIT);
 635    tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
 636
 637    tcg_temp_free(t0);
 638    tcg_temp_free_i32(t1);
 639}
 640
 641static inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
 642{
 643    TCGv t0 = tcg_const_tl(arg1);
 644    gen_op_cmp(arg0, t0, s, crf);
 645    tcg_temp_free(t0);
 646}
 647
 648static inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
 649{
 650    TCGv t0, t1;
 651    t0 = tcg_temp_new();
 652    t1 = tcg_temp_new();
 653    if (s) {
 654        tcg_gen_ext32s_tl(t0, arg0);
 655        tcg_gen_ext32s_tl(t1, arg1);
 656    } else {
 657        tcg_gen_ext32u_tl(t0, arg0);
 658        tcg_gen_ext32u_tl(t1, arg1);
 659    }
 660    gen_op_cmp(t0, t1, s, crf);
 661    tcg_temp_free(t1);
 662    tcg_temp_free(t0);
 663}
 664
 665static inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf)
 666{
 667    TCGv t0 = tcg_const_tl(arg1);
 668    gen_op_cmp32(arg0, t0, s, crf);
 669    tcg_temp_free(t0);
 670}
 671
 672static inline void gen_set_Rc0(DisasContext *ctx, TCGv reg)
 673{
 674    if (NARROW_MODE(ctx)) {
 675        gen_op_cmpi32(reg, 0, 1, 0);
 676    } else {
 677        gen_op_cmpi(reg, 0, 1, 0);
 678    }
 679}
 680
 681/* cmp */
 682static void gen_cmp(DisasContext *ctx)
 683{
 684    if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
 685        gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
 686                   1, crfD(ctx->opcode));
 687    } else {
 688        gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
 689                     1, crfD(ctx->opcode));
 690    }
 691}
 692
 693/* cmpi */
 694static void gen_cmpi(DisasContext *ctx)
 695{
 696    if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
 697        gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
 698                    1, crfD(ctx->opcode));
 699    } else {
 700        gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], SIMM(ctx->opcode),
 701                      1, crfD(ctx->opcode));
 702    }
 703}
 704
 705/* cmpl */
 706static void gen_cmpl(DisasContext *ctx)
 707{
 708    if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
 709        gen_op_cmp(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
 710                   0, crfD(ctx->opcode));
 711    } else {
 712        gen_op_cmp32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
 713                     0, crfD(ctx->opcode));
 714    }
 715}
 716
 717/* cmpli */
 718static void gen_cmpli(DisasContext *ctx)
 719{
 720    if ((ctx->opcode & 0x00200000) && (ctx->insns_flags & PPC_64B)) {
 721        gen_op_cmpi(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
 722                    0, crfD(ctx->opcode));
 723    } else {
 724        gen_op_cmpi32(cpu_gpr[rA(ctx->opcode)], UIMM(ctx->opcode),
 725                      0, crfD(ctx->opcode));
 726    }
 727}
 728
 729/* cmprb - range comparison: isupper, isaplha, islower*/
 730static void gen_cmprb(DisasContext *ctx)
 731{
 732    TCGv_i32 src1 = tcg_temp_new_i32();
 733    TCGv_i32 src2 = tcg_temp_new_i32();
 734    TCGv_i32 src2lo = tcg_temp_new_i32();
 735    TCGv_i32 src2hi = tcg_temp_new_i32();
 736    TCGv_i32 crf = cpu_crf[crfD(ctx->opcode)];
 737
 738    tcg_gen_trunc_tl_i32(src1, cpu_gpr[rA(ctx->opcode)]);
 739    tcg_gen_trunc_tl_i32(src2, cpu_gpr[rB(ctx->opcode)]);
 740
 741    tcg_gen_andi_i32(src1, src1, 0xFF);
 742    tcg_gen_ext8u_i32(src2lo, src2);
 743    tcg_gen_shri_i32(src2, src2, 8);
 744    tcg_gen_ext8u_i32(src2hi, src2);
 745
 746    tcg_gen_setcond_i32(TCG_COND_LEU, src2lo, src2lo, src1);
 747    tcg_gen_setcond_i32(TCG_COND_LEU, src2hi, src1, src2hi);
 748    tcg_gen_and_i32(crf, src2lo, src2hi);
 749
 750    if (ctx->opcode & 0x00200000) {
 751        tcg_gen_shri_i32(src2, src2, 8);
 752        tcg_gen_ext8u_i32(src2lo, src2);
 753        tcg_gen_shri_i32(src2, src2, 8);
 754        tcg_gen_ext8u_i32(src2hi, src2);
 755        tcg_gen_setcond_i32(TCG_COND_LEU, src2lo, src2lo, src1);
 756        tcg_gen_setcond_i32(TCG_COND_LEU, src2hi, src1, src2hi);
 757        tcg_gen_and_i32(src2lo, src2lo, src2hi);
 758        tcg_gen_or_i32(crf, crf, src2lo);
 759    }
 760    tcg_gen_shli_i32(crf, crf, CRF_GT_BIT);
 761    tcg_temp_free_i32(src1);
 762    tcg_temp_free_i32(src2);
 763    tcg_temp_free_i32(src2lo);
 764    tcg_temp_free_i32(src2hi);
 765}
 766
 767#if defined(TARGET_PPC64)
 768/* cmpeqb */
 769static void gen_cmpeqb(DisasContext *ctx)
 770{
 771    gen_helper_cmpeqb(cpu_crf[crfD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
 772                      cpu_gpr[rB(ctx->opcode)]);
 773}
 774#endif
 775
 776/* isel (PowerPC 2.03 specification) */
 777static void gen_isel(DisasContext *ctx)
 778{
 779    uint32_t bi = rC(ctx->opcode);
 780    uint32_t mask = 0x08 >> (bi & 0x03);
 781    TCGv t0 = tcg_temp_new();
 782    TCGv zr;
 783
 784    tcg_gen_extu_i32_tl(t0, cpu_crf[bi >> 2]);
 785    tcg_gen_andi_tl(t0, t0, mask);
 786
 787    zr = tcg_const_tl(0);
 788    tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rD(ctx->opcode)], t0, zr,
 789                       rA(ctx->opcode) ? cpu_gpr[rA(ctx->opcode)] : zr,
 790                       cpu_gpr[rB(ctx->opcode)]);
 791    tcg_temp_free(zr);
 792    tcg_temp_free(t0);
 793}
 794
 795/* cmpb: PowerPC 2.05 specification */
 796static void gen_cmpb(DisasContext *ctx)
 797{
 798    gen_helper_cmpb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],
 799                    cpu_gpr[rB(ctx->opcode)]);
 800}
 801
 802/***                           Integer arithmetic                          ***/
 803
 804static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0,
 805                                           TCGv arg1, TCGv arg2, int sub)
 806{
 807    TCGv t0 = tcg_temp_new();
 808
 809    tcg_gen_xor_tl(cpu_ov, arg0, arg2);
 810    tcg_gen_xor_tl(t0, arg1, arg2);
 811    if (sub) {
 812        tcg_gen_and_tl(cpu_ov, cpu_ov, t0);
 813    } else {
 814        tcg_gen_andc_tl(cpu_ov, cpu_ov, t0);
 815    }
 816    tcg_temp_free(t0);
 817    if (NARROW_MODE(ctx)) {
 818        tcg_gen_extract_tl(cpu_ov, cpu_ov, 31, 1);
 819        if (is_isa300(ctx)) {
 820            tcg_gen_mov_tl(cpu_ov32, cpu_ov);
 821        }
 822    } else {
 823        if (is_isa300(ctx)) {
 824            tcg_gen_extract_tl(cpu_ov32, cpu_ov, 31, 1);
 825        }
 826        tcg_gen_extract_tl(cpu_ov, cpu_ov, TARGET_LONG_BITS - 1, 1);
 827    }
 828    tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
 829}
 830
 831static inline void gen_op_arith_compute_ca32(DisasContext *ctx,
 832                                             TCGv res, TCGv arg0, TCGv arg1,
 833                                             int sub)
 834{
 835    TCGv t0;
 836
 837    if (!is_isa300(ctx)) {
 838        return;
 839    }
 840
 841    t0 = tcg_temp_new();
 842    if (sub) {
 843        tcg_gen_eqv_tl(t0, arg0, arg1);
 844    } else {
 845        tcg_gen_xor_tl(t0, arg0, arg1);
 846    }
 847    tcg_gen_xor_tl(t0, t0, res);
 848    tcg_gen_extract_tl(cpu_ca32, t0, 32, 1);
 849    tcg_temp_free(t0);
 850}
 851
 852/* Common add function */
 853static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1,
 854                                    TCGv arg2, bool add_ca, bool compute_ca,
 855                                    bool compute_ov, bool compute_rc0)
 856{
 857    TCGv t0 = ret;
 858
 859    if (compute_ca || compute_ov) {
 860        t0 = tcg_temp_new();
 861    }
 862
 863    if (compute_ca) {
 864        if (NARROW_MODE(ctx)) {
 865            /* Caution: a non-obvious corner case of the spec is that we
 866               must produce the *entire* 64-bit addition, but produce the
 867               carry into bit 32.  */
 868            TCGv t1 = tcg_temp_new();
 869            tcg_gen_xor_tl(t1, arg1, arg2);        /* add without carry */
 870            tcg_gen_add_tl(t0, arg1, arg2);
 871            if (add_ca) {
 872                tcg_gen_add_tl(t0, t0, cpu_ca);
 873            }
 874            tcg_gen_xor_tl(cpu_ca, t0, t1);        /* bits changed w/ carry */
 875            tcg_temp_free(t1);
 876            tcg_gen_extract_tl(cpu_ca, cpu_ca, 32, 1);
 877            if (is_isa300(ctx)) {
 878                tcg_gen_mov_tl(cpu_ca32, cpu_ca);
 879            }
 880        } else {
 881            TCGv zero = tcg_const_tl(0);
 882            if (add_ca) {
 883                tcg_gen_add2_tl(t0, cpu_ca, arg1, zero, cpu_ca, zero);
 884                tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, arg2, zero);
 885            } else {
 886                tcg_gen_add2_tl(t0, cpu_ca, arg1, zero, arg2, zero);
 887            }
 888            gen_op_arith_compute_ca32(ctx, t0, arg1, arg2, 0);
 889            tcg_temp_free(zero);
 890        }
 891    } else {
 892        tcg_gen_add_tl(t0, arg1, arg2);
 893        if (add_ca) {
 894            tcg_gen_add_tl(t0, t0, cpu_ca);
 895        }
 896    }
 897
 898    if (compute_ov) {
 899        gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0);
 900    }
 901    if (unlikely(compute_rc0)) {
 902        gen_set_Rc0(ctx, t0);
 903    }
 904
 905    if (!TCGV_EQUAL(t0, ret)) {
 906        tcg_gen_mov_tl(ret, t0);
 907        tcg_temp_free(t0);
 908    }
 909}
 910/* Add functions with two operands */
 911#define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
 912static void glue(gen_, name)(DisasContext *ctx)                               \
 913{                                                                             \
 914    gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
 915                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
 916                     add_ca, compute_ca, compute_ov, Rc(ctx->opcode));        \
 917}
 918/* Add functions with one operand and one immediate */
 919#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
 920                                add_ca, compute_ca, compute_ov)               \
 921static void glue(gen_, name)(DisasContext *ctx)                               \
 922{                                                                             \
 923    TCGv t0 = tcg_const_tl(const_val);                                        \
 924    gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)],                           \
 925                     cpu_gpr[rA(ctx->opcode)], t0,                            \
 926                     add_ca, compute_ca, compute_ov, Rc(ctx->opcode));        \
 927    tcg_temp_free(t0);                                                        \
 928}
 929
 930/* add  add.  addo  addo. */
 931GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
 932GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
 933/* addc  addc.  addco  addco. */
 934GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
 935GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
 936/* adde  adde.  addeo  addeo. */
 937GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
 938GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
 939/* addme  addme.  addmeo  addmeo.  */
 940GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
 941GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
 942/* addze  addze.  addzeo  addzeo.*/
 943GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
 944GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
 945/* addi */
 946static void gen_addi(DisasContext *ctx)
 947{
 948    target_long simm = SIMM(ctx->opcode);
 949
 950    if (rA(ctx->opcode) == 0) {
 951        /* li case */
 952        tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm);
 953    } else {
 954        tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)],
 955                        cpu_gpr[rA(ctx->opcode)], simm);
 956    }
 957}
 958/* addic  addic.*/
 959static inline void gen_op_addic(DisasContext *ctx, bool compute_rc0)
 960{
 961    TCGv c = tcg_const_tl(SIMM(ctx->opcode));
 962    gen_op_arith_add(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
 963                     c, 0, 1, 0, compute_rc0);
 964    tcg_temp_free(c);
 965}
 966
 967static void gen_addic(DisasContext *ctx)
 968{
 969    gen_op_addic(ctx, 0);
 970}
 971
 972static void gen_addic_(DisasContext *ctx)
 973{
 974    gen_op_addic(ctx, 1);
 975}
 976
 977/* addis */
 978static void gen_addis(DisasContext *ctx)
 979{
 980    target_long simm = SIMM(ctx->opcode);
 981
 982    if (rA(ctx->opcode) == 0) {
 983        /* lis case */
 984        tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], simm << 16);
 985    } else {
 986        tcg_gen_addi_tl(cpu_gpr[rD(ctx->opcode)],
 987                        cpu_gpr[rA(ctx->opcode)], simm << 16);
 988    }
 989}
 990
 991/* addpcis */
 992static void gen_addpcis(DisasContext *ctx)
 993{
 994    target_long d = DX(ctx->opcode);
 995
 996    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], ctx->nip + (d << 16));
 997}
 998
 999static inline void gen_op_arith_divw(DisasContext *ctx, TCGv ret, TCGv arg1,
1000                                     TCGv arg2, int sign, int compute_ov)
1001{
1002    TCGv_i32 t0 = tcg_temp_new_i32();
1003    TCGv_i32 t1 = tcg_temp_new_i32();
1004    TCGv_i32 t2 = tcg_temp_new_i32();
1005    TCGv_i32 t3 = tcg_temp_new_i32();
1006
1007    tcg_gen_trunc_tl_i32(t0, arg1);
1008    tcg_gen_trunc_tl_i32(t1, arg2);
1009    if (sign) {
1010        tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t0, INT_MIN);
1011        tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, -1);
1012        tcg_gen_and_i32(t2, t2, t3);
1013        tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, 0);
1014        tcg_gen_or_i32(t2, t2, t3);
1015        tcg_gen_movi_i32(t3, 0);
1016        tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1);
1017        tcg_gen_div_i32(t3, t0, t1);
1018        tcg_gen_extu_i32_tl(ret, t3);
1019    } else {
1020        tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t1, 0);
1021        tcg_gen_movi_i32(t3, 0);
1022        tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1);
1023        tcg_gen_divu_i32(t3, t0, t1);
1024        tcg_gen_extu_i32_tl(ret, t3);
1025    }
1026    if (compute_ov) {
1027        tcg_gen_extu_i32_tl(cpu_ov, t2);
1028        if (is_isa300(ctx)) {
1029            tcg_gen_extu_i32_tl(cpu_ov32, t2);
1030        }
1031        tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
1032    }
1033    tcg_temp_free_i32(t0);
1034    tcg_temp_free_i32(t1);
1035    tcg_temp_free_i32(t2);
1036    tcg_temp_free_i32(t3);
1037
1038    if (unlikely(Rc(ctx->opcode) != 0))
1039        gen_set_Rc0(ctx, ret);
1040}
1041/* Div functions */
1042#define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
1043static void glue(gen_, name)(DisasContext *ctx)                                       \
1044{                                                                             \
1045    gen_op_arith_divw(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1046                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],      \
1047                     sign, compute_ov);                                       \
1048}
1049/* divwu  divwu.  divwuo  divwuo.   */
1050GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0);
1051GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1);
1052/* divw  divw.  divwo  divwo.   */
1053GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0);
1054GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1);
1055
1056/* div[wd]eu[o][.] */
1057#define GEN_DIVE(name, hlpr, compute_ov)                                      \
1058static void gen_##name(DisasContext *ctx)                                     \
1059{                                                                             \
1060    TCGv_i32 t0 = tcg_const_i32(compute_ov);                                  \
1061    gen_helper_##hlpr(cpu_gpr[rD(ctx->opcode)], cpu_env,                      \
1062                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0); \
1063    tcg_temp_free_i32(t0);                                                    \
1064    if (unlikely(Rc(ctx->opcode) != 0)) {                                     \
1065        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);                           \
1066    }                                                                         \
1067}
1068
1069GEN_DIVE(divweu, divweu, 0);
1070GEN_DIVE(divweuo, divweu, 1);
1071GEN_DIVE(divwe, divwe, 0);
1072GEN_DIVE(divweo, divwe, 1);
1073
1074#if defined(TARGET_PPC64)
1075static inline void gen_op_arith_divd(DisasContext *ctx, TCGv ret, TCGv arg1,
1076                                     TCGv arg2, int sign, int compute_ov)
1077{
1078    TCGv_i64 t0 = tcg_temp_new_i64();
1079    TCGv_i64 t1 = tcg_temp_new_i64();
1080    TCGv_i64 t2 = tcg_temp_new_i64();
1081    TCGv_i64 t3 = tcg_temp_new_i64();
1082
1083    tcg_gen_mov_i64(t0, arg1);
1084    tcg_gen_mov_i64(t1, arg2);
1085    if (sign) {
1086        tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t0, INT64_MIN);
1087        tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, -1);
1088        tcg_gen_and_i64(t2, t2, t3);
1089        tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, 0);
1090        tcg_gen_or_i64(t2, t2, t3);
1091        tcg_gen_movi_i64(t3, 0);
1092        tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1);
1093        tcg_gen_div_i64(ret, t0, t1);
1094    } else {
1095        tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t1, 0);
1096        tcg_gen_movi_i64(t3, 0);
1097        tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1);
1098        tcg_gen_divu_i64(ret, t0, t1);
1099    }
1100    if (compute_ov) {
1101        tcg_gen_mov_tl(cpu_ov, t2);
1102        if (is_isa300(ctx)) {
1103            tcg_gen_mov_tl(cpu_ov32, t2);
1104        }
1105        tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
1106    }
1107    tcg_temp_free_i64(t0);
1108    tcg_temp_free_i64(t1);
1109    tcg_temp_free_i64(t2);
1110    tcg_temp_free_i64(t3);
1111
1112    if (unlikely(Rc(ctx->opcode) != 0))
1113        gen_set_Rc0(ctx, ret);
1114}
1115
1116#define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
1117static void glue(gen_, name)(DisasContext *ctx)                                       \
1118{                                                                             \
1119    gen_op_arith_divd(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1120                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
1121                      sign, compute_ov);                                      \
1122}
1123/* divdu  divdu.  divduo  divduo.   */
1124GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0);
1125GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1);
1126/* divd  divd.  divdo  divdo.   */
1127GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0);
1128GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
1129
1130GEN_DIVE(divdeu, divdeu, 0);
1131GEN_DIVE(divdeuo, divdeu, 1);
1132GEN_DIVE(divde, divde, 0);
1133GEN_DIVE(divdeo, divde, 1);
1134#endif
1135
1136static inline void gen_op_arith_modw(DisasContext *ctx, TCGv ret, TCGv arg1,
1137                                     TCGv arg2, int sign)
1138{
1139    TCGv_i32 t0 = tcg_temp_new_i32();
1140    TCGv_i32 t1 = tcg_temp_new_i32();
1141
1142    tcg_gen_trunc_tl_i32(t0, arg1);
1143    tcg_gen_trunc_tl_i32(t1, arg2);
1144    if (sign) {
1145        TCGv_i32 t2 = tcg_temp_new_i32();
1146        TCGv_i32 t3 = tcg_temp_new_i32();
1147        tcg_gen_setcondi_i32(TCG_COND_EQ, t2, t0, INT_MIN);
1148        tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, -1);
1149        tcg_gen_and_i32(t2, t2, t3);
1150        tcg_gen_setcondi_i32(TCG_COND_EQ, t3, t1, 0);
1151        tcg_gen_or_i32(t2, t2, t3);
1152        tcg_gen_movi_i32(t3, 0);
1153        tcg_gen_movcond_i32(TCG_COND_NE, t1, t2, t3, t2, t1);
1154        tcg_gen_rem_i32(t3, t0, t1);
1155        tcg_gen_ext_i32_tl(ret, t3);
1156        tcg_temp_free_i32(t2);
1157        tcg_temp_free_i32(t3);
1158    } else {
1159        TCGv_i32 t2 = tcg_const_i32(1);
1160        TCGv_i32 t3 = tcg_const_i32(0);
1161        tcg_gen_movcond_i32(TCG_COND_EQ, t1, t1, t3, t2, t1);
1162        tcg_gen_remu_i32(t3, t0, t1);
1163        tcg_gen_extu_i32_tl(ret, t3);
1164        tcg_temp_free_i32(t2);
1165        tcg_temp_free_i32(t3);
1166    }
1167    tcg_temp_free_i32(t0);
1168    tcg_temp_free_i32(t1);
1169}
1170
1171#define GEN_INT_ARITH_MODW(name, opc3, sign)                                \
1172static void glue(gen_, name)(DisasContext *ctx)                             \
1173{                                                                           \
1174    gen_op_arith_modw(ctx, cpu_gpr[rD(ctx->opcode)],                        \
1175                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],   \
1176                      sign);                                                \
1177}
1178
1179GEN_INT_ARITH_MODW(moduw, 0x08, 0);
1180GEN_INT_ARITH_MODW(modsw, 0x18, 1);
1181
1182#if defined(TARGET_PPC64)
1183static inline void gen_op_arith_modd(DisasContext *ctx, TCGv ret, TCGv arg1,
1184                                     TCGv arg2, int sign)
1185{
1186    TCGv_i64 t0 = tcg_temp_new_i64();
1187    TCGv_i64 t1 = tcg_temp_new_i64();
1188
1189    tcg_gen_mov_i64(t0, arg1);
1190    tcg_gen_mov_i64(t1, arg2);
1191    if (sign) {
1192        TCGv_i64 t2 = tcg_temp_new_i64();
1193        TCGv_i64 t3 = tcg_temp_new_i64();
1194        tcg_gen_setcondi_i64(TCG_COND_EQ, t2, t0, INT64_MIN);
1195        tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, -1);
1196        tcg_gen_and_i64(t2, t2, t3);
1197        tcg_gen_setcondi_i64(TCG_COND_EQ, t3, t1, 0);
1198        tcg_gen_or_i64(t2, t2, t3);
1199        tcg_gen_movi_i64(t3, 0);
1200        tcg_gen_movcond_i64(TCG_COND_NE, t1, t2, t3, t2, t1);
1201        tcg_gen_rem_i64(ret, t0, t1);
1202        tcg_temp_free_i64(t2);
1203        tcg_temp_free_i64(t3);
1204    } else {
1205        TCGv_i64 t2 = tcg_const_i64(1);
1206        TCGv_i64 t3 = tcg_const_i64(0);
1207        tcg_gen_movcond_i64(TCG_COND_EQ, t1, t1, t3, t2, t1);
1208        tcg_gen_remu_i64(ret, t0, t1);
1209        tcg_temp_free_i64(t2);
1210        tcg_temp_free_i64(t3);
1211    }
1212    tcg_temp_free_i64(t0);
1213    tcg_temp_free_i64(t1);
1214}
1215
1216#define GEN_INT_ARITH_MODD(name, opc3, sign)                            \
1217static void glue(gen_, name)(DisasContext *ctx)                           \
1218{                                                                         \
1219  gen_op_arith_modd(ctx, cpu_gpr[rD(ctx->opcode)],                        \
1220                    cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],   \
1221                    sign);                                                \
1222}
1223
1224GEN_INT_ARITH_MODD(modud, 0x08, 0);
1225GEN_INT_ARITH_MODD(modsd, 0x18, 1);
1226#endif
1227
1228/* mulhw  mulhw. */
1229static void gen_mulhw(DisasContext *ctx)
1230{
1231    TCGv_i32 t0 = tcg_temp_new_i32();
1232    TCGv_i32 t1 = tcg_temp_new_i32();
1233
1234    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
1235    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
1236    tcg_gen_muls2_i32(t0, t1, t0, t1);
1237    tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);
1238    tcg_temp_free_i32(t0);
1239    tcg_temp_free_i32(t1);
1240    if (unlikely(Rc(ctx->opcode) != 0))
1241        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1242}
1243
1244/* mulhwu  mulhwu.  */
1245static void gen_mulhwu(DisasContext *ctx)
1246{
1247    TCGv_i32 t0 = tcg_temp_new_i32();
1248    TCGv_i32 t1 = tcg_temp_new_i32();
1249
1250    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
1251    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
1252    tcg_gen_mulu2_i32(t0, t1, t0, t1);
1253    tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);
1254    tcg_temp_free_i32(t0);
1255    tcg_temp_free_i32(t1);
1256    if (unlikely(Rc(ctx->opcode) != 0))
1257        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1258}
1259
1260/* mullw  mullw. */
1261static void gen_mullw(DisasContext *ctx)
1262{
1263#if defined(TARGET_PPC64)
1264    TCGv_i64 t0, t1;
1265    t0 = tcg_temp_new_i64();
1266    t1 = tcg_temp_new_i64();
1267    tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
1268    tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
1269    tcg_gen_mul_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);
1270    tcg_temp_free(t0);
1271    tcg_temp_free(t1);
1272#else
1273    tcg_gen_mul_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1274                    cpu_gpr[rB(ctx->opcode)]);
1275#endif
1276    if (unlikely(Rc(ctx->opcode) != 0))
1277        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1278}
1279
1280/* mullwo  mullwo. */
1281static void gen_mullwo(DisasContext *ctx)
1282{
1283    TCGv_i32 t0 = tcg_temp_new_i32();
1284    TCGv_i32 t1 = tcg_temp_new_i32();
1285
1286    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);
1287    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);
1288    tcg_gen_muls2_i32(t0, t1, t0, t1);
1289#if defined(TARGET_PPC64)
1290    tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);
1291#else
1292    tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], t0);
1293#endif
1294
1295    tcg_gen_sari_i32(t0, t0, 31);
1296    tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t1);
1297    tcg_gen_extu_i32_tl(cpu_ov, t0);
1298    if (is_isa300(ctx)) {
1299        tcg_gen_mov_tl(cpu_ov32, cpu_ov);
1300    }
1301    tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
1302
1303    tcg_temp_free_i32(t0);
1304    tcg_temp_free_i32(t1);
1305    if (unlikely(Rc(ctx->opcode) != 0))
1306        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1307}
1308
1309/* mulli */
1310static void gen_mulli(DisasContext *ctx)
1311{
1312    tcg_gen_muli_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1313                    SIMM(ctx->opcode));
1314}
1315
1316#if defined(TARGET_PPC64)
1317/* mulhd  mulhd. */
1318static void gen_mulhd(DisasContext *ctx)
1319{
1320    TCGv lo = tcg_temp_new();
1321    tcg_gen_muls2_tl(lo, cpu_gpr[rD(ctx->opcode)],
1322                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1323    tcg_temp_free(lo);
1324    if (unlikely(Rc(ctx->opcode) != 0)) {
1325        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1326    }
1327}
1328
1329/* mulhdu  mulhdu. */
1330static void gen_mulhdu(DisasContext *ctx)
1331{
1332    TCGv lo = tcg_temp_new();
1333    tcg_gen_mulu2_tl(lo, cpu_gpr[rD(ctx->opcode)],
1334                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1335    tcg_temp_free(lo);
1336    if (unlikely(Rc(ctx->opcode) != 0)) {
1337        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1338    }
1339}
1340
1341/* mulld  mulld. */
1342static void gen_mulld(DisasContext *ctx)
1343{
1344    tcg_gen_mul_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1345                   cpu_gpr[rB(ctx->opcode)]);
1346    if (unlikely(Rc(ctx->opcode) != 0))
1347        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1348}
1349
1350/* mulldo  mulldo. */
1351static void gen_mulldo(DisasContext *ctx)
1352{
1353    TCGv_i64 t0 = tcg_temp_new_i64();
1354    TCGv_i64 t1 = tcg_temp_new_i64();
1355
1356    tcg_gen_muls2_i64(t0, t1, cpu_gpr[rA(ctx->opcode)],
1357                      cpu_gpr[rB(ctx->opcode)]);
1358    tcg_gen_mov_i64(cpu_gpr[rD(ctx->opcode)], t0);
1359
1360    tcg_gen_sari_i64(t0, t0, 63);
1361    tcg_gen_setcond_i64(TCG_COND_NE, cpu_ov, t0, t1);
1362    if (is_isa300(ctx)) {
1363        tcg_gen_mov_tl(cpu_ov32, cpu_ov);
1364    }
1365    tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
1366
1367    tcg_temp_free_i64(t0);
1368    tcg_temp_free_i64(t1);
1369
1370    if (unlikely(Rc(ctx->opcode) != 0)) {
1371        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1372    }
1373}
1374#endif
1375
1376/* Common subf function */
1377static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,
1378                                     TCGv arg2, bool add_ca, bool compute_ca,
1379                                     bool compute_ov, bool compute_rc0)
1380{
1381    TCGv t0 = ret;
1382
1383    if (compute_ca || compute_ov) {
1384        t0 = tcg_temp_new();
1385    }
1386
1387    if (compute_ca) {
1388        /* dest = ~arg1 + arg2 [+ ca].  */
1389        if (NARROW_MODE(ctx)) {
1390            /* Caution: a non-obvious corner case of the spec is that we
1391               must produce the *entire* 64-bit addition, but produce the
1392               carry into bit 32.  */
1393            TCGv inv1 = tcg_temp_new();
1394            TCGv t1 = tcg_temp_new();
1395            tcg_gen_not_tl(inv1, arg1);
1396            if (add_ca) {
1397                tcg_gen_add_tl(t0, arg2, cpu_ca);
1398            } else {
1399                tcg_gen_addi_tl(t0, arg2, 1);
1400            }
1401            tcg_gen_xor_tl(t1, arg2, inv1);         /* add without carry */
1402            tcg_gen_add_tl(t0, t0, inv1);
1403            tcg_temp_free(inv1);
1404            tcg_gen_xor_tl(cpu_ca, t0, t1);         /* bits changes w/ carry */
1405            tcg_temp_free(t1);
1406            tcg_gen_extract_tl(cpu_ca, cpu_ca, 32, 1);
1407            if (is_isa300(ctx)) {
1408                tcg_gen_mov_tl(cpu_ca32, cpu_ca);
1409            }
1410        } else if (add_ca) {
1411            TCGv zero, inv1 = tcg_temp_new();
1412            tcg_gen_not_tl(inv1, arg1);
1413            zero = tcg_const_tl(0);
1414            tcg_gen_add2_tl(t0, cpu_ca, arg2, zero, cpu_ca, zero);
1415            tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, inv1, zero);
1416            gen_op_arith_compute_ca32(ctx, t0, inv1, arg2, 0);
1417            tcg_temp_free(zero);
1418            tcg_temp_free(inv1);
1419        } else {
1420            tcg_gen_setcond_tl(TCG_COND_GEU, cpu_ca, arg2, arg1);
1421            tcg_gen_sub_tl(t0, arg2, arg1);
1422            gen_op_arith_compute_ca32(ctx, t0, arg1, arg2, 1);
1423        }
1424    } else if (add_ca) {
1425        /* Since we're ignoring carry-out, we can simplify the
1426           standard ~arg1 + arg2 + ca to arg2 - arg1 + ca - 1.  */
1427        tcg_gen_sub_tl(t0, arg2, arg1);
1428        tcg_gen_add_tl(t0, t0, cpu_ca);
1429        tcg_gen_subi_tl(t0, t0, 1);
1430    } else {
1431        tcg_gen_sub_tl(t0, arg2, arg1);
1432    }
1433
1434    if (compute_ov) {
1435        gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1);
1436    }
1437    if (unlikely(compute_rc0)) {
1438        gen_set_Rc0(ctx, t0);
1439    }
1440
1441    if (!TCGV_EQUAL(t0, ret)) {
1442        tcg_gen_mov_tl(ret, t0);
1443        tcg_temp_free(t0);
1444    }
1445}
1446/* Sub functions with Two operands functions */
1447#define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
1448static void glue(gen_, name)(DisasContext *ctx)                               \
1449{                                                                             \
1450    gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1451                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],     \
1452                      add_ca, compute_ca, compute_ov, Rc(ctx->opcode));       \
1453}
1454/* Sub functions with one operand and one immediate */
1455#define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
1456                                add_ca, compute_ca, compute_ov)               \
1457static void glue(gen_, name)(DisasContext *ctx)                               \
1458{                                                                             \
1459    TCGv t0 = tcg_const_tl(const_val);                                        \
1460    gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)],                          \
1461                      cpu_gpr[rA(ctx->opcode)], t0,                           \
1462                      add_ca, compute_ca, compute_ov, Rc(ctx->opcode));       \
1463    tcg_temp_free(t0);                                                        \
1464}
1465/* subf  subf.  subfo  subfo. */
1466GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
1467GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
1468/* subfc  subfc.  subfco  subfco. */
1469GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
1470GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
1471/* subfe  subfe.  subfeo  subfo. */
1472GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
1473GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
1474/* subfme  subfme.  subfmeo  subfmeo.  */
1475GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
1476GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
1477/* subfze  subfze.  subfzeo  subfzeo.*/
1478GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
1479GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
1480
1481/* subfic */
1482static void gen_subfic(DisasContext *ctx)
1483{
1484    TCGv c = tcg_const_tl(SIMM(ctx->opcode));
1485    gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1486                      c, 0, 1, 0, 0);
1487    tcg_temp_free(c);
1488}
1489
1490/* neg neg. nego nego. */
1491static inline void gen_op_arith_neg(DisasContext *ctx, bool compute_ov)
1492{
1493    TCGv zero = tcg_const_tl(0);
1494    gen_op_arith_subf(ctx, cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
1495                      zero, 0, 0, compute_ov, Rc(ctx->opcode));
1496    tcg_temp_free(zero);
1497}
1498
1499static void gen_neg(DisasContext *ctx)
1500{
1501    tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
1502    if (unlikely(Rc(ctx->opcode))) {
1503        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
1504    }
1505}
1506
1507static void gen_nego(DisasContext *ctx)
1508{
1509    gen_op_arith_neg(ctx, 1);
1510}
1511
1512/***                            Integer logical                            ***/
1513#define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
1514static void glue(gen_, name)(DisasContext *ctx)                                       \
1515{                                                                             \
1516    tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)],                \
1517       cpu_gpr[rB(ctx->opcode)]);                                             \
1518    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1519        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1520}
1521
1522#define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
1523static void glue(gen_, name)(DisasContext *ctx)                                       \
1524{                                                                             \
1525    tcg_op(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);               \
1526    if (unlikely(Rc(ctx->opcode) != 0))                                       \
1527        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);                           \
1528}
1529
1530/* and & and. */
1531GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER);
1532/* andc & andc. */
1533GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER);
1534
1535/* andi. */
1536static void gen_andi_(DisasContext *ctx)
1537{
1538    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode));
1539    gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1540}
1541
1542/* andis. */
1543static void gen_andis_(DisasContext *ctx)
1544{
1545    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], UIMM(ctx->opcode) << 16);
1546    gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1547}
1548
1549/* cntlzw */
1550static void gen_cntlzw(DisasContext *ctx)
1551{
1552    TCGv_i32 t = tcg_temp_new_i32();
1553
1554    tcg_gen_trunc_tl_i32(t, cpu_gpr[rS(ctx->opcode)]);
1555    tcg_gen_clzi_i32(t, t, 32);
1556    tcg_gen_extu_i32_tl(cpu_gpr[rA(ctx->opcode)], t);
1557    tcg_temp_free_i32(t);
1558
1559    if (unlikely(Rc(ctx->opcode) != 0))
1560        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1561}
1562
1563/* cnttzw */
1564static void gen_cnttzw(DisasContext *ctx)
1565{
1566    TCGv_i32 t = tcg_temp_new_i32();
1567
1568    tcg_gen_trunc_tl_i32(t, cpu_gpr[rS(ctx->opcode)]);
1569    tcg_gen_ctzi_i32(t, t, 32);
1570    tcg_gen_extu_i32_tl(cpu_gpr[rA(ctx->opcode)], t);
1571    tcg_temp_free_i32(t);
1572
1573    if (unlikely(Rc(ctx->opcode) != 0)) {
1574        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1575    }
1576}
1577
1578/* eqv & eqv. */
1579GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER);
1580/* extsb & extsb. */
1581GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER);
1582/* extsh & extsh. */
1583GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER);
1584/* nand & nand. */
1585GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER);
1586/* nor & nor. */
1587GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER);
1588
1589#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
1590static void gen_pause(DisasContext *ctx)
1591{
1592    TCGv_i32 t0 = tcg_const_i32(0);
1593    tcg_gen_st_i32(t0, cpu_env,
1594                   -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
1595    tcg_temp_free_i32(t0);
1596
1597    /* Stop translation, this gives other CPUs a chance to run */
1598    gen_exception_nip(ctx, EXCP_HLT, ctx->nip);
1599}
1600#endif /* defined(TARGET_PPC64) */
1601
1602/* or & or. */
1603static void gen_or(DisasContext *ctx)
1604{
1605    int rs, ra, rb;
1606
1607    rs = rS(ctx->opcode);
1608    ra = rA(ctx->opcode);
1609    rb = rB(ctx->opcode);
1610    /* Optimisation for mr. ri case */
1611    if (rs != ra || rs != rb) {
1612        if (rs != rb)
1613            tcg_gen_or_tl(cpu_gpr[ra], cpu_gpr[rs], cpu_gpr[rb]);
1614        else
1615            tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rs]);
1616        if (unlikely(Rc(ctx->opcode) != 0))
1617            gen_set_Rc0(ctx, cpu_gpr[ra]);
1618    } else if (unlikely(Rc(ctx->opcode) != 0)) {
1619        gen_set_Rc0(ctx, cpu_gpr[rs]);
1620#if defined(TARGET_PPC64)
1621    } else if (rs != 0) { /* 0 is nop */
1622        int prio = 0;
1623
1624        switch (rs) {
1625        case 1:
1626            /* Set process priority to low */
1627            prio = 2;
1628            break;
1629        case 6:
1630            /* Set process priority to medium-low */
1631            prio = 3;
1632            break;
1633        case 2:
1634            /* Set process priority to normal */
1635            prio = 4;
1636            break;
1637#if !defined(CONFIG_USER_ONLY)
1638        case 31:
1639            if (!ctx->pr) {
1640                /* Set process priority to very low */
1641                prio = 1;
1642            }
1643            break;
1644        case 5:
1645            if (!ctx->pr) {
1646                /* Set process priority to medium-hight */
1647                prio = 5;
1648            }
1649            break;
1650        case 3:
1651            if (!ctx->pr) {
1652                /* Set process priority to high */
1653                prio = 6;
1654            }
1655            break;
1656        case 7:
1657            if (ctx->hv && !ctx->pr) {
1658                /* Set process priority to very high */
1659                prio = 7;
1660            }
1661            break;
1662#endif
1663        default:
1664            break;
1665        }
1666        if (prio) {
1667            TCGv t0 = tcg_temp_new();
1668            gen_load_spr(t0, SPR_PPR);
1669            tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
1670            tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
1671            gen_store_spr(SPR_PPR, t0);
1672            tcg_temp_free(t0);
1673        }
1674#if !defined(CONFIG_USER_ONLY)
1675        /* Pause out of TCG otherwise spin loops with smt_low eat too much
1676         * CPU and the kernel hangs.  This applies to all encodings other
1677         * than no-op, e.g., miso(rs=26), yield(27), mdoio(29), mdoom(30),
1678         * and all currently undefined.
1679         */
1680        gen_pause(ctx);
1681#endif
1682#endif
1683    }
1684}
1685/* orc & orc. */
1686GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER);
1687
1688/* xor & xor. */
1689static void gen_xor(DisasContext *ctx)
1690{
1691    /* Optimisation for "set to zero" case */
1692    if (rS(ctx->opcode) != rB(ctx->opcode))
1693        tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1694    else
1695        tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
1696    if (unlikely(Rc(ctx->opcode) != 0))
1697        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1698}
1699
1700/* ori */
1701static void gen_ori(DisasContext *ctx)
1702{
1703    target_ulong uimm = UIMM(ctx->opcode);
1704
1705    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1706        return;
1707    }
1708    tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1709}
1710
1711/* oris */
1712static void gen_oris(DisasContext *ctx)
1713{
1714    target_ulong uimm = UIMM(ctx->opcode);
1715
1716    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1717        /* NOP */
1718        return;
1719    }
1720    tcg_gen_ori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1721}
1722
1723/* xori */
1724static void gen_xori(DisasContext *ctx)
1725{
1726    target_ulong uimm = UIMM(ctx->opcode);
1727
1728    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1729        /* NOP */
1730        return;
1731    }
1732    tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm);
1733}
1734
1735/* xoris */
1736static void gen_xoris(DisasContext *ctx)
1737{
1738    target_ulong uimm = UIMM(ctx->opcode);
1739
1740    if (rS(ctx->opcode) == rA(ctx->opcode) && uimm == 0) {
1741        /* NOP */
1742        return;
1743    }
1744    tcg_gen_xori_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], uimm << 16);
1745}
1746
1747/* popcntb : PowerPC 2.03 specification */
1748static void gen_popcntb(DisasContext *ctx)
1749{
1750    gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1751}
1752
1753static void gen_popcntw(DisasContext *ctx)
1754{
1755#if defined(TARGET_PPC64)
1756    gen_helper_popcntw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1757#else
1758    tcg_gen_ctpop_i32(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1759#endif
1760}
1761
1762#if defined(TARGET_PPC64)
1763/* popcntd: PowerPC 2.06 specification */
1764static void gen_popcntd(DisasContext *ctx)
1765{
1766    tcg_gen_ctpop_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
1767}
1768#endif
1769
1770/* prtyw: PowerPC 2.05 specification */
1771static void gen_prtyw(DisasContext *ctx)
1772{
1773    TCGv ra = cpu_gpr[rA(ctx->opcode)];
1774    TCGv rs = cpu_gpr[rS(ctx->opcode)];
1775    TCGv t0 = tcg_temp_new();
1776    tcg_gen_shri_tl(t0, rs, 16);
1777    tcg_gen_xor_tl(ra, rs, t0);
1778    tcg_gen_shri_tl(t0, ra, 8);
1779    tcg_gen_xor_tl(ra, ra, t0);
1780    tcg_gen_andi_tl(ra, ra, (target_ulong)0x100000001ULL);
1781    tcg_temp_free(t0);
1782}
1783
1784#if defined(TARGET_PPC64)
1785/* prtyd: PowerPC 2.05 specification */
1786static void gen_prtyd(DisasContext *ctx)
1787{
1788    TCGv ra = cpu_gpr[rA(ctx->opcode)];
1789    TCGv rs = cpu_gpr[rS(ctx->opcode)];
1790    TCGv t0 = tcg_temp_new();
1791    tcg_gen_shri_tl(t0, rs, 32);
1792    tcg_gen_xor_tl(ra, rs, t0);
1793    tcg_gen_shri_tl(t0, ra, 16);
1794    tcg_gen_xor_tl(ra, ra, t0);
1795    tcg_gen_shri_tl(t0, ra, 8);
1796    tcg_gen_xor_tl(ra, ra, t0);
1797    tcg_gen_andi_tl(ra, ra, 1);
1798    tcg_temp_free(t0);
1799}
1800#endif
1801
1802#if defined(TARGET_PPC64)
1803/* bpermd */
1804static void gen_bpermd(DisasContext *ctx)
1805{
1806    gen_helper_bpermd(cpu_gpr[rA(ctx->opcode)],
1807                      cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
1808}
1809#endif
1810
1811#if defined(TARGET_PPC64)
1812/* extsw & extsw. */
1813GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
1814
1815/* cntlzd */
1816static void gen_cntlzd(DisasContext *ctx)
1817{
1818    tcg_gen_clzi_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 64);
1819    if (unlikely(Rc(ctx->opcode) != 0))
1820        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1821}
1822
1823/* cnttzd */
1824static void gen_cnttzd(DisasContext *ctx)
1825{
1826    tcg_gen_ctzi_i64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], 64);
1827    if (unlikely(Rc(ctx->opcode) != 0)) {
1828        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
1829    }
1830}
1831
1832/* darn */
1833static void gen_darn(DisasContext *ctx)
1834{
1835    int l = L(ctx->opcode);
1836
1837    if (l == 0) {
1838        gen_helper_darn32(cpu_gpr[rD(ctx->opcode)]);
1839    } else if (l <= 2) {
1840        /* Return 64-bit random for both CRN and RRN */
1841        gen_helper_darn64(cpu_gpr[rD(ctx->opcode)]);
1842    } else {
1843        tcg_gen_movi_i64(cpu_gpr[rD(ctx->opcode)], -1);
1844    }
1845}
1846#endif
1847
1848/***                             Integer rotate                            ***/
1849
1850/* rlwimi & rlwimi. */
1851static void gen_rlwimi(DisasContext *ctx)
1852{
1853    TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
1854    TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
1855    uint32_t sh = SH(ctx->opcode);
1856    uint32_t mb = MB(ctx->opcode);
1857    uint32_t me = ME(ctx->opcode);
1858
1859    if (sh == (31-me) && mb <= me) {
1860        tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1);
1861    } else {
1862        target_ulong mask;
1863        TCGv t1;
1864
1865#if defined(TARGET_PPC64)
1866        mb += 32;
1867        me += 32;
1868#endif
1869        mask = MASK(mb, me);
1870
1871        t1 = tcg_temp_new();
1872        if (mask <= 0xffffffffu) {
1873            TCGv_i32 t0 = tcg_temp_new_i32();
1874            tcg_gen_trunc_tl_i32(t0, t_rs);
1875            tcg_gen_rotli_i32(t0, t0, sh);
1876            tcg_gen_extu_i32_tl(t1, t0);
1877            tcg_temp_free_i32(t0);
1878        } else {
1879#if defined(TARGET_PPC64)
1880            tcg_gen_deposit_i64(t1, t_rs, t_rs, 32, 32);
1881            tcg_gen_rotli_i64(t1, t1, sh);
1882#else
1883            g_assert_not_reached();
1884#endif
1885        }
1886
1887        tcg_gen_andi_tl(t1, t1, mask);
1888        tcg_gen_andi_tl(t_ra, t_ra, ~mask);
1889        tcg_gen_or_tl(t_ra, t_ra, t1);
1890        tcg_temp_free(t1);
1891    }
1892    if (unlikely(Rc(ctx->opcode) != 0)) {
1893        gen_set_Rc0(ctx, t_ra);
1894    }
1895}
1896
1897/* rlwinm & rlwinm. */
1898static void gen_rlwinm(DisasContext *ctx)
1899{
1900    TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
1901    TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
1902    int sh = SH(ctx->opcode);
1903    int mb = MB(ctx->opcode);
1904    int me = ME(ctx->opcode);
1905    int len = me - mb + 1;
1906    int rsh = (32 - sh) & 31;
1907
1908    if (sh != 0 && len > 0 && me == (31 - sh)) {
1909        tcg_gen_deposit_z_tl(t_ra, t_rs, sh, len);
1910    } else if (me == 31 && rsh + len <= 32) {
1911        tcg_gen_extract_tl(t_ra, t_rs, rsh, len);
1912    } else {
1913        target_ulong mask;
1914#if defined(TARGET_PPC64)
1915        mb += 32;
1916        me += 32;
1917#endif
1918        mask = MASK(mb, me);
1919        if (sh == 0) {
1920            tcg_gen_andi_tl(t_ra, t_rs, mask);
1921        } else if (mask <= 0xffffffffu) {
1922            TCGv_i32 t0 = tcg_temp_new_i32();
1923            tcg_gen_trunc_tl_i32(t0, t_rs);
1924            tcg_gen_rotli_i32(t0, t0, sh);
1925            tcg_gen_andi_i32(t0, t0, mask);
1926            tcg_gen_extu_i32_tl(t_ra, t0);
1927            tcg_temp_free_i32(t0);
1928        } else {
1929#if defined(TARGET_PPC64)
1930            tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32);
1931            tcg_gen_rotli_i64(t_ra, t_ra, sh);
1932            tcg_gen_andi_i64(t_ra, t_ra, mask);
1933#else
1934            g_assert_not_reached();
1935#endif
1936        }
1937    }
1938    if (unlikely(Rc(ctx->opcode) != 0)) {
1939        gen_set_Rc0(ctx, t_ra);
1940    }
1941}
1942
1943/* rlwnm & rlwnm. */
1944static void gen_rlwnm(DisasContext *ctx)
1945{
1946    TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
1947    TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
1948    TCGv t_rb = cpu_gpr[rB(ctx->opcode)];
1949    uint32_t mb = MB(ctx->opcode);
1950    uint32_t me = ME(ctx->opcode);
1951    target_ulong mask;
1952
1953#if defined(TARGET_PPC64)
1954    mb += 32;
1955    me += 32;
1956#endif
1957    mask = MASK(mb, me);
1958
1959    if (mask <= 0xffffffffu) {
1960        TCGv_i32 t0 = tcg_temp_new_i32();
1961        TCGv_i32 t1 = tcg_temp_new_i32();
1962        tcg_gen_trunc_tl_i32(t0, t_rb);
1963        tcg_gen_trunc_tl_i32(t1, t_rs);
1964        tcg_gen_andi_i32(t0, t0, 0x1f);
1965        tcg_gen_rotl_i32(t1, t1, t0);
1966        tcg_gen_extu_i32_tl(t_ra, t1);
1967        tcg_temp_free_i32(t0);
1968        tcg_temp_free_i32(t1);
1969    } else {
1970#if defined(TARGET_PPC64)
1971        TCGv_i64 t0 = tcg_temp_new_i64();
1972        tcg_gen_andi_i64(t0, t_rb, 0x1f);
1973        tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32);
1974        tcg_gen_rotl_i64(t_ra, t_ra, t0);
1975        tcg_temp_free_i64(t0);
1976#else
1977        g_assert_not_reached();
1978#endif
1979    }
1980
1981    tcg_gen_andi_tl(t_ra, t_ra, mask);
1982
1983    if (unlikely(Rc(ctx->opcode) != 0)) {
1984        gen_set_Rc0(ctx, t_ra);
1985    }
1986}
1987
1988#if defined(TARGET_PPC64)
1989#define GEN_PPC64_R2(name, opc1, opc2)                                        \
1990static void glue(gen_, name##0)(DisasContext *ctx)                            \
1991{                                                                             \
1992    gen_##name(ctx, 0);                                                       \
1993}                                                                             \
1994                                                                              \
1995static void glue(gen_, name##1)(DisasContext *ctx)                            \
1996{                                                                             \
1997    gen_##name(ctx, 1);                                                       \
1998}
1999#define GEN_PPC64_R4(name, opc1, opc2)                                        \
2000static void glue(gen_, name##0)(DisasContext *ctx)                            \
2001{                                                                             \
2002    gen_##name(ctx, 0, 0);                                                    \
2003}                                                                             \
2004                                                                              \
2005static void glue(gen_, name##1)(DisasContext *ctx)                            \
2006{                                                                             \
2007    gen_##name(ctx, 0, 1);                                                    \
2008}                                                                             \
2009                                                                              \
2010static void glue(gen_, name##2)(DisasContext *ctx)                            \
2011{                                                                             \
2012    gen_##name(ctx, 1, 0);                                                    \
2013}                                                                             \
2014                                                                              \
2015static void glue(gen_, name##3)(DisasContext *ctx)                            \
2016{                                                                             \
2017    gen_##name(ctx, 1, 1);                                                    \
2018}
2019
2020static void gen_rldinm(DisasContext *ctx, int mb, int me, int sh)
2021{
2022    TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
2023    TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
2024    int len = me - mb + 1;
2025    int rsh = (64 - sh) & 63;
2026
2027    if (sh != 0 && len > 0 && me == (63 - sh)) {
2028        tcg_gen_deposit_z_tl(t_ra, t_rs, sh, len);
2029    } else if (me == 63 && rsh + len <= 64) {
2030        tcg_gen_extract_tl(t_ra, t_rs, rsh, len);
2031    } else {
2032        tcg_gen_rotli_tl(t_ra, t_rs, sh);
2033        tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me));
2034    }
2035    if (unlikely(Rc(ctx->opcode) != 0)) {
2036        gen_set_Rc0(ctx, t_ra);
2037    }
2038}
2039
2040/* rldicl - rldicl. */
2041static inline void gen_rldicl(DisasContext *ctx, int mbn, int shn)
2042{
2043    uint32_t sh, mb;
2044
2045    sh = SH(ctx->opcode) | (shn << 5);
2046    mb = MB(ctx->opcode) | (mbn << 5);
2047    gen_rldinm(ctx, mb, 63, sh);
2048}
2049GEN_PPC64_R4(rldicl, 0x1E, 0x00);
2050
2051/* rldicr - rldicr. */
2052static inline void gen_rldicr(DisasContext *ctx, int men, int shn)
2053{
2054    uint32_t sh, me;
2055
2056    sh = SH(ctx->opcode) | (shn << 5);
2057    me = MB(ctx->opcode) | (men << 5);
2058    gen_rldinm(ctx, 0, me, sh);
2059}
2060GEN_PPC64_R4(rldicr, 0x1E, 0x02);
2061
2062/* rldic - rldic. */
2063static inline void gen_rldic(DisasContext *ctx, int mbn, int shn)
2064{
2065    uint32_t sh, mb;
2066
2067    sh = SH(ctx->opcode) | (shn << 5);
2068    mb = MB(ctx->opcode) | (mbn << 5);
2069    gen_rldinm(ctx, mb, 63 - sh, sh);
2070}
2071GEN_PPC64_R4(rldic, 0x1E, 0x04);
2072
2073static void gen_rldnm(DisasContext *ctx, int mb, int me)
2074{
2075    TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
2076    TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
2077    TCGv t_rb = cpu_gpr[rB(ctx->opcode)];
2078    TCGv t0;
2079
2080    t0 = tcg_temp_new();
2081    tcg_gen_andi_tl(t0, t_rb, 0x3f);
2082    tcg_gen_rotl_tl(t_ra, t_rs, t0);
2083    tcg_temp_free(t0);
2084
2085    tcg_gen_andi_tl(t_ra, t_ra, MASK(mb, me));
2086    if (unlikely(Rc(ctx->opcode) != 0)) {
2087        gen_set_Rc0(ctx, t_ra);
2088    }
2089}
2090
2091/* rldcl - rldcl. */
2092static inline void gen_rldcl(DisasContext *ctx, int mbn)
2093{
2094    uint32_t mb;
2095
2096    mb = MB(ctx->opcode) | (mbn << 5);
2097    gen_rldnm(ctx, mb, 63);
2098}
2099GEN_PPC64_R2(rldcl, 0x1E, 0x08);
2100
2101/* rldcr - rldcr. */
2102static inline void gen_rldcr(DisasContext *ctx, int men)
2103{
2104    uint32_t me;
2105
2106    me = MB(ctx->opcode) | (men << 5);
2107    gen_rldnm(ctx, 0, me);
2108}
2109GEN_PPC64_R2(rldcr, 0x1E, 0x09);
2110
2111/* rldimi - rldimi. */
2112static void gen_rldimi(DisasContext *ctx, int mbn, int shn)
2113{
2114    TCGv t_ra = cpu_gpr[rA(ctx->opcode)];
2115    TCGv t_rs = cpu_gpr[rS(ctx->opcode)];
2116    uint32_t sh = SH(ctx->opcode) | (shn << 5);
2117    uint32_t mb = MB(ctx->opcode) | (mbn << 5);
2118    uint32_t me = 63 - sh;
2119
2120    if (mb <= me) {
2121        tcg_gen_deposit_tl(t_ra, t_ra, t_rs, sh, me - mb + 1);
2122    } else {
2123        target_ulong mask = MASK(mb, me);
2124        TCGv t1 = tcg_temp_new();
2125
2126        tcg_gen_rotli_tl(t1, t_rs, sh);
2127        tcg_gen_andi_tl(t1, t1, mask);
2128        tcg_gen_andi_tl(t_ra, t_ra, ~mask);
2129        tcg_gen_or_tl(t_ra, t_ra, t1);
2130        tcg_temp_free(t1);
2131    }
2132    if (unlikely(Rc(ctx->opcode) != 0)) {
2133        gen_set_Rc0(ctx, t_ra);
2134    }
2135}
2136GEN_PPC64_R4(rldimi, 0x1E, 0x06);
2137#endif
2138
2139/***                             Integer shift                             ***/
2140
2141/* slw & slw. */
2142static void gen_slw(DisasContext *ctx)
2143{
2144    TCGv t0, t1;
2145
2146    t0 = tcg_temp_new();
2147    /* AND rS with a mask that is 0 when rB >= 0x20 */
2148#if defined(TARGET_PPC64)
2149    tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
2150    tcg_gen_sari_tl(t0, t0, 0x3f);
2151#else
2152    tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
2153    tcg_gen_sari_tl(t0, t0, 0x1f);
2154#endif
2155    tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
2156    t1 = tcg_temp_new();
2157    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
2158    tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
2159    tcg_temp_free(t1);
2160    tcg_temp_free(t0);
2161    tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
2162    if (unlikely(Rc(ctx->opcode) != 0))
2163        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2164}
2165
2166/* sraw & sraw. */
2167static void gen_sraw(DisasContext *ctx)
2168{
2169    gen_helper_sraw(cpu_gpr[rA(ctx->opcode)], cpu_env,
2170                    cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2171    if (unlikely(Rc(ctx->opcode) != 0))
2172        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2173}
2174
2175/* srawi & srawi. */
2176static void gen_srawi(DisasContext *ctx)
2177{
2178    int sh = SH(ctx->opcode);
2179    TCGv dst = cpu_gpr[rA(ctx->opcode)];
2180    TCGv src = cpu_gpr[rS(ctx->opcode)];
2181    if (sh == 0) {
2182        tcg_gen_ext32s_tl(dst, src);
2183        tcg_gen_movi_tl(cpu_ca, 0);
2184    } else {
2185        TCGv t0;
2186        tcg_gen_ext32s_tl(dst, src);
2187        tcg_gen_andi_tl(cpu_ca, dst, (1ULL << sh) - 1);
2188        t0 = tcg_temp_new();
2189        tcg_gen_sari_tl(t0, dst, TARGET_LONG_BITS - 1);
2190        tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
2191        tcg_temp_free(t0);
2192        tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
2193        tcg_gen_sari_tl(dst, dst, sh);
2194    }
2195    if (unlikely(Rc(ctx->opcode) != 0)) {
2196        gen_set_Rc0(ctx, dst);
2197    }
2198}
2199
2200/* srw & srw. */
2201static void gen_srw(DisasContext *ctx)
2202{
2203    TCGv t0, t1;
2204
2205    t0 = tcg_temp_new();
2206    /* AND rS with a mask that is 0 when rB >= 0x20 */
2207#if defined(TARGET_PPC64)
2208    tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3a);
2209    tcg_gen_sari_tl(t0, t0, 0x3f);
2210#else
2211    tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1a);
2212    tcg_gen_sari_tl(t0, t0, 0x1f);
2213#endif
2214    tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
2215    tcg_gen_ext32u_tl(t0, t0);
2216    t1 = tcg_temp_new();
2217    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1f);
2218    tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
2219    tcg_temp_free(t1);
2220    tcg_temp_free(t0);
2221    if (unlikely(Rc(ctx->opcode) != 0))
2222        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2223}
2224
2225#if defined(TARGET_PPC64)
2226/* sld & sld. */
2227static void gen_sld(DisasContext *ctx)
2228{
2229    TCGv t0, t1;
2230
2231    t0 = tcg_temp_new();
2232    /* AND rS with a mask that is 0 when rB >= 0x40 */
2233    tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
2234    tcg_gen_sari_tl(t0, t0, 0x3f);
2235    tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
2236    t1 = tcg_temp_new();
2237    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
2238    tcg_gen_shl_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
2239    tcg_temp_free(t1);
2240    tcg_temp_free(t0);
2241    if (unlikely(Rc(ctx->opcode) != 0))
2242        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2243}
2244
2245/* srad & srad. */
2246static void gen_srad(DisasContext *ctx)
2247{
2248    gen_helper_srad(cpu_gpr[rA(ctx->opcode)], cpu_env,
2249                    cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2250    if (unlikely(Rc(ctx->opcode) != 0))
2251        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2252}
2253/* sradi & sradi. */
2254static inline void gen_sradi(DisasContext *ctx, int n)
2255{
2256    int sh = SH(ctx->opcode) + (n << 5);
2257    TCGv dst = cpu_gpr[rA(ctx->opcode)];
2258    TCGv src = cpu_gpr[rS(ctx->opcode)];
2259    if (sh == 0) {
2260        tcg_gen_mov_tl(dst, src);
2261        tcg_gen_movi_tl(cpu_ca, 0);
2262    } else {
2263        TCGv t0;
2264        tcg_gen_andi_tl(cpu_ca, src, (1ULL << sh) - 1);
2265        t0 = tcg_temp_new();
2266        tcg_gen_sari_tl(t0, src, TARGET_LONG_BITS - 1);
2267        tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
2268        tcg_temp_free(t0);
2269        tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
2270        tcg_gen_sari_tl(dst, src, sh);
2271    }
2272    if (unlikely(Rc(ctx->opcode) != 0)) {
2273        gen_set_Rc0(ctx, dst);
2274    }
2275}
2276
2277static void gen_sradi0(DisasContext *ctx)
2278{
2279    gen_sradi(ctx, 0);
2280}
2281
2282static void gen_sradi1(DisasContext *ctx)
2283{
2284    gen_sradi(ctx, 1);
2285}
2286
2287/* extswsli & extswsli. */
2288static inline void gen_extswsli(DisasContext *ctx, int n)
2289{
2290    int sh = SH(ctx->opcode) + (n << 5);
2291    TCGv dst = cpu_gpr[rA(ctx->opcode)];
2292    TCGv src = cpu_gpr[rS(ctx->opcode)];
2293
2294    tcg_gen_ext32s_tl(dst, src);
2295    tcg_gen_shli_tl(dst, dst, sh);
2296    if (unlikely(Rc(ctx->opcode) != 0)) {
2297        gen_set_Rc0(ctx, dst);
2298    }
2299}
2300
2301static void gen_extswsli0(DisasContext *ctx)
2302{
2303    gen_extswsli(ctx, 0);
2304}
2305
2306static void gen_extswsli1(DisasContext *ctx)
2307{
2308    gen_extswsli(ctx, 1);
2309}
2310
2311/* srd & srd. */
2312static void gen_srd(DisasContext *ctx)
2313{
2314    TCGv t0, t1;
2315
2316    t0 = tcg_temp_new();
2317    /* AND rS with a mask that is 0 when rB >= 0x40 */
2318    tcg_gen_shli_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x39);
2319    tcg_gen_sari_tl(t0, t0, 0x3f);
2320    tcg_gen_andc_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
2321    t1 = tcg_temp_new();
2322    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x3f);
2323    tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
2324    tcg_temp_free(t1);
2325    tcg_temp_free(t0);
2326    if (unlikely(Rc(ctx->opcode) != 0))
2327        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
2328}
2329#endif
2330
2331/***                           Addressing modes                            ***/
2332/* Register indirect with immediate index : EA = (rA|0) + SIMM */
2333static inline void gen_addr_imm_index(DisasContext *ctx, TCGv EA,
2334                                      target_long maskl)
2335{
2336    target_long simm = SIMM(ctx->opcode);
2337
2338    simm &= ~maskl;
2339    if (rA(ctx->opcode) == 0) {
2340        if (NARROW_MODE(ctx)) {
2341            simm = (uint32_t)simm;
2342        }
2343        tcg_gen_movi_tl(EA, simm);
2344    } else if (likely(simm != 0)) {
2345        tcg_gen_addi_tl(EA, cpu_gpr[rA(ctx->opcode)], simm);
2346        if (NARROW_MODE(ctx)) {
2347            tcg_gen_ext32u_tl(EA, EA);
2348        }
2349    } else {
2350        if (NARROW_MODE(ctx)) {
2351            tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2352        } else {
2353            tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2354        }
2355    }
2356}
2357
2358static inline void gen_addr_reg_index(DisasContext *ctx, TCGv EA)
2359{
2360    if (rA(ctx->opcode) == 0) {
2361        if (NARROW_MODE(ctx)) {
2362            tcg_gen_ext32u_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2363        } else {
2364            tcg_gen_mov_tl(EA, cpu_gpr[rB(ctx->opcode)]);
2365        }
2366    } else {
2367        tcg_gen_add_tl(EA, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
2368        if (NARROW_MODE(ctx)) {
2369            tcg_gen_ext32u_tl(EA, EA);
2370        }
2371    }
2372}
2373
2374static inline void gen_addr_register(DisasContext *ctx, TCGv EA)
2375{
2376    if (rA(ctx->opcode) == 0) {
2377        tcg_gen_movi_tl(EA, 0);
2378    } else if (NARROW_MODE(ctx)) {
2379        tcg_gen_ext32u_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2380    } else {
2381        tcg_gen_mov_tl(EA, cpu_gpr[rA(ctx->opcode)]);
2382    }
2383}
2384
2385static inline void gen_addr_add(DisasContext *ctx, TCGv ret, TCGv arg1,
2386                                target_long val)
2387{
2388    tcg_gen_addi_tl(ret, arg1, val);
2389    if (NARROW_MODE(ctx)) {
2390        tcg_gen_ext32u_tl(ret, ret);
2391    }
2392}
2393
2394static inline void gen_check_align(DisasContext *ctx, TCGv EA, int mask)
2395{
2396    TCGLabel *l1 = gen_new_label();
2397    TCGv t0 = tcg_temp_new();
2398    TCGv_i32 t1, t2;
2399    tcg_gen_andi_tl(t0, EA, mask);
2400    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2401    t1 = tcg_const_i32(POWERPC_EXCP_ALIGN);
2402    t2 = tcg_const_i32(ctx->opcode & 0x03FF0000);
2403    gen_update_nip(ctx, ctx->nip - 4);
2404    gen_helper_raise_exception_err(cpu_env, t1, t2);
2405    tcg_temp_free_i32(t1);
2406    tcg_temp_free_i32(t2);
2407    gen_set_label(l1);
2408    tcg_temp_free(t0);
2409}
2410
2411static inline void gen_align_no_le(DisasContext *ctx)
2412{
2413    gen_exception_err(ctx, POWERPC_EXCP_ALIGN,
2414                      (ctx->opcode & 0x03FF0000) | POWERPC_EXCP_ALIGN_LE);
2415}
2416
2417/***                             Integer load                              ***/
2418#define DEF_MEMOP(op) ((op) | ctx->default_tcg_memop_mask)
2419#define BSWAP_MEMOP(op) ((op) | (ctx->default_tcg_memop_mask ^ MO_BSWAP))
2420
2421#define GEN_QEMU_LOAD_TL(ldop, op)                                      \
2422static void glue(gen_qemu_, ldop)(DisasContext *ctx,                    \
2423                                  TCGv val,                             \
2424                                  TCGv addr)                            \
2425{                                                                       \
2426    tcg_gen_qemu_ld_tl(val, addr, ctx->mem_idx, op);                    \
2427}
2428
2429GEN_QEMU_LOAD_TL(ld8u,  DEF_MEMOP(MO_UB))
2430GEN_QEMU_LOAD_TL(ld16u, DEF_MEMOP(MO_UW))
2431GEN_QEMU_LOAD_TL(ld16s, DEF_MEMOP(MO_SW))
2432GEN_QEMU_LOAD_TL(ld32u, DEF_MEMOP(MO_UL))
2433GEN_QEMU_LOAD_TL(ld32s, DEF_MEMOP(MO_SL))
2434
2435GEN_QEMU_LOAD_TL(ld16ur, BSWAP_MEMOP(MO_UW))
2436GEN_QEMU_LOAD_TL(ld32ur, BSWAP_MEMOP(MO_UL))
2437
2438#define GEN_QEMU_LOAD_64(ldop, op)                                  \
2439static void glue(gen_qemu_, glue(ldop, _i64))(DisasContext *ctx,    \
2440                                             TCGv_i64 val,          \
2441                                             TCGv addr)             \
2442{                                                                   \
2443    tcg_gen_qemu_ld_i64(val, addr, ctx->mem_idx, op);               \
2444}
2445
2446GEN_QEMU_LOAD_64(ld8u,  DEF_MEMOP(MO_UB))
2447GEN_QEMU_LOAD_64(ld16u, DEF_MEMOP(MO_UW))
2448GEN_QEMU_LOAD_64(ld32u, DEF_MEMOP(MO_UL))
2449GEN_QEMU_LOAD_64(ld32s, DEF_MEMOP(MO_SL))
2450GEN_QEMU_LOAD_64(ld64,  DEF_MEMOP(MO_Q))
2451
2452#if defined(TARGET_PPC64)
2453GEN_QEMU_LOAD_64(ld64ur, BSWAP_MEMOP(MO_Q))
2454#endif
2455
2456#define GEN_QEMU_STORE_TL(stop, op)                                     \
2457static void glue(gen_qemu_, stop)(DisasContext *ctx,                    \
2458                                  TCGv val,                             \
2459                                  TCGv addr)                            \
2460{                                                                       \
2461    tcg_gen_qemu_st_tl(val, addr, ctx->mem_idx, op);                    \
2462}
2463
2464GEN_QEMU_STORE_TL(st8,  DEF_MEMOP(MO_UB))
2465GEN_QEMU_STORE_TL(st16, DEF_MEMOP(MO_UW))
2466GEN_QEMU_STORE_TL(st32, DEF_MEMOP(MO_UL))
2467
2468GEN_QEMU_STORE_TL(st16r, BSWAP_MEMOP(MO_UW))
2469GEN_QEMU_STORE_TL(st32r, BSWAP_MEMOP(MO_UL))
2470
2471#define GEN_QEMU_STORE_64(stop, op)                               \
2472static void glue(gen_qemu_, glue(stop, _i64))(DisasContext *ctx,  \
2473                                              TCGv_i64 val,       \
2474                                              TCGv addr)          \
2475{                                                                 \
2476    tcg_gen_qemu_st_i64(val, addr, ctx->mem_idx, op);             \
2477}
2478
2479GEN_QEMU_STORE_64(st8,  DEF_MEMOP(MO_UB))
2480GEN_QEMU_STORE_64(st16, DEF_MEMOP(MO_UW))
2481GEN_QEMU_STORE_64(st32, DEF_MEMOP(MO_UL))
2482GEN_QEMU_STORE_64(st64, DEF_MEMOP(MO_Q))
2483
2484#if defined(TARGET_PPC64)
2485GEN_QEMU_STORE_64(st64r, BSWAP_MEMOP(MO_Q))
2486#endif
2487
2488#define GEN_LD(name, ldop, opc, type)                                         \
2489static void glue(gen_, name)(DisasContext *ctx)                                       \
2490{                                                                             \
2491    TCGv EA;                                                                  \
2492    gen_set_access_type(ctx, ACCESS_INT);                                     \
2493    EA = tcg_temp_new();                                                      \
2494    gen_addr_imm_index(ctx, EA, 0);                                           \
2495    gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2496    tcg_temp_free(EA);                                                        \
2497}
2498
2499#define GEN_LDU(name, ldop, opc, type)                                        \
2500static void glue(gen_, name##u)(DisasContext *ctx)                                    \
2501{                                                                             \
2502    TCGv EA;                                                                  \
2503    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2504                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2505        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2506        return;                                                               \
2507    }                                                                         \
2508    gen_set_access_type(ctx, ACCESS_INT);                                     \
2509    EA = tcg_temp_new();                                                      \
2510    if (type == PPC_64B)                                                      \
2511        gen_addr_imm_index(ctx, EA, 0x03);                                    \
2512    else                                                                      \
2513        gen_addr_imm_index(ctx, EA, 0);                                       \
2514    gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2515    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2516    tcg_temp_free(EA);                                                        \
2517}
2518
2519#define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
2520static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
2521{                                                                             \
2522    TCGv EA;                                                                  \
2523    if (unlikely(rA(ctx->opcode) == 0 ||                                      \
2524                 rA(ctx->opcode) == rD(ctx->opcode))) {                       \
2525        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2526        return;                                                               \
2527    }                                                                         \
2528    gen_set_access_type(ctx, ACCESS_INT);                                     \
2529    EA = tcg_temp_new();                                                      \
2530    gen_addr_reg_index(ctx, EA);                                              \
2531    gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2532    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2533    tcg_temp_free(EA);                                                        \
2534}
2535
2536#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk)                   \
2537static void glue(gen_, name##x)(DisasContext *ctx)                            \
2538{                                                                             \
2539    TCGv EA;                                                                  \
2540    chk;                                                                      \
2541    gen_set_access_type(ctx, ACCESS_INT);                                     \
2542    EA = tcg_temp_new();                                                      \
2543    gen_addr_reg_index(ctx, EA);                                              \
2544    gen_qemu_##ldop(ctx, cpu_gpr[rD(ctx->opcode)], EA);                       \
2545    tcg_temp_free(EA);                                                        \
2546}
2547
2548#define GEN_LDX(name, ldop, opc2, opc3, type)                                 \
2549    GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_NONE)
2550
2551#define GEN_LDX_HVRM(name, ldop, opc2, opc3, type)                            \
2552    GEN_LDX_E(name, ldop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
2553
2554#define GEN_LDS(name, ldop, op, type)                                         \
2555GEN_LD(name, ldop, op | 0x20, type);                                          \
2556GEN_LDU(name, ldop, op | 0x21, type);                                         \
2557GEN_LDUX(name, ldop, 0x17, op | 0x01, type);                                  \
2558GEN_LDX(name, ldop, 0x17, op | 0x00, type)
2559
2560/* lbz lbzu lbzux lbzx */
2561GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER);
2562/* lha lhau lhaux lhax */
2563GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER);
2564/* lhz lhzu lhzux lhzx */
2565GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER);
2566/* lwz lwzu lwzux lwzx */
2567GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER);
2568#if defined(TARGET_PPC64)
2569/* lwaux */
2570GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B);
2571/* lwax */
2572GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B);
2573/* ldux */
2574GEN_LDUX(ld, ld64_i64, 0x15, 0x01, PPC_64B);
2575/* ldx */
2576GEN_LDX(ld, ld64_i64, 0x15, 0x00, PPC_64B);
2577
2578/* CI load/store variants */
2579GEN_LDX_HVRM(ldcix, ld64_i64, 0x15, 0x1b, PPC_CILDST)
2580GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x15, PPC_CILDST)
2581GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
2582GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
2583
2584static void gen_ld(DisasContext *ctx)
2585{
2586    TCGv EA;
2587    if (Rc(ctx->opcode)) {
2588        if (unlikely(rA(ctx->opcode) == 0 ||
2589                     rA(ctx->opcode) == rD(ctx->opcode))) {
2590            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2591            return;
2592        }
2593    }
2594    gen_set_access_type(ctx, ACCESS_INT);
2595    EA = tcg_temp_new();
2596    gen_addr_imm_index(ctx, EA, 0x03);
2597    if (ctx->opcode & 0x02) {
2598        /* lwa (lwau is undefined) */
2599        gen_qemu_ld32s(ctx, cpu_gpr[rD(ctx->opcode)], EA);
2600    } else {
2601        /* ld - ldu */
2602        gen_qemu_ld64_i64(ctx, cpu_gpr[rD(ctx->opcode)], EA);
2603    }
2604    if (Rc(ctx->opcode))
2605        tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
2606    tcg_temp_free(EA);
2607}
2608
2609/* lq */
2610static void gen_lq(DisasContext *ctx)
2611{
2612    int ra, rd;
2613    TCGv EA;
2614
2615    /* lq is a legal user mode instruction starting in ISA 2.07 */
2616    bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
2617    bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
2618
2619    if (!legal_in_user_mode && ctx->pr) {
2620        gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2621        return;
2622    }
2623
2624    if (!le_is_supported && ctx->le_mode) {
2625        gen_align_no_le(ctx);
2626        return;
2627    }
2628    ra = rA(ctx->opcode);
2629    rd = rD(ctx->opcode);
2630    if (unlikely((rd & 1) || rd == ra)) {
2631        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2632        return;
2633    }
2634
2635    gen_set_access_type(ctx, ACCESS_INT);
2636    EA = tcg_temp_new();
2637    gen_addr_imm_index(ctx, EA, 0x0F);
2638
2639    /* We only need to swap high and low halves. gen_qemu_ld64_i64 does
2640       necessary 64-bit byteswap already. */
2641    if (unlikely(ctx->le_mode)) {
2642        gen_qemu_ld64_i64(ctx, cpu_gpr[rd + 1], EA);
2643        gen_addr_add(ctx, EA, EA, 8);
2644        gen_qemu_ld64_i64(ctx, cpu_gpr[rd], EA);
2645    } else {
2646        gen_qemu_ld64_i64(ctx, cpu_gpr[rd], EA);
2647        gen_addr_add(ctx, EA, EA, 8);
2648        gen_qemu_ld64_i64(ctx, cpu_gpr[rd + 1], EA);
2649    }
2650    tcg_temp_free(EA);
2651}
2652#endif
2653
2654/***                              Integer store                            ***/
2655#define GEN_ST(name, stop, opc, type)                                         \
2656static void glue(gen_, name)(DisasContext *ctx)                                       \
2657{                                                                             \
2658    TCGv EA;                                                                  \
2659    gen_set_access_type(ctx, ACCESS_INT);                                     \
2660    EA = tcg_temp_new();                                                      \
2661    gen_addr_imm_index(ctx, EA, 0);                                           \
2662    gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2663    tcg_temp_free(EA);                                                        \
2664}
2665
2666#define GEN_STU(name, stop, opc, type)                                        \
2667static void glue(gen_, stop##u)(DisasContext *ctx)                                    \
2668{                                                                             \
2669    TCGv EA;                                                                  \
2670    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2671        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2672        return;                                                               \
2673    }                                                                         \
2674    gen_set_access_type(ctx, ACCESS_INT);                                     \
2675    EA = tcg_temp_new();                                                      \
2676    if (type == PPC_64B)                                                      \
2677        gen_addr_imm_index(ctx, EA, 0x03);                                    \
2678    else                                                                      \
2679        gen_addr_imm_index(ctx, EA, 0);                                       \
2680    gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2681    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2682    tcg_temp_free(EA);                                                        \
2683}
2684
2685#define GEN_STUX(name, stop, opc2, opc3, type)                                \
2686static void glue(gen_, name##ux)(DisasContext *ctx)                                   \
2687{                                                                             \
2688    TCGv EA;                                                                  \
2689    if (unlikely(rA(ctx->opcode) == 0)) {                                     \
2690        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);                   \
2691        return;                                                               \
2692    }                                                                         \
2693    gen_set_access_type(ctx, ACCESS_INT);                                     \
2694    EA = tcg_temp_new();                                                      \
2695    gen_addr_reg_index(ctx, EA);                                              \
2696    gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2697    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
2698    tcg_temp_free(EA);                                                        \
2699}
2700
2701#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk)                   \
2702static void glue(gen_, name##x)(DisasContext *ctx)                            \
2703{                                                                             \
2704    TCGv EA;                                                                  \
2705    chk;                                                                      \
2706    gen_set_access_type(ctx, ACCESS_INT);                                     \
2707    EA = tcg_temp_new();                                                      \
2708    gen_addr_reg_index(ctx, EA);                                              \
2709    gen_qemu_##stop(ctx, cpu_gpr[rS(ctx->opcode)], EA);                       \
2710    tcg_temp_free(EA);                                                        \
2711}
2712#define GEN_STX(name, stop, opc2, opc3, type)                                 \
2713    GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_NONE)
2714
2715#define GEN_STX_HVRM(name, stop, opc2, opc3, type)                            \
2716    GEN_STX_E(name, stop, opc2, opc3, type, PPC_NONE, CHK_HVRM)
2717
2718#define GEN_STS(name, stop, op, type)                                         \
2719GEN_ST(name, stop, op | 0x20, type);                                          \
2720GEN_STU(name, stop, op | 0x21, type);                                         \
2721GEN_STUX(name, stop, 0x17, op | 0x01, type);                                  \
2722GEN_STX(name, stop, 0x17, op | 0x00, type)
2723
2724/* stb stbu stbux stbx */
2725GEN_STS(stb, st8, 0x06, PPC_INTEGER);
2726/* sth sthu sthux sthx */
2727GEN_STS(sth, st16, 0x0C, PPC_INTEGER);
2728/* stw stwu stwux stwx */
2729GEN_STS(stw, st32, 0x04, PPC_INTEGER);
2730#if defined(TARGET_PPC64)
2731GEN_STUX(std, st64_i64, 0x15, 0x05, PPC_64B);
2732GEN_STX(std, st64_i64, 0x15, 0x04, PPC_64B);
2733GEN_STX_HVRM(stdcix, st64_i64, 0x15, 0x1f, PPC_CILDST)
2734GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
2735GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
2736GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
2737
2738static void gen_std(DisasContext *ctx)
2739{
2740    int rs;
2741    TCGv EA;
2742
2743    rs = rS(ctx->opcode);
2744    if ((ctx->opcode & 0x3) == 0x2) { /* stq */
2745        bool legal_in_user_mode = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
2746        bool le_is_supported = (ctx->insns_flags2 & PPC2_LSQ_ISA207) != 0;
2747
2748        if (!(ctx->insns_flags & PPC_64BX)) {
2749            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2750        }
2751
2752        if (!legal_in_user_mode && ctx->pr) {
2753            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);
2754            return;
2755        }
2756
2757        if (!le_is_supported && ctx->le_mode) {
2758            gen_align_no_le(ctx);
2759            return;
2760        }
2761
2762        if (unlikely(rs & 1)) {
2763            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2764            return;
2765        }
2766        gen_set_access_type(ctx, ACCESS_INT);
2767        EA = tcg_temp_new();
2768        gen_addr_imm_index(ctx, EA, 0x03);
2769
2770        /* We only need to swap high and low halves. gen_qemu_st64_i64 does
2771           necessary 64-bit byteswap already. */
2772        if (unlikely(ctx->le_mode)) {
2773            gen_qemu_st64_i64(ctx, cpu_gpr[rs + 1], EA);
2774            gen_addr_add(ctx, EA, EA, 8);
2775            gen_qemu_st64_i64(ctx, cpu_gpr[rs], EA);
2776        } else {
2777            gen_qemu_st64_i64(ctx, cpu_gpr[rs], EA);
2778            gen_addr_add(ctx, EA, EA, 8);
2779            gen_qemu_st64_i64(ctx, cpu_gpr[rs + 1], EA);
2780        }
2781        tcg_temp_free(EA);
2782    } else {
2783        /* std / stdu*/
2784        if (Rc(ctx->opcode)) {
2785            if (unlikely(rA(ctx->opcode) == 0)) {
2786                gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
2787                return;
2788            }
2789        }
2790        gen_set_access_type(ctx, ACCESS_INT);
2791        EA = tcg_temp_new();
2792        gen_addr_imm_index(ctx, EA, 0x03);
2793        gen_qemu_st64_i64(ctx, cpu_gpr[rs], EA);
2794        if (Rc(ctx->opcode))
2795            tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);
2796        tcg_temp_free(EA);
2797    }
2798}
2799#endif
2800/***                Integer load and store with byte reverse               ***/
2801
2802/* lhbrx */
2803GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
2804
2805/* lwbrx */
2806GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
2807
2808#if defined(TARGET_PPC64)
2809/* ldbrx */
2810GEN_LDX_E(ldbr, ld64ur_i64, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE);
2811/* stdbrx */
2812GEN_STX_E(stdbr, st64r_i64, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE);
2813#endif  /* TARGET_PPC64 */
2814
2815/* sthbrx */
2816GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
2817/* stwbrx */
2818GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
2819
2820/***                    Integer load and store multiple                    ***/
2821
2822/* lmw */
2823static void gen_lmw(DisasContext *ctx)
2824{
2825    TCGv t0;
2826    TCGv_i32 t1;
2827
2828    if (ctx->le_mode) {
2829        gen_align_no_le(ctx);
2830        return;
2831    }
2832    gen_set_access_type(ctx, ACCESS_INT);
2833    t0 = tcg_temp_new();
2834    t1 = tcg_const_i32(rD(ctx->opcode));
2835    gen_addr_imm_index(ctx, t0, 0);
2836    gen_helper_lmw(cpu_env, t0, t1);
2837    tcg_temp_free(t0);
2838    tcg_temp_free_i32(t1);
2839}
2840
2841/* stmw */
2842static void gen_stmw(DisasContext *ctx)
2843{
2844    TCGv t0;
2845    TCGv_i32 t1;
2846
2847    if (ctx->le_mode) {
2848        gen_align_no_le(ctx);
2849        return;
2850    }
2851    gen_set_access_type(ctx, ACCESS_INT);
2852    t0 = tcg_temp_new();
2853    t1 = tcg_const_i32(rS(ctx->opcode));
2854    gen_addr_imm_index(ctx, t0, 0);
2855    gen_helper_stmw(cpu_env, t0, t1);
2856    tcg_temp_free(t0);
2857    tcg_temp_free_i32(t1);
2858}
2859
2860/***                    Integer load and store strings                     ***/
2861
2862/* lswi */
2863/* PowerPC32 specification says we must generate an exception if
2864 * rA is in the range of registers to be loaded.
2865 * In an other hand, IBM says this is valid, but rA won't be loaded.
2866 * For now, I'll follow the spec...
2867 */
2868static void gen_lswi(DisasContext *ctx)
2869{
2870    TCGv t0;
2871    TCGv_i32 t1, t2;
2872    int nb = NB(ctx->opcode);
2873    int start = rD(ctx->opcode);
2874    int ra = rA(ctx->opcode);
2875    int nr;
2876
2877    if (ctx->le_mode) {
2878        gen_align_no_le(ctx);
2879        return;
2880    }
2881    if (nb == 0)
2882        nb = 32;
2883    nr = (nb + 3) / 4;
2884    if (unlikely(lsw_reg_in_range(start, nr, ra))) {
2885        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX);
2886        return;
2887    }
2888    gen_set_access_type(ctx, ACCESS_INT);
2889    t0 = tcg_temp_new();
2890    gen_addr_register(ctx, t0);
2891    t1 = tcg_const_i32(nb);
2892    t2 = tcg_const_i32(start);
2893    gen_helper_lsw(cpu_env, t0, t1, t2);
2894    tcg_temp_free(t0);
2895    tcg_temp_free_i32(t1);
2896    tcg_temp_free_i32(t2);
2897}
2898
2899/* lswx */
2900static void gen_lswx(DisasContext *ctx)
2901{
2902    TCGv t0;
2903    TCGv_i32 t1, t2, t3;
2904
2905    if (ctx->le_mode) {
2906        gen_align_no_le(ctx);
2907        return;
2908    }
2909    gen_set_access_type(ctx, ACCESS_INT);
2910    t0 = tcg_temp_new();
2911    gen_addr_reg_index(ctx, t0);
2912    t1 = tcg_const_i32(rD(ctx->opcode));
2913    t2 = tcg_const_i32(rA(ctx->opcode));
2914    t3 = tcg_const_i32(rB(ctx->opcode));
2915    gen_helper_lswx(cpu_env, t0, t1, t2, t3);
2916    tcg_temp_free(t0);
2917    tcg_temp_free_i32(t1);
2918    tcg_temp_free_i32(t2);
2919    tcg_temp_free_i32(t3);
2920}
2921
2922/* stswi */
2923static void gen_stswi(DisasContext *ctx)
2924{
2925    TCGv t0;
2926    TCGv_i32 t1, t2;
2927    int nb = NB(ctx->opcode);
2928
2929    if (ctx->le_mode) {
2930        gen_align_no_le(ctx);
2931        return;
2932    }
2933    gen_set_access_type(ctx, ACCESS_INT);
2934    t0 = tcg_temp_new();
2935    gen_addr_register(ctx, t0);
2936    if (nb == 0)
2937        nb = 32;
2938    t1 = tcg_const_i32(nb);
2939    t2 = tcg_const_i32(rS(ctx->opcode));
2940    gen_helper_stsw(cpu_env, t0, t1, t2);
2941    tcg_temp_free(t0);
2942    tcg_temp_free_i32(t1);
2943    tcg_temp_free_i32(t2);
2944}
2945
2946/* stswx */
2947static void gen_stswx(DisasContext *ctx)
2948{
2949    TCGv t0;
2950    TCGv_i32 t1, t2;
2951
2952    if (ctx->le_mode) {
2953        gen_align_no_le(ctx);
2954        return;
2955    }
2956    gen_set_access_type(ctx, ACCESS_INT);
2957    t0 = tcg_temp_new();
2958    gen_addr_reg_index(ctx, t0);
2959    t1 = tcg_temp_new_i32();
2960    tcg_gen_trunc_tl_i32(t1, cpu_xer);
2961    tcg_gen_andi_i32(t1, t1, 0x7F);
2962    t2 = tcg_const_i32(rS(ctx->opcode));
2963    gen_helper_stsw(cpu_env, t0, t1, t2);
2964    tcg_temp_free(t0);
2965    tcg_temp_free_i32(t1);
2966    tcg_temp_free_i32(t2);
2967}
2968
2969/***                        Memory synchronisation                         ***/
2970/* eieio */
2971static void gen_eieio(DisasContext *ctx)
2972{
2973    tcg_gen_mb(TCG_MO_LD_ST | TCG_BAR_SC);
2974}
2975
2976#if !defined(CONFIG_USER_ONLY)
2977static inline void gen_check_tlb_flush(DisasContext *ctx, bool global)
2978{
2979    TCGv_i32 t;
2980    TCGLabel *l;
2981
2982    if (!ctx->lazy_tlb_flush) {
2983        return;
2984    }
2985    l = gen_new_label();
2986    t = tcg_temp_new_i32();
2987    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
2988    tcg_gen_brcondi_i32(TCG_COND_EQ, t, 0, l);
2989    if (global) {
2990        gen_helper_check_tlb_flush_global(cpu_env);
2991    } else {
2992        gen_helper_check_tlb_flush_local(cpu_env);
2993    }
2994    gen_set_label(l);
2995    tcg_temp_free_i32(t);
2996}
2997#else
2998static inline void gen_check_tlb_flush(DisasContext *ctx, bool global) { }
2999#endif
3000
3001/* isync */
3002static void gen_isync(DisasContext *ctx)
3003{
3004    /*
3005     * We need to check for a pending TLB flush. This can only happen in
3006     * kernel mode however so check MSR_PR
3007     */
3008    if (!ctx->pr) {
3009        gen_check_tlb_flush(ctx, false);
3010    }
3011    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
3012    gen_stop_exception(ctx);
3013}
3014
3015#define MEMOP_GET_SIZE(x)  (1 << ((x) & MO_SIZE))
3016
3017#define LARX(name, memop)                                            \
3018static void gen_##name(DisasContext *ctx)                            \
3019{                                                                    \
3020    TCGv t0;                                                         \
3021    TCGv gpr = cpu_gpr[rD(ctx->opcode)];                             \
3022    int len = MEMOP_GET_SIZE(memop);                                 \
3023    gen_set_access_type(ctx, ACCESS_RES);                            \
3024    t0 = tcg_temp_local_new();                                       \
3025    gen_addr_reg_index(ctx, t0);                                     \
3026    if ((len) > 1) {                                                 \
3027        gen_check_align(ctx, t0, (len)-1);                           \
3028    }                                                                \
3029    tcg_gen_qemu_ld_tl(gpr, t0, ctx->mem_idx, memop);                \
3030    tcg_gen_mov_tl(cpu_reserve, t0);                                 \
3031    tcg_gen_mov_tl(cpu_reserve_val, gpr);                            \
3032    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);                           \
3033    tcg_temp_free(t0);                                               \
3034}
3035
3036/* lwarx */
3037LARX(lbarx, DEF_MEMOP(MO_UB))
3038LARX(lharx, DEF_MEMOP(MO_UW))
3039LARX(lwarx, DEF_MEMOP(MO_UL))
3040
3041#define LD_ATOMIC(name, memop, tp, op, eop)                             \
3042static void gen_##name(DisasContext *ctx)                               \
3043{                                                                       \
3044    int len = MEMOP_GET_SIZE(memop);                                    \
3045    uint32_t gpr_FC = FC(ctx->opcode);                                  \
3046    TCGv EA = tcg_temp_local_new();                                     \
3047    TCGv_##tp t0, t1;                                                   \
3048                                                                        \
3049    gen_addr_register(ctx, EA);                                         \
3050    if (len > 1) {                                                      \
3051        gen_check_align(ctx, EA, len - 1);                              \
3052    }                                                                   \
3053    t0 = tcg_temp_new_##tp();                                           \
3054    t1 = tcg_temp_new_##tp();                                           \
3055    tcg_gen_##op(t0, cpu_gpr[rD(ctx->opcode) + 1]);                     \
3056                                                                        \
3057    switch (gpr_FC) {                                                   \
3058    case 0: /* Fetch and add */                                         \
3059        tcg_gen_atomic_fetch_add_##tp(t1, EA, t0, ctx->mem_idx, memop); \
3060        break;                                                          \
3061    case 1: /* Fetch and xor */                                         \
3062        tcg_gen_atomic_fetch_xor_##tp(t1, EA, t0, ctx->mem_idx, memop); \
3063        break;                                                          \
3064    case 2: /* Fetch and or */                                          \
3065        tcg_gen_atomic_fetch_or_##tp(t1, EA, t0, ctx->mem_idx, memop);  \
3066        break;                                                          \
3067    case 3: /* Fetch and 'and' */                                       \
3068        tcg_gen_atomic_fetch_and_##tp(t1, EA, t0, ctx->mem_idx, memop); \
3069        break;                                                          \
3070    case 8: /* Swap */                                                  \
3071        tcg_gen_atomic_xchg_##tp(t1, EA, t0, ctx->mem_idx, memop);      \
3072        break;                                                          \
3073    case 4:  /* Fetch and max unsigned */                               \
3074    case 5:  /* Fetch and max signed */                                 \
3075    case 6:  /* Fetch and min unsigned */                               \
3076    case 7:  /* Fetch and min signed */                                 \
3077    case 16: /* compare and swap not equal */                           \
3078    case 24: /* Fetch and increment bounded */                          \
3079    case 25: /* Fetch and increment equal */                            \
3080    case 28: /* Fetch and decrement bounded */                          \
3081        gen_invalid(ctx);                                               \
3082        break;                                                          \
3083    default:                                                            \
3084        /* invoke data storage error handler */                         \
3085        gen_exception_err(ctx, POWERPC_EXCP_DSI, POWERPC_EXCP_INVAL);   \
3086    }                                                                   \
3087    tcg_gen_##eop(cpu_gpr[rD(ctx->opcode)], t1);                        \
3088    tcg_temp_free_##tp(t0);                                             \
3089    tcg_temp_free_##tp(t1);                                             \
3090    tcg_temp_free(EA);                                                  \
3091}
3092
3093LD_ATOMIC(lwat, DEF_MEMOP(MO_UL), i32, trunc_tl_i32, extu_i32_tl)
3094#if defined(TARGET_PPC64)
3095LD_ATOMIC(ldat, DEF_MEMOP(MO_Q), i64, mov_i64, mov_i64)
3096#endif
3097
3098#define ST_ATOMIC(name, memop, tp, op)                                  \
3099static void gen_##name(DisasContext *ctx)                               \
3100{                                                                       \
3101    int len = MEMOP_GET_SIZE(memop);                                    \
3102    uint32_t gpr_FC = FC(ctx->opcode);                                  \
3103    TCGv EA = tcg_temp_local_new();                                     \
3104    TCGv_##tp t0, t1;                                                   \
3105                                                                        \
3106    gen_addr_register(ctx, EA);                                         \
3107    if (len > 1) {                                                      \
3108        gen_check_align(ctx, EA, len - 1);                              \
3109    }                                                                   \
3110    t0 = tcg_temp_new_##tp();                                           \
3111    t1 = tcg_temp_new_##tp();                                           \
3112    tcg_gen_##op(t0, cpu_gpr[rD(ctx->opcode) + 1]);                     \
3113                                                                        \
3114    switch (gpr_FC) {                                                   \
3115    case 0: /* add and Store */                                         \
3116        tcg_gen_atomic_add_fetch_##tp(t1, EA, t0, ctx->mem_idx, memop); \
3117        break;                                                          \
3118    case 1: /* xor and Store */                                         \
3119        tcg_gen_atomic_xor_fetch_##tp(t1, EA, t0, ctx->mem_idx, memop); \
3120        break;                                                          \
3121    case 2: /* Or and Store */                                          \
3122        tcg_gen_atomic_or_fetch_##tp(t1, EA, t0, ctx->mem_idx, memop);  \
3123        break;                                                          \
3124    case 3: /* 'and' and Store */                                       \
3125        tcg_gen_atomic_and_fetch_##tp(t1, EA, t0, ctx->mem_idx, memop); \
3126        break;                                                          \
3127    case 4:  /* Store max unsigned */                                   \
3128    case 5:  /* Store max signed */                                     \
3129    case 6:  /* Store min unsigned */                                   \
3130    case 7:  /* Store min signed */                                     \
3131    case 24: /* Store twin  */                                          \
3132        gen_invalid(ctx);                                               \
3133        break;                                                          \
3134    default:                                                            \
3135        /* invoke data storage error handler */                         \
3136        gen_exception_err(ctx, POWERPC_EXCP_DSI, POWERPC_EXCP_INVAL);   \
3137    }                                                                   \
3138    tcg_temp_free_##tp(t0);                                             \
3139    tcg_temp_free_##tp(t1);                                             \
3140    tcg_temp_free(EA);                                                  \
3141}
3142
3143ST_ATOMIC(stwat, DEF_MEMOP(MO_UL), i32, trunc_tl_i32)
3144#if defined(TARGET_PPC64)
3145ST_ATOMIC(stdat, DEF_MEMOP(MO_Q), i64, mov_i64)
3146#endif
3147
3148#if defined(CONFIG_USER_ONLY)
3149static void gen_conditional_store(DisasContext *ctx, TCGv EA,
3150                                  int reg, int memop)
3151{
3152    TCGv t0 = tcg_temp_new();
3153
3154    tcg_gen_st_tl(EA, cpu_env, offsetof(CPUPPCState, reserve_ea));
3155    tcg_gen_movi_tl(t0, (MEMOP_GET_SIZE(memop) << 5) | reg);
3156    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, reserve_info));
3157    tcg_temp_free(t0);
3158    gen_exception_err(ctx, POWERPC_EXCP_STCX, 0);
3159}
3160#else
3161static void gen_conditional_store(DisasContext *ctx, TCGv EA,
3162                                  int reg, int memop)
3163{
3164    TCGLabel *l1 = gen_new_label();
3165    TCGLabel *l2 = gen_new_label();
3166    TCGv t0;
3167
3168    tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, l1);
3169
3170    t0 = tcg_temp_new();
3171    tcg_gen_atomic_cmpxchg_tl(t0, cpu_reserve, cpu_reserve_val,
3172                              cpu_gpr[reg], ctx->mem_idx,
3173                              DEF_MEMOP(memop) | MO_ALIGN);
3174    tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_reserve_val);
3175    tcg_gen_shli_tl(t0, t0, CRF_EQ_BIT);
3176    tcg_gen_or_tl(t0, t0, cpu_so);
3177    tcg_gen_trunc_tl_i32(cpu_crf[0], t0);
3178    tcg_temp_free(t0);
3179    tcg_gen_br(l2);
3180
3181    gen_set_label(l1);
3182
3183    /* Address mismatch implies failure.  But we still need to provide the
3184       memory barrier semantics of the instruction.  */
3185    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
3186    tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
3187
3188    gen_set_label(l2);
3189    tcg_gen_movi_tl(cpu_reserve, -1);
3190}
3191#endif
3192
3193#define STCX(name, memop)                                   \
3194static void gen_##name(DisasContext *ctx)                   \
3195{                                                           \
3196    TCGv t0;                                                \
3197    int len = MEMOP_GET_SIZE(memop);                        \
3198    gen_set_access_type(ctx, ACCESS_RES);                   \
3199    t0 = tcg_temp_local_new();                              \
3200    gen_addr_reg_index(ctx, t0);                            \
3201    if (len > 1) {                                          \
3202        gen_check_align(ctx, t0, (len) - 1);                \
3203    }                                                       \
3204    gen_conditional_store(ctx, t0, rS(ctx->opcode), memop); \
3205    tcg_temp_free(t0);                                      \
3206}
3207
3208STCX(stbcx_, DEF_MEMOP(MO_UB))
3209STCX(sthcx_, DEF_MEMOP(MO_UW))
3210STCX(stwcx_, DEF_MEMOP(MO_UL))
3211
3212#if defined(TARGET_PPC64)
3213/* ldarx */
3214LARX(ldarx, DEF_MEMOP(MO_Q))
3215/* stdcx. */
3216STCX(stdcx_, DEF_MEMOP(MO_Q))
3217
3218/* lqarx */
3219static void gen_lqarx(DisasContext *ctx)
3220{
3221    TCGv EA;
3222    int rd = rD(ctx->opcode);
3223    TCGv gpr1, gpr2;
3224
3225    if (unlikely((rd & 1) || (rd == rA(ctx->opcode)) ||
3226                 (rd == rB(ctx->opcode)))) {
3227        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3228        return;
3229    }
3230
3231    gen_set_access_type(ctx, ACCESS_RES);
3232    EA = tcg_temp_local_new();
3233    gen_addr_reg_index(ctx, EA);
3234    gen_check_align(ctx, EA, 15);
3235    if (unlikely(ctx->le_mode)) {
3236        gpr1 = cpu_gpr[rd+1];
3237        gpr2 = cpu_gpr[rd];
3238    } else {
3239        gpr1 = cpu_gpr[rd];
3240        gpr2 = cpu_gpr[rd+1];
3241    }
3242    tcg_gen_qemu_ld_i64(gpr1, EA, ctx->mem_idx, DEF_MEMOP(MO_Q));
3243    tcg_gen_mov_tl(cpu_reserve, EA);
3244    gen_addr_add(ctx, EA, EA, 8);
3245    tcg_gen_qemu_ld_i64(gpr2, EA, ctx->mem_idx, DEF_MEMOP(MO_Q));
3246
3247    tcg_gen_st_tl(gpr1, cpu_env, offsetof(CPUPPCState, reserve_val));
3248    tcg_gen_st_tl(gpr2, cpu_env, offsetof(CPUPPCState, reserve_val2));
3249    tcg_temp_free(EA);
3250}
3251
3252/* stqcx. */
3253static void gen_stqcx_(DisasContext *ctx)
3254{
3255    TCGv EA;
3256    int reg = rS(ctx->opcode);
3257    int len = 16;
3258#if !defined(CONFIG_USER_ONLY)
3259    TCGLabel *l1;
3260    TCGv gpr1, gpr2;
3261#endif
3262
3263    if (unlikely((rD(ctx->opcode) & 1))) {
3264        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3265        return;
3266    }
3267    gen_set_access_type(ctx, ACCESS_RES);
3268    EA = tcg_temp_local_new();
3269    gen_addr_reg_index(ctx, EA);
3270    if (len > 1) {
3271        gen_check_align(ctx, EA, (len) - 1);
3272    }
3273
3274#if defined(CONFIG_USER_ONLY)
3275    gen_conditional_store(ctx, EA, reg, 16);
3276#else
3277    tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
3278    l1 = gen_new_label();
3279    tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, l1);
3280    tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], CRF_EQ);
3281
3282    if (unlikely(ctx->le_mode)) {
3283        gpr1 = cpu_gpr[reg + 1];
3284        gpr2 = cpu_gpr[reg];
3285    } else {
3286        gpr1 = cpu_gpr[reg];
3287        gpr2 = cpu_gpr[reg + 1];
3288    }
3289    tcg_gen_qemu_st_tl(gpr1, EA, ctx->mem_idx, DEF_MEMOP(MO_Q));
3290    gen_addr_add(ctx, EA, EA, 8);
3291    tcg_gen_qemu_st_tl(gpr2, EA, ctx->mem_idx, DEF_MEMOP(MO_Q));
3292
3293    gen_set_label(l1);
3294    tcg_gen_movi_tl(cpu_reserve, -1);
3295#endif
3296    tcg_temp_free(EA);
3297}
3298
3299#endif /* defined(TARGET_PPC64) */
3300
3301/* sync */
3302static void gen_sync(DisasContext *ctx)
3303{
3304    uint32_t l = (ctx->opcode >> 21) & 3;
3305
3306    /*
3307     * We may need to check for a pending TLB flush.
3308     *
3309     * We do this on ptesync (l == 2) on ppc64 and any sync pn ppc32.
3310     *
3311     * Additionally, this can only happen in kernel mode however so
3312     * check MSR_PR as well.
3313     */
3314    if (((l == 2) || !(ctx->insns_flags & PPC_64B)) && !ctx->pr) {
3315        gen_check_tlb_flush(ctx, true);
3316    }
3317    tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
3318}
3319
3320/* wait */
3321static void gen_wait(DisasContext *ctx)
3322{
3323    TCGv_i32 t0 = tcg_const_i32(1);
3324    tcg_gen_st_i32(t0, cpu_env,
3325                   -offsetof(PowerPCCPU, env) + offsetof(CPUState, halted));
3326    tcg_temp_free_i32(t0);
3327    /* Stop translation, as the CPU is supposed to sleep from now */
3328    gen_exception_nip(ctx, EXCP_HLT, ctx->nip);
3329}
3330
3331#if defined(TARGET_PPC64)
3332static void gen_doze(DisasContext *ctx)
3333{
3334#if defined(CONFIG_USER_ONLY)
3335    GEN_PRIV;
3336#else
3337    TCGv_i32 t;
3338
3339    CHK_HV;
3340    t = tcg_const_i32(PPC_PM_DOZE);
3341    gen_helper_pminsn(cpu_env, t);
3342    tcg_temp_free_i32(t);
3343    gen_stop_exception(ctx);
3344#endif /* defined(CONFIG_USER_ONLY) */
3345}
3346
3347static void gen_nap(DisasContext *ctx)
3348{
3349#if defined(CONFIG_USER_ONLY)
3350    GEN_PRIV;
3351#else
3352    TCGv_i32 t;
3353
3354    CHK_HV;
3355    t = tcg_const_i32(PPC_PM_NAP);
3356    gen_helper_pminsn(cpu_env, t);
3357    tcg_temp_free_i32(t);
3358    gen_stop_exception(ctx);
3359#endif /* defined(CONFIG_USER_ONLY) */
3360}
3361
3362static void gen_stop(DisasContext *ctx)
3363{
3364    gen_nap(ctx);
3365}
3366
3367static void gen_sleep(DisasContext *ctx)
3368{
3369#if defined(CONFIG_USER_ONLY)
3370    GEN_PRIV;
3371#else
3372    TCGv_i32 t;
3373
3374    CHK_HV;
3375    t = tcg_const_i32(PPC_PM_SLEEP);
3376    gen_helper_pminsn(cpu_env, t);
3377    tcg_temp_free_i32(t);
3378    gen_stop_exception(ctx);
3379#endif /* defined(CONFIG_USER_ONLY) */
3380}
3381
3382static void gen_rvwinkle(DisasContext *ctx)
3383{
3384#if defined(CONFIG_USER_ONLY)
3385    GEN_PRIV;
3386#else
3387    TCGv_i32 t;
3388
3389    CHK_HV;
3390    t = tcg_const_i32(PPC_PM_RVWINKLE);
3391    gen_helper_pminsn(cpu_env, t);
3392    tcg_temp_free_i32(t);
3393    gen_stop_exception(ctx);
3394#endif /* defined(CONFIG_USER_ONLY) */
3395}
3396#endif /* #if defined(TARGET_PPC64) */
3397
3398static inline void gen_update_cfar(DisasContext *ctx, target_ulong nip)
3399{
3400#if defined(TARGET_PPC64)
3401    if (ctx->has_cfar)
3402        tcg_gen_movi_tl(cpu_cfar, nip);
3403#endif
3404}
3405
3406static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
3407{
3408    if (unlikely(ctx->singlestep_enabled)) {
3409        return false;
3410    }
3411
3412#ifndef CONFIG_USER_ONLY
3413    return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
3414#else
3415    return true;
3416#endif
3417}
3418
3419/***                                Branch                                 ***/
3420static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3421{
3422    if (NARROW_MODE(ctx)) {
3423        dest = (uint32_t) dest;
3424    }
3425    if (use_goto_tb(ctx, dest)) {
3426        tcg_gen_goto_tb(n);
3427        tcg_gen_movi_tl(cpu_nip, dest & ~3);
3428        tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
3429    } else {
3430        tcg_gen_movi_tl(cpu_nip, dest & ~3);
3431        if (unlikely(ctx->singlestep_enabled)) {
3432            if ((ctx->singlestep_enabled &
3433                (CPU_BRANCH_STEP | CPU_SINGLE_STEP)) &&
3434                (ctx->exception == POWERPC_EXCP_BRANCH ||
3435                 ctx->exception == POWERPC_EXCP_TRACE)) {
3436                gen_exception_nip(ctx, POWERPC_EXCP_TRACE, dest);
3437            }
3438            if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) {
3439                gen_debug_exception(ctx);
3440            }
3441        }
3442        tcg_gen_exit_tb(0);
3443    }
3444}
3445
3446static inline void gen_setlr(DisasContext *ctx, target_ulong nip)
3447{
3448    if (NARROW_MODE(ctx)) {
3449        nip = (uint32_t)nip;
3450    }
3451    tcg_gen_movi_tl(cpu_lr, nip);
3452}
3453
3454/* b ba bl bla */
3455static void gen_b(DisasContext *ctx)
3456{
3457    target_ulong li, target;
3458
3459    ctx->exception = POWERPC_EXCP_BRANCH;
3460    /* sign extend LI */
3461    li = LI(ctx->opcode);
3462    li = (li ^ 0x02000000) - 0x02000000;
3463    if (likely(AA(ctx->opcode) == 0)) {
3464        target = ctx->nip + li - 4;
3465    } else {
3466        target = li;
3467    }
3468    if (LK(ctx->opcode)) {
3469        gen_setlr(ctx, ctx->nip);
3470    }
3471    gen_update_cfar(ctx, ctx->nip - 4);
3472    gen_goto_tb(ctx, 0, target);
3473}
3474
3475#define BCOND_IM  0
3476#define BCOND_LR  1
3477#define BCOND_CTR 2
3478#define BCOND_TAR 3
3479
3480static inline void gen_bcond(DisasContext *ctx, int type)
3481{
3482    uint32_t bo = BO(ctx->opcode);
3483    TCGLabel *l1;
3484    TCGv target;
3485
3486    ctx->exception = POWERPC_EXCP_BRANCH;
3487    if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) {
3488        target = tcg_temp_local_new();
3489        if (type == BCOND_CTR)
3490            tcg_gen_mov_tl(target, cpu_ctr);
3491        else if (type == BCOND_TAR)
3492            gen_load_spr(target, SPR_TAR);
3493        else
3494            tcg_gen_mov_tl(target, cpu_lr);
3495    } else {
3496        TCGV_UNUSED(target);
3497    }
3498    if (LK(ctx->opcode))
3499        gen_setlr(ctx, ctx->nip);
3500    l1 = gen_new_label();
3501    if ((bo & 0x4) == 0) {
3502        /* Decrement and test CTR */
3503        TCGv temp = tcg_temp_new();
3504        if (unlikely(type == BCOND_CTR)) {
3505            gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3506            return;
3507        }
3508        tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1);
3509        if (NARROW_MODE(ctx)) {
3510            tcg_gen_ext32u_tl(temp, cpu_ctr);
3511        } else {
3512            tcg_gen_mov_tl(temp, cpu_ctr);
3513        }
3514        if (bo & 0x2) {
3515            tcg_gen_brcondi_tl(TCG_COND_NE, temp, 0, l1);
3516        } else {
3517            tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
3518        }
3519        tcg_temp_free(temp);
3520    }
3521    if ((bo & 0x10) == 0) {
3522        /* Test CR */
3523        uint32_t bi = BI(ctx->opcode);
3524        uint32_t mask = 0x08 >> (bi & 0x03);
3525        TCGv_i32 temp = tcg_temp_new_i32();
3526
3527        if (bo & 0x8) {
3528            tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3529            tcg_gen_brcondi_i32(TCG_COND_EQ, temp, 0, l1);
3530        } else {
3531            tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
3532            tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);
3533        }
3534        tcg_temp_free_i32(temp);
3535    }
3536    gen_update_cfar(ctx, ctx->nip - 4);
3537    if (type == BCOND_IM) {
3538        target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
3539        if (likely(AA(ctx->opcode) == 0)) {
3540            gen_goto_tb(ctx, 0, ctx->nip + li - 4);
3541        } else {
3542            gen_goto_tb(ctx, 0, li);
3543        }
3544        if ((bo & 0x14) != 0x14) {
3545            gen_set_label(l1);
3546            gen_goto_tb(ctx, 1, ctx->nip);
3547        }
3548    } else {
3549        if (NARROW_MODE(ctx)) {
3550            tcg_gen_andi_tl(cpu_nip, target, (uint32_t)~3);
3551        } else {
3552            tcg_gen_andi_tl(cpu_nip, target, ~3);
3553        }
3554        tcg_gen_exit_tb(0);
3555        if ((bo & 0x14) != 0x14) {
3556            gen_set_label(l1);
3557            gen_update_nip(ctx, ctx->nip);
3558            tcg_gen_exit_tb(0);
3559        }
3560    }
3561    if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) {
3562        tcg_temp_free(target);
3563    }
3564}
3565
3566static void gen_bc(DisasContext *ctx)
3567{
3568    gen_bcond(ctx, BCOND_IM);
3569}
3570
3571static void gen_bcctr(DisasContext *ctx)
3572{
3573    gen_bcond(ctx, BCOND_CTR);
3574}
3575
3576static void gen_bclr(DisasContext *ctx)
3577{
3578    gen_bcond(ctx, BCOND_LR);
3579}
3580
3581static void gen_bctar(DisasContext *ctx)
3582{
3583    gen_bcond(ctx, BCOND_TAR);
3584}
3585
3586/***                      Condition register logical                       ***/
3587#define GEN_CRLOGIC(name, tcg_op, opc)                                        \
3588static void glue(gen_, name)(DisasContext *ctx)                                       \
3589{                                                                             \
3590    uint8_t bitmask;                                                          \
3591    int sh;                                                                   \
3592    TCGv_i32 t0, t1;                                                          \
3593    sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
3594    t0 = tcg_temp_new_i32();                                                  \
3595    if (sh > 0)                                                               \
3596        tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh);            \
3597    else if (sh < 0)                                                          \
3598        tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh);           \
3599    else                                                                      \
3600        tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]);                 \
3601    t1 = tcg_temp_new_i32();                                                  \
3602    sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
3603    if (sh > 0)                                                               \
3604        tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh);            \
3605    else if (sh < 0)                                                          \
3606        tcg_gen_shli_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], -sh);           \
3607    else                                                                      \
3608        tcg_gen_mov_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2]);                 \
3609    tcg_op(t0, t0, t1);                                                       \
3610    bitmask = 0x08 >> (crbD(ctx->opcode) & 0x03);                             \
3611    tcg_gen_andi_i32(t0, t0, bitmask);                                        \
3612    tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask);          \
3613    tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1);                  \
3614    tcg_temp_free_i32(t0);                                                    \
3615    tcg_temp_free_i32(t1);                                                    \
3616}
3617
3618/* crand */
3619GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08);
3620/* crandc */
3621GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04);
3622/* creqv */
3623GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09);
3624/* crnand */
3625GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07);
3626/* crnor */
3627GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01);
3628/* cror */
3629GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E);
3630/* crorc */
3631GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D);
3632/* crxor */
3633GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06);
3634
3635/* mcrf */
3636static void gen_mcrf(DisasContext *ctx)
3637{
3638    tcg_gen_mov_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfS(ctx->opcode)]);
3639}
3640
3641/***                           System linkage                              ***/
3642
3643/* rfi (supervisor only) */
3644static void gen_rfi(DisasContext *ctx)
3645{
3646#if defined(CONFIG_USER_ONLY)
3647    GEN_PRIV;
3648#else
3649    /* This instruction doesn't exist anymore on 64-bit server
3650     * processors compliant with arch 2.x
3651     */
3652    if (ctx->insns_flags & PPC_SEGMENT_64B) {
3653        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3654        return;
3655    }
3656    /* Restore CPU state */
3657    CHK_SV;
3658    gen_update_cfar(ctx, ctx->nip - 4);
3659    gen_helper_rfi(cpu_env);
3660    gen_sync_exception(ctx);
3661#endif
3662}
3663
3664#if defined(TARGET_PPC64)
3665static void gen_rfid(DisasContext *ctx)
3666{
3667#if defined(CONFIG_USER_ONLY)
3668    GEN_PRIV;
3669#else
3670    /* Restore CPU state */
3671    CHK_SV;
3672    gen_update_cfar(ctx, ctx->nip - 4);
3673    gen_helper_rfid(cpu_env);
3674    gen_sync_exception(ctx);
3675#endif
3676}
3677
3678static void gen_hrfid(DisasContext *ctx)
3679{
3680#if defined(CONFIG_USER_ONLY)
3681    GEN_PRIV;
3682#else
3683    /* Restore CPU state */
3684    CHK_HV;
3685    gen_helper_hrfid(cpu_env);
3686    gen_sync_exception(ctx);
3687#endif
3688}
3689#endif
3690
3691/* sc */
3692#if defined(CONFIG_USER_ONLY)
3693#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL_USER
3694#else
3695#define POWERPC_SYSCALL POWERPC_EXCP_SYSCALL
3696#endif
3697static void gen_sc(DisasContext *ctx)
3698{
3699    uint32_t lev;
3700
3701    lev = (ctx->opcode >> 5) & 0x7F;
3702    gen_exception_err(ctx, POWERPC_SYSCALL, lev);
3703}
3704
3705/***                                Trap                                   ***/
3706
3707/* Check for unconditional traps (always or never) */
3708static bool check_unconditional_trap(DisasContext *ctx)
3709{
3710    /* Trap never */
3711    if (TO(ctx->opcode) == 0) {
3712        return true;
3713    }
3714    /* Trap always */
3715    if (TO(ctx->opcode) == 31) {
3716        gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
3717        return true;
3718    }
3719    return false;
3720}
3721
3722/* tw */
3723static void gen_tw(DisasContext *ctx)
3724{
3725    TCGv_i32 t0;
3726
3727    if (check_unconditional_trap(ctx)) {
3728        return;
3729    }
3730    t0 = tcg_const_i32(TO(ctx->opcode));
3731    gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
3732                  t0);
3733    tcg_temp_free_i32(t0);
3734}
3735
3736/* twi */
3737static void gen_twi(DisasContext *ctx)
3738{
3739    TCGv t0;
3740    TCGv_i32 t1;
3741
3742    if (check_unconditional_trap(ctx)) {
3743        return;
3744    }
3745    t0 = tcg_const_tl(SIMM(ctx->opcode));
3746    t1 = tcg_const_i32(TO(ctx->opcode));
3747    gen_helper_tw(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
3748    tcg_temp_free(t0);
3749    tcg_temp_free_i32(t1);
3750}
3751
3752#if defined(TARGET_PPC64)
3753/* td */
3754static void gen_td(DisasContext *ctx)
3755{
3756    TCGv_i32 t0;
3757
3758    if (check_unconditional_trap(ctx)) {
3759        return;
3760    }
3761    t0 = tcg_const_i32(TO(ctx->opcode));
3762    gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],
3763                  t0);
3764    tcg_temp_free_i32(t0);
3765}
3766
3767/* tdi */
3768static void gen_tdi(DisasContext *ctx)
3769{
3770    TCGv t0;
3771    TCGv_i32 t1;
3772
3773    if (check_unconditional_trap(ctx)) {
3774        return;
3775    }
3776    t0 = tcg_const_tl(SIMM(ctx->opcode));
3777    t1 = tcg_const_i32(TO(ctx->opcode));
3778    gen_helper_td(cpu_env, cpu_gpr[rA(ctx->opcode)], t0, t1);
3779    tcg_temp_free(t0);
3780    tcg_temp_free_i32(t1);
3781}
3782#endif
3783
3784/***                          Processor control                            ***/
3785
3786static void gen_read_xer(DisasContext *ctx, TCGv dst)
3787{
3788    TCGv t0 = tcg_temp_new();
3789    TCGv t1 = tcg_temp_new();
3790    TCGv t2 = tcg_temp_new();
3791    tcg_gen_mov_tl(dst, cpu_xer);
3792    tcg_gen_shli_tl(t0, cpu_so, XER_SO);
3793    tcg_gen_shli_tl(t1, cpu_ov, XER_OV);
3794    tcg_gen_shli_tl(t2, cpu_ca, XER_CA);
3795    tcg_gen_or_tl(t0, t0, t1);
3796    tcg_gen_or_tl(dst, dst, t2);
3797    tcg_gen_or_tl(dst, dst, t0);
3798    if (is_isa300(ctx)) {
3799        tcg_gen_shli_tl(t0, cpu_ov32, XER_OV32);
3800        tcg_gen_or_tl(dst, dst, t0);
3801        tcg_gen_shli_tl(t0, cpu_ca32, XER_CA32);
3802        tcg_gen_or_tl(dst, dst, t0);
3803    }
3804    tcg_temp_free(t0);
3805    tcg_temp_free(t1);
3806    tcg_temp_free(t2);
3807}
3808
3809static void gen_write_xer(TCGv src)
3810{
3811    /* Write all flags, while reading back check for isa300 */
3812    tcg_gen_andi_tl(cpu_xer, src,
3813                    ~((1u << XER_SO) |
3814                      (1u << XER_OV) | (1u << XER_OV32) |
3815                      (1u << XER_CA) | (1u << XER_CA32)));
3816    tcg_gen_extract_tl(cpu_ov32, src, XER_OV32, 1);
3817    tcg_gen_extract_tl(cpu_ca32, src, XER_CA32, 1);
3818    tcg_gen_extract_tl(cpu_so, src, XER_SO, 1);
3819    tcg_gen_extract_tl(cpu_ov, src, XER_OV, 1);
3820    tcg_gen_extract_tl(cpu_ca, src, XER_CA, 1);
3821}
3822
3823/* mcrxr */
3824static void gen_mcrxr(DisasContext *ctx)
3825{
3826    TCGv_i32 t0 = tcg_temp_new_i32();
3827    TCGv_i32 t1 = tcg_temp_new_i32();
3828    TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)];
3829
3830    tcg_gen_trunc_tl_i32(t0, cpu_so);
3831    tcg_gen_trunc_tl_i32(t1, cpu_ov);
3832    tcg_gen_trunc_tl_i32(dst, cpu_ca);
3833    tcg_gen_shli_i32(t0, t0, 3);
3834    tcg_gen_shli_i32(t1, t1, 2);
3835    tcg_gen_shli_i32(dst, dst, 1);
3836    tcg_gen_or_i32(dst, dst, t0);
3837    tcg_gen_or_i32(dst, dst, t1);
3838    tcg_temp_free_i32(t0);
3839    tcg_temp_free_i32(t1);
3840
3841    tcg_gen_movi_tl(cpu_so, 0);
3842    tcg_gen_movi_tl(cpu_ov, 0);
3843    tcg_gen_movi_tl(cpu_ca, 0);
3844}
3845
3846#ifdef TARGET_PPC64
3847/* mcrxrx */
3848static void gen_mcrxrx(DisasContext *ctx)
3849{
3850    TCGv t0 = tcg_temp_new();
3851    TCGv t1 = tcg_temp_new();
3852    TCGv_i32 dst = cpu_crf[crfD(ctx->opcode)];
3853
3854    /* copy OV and OV32 */
3855    tcg_gen_shli_tl(t0, cpu_ov, 1);
3856    tcg_gen_or_tl(t0, t0, cpu_ov32);
3857    tcg_gen_shli_tl(t0, t0, 2);
3858    /* copy CA and CA32 */
3859    tcg_gen_shli_tl(t1, cpu_ca, 1);
3860    tcg_gen_or_tl(t1, t1, cpu_ca32);
3861    tcg_gen_or_tl(t0, t0, t1);
3862    tcg_gen_trunc_tl_i32(dst, t0);
3863    tcg_temp_free(t0);
3864    tcg_temp_free(t1);
3865}
3866#endif
3867
3868/* mfcr mfocrf */
3869static void gen_mfcr(DisasContext *ctx)
3870{
3871    uint32_t crm, crn;
3872
3873    if (likely(ctx->opcode & 0x00100000)) {
3874        crm = CRM(ctx->opcode);
3875        if (likely(crm && ((crm & (crm - 1)) == 0))) {
3876            crn = ctz32 (crm);
3877            tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
3878            tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)],
3879                            cpu_gpr[rD(ctx->opcode)], crn * 4);
3880        }
3881    } else {
3882        TCGv_i32 t0 = tcg_temp_new_i32();
3883        tcg_gen_mov_i32(t0, cpu_crf[0]);
3884        tcg_gen_shli_i32(t0, t0, 4);
3885        tcg_gen_or_i32(t0, t0, cpu_crf[1]);
3886        tcg_gen_shli_i32(t0, t0, 4);
3887        tcg_gen_or_i32(t0, t0, cpu_crf[2]);
3888        tcg_gen_shli_i32(t0, t0, 4);
3889        tcg_gen_or_i32(t0, t0, cpu_crf[3]);
3890        tcg_gen_shli_i32(t0, t0, 4);
3891        tcg_gen_or_i32(t0, t0, cpu_crf[4]);
3892        tcg_gen_shli_i32(t0, t0, 4);
3893        tcg_gen_or_i32(t0, t0, cpu_crf[5]);
3894        tcg_gen_shli_i32(t0, t0, 4);
3895        tcg_gen_or_i32(t0, t0, cpu_crf[6]);
3896        tcg_gen_shli_i32(t0, t0, 4);
3897        tcg_gen_or_i32(t0, t0, cpu_crf[7]);
3898        tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
3899        tcg_temp_free_i32(t0);
3900    }
3901}
3902
3903/* mfmsr */
3904static void gen_mfmsr(DisasContext *ctx)
3905{
3906    CHK_SV;
3907    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr);
3908}
3909
3910static void spr_noaccess(DisasContext *ctx, int gprn, int sprn)
3911{
3912#if 0
3913    sprn = ((sprn >> 5) & 0x1F) | ((sprn & 0x1F) << 5);
3914    printf("ERROR: try to access SPR %d !\n", sprn);
3915#endif
3916}
3917#define SPR_NOACCESS (&spr_noaccess)
3918
3919/* mfspr */
3920static inline void gen_op_mfspr(DisasContext *ctx)
3921{
3922    void (*read_cb)(DisasContext *ctx, int gprn, int sprn);
3923    uint32_t sprn = SPR(ctx->opcode);
3924
3925#if defined(CONFIG_USER_ONLY)
3926    read_cb = ctx->spr_cb[sprn].uea_read;
3927#else
3928    if (ctx->pr) {
3929        read_cb = ctx->spr_cb[sprn].uea_read;
3930    } else if (ctx->hv) {
3931        read_cb = ctx->spr_cb[sprn].hea_read;
3932    } else {
3933        read_cb = ctx->spr_cb[sprn].oea_read;
3934    }
3935#endif
3936    if (likely(read_cb != NULL)) {
3937        if (likely(read_cb != SPR_NOACCESS)) {
3938            (*read_cb)(ctx, rD(ctx->opcode), sprn);
3939        } else {
3940            /* Privilege exception */
3941            /* This is a hack to avoid warnings when running Linux:
3942             * this OS breaks the PowerPC virtualisation model,
3943             * allowing userland application to read the PVR
3944             */
3945            if (sprn != SPR_PVR) {
3946                fprintf(stderr, "Trying to read privileged spr %d (0x%03x) at "
3947                        TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
3948                if (qemu_log_separate()) {
3949                    qemu_log("Trying to read privileged spr %d (0x%03x) at "
3950                             TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
3951                }
3952            }
3953            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
3954        }
3955    } else {
3956        /* ISA 2.07 defines these as no-ops */
3957        if ((ctx->insns_flags2 & PPC2_ISA207S) &&
3958            (sprn >= 808 && sprn <= 811)) {
3959            /* This is a nop */
3960            return;
3961        }
3962        /* Not defined */
3963        fprintf(stderr, "Trying to read invalid spr %d (0x%03x) at "
3964                TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
3965        if (qemu_log_separate()) {
3966            qemu_log("Trying to read invalid spr %d (0x%03x) at "
3967                     TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
3968        }
3969
3970        /* The behaviour depends on MSR:PR and SPR# bit 0x10,
3971         * it can generate a priv, a hv emu or a no-op
3972         */
3973        if (sprn & 0x10) {
3974            if (ctx->pr) {
3975                gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
3976            }
3977        } else {
3978            if (ctx->pr || sprn == 0 || sprn == 4 || sprn == 5 || sprn == 6) {
3979                gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
3980            }
3981        }
3982    }
3983}
3984
3985static void gen_mfspr(DisasContext *ctx)
3986{
3987    gen_op_mfspr(ctx);
3988}
3989
3990/* mftb */
3991static void gen_mftb(DisasContext *ctx)
3992{
3993    gen_op_mfspr(ctx);
3994}
3995
3996/* mtcrf mtocrf*/
3997static void gen_mtcrf(DisasContext *ctx)
3998{
3999    uint32_t crm, crn;
4000
4001    crm = CRM(ctx->opcode);
4002    if (likely((ctx->opcode & 0x00100000))) {
4003        if (crm && ((crm & (crm - 1)) == 0)) {
4004            TCGv_i32 temp = tcg_temp_new_i32();
4005            crn = ctz32 (crm);
4006            tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
4007            tcg_gen_shri_i32(temp, temp, crn * 4);
4008            tcg_gen_andi_i32(cpu_crf[7 - crn], temp, 0xf);
4009            tcg_temp_free_i32(temp);
4010        }
4011    } else {
4012        TCGv_i32 temp = tcg_temp_new_i32();
4013        tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
4014        for (crn = 0 ; crn < 8 ; crn++) {
4015            if (crm & (1 << crn)) {
4016                    tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
4017                    tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
4018            }
4019        }
4020        tcg_temp_free_i32(temp);
4021    }
4022}
4023
4024/* mtmsr */
4025#if defined(TARGET_PPC64)
4026static void gen_mtmsrd(DisasContext *ctx)
4027{
4028    CHK_SV;
4029
4030#if !defined(CONFIG_USER_ONLY)
4031    if (ctx->opcode & 0x00010000) {
4032        /* Special form that does not need any synchronisation */
4033        TCGv t0 = tcg_temp_new();
4034        tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
4035        tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));
4036        tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
4037        tcg_temp_free(t0);
4038    } else {
4039        /* XXX: we need to update nip before the store
4040         *      if we enter power saving mode, we will exit the loop
4041         *      directly from ppc_store_msr
4042         */
4043        gen_update_nip(ctx, ctx->nip);
4044        gen_helper_store_msr(cpu_env, cpu_gpr[rS(ctx->opcode)]);
4045        /* Must stop the translation as machine state (may have) changed */
4046        /* Note that mtmsr is not always defined as context-synchronizing */
4047        gen_stop_exception(ctx);
4048    }
4049#endif /* !defined(CONFIG_USER_ONLY) */
4050}
4051#endif /* defined(TARGET_PPC64) */
4052
4053static void gen_mtmsr(DisasContext *ctx)
4054{
4055    CHK_SV;
4056
4057#if !defined(CONFIG_USER_ONLY)
4058   if (ctx->opcode & 0x00010000) {
4059        /* Special form that does not need any synchronisation */
4060        TCGv t0 = tcg_temp_new();
4061        tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1 << MSR_RI) | (1 << MSR_EE));
4062        tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(target_ulong)((1 << MSR_RI) | (1 << MSR_EE)));
4063        tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
4064        tcg_temp_free(t0);
4065    } else {
4066        TCGv msr = tcg_temp_new();
4067
4068        /* XXX: we need to update nip before the store
4069         *      if we enter power saving mode, we will exit the loop
4070         *      directly from ppc_store_msr
4071         */
4072        gen_update_nip(ctx, ctx->nip);
4073#if defined(TARGET_PPC64)
4074        tcg_gen_deposit_tl(msr, cpu_msr, cpu_gpr[rS(ctx->opcode)], 0, 32);
4075#else
4076        tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]);
4077#endif
4078        gen_helper_store_msr(cpu_env, msr);
4079        tcg_temp_free(msr);
4080        /* Must stop the translation as machine state (may have) changed */
4081        /* Note that mtmsr is not always defined as context-synchronizing */
4082        gen_stop_exception(ctx);
4083    }
4084#endif
4085}
4086
4087/* mtspr */
4088static void gen_mtspr(DisasContext *ctx)
4089{
4090    void (*write_cb)(DisasContext *ctx, int sprn, int gprn);
4091    uint32_t sprn = SPR(ctx->opcode);
4092
4093#if defined(CONFIG_USER_ONLY)
4094    write_cb = ctx->spr_cb[sprn].uea_write;
4095#else
4096    if (ctx->pr) {
4097        write_cb = ctx->spr_cb[sprn].uea_write;
4098    } else if (ctx->hv) {
4099        write_cb = ctx->spr_cb[sprn].hea_write;
4100    } else {
4101        write_cb = ctx->spr_cb[sprn].oea_write;
4102    }
4103#endif
4104    if (likely(write_cb != NULL)) {
4105        if (likely(write_cb != SPR_NOACCESS)) {
4106            (*write_cb)(ctx, sprn, rS(ctx->opcode));
4107        } else {
4108            /* Privilege exception */
4109            fprintf(stderr, "Trying to write privileged spr %d (0x%03x) at "
4110                    TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4111            if (qemu_log_separate()) {
4112                qemu_log("Trying to write privileged spr %d (0x%03x) at "
4113                         TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4114            }
4115            gen_priv_exception(ctx, POWERPC_EXCP_PRIV_REG);
4116        }
4117    } else {
4118        /* ISA 2.07 defines these as no-ops */
4119        if ((ctx->insns_flags2 & PPC2_ISA207S) &&
4120            (sprn >= 808 && sprn <= 811)) {
4121            /* This is a nop */
4122            return;
4123        }
4124
4125        /* Not defined */
4126        if (qemu_log_separate()) {
4127            qemu_log("Trying to write invalid spr %d (0x%03x) at "
4128                     TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4129        }
4130        fprintf(stderr, "Trying to write invalid spr %d (0x%03x) at "
4131                TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
4132
4133
4134        /* The behaviour depends on MSR:PR and SPR# bit 0x10,
4135         * it can generate a priv, a hv emu or a no-op
4136         */
4137        if (sprn & 0x10) {
4138            if (ctx->pr) {
4139                gen_priv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4140            }
4141        } else {
4142            if (ctx->pr || sprn == 0) {
4143                gen_hvpriv_exception(ctx, POWERPC_EXCP_INVAL_SPR);
4144            }
4145        }
4146    }
4147}
4148
4149#if defined(TARGET_PPC64)
4150/* setb */
4151static void gen_setb(DisasContext *ctx)
4152{
4153    TCGv_i32 t0 = tcg_temp_new_i32();
4154    TCGv_i32 t8 = tcg_temp_new_i32();
4155    TCGv_i32 tm1 = tcg_temp_new_i32();
4156    int crf = crfS(ctx->opcode);
4157
4158    tcg_gen_setcondi_i32(TCG_COND_GEU, t0, cpu_crf[crf], 4);
4159    tcg_gen_movi_i32(t8, 8);
4160    tcg_gen_movi_i32(tm1, -1);
4161    tcg_gen_movcond_i32(TCG_COND_GEU, t0, cpu_crf[crf], t8, tm1, t0);
4162    tcg_gen_ext_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
4163
4164    tcg_temp_free_i32(t0);
4165    tcg_temp_free_i32(t8);
4166    tcg_temp_free_i32(tm1);
4167}
4168#endif
4169
4170/***                         Cache management                              ***/
4171
4172/* dcbf */
4173static void gen_dcbf(DisasContext *ctx)
4174{
4175    /* XXX: specification says this is treated as a load by the MMU */
4176    TCGv t0;
4177    gen_set_access_type(ctx, ACCESS_CACHE);
4178    t0 = tcg_temp_new();
4179    gen_addr_reg_index(ctx, t0);
4180    gen_qemu_ld8u(ctx, t0, t0);
4181    tcg_temp_free(t0);
4182}
4183
4184/* dcbi (Supervisor only) */
4185static void gen_dcbi(DisasContext *ctx)
4186{
4187#if defined(CONFIG_USER_ONLY)
4188    GEN_PRIV;
4189#else
4190    TCGv EA, val;
4191
4192    CHK_SV;
4193    EA = tcg_temp_new();
4194    gen_set_access_type(ctx, ACCESS_CACHE);
4195    gen_addr_reg_index(ctx, EA);
4196    val = tcg_temp_new();
4197    /* XXX: specification says this should be treated as a store by the MMU */
4198    gen_qemu_ld8u(ctx, val, EA);
4199    gen_qemu_st8(ctx, val, EA);
4200    tcg_temp_free(val);
4201    tcg_temp_free(EA);
4202#endif /* defined(CONFIG_USER_ONLY) */
4203}
4204
4205/* dcdst */
4206static void gen_dcbst(DisasContext *ctx)
4207{
4208    /* XXX: specification say this is treated as a load by the MMU */
4209    TCGv t0;
4210    gen_set_access_type(ctx, ACCESS_CACHE);
4211    t0 = tcg_temp_new();
4212    gen_addr_reg_index(ctx, t0);
4213    gen_qemu_ld8u(ctx, t0, t0);
4214    tcg_temp_free(t0);
4215}
4216
4217/* dcbt */
4218static void gen_dcbt(DisasContext *ctx)
4219{
4220    /* interpreted as no-op */
4221    /* XXX: specification say this is treated as a load by the MMU
4222     *      but does not generate any exception
4223     */
4224}
4225
4226/* dcbtst */
4227static void gen_dcbtst(DisasContext *ctx)
4228{
4229    /* interpreted as no-op */
4230    /* XXX: specification say this is treated as a load by the MMU
4231     *      but does not generate any exception
4232     */
4233}
4234
4235/* dcbtls */
4236static void gen_dcbtls(DisasContext *ctx)
4237{
4238    /* Always fails locking the cache */
4239    TCGv t0 = tcg_temp_new();
4240    gen_load_spr(t0, SPR_Exxx_L1CSR0);
4241    tcg_gen_ori_tl(t0, t0, L1CSR0_CUL);
4242    gen_store_spr(SPR_Exxx_L1CSR0, t0);
4243    tcg_temp_free(t0);
4244}
4245
4246/* dcbz */
4247static void gen_dcbz(DisasContext *ctx)
4248{
4249    TCGv tcgv_addr;
4250    TCGv_i32 tcgv_op;
4251
4252    gen_set_access_type(ctx, ACCESS_CACHE);
4253    tcgv_addr = tcg_temp_new();
4254    tcgv_op = tcg_const_i32(ctx->opcode & 0x03FF000);
4255    gen_addr_reg_index(ctx, tcgv_addr);
4256    gen_helper_dcbz(cpu_env, tcgv_addr, tcgv_op);
4257    tcg_temp_free(tcgv_addr);
4258    tcg_temp_free_i32(tcgv_op);
4259}
4260
4261/* dst / dstt */
4262static void gen_dst(DisasContext *ctx)
4263{
4264    if (rA(ctx->opcode) == 0) {
4265        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
4266    } else {
4267        /* interpreted as no-op */
4268    }
4269}
4270
4271/* dstst /dststt */
4272static void gen_dstst(DisasContext *ctx)
4273{
4274    if (rA(ctx->opcode) == 0) {
4275        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
4276    } else {
4277        /* interpreted as no-op */
4278    }
4279
4280}
4281
4282/* dss / dssall */
4283static void gen_dss(DisasContext *ctx)
4284{
4285    /* interpreted as no-op */
4286}
4287
4288/* icbi */
4289static void gen_icbi(DisasContext *ctx)
4290{
4291    TCGv t0;
4292    gen_set_access_type(ctx, ACCESS_CACHE);
4293    t0 = tcg_temp_new();
4294    gen_addr_reg_index(ctx, t0);
4295    gen_helper_icbi(cpu_env, t0);
4296    tcg_temp_free(t0);
4297}
4298
4299/* Optional: */
4300/* dcba */
4301static void gen_dcba(DisasContext *ctx)
4302{
4303    /* interpreted as no-op */
4304    /* XXX: specification say this is treated as a store by the MMU
4305     *      but does not generate any exception
4306     */
4307}
4308
4309/***                    Segment register manipulation                      ***/
4310/* Supervisor only: */
4311
4312/* mfsr */
4313static void gen_mfsr(DisasContext *ctx)
4314{
4315#if defined(CONFIG_USER_ONLY)
4316    GEN_PRIV;
4317#else
4318    TCGv t0;
4319
4320    CHK_SV;
4321    t0 = tcg_const_tl(SR(ctx->opcode));
4322    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4323    tcg_temp_free(t0);
4324#endif /* defined(CONFIG_USER_ONLY) */
4325}
4326
4327/* mfsrin */
4328static void gen_mfsrin(DisasContext *ctx)
4329{
4330#if defined(CONFIG_USER_ONLY)
4331    GEN_PRIV;
4332#else
4333    TCGv t0;
4334
4335    CHK_SV;
4336    t0 = tcg_temp_new();
4337    tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4);
4338    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4339    tcg_temp_free(t0);
4340#endif /* defined(CONFIG_USER_ONLY) */
4341}
4342
4343/* mtsr */
4344static void gen_mtsr(DisasContext *ctx)
4345{
4346#if defined(CONFIG_USER_ONLY)
4347    GEN_PRIV;
4348#else
4349    TCGv t0;
4350
4351    CHK_SV;
4352    t0 = tcg_const_tl(SR(ctx->opcode));
4353    gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4354    tcg_temp_free(t0);
4355#endif /* defined(CONFIG_USER_ONLY) */
4356}
4357
4358/* mtsrin */
4359static void gen_mtsrin(DisasContext *ctx)
4360{
4361#if defined(CONFIG_USER_ONLY)
4362    GEN_PRIV;
4363#else
4364    TCGv t0;
4365    CHK_SV;
4366
4367    t0 = tcg_temp_new();
4368    tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4);
4369    gen_helper_store_sr(cpu_env, t0, cpu_gpr[rD(ctx->opcode)]);
4370    tcg_temp_free(t0);
4371#endif /* defined(CONFIG_USER_ONLY) */
4372}
4373
4374#if defined(TARGET_PPC64)
4375/* Specific implementation for PowerPC 64 "bridge" emulation using SLB */
4376
4377/* mfsr */
4378static void gen_mfsr_64b(DisasContext *ctx)
4379{
4380#if defined(CONFIG_USER_ONLY)
4381    GEN_PRIV;
4382#else
4383    TCGv t0;
4384
4385    CHK_SV;
4386    t0 = tcg_const_tl(SR(ctx->opcode));
4387    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4388    tcg_temp_free(t0);
4389#endif /* defined(CONFIG_USER_ONLY) */
4390}
4391
4392/* mfsrin */
4393static void gen_mfsrin_64b(DisasContext *ctx)
4394{
4395#if defined(CONFIG_USER_ONLY)
4396    GEN_PRIV;
4397#else
4398    TCGv t0;
4399
4400    CHK_SV;
4401    t0 = tcg_temp_new();
4402    tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4);
4403    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4404    tcg_temp_free(t0);
4405#endif /* defined(CONFIG_USER_ONLY) */
4406}
4407
4408/* mtsr */
4409static void gen_mtsr_64b(DisasContext *ctx)
4410{
4411#if defined(CONFIG_USER_ONLY)
4412    GEN_PRIV;
4413#else
4414    TCGv t0;
4415
4416    CHK_SV;
4417    t0 = tcg_const_tl(SR(ctx->opcode));
4418    gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4419    tcg_temp_free(t0);
4420#endif /* defined(CONFIG_USER_ONLY) */
4421}
4422
4423/* mtsrin */
4424static void gen_mtsrin_64b(DisasContext *ctx)
4425{
4426#if defined(CONFIG_USER_ONLY)
4427    GEN_PRIV;
4428#else
4429    TCGv t0;
4430
4431    CHK_SV;
4432    t0 = tcg_temp_new();
4433    tcg_gen_extract_tl(t0, cpu_gpr[rB(ctx->opcode)], 28, 4);
4434    gen_helper_store_sr(cpu_env, t0, cpu_gpr[rS(ctx->opcode)]);
4435    tcg_temp_free(t0);
4436#endif /* defined(CONFIG_USER_ONLY) */
4437}
4438
4439/* slbmte */
4440static void gen_slbmte(DisasContext *ctx)
4441{
4442#if defined(CONFIG_USER_ONLY)
4443    GEN_PRIV;
4444#else
4445    CHK_SV;
4446
4447    gen_helper_store_slb(cpu_env, cpu_gpr[rB(ctx->opcode)],
4448                         cpu_gpr[rS(ctx->opcode)]);
4449#endif /* defined(CONFIG_USER_ONLY) */
4450}
4451
4452static void gen_slbmfee(DisasContext *ctx)
4453{
4454#if defined(CONFIG_USER_ONLY)
4455    GEN_PRIV;
4456#else
4457    CHK_SV;
4458
4459    gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env,
4460                             cpu_gpr[rB(ctx->opcode)]);
4461#endif /* defined(CONFIG_USER_ONLY) */
4462}
4463
4464static void gen_slbmfev(DisasContext *ctx)
4465{
4466#if defined(CONFIG_USER_ONLY)
4467    GEN_PRIV;
4468#else
4469    CHK_SV;
4470
4471    gen_helper_load_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
4472                             cpu_gpr[rB(ctx->opcode)]);
4473#endif /* defined(CONFIG_USER_ONLY) */
4474}
4475
4476static void gen_slbfee_(DisasContext *ctx)
4477{
4478#if defined(CONFIG_USER_ONLY)
4479    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4480#else
4481    TCGLabel *l1, *l2;
4482
4483    if (unlikely(ctx->pr)) {
4484        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
4485        return;
4486    }
4487    gen_helper_find_slb_vsid(cpu_gpr[rS(ctx->opcode)], cpu_env,
4488                             cpu_gpr[rB(ctx->opcode)]);
4489    l1 = gen_new_label();
4490    l2 = gen_new_label();
4491    tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
4492    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rS(ctx->opcode)], -1, l1);
4493    tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], CRF_EQ);
4494    tcg_gen_br(l2);
4495    gen_set_label(l1);
4496    tcg_gen_movi_tl(cpu_gpr[rS(ctx->opcode)], 0);
4497    gen_set_label(l2);
4498#endif
4499}
4500#endif /* defined(TARGET_PPC64) */
4501
4502/***                      Lookaside buffer management                      ***/
4503/* Optional & supervisor only: */
4504
4505/* tlbia */
4506static void gen_tlbia(DisasContext *ctx)
4507{
4508#if defined(CONFIG_USER_ONLY)
4509    GEN_PRIV;
4510#else
4511    CHK_HV;
4512
4513    gen_helper_tlbia(cpu_env);
4514#endif  /* defined(CONFIG_USER_ONLY) */
4515}
4516
4517/* tlbiel */
4518static void gen_tlbiel(DisasContext *ctx)
4519{
4520#if defined(CONFIG_USER_ONLY)
4521    GEN_PRIV;
4522#else
4523    CHK_SV;
4524
4525    gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
4526#endif /* defined(CONFIG_USER_ONLY) */
4527}
4528
4529/* tlbie */
4530static void gen_tlbie(DisasContext *ctx)
4531{
4532#if defined(CONFIG_USER_ONLY)
4533    GEN_PRIV;
4534#else
4535    TCGv_i32 t1;
4536
4537    if (ctx->gtse) {
4538        CHK_SV; /* If gtse is set then tblie is supervisor privileged */
4539    } else {
4540        CHK_HV; /* Else hypervisor privileged */
4541    }
4542
4543    if (NARROW_MODE(ctx)) {
4544        TCGv t0 = tcg_temp_new();
4545        tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
4546        gen_helper_tlbie(cpu_env, t0);
4547        tcg_temp_free(t0);
4548    } else {
4549        gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
4550    }
4551    t1 = tcg_temp_new_i32();
4552    tcg_gen_ld_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
4553    tcg_gen_ori_i32(t1, t1, TLB_NEED_GLOBAL_FLUSH);
4554    tcg_gen_st_i32(t1, cpu_env, offsetof(CPUPPCState, tlb_need_flush));
4555    tcg_temp_free_i32(t1);
4556#endif /* defined(CONFIG_USER_ONLY) */
4557}
4558
4559/* tlbsync */
4560static void gen_tlbsync(DisasContext *ctx)
4561{
4562#if defined(CONFIG_USER_ONLY)
4563    GEN_PRIV;
4564#else
4565    CHK_HV;
4566
4567    /* BookS does both ptesync and tlbsync make tlbsync a nop for server */
4568    if (ctx->insns_flags & PPC_BOOKE) {
4569        gen_check_tlb_flush(ctx, true);
4570    }
4571#endif /* defined(CONFIG_USER_ONLY) */
4572}
4573
4574#if defined(TARGET_PPC64)
4575/* slbia */
4576static void gen_slbia(DisasContext *ctx)
4577{
4578#if defined(CONFIG_USER_ONLY)
4579    GEN_PRIV;
4580#else
4581    CHK_SV;
4582
4583    gen_helper_slbia(cpu_env);
4584#endif /* defined(CONFIG_USER_ONLY) */
4585}
4586
4587/* slbie */
4588static void gen_slbie(DisasContext *ctx)
4589{
4590#if defined(CONFIG_USER_ONLY)
4591    GEN_PRIV;
4592#else
4593    CHK_SV;
4594
4595    gen_helper_slbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);
4596#endif /* defined(CONFIG_USER_ONLY) */
4597}
4598
4599/* slbieg */
4600static void gen_slbieg(DisasContext *ctx)
4601{
4602#if defined(CONFIG_USER_ONLY)
4603    GEN_PRIV;
4604#else
4605    CHK_SV;
4606
4607    gen_helper_slbieg(cpu_env, cpu_gpr[rB(ctx->opcode)]);
4608#endif /* defined(CONFIG_USER_ONLY) */
4609}
4610
4611/* slbsync */
4612static void gen_slbsync(DisasContext *ctx)
4613{
4614#if defined(CONFIG_USER_ONLY)
4615    GEN_PRIV;
4616#else
4617    CHK_SV;
4618    gen_check_tlb_flush(ctx, true);
4619#endif /* defined(CONFIG_USER_ONLY) */
4620}
4621
4622#endif  /* defined(TARGET_PPC64) */
4623
4624/***                              External control                         ***/
4625/* Optional: */
4626
4627/* eciwx */
4628static void gen_eciwx(DisasContext *ctx)
4629{
4630    TCGv t0;
4631    /* Should check EAR[E] ! */
4632    gen_set_access_type(ctx, ACCESS_EXT);
4633    t0 = tcg_temp_new();
4634    gen_addr_reg_index(ctx, t0);
4635    gen_check_align(ctx, t0, 0x03);
4636    gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], t0);
4637    tcg_temp_free(t0);
4638}
4639
4640/* ecowx */
4641static void gen_ecowx(DisasContext *ctx)
4642{
4643    TCGv t0;
4644    /* Should check EAR[E] ! */
4645    gen_set_access_type(ctx, ACCESS_EXT);
4646    t0 = tcg_temp_new();
4647    gen_addr_reg_index(ctx, t0);
4648    gen_check_align(ctx, t0, 0x03);
4649    gen_qemu_st32(ctx, cpu_gpr[rD(ctx->opcode)], t0);
4650    tcg_temp_free(t0);
4651}
4652
4653/* PowerPC 601 specific instructions */
4654
4655/* abs - abs. */
4656static void gen_abs(DisasContext *ctx)
4657{
4658    TCGLabel *l1 = gen_new_label();
4659    TCGLabel *l2 = gen_new_label();
4660    tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);
4661    tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4662    tcg_gen_br(l2);
4663    gen_set_label(l1);
4664    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4665    gen_set_label(l2);
4666    if (unlikely(Rc(ctx->opcode) != 0))
4667        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4668}
4669
4670/* abso - abso. */
4671static void gen_abso(DisasContext *ctx)
4672{
4673    TCGLabel *l1 = gen_new_label();
4674    TCGLabel *l2 = gen_new_label();
4675    TCGLabel *l3 = gen_new_label();
4676    /* Start with XER OV disabled, the most likely case */
4677    tcg_gen_movi_tl(cpu_ov, 0);
4678    tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
4679    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
4680    tcg_gen_movi_tl(cpu_ov, 1);
4681    tcg_gen_movi_tl(cpu_so, 1);
4682    tcg_gen_br(l2);
4683    gen_set_label(l1);
4684    tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4685    tcg_gen_br(l3);
4686    gen_set_label(l2);
4687    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4688    gen_set_label(l3);
4689    if (unlikely(Rc(ctx->opcode) != 0))
4690        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4691}
4692
4693/* clcs */
4694static void gen_clcs(DisasContext *ctx)
4695{
4696    TCGv_i32 t0 = tcg_const_i32(rA(ctx->opcode));
4697    gen_helper_clcs(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
4698    tcg_temp_free_i32(t0);
4699    /* Rc=1 sets CR0 to an undefined state */
4700}
4701
4702/* div - div. */
4703static void gen_div(DisasContext *ctx)
4704{
4705    gen_helper_div(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
4706                   cpu_gpr[rB(ctx->opcode)]);
4707    if (unlikely(Rc(ctx->opcode) != 0))
4708        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4709}
4710
4711/* divo - divo. */
4712static void gen_divo(DisasContext *ctx)
4713{
4714    gen_helper_divo(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
4715                    cpu_gpr[rB(ctx->opcode)]);
4716    if (unlikely(Rc(ctx->opcode) != 0))
4717        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4718}
4719
4720/* divs - divs. */
4721static void gen_divs(DisasContext *ctx)
4722{
4723    gen_helper_divs(cpu_gpr[rD(ctx->opcode)], cpu_env, cpu_gpr[rA(ctx->opcode)],
4724                    cpu_gpr[rB(ctx->opcode)]);
4725    if (unlikely(Rc(ctx->opcode) != 0))
4726        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4727}
4728
4729/* divso - divso. */
4730static void gen_divso(DisasContext *ctx)
4731{
4732    gen_helper_divso(cpu_gpr[rD(ctx->opcode)], cpu_env,
4733                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4734    if (unlikely(Rc(ctx->opcode) != 0))
4735        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4736}
4737
4738/* doz - doz. */
4739static void gen_doz(DisasContext *ctx)
4740{
4741    TCGLabel *l1 = gen_new_label();
4742    TCGLabel *l2 = gen_new_label();
4743    tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
4744    tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4745    tcg_gen_br(l2);
4746    gen_set_label(l1);
4747    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4748    gen_set_label(l2);
4749    if (unlikely(Rc(ctx->opcode) != 0))
4750        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4751}
4752
4753/* dozo - dozo. */
4754static void gen_dozo(DisasContext *ctx)
4755{
4756    TCGLabel *l1 = gen_new_label();
4757    TCGLabel *l2 = gen_new_label();
4758    TCGv t0 = tcg_temp_new();
4759    TCGv t1 = tcg_temp_new();
4760    TCGv t2 = tcg_temp_new();
4761    /* Start with XER OV disabled, the most likely case */
4762    tcg_gen_movi_tl(cpu_ov, 0);
4763    tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);
4764    tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4765    tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4766    tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0);
4767    tcg_gen_andc_tl(t1, t1, t2);
4768    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
4769    tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
4770    tcg_gen_movi_tl(cpu_ov, 1);
4771    tcg_gen_movi_tl(cpu_so, 1);
4772    tcg_gen_br(l2);
4773    gen_set_label(l1);
4774    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4775    gen_set_label(l2);
4776    tcg_temp_free(t0);
4777    tcg_temp_free(t1);
4778    tcg_temp_free(t2);
4779    if (unlikely(Rc(ctx->opcode) != 0))
4780        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4781}
4782
4783/* dozi */
4784static void gen_dozi(DisasContext *ctx)
4785{
4786    target_long simm = SIMM(ctx->opcode);
4787    TCGLabel *l1 = gen_new_label();
4788    TCGLabel *l2 = gen_new_label();
4789    tcg_gen_brcondi_tl(TCG_COND_LT, cpu_gpr[rA(ctx->opcode)], simm, l1);
4790    tcg_gen_subfi_tl(cpu_gpr[rD(ctx->opcode)], simm, cpu_gpr[rA(ctx->opcode)]);
4791    tcg_gen_br(l2);
4792    gen_set_label(l1);
4793    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);
4794    gen_set_label(l2);
4795    if (unlikely(Rc(ctx->opcode) != 0))
4796        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4797}
4798
4799/* lscbx - lscbx. */
4800static void gen_lscbx(DisasContext *ctx)
4801{
4802    TCGv t0 = tcg_temp_new();
4803    TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
4804    TCGv_i32 t2 = tcg_const_i32(rA(ctx->opcode));
4805    TCGv_i32 t3 = tcg_const_i32(rB(ctx->opcode));
4806
4807    gen_addr_reg_index(ctx, t0);
4808    gen_helper_lscbx(t0, cpu_env, t0, t1, t2, t3);
4809    tcg_temp_free_i32(t1);
4810    tcg_temp_free_i32(t2);
4811    tcg_temp_free_i32(t3);
4812    tcg_gen_andi_tl(cpu_xer, cpu_xer, ~0x7F);
4813    tcg_gen_or_tl(cpu_xer, cpu_xer, t0);
4814    if (unlikely(Rc(ctx->opcode) != 0))
4815        gen_set_Rc0(ctx, t0);
4816    tcg_temp_free(t0);
4817}
4818
4819/* maskg - maskg. */
4820static void gen_maskg(DisasContext *ctx)
4821{
4822    TCGLabel *l1 = gen_new_label();
4823    TCGv t0 = tcg_temp_new();
4824    TCGv t1 = tcg_temp_new();
4825    TCGv t2 = tcg_temp_new();
4826    TCGv t3 = tcg_temp_new();
4827    tcg_gen_movi_tl(t3, 0xFFFFFFFF);
4828    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4829    tcg_gen_andi_tl(t1, cpu_gpr[rS(ctx->opcode)], 0x1F);
4830    tcg_gen_addi_tl(t2, t0, 1);
4831    tcg_gen_shr_tl(t2, t3, t2);
4832    tcg_gen_shr_tl(t3, t3, t1);
4833    tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], t2, t3);
4834    tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4835    tcg_gen_neg_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4836    gen_set_label(l1);
4837    tcg_temp_free(t0);
4838    tcg_temp_free(t1);
4839    tcg_temp_free(t2);
4840    tcg_temp_free(t3);
4841    if (unlikely(Rc(ctx->opcode) != 0))
4842        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4843}
4844
4845/* maskir - maskir. */
4846static void gen_maskir(DisasContext *ctx)
4847{
4848    TCGv t0 = tcg_temp_new();
4849    TCGv t1 = tcg_temp_new();
4850    tcg_gen_and_tl(t0, cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4851    tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
4852    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4853    tcg_temp_free(t0);
4854    tcg_temp_free(t1);
4855    if (unlikely(Rc(ctx->opcode) != 0))
4856        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4857}
4858
4859/* mul - mul. */
4860static void gen_mul(DisasContext *ctx)
4861{
4862    TCGv_i64 t0 = tcg_temp_new_i64();
4863    TCGv_i64 t1 = tcg_temp_new_i64();
4864    TCGv t2 = tcg_temp_new();
4865    tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
4866    tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
4867    tcg_gen_mul_i64(t0, t0, t1);
4868    tcg_gen_trunc_i64_tl(t2, t0);
4869    gen_store_spr(SPR_MQ, t2);
4870    tcg_gen_shri_i64(t1, t0, 32);
4871    tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
4872    tcg_temp_free_i64(t0);
4873    tcg_temp_free_i64(t1);
4874    tcg_temp_free(t2);
4875    if (unlikely(Rc(ctx->opcode) != 0))
4876        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4877}
4878
4879/* mulo - mulo. */
4880static void gen_mulo(DisasContext *ctx)
4881{
4882    TCGLabel *l1 = gen_new_label();
4883    TCGv_i64 t0 = tcg_temp_new_i64();
4884    TCGv_i64 t1 = tcg_temp_new_i64();
4885    TCGv t2 = tcg_temp_new();
4886    /* Start with XER OV disabled, the most likely case */
4887    tcg_gen_movi_tl(cpu_ov, 0);
4888    tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
4889    tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
4890    tcg_gen_mul_i64(t0, t0, t1);
4891    tcg_gen_trunc_i64_tl(t2, t0);
4892    gen_store_spr(SPR_MQ, t2);
4893    tcg_gen_shri_i64(t1, t0, 32);
4894    tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1);
4895    tcg_gen_ext32s_i64(t1, t0);
4896    tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
4897    tcg_gen_movi_tl(cpu_ov, 1);
4898    tcg_gen_movi_tl(cpu_so, 1);
4899    gen_set_label(l1);
4900    tcg_temp_free_i64(t0);
4901    tcg_temp_free_i64(t1);
4902    tcg_temp_free(t2);
4903    if (unlikely(Rc(ctx->opcode) != 0))
4904        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4905}
4906
4907/* nabs - nabs. */
4908static void gen_nabs(DisasContext *ctx)
4909{
4910    TCGLabel *l1 = gen_new_label();
4911    TCGLabel *l2 = gen_new_label();
4912    tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
4913    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4914    tcg_gen_br(l2);
4915    gen_set_label(l1);
4916    tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4917    gen_set_label(l2);
4918    if (unlikely(Rc(ctx->opcode) != 0))
4919        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4920}
4921
4922/* nabso - nabso. */
4923static void gen_nabso(DisasContext *ctx)
4924{
4925    TCGLabel *l1 = gen_new_label();
4926    TCGLabel *l2 = gen_new_label();
4927    tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
4928    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4929    tcg_gen_br(l2);
4930    gen_set_label(l1);
4931    tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
4932    gen_set_label(l2);
4933    /* nabs never overflows */
4934    tcg_gen_movi_tl(cpu_ov, 0);
4935    if (unlikely(Rc(ctx->opcode) != 0))
4936        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
4937}
4938
4939/* rlmi - rlmi. */
4940static void gen_rlmi(DisasContext *ctx)
4941{
4942    uint32_t mb = MB(ctx->opcode);
4943    uint32_t me = ME(ctx->opcode);
4944    TCGv t0 = tcg_temp_new();
4945    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4946    tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4947    tcg_gen_andi_tl(t0, t0, MASK(mb, me));
4948    tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~MASK(mb, me));
4949    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], t0);
4950    tcg_temp_free(t0);
4951    if (unlikely(Rc(ctx->opcode) != 0))
4952        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4953}
4954
4955/* rrib - rrib. */
4956static void gen_rrib(DisasContext *ctx)
4957{
4958    TCGv t0 = tcg_temp_new();
4959    TCGv t1 = tcg_temp_new();
4960    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4961    tcg_gen_movi_tl(t1, 0x80000000);
4962    tcg_gen_shr_tl(t1, t1, t0);
4963    tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
4964    tcg_gen_and_tl(t0, t0, t1);
4965    tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], t1);
4966    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
4967    tcg_temp_free(t0);
4968    tcg_temp_free(t1);
4969    if (unlikely(Rc(ctx->opcode) != 0))
4970        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4971}
4972
4973/* sle - sle. */
4974static void gen_sle(DisasContext *ctx)
4975{
4976    TCGv t0 = tcg_temp_new();
4977    TCGv t1 = tcg_temp_new();
4978    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
4979    tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
4980    tcg_gen_subfi_tl(t1, 32, t1);
4981    tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
4982    tcg_gen_or_tl(t1, t0, t1);
4983    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
4984    gen_store_spr(SPR_MQ, t1);
4985    tcg_temp_free(t0);
4986    tcg_temp_free(t1);
4987    if (unlikely(Rc(ctx->opcode) != 0))
4988        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
4989}
4990
4991/* sleq - sleq. */
4992static void gen_sleq(DisasContext *ctx)
4993{
4994    TCGv t0 = tcg_temp_new();
4995    TCGv t1 = tcg_temp_new();
4996    TCGv t2 = tcg_temp_new();
4997    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
4998    tcg_gen_movi_tl(t2, 0xFFFFFFFF);
4999    tcg_gen_shl_tl(t2, t2, t0);
5000    tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5001    gen_load_spr(t1, SPR_MQ);
5002    gen_store_spr(SPR_MQ, t0);
5003    tcg_gen_and_tl(t0, t0, t2);
5004    tcg_gen_andc_tl(t1, t1, t2);
5005    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5006    tcg_temp_free(t0);
5007    tcg_temp_free(t1);
5008    tcg_temp_free(t2);
5009    if (unlikely(Rc(ctx->opcode) != 0))
5010        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5011}
5012
5013/* sliq - sliq. */
5014static void gen_sliq(DisasContext *ctx)
5015{
5016    int sh = SH(ctx->opcode);
5017    TCGv t0 = tcg_temp_new();
5018    TCGv t1 = tcg_temp_new();
5019    tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5020    tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5021    tcg_gen_or_tl(t1, t0, t1);
5022    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5023    gen_store_spr(SPR_MQ, t1);
5024    tcg_temp_free(t0);
5025    tcg_temp_free(t1);
5026    if (unlikely(Rc(ctx->opcode) != 0))
5027        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5028}
5029
5030/* slliq - slliq. */
5031static void gen_slliq(DisasContext *ctx)
5032{
5033    int sh = SH(ctx->opcode);
5034    TCGv t0 = tcg_temp_new();
5035    TCGv t1 = tcg_temp_new();
5036    tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5037    gen_load_spr(t1, SPR_MQ);
5038    gen_store_spr(SPR_MQ, t0);
5039    tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU << sh));
5040    tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU << sh));
5041    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5042    tcg_temp_free(t0);
5043    tcg_temp_free(t1);
5044    if (unlikely(Rc(ctx->opcode) != 0))
5045        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5046}
5047
5048/* sllq - sllq. */
5049static void gen_sllq(DisasContext *ctx)
5050{
5051    TCGLabel *l1 = gen_new_label();
5052    TCGLabel *l2 = gen_new_label();
5053    TCGv t0 = tcg_temp_local_new();
5054    TCGv t1 = tcg_temp_local_new();
5055    TCGv t2 = tcg_temp_local_new();
5056    tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5057    tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5058    tcg_gen_shl_tl(t1, t1, t2);
5059    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5060    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5061    gen_load_spr(t0, SPR_MQ);
5062    tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5063    tcg_gen_br(l2);
5064    gen_set_label(l1);
5065    tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5066    gen_load_spr(t2, SPR_MQ);
5067    tcg_gen_andc_tl(t1, t2, t1);
5068    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5069    gen_set_label(l2);
5070    tcg_temp_free(t0);
5071    tcg_temp_free(t1);
5072    tcg_temp_free(t2);
5073    if (unlikely(Rc(ctx->opcode) != 0))
5074        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5075}
5076
5077/* slq - slq. */
5078static void gen_slq(DisasContext *ctx)
5079{
5080    TCGLabel *l1 = gen_new_label();
5081    TCGv t0 = tcg_temp_new();
5082    TCGv t1 = tcg_temp_new();
5083    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5084    tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5085    tcg_gen_subfi_tl(t1, 32, t1);
5086    tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5087    tcg_gen_or_tl(t1, t0, t1);
5088    gen_store_spr(SPR_MQ, t1);
5089    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
5090    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5091    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5092    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
5093    gen_set_label(l1);
5094    tcg_temp_free(t0);
5095    tcg_temp_free(t1);
5096    if (unlikely(Rc(ctx->opcode) != 0))
5097        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5098}
5099
5100/* sraiq - sraiq. */
5101static void gen_sraiq(DisasContext *ctx)
5102{
5103    int sh = SH(ctx->opcode);
5104    TCGLabel *l1 = gen_new_label();
5105    TCGv t0 = tcg_temp_new();
5106    TCGv t1 = tcg_temp_new();
5107    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5108    tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5109    tcg_gen_or_tl(t0, t0, t1);
5110    gen_store_spr(SPR_MQ, t0);
5111    tcg_gen_movi_tl(cpu_ca, 0);
5112    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5113    tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
5114    tcg_gen_movi_tl(cpu_ca, 1);
5115    gen_set_label(l1);
5116    tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
5117    tcg_temp_free(t0);
5118    tcg_temp_free(t1);
5119    if (unlikely(Rc(ctx->opcode) != 0))
5120        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5121}
5122
5123/* sraq - sraq. */
5124static void gen_sraq(DisasContext *ctx)
5125{
5126    TCGLabel *l1 = gen_new_label();
5127    TCGLabel *l2 = gen_new_label();
5128    TCGv t0 = tcg_temp_new();
5129    TCGv t1 = tcg_temp_local_new();
5130    TCGv t2 = tcg_temp_local_new();
5131    tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5132    tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5133    tcg_gen_sar_tl(t1, cpu_gpr[rS(ctx->opcode)], t2);
5134    tcg_gen_subfi_tl(t2, 32, t2);
5135    tcg_gen_shl_tl(t2, cpu_gpr[rS(ctx->opcode)], t2);
5136    tcg_gen_or_tl(t0, t0, t2);
5137    gen_store_spr(SPR_MQ, t0);
5138    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5139    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l1);
5140    tcg_gen_mov_tl(t2, cpu_gpr[rS(ctx->opcode)]);
5141    tcg_gen_sari_tl(t1, cpu_gpr[rS(ctx->opcode)], 31);
5142    gen_set_label(l1);
5143    tcg_temp_free(t0);
5144    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1);
5145    tcg_gen_movi_tl(cpu_ca, 0);
5146    tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);
5147    tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, l2);
5148    tcg_gen_movi_tl(cpu_ca, 1);
5149    gen_set_label(l2);
5150    tcg_temp_free(t1);
5151    tcg_temp_free(t2);
5152    if (unlikely(Rc(ctx->opcode) != 0))
5153        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5154}
5155
5156/* sre - sre. */
5157static void gen_sre(DisasContext *ctx)
5158{
5159    TCGv t0 = tcg_temp_new();
5160    TCGv t1 = tcg_temp_new();
5161    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5162    tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5163    tcg_gen_subfi_tl(t1, 32, t1);
5164    tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5165    tcg_gen_or_tl(t1, t0, t1);
5166    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5167    gen_store_spr(SPR_MQ, t1);
5168    tcg_temp_free(t0);
5169    tcg_temp_free(t1);
5170    if (unlikely(Rc(ctx->opcode) != 0))
5171        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5172}
5173
5174/* srea - srea. */
5175static void gen_srea(DisasContext *ctx)
5176{
5177    TCGv t0 = tcg_temp_new();
5178    TCGv t1 = tcg_temp_new();
5179    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5180    tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5181    gen_store_spr(SPR_MQ, t0);
5182    tcg_gen_sar_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], t1);
5183    tcg_temp_free(t0);
5184    tcg_temp_free(t1);
5185    if (unlikely(Rc(ctx->opcode) != 0))
5186        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5187}
5188
5189/* sreq */
5190static void gen_sreq(DisasContext *ctx)
5191{
5192    TCGv t0 = tcg_temp_new();
5193    TCGv t1 = tcg_temp_new();
5194    TCGv t2 = tcg_temp_new();
5195    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F);
5196    tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5197    tcg_gen_shr_tl(t1, t1, t0);
5198    tcg_gen_rotr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
5199    gen_load_spr(t2, SPR_MQ);
5200    gen_store_spr(SPR_MQ, t0);
5201    tcg_gen_and_tl(t0, t0, t1);
5202    tcg_gen_andc_tl(t2, t2, t1);
5203    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
5204    tcg_temp_free(t0);
5205    tcg_temp_free(t1);
5206    tcg_temp_free(t2);
5207    if (unlikely(Rc(ctx->opcode) != 0))
5208        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5209}
5210
5211/* sriq */
5212static void gen_sriq(DisasContext *ctx)
5213{
5214    int sh = SH(ctx->opcode);
5215    TCGv t0 = tcg_temp_new();
5216    TCGv t1 = tcg_temp_new();
5217    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5218    tcg_gen_shli_tl(t1, cpu_gpr[rS(ctx->opcode)], 32 - sh);
5219    tcg_gen_or_tl(t1, t0, t1);
5220    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5221    gen_store_spr(SPR_MQ, t1);
5222    tcg_temp_free(t0);
5223    tcg_temp_free(t1);
5224    if (unlikely(Rc(ctx->opcode) != 0))
5225        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5226}
5227
5228/* srliq */
5229static void gen_srliq(DisasContext *ctx)
5230{
5231    int sh = SH(ctx->opcode);
5232    TCGv t0 = tcg_temp_new();
5233    TCGv t1 = tcg_temp_new();
5234    tcg_gen_rotri_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
5235    gen_load_spr(t1, SPR_MQ);
5236    gen_store_spr(SPR_MQ, t0);
5237    tcg_gen_andi_tl(t0, t0,  (0xFFFFFFFFU >> sh));
5238    tcg_gen_andi_tl(t1, t1, ~(0xFFFFFFFFU >> sh));
5239    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5240    tcg_temp_free(t0);
5241    tcg_temp_free(t1);
5242    if (unlikely(Rc(ctx->opcode) != 0))
5243        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5244}
5245
5246/* srlq */
5247static void gen_srlq(DisasContext *ctx)
5248{
5249    TCGLabel *l1 = gen_new_label();
5250    TCGLabel *l2 = gen_new_label();
5251    TCGv t0 = tcg_temp_local_new();
5252    TCGv t1 = tcg_temp_local_new();
5253    TCGv t2 = tcg_temp_local_new();
5254    tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x1F);
5255    tcg_gen_movi_tl(t1, 0xFFFFFFFF);
5256    tcg_gen_shr_tl(t2, t1, t2);
5257    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x20);
5258    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5259    gen_load_spr(t0, SPR_MQ);
5260    tcg_gen_and_tl(cpu_gpr[rA(ctx->opcode)], t0, t2);
5261    tcg_gen_br(l2);
5262    gen_set_label(l1);
5263    tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t2);
5264    tcg_gen_and_tl(t0, t0, t2);
5265    gen_load_spr(t1, SPR_MQ);
5266    tcg_gen_andc_tl(t1, t1, t2);
5267    tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
5268    gen_set_label(l2);
5269    tcg_temp_free(t0);
5270    tcg_temp_free(t1);
5271    tcg_temp_free(t2);
5272    if (unlikely(Rc(ctx->opcode) != 0))
5273        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5274}
5275
5276/* srq */
5277static void gen_srq(DisasContext *ctx)
5278{
5279    TCGLabel *l1 = gen_new_label();
5280    TCGv t0 = tcg_temp_new();
5281    TCGv t1 = tcg_temp_new();
5282    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);
5283    tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);
5284    tcg_gen_subfi_tl(t1, 32, t1);
5285    tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);
5286    tcg_gen_or_tl(t1, t0, t1);
5287    gen_store_spr(SPR_MQ, t1);
5288    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);
5289    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
5290    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
5291    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
5292    gen_set_label(l1);
5293    tcg_temp_free(t0);
5294    tcg_temp_free(t1);
5295    if (unlikely(Rc(ctx->opcode) != 0))
5296        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
5297}
5298
5299/* PowerPC 602 specific instructions */
5300
5301/* dsa  */
5302static void gen_dsa(DisasContext *ctx)
5303{
5304    /* XXX: TODO */
5305    gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5306}
5307
5308/* esa */
5309static void gen_esa(DisasContext *ctx)
5310{
5311    /* XXX: TODO */
5312    gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5313}
5314
5315/* mfrom */
5316static void gen_mfrom(DisasContext *ctx)
5317{
5318#if defined(CONFIG_USER_ONLY)
5319    GEN_PRIV;
5320#else
5321    CHK_SV;
5322    gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
5323#endif /* defined(CONFIG_USER_ONLY) */
5324}
5325
5326/* 602 - 603 - G2 TLB management */
5327
5328/* tlbld */
5329static void gen_tlbld_6xx(DisasContext *ctx)
5330{
5331#if defined(CONFIG_USER_ONLY)
5332    GEN_PRIV;
5333#else
5334    CHK_SV;
5335    gen_helper_6xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5336#endif /* defined(CONFIG_USER_ONLY) */
5337}
5338
5339/* tlbli */
5340static void gen_tlbli_6xx(DisasContext *ctx)
5341{
5342#if defined(CONFIG_USER_ONLY)
5343    GEN_PRIV;
5344#else
5345    CHK_SV;
5346    gen_helper_6xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5347#endif /* defined(CONFIG_USER_ONLY) */
5348}
5349
5350/* 74xx TLB management */
5351
5352/* tlbld */
5353static void gen_tlbld_74xx(DisasContext *ctx)
5354{
5355#if defined(CONFIG_USER_ONLY)
5356    GEN_PRIV;
5357#else
5358    CHK_SV;
5359    gen_helper_74xx_tlbd(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5360#endif /* defined(CONFIG_USER_ONLY) */
5361}
5362
5363/* tlbli */
5364static void gen_tlbli_74xx(DisasContext *ctx)
5365{
5366#if defined(CONFIG_USER_ONLY)
5367    GEN_PRIV;
5368#else
5369    CHK_SV;
5370    gen_helper_74xx_tlbi(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5371#endif /* defined(CONFIG_USER_ONLY) */
5372}
5373
5374/* POWER instructions not in PowerPC 601 */
5375
5376/* clf */
5377static void gen_clf(DisasContext *ctx)
5378{
5379    /* Cache line flush: implemented as no-op */
5380}
5381
5382/* cli */
5383static void gen_cli(DisasContext *ctx)
5384{
5385#if defined(CONFIG_USER_ONLY)
5386    GEN_PRIV;
5387#else
5388    /* Cache line invalidate: privileged and treated as no-op */
5389    CHK_SV;
5390#endif /* defined(CONFIG_USER_ONLY) */
5391}
5392
5393/* dclst */
5394static void gen_dclst(DisasContext *ctx)
5395{
5396    /* Data cache line store: treated as no-op */
5397}
5398
5399static void gen_mfsri(DisasContext *ctx)
5400{
5401#if defined(CONFIG_USER_ONLY)
5402    GEN_PRIV;
5403#else
5404    int ra = rA(ctx->opcode);
5405    int rd = rD(ctx->opcode);
5406    TCGv t0;
5407
5408    CHK_SV;
5409    t0 = tcg_temp_new();
5410    gen_addr_reg_index(ctx, t0);
5411    tcg_gen_extract_tl(t0, t0, 28, 4);
5412    gen_helper_load_sr(cpu_gpr[rd], cpu_env, t0);
5413    tcg_temp_free(t0);
5414    if (ra != 0 && ra != rd)
5415        tcg_gen_mov_tl(cpu_gpr[ra], cpu_gpr[rd]);
5416#endif /* defined(CONFIG_USER_ONLY) */
5417}
5418
5419static void gen_rac(DisasContext *ctx)
5420{
5421#if defined(CONFIG_USER_ONLY)
5422    GEN_PRIV;
5423#else
5424    TCGv t0;
5425
5426    CHK_SV;
5427    t0 = tcg_temp_new();
5428    gen_addr_reg_index(ctx, t0);
5429    gen_helper_rac(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
5430    tcg_temp_free(t0);
5431#endif /* defined(CONFIG_USER_ONLY) */
5432}
5433
5434static void gen_rfsvc(DisasContext *ctx)
5435{
5436#if defined(CONFIG_USER_ONLY)
5437    GEN_PRIV;
5438#else
5439    CHK_SV;
5440
5441    gen_helper_rfsvc(cpu_env);
5442    gen_sync_exception(ctx);
5443#endif /* defined(CONFIG_USER_ONLY) */
5444}
5445
5446/* svc is not implemented for now */
5447
5448/* BookE specific instructions */
5449
5450/* XXX: not implemented on 440 ? */
5451static void gen_mfapidi(DisasContext *ctx)
5452{
5453    /* XXX: TODO */
5454    gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5455}
5456
5457/* XXX: not implemented on 440 ? */
5458static void gen_tlbiva(DisasContext *ctx)
5459{
5460#if defined(CONFIG_USER_ONLY)
5461    GEN_PRIV;
5462#else
5463    TCGv t0;
5464
5465    CHK_SV;
5466    t0 = tcg_temp_new();
5467    gen_addr_reg_index(ctx, t0);
5468    gen_helper_tlbiva(cpu_env, cpu_gpr[rB(ctx->opcode)]);
5469    tcg_temp_free(t0);
5470#endif /* defined(CONFIG_USER_ONLY) */
5471}
5472
5473/* All 405 MAC instructions are translated here */
5474static inline void gen_405_mulladd_insn(DisasContext *ctx, int opc2, int opc3,
5475                                        int ra, int rb, int rt, int Rc)
5476{
5477    TCGv t0, t1;
5478
5479    t0 = tcg_temp_local_new();
5480    t1 = tcg_temp_local_new();
5481
5482    switch (opc3 & 0x0D) {
5483    case 0x05:
5484        /* macchw    - macchw.    - macchwo   - macchwo.   */
5485        /* macchws   - macchws.   - macchwso  - macchwso.  */
5486        /* nmacchw   - nmacchw.   - nmacchwo  - nmacchwo.  */
5487        /* nmacchws  - nmacchws.  - nmacchwso - nmacchwso. */
5488        /* mulchw - mulchw. */
5489        tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5490        tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5491        tcg_gen_ext16s_tl(t1, t1);
5492        break;
5493    case 0x04:
5494        /* macchwu   - macchwu.   - macchwuo  - macchwuo.  */
5495        /* macchwsu  - macchwsu.  - macchwsuo - macchwsuo. */
5496        /* mulchwu - mulchwu. */
5497        tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5498        tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5499        tcg_gen_ext16u_tl(t1, t1);
5500        break;
5501    case 0x01:
5502        /* machhw    - machhw.    - machhwo   - machhwo.   */
5503        /* machhws   - machhws.   - machhwso  - machhwso.  */
5504        /* nmachhw   - nmachhw.   - nmachhwo  - nmachhwo.  */
5505        /* nmachhws  - nmachhws.  - nmachhwso - nmachhwso. */
5506        /* mulhhw - mulhhw. */
5507        tcg_gen_sari_tl(t0, cpu_gpr[ra], 16);
5508        tcg_gen_ext16s_tl(t0, t0);
5509        tcg_gen_sari_tl(t1, cpu_gpr[rb], 16);
5510        tcg_gen_ext16s_tl(t1, t1);
5511        break;
5512    case 0x00:
5513        /* machhwu   - machhwu.   - machhwuo  - machhwuo.  */
5514        /* machhwsu  - machhwsu.  - machhwsuo - machhwsuo. */
5515        /* mulhhwu - mulhhwu. */
5516        tcg_gen_shri_tl(t0, cpu_gpr[ra], 16);
5517        tcg_gen_ext16u_tl(t0, t0);
5518        tcg_gen_shri_tl(t1, cpu_gpr[rb], 16);
5519        tcg_gen_ext16u_tl(t1, t1);
5520        break;
5521    case 0x0D:
5522        /* maclhw    - maclhw.    - maclhwo   - maclhwo.   */
5523        /* maclhws   - maclhws.   - maclhwso  - maclhwso.  */
5524        /* nmaclhw   - nmaclhw.   - nmaclhwo  - nmaclhwo.  */
5525        /* nmaclhws  - nmaclhws.  - nmaclhwso - nmaclhwso. */
5526        /* mullhw - mullhw. */
5527        tcg_gen_ext16s_tl(t0, cpu_gpr[ra]);
5528        tcg_gen_ext16s_tl(t1, cpu_gpr[rb]);
5529        break;
5530    case 0x0C:
5531        /* maclhwu   - maclhwu.   - maclhwuo  - maclhwuo.  */
5532        /* maclhwsu  - maclhwsu.  - maclhwsuo - maclhwsuo. */
5533        /* mullhwu - mullhwu. */
5534        tcg_gen_ext16u_tl(t0, cpu_gpr[ra]);
5535        tcg_gen_ext16u_tl(t1, cpu_gpr[rb]);
5536        break;
5537    }
5538    if (opc2 & 0x04) {
5539        /* (n)multiply-and-accumulate (0x0C / 0x0E) */
5540        tcg_gen_mul_tl(t1, t0, t1);
5541        if (opc2 & 0x02) {
5542            /* nmultiply-and-accumulate (0x0E) */
5543            tcg_gen_sub_tl(t0, cpu_gpr[rt], t1);
5544        } else {
5545            /* multiply-and-accumulate (0x0C) */
5546            tcg_gen_add_tl(t0, cpu_gpr[rt], t1);
5547        }
5548
5549        if (opc3 & 0x12) {
5550            /* Check overflow and/or saturate */
5551            TCGLabel *l1 = gen_new_label();
5552
5553            if (opc3 & 0x10) {
5554                /* Start with XER OV disabled, the most likely case */
5555                tcg_gen_movi_tl(cpu_ov, 0);
5556            }
5557            if (opc3 & 0x01) {
5558                /* Signed */
5559                tcg_gen_xor_tl(t1, cpu_gpr[rt], t1);
5560                tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
5561                tcg_gen_xor_tl(t1, cpu_gpr[rt], t0);
5562                tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
5563                if (opc3 & 0x02) {
5564                    /* Saturate */
5565                    tcg_gen_sari_tl(t0, cpu_gpr[rt], 31);
5566                    tcg_gen_xori_tl(t0, t0, 0x7fffffff);
5567                }
5568            } else {
5569                /* Unsigned */
5570                tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5571                if (opc3 & 0x02) {
5572                    /* Saturate */
5573                    tcg_gen_movi_tl(t0, UINT32_MAX);
5574                }
5575            }
5576            if (opc3 & 0x10) {
5577                /* Check overflow */
5578                tcg_gen_movi_tl(cpu_ov, 1);
5579                tcg_gen_movi_tl(cpu_so, 1);
5580            }
5581            gen_set_label(l1);
5582            tcg_gen_mov_tl(cpu_gpr[rt], t0);
5583        }
5584    } else {
5585        tcg_gen_mul_tl(cpu_gpr[rt], t0, t1);
5586    }
5587    tcg_temp_free(t0);
5588    tcg_temp_free(t1);
5589    if (unlikely(Rc) != 0) {
5590        /* Update Rc0 */
5591        gen_set_Rc0(ctx, cpu_gpr[rt]);
5592    }
5593}
5594
5595#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
5596static void glue(gen_, name)(DisasContext *ctx)                               \
5597{                                                                             \
5598    gen_405_mulladd_insn(ctx, opc2, opc3, rA(ctx->opcode), rB(ctx->opcode),   \
5599                         rD(ctx->opcode), Rc(ctx->opcode));                   \
5600}
5601
5602/* macchw    - macchw.    */
5603GEN_MAC_HANDLER(macchw, 0x0C, 0x05);
5604/* macchwo   - macchwo.   */
5605GEN_MAC_HANDLER(macchwo, 0x0C, 0x15);
5606/* macchws   - macchws.   */
5607GEN_MAC_HANDLER(macchws, 0x0C, 0x07);
5608/* macchwso  - macchwso.  */
5609GEN_MAC_HANDLER(macchwso, 0x0C, 0x17);
5610/* macchwsu  - macchwsu.  */
5611GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06);
5612/* macchwsuo - macchwsuo. */
5613GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16);
5614/* macchwu   - macchwu.   */
5615GEN_MAC_HANDLER(macchwu, 0x0C, 0x04);
5616/* macchwuo  - macchwuo.  */
5617GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14);
5618/* machhw    - machhw.    */
5619GEN_MAC_HANDLER(machhw, 0x0C, 0x01);
5620/* machhwo   - machhwo.   */
5621GEN_MAC_HANDLER(machhwo, 0x0C, 0x11);
5622/* machhws   - machhws.   */
5623GEN_MAC_HANDLER(machhws, 0x0C, 0x03);
5624/* machhwso  - machhwso.  */
5625GEN_MAC_HANDLER(machhwso, 0x0C, 0x13);
5626/* machhwsu  - machhwsu.  */
5627GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02);
5628/* machhwsuo - machhwsuo. */
5629GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12);
5630/* machhwu   - machhwu.   */
5631GEN_MAC_HANDLER(machhwu, 0x0C, 0x00);
5632/* machhwuo  - machhwuo.  */
5633GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10);
5634/* maclhw    - maclhw.    */
5635GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D);
5636/* maclhwo   - maclhwo.   */
5637GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D);
5638/* maclhws   - maclhws.   */
5639GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F);
5640/* maclhwso  - maclhwso.  */
5641GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F);
5642/* maclhwu   - maclhwu.   */
5643GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C);
5644/* maclhwuo  - maclhwuo.  */
5645GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C);
5646/* maclhwsu  - maclhwsu.  */
5647GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E);
5648/* maclhwsuo - maclhwsuo. */
5649GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E);
5650/* nmacchw   - nmacchw.   */
5651GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05);
5652/* nmacchwo  - nmacchwo.  */
5653GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15);
5654/* nmacchws  - nmacchws.  */
5655GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07);
5656/* nmacchwso - nmacchwso. */
5657GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17);
5658/* nmachhw   - nmachhw.   */
5659GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01);
5660/* nmachhwo  - nmachhwo.  */
5661GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11);
5662/* nmachhws  - nmachhws.  */
5663GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03);
5664/* nmachhwso - nmachhwso. */
5665GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13);
5666/* nmaclhw   - nmaclhw.   */
5667GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D);
5668/* nmaclhwo  - nmaclhwo.  */
5669GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D);
5670/* nmaclhws  - nmaclhws.  */
5671GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F);
5672/* nmaclhwso - nmaclhwso. */
5673GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F);
5674
5675/* mulchw  - mulchw.  */
5676GEN_MAC_HANDLER(mulchw, 0x08, 0x05);
5677/* mulchwu - mulchwu. */
5678GEN_MAC_HANDLER(mulchwu, 0x08, 0x04);
5679/* mulhhw  - mulhhw.  */
5680GEN_MAC_HANDLER(mulhhw, 0x08, 0x01);
5681/* mulhhwu - mulhhwu. */
5682GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00);
5683/* mullhw  - mullhw.  */
5684GEN_MAC_HANDLER(mullhw, 0x08, 0x0D);
5685/* mullhwu - mullhwu. */
5686GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
5687
5688/* mfdcr */
5689static void gen_mfdcr(DisasContext *ctx)
5690{
5691#if defined(CONFIG_USER_ONLY)
5692    GEN_PRIV;
5693#else
5694    TCGv dcrn;
5695
5696    CHK_SV;
5697    dcrn = tcg_const_tl(SPR(ctx->opcode));
5698    gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env, dcrn);
5699    tcg_temp_free(dcrn);
5700#endif /* defined(CONFIG_USER_ONLY) */
5701}
5702
5703/* mtdcr */
5704static void gen_mtdcr(DisasContext *ctx)
5705{
5706#if defined(CONFIG_USER_ONLY)
5707    GEN_PRIV;
5708#else
5709    TCGv dcrn;
5710
5711    CHK_SV;
5712    dcrn = tcg_const_tl(SPR(ctx->opcode));
5713    gen_helper_store_dcr(cpu_env, dcrn, cpu_gpr[rS(ctx->opcode)]);
5714    tcg_temp_free(dcrn);
5715#endif /* defined(CONFIG_USER_ONLY) */
5716}
5717
5718/* mfdcrx */
5719/* XXX: not implemented on 440 ? */
5720static void gen_mfdcrx(DisasContext *ctx)
5721{
5722#if defined(CONFIG_USER_ONLY)
5723    GEN_PRIV;
5724#else
5725    CHK_SV;
5726    gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
5727                        cpu_gpr[rA(ctx->opcode)]);
5728    /* Note: Rc update flag set leads to undefined state of Rc0 */
5729#endif /* defined(CONFIG_USER_ONLY) */
5730}
5731
5732/* mtdcrx */
5733/* XXX: not implemented on 440 ? */
5734static void gen_mtdcrx(DisasContext *ctx)
5735{
5736#if defined(CONFIG_USER_ONLY)
5737    GEN_PRIV;
5738#else
5739    CHK_SV;
5740    gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
5741                         cpu_gpr[rS(ctx->opcode)]);
5742    /* Note: Rc update flag set leads to undefined state of Rc0 */
5743#endif /* defined(CONFIG_USER_ONLY) */
5744}
5745
5746/* mfdcrux (PPC 460) : user-mode access to DCR */
5747static void gen_mfdcrux(DisasContext *ctx)
5748{
5749    gen_helper_load_dcr(cpu_gpr[rD(ctx->opcode)], cpu_env,
5750                        cpu_gpr[rA(ctx->opcode)]);
5751    /* Note: Rc update flag set leads to undefined state of Rc0 */
5752}
5753
5754/* mtdcrux (PPC 460) : user-mode access to DCR */
5755static void gen_mtdcrux(DisasContext *ctx)
5756{
5757    gen_helper_store_dcr(cpu_env, cpu_gpr[rA(ctx->opcode)],
5758                         cpu_gpr[rS(ctx->opcode)]);
5759    /* Note: Rc update flag set leads to undefined state of Rc0 */
5760}
5761
5762/* dccci */
5763static void gen_dccci(DisasContext *ctx)
5764{
5765    CHK_SV;
5766    /* interpreted as no-op */
5767}
5768
5769/* dcread */
5770static void gen_dcread(DisasContext *ctx)
5771{
5772#if defined(CONFIG_USER_ONLY)
5773    GEN_PRIV;
5774#else
5775    TCGv EA, val;
5776
5777    CHK_SV;
5778    gen_set_access_type(ctx, ACCESS_CACHE);
5779    EA = tcg_temp_new();
5780    gen_addr_reg_index(ctx, EA);
5781    val = tcg_temp_new();
5782    gen_qemu_ld32u(ctx, val, EA);
5783    tcg_temp_free(val);
5784    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
5785    tcg_temp_free(EA);
5786#endif /* defined(CONFIG_USER_ONLY) */
5787}
5788
5789/* icbt */
5790static void gen_icbt_40x(DisasContext *ctx)
5791{
5792    /* interpreted as no-op */
5793    /* XXX: specification say this is treated as a load by the MMU
5794     *      but does not generate any exception
5795     */
5796}
5797
5798/* iccci */
5799static void gen_iccci(DisasContext *ctx)
5800{
5801    CHK_SV;
5802    /* interpreted as no-op */
5803}
5804
5805/* icread */
5806static void gen_icread(DisasContext *ctx)
5807{
5808    CHK_SV;
5809    /* interpreted as no-op */
5810}
5811
5812/* rfci (supervisor only) */
5813static void gen_rfci_40x(DisasContext *ctx)
5814{
5815#if defined(CONFIG_USER_ONLY)
5816    GEN_PRIV;
5817#else
5818    CHK_SV;
5819    /* Restore CPU state */
5820    gen_helper_40x_rfci(cpu_env);
5821    gen_sync_exception(ctx);
5822#endif /* defined(CONFIG_USER_ONLY) */
5823}
5824
5825static void gen_rfci(DisasContext *ctx)
5826{
5827#if defined(CONFIG_USER_ONLY)
5828    GEN_PRIV;
5829#else
5830    CHK_SV;
5831    /* Restore CPU state */
5832    gen_helper_rfci(cpu_env);
5833    gen_sync_exception(ctx);
5834#endif /* defined(CONFIG_USER_ONLY) */
5835}
5836
5837/* BookE specific */
5838
5839/* XXX: not implemented on 440 ? */
5840static void gen_rfdi(DisasContext *ctx)
5841{
5842#if defined(CONFIG_USER_ONLY)
5843    GEN_PRIV;
5844#else
5845    CHK_SV;
5846    /* Restore CPU state */
5847    gen_helper_rfdi(cpu_env);
5848    gen_sync_exception(ctx);
5849#endif /* defined(CONFIG_USER_ONLY) */
5850}
5851
5852/* XXX: not implemented on 440 ? */
5853static void gen_rfmci(DisasContext *ctx)
5854{
5855#if defined(CONFIG_USER_ONLY)
5856    GEN_PRIV;
5857#else
5858    CHK_SV;
5859    /* Restore CPU state */
5860    gen_helper_rfmci(cpu_env);
5861    gen_sync_exception(ctx);
5862#endif /* defined(CONFIG_USER_ONLY) */
5863}
5864
5865/* TLB management - PowerPC 405 implementation */
5866
5867/* tlbre */
5868static void gen_tlbre_40x(DisasContext *ctx)
5869{
5870#if defined(CONFIG_USER_ONLY)
5871    GEN_PRIV;
5872#else
5873    CHK_SV;
5874    switch (rB(ctx->opcode)) {
5875    case 0:
5876        gen_helper_4xx_tlbre_hi(cpu_gpr[rD(ctx->opcode)], cpu_env,
5877                                cpu_gpr[rA(ctx->opcode)]);
5878        break;
5879    case 1:
5880        gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_env,
5881                                cpu_gpr[rA(ctx->opcode)]);
5882        break;
5883    default:
5884        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5885        break;
5886    }
5887#endif /* defined(CONFIG_USER_ONLY) */
5888}
5889
5890/* tlbsx - tlbsx. */
5891static void gen_tlbsx_40x(DisasContext *ctx)
5892{
5893#if defined(CONFIG_USER_ONLY)
5894    GEN_PRIV;
5895#else
5896    TCGv t0;
5897
5898    CHK_SV;
5899    t0 = tcg_temp_new();
5900    gen_addr_reg_index(ctx, t0);
5901    gen_helper_4xx_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
5902    tcg_temp_free(t0);
5903    if (Rc(ctx->opcode)) {
5904        TCGLabel *l1 = gen_new_label();
5905        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
5906        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
5907        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
5908        gen_set_label(l1);
5909    }
5910#endif /* defined(CONFIG_USER_ONLY) */
5911}
5912
5913/* tlbwe */
5914static void gen_tlbwe_40x(DisasContext *ctx)
5915{
5916#if defined(CONFIG_USER_ONLY)
5917    GEN_PRIV;
5918#else
5919    CHK_SV;
5920
5921    switch (rB(ctx->opcode)) {
5922    case 0:
5923        gen_helper_4xx_tlbwe_hi(cpu_env, cpu_gpr[rA(ctx->opcode)],
5924                                cpu_gpr[rS(ctx->opcode)]);
5925        break;
5926    case 1:
5927        gen_helper_4xx_tlbwe_lo(cpu_env, cpu_gpr[rA(ctx->opcode)],
5928                                cpu_gpr[rS(ctx->opcode)]);
5929        break;
5930    default:
5931        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5932        break;
5933    }
5934#endif /* defined(CONFIG_USER_ONLY) */
5935}
5936
5937/* TLB management - PowerPC 440 implementation */
5938
5939/* tlbre */
5940static void gen_tlbre_440(DisasContext *ctx)
5941{
5942#if defined(CONFIG_USER_ONLY)
5943    GEN_PRIV;
5944#else
5945    CHK_SV;
5946
5947    switch (rB(ctx->opcode)) {
5948    case 0:
5949    case 1:
5950    case 2:
5951        {
5952            TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
5953            gen_helper_440_tlbre(cpu_gpr[rD(ctx->opcode)], cpu_env,
5954                                 t0, cpu_gpr[rA(ctx->opcode)]);
5955            tcg_temp_free_i32(t0);
5956        }
5957        break;
5958    default:
5959        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5960        break;
5961    }
5962#endif /* defined(CONFIG_USER_ONLY) */
5963}
5964
5965/* tlbsx - tlbsx. */
5966static void gen_tlbsx_440(DisasContext *ctx)
5967{
5968#if defined(CONFIG_USER_ONLY)
5969    GEN_PRIV;
5970#else
5971    TCGv t0;
5972
5973    CHK_SV;
5974    t0 = tcg_temp_new();
5975    gen_addr_reg_index(ctx, t0);
5976    gen_helper_440_tlbsx(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);
5977    tcg_temp_free(t0);
5978    if (Rc(ctx->opcode)) {
5979        TCGLabel *l1 = gen_new_label();
5980        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
5981        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rD(ctx->opcode)], -1, l1);
5982        tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 0x02);
5983        gen_set_label(l1);
5984    }
5985#endif /* defined(CONFIG_USER_ONLY) */
5986}
5987
5988/* tlbwe */
5989static void gen_tlbwe_440(DisasContext *ctx)
5990{
5991#if defined(CONFIG_USER_ONLY)
5992    GEN_PRIV;
5993#else
5994    CHK_SV;
5995    switch (rB(ctx->opcode)) {
5996    case 0:
5997    case 1:
5998    case 2:
5999        {
6000            TCGv_i32 t0 = tcg_const_i32(rB(ctx->opcode));
6001            gen_helper_440_tlbwe(cpu_env, t0, cpu_gpr[rA(ctx->opcode)],
6002                                 cpu_gpr[rS(ctx->opcode)]);
6003            tcg_temp_free_i32(t0);
6004        }
6005        break;
6006    default:
6007        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6008        break;
6009    }
6010#endif /* defined(CONFIG_USER_ONLY) */
6011}
6012
6013/* TLB management - PowerPC BookE 2.06 implementation */
6014
6015/* tlbre */
6016static void gen_tlbre_booke206(DisasContext *ctx)
6017{
6018 #if defined(CONFIG_USER_ONLY)
6019    GEN_PRIV;
6020#else
6021   CHK_SV;
6022    gen_helper_booke206_tlbre(cpu_env);
6023#endif /* defined(CONFIG_USER_ONLY) */
6024}
6025
6026/* tlbsx - tlbsx. */
6027static void gen_tlbsx_booke206(DisasContext *ctx)
6028{
6029#if defined(CONFIG_USER_ONLY)
6030    GEN_PRIV;
6031#else
6032    TCGv t0;
6033
6034    CHK_SV;
6035    if (rA(ctx->opcode)) {
6036        t0 = tcg_temp_new();
6037        tcg_gen_mov_tl(t0, cpu_gpr[rD(ctx->opcode)]);
6038    } else {
6039        t0 = tcg_const_tl(0);
6040    }
6041
6042    tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]);
6043    gen_helper_booke206_tlbsx(cpu_env, t0);
6044    tcg_temp_free(t0);
6045#endif /* defined(CONFIG_USER_ONLY) */
6046}
6047
6048/* tlbwe */
6049static void gen_tlbwe_booke206(DisasContext *ctx)
6050{
6051#if defined(CONFIG_USER_ONLY)
6052    GEN_PRIV;
6053#else
6054    CHK_SV;
6055    gen_helper_booke206_tlbwe(cpu_env);
6056#endif /* defined(CONFIG_USER_ONLY) */
6057}
6058
6059static void gen_tlbivax_booke206(DisasContext *ctx)
6060{
6061#if defined(CONFIG_USER_ONLY)
6062    GEN_PRIV;
6063#else
6064    TCGv t0;
6065
6066    CHK_SV;
6067    t0 = tcg_temp_new();
6068    gen_addr_reg_index(ctx, t0);
6069    gen_helper_booke206_tlbivax(cpu_env, t0);
6070    tcg_temp_free(t0);
6071#endif /* defined(CONFIG_USER_ONLY) */
6072}
6073
6074static void gen_tlbilx_booke206(DisasContext *ctx)
6075{
6076#if defined(CONFIG_USER_ONLY)
6077    GEN_PRIV;
6078#else
6079    TCGv t0;
6080
6081    CHK_SV;
6082    t0 = tcg_temp_new();
6083    gen_addr_reg_index(ctx, t0);
6084
6085    switch((ctx->opcode >> 21) & 0x3) {
6086    case 0:
6087        gen_helper_booke206_tlbilx0(cpu_env, t0);
6088        break;
6089    case 1:
6090        gen_helper_booke206_tlbilx1(cpu_env, t0);
6091        break;
6092    case 3:
6093        gen_helper_booke206_tlbilx3(cpu_env, t0);
6094        break;
6095    default:
6096        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
6097        break;
6098    }
6099
6100    tcg_temp_free(t0);
6101#endif /* defined(CONFIG_USER_ONLY) */
6102}
6103
6104
6105/* wrtee */
6106static void gen_wrtee(DisasContext *ctx)
6107{
6108#if defined(CONFIG_USER_ONLY)
6109    GEN_PRIV;
6110#else
6111    TCGv t0;
6112
6113    CHK_SV;
6114    t0 = tcg_temp_new();
6115    tcg_gen_andi_tl(t0, cpu_gpr[rD(ctx->opcode)], (1 << MSR_EE));
6116    tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
6117    tcg_gen_or_tl(cpu_msr, cpu_msr, t0);
6118    tcg_temp_free(t0);
6119    /* Stop translation to have a chance to raise an exception
6120     * if we just set msr_ee to 1
6121     */
6122    gen_stop_exception(ctx);
6123#endif /* defined(CONFIG_USER_ONLY) */
6124}
6125
6126/* wrteei */
6127static void gen_wrteei(DisasContext *ctx)
6128{
6129#if defined(CONFIG_USER_ONLY)
6130    GEN_PRIV;
6131#else
6132    CHK_SV;
6133    if (ctx->opcode & 0x00008000) {
6134        tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE));
6135        /* Stop translation to have a chance to raise an exception */
6136        gen_stop_exception(ctx);
6137    } else {
6138        tcg_gen_andi_tl(cpu_msr, cpu_msr, ~(1 << MSR_EE));
6139    }
6140#endif /* defined(CONFIG_USER_ONLY) */
6141}
6142
6143/* PowerPC 440 specific instructions */
6144
6145/* dlmzb */
6146static void gen_dlmzb(DisasContext *ctx)
6147{
6148    TCGv_i32 t0 = tcg_const_i32(Rc(ctx->opcode));
6149    gen_helper_dlmzb(cpu_gpr[rA(ctx->opcode)], cpu_env,
6150                     cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], t0);
6151    tcg_temp_free_i32(t0);
6152}
6153
6154/* mbar replaces eieio on 440 */
6155static void gen_mbar(DisasContext *ctx)
6156{
6157    /* interpreted as no-op */
6158}
6159
6160/* msync replaces sync on 440 */
6161static void gen_msync_4xx(DisasContext *ctx)
6162{
6163    /* interpreted as no-op */
6164}
6165
6166/* icbt */
6167static void gen_icbt_440(DisasContext *ctx)
6168{
6169    /* interpreted as no-op */
6170    /* XXX: specification say this is treated as a load by the MMU
6171     *      but does not generate any exception
6172     */
6173}
6174
6175/* Embedded.Processor Control */
6176
6177static void gen_msgclr(DisasContext *ctx)
6178{
6179#if defined(CONFIG_USER_ONLY)
6180    GEN_PRIV;
6181#else
6182    CHK_SV;
6183    gen_helper_msgclr(cpu_env, cpu_gpr[rB(ctx->opcode)]);
6184#endif /* defined(CONFIG_USER_ONLY) */
6185}
6186
6187static void gen_msgsnd(DisasContext *ctx)
6188{
6189#if defined(CONFIG_USER_ONLY)
6190    GEN_PRIV;
6191#else
6192    CHK_SV;
6193    gen_helper_msgsnd(cpu_gpr[rB(ctx->opcode)]);
6194#endif /* defined(CONFIG_USER_ONLY) */
6195}
6196
6197
6198#if defined(TARGET_PPC64)
6199static void gen_maddld(DisasContext *ctx)
6200{
6201    TCGv_i64 t1 = tcg_temp_new_i64();
6202
6203    tcg_gen_mul_i64(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
6204    tcg_gen_add_i64(cpu_gpr[rD(ctx->opcode)], t1, cpu_gpr[rC(ctx->opcode)]);
6205    tcg_temp_free_i64(t1);
6206}
6207
6208/* maddhd maddhdu */
6209static void gen_maddhd_maddhdu(DisasContext *ctx)
6210{
6211    TCGv_i64 lo = tcg_temp_new_i64();
6212    TCGv_i64 hi = tcg_temp_new_i64();
6213    TCGv_i64 t1 = tcg_temp_new_i64();
6214
6215    if (Rc(ctx->opcode)) {
6216        tcg_gen_mulu2_i64(lo, hi, cpu_gpr[rA(ctx->opcode)],
6217                          cpu_gpr[rB(ctx->opcode)]);
6218        tcg_gen_movi_i64(t1, 0);
6219    } else {
6220        tcg_gen_muls2_i64(lo, hi, cpu_gpr[rA(ctx->opcode)],
6221                          cpu_gpr[rB(ctx->opcode)]);
6222        tcg_gen_sari_i64(t1, cpu_gpr[rC(ctx->opcode)], 63);
6223    }
6224    tcg_gen_add2_i64(t1, cpu_gpr[rD(ctx->opcode)], lo, hi,
6225                     cpu_gpr[rC(ctx->opcode)], t1);
6226    tcg_temp_free_i64(lo);
6227    tcg_temp_free_i64(hi);
6228    tcg_temp_free_i64(t1);
6229}
6230#endif /* defined(TARGET_PPC64) */
6231
6232static void gen_tbegin(DisasContext *ctx)
6233{
6234    if (unlikely(!ctx->tm_enabled)) {
6235        gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);
6236        return;
6237    }
6238    gen_helper_tbegin(cpu_env);
6239}
6240
6241#define GEN_TM_NOOP(name)                                      \
6242static inline void gen_##name(DisasContext *ctx)               \
6243{                                                              \
6244    if (unlikely(!ctx->tm_enabled)) {                          \
6245        gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);   \
6246        return;                                                \
6247    }                                                          \
6248    /* Because tbegin always fails in QEMU, these user         \
6249     * space instructions all have a simple implementation:    \
6250     *                                                         \
6251     *     CR[0] = 0b0 || MSR[TS] || 0b0                       \
6252     *           = 0b0 || 0b00    || 0b0                       \
6253     */                                                        \
6254    tcg_gen_movi_i32(cpu_crf[0], 0);                           \
6255}
6256
6257GEN_TM_NOOP(tend);
6258GEN_TM_NOOP(tabort);
6259GEN_TM_NOOP(tabortwc);
6260GEN_TM_NOOP(tabortwci);
6261GEN_TM_NOOP(tabortdc);
6262GEN_TM_NOOP(tabortdci);
6263GEN_TM_NOOP(tsr);
6264static inline void gen_cp_abort(DisasContext *ctx)
6265{
6266    // Do Nothing
6267}
6268
6269#define GEN_CP_PASTE_NOOP(name)                           \
6270static inline void gen_##name(DisasContext *ctx)          \
6271{                                                         \
6272    /* Generate invalid exception until                   \
6273     * we have an implementation of the copy              \
6274     * paste facility                                     \
6275     */                                                   \
6276    gen_invalid(ctx);                                     \
6277}
6278
6279GEN_CP_PASTE_NOOP(copy)
6280GEN_CP_PASTE_NOOP(paste)
6281
6282static void gen_tcheck(DisasContext *ctx)
6283{
6284    if (unlikely(!ctx->tm_enabled)) {
6285        gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);
6286        return;
6287    }
6288    /* Because tbegin always fails, the tcheck implementation
6289     * is simple:
6290     *
6291     * CR[CRF] = TDOOMED || MSR[TS] || 0b0
6292     *         = 0b1 || 0b00 || 0b0
6293     */
6294    tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0x8);
6295}
6296
6297#if defined(CONFIG_USER_ONLY)
6298#define GEN_TM_PRIV_NOOP(name)                                 \
6299static inline void gen_##name(DisasContext *ctx)               \
6300{                                                              \
6301    gen_priv_exception(ctx, POWERPC_EXCP_PRIV_OPC);           \
6302}
6303
6304#else
6305
6306#define GEN_TM_PRIV_NOOP(name)                                 \
6307static inline void gen_##name(DisasContext *ctx)               \
6308{                                                              \
6309    CHK_SV;                                                    \
6310    if (unlikely(!ctx->tm_enabled)) {                          \
6311        gen_exception_err(ctx, POWERPC_EXCP_FU, FSCR_IC_TM);   \
6312        return;                                                \
6313    }                                                          \
6314    /* Because tbegin always fails, the implementation is      \
6315     * simple:                                                 \
6316     *                                                         \
6317     *   CR[0] = 0b0 || MSR[TS] || 0b0                         \
6318     *         = 0b0 || 0b00 | 0b0                             \
6319     */                                                        \
6320    tcg_gen_movi_i32(cpu_crf[0], 0);                           \
6321}
6322
6323#endif
6324
6325GEN_TM_PRIV_NOOP(treclaim);
6326GEN_TM_PRIV_NOOP(trechkpt);
6327
6328#include "translate/fp-impl.inc.c"
6329
6330#include "translate/vmx-impl.inc.c"
6331
6332#include "translate/vsx-impl.inc.c"
6333
6334#include "translate/dfp-impl.inc.c"
6335
6336#include "translate/spe-impl.inc.c"
6337
6338/* Handles lfdp, lxsd, lxssp */
6339static void gen_dform39(DisasContext *ctx)
6340{
6341    switch (ctx->opcode & 0x3) {
6342    case 0: /* lfdp */
6343        if (ctx->insns_flags2 & PPC2_ISA205) {
6344            return gen_lfdp(ctx);
6345        }
6346        break;
6347    case 2: /* lxsd */
6348        if (ctx->insns_flags2 & PPC2_ISA300) {
6349            return gen_lxsd(ctx);
6350        }
6351        break;
6352    case 3: /* lxssp */
6353        if (ctx->insns_flags2 & PPC2_ISA300) {
6354            return gen_lxssp(ctx);
6355        }
6356        break;
6357    }
6358    return gen_invalid(ctx);
6359}
6360
6361/* handles stfdp, lxv, stxsd, stxssp lxvx */
6362static void gen_dform3D(DisasContext *ctx)
6363{
6364    if ((ctx->opcode & 3) == 1) { /* DQ-FORM */
6365        switch (ctx->opcode & 0x7) {
6366        case 1: /* lxv */
6367            if (ctx->insns_flags2 & PPC2_ISA300) {
6368                return gen_lxv(ctx);
6369            }
6370            break;
6371        case 5: /* stxv */
6372            if (ctx->insns_flags2 & PPC2_ISA300) {
6373                return gen_stxv(ctx);
6374            }
6375            break;
6376        }
6377    } else { /* DS-FORM */
6378        switch (ctx->opcode & 0x3) {
6379        case 0: /* stfdp */
6380            if (ctx->insns_flags2 & PPC2_ISA205) {
6381                return gen_stfdp(ctx);
6382            }
6383            break;
6384        case 2: /* stxsd */
6385            if (ctx->insns_flags2 & PPC2_ISA300) {
6386                return gen_stxsd(ctx);
6387            }
6388            break;
6389        case 3: /* stxssp */
6390            if (ctx->insns_flags2 & PPC2_ISA300) {
6391                return gen_stxssp(ctx);
6392            }
6393            break;
6394        }
6395    }
6396    return gen_invalid(ctx);
6397}
6398
6399static opcode_t opcodes[] = {
6400GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE),
6401GEN_HANDLER(cmp, 0x1F, 0x00, 0x00, 0x00400000, PPC_INTEGER),
6402GEN_HANDLER(cmpi, 0x0B, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
6403GEN_HANDLER(cmpl, 0x1F, 0x00, 0x01, 0x00400001, PPC_INTEGER),
6404GEN_HANDLER(cmpli, 0x0A, 0xFF, 0xFF, 0x00400000, PPC_INTEGER),
6405#if defined(TARGET_PPC64)
6406GEN_HANDLER_E(cmpeqb, 0x1F, 0x00, 0x07, 0x00600000, PPC_NONE, PPC2_ISA300),
6407#endif
6408GEN_HANDLER_E(cmpb, 0x1F, 0x1C, 0x0F, 0x00000001, PPC_NONE, PPC2_ISA205),
6409GEN_HANDLER_E(cmprb, 0x1F, 0x00, 0x06, 0x00400001, PPC_NONE, PPC2_ISA300),
6410GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL),
6411GEN_HANDLER(addi, 0x0E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6412GEN_HANDLER(addic, 0x0C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6413GEN_HANDLER2(addic_, "addic.", 0x0D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6414GEN_HANDLER(addis, 0x0F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6415GEN_HANDLER_E(addpcis, 0x13, 0x2, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA300),
6416GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER),
6417GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER),
6418GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER),
6419GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER),
6420GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6421#if defined(TARGET_PPC64)
6422GEN_HANDLER(mulld, 0x1F, 0x09, 0x07, 0x00000000, PPC_64B),
6423#endif
6424GEN_HANDLER(neg, 0x1F, 0x08, 0x03, 0x0000F800, PPC_INTEGER),
6425GEN_HANDLER(nego, 0x1F, 0x08, 0x13, 0x0000F800, PPC_INTEGER),
6426GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6427GEN_HANDLER2(andi_, "andi.", 0x1C, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6428GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6429GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER),
6430GEN_HANDLER_E(cnttzw, 0x1F, 0x1A, 0x10, 0x00000000, PPC_NONE, PPC2_ISA300),
6431GEN_HANDLER_E(copy, 0x1F, 0x06, 0x18, 0x03C00001, PPC_NONE, PPC2_ISA300),
6432GEN_HANDLER_E(cp_abort, 0x1F, 0x06, 0x1A, 0x03FFF801, PPC_NONE, PPC2_ISA300),
6433GEN_HANDLER_E(paste, 0x1F, 0x06, 0x1C, 0x03C00000, PPC_NONE, PPC2_ISA300),
6434GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER),
6435GEN_HANDLER(xor, 0x1F, 0x1C, 0x09, 0x00000000, PPC_INTEGER),
6436GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6437GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6438GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6439GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6440GEN_HANDLER(popcntb, 0x1F, 0x1A, 0x03, 0x0000F801, PPC_POPCNTB),
6441GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD),
6442GEN_HANDLER_E(prtyw, 0x1F, 0x1A, 0x04, 0x0000F801, PPC_NONE, PPC2_ISA205),
6443#if defined(TARGET_PPC64)
6444GEN_HANDLER(popcntd, 0x1F, 0x1A, 0x0F, 0x0000F801, PPC_POPCNTWD),
6445GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B),
6446GEN_HANDLER_E(cnttzd, 0x1F, 0x1A, 0x11, 0x00000000, PPC_NONE, PPC2_ISA300),
6447GEN_HANDLER_E(darn, 0x1F, 0x13, 0x17, 0x001CF801, PPC_NONE, PPC2_ISA300),
6448GEN_HANDLER_E(prtyd, 0x1F, 0x1A, 0x05, 0x0000F801, PPC_NONE, PPC2_ISA205),
6449GEN_HANDLER_E(bpermd, 0x1F, 0x1C, 0x07, 0x00000001, PPC_NONE, PPC2_PERM_ISA206),
6450#endif
6451GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6452GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6453GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6454GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER),
6455GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER),
6456GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER),
6457GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER),
6458#if defined(TARGET_PPC64)
6459GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B),
6460GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B),
6461GEN_HANDLER2(sradi0, "sradi", 0x1F, 0x1A, 0x19, 0x00000000, PPC_64B),
6462GEN_HANDLER2(sradi1, "sradi", 0x1F, 0x1B, 0x19, 0x00000000, PPC_64B),
6463GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B),
6464GEN_HANDLER2_E(extswsli0, "extswsli", 0x1F, 0x1A, 0x1B, 0x00000000,
6465               PPC_NONE, PPC2_ISA300),
6466GEN_HANDLER2_E(extswsli1, "extswsli", 0x1F, 0x1B, 0x1B, 0x00000000,
6467               PPC_NONE, PPC2_ISA300),
6468#endif
6469#if defined(TARGET_PPC64)
6470GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B),
6471GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX),
6472GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B),
6473#endif
6474/* handles lfdp, lxsd, lxssp */
6475GEN_HANDLER_E(dform39, 0x39, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
6476/* handles stfdp, lxv, stxsd, stxssp, stxv */
6477GEN_HANDLER_E(dform3D, 0x3D, 0xFF, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA205),
6478GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6479GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
6480GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_STRING),
6481GEN_HANDLER(lswx, 0x1F, 0x15, 0x10, 0x00000001, PPC_STRING),
6482GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
6483GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
6484GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FFF801, PPC_MEM_EIEIO),
6485GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
6486GEN_HANDLER_E(lbarx, 0x1F, 0x14, 0x01, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
6487GEN_HANDLER_E(lharx, 0x1F, 0x14, 0x03, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
6488GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES),
6489GEN_HANDLER_E(lwat, 0x1F, 0x06, 0x12, 0x00000001, PPC_NONE, PPC2_ISA300),
6490GEN_HANDLER_E(stwat, 0x1F, 0x06, 0x16, 0x00000001, PPC_NONE, PPC2_ISA300),
6491GEN_HANDLER_E(stbcx_, 0x1F, 0x16, 0x15, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
6492GEN_HANDLER_E(sthcx_, 0x1F, 0x16, 0x16, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
6493GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
6494#if defined(TARGET_PPC64)
6495GEN_HANDLER_E(ldat, 0x1F, 0x06, 0x13, 0x00000001, PPC_NONE, PPC2_ISA300),
6496GEN_HANDLER_E(stdat, 0x1F, 0x06, 0x17, 0x00000001, PPC_NONE, PPC2_ISA300),
6497GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B),
6498GEN_HANDLER_E(lqarx, 0x1F, 0x14, 0x08, 0, PPC_NONE, PPC2_LSQ_ISA207),
6499GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
6500GEN_HANDLER_E(stqcx_, 0x1F, 0x16, 0x05, 0, PPC_NONE, PPC2_LSQ_ISA207),
6501#endif
6502GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x039FF801, PPC_MEM_SYNC),
6503GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x03FFF801, PPC_WAIT),
6504GEN_HANDLER_E(wait, 0x1F, 0x1E, 0x00, 0x039FF801, PPC_NONE, PPC2_ISA300),
6505GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
6506GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
6507GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW),
6508GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW),
6509GEN_HANDLER_E(bctar, 0x13, 0x10, 0x11, 0x0000E000, PPC_NONE, PPC2_BCTAR_ISA207),
6510GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER),
6511GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW),
6512#if defined(TARGET_PPC64)
6513GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B),
6514GEN_HANDLER_E(stop, 0x13, 0x12, 0x0b, 0x03FFF801, PPC_NONE, PPC2_ISA300),
6515GEN_HANDLER_E(doze, 0x13, 0x12, 0x0c, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
6516GEN_HANDLER_E(nap, 0x13, 0x12, 0x0d, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
6517GEN_HANDLER_E(sleep, 0x13, 0x12, 0x0e, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
6518GEN_HANDLER_E(rvwinkle, 0x13, 0x12, 0x0f, 0x03FFF801, PPC_NONE, PPC2_PM_ISA206),
6519GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H),
6520#endif
6521GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW),
6522GEN_HANDLER(tw, 0x1F, 0x04, 0x00, 0x00000001, PPC_FLOW),
6523GEN_HANDLER(twi, 0x03, 0xFF, 0xFF, 0x00000000, PPC_FLOW),
6524#if defined(TARGET_PPC64)
6525GEN_HANDLER(td, 0x1F, 0x04, 0x02, 0x00000001, PPC_64B),
6526GEN_HANDLER(tdi, 0x02, 0xFF, 0xFF, 0x00000000, PPC_64B),
6527#endif
6528GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC),
6529GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC),
6530GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC),
6531GEN_HANDLER(mfspr, 0x1F, 0x13, 0x0A, 0x00000001, PPC_MISC),
6532GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB),
6533GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC),
6534#if defined(TARGET_PPC64)
6535GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B),
6536GEN_HANDLER_E(setb, 0x1F, 0x00, 0x04, 0x0003F801, PPC_NONE, PPC2_ISA300),
6537GEN_HANDLER_E(mcrxrx, 0x1F, 0x00, 0x12, 0x007FF801, PPC_NONE, PPC2_ISA300),
6538#endif
6539GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001EF801, PPC_MISC),
6540GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000000, PPC_MISC),
6541GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE),
6542GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
6543GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
6544GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x00000001, PPC_CACHE),
6545GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x00000001, PPC_CACHE),
6546GEN_HANDLER_E(dcbtls, 0x1F, 0x06, 0x05, 0x02000001, PPC_BOOKE, PPC2_BOOKE206),
6547GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ),
6548GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
6549GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC),
6550GEN_HANDLER(dss, 0x1F, 0x16, 0x19, 0x019FF801, PPC_ALTIVEC),
6551GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE_ICBI),
6552GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA),
6553GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT),
6554GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT),
6555GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT),
6556GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT),
6557#if defined(TARGET_PPC64)
6558GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B),
6559GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
6560             PPC_SEGMENT_64B),
6561GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B),
6562GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
6563             PPC_SEGMENT_64B),
6564GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x001F0001, PPC_SEGMENT_64B),
6565GEN_HANDLER2(slbmfee, "slbmfee", 0x1F, 0x13, 0x1C, 0x001F0001, PPC_SEGMENT_64B),
6566GEN_HANDLER2(slbmfev, "slbmfev", 0x1F, 0x13, 0x1A, 0x001F0001, PPC_SEGMENT_64B),
6567GEN_HANDLER2(slbfee_, "slbfee.", 0x1F, 0x13, 0x1E, 0x001F0000, PPC_SEGMENT_64B),
6568#endif
6569GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA),
6570/* XXX Those instructions will need to be handled differently for
6571 * different ISA versions */
6572GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x001F0001, PPC_MEM_TLBIE),
6573GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x001F0001, PPC_MEM_TLBIE),
6574GEN_HANDLER_E(tlbiel, 0x1F, 0x12, 0x08, 0x00100001, PPC_NONE, PPC2_ISA300),
6575GEN_HANDLER_E(tlbie, 0x1F, 0x12, 0x09, 0x00100001, PPC_NONE, PPC2_ISA300),
6576GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC),
6577#if defined(TARGET_PPC64)
6578GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x031FFC01, PPC_SLBI),
6579GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI),
6580GEN_HANDLER_E(slbieg, 0x1F, 0x12, 0x0E, 0x001F0001, PPC_NONE, PPC2_ISA300),
6581GEN_HANDLER_E(slbsync, 0x1F, 0x12, 0x0A, 0x03FFF801, PPC_NONE, PPC2_ISA300),
6582#endif
6583GEN_HANDLER(eciwx, 0x1F, 0x16, 0x0D, 0x00000001, PPC_EXTERN),
6584GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN),
6585GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR),
6586GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR),
6587GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR),
6588GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR),
6589GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR),
6590GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR),
6591GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR),
6592GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR),
6593GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR),
6594GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
6595GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR),
6596GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR),
6597GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR),
6598GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR),
6599GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR),
6600GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR),
6601GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR),
6602GEN_HANDLER(rlmi, 0x16, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR),
6603GEN_HANDLER(rrib, 0x1F, 0x19, 0x10, 0x00000000, PPC_POWER_BR),
6604GEN_HANDLER(sle, 0x1F, 0x19, 0x04, 0x00000000, PPC_POWER_BR),
6605GEN_HANDLER(sleq, 0x1F, 0x19, 0x06, 0x00000000, PPC_POWER_BR),
6606GEN_HANDLER(sliq, 0x1F, 0x18, 0x05, 0x00000000, PPC_POWER_BR),
6607GEN_HANDLER(slliq, 0x1F, 0x18, 0x07, 0x00000000, PPC_POWER_BR),
6608GEN_HANDLER(sllq, 0x1F, 0x18, 0x06, 0x00000000, PPC_POWER_BR),
6609GEN_HANDLER(slq, 0x1F, 0x18, 0x04, 0x00000000, PPC_POWER_BR),
6610GEN_HANDLER(sraiq, 0x1F, 0x18, 0x1D, 0x00000000, PPC_POWER_BR),
6611GEN_HANDLER(sraq, 0x1F, 0x18, 0x1C, 0x00000000, PPC_POWER_BR),
6612GEN_HANDLER(sre, 0x1F, 0x19, 0x14, 0x00000000, PPC_POWER_BR),
6613GEN_HANDLER(srea, 0x1F, 0x19, 0x1C, 0x00000000, PPC_POWER_BR),
6614GEN_HANDLER(sreq, 0x1F, 0x19, 0x16, 0x00000000, PPC_POWER_BR),
6615GEN_HANDLER(sriq, 0x1F, 0x18, 0x15, 0x00000000, PPC_POWER_BR),
6616GEN_HANDLER(srliq, 0x1F, 0x18, 0x17, 0x00000000, PPC_POWER_BR),
6617GEN_HANDLER(srlq, 0x1F, 0x18, 0x16, 0x00000000, PPC_POWER_BR),
6618GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR),
6619GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC),
6620GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC),
6621GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC),
6622GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB),
6623GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB),
6624GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB),
6625GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB),
6626GEN_HANDLER(clf, 0x1F, 0x16, 0x03, 0x03E00000, PPC_POWER),
6627GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER),
6628GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER),
6629GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER),
6630GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER),
6631GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER),
6632GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
6633GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
6634GEN_HANDLER(lfqux, 0x1F, 0x17, 0x19, 0x00000001, PPC_POWER2),
6635GEN_HANDLER(lfqx, 0x1F, 0x17, 0x18, 0x00000001, PPC_POWER2),
6636GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
6637GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2),
6638GEN_HANDLER(stfqux, 0x1F, 0x17, 0x1D, 0x00000001, PPC_POWER2),
6639GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2),
6640GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI),
6641GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA),
6642GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR),
6643GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR),
6644GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX),
6645GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX),
6646GEN_HANDLER(mfdcrux, 0x1F, 0x03, 0x09, 0x00000000, PPC_DCRUX),
6647GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX),
6648GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON),
6649GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON),
6650GEN_HANDLER2(icbt_40x, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT),
6651GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON),
6652GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON),
6653GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP),
6654GEN_HANDLER_E(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE, PPC2_BOOKE206),
6655GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI),
6656GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI),
6657GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB),
6658GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB),
6659GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB),
6660GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE),
6661GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE),
6662GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE),
6663GEN_HANDLER2_E(tlbre_booke206, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001,
6664               PPC_NONE, PPC2_BOOKE206),
6665GEN_HANDLER2_E(tlbsx_booke206, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000,
6666               PPC_NONE, PPC2_BOOKE206),
6667GEN_HANDLER2_E(tlbwe_booke206, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001,
6668               PPC_NONE, PPC2_BOOKE206),
6669GEN_HANDLER2_E(tlbivax_booke206, "tlbivax", 0x1F, 0x12, 0x18, 0x00000001,
6670               PPC_NONE, PPC2_BOOKE206),
6671GEN_HANDLER2_E(tlbilx_booke206, "tlbilx", 0x1F, 0x12, 0x00, 0x03800001,
6672               PPC_NONE, PPC2_BOOKE206),
6673GEN_HANDLER2_E(msgsnd, "msgsnd", 0x1F, 0x0E, 0x06, 0x03ff0001,
6674               PPC_NONE, PPC2_PRCNTL),
6675GEN_HANDLER2_E(msgclr, "msgclr", 0x1F, 0x0E, 0x07, 0x03ff0001,
6676               PPC_NONE, PPC2_PRCNTL),
6677GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE),
6678GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000E7C01, PPC_WRTEE),
6679GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC),
6680GEN_HANDLER_E(mbar, 0x1F, 0x16, 0x1a, 0x001FF801,
6681              PPC_BOOKE, PPC2_BOOKE206),
6682GEN_HANDLER(msync_4xx, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE),
6683GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001,
6684               PPC_BOOKE, PPC2_BOOKE206),
6685GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC),
6686GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC),
6687GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
6688GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
6689GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC),
6690#if defined(TARGET_PPC64)
6691GEN_HANDLER_E(maddhd_maddhdu, 0x04, 0x18, 0xFF, 0x00000000, PPC_NONE,
6692              PPC2_ISA300),
6693GEN_HANDLER_E(maddld, 0x04, 0x19, 0xFF, 0x00000000, PPC_NONE, PPC2_ISA300),
6694#endif
6695
6696#undef GEN_INT_ARITH_ADD
6697#undef GEN_INT_ARITH_ADD_CONST
6698#define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov)         \
6699GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x00000000, PPC_INTEGER),
6700#define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,                        \
6701                                add_ca, compute_ca, compute_ov)               \
6702GEN_HANDLER(name, 0x1F, 0x0A, opc3, 0x0000F800, PPC_INTEGER),
6703GEN_INT_ARITH_ADD(add, 0x08, 0, 0, 0)
6704GEN_INT_ARITH_ADD(addo, 0x18, 0, 0, 1)
6705GEN_INT_ARITH_ADD(addc, 0x00, 0, 1, 0)
6706GEN_INT_ARITH_ADD(addco, 0x10, 0, 1, 1)
6707GEN_INT_ARITH_ADD(adde, 0x04, 1, 1, 0)
6708GEN_INT_ARITH_ADD(addeo, 0x14, 1, 1, 1)
6709GEN_INT_ARITH_ADD_CONST(addme, 0x07, -1LL, 1, 1, 0)
6710GEN_INT_ARITH_ADD_CONST(addmeo, 0x17, -1LL, 1, 1, 1)
6711GEN_INT_ARITH_ADD_CONST(addze, 0x06, 0, 1, 1, 0)
6712GEN_INT_ARITH_ADD_CONST(addzeo, 0x16, 0, 1, 1, 1)
6713
6714#undef GEN_INT_ARITH_DIVW
6715#define GEN_INT_ARITH_DIVW(name, opc3, sign, compute_ov)                      \
6716GEN_HANDLER(name, 0x1F, 0x0B, opc3, 0x00000000, PPC_INTEGER)
6717GEN_INT_ARITH_DIVW(divwu, 0x0E, 0, 0),
6718GEN_INT_ARITH_DIVW(divwuo, 0x1E, 0, 1),
6719GEN_INT_ARITH_DIVW(divw, 0x0F, 1, 0),
6720GEN_INT_ARITH_DIVW(divwo, 0x1F, 1, 1),
6721GEN_HANDLER_E(divwe, 0x1F, 0x0B, 0x0D, 0, PPC_NONE, PPC2_DIVE_ISA206),
6722GEN_HANDLER_E(divweo, 0x1F, 0x0B, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206),
6723GEN_HANDLER_E(divweu, 0x1F, 0x0B, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
6724GEN_HANDLER_E(divweuo, 0x1F, 0x0B, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
6725GEN_HANDLER_E(modsw, 0x1F, 0x0B, 0x18, 0x00000001, PPC_NONE, PPC2_ISA300),
6726GEN_HANDLER_E(moduw, 0x1F, 0x0B, 0x08, 0x00000001, PPC_NONE, PPC2_ISA300),
6727
6728#if defined(TARGET_PPC64)
6729#undef GEN_INT_ARITH_DIVD
6730#define GEN_INT_ARITH_DIVD(name, opc3, sign, compute_ov)                      \
6731GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
6732GEN_INT_ARITH_DIVD(divdu, 0x0E, 0, 0),
6733GEN_INT_ARITH_DIVD(divduo, 0x1E, 0, 1),
6734GEN_INT_ARITH_DIVD(divd, 0x0F, 1, 0),
6735GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
6736
6737GEN_HANDLER_E(divdeu, 0x1F, 0x09, 0x0C, 0, PPC_NONE, PPC2_DIVE_ISA206),
6738GEN_HANDLER_E(divdeuo, 0x1F, 0x09, 0x1C, 0, PPC_NONE, PPC2_DIVE_ISA206),
6739GEN_HANDLER_E(divde, 0x1F, 0x09, 0x0D, 0, PPC_NONE, PPC2_DIVE_ISA206),
6740GEN_HANDLER_E(divdeo, 0x1F, 0x09, 0x1D, 0, PPC_NONE, PPC2_DIVE_ISA206),
6741GEN_HANDLER_E(modsd, 0x1F, 0x09, 0x18, 0x00000001, PPC_NONE, PPC2_ISA300),
6742GEN_HANDLER_E(modud, 0x1F, 0x09, 0x08, 0x00000001, PPC_NONE, PPC2_ISA300),
6743
6744#undef GEN_INT_ARITH_MUL_HELPER
6745#define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
6746GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)
6747GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00),
6748GEN_INT_ARITH_MUL_HELPER(mulhd, 0x02),
6749GEN_INT_ARITH_MUL_HELPER(mulldo, 0x17),
6750#endif
6751
6752#undef GEN_INT_ARITH_SUBF
6753#undef GEN_INT_ARITH_SUBF_CONST
6754#define GEN_INT_ARITH_SUBF(name, opc3, add_ca, compute_ca, compute_ov)        \
6755GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x00000000, PPC_INTEGER),
6756#define GEN_INT_ARITH_SUBF_CONST(name, opc3, const_val,                       \
6757                                add_ca, compute_ca, compute_ov)               \
6758GEN_HANDLER(name, 0x1F, 0x08, opc3, 0x0000F800, PPC_INTEGER),
6759GEN_INT_ARITH_SUBF(subf, 0x01, 0, 0, 0)
6760GEN_INT_ARITH_SUBF(subfo, 0x11, 0, 0, 1)
6761GEN_INT_ARITH_SUBF(subfc, 0x00, 0, 1, 0)
6762GEN_INT_ARITH_SUBF(subfco, 0x10, 0, 1, 1)
6763GEN_INT_ARITH_SUBF(subfe, 0x04, 1, 1, 0)
6764GEN_INT_ARITH_SUBF(subfeo, 0x14, 1, 1, 1)
6765GEN_INT_ARITH_SUBF_CONST(subfme, 0x07, -1LL, 1, 1, 0)
6766GEN_INT_ARITH_SUBF_CONST(subfmeo, 0x17, -1LL, 1, 1, 1)
6767GEN_INT_ARITH_SUBF_CONST(subfze, 0x06, 0, 1, 1, 0)
6768GEN_INT_ARITH_SUBF_CONST(subfzeo, 0x16, 0, 1, 1, 1)
6769
6770#undef GEN_LOGICAL1
6771#undef GEN_LOGICAL2
6772#define GEN_LOGICAL2(name, tcg_op, opc, type)                                 \
6773GEN_HANDLER(name, 0x1F, 0x1C, opc, 0x00000000, type)
6774#define GEN_LOGICAL1(name, tcg_op, opc, type)                                 \
6775GEN_HANDLER(name, 0x1F, 0x1A, opc, 0x00000000, type)
6776GEN_LOGICAL2(and, tcg_gen_and_tl, 0x00, PPC_INTEGER),
6777GEN_LOGICAL2(andc, tcg_gen_andc_tl, 0x01, PPC_INTEGER),
6778GEN_LOGICAL2(eqv, tcg_gen_eqv_tl, 0x08, PPC_INTEGER),
6779GEN_LOGICAL1(extsb, tcg_gen_ext8s_tl, 0x1D, PPC_INTEGER),
6780GEN_LOGICAL1(extsh, tcg_gen_ext16s_tl, 0x1C, PPC_INTEGER),
6781GEN_LOGICAL2(nand, tcg_gen_nand_tl, 0x0E, PPC_INTEGER),
6782GEN_LOGICAL2(nor, tcg_gen_nor_tl, 0x03, PPC_INTEGER),
6783GEN_LOGICAL2(orc, tcg_gen_orc_tl, 0x0C, PPC_INTEGER),
6784#if defined(TARGET_PPC64)
6785GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B),
6786#endif
6787
6788#if defined(TARGET_PPC64)
6789#undef GEN_PPC64_R2
6790#undef GEN_PPC64_R4
6791#define GEN_PPC64_R2(name, opc1, opc2)                                        \
6792GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
6793GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
6794             PPC_64B)
6795#define GEN_PPC64_R4(name, opc1, opc2)                                        \
6796GEN_HANDLER2(name##0, stringify(name), opc1, opc2, 0xFF, 0x00000000, PPC_64B),\
6797GEN_HANDLER2(name##1, stringify(name), opc1, opc2 | 0x01, 0xFF, 0x00000000,   \
6798             PPC_64B),                                                        \
6799GEN_HANDLER2(name##2, stringify(name), opc1, opc2 | 0x10, 0xFF, 0x00000000,   \
6800             PPC_64B),                                                        \
6801GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000,   \
6802             PPC_64B)
6803GEN_PPC64_R4(rldicl, 0x1E, 0x00),
6804GEN_PPC64_R4(rldicr, 0x1E, 0x02),
6805GEN_PPC64_R4(rldic, 0x1E, 0x04),
6806GEN_PPC64_R2(rldcl, 0x1E, 0x08),
6807GEN_PPC64_R2(rldcr, 0x1E, 0x09),
6808GEN_PPC64_R4(rldimi, 0x1E, 0x06),
6809#endif
6810
6811#undef GEN_LD
6812#undef GEN_LDU
6813#undef GEN_LDUX
6814#undef GEN_LDX_E
6815#undef GEN_LDS
6816#define GEN_LD(name, ldop, opc, type)                                         \
6817GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
6818#define GEN_LDU(name, ldop, opc, type)                                        \
6819GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
6820#define GEN_LDUX(name, ldop, opc2, opc3, type)                                \
6821GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
6822#define GEN_LDX_E(name, ldop, opc2, opc3, type, type2, chk)                   \
6823GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
6824#define GEN_LDS(name, ldop, op, type)                                         \
6825GEN_LD(name, ldop, op | 0x20, type)                                           \
6826GEN_LDU(name, ldop, op | 0x21, type)                                          \
6827GEN_LDUX(name, ldop, 0x17, op | 0x01, type)                                   \
6828GEN_LDX(name, ldop, 0x17, op | 0x00, type)
6829
6830GEN_LDS(lbz, ld8u, 0x02, PPC_INTEGER)
6831GEN_LDS(lha, ld16s, 0x0A, PPC_INTEGER)
6832GEN_LDS(lhz, ld16u, 0x08, PPC_INTEGER)
6833GEN_LDS(lwz, ld32u, 0x00, PPC_INTEGER)
6834#if defined(TARGET_PPC64)
6835GEN_LDUX(lwa, ld32s, 0x15, 0x0B, PPC_64B)
6836GEN_LDX(lwa, ld32s, 0x15, 0x0A, PPC_64B)
6837GEN_LDUX(ld, ld64_i64, 0x15, 0x01, PPC_64B)
6838GEN_LDX(ld, ld64_i64, 0x15, 0x00, PPC_64B)
6839GEN_LDX_E(ldbr, ld64ur_i64, 0x14, 0x10, PPC_NONE, PPC2_DBRX, CHK_NONE)
6840
6841/* HV/P7 and later only */
6842GEN_LDX_HVRM(ldcix, ld64_i64, 0x15, 0x1b, PPC_CILDST)
6843GEN_LDX_HVRM(lwzcix, ld32u, 0x15, 0x18, PPC_CILDST)
6844GEN_LDX_HVRM(lhzcix, ld16u, 0x15, 0x19, PPC_CILDST)
6845GEN_LDX_HVRM(lbzcix, ld8u, 0x15, 0x1a, PPC_CILDST)
6846#endif
6847GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER)
6848GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER)
6849
6850#undef GEN_ST
6851#undef GEN_STU
6852#undef GEN_STUX
6853#undef GEN_STX_E
6854#undef GEN_STS
6855#define GEN_ST(name, stop, opc, type)                                         \
6856GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
6857#define GEN_STU(name, stop, opc, type)                                        \
6858GEN_HANDLER(stop##u, opc, 0xFF, 0xFF, 0x00000000, type),
6859#define GEN_STUX(name, stop, opc2, opc3, type)                                \
6860GEN_HANDLER(name##ux, 0x1F, opc2, opc3, 0x00000001, type),
6861#define GEN_STX_E(name, stop, opc2, opc3, type, type2, chk)                   \
6862GEN_HANDLER_E(name##x, 0x1F, opc2, opc3, 0x00000001, type, type2),
6863#define GEN_STS(name, stop, op, type)                                         \
6864GEN_ST(name, stop, op | 0x20, type)                                           \
6865GEN_STU(name, stop, op | 0x21, type)                                          \
6866GEN_STUX(name, stop, 0x17, op | 0x01, type)                                   \
6867GEN_STX(name, stop, 0x17, op | 0x00, type)
6868
6869GEN_STS(stb, st8, 0x06, PPC_INTEGER)
6870GEN_STS(sth, st16, 0x0C, PPC_INTEGER)
6871GEN_STS(stw, st32, 0x04, PPC_INTEGER)
6872#if defined(TARGET_PPC64)
6873GEN_STUX(std, st64_i64, 0x15, 0x05, PPC_64B)
6874GEN_STX(std, st64_i64, 0x15, 0x04, PPC_64B)
6875GEN_STX_E(stdbr, st64r_i64, 0x14, 0x14, PPC_NONE, PPC2_DBRX, CHK_NONE)
6876GEN_STX_HVRM(stdcix, st64_i64, 0x15, 0x1f, PPC_CILDST)
6877GEN_STX_HVRM(stwcix, st32, 0x15, 0x1c, PPC_CILDST)
6878GEN_STX_HVRM(sthcix, st16, 0x15, 0x1d, PPC_CILDST)
6879GEN_STX_HVRM(stbcix, st8, 0x15, 0x1e, PPC_CILDST)
6880#endif
6881GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER)
6882GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER)
6883
6884#undef GEN_CRLOGIC
6885#define GEN_CRLOGIC(name, tcg_op, opc)                                        \
6886GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)
6887GEN_CRLOGIC(crand, tcg_gen_and_i32, 0x08),
6888GEN_CRLOGIC(crandc, tcg_gen_andc_i32, 0x04),
6889GEN_CRLOGIC(creqv, tcg_gen_eqv_i32, 0x09),
6890GEN_CRLOGIC(crnand, tcg_gen_nand_i32, 0x07),
6891GEN_CRLOGIC(crnor, tcg_gen_nor_i32, 0x01),
6892GEN_CRLOGIC(cror, tcg_gen_or_i32, 0x0E),
6893GEN_CRLOGIC(crorc, tcg_gen_orc_i32, 0x0D),
6894GEN_CRLOGIC(crxor, tcg_gen_xor_i32, 0x06),
6895
6896#undef GEN_MAC_HANDLER
6897#define GEN_MAC_HANDLER(name, opc2, opc3)                                     \
6898GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_405_MAC)
6899GEN_MAC_HANDLER(macchw, 0x0C, 0x05),
6900GEN_MAC_HANDLER(macchwo, 0x0C, 0x15),
6901GEN_MAC_HANDLER(macchws, 0x0C, 0x07),
6902GEN_MAC_HANDLER(macchwso, 0x0C, 0x17),
6903GEN_MAC_HANDLER(macchwsu, 0x0C, 0x06),
6904GEN_MAC_HANDLER(macchwsuo, 0x0C, 0x16),
6905GEN_MAC_HANDLER(macchwu, 0x0C, 0x04),
6906GEN_MAC_HANDLER(macchwuo, 0x0C, 0x14),
6907GEN_MAC_HANDLER(machhw, 0x0C, 0x01),
6908GEN_MAC_HANDLER(machhwo, 0x0C, 0x11),
6909GEN_MAC_HANDLER(machhws, 0x0C, 0x03),
6910GEN_MAC_HANDLER(machhwso, 0x0C, 0x13),
6911GEN_MAC_HANDLER(machhwsu, 0x0C, 0x02),
6912GEN_MAC_HANDLER(machhwsuo, 0x0C, 0x12),
6913GEN_MAC_HANDLER(machhwu, 0x0C, 0x00),
6914GEN_MAC_HANDLER(machhwuo, 0x0C, 0x10),
6915GEN_MAC_HANDLER(maclhw, 0x0C, 0x0D),
6916GEN_MAC_HANDLER(maclhwo, 0x0C, 0x1D),
6917GEN_MAC_HANDLER(maclhws, 0x0C, 0x0F),
6918GEN_MAC_HANDLER(maclhwso, 0x0C, 0x1F),
6919GEN_MAC_HANDLER(maclhwu, 0x0C, 0x0C),
6920GEN_MAC_HANDLER(maclhwuo, 0x0C, 0x1C),
6921GEN_MAC_HANDLER(maclhwsu, 0x0C, 0x0E),
6922GEN_MAC_HANDLER(maclhwsuo, 0x0C, 0x1E),
6923GEN_MAC_HANDLER(nmacchw, 0x0E, 0x05),
6924GEN_MAC_HANDLER(nmacchwo, 0x0E, 0x15),
6925GEN_MAC_HANDLER(nmacchws, 0x0E, 0x07),
6926GEN_MAC_HANDLER(nmacchwso, 0x0E, 0x17),
6927GEN_MAC_HANDLER(nmachhw, 0x0E, 0x01),
6928GEN_MAC_HANDLER(nmachhwo, 0x0E, 0x11),
6929GEN_MAC_HANDLER(nmachhws, 0x0E, 0x03),
6930GEN_MAC_HANDLER(nmachhwso, 0x0E, 0x13),
6931GEN_MAC_HANDLER(nmaclhw, 0x0E, 0x0D),
6932GEN_MAC_HANDLER(nmaclhwo, 0x0E, 0x1D),
6933GEN_MAC_HANDLER(nmaclhws, 0x0E, 0x0F),
6934GEN_MAC_HANDLER(nmaclhwso, 0x0E, 0x1F),
6935GEN_MAC_HANDLER(mulchw, 0x08, 0x05),
6936GEN_MAC_HANDLER(mulchwu, 0x08, 0x04),
6937GEN_MAC_HANDLER(mulhhw, 0x08, 0x01),
6938GEN_MAC_HANDLER(mulhhwu, 0x08, 0x00),
6939GEN_MAC_HANDLER(mullhw, 0x08, 0x0D),
6940GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C),
6941
6942GEN_HANDLER2_E(tbegin, "tbegin", 0x1F, 0x0E, 0x14, 0x01DFF800, \
6943               PPC_NONE, PPC2_TM),
6944GEN_HANDLER2_E(tend,   "tend",   0x1F, 0x0E, 0x15, 0x01FFF800, \
6945               PPC_NONE, PPC2_TM),
6946GEN_HANDLER2_E(tabort, "tabort", 0x1F, 0x0E, 0x1C, 0x03E0F800, \
6947               PPC_NONE, PPC2_TM),
6948GEN_HANDLER2_E(tabortwc, "tabortwc", 0x1F, 0x0E, 0x18, 0x00000000, \
6949               PPC_NONE, PPC2_TM),
6950GEN_HANDLER2_E(tabortwci, "tabortwci", 0x1F, 0x0E, 0x1A, 0x00000000, \
6951               PPC_NONE, PPC2_TM),
6952GEN_HANDLER2_E(tabortdc, "tabortdc", 0x1F, 0x0E, 0x19, 0x00000000, \
6953               PPC_NONE, PPC2_TM),
6954GEN_HANDLER2_E(tabortdci, "tabortdci", 0x1F, 0x0E, 0x1B, 0x00000000, \
6955               PPC_NONE, PPC2_TM),
6956GEN_HANDLER2_E(tsr, "tsr", 0x1F, 0x0E, 0x17, 0x03DFF800, \
6957               PPC_NONE, PPC2_TM),
6958GEN_HANDLER2_E(tcheck, "tcheck", 0x1F, 0x0E, 0x16, 0x007FF800, \
6959               PPC_NONE, PPC2_TM),
6960GEN_HANDLER2_E(treclaim, "treclaim", 0x1F, 0x0E, 0x1D, 0x03E0F800, \
6961               PPC_NONE, PPC2_TM),
6962GEN_HANDLER2_E(trechkpt, "trechkpt", 0x1F, 0x0E, 0x1F, 0x03FFF800, \
6963               PPC_NONE, PPC2_TM),
6964
6965#include "translate/fp-ops.inc.c"
6966
6967#include "translate/vmx-ops.inc.c"
6968
6969#include "translate/vsx-ops.inc.c"
6970
6971#include "translate/dfp-ops.inc.c"
6972
6973#include "translate/spe-ops.inc.c"
6974};
6975
6976#include "helper_regs.h"
6977#include "translate_init.c"
6978
6979/*****************************************************************************/
6980/* Misc PowerPC helpers */
6981void ppc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
6982                        int flags)
6983{
6984#define RGPL  4
6985#define RFPL  4
6986
6987    PowerPCCPU *cpu = POWERPC_CPU(cs);
6988    CPUPPCState *env = &cpu->env;
6989    int i;
6990
6991    cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
6992                TARGET_FMT_lx " XER " TARGET_FMT_lx " CPU#%d\n",
6993                env->nip, env->lr, env->ctr, cpu_read_xer(env),
6994                cs->cpu_index);
6995    cpu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx "  HF "
6996                TARGET_FMT_lx " iidx %d didx %d\n",
6997                env->msr, env->spr[SPR_HID0],
6998                env->hflags, env->immu_idx, env->dmmu_idx);
6999#if !defined(NO_TIMER_DUMP)
7000    cpu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
7001#if !defined(CONFIG_USER_ONLY)
7002                " DECR %08" PRIu32
7003#endif
7004                "\n",
7005                cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
7006#if !defined(CONFIG_USER_ONLY)
7007                , cpu_ppc_load_decr(env)
7008#endif
7009                );
7010#endif
7011    for (i = 0; i < 32; i++) {
7012        if ((i & (RGPL - 1)) == 0)
7013            cpu_fprintf(f, "GPR%02d", i);
7014        cpu_fprintf(f, " %016" PRIx64, ppc_dump_gpr(env, i));
7015        if ((i & (RGPL - 1)) == (RGPL - 1))
7016            cpu_fprintf(f, "\n");
7017    }
7018    cpu_fprintf(f, "CR ");
7019    for (i = 0; i < 8; i++)
7020        cpu_fprintf(f, "%01x", env->crf[i]);
7021    cpu_fprintf(f, "  [");
7022    for (i = 0; i < 8; i++) {
7023        char a = '-';
7024        if (env->crf[i] & 0x08)
7025            a = 'L';
7026        else if (env->crf[i] & 0x04)
7027            a = 'G';
7028        else if (env->crf[i] & 0x02)
7029            a = 'E';
7030        cpu_fprintf(f, " %c%c", a, env->crf[i] & 0x01 ? 'O' : ' ');
7031    }
7032    cpu_fprintf(f, " ]             RES " TARGET_FMT_lx "\n",
7033                env->reserve_addr);
7034    for (i = 0; i < 32; i++) {
7035        if ((i & (RFPL - 1)) == 0)
7036            cpu_fprintf(f, "FPR%02d", i);
7037        cpu_fprintf(f, " %016" PRIx64, *((uint64_t *)&env->fpr[i]));
7038        if ((i & (RFPL - 1)) == (RFPL - 1))
7039            cpu_fprintf(f, "\n");
7040    }
7041    cpu_fprintf(f, "FPSCR " TARGET_FMT_lx "\n", env->fpscr);
7042#if !defined(CONFIG_USER_ONLY)
7043    cpu_fprintf(f, " SRR0 " TARGET_FMT_lx "  SRR1 " TARGET_FMT_lx
7044                   "    PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n",
7045                env->spr[SPR_SRR0], env->spr[SPR_SRR1],
7046                env->spr[SPR_PVR], env->spr[SPR_VRSAVE]);
7047
7048    cpu_fprintf(f, "SPRG0 " TARGET_FMT_lx " SPRG1 " TARGET_FMT_lx
7049                   "  SPRG2 " TARGET_FMT_lx "  SPRG3 " TARGET_FMT_lx "\n",
7050                env->spr[SPR_SPRG0], env->spr[SPR_SPRG1],
7051                env->spr[SPR_SPRG2], env->spr[SPR_SPRG3]);
7052
7053    cpu_fprintf(f, "SPRG4 " TARGET_FMT_lx " SPRG5 " TARGET_FMT_lx
7054                   "  SPRG6 " TARGET_FMT_lx "  SPRG7 " TARGET_FMT_lx "\n",
7055                env->spr[SPR_SPRG4], env->spr[SPR_SPRG5],
7056                env->spr[SPR_SPRG6], env->spr[SPR_SPRG7]);
7057
7058#if defined(TARGET_PPC64)
7059    if (env->excp_model == POWERPC_EXCP_POWER7 ||
7060        env->excp_model == POWERPC_EXCP_POWER8) {
7061        cpu_fprintf(f, "HSRR0 " TARGET_FMT_lx " HSRR1 " TARGET_FMT_lx "\n",
7062                    env->spr[SPR_HSRR0], env->spr[SPR_HSRR1]);
7063    }
7064#endif
7065    if (env->excp_model == POWERPC_EXCP_BOOKE) {
7066        cpu_fprintf(f, "CSRR0 " TARGET_FMT_lx " CSRR1 " TARGET_FMT_lx
7067                       " MCSRR0 " TARGET_FMT_lx " MCSRR1 " TARGET_FMT_lx "\n",
7068                    env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1],
7069                    env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1]);
7070
7071        cpu_fprintf(f, "  TCR " TARGET_FMT_lx "   TSR " TARGET_FMT_lx
7072                       "    ESR " TARGET_FMT_lx "   DEAR " TARGET_FMT_lx "\n",
7073                    env->spr[SPR_BOOKE_TCR], env->spr[SPR_BOOKE_TSR],
7074                    env->spr[SPR_BOOKE_ESR], env->spr[SPR_BOOKE_DEAR]);
7075
7076        cpu_fprintf(f, "  PIR " TARGET_FMT_lx " DECAR " TARGET_FMT_lx
7077                       "   IVPR " TARGET_FMT_lx "   EPCR " TARGET_FMT_lx "\n",
7078                    env->spr[SPR_BOOKE_PIR], env->spr[SPR_BOOKE_DECAR],
7079                    env->spr[SPR_BOOKE_IVPR], env->spr[SPR_BOOKE_EPCR]);
7080
7081        cpu_fprintf(f, " MCSR " TARGET_FMT_lx " SPRG8 " TARGET_FMT_lx
7082                       "    EPR " TARGET_FMT_lx "\n",
7083                    env->spr[SPR_BOOKE_MCSR], env->spr[SPR_BOOKE_SPRG8],
7084                    env->spr[SPR_BOOKE_EPR]);
7085
7086        /* FSL-specific */
7087        cpu_fprintf(f, " MCAR " TARGET_FMT_lx "  PID1 " TARGET_FMT_lx
7088                       "   PID2 " TARGET_FMT_lx "    SVR " TARGET_FMT_lx "\n",
7089                    env->spr[SPR_Exxx_MCAR], env->spr[SPR_BOOKE_PID1],
7090                    env->spr[SPR_BOOKE_PID2], env->spr[SPR_E500_SVR]);
7091
7092        /*
7093         * IVORs are left out as they are large and do not change often --
7094         * they can be read with "p $ivor0", "p $ivor1", etc.
7095         */
7096    }
7097
7098#if defined(TARGET_PPC64)
7099    if (env->flags & POWERPC_FLAG_CFAR) {
7100        cpu_fprintf(f, " CFAR " TARGET_FMT_lx"\n", env->cfar);
7101    }
7102#endif
7103
7104    if (env->spr_cb[SPR_LPCR].name)
7105        cpu_fprintf(f, " LPCR " TARGET_FMT_lx "\n", env->spr[SPR_LPCR]);
7106
7107    switch (POWERPC_MMU_VER(env->mmu_model)) {
7108    case POWERPC_MMU_32B:
7109    case POWERPC_MMU_601:
7110    case POWERPC_MMU_SOFT_6xx:
7111    case POWERPC_MMU_SOFT_74xx:
7112#if defined(TARGET_PPC64)
7113    case POWERPC_MMU_VER_64B:
7114    case POWERPC_MMU_VER_2_03:
7115    case POWERPC_MMU_VER_2_06:
7116    case POWERPC_MMU_VER_2_07:
7117    case POWERPC_MMU_VER_3_00:
7118#endif
7119        if (env->spr_cb[SPR_SDR1].name) { /* SDR1 Exists */
7120            cpu_fprintf(f, " SDR1 " TARGET_FMT_lx " ", env->spr[SPR_SDR1]);
7121        }
7122        cpu_fprintf(f, "  DAR " TARGET_FMT_lx "  DSISR " TARGET_FMT_lx "\n",
7123                    env->spr[SPR_DAR], env->spr[SPR_DSISR]);
7124        break;
7125    case POWERPC_MMU_BOOKE206:
7126        cpu_fprintf(f, " MAS0 " TARGET_FMT_lx "  MAS1 " TARGET_FMT_lx
7127                       "   MAS2 " TARGET_FMT_lx "   MAS3 " TARGET_FMT_lx "\n",
7128                    env->spr[SPR_BOOKE_MAS0], env->spr[SPR_BOOKE_MAS1],
7129                    env->spr[SPR_BOOKE_MAS2], env->spr[SPR_BOOKE_MAS3]);
7130
7131        cpu_fprintf(f, " MAS4 " TARGET_FMT_lx "  MAS6 " TARGET_FMT_lx
7132                       "   MAS7 " TARGET_FMT_lx "    PID " TARGET_FMT_lx "\n",
7133                    env->spr[SPR_BOOKE_MAS4], env->spr[SPR_BOOKE_MAS6],
7134                    env->spr[SPR_BOOKE_MAS7], env->spr[SPR_BOOKE_PID]);
7135
7136        cpu_fprintf(f, "MMUCFG " TARGET_FMT_lx " TLB0CFG " TARGET_FMT_lx
7137                       " TLB1CFG " TARGET_FMT_lx "\n",
7138                    env->spr[SPR_MMUCFG], env->spr[SPR_BOOKE_TLB0CFG],
7139                    env->spr[SPR_BOOKE_TLB1CFG]);
7140        break;
7141    default:
7142        break;
7143    }
7144#endif
7145
7146#undef RGPL
7147#undef RFPL
7148}
7149
7150void ppc_cpu_dump_statistics(CPUState *cs, FILE*f,
7151                             fprintf_function cpu_fprintf, int flags)
7152{
7153#if defined(DO_PPC_STATISTICS)
7154    PowerPCCPU *cpu = POWERPC_CPU(cs);
7155    opc_handler_t **t1, **t2, **t3, *handler;
7156    int op1, op2, op3;
7157
7158    t1 = cpu->env.opcodes;
7159    for (op1 = 0; op1 < 64; op1++) {
7160        handler = t1[op1];
7161        if (is_indirect_opcode(handler)) {
7162            t2 = ind_table(handler);
7163            for (op2 = 0; op2 < 32; op2++) {
7164                handler = t2[op2];
7165                if (is_indirect_opcode(handler)) {
7166                    t3 = ind_table(handler);
7167                    for (op3 = 0; op3 < 32; op3++) {
7168                        handler = t3[op3];
7169                        if (handler->count == 0)
7170                            continue;
7171                        cpu_fprintf(f, "%02x %02x %02x (%02x %04d) %16s: "
7172                                    "%016" PRIx64 " %" PRId64 "\n",
7173                                    op1, op2, op3, op1, (op3 << 5) | op2,
7174                                    handler->oname,
7175                                    handler->count, handler->count);
7176                    }
7177                } else {
7178                    if (handler->count == 0)
7179                        continue;
7180                    cpu_fprintf(f, "%02x %02x    (%02x %04d) %16s: "
7181                                "%016" PRIx64 " %" PRId64 "\n",
7182                                op1, op2, op1, op2, handler->oname,
7183                                handler->count, handler->count);
7184                }
7185            }
7186        } else {
7187            if (handler->count == 0)
7188                continue;
7189            cpu_fprintf(f, "%02x       (%02x     ) %16s: %016" PRIx64
7190                        " %" PRId64 "\n",
7191                        op1, op1, handler->oname,
7192                        handler->count, handler->count);
7193        }
7194    }
7195#endif
7196}
7197
7198/*****************************************************************************/
7199void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
7200{
7201    CPUPPCState *env = cs->env_ptr;
7202    DisasContext ctx, *ctxp = &ctx;
7203    opc_handler_t **table, *handler;
7204    target_ulong pc_start;
7205    int num_insns;
7206    int max_insns;
7207
7208    pc_start = tb->pc;
7209    ctx.nip = pc_start;
7210    ctx.tb = tb;
7211    ctx.exception = POWERPC_EXCP_NONE;
7212    ctx.spr_cb = env->spr_cb;
7213    ctx.pr = msr_pr;
7214    ctx.mem_idx = env->dmmu_idx;
7215    ctx.dr = msr_dr;
7216#if !defined(CONFIG_USER_ONLY)
7217    ctx.hv = msr_hv || !env->has_hv_mode;
7218#endif
7219    ctx.insns_flags = env->insns_flags;
7220    ctx.insns_flags2 = env->insns_flags2;
7221    ctx.access_type = -1;
7222    ctx.need_access_type = !(env->mmu_model & POWERPC_MMU_64B);
7223    ctx.le_mode = !!(env->hflags & (1 << MSR_LE));
7224    ctx.default_tcg_memop_mask = ctx.le_mode ? MO_LE : MO_BE;
7225#if defined(TARGET_PPC64)
7226    ctx.sf_mode = msr_is_64bit(env, env->msr);
7227    ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
7228#endif
7229    if (env->mmu_model == POWERPC_MMU_32B ||
7230        env->mmu_model == POWERPC_MMU_601 ||
7231        (env->mmu_model & POWERPC_MMU_64B))
7232            ctx.lazy_tlb_flush = true;
7233
7234    ctx.fpu_enabled = !!msr_fp;
7235    if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
7236        ctx.spe_enabled = !!msr_spe;
7237    else
7238        ctx.spe_enabled = false;
7239    if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
7240        ctx.altivec_enabled = !!msr_vr;
7241    else
7242        ctx.altivec_enabled = false;
7243    if ((env->flags & POWERPC_FLAG_VSX) && msr_vsx) {
7244        ctx.vsx_enabled = !!msr_vsx;
7245    } else {
7246        ctx.vsx_enabled = false;
7247    }
7248#if defined(TARGET_PPC64)
7249    if ((env->flags & POWERPC_FLAG_TM) && msr_tm) {
7250        ctx.tm_enabled = !!msr_tm;
7251    } else {
7252        ctx.tm_enabled = false;
7253    }
7254#endif
7255    ctx.gtse = !!(env->spr[SPR_LPCR] & LPCR_GTSE);
7256    if ((env->flags & POWERPC_FLAG_SE) && msr_se)
7257        ctx.singlestep_enabled = CPU_SINGLE_STEP;
7258    else
7259        ctx.singlestep_enabled = 0;
7260    if ((env->flags & POWERPC_FLAG_BE) && msr_be)
7261        ctx.singlestep_enabled |= CPU_BRANCH_STEP;
7262    if (unlikely(cs->singlestep_enabled)) {
7263        ctx.singlestep_enabled |= GDBSTUB_SINGLE_STEP;
7264    }
7265#if defined (DO_SINGLE_STEP) && 0
7266    /* Single step trace mode */
7267    msr_se = 1;
7268#endif
7269    num_insns = 0;
7270    max_insns = tb->cflags & CF_COUNT_MASK;
7271    if (max_insns == 0) {
7272        max_insns = CF_COUNT_MASK;
7273    }
7274    if (max_insns > TCG_MAX_INSNS) {
7275        max_insns = TCG_MAX_INSNS;
7276    }
7277
7278    gen_tb_start(tb);
7279    tcg_clear_temp_count();
7280    /* Set env in case of segfault during code fetch */
7281    while (ctx.exception == POWERPC_EXCP_NONE && !tcg_op_buf_full()) {
7282        tcg_gen_insn_start(ctx.nip);
7283        num_insns++;
7284
7285        if (unlikely(cpu_breakpoint_test(cs, ctx.nip, BP_ANY))) {
7286            gen_debug_exception(ctxp);
7287            /* The address covered by the breakpoint must be included in
7288               [tb->pc, tb->pc + tb->size) in order to for it to be
7289               properly cleared -- thus we increment the PC here so that
7290               the logic setting tb->size below does the right thing.  */
7291            ctx.nip += 4;
7292            break;
7293        }
7294
7295        LOG_DISAS("----------------\n");
7296        LOG_DISAS("nip=" TARGET_FMT_lx " super=%d ir=%d\n",
7297                  ctx.nip, ctx.mem_idx, (int)msr_ir);
7298        if (num_insns == max_insns && (tb->cflags & CF_LAST_IO))
7299            gen_io_start();
7300        if (unlikely(need_byteswap(&ctx))) {
7301            ctx.opcode = bswap32(cpu_ldl_code(env, ctx.nip));
7302        } else {
7303            ctx.opcode = cpu_ldl_code(env, ctx.nip);
7304        }
7305        LOG_DISAS("translate opcode %08x (%02x %02x %02x %02x) (%s)\n",
7306                  ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
7307                  opc3(ctx.opcode), opc4(ctx.opcode),
7308                  ctx.le_mode ? "little" : "big");
7309        ctx.nip += 4;
7310        table = env->opcodes;
7311        handler = table[opc1(ctx.opcode)];
7312        if (is_indirect_opcode(handler)) {
7313            table = ind_table(handler);
7314            handler = table[opc2(ctx.opcode)];
7315            if (is_indirect_opcode(handler)) {
7316                table = ind_table(handler);
7317                handler = table[opc3(ctx.opcode)];
7318                if (is_indirect_opcode(handler)) {
7319                    table = ind_table(handler);
7320                    handler = table[opc4(ctx.opcode)];
7321                }
7322            }
7323        }
7324        /* Is opcode *REALLY* valid ? */
7325        if (unlikely(handler->handler == &gen_invalid)) {
7326            qemu_log_mask(LOG_GUEST_ERROR, "invalid/unsupported opcode: "
7327                          "%02x - %02x - %02x - %02x (%08x) "
7328                          TARGET_FMT_lx " %d\n",
7329                          opc1(ctx.opcode), opc2(ctx.opcode),
7330                          opc3(ctx.opcode), opc4(ctx.opcode),
7331                          ctx.opcode, ctx.nip - 4, (int)msr_ir);
7332        } else {
7333            uint32_t inval;
7334
7335            if (unlikely(handler->type & (PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE) && Rc(ctx.opcode))) {
7336                inval = handler->inval2;
7337            } else {
7338                inval = handler->inval1;
7339            }
7340
7341            if (unlikely((ctx.opcode & inval) != 0)) {
7342                qemu_log_mask(LOG_GUEST_ERROR, "invalid bits: %08x for opcode: "
7343                              "%02x - %02x - %02x - %02x (%08x) "
7344                              TARGET_FMT_lx "\n", ctx.opcode & inval,
7345                              opc1(ctx.opcode), opc2(ctx.opcode),
7346                              opc3(ctx.opcode), opc4(ctx.opcode),
7347                              ctx.opcode, ctx.nip - 4);
7348                gen_inval_exception(ctxp, POWERPC_EXCP_INVAL_INVAL);
7349                break;
7350            }
7351        }
7352        (*(handler->handler))(&ctx);
7353#if defined(DO_PPC_STATISTICS)
7354        handler->count++;
7355#endif
7356        /* Check trace mode exceptions */
7357        if (unlikely(ctx.singlestep_enabled & CPU_SINGLE_STEP &&
7358                     (ctx.nip <= 0x100 || ctx.nip > 0xF00) &&
7359                     ctx.exception != POWERPC_SYSCALL &&
7360                     ctx.exception != POWERPC_EXCP_TRAP &&
7361                     ctx.exception != POWERPC_EXCP_BRANCH)) {
7362            gen_exception_nip(ctxp, POWERPC_EXCP_TRACE, ctx.nip);
7363        } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
7364                            (cs->singlestep_enabled) ||
7365                            singlestep ||
7366                            num_insns >= max_insns)) {
7367            /* if we reach a page boundary or are single stepping, stop
7368             * generation
7369             */
7370            break;
7371        }
7372        if (tcg_check_temp_count()) {
7373            fprintf(stderr, "Opcode %02x %02x %02x %02x (%08x) leaked "
7374                    "temporaries\n", opc1(ctx.opcode), opc2(ctx.opcode),
7375                    opc3(ctx.opcode), opc4(ctx.opcode), ctx.opcode);
7376            exit(1);
7377        }
7378    }
7379    if (tb->cflags & CF_LAST_IO)
7380        gen_io_end();
7381    if (ctx.exception == POWERPC_EXCP_NONE) {
7382        gen_goto_tb(&ctx, 0, ctx.nip);
7383    } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
7384        if (unlikely(cs->singlestep_enabled)) {
7385            gen_debug_exception(ctxp);
7386        }
7387        /* Generate the return instruction */
7388        tcg_gen_exit_tb(0);
7389    }
7390    gen_tb_end(tb, num_insns);
7391
7392    tb->size = ctx.nip - pc_start;
7393    tb->icount = num_insns;
7394
7395#if defined(DEBUG_DISAS)
7396    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
7397        && qemu_log_in_addr_range(pc_start)) {
7398        int flags;
7399        flags = env->bfd_mach;
7400        flags |= ctx.le_mode << 16;
7401        qemu_log_lock();
7402        qemu_log("IN: %s\n", lookup_symbol(pc_start));
7403        log_target_disas(cs, pc_start, ctx.nip - pc_start, flags);
7404        qemu_log("\n");
7405        qemu_log_unlock();
7406    }
7407#endif
7408}
7409
7410void restore_state_to_opc(CPUPPCState *env, TranslationBlock *tb,
7411                          target_ulong *data)
7412{
7413    env->nip = data[0];
7414}
7415