qemu/target/alpha/translate.c
<<
>>
Prefs
   1/*
   2 *  Alpha emulation cpu translation for qemu.
   3 *
   4 *  Copyright (c) 2007 Jocelyn Mayer
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include "qemu/osdep.h"
  21#include "cpu.h"
  22#include "sysemu/cpus.h"
  23#include "disas/disas.h"
  24#include "qemu/host-utils.h"
  25#include "exec/exec-all.h"
  26#include "tcg-op.h"
  27#include "exec/cpu_ldst.h"
  28#include "exec/helper-proto.h"
  29#include "exec/helper-gen.h"
  30#include "trace-tcg.h"
  31#include "exec/translator.h"
  32#include "exec/log.h"
  33
  34
  35#undef ALPHA_DEBUG_DISAS
  36#define CONFIG_SOFTFLOAT_INLINE
  37
  38#ifdef ALPHA_DEBUG_DISAS
  39#  define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
  40#else
  41#  define LOG_DISAS(...) do { } while (0)
  42#endif
  43
  44typedef struct DisasContext DisasContext;
  45struct DisasContext {
  46    DisasContextBase base;
  47
  48#ifndef CONFIG_USER_ONLY
  49    uint64_t palbr;
  50#endif
  51    uint32_t tbflags;
  52    int mem_idx;
  53
  54    /* implver and amask values for this CPU.  */
  55    int implver;
  56    int amask;
  57
  58    /* Current rounding mode for this TB.  */
  59    int tb_rm;
  60    /* Current flush-to-zero setting for this TB.  */
  61    int tb_ftz;
  62
  63    /* The set of registers active in the current context.  */
  64    TCGv *ir;
  65
  66    /* Temporaries for $31 and $f31 as source and destination.  */
  67    TCGv zero;
  68    TCGv sink;
  69    /* Temporary for immediate constants.  */
  70    TCGv lit;
  71};
  72
  73/* Target-specific return values from translate_one, indicating the
  74   state of the TB.  Note that DISAS_NEXT indicates that we are not
  75   exiting the TB.  */
  76#define DISAS_PC_UPDATED_NOCHAIN  DISAS_TARGET_0
  77#define DISAS_PC_UPDATED          DISAS_TARGET_1
  78#define DISAS_PC_STALE            DISAS_TARGET_2
  79
  80/* global register indexes */
  81static TCGv cpu_std_ir[31];
  82static TCGv cpu_fir[31];
  83static TCGv cpu_pc;
  84static TCGv cpu_lock_addr;
  85static TCGv cpu_lock_value;
  86
  87#ifndef CONFIG_USER_ONLY
  88static TCGv cpu_pal_ir[31];
  89#endif
  90
  91#include "exec/gen-icount.h"
  92
  93void alpha_translate_init(void)
  94{
  95#define DEF_VAR(V)  { &cpu_##V, #V, offsetof(CPUAlphaState, V) }
  96
  97    typedef struct { TCGv *var; const char *name; int ofs; } GlobalVar;
  98    static const GlobalVar vars[] = {
  99        DEF_VAR(pc),
 100        DEF_VAR(lock_addr),
 101        DEF_VAR(lock_value),
 102    };
 103
 104#undef DEF_VAR
 105
 106    /* Use the symbolic register names that match the disassembler.  */
 107    static const char greg_names[31][4] = {
 108        "v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
 109        "t7", "s0", "s1", "s2", "s3", "s4", "s5", "fp",
 110        "a0", "a1", "a2", "a3", "a4", "a5", "t8", "t9",
 111        "t10", "t11", "ra", "t12", "at", "gp", "sp"
 112    };
 113    static const char freg_names[31][4] = {
 114        "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
 115        "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
 116        "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
 117        "f24", "f25", "f26", "f27", "f28", "f29", "f30"
 118    };
 119#ifndef CONFIG_USER_ONLY
 120    static const char shadow_names[8][8] = {
 121        "pal_t7", "pal_s0", "pal_s1", "pal_s2",
 122        "pal_s3", "pal_s4", "pal_s5", "pal_t11"
 123    };
 124#endif
 125
 126    int i;
 127
 128    for (i = 0; i < 31; i++) {
 129        cpu_std_ir[i] = tcg_global_mem_new_i64(cpu_env,
 130                                               offsetof(CPUAlphaState, ir[i]),
 131                                               greg_names[i]);
 132    }
 133
 134    for (i = 0; i < 31; i++) {
 135        cpu_fir[i] = tcg_global_mem_new_i64(cpu_env,
 136                                            offsetof(CPUAlphaState, fir[i]),
 137                                            freg_names[i]);
 138    }
 139
 140#ifndef CONFIG_USER_ONLY
 141    memcpy(cpu_pal_ir, cpu_std_ir, sizeof(cpu_pal_ir));
 142    for (i = 0; i < 8; i++) {
 143        int r = (i == 7 ? 25 : i + 8);
 144        cpu_pal_ir[r] = tcg_global_mem_new_i64(cpu_env,
 145                                               offsetof(CPUAlphaState,
 146                                                        shadow[i]),
 147                                               shadow_names[i]);
 148    }
 149#endif
 150
 151    for (i = 0; i < ARRAY_SIZE(vars); ++i) {
 152        const GlobalVar *v = &vars[i];
 153        *v->var = tcg_global_mem_new_i64(cpu_env, v->ofs, v->name);
 154    }
 155}
 156
 157static TCGv load_zero(DisasContext *ctx)
 158{
 159    if (!ctx->zero) {
 160        ctx->zero = tcg_const_i64(0);
 161    }
 162    return ctx->zero;
 163}
 164
 165static TCGv dest_sink(DisasContext *ctx)
 166{
 167    if (!ctx->sink) {
 168        ctx->sink = tcg_temp_new();
 169    }
 170    return ctx->sink;
 171}
 172
 173static void free_context_temps(DisasContext *ctx)
 174{
 175    if (ctx->sink) {
 176        tcg_gen_discard_i64(ctx->sink);
 177        tcg_temp_free(ctx->sink);
 178        ctx->sink = NULL;
 179    }
 180    if (ctx->zero) {
 181        tcg_temp_free(ctx->zero);
 182        ctx->zero = NULL;
 183    }
 184    if (ctx->lit) {
 185        tcg_temp_free(ctx->lit);
 186        ctx->lit = NULL;
 187    }
 188}
 189
 190static TCGv load_gpr(DisasContext *ctx, unsigned reg)
 191{
 192    if (likely(reg < 31)) {
 193        return ctx->ir[reg];
 194    } else {
 195        return load_zero(ctx);
 196    }
 197}
 198
 199static TCGv load_gpr_lit(DisasContext *ctx, unsigned reg,
 200                         uint8_t lit, bool islit)
 201{
 202    if (islit) {
 203        ctx->lit = tcg_const_i64(lit);
 204        return ctx->lit;
 205    } else if (likely(reg < 31)) {
 206        return ctx->ir[reg];
 207    } else {
 208        return load_zero(ctx);
 209    }
 210}
 211
 212static TCGv dest_gpr(DisasContext *ctx, unsigned reg)
 213{
 214    if (likely(reg < 31)) {
 215        return ctx->ir[reg];
 216    } else {
 217        return dest_sink(ctx);
 218    }
 219}
 220
 221static TCGv load_fpr(DisasContext *ctx, unsigned reg)
 222{
 223    if (likely(reg < 31)) {
 224        return cpu_fir[reg];
 225    } else {
 226        return load_zero(ctx);
 227    }
 228}
 229
 230static TCGv dest_fpr(DisasContext *ctx, unsigned reg)
 231{
 232    if (likely(reg < 31)) {
 233        return cpu_fir[reg];
 234    } else {
 235        return dest_sink(ctx);
 236    }
 237}
 238
 239static int get_flag_ofs(unsigned shift)
 240{
 241    int ofs = offsetof(CPUAlphaState, flags);
 242#ifdef HOST_WORDS_BIGENDIAN
 243    ofs += 3 - (shift / 8);
 244#else
 245    ofs += shift / 8;
 246#endif
 247    return ofs;
 248}
 249
 250static void ld_flag_byte(TCGv val, unsigned shift)
 251{
 252    tcg_gen_ld8u_i64(val, cpu_env, get_flag_ofs(shift));
 253}
 254
 255static void st_flag_byte(TCGv val, unsigned shift)
 256{
 257    tcg_gen_st8_i64(val, cpu_env, get_flag_ofs(shift));
 258}
 259
 260static void gen_excp_1(int exception, int error_code)
 261{
 262    TCGv_i32 tmp1, tmp2;
 263
 264    tmp1 = tcg_const_i32(exception);
 265    tmp2 = tcg_const_i32(error_code);
 266    gen_helper_excp(cpu_env, tmp1, tmp2);
 267    tcg_temp_free_i32(tmp2);
 268    tcg_temp_free_i32(tmp1);
 269}
 270
 271static DisasJumpType gen_excp(DisasContext *ctx, int exception, int error_code)
 272{
 273    tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
 274    gen_excp_1(exception, error_code);
 275    return DISAS_NORETURN;
 276}
 277
 278static inline DisasJumpType gen_invalid(DisasContext *ctx)
 279{
 280    return gen_excp(ctx, EXCP_OPCDEC, 0);
 281}
 282
 283static inline void gen_qemu_ldf(TCGv t0, TCGv t1, int flags)
 284{
 285    TCGv_i32 tmp32 = tcg_temp_new_i32();
 286    tcg_gen_qemu_ld_i32(tmp32, t1, flags, MO_LEUL);
 287    gen_helper_memory_to_f(t0, tmp32);
 288    tcg_temp_free_i32(tmp32);
 289}
 290
 291static inline void gen_qemu_ldg(TCGv t0, TCGv t1, int flags)
 292{
 293    TCGv tmp = tcg_temp_new();
 294    tcg_gen_qemu_ld_i64(tmp, t1, flags, MO_LEQ);
 295    gen_helper_memory_to_g(t0, tmp);
 296    tcg_temp_free(tmp);
 297}
 298
 299static inline void gen_qemu_lds(TCGv t0, TCGv t1, int flags)
 300{
 301    TCGv_i32 tmp32 = tcg_temp_new_i32();
 302    tcg_gen_qemu_ld_i32(tmp32, t1, flags, MO_LEUL);
 303    gen_helper_memory_to_s(t0, tmp32);
 304    tcg_temp_free_i32(tmp32);
 305}
 306
 307static inline void gen_qemu_ldl_l(TCGv t0, TCGv t1, int flags)
 308{
 309    tcg_gen_qemu_ld_i64(t0, t1, flags, MO_LESL);
 310    tcg_gen_mov_i64(cpu_lock_addr, t1);
 311    tcg_gen_mov_i64(cpu_lock_value, t0);
 312}
 313
 314static inline void gen_qemu_ldq_l(TCGv t0, TCGv t1, int flags)
 315{
 316    tcg_gen_qemu_ld_i64(t0, t1, flags, MO_LEQ);
 317    tcg_gen_mov_i64(cpu_lock_addr, t1);
 318    tcg_gen_mov_i64(cpu_lock_value, t0);
 319}
 320
 321static inline void gen_load_mem(DisasContext *ctx,
 322                                void (*tcg_gen_qemu_load)(TCGv t0, TCGv t1,
 323                                                          int flags),
 324                                int ra, int rb, int32_t disp16, bool fp,
 325                                bool clear)
 326{
 327    TCGv tmp, addr, va;
 328
 329    /* LDQ_U with ra $31 is UNOP.  Other various loads are forms of
 330       prefetches, which we can treat as nops.  No worries about
 331       missed exceptions here.  */
 332    if (unlikely(ra == 31)) {
 333        return;
 334    }
 335
 336    tmp = tcg_temp_new();
 337    addr = load_gpr(ctx, rb);
 338
 339    if (disp16) {
 340        tcg_gen_addi_i64(tmp, addr, disp16);
 341        addr = tmp;
 342    }
 343    if (clear) {
 344        tcg_gen_andi_i64(tmp, addr, ~0x7);
 345        addr = tmp;
 346    }
 347
 348    va = (fp ? cpu_fir[ra] : ctx->ir[ra]);
 349    tcg_gen_qemu_load(va, addr, ctx->mem_idx);
 350
 351    tcg_temp_free(tmp);
 352}
 353
 354static inline void gen_qemu_stf(TCGv t0, TCGv t1, int flags)
 355{
 356    TCGv_i32 tmp32 = tcg_temp_new_i32();
 357    gen_helper_f_to_memory(tmp32, t0);
 358    tcg_gen_qemu_st_i32(tmp32, t1, flags, MO_LEUL);
 359    tcg_temp_free_i32(tmp32);
 360}
 361
 362static inline void gen_qemu_stg(TCGv t0, TCGv t1, int flags)
 363{
 364    TCGv tmp = tcg_temp_new();
 365    gen_helper_g_to_memory(tmp, t0);
 366    tcg_gen_qemu_st_i64(tmp, t1, flags, MO_LEQ);
 367    tcg_temp_free(tmp);
 368}
 369
 370static inline void gen_qemu_sts(TCGv t0, TCGv t1, int flags)
 371{
 372    TCGv_i32 tmp32 = tcg_temp_new_i32();
 373    gen_helper_s_to_memory(tmp32, t0);
 374    tcg_gen_qemu_st_i32(tmp32, t1, flags, MO_LEUL);
 375    tcg_temp_free_i32(tmp32);
 376}
 377
 378static inline void gen_store_mem(DisasContext *ctx,
 379                                 void (*tcg_gen_qemu_store)(TCGv t0, TCGv t1,
 380                                                            int flags),
 381                                 int ra, int rb, int32_t disp16, bool fp,
 382                                 bool clear)
 383{
 384    TCGv tmp, addr, va;
 385
 386    tmp = tcg_temp_new();
 387    addr = load_gpr(ctx, rb);
 388
 389    if (disp16) {
 390        tcg_gen_addi_i64(tmp, addr, disp16);
 391        addr = tmp;
 392    }
 393    if (clear) {
 394        tcg_gen_andi_i64(tmp, addr, ~0x7);
 395        addr = tmp;
 396    }
 397
 398    va = (fp ? load_fpr(ctx, ra) : load_gpr(ctx, ra));
 399    tcg_gen_qemu_store(va, addr, ctx->mem_idx);
 400
 401    tcg_temp_free(tmp);
 402}
 403
 404static DisasJumpType gen_store_conditional(DisasContext *ctx, int ra, int rb,
 405                                           int32_t disp16, int mem_idx,
 406                                           MemOp op)
 407{
 408    TCGLabel *lab_fail, *lab_done;
 409    TCGv addr, val;
 410
 411    addr = tcg_temp_new_i64();
 412    tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
 413    free_context_temps(ctx);
 414
 415    lab_fail = gen_new_label();
 416    lab_done = gen_new_label();
 417    tcg_gen_brcond_i64(TCG_COND_NE, addr, cpu_lock_addr, lab_fail);
 418    tcg_temp_free_i64(addr);
 419
 420    val = tcg_temp_new_i64();
 421    tcg_gen_atomic_cmpxchg_i64(val, cpu_lock_addr, cpu_lock_value,
 422                               load_gpr(ctx, ra), mem_idx, op);
 423    free_context_temps(ctx);
 424
 425    if (ra != 31) {
 426        tcg_gen_setcond_i64(TCG_COND_EQ, ctx->ir[ra], val, cpu_lock_value);
 427    }
 428    tcg_temp_free_i64(val);
 429    tcg_gen_br(lab_done);
 430
 431    gen_set_label(lab_fail);
 432    if (ra != 31) {
 433        tcg_gen_movi_i64(ctx->ir[ra], 0);
 434    }
 435
 436    gen_set_label(lab_done);
 437    tcg_gen_movi_i64(cpu_lock_addr, -1);
 438    return DISAS_NEXT;
 439}
 440
 441static bool in_superpage(DisasContext *ctx, int64_t addr)
 442{
 443#ifndef CONFIG_USER_ONLY
 444    return ((ctx->tbflags & ENV_FLAG_PS_USER) == 0
 445            && addr >> TARGET_VIRT_ADDR_SPACE_BITS == -1
 446            && ((addr >> 41) & 3) == 2);
 447#else
 448    return false;
 449#endif
 450}
 451
 452static bool use_exit_tb(DisasContext *ctx)
 453{
 454    return ((tb_cflags(ctx->base.tb) & CF_LAST_IO)
 455            || ctx->base.singlestep_enabled
 456            || singlestep);
 457}
 458
 459static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
 460{
 461    /* Suppress goto_tb in the case of single-steping and IO.  */
 462    if (unlikely(use_exit_tb(ctx))) {
 463        return false;
 464    }
 465#ifndef CONFIG_USER_ONLY
 466    /* If the destination is in the superpage, the page perms can't change.  */
 467    if (in_superpage(ctx, dest)) {
 468        return true;
 469    }
 470    /* Check for the dest on the same page as the start of the TB.  */
 471    return ((ctx->base.tb->pc ^ dest) & TARGET_PAGE_MASK) == 0;
 472#else
 473    return true;
 474#endif
 475}
 476
 477static DisasJumpType gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
 478{
 479    uint64_t dest = ctx->base.pc_next + (disp << 2);
 480
 481    if (ra != 31) {
 482        tcg_gen_movi_i64(ctx->ir[ra], ctx->base.pc_next);
 483    }
 484
 485    /* Notice branch-to-next; used to initialize RA with the PC.  */
 486    if (disp == 0) {
 487        return 0;
 488    } else if (use_goto_tb(ctx, dest)) {
 489        tcg_gen_goto_tb(0);
 490        tcg_gen_movi_i64(cpu_pc, dest);
 491        tcg_gen_exit_tb(ctx->base.tb, 0);
 492        return DISAS_NORETURN;
 493    } else {
 494        tcg_gen_movi_i64(cpu_pc, dest);
 495        return DISAS_PC_UPDATED;
 496    }
 497}
 498
 499static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond,
 500                                        TCGv cmp, int32_t disp)
 501{
 502    uint64_t dest = ctx->base.pc_next + (disp << 2);
 503    TCGLabel *lab_true = gen_new_label();
 504
 505    if (use_goto_tb(ctx, dest)) {
 506        tcg_gen_brcondi_i64(cond, cmp, 0, lab_true);
 507
 508        tcg_gen_goto_tb(0);
 509        tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
 510        tcg_gen_exit_tb(ctx->base.tb, 0);
 511
 512        gen_set_label(lab_true);
 513        tcg_gen_goto_tb(1);
 514        tcg_gen_movi_i64(cpu_pc, dest);
 515        tcg_gen_exit_tb(ctx->base.tb, 1);
 516
 517        return DISAS_NORETURN;
 518    } else {
 519        TCGv_i64 z = tcg_const_i64(0);
 520        TCGv_i64 d = tcg_const_i64(dest);
 521        TCGv_i64 p = tcg_const_i64(ctx->base.pc_next);
 522
 523        tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p);
 524
 525        tcg_temp_free_i64(z);
 526        tcg_temp_free_i64(d);
 527        tcg_temp_free_i64(p);
 528        return DISAS_PC_UPDATED;
 529    }
 530}
 531
 532static DisasJumpType gen_bcond(DisasContext *ctx, TCGCond cond, int ra,
 533                               int32_t disp, int mask)
 534{
 535    if (mask) {
 536        TCGv tmp = tcg_temp_new();
 537        DisasJumpType ret;
 538
 539        tcg_gen_andi_i64(tmp, load_gpr(ctx, ra), 1);
 540        ret = gen_bcond_internal(ctx, cond, tmp, disp);
 541        tcg_temp_free(tmp);
 542        return ret;
 543    }
 544    return gen_bcond_internal(ctx, cond, load_gpr(ctx, ra), disp);
 545}
 546
 547/* Fold -0.0 for comparison with COND.  */
 548
 549static void gen_fold_mzero(TCGCond cond, TCGv dest, TCGv src)
 550{
 551    uint64_t mzero = 1ull << 63;
 552
 553    switch (cond) {
 554    case TCG_COND_LE:
 555    case TCG_COND_GT:
 556        /* For <= or >, the -0.0 value directly compares the way we want.  */
 557        tcg_gen_mov_i64(dest, src);
 558        break;
 559
 560    case TCG_COND_EQ:
 561    case TCG_COND_NE:
 562        /* For == or !=, we can simply mask off the sign bit and compare.  */
 563        tcg_gen_andi_i64(dest, src, mzero - 1);
 564        break;
 565
 566    case TCG_COND_GE:
 567    case TCG_COND_LT:
 568        /* For >= or <, map -0.0 to +0.0 via comparison and mask.  */
 569        tcg_gen_setcondi_i64(TCG_COND_NE, dest, src, mzero);
 570        tcg_gen_neg_i64(dest, dest);
 571        tcg_gen_and_i64(dest, dest, src);
 572        break;
 573
 574    default:
 575        abort();
 576    }
 577}
 578
 579static DisasJumpType gen_fbcond(DisasContext *ctx, TCGCond cond, int ra,
 580                                int32_t disp)
 581{
 582    TCGv cmp_tmp = tcg_temp_new();
 583    DisasJumpType ret;
 584
 585    gen_fold_mzero(cond, cmp_tmp, load_fpr(ctx, ra));
 586    ret = gen_bcond_internal(ctx, cond, cmp_tmp, disp);
 587    tcg_temp_free(cmp_tmp);
 588    return ret;
 589}
 590
 591static void gen_fcmov(DisasContext *ctx, TCGCond cond, int ra, int rb, int rc)
 592{
 593    TCGv_i64 va, vb, z;
 594
 595    z = load_zero(ctx);
 596    vb = load_fpr(ctx, rb);
 597    va = tcg_temp_new();
 598    gen_fold_mzero(cond, va, load_fpr(ctx, ra));
 599
 600    tcg_gen_movcond_i64(cond, dest_fpr(ctx, rc), va, z, vb, load_fpr(ctx, rc));
 601
 602    tcg_temp_free(va);
 603}
 604
 605#define QUAL_RM_N       0x080   /* Round mode nearest even */
 606#define QUAL_RM_C       0x000   /* Round mode chopped */
 607#define QUAL_RM_M       0x040   /* Round mode minus infinity */
 608#define QUAL_RM_D       0x0c0   /* Round mode dynamic */
 609#define QUAL_RM_MASK    0x0c0
 610
 611#define QUAL_U          0x100   /* Underflow enable (fp output) */
 612#define QUAL_V          0x100   /* Overflow enable (int output) */
 613#define QUAL_S          0x400   /* Software completion enable */
 614#define QUAL_I          0x200   /* Inexact detection enable */
 615
 616static void gen_qual_roundmode(DisasContext *ctx, int fn11)
 617{
 618    TCGv_i32 tmp;
 619
 620    fn11 &= QUAL_RM_MASK;
 621    if (fn11 == ctx->tb_rm) {
 622        return;
 623    }
 624    ctx->tb_rm = fn11;
 625
 626    tmp = tcg_temp_new_i32();
 627    switch (fn11) {
 628    case QUAL_RM_N:
 629        tcg_gen_movi_i32(tmp, float_round_nearest_even);
 630        break;
 631    case QUAL_RM_C:
 632        tcg_gen_movi_i32(tmp, float_round_to_zero);
 633        break;
 634    case QUAL_RM_M:
 635        tcg_gen_movi_i32(tmp, float_round_down);
 636        break;
 637    case QUAL_RM_D:
 638        tcg_gen_ld8u_i32(tmp, cpu_env,
 639                         offsetof(CPUAlphaState, fpcr_dyn_round));
 640        break;
 641    }
 642
 643#if defined(CONFIG_SOFTFLOAT_INLINE)
 644    /* ??? The "fpu/softfloat.h" interface is to call set_float_rounding_mode.
 645       With CONFIG_SOFTFLOAT that expands to an out-of-line call that just
 646       sets the one field.  */
 647    tcg_gen_st8_i32(tmp, cpu_env,
 648                    offsetof(CPUAlphaState, fp_status.float_rounding_mode));
 649#else
 650    gen_helper_setroundmode(tmp);
 651#endif
 652
 653    tcg_temp_free_i32(tmp);
 654}
 655
 656static void gen_qual_flushzero(DisasContext *ctx, int fn11)
 657{
 658    TCGv_i32 tmp;
 659
 660    fn11 &= QUAL_U;
 661    if (fn11 == ctx->tb_ftz) {
 662        return;
 663    }
 664    ctx->tb_ftz = fn11;
 665
 666    tmp = tcg_temp_new_i32();
 667    if (fn11) {
 668        /* Underflow is enabled, use the FPCR setting.  */
 669        tcg_gen_ld8u_i32(tmp, cpu_env,
 670                         offsetof(CPUAlphaState, fpcr_flush_to_zero));
 671    } else {
 672        /* Underflow is disabled, force flush-to-zero.  */
 673        tcg_gen_movi_i32(tmp, 1);
 674    }
 675
 676#if defined(CONFIG_SOFTFLOAT_INLINE)
 677    tcg_gen_st8_i32(tmp, cpu_env,
 678                    offsetof(CPUAlphaState, fp_status.flush_to_zero));
 679#else
 680    gen_helper_setflushzero(tmp);
 681#endif
 682
 683    tcg_temp_free_i32(tmp);
 684}
 685
 686static TCGv gen_ieee_input(DisasContext *ctx, int reg, int fn11, int is_cmp)
 687{
 688    TCGv val;
 689
 690    if (unlikely(reg == 31)) {
 691        val = load_zero(ctx);
 692    } else {
 693        val = cpu_fir[reg];
 694        if ((fn11 & QUAL_S) == 0) {
 695            if (is_cmp) {
 696                gen_helper_ieee_input_cmp(cpu_env, val);
 697            } else {
 698                gen_helper_ieee_input(cpu_env, val);
 699            }
 700        } else {
 701#ifndef CONFIG_USER_ONLY
 702            /* In system mode, raise exceptions for denormals like real
 703               hardware.  In user mode, proceed as if the OS completion
 704               handler is handling the denormal as per spec.  */
 705            gen_helper_ieee_input_s(cpu_env, val);
 706#endif
 707        }
 708    }
 709    return val;
 710}
 711
 712static void gen_fp_exc_raise(int rc, int fn11)
 713{
 714    /* ??? We ought to be able to do something with imprecise exceptions.
 715       E.g. notice we're still in the trap shadow of something within the
 716       TB and do not generate the code to signal the exception; end the TB
 717       when an exception is forced to arrive, either by consumption of a
 718       register value or TRAPB or EXCB.  */
 719    TCGv_i32 reg, ign;
 720    uint32_t ignore = 0;
 721
 722    if (!(fn11 & QUAL_U)) {
 723        /* Note that QUAL_U == QUAL_V, so ignore either.  */
 724        ignore |= FPCR_UNF | FPCR_IOV;
 725    }
 726    if (!(fn11 & QUAL_I)) {
 727        ignore |= FPCR_INE;
 728    }
 729    ign = tcg_const_i32(ignore);
 730
 731    /* ??? Pass in the regno of the destination so that the helper can
 732       set EXC_MASK, which contains a bitmask of destination registers
 733       that have caused arithmetic traps.  A simple userspace emulation
 734       does not require this.  We do need it for a guest kernel's entArith,
 735       or if we were to do something clever with imprecise exceptions.  */
 736    reg = tcg_const_i32(rc + 32);
 737    if (fn11 & QUAL_S) {
 738        gen_helper_fp_exc_raise_s(cpu_env, ign, reg);
 739    } else {
 740        gen_helper_fp_exc_raise(cpu_env, ign, reg);
 741    }
 742
 743    tcg_temp_free_i32(reg);
 744    tcg_temp_free_i32(ign);
 745}
 746
 747static void gen_cvtlq(TCGv vc, TCGv vb)
 748{
 749    TCGv tmp = tcg_temp_new();
 750
 751    /* The arithmetic right shift here, plus the sign-extended mask below
 752       yields a sign-extended result without an explicit ext32s_i64.  */
 753    tcg_gen_shri_i64(tmp, vb, 29);
 754    tcg_gen_sari_i64(vc, vb, 32);
 755    tcg_gen_deposit_i64(vc, vc, tmp, 0, 30);
 756
 757    tcg_temp_free(tmp);
 758}
 759
 760static void gen_ieee_arith2(DisasContext *ctx,
 761                            void (*helper)(TCGv, TCGv_ptr, TCGv),
 762                            int rb, int rc, int fn11)
 763{
 764    TCGv vb;
 765
 766    gen_qual_roundmode(ctx, fn11);
 767    gen_qual_flushzero(ctx, fn11);
 768
 769    vb = gen_ieee_input(ctx, rb, fn11, 0);
 770    helper(dest_fpr(ctx, rc), cpu_env, vb);
 771
 772    gen_fp_exc_raise(rc, fn11);
 773}
 774
 775#define IEEE_ARITH2(name)                                       \
 776static inline void glue(gen_, name)(DisasContext *ctx,          \
 777                                    int rb, int rc, int fn11)   \
 778{                                                               \
 779    gen_ieee_arith2(ctx, gen_helper_##name, rb, rc, fn11);      \
 780}
 781IEEE_ARITH2(sqrts)
 782IEEE_ARITH2(sqrtt)
 783IEEE_ARITH2(cvtst)
 784IEEE_ARITH2(cvtts)
 785
 786static void gen_cvttq(DisasContext *ctx, int rb, int rc, int fn11)
 787{
 788    TCGv vb, vc;
 789
 790    /* No need to set flushzero, since we have an integer output.  */
 791    vb = gen_ieee_input(ctx, rb, fn11, 0);
 792    vc = dest_fpr(ctx, rc);
 793
 794    /* Almost all integer conversions use cropped rounding;
 795       special case that.  */
 796    if ((fn11 & QUAL_RM_MASK) == QUAL_RM_C) {
 797        gen_helper_cvttq_c(vc, cpu_env, vb);
 798    } else {
 799        gen_qual_roundmode(ctx, fn11);
 800        gen_helper_cvttq(vc, cpu_env, vb);
 801    }
 802    gen_fp_exc_raise(rc, fn11);
 803}
 804
 805static void gen_ieee_intcvt(DisasContext *ctx,
 806                            void (*helper)(TCGv, TCGv_ptr, TCGv),
 807                            int rb, int rc, int fn11)
 808{
 809    TCGv vb, vc;
 810
 811    gen_qual_roundmode(ctx, fn11);
 812    vb = load_fpr(ctx, rb);
 813    vc = dest_fpr(ctx, rc);
 814
 815    /* The only exception that can be raised by integer conversion
 816       is inexact.  Thus we only need to worry about exceptions when
 817       inexact handling is requested.  */
 818    if (fn11 & QUAL_I) {
 819        helper(vc, cpu_env, vb);
 820        gen_fp_exc_raise(rc, fn11);
 821    } else {
 822        helper(vc, cpu_env, vb);
 823    }
 824}
 825
 826#define IEEE_INTCVT(name)                                       \
 827static inline void glue(gen_, name)(DisasContext *ctx,          \
 828                                    int rb, int rc, int fn11)   \
 829{                                                               \
 830    gen_ieee_intcvt(ctx, gen_helper_##name, rb, rc, fn11);      \
 831}
 832IEEE_INTCVT(cvtqs)
 833IEEE_INTCVT(cvtqt)
 834
 835static void gen_cpy_mask(TCGv vc, TCGv va, TCGv vb, bool inv_a, uint64_t mask)
 836{
 837    TCGv vmask = tcg_const_i64(mask);
 838    TCGv tmp = tcg_temp_new_i64();
 839
 840    if (inv_a) {
 841        tcg_gen_andc_i64(tmp, vmask, va);
 842    } else {
 843        tcg_gen_and_i64(tmp, va, vmask);
 844    }
 845
 846    tcg_gen_andc_i64(vc, vb, vmask);
 847    tcg_gen_or_i64(vc, vc, tmp);
 848
 849    tcg_temp_free(vmask);
 850    tcg_temp_free(tmp);
 851}
 852
 853static void gen_ieee_arith3(DisasContext *ctx,
 854                            void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv),
 855                            int ra, int rb, int rc, int fn11)
 856{
 857    TCGv va, vb, vc;
 858
 859    gen_qual_roundmode(ctx, fn11);
 860    gen_qual_flushzero(ctx, fn11);
 861
 862    va = gen_ieee_input(ctx, ra, fn11, 0);
 863    vb = gen_ieee_input(ctx, rb, fn11, 0);
 864    vc = dest_fpr(ctx, rc);
 865    helper(vc, cpu_env, va, vb);
 866
 867    gen_fp_exc_raise(rc, fn11);
 868}
 869
 870#define IEEE_ARITH3(name)                                               \
 871static inline void glue(gen_, name)(DisasContext *ctx,                  \
 872                                    int ra, int rb, int rc, int fn11)   \
 873{                                                                       \
 874    gen_ieee_arith3(ctx, gen_helper_##name, ra, rb, rc, fn11);          \
 875}
 876IEEE_ARITH3(adds)
 877IEEE_ARITH3(subs)
 878IEEE_ARITH3(muls)
 879IEEE_ARITH3(divs)
 880IEEE_ARITH3(addt)
 881IEEE_ARITH3(subt)
 882IEEE_ARITH3(mult)
 883IEEE_ARITH3(divt)
 884
 885static void gen_ieee_compare(DisasContext *ctx,
 886                             void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv),
 887                             int ra, int rb, int rc, int fn11)
 888{
 889    TCGv va, vb, vc;
 890
 891    va = gen_ieee_input(ctx, ra, fn11, 1);
 892    vb = gen_ieee_input(ctx, rb, fn11, 1);
 893    vc = dest_fpr(ctx, rc);
 894    helper(vc, cpu_env, va, vb);
 895
 896    gen_fp_exc_raise(rc, fn11);
 897}
 898
 899#define IEEE_CMP3(name)                                                 \
 900static inline void glue(gen_, name)(DisasContext *ctx,                  \
 901                                    int ra, int rb, int rc, int fn11)   \
 902{                                                                       \
 903    gen_ieee_compare(ctx, gen_helper_##name, ra, rb, rc, fn11);         \
 904}
 905IEEE_CMP3(cmptun)
 906IEEE_CMP3(cmpteq)
 907IEEE_CMP3(cmptlt)
 908IEEE_CMP3(cmptle)
 909
 910static inline uint64_t zapnot_mask(uint8_t lit)
 911{
 912    uint64_t mask = 0;
 913    int i;
 914
 915    for (i = 0; i < 8; ++i) {
 916        if ((lit >> i) & 1) {
 917            mask |= 0xffull << (i * 8);
 918        }
 919    }
 920    return mask;
 921}
 922
 923/* Implement zapnot with an immediate operand, which expands to some
 924   form of immediate AND.  This is a basic building block in the
 925   definition of many of the other byte manipulation instructions.  */
 926static void gen_zapnoti(TCGv dest, TCGv src, uint8_t lit)
 927{
 928    switch (lit) {
 929    case 0x00:
 930        tcg_gen_movi_i64(dest, 0);
 931        break;
 932    case 0x01:
 933        tcg_gen_ext8u_i64(dest, src);
 934        break;
 935    case 0x03:
 936        tcg_gen_ext16u_i64(dest, src);
 937        break;
 938    case 0x0f:
 939        tcg_gen_ext32u_i64(dest, src);
 940        break;
 941    case 0xff:
 942        tcg_gen_mov_i64(dest, src);
 943        break;
 944    default:
 945        tcg_gen_andi_i64(dest, src, zapnot_mask(lit));
 946        break;
 947    }
 948}
 949
 950/* EXTWH, EXTLH, EXTQH */
 951static void gen_ext_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
 952                      uint8_t lit, uint8_t byte_mask)
 953{
 954    if (islit) {
 955        int pos = (64 - lit * 8) & 0x3f;
 956        int len = cto32(byte_mask) * 8;
 957        if (pos < len) {
 958            tcg_gen_deposit_z_i64(vc, va, pos, len - pos);
 959        } else {
 960            tcg_gen_movi_i64(vc, 0);
 961        }
 962    } else {
 963        TCGv tmp = tcg_temp_new();
 964        tcg_gen_shli_i64(tmp, load_gpr(ctx, rb), 3);
 965        tcg_gen_neg_i64(tmp, tmp);
 966        tcg_gen_andi_i64(tmp, tmp, 0x3f);
 967        tcg_gen_shl_i64(vc, va, tmp);
 968        tcg_temp_free(tmp);
 969    }
 970    gen_zapnoti(vc, vc, byte_mask);
 971}
 972
 973/* EXTBL, EXTWL, EXTLL, EXTQL */
 974static void gen_ext_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
 975                      uint8_t lit, uint8_t byte_mask)
 976{
 977    if (islit) {
 978        int pos = (lit & 7) * 8;
 979        int len = cto32(byte_mask) * 8;
 980        if (pos + len >= 64) {
 981            len = 64 - pos;
 982        }
 983        tcg_gen_extract_i64(vc, va, pos, len);
 984    } else {
 985        TCGv tmp = tcg_temp_new();
 986        tcg_gen_andi_i64(tmp, load_gpr(ctx, rb), 7);
 987        tcg_gen_shli_i64(tmp, tmp, 3);
 988        tcg_gen_shr_i64(vc, va, tmp);
 989        tcg_temp_free(tmp);
 990        gen_zapnoti(vc, vc, byte_mask);
 991    }
 992}
 993
 994/* INSWH, INSLH, INSQH */
 995static void gen_ins_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
 996                      uint8_t lit, uint8_t byte_mask)
 997{
 998    if (islit) {
 999        int pos = 64 - (lit & 7) * 8;
1000        int len = cto32(byte_mask) * 8;
1001        if (pos < len) {
1002            tcg_gen_extract_i64(vc, va, pos, len - pos);
1003        } else {
1004            tcg_gen_movi_i64(vc, 0);
1005        }
1006    } else {
1007        TCGv tmp = tcg_temp_new();
1008        TCGv shift = tcg_temp_new();
1009
1010        /* The instruction description has us left-shift the byte mask
1011           and extract bits <15:8> and apply that zap at the end.  This
1012           is equivalent to simply performing the zap first and shifting
1013           afterward.  */
1014        gen_zapnoti(tmp, va, byte_mask);
1015
1016        /* If (B & 7) == 0, we need to shift by 64 and leave a zero.  Do this
1017           portably by splitting the shift into two parts: shift_count-1 and 1.
1018           Arrange for the -1 by using ones-complement instead of
1019           twos-complement in the negation: ~(B * 8) & 63.  */
1020
1021        tcg_gen_shli_i64(shift, load_gpr(ctx, rb), 3);
1022        tcg_gen_not_i64(shift, shift);
1023        tcg_gen_andi_i64(shift, shift, 0x3f);
1024
1025        tcg_gen_shr_i64(vc, tmp, shift);
1026        tcg_gen_shri_i64(vc, vc, 1);
1027        tcg_temp_free(shift);
1028        tcg_temp_free(tmp);
1029    }
1030}
1031
1032/* INSBL, INSWL, INSLL, INSQL */
1033static void gen_ins_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
1034                      uint8_t lit, uint8_t byte_mask)
1035{
1036    if (islit) {
1037        int pos = (lit & 7) * 8;
1038        int len = cto32(byte_mask) * 8;
1039        if (pos + len > 64) {
1040            len = 64 - pos;
1041        }
1042        tcg_gen_deposit_z_i64(vc, va, pos, len);
1043    } else {
1044        TCGv tmp = tcg_temp_new();
1045        TCGv shift = tcg_temp_new();
1046
1047        /* The instruction description has us left-shift the byte mask
1048           and extract bits <15:8> and apply that zap at the end.  This
1049           is equivalent to simply performing the zap first and shifting
1050           afterward.  */
1051        gen_zapnoti(tmp, va, byte_mask);
1052
1053        tcg_gen_andi_i64(shift, load_gpr(ctx, rb), 7);
1054        tcg_gen_shli_i64(shift, shift, 3);
1055        tcg_gen_shl_i64(vc, tmp, shift);
1056        tcg_temp_free(shift);
1057        tcg_temp_free(tmp);
1058    }
1059}
1060
1061/* MSKWH, MSKLH, MSKQH */
1062static void gen_msk_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
1063                      uint8_t lit, uint8_t byte_mask)
1064{
1065    if (islit) {
1066        gen_zapnoti(vc, va, ~((byte_mask << (lit & 7)) >> 8));
1067    } else {
1068        TCGv shift = tcg_temp_new();
1069        TCGv mask = tcg_temp_new();
1070
1071        /* The instruction description is as above, where the byte_mask
1072           is shifted left, and then we extract bits <15:8>.  This can be
1073           emulated with a right-shift on the expanded byte mask.  This
1074           requires extra care because for an input <2:0> == 0 we need a
1075           shift of 64 bits in order to generate a zero.  This is done by
1076           splitting the shift into two parts, the variable shift - 1
1077           followed by a constant 1 shift.  The code we expand below is
1078           equivalent to ~(B * 8) & 63.  */
1079
1080        tcg_gen_shli_i64(shift, load_gpr(ctx, rb), 3);
1081        tcg_gen_not_i64(shift, shift);
1082        tcg_gen_andi_i64(shift, shift, 0x3f);
1083        tcg_gen_movi_i64(mask, zapnot_mask (byte_mask));
1084        tcg_gen_shr_i64(mask, mask, shift);
1085        tcg_gen_shri_i64(mask, mask, 1);
1086
1087        tcg_gen_andc_i64(vc, va, mask);
1088
1089        tcg_temp_free(mask);
1090        tcg_temp_free(shift);
1091    }
1092}
1093
1094/* MSKBL, MSKWL, MSKLL, MSKQL */
1095static void gen_msk_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit,
1096                      uint8_t lit, uint8_t byte_mask)
1097{
1098    if (islit) {
1099        gen_zapnoti(vc, va, ~(byte_mask << (lit & 7)));
1100    } else {
1101        TCGv shift = tcg_temp_new();
1102        TCGv mask = tcg_temp_new();
1103
1104        tcg_gen_andi_i64(shift, load_gpr(ctx, rb), 7);
1105        tcg_gen_shli_i64(shift, shift, 3);
1106        tcg_gen_movi_i64(mask, zapnot_mask(byte_mask));
1107        tcg_gen_shl_i64(mask, mask, shift);
1108
1109        tcg_gen_andc_i64(vc, va, mask);
1110
1111        tcg_temp_free(mask);
1112        tcg_temp_free(shift);
1113    }
1114}
1115
1116static void gen_rx(DisasContext *ctx, int ra, int set)
1117{
1118    TCGv tmp;
1119
1120    if (ra != 31) {
1121        ld_flag_byte(ctx->ir[ra], ENV_FLAG_RX_SHIFT);
1122    }
1123
1124    tmp = tcg_const_i64(set);
1125    st_flag_byte(ctx->ir[ra], ENV_FLAG_RX_SHIFT);
1126    tcg_temp_free(tmp);
1127}
1128
1129static DisasJumpType gen_call_pal(DisasContext *ctx, int palcode)
1130{
1131    /* We're emulating OSF/1 PALcode.  Many of these are trivial access
1132       to internal cpu registers.  */
1133
1134    /* Unprivileged PAL call */
1135    if (palcode >= 0x80 && palcode < 0xC0) {
1136        switch (palcode) {
1137        case 0x86:
1138            /* IMB */
1139            /* No-op inside QEMU.  */
1140            break;
1141        case 0x9E:
1142            /* RDUNIQUE */
1143            tcg_gen_ld_i64(ctx->ir[IR_V0], cpu_env,
1144                           offsetof(CPUAlphaState, unique));
1145            break;
1146        case 0x9F:
1147            /* WRUNIQUE */
1148            tcg_gen_st_i64(ctx->ir[IR_A0], cpu_env,
1149                           offsetof(CPUAlphaState, unique));
1150            break;
1151        default:
1152            palcode &= 0xbf;
1153            goto do_call_pal;
1154        }
1155        return DISAS_NEXT;
1156    }
1157
1158#ifndef CONFIG_USER_ONLY
1159    /* Privileged PAL code */
1160    if (palcode < 0x40 && (ctx->tbflags & ENV_FLAG_PS_USER) == 0) {
1161        switch (palcode) {
1162        case 0x01:
1163            /* CFLUSH */
1164            /* No-op inside QEMU.  */
1165            break;
1166        case 0x02:
1167            /* DRAINA */
1168            /* No-op inside QEMU.  */
1169            break;
1170        case 0x2D:
1171            /* WRVPTPTR */
1172            tcg_gen_st_i64(ctx->ir[IR_A0], cpu_env,
1173                           offsetof(CPUAlphaState, vptptr));
1174            break;
1175        case 0x31:
1176            /* WRVAL */
1177            tcg_gen_st_i64(ctx->ir[IR_A0], cpu_env,
1178                           offsetof(CPUAlphaState, sysval));
1179            break;
1180        case 0x32:
1181            /* RDVAL */
1182            tcg_gen_ld_i64(ctx->ir[IR_V0], cpu_env,
1183                           offsetof(CPUAlphaState, sysval));
1184            break;
1185
1186        case 0x35:
1187            /* SWPIPL */
1188            /* Note that we already know we're in kernel mode, so we know
1189               that PS only contains the 3 IPL bits.  */
1190            ld_flag_byte(ctx->ir[IR_V0], ENV_FLAG_PS_SHIFT);
1191
1192            /* But make sure and store only the 3 IPL bits from the user.  */
1193            {
1194                TCGv tmp = tcg_temp_new();
1195                tcg_gen_andi_i64(tmp, ctx->ir[IR_A0], PS_INT_MASK);
1196                st_flag_byte(tmp, ENV_FLAG_PS_SHIFT);
1197                tcg_temp_free(tmp);
1198            }
1199
1200            /* Allow interrupts to be recognized right away.  */
1201            tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
1202            return DISAS_PC_UPDATED_NOCHAIN;
1203
1204        case 0x36:
1205            /* RDPS */
1206            ld_flag_byte(ctx->ir[IR_V0], ENV_FLAG_PS_SHIFT);
1207            break;
1208
1209        case 0x38:
1210            /* WRUSP */
1211            tcg_gen_st_i64(ctx->ir[IR_A0], cpu_env,
1212                           offsetof(CPUAlphaState, usp));
1213            break;
1214        case 0x3A:
1215            /* RDUSP */
1216            tcg_gen_ld_i64(ctx->ir[IR_V0], cpu_env,
1217                           offsetof(CPUAlphaState, usp));
1218            break;
1219        case 0x3C:
1220            /* WHAMI */
1221            tcg_gen_ld32s_i64(ctx->ir[IR_V0], cpu_env,
1222                -offsetof(AlphaCPU, env) + offsetof(CPUState, cpu_index));
1223            break;
1224
1225        case 0x3E:
1226            /* WTINT */
1227            {
1228                TCGv_i32 tmp = tcg_const_i32(1);
1229                tcg_gen_st_i32(tmp, cpu_env, -offsetof(AlphaCPU, env) +
1230                                             offsetof(CPUState, halted));
1231                tcg_temp_free_i32(tmp);
1232            }
1233            tcg_gen_movi_i64(ctx->ir[IR_V0], 0);
1234            return gen_excp(ctx, EXCP_HALTED, 0);
1235
1236        default:
1237            palcode &= 0x3f;
1238            goto do_call_pal;
1239        }
1240        return DISAS_NEXT;
1241    }
1242#endif
1243    return gen_invalid(ctx);
1244
1245 do_call_pal:
1246#ifdef CONFIG_USER_ONLY
1247    return gen_excp(ctx, EXCP_CALL_PAL, palcode);
1248#else
1249    {
1250        TCGv tmp = tcg_temp_new();
1251        uint64_t exc_addr = ctx->base.pc_next;
1252        uint64_t entry = ctx->palbr;
1253
1254        if (ctx->tbflags & ENV_FLAG_PAL_MODE) {
1255            exc_addr |= 1;
1256        } else {
1257            tcg_gen_movi_i64(tmp, 1);
1258            st_flag_byte(tmp, ENV_FLAG_PAL_SHIFT);
1259        }
1260
1261        tcg_gen_movi_i64(tmp, exc_addr);
1262        tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUAlphaState, exc_addr));
1263        tcg_temp_free(tmp);
1264
1265        entry += (palcode & 0x80
1266                  ? 0x2000 + (palcode - 0x80) * 64
1267                  : 0x1000 + palcode * 64);
1268
1269        /* Since the destination is running in PALmode, we don't really
1270           need the page permissions check.  We'll see the existence of
1271           the page when we create the TB, and we'll flush all TBs if
1272           we change the PAL base register.  */
1273        if (!use_exit_tb(ctx)) {
1274            tcg_gen_goto_tb(0);
1275            tcg_gen_movi_i64(cpu_pc, entry);
1276            tcg_gen_exit_tb(ctx->base.tb, 0);
1277            return DISAS_NORETURN;
1278        } else {
1279            tcg_gen_movi_i64(cpu_pc, entry);
1280            return DISAS_PC_UPDATED;
1281        }
1282    }
1283#endif
1284}
1285
1286#ifndef CONFIG_USER_ONLY
1287
1288#define PR_LONG         0x200000
1289
1290static int cpu_pr_data(int pr)
1291{
1292    switch (pr) {
1293    case  2: return offsetof(CPUAlphaState, pcc_ofs) | PR_LONG;
1294    case  3: return offsetof(CPUAlphaState, trap_arg0);
1295    case  4: return offsetof(CPUAlphaState, trap_arg1);
1296    case  5: return offsetof(CPUAlphaState, trap_arg2);
1297    case  6: return offsetof(CPUAlphaState, exc_addr);
1298    case  7: return offsetof(CPUAlphaState, palbr);
1299    case  8: return offsetof(CPUAlphaState, ptbr);
1300    case  9: return offsetof(CPUAlphaState, vptptr);
1301    case 10: return offsetof(CPUAlphaState, unique);
1302    case 11: return offsetof(CPUAlphaState, sysval);
1303    case 12: return offsetof(CPUAlphaState, usp);
1304
1305    case 40 ... 63:
1306        return offsetof(CPUAlphaState, scratch[pr - 40]);
1307
1308    case 251:
1309        return offsetof(CPUAlphaState, alarm_expire);
1310    }
1311    return 0;
1312}
1313
1314static DisasJumpType gen_mfpr(DisasContext *ctx, TCGv va, int regno)
1315{
1316    void (*helper)(TCGv);
1317    int data;
1318
1319    switch (regno) {
1320    case 32 ... 39:
1321        /* Accessing the "non-shadow" general registers.  */
1322        regno = regno == 39 ? 25 : regno - 32 + 8;
1323        tcg_gen_mov_i64(va, cpu_std_ir[regno]);
1324        break;
1325
1326    case 250: /* WALLTIME */
1327        helper = gen_helper_get_walltime;
1328        goto do_helper;
1329    case 249: /* VMTIME */
1330        helper = gen_helper_get_vmtime;
1331    do_helper:
1332        if (use_icount) {
1333            gen_io_start();
1334            helper(va);
1335            return DISAS_PC_STALE;
1336        } else {
1337            helper(va);
1338        }
1339        break;
1340
1341    case 0: /* PS */
1342        ld_flag_byte(va, ENV_FLAG_PS_SHIFT);
1343        break;
1344    case 1: /* FEN */
1345        ld_flag_byte(va, ENV_FLAG_FEN_SHIFT);
1346        break;
1347
1348    default:
1349        /* The basic registers are data only, and unknown registers
1350           are read-zero, write-ignore.  */
1351        data = cpu_pr_data(regno);
1352        if (data == 0) {
1353            tcg_gen_movi_i64(va, 0);
1354        } else if (data & PR_LONG) {
1355            tcg_gen_ld32s_i64(va, cpu_env, data & ~PR_LONG);
1356        } else {
1357            tcg_gen_ld_i64(va, cpu_env, data);
1358        }
1359        break;
1360    }
1361
1362    return DISAS_NEXT;
1363}
1364
1365static DisasJumpType gen_mtpr(DisasContext *ctx, TCGv vb, int regno)
1366{
1367    int data;
1368
1369    switch (regno) {
1370    case 255:
1371        /* TBIA */
1372        gen_helper_tbia(cpu_env);
1373        break;
1374
1375    case 254:
1376        /* TBIS */
1377        gen_helper_tbis(cpu_env, vb);
1378        break;
1379
1380    case 253:
1381        /* WAIT */
1382        {
1383            TCGv_i32 tmp = tcg_const_i32(1);
1384            tcg_gen_st_i32(tmp, cpu_env, -offsetof(AlphaCPU, env) +
1385                                         offsetof(CPUState, halted));
1386            tcg_temp_free_i32(tmp);
1387        }
1388        return gen_excp(ctx, EXCP_HALTED, 0);
1389
1390    case 252:
1391        /* HALT */
1392        gen_helper_halt(vb);
1393        return DISAS_PC_STALE;
1394
1395    case 251:
1396        /* ALARM */
1397        gen_helper_set_alarm(cpu_env, vb);
1398        break;
1399
1400    case 7:
1401        /* PALBR */
1402        tcg_gen_st_i64(vb, cpu_env, offsetof(CPUAlphaState, palbr));
1403        /* Changing the PAL base register implies un-chaining all of the TBs
1404           that ended with a CALL_PAL.  Since the base register usually only
1405           changes during boot, flushing everything works well.  */
1406        gen_helper_tb_flush(cpu_env);
1407        return DISAS_PC_STALE;
1408
1409    case 32 ... 39:
1410        /* Accessing the "non-shadow" general registers.  */
1411        regno = regno == 39 ? 25 : regno - 32 + 8;
1412        tcg_gen_mov_i64(cpu_std_ir[regno], vb);
1413        break;
1414
1415    case 0: /* PS */
1416        st_flag_byte(vb, ENV_FLAG_PS_SHIFT);
1417        break;
1418    case 1: /* FEN */
1419        st_flag_byte(vb, ENV_FLAG_FEN_SHIFT);
1420        break;
1421
1422    default:
1423        /* The basic registers are data only, and unknown registers
1424           are read-zero, write-ignore.  */
1425        data = cpu_pr_data(regno);
1426        if (data != 0) {
1427            if (data & PR_LONG) {
1428                tcg_gen_st32_i64(vb, cpu_env, data & ~PR_LONG);
1429            } else {
1430                tcg_gen_st_i64(vb, cpu_env, data);
1431            }
1432        }
1433        break;
1434    }
1435
1436    return DISAS_NEXT;
1437}
1438#endif /* !USER_ONLY*/
1439
1440#define REQUIRE_NO_LIT                          \
1441    do {                                        \
1442        if (real_islit) {                       \
1443            goto invalid_opc;                   \
1444        }                                       \
1445    } while (0)
1446
1447#define REQUIRE_AMASK(FLAG)                     \
1448    do {                                        \
1449        if ((ctx->amask & AMASK_##FLAG) == 0) { \
1450            goto invalid_opc;                   \
1451        }                                       \
1452    } while (0)
1453
1454#define REQUIRE_TB_FLAG(FLAG)                   \
1455    do {                                        \
1456        if ((ctx->tbflags & (FLAG)) == 0) {     \
1457            goto invalid_opc;                   \
1458        }                                       \
1459    } while (0)
1460
1461#define REQUIRE_REG_31(WHICH)                   \
1462    do {                                        \
1463        if (WHICH != 31) {                      \
1464            goto invalid_opc;                   \
1465        }                                       \
1466    } while (0)
1467
1468static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
1469{
1470    int32_t disp21, disp16, disp12 __attribute__((unused));
1471    uint16_t fn11;
1472    uint8_t opc, ra, rb, rc, fpfn, fn7, lit;
1473    bool islit, real_islit;
1474    TCGv va, vb, vc, tmp, tmp2;
1475    TCGv_i32 t32;
1476    DisasJumpType ret;
1477
1478    /* Decode all instruction fields */
1479    opc = extract32(insn, 26, 6);
1480    ra = extract32(insn, 21, 5);
1481    rb = extract32(insn, 16, 5);
1482    rc = extract32(insn, 0, 5);
1483    real_islit = islit = extract32(insn, 12, 1);
1484    lit = extract32(insn, 13, 8);
1485
1486    disp21 = sextract32(insn, 0, 21);
1487    disp16 = sextract32(insn, 0, 16);
1488    disp12 = sextract32(insn, 0, 12);
1489
1490    fn11 = extract32(insn, 5, 11);
1491    fpfn = extract32(insn, 5, 6);
1492    fn7 = extract32(insn, 5, 7);
1493
1494    if (rb == 31 && !islit) {
1495        islit = true;
1496        lit = 0;
1497    }
1498
1499    ret = DISAS_NEXT;
1500    switch (opc) {
1501    case 0x00:
1502        /* CALL_PAL */
1503        ret = gen_call_pal(ctx, insn & 0x03ffffff);
1504        break;
1505    case 0x01:
1506        /* OPC01 */
1507        goto invalid_opc;
1508    case 0x02:
1509        /* OPC02 */
1510        goto invalid_opc;
1511    case 0x03:
1512        /* OPC03 */
1513        goto invalid_opc;
1514    case 0x04:
1515        /* OPC04 */
1516        goto invalid_opc;
1517    case 0x05:
1518        /* OPC05 */
1519        goto invalid_opc;
1520    case 0x06:
1521        /* OPC06 */
1522        goto invalid_opc;
1523    case 0x07:
1524        /* OPC07 */
1525        goto invalid_opc;
1526
1527    case 0x09:
1528        /* LDAH */
1529        disp16 = (uint32_t)disp16 << 16;
1530        /* fall through */
1531    case 0x08:
1532        /* LDA */
1533        va = dest_gpr(ctx, ra);
1534        /* It's worth special-casing immediate loads.  */
1535        if (rb == 31) {
1536            tcg_gen_movi_i64(va, disp16);
1537        } else {
1538            tcg_gen_addi_i64(va, load_gpr(ctx, rb), disp16);
1539        }
1540        break;
1541
1542    case 0x0A:
1543        /* LDBU */
1544        REQUIRE_AMASK(BWX);
1545        gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
1546        break;
1547    case 0x0B:
1548        /* LDQ_U */
1549        gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);
1550        break;
1551    case 0x0C:
1552        /* LDWU */
1553        REQUIRE_AMASK(BWX);
1554        gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);
1555        break;
1556    case 0x0D:
1557        /* STW */
1558        REQUIRE_AMASK(BWX);
1559        gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0);
1560        break;
1561    case 0x0E:
1562        /* STB */
1563        REQUIRE_AMASK(BWX);
1564        gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0);
1565        break;
1566    case 0x0F:
1567        /* STQ_U */
1568        gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1);
1569        break;
1570
1571    case 0x10:
1572        vc = dest_gpr(ctx, rc);
1573        vb = load_gpr_lit(ctx, rb, lit, islit);
1574
1575        if (ra == 31) {
1576            if (fn7 == 0x00) {
1577                /* Special case ADDL as SEXTL.  */
1578                tcg_gen_ext32s_i64(vc, vb);
1579                break;
1580            }
1581            if (fn7 == 0x29) {
1582                /* Special case SUBQ as NEGQ.  */
1583                tcg_gen_neg_i64(vc, vb);
1584                break;
1585            }
1586        }
1587
1588        va = load_gpr(ctx, ra);
1589        switch (fn7) {
1590        case 0x00:
1591            /* ADDL */
1592            tcg_gen_add_i64(vc, va, vb);
1593            tcg_gen_ext32s_i64(vc, vc);
1594            break;
1595        case 0x02:
1596            /* S4ADDL */
1597            tmp = tcg_temp_new();
1598            tcg_gen_shli_i64(tmp, va, 2);
1599            tcg_gen_add_i64(tmp, tmp, vb);
1600            tcg_gen_ext32s_i64(vc, tmp);
1601            tcg_temp_free(tmp);
1602            break;
1603        case 0x09:
1604            /* SUBL */
1605            tcg_gen_sub_i64(vc, va, vb);
1606            tcg_gen_ext32s_i64(vc, vc);
1607            break;
1608        case 0x0B:
1609            /* S4SUBL */
1610            tmp = tcg_temp_new();
1611            tcg_gen_shli_i64(tmp, va, 2);
1612            tcg_gen_sub_i64(tmp, tmp, vb);
1613            tcg_gen_ext32s_i64(vc, tmp);
1614            tcg_temp_free(tmp);
1615            break;
1616        case 0x0F:
1617            /* CMPBGE */
1618            if (ra == 31) {
1619                /* Special case 0 >= X as X == 0.  */
1620                gen_helper_cmpbe0(vc, vb);
1621            } else {
1622                gen_helper_cmpbge(vc, va, vb);
1623            }
1624            break;
1625        case 0x12:
1626            /* S8ADDL */
1627            tmp = tcg_temp_new();
1628            tcg_gen_shli_i64(tmp, va, 3);
1629            tcg_gen_add_i64(tmp, tmp, vb);
1630            tcg_gen_ext32s_i64(vc, tmp);
1631            tcg_temp_free(tmp);
1632            break;
1633        case 0x1B:
1634            /* S8SUBL */
1635            tmp = tcg_temp_new();
1636            tcg_gen_shli_i64(tmp, va, 3);
1637            tcg_gen_sub_i64(tmp, tmp, vb);
1638            tcg_gen_ext32s_i64(vc, tmp);
1639            tcg_temp_free(tmp);
1640            break;
1641        case 0x1D:
1642            /* CMPULT */
1643            tcg_gen_setcond_i64(TCG_COND_LTU, vc, va, vb);
1644            break;
1645        case 0x20:
1646            /* ADDQ */
1647            tcg_gen_add_i64(vc, va, vb);
1648            break;
1649        case 0x22:
1650            /* S4ADDQ */
1651            tmp = tcg_temp_new();
1652            tcg_gen_shli_i64(tmp, va, 2);
1653            tcg_gen_add_i64(vc, tmp, vb);
1654            tcg_temp_free(tmp);
1655            break;
1656        case 0x29:
1657            /* SUBQ */
1658            tcg_gen_sub_i64(vc, va, vb);
1659            break;
1660        case 0x2B:
1661            /* S4SUBQ */
1662            tmp = tcg_temp_new();
1663            tcg_gen_shli_i64(tmp, va, 2);
1664            tcg_gen_sub_i64(vc, tmp, vb);
1665            tcg_temp_free(tmp);
1666            break;
1667        case 0x2D:
1668            /* CMPEQ */
1669            tcg_gen_setcond_i64(TCG_COND_EQ, vc, va, vb);
1670            break;
1671        case 0x32:
1672            /* S8ADDQ */
1673            tmp = tcg_temp_new();
1674            tcg_gen_shli_i64(tmp, va, 3);
1675            tcg_gen_add_i64(vc, tmp, vb);
1676            tcg_temp_free(tmp);
1677            break;
1678        case 0x3B:
1679            /* S8SUBQ */
1680            tmp = tcg_temp_new();
1681            tcg_gen_shli_i64(tmp, va, 3);
1682            tcg_gen_sub_i64(vc, tmp, vb);
1683            tcg_temp_free(tmp);
1684            break;
1685        case 0x3D:
1686            /* CMPULE */
1687            tcg_gen_setcond_i64(TCG_COND_LEU, vc, va, vb);
1688            break;
1689        case 0x40:
1690            /* ADDL/V */
1691            tmp = tcg_temp_new();
1692            tcg_gen_ext32s_i64(tmp, va);
1693            tcg_gen_ext32s_i64(vc, vb);
1694            tcg_gen_add_i64(tmp, tmp, vc);
1695            tcg_gen_ext32s_i64(vc, tmp);
1696            gen_helper_check_overflow(cpu_env, vc, tmp);
1697            tcg_temp_free(tmp);
1698            break;
1699        case 0x49:
1700            /* SUBL/V */
1701            tmp = tcg_temp_new();
1702            tcg_gen_ext32s_i64(tmp, va);
1703            tcg_gen_ext32s_i64(vc, vb);
1704            tcg_gen_sub_i64(tmp, tmp, vc);
1705            tcg_gen_ext32s_i64(vc, tmp);
1706            gen_helper_check_overflow(cpu_env, vc, tmp);
1707            tcg_temp_free(tmp);
1708            break;
1709        case 0x4D:
1710            /* CMPLT */
1711            tcg_gen_setcond_i64(TCG_COND_LT, vc, va, vb);
1712            break;
1713        case 0x60:
1714            /* ADDQ/V */
1715            tmp = tcg_temp_new();
1716            tmp2 = tcg_temp_new();
1717            tcg_gen_eqv_i64(tmp, va, vb);
1718            tcg_gen_mov_i64(tmp2, va);
1719            tcg_gen_add_i64(vc, va, vb);
1720            tcg_gen_xor_i64(tmp2, tmp2, vc);
1721            tcg_gen_and_i64(tmp, tmp, tmp2);
1722            tcg_gen_shri_i64(tmp, tmp, 63);
1723            tcg_gen_movi_i64(tmp2, 0);
1724            gen_helper_check_overflow(cpu_env, tmp, tmp2);
1725            tcg_temp_free(tmp);
1726            tcg_temp_free(tmp2);
1727            break;
1728        case 0x69:
1729            /* SUBQ/V */
1730            tmp = tcg_temp_new();
1731            tmp2 = tcg_temp_new();
1732            tcg_gen_xor_i64(tmp, va, vb);
1733            tcg_gen_mov_i64(tmp2, va);
1734            tcg_gen_sub_i64(vc, va, vb);
1735            tcg_gen_xor_i64(tmp2, tmp2, vc);
1736            tcg_gen_and_i64(tmp, tmp, tmp2);
1737            tcg_gen_shri_i64(tmp, tmp, 63);
1738            tcg_gen_movi_i64(tmp2, 0);
1739            gen_helper_check_overflow(cpu_env, tmp, tmp2);
1740            tcg_temp_free(tmp);
1741            tcg_temp_free(tmp2);
1742            break;
1743        case 0x6D:
1744            /* CMPLE */
1745            tcg_gen_setcond_i64(TCG_COND_LE, vc, va, vb);
1746            break;
1747        default:
1748            goto invalid_opc;
1749        }
1750        break;
1751
1752    case 0x11:
1753        if (fn7 == 0x20) {
1754            if (rc == 31) {
1755                /* Special case BIS as NOP.  */
1756                break;
1757            }
1758            if (ra == 31) {
1759                /* Special case BIS as MOV.  */
1760                vc = dest_gpr(ctx, rc);
1761                if (islit) {
1762                    tcg_gen_movi_i64(vc, lit);
1763                } else {
1764                    tcg_gen_mov_i64(vc, load_gpr(ctx, rb));
1765                }
1766                break;
1767            }
1768        }
1769
1770        vc = dest_gpr(ctx, rc);
1771        vb = load_gpr_lit(ctx, rb, lit, islit);
1772
1773        if (fn7 == 0x28 && ra == 31) {
1774            /* Special case ORNOT as NOT.  */
1775            tcg_gen_not_i64(vc, vb);
1776            break;
1777        }
1778
1779        va = load_gpr(ctx, ra);
1780        switch (fn7) {
1781        case 0x00:
1782            /* AND */
1783            tcg_gen_and_i64(vc, va, vb);
1784            break;
1785        case 0x08:
1786            /* BIC */
1787            tcg_gen_andc_i64(vc, va, vb);
1788            break;
1789        case 0x14:
1790            /* CMOVLBS */
1791            tmp = tcg_temp_new();
1792            tcg_gen_andi_i64(tmp, va, 1);
1793            tcg_gen_movcond_i64(TCG_COND_NE, vc, tmp, load_zero(ctx),
1794                                vb, load_gpr(ctx, rc));
1795            tcg_temp_free(tmp);
1796            break;
1797        case 0x16:
1798            /* CMOVLBC */
1799            tmp = tcg_temp_new();
1800            tcg_gen_andi_i64(tmp, va, 1);
1801            tcg_gen_movcond_i64(TCG_COND_EQ, vc, tmp, load_zero(ctx),
1802                                vb, load_gpr(ctx, rc));
1803            tcg_temp_free(tmp);
1804            break;
1805        case 0x20:
1806            /* BIS */
1807            tcg_gen_or_i64(vc, va, vb);
1808            break;
1809        case 0x24:
1810            /* CMOVEQ */
1811            tcg_gen_movcond_i64(TCG_COND_EQ, vc, va, load_zero(ctx),
1812                                vb, load_gpr(ctx, rc));
1813            break;
1814        case 0x26:
1815            /* CMOVNE */
1816            tcg_gen_movcond_i64(TCG_COND_NE, vc, va, load_zero(ctx),
1817                                vb, load_gpr(ctx, rc));
1818            break;
1819        case 0x28:
1820            /* ORNOT */
1821            tcg_gen_orc_i64(vc, va, vb);
1822            break;
1823        case 0x40:
1824            /* XOR */
1825            tcg_gen_xor_i64(vc, va, vb);
1826            break;
1827        case 0x44:
1828            /* CMOVLT */
1829            tcg_gen_movcond_i64(TCG_COND_LT, vc, va, load_zero(ctx),
1830                                vb, load_gpr(ctx, rc));
1831            break;
1832        case 0x46:
1833            /* CMOVGE */
1834            tcg_gen_movcond_i64(TCG_COND_GE, vc, va, load_zero(ctx),
1835                                vb, load_gpr(ctx, rc));
1836            break;
1837        case 0x48:
1838            /* EQV */
1839            tcg_gen_eqv_i64(vc, va, vb);
1840            break;
1841        case 0x61:
1842            /* AMASK */
1843            REQUIRE_REG_31(ra);
1844            tcg_gen_andi_i64(vc, vb, ~ctx->amask);
1845            break;
1846        case 0x64:
1847            /* CMOVLE */
1848            tcg_gen_movcond_i64(TCG_COND_LE, vc, va, load_zero(ctx),
1849                                vb, load_gpr(ctx, rc));
1850            break;
1851        case 0x66:
1852            /* CMOVGT */
1853            tcg_gen_movcond_i64(TCG_COND_GT, vc, va, load_zero(ctx),
1854                                vb, load_gpr(ctx, rc));
1855            break;
1856        case 0x6C:
1857            /* IMPLVER */
1858            REQUIRE_REG_31(ra);
1859            tcg_gen_movi_i64(vc, ctx->implver);
1860            break;
1861        default:
1862            goto invalid_opc;
1863        }
1864        break;
1865
1866    case 0x12:
1867        vc = dest_gpr(ctx, rc);
1868        va = load_gpr(ctx, ra);
1869        switch (fn7) {
1870        case 0x02:
1871            /* MSKBL */
1872            gen_msk_l(ctx, vc, va, rb, islit, lit, 0x01);
1873            break;
1874        case 0x06:
1875            /* EXTBL */
1876            gen_ext_l(ctx, vc, va, rb, islit, lit, 0x01);
1877            break;
1878        case 0x0B:
1879            /* INSBL */
1880            gen_ins_l(ctx, vc, va, rb, islit, lit, 0x01);
1881            break;
1882        case 0x12:
1883            /* MSKWL */
1884            gen_msk_l(ctx, vc, va, rb, islit, lit, 0x03);
1885            break;
1886        case 0x16:
1887            /* EXTWL */
1888            gen_ext_l(ctx, vc, va, rb, islit, lit, 0x03);
1889            break;
1890        case 0x1B:
1891            /* INSWL */
1892            gen_ins_l(ctx, vc, va, rb, islit, lit, 0x03);
1893            break;
1894        case 0x22:
1895            /* MSKLL */
1896            gen_msk_l(ctx, vc, va, rb, islit, lit, 0x0f);
1897            break;
1898        case 0x26:
1899            /* EXTLL */
1900            gen_ext_l(ctx, vc, va, rb, islit, lit, 0x0f);
1901            break;
1902        case 0x2B:
1903            /* INSLL */
1904            gen_ins_l(ctx, vc, va, rb, islit, lit, 0x0f);
1905            break;
1906        case 0x30:
1907            /* ZAP */
1908            if (islit) {
1909                gen_zapnoti(vc, va, ~lit);
1910            } else {
1911                gen_helper_zap(vc, va, load_gpr(ctx, rb));
1912            }
1913            break;
1914        case 0x31:
1915            /* ZAPNOT */
1916            if (islit) {
1917                gen_zapnoti(vc, va, lit);
1918            } else {
1919                gen_helper_zapnot(vc, va, load_gpr(ctx, rb));
1920            }
1921            break;
1922        case 0x32:
1923            /* MSKQL */
1924            gen_msk_l(ctx, vc, va, rb, islit, lit, 0xff);
1925            break;
1926        case 0x34:
1927            /* SRL */
1928            if (islit) {
1929                tcg_gen_shri_i64(vc, va, lit & 0x3f);
1930            } else {
1931                tmp = tcg_temp_new();
1932                vb = load_gpr(ctx, rb);
1933                tcg_gen_andi_i64(tmp, vb, 0x3f);
1934                tcg_gen_shr_i64(vc, va, tmp);
1935                tcg_temp_free(tmp);
1936            }
1937            break;
1938        case 0x36:
1939            /* EXTQL */
1940            gen_ext_l(ctx, vc, va, rb, islit, lit, 0xff);
1941            break;
1942        case 0x39:
1943            /* SLL */
1944            if (islit) {
1945                tcg_gen_shli_i64(vc, va, lit & 0x3f);
1946            } else {
1947                tmp = tcg_temp_new();
1948                vb = load_gpr(ctx, rb);
1949                tcg_gen_andi_i64(tmp, vb, 0x3f);
1950                tcg_gen_shl_i64(vc, va, tmp);
1951                tcg_temp_free(tmp);
1952            }
1953            break;
1954        case 0x3B:
1955            /* INSQL */
1956            gen_ins_l(ctx, vc, va, rb, islit, lit, 0xff);
1957            break;
1958        case 0x3C:
1959            /* SRA */
1960            if (islit) {
1961                tcg_gen_sari_i64(vc, va, lit & 0x3f);
1962            } else {
1963                tmp = tcg_temp_new();
1964                vb = load_gpr(ctx, rb);
1965                tcg_gen_andi_i64(tmp, vb, 0x3f);
1966                tcg_gen_sar_i64(vc, va, tmp);
1967                tcg_temp_free(tmp);
1968            }
1969            break;
1970        case 0x52:
1971            /* MSKWH */
1972            gen_msk_h(ctx, vc, va, rb, islit, lit, 0x03);
1973            break;
1974        case 0x57:
1975            /* INSWH */
1976            gen_ins_h(ctx, vc, va, rb, islit, lit, 0x03);
1977            break;
1978        case 0x5A:
1979            /* EXTWH */
1980            gen_ext_h(ctx, vc, va, rb, islit, lit, 0x03);
1981            break;
1982        case 0x62:
1983            /* MSKLH */
1984            gen_msk_h(ctx, vc, va, rb, islit, lit, 0x0f);
1985            break;
1986        case 0x67:
1987            /* INSLH */
1988            gen_ins_h(ctx, vc, va, rb, islit, lit, 0x0f);
1989            break;
1990        case 0x6A:
1991            /* EXTLH */
1992            gen_ext_h(ctx, vc, va, rb, islit, lit, 0x0f);
1993            break;
1994        case 0x72:
1995            /* MSKQH */
1996            gen_msk_h(ctx, vc, va, rb, islit, lit, 0xff);
1997            break;
1998        case 0x77:
1999            /* INSQH */
2000            gen_ins_h(ctx, vc, va, rb, islit, lit, 0xff);
2001            break;
2002        case 0x7A:
2003            /* EXTQH */
2004            gen_ext_h(ctx, vc, va, rb, islit, lit, 0xff);
2005            break;
2006        default:
2007            goto invalid_opc;
2008        }
2009        break;
2010
2011    case 0x13:
2012        vc = dest_gpr(ctx, rc);
2013        vb = load_gpr_lit(ctx, rb, lit, islit);
2014        va = load_gpr(ctx, ra);
2015        switch (fn7) {
2016        case 0x00:
2017            /* MULL */
2018            tcg_gen_mul_i64(vc, va, vb);
2019            tcg_gen_ext32s_i64(vc, vc);
2020            break;
2021        case 0x20:
2022            /* MULQ */
2023            tcg_gen_mul_i64(vc, va, vb);
2024            break;
2025        case 0x30:
2026            /* UMULH */
2027            tmp = tcg_temp_new();
2028            tcg_gen_mulu2_i64(tmp, vc, va, vb);
2029            tcg_temp_free(tmp);
2030            break;
2031        case 0x40:
2032            /* MULL/V */
2033            tmp = tcg_temp_new();
2034            tcg_gen_ext32s_i64(tmp, va);
2035            tcg_gen_ext32s_i64(vc, vb);
2036            tcg_gen_mul_i64(tmp, tmp, vc);
2037            tcg_gen_ext32s_i64(vc, tmp);
2038            gen_helper_check_overflow(cpu_env, vc, tmp);
2039            tcg_temp_free(tmp);
2040            break;
2041        case 0x60:
2042            /* MULQ/V */
2043            tmp = tcg_temp_new();
2044            tmp2 = tcg_temp_new();
2045            tcg_gen_muls2_i64(vc, tmp, va, vb);
2046            tcg_gen_sari_i64(tmp2, vc, 63);
2047            gen_helper_check_overflow(cpu_env, tmp, tmp2);
2048            tcg_temp_free(tmp);
2049            tcg_temp_free(tmp2);
2050            break;
2051        default:
2052            goto invalid_opc;
2053        }
2054        break;
2055
2056    case 0x14:
2057        REQUIRE_AMASK(FIX);
2058        vc = dest_fpr(ctx, rc);
2059        switch (fpfn) { /* fn11 & 0x3F */
2060        case 0x04:
2061            /* ITOFS */
2062            REQUIRE_REG_31(rb);
2063            t32 = tcg_temp_new_i32();
2064            va = load_gpr(ctx, ra);
2065            tcg_gen_extrl_i64_i32(t32, va);
2066            gen_helper_memory_to_s(vc, t32);
2067            tcg_temp_free_i32(t32);
2068            break;
2069        case 0x0A:
2070            /* SQRTF */
2071            REQUIRE_REG_31(ra);
2072            vb = load_fpr(ctx, rb);
2073            gen_helper_sqrtf(vc, cpu_env, vb);
2074            break;
2075        case 0x0B:
2076            /* SQRTS */
2077            REQUIRE_REG_31(ra);
2078            gen_sqrts(ctx, rb, rc, fn11);
2079            break;
2080        case 0x14:
2081            /* ITOFF */
2082            REQUIRE_REG_31(rb);
2083            t32 = tcg_temp_new_i32();
2084            va = load_gpr(ctx, ra);
2085            tcg_gen_extrl_i64_i32(t32, va);
2086            gen_helper_memory_to_f(vc, t32);
2087            tcg_temp_free_i32(t32);
2088            break;
2089        case 0x24:
2090            /* ITOFT */
2091            REQUIRE_REG_31(rb);
2092            va = load_gpr(ctx, ra);
2093            tcg_gen_mov_i64(vc, va);
2094            break;
2095        case 0x2A:
2096            /* SQRTG */
2097            REQUIRE_REG_31(ra);
2098            vb = load_fpr(ctx, rb);
2099            gen_helper_sqrtg(vc, cpu_env, vb);
2100            break;
2101        case 0x02B:
2102            /* SQRTT */
2103            REQUIRE_REG_31(ra);
2104            gen_sqrtt(ctx, rb, rc, fn11);
2105            break;
2106        default:
2107            goto invalid_opc;
2108        }
2109        break;
2110
2111    case 0x15:
2112        /* VAX floating point */
2113        /* XXX: rounding mode and trap are ignored (!) */
2114        vc = dest_fpr(ctx, rc);
2115        vb = load_fpr(ctx, rb);
2116        va = load_fpr(ctx, ra);
2117        switch (fpfn) { /* fn11 & 0x3F */
2118        case 0x00:
2119            /* ADDF */
2120            gen_helper_addf(vc, cpu_env, va, vb);
2121            break;
2122        case 0x01:
2123            /* SUBF */
2124            gen_helper_subf(vc, cpu_env, va, vb);
2125            break;
2126        case 0x02:
2127            /* MULF */
2128            gen_helper_mulf(vc, cpu_env, va, vb);
2129            break;
2130        case 0x03:
2131            /* DIVF */
2132            gen_helper_divf(vc, cpu_env, va, vb);
2133            break;
2134        case 0x1E:
2135            /* CVTDG -- TODO */
2136            REQUIRE_REG_31(ra);
2137            goto invalid_opc;
2138        case 0x20:
2139            /* ADDG */
2140            gen_helper_addg(vc, cpu_env, va, vb);
2141            break;
2142        case 0x21:
2143            /* SUBG */
2144            gen_helper_subg(vc, cpu_env, va, vb);
2145            break;
2146        case 0x22:
2147            /* MULG */
2148            gen_helper_mulg(vc, cpu_env, va, vb);
2149            break;
2150        case 0x23:
2151            /* DIVG */
2152            gen_helper_divg(vc, cpu_env, va, vb);
2153            break;
2154        case 0x25:
2155            /* CMPGEQ */
2156            gen_helper_cmpgeq(vc, cpu_env, va, vb);
2157            break;
2158        case 0x26:
2159            /* CMPGLT */
2160            gen_helper_cmpglt(vc, cpu_env, va, vb);
2161            break;
2162        case 0x27:
2163            /* CMPGLE */
2164            gen_helper_cmpgle(vc, cpu_env, va, vb);
2165            break;
2166        case 0x2C:
2167            /* CVTGF */
2168            REQUIRE_REG_31(ra);
2169            gen_helper_cvtgf(vc, cpu_env, vb);
2170            break;
2171        case 0x2D:
2172            /* CVTGD -- TODO */
2173            REQUIRE_REG_31(ra);
2174            goto invalid_opc;
2175        case 0x2F:
2176            /* CVTGQ */
2177            REQUIRE_REG_31(ra);
2178            gen_helper_cvtgq(vc, cpu_env, vb);
2179            break;
2180        case 0x3C:
2181            /* CVTQF */
2182            REQUIRE_REG_31(ra);
2183            gen_helper_cvtqf(vc, cpu_env, vb);
2184            break;
2185        case 0x3E:
2186            /* CVTQG */
2187            REQUIRE_REG_31(ra);
2188            gen_helper_cvtqg(vc, cpu_env, vb);
2189            break;
2190        default:
2191            goto invalid_opc;
2192        }
2193        break;
2194
2195    case 0x16:
2196        /* IEEE floating-point */
2197        switch (fpfn) { /* fn11 & 0x3F */
2198        case 0x00:
2199            /* ADDS */
2200            gen_adds(ctx, ra, rb, rc, fn11);
2201            break;
2202        case 0x01:
2203            /* SUBS */
2204            gen_subs(ctx, ra, rb, rc, fn11);
2205            break;
2206        case 0x02:
2207            /* MULS */
2208            gen_muls(ctx, ra, rb, rc, fn11);
2209            break;
2210        case 0x03:
2211            /* DIVS */
2212            gen_divs(ctx, ra, rb, rc, fn11);
2213            break;
2214        case 0x20:
2215            /* ADDT */
2216            gen_addt(ctx, ra, rb, rc, fn11);
2217            break;
2218        case 0x21:
2219            /* SUBT */
2220            gen_subt(ctx, ra, rb, rc, fn11);
2221            break;
2222        case 0x22:
2223            /* MULT */
2224            gen_mult(ctx, ra, rb, rc, fn11);
2225            break;
2226        case 0x23:
2227            /* DIVT */
2228            gen_divt(ctx, ra, rb, rc, fn11);
2229            break;
2230        case 0x24:
2231            /* CMPTUN */
2232            gen_cmptun(ctx, ra, rb, rc, fn11);
2233            break;
2234        case 0x25:
2235            /* CMPTEQ */
2236            gen_cmpteq(ctx, ra, rb, rc, fn11);
2237            break;
2238        case 0x26:
2239            /* CMPTLT */
2240            gen_cmptlt(ctx, ra, rb, rc, fn11);
2241            break;
2242        case 0x27:
2243            /* CMPTLE */
2244            gen_cmptle(ctx, ra, rb, rc, fn11);
2245            break;
2246        case 0x2C:
2247            REQUIRE_REG_31(ra);
2248            if (fn11 == 0x2AC || fn11 == 0x6AC) {
2249                /* CVTST */
2250                gen_cvtst(ctx, rb, rc, fn11);
2251            } else {
2252                /* CVTTS */
2253                gen_cvtts(ctx, rb, rc, fn11);
2254            }
2255            break;
2256        case 0x2F:
2257            /* CVTTQ */
2258            REQUIRE_REG_31(ra);
2259            gen_cvttq(ctx, rb, rc, fn11);
2260            break;
2261        case 0x3C:
2262            /* CVTQS */
2263            REQUIRE_REG_31(ra);
2264            gen_cvtqs(ctx, rb, rc, fn11);
2265            break;
2266        case 0x3E:
2267            /* CVTQT */
2268            REQUIRE_REG_31(ra);
2269            gen_cvtqt(ctx, rb, rc, fn11);
2270            break;
2271        default:
2272            goto invalid_opc;
2273        }
2274        break;
2275
2276    case 0x17:
2277        switch (fn11) {
2278        case 0x010:
2279            /* CVTLQ */
2280            REQUIRE_REG_31(ra);
2281            vc = dest_fpr(ctx, rc);
2282            vb = load_fpr(ctx, rb);
2283            gen_cvtlq(vc, vb);
2284            break;
2285        case 0x020:
2286            /* CPYS */
2287            if (rc == 31) {
2288                /* Special case CPYS as FNOP.  */
2289            } else {
2290                vc = dest_fpr(ctx, rc);
2291                va = load_fpr(ctx, ra);
2292                if (ra == rb) {
2293                    /* Special case CPYS as FMOV.  */
2294                    tcg_gen_mov_i64(vc, va);
2295                } else {
2296                    vb = load_fpr(ctx, rb);
2297                    gen_cpy_mask(vc, va, vb, 0, 0x8000000000000000ULL);
2298                }
2299            }
2300            break;
2301        case 0x021:
2302            /* CPYSN */
2303            vc = dest_fpr(ctx, rc);
2304            vb = load_fpr(ctx, rb);
2305            va = load_fpr(ctx, ra);
2306            gen_cpy_mask(vc, va, vb, 1, 0x8000000000000000ULL);
2307            break;
2308        case 0x022:
2309            /* CPYSE */
2310            vc = dest_fpr(ctx, rc);
2311            vb = load_fpr(ctx, rb);
2312            va = load_fpr(ctx, ra);
2313            gen_cpy_mask(vc, va, vb, 0, 0xFFF0000000000000ULL);
2314            break;
2315        case 0x024:
2316            /* MT_FPCR */
2317            va = load_fpr(ctx, ra);
2318            gen_helper_store_fpcr(cpu_env, va);
2319            if (ctx->tb_rm == QUAL_RM_D) {
2320                /* Re-do the copy of the rounding mode to fp_status
2321                   the next time we use dynamic rounding.  */
2322                ctx->tb_rm = -1;
2323            }
2324            break;
2325        case 0x025:
2326            /* MF_FPCR */
2327            va = dest_fpr(ctx, ra);
2328            gen_helper_load_fpcr(va, cpu_env);
2329            break;
2330        case 0x02A:
2331            /* FCMOVEQ */
2332            gen_fcmov(ctx, TCG_COND_EQ, ra, rb, rc);
2333            break;
2334        case 0x02B:
2335            /* FCMOVNE */
2336            gen_fcmov(ctx, TCG_COND_NE, ra, rb, rc);
2337            break;
2338        case 0x02C:
2339            /* FCMOVLT */
2340            gen_fcmov(ctx, TCG_COND_LT, ra, rb, rc);
2341            break;
2342        case 0x02D:
2343            /* FCMOVGE */
2344            gen_fcmov(ctx, TCG_COND_GE, ra, rb, rc);
2345            break;
2346        case 0x02E:
2347            /* FCMOVLE */
2348            gen_fcmov(ctx, TCG_COND_LE, ra, rb, rc);
2349            break;
2350        case 0x02F:
2351            /* FCMOVGT */
2352            gen_fcmov(ctx, TCG_COND_GT, ra, rb, rc);
2353            break;
2354        case 0x030: /* CVTQL */
2355        case 0x130: /* CVTQL/V */
2356        case 0x530: /* CVTQL/SV */
2357            REQUIRE_REG_31(ra);
2358            vc = dest_fpr(ctx, rc);
2359            vb = load_fpr(ctx, rb);
2360            gen_helper_cvtql(vc, cpu_env, vb);
2361            gen_fp_exc_raise(rc, fn11);
2362            break;
2363        default:
2364            goto invalid_opc;
2365        }
2366        break;
2367
2368    case 0x18:
2369        switch ((uint16_t)disp16) {
2370        case 0x0000:
2371            /* TRAPB */
2372            /* No-op.  */
2373            break;
2374        case 0x0400:
2375            /* EXCB */
2376            /* No-op.  */
2377            break;
2378        case 0x4000:
2379            /* MB */
2380            tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
2381            break;
2382        case 0x4400:
2383            /* WMB */
2384            tcg_gen_mb(TCG_MO_ST_ST | TCG_BAR_SC);
2385            break;
2386        case 0x8000:
2387            /* FETCH */
2388            /* No-op */
2389            break;
2390        case 0xA000:
2391            /* FETCH_M */
2392            /* No-op */
2393            break;
2394        case 0xC000:
2395            /* RPCC */
2396            va = dest_gpr(ctx, ra);
2397            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
2398                gen_io_start();
2399                gen_helper_load_pcc(va, cpu_env);
2400                ret = DISAS_PC_STALE;
2401            } else {
2402                gen_helper_load_pcc(va, cpu_env);
2403            }
2404            break;
2405        case 0xE000:
2406            /* RC */
2407            gen_rx(ctx, ra, 0);
2408            break;
2409        case 0xE800:
2410            /* ECB */
2411            break;
2412        case 0xF000:
2413            /* RS */
2414            gen_rx(ctx, ra, 1);
2415            break;
2416        case 0xF800:
2417            /* WH64 */
2418            /* No-op */
2419            break;
2420        case 0xFC00:
2421            /* WH64EN */
2422            /* No-op */
2423            break;
2424        default:
2425            goto invalid_opc;
2426        }
2427        break;
2428
2429    case 0x19:
2430        /* HW_MFPR (PALcode) */
2431#ifndef CONFIG_USER_ONLY
2432        REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);
2433        va = dest_gpr(ctx, ra);
2434        ret = gen_mfpr(ctx, va, insn & 0xffff);
2435        break;
2436#else
2437        goto invalid_opc;
2438#endif
2439
2440    case 0x1A:
2441        /* JMP, JSR, RET, JSR_COROUTINE.  These only differ by the branch
2442           prediction stack action, which of course we don't implement.  */
2443        vb = load_gpr(ctx, rb);
2444        tcg_gen_andi_i64(cpu_pc, vb, ~3);
2445        if (ra != 31) {
2446            tcg_gen_movi_i64(ctx->ir[ra], ctx->base.pc_next);
2447        }
2448        ret = DISAS_PC_UPDATED;
2449        break;
2450
2451    case 0x1B:
2452        /* HW_LD (PALcode) */
2453#ifndef CONFIG_USER_ONLY
2454        REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);
2455        {
2456            TCGv addr = tcg_temp_new();
2457            vb = load_gpr(ctx, rb);
2458            va = dest_gpr(ctx, ra);
2459
2460            tcg_gen_addi_i64(addr, vb, disp12);
2461            switch ((insn >> 12) & 0xF) {
2462            case 0x0:
2463                /* Longword physical access (hw_ldl/p) */
2464                tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LESL);
2465                break;
2466            case 0x1:
2467                /* Quadword physical access (hw_ldq/p) */
2468                tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LEQ);
2469                break;
2470            case 0x2:
2471                /* Longword physical access with lock (hw_ldl_l/p) */
2472                gen_qemu_ldl_l(va, addr, MMU_PHYS_IDX);
2473                break;
2474            case 0x3:
2475                /* Quadword physical access with lock (hw_ldq_l/p) */
2476                gen_qemu_ldq_l(va, addr, MMU_PHYS_IDX);
2477                break;
2478            case 0x4:
2479                /* Longword virtual PTE fetch (hw_ldl/v) */
2480                goto invalid_opc;
2481            case 0x5:
2482                /* Quadword virtual PTE fetch (hw_ldq/v) */
2483                goto invalid_opc;
2484                break;
2485            case 0x6:
2486                /* Invalid */
2487                goto invalid_opc;
2488            case 0x7:
2489                /* Invaliid */
2490                goto invalid_opc;
2491            case 0x8:
2492                /* Longword virtual access (hw_ldl) */
2493                goto invalid_opc;
2494            case 0x9:
2495                /* Quadword virtual access (hw_ldq) */
2496                goto invalid_opc;
2497            case 0xA:
2498                /* Longword virtual access with protection check (hw_ldl/w) */
2499                tcg_gen_qemu_ld_i64(va, addr, MMU_KERNEL_IDX, MO_LESL);
2500                break;
2501            case 0xB:
2502                /* Quadword virtual access with protection check (hw_ldq/w) */
2503                tcg_gen_qemu_ld_i64(va, addr, MMU_KERNEL_IDX, MO_LEQ);
2504                break;
2505            case 0xC:
2506                /* Longword virtual access with alt access mode (hw_ldl/a)*/
2507                goto invalid_opc;
2508            case 0xD:
2509                /* Quadword virtual access with alt access mode (hw_ldq/a) */
2510                goto invalid_opc;
2511            case 0xE:
2512                /* Longword virtual access with alternate access mode and
2513                   protection checks (hw_ldl/wa) */
2514                tcg_gen_qemu_ld_i64(va, addr, MMU_USER_IDX, MO_LESL);
2515                break;
2516            case 0xF:
2517                /* Quadword virtual access with alternate access mode and
2518                   protection checks (hw_ldq/wa) */
2519                tcg_gen_qemu_ld_i64(va, addr, MMU_USER_IDX, MO_LEQ);
2520                break;
2521            }
2522            tcg_temp_free(addr);
2523            break;
2524        }
2525#else
2526        goto invalid_opc;
2527#endif
2528
2529    case 0x1C:
2530        vc = dest_gpr(ctx, rc);
2531        if (fn7 == 0x70) {
2532            /* FTOIT */
2533            REQUIRE_AMASK(FIX);
2534            REQUIRE_REG_31(rb);
2535            va = load_fpr(ctx, ra);
2536            tcg_gen_mov_i64(vc, va);
2537            break;
2538        } else if (fn7 == 0x78) {
2539            /* FTOIS */
2540            REQUIRE_AMASK(FIX);
2541            REQUIRE_REG_31(rb);
2542            t32 = tcg_temp_new_i32();
2543            va = load_fpr(ctx, ra);
2544            gen_helper_s_to_memory(t32, va);
2545            tcg_gen_ext_i32_i64(vc, t32);
2546            tcg_temp_free_i32(t32);
2547            break;
2548        }
2549
2550        vb = load_gpr_lit(ctx, rb, lit, islit);
2551        switch (fn7) {
2552        case 0x00:
2553            /* SEXTB */
2554            REQUIRE_AMASK(BWX);
2555            REQUIRE_REG_31(ra);
2556            tcg_gen_ext8s_i64(vc, vb);
2557            break;
2558        case 0x01:
2559            /* SEXTW */
2560            REQUIRE_AMASK(BWX);
2561            REQUIRE_REG_31(ra);
2562            tcg_gen_ext16s_i64(vc, vb);
2563            break;
2564        case 0x30:
2565            /* CTPOP */
2566            REQUIRE_AMASK(CIX);
2567            REQUIRE_REG_31(ra);
2568            REQUIRE_NO_LIT;
2569            tcg_gen_ctpop_i64(vc, vb);
2570            break;
2571        case 0x31:
2572            /* PERR */
2573            REQUIRE_AMASK(MVI);
2574            REQUIRE_NO_LIT;
2575            va = load_gpr(ctx, ra);
2576            gen_helper_perr(vc, va, vb);
2577            break;
2578        case 0x32:
2579            /* CTLZ */
2580            REQUIRE_AMASK(CIX);
2581            REQUIRE_REG_31(ra);
2582            REQUIRE_NO_LIT;
2583            tcg_gen_clzi_i64(vc, vb, 64);
2584            break;
2585        case 0x33:
2586            /* CTTZ */
2587            REQUIRE_AMASK(CIX);
2588            REQUIRE_REG_31(ra);
2589            REQUIRE_NO_LIT;
2590            tcg_gen_ctzi_i64(vc, vb, 64);
2591            break;
2592        case 0x34:
2593            /* UNPKBW */
2594            REQUIRE_AMASK(MVI);
2595            REQUIRE_REG_31(ra);
2596            REQUIRE_NO_LIT;
2597            gen_helper_unpkbw(vc, vb);
2598            break;
2599        case 0x35:
2600            /* UNPKBL */
2601            REQUIRE_AMASK(MVI);
2602            REQUIRE_REG_31(ra);
2603            REQUIRE_NO_LIT;
2604            gen_helper_unpkbl(vc, vb);
2605            break;
2606        case 0x36:
2607            /* PKWB */
2608            REQUIRE_AMASK(MVI);
2609            REQUIRE_REG_31(ra);
2610            REQUIRE_NO_LIT;
2611            gen_helper_pkwb(vc, vb);
2612            break;
2613        case 0x37:
2614            /* PKLB */
2615            REQUIRE_AMASK(MVI);
2616            REQUIRE_REG_31(ra);
2617            REQUIRE_NO_LIT;
2618            gen_helper_pklb(vc, vb);
2619            break;
2620        case 0x38:
2621            /* MINSB8 */
2622            REQUIRE_AMASK(MVI);
2623            va = load_gpr(ctx, ra);
2624            gen_helper_minsb8(vc, va, vb);
2625            break;
2626        case 0x39:
2627            /* MINSW4 */
2628            REQUIRE_AMASK(MVI);
2629            va = load_gpr(ctx, ra);
2630            gen_helper_minsw4(vc, va, vb);
2631            break;
2632        case 0x3A:
2633            /* MINUB8 */
2634            REQUIRE_AMASK(MVI);
2635            va = load_gpr(ctx, ra);
2636            gen_helper_minub8(vc, va, vb);
2637            break;
2638        case 0x3B:
2639            /* MINUW4 */
2640            REQUIRE_AMASK(MVI);
2641            va = load_gpr(ctx, ra);
2642            gen_helper_minuw4(vc, va, vb);
2643            break;
2644        case 0x3C:
2645            /* MAXUB8 */
2646            REQUIRE_AMASK(MVI);
2647            va = load_gpr(ctx, ra);
2648            gen_helper_maxub8(vc, va, vb);
2649            break;
2650        case 0x3D:
2651            /* MAXUW4 */
2652            REQUIRE_AMASK(MVI);
2653            va = load_gpr(ctx, ra);
2654            gen_helper_maxuw4(vc, va, vb);
2655            break;
2656        case 0x3E:
2657            /* MAXSB8 */
2658            REQUIRE_AMASK(MVI);
2659            va = load_gpr(ctx, ra);
2660            gen_helper_maxsb8(vc, va, vb);
2661            break;
2662        case 0x3F:
2663            /* MAXSW4 */
2664            REQUIRE_AMASK(MVI);
2665            va = load_gpr(ctx, ra);
2666            gen_helper_maxsw4(vc, va, vb);
2667            break;
2668        default:
2669            goto invalid_opc;
2670        }
2671        break;
2672
2673    case 0x1D:
2674        /* HW_MTPR (PALcode) */
2675#ifndef CONFIG_USER_ONLY
2676        REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);
2677        vb = load_gpr(ctx, rb);
2678        ret = gen_mtpr(ctx, vb, insn & 0xffff);
2679        break;
2680#else
2681        goto invalid_opc;
2682#endif
2683
2684    case 0x1E:
2685        /* HW_RET (PALcode) */
2686#ifndef CONFIG_USER_ONLY
2687        REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);
2688        if (rb == 31) {
2689            /* Pre-EV6 CPUs interpreted this as HW_REI, loading the return
2690               address from EXC_ADDR.  This turns out to be useful for our
2691               emulation PALcode, so continue to accept it.  */
2692            ctx->lit = vb = tcg_temp_new();
2693            tcg_gen_ld_i64(vb, cpu_env, offsetof(CPUAlphaState, exc_addr));
2694        } else {
2695            vb = load_gpr(ctx, rb);
2696        }
2697        tcg_gen_movi_i64(cpu_lock_addr, -1);
2698        tmp = tcg_temp_new();
2699        tcg_gen_movi_i64(tmp, 0);
2700        st_flag_byte(tmp, ENV_FLAG_RX_SHIFT);
2701        tcg_gen_andi_i64(tmp, vb, 1);
2702        st_flag_byte(tmp, ENV_FLAG_PAL_SHIFT);
2703        tcg_temp_free(tmp);
2704        tcg_gen_andi_i64(cpu_pc, vb, ~3);
2705        /* Allow interrupts to be recognized right away.  */
2706        ret = DISAS_PC_UPDATED_NOCHAIN;
2707        break;
2708#else
2709        goto invalid_opc;
2710#endif
2711
2712    case 0x1F:
2713        /* HW_ST (PALcode) */
2714#ifndef CONFIG_USER_ONLY
2715        REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE);
2716        {
2717            switch ((insn >> 12) & 0xF) {
2718            case 0x0:
2719                /* Longword physical access */
2720                va = load_gpr(ctx, ra);
2721                vb = load_gpr(ctx, rb);
2722                tmp = tcg_temp_new();
2723                tcg_gen_addi_i64(tmp, vb, disp12);
2724                tcg_gen_qemu_st_i64(va, tmp, MMU_PHYS_IDX, MO_LESL);
2725                tcg_temp_free(tmp);
2726                break;
2727            case 0x1:
2728                /* Quadword physical access */
2729                va = load_gpr(ctx, ra);
2730                vb = load_gpr(ctx, rb);
2731                tmp = tcg_temp_new();
2732                tcg_gen_addi_i64(tmp, vb, disp12);
2733                tcg_gen_qemu_st_i64(va, tmp, MMU_PHYS_IDX, MO_LEQ);
2734                tcg_temp_free(tmp);
2735                break;
2736            case 0x2:
2737                /* Longword physical access with lock */
2738                ret = gen_store_conditional(ctx, ra, rb, disp12,
2739                                            MMU_PHYS_IDX, MO_LESL);
2740                break;
2741            case 0x3:
2742                /* Quadword physical access with lock */
2743                ret = gen_store_conditional(ctx, ra, rb, disp12,
2744                                            MMU_PHYS_IDX, MO_LEQ);
2745                break;
2746            case 0x4:
2747                /* Longword virtual access */
2748                goto invalid_opc;
2749            case 0x5:
2750                /* Quadword virtual access */
2751                goto invalid_opc;
2752            case 0x6:
2753                /* Invalid */
2754                goto invalid_opc;
2755            case 0x7:
2756                /* Invalid */
2757                goto invalid_opc;
2758            case 0x8:
2759                /* Invalid */
2760                goto invalid_opc;
2761            case 0x9:
2762                /* Invalid */
2763                goto invalid_opc;
2764            case 0xA:
2765                /* Invalid */
2766                goto invalid_opc;
2767            case 0xB:
2768                /* Invalid */
2769                goto invalid_opc;
2770            case 0xC:
2771                /* Longword virtual access with alternate access mode */
2772                goto invalid_opc;
2773            case 0xD:
2774                /* Quadword virtual access with alternate access mode */
2775                goto invalid_opc;
2776            case 0xE:
2777                /* Invalid */
2778                goto invalid_opc;
2779            case 0xF:
2780                /* Invalid */
2781                goto invalid_opc;
2782            }
2783            break;
2784        }
2785#else
2786        goto invalid_opc;
2787#endif
2788    case 0x20:
2789        /* LDF */
2790        gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0);
2791        break;
2792    case 0x21:
2793        /* LDG */
2794        gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0);
2795        break;
2796    case 0x22:
2797        /* LDS */
2798        gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0);
2799        break;
2800    case 0x23:
2801        /* LDT */
2802        gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0);
2803        break;
2804    case 0x24:
2805        /* STF */
2806        gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0);
2807        break;
2808    case 0x25:
2809        /* STG */
2810        gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0);
2811        break;
2812    case 0x26:
2813        /* STS */
2814        gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0);
2815        break;
2816    case 0x27:
2817        /* STT */
2818        gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0);
2819        break;
2820    case 0x28:
2821        /* LDL */
2822        gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0);
2823        break;
2824    case 0x29:
2825        /* LDQ */
2826        gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0);
2827        break;
2828    case 0x2A:
2829        /* LDL_L */
2830        gen_load_mem(ctx, &gen_qemu_ldl_l, ra, rb, disp16, 0, 0);
2831        break;
2832    case 0x2B:
2833        /* LDQ_L */
2834        gen_load_mem(ctx, &gen_qemu_ldq_l, ra, rb, disp16, 0, 0);
2835        break;
2836    case 0x2C:
2837        /* STL */
2838        gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0);
2839        break;
2840    case 0x2D:
2841        /* STQ */
2842        gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0);
2843        break;
2844    case 0x2E:
2845        /* STL_C */
2846        ret = gen_store_conditional(ctx, ra, rb, disp16,
2847                                    ctx->mem_idx, MO_LESL);
2848        break;
2849    case 0x2F:
2850        /* STQ_C */
2851        ret = gen_store_conditional(ctx, ra, rb, disp16,
2852                                    ctx->mem_idx, MO_LEQ);
2853        break;
2854    case 0x30:
2855        /* BR */
2856        ret = gen_bdirect(ctx, ra, disp21);
2857        break;
2858    case 0x31: /* FBEQ */
2859        ret = gen_fbcond(ctx, TCG_COND_EQ, ra, disp21);
2860        break;
2861    case 0x32: /* FBLT */
2862        ret = gen_fbcond(ctx, TCG_COND_LT, ra, disp21);
2863        break;
2864    case 0x33: /* FBLE */
2865        ret = gen_fbcond(ctx, TCG_COND_LE, ra, disp21);
2866        break;
2867    case 0x34:
2868        /* BSR */
2869        ret = gen_bdirect(ctx, ra, disp21);
2870        break;
2871    case 0x35: /* FBNE */
2872        ret = gen_fbcond(ctx, TCG_COND_NE, ra, disp21);
2873        break;
2874    case 0x36: /* FBGE */
2875        ret = gen_fbcond(ctx, TCG_COND_GE, ra, disp21);
2876        break;
2877    case 0x37: /* FBGT */
2878        ret = gen_fbcond(ctx, TCG_COND_GT, ra, disp21);
2879        break;
2880    case 0x38:
2881        /* BLBC */
2882        ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 1);
2883        break;
2884    case 0x39:
2885        /* BEQ */
2886        ret = gen_bcond(ctx, TCG_COND_EQ, ra, disp21, 0);
2887        break;
2888    case 0x3A:
2889        /* BLT */
2890        ret = gen_bcond(ctx, TCG_COND_LT, ra, disp21, 0);
2891        break;
2892    case 0x3B:
2893        /* BLE */
2894        ret = gen_bcond(ctx, TCG_COND_LE, ra, disp21, 0);
2895        break;
2896    case 0x3C:
2897        /* BLBS */
2898        ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 1);
2899        break;
2900    case 0x3D:
2901        /* BNE */
2902        ret = gen_bcond(ctx, TCG_COND_NE, ra, disp21, 0);
2903        break;
2904    case 0x3E:
2905        /* BGE */
2906        ret = gen_bcond(ctx, TCG_COND_GE, ra, disp21, 0);
2907        break;
2908    case 0x3F:
2909        /* BGT */
2910        ret = gen_bcond(ctx, TCG_COND_GT, ra, disp21, 0);
2911        break;
2912    invalid_opc:
2913        ret = gen_invalid(ctx);
2914        break;
2915    }
2916
2917    return ret;
2918}
2919
2920static void alpha_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
2921{
2922    DisasContext *ctx = container_of(dcbase, DisasContext, base);
2923    CPUAlphaState *env = cpu->env_ptr;
2924    int64_t bound, mask;
2925
2926    ctx->tbflags = ctx->base.tb->flags;
2927    ctx->mem_idx = cpu_mmu_index(env, false);
2928    ctx->implver = env->implver;
2929    ctx->amask = env->amask;
2930
2931#ifdef CONFIG_USER_ONLY
2932    ctx->ir = cpu_std_ir;
2933#else
2934    ctx->palbr = env->palbr;
2935    ctx->ir = (ctx->tbflags & ENV_FLAG_PAL_MODE ? cpu_pal_ir : cpu_std_ir);
2936#endif
2937
2938    /* ??? Every TB begins with unset rounding mode, to be initialized on
2939       the first fp insn of the TB.  Alternately we could define a proper
2940       default for every TB (e.g. QUAL_RM_N or QUAL_RM_D) and make sure
2941       to reset the FP_STATUS to that default at the end of any TB that
2942       changes the default.  We could even (gasp) dynamiclly figure out
2943       what default would be most efficient given the running program.  */
2944    ctx->tb_rm = -1;
2945    /* Similarly for flush-to-zero.  */
2946    ctx->tb_ftz = -1;
2947
2948    ctx->zero = NULL;
2949    ctx->sink = NULL;
2950    ctx->lit = NULL;
2951
2952    /* Bound the number of insns to execute to those left on the page.  */
2953    if (in_superpage(ctx, ctx->base.pc_first)) {
2954        mask = -1ULL << 41;
2955    } else {
2956        mask = TARGET_PAGE_MASK;
2957    }
2958    bound = -(ctx->base.pc_first | mask) / 4;
2959    ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
2960}
2961
2962static void alpha_tr_tb_start(DisasContextBase *db, CPUState *cpu)
2963{
2964}
2965
2966static void alpha_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
2967{
2968    tcg_gen_insn_start(dcbase->pc_next);
2969}
2970
2971static bool alpha_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
2972                                      const CPUBreakpoint *bp)
2973{
2974    DisasContext *ctx = container_of(dcbase, DisasContext, base);
2975
2976    ctx->base.is_jmp = gen_excp(ctx, EXCP_DEBUG, 0);
2977
2978    /* The address covered by the breakpoint must be included in
2979       [tb->pc, tb->pc + tb->size) in order to for it to be
2980       properly cleared -- thus we increment the PC here so that
2981       the logic setting tb->size below does the right thing.  */
2982    ctx->base.pc_next += 4;
2983    return true;
2984}
2985
2986static void alpha_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
2987{
2988    DisasContext *ctx = container_of(dcbase, DisasContext, base);
2989    CPUAlphaState *env = cpu->env_ptr;
2990    uint32_t insn = translator_ldl(env, ctx->base.pc_next);
2991
2992    ctx->base.pc_next += 4;
2993    ctx->base.is_jmp = translate_one(ctx, insn);
2994
2995    free_context_temps(ctx);
2996    translator_loop_temp_check(&ctx->base);
2997}
2998
2999static void alpha_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
3000{
3001    DisasContext *ctx = container_of(dcbase, DisasContext, base);
3002
3003    switch (ctx->base.is_jmp) {
3004    case DISAS_NORETURN:
3005        break;
3006    case DISAS_TOO_MANY:
3007        if (use_goto_tb(ctx, ctx->base.pc_next)) {
3008            tcg_gen_goto_tb(0);
3009            tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
3010            tcg_gen_exit_tb(ctx->base.tb, 0);
3011        }
3012        /* FALLTHRU */
3013    case DISAS_PC_STALE:
3014        tcg_gen_movi_i64(cpu_pc, ctx->base.pc_next);
3015        /* FALLTHRU */
3016    case DISAS_PC_UPDATED:
3017        if (!use_exit_tb(ctx)) {
3018            tcg_gen_lookup_and_goto_ptr();
3019            break;
3020        }
3021        /* FALLTHRU */
3022    case DISAS_PC_UPDATED_NOCHAIN:
3023        if (ctx->base.singlestep_enabled) {
3024            gen_excp_1(EXCP_DEBUG, 0);
3025        } else {
3026            tcg_gen_exit_tb(NULL, 0);
3027        }
3028        break;
3029    default:
3030        g_assert_not_reached();
3031    }
3032}
3033
3034static void alpha_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
3035{
3036    qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
3037    log_target_disas(cpu, dcbase->pc_first, dcbase->tb->size);
3038}
3039
3040static const TranslatorOps alpha_tr_ops = {
3041    .init_disas_context = alpha_tr_init_disas_context,
3042    .tb_start           = alpha_tr_tb_start,
3043    .insn_start         = alpha_tr_insn_start,
3044    .breakpoint_check   = alpha_tr_breakpoint_check,
3045    .translate_insn     = alpha_tr_translate_insn,
3046    .tb_stop            = alpha_tr_tb_stop,
3047    .disas_log          = alpha_tr_disas_log,
3048};
3049
3050void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
3051{
3052    DisasContext dc;
3053    translator_loop(&alpha_tr_ops, &dc.base, cpu, tb, max_insns);
3054}
3055
3056void restore_state_to_opc(CPUAlphaState *env, TranslationBlock *tb,
3057                          target_ulong *data)
3058{
3059    env->pc = data[0];
3060}
3061