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