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