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