qemu/target/s390x/translate.c
<<
>>
Prefs
   1/*
   2 *  S/390 translation
   3 *
   4 *  Copyright (c) 2009 Ulrich Hecht
   5 *  Copyright (c) 2010 Alexander Graf
   6 *
   7 * This library is free software; you can redistribute it and/or
   8 * modify it under the terms of the GNU Lesser General Public
   9 * License as published by the Free Software Foundation; either
  10 * version 2 of the License, or (at your option) any later version.
  11 *
  12 * This library is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15 * Lesser General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU Lesser General Public
  18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  19 */
  20
  21/* #define DEBUG_INLINE_BRANCHES */
  22#define S390X_DEBUG_DISAS
  23/* #define S390X_DEBUG_DISAS_VERBOSE */
  24
  25#ifdef S390X_DEBUG_DISAS_VERBOSE
  26#  define LOG_DISAS(...) qemu_log(__VA_ARGS__)
  27#else
  28#  define LOG_DISAS(...) do { } while (0)
  29#endif
  30
  31#include "qemu/osdep.h"
  32#include "cpu.h"
  33#include "disas/disas.h"
  34#include "exec/exec-all.h"
  35#include "tcg-op.h"
  36#include "qemu/log.h"
  37#include "qemu/host-utils.h"
  38#include "exec/cpu_ldst.h"
  39
  40/* global register indexes */
  41static TCGv_env cpu_env;
  42
  43#include "exec/gen-icount.h"
  44#include "exec/helper-proto.h"
  45#include "exec/helper-gen.h"
  46
  47#include "trace-tcg.h"
  48#include "exec/log.h"
  49
  50
  51/* Information that (most) every instruction needs to manipulate.  */
  52typedef struct DisasContext DisasContext;
  53typedef struct DisasInsn DisasInsn;
  54typedef struct DisasFields DisasFields;
  55
  56struct DisasContext {
  57    struct TranslationBlock *tb;
  58    const DisasInsn *insn;
  59    DisasFields *fields;
  60    uint64_t ex_value;
  61    uint64_t pc, next_pc;
  62    uint32_t ilen;
  63    enum cc_op cc_op;
  64    bool singlestep_enabled;
  65};
  66
  67/* Information carried about a condition to be evaluated.  */
  68typedef struct {
  69    TCGCond cond:8;
  70    bool is_64;
  71    bool g1;
  72    bool g2;
  73    union {
  74        struct { TCGv_i64 a, b; } s64;
  75        struct { TCGv_i32 a, b; } s32;
  76    } u;
  77} DisasCompare;
  78
  79#define DISAS_EXCP 4
  80
  81#ifdef DEBUG_INLINE_BRANCHES
  82static uint64_t inline_branch_hit[CC_OP_MAX];
  83static uint64_t inline_branch_miss[CC_OP_MAX];
  84#endif
  85
  86static uint64_t pc_to_link_info(DisasContext *s, uint64_t pc)
  87{
  88    if (!(s->tb->flags & FLAG_MASK_64)) {
  89        if (s->tb->flags & FLAG_MASK_32) {
  90            return pc | 0x80000000;
  91        }
  92    }
  93    return pc;
  94}
  95
  96static TCGv_i64 psw_addr;
  97static TCGv_i64 psw_mask;
  98static TCGv_i64 gbea;
  99
 100static TCGv_i32 cc_op;
 101static TCGv_i64 cc_src;
 102static TCGv_i64 cc_dst;
 103static TCGv_i64 cc_vr;
 104
 105static char cpu_reg_names[32][4];
 106static TCGv_i64 regs[16];
 107static TCGv_i64 fregs[16];
 108
 109void s390x_translate_init(void)
 110{
 111    int i;
 112
 113    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
 114    tcg_ctx.tcg_env = cpu_env;
 115    psw_addr = tcg_global_mem_new_i64(cpu_env,
 116                                      offsetof(CPUS390XState, psw.addr),
 117                                      "psw_addr");
 118    psw_mask = tcg_global_mem_new_i64(cpu_env,
 119                                      offsetof(CPUS390XState, psw.mask),
 120                                      "psw_mask");
 121    gbea = tcg_global_mem_new_i64(cpu_env,
 122                                  offsetof(CPUS390XState, gbea),
 123                                  "gbea");
 124
 125    cc_op = tcg_global_mem_new_i32(cpu_env, offsetof(CPUS390XState, cc_op),
 126                                   "cc_op");
 127    cc_src = tcg_global_mem_new_i64(cpu_env, offsetof(CPUS390XState, cc_src),
 128                                    "cc_src");
 129    cc_dst = tcg_global_mem_new_i64(cpu_env, offsetof(CPUS390XState, cc_dst),
 130                                    "cc_dst");
 131    cc_vr = tcg_global_mem_new_i64(cpu_env, offsetof(CPUS390XState, cc_vr),
 132                                   "cc_vr");
 133
 134    for (i = 0; i < 16; i++) {
 135        snprintf(cpu_reg_names[i], sizeof(cpu_reg_names[0]), "r%d", i);
 136        regs[i] = tcg_global_mem_new(cpu_env,
 137                                     offsetof(CPUS390XState, regs[i]),
 138                                     cpu_reg_names[i]);
 139    }
 140
 141    for (i = 0; i < 16; i++) {
 142        snprintf(cpu_reg_names[i + 16], sizeof(cpu_reg_names[0]), "f%d", i);
 143        fregs[i] = tcg_global_mem_new(cpu_env,
 144                                      offsetof(CPUS390XState, vregs[i][0].d),
 145                                      cpu_reg_names[i + 16]);
 146    }
 147}
 148
 149static TCGv_i64 load_reg(int reg)
 150{
 151    TCGv_i64 r = tcg_temp_new_i64();
 152    tcg_gen_mov_i64(r, regs[reg]);
 153    return r;
 154}
 155
 156static TCGv_i64 load_freg32_i64(int reg)
 157{
 158    TCGv_i64 r = tcg_temp_new_i64();
 159    tcg_gen_shri_i64(r, fregs[reg], 32);
 160    return r;
 161}
 162
 163static void store_reg(int reg, TCGv_i64 v)
 164{
 165    tcg_gen_mov_i64(regs[reg], v);
 166}
 167
 168static void store_freg(int reg, TCGv_i64 v)
 169{
 170    tcg_gen_mov_i64(fregs[reg], v);
 171}
 172
 173static void store_reg32_i64(int reg, TCGv_i64 v)
 174{
 175    /* 32 bit register writes keep the upper half */
 176    tcg_gen_deposit_i64(regs[reg], regs[reg], v, 0, 32);
 177}
 178
 179static void store_reg32h_i64(int reg, TCGv_i64 v)
 180{
 181    tcg_gen_deposit_i64(regs[reg], regs[reg], v, 32, 32);
 182}
 183
 184static void store_freg32_i64(int reg, TCGv_i64 v)
 185{
 186    tcg_gen_deposit_i64(fregs[reg], fregs[reg], v, 32, 32);
 187}
 188
 189static void return_low128(TCGv_i64 dest)
 190{
 191    tcg_gen_ld_i64(dest, cpu_env, offsetof(CPUS390XState, retxl));
 192}
 193
 194static void update_psw_addr(DisasContext *s)
 195{
 196    /* psw.addr */
 197    tcg_gen_movi_i64(psw_addr, s->pc);
 198}
 199
 200static void per_branch(DisasContext *s, bool to_next)
 201{
 202#ifndef CONFIG_USER_ONLY
 203    tcg_gen_movi_i64(gbea, s->pc);
 204
 205    if (s->tb->flags & FLAG_MASK_PER) {
 206        TCGv_i64 next_pc = to_next ? tcg_const_i64(s->next_pc) : psw_addr;
 207        gen_helper_per_branch(cpu_env, gbea, next_pc);
 208        if (to_next) {
 209            tcg_temp_free_i64(next_pc);
 210        }
 211    }
 212#endif
 213}
 214
 215static void per_branch_cond(DisasContext *s, TCGCond cond,
 216                            TCGv_i64 arg1, TCGv_i64 arg2)
 217{
 218#ifndef CONFIG_USER_ONLY
 219    if (s->tb->flags & FLAG_MASK_PER) {
 220        TCGLabel *lab = gen_new_label();
 221        tcg_gen_brcond_i64(tcg_invert_cond(cond), arg1, arg2, lab);
 222
 223        tcg_gen_movi_i64(gbea, s->pc);
 224        gen_helper_per_branch(cpu_env, gbea, psw_addr);
 225
 226        gen_set_label(lab);
 227    } else {
 228        TCGv_i64 pc = tcg_const_i64(s->pc);
 229        tcg_gen_movcond_i64(cond, gbea, arg1, arg2, gbea, pc);
 230        tcg_temp_free_i64(pc);
 231    }
 232#endif
 233}
 234
 235static void per_breaking_event(DisasContext *s)
 236{
 237    tcg_gen_movi_i64(gbea, s->pc);
 238}
 239
 240static void update_cc_op(DisasContext *s)
 241{
 242    if (s->cc_op != CC_OP_DYNAMIC && s->cc_op != CC_OP_STATIC) {
 243        tcg_gen_movi_i32(cc_op, s->cc_op);
 244    }
 245}
 246
 247static void potential_page_fault(DisasContext *s)
 248{
 249    update_psw_addr(s);
 250    update_cc_op(s);
 251}
 252
 253static inline uint64_t ld_code2(CPUS390XState *env, uint64_t pc)
 254{
 255    return (uint64_t)cpu_lduw_code(env, pc);
 256}
 257
 258static inline uint64_t ld_code4(CPUS390XState *env, uint64_t pc)
 259{
 260    return (uint64_t)(uint32_t)cpu_ldl_code(env, pc);
 261}
 262
 263static int get_mem_index(DisasContext *s)
 264{
 265    switch (s->tb->flags & FLAG_MASK_ASC) {
 266    case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
 267        return 0;
 268    case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT:
 269        return 1;
 270    case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT:
 271        return 2;
 272    default:
 273        tcg_abort();
 274        break;
 275    }
 276}
 277
 278static void gen_exception(int excp)
 279{
 280    TCGv_i32 tmp = tcg_const_i32(excp);
 281    gen_helper_exception(cpu_env, tmp);
 282    tcg_temp_free_i32(tmp);
 283}
 284
 285static void gen_program_exception(DisasContext *s, int code)
 286{
 287    TCGv_i32 tmp;
 288
 289    /* Remember what pgm exeption this was.  */
 290    tmp = tcg_const_i32(code);
 291    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUS390XState, int_pgm_code));
 292    tcg_temp_free_i32(tmp);
 293
 294    tmp = tcg_const_i32(s->ilen);
 295    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUS390XState, int_pgm_ilen));
 296    tcg_temp_free_i32(tmp);
 297
 298    /* update the psw */
 299    update_psw_addr(s);
 300
 301    /* Save off cc.  */
 302    update_cc_op(s);
 303
 304    /* Trigger exception.  */
 305    gen_exception(EXCP_PGM);
 306}
 307
 308static inline void gen_illegal_opcode(DisasContext *s)
 309{
 310    gen_program_exception(s, PGM_OPERATION);
 311}
 312
 313static inline void gen_trap(DisasContext *s)
 314{
 315    TCGv_i32 t;
 316
 317    /* Set DXC to 0xff.  */
 318    t = tcg_temp_new_i32();
 319    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUS390XState, fpc));
 320    tcg_gen_ori_i32(t, t, 0xff00);
 321    tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, fpc));
 322    tcg_temp_free_i32(t);
 323
 324    gen_program_exception(s, PGM_DATA);
 325}
 326
 327#ifndef CONFIG_USER_ONLY
 328static void check_privileged(DisasContext *s)
 329{
 330    if (s->tb->flags & FLAG_MASK_PSTATE) {
 331        gen_program_exception(s, PGM_PRIVILEGED);
 332    }
 333}
 334#endif
 335
 336static TCGv_i64 get_address(DisasContext *s, int x2, int b2, int d2)
 337{
 338    TCGv_i64 tmp = tcg_temp_new_i64();
 339    bool need_31 = !(s->tb->flags & FLAG_MASK_64);
 340
 341    /* Note that d2 is limited to 20 bits, signed.  If we crop negative
 342       displacements early we create larger immedate addends.  */
 343
 344    /* Note that addi optimizes the imm==0 case.  */
 345    if (b2 && x2) {
 346        tcg_gen_add_i64(tmp, regs[b2], regs[x2]);
 347        tcg_gen_addi_i64(tmp, tmp, d2);
 348    } else if (b2) {
 349        tcg_gen_addi_i64(tmp, regs[b2], d2);
 350    } else if (x2) {
 351        tcg_gen_addi_i64(tmp, regs[x2], d2);
 352    } else {
 353        if (need_31) {
 354            d2 &= 0x7fffffff;
 355            need_31 = false;
 356        }
 357        tcg_gen_movi_i64(tmp, d2);
 358    }
 359    if (need_31) {
 360        tcg_gen_andi_i64(tmp, tmp, 0x7fffffff);
 361    }
 362
 363    return tmp;
 364}
 365
 366static inline bool live_cc_data(DisasContext *s)
 367{
 368    return (s->cc_op != CC_OP_DYNAMIC
 369            && s->cc_op != CC_OP_STATIC
 370            && s->cc_op > 3);
 371}
 372
 373static inline void gen_op_movi_cc(DisasContext *s, uint32_t val)
 374{
 375    if (live_cc_data(s)) {
 376        tcg_gen_discard_i64(cc_src);
 377        tcg_gen_discard_i64(cc_dst);
 378        tcg_gen_discard_i64(cc_vr);
 379    }
 380    s->cc_op = CC_OP_CONST0 + val;
 381}
 382
 383static void gen_op_update1_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 dst)
 384{
 385    if (live_cc_data(s)) {
 386        tcg_gen_discard_i64(cc_src);
 387        tcg_gen_discard_i64(cc_vr);
 388    }
 389    tcg_gen_mov_i64(cc_dst, dst);
 390    s->cc_op = op;
 391}
 392
 393static void gen_op_update2_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
 394                                  TCGv_i64 dst)
 395{
 396    if (live_cc_data(s)) {
 397        tcg_gen_discard_i64(cc_vr);
 398    }
 399    tcg_gen_mov_i64(cc_src, src);
 400    tcg_gen_mov_i64(cc_dst, dst);
 401    s->cc_op = op;
 402}
 403
 404static void gen_op_update3_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
 405                                  TCGv_i64 dst, TCGv_i64 vr)
 406{
 407    tcg_gen_mov_i64(cc_src, src);
 408    tcg_gen_mov_i64(cc_dst, dst);
 409    tcg_gen_mov_i64(cc_vr, vr);
 410    s->cc_op = op;
 411}
 412
 413static void set_cc_nz_u64(DisasContext *s, TCGv_i64 val)
 414{
 415    gen_op_update1_cc_i64(s, CC_OP_NZ, val);
 416}
 417
 418static void gen_set_cc_nz_f32(DisasContext *s, TCGv_i64 val)
 419{
 420    gen_op_update1_cc_i64(s, CC_OP_NZ_F32, val);
 421}
 422
 423static void gen_set_cc_nz_f64(DisasContext *s, TCGv_i64 val)
 424{
 425    gen_op_update1_cc_i64(s, CC_OP_NZ_F64, val);
 426}
 427
 428static void gen_set_cc_nz_f128(DisasContext *s, TCGv_i64 vh, TCGv_i64 vl)
 429{
 430    gen_op_update2_cc_i64(s, CC_OP_NZ_F128, vh, vl);
 431}
 432
 433/* CC value is in env->cc_op */
 434static void set_cc_static(DisasContext *s)
 435{
 436    if (live_cc_data(s)) {
 437        tcg_gen_discard_i64(cc_src);
 438        tcg_gen_discard_i64(cc_dst);
 439        tcg_gen_discard_i64(cc_vr);
 440    }
 441    s->cc_op = CC_OP_STATIC;
 442}
 443
 444/* calculates cc into cc_op */
 445static void gen_op_calc_cc(DisasContext *s)
 446{
 447    TCGv_i32 local_cc_op;
 448    TCGv_i64 dummy;
 449
 450    TCGV_UNUSED_I32(local_cc_op);
 451    TCGV_UNUSED_I64(dummy);
 452    switch (s->cc_op) {
 453    default:
 454        dummy = tcg_const_i64(0);
 455        /* FALLTHRU */
 456    case CC_OP_ADD_64:
 457    case CC_OP_ADDU_64:
 458    case CC_OP_ADDC_64:
 459    case CC_OP_SUB_64:
 460    case CC_OP_SUBU_64:
 461    case CC_OP_SUBB_64:
 462    case CC_OP_ADD_32:
 463    case CC_OP_ADDU_32:
 464    case CC_OP_ADDC_32:
 465    case CC_OP_SUB_32:
 466    case CC_OP_SUBU_32:
 467    case CC_OP_SUBB_32:
 468        local_cc_op = tcg_const_i32(s->cc_op);
 469        break;
 470    case CC_OP_CONST0:
 471    case CC_OP_CONST1:
 472    case CC_OP_CONST2:
 473    case CC_OP_CONST3:
 474    case CC_OP_STATIC:
 475    case CC_OP_DYNAMIC:
 476        break;
 477    }
 478
 479    switch (s->cc_op) {
 480    case CC_OP_CONST0:
 481    case CC_OP_CONST1:
 482    case CC_OP_CONST2:
 483    case CC_OP_CONST3:
 484        /* s->cc_op is the cc value */
 485        tcg_gen_movi_i32(cc_op, s->cc_op - CC_OP_CONST0);
 486        break;
 487    case CC_OP_STATIC:
 488        /* env->cc_op already is the cc value */
 489        break;
 490    case CC_OP_NZ:
 491    case CC_OP_ABS_64:
 492    case CC_OP_NABS_64:
 493    case CC_OP_ABS_32:
 494    case CC_OP_NABS_32:
 495    case CC_OP_LTGT0_32:
 496    case CC_OP_LTGT0_64:
 497    case CC_OP_COMP_32:
 498    case CC_OP_COMP_64:
 499    case CC_OP_NZ_F32:
 500    case CC_OP_NZ_F64:
 501    case CC_OP_FLOGR:
 502        /* 1 argument */
 503        gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, dummy, cc_dst, dummy);
 504        break;
 505    case CC_OP_ICM:
 506    case CC_OP_LTGT_32:
 507    case CC_OP_LTGT_64:
 508    case CC_OP_LTUGTU_32:
 509    case CC_OP_LTUGTU_64:
 510    case CC_OP_TM_32:
 511    case CC_OP_TM_64:
 512    case CC_OP_SLA_32:
 513    case CC_OP_SLA_64:
 514    case CC_OP_NZ_F128:
 515        /* 2 arguments */
 516        gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, dummy);
 517        break;
 518    case CC_OP_ADD_64:
 519    case CC_OP_ADDU_64:
 520    case CC_OP_ADDC_64:
 521    case CC_OP_SUB_64:
 522    case CC_OP_SUBU_64:
 523    case CC_OP_SUBB_64:
 524    case CC_OP_ADD_32:
 525    case CC_OP_ADDU_32:
 526    case CC_OP_ADDC_32:
 527    case CC_OP_SUB_32:
 528    case CC_OP_SUBU_32:
 529    case CC_OP_SUBB_32:
 530        /* 3 arguments */
 531        gen_helper_calc_cc(cc_op, cpu_env, local_cc_op, cc_src, cc_dst, cc_vr);
 532        break;
 533    case CC_OP_DYNAMIC:
 534        /* unknown operation - assume 3 arguments and cc_op in env */
 535        gen_helper_calc_cc(cc_op, cpu_env, cc_op, cc_src, cc_dst, cc_vr);
 536        break;
 537    default:
 538        tcg_abort();
 539    }
 540
 541    if (!TCGV_IS_UNUSED_I32(local_cc_op)) {
 542        tcg_temp_free_i32(local_cc_op);
 543    }
 544    if (!TCGV_IS_UNUSED_I64(dummy)) {
 545        tcg_temp_free_i64(dummy);
 546    }
 547
 548    /* We now have cc in cc_op as constant */
 549    set_cc_static(s);
 550}
 551
 552static bool use_exit_tb(DisasContext *s)
 553{
 554    return (s->singlestep_enabled ||
 555            (s->tb->cflags & CF_LAST_IO) ||
 556            (s->tb->flags & FLAG_MASK_PER));
 557}
 558
 559static bool use_goto_tb(DisasContext *s, uint64_t dest)
 560{
 561    if (unlikely(use_exit_tb(s))) {
 562        return false;
 563    }
 564#ifndef CONFIG_USER_ONLY
 565    return (dest & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) ||
 566           (dest & TARGET_PAGE_MASK) == (s->pc & TARGET_PAGE_MASK);
 567#else
 568    return true;
 569#endif
 570}
 571
 572static void account_noninline_branch(DisasContext *s, int cc_op)
 573{
 574#ifdef DEBUG_INLINE_BRANCHES
 575    inline_branch_miss[cc_op]++;
 576#endif
 577}
 578
 579static void account_inline_branch(DisasContext *s, int cc_op)
 580{
 581#ifdef DEBUG_INLINE_BRANCHES
 582    inline_branch_hit[cc_op]++;
 583#endif
 584}
 585
 586/* Table of mask values to comparison codes, given a comparison as input.
 587   For such, CC=3 should not be possible.  */
 588static const TCGCond ltgt_cond[16] = {
 589    TCG_COND_NEVER,  TCG_COND_NEVER,     /*    |    |    | x */
 590    TCG_COND_GT,     TCG_COND_GT,        /*    |    | GT | x */
 591    TCG_COND_LT,     TCG_COND_LT,        /*    | LT |    | x */
 592    TCG_COND_NE,     TCG_COND_NE,        /*    | LT | GT | x */
 593    TCG_COND_EQ,     TCG_COND_EQ,        /* EQ |    |    | x */
 594    TCG_COND_GE,     TCG_COND_GE,        /* EQ |    | GT | x */
 595    TCG_COND_LE,     TCG_COND_LE,        /* EQ | LT |    | x */
 596    TCG_COND_ALWAYS, TCG_COND_ALWAYS,    /* EQ | LT | GT | x */
 597};
 598
 599/* Table of mask values to comparison codes, given a logic op as input.
 600   For such, only CC=0 and CC=1 should be possible.  */
 601static const TCGCond nz_cond[16] = {
 602    TCG_COND_NEVER, TCG_COND_NEVER,      /*    |    | x | x */
 603    TCG_COND_NEVER, TCG_COND_NEVER,
 604    TCG_COND_NE, TCG_COND_NE,            /*    | NE | x | x */
 605    TCG_COND_NE, TCG_COND_NE,
 606    TCG_COND_EQ, TCG_COND_EQ,            /* EQ |    | x | x */
 607    TCG_COND_EQ, TCG_COND_EQ,
 608    TCG_COND_ALWAYS, TCG_COND_ALWAYS,    /* EQ | NE | x | x */
 609    TCG_COND_ALWAYS, TCG_COND_ALWAYS,
 610};
 611
 612/* Interpret MASK in terms of S->CC_OP, and fill in C with all the
 613   details required to generate a TCG comparison.  */
 614static void disas_jcc(DisasContext *s, DisasCompare *c, uint32_t mask)
 615{
 616    TCGCond cond;
 617    enum cc_op old_cc_op = s->cc_op;
 618
 619    if (mask == 15 || mask == 0) {
 620        c->cond = (mask ? TCG_COND_ALWAYS : TCG_COND_NEVER);
 621        c->u.s32.a = cc_op;
 622        c->u.s32.b = cc_op;
 623        c->g1 = c->g2 = true;
 624        c->is_64 = false;
 625        return;
 626    }
 627
 628    /* Find the TCG condition for the mask + cc op.  */
 629    switch (old_cc_op) {
 630    case CC_OP_LTGT0_32:
 631    case CC_OP_LTGT0_64:
 632    case CC_OP_LTGT_32:
 633    case CC_OP_LTGT_64:
 634        cond = ltgt_cond[mask];
 635        if (cond == TCG_COND_NEVER) {
 636            goto do_dynamic;
 637        }
 638        account_inline_branch(s, old_cc_op);
 639        break;
 640
 641    case CC_OP_LTUGTU_32:
 642    case CC_OP_LTUGTU_64:
 643        cond = tcg_unsigned_cond(ltgt_cond[mask]);
 644        if (cond == TCG_COND_NEVER) {
 645            goto do_dynamic;
 646        }
 647        account_inline_branch(s, old_cc_op);
 648        break;
 649
 650    case CC_OP_NZ:
 651        cond = nz_cond[mask];
 652        if (cond == TCG_COND_NEVER) {
 653            goto do_dynamic;
 654        }
 655        account_inline_branch(s, old_cc_op);
 656        break;
 657
 658    case CC_OP_TM_32:
 659    case CC_OP_TM_64:
 660        switch (mask) {
 661        case 8:
 662            cond = TCG_COND_EQ;
 663            break;
 664        case 4 | 2 | 1:
 665            cond = TCG_COND_NE;
 666            break;
 667        default:
 668            goto do_dynamic;
 669        }
 670        account_inline_branch(s, old_cc_op);
 671        break;
 672
 673    case CC_OP_ICM:
 674        switch (mask) {
 675        case 8:
 676            cond = TCG_COND_EQ;
 677            break;
 678        case 4 | 2 | 1:
 679        case 4 | 2:
 680            cond = TCG_COND_NE;
 681            break;
 682        default:
 683            goto do_dynamic;
 684        }
 685        account_inline_branch(s, old_cc_op);
 686        break;
 687
 688    case CC_OP_FLOGR:
 689        switch (mask & 0xa) {
 690        case 8: /* src == 0 -> no one bit found */
 691            cond = TCG_COND_EQ;
 692            break;
 693        case 2: /* src != 0 -> one bit found */
 694            cond = TCG_COND_NE;
 695            break;
 696        default:
 697            goto do_dynamic;
 698        }
 699        account_inline_branch(s, old_cc_op);
 700        break;
 701
 702    case CC_OP_ADDU_32:
 703    case CC_OP_ADDU_64:
 704        switch (mask) {
 705        case 8 | 2: /* vr == 0 */
 706            cond = TCG_COND_EQ;
 707            break;
 708        case 4 | 1: /* vr != 0 */
 709            cond = TCG_COND_NE;
 710            break;
 711        case 8 | 4: /* no carry -> vr >= src */
 712            cond = TCG_COND_GEU;
 713            break;
 714        case 2 | 1: /* carry -> vr < src */
 715            cond = TCG_COND_LTU;
 716            break;
 717        default:
 718            goto do_dynamic;
 719        }
 720        account_inline_branch(s, old_cc_op);
 721        break;
 722
 723    case CC_OP_SUBU_32:
 724    case CC_OP_SUBU_64:
 725        /* Note that CC=0 is impossible; treat it as dont-care.  */
 726        switch (mask & 7) {
 727        case 2: /* zero -> op1 == op2 */
 728            cond = TCG_COND_EQ;
 729            break;
 730        case 4 | 1: /* !zero -> op1 != op2 */
 731            cond = TCG_COND_NE;
 732            break;
 733        case 4: /* borrow (!carry) -> op1 < op2 */
 734            cond = TCG_COND_LTU;
 735            break;
 736        case 2 | 1: /* !borrow (carry) -> op1 >= op2 */
 737            cond = TCG_COND_GEU;
 738            break;
 739        default:
 740            goto do_dynamic;
 741        }
 742        account_inline_branch(s, old_cc_op);
 743        break;
 744
 745    default:
 746    do_dynamic:
 747        /* Calculate cc value.  */
 748        gen_op_calc_cc(s);
 749        /* FALLTHRU */
 750
 751    case CC_OP_STATIC:
 752        /* Jump based on CC.  We'll load up the real cond below;
 753           the assignment here merely avoids a compiler warning.  */
 754        account_noninline_branch(s, old_cc_op);
 755        old_cc_op = CC_OP_STATIC;
 756        cond = TCG_COND_NEVER;
 757        break;
 758    }
 759
 760    /* Load up the arguments of the comparison.  */
 761    c->is_64 = true;
 762    c->g1 = c->g2 = false;
 763    switch (old_cc_op) {
 764    case CC_OP_LTGT0_32:
 765        c->is_64 = false;
 766        c->u.s32.a = tcg_temp_new_i32();
 767        tcg_gen_extrl_i64_i32(c->u.s32.a, cc_dst);
 768        c->u.s32.b = tcg_const_i32(0);
 769        break;
 770    case CC_OP_LTGT_32:
 771    case CC_OP_LTUGTU_32:
 772    case CC_OP_SUBU_32:
 773        c->is_64 = false;
 774        c->u.s32.a = tcg_temp_new_i32();
 775        tcg_gen_extrl_i64_i32(c->u.s32.a, cc_src);
 776        c->u.s32.b = tcg_temp_new_i32();
 777        tcg_gen_extrl_i64_i32(c->u.s32.b, cc_dst);
 778        break;
 779
 780    case CC_OP_LTGT0_64:
 781    case CC_OP_NZ:
 782    case CC_OP_FLOGR:
 783        c->u.s64.a = cc_dst;
 784        c->u.s64.b = tcg_const_i64(0);
 785        c->g1 = true;
 786        break;
 787    case CC_OP_LTGT_64:
 788    case CC_OP_LTUGTU_64:
 789    case CC_OP_SUBU_64:
 790        c->u.s64.a = cc_src;
 791        c->u.s64.b = cc_dst;
 792        c->g1 = c->g2 = true;
 793        break;
 794
 795    case CC_OP_TM_32:
 796    case CC_OP_TM_64:
 797    case CC_OP_ICM:
 798        c->u.s64.a = tcg_temp_new_i64();
 799        c->u.s64.b = tcg_const_i64(0);
 800        tcg_gen_and_i64(c->u.s64.a, cc_src, cc_dst);
 801        break;
 802
 803    case CC_OP_ADDU_32:
 804        c->is_64 = false;
 805        c->u.s32.a = tcg_temp_new_i32();
 806        c->u.s32.b = tcg_temp_new_i32();
 807        tcg_gen_extrl_i64_i32(c->u.s32.a, cc_vr);
 808        if (cond == TCG_COND_EQ || cond == TCG_COND_NE) {
 809            tcg_gen_movi_i32(c->u.s32.b, 0);
 810        } else {
 811            tcg_gen_extrl_i64_i32(c->u.s32.b, cc_src);
 812        }
 813        break;
 814
 815    case CC_OP_ADDU_64:
 816        c->u.s64.a = cc_vr;
 817        c->g1 = true;
 818        if (cond == TCG_COND_EQ || cond == TCG_COND_NE) {
 819            c->u.s64.b = tcg_const_i64(0);
 820        } else {
 821            c->u.s64.b = cc_src;
 822            c->g2 = true;
 823        }
 824        break;
 825
 826    case CC_OP_STATIC:
 827        c->is_64 = false;
 828        c->u.s32.a = cc_op;
 829        c->g1 = true;
 830        switch (mask) {
 831        case 0x8 | 0x4 | 0x2: /* cc != 3 */
 832            cond = TCG_COND_NE;
 833            c->u.s32.b = tcg_const_i32(3);
 834            break;
 835        case 0x8 | 0x4 | 0x1: /* cc != 2 */
 836            cond = TCG_COND_NE;
 837            c->u.s32.b = tcg_const_i32(2);
 838            break;
 839        case 0x8 | 0x2 | 0x1: /* cc != 1 */
 840            cond = TCG_COND_NE;
 841            c->u.s32.b = tcg_const_i32(1);
 842            break;
 843        case 0x8 | 0x2: /* cc == 0 || cc == 2 => (cc & 1) == 0 */
 844            cond = TCG_COND_EQ;
 845            c->g1 = false;
 846            c->u.s32.a = tcg_temp_new_i32();
 847            c->u.s32.b = tcg_const_i32(0);
 848            tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
 849            break;
 850        case 0x8 | 0x4: /* cc < 2 */
 851            cond = TCG_COND_LTU;
 852            c->u.s32.b = tcg_const_i32(2);
 853            break;
 854        case 0x8: /* cc == 0 */
 855            cond = TCG_COND_EQ;
 856            c->u.s32.b = tcg_const_i32(0);
 857            break;
 858        case 0x4 | 0x2 | 0x1: /* cc != 0 */
 859            cond = TCG_COND_NE;
 860            c->u.s32.b = tcg_const_i32(0);
 861            break;
 862        case 0x4 | 0x1: /* cc == 1 || cc == 3 => (cc & 1) != 0 */
 863            cond = TCG_COND_NE;
 864            c->g1 = false;
 865            c->u.s32.a = tcg_temp_new_i32();
 866            c->u.s32.b = tcg_const_i32(0);
 867            tcg_gen_andi_i32(c->u.s32.a, cc_op, 1);
 868            break;
 869        case 0x4: /* cc == 1 */
 870            cond = TCG_COND_EQ;
 871            c->u.s32.b = tcg_const_i32(1);
 872            break;
 873        case 0x2 | 0x1: /* cc > 1 */
 874            cond = TCG_COND_GTU;
 875            c->u.s32.b = tcg_const_i32(1);
 876            break;
 877        case 0x2: /* cc == 2 */
 878            cond = TCG_COND_EQ;
 879            c->u.s32.b = tcg_const_i32(2);
 880            break;
 881        case 0x1: /* cc == 3 */
 882            cond = TCG_COND_EQ;
 883            c->u.s32.b = tcg_const_i32(3);
 884            break;
 885        default:
 886            /* CC is masked by something else: (8 >> cc) & mask.  */
 887            cond = TCG_COND_NE;
 888            c->g1 = false;
 889            c->u.s32.a = tcg_const_i32(8);
 890            c->u.s32.b = tcg_const_i32(0);
 891            tcg_gen_shr_i32(c->u.s32.a, c->u.s32.a, cc_op);
 892            tcg_gen_andi_i32(c->u.s32.a, c->u.s32.a, mask);
 893            break;
 894        }
 895        break;
 896
 897    default:
 898        abort();
 899    }
 900    c->cond = cond;
 901}
 902
 903static void free_compare(DisasCompare *c)
 904{
 905    if (!c->g1) {
 906        if (c->is_64) {
 907            tcg_temp_free_i64(c->u.s64.a);
 908        } else {
 909            tcg_temp_free_i32(c->u.s32.a);
 910        }
 911    }
 912    if (!c->g2) {
 913        if (c->is_64) {
 914            tcg_temp_free_i64(c->u.s64.b);
 915        } else {
 916            tcg_temp_free_i32(c->u.s32.b);
 917        }
 918    }
 919}
 920
 921/* ====================================================================== */
 922/* Define the insn format enumeration.  */
 923#define F0(N)                         FMT_##N,
 924#define F1(N, X1)                     F0(N)
 925#define F2(N, X1, X2)                 F0(N)
 926#define F3(N, X1, X2, X3)             F0(N)
 927#define F4(N, X1, X2, X3, X4)         F0(N)
 928#define F5(N, X1, X2, X3, X4, X5)     F0(N)
 929
 930typedef enum {
 931#include "insn-format.def"
 932} DisasFormat;
 933
 934#undef F0
 935#undef F1
 936#undef F2
 937#undef F3
 938#undef F4
 939#undef F5
 940
 941/* Define a structure to hold the decoded fields.  We'll store each inside
 942   an array indexed by an enum.  In order to conserve memory, we'll arrange
 943   for fields that do not exist at the same time to overlap, thus the "C"
 944   for compact.  For checking purposes there is an "O" for original index
 945   as well that will be applied to availability bitmaps.  */
 946
 947enum DisasFieldIndexO {
 948    FLD_O_r1,
 949    FLD_O_r2,
 950    FLD_O_r3,
 951    FLD_O_m1,
 952    FLD_O_m3,
 953    FLD_O_m4,
 954    FLD_O_b1,
 955    FLD_O_b2,
 956    FLD_O_b4,
 957    FLD_O_d1,
 958    FLD_O_d2,
 959    FLD_O_d4,
 960    FLD_O_x2,
 961    FLD_O_l1,
 962    FLD_O_l2,
 963    FLD_O_i1,
 964    FLD_O_i2,
 965    FLD_O_i3,
 966    FLD_O_i4,
 967    FLD_O_i5
 968};
 969
 970enum DisasFieldIndexC {
 971    FLD_C_r1 = 0,
 972    FLD_C_m1 = 0,
 973    FLD_C_b1 = 0,
 974    FLD_C_i1 = 0,
 975
 976    FLD_C_r2 = 1,
 977    FLD_C_b2 = 1,
 978    FLD_C_i2 = 1,
 979
 980    FLD_C_r3 = 2,
 981    FLD_C_m3 = 2,
 982    FLD_C_i3 = 2,
 983
 984    FLD_C_m4 = 3,
 985    FLD_C_b4 = 3,
 986    FLD_C_i4 = 3,
 987    FLD_C_l1 = 3,
 988
 989    FLD_C_i5 = 4,
 990    FLD_C_d1 = 4,
 991
 992    FLD_C_d2 = 5,
 993
 994    FLD_C_d4 = 6,
 995    FLD_C_x2 = 6,
 996    FLD_C_l2 = 6,
 997
 998    NUM_C_FIELD = 7
 999};
1000
1001struct DisasFields {
1002    uint64_t raw_insn;
1003    unsigned op:8;
1004    unsigned op2:8;
1005    unsigned presentC:16;
1006    unsigned int presentO;
1007    int c[NUM_C_FIELD];
1008};
1009
1010/* This is the way fields are to be accessed out of DisasFields.  */
1011#define have_field(S, F)  have_field1((S), FLD_O_##F)
1012#define get_field(S, F)   get_field1((S), FLD_O_##F, FLD_C_##F)
1013
1014static bool have_field1(const DisasFields *f, enum DisasFieldIndexO c)
1015{
1016    return (f->presentO >> c) & 1;
1017}
1018
1019static int get_field1(const DisasFields *f, enum DisasFieldIndexO o,
1020                      enum DisasFieldIndexC c)
1021{
1022    assert(have_field1(f, o));
1023    return f->c[c];
1024}
1025
1026/* Describe the layout of each field in each format.  */
1027typedef struct DisasField {
1028    unsigned int beg:8;
1029    unsigned int size:8;
1030    unsigned int type:2;
1031    unsigned int indexC:6;
1032    enum DisasFieldIndexO indexO:8;
1033} DisasField;
1034
1035typedef struct DisasFormatInfo {
1036    DisasField op[NUM_C_FIELD];
1037} DisasFormatInfo;
1038
1039#define R(N, B)       {  B,  4, 0, FLD_C_r##N, FLD_O_r##N }
1040#define M(N, B)       {  B,  4, 0, FLD_C_m##N, FLD_O_m##N }
1041#define BD(N, BB, BD) { BB,  4, 0, FLD_C_b##N, FLD_O_b##N }, \
1042                      { BD, 12, 0, FLD_C_d##N, FLD_O_d##N }
1043#define BXD(N)        { 16,  4, 0, FLD_C_b##N, FLD_O_b##N }, \
1044                      { 12,  4, 0, FLD_C_x##N, FLD_O_x##N }, \
1045                      { 20, 12, 0, FLD_C_d##N, FLD_O_d##N }
1046#define BDL(N)        { 16,  4, 0, FLD_C_b##N, FLD_O_b##N }, \
1047                      { 20, 20, 2, FLD_C_d##N, FLD_O_d##N }
1048#define BXDL(N)       { 16,  4, 0, FLD_C_b##N, FLD_O_b##N }, \
1049                      { 12,  4, 0, FLD_C_x##N, FLD_O_x##N }, \
1050                      { 20, 20, 2, FLD_C_d##N, FLD_O_d##N }
1051#define I(N, B, S)    {  B,  S, 1, FLD_C_i##N, FLD_O_i##N }
1052#define L(N, B, S)    {  B,  S, 0, FLD_C_l##N, FLD_O_l##N }
1053
1054#define F0(N)                     { { } },
1055#define F1(N, X1)                 { { X1 } },
1056#define F2(N, X1, X2)             { { X1, X2 } },
1057#define F3(N, X1, X2, X3)         { { X1, X2, X3 } },
1058#define F4(N, X1, X2, X3, X4)     { { X1, X2, X3, X4 } },
1059#define F5(N, X1, X2, X3, X4, X5) { { X1, X2, X3, X4, X5 } },
1060
1061static const DisasFormatInfo format_info[] = {
1062#include "insn-format.def"
1063};
1064
1065#undef F0
1066#undef F1
1067#undef F2
1068#undef F3
1069#undef F4
1070#undef F5
1071#undef R
1072#undef M
1073#undef BD
1074#undef BXD
1075#undef BDL
1076#undef BXDL
1077#undef I
1078#undef L
1079
1080/* Generally, we'll extract operands into this structures, operate upon
1081   them, and store them back.  See the "in1", "in2", "prep", "wout" sets
1082   of routines below for more details.  */
1083typedef struct {
1084    bool g_out, g_out2, g_in1, g_in2;
1085    TCGv_i64 out, out2, in1, in2;
1086    TCGv_i64 addr1;
1087} DisasOps;
1088
1089/* Instructions can place constraints on their operands, raising specification
1090   exceptions if they are violated.  To make this easy to automate, each "in1",
1091   "in2", "prep", "wout" helper will have a SPEC_<name> define that equals one
1092   of the following, or 0.  To make this easy to document, we'll put the
1093   SPEC_<name> defines next to <name>.  */
1094
1095#define SPEC_r1_even    1
1096#define SPEC_r2_even    2
1097#define SPEC_r3_even    4
1098#define SPEC_r1_f128    8
1099#define SPEC_r2_f128    16
1100
1101/* Return values from translate_one, indicating the state of the TB.  */
1102typedef enum {
1103    /* Continue the TB.  */
1104    NO_EXIT,
1105    /* We have emitted one or more goto_tb.  No fixup required.  */
1106    EXIT_GOTO_TB,
1107    /* We are not using a goto_tb (for whatever reason), but have updated
1108       the PC (for whatever reason), so there's no need to do it again on
1109       exiting the TB.  */
1110    EXIT_PC_UPDATED,
1111    /* We have updated the PC and CC values.  */
1112    EXIT_PC_CC_UPDATED,
1113    /* We are exiting the TB, but have neither emitted a goto_tb, nor
1114       updated the PC for the next instruction to be executed.  */
1115    EXIT_PC_STALE,
1116    /* We are exiting the TB to the main loop.  */
1117    EXIT_PC_STALE_NOCHAIN,
1118    /* We are ending the TB with a noreturn function call, e.g. longjmp.
1119       No following code will be executed.  */
1120    EXIT_NORETURN,
1121} ExitStatus;
1122
1123struct DisasInsn {
1124    unsigned opc:16;
1125    DisasFormat fmt:8;
1126    unsigned fac:8;
1127    unsigned spec:8;
1128
1129    const char *name;
1130
1131    void (*help_in1)(DisasContext *, DisasFields *, DisasOps *);
1132    void (*help_in2)(DisasContext *, DisasFields *, DisasOps *);
1133    void (*help_prep)(DisasContext *, DisasFields *, DisasOps *);
1134    void (*help_wout)(DisasContext *, DisasFields *, DisasOps *);
1135    void (*help_cout)(DisasContext *, DisasOps *);
1136    ExitStatus (*help_op)(DisasContext *, DisasOps *);
1137
1138    uint64_t data;
1139};
1140
1141/* ====================================================================== */
1142/* Miscellaneous helpers, used by several operations.  */
1143
1144static void help_l2_shift(DisasContext *s, DisasFields *f,
1145                          DisasOps *o, int mask)
1146{
1147    int b2 = get_field(f, b2);
1148    int d2 = get_field(f, d2);
1149
1150    if (b2 == 0) {
1151        o->in2 = tcg_const_i64(d2 & mask);
1152    } else {
1153        o->in2 = get_address(s, 0, b2, d2);
1154        tcg_gen_andi_i64(o->in2, o->in2, mask);
1155    }
1156}
1157
1158static ExitStatus help_goto_direct(DisasContext *s, uint64_t dest)
1159{
1160    if (dest == s->next_pc) {
1161        per_branch(s, true);
1162        return NO_EXIT;
1163    }
1164    if (use_goto_tb(s, dest)) {
1165        update_cc_op(s);
1166        per_breaking_event(s);
1167        tcg_gen_goto_tb(0);
1168        tcg_gen_movi_i64(psw_addr, dest);
1169        tcg_gen_exit_tb((uintptr_t)s->tb);
1170        return EXIT_GOTO_TB;
1171    } else {
1172        tcg_gen_movi_i64(psw_addr, dest);
1173        per_branch(s, false);
1174        return EXIT_PC_UPDATED;
1175    }
1176}
1177
1178static ExitStatus help_branch(DisasContext *s, DisasCompare *c,
1179                              bool is_imm, int imm, TCGv_i64 cdest)
1180{
1181    ExitStatus ret;
1182    uint64_t dest = s->pc + 2 * imm;
1183    TCGLabel *lab;
1184
1185    /* Take care of the special cases first.  */
1186    if (c->cond == TCG_COND_NEVER) {
1187        ret = NO_EXIT;
1188        goto egress;
1189    }
1190    if (is_imm) {
1191        if (dest == s->next_pc) {
1192            /* Branch to next.  */
1193            per_branch(s, true);
1194            ret = NO_EXIT;
1195            goto egress;
1196        }
1197        if (c->cond == TCG_COND_ALWAYS) {
1198            ret = help_goto_direct(s, dest);
1199            goto egress;
1200        }
1201    } else {
1202        if (TCGV_IS_UNUSED_I64(cdest)) {
1203            /* E.g. bcr %r0 -> no branch.  */
1204            ret = NO_EXIT;
1205            goto egress;
1206        }
1207        if (c->cond == TCG_COND_ALWAYS) {
1208            tcg_gen_mov_i64(psw_addr, cdest);
1209            per_branch(s, false);
1210            ret = EXIT_PC_UPDATED;
1211            goto egress;
1212        }
1213    }
1214
1215    if (use_goto_tb(s, s->next_pc)) {
1216        if (is_imm && use_goto_tb(s, dest)) {
1217            /* Both exits can use goto_tb.  */
1218            update_cc_op(s);
1219
1220            lab = gen_new_label();
1221            if (c->is_64) {
1222                tcg_gen_brcond_i64(c->cond, c->u.s64.a, c->u.s64.b, lab);
1223            } else {
1224                tcg_gen_brcond_i32(c->cond, c->u.s32.a, c->u.s32.b, lab);
1225            }
1226
1227            /* Branch not taken.  */
1228            tcg_gen_goto_tb(0);
1229            tcg_gen_movi_i64(psw_addr, s->next_pc);
1230            tcg_gen_exit_tb((uintptr_t)s->tb + 0);
1231
1232            /* Branch taken.  */
1233            gen_set_label(lab);
1234            per_breaking_event(s);
1235            tcg_gen_goto_tb(1);
1236            tcg_gen_movi_i64(psw_addr, dest);
1237            tcg_gen_exit_tb((uintptr_t)s->tb + 1);
1238
1239            ret = EXIT_GOTO_TB;
1240        } else {
1241            /* Fallthru can use goto_tb, but taken branch cannot.  */
1242            /* Store taken branch destination before the brcond.  This
1243               avoids having to allocate a new local temp to hold it.
1244               We'll overwrite this in the not taken case anyway.  */
1245            if (!is_imm) {
1246                tcg_gen_mov_i64(psw_addr, cdest);
1247            }
1248
1249            lab = gen_new_label();
1250            if (c->is_64) {
1251                tcg_gen_brcond_i64(c->cond, c->u.s64.a, c->u.s64.b, lab);
1252            } else {
1253                tcg_gen_brcond_i32(c->cond, c->u.s32.a, c->u.s32.b, lab);
1254            }
1255
1256            /* Branch not taken.  */
1257            update_cc_op(s);
1258            tcg_gen_goto_tb(0);
1259            tcg_gen_movi_i64(psw_addr, s->next_pc);
1260            tcg_gen_exit_tb((uintptr_t)s->tb + 0);
1261
1262            gen_set_label(lab);
1263            if (is_imm) {
1264                tcg_gen_movi_i64(psw_addr, dest);
1265            }
1266            per_breaking_event(s);
1267            ret = EXIT_PC_UPDATED;
1268        }
1269    } else {
1270        /* Fallthru cannot use goto_tb.  This by itself is vanishingly rare.
1271           Most commonly we're single-stepping or some other condition that
1272           disables all use of goto_tb.  Just update the PC and exit.  */
1273
1274        TCGv_i64 next = tcg_const_i64(s->next_pc);
1275        if (is_imm) {
1276            cdest = tcg_const_i64(dest);
1277        }
1278
1279        if (c->is_64) {
1280            tcg_gen_movcond_i64(c->cond, psw_addr, c->u.s64.a, c->u.s64.b,
1281                                cdest, next);
1282            per_branch_cond(s, c->cond, c->u.s64.a, c->u.s64.b);
1283        } else {
1284            TCGv_i32 t0 = tcg_temp_new_i32();
1285            TCGv_i64 t1 = tcg_temp_new_i64();
1286            TCGv_i64 z = tcg_const_i64(0);
1287            tcg_gen_setcond_i32(c->cond, t0, c->u.s32.a, c->u.s32.b);
1288            tcg_gen_extu_i32_i64(t1, t0);
1289            tcg_temp_free_i32(t0);
1290            tcg_gen_movcond_i64(TCG_COND_NE, psw_addr, t1, z, cdest, next);
1291            per_branch_cond(s, TCG_COND_NE, t1, z);
1292            tcg_temp_free_i64(t1);
1293            tcg_temp_free_i64(z);
1294        }
1295
1296        if (is_imm) {
1297            tcg_temp_free_i64(cdest);
1298        }
1299        tcg_temp_free_i64(next);
1300
1301        ret = EXIT_PC_UPDATED;
1302    }
1303
1304 egress:
1305    free_compare(c);
1306    return ret;
1307}
1308
1309/* ====================================================================== */
1310/* The operations.  These perform the bulk of the work for any insn,
1311   usually after the operands have been loaded and output initialized.  */
1312
1313static ExitStatus op_abs(DisasContext *s, DisasOps *o)
1314{
1315    TCGv_i64 z, n;
1316    z = tcg_const_i64(0);
1317    n = tcg_temp_new_i64();
1318    tcg_gen_neg_i64(n, o->in2);
1319    tcg_gen_movcond_i64(TCG_COND_LT, o->out, o->in2, z, n, o->in2);
1320    tcg_temp_free_i64(n);
1321    tcg_temp_free_i64(z);
1322    return NO_EXIT;
1323}
1324
1325static ExitStatus op_absf32(DisasContext *s, DisasOps *o)
1326{
1327    tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffull);
1328    return NO_EXIT;
1329}
1330
1331static ExitStatus op_absf64(DisasContext *s, DisasOps *o)
1332{
1333    tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffffffffffull);
1334    return NO_EXIT;
1335}
1336
1337static ExitStatus op_absf128(DisasContext *s, DisasOps *o)
1338{
1339    tcg_gen_andi_i64(o->out, o->in1, 0x7fffffffffffffffull);
1340    tcg_gen_mov_i64(o->out2, o->in2);
1341    return NO_EXIT;
1342}
1343
1344static ExitStatus op_add(DisasContext *s, DisasOps *o)
1345{
1346    tcg_gen_add_i64(o->out, o->in1, o->in2);
1347    return NO_EXIT;
1348}
1349
1350static ExitStatus op_addc(DisasContext *s, DisasOps *o)
1351{
1352    DisasCompare cmp;
1353    TCGv_i64 carry;
1354
1355    tcg_gen_add_i64(o->out, o->in1, o->in2);
1356
1357    /* The carry flag is the msb of CC, therefore the branch mask that would
1358       create that comparison is 3.  Feeding the generated comparison to
1359       setcond produces the carry flag that we desire.  */
1360    disas_jcc(s, &cmp, 3);
1361    carry = tcg_temp_new_i64();
1362    if (cmp.is_64) {
1363        tcg_gen_setcond_i64(cmp.cond, carry, cmp.u.s64.a, cmp.u.s64.b);
1364    } else {
1365        TCGv_i32 t = tcg_temp_new_i32();
1366        tcg_gen_setcond_i32(cmp.cond, t, cmp.u.s32.a, cmp.u.s32.b);
1367        tcg_gen_extu_i32_i64(carry, t);
1368        tcg_temp_free_i32(t);
1369    }
1370    free_compare(&cmp);
1371
1372    tcg_gen_add_i64(o->out, o->out, carry);
1373    tcg_temp_free_i64(carry);
1374    return NO_EXIT;
1375}
1376
1377static ExitStatus op_aeb(DisasContext *s, DisasOps *o)
1378{
1379    gen_helper_aeb(o->out, cpu_env, o->in1, o->in2);
1380    return NO_EXIT;
1381}
1382
1383static ExitStatus op_adb(DisasContext *s, DisasOps *o)
1384{
1385    gen_helper_adb(o->out, cpu_env, o->in1, o->in2);
1386    return NO_EXIT;
1387}
1388
1389static ExitStatus op_axb(DisasContext *s, DisasOps *o)
1390{
1391    gen_helper_axb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
1392    return_low128(o->out2);
1393    return NO_EXIT;
1394}
1395
1396static ExitStatus op_and(DisasContext *s, DisasOps *o)
1397{
1398    tcg_gen_and_i64(o->out, o->in1, o->in2);
1399    return NO_EXIT;
1400}
1401
1402static ExitStatus op_andi(DisasContext *s, DisasOps *o)
1403{
1404    int shift = s->insn->data & 0xff;
1405    int size = s->insn->data >> 8;
1406    uint64_t mask = ((1ull << size) - 1) << shift;
1407
1408    assert(!o->g_in2);
1409    tcg_gen_shli_i64(o->in2, o->in2, shift);
1410    tcg_gen_ori_i64(o->in2, o->in2, ~mask);
1411    tcg_gen_and_i64(o->out, o->in1, o->in2);
1412
1413    /* Produce the CC from only the bits manipulated.  */
1414    tcg_gen_andi_i64(cc_dst, o->out, mask);
1415    set_cc_nz_u64(s, cc_dst);
1416    return NO_EXIT;
1417}
1418
1419static ExitStatus op_bas(DisasContext *s, DisasOps *o)
1420{
1421    tcg_gen_movi_i64(o->out, pc_to_link_info(s, s->next_pc));
1422    if (!TCGV_IS_UNUSED_I64(o->in2)) {
1423        tcg_gen_mov_i64(psw_addr, o->in2);
1424        per_branch(s, false);
1425        return EXIT_PC_UPDATED;
1426    } else {
1427        return NO_EXIT;
1428    }
1429}
1430
1431static ExitStatus op_basi(DisasContext *s, DisasOps *o)
1432{
1433    tcg_gen_movi_i64(o->out, pc_to_link_info(s, s->next_pc));
1434    return help_goto_direct(s, s->pc + 2 * get_field(s->fields, i2));
1435}
1436
1437static ExitStatus op_bc(DisasContext *s, DisasOps *o)
1438{
1439    int m1 = get_field(s->fields, m1);
1440    bool is_imm = have_field(s->fields, i2);
1441    int imm = is_imm ? get_field(s->fields, i2) : 0;
1442    DisasCompare c;
1443
1444    /* BCR with R2 = 0 causes no branching */
1445    if (have_field(s->fields, r2) && get_field(s->fields, r2) == 0) {
1446        if (m1 == 14) {
1447            /* Perform serialization */
1448            /* FIXME: check for fast-BCR-serialization facility */
1449            tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
1450        }
1451        if (m1 == 15) {
1452            /* Perform serialization */
1453            /* FIXME: perform checkpoint-synchronisation */
1454            tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
1455        }
1456        return NO_EXIT;
1457    }
1458
1459    disas_jcc(s, &c, m1);
1460    return help_branch(s, &c, is_imm, imm, o->in2);
1461}
1462
1463static ExitStatus op_bct32(DisasContext *s, DisasOps *o)
1464{
1465    int r1 = get_field(s->fields, r1);
1466    bool is_imm = have_field(s->fields, i2);
1467    int imm = is_imm ? get_field(s->fields, i2) : 0;
1468    DisasCompare c;
1469    TCGv_i64 t;
1470
1471    c.cond = TCG_COND_NE;
1472    c.is_64 = false;
1473    c.g1 = false;
1474    c.g2 = false;
1475
1476    t = tcg_temp_new_i64();
1477    tcg_gen_subi_i64(t, regs[r1], 1);
1478    store_reg32_i64(r1, t);
1479    c.u.s32.a = tcg_temp_new_i32();
1480    c.u.s32.b = tcg_const_i32(0);
1481    tcg_gen_extrl_i64_i32(c.u.s32.a, t);
1482    tcg_temp_free_i64(t);
1483
1484    return help_branch(s, &c, is_imm, imm, o->in2);
1485}
1486
1487static ExitStatus op_bcth(DisasContext *s, DisasOps *o)
1488{
1489    int r1 = get_field(s->fields, r1);
1490    int imm = get_field(s->fields, i2);
1491    DisasCompare c;
1492    TCGv_i64 t;
1493
1494    c.cond = TCG_COND_NE;
1495    c.is_64 = false;
1496    c.g1 = false;
1497    c.g2 = false;
1498
1499    t = tcg_temp_new_i64();
1500    tcg_gen_shri_i64(t, regs[r1], 32);
1501    tcg_gen_subi_i64(t, t, 1);
1502    store_reg32h_i64(r1, t);
1503    c.u.s32.a = tcg_temp_new_i32();
1504    c.u.s32.b = tcg_const_i32(0);
1505    tcg_gen_extrl_i64_i32(c.u.s32.a, t);
1506    tcg_temp_free_i64(t);
1507
1508    return help_branch(s, &c, 1, imm, o->in2);
1509}
1510
1511static ExitStatus op_bct64(DisasContext *s, DisasOps *o)
1512{
1513    int r1 = get_field(s->fields, r1);
1514    bool is_imm = have_field(s->fields, i2);
1515    int imm = is_imm ? get_field(s->fields, i2) : 0;
1516    DisasCompare c;
1517
1518    c.cond = TCG_COND_NE;
1519    c.is_64 = true;
1520    c.g1 = true;
1521    c.g2 = false;
1522
1523    tcg_gen_subi_i64(regs[r1], regs[r1], 1);
1524    c.u.s64.a = regs[r1];
1525    c.u.s64.b = tcg_const_i64(0);
1526
1527    return help_branch(s, &c, is_imm, imm, o->in2);
1528}
1529
1530static ExitStatus op_bx32(DisasContext *s, DisasOps *o)
1531{
1532    int r1 = get_field(s->fields, r1);
1533    int r3 = get_field(s->fields, r3);
1534    bool is_imm = have_field(s->fields, i2);
1535    int imm = is_imm ? get_field(s->fields, i2) : 0;
1536    DisasCompare c;
1537    TCGv_i64 t;
1538
1539    c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT);
1540    c.is_64 = false;
1541    c.g1 = false;
1542    c.g2 = false;
1543
1544    t = tcg_temp_new_i64();
1545    tcg_gen_add_i64(t, regs[r1], regs[r3]);
1546    c.u.s32.a = tcg_temp_new_i32();
1547    c.u.s32.b = tcg_temp_new_i32();
1548    tcg_gen_extrl_i64_i32(c.u.s32.a, t);
1549    tcg_gen_extrl_i64_i32(c.u.s32.b, regs[r3 | 1]);
1550    store_reg32_i64(r1, t);
1551    tcg_temp_free_i64(t);
1552
1553    return help_branch(s, &c, is_imm, imm, o->in2);
1554}
1555
1556static ExitStatus op_bx64(DisasContext *s, DisasOps *o)
1557{
1558    int r1 = get_field(s->fields, r1);
1559    int r3 = get_field(s->fields, r3);
1560    bool is_imm = have_field(s->fields, i2);
1561    int imm = is_imm ? get_field(s->fields, i2) : 0;
1562    DisasCompare c;
1563
1564    c.cond = (s->insn->data ? TCG_COND_LE : TCG_COND_GT);
1565    c.is_64 = true;
1566
1567    if (r1 == (r3 | 1)) {
1568        c.u.s64.b = load_reg(r3 | 1);
1569        c.g2 = false;
1570    } else {
1571        c.u.s64.b = regs[r3 | 1];
1572        c.g2 = true;
1573    }
1574
1575    tcg_gen_add_i64(regs[r1], regs[r1], regs[r3]);
1576    c.u.s64.a = regs[r1];
1577    c.g1 = true;
1578
1579    return help_branch(s, &c, is_imm, imm, o->in2);
1580}
1581
1582static ExitStatus op_cj(DisasContext *s, DisasOps *o)
1583{
1584    int imm, m3 = get_field(s->fields, m3);
1585    bool is_imm;
1586    DisasCompare c;
1587
1588    c.cond = ltgt_cond[m3];
1589    if (s->insn->data) {
1590        c.cond = tcg_unsigned_cond(c.cond);
1591    }
1592    c.is_64 = c.g1 = c.g2 = true;
1593    c.u.s64.a = o->in1;
1594    c.u.s64.b = o->in2;
1595
1596    is_imm = have_field(s->fields, i4);
1597    if (is_imm) {
1598        imm = get_field(s->fields, i4);
1599    } else {
1600        imm = 0;
1601        o->out = get_address(s, 0, get_field(s->fields, b4),
1602                             get_field(s->fields, d4));
1603    }
1604
1605    return help_branch(s, &c, is_imm, imm, o->out);
1606}
1607
1608static ExitStatus op_ceb(DisasContext *s, DisasOps *o)
1609{
1610    gen_helper_ceb(cc_op, cpu_env, o->in1, o->in2);
1611    set_cc_static(s);
1612    return NO_EXIT;
1613}
1614
1615static ExitStatus op_cdb(DisasContext *s, DisasOps *o)
1616{
1617    gen_helper_cdb(cc_op, cpu_env, o->in1, o->in2);
1618    set_cc_static(s);
1619    return NO_EXIT;
1620}
1621
1622static ExitStatus op_cxb(DisasContext *s, DisasOps *o)
1623{
1624    gen_helper_cxb(cc_op, cpu_env, o->out, o->out2, o->in1, o->in2);
1625    set_cc_static(s);
1626    return NO_EXIT;
1627}
1628
1629static ExitStatus op_cfeb(DisasContext *s, DisasOps *o)
1630{
1631    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1632    gen_helper_cfeb(o->out, cpu_env, o->in2, m3);
1633    tcg_temp_free_i32(m3);
1634    gen_set_cc_nz_f32(s, o->in2);
1635    return NO_EXIT;
1636}
1637
1638static ExitStatus op_cfdb(DisasContext *s, DisasOps *o)
1639{
1640    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1641    gen_helper_cfdb(o->out, cpu_env, o->in2, m3);
1642    tcg_temp_free_i32(m3);
1643    gen_set_cc_nz_f64(s, o->in2);
1644    return NO_EXIT;
1645}
1646
1647static ExitStatus op_cfxb(DisasContext *s, DisasOps *o)
1648{
1649    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1650    gen_helper_cfxb(o->out, cpu_env, o->in1, o->in2, m3);
1651    tcg_temp_free_i32(m3);
1652    gen_set_cc_nz_f128(s, o->in1, o->in2);
1653    return NO_EXIT;
1654}
1655
1656static ExitStatus op_cgeb(DisasContext *s, DisasOps *o)
1657{
1658    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1659    gen_helper_cgeb(o->out, cpu_env, o->in2, m3);
1660    tcg_temp_free_i32(m3);
1661    gen_set_cc_nz_f32(s, o->in2);
1662    return NO_EXIT;
1663}
1664
1665static ExitStatus op_cgdb(DisasContext *s, DisasOps *o)
1666{
1667    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1668    gen_helper_cgdb(o->out, cpu_env, o->in2, m3);
1669    tcg_temp_free_i32(m3);
1670    gen_set_cc_nz_f64(s, o->in2);
1671    return NO_EXIT;
1672}
1673
1674static ExitStatus op_cgxb(DisasContext *s, DisasOps *o)
1675{
1676    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1677    gen_helper_cgxb(o->out, cpu_env, o->in1, o->in2, m3);
1678    tcg_temp_free_i32(m3);
1679    gen_set_cc_nz_f128(s, o->in1, o->in2);
1680    return NO_EXIT;
1681}
1682
1683static ExitStatus op_clfeb(DisasContext *s, DisasOps *o)
1684{
1685    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1686    gen_helper_clfeb(o->out, cpu_env, o->in2, m3);
1687    tcg_temp_free_i32(m3);
1688    gen_set_cc_nz_f32(s, o->in2);
1689    return NO_EXIT;
1690}
1691
1692static ExitStatus op_clfdb(DisasContext *s, DisasOps *o)
1693{
1694    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1695    gen_helper_clfdb(o->out, cpu_env, o->in2, m3);
1696    tcg_temp_free_i32(m3);
1697    gen_set_cc_nz_f64(s, o->in2);
1698    return NO_EXIT;
1699}
1700
1701static ExitStatus op_clfxb(DisasContext *s, DisasOps *o)
1702{
1703    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1704    gen_helper_clfxb(o->out, cpu_env, o->in1, o->in2, m3);
1705    tcg_temp_free_i32(m3);
1706    gen_set_cc_nz_f128(s, o->in1, o->in2);
1707    return NO_EXIT;
1708}
1709
1710static ExitStatus op_clgeb(DisasContext *s, DisasOps *o)
1711{
1712    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1713    gen_helper_clgeb(o->out, cpu_env, o->in2, m3);
1714    tcg_temp_free_i32(m3);
1715    gen_set_cc_nz_f32(s, o->in2);
1716    return NO_EXIT;
1717}
1718
1719static ExitStatus op_clgdb(DisasContext *s, DisasOps *o)
1720{
1721    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1722    gen_helper_clgdb(o->out, cpu_env, o->in2, m3);
1723    tcg_temp_free_i32(m3);
1724    gen_set_cc_nz_f64(s, o->in2);
1725    return NO_EXIT;
1726}
1727
1728static ExitStatus op_clgxb(DisasContext *s, DisasOps *o)
1729{
1730    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1731    gen_helper_clgxb(o->out, cpu_env, o->in1, o->in2, m3);
1732    tcg_temp_free_i32(m3);
1733    gen_set_cc_nz_f128(s, o->in1, o->in2);
1734    return NO_EXIT;
1735}
1736
1737static ExitStatus op_cegb(DisasContext *s, DisasOps *o)
1738{
1739    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1740    gen_helper_cegb(o->out, cpu_env, o->in2, m3);
1741    tcg_temp_free_i32(m3);
1742    return NO_EXIT;
1743}
1744
1745static ExitStatus op_cdgb(DisasContext *s, DisasOps *o)
1746{
1747    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1748    gen_helper_cdgb(o->out, cpu_env, o->in2, m3);
1749    tcg_temp_free_i32(m3);
1750    return NO_EXIT;
1751}
1752
1753static ExitStatus op_cxgb(DisasContext *s, DisasOps *o)
1754{
1755    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1756    gen_helper_cxgb(o->out, cpu_env, o->in2, m3);
1757    tcg_temp_free_i32(m3);
1758    return_low128(o->out2);
1759    return NO_EXIT;
1760}
1761
1762static ExitStatus op_celgb(DisasContext *s, DisasOps *o)
1763{
1764    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1765    gen_helper_celgb(o->out, cpu_env, o->in2, m3);
1766    tcg_temp_free_i32(m3);
1767    return NO_EXIT;
1768}
1769
1770static ExitStatus op_cdlgb(DisasContext *s, DisasOps *o)
1771{
1772    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1773    gen_helper_cdlgb(o->out, cpu_env, o->in2, m3);
1774    tcg_temp_free_i32(m3);
1775    return NO_EXIT;
1776}
1777
1778static ExitStatus op_cxlgb(DisasContext *s, DisasOps *o)
1779{
1780    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1781    gen_helper_cxlgb(o->out, cpu_env, o->in2, m3);
1782    tcg_temp_free_i32(m3);
1783    return_low128(o->out2);
1784    return NO_EXIT;
1785}
1786
1787static ExitStatus op_cksm(DisasContext *s, DisasOps *o)
1788{
1789    int r2 = get_field(s->fields, r2);
1790    TCGv_i64 len = tcg_temp_new_i64();
1791
1792    gen_helper_cksm(len, cpu_env, o->in1, o->in2, regs[r2 + 1]);
1793    set_cc_static(s);
1794    return_low128(o->out);
1795
1796    tcg_gen_add_i64(regs[r2], regs[r2], len);
1797    tcg_gen_sub_i64(regs[r2 + 1], regs[r2 + 1], len);
1798    tcg_temp_free_i64(len);
1799
1800    return NO_EXIT;
1801}
1802
1803static ExitStatus op_clc(DisasContext *s, DisasOps *o)
1804{
1805    int l = get_field(s->fields, l1);
1806    TCGv_i32 vl;
1807
1808    switch (l + 1) {
1809    case 1:
1810        tcg_gen_qemu_ld8u(cc_src, o->addr1, get_mem_index(s));
1811        tcg_gen_qemu_ld8u(cc_dst, o->in2, get_mem_index(s));
1812        break;
1813    case 2:
1814        tcg_gen_qemu_ld16u(cc_src, o->addr1, get_mem_index(s));
1815        tcg_gen_qemu_ld16u(cc_dst, o->in2, get_mem_index(s));
1816        break;
1817    case 4:
1818        tcg_gen_qemu_ld32u(cc_src, o->addr1, get_mem_index(s));
1819        tcg_gen_qemu_ld32u(cc_dst, o->in2, get_mem_index(s));
1820        break;
1821    case 8:
1822        tcg_gen_qemu_ld64(cc_src, o->addr1, get_mem_index(s));
1823        tcg_gen_qemu_ld64(cc_dst, o->in2, get_mem_index(s));
1824        break;
1825    default:
1826        vl = tcg_const_i32(l);
1827        gen_helper_clc(cc_op, cpu_env, vl, o->addr1, o->in2);
1828        tcg_temp_free_i32(vl);
1829        set_cc_static(s);
1830        return NO_EXIT;
1831    }
1832    gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, cc_src, cc_dst);
1833    return NO_EXIT;
1834}
1835
1836static ExitStatus op_clcl(DisasContext *s, DisasOps *o)
1837{
1838    int r1 = get_field(s->fields, r1);
1839    int r2 = get_field(s->fields, r2);
1840    TCGv_i32 t1, t2;
1841
1842    /* r1 and r2 must be even.  */
1843    if (r1 & 1 || r2 & 1) {
1844        gen_program_exception(s, PGM_SPECIFICATION);
1845        return EXIT_NORETURN;
1846    }
1847
1848    t1 = tcg_const_i32(r1);
1849    t2 = tcg_const_i32(r2);
1850    gen_helper_clcl(cc_op, cpu_env, t1, t2);
1851    tcg_temp_free_i32(t1);
1852    tcg_temp_free_i32(t2);
1853    set_cc_static(s);
1854    return NO_EXIT;
1855}
1856
1857static ExitStatus op_clcle(DisasContext *s, DisasOps *o)
1858{
1859    int r1 = get_field(s->fields, r1);
1860    int r3 = get_field(s->fields, r3);
1861    TCGv_i32 t1, t3;
1862
1863    /* r1 and r3 must be even.  */
1864    if (r1 & 1 || r3 & 1) {
1865        gen_program_exception(s, PGM_SPECIFICATION);
1866        return EXIT_NORETURN;
1867    }
1868
1869    t1 = tcg_const_i32(r1);
1870    t3 = tcg_const_i32(r3);
1871    gen_helper_clcle(cc_op, cpu_env, t1, o->in2, t3);
1872    tcg_temp_free_i32(t1);
1873    tcg_temp_free_i32(t3);
1874    set_cc_static(s);
1875    return NO_EXIT;
1876}
1877
1878static ExitStatus op_clclu(DisasContext *s, DisasOps *o)
1879{
1880    int r1 = get_field(s->fields, r1);
1881    int r3 = get_field(s->fields, r3);
1882    TCGv_i32 t1, t3;
1883
1884    /* r1 and r3 must be even.  */
1885    if (r1 & 1 || r3 & 1) {
1886        gen_program_exception(s, PGM_SPECIFICATION);
1887        return EXIT_NORETURN;
1888    }
1889
1890    t1 = tcg_const_i32(r1);
1891    t3 = tcg_const_i32(r3);
1892    gen_helper_clclu(cc_op, cpu_env, t1, o->in2, t3);
1893    tcg_temp_free_i32(t1);
1894    tcg_temp_free_i32(t3);
1895    set_cc_static(s);
1896    return NO_EXIT;
1897}
1898
1899static ExitStatus op_clm(DisasContext *s, DisasOps *o)
1900{
1901    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
1902    TCGv_i32 t1 = tcg_temp_new_i32();
1903    tcg_gen_extrl_i64_i32(t1, o->in1);
1904    gen_helper_clm(cc_op, cpu_env, t1, m3, o->in2);
1905    set_cc_static(s);
1906    tcg_temp_free_i32(t1);
1907    tcg_temp_free_i32(m3);
1908    return NO_EXIT;
1909}
1910
1911static ExitStatus op_clst(DisasContext *s, DisasOps *o)
1912{
1913    gen_helper_clst(o->in1, cpu_env, regs[0], o->in1, o->in2);
1914    set_cc_static(s);
1915    return_low128(o->in2);
1916    return NO_EXIT;
1917}
1918
1919static ExitStatus op_cps(DisasContext *s, DisasOps *o)
1920{
1921    TCGv_i64 t = tcg_temp_new_i64();
1922    tcg_gen_andi_i64(t, o->in1, 0x8000000000000000ull);
1923    tcg_gen_andi_i64(o->out, o->in2, 0x7fffffffffffffffull);
1924    tcg_gen_or_i64(o->out, o->out, t);
1925    tcg_temp_free_i64(t);
1926    return NO_EXIT;
1927}
1928
1929static ExitStatus op_cs(DisasContext *s, DisasOps *o)
1930{
1931    int d2 = get_field(s->fields, d2);
1932    int b2 = get_field(s->fields, b2);
1933    TCGv_i64 addr, cc;
1934
1935    /* Note that in1 = R3 (new value) and
1936       in2 = (zero-extended) R1 (expected value).  */
1937
1938    addr = get_address(s, 0, b2, d2);
1939    tcg_gen_atomic_cmpxchg_i64(o->out, addr, o->in2, o->in1,
1940                               get_mem_index(s), s->insn->data | MO_ALIGN);
1941    tcg_temp_free_i64(addr);
1942
1943    /* Are the memory and expected values (un)equal?  Note that this setcond
1944       produces the output CC value, thus the NE sense of the test.  */
1945    cc = tcg_temp_new_i64();
1946    tcg_gen_setcond_i64(TCG_COND_NE, cc, o->in2, o->out);
1947    tcg_gen_extrl_i64_i32(cc_op, cc);
1948    tcg_temp_free_i64(cc);
1949    set_cc_static(s);
1950
1951    return NO_EXIT;
1952}
1953
1954static ExitStatus op_cdsg(DisasContext *s, DisasOps *o)
1955{
1956    int r1 = get_field(s->fields, r1);
1957    int r3 = get_field(s->fields, r3);
1958    int d2 = get_field(s->fields, d2);
1959    int b2 = get_field(s->fields, b2);
1960    TCGv_i64 addr;
1961    TCGv_i32 t_r1, t_r3;
1962
1963    /* Note that R1:R1+1 = expected value and R3:R3+1 = new value.  */
1964    addr = get_address(s, 0, b2, d2);
1965    t_r1 = tcg_const_i32(r1);
1966    t_r3 = tcg_const_i32(r3);
1967    gen_helper_cdsg(cpu_env, addr, t_r1, t_r3);
1968    tcg_temp_free_i64(addr);
1969    tcg_temp_free_i32(t_r1);
1970    tcg_temp_free_i32(t_r3);
1971
1972    set_cc_static(s);
1973    return NO_EXIT;
1974}
1975
1976static ExitStatus op_csst(DisasContext *s, DisasOps *o)
1977{
1978    int r3 = get_field(s->fields, r3);
1979    TCGv_i32 t_r3 = tcg_const_i32(r3);
1980
1981    gen_helper_csst(cc_op, cpu_env, t_r3, o->in1, o->in2);
1982    tcg_temp_free_i32(t_r3);
1983
1984    set_cc_static(s);
1985    return NO_EXIT;
1986}
1987
1988#ifndef CONFIG_USER_ONLY
1989static ExitStatus op_csp(DisasContext *s, DisasOps *o)
1990{
1991    TCGMemOp mop = s->insn->data;
1992    TCGv_i64 addr, old, cc;
1993    TCGLabel *lab = gen_new_label();
1994
1995    /* Note that in1 = R1 (zero-extended expected value),
1996       out = R1 (original reg), out2 = R1+1 (new value).  */
1997
1998    check_privileged(s);
1999    addr = tcg_temp_new_i64();
2000    old = tcg_temp_new_i64();
2001    tcg_gen_andi_i64(addr, o->in2, -1ULL << (mop & MO_SIZE));
2002    tcg_gen_atomic_cmpxchg_i64(old, addr, o->in1, o->out2,
2003                               get_mem_index(s), mop | MO_ALIGN);
2004    tcg_temp_free_i64(addr);
2005
2006    /* Are the memory and expected values (un)equal?  */
2007    cc = tcg_temp_new_i64();
2008    tcg_gen_setcond_i64(TCG_COND_NE, cc, o->in1, old);
2009    tcg_gen_extrl_i64_i32(cc_op, cc);
2010
2011    /* Write back the output now, so that it happens before the
2012       following branch, so that we don't need local temps.  */
2013    if ((mop & MO_SIZE) == MO_32) {
2014        tcg_gen_deposit_i64(o->out, o->out, old, 0, 32);
2015    } else {
2016        tcg_gen_mov_i64(o->out, old);
2017    }
2018    tcg_temp_free_i64(old);
2019
2020    /* If the comparison was equal, and the LSB of R2 was set,
2021       then we need to flush the TLB (for all cpus).  */
2022    tcg_gen_xori_i64(cc, cc, 1);
2023    tcg_gen_and_i64(cc, cc, o->in2);
2024    tcg_gen_brcondi_i64(TCG_COND_EQ, cc, 0, lab);
2025    tcg_temp_free_i64(cc);
2026
2027    gen_helper_purge(cpu_env);
2028    gen_set_label(lab);
2029
2030    return NO_EXIT;
2031}
2032#endif
2033
2034static ExitStatus op_cvd(DisasContext *s, DisasOps *o)
2035{
2036    TCGv_i64 t1 = tcg_temp_new_i64();
2037    TCGv_i32 t2 = tcg_temp_new_i32();
2038    tcg_gen_extrl_i64_i32(t2, o->in1);
2039    gen_helper_cvd(t1, t2);
2040    tcg_temp_free_i32(t2);
2041    tcg_gen_qemu_st64(t1, o->in2, get_mem_index(s));
2042    tcg_temp_free_i64(t1);
2043    return NO_EXIT;
2044}
2045
2046static ExitStatus op_ct(DisasContext *s, DisasOps *o)
2047{
2048    int m3 = get_field(s->fields, m3);
2049    TCGLabel *lab = gen_new_label();
2050    TCGCond c;
2051
2052    c = tcg_invert_cond(ltgt_cond[m3]);
2053    if (s->insn->data) {
2054        c = tcg_unsigned_cond(c);
2055    }
2056    tcg_gen_brcond_i64(c, o->in1, o->in2, lab);
2057
2058    /* Trap.  */
2059    gen_trap(s);
2060
2061    gen_set_label(lab);
2062    return NO_EXIT;
2063}
2064
2065static ExitStatus op_cuXX(DisasContext *s, DisasOps *o)
2066{
2067    int m3 = get_field(s->fields, m3);
2068    int r1 = get_field(s->fields, r1);
2069    int r2 = get_field(s->fields, r2);
2070    TCGv_i32 tr1, tr2, chk;
2071
2072    /* R1 and R2 must both be even.  */
2073    if ((r1 | r2) & 1) {
2074        gen_program_exception(s, PGM_SPECIFICATION);
2075        return EXIT_NORETURN;
2076    }
2077    if (!s390_has_feat(S390_FEAT_ETF3_ENH)) {
2078        m3 = 0;
2079    }
2080
2081    tr1 = tcg_const_i32(r1);
2082    tr2 = tcg_const_i32(r2);
2083    chk = tcg_const_i32(m3);
2084
2085    switch (s->insn->data) {
2086    case 12:
2087        gen_helper_cu12(cc_op, cpu_env, tr1, tr2, chk);
2088        break;
2089    case 14:
2090        gen_helper_cu14(cc_op, cpu_env, tr1, tr2, chk);
2091        break;
2092    case 21:
2093        gen_helper_cu21(cc_op, cpu_env, tr1, tr2, chk);
2094        break;
2095    case 24:
2096        gen_helper_cu24(cc_op, cpu_env, tr1, tr2, chk);
2097        break;
2098    case 41:
2099        gen_helper_cu41(cc_op, cpu_env, tr1, tr2, chk);
2100        break;
2101    case 42:
2102        gen_helper_cu42(cc_op, cpu_env, tr1, tr2, chk);
2103        break;
2104    default:
2105        g_assert_not_reached();
2106    }
2107
2108    tcg_temp_free_i32(tr1);
2109    tcg_temp_free_i32(tr2);
2110    tcg_temp_free_i32(chk);
2111    set_cc_static(s);
2112    return NO_EXIT;
2113}
2114
2115#ifndef CONFIG_USER_ONLY
2116static ExitStatus op_diag(DisasContext *s, DisasOps *o)
2117{
2118    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2119    TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2120    TCGv_i32 func_code = tcg_const_i32(get_field(s->fields, i2));
2121
2122    check_privileged(s);
2123    update_psw_addr(s);
2124    gen_op_calc_cc(s);
2125
2126    gen_helper_diag(cpu_env, r1, r3, func_code);
2127
2128    tcg_temp_free_i32(func_code);
2129    tcg_temp_free_i32(r3);
2130    tcg_temp_free_i32(r1);
2131    return NO_EXIT;
2132}
2133#endif
2134
2135static ExitStatus op_divs32(DisasContext *s, DisasOps *o)
2136{
2137    gen_helper_divs32(o->out2, cpu_env, o->in1, o->in2);
2138    return_low128(o->out);
2139    return NO_EXIT;
2140}
2141
2142static ExitStatus op_divu32(DisasContext *s, DisasOps *o)
2143{
2144    gen_helper_divu32(o->out2, cpu_env, o->in1, o->in2);
2145    return_low128(o->out);
2146    return NO_EXIT;
2147}
2148
2149static ExitStatus op_divs64(DisasContext *s, DisasOps *o)
2150{
2151    gen_helper_divs64(o->out2, cpu_env, o->in1, o->in2);
2152    return_low128(o->out);
2153    return NO_EXIT;
2154}
2155
2156static ExitStatus op_divu64(DisasContext *s, DisasOps *o)
2157{
2158    gen_helper_divu64(o->out2, cpu_env, o->out, o->out2, o->in2);
2159    return_low128(o->out);
2160    return NO_EXIT;
2161}
2162
2163static ExitStatus op_deb(DisasContext *s, DisasOps *o)
2164{
2165    gen_helper_deb(o->out, cpu_env, o->in1, o->in2);
2166    return NO_EXIT;
2167}
2168
2169static ExitStatus op_ddb(DisasContext *s, DisasOps *o)
2170{
2171    gen_helper_ddb(o->out, cpu_env, o->in1, o->in2);
2172    return NO_EXIT;
2173}
2174
2175static ExitStatus op_dxb(DisasContext *s, DisasOps *o)
2176{
2177    gen_helper_dxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
2178    return_low128(o->out2);
2179    return NO_EXIT;
2180}
2181
2182static ExitStatus op_ear(DisasContext *s, DisasOps *o)
2183{
2184    int r2 = get_field(s->fields, r2);
2185    tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, aregs[r2]));
2186    return NO_EXIT;
2187}
2188
2189static ExitStatus op_ecag(DisasContext *s, DisasOps *o)
2190{
2191    /* No cache information provided.  */
2192    tcg_gen_movi_i64(o->out, -1);
2193    return NO_EXIT;
2194}
2195
2196static ExitStatus op_efpc(DisasContext *s, DisasOps *o)
2197{
2198    tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, fpc));
2199    return NO_EXIT;
2200}
2201
2202static ExitStatus op_epsw(DisasContext *s, DisasOps *o)
2203{
2204    int r1 = get_field(s->fields, r1);
2205    int r2 = get_field(s->fields, r2);
2206    TCGv_i64 t = tcg_temp_new_i64();
2207
2208    /* Note the "subsequently" in the PoO, which implies a defined result
2209       if r1 == r2.  Thus we cannot defer these writes to an output hook.  */
2210    tcg_gen_shri_i64(t, psw_mask, 32);
2211    store_reg32_i64(r1, t);
2212    if (r2 != 0) {
2213        store_reg32_i64(r2, psw_mask);
2214    }
2215
2216    tcg_temp_free_i64(t);
2217    return NO_EXIT;
2218}
2219
2220static ExitStatus op_ex(DisasContext *s, DisasOps *o)
2221{
2222    int r1 = get_field(s->fields, r1);
2223    TCGv_i32 ilen;
2224    TCGv_i64 v1;
2225
2226    /* Nested EXECUTE is not allowed.  */
2227    if (unlikely(s->ex_value)) {
2228        gen_program_exception(s, PGM_EXECUTE);
2229        return EXIT_NORETURN;
2230    }
2231
2232    update_psw_addr(s);
2233    update_cc_op(s);
2234
2235    if (r1 == 0) {
2236        v1 = tcg_const_i64(0);
2237    } else {
2238        v1 = regs[r1];
2239    }
2240
2241    ilen = tcg_const_i32(s->ilen);
2242    gen_helper_ex(cpu_env, ilen, v1, o->in2);
2243    tcg_temp_free_i32(ilen);
2244
2245    if (r1 == 0) {
2246        tcg_temp_free_i64(v1);
2247    }
2248
2249    return EXIT_PC_CC_UPDATED;
2250}
2251
2252static ExitStatus op_fieb(DisasContext *s, DisasOps *o)
2253{
2254    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
2255    gen_helper_fieb(o->out, cpu_env, o->in2, m3);
2256    tcg_temp_free_i32(m3);
2257    return NO_EXIT;
2258}
2259
2260static ExitStatus op_fidb(DisasContext *s, DisasOps *o)
2261{
2262    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
2263    gen_helper_fidb(o->out, cpu_env, o->in2, m3);
2264    tcg_temp_free_i32(m3);
2265    return NO_EXIT;
2266}
2267
2268static ExitStatus op_fixb(DisasContext *s, DisasOps *o)
2269{
2270    TCGv_i32 m3 = tcg_const_i32(get_field(s->fields, m3));
2271    gen_helper_fixb(o->out, cpu_env, o->in1, o->in2, m3);
2272    return_low128(o->out2);
2273    tcg_temp_free_i32(m3);
2274    return NO_EXIT;
2275}
2276
2277static ExitStatus op_flogr(DisasContext *s, DisasOps *o)
2278{
2279    /* We'll use the original input for cc computation, since we get to
2280       compare that against 0, which ought to be better than comparing
2281       the real output against 64.  It also lets cc_dst be a convenient
2282       temporary during our computation.  */
2283    gen_op_update1_cc_i64(s, CC_OP_FLOGR, o->in2);
2284
2285    /* R1 = IN ? CLZ(IN) : 64.  */
2286    tcg_gen_clzi_i64(o->out, o->in2, 64);
2287
2288    /* R1+1 = IN & ~(found bit).  Note that we may attempt to shift this
2289       value by 64, which is undefined.  But since the shift is 64 iff the
2290       input is zero, we still get the correct result after and'ing.  */
2291    tcg_gen_movi_i64(o->out2, 0x8000000000000000ull);
2292    tcg_gen_shr_i64(o->out2, o->out2, o->out);
2293    tcg_gen_andc_i64(o->out2, cc_dst, o->out2);
2294    return NO_EXIT;
2295}
2296
2297static ExitStatus op_icm(DisasContext *s, DisasOps *o)
2298{
2299    int m3 = get_field(s->fields, m3);
2300    int pos, len, base = s->insn->data;
2301    TCGv_i64 tmp = tcg_temp_new_i64();
2302    uint64_t ccm;
2303
2304    switch (m3) {
2305    case 0xf:
2306        /* Effectively a 32-bit load.  */
2307        tcg_gen_qemu_ld32u(tmp, o->in2, get_mem_index(s));
2308        len = 32;
2309        goto one_insert;
2310
2311    case 0xc:
2312    case 0x6:
2313    case 0x3:
2314        /* Effectively a 16-bit load.  */
2315        tcg_gen_qemu_ld16u(tmp, o->in2, get_mem_index(s));
2316        len = 16;
2317        goto one_insert;
2318
2319    case 0x8:
2320    case 0x4:
2321    case 0x2:
2322    case 0x1:
2323        /* Effectively an 8-bit load.  */
2324        tcg_gen_qemu_ld8u(tmp, o->in2, get_mem_index(s));
2325        len = 8;
2326        goto one_insert;
2327
2328    one_insert:
2329        pos = base + ctz32(m3) * 8;
2330        tcg_gen_deposit_i64(o->out, o->out, tmp, pos, len);
2331        ccm = ((1ull << len) - 1) << pos;
2332        break;
2333
2334    default:
2335        /* This is going to be a sequence of loads and inserts.  */
2336        pos = base + 32 - 8;
2337        ccm = 0;
2338        while (m3) {
2339            if (m3 & 0x8) {
2340                tcg_gen_qemu_ld8u(tmp, o->in2, get_mem_index(s));
2341                tcg_gen_addi_i64(o->in2, o->in2, 1);
2342                tcg_gen_deposit_i64(o->out, o->out, tmp, pos, 8);
2343                ccm |= 0xff << pos;
2344            }
2345            m3 = (m3 << 1) & 0xf;
2346            pos -= 8;
2347        }
2348        break;
2349    }
2350
2351    tcg_gen_movi_i64(tmp, ccm);
2352    gen_op_update2_cc_i64(s, CC_OP_ICM, tmp, o->out);
2353    tcg_temp_free_i64(tmp);
2354    return NO_EXIT;
2355}
2356
2357static ExitStatus op_insi(DisasContext *s, DisasOps *o)
2358{
2359    int shift = s->insn->data & 0xff;
2360    int size = s->insn->data >> 8;
2361    tcg_gen_deposit_i64(o->out, o->in1, o->in2, shift, size);
2362    return NO_EXIT;
2363}
2364
2365static ExitStatus op_ipm(DisasContext *s, DisasOps *o)
2366{
2367    TCGv_i64 t1;
2368
2369    gen_op_calc_cc(s);
2370    tcg_gen_andi_i64(o->out, o->out, ~0xff000000ull);
2371
2372    t1 = tcg_temp_new_i64();
2373    tcg_gen_shli_i64(t1, psw_mask, 20);
2374    tcg_gen_shri_i64(t1, t1, 36);
2375    tcg_gen_or_i64(o->out, o->out, t1);
2376
2377    tcg_gen_extu_i32_i64(t1, cc_op);
2378    tcg_gen_shli_i64(t1, t1, 28);
2379    tcg_gen_or_i64(o->out, o->out, t1);
2380    tcg_temp_free_i64(t1);
2381    return NO_EXIT;
2382}
2383
2384#ifndef CONFIG_USER_ONLY
2385static ExitStatus op_idte(DisasContext *s, DisasOps *o)
2386{
2387    TCGv_i32 m4;
2388
2389    check_privileged(s);
2390    if (s390_has_feat(S390_FEAT_LOCAL_TLB_CLEARING)) {
2391        m4 = tcg_const_i32(get_field(s->fields, m4));
2392    } else {
2393        m4 = tcg_const_i32(0);
2394    }
2395    gen_helper_idte(cpu_env, o->in1, o->in2, m4);
2396    tcg_temp_free_i32(m4);
2397    return NO_EXIT;
2398}
2399
2400static ExitStatus op_ipte(DisasContext *s, DisasOps *o)
2401{
2402    TCGv_i32 m4;
2403
2404    check_privileged(s);
2405    if (s390_has_feat(S390_FEAT_LOCAL_TLB_CLEARING)) {
2406        m4 = tcg_const_i32(get_field(s->fields, m4));
2407    } else {
2408        m4 = tcg_const_i32(0);
2409    }
2410    gen_helper_ipte(cpu_env, o->in1, o->in2, m4);
2411    tcg_temp_free_i32(m4);
2412    return NO_EXIT;
2413}
2414
2415static ExitStatus op_iske(DisasContext *s, DisasOps *o)
2416{
2417    check_privileged(s);
2418    gen_helper_iske(o->out, cpu_env, o->in2);
2419    return NO_EXIT;
2420}
2421#endif
2422
2423static ExitStatus op_keb(DisasContext *s, DisasOps *o)
2424{
2425    gen_helper_keb(cc_op, cpu_env, o->in1, o->in2);
2426    set_cc_static(s);
2427    return NO_EXIT;
2428}
2429
2430static ExitStatus op_kdb(DisasContext *s, DisasOps *o)
2431{
2432    gen_helper_kdb(cc_op, cpu_env, o->in1, o->in2);
2433    set_cc_static(s);
2434    return NO_EXIT;
2435}
2436
2437static ExitStatus op_kxb(DisasContext *s, DisasOps *o)
2438{
2439    gen_helper_kxb(cc_op, cpu_env, o->out, o->out2, o->in1, o->in2);
2440    set_cc_static(s);
2441    return NO_EXIT;
2442}
2443
2444static ExitStatus op_laa(DisasContext *s, DisasOps *o)
2445{
2446    /* The real output is indeed the original value in memory;
2447       recompute the addition for the computation of CC.  */
2448    tcg_gen_atomic_fetch_add_i64(o->in2, o->in2, o->in1, get_mem_index(s),
2449                                 s->insn->data | MO_ALIGN);
2450    /* However, we need to recompute the addition for setting CC.  */
2451    tcg_gen_add_i64(o->out, o->in1, o->in2);
2452    return NO_EXIT;
2453}
2454
2455static ExitStatus op_lan(DisasContext *s, DisasOps *o)
2456{
2457    /* The real output is indeed the original value in memory;
2458       recompute the addition for the computation of CC.  */
2459    tcg_gen_atomic_fetch_and_i64(o->in2, o->in2, o->in1, get_mem_index(s),
2460                                 s->insn->data | MO_ALIGN);
2461    /* However, we need to recompute the operation for setting CC.  */
2462    tcg_gen_and_i64(o->out, o->in1, o->in2);
2463    return NO_EXIT;
2464}
2465
2466static ExitStatus op_lao(DisasContext *s, DisasOps *o)
2467{
2468    /* The real output is indeed the original value in memory;
2469       recompute the addition for the computation of CC.  */
2470    tcg_gen_atomic_fetch_or_i64(o->in2, o->in2, o->in1, get_mem_index(s),
2471                                s->insn->data | MO_ALIGN);
2472    /* However, we need to recompute the operation for setting CC.  */
2473    tcg_gen_or_i64(o->out, o->in1, o->in2);
2474    return NO_EXIT;
2475}
2476
2477static ExitStatus op_lax(DisasContext *s, DisasOps *o)
2478{
2479    /* The real output is indeed the original value in memory;
2480       recompute the addition for the computation of CC.  */
2481    tcg_gen_atomic_fetch_xor_i64(o->in2, o->in2, o->in1, get_mem_index(s),
2482                                 s->insn->data | MO_ALIGN);
2483    /* However, we need to recompute the operation for setting CC.  */
2484    tcg_gen_xor_i64(o->out, o->in1, o->in2);
2485    return NO_EXIT;
2486}
2487
2488static ExitStatus op_ldeb(DisasContext *s, DisasOps *o)
2489{
2490    gen_helper_ldeb(o->out, cpu_env, o->in2);
2491    return NO_EXIT;
2492}
2493
2494static ExitStatus op_ledb(DisasContext *s, DisasOps *o)
2495{
2496    gen_helper_ledb(o->out, cpu_env, o->in2);
2497    return NO_EXIT;
2498}
2499
2500static ExitStatus op_ldxb(DisasContext *s, DisasOps *o)
2501{
2502    gen_helper_ldxb(o->out, cpu_env, o->in1, o->in2);
2503    return NO_EXIT;
2504}
2505
2506static ExitStatus op_lexb(DisasContext *s, DisasOps *o)
2507{
2508    gen_helper_lexb(o->out, cpu_env, o->in1, o->in2);
2509    return NO_EXIT;
2510}
2511
2512static ExitStatus op_lxdb(DisasContext *s, DisasOps *o)
2513{
2514    gen_helper_lxdb(o->out, cpu_env, o->in2);
2515    return_low128(o->out2);
2516    return NO_EXIT;
2517}
2518
2519static ExitStatus op_lxeb(DisasContext *s, DisasOps *o)
2520{
2521    gen_helper_lxeb(o->out, cpu_env, o->in2);
2522    return_low128(o->out2);
2523    return NO_EXIT;
2524}
2525
2526static ExitStatus op_llgt(DisasContext *s, DisasOps *o)
2527{
2528    tcg_gen_andi_i64(o->out, o->in2, 0x7fffffff);
2529    return NO_EXIT;
2530}
2531
2532static ExitStatus op_ld8s(DisasContext *s, DisasOps *o)
2533{
2534    tcg_gen_qemu_ld8s(o->out, o->in2, get_mem_index(s));
2535    return NO_EXIT;
2536}
2537
2538static ExitStatus op_ld8u(DisasContext *s, DisasOps *o)
2539{
2540    tcg_gen_qemu_ld8u(o->out, o->in2, get_mem_index(s));
2541    return NO_EXIT;
2542}
2543
2544static ExitStatus op_ld16s(DisasContext *s, DisasOps *o)
2545{
2546    tcg_gen_qemu_ld16s(o->out, o->in2, get_mem_index(s));
2547    return NO_EXIT;
2548}
2549
2550static ExitStatus op_ld16u(DisasContext *s, DisasOps *o)
2551{
2552    tcg_gen_qemu_ld16u(o->out, o->in2, get_mem_index(s));
2553    return NO_EXIT;
2554}
2555
2556static ExitStatus op_ld32s(DisasContext *s, DisasOps *o)
2557{
2558    tcg_gen_qemu_ld32s(o->out, o->in2, get_mem_index(s));
2559    return NO_EXIT;
2560}
2561
2562static ExitStatus op_ld32u(DisasContext *s, DisasOps *o)
2563{
2564    tcg_gen_qemu_ld32u(o->out, o->in2, get_mem_index(s));
2565    return NO_EXIT;
2566}
2567
2568static ExitStatus op_ld64(DisasContext *s, DisasOps *o)
2569{
2570    tcg_gen_qemu_ld64(o->out, o->in2, get_mem_index(s));
2571    return NO_EXIT;
2572}
2573
2574static ExitStatus op_lat(DisasContext *s, DisasOps *o)
2575{
2576    TCGLabel *lab = gen_new_label();
2577    store_reg32_i64(get_field(s->fields, r1), o->in2);
2578    /* The value is stored even in case of trap. */
2579    tcg_gen_brcondi_i64(TCG_COND_NE, o->in2, 0, lab);
2580    gen_trap(s);
2581    gen_set_label(lab);
2582    return NO_EXIT;
2583}
2584
2585static ExitStatus op_lgat(DisasContext *s, DisasOps *o)
2586{
2587    TCGLabel *lab = gen_new_label();
2588    tcg_gen_qemu_ld64(o->out, o->in2, get_mem_index(s));
2589    /* The value is stored even in case of trap. */
2590    tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab);
2591    gen_trap(s);
2592    gen_set_label(lab);
2593    return NO_EXIT;
2594}
2595
2596static ExitStatus op_lfhat(DisasContext *s, DisasOps *o)
2597{
2598    TCGLabel *lab = gen_new_label();
2599    store_reg32h_i64(get_field(s->fields, r1), o->in2);
2600    /* The value is stored even in case of trap. */
2601    tcg_gen_brcondi_i64(TCG_COND_NE, o->in2, 0, lab);
2602    gen_trap(s);
2603    gen_set_label(lab);
2604    return NO_EXIT;
2605}
2606
2607static ExitStatus op_llgfat(DisasContext *s, DisasOps *o)
2608{
2609    TCGLabel *lab = gen_new_label();
2610    tcg_gen_qemu_ld32u(o->out, o->in2, get_mem_index(s));
2611    /* The value is stored even in case of trap. */
2612    tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab);
2613    gen_trap(s);
2614    gen_set_label(lab);
2615    return NO_EXIT;
2616}
2617
2618static ExitStatus op_llgtat(DisasContext *s, DisasOps *o)
2619{
2620    TCGLabel *lab = gen_new_label();
2621    tcg_gen_andi_i64(o->out, o->in2, 0x7fffffff);
2622    /* The value is stored even in case of trap. */
2623    tcg_gen_brcondi_i64(TCG_COND_NE, o->out, 0, lab);
2624    gen_trap(s);
2625    gen_set_label(lab);
2626    return NO_EXIT;
2627}
2628
2629static ExitStatus op_loc(DisasContext *s, DisasOps *o)
2630{
2631    DisasCompare c;
2632
2633    disas_jcc(s, &c, get_field(s->fields, m3));
2634
2635    if (c.is_64) {
2636        tcg_gen_movcond_i64(c.cond, o->out, c.u.s64.a, c.u.s64.b,
2637                            o->in2, o->in1);
2638        free_compare(&c);
2639    } else {
2640        TCGv_i32 t32 = tcg_temp_new_i32();
2641        TCGv_i64 t, z;
2642
2643        tcg_gen_setcond_i32(c.cond, t32, c.u.s32.a, c.u.s32.b);
2644        free_compare(&c);
2645
2646        t = tcg_temp_new_i64();
2647        tcg_gen_extu_i32_i64(t, t32);
2648        tcg_temp_free_i32(t32);
2649
2650        z = tcg_const_i64(0);
2651        tcg_gen_movcond_i64(TCG_COND_NE, o->out, t, z, o->in2, o->in1);
2652        tcg_temp_free_i64(t);
2653        tcg_temp_free_i64(z);
2654    }
2655
2656    return NO_EXIT;
2657}
2658
2659#ifndef CONFIG_USER_ONLY
2660static ExitStatus op_lctl(DisasContext *s, DisasOps *o)
2661{
2662    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2663    TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2664    check_privileged(s);
2665    gen_helper_lctl(cpu_env, r1, o->in2, r3);
2666    tcg_temp_free_i32(r1);
2667    tcg_temp_free_i32(r3);
2668    return NO_EXIT;
2669}
2670
2671static ExitStatus op_lctlg(DisasContext *s, DisasOps *o)
2672{
2673    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2674    TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2675    check_privileged(s);
2676    gen_helper_lctlg(cpu_env, r1, o->in2, r3);
2677    tcg_temp_free_i32(r1);
2678    tcg_temp_free_i32(r3);
2679    return NO_EXIT;
2680}
2681
2682static ExitStatus op_lra(DisasContext *s, DisasOps *o)
2683{
2684    check_privileged(s);
2685    gen_helper_lra(o->out, cpu_env, o->in2);
2686    set_cc_static(s);
2687    return NO_EXIT;
2688}
2689
2690static ExitStatus op_lpp(DisasContext *s, DisasOps *o)
2691{
2692    check_privileged(s);
2693
2694    tcg_gen_st_i64(o->in2, cpu_env, offsetof(CPUS390XState, pp));
2695    return NO_EXIT;
2696}
2697
2698static ExitStatus op_lpsw(DisasContext *s, DisasOps *o)
2699{
2700    TCGv_i64 t1, t2;
2701
2702    check_privileged(s);
2703    per_breaking_event(s);
2704
2705    t1 = tcg_temp_new_i64();
2706    t2 = tcg_temp_new_i64();
2707    tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2708    tcg_gen_addi_i64(o->in2, o->in2, 4);
2709    tcg_gen_qemu_ld32u(t2, o->in2, get_mem_index(s));
2710    /* Convert the 32-bit PSW_MASK into the 64-bit PSW_MASK.  */
2711    tcg_gen_shli_i64(t1, t1, 32);
2712    gen_helper_load_psw(cpu_env, t1, t2);
2713    tcg_temp_free_i64(t1);
2714    tcg_temp_free_i64(t2);
2715    return EXIT_NORETURN;
2716}
2717
2718static ExitStatus op_lpswe(DisasContext *s, DisasOps *o)
2719{
2720    TCGv_i64 t1, t2;
2721
2722    check_privileged(s);
2723    per_breaking_event(s);
2724
2725    t1 = tcg_temp_new_i64();
2726    t2 = tcg_temp_new_i64();
2727    tcg_gen_qemu_ld64(t1, o->in2, get_mem_index(s));
2728    tcg_gen_addi_i64(o->in2, o->in2, 8);
2729    tcg_gen_qemu_ld64(t2, o->in2, get_mem_index(s));
2730    gen_helper_load_psw(cpu_env, t1, t2);
2731    tcg_temp_free_i64(t1);
2732    tcg_temp_free_i64(t2);
2733    return EXIT_NORETURN;
2734}
2735#endif
2736
2737static ExitStatus op_lam(DisasContext *s, DisasOps *o)
2738{
2739    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
2740    TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
2741    gen_helper_lam(cpu_env, r1, o->in2, r3);
2742    tcg_temp_free_i32(r1);
2743    tcg_temp_free_i32(r3);
2744    return NO_EXIT;
2745}
2746
2747static ExitStatus op_lm32(DisasContext *s, DisasOps *o)
2748{
2749    int r1 = get_field(s->fields, r1);
2750    int r3 = get_field(s->fields, r3);
2751    TCGv_i64 t1, t2;
2752
2753    /* Only one register to read. */
2754    t1 = tcg_temp_new_i64();
2755    if (unlikely(r1 == r3)) {
2756        tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2757        store_reg32_i64(r1, t1);
2758        tcg_temp_free(t1);
2759        return NO_EXIT;
2760    }
2761
2762    /* First load the values of the first and last registers to trigger
2763       possible page faults. */
2764    t2 = tcg_temp_new_i64();
2765    tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2766    tcg_gen_addi_i64(t2, o->in2, 4 * ((r3 - r1) & 15));
2767    tcg_gen_qemu_ld32u(t2, t2, get_mem_index(s));
2768    store_reg32_i64(r1, t1);
2769    store_reg32_i64(r3, t2);
2770
2771    /* Only two registers to read. */
2772    if (((r1 + 1) & 15) == r3) {
2773        tcg_temp_free(t2);
2774        tcg_temp_free(t1);
2775        return NO_EXIT;
2776    }
2777
2778    /* Then load the remaining registers. Page fault can't occur. */
2779    r3 = (r3 - 1) & 15;
2780    tcg_gen_movi_i64(t2, 4);
2781    while (r1 != r3) {
2782        r1 = (r1 + 1) & 15;
2783        tcg_gen_add_i64(o->in2, o->in2, t2);
2784        tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2785        store_reg32_i64(r1, t1);
2786    }
2787    tcg_temp_free(t2);
2788    tcg_temp_free(t1);
2789
2790    return NO_EXIT;
2791}
2792
2793static ExitStatus op_lmh(DisasContext *s, DisasOps *o)
2794{
2795    int r1 = get_field(s->fields, r1);
2796    int r3 = get_field(s->fields, r3);
2797    TCGv_i64 t1, t2;
2798
2799    /* Only one register to read. */
2800    t1 = tcg_temp_new_i64();
2801    if (unlikely(r1 == r3)) {
2802        tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2803        store_reg32h_i64(r1, t1);
2804        tcg_temp_free(t1);
2805        return NO_EXIT;
2806    }
2807
2808    /* First load the values of the first and last registers to trigger
2809       possible page faults. */
2810    t2 = tcg_temp_new_i64();
2811    tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2812    tcg_gen_addi_i64(t2, o->in2, 4 * ((r3 - r1) & 15));
2813    tcg_gen_qemu_ld32u(t2, t2, get_mem_index(s));
2814    store_reg32h_i64(r1, t1);
2815    store_reg32h_i64(r3, t2);
2816
2817    /* Only two registers to read. */
2818    if (((r1 + 1) & 15) == r3) {
2819        tcg_temp_free(t2);
2820        tcg_temp_free(t1);
2821        return NO_EXIT;
2822    }
2823
2824    /* Then load the remaining registers. Page fault can't occur. */
2825    r3 = (r3 - 1) & 15;
2826    tcg_gen_movi_i64(t2, 4);
2827    while (r1 != r3) {
2828        r1 = (r1 + 1) & 15;
2829        tcg_gen_add_i64(o->in2, o->in2, t2);
2830        tcg_gen_qemu_ld32u(t1, o->in2, get_mem_index(s));
2831        store_reg32h_i64(r1, t1);
2832    }
2833    tcg_temp_free(t2);
2834    tcg_temp_free(t1);
2835
2836    return NO_EXIT;
2837}
2838
2839static ExitStatus op_lm64(DisasContext *s, DisasOps *o)
2840{
2841    int r1 = get_field(s->fields, r1);
2842    int r3 = get_field(s->fields, r3);
2843    TCGv_i64 t1, t2;
2844
2845    /* Only one register to read. */
2846    if (unlikely(r1 == r3)) {
2847        tcg_gen_qemu_ld64(regs[r1], o->in2, get_mem_index(s));
2848        return NO_EXIT;
2849    }
2850
2851    /* First load the values of the first and last registers to trigger
2852       possible page faults. */
2853    t1 = tcg_temp_new_i64();
2854    t2 = tcg_temp_new_i64();
2855    tcg_gen_qemu_ld64(t1, o->in2, get_mem_index(s));
2856    tcg_gen_addi_i64(t2, o->in2, 8 * ((r3 - r1) & 15));
2857    tcg_gen_qemu_ld64(regs[r3], t2, get_mem_index(s));
2858    tcg_gen_mov_i64(regs[r1], t1);
2859    tcg_temp_free(t2);
2860
2861    /* Only two registers to read. */
2862    if (((r1 + 1) & 15) == r3) {
2863        tcg_temp_free(t1);
2864        return NO_EXIT;
2865    }
2866
2867    /* Then load the remaining registers. Page fault can't occur. */
2868    r3 = (r3 - 1) & 15;
2869    tcg_gen_movi_i64(t1, 8);
2870    while (r1 != r3) {
2871        r1 = (r1 + 1) & 15;
2872        tcg_gen_add_i64(o->in2, o->in2, t1);
2873        tcg_gen_qemu_ld64(regs[r1], o->in2, get_mem_index(s));
2874    }
2875    tcg_temp_free(t1);
2876
2877    return NO_EXIT;
2878}
2879
2880static ExitStatus op_lpd(DisasContext *s, DisasOps *o)
2881{
2882    TCGv_i64 a1, a2;
2883    TCGMemOp mop = s->insn->data;
2884
2885    /* In a parallel context, stop the world and single step.  */
2886    if (parallel_cpus) {
2887        potential_page_fault(s);
2888        gen_exception(EXCP_ATOMIC);
2889        return EXIT_NORETURN;
2890    }
2891
2892    /* In a serial context, perform the two loads ... */
2893    a1 = get_address(s, 0, get_field(s->fields, b1), get_field(s->fields, d1));
2894    a2 = get_address(s, 0, get_field(s->fields, b2), get_field(s->fields, d2));
2895    tcg_gen_qemu_ld_i64(o->out, a1, get_mem_index(s), mop | MO_ALIGN);
2896    tcg_gen_qemu_ld_i64(o->out2, a2, get_mem_index(s), mop | MO_ALIGN);
2897    tcg_temp_free_i64(a1);
2898    tcg_temp_free_i64(a2);
2899
2900    /* ... and indicate that we performed them while interlocked.  */
2901    gen_op_movi_cc(s, 0);
2902    return NO_EXIT;
2903}
2904
2905static ExitStatus op_lpq(DisasContext *s, DisasOps *o)
2906{
2907    gen_helper_lpq(o->out, cpu_env, o->in2);
2908    return_low128(o->out2);
2909    return NO_EXIT;
2910}
2911
2912#ifndef CONFIG_USER_ONLY
2913static ExitStatus op_lura(DisasContext *s, DisasOps *o)
2914{
2915    check_privileged(s);
2916    potential_page_fault(s);
2917    gen_helper_lura(o->out, cpu_env, o->in2);
2918    return NO_EXIT;
2919}
2920
2921static ExitStatus op_lurag(DisasContext *s, DisasOps *o)
2922{
2923    check_privileged(s);
2924    potential_page_fault(s);
2925    gen_helper_lurag(o->out, cpu_env, o->in2);
2926    return NO_EXIT;
2927}
2928#endif
2929
2930static ExitStatus op_lzrb(DisasContext *s, DisasOps *o)
2931{
2932    tcg_gen_andi_i64(o->out, o->in2, -256);
2933    return NO_EXIT;
2934}
2935
2936static ExitStatus op_mov2(DisasContext *s, DisasOps *o)
2937{
2938    o->out = o->in2;
2939    o->g_out = o->g_in2;
2940    TCGV_UNUSED_I64(o->in2);
2941    o->g_in2 = false;
2942    return NO_EXIT;
2943}
2944
2945static ExitStatus op_mov2e(DisasContext *s, DisasOps *o)
2946{
2947    int b2 = get_field(s->fields, b2);
2948    TCGv ar1 = tcg_temp_new_i64();
2949
2950    o->out = o->in2;
2951    o->g_out = o->g_in2;
2952    TCGV_UNUSED_I64(o->in2);
2953    o->g_in2 = false;
2954
2955    switch (s->tb->flags & FLAG_MASK_ASC) {
2956    case PSW_ASC_PRIMARY >> FLAG_MASK_PSW_SHIFT:
2957        tcg_gen_movi_i64(ar1, 0);
2958        break;
2959    case PSW_ASC_ACCREG >> FLAG_MASK_PSW_SHIFT:
2960        tcg_gen_movi_i64(ar1, 1);
2961        break;
2962    case PSW_ASC_SECONDARY >> FLAG_MASK_PSW_SHIFT:
2963        if (b2) {
2964            tcg_gen_ld32u_i64(ar1, cpu_env, offsetof(CPUS390XState, aregs[b2]));
2965        } else {
2966            tcg_gen_movi_i64(ar1, 0);
2967        }
2968        break;
2969    case PSW_ASC_HOME >> FLAG_MASK_PSW_SHIFT:
2970        tcg_gen_movi_i64(ar1, 2);
2971        break;
2972    }
2973
2974    tcg_gen_st32_i64(ar1, cpu_env, offsetof(CPUS390XState, aregs[1]));
2975    tcg_temp_free_i64(ar1);
2976
2977    return NO_EXIT;
2978}
2979
2980static ExitStatus op_movx(DisasContext *s, DisasOps *o)
2981{
2982    o->out = o->in1;
2983    o->out2 = o->in2;
2984    o->g_out = o->g_in1;
2985    o->g_out2 = o->g_in2;
2986    TCGV_UNUSED_I64(o->in1);
2987    TCGV_UNUSED_I64(o->in2);
2988    o->g_in1 = o->g_in2 = false;
2989    return NO_EXIT;
2990}
2991
2992static ExitStatus op_mvc(DisasContext *s, DisasOps *o)
2993{
2994    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
2995    gen_helper_mvc(cpu_env, l, o->addr1, o->in2);
2996    tcg_temp_free_i32(l);
2997    return NO_EXIT;
2998}
2999
3000static ExitStatus op_mvcin(DisasContext *s, DisasOps *o)
3001{
3002    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3003    gen_helper_mvcin(cpu_env, l, o->addr1, o->in2);
3004    tcg_temp_free_i32(l);
3005    return NO_EXIT;
3006}
3007
3008static ExitStatus op_mvcl(DisasContext *s, DisasOps *o)
3009{
3010    int r1 = get_field(s->fields, r1);
3011    int r2 = get_field(s->fields, r2);
3012    TCGv_i32 t1, t2;
3013
3014    /* r1 and r2 must be even.  */
3015    if (r1 & 1 || r2 & 1) {
3016        gen_program_exception(s, PGM_SPECIFICATION);
3017        return EXIT_NORETURN;
3018    }
3019
3020    t1 = tcg_const_i32(r1);
3021    t2 = tcg_const_i32(r2);
3022    gen_helper_mvcl(cc_op, cpu_env, t1, t2);
3023    tcg_temp_free_i32(t1);
3024    tcg_temp_free_i32(t2);
3025    set_cc_static(s);
3026    return NO_EXIT;
3027}
3028
3029static ExitStatus op_mvcle(DisasContext *s, DisasOps *o)
3030{
3031    int r1 = get_field(s->fields, r1);
3032    int r3 = get_field(s->fields, r3);
3033    TCGv_i32 t1, t3;
3034
3035    /* r1 and r3 must be even.  */
3036    if (r1 & 1 || r3 & 1) {
3037        gen_program_exception(s, PGM_SPECIFICATION);
3038        return EXIT_NORETURN;
3039    }
3040
3041    t1 = tcg_const_i32(r1);
3042    t3 = tcg_const_i32(r3);
3043    gen_helper_mvcle(cc_op, cpu_env, t1, o->in2, t3);
3044    tcg_temp_free_i32(t1);
3045    tcg_temp_free_i32(t3);
3046    set_cc_static(s);
3047    return NO_EXIT;
3048}
3049
3050static ExitStatus op_mvclu(DisasContext *s, DisasOps *o)
3051{
3052    int r1 = get_field(s->fields, r1);
3053    int r3 = get_field(s->fields, r3);
3054    TCGv_i32 t1, t3;
3055
3056    /* r1 and r3 must be even.  */
3057    if (r1 & 1 || r3 & 1) {
3058        gen_program_exception(s, PGM_SPECIFICATION);
3059        return EXIT_NORETURN;
3060    }
3061
3062    t1 = tcg_const_i32(r1);
3063    t3 = tcg_const_i32(r3);
3064    gen_helper_mvclu(cc_op, cpu_env, t1, o->in2, t3);
3065    tcg_temp_free_i32(t1);
3066    tcg_temp_free_i32(t3);
3067    set_cc_static(s);
3068    return NO_EXIT;
3069}
3070
3071static ExitStatus op_mvcos(DisasContext *s, DisasOps *o)
3072{
3073    int r3 = get_field(s->fields, r3);
3074    gen_helper_mvcos(cc_op, cpu_env, o->addr1, o->in2, regs[r3]);
3075    set_cc_static(s);
3076    return NO_EXIT;
3077}
3078
3079#ifndef CONFIG_USER_ONLY
3080static ExitStatus op_mvcp(DisasContext *s, DisasOps *o)
3081{
3082    int r1 = get_field(s->fields, l1);
3083    check_privileged(s);
3084    gen_helper_mvcp(cc_op, cpu_env, regs[r1], o->addr1, o->in2);
3085    set_cc_static(s);
3086    return NO_EXIT;
3087}
3088
3089static ExitStatus op_mvcs(DisasContext *s, DisasOps *o)
3090{
3091    int r1 = get_field(s->fields, l1);
3092    check_privileged(s);
3093    gen_helper_mvcs(cc_op, cpu_env, regs[r1], o->addr1, o->in2);
3094    set_cc_static(s);
3095    return NO_EXIT;
3096}
3097#endif
3098
3099static ExitStatus op_mvn(DisasContext *s, DisasOps *o)
3100{
3101    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3102    gen_helper_mvn(cpu_env, l, o->addr1, o->in2);
3103    tcg_temp_free_i32(l);
3104    return NO_EXIT;
3105}
3106
3107static ExitStatus op_mvo(DisasContext *s, DisasOps *o)
3108{
3109    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3110    gen_helper_mvo(cpu_env, l, o->addr1, o->in2);
3111    tcg_temp_free_i32(l);
3112    return NO_EXIT;
3113}
3114
3115static ExitStatus op_mvpg(DisasContext *s, DisasOps *o)
3116{
3117    gen_helper_mvpg(cc_op, cpu_env, regs[0], o->in1, o->in2);
3118    set_cc_static(s);
3119    return NO_EXIT;
3120}
3121
3122static ExitStatus op_mvst(DisasContext *s, DisasOps *o)
3123{
3124    gen_helper_mvst(o->in1, cpu_env, regs[0], o->in1, o->in2);
3125    set_cc_static(s);
3126    return_low128(o->in2);
3127    return NO_EXIT;
3128}
3129
3130static ExitStatus op_mvz(DisasContext *s, DisasOps *o)
3131{
3132    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3133    gen_helper_mvz(cpu_env, l, o->addr1, o->in2);
3134    tcg_temp_free_i32(l);
3135    return NO_EXIT;
3136}
3137
3138static ExitStatus op_mul(DisasContext *s, DisasOps *o)
3139{
3140    tcg_gen_mul_i64(o->out, o->in1, o->in2);
3141    return NO_EXIT;
3142}
3143
3144static ExitStatus op_mul128(DisasContext *s, DisasOps *o)
3145{
3146    tcg_gen_mulu2_i64(o->out2, o->out, o->in1, o->in2);
3147    return NO_EXIT;
3148}
3149
3150static ExitStatus op_meeb(DisasContext *s, DisasOps *o)
3151{
3152    gen_helper_meeb(o->out, cpu_env, o->in1, o->in2);
3153    return NO_EXIT;
3154}
3155
3156static ExitStatus op_mdeb(DisasContext *s, DisasOps *o)
3157{
3158    gen_helper_mdeb(o->out, cpu_env, o->in1, o->in2);
3159    return NO_EXIT;
3160}
3161
3162static ExitStatus op_mdb(DisasContext *s, DisasOps *o)
3163{
3164    gen_helper_mdb(o->out, cpu_env, o->in1, o->in2);
3165    return NO_EXIT;
3166}
3167
3168static ExitStatus op_mxb(DisasContext *s, DisasOps *o)
3169{
3170    gen_helper_mxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
3171    return_low128(o->out2);
3172    return NO_EXIT;
3173}
3174
3175static ExitStatus op_mxdb(DisasContext *s, DisasOps *o)
3176{
3177    gen_helper_mxdb(o->out, cpu_env, o->out, o->out2, o->in2);
3178    return_low128(o->out2);
3179    return NO_EXIT;
3180}
3181
3182static ExitStatus op_maeb(DisasContext *s, DisasOps *o)
3183{
3184    TCGv_i64 r3 = load_freg32_i64(get_field(s->fields, r3));
3185    gen_helper_maeb(o->out, cpu_env, o->in1, o->in2, r3);
3186    tcg_temp_free_i64(r3);
3187    return NO_EXIT;
3188}
3189
3190static ExitStatus op_madb(DisasContext *s, DisasOps *o)
3191{
3192    int r3 = get_field(s->fields, r3);
3193    gen_helper_madb(o->out, cpu_env, o->in1, o->in2, fregs[r3]);
3194    return NO_EXIT;
3195}
3196
3197static ExitStatus op_mseb(DisasContext *s, DisasOps *o)
3198{
3199    TCGv_i64 r3 = load_freg32_i64(get_field(s->fields, r3));
3200    gen_helper_mseb(o->out, cpu_env, o->in1, o->in2, r3);
3201    tcg_temp_free_i64(r3);
3202    return NO_EXIT;
3203}
3204
3205static ExitStatus op_msdb(DisasContext *s, DisasOps *o)
3206{
3207    int r3 = get_field(s->fields, r3);
3208    gen_helper_msdb(o->out, cpu_env, o->in1, o->in2, fregs[r3]);
3209    return NO_EXIT;
3210}
3211
3212static ExitStatus op_nabs(DisasContext *s, DisasOps *o)
3213{
3214    TCGv_i64 z, n;
3215    z = tcg_const_i64(0);
3216    n = tcg_temp_new_i64();
3217    tcg_gen_neg_i64(n, o->in2);
3218    tcg_gen_movcond_i64(TCG_COND_GE, o->out, o->in2, z, n, o->in2);
3219    tcg_temp_free_i64(n);
3220    tcg_temp_free_i64(z);
3221    return NO_EXIT;
3222}
3223
3224static ExitStatus op_nabsf32(DisasContext *s, DisasOps *o)
3225{
3226    tcg_gen_ori_i64(o->out, o->in2, 0x80000000ull);
3227    return NO_EXIT;
3228}
3229
3230static ExitStatus op_nabsf64(DisasContext *s, DisasOps *o)
3231{
3232    tcg_gen_ori_i64(o->out, o->in2, 0x8000000000000000ull);
3233    return NO_EXIT;
3234}
3235
3236static ExitStatus op_nabsf128(DisasContext *s, DisasOps *o)
3237{
3238    tcg_gen_ori_i64(o->out, o->in1, 0x8000000000000000ull);
3239    tcg_gen_mov_i64(o->out2, o->in2);
3240    return NO_EXIT;
3241}
3242
3243static ExitStatus op_nc(DisasContext *s, DisasOps *o)
3244{
3245    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3246    gen_helper_nc(cc_op, cpu_env, l, o->addr1, o->in2);
3247    tcg_temp_free_i32(l);
3248    set_cc_static(s);
3249    return NO_EXIT;
3250}
3251
3252static ExitStatus op_neg(DisasContext *s, DisasOps *o)
3253{
3254    tcg_gen_neg_i64(o->out, o->in2);
3255    return NO_EXIT;
3256}
3257
3258static ExitStatus op_negf32(DisasContext *s, DisasOps *o)
3259{
3260    tcg_gen_xori_i64(o->out, o->in2, 0x80000000ull);
3261    return NO_EXIT;
3262}
3263
3264static ExitStatus op_negf64(DisasContext *s, DisasOps *o)
3265{
3266    tcg_gen_xori_i64(o->out, o->in2, 0x8000000000000000ull);
3267    return NO_EXIT;
3268}
3269
3270static ExitStatus op_negf128(DisasContext *s, DisasOps *o)
3271{
3272    tcg_gen_xori_i64(o->out, o->in1, 0x8000000000000000ull);
3273    tcg_gen_mov_i64(o->out2, o->in2);
3274    return NO_EXIT;
3275}
3276
3277static ExitStatus op_oc(DisasContext *s, DisasOps *o)
3278{
3279    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3280    gen_helper_oc(cc_op, cpu_env, l, o->addr1, o->in2);
3281    tcg_temp_free_i32(l);
3282    set_cc_static(s);
3283    return NO_EXIT;
3284}
3285
3286static ExitStatus op_or(DisasContext *s, DisasOps *o)
3287{
3288    tcg_gen_or_i64(o->out, o->in1, o->in2);
3289    return NO_EXIT;
3290}
3291
3292static ExitStatus op_ori(DisasContext *s, DisasOps *o)
3293{
3294    int shift = s->insn->data & 0xff;
3295    int size = s->insn->data >> 8;
3296    uint64_t mask = ((1ull << size) - 1) << shift;
3297
3298    assert(!o->g_in2);
3299    tcg_gen_shli_i64(o->in2, o->in2, shift);
3300    tcg_gen_or_i64(o->out, o->in1, o->in2);
3301
3302    /* Produce the CC from only the bits manipulated.  */
3303    tcg_gen_andi_i64(cc_dst, o->out, mask);
3304    set_cc_nz_u64(s, cc_dst);
3305    return NO_EXIT;
3306}
3307
3308static ExitStatus op_pack(DisasContext *s, DisasOps *o)
3309{
3310    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
3311    gen_helper_pack(cpu_env, l, o->addr1, o->in2);
3312    tcg_temp_free_i32(l);
3313    return NO_EXIT;
3314}
3315
3316static ExitStatus op_pka(DisasContext *s, DisasOps *o)
3317{
3318    int l2 = get_field(s->fields, l2) + 1;
3319    TCGv_i32 l;
3320
3321    /* The length must not exceed 32 bytes.  */
3322    if (l2 > 32) {
3323        gen_program_exception(s, PGM_SPECIFICATION);
3324        return EXIT_NORETURN;
3325    }
3326    l = tcg_const_i32(l2);
3327    gen_helper_pka(cpu_env, o->addr1, o->in2, l);
3328    tcg_temp_free_i32(l);
3329    return NO_EXIT;
3330}
3331
3332static ExitStatus op_pku(DisasContext *s, DisasOps *o)
3333{
3334    int l2 = get_field(s->fields, l2) + 1;
3335    TCGv_i32 l;
3336
3337    /* The length must be even and should not exceed 64 bytes.  */
3338    if ((l2 & 1) || (l2 > 64)) {
3339        gen_program_exception(s, PGM_SPECIFICATION);
3340        return EXIT_NORETURN;
3341    }
3342    l = tcg_const_i32(l2);
3343    gen_helper_pku(cpu_env, o->addr1, o->in2, l);
3344    tcg_temp_free_i32(l);
3345    return NO_EXIT;
3346}
3347
3348static ExitStatus op_popcnt(DisasContext *s, DisasOps *o)
3349{
3350    gen_helper_popcnt(o->out, o->in2);
3351    return NO_EXIT;
3352}
3353
3354#ifndef CONFIG_USER_ONLY
3355static ExitStatus op_ptlb(DisasContext *s, DisasOps *o)
3356{
3357    check_privileged(s);
3358    gen_helper_ptlb(cpu_env);
3359    return NO_EXIT;
3360}
3361#endif
3362
3363static ExitStatus op_risbg(DisasContext *s, DisasOps *o)
3364{
3365    int i3 = get_field(s->fields, i3);
3366    int i4 = get_field(s->fields, i4);
3367    int i5 = get_field(s->fields, i5);
3368    int do_zero = i4 & 0x80;
3369    uint64_t mask, imask, pmask;
3370    int pos, len, rot;
3371
3372    /* Adjust the arguments for the specific insn.  */
3373    switch (s->fields->op2) {
3374    case 0x55: /* risbg */
3375        i3 &= 63;
3376        i4 &= 63;
3377        pmask = ~0;
3378        break;
3379    case 0x5d: /* risbhg */
3380        i3 &= 31;
3381        i4 &= 31;
3382        pmask = 0xffffffff00000000ull;
3383        break;
3384    case 0x51: /* risblg */
3385        i3 &= 31;
3386        i4 &= 31;
3387        pmask = 0x00000000ffffffffull;
3388        break;
3389    default:
3390        abort();
3391    }
3392
3393    /* MASK is the set of bits to be inserted from R2.
3394       Take care for I3/I4 wraparound.  */
3395    mask = pmask >> i3;
3396    if (i3 <= i4) {
3397        mask ^= pmask >> i4 >> 1;
3398    } else {
3399        mask |= ~(pmask >> i4 >> 1);
3400    }
3401    mask &= pmask;
3402
3403    /* IMASK is the set of bits to be kept from R1.  In the case of the high/low
3404       insns, we need to keep the other half of the register.  */
3405    imask = ~mask | ~pmask;
3406    if (do_zero) {
3407        if (s->fields->op2 == 0x55) {
3408            imask = 0;
3409        } else {
3410            imask = ~pmask;
3411        }
3412    }
3413
3414    len = i4 - i3 + 1;
3415    pos = 63 - i4;
3416    rot = i5 & 63;
3417    if (s->fields->op2 == 0x5d) {
3418        pos += 32;
3419    }
3420
3421    /* In some cases we can implement this with extract.  */
3422    if (imask == 0 && pos == 0 && len > 0 && len <= rot) {
3423        tcg_gen_extract_i64(o->out, o->in2, 64 - rot, len);
3424        return NO_EXIT;
3425    }
3426
3427    /* In some cases we can implement this with deposit.  */
3428    if (len > 0 && (imask == 0 || ~mask == imask)) {
3429        /* Note that we rotate the bits to be inserted to the lsb, not to
3430           the position as described in the PoO.  */
3431        rot = (rot - pos) & 63;
3432    } else {
3433        pos = -1;
3434    }
3435
3436    /* Rotate the input as necessary.  */
3437    tcg_gen_rotli_i64(o->in2, o->in2, rot);
3438
3439    /* Insert the selected bits into the output.  */
3440    if (pos >= 0) {
3441        if (imask == 0) {
3442            tcg_gen_deposit_z_i64(o->out, o->in2, pos, len);
3443        } else {
3444            tcg_gen_deposit_i64(o->out, o->out, o->in2, pos, len);
3445        }
3446    } else if (imask == 0) {
3447        tcg_gen_andi_i64(o->out, o->in2, mask);
3448    } else {
3449        tcg_gen_andi_i64(o->in2, o->in2, mask);
3450        tcg_gen_andi_i64(o->out, o->out, imask);
3451        tcg_gen_or_i64(o->out, o->out, o->in2);
3452    }
3453    return NO_EXIT;
3454}
3455
3456static ExitStatus op_rosbg(DisasContext *s, DisasOps *o)
3457{
3458    int i3 = get_field(s->fields, i3);
3459    int i4 = get_field(s->fields, i4);
3460    int i5 = get_field(s->fields, i5);
3461    uint64_t mask;
3462
3463    /* If this is a test-only form, arrange to discard the result.  */
3464    if (i3 & 0x80) {
3465        o->out = tcg_temp_new_i64();
3466        o->g_out = false;
3467    }
3468
3469    i3 &= 63;
3470    i4 &= 63;
3471    i5 &= 63;
3472
3473    /* MASK is the set of bits to be operated on from R2.
3474       Take care for I3/I4 wraparound.  */
3475    mask = ~0ull >> i3;
3476    if (i3 <= i4) {
3477        mask ^= ~0ull >> i4 >> 1;
3478    } else {
3479        mask |= ~(~0ull >> i4 >> 1);
3480    }
3481
3482    /* Rotate the input as necessary.  */
3483    tcg_gen_rotli_i64(o->in2, o->in2, i5);
3484
3485    /* Operate.  */
3486    switch (s->fields->op2) {
3487    case 0x55: /* AND */
3488        tcg_gen_ori_i64(o->in2, o->in2, ~mask);
3489        tcg_gen_and_i64(o->out, o->out, o->in2);
3490        break;
3491    case 0x56: /* OR */
3492        tcg_gen_andi_i64(o->in2, o->in2, mask);
3493        tcg_gen_or_i64(o->out, o->out, o->in2);
3494        break;
3495    case 0x57: /* XOR */
3496        tcg_gen_andi_i64(o->in2, o->in2, mask);
3497        tcg_gen_xor_i64(o->out, o->out, o->in2);
3498        break;
3499    default:
3500        abort();
3501    }
3502
3503    /* Set the CC.  */
3504    tcg_gen_andi_i64(cc_dst, o->out, mask);
3505    set_cc_nz_u64(s, cc_dst);
3506    return NO_EXIT;
3507}
3508
3509static ExitStatus op_rev16(DisasContext *s, DisasOps *o)
3510{
3511    tcg_gen_bswap16_i64(o->out, o->in2);
3512    return NO_EXIT;
3513}
3514
3515static ExitStatus op_rev32(DisasContext *s, DisasOps *o)
3516{
3517    tcg_gen_bswap32_i64(o->out, o->in2);
3518    return NO_EXIT;
3519}
3520
3521static ExitStatus op_rev64(DisasContext *s, DisasOps *o)
3522{
3523    tcg_gen_bswap64_i64(o->out, o->in2);
3524    return NO_EXIT;
3525}
3526
3527static ExitStatus op_rll32(DisasContext *s, DisasOps *o)
3528{
3529    TCGv_i32 t1 = tcg_temp_new_i32();
3530    TCGv_i32 t2 = tcg_temp_new_i32();
3531    TCGv_i32 to = tcg_temp_new_i32();
3532    tcg_gen_extrl_i64_i32(t1, o->in1);
3533    tcg_gen_extrl_i64_i32(t2, o->in2);
3534    tcg_gen_rotl_i32(to, t1, t2);
3535    tcg_gen_extu_i32_i64(o->out, to);
3536    tcg_temp_free_i32(t1);
3537    tcg_temp_free_i32(t2);
3538    tcg_temp_free_i32(to);
3539    return NO_EXIT;
3540}
3541
3542static ExitStatus op_rll64(DisasContext *s, DisasOps *o)
3543{
3544    tcg_gen_rotl_i64(o->out, o->in1, o->in2);
3545    return NO_EXIT;
3546}
3547
3548#ifndef CONFIG_USER_ONLY
3549static ExitStatus op_rrbe(DisasContext *s, DisasOps *o)
3550{
3551    check_privileged(s);
3552    gen_helper_rrbe(cc_op, cpu_env, o->in2);
3553    set_cc_static(s);
3554    return NO_EXIT;
3555}
3556
3557static ExitStatus op_sacf(DisasContext *s, DisasOps *o)
3558{
3559    check_privileged(s);
3560    gen_helper_sacf(cpu_env, o->in2);
3561    /* Addressing mode has changed, so end the block.  */
3562    return EXIT_PC_STALE;
3563}
3564#endif
3565
3566static ExitStatus op_sam(DisasContext *s, DisasOps *o)
3567{
3568    int sam = s->insn->data;
3569    TCGv_i64 tsam;
3570    uint64_t mask;
3571
3572    switch (sam) {
3573    case 0:
3574        mask = 0xffffff;
3575        break;
3576    case 1:
3577        mask = 0x7fffffff;
3578        break;
3579    default:
3580        mask = -1;
3581        break;
3582    }
3583
3584    /* Bizarre but true, we check the address of the current insn for the
3585       specification exception, not the next to be executed.  Thus the PoO
3586       documents that Bad Things Happen two bytes before the end.  */
3587    if (s->pc & ~mask) {
3588        gen_program_exception(s, PGM_SPECIFICATION);
3589        return EXIT_NORETURN;
3590    }
3591    s->next_pc &= mask;
3592
3593    tsam = tcg_const_i64(sam);
3594    tcg_gen_deposit_i64(psw_mask, psw_mask, tsam, 31, 2);
3595    tcg_temp_free_i64(tsam);
3596
3597    /* Always exit the TB, since we (may have) changed execution mode.  */
3598    return EXIT_PC_STALE;
3599}
3600
3601static ExitStatus op_sar(DisasContext *s, DisasOps *o)
3602{
3603    int r1 = get_field(s->fields, r1);
3604    tcg_gen_st32_i64(o->in2, cpu_env, offsetof(CPUS390XState, aregs[r1]));
3605    return NO_EXIT;
3606}
3607
3608static ExitStatus op_seb(DisasContext *s, DisasOps *o)
3609{
3610    gen_helper_seb(o->out, cpu_env, o->in1, o->in2);
3611    return NO_EXIT;
3612}
3613
3614static ExitStatus op_sdb(DisasContext *s, DisasOps *o)
3615{
3616    gen_helper_sdb(o->out, cpu_env, o->in1, o->in2);
3617    return NO_EXIT;
3618}
3619
3620static ExitStatus op_sxb(DisasContext *s, DisasOps *o)
3621{
3622    gen_helper_sxb(o->out, cpu_env, o->out, o->out2, o->in1, o->in2);
3623    return_low128(o->out2);
3624    return NO_EXIT;
3625}
3626
3627static ExitStatus op_sqeb(DisasContext *s, DisasOps *o)
3628{
3629    gen_helper_sqeb(o->out, cpu_env, o->in2);
3630    return NO_EXIT;
3631}
3632
3633static ExitStatus op_sqdb(DisasContext *s, DisasOps *o)
3634{
3635    gen_helper_sqdb(o->out, cpu_env, o->in2);
3636    return NO_EXIT;
3637}
3638
3639static ExitStatus op_sqxb(DisasContext *s, DisasOps *o)
3640{
3641    gen_helper_sqxb(o->out, cpu_env, o->in1, o->in2);
3642    return_low128(o->out2);
3643    return NO_EXIT;
3644}
3645
3646#ifndef CONFIG_USER_ONLY
3647static ExitStatus op_servc(DisasContext *s, DisasOps *o)
3648{
3649    check_privileged(s);
3650    potential_page_fault(s);
3651    gen_helper_servc(cc_op, cpu_env, o->in2, o->in1);
3652    set_cc_static(s);
3653    return NO_EXIT;
3654}
3655
3656static ExitStatus op_sigp(DisasContext *s, DisasOps *o)
3657{
3658    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
3659    check_privileged(s);
3660    potential_page_fault(s);
3661    gen_helper_sigp(cc_op, cpu_env, o->in2, r1, o->in1);
3662    set_cc_static(s);
3663    tcg_temp_free_i32(r1);
3664    return NO_EXIT;
3665}
3666#endif
3667
3668static ExitStatus op_soc(DisasContext *s, DisasOps *o)
3669{
3670    DisasCompare c;
3671    TCGv_i64 a, h;
3672    TCGLabel *lab;
3673    int r1;
3674
3675    disas_jcc(s, &c, get_field(s->fields, m3));
3676
3677    /* We want to store when the condition is fulfilled, so branch
3678       out when it's not */
3679    c.cond = tcg_invert_cond(c.cond);
3680
3681    lab = gen_new_label();
3682    if (c.is_64) {
3683        tcg_gen_brcond_i64(c.cond, c.u.s64.a, c.u.s64.b, lab);
3684    } else {
3685        tcg_gen_brcond_i32(c.cond, c.u.s32.a, c.u.s32.b, lab);
3686    }
3687    free_compare(&c);
3688
3689    r1 = get_field(s->fields, r1);
3690    a = get_address(s, 0, get_field(s->fields, b2), get_field(s->fields, d2));
3691    switch (s->insn->data) {
3692    case 1: /* STOCG */
3693        tcg_gen_qemu_st64(regs[r1], a, get_mem_index(s));
3694        break;
3695    case 0: /* STOC */
3696        tcg_gen_qemu_st32(regs[r1], a, get_mem_index(s));
3697        break;
3698    case 2: /* STOCFH */
3699        h = tcg_temp_new_i64();
3700        tcg_gen_shri_i64(h, regs[r1], 32);
3701        tcg_gen_qemu_st32(h, a, get_mem_index(s));
3702        tcg_temp_free_i64(h);
3703        break;
3704    default:
3705        g_assert_not_reached();
3706    }
3707    tcg_temp_free_i64(a);
3708
3709    gen_set_label(lab);
3710    return NO_EXIT;
3711}
3712
3713static ExitStatus op_sla(DisasContext *s, DisasOps *o)
3714{
3715    uint64_t sign = 1ull << s->insn->data;
3716    enum cc_op cco = s->insn->data == 31 ? CC_OP_SLA_32 : CC_OP_SLA_64;
3717    gen_op_update2_cc_i64(s, cco, o->in1, o->in2);
3718    tcg_gen_shl_i64(o->out, o->in1, o->in2);
3719    /* The arithmetic left shift is curious in that it does not affect
3720       the sign bit.  Copy that over from the source unchanged.  */
3721    tcg_gen_andi_i64(o->out, o->out, ~sign);
3722    tcg_gen_andi_i64(o->in1, o->in1, sign);
3723    tcg_gen_or_i64(o->out, o->out, o->in1);
3724    return NO_EXIT;
3725}
3726
3727static ExitStatus op_sll(DisasContext *s, DisasOps *o)
3728{
3729    tcg_gen_shl_i64(o->out, o->in1, o->in2);
3730    return NO_EXIT;
3731}
3732
3733static ExitStatus op_sra(DisasContext *s, DisasOps *o)
3734{
3735    tcg_gen_sar_i64(o->out, o->in1, o->in2);
3736    return NO_EXIT;
3737}
3738
3739static ExitStatus op_srl(DisasContext *s, DisasOps *o)
3740{
3741    tcg_gen_shr_i64(o->out, o->in1, o->in2);
3742    return NO_EXIT;
3743}
3744
3745static ExitStatus op_sfpc(DisasContext *s, DisasOps *o)
3746{
3747    gen_helper_sfpc(cpu_env, o->in2);
3748    return NO_EXIT;
3749}
3750
3751static ExitStatus op_sfas(DisasContext *s, DisasOps *o)
3752{
3753    gen_helper_sfas(cpu_env, o->in2);
3754    return NO_EXIT;
3755}
3756
3757static ExitStatus op_srnm(DisasContext *s, DisasOps *o)
3758{
3759    int b2 = get_field(s->fields, b2);
3760    int d2 = get_field(s->fields, d2);
3761    TCGv_i64 t1 = tcg_temp_new_i64();
3762    TCGv_i64 t2 = tcg_temp_new_i64();
3763    int mask, pos, len;
3764
3765    switch (s->fields->op2) {
3766    case 0x99: /* SRNM */
3767        pos = 0, len = 2;
3768        break;
3769    case 0xb8: /* SRNMB */
3770        pos = 0, len = 3;
3771        break;
3772    case 0xb9: /* SRNMT */
3773        pos = 4, len = 3;
3774        break;
3775    default:
3776        tcg_abort();
3777    }
3778    mask = (1 << len) - 1;
3779
3780    /* Insert the value into the appropriate field of the FPC.  */
3781    if (b2 == 0) {
3782        tcg_gen_movi_i64(t1, d2 & mask);
3783    } else {
3784        tcg_gen_addi_i64(t1, regs[b2], d2);
3785        tcg_gen_andi_i64(t1, t1, mask);
3786    }
3787    tcg_gen_ld32u_i64(t2, cpu_env, offsetof(CPUS390XState, fpc));
3788    tcg_gen_deposit_i64(t2, t2, t1, pos, len);
3789    tcg_temp_free_i64(t1);
3790
3791    /* Then install the new FPC to set the rounding mode in fpu_status.  */
3792    gen_helper_sfpc(cpu_env, t2);
3793    tcg_temp_free_i64(t2);
3794    return NO_EXIT;
3795}
3796
3797#ifndef CONFIG_USER_ONLY
3798static ExitStatus op_spka(DisasContext *s, DisasOps *o)
3799{
3800    check_privileged(s);
3801    tcg_gen_shri_i64(o->in2, o->in2, 4);
3802    tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, PSW_SHIFT_KEY, 4);
3803    return NO_EXIT;
3804}
3805
3806static ExitStatus op_sske(DisasContext *s, DisasOps *o)
3807{
3808    check_privileged(s);
3809    gen_helper_sske(cpu_env, o->in1, o->in2);
3810    return NO_EXIT;
3811}
3812
3813static ExitStatus op_ssm(DisasContext *s, DisasOps *o)
3814{
3815    check_privileged(s);
3816    tcg_gen_deposit_i64(psw_mask, psw_mask, o->in2, 56, 8);
3817    /* Exit to main loop to reevaluate s390_cpu_exec_interrupt.  */
3818    return EXIT_PC_STALE_NOCHAIN;
3819}
3820
3821static ExitStatus op_stap(DisasContext *s, DisasOps *o)
3822{
3823    check_privileged(s);
3824    /* ??? Surely cpu address != cpu number.  In any case the previous
3825       version of this stored more than the required half-word, so it
3826       is unlikely this has ever been tested.  */
3827    tcg_gen_ld32u_i64(o->out, cpu_env, offsetof(CPUS390XState, cpu_num));
3828    return NO_EXIT;
3829}
3830
3831static ExitStatus op_stck(DisasContext *s, DisasOps *o)
3832{
3833    gen_helper_stck(o->out, cpu_env);
3834    /* ??? We don't implement clock states.  */
3835    gen_op_movi_cc(s, 0);
3836    return NO_EXIT;
3837}
3838
3839static ExitStatus op_stcke(DisasContext *s, DisasOps *o)
3840{
3841    TCGv_i64 c1 = tcg_temp_new_i64();
3842    TCGv_i64 c2 = tcg_temp_new_i64();
3843    gen_helper_stck(c1, cpu_env);
3844    /* Shift the 64-bit value into its place as a zero-extended
3845       104-bit value.  Note that "bit positions 64-103 are always
3846       non-zero so that they compare differently to STCK"; we set
3847       the least significant bit to 1.  */
3848    tcg_gen_shli_i64(c2, c1, 56);
3849    tcg_gen_shri_i64(c1, c1, 8);
3850    tcg_gen_ori_i64(c2, c2, 0x10000);
3851    tcg_gen_qemu_st64(c1, o->in2, get_mem_index(s));
3852    tcg_gen_addi_i64(o->in2, o->in2, 8);
3853    tcg_gen_qemu_st64(c2, o->in2, get_mem_index(s));
3854    tcg_temp_free_i64(c1);
3855    tcg_temp_free_i64(c2);
3856    /* ??? We don't implement clock states.  */
3857    gen_op_movi_cc(s, 0);
3858    return NO_EXIT;
3859}
3860
3861static ExitStatus op_sckc(DisasContext *s, DisasOps *o)
3862{
3863    check_privileged(s);
3864    gen_helper_sckc(cpu_env, o->in2);
3865    return NO_EXIT;
3866}
3867
3868static ExitStatus op_stckc(DisasContext *s, DisasOps *o)
3869{
3870    check_privileged(s);
3871    gen_helper_stckc(o->out, cpu_env);
3872    return NO_EXIT;
3873}
3874
3875static ExitStatus op_stctg(DisasContext *s, DisasOps *o)
3876{
3877    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
3878    TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
3879    check_privileged(s);
3880    gen_helper_stctg(cpu_env, r1, o->in2, r3);
3881    tcg_temp_free_i32(r1);
3882    tcg_temp_free_i32(r3);
3883    return NO_EXIT;
3884}
3885
3886static ExitStatus op_stctl(DisasContext *s, DisasOps *o)
3887{
3888    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
3889    TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
3890    check_privileged(s);
3891    gen_helper_stctl(cpu_env, r1, o->in2, r3);
3892    tcg_temp_free_i32(r1);
3893    tcg_temp_free_i32(r3);
3894    return NO_EXIT;
3895}
3896
3897static ExitStatus op_stidp(DisasContext *s, DisasOps *o)
3898{
3899    check_privileged(s);
3900    tcg_gen_ld_i64(o->out, cpu_env, offsetof(CPUS390XState, cpuid));
3901    tcg_gen_qemu_st_i64(o->out, o->addr1, get_mem_index(s), MO_TEQ | MO_ALIGN);
3902    return NO_EXIT;
3903}
3904
3905static ExitStatus op_spt(DisasContext *s, DisasOps *o)
3906{
3907    check_privileged(s);
3908    gen_helper_spt(cpu_env, o->in2);
3909    return NO_EXIT;
3910}
3911
3912static ExitStatus op_stfl(DisasContext *s, DisasOps *o)
3913{
3914    check_privileged(s);
3915    gen_helper_stfl(cpu_env);
3916    return NO_EXIT;
3917}
3918
3919static ExitStatus op_stpt(DisasContext *s, DisasOps *o)
3920{
3921    check_privileged(s);
3922    gen_helper_stpt(o->out, cpu_env);
3923    return NO_EXIT;
3924}
3925
3926static ExitStatus op_stsi(DisasContext *s, DisasOps *o)
3927{
3928    check_privileged(s);
3929    potential_page_fault(s);
3930    gen_helper_stsi(cc_op, cpu_env, o->in2, regs[0], regs[1]);
3931    set_cc_static(s);
3932    return NO_EXIT;
3933}
3934
3935static ExitStatus op_spx(DisasContext *s, DisasOps *o)
3936{
3937    check_privileged(s);
3938    gen_helper_spx(cpu_env, o->in2);
3939    return NO_EXIT;
3940}
3941
3942static ExitStatus op_xsch(DisasContext *s, DisasOps *o)
3943{
3944    check_privileged(s);
3945    potential_page_fault(s);
3946    gen_helper_xsch(cpu_env, regs[1]);
3947    set_cc_static(s);
3948    return NO_EXIT;
3949}
3950
3951static ExitStatus op_csch(DisasContext *s, DisasOps *o)
3952{
3953    check_privileged(s);
3954    potential_page_fault(s);
3955    gen_helper_csch(cpu_env, regs[1]);
3956    set_cc_static(s);
3957    return NO_EXIT;
3958}
3959
3960static ExitStatus op_hsch(DisasContext *s, DisasOps *o)
3961{
3962    check_privileged(s);
3963    potential_page_fault(s);
3964    gen_helper_hsch(cpu_env, regs[1]);
3965    set_cc_static(s);
3966    return NO_EXIT;
3967}
3968
3969static ExitStatus op_msch(DisasContext *s, DisasOps *o)
3970{
3971    check_privileged(s);
3972    potential_page_fault(s);
3973    gen_helper_msch(cpu_env, regs[1], o->in2);
3974    set_cc_static(s);
3975    return NO_EXIT;
3976}
3977
3978static ExitStatus op_rchp(DisasContext *s, DisasOps *o)
3979{
3980    check_privileged(s);
3981    potential_page_fault(s);
3982    gen_helper_rchp(cpu_env, regs[1]);
3983    set_cc_static(s);
3984    return NO_EXIT;
3985}
3986
3987static ExitStatus op_rsch(DisasContext *s, DisasOps *o)
3988{
3989    check_privileged(s);
3990    potential_page_fault(s);
3991    gen_helper_rsch(cpu_env, regs[1]);
3992    set_cc_static(s);
3993    return NO_EXIT;
3994}
3995
3996static ExitStatus op_ssch(DisasContext *s, DisasOps *o)
3997{
3998    check_privileged(s);
3999    potential_page_fault(s);
4000    gen_helper_ssch(cpu_env, regs[1], o->in2);
4001    set_cc_static(s);
4002    return NO_EXIT;
4003}
4004
4005static ExitStatus op_stsch(DisasContext *s, DisasOps *o)
4006{
4007    check_privileged(s);
4008    potential_page_fault(s);
4009    gen_helper_stsch(cpu_env, regs[1], o->in2);
4010    set_cc_static(s);
4011    return NO_EXIT;
4012}
4013
4014static ExitStatus op_tsch(DisasContext *s, DisasOps *o)
4015{
4016    check_privileged(s);
4017    potential_page_fault(s);
4018    gen_helper_tsch(cpu_env, regs[1], o->in2);
4019    set_cc_static(s);
4020    return NO_EXIT;
4021}
4022
4023static ExitStatus op_chsc(DisasContext *s, DisasOps *o)
4024{
4025    check_privileged(s);
4026    potential_page_fault(s);
4027    gen_helper_chsc(cpu_env, o->in2);
4028    set_cc_static(s);
4029    return NO_EXIT;
4030}
4031
4032static ExitStatus op_stpx(DisasContext *s, DisasOps *o)
4033{
4034    check_privileged(s);
4035    tcg_gen_ld_i64(o->out, cpu_env, offsetof(CPUS390XState, psa));
4036    tcg_gen_andi_i64(o->out, o->out, 0x7fffe000);
4037    return NO_EXIT;
4038}
4039
4040static ExitStatus op_stnosm(DisasContext *s, DisasOps *o)
4041{
4042    uint64_t i2 = get_field(s->fields, i2);
4043    TCGv_i64 t;
4044
4045    check_privileged(s);
4046
4047    /* It is important to do what the instruction name says: STORE THEN.
4048       If we let the output hook perform the store then if we fault and
4049       restart, we'll have the wrong SYSTEM MASK in place.  */
4050    t = tcg_temp_new_i64();
4051    tcg_gen_shri_i64(t, psw_mask, 56);
4052    tcg_gen_qemu_st8(t, o->addr1, get_mem_index(s));
4053    tcg_temp_free_i64(t);
4054
4055    if (s->fields->op == 0xac) {
4056        tcg_gen_andi_i64(psw_mask, psw_mask,
4057                         (i2 << 56) | 0x00ffffffffffffffull);
4058    } else {
4059        tcg_gen_ori_i64(psw_mask, psw_mask, i2 << 56);
4060    }
4061
4062    /* Exit to main loop to reevaluate s390_cpu_exec_interrupt.  */
4063    return EXIT_PC_STALE_NOCHAIN;
4064}
4065
4066static ExitStatus op_stura(DisasContext *s, DisasOps *o)
4067{
4068    check_privileged(s);
4069    potential_page_fault(s);
4070    gen_helper_stura(cpu_env, o->in2, o->in1);
4071    return NO_EXIT;
4072}
4073
4074static ExitStatus op_sturg(DisasContext *s, DisasOps *o)
4075{
4076    check_privileged(s);
4077    potential_page_fault(s);
4078    gen_helper_sturg(cpu_env, o->in2, o->in1);
4079    return NO_EXIT;
4080}
4081#endif
4082
4083static ExitStatus op_stfle(DisasContext *s, DisasOps *o)
4084{
4085    potential_page_fault(s);
4086    gen_helper_stfle(cc_op, cpu_env, o->in2);
4087    set_cc_static(s);
4088    return NO_EXIT;
4089}
4090
4091static ExitStatus op_st8(DisasContext *s, DisasOps *o)
4092{
4093    tcg_gen_qemu_st8(o->in1, o->in2, get_mem_index(s));
4094    return NO_EXIT;
4095}
4096
4097static ExitStatus op_st16(DisasContext *s, DisasOps *o)
4098{
4099    tcg_gen_qemu_st16(o->in1, o->in2, get_mem_index(s));
4100    return NO_EXIT;
4101}
4102
4103static ExitStatus op_st32(DisasContext *s, DisasOps *o)
4104{
4105    tcg_gen_qemu_st32(o->in1, o->in2, get_mem_index(s));
4106    return NO_EXIT;
4107}
4108
4109static ExitStatus op_st64(DisasContext *s, DisasOps *o)
4110{
4111    tcg_gen_qemu_st64(o->in1, o->in2, get_mem_index(s));
4112    return NO_EXIT;
4113}
4114
4115static ExitStatus op_stam(DisasContext *s, DisasOps *o)
4116{
4117    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4118    TCGv_i32 r3 = tcg_const_i32(get_field(s->fields, r3));
4119    gen_helper_stam(cpu_env, r1, o->in2, r3);
4120    tcg_temp_free_i32(r1);
4121    tcg_temp_free_i32(r3);
4122    return NO_EXIT;
4123}
4124
4125static ExitStatus op_stcm(DisasContext *s, DisasOps *o)
4126{
4127    int m3 = get_field(s->fields, m3);
4128    int pos, base = s->insn->data;
4129    TCGv_i64 tmp = tcg_temp_new_i64();
4130
4131    pos = base + ctz32(m3) * 8;
4132    switch (m3) {
4133    case 0xf:
4134        /* Effectively a 32-bit store.  */
4135        tcg_gen_shri_i64(tmp, o->in1, pos);
4136        tcg_gen_qemu_st32(tmp, o->in2, get_mem_index(s));
4137        break;
4138
4139    case 0xc:
4140    case 0x6:
4141    case 0x3:
4142        /* Effectively a 16-bit store.  */
4143        tcg_gen_shri_i64(tmp, o->in1, pos);
4144        tcg_gen_qemu_st16(tmp, o->in2, get_mem_index(s));
4145        break;
4146
4147    case 0x8:
4148    case 0x4:
4149    case 0x2:
4150    case 0x1:
4151        /* Effectively an 8-bit store.  */
4152        tcg_gen_shri_i64(tmp, o->in1, pos);
4153        tcg_gen_qemu_st8(tmp, o->in2, get_mem_index(s));
4154        break;
4155
4156    default:
4157        /* This is going to be a sequence of shifts and stores.  */
4158        pos = base + 32 - 8;
4159        while (m3) {
4160            if (m3 & 0x8) {
4161                tcg_gen_shri_i64(tmp, o->in1, pos);
4162                tcg_gen_qemu_st8(tmp, o->in2, get_mem_index(s));
4163                tcg_gen_addi_i64(o->in2, o->in2, 1);
4164            }
4165            m3 = (m3 << 1) & 0xf;
4166            pos -= 8;
4167        }
4168        break;
4169    }
4170    tcg_temp_free_i64(tmp);
4171    return NO_EXIT;
4172}
4173
4174static ExitStatus op_stm(DisasContext *s, DisasOps *o)
4175{
4176    int r1 = get_field(s->fields, r1);
4177    int r3 = get_field(s->fields, r3);
4178    int size = s->insn->data;
4179    TCGv_i64 tsize = tcg_const_i64(size);
4180
4181    while (1) {
4182        if (size == 8) {
4183            tcg_gen_qemu_st64(regs[r1], o->in2, get_mem_index(s));
4184        } else {
4185            tcg_gen_qemu_st32(regs[r1], o->in2, get_mem_index(s));
4186        }
4187        if (r1 == r3) {
4188            break;
4189        }
4190        tcg_gen_add_i64(o->in2, o->in2, tsize);
4191        r1 = (r1 + 1) & 15;
4192    }
4193
4194    tcg_temp_free_i64(tsize);
4195    return NO_EXIT;
4196}
4197
4198static ExitStatus op_stmh(DisasContext *s, DisasOps *o)
4199{
4200    int r1 = get_field(s->fields, r1);
4201    int r3 = get_field(s->fields, r3);
4202    TCGv_i64 t = tcg_temp_new_i64();
4203    TCGv_i64 t4 = tcg_const_i64(4);
4204    TCGv_i64 t32 = tcg_const_i64(32);
4205
4206    while (1) {
4207        tcg_gen_shl_i64(t, regs[r1], t32);
4208        tcg_gen_qemu_st32(t, o->in2, get_mem_index(s));
4209        if (r1 == r3) {
4210            break;
4211        }
4212        tcg_gen_add_i64(o->in2, o->in2, t4);
4213        r1 = (r1 + 1) & 15;
4214    }
4215
4216    tcg_temp_free_i64(t);
4217    tcg_temp_free_i64(t4);
4218    tcg_temp_free_i64(t32);
4219    return NO_EXIT;
4220}
4221
4222static ExitStatus op_stpq(DisasContext *s, DisasOps *o)
4223{
4224    gen_helper_stpq(cpu_env, o->in2, o->out2, o->out);
4225    return NO_EXIT;
4226}
4227
4228static ExitStatus op_srst(DisasContext *s, DisasOps *o)
4229{
4230    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4231    TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4232
4233    gen_helper_srst(cpu_env, r1, r2);
4234
4235    tcg_temp_free_i32(r1);
4236    tcg_temp_free_i32(r2);
4237    set_cc_static(s);
4238    return NO_EXIT;
4239}
4240
4241static ExitStatus op_srstu(DisasContext *s, DisasOps *o)
4242{
4243    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4244    TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4245
4246    gen_helper_srstu(cpu_env, r1, r2);
4247
4248    tcg_temp_free_i32(r1);
4249    tcg_temp_free_i32(r2);
4250    set_cc_static(s);
4251    return NO_EXIT;
4252}
4253
4254static ExitStatus op_sub(DisasContext *s, DisasOps *o)
4255{
4256    tcg_gen_sub_i64(o->out, o->in1, o->in2);
4257    return NO_EXIT;
4258}
4259
4260static ExitStatus op_subb(DisasContext *s, DisasOps *o)
4261{
4262    DisasCompare cmp;
4263    TCGv_i64 borrow;
4264
4265    tcg_gen_sub_i64(o->out, o->in1, o->in2);
4266
4267    /* The !borrow flag is the msb of CC.  Since we want the inverse of
4268       that, we ask for a comparison of CC=0 | CC=1 -> mask of 8 | 4.  */
4269    disas_jcc(s, &cmp, 8 | 4);
4270    borrow = tcg_temp_new_i64();
4271    if (cmp.is_64) {
4272        tcg_gen_setcond_i64(cmp.cond, borrow, cmp.u.s64.a, cmp.u.s64.b);
4273    } else {
4274        TCGv_i32 t = tcg_temp_new_i32();
4275        tcg_gen_setcond_i32(cmp.cond, t, cmp.u.s32.a, cmp.u.s32.b);
4276        tcg_gen_extu_i32_i64(borrow, t);
4277        tcg_temp_free_i32(t);
4278    }
4279    free_compare(&cmp);
4280
4281    tcg_gen_sub_i64(o->out, o->out, borrow);
4282    tcg_temp_free_i64(borrow);
4283    return NO_EXIT;
4284}
4285
4286static ExitStatus op_svc(DisasContext *s, DisasOps *o)
4287{
4288    TCGv_i32 t;
4289
4290    update_psw_addr(s);
4291    update_cc_op(s);
4292
4293    t = tcg_const_i32(get_field(s->fields, i1) & 0xff);
4294    tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, int_svc_code));
4295    tcg_temp_free_i32(t);
4296
4297    t = tcg_const_i32(s->ilen);
4298    tcg_gen_st_i32(t, cpu_env, offsetof(CPUS390XState, int_svc_ilen));
4299    tcg_temp_free_i32(t);
4300
4301    gen_exception(EXCP_SVC);
4302    return EXIT_NORETURN;
4303}
4304
4305static ExitStatus op_tam(DisasContext *s, DisasOps *o)
4306{
4307    int cc = 0;
4308
4309    cc |= (s->tb->flags & FLAG_MASK_64) ? 2 : 0;
4310    cc |= (s->tb->flags & FLAG_MASK_32) ? 1 : 0;
4311    gen_op_movi_cc(s, cc);
4312    return NO_EXIT;
4313}
4314
4315static ExitStatus op_tceb(DisasContext *s, DisasOps *o)
4316{
4317    gen_helper_tceb(cc_op, cpu_env, o->in1, o->in2);
4318    set_cc_static(s);
4319    return NO_EXIT;
4320}
4321
4322static ExitStatus op_tcdb(DisasContext *s, DisasOps *o)
4323{
4324    gen_helper_tcdb(cc_op, cpu_env, o->in1, o->in2);
4325    set_cc_static(s);
4326    return NO_EXIT;
4327}
4328
4329static ExitStatus op_tcxb(DisasContext *s, DisasOps *o)
4330{
4331    gen_helper_tcxb(cc_op, cpu_env, o->out, o->out2, o->in2);
4332    set_cc_static(s);
4333    return NO_EXIT;
4334}
4335
4336#ifndef CONFIG_USER_ONLY
4337
4338static ExitStatus op_testblock(DisasContext *s, DisasOps *o)
4339{
4340    check_privileged(s);
4341    gen_helper_testblock(cc_op, cpu_env, o->in2);
4342    set_cc_static(s);
4343    return NO_EXIT;
4344}
4345
4346static ExitStatus op_tprot(DisasContext *s, DisasOps *o)
4347{
4348    gen_helper_tprot(cc_op, o->addr1, o->in2);
4349    set_cc_static(s);
4350    return NO_EXIT;
4351}
4352
4353#endif
4354
4355static ExitStatus op_tp(DisasContext *s, DisasOps *o)
4356{
4357    TCGv_i32 l1 = tcg_const_i32(get_field(s->fields, l1) + 1);
4358    gen_helper_tp(cc_op, cpu_env, o->addr1, l1);
4359    tcg_temp_free_i32(l1);
4360    set_cc_static(s);
4361    return NO_EXIT;
4362}
4363
4364static ExitStatus op_tr(DisasContext *s, DisasOps *o)
4365{
4366    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
4367    gen_helper_tr(cpu_env, l, o->addr1, o->in2);
4368    tcg_temp_free_i32(l);
4369    set_cc_static(s);
4370    return NO_EXIT;
4371}
4372
4373static ExitStatus op_tre(DisasContext *s, DisasOps *o)
4374{
4375    gen_helper_tre(o->out, cpu_env, o->out, o->out2, o->in2);
4376    return_low128(o->out2);
4377    set_cc_static(s);
4378    return NO_EXIT;
4379}
4380
4381static ExitStatus op_trt(DisasContext *s, DisasOps *o)
4382{
4383    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
4384    gen_helper_trt(cc_op, cpu_env, l, o->addr1, o->in2);
4385    tcg_temp_free_i32(l);
4386    set_cc_static(s);
4387    return NO_EXIT;
4388}
4389
4390static ExitStatus op_trtr(DisasContext *s, DisasOps *o)
4391{
4392    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
4393    gen_helper_trtr(cc_op, cpu_env, l, o->addr1, o->in2);
4394    tcg_temp_free_i32(l);
4395    set_cc_static(s);
4396    return NO_EXIT;
4397}
4398
4399static ExitStatus op_trXX(DisasContext *s, DisasOps *o)
4400{
4401    TCGv_i32 r1 = tcg_const_i32(get_field(s->fields, r1));
4402    TCGv_i32 r2 = tcg_const_i32(get_field(s->fields, r2));
4403    TCGv_i32 sizes = tcg_const_i32(s->insn->opc & 3);
4404    TCGv_i32 tst = tcg_temp_new_i32();
4405    int m3 = get_field(s->fields, m3);
4406
4407    if (!s390_has_feat(S390_FEAT_ETF2_ENH)) {
4408        m3 = 0;
4409    }
4410    if (m3 & 1) {
4411        tcg_gen_movi_i32(tst, -1);
4412    } else {
4413        tcg_gen_extrl_i64_i32(tst, regs[0]);
4414        if (s->insn->opc & 3) {
4415            tcg_gen_ext8u_i32(tst, tst);
4416        } else {
4417            tcg_gen_ext16u_i32(tst, tst);
4418        }
4419    }
4420    gen_helper_trXX(cc_op, cpu_env, r1, r2, tst, sizes);
4421
4422    tcg_temp_free_i32(r1);
4423    tcg_temp_free_i32(r2);
4424    tcg_temp_free_i32(sizes);
4425    tcg_temp_free_i32(tst);
4426    set_cc_static(s);
4427    return NO_EXIT;
4428}
4429
4430static ExitStatus op_ts(DisasContext *s, DisasOps *o)
4431{
4432    TCGv_i32 t1 = tcg_const_i32(0xff);
4433    tcg_gen_atomic_xchg_i32(t1, o->in2, t1, get_mem_index(s), MO_UB);
4434    tcg_gen_extract_i32(cc_op, t1, 7, 1);
4435    tcg_temp_free_i32(t1);
4436    set_cc_static(s);
4437    return NO_EXIT;
4438}
4439
4440static ExitStatus op_unpk(DisasContext *s, DisasOps *o)
4441{
4442    TCGv_i32 l = tcg_const_i32(get_field(s->fields, l1));
4443    gen_helper_unpk(cpu_env, l, o->addr1, o->in2);
4444    tcg_temp_free_i32(l);
4445    return NO_EXIT;
4446}
4447
4448static ExitStatus op_unpka(DisasContext *s, DisasOps *o)
4449{
4450    int l1 = get_field(s->fields, l1) + 1;
4451    TCGv_i32 l;
4452
4453    /* The length must not exceed 32 bytes.  */
4454    if (l1 > 32) {
4455        gen_program_exception(s, PGM_SPECIFICATION);
4456        return EXIT_NORETURN;
4457    }
4458    l = tcg_const_i32(l1);
4459    gen_helper_unpka(cc_op, cpu_env, o->addr1, l, o->in2);
4460    tcg_temp_free_i32(l);
4461    set_cc_static(s);
4462    return NO_EXIT;
4463}
4464
4465static ExitStatus op_unpku(DisasContext *s, DisasOps *o)
4466{
4467    int l1 = get_field(s->fields, l1) + 1;
4468    TCGv_i32 l;
4469
4470    /* The length must be even and should not exceed 64 bytes.  */
4471    if ((l1 & 1) || (l1 > 64)) {
4472        gen_program_exception(s, PGM_SPECIFICATION);
4473        return EXIT_NORETURN;
4474    }
4475    l = tcg_const_i32(l1);
4476    gen_helper_unpku(cc_op, cpu_env, o->addr1, l, o->in2);
4477    tcg_temp_free_i32(l);
4478    set_cc_static(s);
4479    return NO_EXIT;
4480}
4481
4482
4483static ExitStatus op_xc(DisasContext *s, DisasOps *o)
4484{
4485    int d1 = get_field(s->fields, d1);
4486    int d2 = get_field(s->fields, d2);
4487    int b1 = get_field(s->fields, b1);
4488    int b2 = get_field(s->fields, b2);
4489    int l = get_field(s->fields, l1);
4490    TCGv_i32 t32;
4491
4492    o->addr1 = get_address(s, 0, b1, d1);
4493
4494    /* If the addresses are identical, this is a store/memset of zero.  */
4495    if (b1 == b2 && d1 == d2 && (l + 1) <= 32) {
4496        o->in2 = tcg_const_i64(0);
4497
4498        l++;
4499        while (l >= 8) {
4500            tcg_gen_qemu_st64(o->in2, o->addr1, get_mem_index(s));
4501            l -= 8;
4502            if (l > 0) {
4503                tcg_gen_addi_i64(o->addr1, o->addr1, 8);
4504            }
4505        }
4506        if (l >= 4) {
4507            tcg_gen_qemu_st32(o->in2, o->addr1, get_mem_index(s));
4508            l -= 4;
4509            if (l > 0) {
4510                tcg_gen_addi_i64(o->addr1, o->addr1, 4);
4511            }
4512        }
4513        if (l >= 2) {
4514            tcg_gen_qemu_st16(o->in2, o->addr1, get_mem_index(s));
4515            l -= 2;
4516            if (l > 0) {
4517                tcg_gen_addi_i64(o->addr1, o->addr1, 2);
4518            }
4519        }
4520        if (l) {
4521            tcg_gen_qemu_st8(o->in2, o->addr1, get_mem_index(s));
4522        }
4523        gen_op_movi_cc(s, 0);
4524        return NO_EXIT;
4525    }
4526
4527    /* But in general we'll defer to a helper.  */
4528    o->in2 = get_address(s, 0, b2, d2);
4529    t32 = tcg_const_i32(l);
4530    gen_helper_xc(cc_op, cpu_env, t32, o->addr1, o->in2);
4531    tcg_temp_free_i32(t32);
4532    set_cc_static(s);
4533    return NO_EXIT;
4534}
4535
4536static ExitStatus op_xor(DisasContext *s, DisasOps *o)
4537{
4538    tcg_gen_xor_i64(o->out, o->in1, o->in2);
4539    return NO_EXIT;
4540}
4541
4542static ExitStatus op_xori(DisasContext *s, DisasOps *o)
4543{
4544    int shift = s->insn->data & 0xff;
4545    int size = s->insn->data >> 8;
4546    uint64_t mask = ((1ull << size) - 1) << shift;
4547
4548    assert(!o->g_in2);
4549    tcg_gen_shli_i64(o->in2, o->in2, shift);
4550    tcg_gen_xor_i64(o->out, o->in1, o->in2);
4551
4552    /* Produce the CC from only the bits manipulated.  */
4553    tcg_gen_andi_i64(cc_dst, o->out, mask);
4554    set_cc_nz_u64(s, cc_dst);
4555    return NO_EXIT;
4556}
4557
4558static ExitStatus op_zero(DisasContext *s, DisasOps *o)
4559{
4560    o->out = tcg_const_i64(0);
4561    return NO_EXIT;
4562}
4563
4564static ExitStatus op_zero2(DisasContext *s, DisasOps *o)
4565{
4566    o->out = tcg_const_i64(0);
4567    o->out2 = o->out;
4568    o->g_out2 = true;
4569    return NO_EXIT;
4570}
4571
4572/* ====================================================================== */
4573/* The "Cc OUTput" generators.  Given the generated output (and in some cases
4574   the original inputs), update the various cc data structures in order to
4575   be able to compute the new condition code.  */
4576
4577static void cout_abs32(DisasContext *s, DisasOps *o)
4578{
4579    gen_op_update1_cc_i64(s, CC_OP_ABS_32, o->out);
4580}
4581
4582static void cout_abs64(DisasContext *s, DisasOps *o)
4583{
4584    gen_op_update1_cc_i64(s, CC_OP_ABS_64, o->out);
4585}
4586
4587static void cout_adds32(DisasContext *s, DisasOps *o)
4588{
4589    gen_op_update3_cc_i64(s, CC_OP_ADD_32, o->in1, o->in2, o->out);
4590}
4591
4592static void cout_adds64(DisasContext *s, DisasOps *o)
4593{
4594    gen_op_update3_cc_i64(s, CC_OP_ADD_64, o->in1, o->in2, o->out);
4595}
4596
4597static void cout_addu32(DisasContext *s, DisasOps *o)
4598{
4599    gen_op_update3_cc_i64(s, CC_OP_ADDU_32, o->in1, o->in2, o->out);
4600}
4601
4602static void cout_addu64(DisasContext *s, DisasOps *o)
4603{
4604    gen_op_update3_cc_i64(s, CC_OP_ADDU_64, o->in1, o->in2, o->out);
4605}
4606
4607static void cout_addc32(DisasContext *s, DisasOps *o)
4608{
4609    gen_op_update3_cc_i64(s, CC_OP_ADDC_32, o->in1, o->in2, o->out);
4610}
4611
4612static void cout_addc64(DisasContext *s, DisasOps *o)
4613{
4614    gen_op_update3_cc_i64(s, CC_OP_ADDC_64, o->in1, o->in2, o->out);
4615}
4616
4617static void cout_cmps32(DisasContext *s, DisasOps *o)
4618{
4619    gen_op_update2_cc_i64(s, CC_OP_LTGT_32, o->in1, o->in2);
4620}
4621
4622static void cout_cmps64(DisasContext *s, DisasOps *o)
4623{
4624    gen_op_update2_cc_i64(s, CC_OP_LTGT_64, o->in1, o->in2);
4625}
4626
4627static void cout_cmpu32(DisasContext *s, DisasOps *o)
4628{
4629    gen_op_update2_cc_i64(s, CC_OP_LTUGTU_32, o->in1, o->in2);
4630}
4631
4632static void cout_cmpu64(DisasContext *s, DisasOps *o)
4633{
4634    gen_op_update2_cc_i64(s, CC_OP_LTUGTU_64, o->in1, o->in2);
4635}
4636
4637static void cout_f32(DisasContext *s, DisasOps *o)
4638{
4639    gen_op_update1_cc_i64(s, CC_OP_NZ_F32, o->out);
4640}
4641
4642static void cout_f64(DisasContext *s, DisasOps *o)
4643{
4644    gen_op_update1_cc_i64(s, CC_OP_NZ_F64, o->out);
4645}
4646
4647static void cout_f128(DisasContext *s, DisasOps *o)
4648{
4649    gen_op_update2_cc_i64(s, CC_OP_NZ_F128, o->out, o->out2);
4650}
4651
4652static void cout_nabs32(DisasContext *s, DisasOps *o)
4653{
4654    gen_op_update1_cc_i64(s, CC_OP_NABS_32, o->out);
4655}
4656
4657static void cout_nabs64(DisasContext *s, DisasOps *o)
4658{
4659    gen_op_update1_cc_i64(s, CC_OP_NABS_64, o->out);
4660}
4661
4662static void cout_neg32(DisasContext *s, DisasOps *o)
4663{
4664    gen_op_update1_cc_i64(s, CC_OP_COMP_32, o->out);
4665}
4666
4667static void cout_neg64(DisasContext *s, DisasOps *o)
4668{
4669    gen_op_update1_cc_i64(s, CC_OP_COMP_64, o->out);
4670}
4671
4672static void cout_nz32(DisasContext *s, DisasOps *o)
4673{
4674    tcg_gen_ext32u_i64(cc_dst, o->out);
4675    gen_op_update1_cc_i64(s, CC_OP_NZ, cc_dst);
4676}
4677
4678static void cout_nz64(DisasContext *s, DisasOps *o)
4679{
4680    gen_op_update1_cc_i64(s, CC_OP_NZ, o->out);
4681}
4682
4683static void cout_s32(DisasContext *s, DisasOps *o)
4684{
4685    gen_op_update1_cc_i64(s, CC_OP_LTGT0_32, o->out);
4686}
4687
4688static void cout_s64(DisasContext *s, DisasOps *o)
4689{
4690    gen_op_update1_cc_i64(s, CC_OP_LTGT0_64, o->out);
4691}
4692
4693static void cout_subs32(DisasContext *s, DisasOps *o)
4694{
4695    gen_op_update3_cc_i64(s, CC_OP_SUB_32, o->in1, o->in2, o->out);
4696}
4697
4698static void cout_subs64(DisasContext *s, DisasOps *o)
4699{
4700    gen_op_update3_cc_i64(s, CC_OP_SUB_64, o->in1, o->in2, o->out);
4701}
4702
4703static void cout_subu32(DisasContext *s, DisasOps *o)
4704{
4705    gen_op_update3_cc_i64(s, CC_OP_SUBU_32, o->in1, o->in2, o->out);
4706}
4707
4708static void cout_subu64(DisasContext *s, DisasOps *o)
4709{
4710    gen_op_update3_cc_i64(s, CC_OP_SUBU_64, o->in1, o->in2, o->out);
4711}
4712
4713static void cout_subb32(DisasContext *s, DisasOps *o)
4714{
4715    gen_op_update3_cc_i64(s, CC_OP_SUBB_32, o->in1, o->in2, o->out);
4716}
4717
4718static void cout_subb64(DisasContext *s, DisasOps *o)
4719{
4720    gen_op_update3_cc_i64(s, CC_OP_SUBB_64, o->in1, o->in2, o->out);
4721}
4722
4723static void cout_tm32(DisasContext *s, DisasOps *o)
4724{
4725    gen_op_update2_cc_i64(s, CC_OP_TM_32, o->in1, o->in2);
4726}
4727
4728static void cout_tm64(DisasContext *s, DisasOps *o)
4729{
4730    gen_op_update2_cc_i64(s, CC_OP_TM_64, o->in1, o->in2);
4731}
4732
4733/* ====================================================================== */
4734/* The "PREParation" generators.  These initialize the DisasOps.OUT fields
4735   with the TCG register to which we will write.  Used in combination with
4736   the "wout" generators, in some cases we need a new temporary, and in
4737   some cases we can write to a TCG global.  */
4738
4739static void prep_new(DisasContext *s, DisasFields *f, DisasOps *o)
4740{
4741    o->out = tcg_temp_new_i64();
4742}
4743#define SPEC_prep_new 0
4744
4745static void prep_new_P(DisasContext *s, DisasFields *f, DisasOps *o)
4746{
4747    o->out = tcg_temp_new_i64();
4748    o->out2 = tcg_temp_new_i64();
4749}
4750#define SPEC_prep_new_P 0
4751
4752static void prep_r1(DisasContext *s, DisasFields *f, DisasOps *o)
4753{
4754    o->out = regs[get_field(f, r1)];
4755    o->g_out = true;
4756}
4757#define SPEC_prep_r1 0
4758
4759static void prep_r1_P(DisasContext *s, DisasFields *f, DisasOps *o)
4760{
4761    int r1 = get_field(f, r1);
4762    o->out = regs[r1];
4763    o->out2 = regs[r1 + 1];
4764    o->g_out = o->g_out2 = true;
4765}
4766#define SPEC_prep_r1_P SPEC_r1_even
4767
4768static void prep_f1(DisasContext *s, DisasFields *f, DisasOps *o)
4769{
4770    o->out = fregs[get_field(f, r1)];
4771    o->g_out = true;
4772}
4773#define SPEC_prep_f1 0
4774
4775static void prep_x1(DisasContext *s, DisasFields *f, DisasOps *o)
4776{
4777    int r1 = get_field(f, r1);
4778    o->out = fregs[r1];
4779    o->out2 = fregs[r1 + 2];
4780    o->g_out = o->g_out2 = true;
4781}
4782#define SPEC_prep_x1 SPEC_r1_f128
4783
4784/* ====================================================================== */
4785/* The "Write OUTput" generators.  These generally perform some non-trivial
4786   copy of data to TCG globals, or to main memory.  The trivial cases are
4787   generally handled by having a "prep" generator install the TCG global
4788   as the destination of the operation.  */
4789
4790static void wout_r1(DisasContext *s, DisasFields *f, DisasOps *o)
4791{
4792    store_reg(get_field(f, r1), o->out);
4793}
4794#define SPEC_wout_r1 0
4795
4796static void wout_r1_8(DisasContext *s, DisasFields *f, DisasOps *o)
4797{
4798    int r1 = get_field(f, r1);
4799    tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 8);
4800}
4801#define SPEC_wout_r1_8 0
4802
4803static void wout_r1_16(DisasContext *s, DisasFields *f, DisasOps *o)
4804{
4805    int r1 = get_field(f, r1);
4806    tcg_gen_deposit_i64(regs[r1], regs[r1], o->out, 0, 16);
4807}
4808#define SPEC_wout_r1_16 0
4809
4810static void wout_r1_32(DisasContext *s, DisasFields *f, DisasOps *o)
4811{
4812    store_reg32_i64(get_field(f, r1), o->out);
4813}
4814#define SPEC_wout_r1_32 0
4815
4816static void wout_r1_32h(DisasContext *s, DisasFields *f, DisasOps *o)
4817{
4818    store_reg32h_i64(get_field(f, r1), o->out);
4819}
4820#define SPEC_wout_r1_32h 0
4821
4822static void wout_r1_P32(DisasContext *s, DisasFields *f, DisasOps *o)
4823{
4824    int r1 = get_field(f, r1);
4825    store_reg32_i64(r1, o->out);
4826    store_reg32_i64(r1 + 1, o->out2);
4827}
4828#define SPEC_wout_r1_P32 SPEC_r1_even
4829
4830static void wout_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o)
4831{
4832    int r1 = get_field(f, r1);
4833    store_reg32_i64(r1 + 1, o->out);
4834    tcg_gen_shri_i64(o->out, o->out, 32);
4835    store_reg32_i64(r1, o->out);
4836}
4837#define SPEC_wout_r1_D32 SPEC_r1_even
4838
4839static void wout_r3_P32(DisasContext *s, DisasFields *f, DisasOps *o)
4840{
4841    int r3 = get_field(f, r3);
4842    store_reg32_i64(r3, o->out);
4843    store_reg32_i64(r3 + 1, o->out2);
4844}
4845#define SPEC_wout_r3_P32 SPEC_r3_even
4846
4847static void wout_r3_P64(DisasContext *s, DisasFields *f, DisasOps *o)
4848{
4849    int r3 = get_field(f, r3);
4850    store_reg(r3, o->out);
4851    store_reg(r3 + 1, o->out2);
4852}
4853#define SPEC_wout_r3_P64 SPEC_r3_even
4854
4855static void wout_e1(DisasContext *s, DisasFields *f, DisasOps *o)
4856{
4857    store_freg32_i64(get_field(f, r1), o->out);
4858}
4859#define SPEC_wout_e1 0
4860
4861static void wout_f1(DisasContext *s, DisasFields *f, DisasOps *o)
4862{
4863    store_freg(get_field(f, r1), o->out);
4864}
4865#define SPEC_wout_f1 0
4866
4867static void wout_x1(DisasContext *s, DisasFields *f, DisasOps *o)
4868{
4869    int f1 = get_field(s->fields, r1);
4870    store_freg(f1, o->out);
4871    store_freg(f1 + 2, o->out2);
4872}
4873#define SPEC_wout_x1 SPEC_r1_f128
4874
4875static void wout_cond_r1r2_32(DisasContext *s, DisasFields *f, DisasOps *o)
4876{
4877    if (get_field(f, r1) != get_field(f, r2)) {
4878        store_reg32_i64(get_field(f, r1), o->out);
4879    }
4880}
4881#define SPEC_wout_cond_r1r2_32 0
4882
4883static void wout_cond_e1e2(DisasContext *s, DisasFields *f, DisasOps *o)
4884{
4885    if (get_field(f, r1) != get_field(f, r2)) {
4886        store_freg32_i64(get_field(f, r1), o->out);
4887    }
4888}
4889#define SPEC_wout_cond_e1e2 0
4890
4891static void wout_m1_8(DisasContext *s, DisasFields *f, DisasOps *o)
4892{
4893    tcg_gen_qemu_st8(o->out, o->addr1, get_mem_index(s));
4894}
4895#define SPEC_wout_m1_8 0
4896
4897static void wout_m1_16(DisasContext *s, DisasFields *f, DisasOps *o)
4898{
4899    tcg_gen_qemu_st16(o->out, o->addr1, get_mem_index(s));
4900}
4901#define SPEC_wout_m1_16 0
4902
4903static void wout_m1_32(DisasContext *s, DisasFields *f, DisasOps *o)
4904{
4905    tcg_gen_qemu_st32(o->out, o->addr1, get_mem_index(s));
4906}
4907#define SPEC_wout_m1_32 0
4908
4909static void wout_m1_64(DisasContext *s, DisasFields *f, DisasOps *o)
4910{
4911    tcg_gen_qemu_st64(o->out, o->addr1, get_mem_index(s));
4912}
4913#define SPEC_wout_m1_64 0
4914
4915static void wout_m2_32(DisasContext *s, DisasFields *f, DisasOps *o)
4916{
4917    tcg_gen_qemu_st32(o->out, o->in2, get_mem_index(s));
4918}
4919#define SPEC_wout_m2_32 0
4920
4921static void wout_in2_r1(DisasContext *s, DisasFields *f, DisasOps *o)
4922{
4923    store_reg(get_field(f, r1), o->in2);
4924}
4925#define SPEC_wout_in2_r1 0
4926
4927static void wout_in2_r1_32(DisasContext *s, DisasFields *f, DisasOps *o)
4928{
4929    store_reg32_i64(get_field(f, r1), o->in2);
4930}
4931#define SPEC_wout_in2_r1_32 0
4932
4933/* ====================================================================== */
4934/* The "INput 1" generators.  These load the first operand to an insn.  */
4935
4936static void in1_r1(DisasContext *s, DisasFields *f, DisasOps *o)
4937{
4938    o->in1 = load_reg(get_field(f, r1));
4939}
4940#define SPEC_in1_r1 0
4941
4942static void in1_r1_o(DisasContext *s, DisasFields *f, DisasOps *o)
4943{
4944    o->in1 = regs[get_field(f, r1)];
4945    o->g_in1 = true;
4946}
4947#define SPEC_in1_r1_o 0
4948
4949static void in1_r1_32s(DisasContext *s, DisasFields *f, DisasOps *o)
4950{
4951    o->in1 = tcg_temp_new_i64();
4952    tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r1)]);
4953}
4954#define SPEC_in1_r1_32s 0
4955
4956static void in1_r1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
4957{
4958    o->in1 = tcg_temp_new_i64();
4959    tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r1)]);
4960}
4961#define SPEC_in1_r1_32u 0
4962
4963static void in1_r1_sr32(DisasContext *s, DisasFields *f, DisasOps *o)
4964{
4965    o->in1 = tcg_temp_new_i64();
4966    tcg_gen_shri_i64(o->in1, regs[get_field(f, r1)], 32);
4967}
4968#define SPEC_in1_r1_sr32 0
4969
4970static void in1_r1p1(DisasContext *s, DisasFields *f, DisasOps *o)
4971{
4972    o->in1 = load_reg(get_field(f, r1) + 1);
4973}
4974#define SPEC_in1_r1p1 SPEC_r1_even
4975
4976static void in1_r1p1_32s(DisasContext *s, DisasFields *f, DisasOps *o)
4977{
4978    o->in1 = tcg_temp_new_i64();
4979    tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r1) + 1]);
4980}
4981#define SPEC_in1_r1p1_32s SPEC_r1_even
4982
4983static void in1_r1p1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
4984{
4985    o->in1 = tcg_temp_new_i64();
4986    tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r1) + 1]);
4987}
4988#define SPEC_in1_r1p1_32u SPEC_r1_even
4989
4990static void in1_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o)
4991{
4992    int r1 = get_field(f, r1);
4993    o->in1 = tcg_temp_new_i64();
4994    tcg_gen_concat32_i64(o->in1, regs[r1 + 1], regs[r1]);
4995}
4996#define SPEC_in1_r1_D32 SPEC_r1_even
4997
4998static void in1_r2(DisasContext *s, DisasFields *f, DisasOps *o)
4999{
5000    o->in1 = load_reg(get_field(f, r2));
5001}
5002#define SPEC_in1_r2 0
5003
5004static void in1_r2_sr32(DisasContext *s, DisasFields *f, DisasOps *o)
5005{
5006    o->in1 = tcg_temp_new_i64();
5007    tcg_gen_shri_i64(o->in1, regs[get_field(f, r2)], 32);
5008}
5009#define SPEC_in1_r2_sr32 0
5010
5011static void in1_r3(DisasContext *s, DisasFields *f, DisasOps *o)
5012{
5013    o->in1 = load_reg(get_field(f, r3));
5014}
5015#define SPEC_in1_r3 0
5016
5017static void in1_r3_o(DisasContext *s, DisasFields *f, DisasOps *o)
5018{
5019    o->in1 = regs[get_field(f, r3)];
5020    o->g_in1 = true;
5021}
5022#define SPEC_in1_r3_o 0
5023
5024static void in1_r3_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5025{
5026    o->in1 = tcg_temp_new_i64();
5027    tcg_gen_ext32s_i64(o->in1, regs[get_field(f, r3)]);
5028}
5029#define SPEC_in1_r3_32s 0
5030
5031static void in1_r3_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5032{
5033    o->in1 = tcg_temp_new_i64();
5034    tcg_gen_ext32u_i64(o->in1, regs[get_field(f, r3)]);
5035}
5036#define SPEC_in1_r3_32u 0
5037
5038static void in1_r3_D32(DisasContext *s, DisasFields *f, DisasOps *o)
5039{
5040    int r3 = get_field(f, r3);
5041    o->in1 = tcg_temp_new_i64();
5042    tcg_gen_concat32_i64(o->in1, regs[r3 + 1], regs[r3]);
5043}
5044#define SPEC_in1_r3_D32 SPEC_r3_even
5045
5046static void in1_e1(DisasContext *s, DisasFields *f, DisasOps *o)
5047{
5048    o->in1 = load_freg32_i64(get_field(f, r1));
5049}
5050#define SPEC_in1_e1 0
5051
5052static void in1_f1_o(DisasContext *s, DisasFields *f, DisasOps *o)
5053{
5054    o->in1 = fregs[get_field(f, r1)];
5055    o->g_in1 = true;
5056}
5057#define SPEC_in1_f1_o 0
5058
5059static void in1_x1_o(DisasContext *s, DisasFields *f, DisasOps *o)
5060{
5061    int r1 = get_field(f, r1);
5062    o->out = fregs[r1];
5063    o->out2 = fregs[r1 + 2];
5064    o->g_out = o->g_out2 = true;
5065}
5066#define SPEC_in1_x1_o SPEC_r1_f128
5067
5068static void in1_f3_o(DisasContext *s, DisasFields *f, DisasOps *o)
5069{
5070    o->in1 = fregs[get_field(f, r3)];
5071    o->g_in1 = true;
5072}
5073#define SPEC_in1_f3_o 0
5074
5075static void in1_la1(DisasContext *s, DisasFields *f, DisasOps *o)
5076{
5077    o->addr1 = get_address(s, 0, get_field(f, b1), get_field(f, d1));
5078}
5079#define SPEC_in1_la1 0
5080
5081static void in1_la2(DisasContext *s, DisasFields *f, DisasOps *o)
5082{
5083    int x2 = have_field(f, x2) ? get_field(f, x2) : 0;
5084    o->addr1 = get_address(s, x2, get_field(f, b2), get_field(f, d2));
5085}
5086#define SPEC_in1_la2 0
5087
5088static void in1_m1_8u(DisasContext *s, DisasFields *f, DisasOps *o)
5089{
5090    in1_la1(s, f, o);
5091    o->in1 = tcg_temp_new_i64();
5092    tcg_gen_qemu_ld8u(o->in1, o->addr1, get_mem_index(s));
5093}
5094#define SPEC_in1_m1_8u 0
5095
5096static void in1_m1_16s(DisasContext *s, DisasFields *f, DisasOps *o)
5097{
5098    in1_la1(s, f, o);
5099    o->in1 = tcg_temp_new_i64();
5100    tcg_gen_qemu_ld16s(o->in1, o->addr1, get_mem_index(s));
5101}
5102#define SPEC_in1_m1_16s 0
5103
5104static void in1_m1_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5105{
5106    in1_la1(s, f, o);
5107    o->in1 = tcg_temp_new_i64();
5108    tcg_gen_qemu_ld16u(o->in1, o->addr1, get_mem_index(s));
5109}
5110#define SPEC_in1_m1_16u 0
5111
5112static void in1_m1_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5113{
5114    in1_la1(s, f, o);
5115    o->in1 = tcg_temp_new_i64();
5116    tcg_gen_qemu_ld32s(o->in1, o->addr1, get_mem_index(s));
5117}
5118#define SPEC_in1_m1_32s 0
5119
5120static void in1_m1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5121{
5122    in1_la1(s, f, o);
5123    o->in1 = tcg_temp_new_i64();
5124    tcg_gen_qemu_ld32u(o->in1, o->addr1, get_mem_index(s));
5125}
5126#define SPEC_in1_m1_32u 0
5127
5128static void in1_m1_64(DisasContext *s, DisasFields *f, DisasOps *o)
5129{
5130    in1_la1(s, f, o);
5131    o->in1 = tcg_temp_new_i64();
5132    tcg_gen_qemu_ld64(o->in1, o->addr1, get_mem_index(s));
5133}
5134#define SPEC_in1_m1_64 0
5135
5136/* ====================================================================== */
5137/* The "INput 2" generators.  These load the second operand to an insn.  */
5138
5139static void in2_r1_o(DisasContext *s, DisasFields *f, DisasOps *o)
5140{
5141    o->in2 = regs[get_field(f, r1)];
5142    o->g_in2 = true;
5143}
5144#define SPEC_in2_r1_o 0
5145
5146static void in2_r1_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5147{
5148    o->in2 = tcg_temp_new_i64();
5149    tcg_gen_ext16u_i64(o->in2, regs[get_field(f, r1)]);
5150}
5151#define SPEC_in2_r1_16u 0
5152
5153static void in2_r1_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5154{
5155    o->in2 = tcg_temp_new_i64();
5156    tcg_gen_ext32u_i64(o->in2, regs[get_field(f, r1)]);
5157}
5158#define SPEC_in2_r1_32u 0
5159
5160static void in2_r1_D32(DisasContext *s, DisasFields *f, DisasOps *o)
5161{
5162    int r1 = get_field(f, r1);
5163    o->in2 = tcg_temp_new_i64();
5164    tcg_gen_concat32_i64(o->in2, regs[r1 + 1], regs[r1]);
5165}
5166#define SPEC_in2_r1_D32 SPEC_r1_even
5167
5168static void in2_r2(DisasContext *s, DisasFields *f, DisasOps *o)
5169{
5170    o->in2 = load_reg(get_field(f, r2));
5171}
5172#define SPEC_in2_r2 0
5173
5174static void in2_r2_o(DisasContext *s, DisasFields *f, DisasOps *o)
5175{
5176    o->in2 = regs[get_field(f, r2)];
5177    o->g_in2 = true;
5178}
5179#define SPEC_in2_r2_o 0
5180
5181static void in2_r2_nz(DisasContext *s, DisasFields *f, DisasOps *o)
5182{
5183    int r2 = get_field(f, r2);
5184    if (r2 != 0) {
5185        o->in2 = load_reg(r2);
5186    }
5187}
5188#define SPEC_in2_r2_nz 0
5189
5190static void in2_r2_8s(DisasContext *s, DisasFields *f, DisasOps *o)
5191{
5192    o->in2 = tcg_temp_new_i64();
5193    tcg_gen_ext8s_i64(o->in2, regs[get_field(f, r2)]);
5194}
5195#define SPEC_in2_r2_8s 0
5196
5197static void in2_r2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
5198{
5199    o->in2 = tcg_temp_new_i64();
5200    tcg_gen_ext8u_i64(o->in2, regs[get_field(f, r2)]);
5201}
5202#define SPEC_in2_r2_8u 0
5203
5204static void in2_r2_16s(DisasContext *s, DisasFields *f, DisasOps *o)
5205{
5206    o->in2 = tcg_temp_new_i64();
5207    tcg_gen_ext16s_i64(o->in2, regs[get_field(f, r2)]);
5208}
5209#define SPEC_in2_r2_16s 0
5210
5211static void in2_r2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5212{
5213    o->in2 = tcg_temp_new_i64();
5214    tcg_gen_ext16u_i64(o->in2, regs[get_field(f, r2)]);
5215}
5216#define SPEC_in2_r2_16u 0
5217
5218static void in2_r3(DisasContext *s, DisasFields *f, DisasOps *o)
5219{
5220    o->in2 = load_reg(get_field(f, r3));
5221}
5222#define SPEC_in2_r3 0
5223
5224static void in2_r3_sr32(DisasContext *s, DisasFields *f, DisasOps *o)
5225{
5226    o->in2 = tcg_temp_new_i64();
5227    tcg_gen_shri_i64(o->in2, regs[get_field(f, r3)], 32);
5228}
5229#define SPEC_in2_r3_sr32 0
5230
5231static void in2_r2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5232{
5233    o->in2 = tcg_temp_new_i64();
5234    tcg_gen_ext32s_i64(o->in2, regs[get_field(f, r2)]);
5235}
5236#define SPEC_in2_r2_32s 0
5237
5238static void in2_r2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5239{
5240    o->in2 = tcg_temp_new_i64();
5241    tcg_gen_ext32u_i64(o->in2, regs[get_field(f, r2)]);
5242}
5243#define SPEC_in2_r2_32u 0
5244
5245static void in2_r2_sr32(DisasContext *s, DisasFields *f, DisasOps *o)
5246{
5247    o->in2 = tcg_temp_new_i64();
5248    tcg_gen_shri_i64(o->in2, regs[get_field(f, r2)], 32);
5249}
5250#define SPEC_in2_r2_sr32 0
5251
5252static void in2_e2(DisasContext *s, DisasFields *f, DisasOps *o)
5253{
5254    o->in2 = load_freg32_i64(get_field(f, r2));
5255}
5256#define SPEC_in2_e2 0
5257
5258static void in2_f2_o(DisasContext *s, DisasFields *f, DisasOps *o)
5259{
5260    o->in2 = fregs[get_field(f, r2)];
5261    o->g_in2 = true;
5262}
5263#define SPEC_in2_f2_o 0
5264
5265static void in2_x2_o(DisasContext *s, DisasFields *f, DisasOps *o)
5266{
5267    int r2 = get_field(f, r2);
5268    o->in1 = fregs[r2];
5269    o->in2 = fregs[r2 + 2];
5270    o->g_in1 = o->g_in2 = true;
5271}
5272#define SPEC_in2_x2_o SPEC_r2_f128
5273
5274static void in2_ra2(DisasContext *s, DisasFields *f, DisasOps *o)
5275{
5276    o->in2 = get_address(s, 0, get_field(f, r2), 0);
5277}
5278#define SPEC_in2_ra2 0
5279
5280static void in2_a2(DisasContext *s, DisasFields *f, DisasOps *o)
5281{
5282    int x2 = have_field(f, x2) ? get_field(f, x2) : 0;
5283    o->in2 = get_address(s, x2, get_field(f, b2), get_field(f, d2));
5284}
5285#define SPEC_in2_a2 0
5286
5287static void in2_ri2(DisasContext *s, DisasFields *f, DisasOps *o)
5288{
5289    o->in2 = tcg_const_i64(s->pc + (int64_t)get_field(f, i2) * 2);
5290}
5291#define SPEC_in2_ri2 0
5292
5293static void in2_sh32(DisasContext *s, DisasFields *f, DisasOps *o)
5294{
5295    help_l2_shift(s, f, o, 31);
5296}
5297#define SPEC_in2_sh32 0
5298
5299static void in2_sh64(DisasContext *s, DisasFields *f, DisasOps *o)
5300{
5301    help_l2_shift(s, f, o, 63);
5302}
5303#define SPEC_in2_sh64 0
5304
5305static void in2_m2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
5306{
5307    in2_a2(s, f, o);
5308    tcg_gen_qemu_ld8u(o->in2, o->in2, get_mem_index(s));
5309}
5310#define SPEC_in2_m2_8u 0
5311
5312static void in2_m2_16s(DisasContext *s, DisasFields *f, DisasOps *o)
5313{
5314    in2_a2(s, f, o);
5315    tcg_gen_qemu_ld16s(o->in2, o->in2, get_mem_index(s));
5316}
5317#define SPEC_in2_m2_16s 0
5318
5319static void in2_m2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5320{
5321    in2_a2(s, f, o);
5322    tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s));
5323}
5324#define SPEC_in2_m2_16u 0
5325
5326static void in2_m2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5327{
5328    in2_a2(s, f, o);
5329    tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s));
5330}
5331#define SPEC_in2_m2_32s 0
5332
5333static void in2_m2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5334{
5335    in2_a2(s, f, o);
5336    tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s));
5337}
5338#define SPEC_in2_m2_32u 0
5339
5340static void in2_m2_64(DisasContext *s, DisasFields *f, DisasOps *o)
5341{
5342    in2_a2(s, f, o);
5343    tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s));
5344}
5345#define SPEC_in2_m2_64 0
5346
5347static void in2_mri2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5348{
5349    in2_ri2(s, f, o);
5350    tcg_gen_qemu_ld16u(o->in2, o->in2, get_mem_index(s));
5351}
5352#define SPEC_in2_mri2_16u 0
5353
5354static void in2_mri2_32s(DisasContext *s, DisasFields *f, DisasOps *o)
5355{
5356    in2_ri2(s, f, o);
5357    tcg_gen_qemu_ld32s(o->in2, o->in2, get_mem_index(s));
5358}
5359#define SPEC_in2_mri2_32s 0
5360
5361static void in2_mri2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5362{
5363    in2_ri2(s, f, o);
5364    tcg_gen_qemu_ld32u(o->in2, o->in2, get_mem_index(s));
5365}
5366#define SPEC_in2_mri2_32u 0
5367
5368static void in2_mri2_64(DisasContext *s, DisasFields *f, DisasOps *o)
5369{
5370    in2_ri2(s, f, o);
5371    tcg_gen_qemu_ld64(o->in2, o->in2, get_mem_index(s));
5372}
5373#define SPEC_in2_mri2_64 0
5374
5375static void in2_i2(DisasContext *s, DisasFields *f, DisasOps *o)
5376{
5377    o->in2 = tcg_const_i64(get_field(f, i2));
5378}
5379#define SPEC_in2_i2 0
5380
5381static void in2_i2_8u(DisasContext *s, DisasFields *f, DisasOps *o)
5382{
5383    o->in2 = tcg_const_i64((uint8_t)get_field(f, i2));
5384}
5385#define SPEC_in2_i2_8u 0
5386
5387static void in2_i2_16u(DisasContext *s, DisasFields *f, DisasOps *o)
5388{
5389    o->in2 = tcg_const_i64((uint16_t)get_field(f, i2));
5390}
5391#define SPEC_in2_i2_16u 0
5392
5393static void in2_i2_32u(DisasContext *s, DisasFields *f, DisasOps *o)
5394{
5395    o->in2 = tcg_const_i64((uint32_t)get_field(f, i2));
5396}
5397#define SPEC_in2_i2_32u 0
5398
5399static void in2_i2_16u_shl(DisasContext *s, DisasFields *f, DisasOps *o)
5400{
5401    uint64_t i2 = (uint16_t)get_field(f, i2);
5402    o->in2 = tcg_const_i64(i2 << s->insn->data);
5403}
5404#define SPEC_in2_i2_16u_shl 0
5405
5406static void in2_i2_32u_shl(DisasContext *s, DisasFields *f, DisasOps *o)
5407{
5408    uint64_t i2 = (uint32_t)get_field(f, i2);
5409    o->in2 = tcg_const_i64(i2 << s->insn->data);
5410}
5411#define SPEC_in2_i2_32u_shl 0
5412
5413#ifndef CONFIG_USER_ONLY
5414static void in2_insn(DisasContext *s, DisasFields *f, DisasOps *o)
5415{
5416    o->in2 = tcg_const_i64(s->fields->raw_insn);
5417}
5418#define SPEC_in2_insn 0
5419#endif
5420
5421/* ====================================================================== */
5422
5423/* Find opc within the table of insns.  This is formulated as a switch
5424   statement so that (1) we get compile-time notice of cut-paste errors
5425   for duplicated opcodes, and (2) the compiler generates the binary
5426   search tree, rather than us having to post-process the table.  */
5427
5428#define C(OPC, NM, FT, FC, I1, I2, P, W, OP, CC) \
5429    D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, 0)
5430
5431#define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) insn_ ## NM,
5432
5433enum DisasInsnEnum {
5434#include "insn-data.def"
5435};
5436
5437#undef D
5438#define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) {                       \
5439    .opc = OPC,                                                             \
5440    .fmt = FMT_##FT,                                                        \
5441    .fac = FAC_##FC,                                                        \
5442    .spec = SPEC_in1_##I1 | SPEC_in2_##I2 | SPEC_prep_##P | SPEC_wout_##W,  \
5443    .name = #NM,                                                            \
5444    .help_in1 = in1_##I1,                                                   \
5445    .help_in2 = in2_##I2,                                                   \
5446    .help_prep = prep_##P,                                                  \
5447    .help_wout = wout_##W,                                                  \
5448    .help_cout = cout_##CC,                                                 \
5449    .help_op = op_##OP,                                                     \
5450    .data = D                                                               \
5451 },
5452
5453/* Allow 0 to be used for NULL in the table below.  */
5454#define in1_0  NULL
5455#define in2_0  NULL
5456#define prep_0  NULL
5457#define wout_0  NULL
5458#define cout_0  NULL
5459#define op_0  NULL
5460
5461#define SPEC_in1_0 0
5462#define SPEC_in2_0 0
5463#define SPEC_prep_0 0
5464#define SPEC_wout_0 0
5465
5466/* Give smaller names to the various facilities.  */
5467#define FAC_Z           S390_FEAT_ZARCH
5468#define FAC_CASS        S390_FEAT_COMPARE_AND_SWAP_AND_STORE
5469#define FAC_DFP         S390_FEAT_DFP
5470#define FAC_DFPR        S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* DFP-rounding */
5471#define FAC_DO          S390_FEAT_STFLE_45 /* distinct-operands */
5472#define FAC_EE          S390_FEAT_EXECUTE_EXT
5473#define FAC_EI          S390_FEAT_EXTENDED_IMMEDIATE
5474#define FAC_FPE         S390_FEAT_FLOATING_POINT_EXT
5475#define FAC_FPSSH       S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* FPS-sign-handling */
5476#define FAC_FPRGR       S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* FPR-GR-transfer */
5477#define FAC_GIE         S390_FEAT_GENERAL_INSTRUCTIONS_EXT
5478#define FAC_HFP_MA      S390_FEAT_HFP_MADDSUB
5479#define FAC_HW          S390_FEAT_STFLE_45 /* high-word */
5480#define FAC_IEEEE_SIM   S390_FEAT_FLOATING_POINT_SUPPPORT_ENH /* IEEE-exception-simulation */
5481#define FAC_MIE         S390_FEAT_STFLE_49 /* misc-instruction-extensions */
5482#define FAC_LAT         S390_FEAT_STFLE_49 /* load-and-trap */
5483#define FAC_LOC         S390_FEAT_STFLE_45 /* load/store on condition 1 */
5484#define FAC_LOC2        S390_FEAT_STFLE_53 /* load/store on condition 2 */
5485#define FAC_LD          S390_FEAT_LONG_DISPLACEMENT
5486#define FAC_PC          S390_FEAT_STFLE_45 /* population count */
5487#define FAC_SCF         S390_FEAT_STORE_CLOCK_FAST
5488#define FAC_SFLE        S390_FEAT_STFLE
5489#define FAC_ILA         S390_FEAT_STFLE_45 /* interlocked-access-facility 1 */
5490#define FAC_MVCOS       S390_FEAT_MOVE_WITH_OPTIONAL_SPEC
5491#define FAC_LPP         S390_FEAT_SET_PROGRAM_PARAMETERS /* load-program-parameter */
5492#define FAC_DAT_ENH     S390_FEAT_DAT_ENH
5493#define FAC_E2          S390_FEAT_EXTENDED_TRANSLATION_2
5494#define FAC_EH          S390_FEAT_STFLE_49 /* execution-hint */
5495#define FAC_PPA         S390_FEAT_STFLE_49 /* processor-assist */
5496#define FAC_LZRB        S390_FEAT_STFLE_53 /* load-and-zero-rightmost-byte */
5497#define FAC_ETF3        S390_FEAT_EXTENDED_TRANSLATION_3
5498
5499static const DisasInsn insn_info[] = {
5500#include "insn-data.def"
5501};
5502
5503#undef D
5504#define D(OPC, NM, FT, FC, I1, I2, P, W, OP, CC, D) \
5505    case OPC: return &insn_info[insn_ ## NM];
5506
5507static const DisasInsn *lookup_opc(uint16_t opc)
5508{
5509    switch (opc) {
5510#include "insn-data.def"
5511    default:
5512        return NULL;
5513    }
5514}
5515
5516#undef D
5517#undef C
5518
5519/* Extract a field from the insn.  The INSN should be left-aligned in
5520   the uint64_t so that we can more easily utilize the big-bit-endian
5521   definitions we extract from the Principals of Operation.  */
5522
5523static void extract_field(DisasFields *o, const DisasField *f, uint64_t insn)
5524{
5525    uint32_t r, m;
5526
5527    if (f->size == 0) {
5528        return;
5529    }
5530
5531    /* Zero extract the field from the insn.  */
5532    r = (insn << f->beg) >> (64 - f->size);
5533
5534    /* Sign-extend, or un-swap the field as necessary.  */
5535    switch (f->type) {
5536    case 0: /* unsigned */
5537        break;
5538    case 1: /* signed */
5539        assert(f->size <= 32);
5540        m = 1u << (f->size - 1);
5541        r = (r ^ m) - m;
5542        break;
5543    case 2: /* dl+dh split, signed 20 bit. */
5544        r = ((int8_t)r << 12) | (r >> 8);
5545        break;
5546    default:
5547        abort();
5548    }
5549
5550    /* Validate that the "compressed" encoding we selected above is valid.
5551       I.e. we havn't make two different original fields overlap.  */
5552    assert(((o->presentC >> f->indexC) & 1) == 0);
5553    o->presentC |= 1 << f->indexC;
5554    o->presentO |= 1 << f->indexO;
5555
5556    o->c[f->indexC] = r;
5557}
5558
5559/* Lookup the insn at the current PC, extracting the operands into O and
5560   returning the info struct for the insn.  Returns NULL for invalid insn.  */
5561
5562static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s,
5563                                     DisasFields *f)
5564{
5565    uint64_t insn, pc = s->pc;
5566    int op, op2, ilen;
5567    const DisasInsn *info;
5568
5569    if (unlikely(s->ex_value)) {
5570        /* Drop the EX data now, so that it's clear on exception paths.  */
5571        TCGv_i64 zero = tcg_const_i64(0);
5572        tcg_gen_st_i64(zero, cpu_env, offsetof(CPUS390XState, ex_value));
5573        tcg_temp_free_i64(zero);
5574
5575        /* Extract the values saved by EXECUTE.  */
5576        insn = s->ex_value & 0xffffffffffff0000ull;
5577        ilen = s->ex_value & 0xf;
5578        op = insn >> 56;
5579    } else {
5580        insn = ld_code2(env, pc);
5581        op = (insn >> 8) & 0xff;
5582        ilen = get_ilen(op);
5583        switch (ilen) {
5584        case 2:
5585            insn = insn << 48;
5586            break;
5587        case 4:
5588            insn = ld_code4(env, pc) << 32;
5589            break;
5590        case 6:
5591            insn = (insn << 48) | (ld_code4(env, pc + 2) << 16);
5592            break;
5593        default:
5594            g_assert_not_reached();
5595        }
5596    }
5597    s->next_pc = s->pc + ilen;
5598    s->ilen = ilen;
5599
5600    /* We can't actually determine the insn format until we've looked up
5601       the full insn opcode.  Which we can't do without locating the
5602       secondary opcode.  Assume by default that OP2 is at bit 40; for
5603       those smaller insns that don't actually have a secondary opcode
5604       this will correctly result in OP2 = 0. */
5605    switch (op) {
5606    case 0x01: /* E */
5607    case 0x80: /* S */
5608    case 0x82: /* S */
5609    case 0x93: /* S */
5610    case 0xb2: /* S, RRF, RRE, IE */
5611    case 0xb3: /* RRE, RRD, RRF */
5612    case 0xb9: /* RRE, RRF */
5613    case 0xe5: /* SSE, SIL */
5614        op2 = (insn << 8) >> 56;
5615        break;
5616    case 0xa5: /* RI */
5617    case 0xa7: /* RI */
5618    case 0xc0: /* RIL */
5619    case 0xc2: /* RIL */
5620    case 0xc4: /* RIL */
5621    case 0xc6: /* RIL */
5622    case 0xc8: /* SSF */
5623    case 0xcc: /* RIL */
5624        op2 = (insn << 12) >> 60;
5625        break;
5626    case 0xc5: /* MII */
5627    case 0xc7: /* SMI */
5628    case 0xd0 ... 0xdf: /* SS */
5629    case 0xe1: /* SS */
5630    case 0xe2: /* SS */
5631    case 0xe8: /* SS */
5632    case 0xe9: /* SS */
5633    case 0xea: /* SS */
5634    case 0xee ... 0xf3: /* SS */
5635    case 0xf8 ... 0xfd: /* SS */
5636        op2 = 0;
5637        break;
5638    default:
5639        op2 = (insn << 40) >> 56;
5640        break;
5641    }
5642
5643    memset(f, 0, sizeof(*f));
5644    f->raw_insn = insn;
5645    f->op = op;
5646    f->op2 = op2;
5647
5648    /* Lookup the instruction.  */
5649    info = lookup_opc(op << 8 | op2);
5650
5651    /* If we found it, extract the operands.  */
5652    if (info != NULL) {
5653        DisasFormat fmt = info->fmt;
5654        int i;
5655
5656        for (i = 0; i < NUM_C_FIELD; ++i) {
5657            extract_field(f, &format_info[fmt].op[i], insn);
5658        }
5659    }
5660    return info;
5661}
5662
5663static ExitStatus translate_one(CPUS390XState *env, DisasContext *s)
5664{
5665    const DisasInsn *insn;
5666    ExitStatus ret = NO_EXIT;
5667    DisasFields f;
5668    DisasOps o;
5669
5670    /* Search for the insn in the table.  */
5671    insn = extract_insn(env, s, &f);
5672
5673    /* Not found means unimplemented/illegal opcode.  */
5674    if (insn == NULL) {
5675        qemu_log_mask(LOG_UNIMP, "unimplemented opcode 0x%02x%02x\n",
5676                      f.op, f.op2);
5677        gen_illegal_opcode(s);
5678        return EXIT_NORETURN;
5679    }
5680
5681#ifndef CONFIG_USER_ONLY
5682    if (s->tb->flags & FLAG_MASK_PER) {
5683        TCGv_i64 addr = tcg_const_i64(s->pc);
5684        gen_helper_per_ifetch(cpu_env, addr);
5685        tcg_temp_free_i64(addr);
5686    }
5687#endif
5688
5689    /* Check for insn specification exceptions.  */
5690    if (insn->spec) {
5691        int spec = insn->spec, excp = 0, r;
5692
5693        if (spec & SPEC_r1_even) {
5694            r = get_field(&f, r1);
5695            if (r & 1) {
5696                excp = PGM_SPECIFICATION;
5697            }
5698        }
5699        if (spec & SPEC_r2_even) {
5700            r = get_field(&f, r2);
5701            if (r & 1) {
5702                excp = PGM_SPECIFICATION;
5703            }
5704        }
5705        if (spec & SPEC_r3_even) {
5706            r = get_field(&f, r3);
5707            if (r & 1) {
5708                excp = PGM_SPECIFICATION;
5709            }
5710        }
5711        if (spec & SPEC_r1_f128) {
5712            r = get_field(&f, r1);
5713            if (r > 13) {
5714                excp = PGM_SPECIFICATION;
5715            }
5716        }
5717        if (spec & SPEC_r2_f128) {
5718            r = get_field(&f, r2);
5719            if (r > 13) {
5720                excp = PGM_SPECIFICATION;
5721            }
5722        }
5723        if (excp) {
5724            gen_program_exception(s, excp);
5725            return EXIT_NORETURN;
5726        }
5727    }
5728
5729    /* Set up the strutures we use to communicate with the helpers. */
5730    s->insn = insn;
5731    s->fields = &f;
5732    o.g_out = o.g_out2 = o.g_in1 = o.g_in2 = false;
5733    TCGV_UNUSED_I64(o.out);
5734    TCGV_UNUSED_I64(o.out2);
5735    TCGV_UNUSED_I64(o.in1);
5736    TCGV_UNUSED_I64(o.in2);
5737    TCGV_UNUSED_I64(o.addr1);
5738
5739    /* Implement the instruction.  */
5740    if (insn->help_in1) {
5741        insn->help_in1(s, &f, &o);
5742    }
5743    if (insn->help_in2) {
5744        insn->help_in2(s, &f, &o);
5745    }
5746    if (insn->help_prep) {
5747        insn->help_prep(s, &f, &o);
5748    }
5749    if (insn->help_op) {
5750        ret = insn->help_op(s, &o);
5751    }
5752    if (insn->help_wout) {
5753        insn->help_wout(s, &f, &o);
5754    }
5755    if (insn->help_cout) {
5756        insn->help_cout(s, &o);
5757    }
5758
5759    /* Free any temporaries created by the helpers.  */
5760    if (!TCGV_IS_UNUSED_I64(o.out) && !o.g_out) {
5761        tcg_temp_free_i64(o.out);
5762    }
5763    if (!TCGV_IS_UNUSED_I64(o.out2) && !o.g_out2) {
5764        tcg_temp_free_i64(o.out2);
5765    }
5766    if (!TCGV_IS_UNUSED_I64(o.in1) && !o.g_in1) {
5767        tcg_temp_free_i64(o.in1);
5768    }
5769    if (!TCGV_IS_UNUSED_I64(o.in2) && !o.g_in2) {
5770        tcg_temp_free_i64(o.in2);
5771    }
5772    if (!TCGV_IS_UNUSED_I64(o.addr1)) {
5773        tcg_temp_free_i64(o.addr1);
5774    }
5775
5776#ifndef CONFIG_USER_ONLY
5777    if (s->tb->flags & FLAG_MASK_PER) {
5778        /* An exception might be triggered, save PSW if not already done.  */
5779        if (ret == NO_EXIT || ret == EXIT_PC_STALE) {
5780            tcg_gen_movi_i64(psw_addr, s->next_pc);
5781        }
5782
5783        /* Save off cc.  */
5784        update_cc_op(s);
5785
5786        /* Call the helper to check for a possible PER exception.  */
5787        gen_helper_per_check_exception(cpu_env);
5788    }
5789#endif
5790
5791    /* Advance to the next instruction.  */
5792    s->pc = s->next_pc;
5793    return ret;
5794}
5795
5796void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
5797{
5798    CPUS390XState *env = cs->env_ptr;
5799    DisasContext dc;
5800    target_ulong pc_start;
5801    uint64_t next_page_start;
5802    int num_insns, max_insns;
5803    ExitStatus status;
5804    bool do_debug;
5805
5806    pc_start = tb->pc;
5807
5808    /* 31-bit mode */
5809    if (!(tb->flags & FLAG_MASK_64)) {
5810        pc_start &= 0x7fffffff;
5811    }
5812
5813    dc.tb = tb;
5814    dc.pc = pc_start;
5815    dc.cc_op = CC_OP_DYNAMIC;
5816    dc.ex_value = tb->cs_base;
5817    do_debug = dc.singlestep_enabled = cs->singlestep_enabled;
5818
5819    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
5820
5821    num_insns = 0;
5822    max_insns = tb->cflags & CF_COUNT_MASK;
5823    if (max_insns == 0) {
5824        max_insns = CF_COUNT_MASK;
5825    }
5826    if (max_insns > TCG_MAX_INSNS) {
5827        max_insns = TCG_MAX_INSNS;
5828    }
5829
5830    gen_tb_start(tb);
5831
5832    do {
5833        tcg_gen_insn_start(dc.pc, dc.cc_op);
5834        num_insns++;
5835
5836        if (unlikely(cpu_breakpoint_test(cs, dc.pc, BP_ANY))) {
5837            status = EXIT_PC_STALE;
5838            do_debug = true;
5839            /* The address covered by the breakpoint must be included in
5840               [tb->pc, tb->pc + tb->size) in order to for it to be
5841               properly cleared -- thus we increment the PC here so that
5842               the logic setting tb->size below does the right thing.  */
5843            dc.pc += 2;
5844            break;
5845        }
5846
5847        if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
5848            gen_io_start();
5849        }
5850
5851        status = translate_one(env, &dc);
5852
5853        /* If we reach a page boundary, are single stepping,
5854           or exhaust instruction count, stop generation.  */
5855        if (status == NO_EXIT
5856            && (dc.pc >= next_page_start
5857                || tcg_op_buf_full()
5858                || num_insns >= max_insns
5859                || singlestep
5860                || cs->singlestep_enabled
5861                || dc.ex_value)) {
5862            status = EXIT_PC_STALE;
5863        }
5864    } while (status == NO_EXIT);
5865
5866    if (tb->cflags & CF_LAST_IO) {
5867        gen_io_end();
5868    }
5869
5870    switch (status) {
5871    case EXIT_GOTO_TB:
5872    case EXIT_NORETURN:
5873        break;
5874    case EXIT_PC_STALE:
5875    case EXIT_PC_STALE_NOCHAIN:
5876        update_psw_addr(&dc);
5877        /* FALLTHRU */
5878    case EXIT_PC_UPDATED:
5879        /* Next TB starts off with CC_OP_DYNAMIC, so make sure the
5880           cc op type is in env */
5881        update_cc_op(&dc);
5882        /* FALLTHRU */
5883    case EXIT_PC_CC_UPDATED:
5884        /* Exit the TB, either by raising a debug exception or by return.  */
5885        if (do_debug) {
5886            gen_exception(EXCP_DEBUG);
5887        } else if (use_exit_tb(&dc) || status == EXIT_PC_STALE_NOCHAIN) {
5888            tcg_gen_exit_tb(0);
5889        } else {
5890            tcg_gen_lookup_and_goto_ptr(psw_addr);
5891        }
5892        break;
5893    default:
5894        g_assert_not_reached();
5895    }
5896
5897    gen_tb_end(tb, num_insns);
5898
5899    tb->size = dc.pc - pc_start;
5900    tb->icount = num_insns;
5901
5902#if defined(S390X_DEBUG_DISAS)
5903    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
5904        && qemu_log_in_addr_range(pc_start)) {
5905        qemu_log_lock();
5906        if (unlikely(dc.ex_value)) {
5907            /* ??? Unfortunately log_target_disas can't use host memory.  */
5908            qemu_log("IN: EXECUTE %016" PRIx64 "\n", dc.ex_value);
5909        } else {
5910            qemu_log("IN: %s\n", lookup_symbol(pc_start));
5911            log_target_disas(cs, pc_start, dc.pc - pc_start, 1);
5912            qemu_log("\n");
5913        }
5914        qemu_log_unlock();
5915    }
5916#endif
5917}
5918
5919void restore_state_to_opc(CPUS390XState *env, TranslationBlock *tb,
5920                          target_ulong *data)
5921{
5922    int cc_op = data[1];
5923    env->psw.addr = data[0];
5924    if ((cc_op != CC_OP_DYNAMIC) && (cc_op != CC_OP_STATIC)) {
5925        env->cc_op = cc_op;
5926    }
5927}
5928