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