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#include <stdarg.h>
  21#include <stdlib.h>
  22#include <stdio.h>
  23#include <string.h>
  24#include <inttypes.h>
  25
  26/* #define DEBUG_ILLEGAL_INSTRUCTIONS */
  27/* #define DEBUG_INLINE_BRANCHES */
  28#define S390X_DEBUG_DISAS
  29/* #define S390X_DEBUG_DISAS_VERBOSE */
  30
  31#ifdef S390X_DEBUG_DISAS_VERBOSE
  32#  define LOG_DISAS(...) qemu_log(__VA_ARGS__)
  33#else
  34#  define LOG_DISAS(...) do { } while (0)
  35#endif
  36
  37#include "cpu.h"
  38#include "disas.h"
  39#include "tcg-op.h"
  40#include "qemu-log.h"
  41
  42/* global register indexes */
  43static TCGv_ptr cpu_env;
  44
  45#include "gen-icount.h"
  46#include "helpers.h"
  47#define GEN_HELPER 1
  48#include "helpers.h"
  49
  50typedef struct DisasContext DisasContext;
  51struct DisasContext {
  52    uint64_t pc;
  53    int is_jmp;
  54    enum cc_op cc_op;
  55    struct TranslationBlock *tb;
  56};
  57
  58#define DISAS_EXCP 4
  59
  60static void gen_op_calc_cc(DisasContext *s);
  61
  62#ifdef DEBUG_INLINE_BRANCHES
  63static uint64_t inline_branch_hit[CC_OP_MAX];
  64static uint64_t inline_branch_miss[CC_OP_MAX];
  65#endif
  66
  67static inline void debug_insn(uint64_t insn)
  68{
  69    LOG_DISAS("insn: 0x%" PRIx64 "\n", insn);
  70}
  71
  72static inline uint64_t pc_to_link_info(DisasContext *s, uint64_t pc)
  73{
  74    if (!(s->tb->flags & FLAG_MASK_64)) {
  75        if (s->tb->flags & FLAG_MASK_32) {
  76            return pc | 0x80000000;
  77        }
  78    }
  79    return pc;
  80}
  81
  82void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
  83                    int flags)
  84{
  85    int i;
  86
  87    for (i = 0; i < 16; i++) {
  88        cpu_fprintf(f, "R%02d=%016" PRIx64, i, env->regs[i]);
  89        if ((i % 4) == 3) {
  90            cpu_fprintf(f, "\n");
  91        } else {
  92            cpu_fprintf(f, " ");
  93        }
  94    }
  95
  96    for (i = 0; i < 16; i++) {
  97        cpu_fprintf(f, "F%02d=%016" PRIx64, i, *(uint64_t *)&env->fregs[i]);
  98        if ((i % 4) == 3) {
  99            cpu_fprintf(f, "\n");
 100        } else {
 101            cpu_fprintf(f, " ");
 102        }
 103    }
 104
 105    cpu_fprintf(f, "\n");
 106
 107#ifndef CONFIG_USER_ONLY
 108    for (i = 0; i < 16; i++) {
 109        cpu_fprintf(f, "C%02d=%016" PRIx64, i, env->cregs[i]);
 110        if ((i % 4) == 3) {
 111            cpu_fprintf(f, "\n");
 112        } else {
 113            cpu_fprintf(f, " ");
 114        }
 115    }
 116#endif
 117
 118    cpu_fprintf(f, "\n");
 119
 120    if (env->cc_op > 3) {
 121        cpu_fprintf(f, "PSW=mask %016" PRIx64 " addr %016" PRIx64 " cc %15s\n",
 122                    env->psw.mask, env->psw.addr, cc_name(env->cc_op));
 123    } else {
 124        cpu_fprintf(f, "PSW=mask %016" PRIx64 " addr %016" PRIx64 " cc %02x\n",
 125                    env->psw.mask, env->psw.addr, env->cc_op);
 126    }
 127
 128#ifdef DEBUG_INLINE_BRANCHES
 129    for (i = 0; i < CC_OP_MAX; i++) {
 130        cpu_fprintf(f, "  %15s = %10ld\t%10ld\n", cc_name(i),
 131                    inline_branch_miss[i], inline_branch_hit[i]);
 132    }
 133#endif
 134}
 135
 136static TCGv_i64 psw_addr;
 137static TCGv_i64 psw_mask;
 138
 139static TCGv_i32 cc_op;
 140static TCGv_i64 cc_src;
 141static TCGv_i64 cc_dst;
 142static TCGv_i64 cc_vr;
 143
 144static char cpu_reg_names[10*3 + 6*4];
 145static TCGv_i64 regs[16];
 146
 147static uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
 148
 149void s390x_translate_init(void)
 150{
 151    int i;
 152    size_t cpu_reg_names_size = sizeof(cpu_reg_names);
 153    char *p;
 154
 155    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
 156    psw_addr = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, psw.addr),
 157                                      "psw_addr");
 158    psw_mask = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, psw.mask),
 159                                      "psw_mask");
 160
 161    cc_op = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, cc_op),
 162                                   "cc_op");
 163    cc_src = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, cc_src),
 164                                    "cc_src");
 165    cc_dst = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, cc_dst),
 166                                    "cc_dst");
 167    cc_vr = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, cc_vr),
 168                                   "cc_vr");
 169
 170    p = cpu_reg_names;
 171    for (i = 0; i < 16; i++) {
 172        snprintf(p, cpu_reg_names_size, "r%d", i);
 173        regs[i] = tcg_global_mem_new(TCG_AREG0,
 174                                     offsetof(CPUState, regs[i]), p);
 175        p += (i < 10) ? 3 : 4;
 176        cpu_reg_names_size -= (i < 10) ? 3 : 4;
 177    }
 178}
 179
 180static inline TCGv_i64 load_reg(int reg)
 181{
 182    TCGv_i64 r = tcg_temp_new_i64();
 183    tcg_gen_mov_i64(r, regs[reg]);
 184    return r;
 185}
 186
 187static inline TCGv_i64 load_freg(int reg)
 188{
 189    TCGv_i64 r = tcg_temp_new_i64();
 190    tcg_gen_ld_i64(r, cpu_env, offsetof(CPUState, fregs[reg].d));
 191    return r;
 192}
 193
 194static inline TCGv_i32 load_freg32(int reg)
 195{
 196    TCGv_i32 r = tcg_temp_new_i32();
 197    tcg_gen_ld_i32(r, cpu_env, offsetof(CPUState, fregs[reg].l.upper));
 198    return r;
 199}
 200
 201static inline TCGv_i32 load_reg32(int reg)
 202{
 203    TCGv_i32 r = tcg_temp_new_i32();
 204    tcg_gen_trunc_i64_i32(r, regs[reg]);
 205    return r;
 206}
 207
 208static inline TCGv_i64 load_reg32_i64(int reg)
 209{
 210    TCGv_i64 r = tcg_temp_new_i64();
 211    tcg_gen_ext32s_i64(r, regs[reg]);
 212    return r;
 213}
 214
 215static inline void store_reg(int reg, TCGv_i64 v)
 216{
 217    tcg_gen_mov_i64(regs[reg], v);
 218}
 219
 220static inline void store_freg(int reg, TCGv_i64 v)
 221{
 222    tcg_gen_st_i64(v, cpu_env, offsetof(CPUState, fregs[reg].d));
 223}
 224
 225static inline void store_reg32(int reg, TCGv_i32 v)
 226{
 227#if HOST_LONG_BITS == 32
 228    tcg_gen_mov_i32(TCGV_LOW(regs[reg]), v);
 229#else
 230    TCGv_i64 tmp = tcg_temp_new_i64();
 231    tcg_gen_extu_i32_i64(tmp, v);
 232    /* 32 bit register writes keep the upper half */
 233    tcg_gen_deposit_i64(regs[reg], regs[reg], tmp, 0, 32);
 234    tcg_temp_free_i64(tmp);
 235#endif
 236}
 237
 238static inline void store_reg32_i64(int reg, TCGv_i64 v)
 239{
 240    /* 32 bit register writes keep the upper half */
 241#if HOST_LONG_BITS == 32
 242    tcg_gen_mov_i32(TCGV_LOW(regs[reg]), TCGV_LOW(v));
 243#else
 244    tcg_gen_deposit_i64(regs[reg], regs[reg], v, 0, 32);
 245#endif
 246}
 247
 248static inline void store_reg16(int reg, TCGv_i32 v)
 249{
 250    TCGv_i64 tmp = tcg_temp_new_i64();
 251    tcg_gen_extu_i32_i64(tmp, v);
 252    /* 16 bit register writes keep the upper bytes */
 253    tcg_gen_deposit_i64(regs[reg], regs[reg], tmp, 0, 16);
 254    tcg_temp_free_i64(tmp);
 255}
 256
 257static inline void store_reg8(int reg, TCGv_i64 v)
 258{
 259    /* 8 bit register writes keep the upper bytes */
 260    tcg_gen_deposit_i64(regs[reg], regs[reg], v, 0, 8);
 261}
 262
 263static inline void store_freg32(int reg, TCGv_i32 v)
 264{
 265    tcg_gen_st_i32(v, cpu_env, offsetof(CPUState, fregs[reg].l.upper));
 266}
 267
 268static inline void update_psw_addr(DisasContext *s)
 269{
 270    /* psw.addr */
 271    tcg_gen_movi_i64(psw_addr, s->pc);
 272}
 273
 274static inline void potential_page_fault(DisasContext *s)
 275{
 276#ifndef CONFIG_USER_ONLY
 277    update_psw_addr(s);
 278    gen_op_calc_cc(s);
 279#endif
 280}
 281
 282static inline uint64_t ld_code2(uint64_t pc)
 283{
 284    return (uint64_t)lduw_code(pc);
 285}
 286
 287static inline uint64_t ld_code4(uint64_t pc)
 288{
 289    return (uint64_t)ldl_code(pc);
 290}
 291
 292static inline uint64_t ld_code6(uint64_t pc)
 293{
 294    uint64_t opc;
 295    opc = (uint64_t)lduw_code(pc) << 32;
 296    opc |= (uint64_t)(uint32_t)ldl_code(pc+2);
 297    return opc;
 298}
 299
 300static inline int get_mem_index(DisasContext *s)
 301{
 302    switch (s->tb->flags & FLAG_MASK_ASC) {
 303    case PSW_ASC_PRIMARY >> 32:
 304        return 0;
 305    case PSW_ASC_SECONDARY >> 32:
 306        return 1;
 307    case PSW_ASC_HOME >> 32:
 308        return 2;
 309    default:
 310        tcg_abort();
 311        break;
 312    }
 313}
 314
 315static inline void gen_debug(DisasContext *s)
 316{
 317    TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
 318    update_psw_addr(s);
 319    gen_op_calc_cc(s);
 320    gen_helper_exception(tmp);
 321    tcg_temp_free_i32(tmp);
 322    s->is_jmp = DISAS_EXCP;
 323}
 324
 325#ifdef CONFIG_USER_ONLY
 326
 327static void gen_illegal_opcode(DisasContext *s, int ilc)
 328{
 329    TCGv_i32 tmp = tcg_const_i32(EXCP_SPEC);
 330    update_psw_addr(s);
 331    gen_op_calc_cc(s);
 332    gen_helper_exception(tmp);
 333    tcg_temp_free_i32(tmp);
 334    s->is_jmp = DISAS_EXCP;
 335}
 336
 337#else /* CONFIG_USER_ONLY */
 338
 339static void debug_print_inst(DisasContext *s, int ilc)
 340{
 341#ifdef DEBUG_ILLEGAL_INSTRUCTIONS
 342    uint64_t inst = 0;
 343
 344    switch (ilc & 3) {
 345    case 1:
 346        inst = ld_code2(s->pc);
 347        break;
 348    case 2:
 349        inst = ld_code4(s->pc);
 350        break;
 351    case 3:
 352        inst = ld_code6(s->pc);
 353        break;
 354    }
 355
 356    fprintf(stderr, "Illegal instruction [%d at %016" PRIx64 "]: 0x%016"
 357            PRIx64 "\n", ilc, s->pc, inst);
 358#endif
 359}
 360
 361static void gen_program_exception(DisasContext *s, int ilc, int code)
 362{
 363    TCGv_i32 tmp;
 364
 365    debug_print_inst(s, ilc);
 366
 367    /* remember what pgm exeption this was */
 368    tmp = tcg_const_i32(code);
 369    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, int_pgm_code));
 370    tcg_temp_free_i32(tmp);
 371
 372    tmp = tcg_const_i32(ilc);
 373    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, int_pgm_ilc));
 374    tcg_temp_free_i32(tmp);
 375
 376    /* advance past instruction */
 377    s->pc += (ilc * 2);
 378    update_psw_addr(s);
 379
 380    /* save off cc */
 381    gen_op_calc_cc(s);
 382
 383    /* trigger exception */
 384    tmp = tcg_const_i32(EXCP_PGM);
 385    gen_helper_exception(tmp);
 386    tcg_temp_free_i32(tmp);
 387
 388    /* end TB here */
 389    s->is_jmp = DISAS_EXCP;
 390}
 391
 392
 393static void gen_illegal_opcode(DisasContext *s, int ilc)
 394{
 395    gen_program_exception(s, ilc, PGM_SPECIFICATION);
 396}
 397
 398static void gen_privileged_exception(DisasContext *s, int ilc)
 399{
 400    gen_program_exception(s, ilc, PGM_PRIVILEGED);
 401}
 402
 403static void check_privileged(DisasContext *s, int ilc)
 404{
 405    if (s->tb->flags & (PSW_MASK_PSTATE >> 32)) {
 406        gen_privileged_exception(s, ilc);
 407    }
 408}
 409
 410#endif /* CONFIG_USER_ONLY */
 411
 412static TCGv_i64 get_address(DisasContext *s, int x2, int b2, int d2)
 413{
 414    TCGv_i64 tmp;
 415
 416    /* 31-bitify the immediate part; register contents are dealt with below */
 417    if (!(s->tb->flags & FLAG_MASK_64)) {
 418        d2 &= 0x7fffffffUL;
 419    }
 420
 421    if (x2) {
 422        if (d2) {
 423            tmp = tcg_const_i64(d2);
 424            tcg_gen_add_i64(tmp, tmp, regs[x2]);
 425        } else {
 426            tmp = load_reg(x2);
 427        }
 428        if (b2) {
 429            tcg_gen_add_i64(tmp, tmp, regs[b2]);
 430        }
 431    } else if (b2) {
 432        if (d2) {
 433            tmp = tcg_const_i64(d2);
 434            tcg_gen_add_i64(tmp, tmp, regs[b2]);
 435        } else {
 436            tmp = load_reg(b2);
 437        }
 438    } else {
 439        tmp = tcg_const_i64(d2);
 440    }
 441
 442    /* 31-bit mode mask if there are values loaded from registers */
 443    if (!(s->tb->flags & FLAG_MASK_64) && (x2 || b2)) {
 444        tcg_gen_andi_i64(tmp, tmp, 0x7fffffffUL);
 445    }
 446
 447    return tmp;
 448}
 449
 450static void gen_op_movi_cc(DisasContext *s, uint32_t val)
 451{
 452    s->cc_op = CC_OP_CONST0 + val;
 453}
 454
 455static void gen_op_update1_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 dst)
 456{
 457    tcg_gen_discard_i64(cc_src);
 458    tcg_gen_mov_i64(cc_dst, dst);
 459    tcg_gen_discard_i64(cc_vr);
 460    s->cc_op = op;
 461}
 462
 463static void gen_op_update1_cc_i32(DisasContext *s, enum cc_op op, TCGv_i32 dst)
 464{
 465    tcg_gen_discard_i64(cc_src);
 466    tcg_gen_extu_i32_i64(cc_dst, dst);
 467    tcg_gen_discard_i64(cc_vr);
 468    s->cc_op = op;
 469}
 470
 471static void gen_op_update2_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
 472                                  TCGv_i64 dst)
 473{
 474    tcg_gen_mov_i64(cc_src, src);
 475    tcg_gen_mov_i64(cc_dst, dst);
 476    tcg_gen_discard_i64(cc_vr);
 477    s->cc_op = op;
 478}
 479
 480static void gen_op_update2_cc_i32(DisasContext *s, enum cc_op op, TCGv_i32 src,
 481                                  TCGv_i32 dst)
 482{
 483    tcg_gen_extu_i32_i64(cc_src, src);
 484    tcg_gen_extu_i32_i64(cc_dst, dst);
 485    tcg_gen_discard_i64(cc_vr);
 486    s->cc_op = op;
 487}
 488
 489static void gen_op_update3_cc_i64(DisasContext *s, enum cc_op op, TCGv_i64 src,
 490                                  TCGv_i64 dst, TCGv_i64 vr)
 491{
 492    tcg_gen_mov_i64(cc_src, src);
 493    tcg_gen_mov_i64(cc_dst, dst);
 494    tcg_gen_mov_i64(cc_vr, vr);
 495    s->cc_op = op;
 496}
 497
 498static void gen_op_update3_cc_i32(DisasContext *s, enum cc_op op, TCGv_i32 src,
 499                                  TCGv_i32 dst, TCGv_i32 vr)
 500{
 501    tcg_gen_extu_i32_i64(cc_src, src);
 502    tcg_gen_extu_i32_i64(cc_dst, dst);
 503    tcg_gen_extu_i32_i64(cc_vr, vr);
 504    s->cc_op = op;
 505}
 506
 507static inline void set_cc_nz_u32(DisasContext *s, TCGv_i32 val)
 508{
 509    gen_op_update1_cc_i32(s, CC_OP_NZ, val);
 510}
 511
 512static inline void set_cc_nz_u64(DisasContext *s, TCGv_i64 val)
 513{
 514    gen_op_update1_cc_i64(s, CC_OP_NZ, val);
 515}
 516
 517static inline void cmp_32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2,
 518                          enum cc_op cond)
 519{
 520    gen_op_update2_cc_i32(s, cond, v1, v2);
 521}
 522
 523static inline void cmp_64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2,
 524                          enum cc_op cond)
 525{
 526    gen_op_update2_cc_i64(s, cond, v1, v2);
 527}
 528
 529static inline void cmp_s32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2)
 530{
 531    cmp_32(s, v1, v2, CC_OP_LTGT_32);
 532}
 533
 534static inline void cmp_u32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2)
 535{
 536    cmp_32(s, v1, v2, CC_OP_LTUGTU_32);
 537}
 538
 539static inline void cmp_s32c(DisasContext *s, TCGv_i32 v1, int32_t v2)
 540{
 541    /* XXX optimize for the constant? put it in s? */
 542    TCGv_i32 tmp = tcg_const_i32(v2);
 543    cmp_32(s, v1, tmp, CC_OP_LTGT_32);
 544    tcg_temp_free_i32(tmp);
 545}
 546
 547static inline void cmp_u32c(DisasContext *s, TCGv_i32 v1, uint32_t v2)
 548{
 549    TCGv_i32 tmp = tcg_const_i32(v2);
 550    cmp_32(s, v1, tmp, CC_OP_LTUGTU_32);
 551    tcg_temp_free_i32(tmp);
 552}
 553
 554static inline void cmp_s64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2)
 555{
 556    cmp_64(s, v1, v2, CC_OP_LTGT_64);
 557}
 558
 559static inline void cmp_u64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2)
 560{
 561    cmp_64(s, v1, v2, CC_OP_LTUGTU_64);
 562}
 563
 564static inline void cmp_s64c(DisasContext *s, TCGv_i64 v1, int64_t v2)
 565{
 566    TCGv_i64 tmp = tcg_const_i64(v2);
 567    cmp_s64(s, v1, tmp);
 568    tcg_temp_free_i64(tmp);
 569}
 570
 571static inline void cmp_u64c(DisasContext *s, TCGv_i64 v1, uint64_t v2)
 572{
 573    TCGv_i64 tmp = tcg_const_i64(v2);
 574    cmp_u64(s, v1, tmp);
 575    tcg_temp_free_i64(tmp);
 576}
 577
 578static inline void set_cc_s32(DisasContext *s, TCGv_i32 val)
 579{
 580    gen_op_update1_cc_i32(s, CC_OP_LTGT0_32, val);
 581}
 582
 583static inline void set_cc_s64(DisasContext *s, TCGv_i64 val)
 584{
 585    gen_op_update1_cc_i64(s, CC_OP_LTGT0_64, val);
 586}
 587
 588static void set_cc_add64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2, TCGv_i64 vr)
 589{
 590    gen_op_update3_cc_i64(s, CC_OP_ADD_64, v1, v2, vr);
 591}
 592
 593static void set_cc_addu64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2,
 594                          TCGv_i64 vr)
 595{
 596    gen_op_update3_cc_i64(s, CC_OP_ADDU_64, v1, v2, vr);
 597}
 598
 599static void set_cc_sub64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2, TCGv_i64 vr)
 600{
 601    gen_op_update3_cc_i64(s, CC_OP_SUB_64, v1, v2, vr);
 602}
 603
 604static void set_cc_subu64(DisasContext *s, TCGv_i64 v1, TCGv_i64 v2,
 605                          TCGv_i64 vr)
 606{
 607    gen_op_update3_cc_i64(s, CC_OP_SUBU_64, v1, v2, vr);
 608}
 609
 610static void set_cc_abs64(DisasContext *s, TCGv_i64 v1)
 611{
 612    gen_op_update1_cc_i64(s, CC_OP_ABS_64, v1);
 613}
 614
 615static void set_cc_nabs64(DisasContext *s, TCGv_i64 v1)
 616{
 617    gen_op_update1_cc_i64(s, CC_OP_NABS_64, v1);
 618}
 619
 620static void set_cc_add32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2, TCGv_i32 vr)
 621{
 622    gen_op_update3_cc_i32(s, CC_OP_ADD_32, v1, v2, vr);
 623}
 624
 625static void set_cc_addu32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2,
 626                          TCGv_i32 vr)
 627{
 628    gen_op_update3_cc_i32(s, CC_OP_ADDU_32, v1, v2, vr);
 629}
 630
 631static void set_cc_sub32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2, TCGv_i32 vr)
 632{
 633    gen_op_update3_cc_i32(s, CC_OP_SUB_32, v1, v2, vr);
 634}
 635
 636static void set_cc_subu32(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2,
 637                          TCGv_i32 vr)
 638{
 639    gen_op_update3_cc_i32(s, CC_OP_SUBU_32, v1, v2, vr);
 640}
 641
 642static void set_cc_abs32(DisasContext *s, TCGv_i32 v1)
 643{
 644    gen_op_update1_cc_i32(s, CC_OP_ABS_32, v1);
 645}
 646
 647static void set_cc_nabs32(DisasContext *s, TCGv_i32 v1)
 648{
 649    gen_op_update1_cc_i32(s, CC_OP_NABS_32, v1);
 650}
 651
 652static void set_cc_comp32(DisasContext *s, TCGv_i32 v1)
 653{
 654    gen_op_update1_cc_i32(s, CC_OP_COMP_32, v1);
 655}
 656
 657static void set_cc_comp64(DisasContext *s, TCGv_i64 v1)
 658{
 659    gen_op_update1_cc_i64(s, CC_OP_COMP_64, v1);
 660}
 661
 662static void set_cc_icm(DisasContext *s, TCGv_i32 v1, TCGv_i32 v2)
 663{
 664    gen_op_update2_cc_i32(s, CC_OP_ICM, v1, v2);
 665}
 666
 667static void set_cc_cmp_f32_i64(DisasContext *s, TCGv_i32 v1, TCGv_i64 v2)
 668{
 669    tcg_gen_extu_i32_i64(cc_src, v1);
 670    tcg_gen_mov_i64(cc_dst, v2);
 671    tcg_gen_discard_i64(cc_vr);
 672    s->cc_op = CC_OP_LTGT_F32;
 673}
 674
 675static void set_cc_nz_f32(DisasContext *s, TCGv_i32 v1)
 676{
 677    gen_op_update1_cc_i32(s, CC_OP_NZ_F32, v1);
 678}
 679
 680static inline void set_cc_nz_f64(DisasContext *s, TCGv_i64 v1)
 681{
 682    gen_op_update1_cc_i64(s, CC_OP_NZ_F64, v1);
 683}
 684
 685/* CC value is in env->cc_op */
 686static inline void set_cc_static(DisasContext *s)
 687{
 688    tcg_gen_discard_i64(cc_src);
 689    tcg_gen_discard_i64(cc_dst);
 690    tcg_gen_discard_i64(cc_vr);
 691    s->cc_op = CC_OP_STATIC;
 692}
 693
 694static inline void gen_op_set_cc_op(DisasContext *s)
 695{
 696    if (s->cc_op != CC_OP_DYNAMIC && s->cc_op != CC_OP_STATIC) {
 697        tcg_gen_movi_i32(cc_op, s->cc_op);
 698    }
 699}
 700
 701static inline void gen_update_cc_op(DisasContext *s)
 702{
 703    gen_op_set_cc_op(s);
 704}
 705
 706/* calculates cc into cc_op */
 707static void gen_op_calc_cc(DisasContext *s)
 708{
 709    TCGv_i32 local_cc_op = tcg_const_i32(s->cc_op);
 710    TCGv_i64 dummy = tcg_const_i64(0);
 711
 712    switch (s->cc_op) {
 713    case CC_OP_CONST0:
 714    case CC_OP_CONST1:
 715    case CC_OP_CONST2:
 716    case CC_OP_CONST3:
 717        /* s->cc_op is the cc value */
 718        tcg_gen_movi_i32(cc_op, s->cc_op - CC_OP_CONST0);
 719        break;
 720    case CC_OP_STATIC:
 721        /* env->cc_op already is the cc value */
 722        break;
 723    case CC_OP_NZ:
 724    case CC_OP_ABS_64:
 725    case CC_OP_NABS_64:
 726    case CC_OP_ABS_32:
 727    case CC_OP_NABS_32:
 728    case CC_OP_LTGT0_32:
 729    case CC_OP_LTGT0_64:
 730    case CC_OP_COMP_32:
 731    case CC_OP_COMP_64:
 732    case CC_OP_NZ_F32:
 733    case CC_OP_NZ_F64:
 734        /* 1 argument */
 735        gen_helper_calc_cc(cc_op, local_cc_op, dummy, cc_dst, dummy);
 736        break;
 737    case CC_OP_ICM:
 738    case CC_OP_LTGT_32:
 739    case CC_OP_LTGT_64:
 740    case CC_OP_LTUGTU_32:
 741    case CC_OP_LTUGTU_64:
 742    case CC_OP_TM_32:
 743    case CC_OP_TM_64:
 744    case CC_OP_LTGT_F32:
 745    case CC_OP_LTGT_F64:
 746    case CC_OP_SLAG:
 747        /* 2 arguments */
 748        gen_helper_calc_cc(cc_op, local_cc_op, cc_src, cc_dst, dummy);
 749        break;
 750    case CC_OP_ADD_64:
 751    case CC_OP_ADDU_64:
 752    case CC_OP_SUB_64:
 753    case CC_OP_SUBU_64:
 754    case CC_OP_ADD_32:
 755    case CC_OP_ADDU_32:
 756    case CC_OP_SUB_32:
 757    case CC_OP_SUBU_32:
 758        /* 3 arguments */
 759        gen_helper_calc_cc(cc_op, local_cc_op, cc_src, cc_dst, cc_vr);
 760        break;
 761    case CC_OP_DYNAMIC:
 762        /* unknown operation - assume 3 arguments and cc_op in env */
 763        gen_helper_calc_cc(cc_op, cc_op, cc_src, cc_dst, cc_vr);
 764        break;
 765    default:
 766        tcg_abort();
 767    }
 768
 769    tcg_temp_free_i32(local_cc_op);
 770
 771    /* We now have cc in cc_op as constant */
 772    set_cc_static(s);
 773}
 774
 775static inline void decode_rr(DisasContext *s, uint64_t insn, int *r1, int *r2)
 776{
 777    debug_insn(insn);
 778
 779    *r1 = (insn >> 4) & 0xf;
 780    *r2 = insn & 0xf;
 781}
 782
 783static inline TCGv_i64 decode_rx(DisasContext *s, uint64_t insn, int *r1,
 784                                 int *x2, int *b2, int *d2)
 785{
 786    debug_insn(insn);
 787
 788    *r1 = (insn >> 20) & 0xf;
 789    *x2 = (insn >> 16) & 0xf;
 790    *b2 = (insn >> 12) & 0xf;
 791    *d2 = insn & 0xfff;
 792
 793    return get_address(s, *x2, *b2, *d2);
 794}
 795
 796static inline void decode_rs(DisasContext *s, uint64_t insn, int *r1, int *r3,
 797                             int *b2, int *d2)
 798{
 799    debug_insn(insn);
 800
 801    *r1 = (insn >> 20) & 0xf;
 802    /* aka m3 */
 803    *r3 = (insn >> 16) & 0xf;
 804    *b2 = (insn >> 12) & 0xf;
 805    *d2 = insn & 0xfff;
 806}
 807
 808static inline TCGv_i64 decode_si(DisasContext *s, uint64_t insn, int *i2,
 809                                 int *b1, int *d1)
 810{
 811    debug_insn(insn);
 812
 813    *i2 = (insn >> 16) & 0xff;
 814    *b1 = (insn >> 12) & 0xf;
 815    *d1 = insn & 0xfff;
 816
 817    return get_address(s, 0, *b1, *d1);
 818}
 819
 820static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong pc)
 821{
 822    TranslationBlock *tb;
 823
 824    gen_update_cc_op(s);
 825
 826    tb = s->tb;
 827    /* NOTE: we handle the case where the TB spans two pages here */
 828    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
 829        (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
 830        /* jump to same page: we can use a direct jump */
 831        tcg_gen_goto_tb(tb_num);
 832        tcg_gen_movi_i64(psw_addr, pc);
 833        tcg_gen_exit_tb((long)tb + tb_num);
 834    } else {
 835        /* jump to another page: currently not optimized */
 836        tcg_gen_movi_i64(psw_addr, pc);
 837        tcg_gen_exit_tb(0);
 838    }
 839}
 840
 841static inline void account_noninline_branch(DisasContext *s, int cc_op)
 842{
 843#ifdef DEBUG_INLINE_BRANCHES
 844    inline_branch_miss[cc_op]++;
 845#endif
 846}
 847
 848static inline void account_inline_branch(DisasContext *s)
 849{
 850#ifdef DEBUG_INLINE_BRANCHES
 851    inline_branch_hit[s->cc_op]++;
 852#endif
 853}
 854
 855static void gen_jcc(DisasContext *s, uint32_t mask, int skip)
 856{
 857    TCGv_i32 tmp, tmp2, r;
 858    TCGv_i64 tmp64;
 859    int old_cc_op;
 860
 861    switch (s->cc_op) {
 862    case CC_OP_LTGT0_32:
 863        tmp = tcg_temp_new_i32();
 864        tcg_gen_trunc_i64_i32(tmp, cc_dst);
 865        switch (mask) {
 866        case 0x8 | 0x4: /* dst <= 0 */
 867            tcg_gen_brcondi_i32(TCG_COND_GT, tmp, 0, skip);
 868            break;
 869        case 0x8 | 0x2: /* dst >= 0 */
 870            tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, skip);
 871            break;
 872        case 0x8: /* dst == 0 */
 873            tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, skip);
 874            break;
 875        case 0x7: /* dst != 0 */
 876        case 0x6: /* dst != 0 */
 877            tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, skip);
 878            break;
 879        case 0x4: /* dst < 0 */
 880            tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, skip);
 881            break;
 882        case 0x2: /* dst > 0 */
 883            tcg_gen_brcondi_i32(TCG_COND_LE, tmp, 0, skip);
 884            break;
 885        default:
 886            tcg_temp_free_i32(tmp);
 887            goto do_dynamic;
 888        }
 889        account_inline_branch(s);
 890        tcg_temp_free_i32(tmp);
 891        break;
 892    case CC_OP_LTGT0_64:
 893        switch (mask) {
 894        case 0x8 | 0x4: /* dst <= 0 */
 895            tcg_gen_brcondi_i64(TCG_COND_GT, cc_dst, 0, skip);
 896            break;
 897        case 0x8 | 0x2: /* dst >= 0 */
 898            tcg_gen_brcondi_i64(TCG_COND_LT, cc_dst, 0, skip);
 899            break;
 900        case 0x8: /* dst == 0 */
 901            tcg_gen_brcondi_i64(TCG_COND_NE, cc_dst, 0, skip);
 902            break;
 903        case 0x7: /* dst != 0 */
 904        case 0x6: /* dst != 0 */
 905            tcg_gen_brcondi_i64(TCG_COND_EQ, cc_dst, 0, skip);
 906            break;
 907        case 0x4: /* dst < 0 */
 908            tcg_gen_brcondi_i64(TCG_COND_GE, cc_dst, 0, skip);
 909            break;
 910        case 0x2: /* dst > 0 */
 911            tcg_gen_brcondi_i64(TCG_COND_LE, cc_dst, 0, skip);
 912            break;
 913        default:
 914            goto do_dynamic;
 915        }
 916        account_inline_branch(s);
 917        break;
 918    case CC_OP_LTGT_32:
 919        tmp = tcg_temp_new_i32();
 920        tmp2 = tcg_temp_new_i32();
 921        tcg_gen_trunc_i64_i32(tmp, cc_src);
 922        tcg_gen_trunc_i64_i32(tmp2, cc_dst);
 923        switch (mask) {
 924        case 0x8 | 0x4: /* src <= dst */
 925            tcg_gen_brcond_i32(TCG_COND_GT, tmp, tmp2, skip);
 926            break;
 927        case 0x8 | 0x2: /* src >= dst */
 928            tcg_gen_brcond_i32(TCG_COND_LT, tmp, tmp2, skip);
 929            break;
 930        case 0x8: /* src == dst */
 931            tcg_gen_brcond_i32(TCG_COND_NE, tmp, tmp2, skip);
 932            break;
 933        case 0x7: /* src != dst */
 934        case 0x6: /* src != dst */
 935            tcg_gen_brcond_i32(TCG_COND_EQ, tmp, tmp2, skip);
 936            break;
 937        case 0x4: /* src < dst */
 938            tcg_gen_brcond_i32(TCG_COND_GE, tmp, tmp2, skip);
 939            break;
 940        case 0x2: /* src > dst */
 941            tcg_gen_brcond_i32(TCG_COND_LE, tmp, tmp2, skip);
 942            break;
 943        default:
 944            tcg_temp_free_i32(tmp);
 945            tcg_temp_free_i32(tmp2);
 946            goto do_dynamic;
 947        }
 948        account_inline_branch(s);
 949        tcg_temp_free_i32(tmp);
 950        tcg_temp_free_i32(tmp2);
 951        break;
 952    case CC_OP_LTGT_64:
 953        switch (mask) {
 954        case 0x8 | 0x4: /* src <= dst */
 955            tcg_gen_brcond_i64(TCG_COND_GT, cc_src, cc_dst, skip);
 956            break;
 957        case 0x8 | 0x2: /* src >= dst */
 958            tcg_gen_brcond_i64(TCG_COND_LT, cc_src, cc_dst, skip);
 959            break;
 960        case 0x8: /* src == dst */
 961            tcg_gen_brcond_i64(TCG_COND_NE, cc_src, cc_dst, skip);
 962            break;
 963        case 0x7: /* src != dst */
 964        case 0x6: /* src != dst */
 965            tcg_gen_brcond_i64(TCG_COND_EQ, cc_src, cc_dst, skip);
 966            break;
 967        case 0x4: /* src < dst */
 968            tcg_gen_brcond_i64(TCG_COND_GE, cc_src, cc_dst, skip);
 969            break;
 970        case 0x2: /* src > dst */
 971            tcg_gen_brcond_i64(TCG_COND_LE, cc_src, cc_dst, skip);
 972            break;
 973        default:
 974            goto do_dynamic;
 975        }
 976        account_inline_branch(s);
 977        break;
 978    case CC_OP_LTUGTU_32:
 979        tmp = tcg_temp_new_i32();
 980        tmp2 = tcg_temp_new_i32();
 981        tcg_gen_trunc_i64_i32(tmp, cc_src);
 982        tcg_gen_trunc_i64_i32(tmp2, cc_dst);
 983        switch (mask) {
 984        case 0x8 | 0x4: /* src <= dst */
 985            tcg_gen_brcond_i32(TCG_COND_GTU, tmp, tmp2, skip);
 986            break;
 987        case 0x8 | 0x2: /* src >= dst */
 988            tcg_gen_brcond_i32(TCG_COND_LTU, tmp, tmp2, skip);
 989            break;
 990        case 0x8: /* src == dst */
 991            tcg_gen_brcond_i32(TCG_COND_NE, tmp, tmp2, skip);
 992            break;
 993        case 0x7: /* src != dst */
 994        case 0x6: /* src != dst */
 995            tcg_gen_brcond_i32(TCG_COND_EQ, tmp, tmp2, skip);
 996            break;
 997        case 0x4: /* src < dst */
 998            tcg_gen_brcond_i32(TCG_COND_GEU, tmp, tmp2, skip);
 999            break;
1000        case 0x2: /* src > dst */
1001            tcg_gen_brcond_i32(TCG_COND_LEU, tmp, tmp2, skip);
1002            break;
1003        default:
1004            tcg_temp_free_i32(tmp);
1005            tcg_temp_free_i32(tmp2);
1006            goto do_dynamic;
1007        }
1008        account_inline_branch(s);
1009        tcg_temp_free_i32(tmp);
1010        tcg_temp_free_i32(tmp2);
1011        break;
1012    case CC_OP_LTUGTU_64:
1013        switch (mask) {
1014        case 0x8 | 0x4: /* src <= dst */
1015            tcg_gen_brcond_i64(TCG_COND_GTU, cc_src, cc_dst, skip);
1016            break;
1017        case 0x8 | 0x2: /* src >= dst */
1018            tcg_gen_brcond_i64(TCG_COND_LTU, cc_src, cc_dst, skip);
1019            break;
1020        case 0x8: /* src == dst */
1021            tcg_gen_brcond_i64(TCG_COND_NE, cc_src, cc_dst, skip);
1022            break;
1023        case 0x7: /* src != dst */
1024        case 0x6: /* src != dst */
1025            tcg_gen_brcond_i64(TCG_COND_EQ, cc_src, cc_dst, skip);
1026            break;
1027        case 0x4: /* src < dst */
1028            tcg_gen_brcond_i64(TCG_COND_GEU, cc_src, cc_dst, skip);
1029            break;
1030        case 0x2: /* src > dst */
1031            tcg_gen_brcond_i64(TCG_COND_LEU, cc_src, cc_dst, skip);
1032            break;
1033        default:
1034            goto do_dynamic;
1035        }
1036        account_inline_branch(s);
1037        break;
1038    case CC_OP_NZ:
1039        switch (mask) {
1040        /* dst == 0 || dst != 0 */
1041        case 0x8 | 0x4:
1042        case 0x8 | 0x4 | 0x2:
1043        case 0x8 | 0x4 | 0x2 | 0x1:
1044        case 0x8 | 0x4 | 0x1:
1045            break;
1046        /* dst == 0 */
1047        case 0x8:
1048        case 0x8 | 0x2:
1049        case 0x8 | 0x2 | 0x1:
1050        case 0x8 | 0x1:
1051            tcg_gen_brcondi_i64(TCG_COND_NE, cc_dst, 0, skip);
1052            break;
1053        /* dst != 0 */
1054        case 0x4:
1055        case 0x4 | 0x2:
1056        case 0x4 | 0x2 | 0x1:
1057        case 0x4 | 0x1:
1058            tcg_gen_brcondi_i64(TCG_COND_EQ, cc_dst, 0, skip);
1059            break;
1060        default:
1061            goto do_dynamic;
1062        }
1063        account_inline_branch(s);
1064        break;
1065    case CC_OP_TM_32:
1066        tmp = tcg_temp_new_i32();
1067        tmp2 = tcg_temp_new_i32();
1068
1069        tcg_gen_trunc_i64_i32(tmp, cc_src);
1070        tcg_gen_trunc_i64_i32(tmp2, cc_dst);
1071        tcg_gen_and_i32(tmp, tmp, tmp2);
1072        switch (mask) {
1073        case 0x8: /* val & mask == 0 */
1074            tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, skip);
1075            break;
1076        case 0x4 | 0x2 | 0x1: /* val & mask != 0 */
1077            tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, skip);
1078            break;
1079        default:
1080            tcg_temp_free_i32(tmp);
1081            tcg_temp_free_i32(tmp2);
1082            goto do_dynamic;
1083        }
1084        tcg_temp_free_i32(tmp);
1085        tcg_temp_free_i32(tmp2);
1086        account_inline_branch(s);
1087        break;
1088    case CC_OP_TM_64:
1089        tmp64 = tcg_temp_new_i64();
1090
1091        tcg_gen_and_i64(tmp64, cc_src, cc_dst);
1092        switch (mask) {
1093        case 0x8: /* val & mask == 0 */
1094            tcg_gen_brcondi_i64(TCG_COND_NE, tmp64, 0, skip);
1095            break;
1096        case 0x4 | 0x2 | 0x1: /* val & mask != 0 */
1097            tcg_gen_brcondi_i64(TCG_COND_EQ, tmp64, 0, skip);
1098            break;
1099        default:
1100            tcg_temp_free_i64(tmp64);
1101            goto do_dynamic;
1102        }
1103        tcg_temp_free_i64(tmp64);
1104        account_inline_branch(s);
1105        break;
1106    case CC_OP_ICM:
1107        switch (mask) {
1108        case 0x8: /* val == 0 */
1109            tcg_gen_brcondi_i64(TCG_COND_NE, cc_dst, 0, skip);
1110            break;
1111        case 0x4 | 0x2 | 0x1: /* val != 0 */
1112        case 0x4 | 0x2: /* val != 0 */
1113            tcg_gen_brcondi_i64(TCG_COND_EQ, cc_dst, 0, skip);
1114            break;
1115        default:
1116            goto do_dynamic;
1117        }
1118        account_inline_branch(s);
1119        break;
1120    case CC_OP_STATIC:
1121        old_cc_op = s->cc_op;
1122        goto do_dynamic_nocccalc;
1123    case CC_OP_DYNAMIC:
1124    default:
1125do_dynamic:
1126        old_cc_op = s->cc_op;
1127        /* calculate cc value */
1128        gen_op_calc_cc(s);
1129
1130do_dynamic_nocccalc:
1131        /* jump based on cc */
1132        account_noninline_branch(s, old_cc_op);
1133
1134        switch (mask) {
1135        case 0x8 | 0x4 | 0x2 | 0x1:
1136            /* always true */
1137            break;
1138        case 0x8 | 0x4 | 0x2: /* cc != 3 */
1139            tcg_gen_brcondi_i32(TCG_COND_EQ, cc_op, 3, skip);
1140            break;
1141        case 0x8 | 0x4 | 0x1: /* cc != 2 */
1142            tcg_gen_brcondi_i32(TCG_COND_EQ, cc_op, 2, skip);
1143            break;
1144        case 0x8 | 0x2 | 0x1: /* cc != 1 */
1145            tcg_gen_brcondi_i32(TCG_COND_EQ, cc_op, 1, skip);
1146            break;
1147        case 0x8 | 0x2: /* cc == 0 || cc == 2 */
1148            tmp = tcg_temp_new_i32();
1149            tcg_gen_andi_i32(tmp, cc_op, 1);
1150            tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, skip);
1151            tcg_temp_free_i32(tmp);
1152            break;
1153        case 0x8 | 0x4: /* cc < 2 */
1154            tcg_gen_brcondi_i32(TCG_COND_GEU, cc_op, 2, skip);
1155            break;
1156        case 0x8: /* cc == 0 */
1157            tcg_gen_brcondi_i32(TCG_COND_NE, cc_op, 0, skip);
1158            break;
1159        case 0x4 | 0x2 | 0x1: /* cc != 0 */
1160            tcg_gen_brcondi_i32(TCG_COND_EQ, cc_op, 0, skip);
1161            break;
1162        case 0x4 | 0x1: /* cc == 1 || cc == 3 */
1163            tmp = tcg_temp_new_i32();
1164            tcg_gen_andi_i32(tmp, cc_op, 1);
1165            tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, skip);
1166            tcg_temp_free_i32(tmp);
1167            break;
1168        case 0x4: /* cc == 1 */
1169            tcg_gen_brcondi_i32(TCG_COND_NE, cc_op, 1, skip);
1170            break;
1171        case 0x2 | 0x1: /* cc > 1 */
1172            tcg_gen_brcondi_i32(TCG_COND_LEU, cc_op, 1, skip);
1173            break;
1174        case 0x2: /* cc == 2 */
1175            tcg_gen_brcondi_i32(TCG_COND_NE, cc_op, 2, skip);
1176            break;
1177        case 0x1: /* cc == 3 */
1178            tcg_gen_brcondi_i32(TCG_COND_NE, cc_op, 3, skip);
1179            break;
1180        default: /* cc is masked by something else */
1181            tmp = tcg_const_i32(3);
1182            /* 3 - cc */
1183            tcg_gen_sub_i32(tmp, tmp, cc_op);
1184            tmp2 = tcg_const_i32(1);
1185            /* 1 << (3 - cc) */
1186            tcg_gen_shl_i32(tmp2, tmp2, tmp);
1187            r = tcg_const_i32(mask);
1188            /* mask & (1 << (3 - cc)) */
1189            tcg_gen_and_i32(r, r, tmp2);
1190            tcg_temp_free_i32(tmp);
1191            tcg_temp_free_i32(tmp2);
1192
1193            tcg_gen_brcondi_i32(TCG_COND_EQ, r, 0, skip);
1194            tcg_temp_free_i32(r);
1195            break;
1196        }
1197        break;
1198    }
1199}
1200
1201static void gen_bcr(DisasContext *s, uint32_t mask, TCGv_i64 target,
1202                    uint64_t offset)
1203{
1204    int skip;
1205
1206    if (mask == 0xf) {
1207        /* unconditional */
1208        tcg_gen_mov_i64(psw_addr, target);
1209        tcg_gen_exit_tb(0);
1210    } else if (mask == 0) {
1211        /* ignore cc and never match */
1212        gen_goto_tb(s, 0, offset + 2);
1213    } else {
1214        TCGv_i64 new_addr = tcg_temp_local_new_i64();
1215
1216        tcg_gen_mov_i64(new_addr, target);
1217        skip = gen_new_label();
1218        gen_jcc(s, mask, skip);
1219        tcg_gen_mov_i64(psw_addr, new_addr);
1220        tcg_temp_free_i64(new_addr);
1221        tcg_gen_exit_tb(0);
1222        gen_set_label(skip);
1223        tcg_temp_free_i64(new_addr);
1224        gen_goto_tb(s, 1, offset + 2);
1225    }
1226}
1227
1228static void gen_brc(uint32_t mask, DisasContext *s, int32_t offset)
1229{
1230    int skip;
1231
1232    if (mask == 0xf) {
1233        /* unconditional */
1234        gen_goto_tb(s, 0, s->pc + offset);
1235    } else if (mask == 0) {
1236        /* ignore cc and never match */
1237        gen_goto_tb(s, 0, s->pc + 4);
1238    } else {
1239        skip = gen_new_label();
1240        gen_jcc(s, mask, skip);
1241        gen_goto_tb(s, 0, s->pc + offset);
1242        gen_set_label(skip);
1243        gen_goto_tb(s, 1, s->pc + 4);
1244    }
1245    s->is_jmp = DISAS_TB_JUMP;
1246}
1247
1248static void gen_op_mvc(DisasContext *s, int l, TCGv_i64 s1, TCGv_i64 s2)
1249{
1250    TCGv_i64 tmp, tmp2;
1251    int i;
1252    int l_memset = gen_new_label();
1253    int l_out = gen_new_label();
1254    TCGv_i64 dest = tcg_temp_local_new_i64();
1255    TCGv_i64 src = tcg_temp_local_new_i64();
1256    TCGv_i32 vl;
1257
1258    /* Find out if we should use the inline version of mvc */
1259    switch (l) {
1260    case 0:
1261    case 1:
1262    case 2:
1263    case 3:
1264    case 4:
1265    case 5:
1266    case 6:
1267    case 7:
1268    case 11:
1269    case 15:
1270        /* use inline */
1271        break;
1272    default:
1273        /* Fall back to helper */
1274        vl = tcg_const_i32(l);
1275        potential_page_fault(s);
1276        gen_helper_mvc(vl, s1, s2);
1277        tcg_temp_free_i32(vl);
1278        return;
1279    }
1280
1281    tcg_gen_mov_i64(dest, s1);
1282    tcg_gen_mov_i64(src, s2);
1283
1284    if (!(s->tb->flags & FLAG_MASK_64)) {
1285        /* XXX what if we overflow while moving? */
1286        tcg_gen_andi_i64(dest, dest, 0x7fffffffUL);
1287        tcg_gen_andi_i64(src, src, 0x7fffffffUL);
1288    }
1289
1290    tmp = tcg_temp_new_i64();
1291    tcg_gen_addi_i64(tmp, src, 1);
1292    tcg_gen_brcond_i64(TCG_COND_EQ, dest, tmp, l_memset);
1293    tcg_temp_free_i64(tmp);
1294
1295    switch (l) {
1296    case 0:
1297        tmp = tcg_temp_new_i64();
1298
1299        tcg_gen_qemu_ld8u(tmp, src, get_mem_index(s));
1300        tcg_gen_qemu_st8(tmp, dest, get_mem_index(s));
1301
1302        tcg_temp_free_i64(tmp);
1303        break;
1304    case 1:
1305        tmp = tcg_temp_new_i64();
1306
1307        tcg_gen_qemu_ld16u(tmp, src, get_mem_index(s));
1308        tcg_gen_qemu_st16(tmp, dest, get_mem_index(s));
1309
1310        tcg_temp_free_i64(tmp);
1311        break;
1312    case 3:
1313        tmp = tcg_temp_new_i64();
1314
1315        tcg_gen_qemu_ld32u(tmp, src, get_mem_index(s));
1316        tcg_gen_qemu_st32(tmp, dest, get_mem_index(s));
1317
1318        tcg_temp_free_i64(tmp);
1319        break;
1320    case 4:
1321        tmp = tcg_temp_new_i64();
1322        tmp2 = tcg_temp_new_i64();
1323
1324        tcg_gen_qemu_ld32u(tmp, src, get_mem_index(s));
1325        tcg_gen_addi_i64(src, src, 4);
1326        tcg_gen_qemu_ld8u(tmp2, src, get_mem_index(s));
1327        tcg_gen_qemu_st32(tmp, dest, get_mem_index(s));
1328        tcg_gen_addi_i64(dest, dest, 4);
1329        tcg_gen_qemu_st8(tmp2, dest, get_mem_index(s));
1330
1331        tcg_temp_free_i64(tmp);
1332        tcg_temp_free_i64(tmp2);
1333        break;
1334    case 7:
1335        tmp = tcg_temp_new_i64();
1336
1337        tcg_gen_qemu_ld64(tmp, src, get_mem_index(s));
1338        tcg_gen_qemu_st64(tmp, dest, get_mem_index(s));
1339
1340        tcg_temp_free_i64(tmp);
1341        break;
1342    default:
1343        /* The inline version can become too big for too uneven numbers, only
1344           use it on known good lengths */
1345        tmp = tcg_temp_new_i64();
1346        tmp2 = tcg_const_i64(8);
1347        for (i = 0; (i + 7) <= l; i += 8) {
1348            tcg_gen_qemu_ld64(tmp, src, get_mem_index(s));
1349            tcg_gen_qemu_st64(tmp, dest, get_mem_index(s));
1350
1351            tcg_gen_add_i64(src, src, tmp2);
1352            tcg_gen_add_i64(dest, dest, tmp2);
1353        }
1354
1355        tcg_temp_free_i64(tmp2);
1356        tmp2 = tcg_const_i64(1);
1357
1358        for (; i <= l; i++) {
1359            tcg_gen_qemu_ld8u(tmp, src, get_mem_index(s));
1360            tcg_gen_qemu_st8(tmp, dest, get_mem_index(s));
1361
1362            tcg_gen_add_i64(src, src, tmp2);
1363            tcg_gen_add_i64(dest, dest, tmp2);
1364        }
1365
1366        tcg_temp_free_i64(tmp2);
1367        tcg_temp_free_i64(tmp);
1368        break;
1369    }
1370
1371    tcg_gen_br(l_out);
1372
1373    gen_set_label(l_memset);
1374    /* memset case (dest == (src + 1)) */
1375
1376    tmp = tcg_temp_new_i64();
1377    tmp2 = tcg_temp_new_i64();
1378    /* fill tmp with the byte */
1379    tcg_gen_qemu_ld8u(tmp, src, get_mem_index(s));
1380    tcg_gen_shli_i64(tmp2, tmp, 8);
1381    tcg_gen_or_i64(tmp, tmp, tmp2);
1382    tcg_gen_shli_i64(tmp2, tmp, 16);
1383    tcg_gen_or_i64(tmp, tmp, tmp2);
1384    tcg_gen_shli_i64(tmp2, tmp, 32);
1385    tcg_gen_or_i64(tmp, tmp, tmp2);
1386    tcg_temp_free_i64(tmp2);
1387
1388    tmp2 = tcg_const_i64(8);
1389
1390    for (i = 0; (i + 7) <= l; i += 8) {
1391        tcg_gen_qemu_st64(tmp, dest, get_mem_index(s));
1392        tcg_gen_addi_i64(dest, dest, 8);
1393    }
1394
1395    tcg_temp_free_i64(tmp2);
1396    tmp2 = tcg_const_i64(1);
1397
1398    for (; i <= l; i++) {
1399        tcg_gen_qemu_st8(tmp, dest, get_mem_index(s));
1400        tcg_gen_addi_i64(dest, dest, 1);
1401    }
1402
1403    tcg_temp_free_i64(tmp2);
1404    tcg_temp_free_i64(tmp);
1405
1406    gen_set_label(l_out);
1407
1408    tcg_temp_free(dest);
1409    tcg_temp_free(src);
1410}
1411
1412static void gen_op_clc(DisasContext *s, int l, TCGv_i64 s1, TCGv_i64 s2)
1413{
1414    TCGv_i64 tmp;
1415    TCGv_i64 tmp2;
1416    TCGv_i32 vl;
1417
1418    /* check for simple 32bit or 64bit match */
1419    switch (l) {
1420    case 0:
1421        tmp = tcg_temp_new_i64();
1422        tmp2 = tcg_temp_new_i64();
1423
1424        tcg_gen_qemu_ld8u(tmp, s1, get_mem_index(s));
1425        tcg_gen_qemu_ld8u(tmp2, s2, get_mem_index(s));
1426        cmp_u64(s, tmp, tmp2);
1427
1428        tcg_temp_free_i64(tmp);
1429        tcg_temp_free_i64(tmp2);
1430        return;
1431    case 1:
1432        tmp = tcg_temp_new_i64();
1433        tmp2 = tcg_temp_new_i64();
1434
1435        tcg_gen_qemu_ld16u(tmp, s1, get_mem_index(s));
1436        tcg_gen_qemu_ld16u(tmp2, s2, get_mem_index(s));
1437        cmp_u64(s, tmp, tmp2);
1438
1439        tcg_temp_free_i64(tmp);
1440        tcg_temp_free_i64(tmp2);
1441        return;
1442    case 3:
1443        tmp = tcg_temp_new_i64();
1444        tmp2 = tcg_temp_new_i64();
1445
1446        tcg_gen_qemu_ld32u(tmp, s1, get_mem_index(s));
1447        tcg_gen_qemu_ld32u(tmp2, s2, get_mem_index(s));
1448        cmp_u64(s, tmp, tmp2);
1449
1450        tcg_temp_free_i64(tmp);
1451        tcg_temp_free_i64(tmp2);
1452        return;
1453    case 7:
1454        tmp = tcg_temp_new_i64();
1455        tmp2 = tcg_temp_new_i64();
1456
1457        tcg_gen_qemu_ld64(tmp, s1, get_mem_index(s));
1458        tcg_gen_qemu_ld64(tmp2, s2, get_mem_index(s));
1459        cmp_u64(s, tmp, tmp2);
1460
1461        tcg_temp_free_i64(tmp);
1462        tcg_temp_free_i64(tmp2);
1463        return;
1464    }
1465
1466    potential_page_fault(s);
1467    vl = tcg_const_i32(l);
1468    gen_helper_clc(cc_op, vl, s1, s2);
1469    tcg_temp_free_i32(vl);
1470    set_cc_static(s);
1471}
1472
1473static void disas_e3(DisasContext* s, int op, int r1, int x2, int b2, int d2)
1474{
1475    TCGv_i64 addr, tmp, tmp2, tmp3, tmp4;
1476    TCGv_i32 tmp32_1, tmp32_2, tmp32_3;
1477
1478    LOG_DISAS("disas_e3: op 0x%x r1 %d x2 %d b2 %d d2 %d\n",
1479              op, r1, x2, b2, d2);
1480    addr = get_address(s, x2, b2, d2);
1481    switch (op) {
1482    case 0x2: /* LTG R1,D2(X2,B2) [RXY] */
1483    case 0x4: /* lg r1,d2(x2,b2) */
1484        tcg_gen_qemu_ld64(regs[r1], addr, get_mem_index(s));
1485        if (op == 0x2) {
1486            set_cc_s64(s, regs[r1]);
1487        }
1488        break;
1489    case 0x12: /* LT R1,D2(X2,B2) [RXY] */
1490        tmp2 = tcg_temp_new_i64();
1491        tmp32_1 = tcg_temp_new_i32();
1492        tcg_gen_qemu_ld32s(tmp2, addr, get_mem_index(s));
1493        tcg_gen_trunc_i64_i32(tmp32_1, tmp2);
1494        store_reg32(r1, tmp32_1);
1495        set_cc_s32(s, tmp32_1);
1496        tcg_temp_free_i64(tmp2);
1497        tcg_temp_free_i32(tmp32_1);
1498        break;
1499    case 0xc: /* MSG      R1,D2(X2,B2)     [RXY] */
1500    case 0x1c: /* MSGF     R1,D2(X2,B2)     [RXY] */
1501        tmp2 = tcg_temp_new_i64();
1502        if (op == 0xc) {
1503            tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
1504        } else {
1505            tcg_gen_qemu_ld32s(tmp2, addr, get_mem_index(s));
1506        }
1507        tcg_gen_mul_i64(regs[r1], regs[r1], tmp2);
1508        tcg_temp_free_i64(tmp2);
1509        break;
1510    case 0xd: /* DSG      R1,D2(X2,B2)     [RXY] */
1511    case 0x1d: /* DSGF      R1,D2(X2,B2)     [RXY] */
1512        tmp2 = tcg_temp_new_i64();
1513        if (op == 0x1d) {
1514            tcg_gen_qemu_ld32s(tmp2, addr, get_mem_index(s));
1515        } else {
1516            tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
1517        }
1518        tmp4 = load_reg(r1 + 1);
1519        tmp3 = tcg_temp_new_i64();
1520        tcg_gen_div_i64(tmp3, tmp4, tmp2);
1521        store_reg(r1 + 1, tmp3);
1522        tcg_gen_rem_i64(tmp3, tmp4, tmp2);
1523        store_reg(r1, tmp3);
1524        tcg_temp_free_i64(tmp2);
1525        tcg_temp_free_i64(tmp3);
1526        tcg_temp_free_i64(tmp4);
1527        break;
1528    case 0x8: /* AG      R1,D2(X2,B2)     [RXY] */
1529    case 0xa: /* ALG      R1,D2(X2,B2)     [RXY] */
1530    case 0x18: /* AGF       R1,D2(X2,B2)     [RXY] */
1531    case 0x1a: /* ALGF      R1,D2(X2,B2)     [RXY] */
1532        if (op == 0x1a) {
1533            tmp2 = tcg_temp_new_i64();
1534            tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s));
1535        } else if (op == 0x18) {
1536            tmp2 = tcg_temp_new_i64();
1537            tcg_gen_qemu_ld32s(tmp2, addr, get_mem_index(s));
1538        } else {
1539            tmp2 = tcg_temp_new_i64();
1540            tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
1541        }
1542        tmp4 = load_reg(r1);
1543        tmp3 = tcg_temp_new_i64();
1544        tcg_gen_add_i64(tmp3, tmp4, tmp2);
1545        store_reg(r1, tmp3);
1546        switch (op) {
1547        case 0x8:
1548        case 0x18:
1549            set_cc_add64(s, tmp4, tmp2, tmp3);
1550            break;
1551        case 0xa:
1552        case 0x1a:
1553            set_cc_addu64(s, tmp4, tmp2, tmp3);
1554            break;
1555        default:
1556            tcg_abort();
1557        }
1558        tcg_temp_free_i64(tmp2);
1559        tcg_temp_free_i64(tmp3);
1560        tcg_temp_free_i64(tmp4);
1561        break;
1562    case 0x9: /* SG      R1,D2(X2,B2)     [RXY] */
1563    case 0xb: /* SLG      R1,D2(X2,B2)     [RXY] */
1564    case 0x19: /* SGF      R1,D2(X2,B2)     [RXY] */
1565    case 0x1b: /* SLGF     R1,D2(X2,B2)     [RXY] */
1566        tmp2 = tcg_temp_new_i64();
1567        if (op == 0x19) {
1568            tcg_gen_qemu_ld32s(tmp2, addr, get_mem_index(s));
1569        } else if (op == 0x1b) {
1570            tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s));
1571        } else {
1572            tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
1573        }
1574        tmp4 = load_reg(r1);
1575        tmp3 = tcg_temp_new_i64();
1576        tcg_gen_sub_i64(tmp3, tmp4, tmp2);
1577        store_reg(r1, tmp3);
1578        switch (op) {
1579        case 0x9:
1580        case 0x19:
1581            set_cc_sub64(s, tmp4, tmp2, tmp3);
1582            break;
1583        case 0xb:
1584        case 0x1b:
1585            set_cc_subu64(s, tmp4, tmp2, tmp3);
1586            break;
1587        default:
1588            tcg_abort();
1589        }
1590        tcg_temp_free_i64(tmp2);
1591        tcg_temp_free_i64(tmp3);
1592        tcg_temp_free_i64(tmp4);
1593        break;
1594    case 0xf: /* LRVG     R1,D2(X2,B2)     [RXE] */
1595        tmp2 = tcg_temp_new_i64();
1596        tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
1597        tcg_gen_bswap64_i64(tmp2, tmp2);
1598        store_reg(r1, tmp2);
1599        tcg_temp_free_i64(tmp2);
1600        break;
1601    case 0x14: /* LGF      R1,D2(X2,B2)     [RXY] */
1602    case 0x16: /* LLGF      R1,D2(X2,B2)     [RXY] */
1603        tmp2 = tcg_temp_new_i64();
1604        tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s));
1605        if (op == 0x14) {
1606            tcg_gen_ext32s_i64(tmp2, tmp2);
1607        }
1608        store_reg(r1, tmp2);
1609        tcg_temp_free_i64(tmp2);
1610        break;
1611    case 0x15: /* LGH     R1,D2(X2,B2)     [RXY] */
1612        tmp2 = tcg_temp_new_i64();
1613        tcg_gen_qemu_ld16s(tmp2, addr, get_mem_index(s));
1614        store_reg(r1, tmp2);
1615        tcg_temp_free_i64(tmp2);
1616        break;
1617    case 0x17: /* LLGT      R1,D2(X2,B2)     [RXY] */
1618        tmp2 = tcg_temp_new_i64();
1619        tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s));
1620        tcg_gen_andi_i64(tmp2, tmp2, 0x7fffffffULL);
1621        store_reg(r1, tmp2);
1622        tcg_temp_free_i64(tmp2);
1623        break;
1624    case 0x1e: /* LRV R1,D2(X2,B2) [RXY] */
1625        tmp2 = tcg_temp_new_i64();
1626        tmp32_1 = tcg_temp_new_i32();
1627        tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s));
1628        tcg_gen_trunc_i64_i32(tmp32_1, tmp2);
1629        tcg_temp_free_i64(tmp2);
1630        tcg_gen_bswap32_i32(tmp32_1, tmp32_1);
1631        store_reg32(r1, tmp32_1);
1632        tcg_temp_free_i32(tmp32_1);
1633        break;
1634    case 0x1f: /* LRVH R1,D2(X2,B2) [RXY] */
1635        tmp2 = tcg_temp_new_i64();
1636        tmp32_1 = tcg_temp_new_i32();
1637        tcg_gen_qemu_ld16u(tmp2, addr, get_mem_index(s));
1638        tcg_gen_trunc_i64_i32(tmp32_1, tmp2);
1639        tcg_temp_free_i64(tmp2);
1640        tcg_gen_bswap16_i32(tmp32_1, tmp32_1);
1641        store_reg16(r1, tmp32_1);
1642        tcg_temp_free_i32(tmp32_1);
1643        break;
1644    case 0x20: /* CG      R1,D2(X2,B2)     [RXY] */
1645    case 0x21: /* CLG      R1,D2(X2,B2) */
1646    case 0x30: /* CGF       R1,D2(X2,B2)     [RXY] */
1647    case 0x31: /* CLGF      R1,D2(X2,B2)     [RXY] */
1648        tmp2 = tcg_temp_new_i64();
1649        switch (op) {
1650        case 0x20:
1651        case 0x21:
1652            tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
1653            break;
1654        case 0x30:
1655            tcg_gen_qemu_ld32s(tmp2, addr, get_mem_index(s));
1656            break;
1657        case 0x31:
1658            tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s));
1659            break;
1660        default:
1661            tcg_abort();
1662        }
1663        switch (op) {
1664        case 0x20:
1665        case 0x30:
1666            cmp_s64(s, regs[r1], tmp2);
1667            break;
1668        case 0x21:
1669        case 0x31:
1670            cmp_u64(s, regs[r1], tmp2);
1671            break;
1672        default:
1673            tcg_abort();
1674        }
1675        tcg_temp_free_i64(tmp2);
1676        break;
1677    case 0x24: /* stg r1, d2(x2,b2) */
1678        tcg_gen_qemu_st64(regs[r1], addr, get_mem_index(s));
1679        break;
1680    case 0x3e: /* STRV R1,D2(X2,B2) [RXY] */
1681        tmp32_1 = load_reg32(r1);
1682        tmp2 = tcg_temp_new_i64();
1683        tcg_gen_bswap32_i32(tmp32_1, tmp32_1);
1684        tcg_gen_extu_i32_i64(tmp2, tmp32_1);
1685        tcg_temp_free_i32(tmp32_1);
1686        tcg_gen_qemu_st32(tmp2, addr, get_mem_index(s));
1687        tcg_temp_free_i64(tmp2);
1688        break;
1689    case 0x50: /* STY  R1,D2(X2,B2) [RXY] */
1690        tmp32_1 = load_reg32(r1);
1691        tmp2 = tcg_temp_new_i64();
1692        tcg_gen_extu_i32_i64(tmp2, tmp32_1);
1693        tcg_temp_free_i32(tmp32_1);
1694        tcg_gen_qemu_st32(tmp2, addr, get_mem_index(s));
1695        tcg_temp_free_i64(tmp2);
1696        break;
1697    case 0x57: /* XY R1,D2(X2,B2) [RXY] */
1698        tmp32_1 = load_reg32(r1);
1699        tmp32_2 = tcg_temp_new_i32();
1700        tmp2 = tcg_temp_new_i64();
1701        tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s));
1702        tcg_gen_trunc_i64_i32(tmp32_2, tmp2);
1703        tcg_temp_free_i64(tmp2);
1704        tcg_gen_xor_i32(tmp32_2, tmp32_1, tmp32_2);
1705        store_reg32(r1, tmp32_2);
1706        set_cc_nz_u32(s, tmp32_2);
1707        tcg_temp_free_i32(tmp32_1);
1708        tcg_temp_free_i32(tmp32_2);
1709        break;
1710    case 0x58: /* LY R1,D2(X2,B2) [RXY] */
1711        tmp3 = tcg_temp_new_i64();
1712        tcg_gen_qemu_ld32u(tmp3, addr, get_mem_index(s));
1713        store_reg32_i64(r1, tmp3);
1714        tcg_temp_free_i64(tmp3);
1715        break;
1716    case 0x5a: /* AY R1,D2(X2,B2) [RXY] */
1717    case 0x5b: /* SY R1,D2(X2,B2) [RXY] */
1718        tmp32_1 = load_reg32(r1);
1719        tmp32_2 = tcg_temp_new_i32();
1720        tmp32_3 = tcg_temp_new_i32();
1721        tmp2 = tcg_temp_new_i64();
1722        tcg_gen_qemu_ld32s(tmp2, addr, get_mem_index(s));
1723        tcg_gen_trunc_i64_i32(tmp32_2, tmp2);
1724        tcg_temp_free_i64(tmp2);
1725        switch (op) {
1726        case 0x5a:
1727            tcg_gen_add_i32(tmp32_3, tmp32_1, tmp32_2);
1728            break;
1729        case 0x5b:
1730            tcg_gen_sub_i32(tmp32_3, tmp32_1, tmp32_2);
1731            break;
1732        default:
1733            tcg_abort();
1734        }
1735        store_reg32(r1, tmp32_3);
1736        switch (op) {
1737        case 0x5a:
1738            set_cc_add32(s, tmp32_1, tmp32_2, tmp32_3);
1739            break;
1740        case 0x5b:
1741            set_cc_sub32(s, tmp32_1, tmp32_2, tmp32_3);
1742            break;
1743        default:
1744            tcg_abort();
1745        }
1746        tcg_temp_free_i32(tmp32_1);
1747        tcg_temp_free_i32(tmp32_2);
1748        tcg_temp_free_i32(tmp32_3);
1749        break;
1750    case 0x71: /* LAY R1,D2(X2,B2) [RXY] */
1751        store_reg(r1, addr);
1752        break;
1753    case 0x72: /* STCY R1,D2(X2,B2) [RXY] */
1754        tmp32_1 = load_reg32(r1);
1755        tmp2 = tcg_temp_new_i64();
1756        tcg_gen_ext_i32_i64(tmp2, tmp32_1);
1757        tcg_gen_qemu_st8(tmp2, addr, get_mem_index(s));
1758        tcg_temp_free_i32(tmp32_1);
1759        tcg_temp_free_i64(tmp2);
1760        break;
1761    case 0x73: /* ICY R1,D2(X2,B2) [RXY] */
1762        tmp3 = tcg_temp_new_i64();
1763        tcg_gen_qemu_ld8u(tmp3, addr, get_mem_index(s));
1764        store_reg8(r1, tmp3);
1765        tcg_temp_free_i64(tmp3);
1766        break;
1767    case 0x76: /* LB R1,D2(X2,B2) [RXY] */
1768    case 0x77: /* LGB R1,D2(X2,B2) [RXY] */
1769        tmp2 = tcg_temp_new_i64();
1770        tcg_gen_qemu_ld8s(tmp2, addr, get_mem_index(s));
1771        switch (op) {
1772        case 0x76:
1773            tcg_gen_ext8s_i64(tmp2, tmp2);
1774            store_reg32_i64(r1, tmp2);
1775            break;
1776        case 0x77:
1777            tcg_gen_ext8s_i64(tmp2, tmp2);
1778            store_reg(r1, tmp2);
1779            break;
1780        default:
1781            tcg_abort();
1782        }
1783        tcg_temp_free_i64(tmp2);
1784        break;
1785    case 0x78: /* LHY R1,D2(X2,B2) [RXY] */
1786        tmp2 = tcg_temp_new_i64();
1787        tcg_gen_qemu_ld16s(tmp2, addr, get_mem_index(s));
1788        store_reg32_i64(r1, tmp2);
1789        tcg_temp_free_i64(tmp2);
1790        break;
1791    case 0x80: /* NG      R1,D2(X2,B2)     [RXY] */
1792    case 0x81: /* OG      R1,D2(X2,B2)     [RXY] */
1793    case 0x82: /* XG      R1,D2(X2,B2)     [RXY] */
1794        tmp3 = tcg_temp_new_i64();
1795        tcg_gen_qemu_ld64(tmp3, addr, get_mem_index(s));
1796        switch (op) {
1797        case 0x80:
1798            tcg_gen_and_i64(regs[r1], regs[r1], tmp3);
1799            break;
1800        case 0x81:
1801            tcg_gen_or_i64(regs[r1], regs[r1], tmp3);
1802            break;
1803        case 0x82:
1804            tcg_gen_xor_i64(regs[r1], regs[r1], tmp3);
1805            break;
1806        default:
1807            tcg_abort();
1808        }
1809        set_cc_nz_u64(s, regs[r1]);
1810        tcg_temp_free_i64(tmp3);
1811        break;
1812    case 0x86: /* MLG      R1,D2(X2,B2)     [RXY] */
1813        tmp2 = tcg_temp_new_i64();
1814        tmp32_1 = tcg_const_i32(r1);
1815        tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
1816        gen_helper_mlg(tmp32_1, tmp2);
1817        tcg_temp_free_i64(tmp2);
1818        tcg_temp_free_i32(tmp32_1);
1819        break;
1820    case 0x87: /* DLG      R1,D2(X2,B2)     [RXY] */
1821        tmp2 = tcg_temp_new_i64();
1822        tmp32_1 = tcg_const_i32(r1);
1823        tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
1824        gen_helper_dlg(tmp32_1, tmp2);
1825        tcg_temp_free_i64(tmp2);
1826        tcg_temp_free_i32(tmp32_1);
1827        break;
1828    case 0x88: /* ALCG      R1,D2(X2,B2)     [RXY] */
1829        tmp2 = tcg_temp_new_i64();
1830        tmp3 = tcg_temp_new_i64();
1831        tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
1832        /* XXX possible optimization point */
1833        gen_op_calc_cc(s);
1834        tcg_gen_extu_i32_i64(tmp3, cc_op);
1835        tcg_gen_shri_i64(tmp3, tmp3, 1);
1836        tcg_gen_andi_i64(tmp3, tmp3, 1);
1837        tcg_gen_add_i64(tmp3, tmp2, tmp3);
1838        tcg_gen_add_i64(tmp3, regs[r1], tmp3);
1839        store_reg(r1, tmp3);
1840        set_cc_addu64(s, regs[r1], tmp2, tmp3);
1841        tcg_temp_free_i64(tmp2);
1842        tcg_temp_free_i64(tmp3);
1843        break;
1844    case 0x89: /* SLBG      R1,D2(X2,B2)     [RXY] */
1845        tmp2 = tcg_temp_new_i64();
1846        tmp32_1 = tcg_const_i32(r1);
1847        tcg_gen_qemu_ld64(tmp2, addr, get_mem_index(s));
1848        /* XXX possible optimization point */
1849        gen_op_calc_cc(s);
1850        gen_helper_slbg(cc_op, cc_op, tmp32_1, regs[r1], tmp2);
1851        set_cc_static(s);
1852        tcg_temp_free_i64(tmp2);
1853        tcg_temp_free_i32(tmp32_1);
1854        break;
1855    case 0x90: /* LLGC      R1,D2(X2,B2)     [RXY] */
1856        tcg_gen_qemu_ld8u(regs[r1], addr, get_mem_index(s));
1857        break;
1858    case 0x91: /* LLGH      R1,D2(X2,B2)     [RXY] */
1859        tcg_gen_qemu_ld16u(regs[r1], addr, get_mem_index(s));
1860        break;
1861    case 0x94: /* LLC     R1,D2(X2,B2)     [RXY] */
1862        tmp2 = tcg_temp_new_i64();
1863        tcg_gen_qemu_ld8u(tmp2, addr, get_mem_index(s));
1864        store_reg32_i64(r1, tmp2);
1865        tcg_temp_free_i64(tmp2);
1866        break;
1867    case 0x95: /* LLH     R1,D2(X2,B2)     [RXY] */
1868        tmp2 = tcg_temp_new_i64();
1869        tcg_gen_qemu_ld16u(tmp2, addr, get_mem_index(s));
1870        store_reg32_i64(r1, tmp2);
1871        tcg_temp_free_i64(tmp2);
1872        break;
1873    case 0x96: /* ML      R1,D2(X2,B2)     [RXY] */
1874        tmp2 = tcg_temp_new_i64();
1875        tmp3 = load_reg((r1 + 1) & 15);
1876        tcg_gen_ext32u_i64(tmp3, tmp3);
1877        tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s));
1878        tcg_gen_mul_i64(tmp2, tmp2, tmp3);
1879        store_reg32_i64((r1 + 1) & 15, tmp2);
1880        tcg_gen_shri_i64(tmp2, tmp2, 32);
1881        store_reg32_i64(r1, tmp2);
1882        tcg_temp_free_i64(tmp2);
1883        tcg_temp_free_i64(tmp3);
1884        break;
1885    case 0x97: /* DL     R1,D2(X2,B2)     [RXY] */
1886        /* reg(r1) = reg(r1, r1+1) % ld32(addr) */
1887        /* reg(r1+1) = reg(r1, r1+1) / ld32(addr) */
1888        tmp = load_reg(r1);
1889        tmp2 = tcg_temp_new_i64();
1890        tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s));
1891        tmp3 = load_reg((r1 + 1) & 15);
1892        tcg_gen_ext32u_i64(tmp2, tmp2);
1893        tcg_gen_ext32u_i64(tmp3, tmp3);
1894        tcg_gen_shli_i64(tmp, tmp, 32);
1895        tcg_gen_or_i64(tmp, tmp, tmp3);
1896
1897        tcg_gen_rem_i64(tmp3, tmp, tmp2);
1898        tcg_gen_div_i64(tmp, tmp, tmp2);
1899        store_reg32_i64((r1 + 1) & 15, tmp);
1900        store_reg32_i64(r1, tmp3);
1901        tcg_temp_free_i64(tmp);
1902        tcg_temp_free_i64(tmp2);
1903        tcg_temp_free_i64(tmp3);
1904        break;
1905    case 0x98: /* ALC     R1,D2(X2,B2)     [RXY] */
1906        tmp2 = tcg_temp_new_i64();
1907        tmp32_1 = load_reg32(r1);
1908        tmp32_2 = tcg_temp_new_i32();
1909        tmp32_3 = tcg_temp_new_i32();
1910        tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s));
1911        tcg_gen_trunc_i64_i32(tmp32_2, tmp2);
1912        /* XXX possible optimization point */
1913        gen_op_calc_cc(s);
1914        gen_helper_addc_u32(tmp32_3, cc_op, tmp32_1, tmp32_2);
1915        set_cc_addu32(s, tmp32_1, tmp32_2, tmp32_3);
1916        store_reg32(r1, tmp32_3);
1917        tcg_temp_free_i64(tmp2);
1918        tcg_temp_free_i32(tmp32_1);
1919        tcg_temp_free_i32(tmp32_2);
1920        tcg_temp_free_i32(tmp32_3);
1921        break;
1922    case 0x99: /* SLB     R1,D2(X2,B2)     [RXY] */
1923        tmp2 = tcg_temp_new_i64();
1924        tmp32_1 = tcg_const_i32(r1);
1925        tmp32_2 = tcg_temp_new_i32();
1926        tcg_gen_qemu_ld32u(tmp2, addr, get_mem_index(s));
1927        tcg_gen_trunc_i64_i32(tmp32_2, tmp2);
1928        /* XXX possible optimization point */
1929        gen_op_calc_cc(s);
1930        gen_helper_slb(cc_op, cc_op, tmp32_1, tmp32_2);
1931        set_cc_static(s);
1932        tcg_temp_free_i64(tmp2);
1933        tcg_temp_free_i32(tmp32_1);
1934        tcg_temp_free_i32(tmp32_2);
1935        break;
1936    default:
1937        LOG_DISAS("illegal e3 operation 0x%x\n", op);
1938        gen_illegal_opcode(s, 3);
1939        break;
1940    }
1941    tcg_temp_free_i64(addr);
1942}
1943
1944#ifndef CONFIG_USER_ONLY
1945static void disas_e5(DisasContext* s, uint64_t insn)
1946{
1947    TCGv_i64 tmp, tmp2;
1948    int op = (insn >> 32) & 0xff;
1949
1950    tmp = get_address(s, 0, (insn >> 28) & 0xf, (insn >> 16) & 0xfff);
1951    tmp2 = get_address(s, 0, (insn >> 12) & 0xf, insn & 0xfff);
1952
1953    LOG_DISAS("disas_e5: insn %" PRIx64 "\n", insn);
1954    switch (op) {
1955    case 0x01: /* TPROT    D1(B1),D2(B2)  [SSE] */
1956        /* Test Protection */
1957        potential_page_fault(s);
1958        gen_helper_tprot(cc_op, tmp, tmp2);
1959        set_cc_static(s);
1960        break;
1961    default:
1962        LOG_DISAS("illegal e5 operation 0x%x\n", op);
1963        gen_illegal_opcode(s, 3);
1964        break;
1965    }
1966
1967    tcg_temp_free_i64(tmp);
1968    tcg_temp_free_i64(tmp2);
1969}
1970#endif
1971
1972static void disas_eb(DisasContext *s, int op, int r1, int r3, int b2, int d2)
1973{
1974    TCGv_i64 tmp, tmp2, tmp3, tmp4;
1975    TCGv_i32 tmp32_1, tmp32_2;
1976    int i, stm_len;
1977    int ilc = 3;
1978
1979    LOG_DISAS("disas_eb: op 0x%x r1 %d r3 %d b2 %d d2 0x%x\n",
1980              op, r1, r3, b2, d2);
1981    switch (op) {
1982    case 0xc: /* SRLG     R1,R3,D2(B2)     [RSY] */
1983    case 0xd: /* SLLG     R1,R3,D2(B2)     [RSY] */
1984    case 0xa: /* SRAG     R1,R3,D2(B2)     [RSY] */
1985    case 0xb: /* SLAG     R1,R3,D2(B2)     [RSY] */
1986    case 0x1c: /* RLLG     R1,R3,D2(B2)     [RSY] */
1987        if (b2) {
1988            tmp = get_address(s, 0, b2, d2);
1989            tcg_gen_andi_i64(tmp, tmp, 0x3f);
1990        } else {
1991            tmp = tcg_const_i64(d2 & 0x3f);
1992        }
1993        switch (op) {
1994        case 0xc:
1995            tcg_gen_shr_i64(regs[r1], regs[r3], tmp);
1996            break;
1997        case 0xd:
1998            tcg_gen_shl_i64(regs[r1], regs[r3], tmp);
1999            break;
2000        case 0xa:
2001            tcg_gen_sar_i64(regs[r1], regs[r3], tmp);
2002            break;
2003        case 0xb:
2004            tmp2 = tcg_temp_new_i64();
2005            tmp3 = tcg_temp_new_i64();
2006            gen_op_update2_cc_i64(s, CC_OP_SLAG, regs[r3], tmp);
2007            tcg_gen_shl_i64(tmp2, regs[r3], tmp);
2008            /* override sign bit with source sign */
2009            tcg_gen_andi_i64(tmp2, tmp2, ~0x8000000000000000ULL);
2010            tcg_gen_andi_i64(tmp3, regs[r3], 0x8000000000000000ULL);
2011            tcg_gen_or_i64(regs[r1], tmp2, tmp3);
2012            tcg_temp_free_i64(tmp2);
2013            tcg_temp_free_i64(tmp3);
2014            break;
2015        case 0x1c:
2016            tcg_gen_rotl_i64(regs[r1], regs[r3], tmp);
2017            break;
2018        default:
2019            tcg_abort();
2020            break;
2021        }
2022        if (op == 0xa) {
2023            set_cc_s64(s, regs[r1]);
2024        }
2025        tcg_temp_free_i64(tmp);
2026        break;
2027    case 0x1d: /* RLL    R1,R3,D2(B2)        [RSY] */
2028        if (b2) {
2029            tmp = get_address(s, 0, b2, d2);
2030            tcg_gen_andi_i64(tmp, tmp, 0x3f);
2031        } else {
2032            tmp = tcg_const_i64(d2 & 0x3f);
2033        }
2034        tmp32_1 = tcg_temp_new_i32();
2035        tmp32_2 = load_reg32(r3);
2036        tcg_gen_trunc_i64_i32(tmp32_1, tmp);
2037        switch (op) {
2038        case 0x1d:
2039            tcg_gen_rotl_i32(tmp32_1, tmp32_2, tmp32_1);
2040            break;
2041        default:
2042            tcg_abort();
2043            break;
2044        }
2045        store_reg32(r1, tmp32_1);
2046        tcg_temp_free_i64(tmp);
2047        tcg_temp_free_i32(tmp32_1);
2048        tcg_temp_free_i32(tmp32_2);
2049        break;
2050    case 0x4:  /* LMG      R1,R3,D2(B2)     [RSE] */
2051    case 0x24: /* STMG     R1,R3,D2(B2)     [RSE] */
2052        stm_len = 8;
2053        goto do_mh;
2054    case 0x26: /* STMH     R1,R3,D2(B2)     [RSE] */
2055    case 0x96: /* LMH      R1,R3,D2(B2)     [RSE] */
2056        stm_len = 4;
2057do_mh:
2058        /* Apparently, unrolling lmg/stmg of any size gains performance -
2059           even for very long ones... */
2060        tmp = get_address(s, 0, b2, d2);
2061        tmp3 = tcg_const_i64(stm_len);
2062        tmp4 = tcg_const_i64(op == 0x26 ? 32 : 4);
2063        for (i = r1;; i = (i + 1) % 16) {
2064            switch (op) {
2065            case 0x4:
2066                tcg_gen_qemu_ld64(regs[i], tmp, get_mem_index(s));
2067                break;
2068            case 0x96:
2069                tmp2 = tcg_temp_new_i64();
2070#if HOST_LONG_BITS == 32
2071                tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
2072                tcg_gen_trunc_i64_i32(TCGV_HIGH(regs[i]), tmp2);
2073#else
2074                tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
2075                tcg_gen_shl_i64(tmp2, tmp2, tmp4);
2076                tcg_gen_ext32u_i64(regs[i], regs[i]);
2077                tcg_gen_or_i64(regs[i], regs[i], tmp2);
2078#endif
2079                tcg_temp_free_i64(tmp2);
2080                break;
2081            case 0x24:
2082                tcg_gen_qemu_st64(regs[i], tmp, get_mem_index(s));
2083                break;
2084            case 0x26:
2085                tmp2 = tcg_temp_new_i64();
2086                tcg_gen_shr_i64(tmp2, regs[i], tmp4);
2087                tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s));
2088                tcg_temp_free_i64(tmp2);
2089                break;
2090            default:
2091                tcg_abort();
2092            }
2093            if (i == r3) {
2094                break;
2095            }
2096            tcg_gen_add_i64(tmp, tmp, tmp3);
2097        }
2098        tcg_temp_free_i64(tmp);
2099        tcg_temp_free_i64(tmp3);
2100        tcg_temp_free_i64(tmp4);
2101        break;
2102    case 0x2c: /* STCMH R1,M3,D2(B2) [RSY] */
2103        tmp = get_address(s, 0, b2, d2);
2104        tmp32_1 = tcg_const_i32(r1);
2105        tmp32_2 = tcg_const_i32(r3);
2106        potential_page_fault(s);
2107        gen_helper_stcmh(tmp32_1, tmp, tmp32_2);
2108        tcg_temp_free_i64(tmp);
2109        tcg_temp_free_i32(tmp32_1);
2110        tcg_temp_free_i32(tmp32_2);
2111        break;
2112#ifndef CONFIG_USER_ONLY
2113    case 0x2f: /* LCTLG     R1,R3,D2(B2)     [RSE] */
2114        /* Load Control */
2115        check_privileged(s, ilc);
2116        tmp = get_address(s, 0, b2, d2);
2117        tmp32_1 = tcg_const_i32(r1);
2118        tmp32_2 = tcg_const_i32(r3);
2119        potential_page_fault(s);
2120        gen_helper_lctlg(tmp32_1, tmp, tmp32_2);
2121        tcg_temp_free_i64(tmp);
2122        tcg_temp_free_i32(tmp32_1);
2123        tcg_temp_free_i32(tmp32_2);
2124        break;
2125    case 0x25: /* STCTG     R1,R3,D2(B2)     [RSE] */
2126        /* Store Control */
2127        check_privileged(s, ilc);
2128        tmp = get_address(s, 0, b2, d2);
2129        tmp32_1 = tcg_const_i32(r1);
2130        tmp32_2 = tcg_const_i32(r3);
2131        potential_page_fault(s);
2132        gen_helper_stctg(tmp32_1, tmp, tmp32_2);
2133        tcg_temp_free_i64(tmp);
2134        tcg_temp_free_i32(tmp32_1);
2135        tcg_temp_free_i32(tmp32_2);
2136        break;
2137#endif
2138    case 0x30: /* CSG     R1,R3,D2(B2)     [RSY] */
2139        tmp = get_address(s, 0, b2, d2);
2140        tmp32_1 = tcg_const_i32(r1);
2141        tmp32_2 = tcg_const_i32(r3);
2142        potential_page_fault(s);
2143        /* XXX rewrite in tcg */
2144        gen_helper_csg(cc_op, tmp32_1, tmp, tmp32_2);
2145        set_cc_static(s);
2146        tcg_temp_free_i64(tmp);
2147        tcg_temp_free_i32(tmp32_1);
2148        tcg_temp_free_i32(tmp32_2);
2149        break;
2150    case 0x3e: /* CDSG R1,R3,D2(B2) [RSY] */
2151        tmp = get_address(s, 0, b2, d2);
2152        tmp32_1 = tcg_const_i32(r1);
2153        tmp32_2 = tcg_const_i32(r3);
2154        potential_page_fault(s);
2155        /* XXX rewrite in tcg */
2156        gen_helper_cdsg(cc_op, tmp32_1, tmp, tmp32_2);
2157        set_cc_static(s);
2158        tcg_temp_free_i64(tmp);
2159        tcg_temp_free_i32(tmp32_1);
2160        tcg_temp_free_i32(tmp32_2);
2161        break;
2162    case 0x51: /* TMY D1(B1),I2 [SIY] */
2163        tmp = get_address(s, 0, b2, d2); /* SIY -> this is the destination */
2164        tmp2 = tcg_const_i64((r1 << 4) | r3);
2165        tcg_gen_qemu_ld8u(tmp, tmp, get_mem_index(s));
2166        /* yes, this is a 32 bit operation with 64 bit tcg registers, because
2167           that incurs less conversions */
2168        cmp_64(s, tmp, tmp2, CC_OP_TM_32);
2169        tcg_temp_free_i64(tmp);
2170        tcg_temp_free_i64(tmp2);
2171        break;
2172    case 0x52: /* MVIY D1(B1),I2 [SIY] */
2173        tmp = get_address(s, 0, b2, d2); /* SIY -> this is the destination */
2174        tmp2 = tcg_const_i64((r1 << 4) | r3);
2175        tcg_gen_qemu_st8(tmp2, tmp, get_mem_index(s));
2176        tcg_temp_free_i64(tmp);
2177        tcg_temp_free_i64(tmp2);
2178        break;
2179    case 0x55: /* CLIY D1(B1),I2 [SIY] */
2180        tmp3 = get_address(s, 0, b2, d2); /* SIY -> this is the 1st operand */
2181        tmp = tcg_temp_new_i64();
2182        tmp32_1 = tcg_temp_new_i32();
2183        tcg_gen_qemu_ld8u(tmp, tmp3, get_mem_index(s));
2184        tcg_gen_trunc_i64_i32(tmp32_1, tmp);
2185        cmp_u32c(s, tmp32_1, (r1 << 4) | r3);
2186        tcg_temp_free_i64(tmp);
2187        tcg_temp_free_i64(tmp3);
2188        tcg_temp_free_i32(tmp32_1);
2189        break;
2190    case 0x80: /* ICMH      R1,M3,D2(B2)     [RSY] */
2191        tmp = get_address(s, 0, b2, d2);
2192        tmp32_1 = tcg_const_i32(r1);
2193        tmp32_2 = tcg_const_i32(r3);
2194        potential_page_fault(s);
2195        /* XXX split CC calculation out */
2196        gen_helper_icmh(cc_op, tmp32_1, tmp, tmp32_2);
2197        set_cc_static(s);
2198        tcg_temp_free_i64(tmp);
2199        tcg_temp_free_i32(tmp32_1);
2200        tcg_temp_free_i32(tmp32_2);
2201        break;
2202    default:
2203        LOG_DISAS("illegal eb operation 0x%x\n", op);
2204        gen_illegal_opcode(s, ilc);
2205        break;
2206    }
2207}
2208
2209static void disas_ed(DisasContext *s, int op, int r1, int x2, int b2, int d2,
2210                     int r1b)
2211{
2212    TCGv_i32 tmp_r1, tmp32;
2213    TCGv_i64 addr, tmp;
2214    addr = get_address(s, x2, b2, d2);
2215    tmp_r1 = tcg_const_i32(r1);
2216    switch (op) {
2217    case 0x5: /* LXDB R1,D2(X2,B2) [RXE] */
2218        potential_page_fault(s);
2219        gen_helper_lxdb(tmp_r1, addr);
2220        break;
2221    case 0x9: /* CEB    R1,D2(X2,B2)       [RXE] */
2222        tmp = tcg_temp_new_i64();
2223        tmp32 = load_freg32(r1);
2224        tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s));
2225        set_cc_cmp_f32_i64(s, tmp32, tmp);
2226        tcg_temp_free_i64(tmp);
2227        tcg_temp_free_i32(tmp32);
2228        break;
2229    case 0xa: /* AEB    R1,D2(X2,B2)       [RXE] */
2230        tmp = tcg_temp_new_i64();
2231        tmp32 = tcg_temp_new_i32();
2232        tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s));
2233        tcg_gen_trunc_i64_i32(tmp32, tmp);
2234        gen_helper_aeb(tmp_r1, tmp32);
2235        tcg_temp_free_i64(tmp);
2236        tcg_temp_free_i32(tmp32);
2237
2238        tmp32 = load_freg32(r1);
2239        set_cc_nz_f32(s, tmp32);
2240        tcg_temp_free_i32(tmp32);
2241        break;
2242    case 0xb: /* SEB    R1,D2(X2,B2)       [RXE] */
2243        tmp = tcg_temp_new_i64();
2244        tmp32 = tcg_temp_new_i32();
2245        tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s));
2246        tcg_gen_trunc_i64_i32(tmp32, tmp);
2247        gen_helper_seb(tmp_r1, tmp32);
2248        tcg_temp_free_i64(tmp);
2249        tcg_temp_free_i32(tmp32);
2250
2251        tmp32 = load_freg32(r1);
2252        set_cc_nz_f32(s, tmp32);
2253        tcg_temp_free_i32(tmp32);
2254        break;
2255    case 0xd: /* DEB    R1,D2(X2,B2)       [RXE] */
2256        tmp = tcg_temp_new_i64();
2257        tmp32 = tcg_temp_new_i32();
2258        tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s));
2259        tcg_gen_trunc_i64_i32(tmp32, tmp);
2260        gen_helper_deb(tmp_r1, tmp32);
2261        tcg_temp_free_i64(tmp);
2262        tcg_temp_free_i32(tmp32);
2263        break;
2264    case 0x10: /* TCEB   R1,D2(X2,B2)       [RXE] */
2265        potential_page_fault(s);
2266        gen_helper_tceb(cc_op, tmp_r1, addr);
2267        set_cc_static(s);
2268        break;
2269    case 0x11: /* TCDB   R1,D2(X2,B2)       [RXE] */
2270        potential_page_fault(s);
2271        gen_helper_tcdb(cc_op, tmp_r1, addr);
2272        set_cc_static(s);
2273        break;
2274    case 0x12: /* TCXB   R1,D2(X2,B2)       [RXE] */
2275        potential_page_fault(s);
2276        gen_helper_tcxb(cc_op, tmp_r1, addr);
2277        set_cc_static(s);
2278        break;
2279    case 0x17: /* MEEB   R1,D2(X2,B2)       [RXE] */
2280        tmp = tcg_temp_new_i64();
2281        tmp32 = tcg_temp_new_i32();
2282        tcg_gen_qemu_ld32u(tmp, addr, get_mem_index(s));
2283        tcg_gen_trunc_i64_i32(tmp32, tmp);
2284        gen_helper_meeb(tmp_r1, tmp32);
2285        tcg_temp_free_i64(tmp);
2286        tcg_temp_free_i32(tmp32);
2287        break;
2288    case 0x19: /* CDB    R1,D2(X2,B2)       [RXE] */
2289        potential_page_fault(s);
2290        gen_helper_cdb(cc_op, tmp_r1, addr);
2291        set_cc_static(s);
2292        break;
2293    case 0x1a: /* ADB    R1,D2(X2,B2)       [RXE] */
2294        potential_page_fault(s);
2295        gen_helper_adb(cc_op, tmp_r1, addr);
2296        set_cc_static(s);
2297        break;
2298    case 0x1b: /* SDB    R1,D2(X2,B2)       [RXE] */
2299        potential_page_fault(s);
2300        gen_helper_sdb(cc_op, tmp_r1, addr);
2301        set_cc_static(s);
2302        break;
2303    case 0x1c: /* MDB    R1,D2(X2,B2)       [RXE] */
2304        potential_page_fault(s);
2305        gen_helper_mdb(tmp_r1, addr);
2306        break;
2307    case 0x1d: /* DDB    R1,D2(X2,B2)       [RXE] */
2308        potential_page_fault(s);
2309        gen_helper_ddb(tmp_r1, addr);
2310        break;
2311    case 0x1e: /* MADB  R1,R3,D2(X2,B2) [RXF] */
2312        /* for RXF insns, r1 is R3 and r1b is R1 */
2313        tmp32 = tcg_const_i32(r1b);
2314        potential_page_fault(s);
2315        gen_helper_madb(tmp32, addr, tmp_r1);
2316        tcg_temp_free_i32(tmp32);
2317        break;
2318    default:
2319        LOG_DISAS("illegal ed operation 0x%x\n", op);
2320        gen_illegal_opcode(s, 3);
2321        return;
2322    }
2323    tcg_temp_free_i32(tmp_r1);
2324    tcg_temp_free_i64(addr);
2325}
2326
2327static void disas_a5(DisasContext *s, int op, int r1, int i2)
2328{
2329    TCGv_i64 tmp, tmp2;
2330    TCGv_i32 tmp32;
2331    LOG_DISAS("disas_a5: op 0x%x r1 %d i2 0x%x\n", op, r1, i2);
2332    switch (op) {
2333    case 0x0: /* IIHH     R1,I2     [RI] */
2334        tmp = tcg_const_i64(i2);
2335        tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 48, 16);
2336        tcg_temp_free_i64(tmp);
2337        break;
2338    case 0x1: /* IIHL     R1,I2     [RI] */
2339        tmp = tcg_const_i64(i2);
2340        tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 32, 16);
2341        tcg_temp_free_i64(tmp);
2342        break;
2343    case 0x2: /* IILH     R1,I2     [RI] */
2344        tmp = tcg_const_i64(i2);
2345        tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 16, 16);
2346        tcg_temp_free_i64(tmp);
2347        break;
2348    case 0x3: /* IILL     R1,I2     [RI] */
2349        tmp = tcg_const_i64(i2);
2350        tcg_gen_deposit_i64(regs[r1], regs[r1], tmp, 0, 16);
2351        tcg_temp_free_i64(tmp);
2352        break;
2353    case 0x4: /* NIHH     R1,I2     [RI] */
2354    case 0x8: /* OIHH     R1,I2     [RI] */
2355        tmp = load_reg(r1);
2356        tmp32 = tcg_temp_new_i32();
2357        switch (op) {
2358        case 0x4:
2359            tmp2 = tcg_const_i64((((uint64_t)i2) << 48)
2360                               | 0x0000ffffffffffffULL);
2361            tcg_gen_and_i64(tmp, tmp, tmp2);
2362            break;
2363        case 0x8:
2364            tmp2 = tcg_const_i64(((uint64_t)i2) << 48);
2365            tcg_gen_or_i64(tmp, tmp, tmp2);
2366            break;
2367        default:
2368            tcg_abort();
2369        }
2370        store_reg(r1, tmp);
2371        tcg_gen_shri_i64(tmp2, tmp, 48);
2372        tcg_gen_trunc_i64_i32(tmp32, tmp2);
2373        set_cc_nz_u32(s, tmp32);
2374        tcg_temp_free_i64(tmp2);
2375        tcg_temp_free_i32(tmp32);
2376        tcg_temp_free_i64(tmp);
2377        break;
2378    case 0x5: /* NIHL     R1,I2     [RI] */
2379    case 0x9: /* OIHL     R1,I2     [RI] */
2380        tmp = load_reg(r1);
2381        tmp32 = tcg_temp_new_i32();
2382        switch (op) {
2383        case 0x5:
2384            tmp2 = tcg_const_i64((((uint64_t)i2) << 32)
2385                               | 0xffff0000ffffffffULL);
2386            tcg_gen_and_i64(tmp, tmp, tmp2);
2387            break;
2388        case 0x9:
2389            tmp2 = tcg_const_i64(((uint64_t)i2) << 32);
2390            tcg_gen_or_i64(tmp, tmp, tmp2);
2391            break;
2392        default:
2393            tcg_abort();
2394        }
2395        store_reg(r1, tmp);
2396        tcg_gen_shri_i64(tmp2, tmp, 32);
2397        tcg_gen_trunc_i64_i32(tmp32, tmp2);
2398        tcg_gen_andi_i32(tmp32, tmp32, 0xffff);
2399        set_cc_nz_u32(s, tmp32);
2400        tcg_temp_free_i64(tmp2);
2401        tcg_temp_free_i32(tmp32);
2402        tcg_temp_free_i64(tmp);
2403        break;
2404    case 0x6: /* NILH     R1,I2     [RI] */
2405    case 0xa: /* OILH     R1,I2     [RI] */
2406        tmp = load_reg(r1);
2407        tmp32 = tcg_temp_new_i32();
2408        switch (op) {
2409        case 0x6:
2410            tmp2 = tcg_const_i64((((uint64_t)i2) << 16)
2411                               | 0xffffffff0000ffffULL);
2412            tcg_gen_and_i64(tmp, tmp, tmp2);
2413            break;
2414        case 0xa:
2415            tmp2 = tcg_const_i64(((uint64_t)i2) << 16);
2416            tcg_gen_or_i64(tmp, tmp, tmp2);
2417            break;
2418        default:
2419            tcg_abort();
2420        }
2421        store_reg(r1, tmp);
2422        tcg_gen_shri_i64(tmp, tmp, 16);
2423        tcg_gen_trunc_i64_i32(tmp32, tmp);
2424        tcg_gen_andi_i32(tmp32, tmp32, 0xffff);
2425        set_cc_nz_u32(s, tmp32);
2426        tcg_temp_free_i64(tmp2);
2427        tcg_temp_free_i32(tmp32);
2428        tcg_temp_free_i64(tmp);
2429        break;
2430    case 0x7: /* NILL     R1,I2     [RI] */
2431    case 0xb: /* OILL     R1,I2     [RI] */
2432        tmp = load_reg(r1);
2433        tmp32 = tcg_temp_new_i32();
2434        switch (op) {
2435        case 0x7:
2436            tmp2 = tcg_const_i64(i2 | 0xffffffffffff0000ULL);
2437            tcg_gen_and_i64(tmp, tmp, tmp2);
2438            break;
2439        case 0xb:
2440            tmp2 = tcg_const_i64(i2);
2441            tcg_gen_or_i64(tmp, tmp, tmp2);
2442            break;
2443        default:
2444            tcg_abort();
2445        }
2446        store_reg(r1, tmp);
2447        tcg_gen_trunc_i64_i32(tmp32, tmp);
2448        tcg_gen_andi_i32(tmp32, tmp32, 0xffff);
2449        set_cc_nz_u32(s, tmp32);        /* signedness should not matter here */
2450        tcg_temp_free_i64(tmp2);
2451        tcg_temp_free_i32(tmp32);
2452        tcg_temp_free_i64(tmp);
2453        break;
2454    case 0xc: /* LLIHH     R1,I2     [RI] */
2455        tmp = tcg_const_i64( ((uint64_t)i2) << 48 );
2456        store_reg(r1, tmp);
2457        tcg_temp_free_i64(tmp);
2458        break;
2459    case 0xd: /* LLIHL     R1,I2     [RI] */
2460        tmp = tcg_const_i64( ((uint64_t)i2) << 32 );
2461        store_reg(r1, tmp);
2462        tcg_temp_free_i64(tmp);
2463        break;
2464    case 0xe: /* LLILH     R1,I2     [RI] */
2465        tmp = tcg_const_i64( ((uint64_t)i2) << 16 );
2466        store_reg(r1, tmp);
2467        tcg_temp_free_i64(tmp);
2468        break;
2469    case 0xf: /* LLILL     R1,I2     [RI] */
2470        tmp = tcg_const_i64(i2);
2471        store_reg(r1, tmp);
2472        tcg_temp_free_i64(tmp);
2473        break;
2474    default:
2475        LOG_DISAS("illegal a5 operation 0x%x\n", op);
2476        gen_illegal_opcode(s, 2);
2477        return;
2478    }
2479}
2480
2481static void disas_a7(DisasContext *s, int op, int r1, int i2)
2482{
2483    TCGv_i64 tmp, tmp2;
2484    TCGv_i32 tmp32_1, tmp32_2, tmp32_3;
2485    int l1;
2486
2487    LOG_DISAS("disas_a7: op 0x%x r1 %d i2 0x%x\n", op, r1, i2);
2488    switch (op) {
2489    case 0x0: /* TMLH or TMH     R1,I2     [RI] */
2490    case 0x1: /* TMLL or TML     R1,I2     [RI] */
2491    case 0x2: /* TMHH     R1,I2     [RI] */
2492    case 0x3: /* TMHL     R1,I2     [RI] */
2493        tmp = load_reg(r1);
2494        tmp2 = tcg_const_i64((uint16_t)i2);
2495        switch (op) {
2496        case 0x0:
2497            tcg_gen_shri_i64(tmp, tmp, 16);
2498            break;
2499        case 0x1:
2500            break;
2501        case 0x2:
2502            tcg_gen_shri_i64(tmp, tmp, 48);
2503            break;
2504        case 0x3:
2505            tcg_gen_shri_i64(tmp, tmp, 32);
2506            break;
2507        }
2508        tcg_gen_andi_i64(tmp, tmp, 0xffff);
2509        cmp_64(s, tmp, tmp2, CC_OP_TM_64);
2510        tcg_temp_free_i64(tmp);
2511        tcg_temp_free_i64(tmp2);
2512        break;
2513    case 0x4: /* brc m1, i2 */
2514        gen_brc(r1, s, i2 * 2LL);
2515        return;
2516    case 0x5: /* BRAS     R1,I2     [RI] */
2517        tmp = tcg_const_i64(pc_to_link_info(s, s->pc + 4));
2518        store_reg(r1, tmp);
2519        tcg_temp_free_i64(tmp);
2520        gen_goto_tb(s, 0, s->pc + i2 * 2LL);
2521        s->is_jmp = DISAS_TB_JUMP;
2522        break;
2523    case 0x6: /* BRCT     R1,I2     [RI] */
2524        tmp32_1 = load_reg32(r1);
2525        tcg_gen_subi_i32(tmp32_1, tmp32_1, 1);
2526        store_reg32(r1, tmp32_1);
2527        gen_update_cc_op(s);
2528        l1 = gen_new_label();
2529        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp32_1, 0, l1);
2530        gen_goto_tb(s, 0, s->pc + (i2 * 2LL));
2531        gen_set_label(l1);
2532        gen_goto_tb(s, 1, s->pc + 4);
2533        s->is_jmp = DISAS_TB_JUMP;
2534        tcg_temp_free_i32(tmp32_1);
2535        break;
2536    case 0x7: /* BRCTG     R1,I2     [RI] */
2537        tmp = load_reg(r1);
2538        tcg_gen_subi_i64(tmp, tmp, 1);
2539        store_reg(r1, tmp);
2540        gen_update_cc_op(s);
2541        l1 = gen_new_label();
2542        tcg_gen_brcondi_i64(TCG_COND_EQ, tmp, 0, l1);
2543        gen_goto_tb(s, 0, s->pc + (i2 * 2LL));
2544        gen_set_label(l1);
2545        gen_goto_tb(s, 1, s->pc + 4);
2546        s->is_jmp = DISAS_TB_JUMP;
2547        tcg_temp_free_i64(tmp);
2548        break;
2549    case 0x8: /* lhi r1, i2 */
2550        tmp32_1 = tcg_const_i32(i2);
2551        store_reg32(r1, tmp32_1);
2552        tcg_temp_free_i32(tmp32_1);
2553        break;
2554    case 0x9: /* lghi r1, i2 */
2555        tmp = tcg_const_i64(i2);
2556        store_reg(r1, tmp);
2557        tcg_temp_free_i64(tmp);
2558        break;
2559    case 0xa: /* AHI     R1,I2     [RI] */
2560        tmp32_1 = load_reg32(r1);
2561        tmp32_2 = tcg_temp_new_i32();
2562        tmp32_3 = tcg_const_i32(i2);
2563
2564        if (i2 < 0) {
2565            tcg_gen_subi_i32(tmp32_2, tmp32_1, -i2);
2566        } else {
2567            tcg_gen_add_i32(tmp32_2, tmp32_1, tmp32_3);
2568        }
2569
2570        store_reg32(r1, tmp32_2);
2571        set_cc_add32(s, tmp32_1, tmp32_3, tmp32_2);
2572        tcg_temp_free_i32(tmp32_1);
2573        tcg_temp_free_i32(tmp32_2);
2574        tcg_temp_free_i32(tmp32_3);
2575        break;
2576    case 0xb: /* aghi r1, i2 */
2577        tmp = load_reg(r1);
2578        tmp2 = tcg_const_i64(i2);
2579
2580        if (i2 < 0) {
2581            tcg_gen_subi_i64(regs[r1], tmp, -i2);
2582        } else {
2583            tcg_gen_add_i64(regs[r1], tmp, tmp2);
2584        }
2585        set_cc_add64(s, tmp, tmp2, regs[r1]);
2586        tcg_temp_free_i64(tmp);
2587        tcg_temp_free_i64(tmp2);
2588        break;
2589    case 0xc: /* MHI     R1,I2     [RI] */
2590        tmp32_1 = load_reg32(r1);
2591        tcg_gen_muli_i32(tmp32_1, tmp32_1, i2);
2592        store_reg32(r1, tmp32_1);
2593        tcg_temp_free_i32(tmp32_1);
2594        break;
2595    case 0xd: /* MGHI     R1,I2     [RI] */
2596        tmp = load_reg(r1);
2597        tcg_gen_muli_i64(tmp, tmp, i2);
2598        store_reg(r1, tmp);
2599        tcg_temp_free_i64(tmp);
2600        break;
2601    case 0xe: /* CHI     R1,I2     [RI] */
2602        tmp32_1 = load_reg32(r1);
2603        cmp_s32c(s, tmp32_1, i2);
2604        tcg_temp_free_i32(tmp32_1);
2605        break;
2606    case 0xf: /* CGHI     R1,I2     [RI] */
2607        tmp = load_reg(r1);
2608        cmp_s64c(s, tmp, i2);
2609        tcg_temp_free_i64(tmp);
2610        break;
2611    default:
2612        LOG_DISAS("illegal a7 operation 0x%x\n", op);
2613        gen_illegal_opcode(s, 2);
2614        return;
2615    }
2616}
2617
2618static void disas_b2(DisasContext *s, int op, uint32_t insn)
2619{
2620    TCGv_i64 tmp, tmp2, tmp3;
2621    TCGv_i32 tmp32_1, tmp32_2, tmp32_3;
2622    int r1, r2;
2623    int ilc = 2;
2624#ifndef CONFIG_USER_ONLY
2625    int r3, d2, b2;
2626#endif
2627
2628    r1 = (insn >> 4) & 0xf;
2629    r2 = insn & 0xf;
2630
2631    LOG_DISAS("disas_b2: op 0x%x r1 %d r2 %d\n", op, r1, r2);
2632
2633    switch (op) {
2634    case 0x22: /* IPM    R1               [RRE] */
2635        tmp32_1 = tcg_const_i32(r1);
2636        gen_op_calc_cc(s);
2637        gen_helper_ipm(cc_op, tmp32_1);
2638        tcg_temp_free_i32(tmp32_1);
2639        break;
2640    case 0x41: /* CKSM    R1,R2     [RRE] */
2641        tmp32_1 = tcg_const_i32(r1);
2642        tmp32_2 = tcg_const_i32(r2);
2643        potential_page_fault(s);
2644        gen_helper_cksm(tmp32_1, tmp32_2);
2645        tcg_temp_free_i32(tmp32_1);
2646        tcg_temp_free_i32(tmp32_2);
2647        gen_op_movi_cc(s, 0);
2648        break;
2649    case 0x4e: /* SAR     R1,R2     [RRE] */
2650        tmp32_1 = load_reg32(r2);
2651        tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUState, aregs[r1]));
2652        tcg_temp_free_i32(tmp32_1);
2653        break;
2654    case 0x4f: /* EAR     R1,R2     [RRE] */
2655        tmp32_1 = tcg_temp_new_i32();
2656        tcg_gen_ld_i32(tmp32_1, cpu_env, offsetof(CPUState, aregs[r2]));
2657        store_reg32(r1, tmp32_1);
2658        tcg_temp_free_i32(tmp32_1);
2659        break;
2660    case 0x52: /* MSR     R1,R2     [RRE] */
2661        tmp32_1 = load_reg32(r1);
2662        tmp32_2 = load_reg32(r2);
2663        tcg_gen_mul_i32(tmp32_1, tmp32_1, tmp32_2);
2664        store_reg32(r1, tmp32_1);
2665        tcg_temp_free_i32(tmp32_1);
2666        tcg_temp_free_i32(tmp32_2);
2667        break;
2668    case 0x54: /* MVPG     R1,R2     [RRE] */
2669        tmp = load_reg(0);
2670        tmp2 = load_reg(r1);
2671        tmp3 = load_reg(r2);
2672        potential_page_fault(s);
2673        gen_helper_mvpg(tmp, tmp2, tmp3);
2674        tcg_temp_free_i64(tmp);
2675        tcg_temp_free_i64(tmp2);
2676        tcg_temp_free_i64(tmp3);
2677        /* XXX check CCO bit and set CC accordingly */
2678        gen_op_movi_cc(s, 0);
2679        break;
2680    case 0x55: /* MVST     R1,R2     [RRE] */
2681        tmp32_1 = load_reg32(0);
2682        tmp32_2 = tcg_const_i32(r1);
2683        tmp32_3 = tcg_const_i32(r2);
2684        potential_page_fault(s);
2685        gen_helper_mvst(tmp32_1, tmp32_2, tmp32_3);
2686        tcg_temp_free_i32(tmp32_1);
2687        tcg_temp_free_i32(tmp32_2);
2688        tcg_temp_free_i32(tmp32_3);
2689        gen_op_movi_cc(s, 1);
2690        break;
2691    case 0x5d: /* CLST     R1,R2     [RRE] */
2692        tmp32_1 = load_reg32(0);
2693        tmp32_2 = tcg_const_i32(r1);
2694        tmp32_3 = tcg_const_i32(r2);
2695        potential_page_fault(s);
2696        gen_helper_clst(cc_op, tmp32_1, tmp32_2, tmp32_3);
2697        set_cc_static(s);
2698        tcg_temp_free_i32(tmp32_1);
2699        tcg_temp_free_i32(tmp32_2);
2700        tcg_temp_free_i32(tmp32_3);
2701        break;
2702    case 0x5e: /* SRST     R1,R2     [RRE] */
2703        tmp32_1 = load_reg32(0);
2704        tmp32_2 = tcg_const_i32(r1);
2705        tmp32_3 = tcg_const_i32(r2);
2706        potential_page_fault(s);
2707        gen_helper_srst(cc_op, tmp32_1, tmp32_2, tmp32_3);
2708        set_cc_static(s);
2709        tcg_temp_free_i32(tmp32_1);
2710        tcg_temp_free_i32(tmp32_2);
2711        tcg_temp_free_i32(tmp32_3);
2712        break;
2713
2714#ifndef CONFIG_USER_ONLY
2715    case 0x02: /* STIDP     D2(B2)     [S] */
2716        /* Store CPU ID */
2717        check_privileged(s, ilc);
2718        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2719        tmp = get_address(s, 0, b2, d2);
2720        potential_page_fault(s);
2721        gen_helper_stidp(tmp);
2722        tcg_temp_free_i64(tmp);
2723        break;
2724    case 0x04: /* SCK       D2(B2)     [S] */
2725        /* Set Clock */
2726        check_privileged(s, ilc);
2727        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2728        tmp = get_address(s, 0, b2, d2);
2729        potential_page_fault(s);
2730        gen_helper_sck(cc_op, tmp);
2731        set_cc_static(s);
2732        tcg_temp_free_i64(tmp);
2733        break;
2734    case 0x05: /* STCK     D2(B2)     [S] */
2735        /* Store Clock */
2736        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2737        tmp = get_address(s, 0, b2, d2);
2738        potential_page_fault(s);
2739        gen_helper_stck(cc_op, tmp);
2740        set_cc_static(s);
2741        tcg_temp_free_i64(tmp);
2742        break;
2743    case 0x06: /* SCKC     D2(B2)     [S] */
2744        /* Set Clock Comparator */
2745        check_privileged(s, ilc);
2746        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2747        tmp = get_address(s, 0, b2, d2);
2748        potential_page_fault(s);
2749        gen_helper_sckc(tmp);
2750        tcg_temp_free_i64(tmp);
2751        break;
2752    case 0x07: /* STCKC    D2(B2)     [S] */
2753        /* Store Clock Comparator */
2754        check_privileged(s, ilc);
2755        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2756        tmp = get_address(s, 0, b2, d2);
2757        potential_page_fault(s);
2758        gen_helper_stckc(tmp);
2759        tcg_temp_free_i64(tmp);
2760        break;
2761    case 0x08: /* SPT      D2(B2)     [S] */
2762        /* Set CPU Timer */
2763        check_privileged(s, ilc);
2764        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2765        tmp = get_address(s, 0, b2, d2);
2766        potential_page_fault(s);
2767        gen_helper_spt(tmp);
2768        tcg_temp_free_i64(tmp);
2769        break;
2770    case 0x09: /* STPT     D2(B2)     [S] */
2771        /* Store CPU Timer */
2772        check_privileged(s, ilc);
2773        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2774        tmp = get_address(s, 0, b2, d2);
2775        potential_page_fault(s);
2776        gen_helper_stpt(tmp);
2777        tcg_temp_free_i64(tmp);
2778        break;
2779    case 0x0a: /* SPKA     D2(B2)     [S] */
2780        /* Set PSW Key from Address */
2781        check_privileged(s, ilc);
2782        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2783        tmp = get_address(s, 0, b2, d2);
2784        tmp2 = tcg_temp_new_i64();
2785        tcg_gen_andi_i64(tmp2, psw_mask, ~PSW_MASK_KEY);
2786        tcg_gen_shli_i64(tmp, tmp, PSW_SHIFT_KEY - 4);
2787        tcg_gen_or_i64(psw_mask, tmp2, tmp);
2788        tcg_temp_free_i64(tmp2);
2789        tcg_temp_free_i64(tmp);
2790        break;
2791    case 0x0d: /* PTLB                [S] */
2792        /* Purge TLB */
2793        check_privileged(s, ilc);
2794        gen_helper_ptlb();
2795        break;
2796    case 0x10: /* SPX      D2(B2)     [S] */
2797        /* Set Prefix Register */
2798        check_privileged(s, ilc);
2799        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2800        tmp = get_address(s, 0, b2, d2);
2801        potential_page_fault(s);
2802        gen_helper_spx(tmp);
2803        tcg_temp_free_i64(tmp);
2804        break;
2805    case 0x11: /* STPX     D2(B2)     [S] */
2806        /* Store Prefix */
2807        check_privileged(s, ilc);
2808        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2809        tmp = get_address(s, 0, b2, d2);
2810        tmp2 = tcg_temp_new_i64();
2811        tcg_gen_ld_i64(tmp2, cpu_env, offsetof(CPUState, psa));
2812        tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s));
2813        tcg_temp_free_i64(tmp);
2814        tcg_temp_free_i64(tmp2);
2815        break;
2816    case 0x12: /* STAP     D2(B2)     [S] */
2817        /* Store CPU Address */
2818        check_privileged(s, ilc);
2819        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2820        tmp = get_address(s, 0, b2, d2);
2821        tmp2 = tcg_temp_new_i64();
2822        tmp32_1 = tcg_temp_new_i32();
2823        tcg_gen_ld_i32(tmp32_1, cpu_env, offsetof(CPUState, cpu_num));
2824        tcg_gen_extu_i32_i64(tmp2, tmp32_1);
2825        tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s));
2826        tcg_temp_free_i64(tmp);
2827        tcg_temp_free_i64(tmp2);
2828        tcg_temp_free_i32(tmp32_1);
2829        break;
2830    case 0x21: /* IPTE     R1,R2      [RRE] */
2831        /* Invalidate PTE */
2832        check_privileged(s, ilc);
2833        r1 = (insn >> 4) & 0xf;
2834        r2 = insn & 0xf;
2835        tmp = load_reg(r1);
2836        tmp2 = load_reg(r2);
2837        gen_helper_ipte(tmp, tmp2);
2838        tcg_temp_free_i64(tmp);
2839        tcg_temp_free_i64(tmp2);
2840        break;
2841    case 0x29: /* ISKE     R1,R2      [RRE] */
2842        /* Insert Storage Key Extended */
2843        check_privileged(s, ilc);
2844        r1 = (insn >> 4) & 0xf;
2845        r2 = insn & 0xf;
2846        tmp = load_reg(r2);
2847        tmp2 = tcg_temp_new_i64();
2848        gen_helper_iske(tmp2, tmp);
2849        store_reg(r1, tmp2);
2850        tcg_temp_free_i64(tmp);
2851        tcg_temp_free_i64(tmp2);
2852        break;
2853    case 0x2a: /* RRBE     R1,R2      [RRE] */
2854        /* Set Storage Key Extended */
2855        check_privileged(s, ilc);
2856        r1 = (insn >> 4) & 0xf;
2857        r2 = insn & 0xf;
2858        tmp32_1 = load_reg32(r1);
2859        tmp = load_reg(r2);
2860        gen_helper_rrbe(cc_op, tmp32_1, tmp);
2861        set_cc_static(s);
2862        tcg_temp_free_i32(tmp32_1);
2863        tcg_temp_free_i64(tmp);
2864        break;
2865    case 0x2b: /* SSKE     R1,R2      [RRE] */
2866        /* Set Storage Key Extended */
2867        check_privileged(s, ilc);
2868        r1 = (insn >> 4) & 0xf;
2869        r2 = insn & 0xf;
2870        tmp32_1 = load_reg32(r1);
2871        tmp = load_reg(r2);
2872        gen_helper_sske(tmp32_1, tmp);
2873        tcg_temp_free_i32(tmp32_1);
2874        tcg_temp_free_i64(tmp);
2875        break;
2876    case 0x34: /* STCH ? */
2877        /* Store Subchannel */
2878        check_privileged(s, ilc);
2879        gen_op_movi_cc(s, 3);
2880        break;
2881    case 0x46: /* STURA    R1,R2      [RRE] */
2882        /* Store Using Real Address */
2883        check_privileged(s, ilc);
2884        r1 = (insn >> 4) & 0xf;
2885        r2 = insn & 0xf;
2886        tmp32_1 = load_reg32(r1);
2887        tmp = load_reg(r2);
2888        potential_page_fault(s);
2889        gen_helper_stura(tmp, tmp32_1);
2890        tcg_temp_free_i32(tmp32_1);
2891        tcg_temp_free_i64(tmp);
2892        break;
2893    case 0x50: /* CSP      R1,R2      [RRE] */
2894        /* Compare And Swap And Purge */
2895        check_privileged(s, ilc);
2896        r1 = (insn >> 4) & 0xf;
2897        r2 = insn & 0xf;
2898        tmp32_1 = tcg_const_i32(r1);
2899        tmp32_2 = tcg_const_i32(r2);
2900        gen_helper_csp(cc_op, tmp32_1, tmp32_2);
2901        set_cc_static(s);
2902        tcg_temp_free_i32(tmp32_1);
2903        tcg_temp_free_i32(tmp32_2);
2904        break;
2905    case 0x5f: /* CHSC ? */
2906        /* Channel Subsystem Call */
2907        check_privileged(s, ilc);
2908        gen_op_movi_cc(s, 3);
2909        break;
2910    case 0x78: /* STCKE    D2(B2)     [S] */
2911        /* Store Clock Extended */
2912        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2913        tmp = get_address(s, 0, b2, d2);
2914        potential_page_fault(s);
2915        gen_helper_stcke(cc_op, tmp);
2916        set_cc_static(s);
2917        tcg_temp_free_i64(tmp);
2918        break;
2919    case 0x79: /* SACF    D2(B2)     [S] */
2920        /* Store Clock Extended */
2921        check_privileged(s, ilc);
2922        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2923        tmp = get_address(s, 0, b2, d2);
2924        potential_page_fault(s);
2925        gen_helper_sacf(tmp);
2926        tcg_temp_free_i64(tmp);
2927        /* addressing mode has changed, so end the block */
2928        s->pc += ilc * 2;
2929        update_psw_addr(s);
2930        s->is_jmp = DISAS_EXCP;
2931        break;
2932    case 0x7d: /* STSI     D2,(B2)     [S] */
2933        check_privileged(s, ilc);
2934        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2935        tmp = get_address(s, 0, b2, d2);
2936        tmp32_1 = load_reg32(0);
2937        tmp32_2 = load_reg32(1);
2938        potential_page_fault(s);
2939        gen_helper_stsi(cc_op, tmp, tmp32_1, tmp32_2);
2940        set_cc_static(s);
2941        tcg_temp_free_i64(tmp);
2942        tcg_temp_free_i32(tmp32_1);
2943        tcg_temp_free_i32(tmp32_2);
2944        break;
2945    case 0x9d: /* LFPC      D2(B2)   [S] */
2946        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2947        tmp = get_address(s, 0, b2, d2);
2948        tmp2 = tcg_temp_new_i64();
2949        tmp32_1 = tcg_temp_new_i32();
2950        tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
2951        tcg_gen_trunc_i64_i32(tmp32_1, tmp2);
2952        tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUState, fpc));
2953        tcg_temp_free_i64(tmp);
2954        tcg_temp_free_i64(tmp2);
2955        tcg_temp_free_i32(tmp32_1);
2956        break;
2957    case 0xb1: /* STFL     D2(B2)     [S] */
2958        /* Store Facility List (CPU features) at 200 */
2959        check_privileged(s, ilc);
2960        tmp2 = tcg_const_i64(0xc0000000);
2961        tmp = tcg_const_i64(200);
2962        tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s));
2963        tcg_temp_free_i64(tmp2);
2964        tcg_temp_free_i64(tmp);
2965        break;
2966    case 0xb2: /* LPSWE    D2(B2)     [S] */
2967        /* Load PSW Extended */
2968        check_privileged(s, ilc);
2969        decode_rs(s, insn, &r1, &r3, &b2, &d2);
2970        tmp = get_address(s, 0, b2, d2);
2971        tmp2 = tcg_temp_new_i64();
2972        tmp3 = tcg_temp_new_i64();
2973        tcg_gen_qemu_ld64(tmp2, tmp, get_mem_index(s));
2974        tcg_gen_addi_i64(tmp, tmp, 8);
2975        tcg_gen_qemu_ld64(tmp3, tmp, get_mem_index(s));
2976        gen_helper_load_psw(tmp2, tmp3);
2977        /* we need to keep cc_op intact */
2978        s->is_jmp = DISAS_JUMP;
2979        tcg_temp_free_i64(tmp);
2980        tcg_temp_free_i64(tmp2);
2981        tcg_temp_free_i64(tmp3);
2982        break;
2983    case 0x20: /* SERVC     R1,R2     [RRE] */
2984        /* SCLP Service call (PV hypercall) */
2985        check_privileged(s, ilc);
2986        potential_page_fault(s);
2987        tmp32_1 = load_reg32(r2);
2988        tmp = load_reg(r1);
2989        gen_helper_servc(cc_op, tmp32_1, tmp);
2990        set_cc_static(s);
2991        tcg_temp_free_i32(tmp32_1);
2992        tcg_temp_free_i64(tmp);
2993        break;
2994#endif
2995    default:
2996        LOG_DISAS("illegal b2 operation 0x%x\n", op);
2997        gen_illegal_opcode(s, ilc);
2998        break;
2999    }
3000}
3001
3002static void disas_b3(DisasContext *s, int op, int m3, int r1, int r2)
3003{
3004    TCGv_i64 tmp;
3005    TCGv_i32 tmp32_1, tmp32_2, tmp32_3;
3006    LOG_DISAS("disas_b3: op 0x%x m3 0x%x r1 %d r2 %d\n", op, m3, r1, r2);
3007#define FP_HELPER(i) \
3008    tmp32_1 = tcg_const_i32(r1); \
3009    tmp32_2 = tcg_const_i32(r2); \
3010    gen_helper_ ## i (tmp32_1, tmp32_2); \
3011    tcg_temp_free_i32(tmp32_1); \
3012    tcg_temp_free_i32(tmp32_2);
3013
3014#define FP_HELPER_CC(i) \
3015    tmp32_1 = tcg_const_i32(r1); \
3016    tmp32_2 = tcg_const_i32(r2); \
3017    gen_helper_ ## i (cc_op, tmp32_1, tmp32_2); \
3018    set_cc_static(s); \
3019    tcg_temp_free_i32(tmp32_1); \
3020    tcg_temp_free_i32(tmp32_2);
3021
3022    switch (op) {
3023    case 0x0: /* LPEBR       R1,R2             [RRE] */
3024        FP_HELPER_CC(lpebr);
3025        break;
3026    case 0x2: /* LTEBR       R1,R2             [RRE] */
3027        FP_HELPER_CC(ltebr);
3028        break;
3029    case 0x3: /* LCEBR       R1,R2             [RRE] */
3030        FP_HELPER_CC(lcebr);
3031        break;
3032    case 0x4: /* LDEBR       R1,R2             [RRE] */
3033        FP_HELPER(ldebr);
3034        break;
3035    case 0x5: /* LXDBR       R1,R2             [RRE] */
3036        FP_HELPER(lxdbr);
3037        break;
3038    case 0x9: /* CEBR        R1,R2             [RRE] */
3039        FP_HELPER_CC(cebr);
3040        break;
3041    case 0xa: /* AEBR        R1,R2             [RRE] */
3042        FP_HELPER_CC(aebr);
3043        break;
3044    case 0xb: /* SEBR        R1,R2             [RRE] */
3045        FP_HELPER_CC(sebr);
3046        break;
3047    case 0xd: /* DEBR        R1,R2             [RRE] */
3048        FP_HELPER(debr);
3049        break;
3050    case 0x10: /* LPDBR       R1,R2             [RRE] */
3051        FP_HELPER_CC(lpdbr);
3052        break;
3053    case 0x12: /* LTDBR       R1,R2             [RRE] */
3054        FP_HELPER_CC(ltdbr);
3055        break;
3056    case 0x13: /* LCDBR       R1,R2             [RRE] */
3057        FP_HELPER_CC(lcdbr);
3058        break;
3059    case 0x15: /* SQBDR       R1,R2             [RRE] */
3060        FP_HELPER(sqdbr);
3061        break;
3062    case 0x17: /* MEEBR       R1,R2             [RRE] */
3063        FP_HELPER(meebr);
3064        break;
3065    case 0x19: /* CDBR        R1,R2             [RRE] */
3066        FP_HELPER_CC(cdbr);
3067        break;
3068    case 0x1a: /* ADBR        R1,R2             [RRE] */
3069        FP_HELPER_CC(adbr);
3070        break;
3071    case 0x1b: /* SDBR        R1,R2             [RRE] */
3072        FP_HELPER_CC(sdbr);
3073        break;
3074    case 0x1c: /* MDBR        R1,R2             [RRE] */
3075        FP_HELPER(mdbr);
3076        break;
3077    case 0x1d: /* DDBR        R1,R2             [RRE] */
3078        FP_HELPER(ddbr);
3079        break;
3080    case 0xe: /* MAEBR  R1,R3,R2 [RRF] */
3081    case 0x1e: /* MADBR R1,R3,R2 [RRF] */
3082    case 0x1f: /* MSDBR R1,R3,R2 [RRF] */
3083        /* for RRF insns, m3 is R1, r1 is R3, and r2 is R2 */
3084        tmp32_1 = tcg_const_i32(m3);
3085        tmp32_2 = tcg_const_i32(r2);
3086        tmp32_3 = tcg_const_i32(r1);
3087        switch (op) {
3088        case 0xe:
3089            gen_helper_maebr(tmp32_1, tmp32_3, tmp32_2);
3090            break;
3091        case 0x1e:
3092            gen_helper_madbr(tmp32_1, tmp32_3, tmp32_2);
3093            break;
3094        case 0x1f:
3095            gen_helper_msdbr(tmp32_1, tmp32_3, tmp32_2);
3096            break;
3097        default:
3098            tcg_abort();
3099        }
3100        tcg_temp_free_i32(tmp32_1);
3101        tcg_temp_free_i32(tmp32_2);
3102        tcg_temp_free_i32(tmp32_3);
3103        break;
3104    case 0x40: /* LPXBR       R1,R2             [RRE] */
3105        FP_HELPER_CC(lpxbr);
3106        break;
3107    case 0x42: /* LTXBR       R1,R2             [RRE] */
3108        FP_HELPER_CC(ltxbr);
3109        break;
3110    case 0x43: /* LCXBR       R1,R2             [RRE] */
3111        FP_HELPER_CC(lcxbr);
3112        break;
3113    case 0x44: /* LEDBR       R1,R2             [RRE] */
3114        FP_HELPER(ledbr);
3115        break;
3116    case 0x45: /* LDXBR       R1,R2             [RRE] */
3117        FP_HELPER(ldxbr);
3118        break;
3119    case 0x46: /* LEXBR       R1,R2             [RRE] */
3120        FP_HELPER(lexbr);
3121        break;
3122    case 0x49: /* CXBR        R1,R2             [RRE] */
3123        FP_HELPER_CC(cxbr);
3124        break;
3125    case 0x4a: /* AXBR        R1,R2             [RRE] */
3126        FP_HELPER_CC(axbr);
3127        break;
3128    case 0x4b: /* SXBR        R1,R2             [RRE] */
3129        FP_HELPER_CC(sxbr);
3130        break;
3131    case 0x4c: /* MXBR        R1,R2             [RRE] */
3132        FP_HELPER(mxbr);
3133        break;
3134    case 0x4d: /* DXBR        R1,R2             [RRE] */
3135        FP_HELPER(dxbr);
3136        break;
3137    case 0x65: /* LXR         R1,R2             [RRE] */
3138        tmp = load_freg(r2);
3139        store_freg(r1, tmp);
3140        tcg_temp_free_i64(tmp);
3141        tmp = load_freg(r2 + 2);
3142        store_freg(r1 + 2, tmp);
3143        tcg_temp_free_i64(tmp);
3144        break;
3145    case 0x74: /* LZER        R1                [RRE] */
3146        tmp32_1 = tcg_const_i32(r1);
3147        gen_helper_lzer(tmp32_1);
3148        tcg_temp_free_i32(tmp32_1);
3149        break;
3150    case 0x75: /* LZDR        R1                [RRE] */
3151        tmp32_1 = tcg_const_i32(r1);
3152        gen_helper_lzdr(tmp32_1);
3153        tcg_temp_free_i32(tmp32_1);
3154        break;
3155    case 0x76: /* LZXR        R1                [RRE] */
3156        tmp32_1 = tcg_const_i32(r1);
3157        gen_helper_lzxr(tmp32_1);
3158        tcg_temp_free_i32(tmp32_1);
3159        break;
3160    case 0x84: /* SFPC        R1                [RRE] */
3161        tmp32_1 = load_reg32(r1);
3162        tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUState, fpc));
3163        tcg_temp_free_i32(tmp32_1);
3164        break;
3165    case 0x8c: /* EFPC        R1                [RRE] */
3166        tmp32_1 = tcg_temp_new_i32();
3167        tcg_gen_ld_i32(tmp32_1, cpu_env, offsetof(CPUState, fpc));
3168        store_reg32(r1, tmp32_1);
3169        tcg_temp_free_i32(tmp32_1);
3170        break;
3171    case 0x94: /* CEFBR       R1,R2             [RRE] */
3172    case 0x95: /* CDFBR       R1,R2             [RRE] */
3173    case 0x96: /* CXFBR       R1,R2             [RRE] */
3174        tmp32_1 = tcg_const_i32(r1);
3175        tmp32_2 = load_reg32(r2);
3176        switch (op) {
3177        case 0x94:
3178            gen_helper_cefbr(tmp32_1, tmp32_2);
3179            break;
3180        case 0x95:
3181            gen_helper_cdfbr(tmp32_1, tmp32_2);
3182            break;
3183        case 0x96:
3184            gen_helper_cxfbr(tmp32_1, tmp32_2);
3185            break;
3186        default:
3187            tcg_abort();
3188        }
3189        tcg_temp_free_i32(tmp32_1);
3190        tcg_temp_free_i32(tmp32_2);
3191        break;
3192    case 0x98: /* CFEBR       R1,R2             [RRE] */
3193    case 0x99: /* CFDBR              R1,R2             [RRE] */
3194    case 0x9a: /* CFXBR       R1,R2             [RRE] */
3195        tmp32_1 = tcg_const_i32(r1);
3196        tmp32_2 = tcg_const_i32(r2);
3197        tmp32_3 = tcg_const_i32(m3);
3198        switch (op) {
3199        case 0x98:
3200            gen_helper_cfebr(cc_op, tmp32_1, tmp32_2, tmp32_3);
3201            break;
3202        case 0x99:
3203            gen_helper_cfdbr(cc_op, tmp32_1, tmp32_2, tmp32_3);
3204            break;
3205        case 0x9a:
3206            gen_helper_cfxbr(cc_op, tmp32_1, tmp32_2, tmp32_3);
3207            break;
3208        default:
3209            tcg_abort();
3210        }
3211        set_cc_static(s);
3212        tcg_temp_free_i32(tmp32_1);
3213        tcg_temp_free_i32(tmp32_2);
3214        tcg_temp_free_i32(tmp32_3);
3215        break;
3216    case 0xa4: /* CEGBR       R1,R2             [RRE] */
3217    case 0xa5: /* CDGBR       R1,R2             [RRE] */
3218        tmp32_1 = tcg_const_i32(r1);
3219        tmp = load_reg(r2);
3220        switch (op) {
3221        case 0xa4:
3222            gen_helper_cegbr(tmp32_1, tmp);
3223            break;
3224        case 0xa5:
3225            gen_helper_cdgbr(tmp32_1, tmp);
3226            break;
3227        default:
3228            tcg_abort();
3229        }
3230        tcg_temp_free_i32(tmp32_1);
3231        tcg_temp_free_i64(tmp);
3232        break;
3233    case 0xa6: /* CXGBR       R1,R2             [RRE] */
3234        tmp32_1 = tcg_const_i32(r1);
3235        tmp = load_reg(r2);
3236        gen_helper_cxgbr(tmp32_1, tmp);
3237        tcg_temp_free_i32(tmp32_1);
3238        tcg_temp_free_i64(tmp);
3239        break;
3240    case 0xa8: /* CGEBR       R1,R2             [RRE] */
3241        tmp32_1 = tcg_const_i32(r1);
3242        tmp32_2 = tcg_const_i32(r2);
3243        tmp32_3 = tcg_const_i32(m3);
3244        gen_helper_cgebr(cc_op, tmp32_1, tmp32_2, tmp32_3);
3245        set_cc_static(s);
3246        tcg_temp_free_i32(tmp32_1);
3247        tcg_temp_free_i32(tmp32_2);
3248        tcg_temp_free_i32(tmp32_3);
3249        break;
3250    case 0xa9: /* CGDBR       R1,R2             [RRE] */
3251        tmp32_1 = tcg_const_i32(r1);
3252        tmp32_2 = tcg_const_i32(r2);
3253        tmp32_3 = tcg_const_i32(m3);
3254        gen_helper_cgdbr(cc_op, tmp32_1, tmp32_2, tmp32_3);
3255        set_cc_static(s);
3256        tcg_temp_free_i32(tmp32_1);
3257        tcg_temp_free_i32(tmp32_2);
3258        tcg_temp_free_i32(tmp32_3);
3259        break;
3260    case 0xaa: /* CGXBR       R1,R2             [RRE] */
3261        tmp32_1 = tcg_const_i32(r1);
3262        tmp32_2 = tcg_const_i32(r2);
3263        tmp32_3 = tcg_const_i32(m3);
3264        gen_helper_cgxbr(cc_op, tmp32_1, tmp32_2, tmp32_3);
3265        set_cc_static(s);
3266        tcg_temp_free_i32(tmp32_1);
3267        tcg_temp_free_i32(tmp32_2);
3268        tcg_temp_free_i32(tmp32_3);
3269        break;
3270    default:
3271        LOG_DISAS("illegal b3 operation 0x%x\n", op);
3272        gen_illegal_opcode(s, 2);
3273        break;
3274    }
3275
3276#undef FP_HELPER_CC
3277#undef FP_HELPER
3278}
3279
3280static void disas_b9(DisasContext *s, int op, int r1, int r2)
3281{
3282    TCGv_i64 tmp, tmp2, tmp3;
3283    TCGv_i32 tmp32_1, tmp32_2, tmp32_3;
3284
3285    LOG_DISAS("disas_b9: op 0x%x r1 %d r2 %d\n", op, r1, r2);
3286    switch (op) {
3287    case 0x0: /* LPGR     R1,R2     [RRE] */
3288    case 0x1: /* LNGR     R1,R2     [RRE] */
3289    case 0x2: /* LTGR R1,R2 [RRE] */
3290    case 0x3: /* LCGR     R1,R2     [RRE] */
3291    case 0x10: /* LPGFR R1,R2 [RRE] */
3292    case 0x11: /* LNFGR     R1,R2     [RRE] */
3293    case 0x12: /* LTGFR R1,R2 [RRE] */
3294    case 0x13: /* LCGFR    R1,R2     [RRE] */
3295        if (op & 0x10) {
3296            tmp = load_reg32_i64(r2);
3297        } else {
3298            tmp = load_reg(r2);
3299        }
3300        switch (op & 0xf) {
3301        case 0x0: /* LP?GR */
3302            set_cc_abs64(s, tmp);
3303            gen_helper_abs_i64(tmp, tmp);
3304            store_reg(r1, tmp);
3305            break;
3306        case 0x1: /* LN?GR */
3307            set_cc_nabs64(s, tmp);
3308            gen_helper_nabs_i64(tmp, tmp);
3309            store_reg(r1, tmp);
3310            break;
3311        case 0x2: /* LT?GR */
3312            if (r1 != r2) {
3313                store_reg(r1, tmp);
3314            }
3315            set_cc_s64(s, tmp);
3316            break;
3317        case 0x3: /* LC?GR */
3318            tcg_gen_neg_i64(regs[r1], tmp);
3319            set_cc_comp64(s, regs[r1]);
3320            break;
3321        }
3322        tcg_temp_free_i64(tmp);
3323        break;
3324    case 0x4: /* LGR R1,R2 [RRE] */
3325        store_reg(r1, regs[r2]);
3326        break;
3327    case 0x6: /* LGBR R1,R2 [RRE] */
3328        tmp2 = load_reg(r2);
3329        tcg_gen_ext8s_i64(tmp2, tmp2);
3330        store_reg(r1, tmp2);
3331        tcg_temp_free_i64(tmp2);
3332        break;
3333    case 0x8: /* AGR     R1,R2     [RRE] */
3334    case 0xa: /* ALGR     R1,R2     [RRE] */
3335        tmp = load_reg(r1);
3336        tmp2 = load_reg(r2);
3337        tmp3 = tcg_temp_new_i64();
3338        tcg_gen_add_i64(tmp3, tmp, tmp2);
3339        store_reg(r1, tmp3);
3340        switch (op) {
3341        case 0x8:
3342            set_cc_add64(s, tmp, tmp2, tmp3);
3343            break;
3344        case 0xa:
3345            set_cc_addu64(s, tmp, tmp2, tmp3);
3346            break;
3347        default:
3348            tcg_abort();
3349        }
3350        tcg_temp_free_i64(tmp);
3351        tcg_temp_free_i64(tmp2);
3352        tcg_temp_free_i64(tmp3);
3353        break;
3354    case 0x9: /* SGR     R1,R2     [RRE] */
3355    case 0xb: /* SLGR     R1,R2     [RRE] */
3356    case 0x1b: /* SLGFR     R1,R2     [RRE] */
3357    case 0x19: /* SGFR     R1,R2     [RRE] */
3358        tmp = load_reg(r1);
3359        switch (op) {
3360        case 0x1b:
3361            tmp32_1 = load_reg32(r2);
3362            tmp2 = tcg_temp_new_i64();
3363            tcg_gen_extu_i32_i64(tmp2, tmp32_1);
3364            tcg_temp_free_i32(tmp32_1);
3365            break;
3366        case 0x19:
3367            tmp32_1 = load_reg32(r2);
3368            tmp2 = tcg_temp_new_i64();
3369            tcg_gen_ext_i32_i64(tmp2, tmp32_1);
3370            tcg_temp_free_i32(tmp32_1);
3371            break;
3372        default:
3373            tmp2 = load_reg(r2);
3374            break;
3375        }
3376        tmp3 = tcg_temp_new_i64();
3377        tcg_gen_sub_i64(tmp3, tmp, tmp2);
3378        store_reg(r1, tmp3);
3379        switch (op) {
3380        case 0x9:
3381        case 0x19:
3382            set_cc_sub64(s, tmp, tmp2, tmp3);
3383            break;
3384        case 0xb:
3385        case 0x1b:
3386            set_cc_subu64(s, tmp, tmp2, tmp3);
3387            break;
3388        default:
3389            tcg_abort();
3390        }
3391        tcg_temp_free_i64(tmp);
3392        tcg_temp_free_i64(tmp2);
3393        tcg_temp_free_i64(tmp3);
3394        break;
3395    case 0xc: /* MSGR      R1,R2     [RRE] */
3396    case 0x1c: /* MSGFR      R1,R2     [RRE] */
3397        tmp = load_reg(r1);
3398        tmp2 = load_reg(r2);
3399        if (op == 0x1c) {
3400            tcg_gen_ext32s_i64(tmp2, tmp2);
3401        }
3402        tcg_gen_mul_i64(tmp, tmp, tmp2);
3403        store_reg(r1, tmp);
3404        tcg_temp_free_i64(tmp);
3405        tcg_temp_free_i64(tmp2);
3406        break;
3407    case 0xd: /* DSGR      R1,R2     [RRE] */
3408    case 0x1d: /* DSGFR      R1,R2     [RRE] */
3409        tmp = load_reg(r1 + 1);
3410        if (op == 0xd) {
3411            tmp2 = load_reg(r2);
3412        } else {
3413            tmp32_1 = load_reg32(r2);
3414            tmp2 = tcg_temp_new_i64();
3415            tcg_gen_ext_i32_i64(tmp2, tmp32_1);
3416            tcg_temp_free_i32(tmp32_1);
3417        }
3418        tmp3 = tcg_temp_new_i64();
3419        tcg_gen_div_i64(tmp3, tmp, tmp2);
3420        store_reg(r1 + 1, tmp3);
3421        tcg_gen_rem_i64(tmp3, tmp, tmp2);
3422        store_reg(r1, tmp3);
3423        tcg_temp_free_i64(tmp);
3424        tcg_temp_free_i64(tmp2);
3425        tcg_temp_free_i64(tmp3);
3426        break;
3427    case 0x14: /* LGFR     R1,R2     [RRE] */
3428        tmp32_1 = load_reg32(r2);
3429        tmp = tcg_temp_new_i64();
3430        tcg_gen_ext_i32_i64(tmp, tmp32_1);
3431        store_reg(r1, tmp);
3432        tcg_temp_free_i32(tmp32_1);
3433        tcg_temp_free_i64(tmp);
3434        break;
3435    case 0x16: /* LLGFR      R1,R2     [RRE] */
3436        tmp32_1 = load_reg32(r2);
3437        tmp = tcg_temp_new_i64();
3438        tcg_gen_extu_i32_i64(tmp, tmp32_1);
3439        store_reg(r1, tmp);
3440        tcg_temp_free_i32(tmp32_1);
3441        tcg_temp_free_i64(tmp);
3442        break;
3443    case 0x17: /* LLGTR      R1,R2     [RRE] */
3444        tmp32_1 = load_reg32(r2);
3445        tmp = tcg_temp_new_i64();
3446        tcg_gen_andi_i32(tmp32_1, tmp32_1, 0x7fffffffUL);
3447        tcg_gen_extu_i32_i64(tmp, tmp32_1);
3448        store_reg(r1, tmp);
3449        tcg_temp_free_i32(tmp32_1);
3450        tcg_temp_free_i64(tmp);
3451        break;
3452    case 0x18: /* AGFR     R1,R2     [RRE] */
3453    case 0x1a: /* ALGFR     R1,R2     [RRE] */
3454        tmp32_1 = load_reg32(r2);
3455        tmp2 = tcg_temp_new_i64();
3456        if (op == 0x18) {
3457            tcg_gen_ext_i32_i64(tmp2, tmp32_1);
3458        } else {
3459            tcg_gen_extu_i32_i64(tmp2, tmp32_1);
3460        }
3461        tcg_temp_free_i32(tmp32_1);
3462        tmp = load_reg(r1);
3463        tmp3 = tcg_temp_new_i64();
3464        tcg_gen_add_i64(tmp3, tmp, tmp2);
3465        store_reg(r1, tmp3);
3466        if (op == 0x18) {
3467            set_cc_add64(s, tmp, tmp2, tmp3);
3468        } else {
3469            set_cc_addu64(s, tmp, tmp2, tmp3);
3470        }
3471        tcg_temp_free_i64(tmp);
3472        tcg_temp_free_i64(tmp2);
3473        tcg_temp_free_i64(tmp3);
3474        break;
3475    case 0x0f: /* LRVGR    R1,R2     [RRE] */
3476        tcg_gen_bswap64_i64(regs[r1], regs[r2]);
3477        break;
3478    case 0x1f: /* LRVR     R1,R2     [RRE] */
3479        tmp32_1 = load_reg32(r2);
3480        tcg_gen_bswap32_i32(tmp32_1, tmp32_1);
3481        store_reg32(r1, tmp32_1);
3482        tcg_temp_free_i32(tmp32_1);
3483        break;
3484    case 0x20: /* CGR      R1,R2     [RRE] */
3485    case 0x30: /* CGFR     R1,R2     [RRE] */
3486        tmp2 = load_reg(r2);
3487        if (op == 0x30) {
3488            tcg_gen_ext32s_i64(tmp2, tmp2);
3489        }
3490        tmp = load_reg(r1);
3491        cmp_s64(s, tmp, tmp2);
3492        tcg_temp_free_i64(tmp);
3493        tcg_temp_free_i64(tmp2);
3494        break;
3495    case 0x21: /* CLGR     R1,R2     [RRE] */
3496    case 0x31: /* CLGFR    R1,R2     [RRE] */
3497        tmp2 = load_reg(r2);
3498        if (op == 0x31) {
3499            tcg_gen_ext32u_i64(tmp2, tmp2);
3500        }
3501        tmp = load_reg(r1);
3502        cmp_u64(s, tmp, tmp2);
3503        tcg_temp_free_i64(tmp);
3504        tcg_temp_free_i64(tmp2);
3505        break;
3506    case 0x26: /* LBR R1,R2 [RRE] */
3507        tmp32_1 = load_reg32(r2);
3508        tcg_gen_ext8s_i32(tmp32_1, tmp32_1);
3509        store_reg32(r1, tmp32_1);
3510        tcg_temp_free_i32(tmp32_1);
3511        break;
3512    case 0x27: /* LHR R1,R2 [RRE] */
3513        tmp32_1 = load_reg32(r2);
3514        tcg_gen_ext16s_i32(tmp32_1, tmp32_1);
3515        store_reg32(r1, tmp32_1);
3516        tcg_temp_free_i32(tmp32_1);
3517        break;
3518    case 0x80: /* NGR R1,R2 [RRE] */
3519    case 0x81: /* OGR R1,R2 [RRE] */
3520    case 0x82: /* XGR R1,R2 [RRE] */
3521        tmp = load_reg(r1);
3522        tmp2 = load_reg(r2);
3523        switch (op) {
3524        case 0x80:
3525            tcg_gen_and_i64(tmp, tmp, tmp2);
3526            break;
3527        case 0x81:
3528            tcg_gen_or_i64(tmp, tmp, tmp2);
3529            break;
3530        case 0x82:
3531            tcg_gen_xor_i64(tmp, tmp, tmp2);
3532            break;
3533        default:
3534            tcg_abort();
3535        }
3536        store_reg(r1, tmp);
3537        set_cc_nz_u64(s, tmp);
3538        tcg_temp_free_i64(tmp);
3539        tcg_temp_free_i64(tmp2);
3540        break;
3541    case 0x83: /* FLOGR R1,R2 [RRE] */
3542        tmp = load_reg(r2);
3543        tmp32_1 = tcg_const_i32(r1);
3544        gen_helper_flogr(cc_op, tmp32_1, tmp);
3545        set_cc_static(s);
3546        tcg_temp_free_i64(tmp);
3547        tcg_temp_free_i32(tmp32_1);
3548        break;
3549    case 0x84: /* LLGCR R1,R2 [RRE] */
3550        tmp = load_reg(r2);
3551        tcg_gen_andi_i64(tmp, tmp, 0xff);
3552        store_reg(r1, tmp);
3553        tcg_temp_free_i64(tmp);
3554        break;
3555    case 0x85: /* LLGHR R1,R2 [RRE] */
3556        tmp = load_reg(r2);
3557        tcg_gen_andi_i64(tmp, tmp, 0xffff);
3558        store_reg(r1, tmp);
3559        tcg_temp_free_i64(tmp);
3560        break;
3561    case 0x87: /* DLGR      R1,R2     [RRE] */
3562        tmp32_1 = tcg_const_i32(r1);
3563        tmp = load_reg(r2);
3564        gen_helper_dlg(tmp32_1, tmp);
3565        tcg_temp_free_i64(tmp);
3566        tcg_temp_free_i32(tmp32_1);
3567        break;
3568    case 0x88: /* ALCGR     R1,R2     [RRE] */
3569        tmp = load_reg(r1);
3570        tmp2 = load_reg(r2);
3571        tmp3 = tcg_temp_new_i64();
3572        gen_op_calc_cc(s);
3573        tcg_gen_extu_i32_i64(tmp3, cc_op);
3574        tcg_gen_shri_i64(tmp3, tmp3, 1);
3575        tcg_gen_andi_i64(tmp3, tmp3, 1);
3576        tcg_gen_add_i64(tmp3, tmp2, tmp3);
3577        tcg_gen_add_i64(tmp3, tmp, tmp3);
3578        store_reg(r1, tmp3);
3579        set_cc_addu64(s, tmp, tmp2, tmp3);
3580        tcg_temp_free_i64(tmp);
3581        tcg_temp_free_i64(tmp2);
3582        tcg_temp_free_i64(tmp3);
3583        break;
3584    case 0x89: /* SLBGR   R1,R2     [RRE] */
3585        tmp = load_reg(r1);
3586        tmp2 = load_reg(r2);
3587        tmp32_1 = tcg_const_i32(r1);
3588        gen_op_calc_cc(s);
3589        gen_helper_slbg(cc_op, cc_op, tmp32_1, tmp, tmp2);
3590        set_cc_static(s);
3591        tcg_temp_free_i64(tmp);
3592        tcg_temp_free_i64(tmp2);
3593        tcg_temp_free_i32(tmp32_1);
3594        break;
3595    case 0x94: /* LLCR R1,R2 [RRE] */
3596        tmp32_1 = load_reg32(r2);
3597        tcg_gen_andi_i32(tmp32_1, tmp32_1, 0xff);
3598        store_reg32(r1, tmp32_1);
3599        tcg_temp_free_i32(tmp32_1);
3600        break;
3601    case 0x95: /* LLHR R1,R2 [RRE] */
3602        tmp32_1 = load_reg32(r2);
3603        tcg_gen_andi_i32(tmp32_1, tmp32_1, 0xffff);
3604        store_reg32(r1, tmp32_1);
3605        tcg_temp_free_i32(tmp32_1);
3606        break;
3607    case 0x96: /* MLR     R1,R2     [RRE] */
3608        /* reg(r1, r1+1) = reg(r1+1) * reg(r2) */
3609        tmp2 = load_reg(r2);
3610        tmp3 = load_reg((r1 + 1) & 15);
3611        tcg_gen_ext32u_i64(tmp2, tmp2);
3612        tcg_gen_ext32u_i64(tmp3, tmp3);
3613        tcg_gen_mul_i64(tmp2, tmp2, tmp3);
3614        store_reg32_i64((r1 + 1) & 15, tmp2);
3615        tcg_gen_shri_i64(tmp2, tmp2, 32);
3616        store_reg32_i64(r1, tmp2);
3617        tcg_temp_free_i64(tmp2);
3618        tcg_temp_free_i64(tmp3);
3619        break;
3620    case 0x97: /* DLR     R1,R2     [RRE] */
3621        /* reg(r1) = reg(r1, r1+1) % reg(r2) */
3622        /* reg(r1+1) = reg(r1, r1+1) / reg(r2) */
3623        tmp = load_reg(r1);
3624        tmp2 = load_reg(r2);
3625        tmp3 = load_reg((r1 + 1) & 15);
3626        tcg_gen_ext32u_i64(tmp2, tmp2);
3627        tcg_gen_ext32u_i64(tmp3, tmp3);
3628        tcg_gen_shli_i64(tmp, tmp, 32);
3629        tcg_gen_or_i64(tmp, tmp, tmp3);
3630
3631        tcg_gen_rem_i64(tmp3, tmp, tmp2);
3632        tcg_gen_div_i64(tmp, tmp, tmp2);
3633        store_reg32_i64((r1 + 1) & 15, tmp);
3634        store_reg32_i64(r1, tmp3);
3635        tcg_temp_free_i64(tmp);
3636        tcg_temp_free_i64(tmp2);
3637        tcg_temp_free_i64(tmp3);
3638        break;
3639    case 0x98: /* ALCR    R1,R2     [RRE] */
3640        tmp32_1 = load_reg32(r1);
3641        tmp32_2 = load_reg32(r2);
3642        tmp32_3 = tcg_temp_new_i32();
3643        /* XXX possible optimization point */
3644        gen_op_calc_cc(s);
3645        gen_helper_addc_u32(tmp32_3, cc_op, tmp32_1, tmp32_2);
3646        set_cc_addu32(s, tmp32_1, tmp32_2, tmp32_3);
3647        store_reg32(r1, tmp32_3);
3648        tcg_temp_free_i32(tmp32_1);
3649        tcg_temp_free_i32(tmp32_2);
3650        tcg_temp_free_i32(tmp32_3);
3651        break;
3652    case 0x99: /* SLBR    R1,R2     [RRE] */
3653        tmp32_1 = load_reg32(r2);
3654        tmp32_2 = tcg_const_i32(r1);
3655        gen_op_calc_cc(s);
3656        gen_helper_slb(cc_op, cc_op, tmp32_2, tmp32_1);
3657        set_cc_static(s);
3658        tcg_temp_free_i32(tmp32_1);
3659        tcg_temp_free_i32(tmp32_2);
3660        break;
3661    default:
3662        LOG_DISAS("illegal b9 operation 0x%x\n", op);
3663        gen_illegal_opcode(s, 2);
3664        break;
3665    }
3666}
3667
3668static void disas_c0(DisasContext *s, int op, int r1, int i2)
3669{
3670    TCGv_i64 tmp;
3671    TCGv_i32 tmp32_1, tmp32_2;
3672    uint64_t target = s->pc + i2 * 2LL;
3673    int l1;
3674
3675    LOG_DISAS("disas_c0: op 0x%x r1 %d i2 %d\n", op, r1, i2);
3676
3677    switch (op) {
3678    case 0: /* larl r1, i2 */
3679        tmp = tcg_const_i64(target);
3680        store_reg(r1, tmp);
3681        tcg_temp_free_i64(tmp);
3682        break;
3683    case 0x1: /* LGFI R1,I2 [RIL] */
3684        tmp = tcg_const_i64((int64_t)i2);
3685        store_reg(r1, tmp);
3686        tcg_temp_free_i64(tmp);
3687        break;
3688    case 0x4: /* BRCL     M1,I2     [RIL] */
3689        /* m1 & (1 << (3 - cc)) */
3690        tmp32_1 = tcg_const_i32(3);
3691        tmp32_2 = tcg_const_i32(1);
3692        gen_op_calc_cc(s);
3693        tcg_gen_sub_i32(tmp32_1, tmp32_1, cc_op);
3694        tcg_gen_shl_i32(tmp32_2, tmp32_2, tmp32_1);
3695        tcg_temp_free_i32(tmp32_1);
3696        tmp32_1 = tcg_const_i32(r1); /* m1 == r1 */
3697        tcg_gen_and_i32(tmp32_1, tmp32_1, tmp32_2);
3698        l1 = gen_new_label();
3699        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp32_1, 0, l1);
3700        gen_goto_tb(s, 0, target);
3701        gen_set_label(l1);
3702        gen_goto_tb(s, 1, s->pc + 6);
3703        s->is_jmp = DISAS_TB_JUMP;
3704        tcg_temp_free_i32(tmp32_1);
3705        tcg_temp_free_i32(tmp32_2);
3706        break;
3707    case 0x5: /* brasl r1, i2 */
3708        tmp = tcg_const_i64(pc_to_link_info(s, s->pc + 6));
3709        store_reg(r1, tmp);
3710        tcg_temp_free_i64(tmp);
3711        gen_goto_tb(s, 0, target);
3712        s->is_jmp = DISAS_TB_JUMP;
3713        break;
3714    case 0x7: /* XILF R1,I2 [RIL] */
3715    case 0xb: /* NILF R1,I2 [RIL] */
3716    case 0xd: /* OILF R1,I2 [RIL] */
3717        tmp32_1 = load_reg32(r1);
3718        switch (op) {
3719        case 0x7:
3720            tcg_gen_xori_i32(tmp32_1, tmp32_1, (uint32_t)i2);
3721            break;
3722        case 0xb:
3723            tcg_gen_andi_i32(tmp32_1, tmp32_1, (uint32_t)i2);
3724            break;
3725        case 0xd:
3726            tcg_gen_ori_i32(tmp32_1, tmp32_1, (uint32_t)i2);
3727            break;
3728        default:
3729            tcg_abort();
3730        }
3731        store_reg32(r1, tmp32_1);
3732        set_cc_nz_u32(s, tmp32_1);
3733        tcg_temp_free_i32(tmp32_1);
3734        break;
3735    case 0x9: /* IILF R1,I2 [RIL] */
3736        tmp32_1 = tcg_const_i32((uint32_t)i2);
3737        store_reg32(r1, tmp32_1);
3738        tcg_temp_free_i32(tmp32_1);
3739        break;
3740    case 0xa: /* NIHF R1,I2 [RIL] */
3741        tmp = load_reg(r1);
3742        tmp32_1 = tcg_temp_new_i32();
3743        tcg_gen_andi_i64(tmp, tmp, (((uint64_t)((uint32_t)i2)) << 32)
3744                                   | 0xffffffffULL);
3745        store_reg(r1, tmp);
3746        tcg_gen_shri_i64(tmp, tmp, 32);
3747        tcg_gen_trunc_i64_i32(tmp32_1, tmp);
3748        set_cc_nz_u32(s, tmp32_1);
3749        tcg_temp_free_i64(tmp);
3750        tcg_temp_free_i32(tmp32_1);
3751        break;
3752    case 0xe: /* LLIHF R1,I2 [RIL] */
3753        tmp = tcg_const_i64(((uint64_t)(uint32_t)i2) << 32);
3754        store_reg(r1, tmp);
3755        tcg_temp_free_i64(tmp);
3756        break;
3757    case 0xf: /* LLILF R1,I2 [RIL] */
3758        tmp = tcg_const_i64((uint32_t)i2);
3759        store_reg(r1, tmp);
3760        tcg_temp_free_i64(tmp);
3761        break;
3762    default:
3763        LOG_DISAS("illegal c0 operation 0x%x\n", op);
3764        gen_illegal_opcode(s, 3);
3765        break;
3766    }
3767}
3768
3769static void disas_c2(DisasContext *s, int op, int r1, int i2)
3770{
3771    TCGv_i64 tmp, tmp2, tmp3;
3772    TCGv_i32 tmp32_1, tmp32_2, tmp32_3;
3773
3774    switch (op) {
3775    case 0x4: /* SLGFI R1,I2 [RIL] */
3776    case 0xa: /* ALGFI R1,I2 [RIL] */
3777        tmp = load_reg(r1);
3778        tmp2 = tcg_const_i64((uint64_t)(uint32_t)i2);
3779        tmp3 = tcg_temp_new_i64();
3780        switch (op) {
3781        case 0x4:
3782            tcg_gen_sub_i64(tmp3, tmp, tmp2);
3783            set_cc_subu64(s, tmp, tmp2, tmp3);
3784            break;
3785        case 0xa:
3786            tcg_gen_add_i64(tmp3, tmp, tmp2);
3787            set_cc_addu64(s, tmp, tmp2, tmp3);
3788            break;
3789        default:
3790            tcg_abort();
3791        }
3792        store_reg(r1, tmp3);
3793        tcg_temp_free_i64(tmp);
3794        tcg_temp_free_i64(tmp2);
3795        tcg_temp_free_i64(tmp3);
3796        break;
3797    case 0x5: /* SLFI R1,I2 [RIL] */
3798    case 0xb: /* ALFI R1,I2 [RIL] */
3799        tmp32_1 = load_reg32(r1);
3800        tmp32_2 = tcg_const_i32(i2);
3801        tmp32_3 = tcg_temp_new_i32();
3802        switch (op) {
3803        case 0x5:
3804            tcg_gen_sub_i32(tmp32_3, tmp32_1, tmp32_2);
3805            set_cc_subu32(s, tmp32_1, tmp32_2, tmp32_3);
3806            break;
3807        case 0xb:
3808            tcg_gen_add_i32(tmp32_3, tmp32_1, tmp32_2);
3809            set_cc_addu32(s, tmp32_1, tmp32_2, tmp32_3);
3810            break;
3811        default:
3812            tcg_abort();
3813        }
3814        store_reg32(r1, tmp32_3);
3815        tcg_temp_free_i32(tmp32_1);
3816        tcg_temp_free_i32(tmp32_2);
3817        tcg_temp_free_i32(tmp32_3);
3818        break;
3819    case 0xc: /* CGFI R1,I2 [RIL] */
3820        tmp = load_reg(r1);
3821        cmp_s64c(s, tmp, (int64_t)i2);
3822        tcg_temp_free_i64(tmp);
3823        break;
3824    case 0xe: /* CLGFI R1,I2 [RIL] */
3825        tmp = load_reg(r1);
3826        cmp_u64c(s, tmp, (uint64_t)(uint32_t)i2);
3827        tcg_temp_free_i64(tmp);
3828        break;
3829    case 0xd: /* CFI R1,I2 [RIL] */
3830        tmp32_1 = load_reg32(r1);
3831        cmp_s32c(s, tmp32_1, i2);
3832        tcg_temp_free_i32(tmp32_1);
3833        break;
3834    case 0xf: /* CLFI R1,I2 [RIL] */
3835        tmp32_1 = load_reg32(r1);
3836        cmp_u32c(s, tmp32_1, i2);
3837        tcg_temp_free_i32(tmp32_1);
3838        break;
3839    default:
3840        LOG_DISAS("illegal c2 operation 0x%x\n", op);
3841        gen_illegal_opcode(s, 3);
3842        break;
3843    }
3844}
3845
3846static void gen_and_or_xor_i32(int opc, TCGv_i32 tmp, TCGv_i32 tmp2)
3847{
3848    switch (opc & 0xf) {
3849    case 0x4:
3850        tcg_gen_and_i32(tmp, tmp, tmp2);
3851        break;
3852    case 0x6:
3853        tcg_gen_or_i32(tmp, tmp, tmp2);
3854        break;
3855    case 0x7:
3856        tcg_gen_xor_i32(tmp, tmp, tmp2);
3857        break;
3858    default:
3859        tcg_abort();
3860    }
3861}
3862
3863static void disas_s390_insn(DisasContext *s)
3864{
3865    TCGv_i64 tmp, tmp2, tmp3, tmp4;
3866    TCGv_i32 tmp32_1, tmp32_2, tmp32_3, tmp32_4;
3867    unsigned char opc;
3868    uint64_t insn;
3869    int op, r1, r2, r3, d1, d2, x2, b1, b2, i, i2, r1b;
3870    TCGv_i32 vl;
3871    int ilc;
3872    int l1;
3873
3874    opc = ldub_code(s->pc);
3875    LOG_DISAS("opc 0x%x\n", opc);
3876
3877    ilc = get_ilc(opc);
3878
3879    switch (opc) {
3880#ifndef CONFIG_USER_ONLY
3881    case 0x01: /* SAM */
3882        insn = ld_code2(s->pc);
3883        /* set addressing mode, but we only do 64bit anyways */
3884        break;
3885#endif
3886    case 0x6: /* BCTR     R1,R2     [RR] */
3887        insn = ld_code2(s->pc);
3888        decode_rr(s, insn, &r1, &r2);
3889        tmp32_1 = load_reg32(r1);
3890        tcg_gen_subi_i32(tmp32_1, tmp32_1, 1);
3891        store_reg32(r1, tmp32_1);
3892
3893        if (r2) {
3894            gen_update_cc_op(s);
3895            l1 = gen_new_label();
3896            tcg_gen_brcondi_i32(TCG_COND_NE, tmp32_1, 0, l1);
3897
3898            /* not taking the branch, jump to after the instruction */
3899            gen_goto_tb(s, 0, s->pc + 2);
3900            gen_set_label(l1);
3901
3902            /* take the branch, move R2 into psw.addr */
3903            tmp32_1 = load_reg32(r2);
3904            tmp = tcg_temp_new_i64();
3905            tcg_gen_extu_i32_i64(tmp, tmp32_1);
3906            tcg_gen_mov_i64(psw_addr, tmp);
3907            s->is_jmp = DISAS_JUMP;
3908            tcg_temp_free_i32(tmp32_1);
3909            tcg_temp_free_i64(tmp);
3910        }
3911        break;
3912    case 0x7: /* BCR    M1,R2     [RR] */
3913        insn = ld_code2(s->pc);
3914        decode_rr(s, insn, &r1, &r2);
3915        if (r2) {
3916            tmp = load_reg(r2);
3917            gen_bcr(s, r1, tmp, s->pc);
3918            tcg_temp_free_i64(tmp);
3919            s->is_jmp = DISAS_TB_JUMP;
3920        } else {
3921            /* XXX: "serialization and checkpoint-synchronization function"? */
3922        }
3923        break;
3924    case 0xa: /* SVC    I         [RR] */
3925        insn = ld_code2(s->pc);
3926        debug_insn(insn);
3927        i = insn & 0xff;
3928        update_psw_addr(s);
3929        gen_op_calc_cc(s);
3930        tmp32_1 = tcg_const_i32(i);
3931        tmp32_2 = tcg_const_i32(ilc * 2);
3932        tmp32_3 = tcg_const_i32(EXCP_SVC);
3933        tcg_gen_st_i32(tmp32_1, cpu_env, offsetof(CPUState, int_svc_code));
3934        tcg_gen_st_i32(tmp32_2, cpu_env, offsetof(CPUState, int_svc_ilc));
3935        gen_helper_exception(tmp32_3);
3936        s->is_jmp = DISAS_EXCP;
3937        tcg_temp_free_i32(tmp32_1);
3938        tcg_temp_free_i32(tmp32_2);
3939        tcg_temp_free_i32(tmp32_3);
3940        break;
3941    case 0xd: /* BASR   R1,R2     [RR] */
3942        insn = ld_code2(s->pc);
3943        decode_rr(s, insn, &r1, &r2);
3944        tmp = tcg_const_i64(pc_to_link_info(s, s->pc + 2));
3945        store_reg(r1, tmp);
3946        if (r2) {
3947            tmp2 = load_reg(r2);
3948            tcg_gen_mov_i64(psw_addr, tmp2);
3949            tcg_temp_free_i64(tmp2);
3950            s->is_jmp = DISAS_JUMP;
3951        }
3952        tcg_temp_free_i64(tmp);
3953        break;
3954    case 0xe: /* MVCL   R1,R2     [RR] */
3955        insn = ld_code2(s->pc);
3956        decode_rr(s, insn, &r1, &r2);
3957        tmp32_1 = tcg_const_i32(r1);
3958        tmp32_2 = tcg_const_i32(r2);
3959        potential_page_fault(s);
3960        gen_helper_mvcl(cc_op, tmp32_1, tmp32_2);
3961        set_cc_static(s);
3962        tcg_temp_free_i32(tmp32_1);
3963        tcg_temp_free_i32(tmp32_2);
3964        break;
3965    case 0x10: /* LPR    R1,R2     [RR] */
3966        insn = ld_code2(s->pc);
3967        decode_rr(s, insn, &r1, &r2);
3968        tmp32_1 = load_reg32(r2);
3969        set_cc_abs32(s, tmp32_1);
3970        gen_helper_abs_i32(tmp32_1, tmp32_1);
3971        store_reg32(r1, tmp32_1);
3972        tcg_temp_free_i32(tmp32_1);
3973        break;
3974    case 0x11: /* LNR    R1,R2     [RR] */
3975        insn = ld_code2(s->pc);
3976        decode_rr(s, insn, &r1, &r2);
3977        tmp32_1 = load_reg32(r2);
3978        set_cc_nabs32(s, tmp32_1);
3979        gen_helper_nabs_i32(tmp32_1, tmp32_1);
3980        store_reg32(r1, tmp32_1);
3981        tcg_temp_free_i32(tmp32_1);
3982        break;
3983    case 0x12: /* LTR    R1,R2     [RR] */
3984        insn = ld_code2(s->pc);
3985        decode_rr(s, insn, &r1, &r2);
3986        tmp32_1 = load_reg32(r2);
3987        if (r1 != r2) {
3988            store_reg32(r1, tmp32_1);
3989        }
3990        set_cc_s32(s, tmp32_1);
3991        tcg_temp_free_i32(tmp32_1);
3992        break;
3993    case 0x13: /* LCR    R1,R2     [RR] */
3994        insn = ld_code2(s->pc);
3995        decode_rr(s, insn, &r1, &r2);
3996        tmp32_1 = load_reg32(r2);
3997        tcg_gen_neg_i32(tmp32_1, tmp32_1);
3998        store_reg32(r1, tmp32_1);
3999        set_cc_comp32(s, tmp32_1);
4000        tcg_temp_free_i32(tmp32_1);
4001        break;
4002    case 0x14: /* NR     R1,R2     [RR] */
4003    case 0x16: /* OR     R1,R2     [RR] */
4004    case 0x17: /* XR     R1,R2     [RR] */
4005        insn = ld_code2(s->pc);
4006        decode_rr(s, insn, &r1, &r2);
4007        tmp32_2 = load_reg32(r2);
4008        tmp32_1 = load_reg32(r1);
4009        gen_and_or_xor_i32(opc, tmp32_1, tmp32_2);
4010        store_reg32(r1, tmp32_1);
4011        set_cc_nz_u32(s, tmp32_1);
4012        tcg_temp_free_i32(tmp32_1);
4013        tcg_temp_free_i32(tmp32_2);
4014        break;
4015    case 0x18: /* LR     R1,R2     [RR] */
4016        insn = ld_code2(s->pc);
4017        decode_rr(s, insn, &r1, &r2);
4018        tmp32_1 = load_reg32(r2);
4019        store_reg32(r1, tmp32_1);
4020        tcg_temp_free_i32(tmp32_1);
4021        break;
4022    case 0x15: /* CLR    R1,R2     [RR] */
4023    case 0x19: /* CR     R1,R2     [RR] */
4024        insn = ld_code2(s->pc);
4025        decode_rr(s, insn, &r1, &r2);
4026        tmp32_1 = load_reg32(r1);
4027        tmp32_2 = load_reg32(r2);
4028        if (opc == 0x15) {
4029            cmp_u32(s, tmp32_1, tmp32_2);
4030        } else {
4031            cmp_s32(s, tmp32_1, tmp32_2);
4032        }
4033        tcg_temp_free_i32(tmp32_1);
4034        tcg_temp_free_i32(tmp32_2);
4035        break;
4036    case 0x1a: /* AR     R1,R2     [RR] */
4037    case 0x1e: /* ALR    R1,R2     [RR] */
4038        insn = ld_code2(s->pc);
4039        decode_rr(s, insn, &r1, &r2);
4040        tmp32_1 = load_reg32(r1);
4041        tmp32_2 = load_reg32(r2);
4042        tmp32_3 = tcg_temp_new_i32();
4043        tcg_gen_add_i32(tmp32_3, tmp32_1, tmp32_2);
4044        store_reg32(r1, tmp32_3);
4045        if (opc == 0x1a) {
4046            set_cc_add32(s, tmp32_1, tmp32_2, tmp32_3);
4047        } else {
4048            set_cc_addu32(s, tmp32_1, tmp32_2, tmp32_3);
4049        }
4050        tcg_temp_free_i32(tmp32_1);
4051        tcg_temp_free_i32(tmp32_2);
4052        tcg_temp_free_i32(tmp32_3);
4053        break;
4054    case 0x1b: /* SR     R1,R2     [RR] */
4055    case 0x1f: /* SLR    R1,R2     [RR] */
4056        insn = ld_code2(s->pc);
4057        decode_rr(s, insn, &r1, &r2);
4058        tmp32_1 = load_reg32(r1);
4059        tmp32_2 = load_reg32(r2);
4060        tmp32_3 = tcg_temp_new_i32();
4061        tcg_gen_sub_i32(tmp32_3, tmp32_1, tmp32_2);
4062        store_reg32(r1, tmp32_3);
4063        if (opc == 0x1b) {
4064            set_cc_sub32(s, tmp32_1, tmp32_2, tmp32_3);
4065        } else {
4066            set_cc_subu32(s, tmp32_1, tmp32_2, tmp32_3);
4067        }
4068        tcg_temp_free_i32(tmp32_1);
4069        tcg_temp_free_i32(tmp32_2);
4070        tcg_temp_free_i32(tmp32_3);
4071        break;
4072    case 0x1c: /* MR     R1,R2     [RR] */
4073        /* reg(r1, r1+1) = reg(r1+1) * reg(r2) */
4074        insn = ld_code2(s->pc);
4075        decode_rr(s, insn, &r1, &r2);
4076        tmp2 = load_reg(r2);
4077        tmp3 = load_reg((r1 + 1) & 15);
4078        tcg_gen_ext32s_i64(tmp2, tmp2);
4079        tcg_gen_ext32s_i64(tmp3, tmp3);
4080        tcg_gen_mul_i64(tmp2, tmp2, tmp3);
4081        store_reg32_i64((r1 + 1) & 15, tmp2);
4082        tcg_gen_shri_i64(tmp2, tmp2, 32);
4083        store_reg32_i64(r1, tmp2);
4084        tcg_temp_free_i64(tmp2);
4085        tcg_temp_free_i64(tmp3);
4086        break;
4087    case 0x1d: /* DR     R1,R2               [RR] */
4088        insn = ld_code2(s->pc);
4089        decode_rr(s, insn, &r1, &r2);
4090        tmp32_1 = load_reg32(r1);
4091        tmp32_2 = load_reg32(r1 + 1);
4092        tmp32_3 = load_reg32(r2);
4093
4094        tmp = tcg_temp_new_i64(); /* dividend */
4095        tmp2 = tcg_temp_new_i64(); /* divisor */
4096        tmp3 = tcg_temp_new_i64();
4097
4098        /* dividend is r(r1 << 32) | r(r1 + 1) */
4099        tcg_gen_extu_i32_i64(tmp, tmp32_1);
4100        tcg_gen_extu_i32_i64(tmp2, tmp32_2);
4101        tcg_gen_shli_i64(tmp, tmp, 32);
4102        tcg_gen_or_i64(tmp, tmp, tmp2);
4103
4104        /* divisor is r(r2) */
4105        tcg_gen_ext_i32_i64(tmp2, tmp32_3);
4106
4107        tcg_gen_div_i64(tmp3, tmp, tmp2);
4108        tcg_gen_rem_i64(tmp, tmp, tmp2);
4109
4110        tcg_gen_trunc_i64_i32(tmp32_1, tmp);
4111        tcg_gen_trunc_i64_i32(tmp32_2, tmp3);
4112
4113        store_reg32(r1, tmp32_1); /* remainder */
4114        store_reg32(r1 + 1, tmp32_2); /* quotient */
4115        tcg_temp_free_i32(tmp32_1);
4116        tcg_temp_free_i32(tmp32_2);
4117        tcg_temp_free_i32(tmp32_3);
4118        tcg_temp_free_i64(tmp);
4119        tcg_temp_free_i64(tmp2);
4120        tcg_temp_free_i64(tmp3);
4121        break;
4122    case 0x28: /* LDR    R1,R2               [RR] */
4123        insn = ld_code2(s->pc);
4124        decode_rr(s, insn, &r1, &r2);
4125        tmp = load_freg(r2);
4126        store_freg(r1, tmp);
4127        tcg_temp_free_i64(tmp);
4128        break;
4129    case 0x38: /* LER    R1,R2               [RR] */
4130        insn = ld_code2(s->pc);
4131        decode_rr(s, insn, &r1, &r2);
4132        tmp32_1 = load_freg32(r2);
4133        store_freg32(r1, tmp32_1);
4134        tcg_temp_free_i32(tmp32_1);
4135        break;
4136    case 0x40: /* STH    R1,D2(X2,B2)     [RX] */
4137        insn = ld_code4(s->pc);
4138        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4139        tmp2 = load_reg(r1);
4140        tcg_gen_qemu_st16(tmp2, tmp, get_mem_index(s));
4141        tcg_temp_free_i64(tmp);
4142        tcg_temp_free_i64(tmp2);
4143        break;
4144    case 0x41:        /* la */
4145        insn = ld_code4(s->pc);
4146        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4147        store_reg(r1, tmp); /* FIXME: 31/24-bit addressing */
4148        tcg_temp_free_i64(tmp);
4149        break;
4150    case 0x42: /* STC    R1,D2(X2,B2)     [RX] */
4151        insn = ld_code4(s->pc);
4152        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4153        tmp2 = load_reg(r1);
4154        tcg_gen_qemu_st8(tmp2, tmp, get_mem_index(s));
4155        tcg_temp_free_i64(tmp);
4156        tcg_temp_free_i64(tmp2);
4157        break;
4158    case 0x43: /* IC     R1,D2(X2,B2)     [RX] */
4159        insn = ld_code4(s->pc);
4160        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4161        tmp2 = tcg_temp_new_i64();
4162        tcg_gen_qemu_ld8u(tmp2, tmp, get_mem_index(s));
4163        store_reg8(r1, tmp2);
4164        tcg_temp_free_i64(tmp);
4165        tcg_temp_free_i64(tmp2);
4166        break;
4167    case 0x44: /* EX     R1,D2(X2,B2)     [RX] */
4168        insn = ld_code4(s->pc);
4169        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4170        tmp2 = load_reg(r1);
4171        tmp3 = tcg_const_i64(s->pc + 4);
4172        update_psw_addr(s);
4173        gen_op_calc_cc(s);
4174        gen_helper_ex(cc_op, cc_op, tmp2, tmp, tmp3);
4175        set_cc_static(s);
4176        tcg_temp_free_i64(tmp);
4177        tcg_temp_free_i64(tmp2);
4178        tcg_temp_free_i64(tmp3);
4179        break;
4180    case 0x46: /* BCT    R1,D2(X2,B2)     [RX] */
4181        insn = ld_code4(s->pc);
4182        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4183        tcg_temp_free_i64(tmp);
4184
4185        tmp32_1 = load_reg32(r1);
4186        tcg_gen_subi_i32(tmp32_1, tmp32_1, 1);
4187        store_reg32(r1, tmp32_1);
4188
4189        gen_update_cc_op(s);
4190        l1 = gen_new_label();
4191        tcg_gen_brcondi_i32(TCG_COND_NE, tmp32_1, 0, l1);
4192
4193        /* not taking the branch, jump to after the instruction */
4194        gen_goto_tb(s, 0, s->pc + 4);
4195        gen_set_label(l1);
4196
4197        /* take the branch, move R2 into psw.addr */
4198        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4199        tcg_gen_mov_i64(psw_addr, tmp);
4200        s->is_jmp = DISAS_JUMP;
4201        tcg_temp_free_i32(tmp32_1);
4202        tcg_temp_free_i64(tmp);
4203        break;
4204    case 0x47: /* BC     M1,D2(X2,B2)     [RX] */
4205        insn = ld_code4(s->pc);
4206        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4207        gen_bcr(s, r1, tmp, s->pc + 4);
4208        tcg_temp_free_i64(tmp);
4209        s->is_jmp = DISAS_TB_JUMP;
4210        break;
4211    case 0x48: /* LH     R1,D2(X2,B2)     [RX] */
4212        insn = ld_code4(s->pc);
4213        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4214        tmp2 = tcg_temp_new_i64();
4215        tcg_gen_qemu_ld16s(tmp2, tmp, get_mem_index(s));
4216        store_reg32_i64(r1, tmp2);
4217        tcg_temp_free_i64(tmp);
4218        tcg_temp_free_i64(tmp2);
4219        break;
4220    case 0x49: /* CH     R1,D2(X2,B2)     [RX] */
4221        insn = ld_code4(s->pc);
4222        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4223        tmp32_1 = load_reg32(r1);
4224        tmp32_2 = tcg_temp_new_i32();
4225        tmp2 = tcg_temp_new_i64();
4226        tcg_gen_qemu_ld16s(tmp2, tmp, get_mem_index(s));
4227        tcg_gen_trunc_i64_i32(tmp32_2, tmp2);
4228        cmp_s32(s, tmp32_1, tmp32_2);
4229        tcg_temp_free_i32(tmp32_1);
4230        tcg_temp_free_i32(tmp32_2);
4231        tcg_temp_free_i64(tmp);
4232        tcg_temp_free_i64(tmp2);
4233        break;
4234    case 0x4a: /* AH     R1,D2(X2,B2)     [RX] */
4235    case 0x4b: /* SH     R1,D2(X2,B2)     [RX] */
4236    case 0x4c: /* MH     R1,D2(X2,B2)     [RX] */
4237        insn = ld_code4(s->pc);
4238        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4239        tmp2 = tcg_temp_new_i64();
4240        tmp32_1 = load_reg32(r1);
4241        tmp32_2 = tcg_temp_new_i32();
4242        tmp32_3 = tcg_temp_new_i32();
4243
4244        tcg_gen_qemu_ld16s(tmp2, tmp, get_mem_index(s));
4245        tcg_gen_trunc_i64_i32(tmp32_2, tmp2);
4246        switch (opc) {
4247        case 0x4a:
4248            tcg_gen_add_i32(tmp32_3, tmp32_1, tmp32_2);
4249            set_cc_add32(s, tmp32_1, tmp32_2, tmp32_3);
4250            break;
4251        case 0x4b:
4252            tcg_gen_sub_i32(tmp32_3, tmp32_1, tmp32_2);
4253            set_cc_sub32(s, tmp32_1, tmp32_2, tmp32_3);
4254            break;
4255        case 0x4c:
4256            tcg_gen_mul_i32(tmp32_3, tmp32_1, tmp32_2);
4257            break;
4258        default:
4259            tcg_abort();
4260        }
4261        store_reg32(r1, tmp32_3);
4262
4263        tcg_temp_free_i32(tmp32_1);
4264        tcg_temp_free_i32(tmp32_2);
4265        tcg_temp_free_i32(tmp32_3);
4266        tcg_temp_free_i64(tmp);
4267        tcg_temp_free_i64(tmp2);
4268        break;
4269    case 0x4d: /* BAS    R1,D2(X2,B2)     [RX] */
4270        insn = ld_code4(s->pc);
4271        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4272        tmp2 = tcg_const_i64(pc_to_link_info(s, s->pc + 4));
4273        store_reg(r1, tmp2);
4274        tcg_gen_mov_i64(psw_addr, tmp);
4275        tcg_temp_free_i64(tmp);
4276        tcg_temp_free_i64(tmp2);
4277        s->is_jmp = DISAS_JUMP;
4278        break;
4279    case 0x4e: /* CVD    R1,D2(X2,B2)     [RX] */
4280        insn = ld_code4(s->pc);
4281        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4282        tmp2 = tcg_temp_new_i64();
4283        tmp32_1 = tcg_temp_new_i32();
4284        tcg_gen_trunc_i64_i32(tmp32_1, regs[r1]);
4285        gen_helper_cvd(tmp2, tmp32_1);
4286        tcg_gen_qemu_st64(tmp2, tmp, get_mem_index(s));
4287        tcg_temp_free_i64(tmp);
4288        tcg_temp_free_i64(tmp2);
4289        tcg_temp_free_i32(tmp32_1);
4290        break;
4291    case 0x50: /* st r1, d2(x2, b2) */
4292        insn = ld_code4(s->pc);
4293        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4294        tmp2 = load_reg(r1);
4295        tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s));
4296        tcg_temp_free_i64(tmp);
4297        tcg_temp_free_i64(tmp2);
4298        break;
4299    case 0x55: /* CL     R1,D2(X2,B2)     [RX] */
4300        insn = ld_code4(s->pc);
4301        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4302        tmp2 = tcg_temp_new_i64();
4303        tmp32_1 = tcg_temp_new_i32();
4304        tmp32_2 = load_reg32(r1);
4305        tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
4306        tcg_gen_trunc_i64_i32(tmp32_1, tmp2);
4307        cmp_u32(s, tmp32_2, tmp32_1);
4308        tcg_temp_free_i64(tmp);
4309        tcg_temp_free_i64(tmp2);
4310        tcg_temp_free_i32(tmp32_1);
4311        tcg_temp_free_i32(tmp32_2);
4312        break;
4313    case 0x54: /* N      R1,D2(X2,B2)     [RX] */
4314    case 0x56: /* O      R1,D2(X2,B2)     [RX] */
4315    case 0x57: /* X      R1,D2(X2,B2)     [RX] */
4316        insn = ld_code4(s->pc);
4317        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4318        tmp2 = tcg_temp_new_i64();
4319        tmp32_1 = load_reg32(r1);
4320        tmp32_2 = tcg_temp_new_i32();
4321        tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
4322        tcg_gen_trunc_i64_i32(tmp32_2, tmp2);
4323        gen_and_or_xor_i32(opc, tmp32_1, tmp32_2);
4324        store_reg32(r1, tmp32_1);
4325        set_cc_nz_u32(s, tmp32_1);
4326        tcg_temp_free_i64(tmp);
4327        tcg_temp_free_i64(tmp2);
4328        tcg_temp_free_i32(tmp32_1);
4329        tcg_temp_free_i32(tmp32_2);
4330        break;
4331    case 0x58: /* l r1, d2(x2, b2) */
4332        insn = ld_code4(s->pc);
4333        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4334        tmp2 = tcg_temp_new_i64();
4335        tmp32_1 = tcg_temp_new_i32();
4336        tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
4337        tcg_gen_trunc_i64_i32(tmp32_1, tmp2);
4338        store_reg32(r1, tmp32_1);
4339        tcg_temp_free_i64(tmp);
4340        tcg_temp_free_i64(tmp2);
4341        tcg_temp_free_i32(tmp32_1);
4342        break;
4343    case 0x59: /* C      R1,D2(X2,B2)     [RX] */
4344        insn = ld_code4(s->pc);
4345        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4346        tmp2 = tcg_temp_new_i64();
4347        tmp32_1 = tcg_temp_new_i32();
4348        tmp32_2 = load_reg32(r1);
4349        tcg_gen_qemu_ld32s(tmp2, tmp, get_mem_index(s));
4350        tcg_gen_trunc_i64_i32(tmp32_1, tmp2);
4351        cmp_s32(s, tmp32_2, tmp32_1);
4352        tcg_temp_free_i64(tmp);
4353        tcg_temp_free_i64(tmp2);
4354        tcg_temp_free_i32(tmp32_1);
4355        tcg_temp_free_i32(tmp32_2);
4356        break;
4357    case 0x5a: /* A      R1,D2(X2,B2)     [RX] */
4358    case 0x5b: /* S      R1,D2(X2,B2)     [RX] */
4359    case 0x5e: /* AL     R1,D2(X2,B2)     [RX] */
4360    case 0x5f: /* SL     R1,D2(X2,B2)     [RX] */
4361        insn = ld_code4(s->pc);
4362        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4363        tmp32_1 = load_reg32(r1);
4364        tmp32_2 = tcg_temp_new_i32();
4365        tmp32_3 = tcg_temp_new_i32();
4366        tcg_gen_qemu_ld32s(tmp, tmp, get_mem_index(s));
4367        tcg_gen_trunc_i64_i32(tmp32_2, tmp);
4368        switch (opc) {
4369        case 0x5a:
4370        case 0x5e:
4371            tcg_gen_add_i32(tmp32_3, tmp32_1, tmp32_2);
4372            break;
4373        case 0x5b:
4374        case 0x5f:
4375            tcg_gen_sub_i32(tmp32_3, tmp32_1, tmp32_2);
4376            break;
4377        default:
4378            tcg_abort();
4379        }
4380        store_reg32(r1, tmp32_3);
4381        switch (opc) {
4382        case 0x5a:
4383            set_cc_add32(s, tmp32_1, tmp32_2, tmp32_3);
4384            break;
4385        case 0x5e:
4386            set_cc_addu32(s, tmp32_1, tmp32_2, tmp32_3);
4387            break;
4388        case 0x5b:
4389            set_cc_sub32(s, tmp32_1, tmp32_2, tmp32_3);
4390            break;
4391        case 0x5f:
4392            set_cc_subu32(s, tmp32_1, tmp32_2, tmp32_3);
4393            break;
4394        default:
4395            tcg_abort();
4396        }
4397        tcg_temp_free_i64(tmp);
4398        tcg_temp_free_i32(tmp32_1);
4399        tcg_temp_free_i32(tmp32_2);
4400        tcg_temp_free_i32(tmp32_3);
4401        break;
4402    case 0x5c: /* M      R1,D2(X2,B2)        [RX] */
4403        /* reg(r1, r1+1) = reg(r1+1) * *(s32*)addr */
4404        insn = ld_code4(s->pc);
4405        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4406        tmp2 = tcg_temp_new_i64();
4407        tcg_gen_qemu_ld32s(tmp2, tmp, get_mem_index(s));
4408        tmp3 = load_reg((r1 + 1) & 15);
4409        tcg_gen_ext32s_i64(tmp2, tmp2);
4410        tcg_gen_ext32s_i64(tmp3, tmp3);
4411        tcg_gen_mul_i64(tmp2, tmp2, tmp3);
4412        store_reg32_i64((r1 + 1) & 15, tmp2);
4413        tcg_gen_shri_i64(tmp2, tmp2, 32);
4414        store_reg32_i64(r1, tmp2);
4415        tcg_temp_free_i64(tmp);
4416        tcg_temp_free_i64(tmp2);
4417        tcg_temp_free_i64(tmp3);
4418        break;
4419    case 0x5d: /* D      R1,D2(X2,B2)        [RX] */
4420        insn = ld_code4(s->pc);
4421        tmp3 = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4422        tmp32_1 = load_reg32(r1);
4423        tmp32_2 = load_reg32(r1 + 1);
4424
4425        tmp = tcg_temp_new_i64();
4426        tmp2 = tcg_temp_new_i64();
4427
4428        /* dividend is r(r1 << 32) | r(r1 + 1) */
4429        tcg_gen_extu_i32_i64(tmp, tmp32_1);
4430        tcg_gen_extu_i32_i64(tmp2, tmp32_2);
4431        tcg_gen_shli_i64(tmp, tmp, 32);
4432        tcg_gen_or_i64(tmp, tmp, tmp2);
4433
4434        /* divisor is in memory */
4435        tcg_gen_qemu_ld32s(tmp2, tmp3, get_mem_index(s));
4436
4437        /* XXX divisor == 0 -> FixP divide exception */
4438
4439        tcg_gen_div_i64(tmp3, tmp, tmp2);
4440        tcg_gen_rem_i64(tmp, tmp, tmp2);
4441
4442        tcg_gen_trunc_i64_i32(tmp32_1, tmp);
4443        tcg_gen_trunc_i64_i32(tmp32_2, tmp3);
4444
4445        store_reg32(r1, tmp32_1); /* remainder */
4446        store_reg32(r1 + 1, tmp32_2); /* quotient */
4447        tcg_temp_free_i32(tmp32_1);
4448        tcg_temp_free_i32(tmp32_2);
4449        tcg_temp_free_i64(tmp);
4450        tcg_temp_free_i64(tmp2);
4451        tcg_temp_free_i64(tmp3);
4452        break;
4453    case 0x60: /* STD    R1,D2(X2,B2)        [RX] */
4454        insn = ld_code4(s->pc);
4455        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4456        tmp2 = load_freg(r1);
4457        tcg_gen_qemu_st64(tmp2, tmp, get_mem_index(s));
4458        tcg_temp_free_i64(tmp);
4459        tcg_temp_free_i64(tmp2);
4460        break;
4461    case 0x68: /* LD    R1,D2(X2,B2)        [RX] */
4462        insn = ld_code4(s->pc);
4463        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4464        tmp2 = tcg_temp_new_i64();
4465        tcg_gen_qemu_ld64(tmp2, tmp, get_mem_index(s));
4466        store_freg(r1, tmp2);
4467        tcg_temp_free_i64(tmp);
4468        tcg_temp_free_i64(tmp2);
4469        break;
4470    case 0x70: /* STE R1,D2(X2,B2) [RX] */
4471        insn = ld_code4(s->pc);
4472        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4473        tmp2 = tcg_temp_new_i64();
4474        tmp32_1 = load_freg32(r1);
4475        tcg_gen_extu_i32_i64(tmp2, tmp32_1);
4476        tcg_gen_qemu_st32(tmp2, tmp, get_mem_index(s));
4477        tcg_temp_free_i64(tmp);
4478        tcg_temp_free_i64(tmp2);
4479        tcg_temp_free_i32(tmp32_1);
4480        break;
4481    case 0x71: /* MS      R1,D2(X2,B2)     [RX] */
4482        insn = ld_code4(s->pc);
4483        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4484        tmp2 = tcg_temp_new_i64();
4485        tmp32_1 = load_reg32(r1);
4486        tmp32_2 = tcg_temp_new_i32();
4487        tcg_gen_qemu_ld32s(tmp2, tmp, get_mem_index(s));
4488        tcg_gen_trunc_i64_i32(tmp32_2, tmp2);
4489        tcg_gen_mul_i32(tmp32_1, tmp32_1, tmp32_2);
4490        store_reg32(r1, tmp32_1);
4491        tcg_temp_free_i64(tmp);
4492        tcg_temp_free_i64(tmp2);
4493        tcg_temp_free_i32(tmp32_1);
4494        tcg_temp_free_i32(tmp32_2);
4495        break;
4496    case 0x78: /* LE     R1,D2(X2,B2)        [RX] */
4497        insn = ld_code4(s->pc);
4498        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4499        tmp2 = tcg_temp_new_i64();
4500        tmp32_1 = tcg_temp_new_i32();
4501        tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
4502        tcg_gen_trunc_i64_i32(tmp32_1, tmp2);
4503        store_freg32(r1, tmp32_1);
4504        tcg_temp_free_i64(tmp);
4505        tcg_temp_free_i64(tmp2);
4506        tcg_temp_free_i32(tmp32_1);
4507        break;
4508#ifndef CONFIG_USER_ONLY
4509    case 0x80: /* SSM      D2(B2)       [S] */
4510        /* Set System Mask */
4511        check_privileged(s, ilc);
4512        insn = ld_code4(s->pc);
4513        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4514        tmp = get_address(s, 0, b2, d2);
4515        tmp2 = tcg_temp_new_i64();
4516        tmp3 = tcg_temp_new_i64();
4517        tcg_gen_andi_i64(tmp3, psw_mask, ~0xff00000000000000ULL);
4518        tcg_gen_qemu_ld8u(tmp2, tmp, get_mem_index(s));
4519        tcg_gen_shli_i64(tmp2, tmp2, 56);
4520        tcg_gen_or_i64(psw_mask, tmp3, tmp2);
4521        tcg_temp_free_i64(tmp);
4522        tcg_temp_free_i64(tmp2);
4523        tcg_temp_free_i64(tmp3);
4524        break;
4525    case 0x82: /* LPSW     D2(B2)       [S] */
4526        /* Load PSW */
4527        check_privileged(s, ilc);
4528        insn = ld_code4(s->pc);
4529        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4530        tmp = get_address(s, 0, b2, d2);
4531        tmp2 = tcg_temp_new_i64();
4532        tmp3 = tcg_temp_new_i64();
4533        tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
4534        tcg_gen_addi_i64(tmp, tmp, 4);
4535        tcg_gen_qemu_ld32u(tmp3, tmp, get_mem_index(s));
4536        gen_helper_load_psw(tmp2, tmp3);
4537        tcg_temp_free_i64(tmp);
4538        tcg_temp_free_i64(tmp2);
4539        tcg_temp_free_i64(tmp3);
4540        /* we need to keep cc_op intact */
4541        s->is_jmp = DISAS_JUMP;
4542        break;
4543    case 0x83: /* DIAG     R1,R3,D2     [RS] */
4544        /* Diagnose call (KVM hypercall) */
4545        check_privileged(s, ilc);
4546        potential_page_fault(s);
4547        insn = ld_code4(s->pc);
4548        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4549        tmp32_1 = tcg_const_i32(insn & 0xfff);
4550        tmp2 = load_reg(2);
4551        tmp3 = load_reg(1);
4552        gen_helper_diag(tmp2, tmp32_1, tmp2, tmp3);
4553        store_reg(2, tmp2);
4554        tcg_temp_free_i32(tmp32_1);
4555        tcg_temp_free_i64(tmp2);
4556        tcg_temp_free_i64(tmp3);
4557        break;
4558#endif
4559    case 0x88: /* SRL    R1,D2(B2)        [RS] */
4560    case 0x89: /* SLL    R1,D2(B2)        [RS] */
4561    case 0x8a: /* SRA    R1,D2(B2)        [RS] */
4562        insn = ld_code4(s->pc);
4563        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4564        tmp = get_address(s, 0, b2, d2);
4565        tmp32_1 = load_reg32(r1);
4566        tmp32_2 = tcg_temp_new_i32();
4567        tcg_gen_trunc_i64_i32(tmp32_2, tmp);
4568        tcg_gen_andi_i32(tmp32_2, tmp32_2, 0x3f);
4569        switch (opc) {
4570        case 0x88:
4571            tcg_gen_shr_i32(tmp32_1, tmp32_1, tmp32_2);
4572            break;
4573        case 0x89:
4574            tcg_gen_shl_i32(tmp32_1, tmp32_1, tmp32_2);
4575            break;
4576        case 0x8a:
4577            tcg_gen_sar_i32(tmp32_1, tmp32_1, tmp32_2);
4578            set_cc_s32(s, tmp32_1);
4579            break;
4580        default:
4581            tcg_abort();
4582        }
4583        store_reg32(r1, tmp32_1);
4584        tcg_temp_free_i64(tmp);
4585        tcg_temp_free_i32(tmp32_1);
4586        tcg_temp_free_i32(tmp32_2);
4587        break;
4588    case 0x8c: /* SRDL   R1,D2(B2)        [RS] */
4589    case 0x8d: /* SLDL   R1,D2(B2)        [RS] */
4590    case 0x8e: /* SRDA   R1,D2(B2)        [RS] */
4591        insn = ld_code4(s->pc);
4592        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4593        tmp = get_address(s, 0, b2, d2); /* shift */
4594        tmp2 = tcg_temp_new_i64();
4595        tmp32_1 = load_reg32(r1);
4596        tmp32_2 = load_reg32(r1 + 1);
4597        tcg_gen_concat_i32_i64(tmp2, tmp32_2, tmp32_1); /* operand */
4598        switch (opc) {
4599        case 0x8c:
4600            tcg_gen_shr_i64(tmp2, tmp2, tmp);
4601            break;
4602        case 0x8d:
4603            tcg_gen_shl_i64(tmp2, tmp2, tmp);
4604            break;
4605        case 0x8e:
4606            tcg_gen_sar_i64(tmp2, tmp2, tmp);
4607            set_cc_s64(s, tmp2);
4608            break;
4609        }
4610        tcg_gen_shri_i64(tmp, tmp2, 32);
4611        tcg_gen_trunc_i64_i32(tmp32_1, tmp);
4612        store_reg32(r1, tmp32_1);
4613        tcg_gen_trunc_i64_i32(tmp32_2, tmp2);
4614        store_reg32(r1 + 1, tmp32_2);
4615        tcg_temp_free_i64(tmp);
4616        tcg_temp_free_i64(tmp2);
4617        break;
4618    case 0x98: /* LM     R1,R3,D2(B2)     [RS] */
4619    case 0x90: /* STM    R1,R3,D2(B2)     [RS] */
4620        insn = ld_code4(s->pc);
4621        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4622
4623        tmp = get_address(s, 0, b2, d2);
4624        tmp2 = tcg_temp_new_i64();
4625        tmp3 = tcg_const_i64(4);
4626        tmp4 = tcg_const_i64(0xffffffff00000000ULL);
4627        for (i = r1;; i = (i + 1) % 16) {
4628            if (opc == 0x98) {
4629                tcg_gen_qemu_ld32u(tmp2, tmp, get_mem_index(s));
4630                tcg_gen_and_i64(regs[i], regs[i], tmp4);
4631                tcg_gen_or_i64(regs[i], regs[i], tmp2);
4632            } else {
4633                tcg_gen_qemu_st32(regs[i], tmp, get_mem_index(s));
4634            }
4635            if (i == r3) {
4636                break;
4637            }
4638            tcg_gen_add_i64(tmp, tmp, tmp3);
4639        }
4640        tcg_temp_free_i64(tmp);
4641        tcg_temp_free_i64(tmp2);
4642        tcg_temp_free_i64(tmp3);
4643        tcg_temp_free_i64(tmp4);
4644        break;
4645    case 0x91: /* TM     D1(B1),I2        [SI] */
4646        insn = ld_code4(s->pc);
4647        tmp = decode_si(s, insn, &i2, &b1, &d1);
4648        tmp2 = tcg_const_i64(i2);
4649        tcg_gen_qemu_ld8u(tmp, tmp, get_mem_index(s));
4650        cmp_64(s, tmp, tmp2, CC_OP_TM_32);
4651        tcg_temp_free_i64(tmp);
4652        tcg_temp_free_i64(tmp2);
4653        break;
4654    case 0x92: /* MVI    D1(B1),I2        [SI] */
4655        insn = ld_code4(s->pc);
4656        tmp = decode_si(s, insn, &i2, &b1, &d1);
4657        tmp2 = tcg_const_i64(i2);
4658        tcg_gen_qemu_st8(tmp2, tmp, get_mem_index(s));
4659        tcg_temp_free_i64(tmp);
4660        tcg_temp_free_i64(tmp2);
4661        break;
4662    case 0x94: /* NI     D1(B1),I2        [SI] */
4663    case 0x96: /* OI     D1(B1),I2        [SI] */
4664    case 0x97: /* XI     D1(B1),I2        [SI] */
4665        insn = ld_code4(s->pc);
4666        tmp = decode_si(s, insn, &i2, &b1, &d1);
4667        tmp2 = tcg_temp_new_i64();
4668        tcg_gen_qemu_ld8u(tmp2, tmp, get_mem_index(s));
4669        switch (opc) {
4670        case 0x94:
4671            tcg_gen_andi_i64(tmp2, tmp2, i2);
4672            break;
4673        case 0x96:
4674            tcg_gen_ori_i64(tmp2, tmp2, i2);
4675            break;
4676        case 0x97:
4677            tcg_gen_xori_i64(tmp2, tmp2, i2);
4678            break;
4679        default:
4680            tcg_abort();
4681        }
4682        tcg_gen_qemu_st8(tmp2, tmp, get_mem_index(s));
4683        set_cc_nz_u64(s, tmp2);
4684        tcg_temp_free_i64(tmp);
4685        tcg_temp_free_i64(tmp2);
4686        break;
4687    case 0x95: /* CLI    D1(B1),I2        [SI] */
4688        insn = ld_code4(s->pc);
4689        tmp = decode_si(s, insn, &i2, &b1, &d1);
4690        tmp2 = tcg_temp_new_i64();
4691        tcg_gen_qemu_ld8u(tmp2, tmp, get_mem_index(s));
4692        cmp_u64c(s, tmp2, i2);
4693        tcg_temp_free_i64(tmp);
4694        tcg_temp_free_i64(tmp2);
4695        break;
4696    case 0x9a: /* LAM      R1,R3,D2(B2)     [RS] */
4697        insn = ld_code4(s->pc);
4698        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4699        tmp = get_address(s, 0, b2, d2);
4700        tmp32_1 = tcg_const_i32(r1);
4701        tmp32_2 = tcg_const_i32(r3);
4702        potential_page_fault(s);
4703        gen_helper_lam(tmp32_1, tmp, tmp32_2);
4704        tcg_temp_free_i64(tmp);
4705        tcg_temp_free_i32(tmp32_1);
4706        tcg_temp_free_i32(tmp32_2);
4707        break;
4708    case 0x9b: /* STAM     R1,R3,D2(B2)     [RS] */
4709        insn = ld_code4(s->pc);
4710        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4711        tmp = get_address(s, 0, b2, d2);
4712        tmp32_1 = tcg_const_i32(r1);
4713        tmp32_2 = tcg_const_i32(r3);
4714        potential_page_fault(s);
4715        gen_helper_stam(tmp32_1, tmp, tmp32_2);
4716        tcg_temp_free_i64(tmp);
4717        tcg_temp_free_i32(tmp32_1);
4718        tcg_temp_free_i32(tmp32_2);
4719        break;
4720    case 0xa5:
4721        insn = ld_code4(s->pc);
4722        r1 = (insn >> 20) & 0xf;
4723        op = (insn >> 16) & 0xf;
4724        i2 = insn & 0xffff;
4725        disas_a5(s, op, r1, i2);
4726        break;
4727    case 0xa7:
4728        insn = ld_code4(s->pc);
4729        r1 = (insn >> 20) & 0xf;
4730        op = (insn >> 16) & 0xf;
4731        i2 = (short)insn;
4732        disas_a7(s, op, r1, i2);
4733        break;
4734    case 0xa8: /* MVCLE   R1,R3,D2(B2)     [RS] */
4735        insn = ld_code4(s->pc);
4736        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4737        tmp = get_address(s, 0, b2, d2);
4738        tmp32_1 = tcg_const_i32(r1);
4739        tmp32_2 = tcg_const_i32(r3);
4740        potential_page_fault(s);
4741        gen_helper_mvcle(cc_op, tmp32_1, tmp, tmp32_2);
4742        set_cc_static(s);
4743        tcg_temp_free_i64(tmp);
4744        tcg_temp_free_i32(tmp32_1);
4745        tcg_temp_free_i32(tmp32_2);
4746        break;
4747    case 0xa9: /* CLCLE   R1,R3,D2(B2)     [RS] */
4748        insn = ld_code4(s->pc);
4749        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4750        tmp = get_address(s, 0, b2, d2);
4751        tmp32_1 = tcg_const_i32(r1);
4752        tmp32_2 = tcg_const_i32(r3);
4753        potential_page_fault(s);
4754        gen_helper_clcle(cc_op, tmp32_1, tmp, tmp32_2);
4755        set_cc_static(s);
4756        tcg_temp_free_i64(tmp);
4757        tcg_temp_free_i32(tmp32_1);
4758        tcg_temp_free_i32(tmp32_2);
4759        break;
4760#ifndef CONFIG_USER_ONLY
4761    case 0xac: /* STNSM   D1(B1),I2     [SI] */
4762    case 0xad: /* STOSM   D1(B1),I2     [SI] */
4763        check_privileged(s, ilc);
4764        insn = ld_code4(s->pc);
4765        tmp = decode_si(s, insn, &i2, &b1, &d1);
4766        tmp2 = tcg_temp_new_i64();
4767        tcg_gen_shri_i64(tmp2, psw_mask, 56);
4768        tcg_gen_qemu_st8(tmp2, tmp, get_mem_index(s));
4769        if (opc == 0xac) {
4770            tcg_gen_andi_i64(psw_mask, psw_mask,
4771                    ((uint64_t)i2 << 56) | 0x00ffffffffffffffULL);
4772        } else {
4773            tcg_gen_ori_i64(psw_mask, psw_mask, (uint64_t)i2 << 56);
4774        }
4775        tcg_temp_free_i64(tmp);
4776        tcg_temp_free_i64(tmp2);
4777        break;
4778    case 0xae: /* SIGP   R1,R3,D2(B2)     [RS] */
4779        check_privileged(s, ilc);
4780        insn = ld_code4(s->pc);
4781        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4782        tmp = get_address(s, 0, b2, d2);
4783        tmp2 = load_reg(r3);
4784        tmp32_1 = tcg_const_i32(r1);
4785        potential_page_fault(s);
4786        gen_helper_sigp(cc_op, tmp, tmp32_1, tmp2);
4787        set_cc_static(s);
4788        tcg_temp_free_i64(tmp);
4789        tcg_temp_free_i64(tmp2);
4790        tcg_temp_free_i32(tmp32_1);
4791        break;
4792    case 0xb1: /* LRA    R1,D2(X2, B2)     [RX] */
4793        check_privileged(s, ilc);
4794        insn = ld_code4(s->pc);
4795        tmp = decode_rx(s, insn, &r1, &x2, &b2, &d2);
4796        tmp32_1 = tcg_const_i32(r1);
4797        potential_page_fault(s);
4798        gen_helper_lra(cc_op, tmp, tmp32_1);
4799        set_cc_static(s);
4800        tcg_temp_free_i64(tmp);
4801        tcg_temp_free_i32(tmp32_1);
4802        break;
4803#endif
4804    case 0xb2:
4805        insn = ld_code4(s->pc);
4806        op = (insn >> 16) & 0xff;
4807        switch (op) {
4808        case 0x9c: /* STFPC    D2(B2) [S] */
4809            d2 = insn & 0xfff;
4810            b2 = (insn >> 12) & 0xf;
4811            tmp32_1 = tcg_temp_new_i32();
4812            tmp = tcg_temp_new_i64();
4813            tmp2 = get_address(s, 0, b2, d2);
4814            tcg_gen_ld_i32(tmp32_1, cpu_env, offsetof(CPUState, fpc));
4815            tcg_gen_extu_i32_i64(tmp, tmp32_1);
4816            tcg_gen_qemu_st32(tmp, tmp2, get_mem_index(s));
4817            tcg_temp_free_i32(tmp32_1);
4818            tcg_temp_free_i64(tmp);
4819            tcg_temp_free_i64(tmp2);
4820            break;
4821        default:
4822            disas_b2(s, op, insn);
4823            break;
4824        }
4825        break;
4826    case 0xb3:
4827        insn = ld_code4(s->pc);
4828        op = (insn >> 16) & 0xff;
4829        r3 = (insn >> 12) & 0xf; /* aka m3 */
4830        r1 = (insn >> 4) & 0xf;
4831        r2 = insn & 0xf;
4832        disas_b3(s, op, r3, r1, r2);
4833        break;
4834#ifndef CONFIG_USER_ONLY
4835    case 0xb6: /* STCTL     R1,R3,D2(B2)     [RS] */
4836        /* Store Control */
4837        check_privileged(s, ilc);
4838        insn = ld_code4(s->pc);
4839        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4840        tmp = get_address(s, 0, b2, d2);
4841        tmp32_1 = tcg_const_i32(r1);
4842        tmp32_2 = tcg_const_i32(r3);
4843        potential_page_fault(s);
4844        gen_helper_stctl(tmp32_1, tmp, tmp32_2);
4845        tcg_temp_free_i64(tmp);
4846        tcg_temp_free_i32(tmp32_1);
4847        tcg_temp_free_i32(tmp32_2);
4848        break;
4849    case 0xb7: /* LCTL      R1,R3,D2(B2)     [RS] */
4850        /* Load Control */
4851        check_privileged(s, ilc);
4852        insn = ld_code4(s->pc);
4853        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4854        tmp = get_address(s, 0, b2, d2);
4855        tmp32_1 = tcg_const_i32(r1);
4856        tmp32_2 = tcg_const_i32(r3);
4857        potential_page_fault(s);
4858        gen_helper_lctl(tmp32_1, tmp, tmp32_2);
4859        tcg_temp_free_i64(tmp);
4860        tcg_temp_free_i32(tmp32_1);
4861        tcg_temp_free_i32(tmp32_2);
4862        break;
4863#endif
4864    case 0xb9:
4865        insn = ld_code4(s->pc);
4866        r1 = (insn >> 4) & 0xf;
4867        r2 = insn & 0xf;
4868        op = (insn >> 16) & 0xff;
4869        disas_b9(s, op, r1, r2);
4870        break;
4871    case 0xba: /* CS     R1,R3,D2(B2)     [RS] */
4872        insn = ld_code4(s->pc);
4873        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4874        tmp = get_address(s, 0, b2, d2);
4875        tmp32_1 = tcg_const_i32(r1);
4876        tmp32_2 = tcg_const_i32(r3);
4877        potential_page_fault(s);
4878        gen_helper_cs(cc_op, tmp32_1, tmp, tmp32_2);
4879        set_cc_static(s);
4880        tcg_temp_free_i64(tmp);
4881        tcg_temp_free_i32(tmp32_1);
4882        tcg_temp_free_i32(tmp32_2);
4883        break;
4884    case 0xbd: /* CLM    R1,M3,D2(B2)     [RS] */
4885        insn = ld_code4(s->pc);
4886        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4887        tmp = get_address(s, 0, b2, d2);
4888        tmp32_1 = load_reg32(r1);
4889        tmp32_2 = tcg_const_i32(r3);
4890        potential_page_fault(s);
4891        gen_helper_clm(cc_op, tmp32_1, tmp32_2, tmp);
4892        set_cc_static(s);
4893        tcg_temp_free_i64(tmp);
4894        tcg_temp_free_i32(tmp32_1);
4895        tcg_temp_free_i32(tmp32_2);
4896        break;
4897    case 0xbe: /* STCM R1,M3,D2(B2) [RS] */
4898        insn = ld_code4(s->pc);
4899        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4900        tmp = get_address(s, 0, b2, d2);
4901        tmp32_1 = load_reg32(r1);
4902        tmp32_2 = tcg_const_i32(r3);
4903        potential_page_fault(s);
4904        gen_helper_stcm(tmp32_1, tmp32_2, tmp);
4905        tcg_temp_free_i64(tmp);
4906        tcg_temp_free_i32(tmp32_1);
4907        tcg_temp_free_i32(tmp32_2);
4908        break;
4909    case 0xbf: /* ICM    R1,M3,D2(B2)     [RS] */
4910        insn = ld_code4(s->pc);
4911        decode_rs(s, insn, &r1, &r3, &b2, &d2);
4912        if (r3 == 15) {
4913            /* effectively a 32-bit load */
4914            tmp = get_address(s, 0, b2, d2);
4915            tmp32_1 = tcg_temp_new_i32();
4916            tmp32_2 = tcg_const_i32(r3);
4917            tcg_gen_qemu_ld32u(tmp, tmp, get_mem_index(s));
4918            store_reg32_i64(r1, tmp);
4919            tcg_gen_trunc_i64_i32(tmp32_1, tmp);
4920            set_cc_icm(s, tmp32_2, tmp32_1);
4921            tcg_temp_free_i64(tmp);
4922            tcg_temp_free_i32(tmp32_1);
4923            tcg_temp_free_i32(tmp32_2);
4924        } else if (r3) {
4925            uint32_t mask = 0x00ffffffUL;
4926            uint32_t shift = 24;
4927            int m3 = r3;
4928            tmp = get_address(s, 0, b2, d2);
4929            tmp2 = tcg_temp_new_i64();
4930            tmp32_1 = load_reg32(r1);
4931            tmp32_2 = tcg_temp_new_i32();
4932            tmp32_3 = tcg_const_i32(r3);
4933            tmp32_4 = tcg_const_i32(0);
4934            while (m3) {
4935                if (m3 & 8) {
4936                    tcg_gen_qemu_ld8u(tmp2, tmp, get_mem_index(s));
4937                    tcg_gen_trunc_i64_i32(tmp32_2, tmp2);
4938                    if (shift) {
4939                        tcg_gen_shli_i32(tmp32_2, tmp32_2, shift);
4940                    }
4941                    tcg_gen_andi_i32(tmp32_1, tmp32_1, mask);
4942                    tcg_gen_or_i32(tmp32_1, tmp32_1, tmp32_2);
4943                    tcg_gen_or_i32(tmp32_4, tmp32_4, tmp32_2);
4944                    tcg_gen_addi_i64(tmp, tmp, 1);
4945                }
4946                m3 = (m3 << 1) & 0xf;
4947                mask = (mask >> 8) | 0xff000000UL;
4948                shift -= 8;
4949            }
4950            store_reg32(r1, tmp32_1);
4951            set_cc_icm(s, tmp32_3, tmp32_4);
4952            tcg_temp_free_i64(tmp);
4953            tcg_temp_free_i64(tmp2);
4954            tcg_temp_free_i32(tmp32_1);
4955            tcg_temp_free_i32(tmp32_2);
4956            tcg_temp_free_i32(tmp32_3);
4957            tcg_temp_free_i32(tmp32_4);
4958        } else {
4959            /* i.e. env->cc = 0 */
4960            gen_op_movi_cc(s, 0);
4961        }
4962        break;
4963    case 0xc0:
4964    case 0xc2:
4965        insn = ld_code6(s->pc);
4966        r1 = (insn >> 36) & 0xf;
4967        op = (insn >> 32) & 0xf;
4968        i2 = (int)insn;
4969        switch (opc) {
4970        case 0xc0:
4971            disas_c0(s, op, r1, i2);
4972            break;
4973        case 0xc2:
4974            disas_c2(s, op, r1, i2);
4975            break;
4976        default:
4977            tcg_abort();
4978        }
4979        break;
4980    case 0xd2: /* MVC    D1(L,B1),D2(B2)         [SS] */
4981    case 0xd4: /* NC     D1(L,B1),D2(B2)         [SS] */
4982    case 0xd5: /* CLC    D1(L,B1),D2(B2)         [SS] */
4983    case 0xd6: /* OC     D1(L,B1),D2(B2)         [SS] */
4984    case 0xd7: /* XC     D1(L,B1),D2(B2)         [SS] */
4985    case 0xdc: /* TR     D1(L,B1),D2(B2)         [SS] */
4986    case 0xf3: /* UNPK   D1(L1,B1),D2(L2,B2)     [SS] */
4987        insn = ld_code6(s->pc);
4988        vl = tcg_const_i32((insn >> 32) & 0xff);
4989        b1 = (insn >> 28) & 0xf;
4990        b2 = (insn >> 12) & 0xf;
4991        d1 = (insn >> 16) & 0xfff;
4992        d2 = insn & 0xfff;
4993        tmp = get_address(s, 0, b1, d1);
4994        tmp2 = get_address(s, 0, b2, d2);
4995        switch (opc) {
4996        case 0xd2:
4997            gen_op_mvc(s, (insn >> 32) & 0xff, tmp, tmp2);
4998            break;
4999        case 0xd4:
5000            potential_page_fault(s);
5001            gen_helper_nc(cc_op, vl, tmp, tmp2);
5002            set_cc_static(s);
5003            break;
5004        case 0xd5:
5005            gen_op_clc(s, (insn >> 32) & 0xff, tmp, tmp2);
5006            break;
5007        case 0xd6:
5008            potential_page_fault(s);
5009            gen_helper_oc(cc_op, vl, tmp, tmp2);
5010            set_cc_static(s);
5011            break;
5012        case 0xd7:
5013            potential_page_fault(s);
5014            gen_helper_xc(cc_op, vl, tmp, tmp2);
5015            set_cc_static(s);
5016            break;
5017        case 0xdc:
5018            potential_page_fault(s);
5019            gen_helper_tr(vl, tmp, tmp2);
5020            set_cc_static(s);
5021            break;
5022        case 0xf3:
5023            potential_page_fault(s);
5024            gen_helper_unpk(vl, tmp, tmp2);
5025            break;
5026        default:
5027            tcg_abort();
5028        }
5029        tcg_temp_free_i64(tmp);
5030        tcg_temp_free_i64(tmp2);
5031        break;
5032#ifndef CONFIG_USER_ONLY
5033    case 0xda: /* MVCP     D1(R1,B1),D2(B2),R3   [SS] */
5034    case 0xdb: /* MVCS     D1(R1,B1),D2(B2),R3   [SS] */
5035        check_privileged(s, ilc);
5036        potential_page_fault(s);
5037        insn = ld_code6(s->pc);
5038        r1 = (insn >> 36) & 0xf;
5039        r3 = (insn >> 32) & 0xf;
5040        b1 = (insn >> 28) & 0xf;
5041        d1 = (insn >> 16) & 0xfff;
5042        b2 = (insn >> 12) & 0xf;
5043        d2 = insn & 0xfff;
5044        tmp = load_reg(r1);
5045        /* XXX key in r3 */
5046        tmp2 = get_address(s, 0, b1, d1);
5047        tmp3 = get_address(s, 0, b2, d2);
5048        if (opc == 0xda) {
5049            gen_helper_mvcp(cc_op, tmp, tmp2, tmp3);
5050        } else {
5051            gen_helper_mvcs(cc_op, tmp, tmp2, tmp3);
5052        }
5053        set_cc_static(s);
5054        tcg_temp_free_i64(tmp);
5055        tcg_temp_free_i64(tmp2);
5056        tcg_temp_free_i64(tmp3);
5057        break;
5058#endif
5059    case 0xe3:
5060        insn = ld_code6(s->pc);
5061        debug_insn(insn);
5062        op = insn & 0xff;
5063        r1 = (insn >> 36) & 0xf;
5064        x2 = (insn >> 32) & 0xf;
5065        b2 = (insn >> 28) & 0xf;
5066        d2 = ((int)((((insn >> 16) & 0xfff)
5067           | ((insn << 4) & 0xff000)) << 12)) >> 12;
5068        disas_e3(s, op,  r1, x2, b2, d2 );
5069        break;
5070#ifndef CONFIG_USER_ONLY
5071    case 0xe5:
5072        /* Test Protection */
5073        check_privileged(s, ilc);
5074        insn = ld_code6(s->pc);
5075        debug_insn(insn);
5076        disas_e5(s, insn);
5077        break;
5078#endif
5079    case 0xeb:
5080        insn = ld_code6(s->pc);
5081        debug_insn(insn);
5082        op = insn & 0xff;
5083        r1 = (insn >> 36) & 0xf;
5084        r3 = (insn >> 32) & 0xf;
5085        b2 = (insn >> 28) & 0xf;
5086        d2 = ((int)((((insn >> 16) & 0xfff)
5087           | ((insn << 4) & 0xff000)) << 12)) >> 12;
5088        disas_eb(s, op, r1, r3, b2, d2);
5089        break;
5090    case 0xed:
5091        insn = ld_code6(s->pc);
5092        debug_insn(insn);
5093        op = insn & 0xff;
5094        r1 = (insn >> 36) & 0xf;
5095        x2 = (insn >> 32) & 0xf;
5096        b2 = (insn >> 28) & 0xf;
5097        d2 = (short)((insn >> 16) & 0xfff);
5098        r1b = (insn >> 12) & 0xf;
5099        disas_ed(s, op, r1, x2, b2, d2, r1b);
5100        break;
5101    default:
5102        LOG_DISAS("unimplemented opcode 0x%x\n", opc);
5103        gen_illegal_opcode(s, ilc);
5104        break;
5105    }
5106
5107    /* Instruction length is encoded in the opcode */
5108    s->pc += (ilc * 2);
5109}
5110
5111static inline void gen_intermediate_code_internal(CPUState *env,
5112                                                  TranslationBlock *tb,
5113                                                  int search_pc)
5114{
5115    DisasContext dc;
5116    target_ulong pc_start;
5117    uint64_t next_page_start;
5118    uint16_t *gen_opc_end;
5119    int j, lj = -1;
5120    int num_insns, max_insns;
5121    CPUBreakpoint *bp;
5122
5123    pc_start = tb->pc;
5124
5125    /* 31-bit mode */
5126    if (!(tb->flags & FLAG_MASK_64)) {
5127        pc_start &= 0x7fffffff;
5128    }
5129
5130    dc.pc = pc_start;
5131    dc.is_jmp = DISAS_NEXT;
5132    dc.tb = tb;
5133    dc.cc_op = CC_OP_DYNAMIC;
5134
5135    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5136
5137    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
5138
5139    num_insns = 0;
5140    max_insns = tb->cflags & CF_COUNT_MASK;
5141    if (max_insns == 0) {
5142        max_insns = CF_COUNT_MASK;
5143    }
5144
5145    gen_icount_start();
5146
5147    do {
5148        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
5149            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
5150                if (bp->pc == dc.pc) {
5151                    gen_debug(&dc);
5152                    break;
5153                }
5154            }
5155        }
5156        if (search_pc) {
5157            j = gen_opc_ptr - gen_opc_buf;
5158            if (lj < j) {
5159                lj++;
5160                while (lj < j) {
5161                    gen_opc_instr_start[lj++] = 0;
5162                }
5163            }
5164            gen_opc_pc[lj] = dc.pc;
5165            gen_opc_cc_op[lj] = dc.cc_op;
5166            gen_opc_instr_start[lj] = 1;
5167            gen_opc_icount[lj] = num_insns;
5168        }
5169        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) {
5170            gen_io_start();
5171        }
5172#if defined(S390X_DEBUG_DISAS_VERBOSE)
5173        LOG_DISAS("pc " TARGET_FMT_lx "\n",
5174                  dc.pc);
5175#endif
5176        disas_s390_insn(&dc);
5177
5178        num_insns++;
5179        if (env->singlestep_enabled) {
5180            gen_debug(&dc);
5181        }
5182    } while (!dc.is_jmp && gen_opc_ptr < gen_opc_end && dc.pc < next_page_start
5183             && num_insns < max_insns && !env->singlestep_enabled
5184             && !singlestep);
5185
5186    if (!dc.is_jmp) {
5187        update_psw_addr(&dc);
5188    }
5189
5190    if (singlestep && dc.cc_op != CC_OP_DYNAMIC) {
5191        gen_op_calc_cc(&dc);
5192    } else {
5193        /* next TB starts off with CC_OP_DYNAMIC, so make sure the cc op type
5194           is in env */
5195        gen_op_set_cc_op(&dc);
5196    }
5197
5198    if (tb->cflags & CF_LAST_IO) {
5199        gen_io_end();
5200    }
5201    /* Generate the return instruction */
5202    if (dc.is_jmp != DISAS_TB_JUMP) {
5203        tcg_gen_exit_tb(0);
5204    }
5205    gen_icount_end(tb, num_insns);
5206    *gen_opc_ptr = INDEX_op_end;
5207    if (search_pc) {
5208        j = gen_opc_ptr - gen_opc_buf;
5209        lj++;
5210        while (lj <= j) {
5211            gen_opc_instr_start[lj++] = 0;
5212        }
5213    } else {
5214        tb->size = dc.pc - pc_start;
5215        tb->icount = num_insns;
5216    }
5217#if defined(S390X_DEBUG_DISAS)
5218    log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
5219    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
5220        qemu_log("IN: %s\n", lookup_symbol(pc_start));
5221        log_target_disas(pc_start, dc.pc - pc_start, 1);
5222        qemu_log("\n");
5223    }
5224#endif
5225}
5226
5227void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5228{
5229    gen_intermediate_code_internal(env, tb, 0);
5230}
5231
5232void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5233{
5234    gen_intermediate_code_internal(env, tb, 1);
5235}
5236
5237void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
5238{
5239    int cc_op;
5240    env->psw.addr = gen_opc_pc[pc_pos];
5241    cc_op = gen_opc_cc_op[pc_pos];
5242    if ((cc_op != CC_OP_DYNAMIC) && (cc_op != CC_OP_STATIC)) {
5243        env->cc_op = cc_op;
5244    }
5245}
5246