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